For dependencies in following patches
Unified · Split
| @@ -29,6 +29,7 @@ Alexandre Belloni <alexandre.belloni@bootlin.com> <alexandre.belloni@free-electr · 28 unmodified lines | ||
| 29 | 29 | Alexei Starovoitov <ast@kernel.org> <alexei.starovoitov@gmail.com> |
| 30 | 30 | Alexei Starovoitov <ast@kernel.org> <ast@fb.com> |
| 31 | 31 | Alexei Starovoitov <ast@kernel.org> <ast@plumgrid.com> |
| 32 | +Alex Hung <alexhung@gmail.com> <alex.hung@canonical.com> | |
| 32 | 33 | Alex Shi <alexs@kernel.org> <alex.shi@intel.com> |
| 33 | 34 | Alex Shi <alexs@kernel.org> <alex.shi@linaro.org> |
| 34 | 35 | Alex Shi <alexs@kernel.org> <alex.shi@linux.alibaba.com> |
| @@ -382,6 +383,7 @@ Santosh Shilimkar <santosh.shilimkar@oracle.org> · 347 unmodified lines | ||
| 382 | 383 | Santosh Shilimkar <ssantosh@kernel.org> |
| 383 | 384 | Sarangdhar Joshi <spjoshi@codeaurora.org> |
| 384 | 385 | Sascha Hauer <s.hauer@pengutronix.de> |
| 386 | +Satya Priya <quic_c_skakit@quicinc.com> <skakit@codeaurora.org> | |
| 385 | 387 | S.Çağlar Onur <caglar@pardus.org.tr> |
| 386 | 388 | Sean Christopherson <seanjc@google.com> <sean.j.christopherson@intel.com> |
| 387 | 389 | Sean Nyekjaer <sean@geanix.com> <sean.nyekjaer@prevas.dk> |
| @@ -389,6 +391,7 @@ Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk> · 1 unmodified line | ||
| 389 | 391 | Sebastian Reichel <sre@kernel.org> <sre@debian.org> |
| 390 | 392 | Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de> |
| 391 | 393 | Seth Forshee <sforshee@kernel.org> <seth.forshee@canonical.com> |
| 394 | +Shannon Nelson <shannon.nelson@amd.com> <snelson@pensando.io> | |
| 392 | 395 | Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com> |
| 393 | 396 | Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com> |
| 394 | 397 | Shuah Khan <shuah@kernel.org> <shuah.khan@hp.com> |
| @@ -416,6 +419,7 @@ TripleX Chung <xxx.phy@gmail.com> <triplex@zh-kernel.org> · 21 unmodified lines | ||
| 416 | 419 | TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn> |
| 417 | 420 | Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com> |
| 418 | 421 | Tycho Andersen <tycho@tycho.pizza> <tycho@tycho.ws> |
| 422 | +Tzung-Bi Shih <tzungbi@kernel.org> <tzungbi@google.com> | |
| 419 | 423 | Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de> |
| 420 | 424 | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> |
| 421 | 425 | Uwe Kleine-König <ukleinek@strlen.de> |
| @@ -918,6 +918,11 @@ S: Ottawa, Ontario · 917 unmodified lines | ||
| 918 | 918 | S: K1N 6Z9 |
| 919 | 919 | S: CANADA |
| 920 | 920 | |
| 921 | +N: Vivien Didelot | |
| 922 | +E: vivien.didelot@gmail.com | |
| 923 | +D: DSA framework and MV88E6XXX driver | |
| 924 | +S: Montreal, Quebec, Canada | |
| 925 | + | |
| 921 | 926 | N: Jeff Dike |
| 922 | 927 | E: jdike@karaya.com |
| 923 | 928 | W: http://user-mode-linux.sourceforge.net |
| @@ -2447,6 +2452,10 @@ S: 482 Shadowgraph Dr. · 1523 unmodified lines | ||
| 2447 | 2452 | S: San Jose, CA 95110 |
| 2448 | 2453 | S: USA |
| 2449 | 2454 | |
| 2455 | +N: Michal Marek | |
| 2456 | +E: michal.lkml@markovi.net | |
| 2457 | +D: Kbuild Maintainer 2009-2017 | |
| 2458 | + | |
| 2450 | 2459 | N: Martin Mares |
| 2451 | 2460 | E: mj@ucw.cz |
| 2452 | 2461 | W: http://www.ucw.cz/~mj/ |
| @@ -6959,3 +6959,14 @@ · 6958 unmodified lines | ||
| 6959 | 6959 | memory, and other data can't be written using |
| 6960 | 6960 | xmon commands. |
| 6961 | 6961 | off xmon is disabled. |
| 6962 | + | |
| 6963 | + amd_pstate= [X86] | |
| 6964 | + disable | |
| 6965 | + Do not enable amd_pstate as the default | |
| 6966 | + scaling driver for the supported processors | |
| 6967 | + passive | |
| 6968 | + Use amd_pstate as a scaling driver, driver requests a | |
| 6969 | + desired performance on this abstract scale and the power | |
| 6970 | + management firmware translates the requests into actual | |
| 6971 | + hardware states (core frequency, data fabric and memory | |
| 6972 | + clocks etc.) | |
| @@ -283,23 +283,19 @@ efficiency frequency management method on AMD processors. · 282 unmodified lines | ||
| 283 | 283 | Kernel Module Options for ``amd-pstate`` |
| 284 | 284 | ========================================= |
| 285 | 285 | |
| 286 | −.. _shared_mem: | |
| 287 | − | |
| 288 | −``shared_mem`` | |
| 289 | −Use a module param (shared_mem) to enable related processors manually with | |
| 290 | −**amd_pstate.shared_mem=1**. | |
| 291 | −Due to the performance issue on the processors with `Shared Memory Support | |
| 292 | −<perf_cap_>`_, we disable it presently and will re-enable this by default | |
| 293 | −once we address performance issue with this solution. | |
| 294 | − | |
| 295 | −To check whether the current processor is using `Full MSR Support <perf_cap_>`_ | |
| 296 | −or `Shared Memory Support <perf_cap_>`_ : :: | |
| 297 | − | |
| 298 | − ray@hr-test1:~$ lscpu | grep cppc | |
| 299 | − Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba ibrs ibpb stibp vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold avic v_vmsave_vmload vgif v_spec_ctrl umip pku ospke vaes vpclmulqdq rdpid overflow_recov succor smca fsrm | |
| 300 | − | |
| 301 | −If the CPU flags have ``cppc``, then this processor supports `Full MSR Support | |
| 302 | −<perf_cap_>`_. Otherwise, it supports `Shared Memory Support <perf_cap_>`_. | |
| 286 | +Passive Mode | |
| 287 | +------------ | |
| 288 | + | |
| 289 | +``amd_pstate=passive`` | |
| 290 | + | |
| 291 | +It will be enabled if the ``amd_pstate=passive`` is passed to the kernel in the command line. | |
| 292 | +In this mode, ``amd_pstate`` driver software specifies a desired QoS target in the CPPC | |
| 293 | +performance scale as a relative number. This can be expressed as percentage of nominal | |
| 294 | +performance (infrastructure max). Below the nominal sustained performance level, | |
| 295 | +desired performance expresses the average performance level of the processor subject | |
| 296 | +to the Performance Reduction Tolerance register. Above the nominal performance level, | |
| 297 | +processor must provide at least nominal performance requested and go higher if current | |
| 298 | +operating conditions allow. | |
| 303 | 299 | |
| 304 | 300 | |
| 305 | 301 | ``cpupower`` tool support for ``amd-pstate`` |
| @@ -340,6 +340,14 @@ Before jumping into the kernel, the following conditions must be met: · 339 unmodified lines | ||
| 340 | 340 | - SMCR_EL2.LEN must be initialised to the same value for all CPUs the |
| 341 | 341 | kernel will execute on. |
| 342 | 342 | |
| 343 | + - HWFGRTR_EL2.nTPIDR2_EL0 (bit 55) must be initialised to 0b01. | |
| 344 | + | |
| 345 | + - HWFGWTR_EL2.nTPIDR2_EL0 (bit 55) must be initialised to 0b01. | |
| 346 | + | |
| 347 | + - HWFGRTR_EL2.nSMPRI_EL1 (bit 54) must be initialised to 0b01. | |
| 348 | + | |
| 349 | + - HWFGWTR_EL2.nSMPRI_EL1 (bit 54) must be initialised to 0b01. | |
| 350 | + | |
| 343 | 351 | For CPUs with the Scalable Matrix Extension FA64 feature (FEAT_SME_FA64) |
| 344 | 352 | |
| 345 | 353 | - If EL3 is present: |
| @@ -92,7 +92,7 @@ operation if the source belongs to the supported system register space. · 91 unmodified lines | ||
| 92 | 92 | |
| 93 | 93 | The infrastructure emulates only the following system register space:: |
| 94 | 94 | |
| 95 | − Op0=3, Op1=0, CRn=0, CRm=0,4,5,6,7 | |
| 95 | + Op0=3, Op1=0, CRn=0, CRm=0,2,3,4,5,6,7 | |
| 96 | 96 | |
| 97 | 97 | (See Table C5-6 'System instruction encodings for non-Debug System |
| 98 | 98 | register accesses' in ARMv8 ARM DDI 0487A.h, for the list of |
| @@ -293,6 +293,42 @@ infrastructure: · 194 unmodified lines | ||
| 293 | 293 | | WFXT | [3-0] | y | |
| 294 | 294 | +------------------------------+---------+---------+ |
| 295 | 295 | |
| 296 | + 10) MVFR0_EL1 - AArch32 Media and VFP Feature Register 0 | |
| 297 | + | |
| 298 | + +------------------------------+---------+---------+ | |
| 299 | + | Name | bits | visible | | |
| 300 | + +------------------------------+---------+---------+ | |
| 301 | + | FPDP | [11-8] | y | | |
| 302 | + +------------------------------+---------+---------+ | |
| 303 | + | |
| 304 | + 11) MVFR1_EL1 - AArch32 Media and VFP Feature Register 1 | |
| 305 | + | |
| 306 | + +------------------------------+---------+---------+ | |
| 307 | + | Name | bits | visible | | |
| 308 | + +------------------------------+---------+---------+ | |
| 309 | + | SIMDFMAC | [31-28] | y | | |
| 310 | + +------------------------------+---------+---------+ | |
| 311 | + | SIMDSP | [19-16] | y | | |
| 312 | + +------------------------------+---------+---------+ | |
| 313 | + | SIMDInt | [15-12] | y | | |
| 314 | + +------------------------------+---------+---------+ | |
| 315 | + | SIMDLS | [11-8] | y | | |
| 316 | + +------------------------------+---------+---------+ | |
| 317 | + | |
| 318 | + 12) ID_ISAR5_EL1 - AArch32 Instruction Set Attribute Register 5 | |
| 319 | + | |
| 320 | + +------------------------------+---------+---------+ | |
| 321 | + | Name | bits | visible | | |
| 322 | + +------------------------------+---------+---------+ | |
| 323 | + | CRC32 | [19-16] | y | | |
| 324 | + +------------------------------+---------+---------+ | |
| 325 | + | SHA2 | [15-12] | y | | |
| 326 | + +------------------------------+---------+---------+ | |
| 327 | + | SHA1 | [11-8] | y | | |
| 328 | + +------------------------------+---------+---------+ | |
| 329 | + | AES | [7-4] | y | | |
| 330 | + +------------------------------+---------+---------+ | |
| 331 | + | |
| 296 | 332 | |
| 297 | 333 | Appendix I: Example |
| 298 | 334 | ------------------- |
| @@ -67,6 +67,7 @@ uninitialized in the local variable, as well as the stack where the value was · 66 unmodified lines | ||
| 67 | 67 | copied to another memory location before use. |
| 68 | 68 | |
| 69 | 69 | A use of uninitialized value ``v`` is reported by KMSAN in the following cases: |
| 70 | + | |
| 70 | 71 | - in a condition, e.g. ``if (v) { ... }``; |
| 71 | 72 | - in an indexing or pointer dereferencing, e.g. ``array[v]`` or ``*v``; |
| 72 | 73 | - when it is copied to userspace or hardware, e.g. ``copy_to_user(..., &v, ...)``; |
| @@ -148,7 +148,7 @@ allOf: · 147 unmodified lines | ||
| 148 | 148 | items: |
| 149 | 149 | - const: oscclk |
| 150 | 150 | - const: dout_clkcmu_fsys1_bus |
| 151 | − - const: dout_clkcmu_fsys1_mmc_card | |
| 151 | + - const: gout_clkcmu_fsys1_mmc_card | |
| 152 | 152 | - const: dout_clkcmu_fsys1_usbdrd |
| 153 | 153 | |
| 154 | 154 | - if: |
| @@ -15,9 +15,22 @@ description: · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | properties: |
| 17 | 17 | compatible: |
| 18 | − enum: | |
| 19 | − - qcom,sfpb-mutex | |
| 20 | − - qcom,tcsr-mutex | |
| 18 | + oneOf: | |
| 19 | + - enum: | |
| 20 | + - qcom,sfpb-mutex | |
| 21 | + - qcom,tcsr-mutex | |
| 22 | + - items: | |
| 23 | + - enum: | |
| 24 | + - qcom,apq8084-tcsr-mutex | |
| 25 | + - qcom,ipq6018-tcsr-mutex | |
| 26 | + - qcom,msm8226-tcsr-mutex | |
| 27 | + - qcom,msm8994-tcsr-mutex | |
| 28 | + - const: qcom,tcsr-mutex | |
| 29 | + - items: | |
| 30 | + - enum: | |
| 31 | + - qcom,msm8974-tcsr-mutex | |
| 32 | + - const: qcom,tcsr-mutex | |
| 33 | + - const: syscon | |
| 21 | 34 | |
| 22 | 35 | reg: |
| 23 | 36 | maxItems: 1 |
| @@ -34,9 +47,9 @@ additionalProperties: false · 10 unmodified lines | ||
| 34 | 47 | |
| 35 | 48 | examples: |
| 36 | 49 | - | |
| 37 | − tcsr_mutex: hwlock@1f40000 { | |
| 38 | − compatible = "qcom,tcsr-mutex"; | |
| 39 | − reg = <0x01f40000 0x40000>; | |
| 40 | − #hwlock-cells = <1>; | |
| 41 | − }; | |
| 50 | + hwlock@1f40000 { | |
| 51 | + compatible = "qcom,tcsr-mutex"; | |
| 52 | + reg = <0x01f40000 0x40000>; | |
| 53 | + #hwlock-cells = <1>; | |
| 54 | + }; | |
| 42 | 55 | ... |
| @@ -62,13 +62,6 @@ properties: · 61 unmodified lines | ||
| 62 | 62 | description: |
| 63 | 63 | Inform the driver that last channel will be used to sensor battery. |
| 64 | 64 | |
| 65 | − aspeed,trim-data-valid: | |
| 66 | − type: boolean | |
| 67 | − description: | | |
| 68 | − The ADC reference voltage can be calibrated to obtain the trimming | |
| 69 | − data which will be stored in otp. This property informs the driver that | |
| 70 | − the data store in the otp is valid. | |
| 71 | − | |
| 72 | 65 | required: |
| 73 | 66 | - compatible |
| 74 | 67 | - reg |
| @@ -16,8 +16,11 @@ description: · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | properties: |
| 18 | 18 | compatible: |
| 19 | − items: | |
| 19 | + oneOf: | |
| 20 | 20 | - const: goodix,gt7375p |
| 21 | + - items: | |
| 22 | + - const: goodix,gt7986u | |
| 23 | + - const: goodix,gt7375p | |
| 21 | 24 | |
| 22 | 25 | reg: |
| 23 | 26 | enum: |
| @@ -24,7 +24,7 @@ properties: · 23 unmodified lines | ||
| 24 | 24 | oneOf: |
| 25 | 25 | - items: |
| 26 | 26 | - enum: |
| 27 | − - qcom,sc7280-bwmon | |
| 27 | + - qcom,sc7280-cpu-bwmon | |
| 28 | 28 | - qcom,sdm845-bwmon |
| 29 | 29 | - const: qcom,msm8998-bwmon |
| 30 | 30 | - const: qcom,msm8998-bwmon # BWMON v4 |
| @@ -36,6 +36,9 @@ properties: · 35 unmodified lines | ||
| 36 | 36 | resets: |
| 37 | 37 | maxItems: 1 |
| 38 | 38 | |
| 39 | + iommus: | |
| 40 | + maxItems: 1 | |
| 41 | + | |
| 39 | 42 | required: |
| 40 | 43 | - compatible |
| 41 | 44 | - reg |
| @@ -43,6 +46,7 @@ required: · 1 unmodified line | ||
| 43 | 46 | - clocks |
| 44 | 47 | - clock-names |
| 45 | 48 | - resets |
| 49 | + - iommus | |
| 46 | 50 | |
| 47 | 51 | additionalProperties: false |
| 48 | 52 | |
| @@ -59,6 +63,7 @@ examples: · 10 unmodified lines | ||
| 59 | 63 | clocks = <&ccu CLK_BUS_VP9>, <&ccu CLK_VP9>; |
| 60 | 64 | clock-names = "bus", "mod"; |
| 61 | 65 | resets = <&ccu RST_BUS_VP9>; |
| 66 | + iommus = <&iommu 5>; | |
| 62 | 67 | }; |
| 63 | 68 | |
| 64 | 69 | ... |
| @@ -47,7 +47,7 @@ properties: · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | nvmem-cells: true |
| 49 | 49 | |
| 50 | − nvmem-cells-names: true | |
| 50 | + nvmem-cell-names: true | |
| 51 | 51 | |
| 52 | 52 | phy-connection-type: |
| 53 | 53 | enum: |
| @@ -81,6 +81,9 @@ properties: · 80 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | power-supply: true |
| 83 | 83 | |
| 84 | + power-domains: | |
| 85 | + maxItems: 1 | |
| 86 | + | |
| 84 | 87 | resets: |
| 85 | 88 | description: | |
| 86 | 89 | A number of phandles to resets that need to be asserted during |
| @@ -8,7 +8,7 @@ title: Audio codec controlled by ChromeOS EC · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | 10 | - Cheng-Yi Chiang <cychiang@chromium.org> |
| 11 | − - Tzung-Bi Shih <tzungbi@google.com> | |
| 11 | + - Tzung-Bi Shih <tzungbi@kernel.org> | |
| 12 | 12 | |
| 13 | 13 | description: | |
| 14 | 14 | Google's ChromeOS EC codec is a digital mic codec provided by the |
| @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# · 6 unmodified lines | ||
| 7 | 7 | title: Realtek rt1015p codec devicetree bindings |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | − - Tzung-Bi Shih <tzungbi@google.com> | |
| 10 | + - Tzung-Bi Shih <tzungbi@kernel.org> | |
| 11 | 11 | |
| 12 | 12 | description: | |
| 13 | 13 | Rt1015p is a rt1015 variant which does not support I2C and |
| @@ -279,6 +279,7 @@ GPIO · 278 unmodified lines | ||
| 279 | 279 | devm_gpio_request_one() |
| 280 | 280 | |
| 281 | 281 | I2C |
| 282 | + devm_i2c_add_adapter() | |
| 282 | 283 | devm_i2c_new_dummy_device() |
| 283 | 284 | |
| 284 | 285 | IIO |
| @@ -16,12 +16,11 @@ Parallel Port Devices · 15 unmodified lines | ||
| 16 | 16 | 16x50 UART Driver |
| 17 | 17 | ================= |
| 18 | 18 | |
| 19 | −.. kernel-doc:: drivers/tty/serial/serial_core.c | |
| 20 | − :export: | |
| 21 | − | |
| 22 | 19 | .. kernel-doc:: drivers/tty/serial/8250/8250_core.c |
| 23 | 20 | :export: |
| 24 | 21 | |
| 22 | +See serial/driver.rst for related APIs. | |
| 23 | + | |
| 25 | 24 | Pulse-Width Modulation (PWM) |
| 26 | 25 | ============================ |
| 27 | 26 | |
| @@ -119,6 +119,16 @@ To avoid this, you can make the vDSO different for different · 118 unmodified lines | ||
| 119 | 119 | kernel versions by including an arbitrary string of "salt" in it. |
| 120 | 120 | This is specified by the Kconfig symbol ``CONFIG_BUILD_SALT``. |
| 121 | 121 | |
| 122 | +Git | |
| 123 | +--- | |
| 124 | + | |
| 125 | +Uncommitted changes or different commit ids in git can also lead | |
| 126 | +to different compilation results. For example, after executing | |
| 127 | +``git reset HEAD^``, even if the code is the same, the | |
| 128 | +``include/config/kernel.release`` generated during compilation | |
| 129 | +will be different, which will eventually lead to binary differences. | |
| 130 | +See ``scripts/setlocalversion`` for details. | |
| 131 | + | |
| 122 | 132 | .. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp |
| 123 | 133 | .. _KBUILD_BUILD_USER and KBUILD_BUILD_HOST: kbuild.html#kbuild-build-user-kbuild-build-host |
| 124 | 134 | .. _KCFLAGS: kbuild.html#kcflags |
| @@ -120,7 +120,7 @@ You can tell you are in a softirq (or tasklet) using the · 119 unmodified lines | ||
| 120 | 120 | .. warning:: |
| 121 | 121 | |
| 122 | 122 | Beware that this will return a false positive if a |
| 123 | − :ref:`botton half lock <local_bh_disable>` is held. | |
| 123 | + :ref:`bottom half lock <local_bh_disable>` is held. | |
| 124 | 124 | |
| 125 | 125 | Some Basic Rules |
| 126 | 126 | ================ |
| @@ -6,4 +6,4 @@ Generic Netlink · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | A wiki document on how to use Generic Netlink can be found here: |
| 8 | 8 | |
| 9 | − * http://www.linuxfoundation.org/collaborate/workgroups/networking/generic_netlink_howto | |
| 9 | + * https://wiki.linuxfoundation.org/networking/generic_netlink_howto | |
| @@ -126,17 +126,10 @@ than one development cycle past their initial release. So, for example, the · 125 unmodified lines | ||
| 126 | 126 | 5.2.21 was the final stable update of the 5.2 release. |
| 127 | 127 | |
| 128 | 128 | Some kernels are designated "long term" kernels; they will receive support |
| 129 | −for a longer period. As of this writing, the current long term kernels | |
| 130 | −and their maintainers are: | |
| 131 | − | |
| 132 | − ====== ================================ ======================= | |
| 133 | − 3.16 Ben Hutchings (very long-term kernel) | |
| 134 | − 4.4 Greg Kroah-Hartman & Sasha Levin (very long-term kernel) | |
| 135 | − 4.9 Greg Kroah-Hartman & Sasha Levin | |
| 136 | − 4.14 Greg Kroah-Hartman & Sasha Levin | |
| 137 | − 4.19 Greg Kroah-Hartman & Sasha Levin | |
| 138 | − 5.4 Greg Kroah-Hartman & Sasha Levin | |
| 139 | − ====== ================================ ======================= | |
| 129 | +for a longer period. Please refer to the following link for the list of active | |
| 130 | +long term kernel versions and their maintainers: | |
| 131 | + | |
| 132 | + https://www.kernel.org/category/releases.html | |
| 140 | 133 | |
| 141 | 134 | The selection of a kernel for long-term support is purely a matter of a |
| 142 | 135 | maintainer having the need and the time to maintain that release. There |
| @@ -51,7 +51,7 @@ the Technical Advisory Board (TAB) or other maintainers if you're · 50 unmodified lines | ||
| 51 | 51 | uncertain how to handle situations that come up. It will not be |
| 52 | 52 | considered a violation report unless you want it to be. If you are |
| 53 | 53 | uncertain about approaching the TAB or any other maintainers, please |
| 54 | −reach out to our conflict mediator, Joanna Lee <joanna.lee@gesmer.com>. | |
| 54 | +reach out to our conflict mediator, Joanna Lee <jlee@linuxfoundation.org>. | |
| 55 | 55 | |
| 56 | 56 | In the end, "be kind to each other" is really what the end goal is for |
| 57 | 57 | everybody. We know everyone is human and we all fail at times, but the |
| @@ -36,7 +36,7 @@ experience, the following books are good for, if anything, reference: · 35 unmodified lines | ||
| 36 | 36 | - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] |
| 37 | 37 | |
| 38 | 38 | The kernel is written using GNU C and the GNU toolchain. While it |
| 39 | −adheres to the ISO C89 standard, it uses a number of extensions that are | |
| 39 | +adheres to the ISO C11 standard, it uses a number of extensions that are | |
| 40 | 40 | not featured in the standard. The kernel is a freestanding C |
| 41 | 41 | environment, with no reliance on the standard C library, so some |
| 42 | 42 | portions of the C standard are not supported. Arbitrary long long |
| @@ -39,7 +39,7 @@ Documentation written by Tom Zanussi · 38 unmodified lines | ||
| 39 | 39 | will use the event's kernel stacktrace as the key. The keywords |
| 40 | 40 | 'keys' or 'key' can be used to specify keys, and the keywords |
| 41 | 41 | 'values', 'vals', or 'val' can be used to specify values. Compound |
| 42 | − keys consisting of up to two fields can be specified by the 'keys' | |
| 42 | + keys consisting of up to three fields can be specified by the 'keys' | |
| 43 | 43 | keyword. Hashing a compound key produces a unique entry in the |
| 44 | 44 | table for each unique combination of component keys, and can be |
| 45 | 45 | useful for providing more fine-grained summaries of event data. |
| @@ -44,7 +44,7 @@ altro, utili riferimenti: · 43 unmodified lines | ||
| 44 | 44 | - "C: A Reference Manual" di Harbison and Steele [Prentice Hall] |
| 45 | 45 | |
| 46 | 46 | Il kernel è stato scritto usando GNU C e la toolchain GNU. |
| 47 | −Sebbene si attenga allo standard ISO C89, esso utilizza una serie di | |
| 47 | +Sebbene si attenga allo standard ISO C11, esso utilizza una serie di | |
| 48 | 48 | estensioni che non sono previste in questo standard. Il kernel è un |
| 49 | 49 | ambiente C indipendente, che non ha alcuna dipendenza dalle librerie |
| 50 | 50 | C standard, così alcune parti del C standard non sono supportate. |
| @@ -65,7 +65,7 @@ Linux カーネル開発のやり方 · 64 unmodified lines | ||
| 65 | 65 | - 『新・詳説 C 言語 H&S リファレンス』 (サミュエル P ハービソン/ガイ L スティール共著 斉藤 信男監訳)[ソフトバンク] |
| 66 | 66 | |
| 67 | 67 | カーネルは GNU C と GNU ツールチェインを使って書かれています。カーネル |
| 68 | −は ISO C89 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って | |
| 68 | +は ISO C11 仕様に準拠して書く一方で、標準には無い言語拡張を多く使って | |
| 69 | 69 | います。カーネルは標準 C ライブラリに依存しない、C 言語非依存環境です。 |
| 70 | 70 | そのため、C の標準の中で使えないものもあります。特に任意の long long |
| 71 | 71 | の除算や浮動小数点は使えません。カーネルがツールチェインや C 言語拡張 |
| @@ -62,7 +62,7 @@ Documentation/process/howto.rst · 61 unmodified lines | ||
| 62 | 62 | - "Practical C Programming" by Steve Oualline [O'Reilly] |
| 63 | 63 | - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] |
| 64 | 64 | |
| 65 | −커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C89 표준을 | |
| 65 | +커널은 GNU C와 GNU 툴체인을 사용하여 작성되었다. 이 툴들은 ISO C11 표준을 | |
| 66 | 66 | 따르는 반면 표준에 있지 않은 많은 확장기능도 가지고 있다. 커널은 표준 C |
| 67 | 67 | 라이브러리와는 관계없이 freestanding C 환경이어서 C 표준의 일부는 |
| 68 | 68 | 지원되지 않는다. 임의의 long long 나누기나 floating point는 지원되지 않는다. |
| @@ -70,8 +70,8 @@ LA64中每个寄存器为64位宽。 ``$r0`` 的内容总是固定为0,而其 · 69 unmodified lines | ||
| 70 | 70 | ================= ================== =================== ========== |
| 71 | 71 | |
| 72 | 72 | .. note:: |
| 73 | − 注意:在一些遗留代码中有时可能见到 ``$v0`` 和 ``$v1`` ,它们是 | |
| 74 | − ``$a0`` 和 ``$a1`` 的别名,属于已经废弃的用法。 | |
| 73 | + 注意:在一些遗留代码中有时可能见到 ``$fv0`` 和 ``$fv1`` ,它们是 | |
| 74 | + ``$fa0`` 和 ``$fa1`` 的别名,属于已经废弃的用法。 | |
| 75 | 75 | |
| 76 | 76 | |
| 77 | 77 | 向量寄存器 |
| @@ -45,7 +45,7 @@ Linux内核大部分是由C语言写成的,一些体系结构相关的代码 · 44 unmodified lines | ||
| 45 | 45 | - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] |
| 46 | 46 | 《C语言参考手册(原书第5版)》(邱仲潘 等译)[机械工业出版社] |
| 47 | 47 | |
| 48 | −Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C89标准,但也用到了一些 | |
| 48 | +Linux内核使用GNU C和GNU工具链开发。虽然它遵循ISO C11标准,但也用到了一些 | |
| 49 | 49 | 标准中没有定义的扩展。内核是自给自足的C环境,不依赖于标准C库的支持,所以 |
| 50 | 50 | 并不支持C标准中的部分定义。比如long long类型的大数除法和浮点运算就不允许 |
| 51 | 51 | 使用。有时候确实很难弄清楚内核对工具链的要求和它所使用的扩展,不幸的是目 |
| @@ -48,7 +48,7 @@ Linux內核大部分是由C語言寫成的,一些體系結構相關的代碼 · 47 unmodified lines | ||
| 48 | 48 | - "C: A Reference Manual" by Harbison and Steele [Prentice Hall] |
| 49 | 49 | 《C語言參考手冊(原書第5版)》(邱仲潘 等譯)[機械工業出版社] |
| 50 | 50 | |
| 51 | −Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C89標準,但也用到了一些 | |
| 51 | +Linux內核使用GNU C和GNU工具鏈開發。雖然它遵循ISO C11標準,但也用到了一些 | |
| 52 | 52 | 標準中沒有定義的擴展。內核是自給自足的C環境,不依賴於標準C庫的支持,所以 |
| 53 | 53 | 並不支持C標準中的部分定義。比如long long類型的大數除法和浮點運算就不允許 |
| 54 | 54 | 使用。有時候確實很難弄清楚內核對工具鏈的要求和它所使用的擴展,不幸的是目 |
| @@ -215,6 +215,7 @@ KVM_S390_VM_TOD_EXT). · 214 unmodified lines | ||
| 215 | 215 | :Parameters: address of a buffer in user space to store the data (u8) to |
| 216 | 216 | :Returns: -EFAULT if the given address is not accessible from kernel space; |
| 217 | 217 | -EINVAL if setting the TOD clock extension to != 0 is not supported |
| 218 | + -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor) | |
| 218 | 219 | |
| 219 | 220 | 3.2. ATTRIBUTE: KVM_S390_VM_TOD_LOW |
| 220 | 221 | ----------------------------------- |
| @@ -224,6 +225,7 @@ the POP (u64). · 3 unmodified lines | ||
| 224 | 225 | |
| 225 | 226 | :Parameters: address of a buffer in user space to store the data (u64) to |
| 226 | 227 | :Returns: -EFAULT if the given address is not accessible from kernel space |
| 228 | + -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor) | |
| 227 | 229 | |
| 228 | 230 | 3.3. ATTRIBUTE: KVM_S390_VM_TOD_EXT |
| 229 | 231 | ----------------------------------- |
| @@ -237,6 +239,7 @@ it, it is stored as 0 and not allowed to be set to a value != 0. · 7 unmodified lines | ||
| 237 | 239 | (kvm_s390_vm_tod_clock) to |
| 238 | 240 | :Returns: -EFAULT if the given address is not accessible from kernel space; |
| 239 | 241 | -EINVAL if setting the TOD clock extension to != 0 is not supported |
| 242 | + -EOPNOTSUPP for a PV guest (TOD managed by the ultravisor) | |
| 240 | 243 | |
| 241 | 244 | 4. GROUP: KVM_S390_VM_CRYPTO |
| 242 | 245 | ============================ |
| @@ -2197,7 +2197,7 @@ M: Wei Xu <xuwei5@hisilicon.com> · 2196 unmodified lines | ||
| 2197 | 2197 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2198 | 2198 | S: Supported |
| 2199 | 2199 | W: http://www.hisilicon.com |
| 2200 | −T: git git://github.com/hisilicon/linux-hisi.git | |
| 2200 | +T: git https://github.com/hisilicon/linux-hisi.git | |
| 2201 | 2201 | F: arch/arm/boot/dts/hi3* |
| 2202 | 2202 | F: arch/arm/boot/dts/hip* |
| 2203 | 2203 | F: arch/arm/boot/dts/hisi* |
| @@ -3984,7 +3984,7 @@ M: Rafał Miłecki <rafal@milecki.pl> · 1780 unmodified lines | ||
| 3984 | 3984 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 3985 | 3985 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 3986 | 3986 | S: Maintained |
| 3987 | −T: git git://github.com/broadcom/stblinux.git | |
| 3987 | +T: git https://github.com/broadcom/stblinux.git | |
| 3988 | 3988 | F: Documentation/devicetree/bindings/arm/bcm/brcm,bcmbca.yaml |
| 3989 | 3989 | F: arch/arm64/boot/dts/broadcom/bcmbca/* |
| 3990 | 3990 | N: bcmbca |
| @@ -4009,7 +4009,7 @@ R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> · 18 unmodified lines | ||
| 4009 | 4009 | L: linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers) |
| 4010 | 4010 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 4011 | 4011 | S: Maintained |
| 4012 | −T: git git://github.com/broadcom/stblinux.git | |
| 4012 | +T: git https://github.com/broadcom/stblinux.git | |
| 4013 | 4013 | F: Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml |
| 4014 | 4014 | F: drivers/pci/controller/pcie-brcmstb.c |
| 4015 | 4015 | F: drivers/staging/vc04_services |
| @@ -4023,7 +4023,7 @@ M: Ray Jui <rjui@broadcom.com> · 7 unmodified lines | ||
| 4023 | 4023 | M: Scott Branden <sbranden@broadcom.com> |
| 4024 | 4024 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 4025 | 4025 | S: Maintained |
| 4026 | −T: git git://github.com/broadcom/mach-bcm | |
| 4026 | +T: git https://github.com/broadcom/mach-bcm | |
| 4027 | 4027 | F: arch/arm/mach-bcm/ |
| 4028 | 4028 | N: bcm281* |
| 4029 | 4029 | N: bcm113* |
| @@ -4088,7 +4088,7 @@ M: Florian Fainelli <f.fainelli@gmail.com> · 58 unmodified lines | ||
| 4088 | 4088 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 4089 | 4089 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 4090 | 4090 | S: Maintained |
| 4091 | −T: git git://github.com/broadcom/stblinux.git | |
| 4091 | +T: git https://github.com/broadcom/stblinux.git | |
| 4092 | 4092 | F: Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml |
| 4093 | 4093 | F: arch/arm/boot/dts/bcm7*.dts* |
| 4094 | 4094 | F: arch/arm/include/asm/hardware/cache-b15-rac.h |
| @@ -4121,7 +4121,7 @@ M: Florian Fainelli <f.fainelli@gmail.com> · 26 unmodified lines | ||
| 4121 | 4121 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 4122 | 4122 | L: linux-mips@vger.kernel.org |
| 4123 | 4123 | S: Maintained |
| 4124 | −T: git git://github.com/broadcom/stblinux.git | |
| 4124 | +T: git https://github.com/broadcom/stblinux.git | |
| 4125 | 4125 | F: arch/mips/bmips/* |
| 4126 | 4126 | F: arch/mips/boot/dts/brcm/bcm*.dts* |
| 4127 | 4127 | F: arch/mips/include/asm/mach-bmips/* |
| @@ -4262,7 +4262,7 @@ M: Scott Branden <sbranden@broadcom.com> · 134 unmodified lines | ||
| 4262 | 4262 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 4263 | 4263 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 4264 | 4264 | S: Maintained |
| 4265 | −T: git git://github.com/broadcom/stblinux.git | |
| 4265 | +T: git https://github.com/broadcom/stblinux.git | |
| 4266 | 4266 | F: arch/arm64/boot/dts/broadcom/northstar2/* |
| 4267 | 4267 | F: arch/arm64/boot/dts/broadcom/stingray/* |
| 4268 | 4268 | F: drivers/clk/bcm/clk-ns* |
| @@ -4332,7 +4332,7 @@ M: Florian Fainelli <f.fainelli@gmail.com> · 63 unmodified lines | ||
| 4332 | 4332 | R: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> |
| 4333 | 4333 | L: linux-pm@vger.kernel.org |
| 4334 | 4334 | S: Maintained |
| 4335 | −T: git git://github.com/broadcom/stblinux.git | |
| 4335 | +T: git https://github.com/broadcom/stblinux.git | |
| 4336 | 4336 | F: drivers/soc/bcm/bcm63xx/bcm-pmb.c |
| 4337 | 4337 | F: include/dt-bindings/soc/bcm-pmb.h |
| 4338 | 4338 | |
| @@ -4809,7 +4809,7 @@ R: Jeff Layton <jlayton@kernel.org> · 470 unmodified lines | ||
| 4809 | 4809 | L: ceph-devel@vger.kernel.org |
| 4810 | 4810 | S: Supported |
| 4811 | 4811 | W: http://ceph.com/ |
| 4812 | −T: git git://github.com/ceph/ceph-client.git | |
| 4812 | +T: git https://github.com/ceph/ceph-client.git | |
| 4813 | 4813 | F: include/linux/ceph/ |
| 4814 | 4814 | F: include/linux/crush/ |
| 4815 | 4815 | F: net/ceph/ |
| @@ -4821,7 +4821,7 @@ R: Jeff Layton <jlayton@kernel.org> · 5 unmodified lines | ||
| 4821 | 4821 | L: ceph-devel@vger.kernel.org |
| 4822 | 4822 | S: Supported |
| 4823 | 4823 | W: http://ceph.com/ |
| 4824 | −T: git git://github.com/ceph/ceph-client.git | |
| 4824 | +T: git https://github.com/ceph/ceph-client.git | |
| 4825 | 4825 | F: Documentation/filesystems/ceph.rst |
| 4826 | 4826 | F: fs/ceph/ |
| 4827 | 4827 | |
| @@ -4911,7 +4911,7 @@ F: drivers/platform/chrome/ · 83 unmodified lines | ||
| 4911 | 4911 | |
| 4912 | 4912 | CHROMEOS EC CODEC DRIVER |
| 4913 | 4913 | M: Cheng-Yi Chiang <cychiang@chromium.org> |
| 4914 | −M: Tzung-Bi Shih <tzungbi@google.com> | |
| 4914 | +M: Tzung-Bi Shih <tzungbi@kernel.org> | |
| 4915 | 4915 | R: Guenter Roeck <groeck@chromium.org> |
| 4916 | 4916 | L: chrome-platform@lists.linux.dev |
| 4917 | 4917 | S: Maintained |
| @@ -5041,7 +5041,7 @@ F: drivers/scsi/snic/ · 123 unmodified lines | ||
| 5041 | 5041 | |
| 5042 | 5042 | CISCO VIC ETHERNET NIC DRIVER |
| 5043 | 5043 | M: Christian Benvenuti <benve@cisco.com> |
| 5044 | −M: Govindarajulu Varadarajan <_govind@gmx.com> | |
| 5044 | +M: Satish Kharat <satishkh@cisco.com> | |
| 5045 | 5045 | S: Supported |
| 5046 | 5046 | F: drivers/net/ethernet/cisco/enic/ |
| 5047 | 5047 | |
| @@ -5585,8 +5585,6 @@ F: drivers/scsi/cxgbi/cxgb3i · 537 unmodified lines | ||
| 5585 | 5585 | |
| 5586 | 5586 | CXGB4 CRYPTO DRIVER (chcr) |
| 5587 | 5587 | M: Ayush Sawal <ayush.sawal@chelsio.com> |
| 5588 | −M: Vinay Kumar Yadav <vinay.yadav@chelsio.com> | |
| 5589 | −M: Rohit Maheshwari <rohitm@chelsio.com> | |
| 5590 | 5588 | L: linux-crypto@vger.kernel.org |
| 5591 | 5589 | S: Supported |
| 5592 | 5590 | W: http://www.chelsio.com |
| @@ -5594,8 +5592,6 @@ F: drivers/crypto/chelsio · 1 unmodified line | ||
| 5594 | 5592 | |
| 5595 | 5593 | CXGB4 INLINE CRYPTO DRIVER |
| 5596 | 5594 | M: Ayush Sawal <ayush.sawal@chelsio.com> |
| 5597 | −M: Vinay Kumar Yadav <vinay.yadav@chelsio.com> | |
| 5598 | −M: Rohit Maheshwari <rohitm@chelsio.com> | |
| 5599 | 5595 | L: netdev@vger.kernel.org |
| 5600 | 5596 | S: Supported |
| 5601 | 5597 | W: http://www.chelsio.com |
| @@ -8602,8 +8598,8 @@ F: include/asm-generic/ · 3000 unmodified lines | ||
| 8602 | 8598 | F: include/uapi/asm-generic/ |
| 8603 | 8599 | |
| 8604 | 8600 | GENERIC PHY FRAMEWORK |
| 8605 | −M: Kishon Vijay Abraham I <kishon@ti.com> | |
| 8606 | 8601 | M: Vinod Koul <vkoul@kernel.org> |
| 8602 | +M: Kishon Vijay Abraham I <kishon@kernel.org> | |
| 8607 | 8603 | L: linux-phy@lists.infradead.org |
| 8608 | 8604 | S: Supported |
| 8609 | 8605 | Q: https://patchwork.kernel.org/project/linux-phy/list/ |
| @@ -9217,7 +9213,7 @@ W: https://www.hisilicon.com · 607 unmodified lines | ||
| 9217 | 9213 | F: drivers/i2c/busses/i2c-hisi.c |
| 9218 | 9214 | |
| 9219 | 9215 | HISILICON LPC BUS DRIVER |
| 9220 | −M: john.garry@huawei.com | |
| 9216 | +M: Jay Fang <f.fangjian@huawei.com> | |
| 9221 | 9217 | S: Maintained |
| 9222 | 9218 | W: http://www.hisilicon.com |
| 9223 | 9219 | F: Documentation/devicetree/bindings/arm/hisilicon/low-pin-count.yaml |
| @@ -9341,7 +9337,7 @@ S: Maintained · 117 unmodified lines | ||
| 9341 | 9337 | F: drivers/crypto/hisilicon/trng/trng.c |
| 9342 | 9338 | |
| 9343 | 9339 | HISILICON V3XX SPI NOR FLASH Controller Driver |
| 9344 | −M: John Garry <john.garry@huawei.com> | |
| 9340 | +M: Jay Fang <f.fangjian@huawei.com> | |
| 9345 | 9341 | S: Maintained |
| 9346 | 9342 | W: http://www.hisilicon.com |
| 9347 | 9343 | F: drivers/spi/spi-hisi-sfc-v3xx.c |
| @@ -9507,7 +9503,6 @@ F: drivers/media/i2c/hi847.c · 159 unmodified lines | ||
| 9507 | 9503 | Hyper-V/Azure CORE AND DRIVERS |
| 9508 | 9504 | M: "K. Y. Srinivasan" <kys@microsoft.com> |
| 9509 | 9505 | M: Haiyang Zhang <haiyangz@microsoft.com> |
| 9510 | −M: Stephen Hemminger <sthemmin@microsoft.com> | |
| 9511 | 9506 | M: Wei Liu <wei.liu@kernel.org> |
| 9512 | 9507 | M: Dexuan Cui <decui@microsoft.com> |
| 9513 | 9508 | L: linux-hyperv@vger.kernel.org |
| @@ -9779,7 +9774,10 @@ S: Supported · 265 unmodified lines | ||
| 9779 | 9774 | F: drivers/pci/hotplug/rpaphp* |
| 9780 | 9775 | |
| 9781 | 9776 | IBM Power SRIOV Virtual NIC Device Driver |
| 9782 | −M: Dany Madden <drt@linux.ibm.com> | |
| 9777 | +M: Haren Myneni <haren@linux.ibm.com> | |
| 9778 | +M: Rick Lindsley <ricklind@linux.ibm.com> | |
| 9779 | +R: Nick Child <nnac123@linux.ibm.com> | |
| 9780 | +R: Dany Madden <danymadden@us.ibm.com> | |
| 9783 | 9781 | R: Thomas Falcon <tlfalcon@linux.ibm.com> |
| 9784 | 9782 | L: netdev@vger.kernel.org |
| 9785 | 9783 | S: Supported |
| @@ -10286,7 +10284,7 @@ T: git https://github.com/intel/gvt-linux.git · 500 unmodified lines | ||
| 10286 | 10284 | F: drivers/gpu/drm/i915/gvt/ |
| 10287 | 10285 | |
| 10288 | 10286 | INTEL HID EVENT DRIVER |
| 10289 | −M: Alex Hung <alex.hung@canonical.com> | |
| 10287 | +M: Alex Hung <alexhung@gmail.com> | |
| 10290 | 10288 | L: platform-driver-x86@vger.kernel.org |
| 10291 | 10289 | S: Maintained |
| 10292 | 10290 | F: drivers/platform/x86/intel/hid.c |
| @@ -11034,6 +11032,7 @@ KCONFIG · 741 unmodified lines | ||
| 11034 | 11032 | M: Masahiro Yamada <masahiroy@kernel.org> |
| 11035 | 11033 | L: linux-kbuild@vger.kernel.org |
| 11036 | 11034 | S: Maintained |
| 11035 | +Q: https://patchwork.kernel.org/project/linux-kbuild/list/ | |
| 11037 | 11036 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git kconfig |
| 11038 | 11037 | F: Documentation/kbuild/kconfig* |
| 11039 | 11038 | F: scripts/Kconfig.include |
| @@ -11091,10 +11090,12 @@ F: fs/autofs/ · 51 unmodified lines | ||
| 11091 | 11090 | |
| 11092 | 11091 | KERNEL BUILD + files below scripts/ (unless maintained elsewhere) |
| 11093 | 11092 | M: Masahiro Yamada <masahiroy@kernel.org> |
| 11094 | −M: Michal Marek <michal.lkml@markovi.net> | |
| 11093 | +R: Nathan Chancellor <nathan@kernel.org> | |
| 11095 | 11094 | R: Nick Desaulniers <ndesaulniers@google.com> |
| 11095 | +R: Nicolas Schier <nicolas@fjasle.eu> | |
| 11096 | 11096 | L: linux-kbuild@vger.kernel.org |
| 11097 | 11097 | S: Maintained |
| 11098 | +Q: https://patchwork.kernel.org/project/linux-kbuild/list/ | |
| 11098 | 11099 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild.git |
| 11099 | 11100 | F: Documentation/kbuild/ |
| 11100 | 11101 | F: Makefile |
| @@ -11249,7 +11250,7 @@ L: kvm@vger.kernel.org · 148 unmodified lines | ||
| 11249 | 11250 | L: kvm-riscv@lists.infradead.org |
| 11250 | 11251 | L: linux-riscv@lists.infradead.org |
| 11251 | 11252 | S: Maintained |
| 11252 | −T: git git://github.com/kvm-riscv/linux.git | |
| 11253 | +T: git https://github.com/kvm-riscv/linux.git | |
| 11253 | 11254 | F: arch/riscv/include/asm/kvm* |
| 11254 | 11255 | F: arch/riscv/include/uapi/asm/kvm* |
| 11255 | 11256 | F: arch/riscv/kvm/ |
| @@ -12224,7 +12225,6 @@ F: arch/mips/boot/dts/img/pistachio* · 968 unmodified lines | ||
| 12224 | 12225 | |
| 12225 | 12226 | MARVELL 88E6XXX ETHERNET SWITCH FABRIC DRIVER |
| 12226 | 12227 | M: Andrew Lunn <andrew@lunn.ch> |
| 12227 | −M: Vivien Didelot <vivien.didelot@gmail.com> | |
| 12228 | 12228 | L: netdev@vger.kernel.org |
| 12229 | 12229 | S: Maintained |
| 12230 | 12230 | F: Documentation/devicetree/bindings/net/dsa/marvell.txt |
| @@ -13625,6 +13625,12 @@ S: Supported · 1394 unmodified lines | ||
| 13625 | 13625 | F: drivers/misc/atmel-ssc.c |
| 13626 | 13626 | F: include/linux/atmel-ssc.h |
| 13627 | 13627 | |
| 13628 | +MICROCHIP SOC DRIVERS | |
| 13629 | +M: Conor Dooley <conor@kernel.org> | |
| 13630 | +S: Supported | |
| 13631 | +T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ | |
| 13632 | +F: drivers/soc/microchip/ | |
| 13633 | + | |
| 13628 | 13634 | MICROCHIP USB251XB DRIVER |
| 13629 | 13635 | M: Richard Leitner <richard.leitner@skidata.com> |
| 13630 | 13636 | L: linux-usb@vger.kernel.org |
| @@ -14331,7 +14337,6 @@ F: drivers/net/wireless/ · 700 unmodified lines | ||
| 14331 | 14337 | |
| 14332 | 14338 | NETWORKING [DSA] |
| 14333 | 14339 | M: Andrew Lunn <andrew@lunn.ch> |
| 14334 | −M: Vivien Didelot <vivien.didelot@gmail.com> | |
| 14335 | 14340 | M: Florian Fainelli <f.fainelli@gmail.com> |
| 14336 | 14341 | M: Vladimir Oltean <olteanv@gmail.com> |
| 14337 | 14342 | S: Maintained |
| @@ -15640,7 +15645,7 @@ F: drivers/input/serio/gscps2.c · 1302 unmodified lines | ||
| 15640 | 15645 | F: drivers/input/serio/hp_sdc* |
| 15641 | 15646 | F: drivers/parisc/ |
| 15642 | 15647 | F: drivers/parport/parport_gsc.* |
| 15643 | −F: drivers/tty/serial/8250/8250_gsc.c | |
| 15648 | +F: drivers/tty/serial/8250/8250_parisc.c | |
| 15644 | 15649 | F: drivers/video/console/sti* |
| 15645 | 15650 | F: drivers/video/fbdev/sti* |
| 15646 | 15651 | F: drivers/video/logo/logo_parisc* |
| @@ -15953,6 +15958,7 @@ Q: https://patchwork.kernel.org/project/linux-pci/list/ · 306 unmodified lines | ||
| 15953 | 15958 | B: https://bugzilla.kernel.org |
| 15954 | 15959 | C: irc://irc.oftc.net/linux-pci |
| 15955 | 15960 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git |
| 15961 | +F: Documentation/devicetree/bindings/pci/ | |
| 15956 | 15962 | F: drivers/pci/controller/ |
| 15957 | 15963 | F: drivers/pci/pci-bridge-emul.c |
| 15958 | 15964 | F: drivers/pci/pci-bridge-emul.h |
| @@ -16059,7 +16065,7 @@ F: Documentation/devicetree/bindings/pci/microchip* · 100 unmodified lines | ||
| 16059 | 16065 | F: drivers/pci/controller/*microchip* |
| 16060 | 16066 | |
| 16061 | 16067 | PCIE DRIVER FOR QUALCOMM MSM |
| 16062 | −M: Stanimir Varbanov <svarbanov@mm-sol.com> | |
| 16068 | +M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> | |
| 16063 | 16069 | L: linux-pci@vger.kernel.org |
| 16064 | 16070 | L: linux-arm-msm@vger.kernel.org |
| 16065 | 16071 | S: Maintained |
| @@ -16149,7 +16155,8 @@ F: include/linux/peci-cpu.h · 83 unmodified lines | ||
| 16149 | 16155 | F: include/linux/peci.h |
| 16150 | 16156 | |
| 16151 | 16157 | PENSANDO ETHERNET DRIVERS |
| 16152 | −M: Shannon Nelson <snelson@pensando.io> | |
| 16158 | +M: Shannon Nelson <shannon.nelson@amd.com> | |
| 16159 | +M: Brett Creeley <brett.creeley@amd.com> | |
| 16153 | 16160 | M: drivers@pensando.io |
| 16154 | 16161 | L: netdev@vger.kernel.org |
| 16155 | 16162 | S: Supported |
| @@ -17232,7 +17239,7 @@ R: Dongsheng Yang <dongsheng.yang@easystack.cn> · 1076 unmodified lines | ||
| 17232 | 17239 | L: ceph-devel@vger.kernel.org |
| 17233 | 17240 | S: Supported |
| 17234 | 17241 | W: http://ceph.com/ |
| 17235 | −T: git git://github.com/ceph/ceph-client.git | |
| 17242 | +T: git https://github.com/ceph/ceph-client.git | |
| 17236 | 17243 | F: Documentation/ABI/testing/sysfs-bus-rbd |
| 17237 | 17244 | F: drivers/block/rbd.c |
| 17238 | 17245 | F: drivers/block/rbd_types.h |
| @@ -17485,10 +17492,8 @@ S: Maintained · 246 unmodified lines | ||
| 17485 | 17492 | F: drivers/net/wireless/realtek/rtw89/ |
| 17486 | 17493 | |
| 17487 | 17494 | REDPINE WIRELESS DRIVER |
| 17488 | −M: Amitkumar Karwar <amitkarwar@gmail.com> | |
| 17489 | −M: Siva Rebbagondla <siva8118@gmail.com> | |
| 17490 | 17495 | L: linux-wireless@vger.kernel.org |
| 17491 | −S: Maintained | |
| 17496 | +S: Orphan | |
| 17492 | 17497 | F: drivers/net/wireless/rsi/ |
| 17493 | 17498 | |
| 17494 | 17499 | REGISTER MAP ABSTRACTION |
| @@ -17733,7 +17738,7 @@ F: arch/riscv/ · 238 unmodified lines | ||
| 17733 | 17738 | N: riscv |
| 17734 | 17739 | K: riscv |
| 17735 | 17740 | |
| 17736 | −RISC-V/MICROCHIP POLARFIRE SOC SUPPORT | |
| 17741 | +RISC-V MICROCHIP FPGA SUPPORT | |
| 17737 | 17742 | M: Conor Dooley <conor.dooley@microchip.com> |
| 17738 | 17743 | M: Daire McNamara <daire.mcnamara@microchip.com> |
| 17739 | 17744 | L: linux-riscv@lists.infradead.org |
| @@ -17751,17 +17756,26 @@ F: Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml · 11 unmodified lines | ||
| 17751 | 17756 | F: arch/riscv/boot/dts/microchip/ |
| 17752 | 17757 | F: drivers/char/hw_random/mpfs-rng.c |
| 17753 | 17758 | F: drivers/clk/microchip/clk-mpfs.c |
| 17754 | −F: drivers/i2c/busses/i2c-microchip-core.c | |
| 17759 | +F: drivers/i2c/busses/i2c-microchip-corei2c.c | |
| 17755 | 17760 | F: drivers/mailbox/mailbox-mpfs.c |
| 17756 | 17761 | F: drivers/pci/controller/pcie-microchip-host.c |
| 17757 | 17762 | F: drivers/reset/reset-mpfs.c |
| 17758 | 17763 | F: drivers/rtc/rtc-mpfs.c |
| 17759 | −F: drivers/soc/microchip/ | |
| 17764 | +F: drivers/soc/microchip/mpfs-sys-controller.c | |
| 17760 | 17765 | F: drivers/spi/spi-microchip-core-qspi.c |
| 17761 | 17766 | F: drivers/spi/spi-microchip-core.c |
| 17762 | 17767 | F: drivers/usb/musb/mpfs.c |
| 17763 | 17768 | F: include/soc/microchip/mpfs.h |
| 17764 | 17769 | |
| 17770 | +RISC-V MISC SOC SUPPORT | |
| 17771 | +M: Conor Dooley <conor@kernel.org> | |
| 17772 | +L: linux-riscv@lists.infradead.org | |
| 17773 | +S: Maintained | |
| 17774 | +Q: https://patchwork.kernel.org/project/linux-riscv/list/ | |
| 17775 | +T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ | |
| 17776 | +F: Documentation/devicetree/bindings/riscv/ | |
| 17777 | +F: arch/riscv/boot/dts/ | |
| 17778 | + | |
| 17765 | 17779 | RNBD BLOCK DRIVERS |
| 17766 | 17780 | M: Md. Haris Iqbal <haris.iqbal@ionos.com> |
| 17767 | 17781 | M: Jack Wang <jinpu.wang@ionos.com> |
| @@ -18002,7 +18016,7 @@ L: linux-fbdev@vger.kernel.org · 234 unmodified lines | ||
| 18002 | 18016 | S: Maintained |
| 18003 | 18017 | F: drivers/video/fbdev/savage/ |
| 18004 | 18018 | |
| 18005 | −S390 | |
| 18019 | +S390 ARCHITECTURE | |
| 18006 | 18020 | M: Heiko Carstens <hca@linux.ibm.com> |
| 18007 | 18021 | M: Vasily Gorbik <gor@linux.ibm.com> |
| 18008 | 18022 | M: Alexander Gordeev <agordeev@linux.ibm.com> |
| @@ -18057,6 +18071,15 @@ L: netdev@vger.kernel.org · 48 unmodified lines | ||
| 18057 | 18071 | S: Supported |
| 18058 | 18072 | F: drivers/s390/net/ |
| 18059 | 18073 | |
| 18074 | +S390 MM | |
| 18075 | +M: Alexander Gordeev <agordeev@linux.ibm.com> | |
| 18076 | +M: Gerald Schaefer <gerald.schaefer@linux.ibm.com> | |
| 18077 | +L: linux-s390@vger.kernel.org | |
| 18078 | +S: Supported | |
| 18079 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git | |
| 18080 | +F: arch/s390/include/asm/pgtable.h | |
| 18081 | +F: arch/s390/mm | |
| 18082 | + | |
| 18060 | 18083 | S390 PCI SUBSYSTEM |
| 18061 | 18084 | M: Niklas Schnelle <schnelle@linux.ibm.com> |
| 18062 | 18085 | M: Gerald Schaefer <gerald.schaefer@linux.ibm.com> |
| @@ -18788,7 +18811,6 @@ M: Palmer Dabbelt <palmer@dabbelt.com> · 725 unmodified lines | ||
| 18788 | 18811 | M: Paul Walmsley <paul.walmsley@sifive.com> |
| 18789 | 18812 | L: linux-riscv@lists.infradead.org |
| 18790 | 18813 | S: Supported |
| 18791 | −T: git https://github.com/sifive/riscv-linux.git | |
| 18792 | 18814 | N: sifive |
| 18793 | 18815 | K: [^@]sifive |
| 18794 | 18816 | |
| @@ -18807,6 +18829,13 @@ S: Maintained · 12 unmodified lines | ||
| 18807 | 18829 | F: Documentation/devicetree/bindings/dma/sifive,fu540-c000-pdma.yaml |
| 18808 | 18830 | F: drivers/dma/sf-pdma/ |
| 18809 | 18831 | |
| 18832 | +SIFIVE SOC DRIVERS | |
| 18833 | +M: Conor Dooley <conor@kernel.org> | |
| 18834 | +L: linux-riscv@lists.infradead.org | |
| 18835 | +S: Maintained | |
| 18836 | +T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ | |
| 18837 | +F: drivers/soc/sifive/ | |
| 18838 | + | |
| 18810 | 18839 | SILEAD TOUCHSCREEN DRIVER |
| 18811 | 18840 | M: Hans de Goede <hdegoede@redhat.com> |
| 18812 | 18841 | L: linux-input@vger.kernel.org |
| @@ -19608,6 +19637,11 @@ M: Ion Badulescu <ionut@badula.org> · 795 unmodified lines | ||
| 19608 | 19637 | S: Odd Fixes |
| 19609 | 19638 | F: drivers/net/ethernet/adaptec/starfire* |
| 19610 | 19639 | |
| 19640 | +STARFIVE DEVICETREES | |
| 19641 | +M: Emil Renner Berthing <kernel@esmil.dk> | |
| 19642 | +S: Maintained | |
| 19643 | +F: arch/riscv/boot/dts/starfive/ | |
| 19644 | + | |
| 19611 | 19645 | STARFIVE JH7100 CLOCK DRIVERS |
| 19612 | 19646 | M: Emil Renner Berthing <kernel@esmil.dk> |
| 19613 | 19647 | S: Maintained |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 6 |
| 3 | 3 | PATCHLEVEL = 1 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc3 | |
| 5 | +EXTRAVERSION = -rc8 | |
| 6 | 6 | NAME = Hurr durr I'ma ninja sloth |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -1218,7 +1218,7 @@ quiet_cmd_ar_vmlinux.a = AR $@ · 1209 unmodified lines | ||
| 1218 | 1218 | cmd_ar_vmlinux.a = \ |
| 1219 | 1219 | rm -f $@; \ |
| 1220 | 1220 | $(AR) cDPrST $@ $(KBUILD_VMLINUX_OBJS); \ |
| 1221 | − $(AR) mPiT $$($(AR) t $@ | head -n1) $@ $$($(AR) t $@ | grep -F --file=$(srctree)/scripts/head-object-list.txt) | |
| 1221 | + $(AR) mPiT $$($(AR) t $@ | sed -n 1p) $@ $$($(AR) t $@ | grep -F -f $(srctree)/scripts/head-object-list.txt) | |
| 1222 | 1222 | |
| 1223 | 1223 | targets += vmlinux.a |
| 1224 | 1224 | vmlinux.a: $(KBUILD_VMLINUX_OBJS) scripts/head-object-list.txt autoksyms_recursive FORCE |
| @@ -12,22 +12,20 @@ · 11 unmodified lines | ||
| 12 | 12 | compatible = "phytec,am335x-pcm-953", "phytec,am335x-phycore-som", "ti,am33xx"; |
| 13 | 13 | |
| 14 | 14 | /* Power */ |
| 15 | − regulators { | |
| 16 | − vcc3v3: fixedregulator@1 { | |
| 17 | − compatible = "regulator-fixed"; | |
| 18 | − regulator-name = "vcc3v3"; | |
| 19 | − regulator-min-microvolt = <3300000>; | |
| 20 | − regulator-max-microvolt = <3300000>; | |
| 21 | − regulator-boot-on; | |
| 22 | − }; | |
| 15 | + vcc3v3: fixedregulator1 { | |
| 16 | + compatible = "regulator-fixed"; | |
| 17 | + regulator-name = "vcc3v3"; | |
| 18 | + regulator-min-microvolt = <3300000>; | |
| 19 | + regulator-max-microvolt = <3300000>; | |
| 20 | + regulator-boot-on; | |
| 21 | + }; | |
| 23 | 22 | |
| 24 | − vcc1v8: fixedregulator@2 { | |
| 25 | − compatible = "regulator-fixed"; | |
| 26 | − regulator-name = "vcc1v8"; | |
| 27 | − regulator-min-microvolt = <1800000>; | |
| 28 | − regulator-max-microvolt = <1800000>; | |
| 29 | − regulator-boot-on; | |
| 30 | − }; | |
| 23 | + vcc1v8: fixedregulator2 { | |
| 24 | + compatible = "regulator-fixed"; | |
| 25 | + regulator-name = "vcc1v8"; | |
| 26 | + regulator-min-microvolt = <1800000>; | |
| 27 | + regulator-max-microvolt = <1800000>; | |
| 28 | + regulator-boot-on; | |
| 31 | 29 | }; |
| 32 | 30 | |
| 33 | 31 | /* User IO */ |
| @@ -666,7 +666,7 @@ · 665 unmodified lines | ||
| 666 | 666 | compatible = "atmel,at91rm9200-udc"; |
| 667 | 667 | reg = <0xfffb0000 0x4000>; |
| 668 | 668 | interrupts = <11 IRQ_TYPE_LEVEL_HIGH 2>; |
| 669 | − clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 2>; | |
| 669 | + clocks = <&pmc PMC_TYPE_PERIPHERAL 11>, <&pmc PMC_TYPE_SYSTEM 1>; | |
| 670 | 670 | clock-names = "pclk", "hclk"; |
| 671 | 671 | status = "disabled"; |
| 672 | 672 | }; |
| @@ -39,6 +39,13 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | }; |
| 41 | 41 | |
| 42 | + usb1 { | |
| 43 | + pinctrl_usb1_vbus_gpio: usb1_vbus_gpio { | |
| 44 | + atmel,pins = | |
| 45 | + <AT91_PIOC 5 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PC5 GPIO */ | |
| 46 | + }; | |
| 47 | + }; | |
| 48 | + | |
| 42 | 49 | mmc0_slot1 { |
| 43 | 50 | pinctrl_board_mmc0_slot1: mmc0_slot1-board { |
| 44 | 51 | atmel,pins = |
| @@ -84,6 +91,8 @@ · 39 unmodified lines | ||
| 84 | 91 | }; |
| 85 | 92 | |
| 86 | 93 | usb1: gadget@fffa4000 { |
| 94 | + pinctrl-0 = <&pinctrl_usb1_vbus_gpio>; | |
| 95 | + pinctrl-names = "default"; | |
| 87 | 96 | atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>; |
| 88 | 97 | status = "okay"; |
| 89 | 98 | }; |
| @@ -364,8 +364,8 @@ · 363 unmodified lines | ||
| 364 | 364 | pinctrl-names = "default"; |
| 365 | 365 | pinctrl-0 = <&pinctrl_wifi>; |
| 366 | 366 | interrupts-extended = <&gpio1 30 IRQ_TYPE_LEVEL_HIGH>; |
| 367 | − ref-clock-frequency = "38400000"; | |
| 368 | − tcxo-clock-frequency = "19200000"; | |
| 367 | + ref-clock-frequency = <38400000>; | |
| 368 | + tcxo-clock-frequency = <19200000>; | |
| 369 | 369 | }; |
| 370 | 370 | }; |
| 371 | 371 | |
| @@ -33,6 +33,10 @@ · 32 unmodified lines | ||
| 33 | 33 | status = "okay"; |
| 34 | 34 | }; |
| 35 | 35 | |
| 36 | +®_pu { | |
| 37 | + regulator-always-on; | |
| 38 | +}; | |
| 39 | + | |
| 36 | 40 | ®_usb_h1_vbus { |
| 37 | 41 | status = "okay"; |
| 38 | 42 | }; |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | user-pb { |
| 31 | 31 | label = "user_pb"; |
| 32 | − gpios = <&gsc_gpio 0 GPIO_ACTIVE_LOW>; | |
| 32 | + gpios = <&gsc_gpio 2 GPIO_ACTIVE_LOW>; | |
| 33 | 33 | linux,code = <BTN_0>; |
| 34 | 34 | }; |
| 35 | 35 | |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | user-pb { |
| 28 | 28 | label = "user_pb"; |
| 29 | − gpios = <&gsc_gpio 0 GPIO_ACTIVE_LOW>; | |
| 29 | + gpios = <&gsc_gpio 2 GPIO_ACTIVE_LOW>; | |
| 30 | 30 | linux,code = <BTN_0>; |
| 31 | 31 | }; |
| 32 | 32 | |
| @@ -33,6 +33,10 @@ · 32 unmodified lines | ||
| 33 | 33 | status = "okay"; |
| 34 | 34 | }; |
| 35 | 35 | |
| 36 | +®_pu { | |
| 37 | + regulator-always-on; | |
| 38 | +}; | |
| 39 | + | |
| 36 | 40 | ®_usb_h1_vbus { |
| 37 | 41 | status = "okay"; |
| 38 | 42 | }; |
| @@ -1270,10 +1270,10 @@ · 1269 unmodified lines | ||
| 1270 | 1270 | clocks = <&clks IMX7D_NAND_USDHC_BUS_RAWNAND_CLK>; |
| 1271 | 1271 | }; |
| 1272 | 1272 | |
| 1273 | − gpmi: nand-controller@33002000{ | |
| 1273 | + gpmi: nand-controller@33002000 { | |
| 1274 | 1274 | compatible = "fsl,imx7d-gpmi-nand"; |
| 1275 | 1275 | #address-cells = <1>; |
| 1276 | − #size-cells = <1>; | |
| 1276 | + #size-cells = <0>; | |
| 1277 | 1277 | reg = <0x33002000 0x2000>, <0x33004000 0x4000>; |
| 1278 | 1278 | reg-names = "gpmi-nand", "bch"; |
| 1279 | 1279 | interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -69,6 +69,12 @@ · 68 unmodified lines | ||
| 69 | 69 | pins = "GPIO_35", "GPIO_36"; |
| 70 | 70 | function = "can0_b"; |
| 71 | 71 | }; |
| 72 | + | |
| 73 | + sgpio_a_pins: sgpio-a-pins { | |
| 74 | + /* SCK, D0, D1, LD */ | |
| 75 | + pins = "GPIO_32", "GPIO_33", "GPIO_34", "GPIO_35"; | |
| 76 | + function = "sgpio_a"; | |
| 77 | + }; | |
| 72 | 78 | }; |
| 73 | 79 | |
| 74 | 80 | &can0 { |
| @@ -118,6 +124,20 @@ · 43 unmodified lines | ||
| 118 | 124 | status = "okay"; |
| 119 | 125 | }; |
| 120 | 126 | |
| 127 | +&sgpio { | |
| 128 | + pinctrl-0 = <&sgpio_a_pins>; | |
| 129 | + pinctrl-names = "default"; | |
| 130 | + microchip,sgpio-port-ranges = <0 3>, <8 11>; | |
| 131 | + status = "okay"; | |
| 132 | + | |
| 133 | + gpio@0 { | |
| 134 | + ngpios = <64>; | |
| 135 | + }; | |
| 136 | + gpio@1 { | |
| 137 | + ngpios = <64>; | |
| 138 | + }; | |
| 139 | +}; | |
| 140 | + | |
| 121 | 141 | &switch { |
| 122 | 142 | status = "okay"; |
| 123 | 143 | }; |
| @@ -35,11 +35,10 @@ · 34 unmodified lines | ||
| 35 | 35 | &i2c1 { |
| 36 | 36 | status = "okay"; |
| 37 | 37 | |
| 38 | − hym8563: hym8563@51 { | |
| 38 | + hym8563: rtc@51 { | |
| 39 | 39 | compatible = "haoyu,hym8563"; |
| 40 | 40 | reg = <0x51>; |
| 41 | 41 | #clock-cells = <0>; |
| 42 | − clock-frequency = <32768>; | |
| 43 | 42 | clock-output-names = "xin32k"; |
| 44 | 43 | }; |
| 45 | 44 | }; |
| @@ -32,7 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | keyup-threshold-microvolt = <2500000>; |
| 33 | 33 | poll-interval = <100>; |
| 34 | 34 | |
| 35 | − recovery { | |
| 35 | + button-recovery { | |
| 36 | 36 | label = "recovery"; |
| 37 | 37 | linux,code = <KEY_VENDOR>; |
| 38 | 38 | press-threshold-microvolt = <0>; |
| @@ -71,7 +71,7 @@ · 70 unmodified lines | ||
| 71 | 71 | #sound-dai-cells = <0>; |
| 72 | 72 | }; |
| 73 | 73 | |
| 74 | − ir_recv: gpio-ir-receiver { | |
| 74 | + ir_recv: ir-receiver { | |
| 75 | 75 | compatible = "gpio-ir-receiver"; |
| 76 | 76 | gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; |
| 77 | 77 | pinctrl-names = "default"; |
| @@ -379,7 +379,7 @@ · 378 unmodified lines | ||
| 379 | 379 | rockchip,pins = <2 RK_PD3 1 &pcfg_pull_none>; |
| 380 | 380 | }; |
| 381 | 381 | |
| 382 | − lcdc1_rgb24: ldcd1-rgb24 { | |
| 382 | + lcdc1_rgb24: lcdc1-rgb24 { | |
| 383 | 383 | rockchip,pins = <2 RK_PA0 1 &pcfg_pull_none>, |
| 384 | 384 | <2 RK_PA1 1 &pcfg_pull_none>, |
| 385 | 385 | <2 RK_PA2 1 &pcfg_pull_none>, |
| @@ -607,7 +607,6 @@ · 221 unmodified lines | ||
| 607 | 607 | |
| 608 | 608 | &global_timer { |
| 609 | 609 | interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>; |
| 610 | − status = "disabled"; | |
| 611 | 610 | }; |
| 612 | 611 | |
| 613 | 612 | &local_timer { |
| @@ -54,7 +54,7 @@ · 53 unmodified lines | ||
| 54 | 54 | vin-supply = <&vcc_sys>; |
| 55 | 55 | }; |
| 56 | 56 | |
| 57 | − hym8563@51 { | |
| 57 | + rtc@51 { | |
| 58 | 58 | compatible = "haoyu,hym8563"; |
| 59 | 59 | reg = <0x51>; |
| 60 | 60 | |
| @@ -28,19 +28,19 @@ · 27 unmodified lines | ||
| 28 | 28 | press-threshold-microvolt = <300000>; |
| 29 | 29 | }; |
| 30 | 30 | |
| 31 | − menu { | |
| 31 | + button-menu { | |
| 32 | 32 | label = "Menu"; |
| 33 | 33 | linux,code = <KEY_MENU>; |
| 34 | 34 | press-threshold-microvolt = <640000>; |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | − esc { | |
| 37 | + button-esc { | |
| 38 | 38 | label = "Esc"; |
| 39 | 39 | linux,code = <KEY_ESC>; |
| 40 | 40 | press-threshold-microvolt = <1000000>; |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | − home { | |
| 43 | + button-home { | |
| 44 | 44 | label = "Home"; |
| 45 | 45 | linux,code = <KEY_HOME>; |
| 46 | 46 | press-threshold-microvolt = <1300000>; |
| @@ -233,11 +233,10 @@ · 232 unmodified lines | ||
| 233 | 233 | vin-supply = <&vcc_sys>; |
| 234 | 234 | }; |
| 235 | 235 | |
| 236 | − hym8563: hym8563@51 { | |
| 236 | + hym8563: rtc@51 { | |
| 237 | 237 | compatible = "haoyu,hym8563"; |
| 238 | 238 | reg = <0x51>; |
| 239 | 239 | #clock-cells = <0>; |
| 240 | − clock-frequency = <32768>; | |
| 241 | 240 | clock-output-names = "xin32k"; |
| 242 | 241 | interrupt-parent = <&gpio7>; |
| 243 | 242 | interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>; |
| @@ -162,11 +162,10 @@ · 161 unmodified lines | ||
| 162 | 162 | vin-supply = <&vcc_sys>; |
| 163 | 163 | }; |
| 164 | 164 | |
| 165 | − hym8563: hym8563@51 { | |
| 165 | + hym8563: rtc@51 { | |
| 166 | 166 | compatible = "haoyu,hym8563"; |
| 167 | 167 | reg = <0x51>; |
| 168 | 168 | #clock-cells = <0>; |
| 169 | − clock-frequency = <32768>; | |
| 170 | 169 | clock-output-names = "xin32k"; |
| 171 | 170 | }; |
| 172 | 171 | |
| @@ -165,11 +165,10 @@ · 164 unmodified lines | ||
| 165 | 165 | }; |
| 166 | 166 | |
| 167 | 167 | &i2c0 { |
| 168 | − hym8563: hym8563@51 { | |
| 168 | + hym8563: rtc@51 { | |
| 169 | 169 | compatible = "haoyu,hym8563"; |
| 170 | 170 | reg = <0x51>; |
| 171 | 171 | #clock-cells = <0>; |
| 172 | − clock-frequency = <32768>; | |
| 173 | 172 | clock-output-names = "xin32k"; |
| 174 | 173 | interrupt-parent = <&gpio0>; |
| 175 | 174 | interrupts = <RK_PA4 IRQ_TYPE_EDGE_FALLING>; |
| @@ -241,7 +241,6 @@ · 240 unmodified lines | ||
| 241 | 241 | interrupt-parent = <&gpio5>; |
| 242 | 242 | interrupts = <RK_PC3 IRQ_TYPE_LEVEL_LOW>; |
| 243 | 243 | #clock-cells = <0>; |
| 244 | − clock-frequency = <32768>; | |
| 245 | 244 | clock-output-names = "hym8563"; |
| 246 | 245 | pinctrl-names = "default"; |
| 247 | 246 | pinctrl-0 = <&hym8563_int>; |
| @@ -76,6 +76,13 @@ · 75 unmodified lines | ||
| 76 | 76 | reg = <0x1013c200 0x20>; |
| 77 | 77 | interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>; |
| 78 | 78 | clocks = <&cru CORE_PERI>; |
| 79 | + status = "disabled"; | |
| 80 | + /* The clock source and the sched_clock provided by the arm_global_timer | |
| 81 | + * on Rockchip rk3066a/rk3188 are quite unstable because their rates | |
| 82 | + * depend on the CPU frequency. | |
| 83 | + * Keep the arm_global_timer disabled in order to have the | |
| 84 | + * DW_APB_TIMER (rk3066a) or ROCKCHIP_TIMER (rk3188) selected by default. | |
| 85 | + */ | |
| 79 | 86 | }; |
| 80 | 87 | |
| 81 | 88 | local_timer: local-timer@1013c600 { |
| @@ -261,7 +261,7 @@ · 260 unmodified lines | ||
| 261 | 261 | #define PIN_PB2__FLEXCOM6_IO0 PINMUX_PIN(PIN_PB2, 2, 1) |
| 262 | 262 | #define PIN_PB2__ADTRG PINMUX_PIN(PIN_PB2, 3, 1) |
| 263 | 263 | #define PIN_PB2__A20 PINMUX_PIN(PIN_PB2, 4, 1) |
| 264 | −#define PIN_PB2__FLEXCOM11_IO0 PINMUX_PIN(PIN_PB2, 6, 3) | |
| 264 | +#define PIN_PB2__FLEXCOM11_IO1 PINMUX_PIN(PIN_PB2, 6, 3) | |
| 265 | 265 | #define PIN_PB3 35 |
| 266 | 266 | #define PIN_PB3__GPIO PINMUX_PIN(PIN_PB3, 0, 0) |
| 267 | 267 | #define PIN_PB3__RF1 PINMUX_PIN(PIN_PB3, 1, 1) |
| @@ -24,6 +24,14 @@ · 23 unmodified lines | ||
| 24 | 24 | polling-delay = <0>; |
| 25 | 25 | polling-delay-passive = <0>; |
| 26 | 26 | thermal-sensors = <&bat_therm>; |
| 27 | + | |
| 28 | + trips { | |
| 29 | + battery-crit-hi { | |
| 30 | + temperature = <70000>; | |
| 31 | + hysteresis = <2000>; | |
| 32 | + type = "critical"; | |
| 33 | + }; | |
| 34 | + }; | |
| 27 | 35 | }; |
| 28 | 36 | }; |
| 29 | 37 | |
| @@ -28,6 +28,14 @@ · 27 unmodified lines | ||
| 28 | 28 | polling-delay = <0>; |
| 29 | 29 | polling-delay-passive = <0>; |
| 30 | 30 | thermal-sensors = <&bat_therm>; |
| 31 | + | |
| 32 | + trips { | |
| 33 | + battery-crit-hi { | |
| 34 | + temperature = <70000>; | |
| 35 | + hysteresis = <2000>; | |
| 36 | + type = "critical"; | |
| 37 | + }; | |
| 38 | + }; | |
| 31 | 39 | }; |
| 32 | 40 | }; |
| 33 | 41 | |
| @@ -44,6 +44,14 @@ · 43 unmodified lines | ||
| 44 | 44 | polling-delay = <0>; |
| 45 | 45 | polling-delay-passive = <0>; |
| 46 | 46 | thermal-sensors = <&bat_therm>; |
| 47 | + | |
| 48 | + trips { | |
| 49 | + battery-crit-hi { | |
| 50 | + temperature = <70000>; | |
| 51 | + hysteresis = <2000>; | |
| 52 | + type = "critical"; | |
| 53 | + }; | |
| 54 | + }; | |
| 47 | 55 | }; |
| 48 | 56 | }; |
| 49 | 57 | |
| @@ -57,6 +57,14 @@ · 56 unmodified lines | ||
| 57 | 57 | polling-delay = <0>; |
| 58 | 58 | polling-delay-passive = <0>; |
| 59 | 59 | thermal-sensors = <&bat_therm>; |
| 60 | + | |
| 61 | + trips { | |
| 62 | + battery-crit-hi { | |
| 63 | + temperature = <70000>; | |
| 64 | + hysteresis = <2000>; | |
| 65 | + type = "critical"; | |
| 66 | + }; | |
| 67 | + }; | |
| 60 | 68 | }; |
| 61 | 69 | }; |
| 62 | 70 | |
| @@ -30,6 +30,14 @@ · 29 unmodified lines | ||
| 30 | 30 | polling-delay = <0>; |
| 31 | 31 | polling-delay-passive = <0>; |
| 32 | 32 | thermal-sensors = <&bat_therm>; |
| 33 | + | |
| 34 | + trips { | |
| 35 | + battery-crit-hi { | |
| 36 | + temperature = <70000>; | |
| 37 | + hysteresis = <2000>; | |
| 38 | + type = "critical"; | |
| 39 | + }; | |
| 40 | + }; | |
| 33 | 41 | }; |
| 34 | 42 | }; |
| 35 | 43 | |
| @@ -35,6 +35,14 @@ · 34 unmodified lines | ||
| 35 | 35 | polling-delay = <0>; |
| 36 | 36 | polling-delay-passive = <0>; |
| 37 | 37 | thermal-sensors = <&bat_therm>; |
| 38 | + | |
| 39 | + trips { | |
| 40 | + battery-crit-hi { | |
| 41 | + temperature = <70000>; | |
| 42 | + hysteresis = <2000>; | |
| 43 | + type = "critical"; | |
| 44 | + }; | |
| 45 | + }; | |
| 38 | 46 | }; |
| 39 | 47 | }; |
| 40 | 48 | |
| @@ -30,6 +30,14 @@ · 29 unmodified lines | ||
| 30 | 30 | polling-delay = <0>; |
| 31 | 31 | polling-delay-passive = <0>; |
| 32 | 32 | thermal-sensors = <&bat_therm>; |
| 33 | + | |
| 34 | + trips { | |
| 35 | + battery-crit-hi { | |
| 36 | + temperature = <70000>; | |
| 37 | + hysteresis = <2000>; | |
| 38 | + type = "critical"; | |
| 39 | + }; | |
| 40 | + }; | |
| 33 | 41 | }; |
| 34 | 42 | }; |
| 35 | 43 | |
| @@ -34,6 +34,14 @@ · 33 unmodified lines | ||
| 34 | 34 | polling-delay = <0>; |
| 35 | 35 | polling-delay-passive = <0>; |
| 36 | 36 | thermal-sensors = <&bat_therm>; |
| 37 | + | |
| 38 | + trips { | |
| 39 | + battery-crit-hi { | |
| 40 | + temperature = <70000>; | |
| 41 | + hysteresis = <2000>; | |
| 42 | + type = "critical"; | |
| 43 | + }; | |
| 44 | + }; | |
| 37 | 45 | }; |
| 38 | 46 | }; |
| 39 | 47 | |
| @@ -30,6 +30,14 @@ · 29 unmodified lines | ||
| 30 | 30 | polling-delay = <0>; |
| 31 | 31 | polling-delay-passive = <0>; |
| 32 | 32 | thermal-sensors = <&bat_therm>; |
| 33 | + | |
| 34 | + trips { | |
| 35 | + battery-crit-hi { | |
| 36 | + temperature = <70000>; | |
| 37 | + hysteresis = <2000>; | |
| 38 | + type = "critical"; | |
| 39 | + }; | |
| 40 | + }; | |
| 33 | 41 | }; |
| 34 | 42 | }; |
| 35 | 43 | |
| @@ -17,7 +17,7 @@ extern unsigned long perf_misc_flags(struct pt_regs *regs); · 16 unmodified lines | ||
| 17 | 17 | |
| 18 | 18 | #define perf_arch_fetch_caller_regs(regs, __ip) { \ |
| 19 | 19 | (regs)->ARM_pc = (__ip); \ |
| 20 | − (regs)->ARM_fp = (unsigned long) __builtin_frame_address(0); \ | |
| 20 | + frame_pointer((regs)) = (unsigned long) __builtin_frame_address(0); \ | |
| 21 | 21 | (regs)->ARM_sp = current_stack_pointer; \ |
| 22 | 22 | (regs)->ARM_cpsr = SVC_MODE; \ |
| 23 | 23 | } |
| @@ -44,12 +44,6 @@ · 43 unmodified lines | ||
| 44 | 44 | |
| 45 | 45 | typedef pte_t *pte_addr_t; |
| 46 | 46 | |
| 47 | −/* | |
| 48 | − * ZERO_PAGE is a global shared page that is always zero: used | |
| 49 | − * for zero-mapped memory areas etc.. | |
| 50 | − */ | |
| 51 | −#define ZERO_PAGE(vaddr) (virt_to_page(0)) | |
| 52 | − | |
| 53 | 47 | /* |
| 54 | 48 | * Mark the prot value as uncacheable and unbufferable. |
| 55 | 49 | */ |
| @@ -10,6 +10,15 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/const.h> |
| 11 | 11 | #include <asm/proc-fns.h> |
| 12 | 12 | |
| 13 | +#ifndef __ASSEMBLY__ | |
| 14 | +/* | |
| 15 | + * ZERO_PAGE is a global shared page that is always zero: used | |
| 16 | + * for zero-mapped memory areas etc.. | |
| 17 | + */ | |
| 18 | +extern struct page *empty_zero_page; | |
| 19 | +#define ZERO_PAGE(vaddr) (empty_zero_page) | |
| 20 | +#endif | |
| 21 | + | |
| 13 | 22 | #ifndef CONFIG_MMU |
| 14 | 23 | |
| 15 | 24 | #include <asm-generic/pgtable-nopud.h> |
| @@ -139,13 +148,6 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, · 123 unmodified lines | ||
| 139 | 148 | */ |
| 140 | 149 | |
| 141 | 150 | #ifndef __ASSEMBLY__ |
| 142 | −/* | |
| 143 | − * ZERO_PAGE is a global shared page that is always zero: used | |
| 144 | − * for zero-mapped memory areas etc.. | |
| 145 | − */ | |
| 146 | −extern struct page *empty_zero_page; | |
| 147 | −#define ZERO_PAGE(vaddr) (empty_zero_page) | |
| 148 | − | |
| 149 | 151 | |
| 150 | 152 | extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; |
| 151 | 153 | |
| @@ -169,10 +169,15 @@ sr_ena_2: · 168 unmodified lines | ||
| 169 | 169 | cmp tmp1, #UDDRC_STAT_SELFREF_TYPE_SW |
| 170 | 170 | bne sr_ena_2 |
| 171 | 171 | |
| 172 | − /* Put DDR PHY's DLL in bypass mode for non-backup modes. */ | |
| 172 | + /* Disable DX DLLs for non-backup modes. */ | |
| 173 | 173 | cmp r7, #AT91_PM_BACKUP |
| 174 | 174 | beq sr_ena_3 |
| 175 | 175 | |
| 176 | + /* Do not soft reset the AC DLL. */ | |
| 177 | + ldr tmp1, [r3, DDR3PHY_ACDLLCR] | |
| 178 | + bic tmp1, tmp1, DDR3PHY_ACDLLCR_DLLSRST | |
| 179 | + str tmp1, [r3, DDR3PHY_ACDLLCR] | |
| 180 | + | |
| 176 | 181 | /* Disable DX DLLs. */ |
| 177 | 182 | ldr tmp1, [r3, #DDR3PHY_DX0DLLCR] |
| 178 | 183 | orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS |
| @@ -393,8 +393,10 @@ static void __init mxs_machine_init(void) · 392 unmodified lines | ||
| 393 | 393 | |
| 394 | 394 | root = of_find_node_by_path("/"); |
| 395 | 395 | ret = of_property_read_string(root, "model", &soc_dev_attr->machine); |
| 396 | − if (ret) | |
| 396 | + if (ret) { | |
| 397 | + kfree(soc_dev_attr); | |
| 397 | 398 | return; |
| 399 | + } | |
| 398 | 400 | |
| 399 | 401 | soc_dev_attr->family = "Freescale MXS Family"; |
| 400 | 402 | soc_dev_attr->soc_id = mxs_get_soc_id(); |
| @@ -26,6 +26,13 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | unsigned long vectors_base; |
| 28 | 28 | |
| 29 | +/* | |
| 30 | + * empty_zero_page is a special page that is used for | |
| 31 | + * zero-initialized data and COW. | |
| 32 | + */ | |
| 33 | +struct page *empty_zero_page; | |
| 34 | +EXPORT_SYMBOL(empty_zero_page); | |
| 35 | + | |
| 29 | 36 | #ifdef CONFIG_ARM_MPU |
| 30 | 37 | struct mpu_rgn_info mpu_rgn_info; |
| 31 | 38 | #endif |
| @@ -148,9 +155,21 @@ void __init adjust_lowmem_bounds(void) · 116 unmodified lines | ||
| 148 | 155 | */ |
| 149 | 156 | void __init paging_init(const struct machine_desc *mdesc) |
| 150 | 157 | { |
| 158 | + void *zero_page; | |
| 159 | + | |
| 151 | 160 | early_trap_init((void *)vectors_base); |
| 152 | 161 | mpu_setup(); |
| 162 | + | |
| 163 | + /* allocate the zero page. */ | |
| 164 | + zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE); | |
| 165 | + if (!zero_page) | |
| 166 | + panic("%s: Failed to allocate %lu bytes align=0x%lx\n", | |
| 167 | + __func__, PAGE_SIZE, PAGE_SIZE); | |
| 168 | + | |
| 153 | 169 | bootmem_init(); |
| 170 | + | |
| 171 | + empty_zero_page = virt_to_page(zero_page); | |
| 172 | + flush_dcache_page(empty_zero_page); | |
| 154 | 173 | } |
| 155 | 174 | |
| 156 | 175 | /* |
| @@ -161,6 +161,7 @@ · 160 unmodified lines | ||
| 161 | 161 | clocks = <&ccu CLK_BUS_VP9>, <&ccu CLK_VP9>; |
| 162 | 162 | clock-names = "bus", "mod"; |
| 163 | 163 | resets = <&ccu RST_BUS_VP9>; |
| 164 | + iommus = <&iommu 5>; | |
| 164 | 165 | }; |
| 165 | 166 | |
| 166 | 167 | video-codec@1c0e000 { |
| @@ -751,12 +751,26 @@ · 750 unmodified lines | ||
| 751 | 751 | polling-delay = <1000>; |
| 752 | 752 | polling-delay-passive = <100>; |
| 753 | 753 | thermal-sensors = <&scpi_sensors0 0>; |
| 754 | + trips { | |
| 755 | + pmic_crit0: trip0 { | |
| 756 | + temperature = <90000>; | |
| 757 | + hysteresis = <2000>; | |
| 758 | + type = "critical"; | |
| 759 | + }; | |
| 760 | + }; | |
| 754 | 761 | }; |
| 755 | 762 | |
| 756 | 763 | soc { |
| 757 | 764 | polling-delay = <1000>; |
| 758 | 765 | polling-delay-passive = <100>; |
| 759 | 766 | thermal-sensors = <&scpi_sensors0 3>; |
| 767 | + trips { | |
| 768 | + soc_crit0: trip0 { | |
| 769 | + temperature = <80000>; | |
| 770 | + hysteresis = <2000>; | |
| 771 | + type = "critical"; | |
| 772 | + }; | |
| 773 | + }; | |
| 760 | 774 | }; |
| 761 | 775 | |
| 762 | 776 | big_cluster_thermal_zone: big-cluster { |
| @@ -779,6 +779,9 @@ · 778 unmodified lines | ||
| 779 | 779 | little-endian; |
| 780 | 780 | #address-cells = <1>; |
| 781 | 781 | #size-cells = <0>; |
| 782 | + clock-frequency = <2500000>; | |
| 783 | + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL | |
| 784 | + QORIQ_CLK_PLL_DIV(1)>; | |
| 782 | 785 | status = "disabled"; |
| 783 | 786 | }; |
| 784 | 787 | |
| @@ -788,6 +791,9 @@ · 3 unmodified lines | ||
| 788 | 791 | little-endian; |
| 789 | 792 | #address-cells = <1>; |
| 790 | 793 | #size-cells = <0>; |
| 794 | + clock-frequency = <2500000>; | |
| 795 | + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL | |
| 796 | + QORIQ_CLK_PLL_DIV(1)>; | |
| 791 | 797 | status = "disabled"; |
| 792 | 798 | }; |
| 793 | 799 | |
| @@ -532,6 +532,9 @@ · 531 unmodified lines | ||
| 532 | 532 | little-endian; |
| 533 | 533 | #address-cells = <1>; |
| 534 | 534 | #size-cells = <0>; |
| 535 | + clock-frequency = <2500000>; | |
| 536 | + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL | |
| 537 | + QORIQ_CLK_PLL_DIV(2)>; | |
| 535 | 538 | status = "disabled"; |
| 536 | 539 | }; |
| 537 | 540 | |
| @@ -541,6 +544,9 @@ · 3 unmodified lines | ||
| 541 | 544 | little-endian; |
| 542 | 545 | #address-cells = <1>; |
| 543 | 546 | #size-cells = <0>; |
| 547 | + clock-frequency = <2500000>; | |
| 548 | + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL | |
| 549 | + QORIQ_CLK_PLL_DIV(2)>; | |
| 544 | 550 | status = "disabled"; |
| 545 | 551 | }; |
| 546 | 552 | |
| @@ -1385,6 +1385,9 @@ · 1384 unmodified lines | ||
| 1385 | 1385 | #address-cells = <1>; |
| 1386 | 1386 | #size-cells = <0>; |
| 1387 | 1387 | little-endian; |
| 1388 | + clock-frequency = <2500000>; | |
| 1389 | + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL | |
| 1390 | + QORIQ_CLK_PLL_DIV(2)>; | |
| 1388 | 1391 | status = "disabled"; |
| 1389 | 1392 | }; |
| 1390 | 1393 | |
| @@ -1395,6 +1398,9 @@ · 4 unmodified lines | ||
| 1395 | 1398 | little-endian; |
| 1396 | 1399 | #address-cells = <1>; |
| 1397 | 1400 | #size-cells = <0>; |
| 1401 | + clock-frequency = <2500000>; | |
| 1402 | + clocks = <&clockgen QORIQ_CLK_PLATFORM_PLL | |
| 1403 | + QORIQ_CLK_PLL_DIV(2)>; | |
| 1398 | 1404 | status = "disabled"; |
| 1399 | 1405 | }; |
| 1400 | 1406 | |
| @@ -38,9 +38,9 @@ conn_subsys: bus@5b000000 { · 37 unmodified lines | ||
| 38 | 38 | interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>; |
| 39 | 39 | reg = <0x5b010000 0x10000>; |
| 40 | 40 | clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>, |
| 41 | − <&sdhc0_lpcg IMX_LPCG_CLK_5>, | |
| 42 | − <&sdhc0_lpcg IMX_LPCG_CLK_0>; | |
| 43 | − clock-names = "ipg", "per", "ahb"; | |
| 41 | + <&sdhc0_lpcg IMX_LPCG_CLK_0>, | |
| 42 | + <&sdhc0_lpcg IMX_LPCG_CLK_5>; | |
| 43 | + clock-names = "ipg", "ahb", "per"; | |
| 44 | 44 | power-domains = <&pd IMX_SC_R_SDHC_0>; |
| 45 | 45 | status = "disabled"; |
| 46 | 46 | }; |
| @@ -49,9 +49,9 @@ conn_subsys: bus@5b000000 { · 2 unmodified lines | ||
| 49 | 49 | interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>; |
| 50 | 50 | reg = <0x5b020000 0x10000>; |
| 51 | 51 | clocks = <&sdhc1_lpcg IMX_LPCG_CLK_4>, |
| 52 | − <&sdhc1_lpcg IMX_LPCG_CLK_5>, | |
| 53 | − <&sdhc1_lpcg IMX_LPCG_CLK_0>; | |
| 54 | − clock-names = "ipg", "per", "ahb"; | |
| 52 | + <&sdhc1_lpcg IMX_LPCG_CLK_0>, | |
| 53 | + <&sdhc1_lpcg IMX_LPCG_CLK_5>; | |
| 54 | + clock-names = "ipg", "ahb", "per"; | |
| 55 | 55 | power-domains = <&pd IMX_SC_R_SDHC_1>; |
| 56 | 56 | fsl,tuning-start-tap = <20>; |
| 57 | 57 | fsl,tuning-step = <2>; |
| @@ -62,9 +62,9 @@ conn_subsys: bus@5b000000 { · 4 unmodified lines | ||
| 62 | 62 | interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>; |
| 63 | 63 | reg = <0x5b030000 0x10000>; |
| 64 | 64 | clocks = <&sdhc2_lpcg IMX_LPCG_CLK_4>, |
| 65 | − <&sdhc2_lpcg IMX_LPCG_CLK_5>, | |
| 66 | − <&sdhc2_lpcg IMX_LPCG_CLK_0>; | |
| 67 | − clock-names = "ipg", "per", "ahb"; | |
| 65 | + <&sdhc2_lpcg IMX_LPCG_CLK_0>, | |
| 66 | + <&sdhc2_lpcg IMX_LPCG_CLK_5>; | |
| 67 | + clock-names = "ipg", "ahb", "per"; | |
| 68 | 68 | power-domains = <&pd IMX_SC_R_SDHC_2>; |
| 69 | 69 | status = "disabled"; |
| 70 | 70 | }; |
| @@ -250,21 +250,21 @@ · 249 unmodified lines | ||
| 250 | 250 | /* SODIMM 96 */ |
| 251 | 251 | MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x1c4 |
| 252 | 252 | /* CPLD_D[7] */ |
| 253 | − MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x1c4 | |
| 253 | + MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x184 | |
| 254 | 254 | /* CPLD_D[6] */ |
| 255 | − MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x1c4 | |
| 255 | + MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0 0x184 | |
| 256 | 256 | /* CPLD_D[5] */ |
| 257 | − MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x1c4 | |
| 257 | + MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11 0x184 | |
| 258 | 258 | /* CPLD_D[4] */ |
| 259 | − MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x1c4 | |
| 259 | + MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12 0x184 | |
| 260 | 260 | /* CPLD_D[3] */ |
| 261 | − MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x1c4 | |
| 261 | + MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13 0x184 | |
| 262 | 262 | /* CPLD_D[2] */ |
| 263 | − MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x1c4 | |
| 263 | + MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x184 | |
| 264 | 264 | /* CPLD_D[1] */ |
| 265 | − MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x1c4 | |
| 265 | + MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x184 | |
| 266 | 266 | /* CPLD_D[0] */ |
| 267 | − MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x1c4 | |
| 267 | + MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x184 | |
| 268 | 268 | /* KBD_intK */ |
| 269 | 269 | MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x1c4 |
| 270 | 270 | /* DISP_reset */ |
| @@ -34,11 +34,25 @@ · 33 unmodified lines | ||
| 34 | 34 | off-on-delay-us = <12000>; |
| 35 | 35 | }; |
| 36 | 36 | |
| 37 | − extcon_usbotg1: extcon-usbotg1 { | |
| 38 | − compatible = "linux,extcon-usb-gpio"; | |
| 37 | + connector { | |
| 38 | + compatible = "gpio-usb-b-connector", "usb-b-connector"; | |
| 39 | + type = "micro"; | |
| 40 | + label = "X19"; | |
| 39 | 41 | pinctrl-names = "default"; |
| 40 | − pinctrl-0 = <&pinctrl_usb1_extcon>; | |
| 41 | − id-gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; | |
| 42 | + pinctrl-0 = <&pinctrl_usb1_connector>; | |
| 43 | + id-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; | |
| 44 | + | |
| 45 | + ports { | |
| 46 | + #address-cells = <1>; | |
| 47 | + #size-cells = <0>; | |
| 48 | + | |
| 49 | + port@0 { | |
| 50 | + reg = <0>; | |
| 51 | + usb_dr_connector: endpoint { | |
| 52 | + remote-endpoint = <&usb1_drd_sw>; | |
| 53 | + }; | |
| 54 | + }; | |
| 55 | + }; | |
| 42 | 56 | }; |
| 43 | 57 | }; |
| 44 | 58 | |
| @@ -105,13 +119,19 @@ · 60 unmodified lines | ||
| 105 | 119 | pinctrl-names = "default"; |
| 106 | 120 | pinctrl-0 = <&pinctrl_usbotg1>; |
| 107 | 121 | dr_mode = "otg"; |
| 108 | − extcon = <&extcon_usbotg1>; | |
| 109 | 122 | srp-disable; |
| 110 | 123 | hnp-disable; |
| 111 | 124 | adp-disable; |
| 112 | 125 | power-active-high; |
| 113 | 126 | over-current-active-low; |
| 127 | + usb-role-switch; | |
| 114 | 128 | status = "okay"; |
| 129 | + | |
| 130 | + port { | |
| 131 | + usb1_drd_sw: endpoint { | |
| 132 | + remote-endpoint = <&usb_dr_connector>; | |
| 133 | + }; | |
| 134 | + }; | |
| 115 | 135 | }; |
| 116 | 136 | |
| 117 | 137 | &usbotg2 { |
| @@ -231,7 +251,7 @@ · 113 unmodified lines | ||
| 231 | 251 | <MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC 0x84>; |
| 232 | 252 | }; |
| 233 | 253 | |
| 234 | − pinctrl_usb1_extcon: usb1-extcongrp { | |
| 254 | + pinctrl_usb1_connector: usb1-connectorgrp { | |
| 235 | 255 | fsl,pins = <MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x1c0>; |
| 236 | 256 | }; |
| 237 | 257 | |
| @@ -276,6 +276,7 @@ · 275 unmodified lines | ||
| 276 | 276 | assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; |
| 277 | 277 | assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>; |
| 278 | 278 | clock-names = "main_clk"; |
| 279 | + power-domains = <&pgc_otg1>; | |
| 279 | 280 | }; |
| 280 | 281 | |
| 281 | 282 | usbphynop2: usbphynop2 { |
| @@ -285,6 +286,7 @@ · 3 unmodified lines | ||
| 285 | 286 | assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; |
| 286 | 287 | assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>; |
| 287 | 288 | clock-names = "main_clk"; |
| 289 | + power-domains = <&pgc_otg2>; | |
| 288 | 290 | }; |
| 289 | 291 | |
| 290 | 292 | soc: soc@0 { |
| @@ -674,13 +676,11 @@ · 383 unmodified lines | ||
| 674 | 676 | pgc_otg1: power-domain@2 { |
| 675 | 677 | #power-domain-cells = <0>; |
| 676 | 678 | reg = <IMX8MM_POWER_DOMAIN_OTG1>; |
| 677 | − power-domains = <&pgc_hsiomix>; | |
| 678 | 679 | }; |
| 679 | 680 | |
| 680 | 681 | pgc_otg2: power-domain@3 { |
| 681 | 682 | #power-domain-cells = <0>; |
| 682 | 683 | reg = <IMX8MM_POWER_DOMAIN_OTG2>; |
| 683 | − power-domains = <&pgc_hsiomix>; | |
| 684 | 684 | }; |
| 685 | 685 | |
| 686 | 686 | pgc_gpumix: power-domain@4 { |
| @@ -1186,7 +1186,7 @@ · 499 unmodified lines | ||
| 1186 | 1186 | assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; |
| 1187 | 1187 | phys = <&usbphynop1>; |
| 1188 | 1188 | fsl,usbmisc = <&usbmisc1 0>; |
| 1189 | − power-domains = <&pgc_otg1>; | |
| 1189 | + power-domains = <&pgc_hsiomix>; | |
| 1190 | 1190 | status = "disabled"; |
| 1191 | 1191 | }; |
| 1192 | 1192 | |
| @@ -1206,7 +1206,7 @@ · 13 unmodified lines | ||
| 1206 | 1206 | assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; |
| 1207 | 1207 | phys = <&usbphynop2>; |
| 1208 | 1208 | fsl,usbmisc = <&usbmisc2 0>; |
| 1209 | − power-domains = <&pgc_otg2>; | |
| 1209 | + power-domains = <&pgc_hsiomix>; | |
| 1210 | 1210 | status = "disabled"; |
| 1211 | 1211 | }; |
| 1212 | 1212 | |
| @@ -1244,10 +1244,10 @@ · 31 unmodified lines | ||
| 1244 | 1244 | clocks = <&clk IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK>; |
| 1245 | 1245 | }; |
| 1246 | 1246 | |
| 1247 | − gpmi: nand-controller@33002000{ | |
| 1247 | + gpmi: nand-controller@33002000 { | |
| 1248 | 1248 | compatible = "fsl,imx8mm-gpmi-nand", "fsl,imx7d-gpmi-nand"; |
| 1249 | 1249 | #address-cells = <1>; |
| 1250 | − #size-cells = <1>; | |
| 1250 | + #size-cells = <0>; | |
| 1251 | 1251 | reg = <0x33002000 0x2000>, <0x33004000 0x4000>; |
| 1252 | 1252 | reg-names = "gpmi-nand", "bch"; |
| 1253 | 1253 | interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -662,7 +662,6 @@ · 661 unmodified lines | ||
| 662 | 662 | pgc_otg1: power-domain@1 { |
| 663 | 663 | #power-domain-cells = <0>; |
| 664 | 664 | reg = <IMX8MN_POWER_DOMAIN_OTG1>; |
| 665 | − power-domains = <&pgc_hsiomix>; | |
| 666 | 665 | }; |
| 667 | 666 | |
| 668 | 667 | pgc_gpumix: power-domain@2 { |
| @@ -1076,7 +1075,7 @@ · 407 unmodified lines | ||
| 1076 | 1075 | assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>; |
| 1077 | 1076 | phys = <&usbphynop1>; |
| 1078 | 1077 | fsl,usbmisc = <&usbmisc1 0>; |
| 1079 | − power-domains = <&pgc_otg1>; | |
| 1078 | + power-domains = <&pgc_hsiomix>; | |
| 1080 | 1079 | status = "disabled"; |
| 1081 | 1080 | }; |
| 1082 | 1081 | |
| @@ -1103,7 +1102,7 @@ · 20 unmodified lines | ||
| 1103 | 1102 | gpmi: nand-controller@33002000 { |
| 1104 | 1103 | compatible = "fsl,imx8mn-gpmi-nand", "fsl,imx7d-gpmi-nand"; |
| 1105 | 1104 | #address-cells = <1>; |
| 1106 | − #size-cells = <1>; | |
| 1105 | + #size-cells = <0>; | |
| 1107 | 1106 | reg = <0x33002000 0x2000>, <0x33004000 0x4000>; |
| 1108 | 1107 | reg-names = "gpmi-nand", "bch"; |
| 1109 | 1108 | interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; |
| @@ -1175,5 +1174,6 @@ · 65 unmodified lines | ||
| 1175 | 1174 | assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>; |
| 1176 | 1175 | assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>; |
| 1177 | 1176 | clock-names = "main_clk"; |
| 1177 | + power-domains = <&pgc_otg1>; | |
| 1178 | 1178 | }; |
| 1179 | 1179 | }; |
| @@ -544,14 +544,14 @@ · 543 unmodified lines | ||
| 544 | 544 | |
| 545 | 545 | pinctrl_pcie0: pcie0grp { |
| 546 | 546 | fsl,pins = < |
| 547 | − MX8MP_IOMUXC_I2C4_SCL__PCIE_CLKREQ_B 0x61 /* open drain, pull up */ | |
| 548 | − MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0x41 | |
| 547 | + MX8MP_IOMUXC_I2C4_SCL__PCIE_CLKREQ_B 0x60 /* open drain, pull up */ | |
| 548 | + MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0x40 | |
| 549 | 549 | >; |
| 550 | 550 | }; |
| 551 | 551 | |
| 552 | 552 | pinctrl_pcie0_reg: pcie0reggrp { |
| 553 | 553 | fsl,pins = < |
| 554 | − MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x41 | |
| 554 | + MX8MP_IOMUXC_SD1_DATA4__GPIO2_IO06 0x40 | |
| 555 | 555 | >; |
| 556 | 556 | }; |
| 557 | 557 | |
| @@ -354,16 +354,6 @@ · 353 unmodified lines | ||
| 354 | 354 | "SODIMM_82", |
| 355 | 355 | "SODIMM_70", |
| 356 | 356 | "SODIMM_72"; |
| 357 | − | |
| 358 | − ctrl-sleep-moci-hog { | |
| 359 | − gpio-hog; | |
| 360 | − /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */ | |
| 361 | − gpios = <29 GPIO_ACTIVE_HIGH>; | |
| 362 | − line-name = "CTRL_SLEEP_MOCI#"; | |
| 363 | − output-high; | |
| 364 | − pinctrl-names = "default"; | |
| 365 | − pinctrl-0 = <&pinctrl_ctrl_sleep_moci>; | |
| 366 | − }; | |
| 367 | 357 | }; |
| 368 | 358 | |
| 369 | 359 | &gpio3 { |
| @@ -432,6 +422,16 @@ · 62 unmodified lines | ||
| 432 | 422 | "SODIMM_256", |
| 433 | 423 | "SODIMM_48", |
| 434 | 424 | "SODIMM_44"; |
| 425 | + | |
| 426 | + ctrl-sleep-moci-hog { | |
| 427 | + gpio-hog; | |
| 428 | + /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */ | |
| 429 | + gpios = <29 GPIO_ACTIVE_HIGH>; | |
| 430 | + line-name = "CTRL_SLEEP_MOCI#"; | |
| 431 | + output-high; | |
| 432 | + pinctrl-names = "default"; | |
| 433 | + pinctrl-0 = <&pinctrl_ctrl_sleep_moci>; | |
| 434 | + }; | |
| 435 | 435 | }; |
| 436 | 436 | |
| 437 | 437 | /* On-module I2C */ |
File mode changed from 100755 to 100644.
| @@ -451,7 +451,7 @@ · 450 unmodified lines | ||
| 451 | 451 | clocks = <&clk IMX93_CLK_GPIO2_GATE>, |
| 452 | 452 | <&clk IMX93_CLK_GPIO2_GATE>; |
| 453 | 453 | clock-names = "gpio", "port"; |
| 454 | − gpio-ranges = <&iomuxc 0 32 32>; | |
| 454 | + gpio-ranges = <&iomuxc 0 4 30>; | |
| 455 | 455 | }; |
| 456 | 456 | |
| 457 | 457 | gpio3: gpio@43820080 { |
| @@ -465,7 +465,8 @@ · 7 unmodified lines | ||
| 465 | 465 | clocks = <&clk IMX93_CLK_GPIO3_GATE>, |
| 466 | 466 | <&clk IMX93_CLK_GPIO3_GATE>; |
| 467 | 467 | clock-names = "gpio", "port"; |
| 468 | − gpio-ranges = <&iomuxc 0 64 32>; | |
| 468 | + gpio-ranges = <&iomuxc 0 84 8>, <&iomuxc 8 66 18>, | |
| 469 | + <&iomuxc 26 34 2>, <&iomuxc 28 0 4>; | |
| 469 | 470 | }; |
| 470 | 471 | |
| 471 | 472 | gpio4: gpio@43830080 { |
| @@ -479,7 +480,7 @@ · 7 unmodified lines | ||
| 479 | 480 | clocks = <&clk IMX93_CLK_GPIO4_GATE>, |
| 480 | 481 | <&clk IMX93_CLK_GPIO4_GATE>; |
| 481 | 482 | clock-names = "gpio", "port"; |
| 482 | − gpio-ranges = <&iomuxc 0 96 32>; | |
| 483 | + gpio-ranges = <&iomuxc 0 38 28>, <&iomuxc 28 36 2>; | |
| 483 | 484 | }; |
| 484 | 485 | |
| 485 | 486 | gpio1: gpio@47400080 { |
| @@ -493,7 +494,7 @@ · 7 unmodified lines | ||
| 493 | 494 | clocks = <&clk IMX93_CLK_GPIO1_GATE>, |
| 494 | 495 | <&clk IMX93_CLK_GPIO1_GATE>; |
| 495 | 496 | clock-names = "gpio", "port"; |
| 496 | − gpio-ranges = <&iomuxc 0 0 32>; | |
| 497 | + gpio-ranges = <&iomuxc 0 92 16>; | |
| 497 | 498 | }; |
| 498 | 499 | |
| 499 | 500 | s4muap: mailbox@47520000 { |
| @@ -501,7 +502,7 @@ · 1 unmodified line | ||
| 501 | 502 | reg = <0x47520000 0x10000>; |
| 502 | 503 | interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>, |
| 503 | 504 | <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>; |
| 504 | − interrupt-names = "txirq", "rxirq"; | |
| 505 | + interrupt-names = "tx", "rx"; | |
| 505 | 506 | #mbox-cells = <2>; |
| 506 | 507 | }; |
| 507 | 508 | |
| @@ -668,7 +668,7 @@ · 667 unmodified lines | ||
| 668 | 668 | |
| 669 | 669 | apcs_glb: mailbox@b111000 { |
| 670 | 670 | compatible = "qcom,ipq8074-apcs-apps-global"; |
| 671 | − reg = <0x0b111000 0x6000>; | |
| 671 | + reg = <0x0b111000 0x1000>; | |
| 672 | 672 | |
| 673 | 673 | #clock-cells = <1>; |
| 674 | 674 | #mbox-cells = <1>; |
| @@ -3504,7 +3504,7 @@ · 3503 unmodified lines | ||
| 3504 | 3504 | }; |
| 3505 | 3505 | |
| 3506 | 3506 | saw3: syscon@9a10000 { |
| 3507 | − compatible = "qcom,tcsr-msm8996", "syscon"; | |
| 3507 | + compatible = "syscon"; | |
| 3508 | 3508 | reg = <0x09a10000 0x1000>; |
| 3509 | 3509 | }; |
| 3510 | 3510 | |
| @@ -43,7 +43,6 @@ · 42 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | regulator-always-on; |
| 45 | 45 | regulator-boot-on; |
| 46 | − regulator-allow-set-load; | |
| 47 | 46 | |
| 48 | 47 | vin-supply = <&vreg_3p3>; |
| 49 | 48 | }; |
| @@ -137,6 +136,9 @@ · 87 unmodified lines | ||
| 137 | 136 | regulator-max-microvolt = <880000>; |
| 138 | 137 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 139 | 138 | regulator-allow-set-load; |
| 139 | + regulator-allowed-modes = | |
| 140 | + <RPMH_REGULATOR_MODE_LPM | |
| 141 | + RPMH_REGULATOR_MODE_HPM>; | |
| 140 | 142 | }; |
| 141 | 143 | |
| 142 | 144 | vreg_l7a_1p8: ldo7 { |
| @@ -152,6 +154,9 @@ · 9 unmodified lines | ||
| 152 | 154 | regulator-max-microvolt = <2960000>; |
| 153 | 155 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 154 | 156 | regulator-allow-set-load; |
| 157 | + regulator-allowed-modes = | |
| 158 | + <RPMH_REGULATOR_MODE_LPM | |
| 159 | + RPMH_REGULATOR_MODE_HPM>; | |
| 155 | 160 | }; |
| 156 | 161 | |
| 157 | 162 | vreg_l11a_0p8: ldo11 { |
| @@ -258,6 +263,9 @@ · 100 unmodified lines | ||
| 258 | 263 | regulator-max-microvolt = <1200000>; |
| 259 | 264 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 260 | 265 | regulator-allow-set-load; |
| 266 | + regulator-allowed-modes = | |
| 267 | + <RPMH_REGULATOR_MODE_LPM | |
| 268 | + RPMH_REGULATOR_MODE_HPM>; | |
| 261 | 269 | }; |
| 262 | 270 | |
| 263 | 271 | vreg_l7c_1p8: ldo7 { |
| @@ -273,6 +281,9 @@ · 9 unmodified lines | ||
| 273 | 281 | regulator-max-microvolt = <1200000>; |
| 274 | 282 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 275 | 283 | regulator-allow-set-load; |
| 284 | + regulator-allowed-modes = | |
| 285 | + <RPMH_REGULATOR_MODE_LPM | |
| 286 | + RPMH_REGULATOR_MODE_HPM>; | |
| 276 | 287 | }; |
| 277 | 288 | |
| 278 | 289 | vreg_l10c_3p3: ldo10 { |
| @@ -83,6 +83,9 @@ · 82 unmodified lines | ||
| 83 | 83 | regulator-max-microvolt = <1200000>; |
| 84 | 84 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 85 | 85 | regulator-allow-set-load; |
| 86 | + regulator-allowed-modes = | |
| 87 | + <RPMH_REGULATOR_MODE_LPM | |
| 88 | + RPMH_REGULATOR_MODE_HPM>; | |
| 86 | 89 | }; |
| 87 | 90 | |
| 88 | 91 | vreg_l4c: ldo4 { |
| @@ -98,6 +101,9 @@ · 9 unmodified lines | ||
| 98 | 101 | regulator-max-microvolt = <1200000>; |
| 99 | 102 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 100 | 103 | regulator-allow-set-load; |
| 104 | + regulator-allowed-modes = | |
| 105 | + <RPMH_REGULATOR_MODE_LPM | |
| 106 | + RPMH_REGULATOR_MODE_HPM>; | |
| 101 | 107 | }; |
| 102 | 108 | |
| 103 | 109 | vreg_l7c: ldo7 { |
| @@ -113,6 +119,9 @@ · 9 unmodified lines | ||
| 113 | 119 | regulator-max-microvolt = <2504000>; |
| 114 | 120 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 115 | 121 | regulator-allow-set-load; |
| 122 | + regulator-allowed-modes = | |
| 123 | + <RPMH_REGULATOR_MODE_LPM | |
| 124 | + RPMH_REGULATOR_MODE_HPM>; | |
| 116 | 125 | }; |
| 117 | 126 | |
| 118 | 127 | vreg_l17c: ldo17 { |
| @@ -121,6 +130,9 @@ · 2 unmodified lines | ||
| 121 | 130 | regulator-max-microvolt = <2504000>; |
| 122 | 131 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 123 | 132 | regulator-allow-set-load; |
| 133 | + regulator-allowed-modes = | |
| 134 | + <RPMH_REGULATOR_MODE_LPM | |
| 135 | + RPMH_REGULATOR_MODE_HPM>; | |
| 124 | 136 | }; |
| 125 | 137 | }; |
| 126 | 138 | |
| @@ -2296,7 +2296,8 @@ · 2295 unmodified lines | ||
| 2296 | 2296 | |
| 2297 | 2297 | lpass_audiocc: clock-controller@3300000 { |
| 2298 | 2298 | compatible = "qcom,sc7280-lpassaudiocc"; |
| 2299 | − reg = <0 0x03300000 0 0x30000>; | |
| 2299 | + reg = <0 0x03300000 0 0x30000>, | |
| 2300 | + <0 0x032a9000 0 0x1000>; | |
| 2300 | 2301 | clocks = <&rpmhcc RPMH_CXO_CLK>, |
| 2301 | 2302 | <&lpass_aon LPASS_AON_CC_MAIN_RCG_CLK_SRC>; |
| 2302 | 2303 | clock-names = "bi_tcxo", "lpass_aon_cc_main_rcg_clk_src"; |
| @@ -124,6 +124,9 @@ · 123 unmodified lines | ||
| 124 | 124 | regulator-max-microvolt = <2504000>; |
| 125 | 125 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 126 | 126 | regulator-allow-set-load; |
| 127 | + regulator-allowed-modes = | |
| 128 | + <RPMH_REGULATOR_MODE_LPM | |
| 129 | + RPMH_REGULATOR_MODE_HPM>; | |
| 127 | 130 | }; |
| 128 | 131 | |
| 129 | 132 | vreg_l13c: ldo13 { |
| @@ -146,6 +149,9 @@ · 16 unmodified lines | ||
| 146 | 149 | regulator-max-microvolt = <1200000>; |
| 147 | 150 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 148 | 151 | regulator-allow-set-load; |
| 152 | + regulator-allowed-modes = | |
| 153 | + <RPMH_REGULATOR_MODE_LPM | |
| 154 | + RPMH_REGULATOR_MODE_HPM>; | |
| 149 | 155 | }; |
| 150 | 156 | |
| 151 | 157 | vreg_l4d: ldo4 { |
| @@ -885,13 +885,13 @@ · 884 unmodified lines | ||
| 885 | 885 | |
| 886 | 886 | ufs_mem_phy: phy@1d87000 { |
| 887 | 887 | compatible = "qcom,sc8280xp-qmp-ufs-phy"; |
| 888 | − reg = <0 0x01d87000 0 0xe10>; | |
| 888 | + reg = <0 0x01d87000 0 0x1c8>; | |
| 889 | 889 | #address-cells = <2>; |
| 890 | 890 | #size-cells = <2>; |
| 891 | 891 | ranges; |
| 892 | 892 | clock-names = "ref", |
| 893 | 893 | "ref_aux"; |
| 894 | − clocks = <&rpmhcc RPMH_CXO_CLK>, | |
| 894 | + clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, | |
| 895 | 895 | <&gcc GCC_UFS_PHY_PHY_AUX_CLK>; |
| 896 | 896 | |
| 897 | 897 | resets = <&ufs_mem_hc 0>; |
| @@ -953,13 +953,13 @@ · 55 unmodified lines | ||
| 953 | 953 | |
| 954 | 954 | ufs_card_phy: phy@1da7000 { |
| 955 | 955 | compatible = "qcom,sc8280xp-qmp-ufs-phy"; |
| 956 | − reg = <0 0x01da7000 0 0xe10>; | |
| 956 | + reg = <0 0x01da7000 0 0x1c8>; | |
| 957 | 957 | #address-cells = <2>; |
| 958 | 958 | #size-cells = <2>; |
| 959 | 959 | ranges; |
| 960 | 960 | clock-names = "ref", |
| 961 | 961 | "ref_aux"; |
| 962 | − clocks = <&gcc GCC_UFS_1_CARD_CLKREF_CLK>, | |
| 962 | + clocks = <&gcc GCC_UFS_REF_CLKREF_CLK>, | |
| 963 | 963 | <&gcc GCC_UFS_CARD_PHY_AUX_CLK>; |
| 964 | 964 | |
| 965 | 965 | resets = <&ufs_card_hc 0>; |
| @@ -1181,26 +1181,16 @@ · 215 unmodified lines | ||
| 1181 | 1181 | usb_0_ssphy: usb3-phy@88eb400 { |
| 1182 | 1182 | reg = <0 0x088eb400 0 0x100>, |
| 1183 | 1183 | <0 0x088eb600 0 0x3ec>, |
| 1184 | − <0 0x088ec400 0 0x1f0>, | |
| 1184 | + <0 0x088ec400 0 0x364>, | |
| 1185 | 1185 | <0 0x088eba00 0 0x100>, |
| 1186 | 1186 | <0 0x088ebc00 0 0x3ec>, |
| 1187 | − <0 0x088ec700 0 0x64>; | |
| 1187 | + <0 0x088ec200 0 0x18>; | |
| 1188 | 1188 | #phy-cells = <0>; |
| 1189 | 1189 | #clock-cells = <0>; |
| 1190 | 1190 | clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; |
| 1191 | 1191 | clock-names = "pipe0"; |
| 1192 | 1192 | clock-output-names = "usb0_phy_pipe_clk_src"; |
| 1193 | 1193 | }; |
| 1194 | − | |
| 1195 | − usb_0_dpphy: dp-phy@88ed200 { | |
| 1196 | − reg = <0 0x088ed200 0 0x200>, | |
| 1197 | − <0 0x088ed400 0 0x200>, | |
| 1198 | − <0 0x088eda00 0 0x200>, | |
| 1199 | − <0 0x088ea600 0 0x200>, | |
| 1200 | − <0 0x088ea800 0 0x200>; | |
| 1201 | − #clock-cells = <1>; | |
| 1202 | − #phy-cells = <0>; | |
| 1203 | − }; | |
| 1204 | 1194 | }; |
| 1205 | 1195 | |
| 1206 | 1196 | usb_1_hsphy: phy@8902000 { |
| @@ -1242,8 +1232,8 @@ · 35 unmodified lines | ||
| 1242 | 1232 | |
| 1243 | 1233 | usb_1_ssphy: usb3-phy@8903400 { |
| 1244 | 1234 | reg = <0 0x08903400 0 0x100>, |
| 1245 | − <0 0x08903c00 0 0x3ec>, | |
| 1246 | − <0 0x08904400 0 0x1f0>, | |
| 1235 | + <0 0x08903600 0 0x3ec>, | |
| 1236 | + <0 0x08904400 0 0x364>, | |
| 1247 | 1237 | <0 0x08903a00 0 0x100>, |
| 1248 | 1238 | <0 0x08903c00 0 0x3ec>, |
| 1249 | 1239 | <0 0x08904200 0 0x18>; |
| @@ -1253,16 +1243,6 @@ · 3 unmodified lines | ||
| 1253 | 1243 | clock-names = "pipe0"; |
| 1254 | 1244 | clock-output-names = "usb1_phy_pipe_clk_src"; |
| 1255 | 1245 | }; |
| 1256 | − | |
| 1257 | − usb_1_dpphy: dp-phy@8904200 { | |
| 1258 | − reg = <0 0x08904200 0 0x200>, | |
| 1259 | − <0 0x08904400 0 0x200>, | |
| 1260 | − <0 0x08904a00 0 0x200>, | |
| 1261 | − <0 0x08904600 0 0x200>, | |
| 1262 | − <0 0x08904800 0 0x200>; | |
| 1263 | − #clock-cells = <1>; | |
| 1264 | − #phy-cells = <0>; | |
| 1265 | − }; | |
| 1266 | 1246 | }; |
| 1267 | 1247 | |
| 1268 | 1248 | system-cache-controller@9200000 { |
| @@ -348,6 +348,9 @@ · 347 unmodified lines | ||
| 348 | 348 | regulator-max-microvolt = <2960000>; |
| 349 | 349 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 350 | 350 | regulator-allow-set-load; |
| 351 | + regulator-allowed-modes = | |
| 352 | + <RPMH_REGULATOR_MODE_LPM | |
| 353 | + RPMH_REGULATOR_MODE_HPM>; | |
| 351 | 354 | }; |
| 352 | 355 | |
| 353 | 356 | vreg_l7c_3p0: ldo7 { |
| @@ -367,6 +370,9 @@ · 13 unmodified lines | ||
| 367 | 370 | regulator-max-microvolt = <2960000>; |
| 368 | 371 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 369 | 372 | regulator-allow-set-load; |
| 373 | + regulator-allowed-modes = | |
| 374 | + <RPMH_REGULATOR_MODE_LPM | |
| 375 | + RPMH_REGULATOR_MODE_HPM>; | |
| 370 | 376 | }; |
| 371 | 377 | |
| 372 | 378 | vreg_l10c_3p3: ldo10 { |
| @@ -317,6 +317,9 @@ · 316 unmodified lines | ||
| 317 | 317 | regulator-max-microvolt = <2960000>; |
| 318 | 318 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 319 | 319 | regulator-allow-set-load; |
| 320 | + regulator-allowed-modes = | |
| 321 | + <RPMH_REGULATOR_MODE_LPM | |
| 322 | + RPMH_REGULATOR_MODE_HPM>; | |
| 320 | 323 | }; |
| 321 | 324 | |
| 322 | 325 | vreg_l7c_2p85: ldo7 { |
| @@ -339,6 +342,9 @@ · 16 unmodified lines | ||
| 339 | 342 | regulator-max-microvolt = <2960000>; |
| 340 | 343 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 341 | 344 | regulator-allow-set-load; |
| 345 | + regulator-allowed-modes = | |
| 346 | + <RPMH_REGULATOR_MODE_LPM | |
| 347 | + RPMH_REGULATOR_MODE_HPM>; | |
| 342 | 348 | }; |
| 343 | 349 | |
| 344 | 350 | vreg_l10c_3p3: ldo10 { |
| @@ -334,6 +334,7 @@ · 333 unmodified lines | ||
| 334 | 334 | exit-latency-us = <6562>; |
| 335 | 335 | min-residency-us = <9987>; |
| 336 | 336 | local-timer-stop; |
| 337 | + status = "disabled"; | |
| 337 | 338 | }; |
| 338 | 339 | }; |
| 339 | 340 | }; |
| @@ -107,6 +107,9 @@ · 106 unmodified lines | ||
| 107 | 107 | regulator-max-microvolt = <888000>; |
| 108 | 108 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 109 | 109 | regulator-allow-set-load; |
| 110 | + regulator-allowed-modes = | |
| 111 | + <RPMH_REGULATOR_MODE_LPM | |
| 112 | + RPMH_REGULATOR_MODE_HPM>; | |
| 110 | 113 | }; |
| 111 | 114 | |
| 112 | 115 | vreg_l6b_1p2: ldo6 { |
| @@ -115,6 +118,9 @@ · 2 unmodified lines | ||
| 115 | 118 | regulator-max-microvolt = <1208000>; |
| 116 | 119 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 117 | 120 | regulator-allow-set-load; |
| 121 | + regulator-allowed-modes = | |
| 122 | + <RPMH_REGULATOR_MODE_LPM | |
| 123 | + RPMH_REGULATOR_MODE_HPM>; | |
| 118 | 124 | }; |
| 119 | 125 | |
| 120 | 126 | vreg_l7b_2p96: ldo7 { |
| @@ -123,6 +129,9 @@ · 2 unmodified lines | ||
| 123 | 129 | regulator-max-microvolt = <2504000>; |
| 124 | 130 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 125 | 131 | regulator-allow-set-load; |
| 132 | + regulator-allowed-modes = | |
| 133 | + <RPMH_REGULATOR_MODE_LPM | |
| 134 | + RPMH_REGULATOR_MODE_HPM>; | |
| 126 | 135 | }; |
| 127 | 136 | |
| 128 | 137 | vreg_l9b_1p2: ldo9 { |
| @@ -131,6 +140,9 @@ · 2 unmodified lines | ||
| 131 | 140 | regulator-max-microvolt = <1200000>; |
| 132 | 141 | regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; |
| 133 | 142 | regulator-allow-set-load; |
| 143 | + regulator-allowed-modes = | |
| 144 | + <RPMH_REGULATOR_MODE_LPM | |
| 145 | + RPMH_REGULATOR_MODE_HPM>; | |
| 134 | 146 | }; |
| 135 | 147 | }; |
| 136 | 148 | |
| @@ -30,31 +30,31 @@ · 29 unmodified lines | ||
| 30 | 30 | keyup-threshold-microvolt = <1800000>; |
| 31 | 31 | poll-interval = <100>; |
| 32 | 32 | |
| 33 | − esc-key { | |
| 33 | + button-esc { | |
| 34 | 34 | label = "esc"; |
| 35 | 35 | linux,code = <KEY_ESC>; |
| 36 | 36 | press-threshold-microvolt = <1310000>; |
| 37 | 37 | }; |
| 38 | 38 | |
| 39 | − home-key { | |
| 39 | + button-home { | |
| 40 | 40 | label = "home"; |
| 41 | 41 | linux,code = <KEY_HOME>; |
| 42 | 42 | press-threshold-microvolt = <624000>; |
| 43 | 43 | }; |
| 44 | 44 | |
| 45 | − menu-key { | |
| 45 | + button-menu { | |
| 46 | 46 | label = "menu"; |
| 47 | 47 | linux,code = <KEY_MENU>; |
| 48 | 48 | press-threshold-microvolt = <987000>; |
| 49 | 49 | }; |
| 50 | 50 | |
| 51 | − vol-down-key { | |
| 51 | + button-down { | |
| 52 | 52 | label = "volume down"; |
| 53 | 53 | linux,code = <KEY_VOLUMEDOWN>; |
| 54 | 54 | press-threshold-microvolt = <300000>; |
| 55 | 55 | }; |
| 56 | 56 | |
| 57 | − vol-up-key { | |
| 57 | + button-up { | |
| 58 | 58 | label = "volume up"; |
| 59 | 59 | linux,code = <KEY_VOLUMEUP>; |
| 60 | 60 | press-threshold-microvolt = <17000>; |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | poll-interval = <100>; |
| 24 | 24 | keyup-threshold-microvolt = <1800000>; |
| 25 | 25 | |
| 26 | − func-key { | |
| 26 | + button-func { | |
| 27 | 27 | linux,code = <KEY_FN>; |
| 28 | 28 | label = "function"; |
| 29 | 29 | press-threshold-microvolt = <18000>; |
| @@ -37,31 +37,31 @@ · 7 unmodified lines | ||
| 37 | 37 | poll-interval = <100>; |
| 38 | 38 | keyup-threshold-microvolt = <1800000>; |
| 39 | 39 | |
| 40 | − esc-key { | |
| 40 | + button-esc { | |
| 41 | 41 | linux,code = <KEY_MICMUTE>; |
| 42 | 42 | label = "micmute"; |
| 43 | 43 | press-threshold-microvolt = <1130000>; |
| 44 | 44 | }; |
| 45 | 45 | |
| 46 | − home-key { | |
| 46 | + button-home { | |
| 47 | 47 | linux,code = <KEY_MODE>; |
| 48 | 48 | label = "mode"; |
| 49 | 49 | press-threshold-microvolt = <901000>; |
| 50 | 50 | }; |
| 51 | 51 | |
| 52 | − menu-key { | |
| 52 | + button-menu { | |
| 53 | 53 | linux,code = <KEY_PLAY>; |
| 54 | 54 | label = "play"; |
| 55 | 55 | press-threshold-microvolt = <624000>; |
| 56 | 56 | }; |
| 57 | 57 | |
| 58 | − vol-down-key { | |
| 58 | + button-down { | |
| 59 | 59 | linux,code = <KEY_VOLUMEDOWN>; |
| 60 | 60 | label = "volume down"; |
| 61 | 61 | press-threshold-microvolt = <300000>; |
| 62 | 62 | }; |
| 63 | 63 | |
| 64 | − vol-up-key { | |
| 64 | + button-up { | |
| 65 | 65 | linux,code = <KEY_VOLUMEUP>; |
| 66 | 66 | label = "volume up"; |
| 67 | 67 | press-threshold-microvolt = <18000>; |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | stdout-path = "serial2:1500000n8"; |
| 20 | 20 | }; |
| 21 | 21 | |
| 22 | − ir_rx { | |
| 22 | + ir-receiver { | |
| 23 | 23 | compatible = "gpio-ir-receiver"; |
| 24 | 24 | gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>; |
| 25 | 25 | pinctrl-names = "default"; |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | keyup-threshold-microvolt = <1800000>; |
| 26 | 26 | poll-interval = <100>; |
| 27 | 27 | |
| 28 | − recovery { | |
| 28 | + button-recovery { | |
| 29 | 29 | label = "recovery"; |
| 30 | 30 | linux,code = <KEY_VENDOR>; |
| 31 | 31 | press-threshold-microvolt = <17000>; |
| @@ -208,11 +208,10 @@ · 207 unmodified lines | ||
| 208 | 208 | vin-supply = <&vcc_sys>; |
| 209 | 209 | }; |
| 210 | 210 | |
| 211 | − hym8563: hym8563@51 { | |
| 211 | + hym8563: rtc@51 { | |
| 212 | 212 | compatible = "haoyu,hym8563"; |
| 213 | 213 | reg = <0x51>; |
| 214 | 214 | #clock-cells = <0>; |
| 215 | − clock-frequency = <32768>; | |
| 216 | 215 | clock-output-names = "xin32k"; |
| 217 | 216 | /* rtc_int is not connected */ |
| 218 | 217 | }; |
| @@ -192,11 +192,10 @@ · 191 unmodified lines | ||
| 192 | 192 | vin-supply = <&vcc_sys>; |
| 193 | 193 | }; |
| 194 | 194 | |
| 195 | − hym8563: hym8563@51 { | |
| 195 | + hym8563: rtc@51 { | |
| 196 | 196 | compatible = "haoyu,hym8563"; |
| 197 | 197 | reg = <0x51>; |
| 198 | 198 | #clock-cells = <0>; |
| 199 | − clock-frequency = <32768>; | |
| 200 | 199 | clock-output-names = "xin32k"; |
| 201 | 200 | /* rtc_int is not connected */ |
| 202 | 201 | }; |
| @@ -734,10 +734,6 @@ camera: &i2c7 { · 733 unmodified lines | ||
| 734 | 734 | }; |
| 735 | 735 | |
| 736 | 736 | /* PINCTRL OVERRIDES */ |
| 737 | −&ec_ap_int_l { | |
| 738 | − rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>; | |
| 739 | −}; | |
| 740 | − | |
| 741 | 737 | &ap_fw_wp { |
| 742 | 738 | rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; |
| 743 | 739 | }; |
| @@ -123,7 +123,7 @@ · 122 unmodified lines | ||
| 123 | 123 | keyup-threshold-microvolt = <1800000>; |
| 124 | 124 | poll-interval = <100>; |
| 125 | 125 | |
| 126 | − recovery { | |
| 126 | + button-recovery { | |
| 127 | 127 | label = "Recovery"; |
| 128 | 128 | linux,code = <KEY_VENDOR>; |
| 129 | 129 | press-threshold-microvolt = <18000>; |
| @@ -39,7 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | keyup-threshold-microvolt = <1800000>; |
| 40 | 40 | poll-interval = <100>; |
| 41 | 41 | |
| 42 | − recovery { | |
| 42 | + button-recovery { | |
| 43 | 43 | label = "Recovery"; |
| 44 | 44 | linux,code = <KEY_VENDOR>; |
| 45 | 45 | press-threshold-microvolt = <18000>; |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | keyup-threshold-microvolt = <1500000>; |
| 20 | 20 | poll-interval = <100>; |
| 21 | 21 | |
| 22 | − recovery { | |
| 22 | + button-recovery { | |
| 23 | 23 | label = "Recovery"; |
| 24 | 24 | linux,code = <KEY_VENDOR>; |
| 25 | 25 | press-threshold-microvolt = <18000>; |
| @@ -167,6 +167,7 @@ · 166 unmodified lines | ||
| 167 | 167 | }; |
| 168 | 168 | |
| 169 | 169 | &emmc_phy { |
| 170 | + rockchip,enable-strobe-pulldown; | |
| 170 | 171 | status = "okay"; |
| 171 | 172 | }; |
| 172 | 173 | |
| @@ -52,13 +52,13 @@ · 51 unmodified lines | ||
| 52 | 52 | press-threshold-microvolt = <300000>; |
| 53 | 53 | }; |
| 54 | 54 | |
| 55 | − back { | |
| 55 | + button-back { | |
| 56 | 56 | label = "Back"; |
| 57 | 57 | linux,code = <KEY_BACK>; |
| 58 | 58 | press-threshold-microvolt = <985000>; |
| 59 | 59 | }; |
| 60 | 60 | |
| 61 | − menu { | |
| 61 | + button-menu { | |
| 62 | 62 | label = "Menu"; |
| 63 | 63 | linux,code = <KEY_MENU>; |
| 64 | 64 | press-threshold-microvolt = <1314000>; |
| @@ -207,7 +207,7 @@ · 206 unmodified lines | ||
| 207 | 207 | cap-sd-highspeed; |
| 208 | 208 | cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; |
| 209 | 209 | disable-wp; |
| 210 | − max-frequency = <150000000>; | |
| 210 | + max-frequency = <40000000>; | |
| 211 | 211 | pinctrl-names = "default"; |
| 212 | 212 | pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; |
| 213 | 213 | vmmc-supply = <&vcc3v3_baseboard>; |
| @@ -98,13 +98,12 @@ · 97 unmodified lines | ||
| 98 | 98 | }; |
| 99 | 99 | |
| 100 | 100 | &i2c0 { |
| 101 | − hym8563: hym8563@51 { | |
| 101 | + hym8563: rtc@51 { | |
| 102 | 102 | compatible = "haoyu,hym8563"; |
| 103 | 103 | reg = <0x51>; |
| 104 | 104 | interrupt-parent = <&gpio0>; |
| 105 | 105 | interrupts = <RK_PA5 IRQ_TYPE_EDGE_FALLING>; |
| 106 | 106 | #clock-cells = <0>; |
| 107 | − clock-frequency = <32768>; | |
| 108 | 107 | clock-output-names = "xin32k"; |
| 109 | 108 | pinctrl-names = "default"; |
| 110 | 109 | pinctrl-0 = <&hym8563_int>; |
| @@ -41,7 +41,7 @@ · 40 unmodified lines | ||
| 41 | 41 | keyup-threshold-microvolt = <1500000>; |
| 42 | 42 | poll-interval = <100>; |
| 43 | 43 | |
| 44 | − recovery { | |
| 44 | + button-recovery { | |
| 45 | 45 | label = "Recovery"; |
| 46 | 46 | linux,code = <KEY_VENDOR>; |
| 47 | 47 | press-threshold-microvolt = <18000>; |
| @@ -509,7 +509,6 @@ · 508 unmodified lines | ||
| 509 | 509 | &i2s1 { |
| 510 | 510 | rockchip,playback-channels = <2>; |
| 511 | 511 | rockchip,capture-channels = <2>; |
| 512 | − status = "okay"; | |
| 513 | 512 | }; |
| 514 | 513 | |
| 515 | 514 | &i2s2 { |
| @@ -33,13 +33,13 @@ · 32 unmodified lines | ||
| 33 | 33 | press-threshold-microvolt = <300000>; |
| 34 | 34 | }; |
| 35 | 35 | |
| 36 | − back { | |
| 36 | + button-back { | |
| 37 | 37 | label = "Back"; |
| 38 | 38 | linux,code = <KEY_BACK>; |
| 39 | 39 | press-threshold-microvolt = <985000>; |
| 40 | 40 | }; |
| 41 | 41 | |
| 42 | − menu { | |
| 42 | + button-menu { | |
| 43 | 43 | label = "Menu"; |
| 44 | 44 | linux,code = <KEY_MENU>; |
| 45 | 45 | press-threshold-microvolt = <1314000>; |
| @@ -297,11 +297,10 @@ · 296 unmodified lines | ||
| 297 | 297 | clock-frequency = <400000>; |
| 298 | 298 | status = "okay"; |
| 299 | 299 | |
| 300 | − hym8563: hym8563@51 { | |
| 300 | + hym8563: rtc@51 { | |
| 301 | 301 | compatible = "haoyu,hym8563"; |
| 302 | 302 | reg = <0x51>; |
| 303 | 303 | #clock-cells = <0>; |
| 304 | − clock-frequency = <32768>; | |
| 305 | 304 | clock-output-names = "hym8563"; |
| 306 | 305 | pinctrl-names = "default"; |
| 307 | 306 | pinctrl-0 = <&hym8563_int>; |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | io-channel-names = "buttons"; |
| 24 | 24 | keyup-threshold-microvolt = <1750000>; |
| 25 | 25 | |
| 26 | − recovery { | |
| 26 | + button-recovery { | |
| 27 | 27 | label = "recovery"; |
| 28 | 28 | linux,code = <KEY_VENDOR>; |
| 29 | 29 | press-threshold-microvolt = <0>; |
| @@ -740,7 +740,7 @@ · 739 unmodified lines | ||
| 740 | 740 | |
| 741 | 741 | &uart1 { |
| 742 | 742 | pinctrl-names = "default"; |
| 743 | − pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn>; | |
| 743 | + pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn &uart1m0_rtsn>; | |
| 744 | 744 | status = "okay"; |
| 745 | 745 | uart-has-rtscts; |
| 746 | 746 | |
| @@ -748,13 +748,14 @@ · 1 unmodified line | ||
| 748 | 748 | compatible = "brcm,bcm43438-bt"; |
| 749 | 749 | clocks = <&rk817 1>; |
| 750 | 750 | clock-names = "lpo"; |
| 751 | − device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; | |
| 752 | − host-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; | |
| 751 | + host-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>; | |
| 752 | + device-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; | |
| 753 | 753 | shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; |
| 754 | 754 | pinctrl-names = "default"; |
| 755 | 755 | pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>; |
| 756 | 756 | vbat-supply = <&vcc_sys>; |
| 757 | 757 | vddio-supply = <&vcca1v8_pmu>; |
| 758 | + max-speed = <3000000>; | |
| 758 | 759 | }; |
| 759 | 760 | }; |
| 760 | 761 | |
| @@ -246,7 +246,7 @@ · 245 unmodified lines | ||
| 246 | 246 | compatible = "rockchip,rk809"; |
| 247 | 247 | reg = <0x20>; |
| 248 | 248 | interrupt-parent = <&gpio0>; |
| 249 | − interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>; | |
| 249 | + interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>; | |
| 250 | 250 | assigned-clocks = <&cru I2S1_MCLKOUT_TX>; |
| 251 | 251 | assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>; |
| 252 | 252 | clock-names = "mclk"; |
| @@ -142,7 +142,7 @@ · 141 unmodified lines | ||
| 142 | 142 | assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>; |
| 143 | 143 | assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>, <&cru SCLK_GMAC1>, <&gmac1_clkin>; |
| 144 | 144 | clock_in_out = "input"; |
| 145 | − phy-mode = "rgmii-id"; | |
| 145 | + phy-mode = "rgmii"; | |
| 146 | 146 | phy-supply = <&vcc_3v3>; |
| 147 | 147 | pinctrl-names = "default"; |
| 148 | 148 | pinctrl-0 = <&gmac1m0_miim |
| @@ -432,11 +432,7 @@ · 283 unmodified lines | ||
| 432 | 432 | |
| 433 | 433 | &i2c3 { |
| 434 | 434 | pinctrl-names = "default"; |
| 435 | − pinctrl-0 = <&i2c3m1_xfer>; | |
| 436 | − status = "okay"; | |
| 437 | −}; | |
| 438 | − | |
| 439 | −&i2c5 { | |
| 435 | + pinctrl-0 = <&i2c3m0_xfer>; | |
| 440 | 436 | status = "okay"; |
| 441 | 437 | }; |
| 442 | 438 | |
| @@ -500,7 +500,6 @@ · 499 unmodified lines | ||
| 500 | 500 | interrupt-parent = <&gpio0>; |
| 501 | 501 | interrupts = <RK_PD3 IRQ_TYPE_EDGE_FALLING>; |
| 502 | 502 | #clock-cells = <0>; |
| 503 | − clock-frequency = <32768>; | |
| 504 | 503 | clock-output-names = "rtcic_32kout"; |
| 505 | 504 | pinctrl-names = "default"; |
| 506 | 505 | pinctrl-0 = <&hym8563_int>; |
| @@ -509,7 +509,6 @@ · 508 unmodified lines | ||
| 509 | 509 | interrupt-parent = <&gpio0>; |
| 510 | 510 | interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>; |
| 511 | 511 | #clock-cells = <0>; |
| 512 | − clock-frequency = <32768>; | |
| 513 | 512 | clock-output-names = "rtcic_32kout"; |
| 514 | 513 | pinctrl-names = "default"; |
| 515 | 514 | pinctrl-0 = <&hym8563_int>; |
| @@ -41,7 +41,7 @@ · 40 unmodified lines | ||
| 41 | 41 | (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT) |
| 42 | 42 | |
| 43 | 43 | #define MIDR_CPU_MODEL(imp, partnum) \ |
| 44 | − (((imp) << MIDR_IMPLEMENTOR_SHIFT) | \ | |
| 44 | + ((_AT(u32, imp) << MIDR_IMPLEMENTOR_SHIFT) | \ | |
| 45 | 45 | (0xf << MIDR_ARCHITECTURE_SHIFT) | \ |
| 46 | 46 | ((partnum) << MIDR_PARTNUM_SHIFT)) |
| 47 | 47 | |
| @@ -863,12 +863,12 @@ static inline bool pte_user_accessible_page(pte_t pte) · 862 unmodified lines | ||
| 863 | 863 | |
| 864 | 864 | static inline bool pmd_user_accessible_page(pmd_t pmd) |
| 865 | 865 | { |
| 866 | − return pmd_present(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)); | |
| 866 | + return pmd_leaf(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd)); | |
| 867 | 867 | } |
| 868 | 868 | |
| 869 | 869 | static inline bool pud_user_accessible_page(pud_t pud) |
| 870 | 870 | { |
| 871 | − return pud_present(pud) && pud_user(pud); | |
| 871 | + return pud_leaf(pud) && pud_user(pud); | |
| 872 | 872 | } |
| 873 | 873 | #endif |
| 874 | 874 | |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #ifndef __ASM_SYSCALL_WRAPPER_H |
| 9 | 9 | #define __ASM_SYSCALL_WRAPPER_H |
| 10 | 10 | |
| 11 | −struct pt_regs; | |
| 11 | +#include <asm/ptrace.h> | |
| 12 | 12 | |
| 13 | 13 | #define SC_ARM64_REGS_TO_ARGS(x, ...) \ |
| 14 | 14 | __MAP(x,__SC_ARGS \ |
| @@ -428,6 +428,30 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = { · 427 unmodified lines | ||
| 428 | 428 | ARM64_FTR_END, |
| 429 | 429 | }; |
| 430 | 430 | |
| 431 | +static const struct arm64_ftr_bits ftr_mvfr0[] = { | |
| 432 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPROUND_SHIFT, 4, 0), | |
| 433 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPSHVEC_SHIFT, 4, 0), | |
| 434 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPSQRT_SHIFT, 4, 0), | |
| 435 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPDIVIDE_SHIFT, 4, 0), | |
| 436 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPTRAP_SHIFT, 4, 0), | |
| 437 | + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPDP_SHIFT, 4, 0), | |
| 438 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_FPSP_SHIFT, 4, 0), | |
| 439 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR0_SIMD_SHIFT, 4, 0), | |
| 440 | + ARM64_FTR_END, | |
| 441 | +}; | |
| 442 | + | |
| 443 | +static const struct arm64_ftr_bits ftr_mvfr1[] = { | |
| 444 | + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDFMAC_SHIFT, 4, 0), | |
| 445 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_FPHP_SHIFT, 4, 0), | |
| 446 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDHP_SHIFT, 4, 0), | |
| 447 | + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDSP_SHIFT, 4, 0), | |
| 448 | + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDINT_SHIFT, 4, 0), | |
| 449 | + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_SIMDLS_SHIFT, 4, 0), | |
| 450 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_FPDNAN_SHIFT, 4, 0), | |
| 451 | + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR1_FPFTZ_SHIFT, 4, 0), | |
| 452 | + ARM64_FTR_END, | |
| 453 | +}; | |
| 454 | + | |
| 431 | 455 | static const struct arm64_ftr_bits ftr_mvfr2[] = { |
| 432 | 456 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR2_FPMISC_SHIFT, 4, 0), |
| 433 | 457 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR2_SIMDMISC_SHIFT, 4, 0), |
| @@ -458,10 +482,10 @@ static const struct arm64_ftr_bits ftr_id_isar0[] = { · 24 unmodified lines | ||
| 458 | 482 | |
| 459 | 483 | static const struct arm64_ftr_bits ftr_id_isar5[] = { |
| 460 | 484 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_RDM_SHIFT, 4, 0), |
| 461 | − ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_CRC32_SHIFT, 4, 0), | |
| 462 | − ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA2_SHIFT, 4, 0), | |
| 463 | − ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA1_SHIFT, 4, 0), | |
| 464 | − ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_AES_SHIFT, 4, 0), | |
| 485 | + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_CRC32_SHIFT, 4, 0), | |
| 486 | + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA2_SHIFT, 4, 0), | |
| 487 | + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SHA1_SHIFT, 4, 0), | |
| 488 | + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_AES_SHIFT, 4, 0), | |
| 465 | 489 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_ISAR5_SEVL_SHIFT, 4, 0), |
| 466 | 490 | ARM64_FTR_END, |
| 467 | 491 | }; |
| @@ -574,7 +598,7 @@ static const struct arm64_ftr_bits ftr_smcr[] = { · 106 unmodified lines | ||
| 574 | 598 | * Common ftr bits for a 32bit register with all hidden, strict |
| 575 | 599 | * attributes, with 4bit feature fields and a default safe value of |
| 576 | 600 | * 0. Covers the following 32bit registers: |
| 577 | − * id_isar[1-4], id_mmfr[1-3], id_pfr1, mvfr[0-1] | |
| 601 | + * id_isar[1-3], id_mmfr[1-3] | |
| 578 | 602 | */ |
| 579 | 603 | static const struct arm64_ftr_bits ftr_generic_32bits[] = { |
| 580 | 604 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0), |
| @@ -645,8 +669,8 @@ static const struct __ftr_reg_entry { · 64 unmodified lines | ||
| 645 | 669 | ARM64_FTR_REG(SYS_ID_ISAR6_EL1, ftr_id_isar6), |
| 646 | 670 | |
| 647 | 671 | /* Op1 = 0, CRn = 0, CRm = 3 */ |
| 648 | − ARM64_FTR_REG(SYS_MVFR0_EL1, ftr_generic_32bits), | |
| 649 | − ARM64_FTR_REG(SYS_MVFR1_EL1, ftr_generic_32bits), | |
| 672 | + ARM64_FTR_REG(SYS_MVFR0_EL1, ftr_mvfr0), | |
| 673 | + ARM64_FTR_REG(SYS_MVFR1_EL1, ftr_mvfr1), | |
| 650 | 674 | ARM64_FTR_REG(SYS_MVFR2_EL1, ftr_mvfr2), |
| 651 | 675 | ARM64_FTR_REG(SYS_ID_PFR2_EL1, ftr_id_pfr2), |
| 652 | 676 | ARM64_FTR_REG(SYS_ID_DFR1_EL1, ftr_id_dfr1), |
| @@ -3339,7 +3363,7 @@ static void __maybe_unused cpu_enable_cnp(struct arm64_cpu_capabilities const *c · 2686 unmodified lines | ||
| 3339 | 3363 | |
| 3340 | 3364 | /* |
| 3341 | 3365 | * We emulate only the following system register space. |
| 3342 | − * Op0 = 0x3, CRn = 0x0, Op1 = 0x0, CRm = [0, 4 - 7] | |
| 3366 | + * Op0 = 0x3, CRn = 0x0, Op1 = 0x0, CRm = [0, 2 - 7] | |
| 3343 | 3367 | * See Table C5-6 System instruction encodings for System register accesses, |
| 3344 | 3368 | * ARMv8 ARM(ARM DDI 0487A.f) for more details. |
| 3345 | 3369 | */ |
| @@ -3349,7 +3373,7 @@ static inline bool __attribute_const__ is_emulated(u32 id) · 3 unmodified lines | ||
| 3349 | 3373 | sys_reg_CRn(id) == 0x0 && |
| 3350 | 3374 | sys_reg_Op1(id) == 0x0 && |
| 3351 | 3375 | (sys_reg_CRm(id) == 0 || |
| 3352 | − ((sys_reg_CRm(id) >= 4) && (sys_reg_CRm(id) <= 7)))); | |
| 3376 | + ((sys_reg_CRm(id) >= 2) && (sys_reg_CRm(id) <= 7)))); | |
| 3353 | 3377 | } |
| 3354 | 3378 | |
| 3355 | 3379 | /* |
| @@ -12,6 +12,14 @@ · 11 unmodified lines | ||
| 12 | 12 | |
| 13 | 13 | #include <asm/efi.h> |
| 14 | 14 | |
| 15 | +static bool region_is_misaligned(const efi_memory_desc_t *md) | |
| 16 | +{ | |
| 17 | + if (PAGE_SIZE == EFI_PAGE_SIZE) | |
| 18 | + return false; | |
| 19 | + return !PAGE_ALIGNED(md->phys_addr) || | |
| 20 | + !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT); | |
| 21 | +} | |
| 22 | + | |
| 15 | 23 | /* |
| 16 | 24 | * Only regions of type EFI_RUNTIME_SERVICES_CODE need to be |
| 17 | 25 | * executable, everything else can be mapped with the XN bits |
| @@ -25,14 +33,22 @@ static __init pteval_t create_mapping_protection(efi_memory_desc_t *md) · 7 unmodified lines | ||
| 25 | 33 | if (type == EFI_MEMORY_MAPPED_IO) |
| 26 | 34 | return PROT_DEVICE_nGnRE; |
| 27 | 35 | |
| 28 | − if (WARN_ONCE(!PAGE_ALIGNED(md->phys_addr), | |
| 29 | − "UEFI Runtime regions are not aligned to 64 KB -- buggy firmware?")) | |
| 36 | + if (region_is_misaligned(md)) { | |
| 37 | + static bool __initdata code_is_misaligned; | |
| 38 | + | |
| 30 | 39 | /* |
| 31 | − * If the region is not aligned to the page size of the OS, we | |
| 32 | − * can not use strict permissions, since that would also affect | |
| 33 | − * the mapping attributes of the adjacent regions. | |
| 40 | + * Regions that are not aligned to the OS page size cannot be | |
| 41 | + * mapped with strict permissions, as those might interfere | |
| 42 | + * with the permissions that are needed by the adjacent | |
| 43 | + * region's mapping. However, if we haven't encountered any | |
| 44 | + * misaligned runtime code regions so far, we can safely use | |
| 45 | + * non-executable permissions for non-code regions. | |
| 34 | 46 | */ |
| 35 | − return pgprot_val(PAGE_KERNEL_EXEC); | |
| 47 | + code_is_misaligned |= (type == EFI_RUNTIME_SERVICES_CODE); | |
| 48 | + | |
| 49 | + return code_is_misaligned ? pgprot_val(PAGE_KERNEL_EXEC) | |
| 50 | + : pgprot_val(PAGE_KERNEL); | |
| 51 | + } | |
| 36 | 52 | |
| 37 | 53 | /* R-- */ |
| 38 | 54 | if ((attr & (EFI_MEMORY_XP | EFI_MEMORY_RO)) == |
| @@ -63,19 +79,16 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) · 24 unmodified lines | ||
| 63 | 79 | bool page_mappings_only = (md->type == EFI_RUNTIME_SERVICES_CODE || |
| 64 | 80 | md->type == EFI_RUNTIME_SERVICES_DATA); |
| 65 | 81 | |
| 66 | − if (!PAGE_ALIGNED(md->phys_addr) || | |
| 67 | − !PAGE_ALIGNED(md->num_pages << EFI_PAGE_SHIFT)) { | |
| 68 | − /* | |
| 69 | − * If the end address of this region is not aligned to page | |
| 70 | − * size, the mapping is rounded up, and may end up sharing a | |
| 71 | − * page frame with the next UEFI memory region. If we create | |
| 72 | − * a block entry now, we may need to split it again when mapping | |
| 73 | − * the next region, and support for that is going to be removed | |
| 74 | − * from the MMU routines. So avoid block mappings altogether in | |
| 75 | − * that case. | |
| 76 | − */ | |
| 82 | + /* | |
| 83 | + * If this region is not aligned to the page size used by the OS, the | |
| 84 | + * mapping will be rounded outwards, and may end up sharing a page | |
| 85 | + * frame with an adjacent runtime memory region. Given that the page | |
| 86 | + * table descriptor covering the shared page will be rewritten when the | |
| 87 | + * adjacent region gets mapped, we must avoid block mappings here so we | |
| 88 | + * don't have to worry about splitting them when that happens. | |
| 89 | + */ | |
| 90 | + if (region_is_misaligned(md)) | |
| 77 | 91 | page_mappings_only = true; |
| 78 | − } | |
| 79 | 92 | |
| 80 | 93 | create_pgd_mapping(mm, md->phys_addr, md->virt_addr, |
| 81 | 94 | md->num_pages << EFI_PAGE_SHIFT, |
| @@ -102,6 +115,9 @@ int __init efi_set_mapping_permissions(struct mm_struct *mm, · 20 unmodified lines | ||
| 102 | 115 | BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE && |
| 103 | 116 | md->type != EFI_RUNTIME_SERVICES_DATA); |
| 104 | 117 | |
| 118 | + if (region_is_misaligned(md)) | |
| 119 | + return 0; | |
| 120 | + | |
| 105 | 121 | /* |
| 106 | 122 | * Calling apply_to_page_range() is only safe on regions that are |
| 107 | 123 | * guaranteed to be mapped down to pages. Since we are only called |
| @@ -329,7 +329,8 @@ static void cortex_a76_erratum_1463225_svc_handler(void) · 328 unmodified lines | ||
| 329 | 329 | __this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 0); |
| 330 | 330 | } |
| 331 | 331 | |
| 332 | −static bool cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs) | |
| 332 | +static __always_inline bool | |
| 333 | +cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs) | |
| 333 | 334 | { |
| 334 | 335 | if (!__this_cpu_read(__in_cortex_a76_erratum_1463225_wa)) |
| 335 | 336 | return false; |
| @@ -299,11 +299,11 @@ SYM_TYPED_FUNC_START(ftrace_stub) · 298 unmodified lines | ||
| 299 | 299 | ret |
| 300 | 300 | SYM_FUNC_END(ftrace_stub) |
| 301 | 301 | |
| 302 | +#ifdef CONFIG_FUNCTION_GRAPH_TRACER | |
| 302 | 303 | SYM_TYPED_FUNC_START(ftrace_stub_graph) |
| 303 | 304 | ret |
| 304 | 305 | SYM_FUNC_END(ftrace_stub_graph) |
| 305 | 306 | |
| 306 | −#ifdef CONFIG_FUNCTION_GRAPH_TRACER | |
| 307 | 307 | /* |
| 308 | 308 | * void return_to_handler(void) |
| 309 | 309 | * |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include <hyp/adjust_pc.h> |
| 14 | 14 | #include <linux/kvm_host.h> |
| 15 | 15 | #include <asm/kvm_emulate.h> |
| 16 | +#include <asm/kvm_mmu.h> | |
| 16 | 17 | |
| 17 | 18 | #if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__) |
| 18 | 19 | #error Hypervisor code only! |
| @@ -115,7 +116,7 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode, · 96 unmodified lines | ||
| 115 | 116 | new |= (old & PSR_C_BIT); |
| 116 | 117 | new |= (old & PSR_V_BIT); |
| 117 | 118 | |
| 118 | − if (kvm_has_mte(vcpu->kvm)) | |
| 119 | + if (kvm_has_mte(kern_hyp_va(vcpu->kvm))) | |
| 119 | 120 | new |= PSR_TCO_BIT; |
| 120 | 121 | |
| 121 | 122 | new |= (old & PSR_DIT_BIT); |
| @@ -87,6 +87,17 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu) · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2); |
| 89 | 89 | write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); |
| 90 | + | |
| 91 | + if (cpus_have_final_cap(ARM64_SME)) { | |
| 92 | + sysreg_clear_set_s(SYS_HFGRTR_EL2, | |
| 93 | + HFGxTR_EL2_nSMPRI_EL1_MASK | | |
| 94 | + HFGxTR_EL2_nTPIDR2_EL0_MASK, | |
| 95 | + 0); | |
| 96 | + sysreg_clear_set_s(SYS_HFGWTR_EL2, | |
| 97 | + HFGxTR_EL2_nSMPRI_EL1_MASK | | |
| 98 | + HFGxTR_EL2_nTPIDR2_EL0_MASK, | |
| 99 | + 0); | |
| 100 | + } | |
| 90 | 101 | } |
| 91 | 102 | |
| 92 | 103 | static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) |
| @@ -96,6 +107,15 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) · 3 unmodified lines | ||
| 96 | 107 | write_sysreg(0, hstr_el2); |
| 97 | 108 | if (kvm_arm_support_pmu_v3()) |
| 98 | 109 | write_sysreg(0, pmuserenr_el0); |
| 110 | + | |
| 111 | + if (cpus_have_final_cap(ARM64_SME)) { | |
| 112 | + sysreg_clear_set_s(SYS_HFGRTR_EL2, 0, | |
| 113 | + HFGxTR_EL2_nSMPRI_EL1_MASK | | |
| 114 | + HFGxTR_EL2_nTPIDR2_EL0_MASK); | |
| 115 | + sysreg_clear_set_s(SYS_HFGWTR_EL2, 0, | |
| 116 | + HFGxTR_EL2_nSMPRI_EL1_MASK | | |
| 117 | + HFGxTR_EL2_nTPIDR2_EL0_MASK); | |
| 118 | + } | |
| 99 | 119 | } |
| 100 | 120 | |
| 101 | 121 | static inline void ___activate_traps(struct kvm_vcpu *vcpu) |
| @@ -516,7 +516,7 @@ static enum pkvm_page_state hyp_get_page_state(kvm_pte_t pte) · 515 unmodified lines | ||
| 516 | 516 | if (!kvm_pte_valid(pte)) |
| 517 | 517 | return PKVM_NOPAGE; |
| 518 | 518 | |
| 519 | − return pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte)); | |
| 519 | + return pkvm_getstate(kvm_pgtable_hyp_pte_prot(pte)); | |
| 520 | 520 | } |
| 521 | 521 | |
| 522 | 522 | static int __hyp_check_page_state_range(u64 addr, u64 size, |
| @@ -55,18 +55,6 @@ static void __activate_traps(struct kvm_vcpu *vcpu) · 54 unmodified lines | ||
| 55 | 55 | write_sysreg(val, cptr_el2); |
| 56 | 56 | write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2); |
| 57 | 57 | |
| 58 | − if (cpus_have_final_cap(ARM64_SME)) { | |
| 59 | − val = read_sysreg_s(SYS_HFGRTR_EL2); | |
| 60 | − val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK | | |
| 61 | − HFGxTR_EL2_nSMPRI_EL1_MASK); | |
| 62 | − write_sysreg_s(val, SYS_HFGRTR_EL2); | |
| 63 | − | |
| 64 | − val = read_sysreg_s(SYS_HFGWTR_EL2); | |
| 65 | − val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK | | |
| 66 | − HFGxTR_EL2_nSMPRI_EL1_MASK); | |
| 67 | − write_sysreg_s(val, SYS_HFGWTR_EL2); | |
| 68 | − } | |
| 69 | − | |
| 70 | 58 | if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) { |
| 71 | 59 | struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt; |
| 72 | 60 | |
| @@ -110,20 +98,6 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) · 37 unmodified lines | ||
| 110 | 98 | |
| 111 | 99 | write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2); |
| 112 | 100 | |
| 113 | − if (cpus_have_final_cap(ARM64_SME)) { | |
| 114 | − u64 val; | |
| 115 | − | |
| 116 | − val = read_sysreg_s(SYS_HFGRTR_EL2); | |
| 117 | − val |= HFGxTR_EL2_nTPIDR2_EL0_MASK | | |
| 118 | − HFGxTR_EL2_nSMPRI_EL1_MASK; | |
| 119 | − write_sysreg_s(val, SYS_HFGRTR_EL2); | |
| 120 | − | |
| 121 | − val = read_sysreg_s(SYS_HFGWTR_EL2); | |
| 122 | − val |= HFGxTR_EL2_nTPIDR2_EL0_MASK | | |
| 123 | − HFGxTR_EL2_nSMPRI_EL1_MASK; | |
| 124 | − write_sysreg_s(val, SYS_HFGWTR_EL2); | |
| 125 | − } | |
| 126 | − | |
| 127 | 101 | cptr = CPTR_EL2_DEFAULT; |
| 128 | 102 | if (vcpu_has_sve(vcpu) && (vcpu->arch.fp_state == FP_STATE_GUEST_OWNED)) |
| 129 | 103 | cptr |= CPTR_EL2_TZ; |
| @@ -63,10 +63,6 @@ static void __activate_traps(struct kvm_vcpu *vcpu) · 62 unmodified lines | ||
| 63 | 63 | __activate_traps_fpsimd32(vcpu); |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | − if (cpus_have_final_cap(ARM64_SME)) | |
| 67 | − write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2, | |
| 68 | − sctlr_el2); | |
| 69 | − | |
| 70 | 66 | write_sysreg(val, cpacr_el1); |
| 71 | 67 | |
| 72 | 68 | write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1); |
| @@ -88,10 +84,6 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) · 15 unmodified lines | ||
| 88 | 84 | */ |
| 89 | 85 | asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT)); |
| 90 | 86 | |
| 91 | − if (cpus_have_final_cap(ARM64_SME)) | |
| 92 | − write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2, | |
| 93 | − sctlr_el2); | |
| 94 | − | |
| 95 | 87 | write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1); |
| 96 | 88 | |
| 97 | 89 | if (!arm64_kernel_unmapped_at_el0()) |
| @@ -26,7 +26,7 @@ bool can_set_direct_map(void) · 25 unmodified lines | ||
| 26 | 26 | * mapped at page granularity, so that it is possible to |
| 27 | 27 | * protect/unprotect single pages. |
| 28 | 28 | */ |
| 29 | − return rodata_full || debug_pagealloc_enabled() || | |
| 29 | + return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() || | |
| 30 | 30 | IS_ENABLED(CONFIG_KFENCE); |
| 31 | 31 | } |
| 32 | 32 | |
| @@ -102,7 +102,8 @@ static int change_memory_common(unsigned long addr, int numpages, · 69 unmodified lines | ||
| 102 | 102 | * If we are manipulating read-only permissions, apply the same |
| 103 | 103 | * change to the linear mapping of the pages that back this VM area. |
| 104 | 104 | */ |
| 105 | − if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY || | |
| 105 | + if (rodata_enabled && | |
| 106 | + rodata_full && (pgprot_val(set_mask) == PTE_RDONLY || | |
| 106 | 107 | pgprot_val(clear_mask) == PTE_RDONLY)) { |
| 107 | 108 | for (i = 0; i < area->nr_pages; i++) { |
| 108 | 109 | __change_memory_common((u64)page_address(area->pages[i]), |
| @@ -97,7 +97,7 @@ KBUILD_LDFLAGS += -m $(ld-emul) · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | ifdef CONFIG_LOONGARCH |
| 99 | 99 | CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ |
| 100 | − egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ | |
| 100 | + grep -E -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ | |
| 101 | 101 | sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') |
| 102 | 102 | endif |
| 103 | 103 | |
| @@ -117,7 +117,7 @@ extern struct fwnode_handle *liointc_handle; · 116 unmodified lines | ||
| 117 | 117 | extern struct fwnode_handle *pch_lpc_handle; |
| 118 | 118 | extern struct fwnode_handle *pch_pic_handle[MAX_IO_PICS]; |
| 119 | 119 | |
| 120 | −extern irqreturn_t loongson3_ipi_interrupt(int irq, void *dev); | |
| 120 | +extern irqreturn_t loongson_ipi_interrupt(int irq, void *dev); | |
| 121 | 121 | |
| 122 | 122 | #include <asm-generic/irq.h> |
| 123 | 123 | |
| @@ -349,13 +349,17 @@ static inline pte_t pte_mkclean(pte_t pte) · 348 unmodified lines | ||
| 349 | 349 | |
| 350 | 350 | static inline pte_t pte_mkdirty(pte_t pte) |
| 351 | 351 | { |
| 352 | − pte_val(pte) |= (_PAGE_DIRTY | _PAGE_MODIFIED); | |
| 352 | + pte_val(pte) |= _PAGE_MODIFIED; | |
| 353 | + if (pte_val(pte) & _PAGE_WRITE) | |
| 354 | + pte_val(pte) |= _PAGE_DIRTY; | |
| 353 | 355 | return pte; |
| 354 | 356 | } |
| 355 | 357 | |
| 356 | 358 | static inline pte_t pte_mkwrite(pte_t pte) |
| 357 | 359 | { |
| 358 | − pte_val(pte) |= (_PAGE_WRITE | _PAGE_DIRTY); | |
| 360 | + pte_val(pte) |= _PAGE_WRITE; | |
| 361 | + if (pte_val(pte) & _PAGE_MODIFIED) | |
| 362 | + pte_val(pte) |= _PAGE_DIRTY; | |
| 359 | 363 | return pte; |
| 360 | 364 | } |
| 361 | 365 | |
| @@ -455,7 +459,9 @@ static inline int pmd_write(pmd_t pmd) · 93 unmodified lines | ||
| 455 | 459 | |
| 456 | 460 | static inline pmd_t pmd_mkwrite(pmd_t pmd) |
| 457 | 461 | { |
| 458 | − pmd_val(pmd) |= (_PAGE_WRITE | _PAGE_DIRTY); | |
| 462 | + pmd_val(pmd) |= _PAGE_WRITE; | |
| 463 | + if (pmd_val(pmd) & _PAGE_MODIFIED) | |
| 464 | + pmd_val(pmd) |= _PAGE_DIRTY; | |
| 459 | 465 | return pmd; |
| 460 | 466 | } |
| 461 | 467 | |
| @@ -478,10 +484,13 @@ static inline pmd_t pmd_mkclean(pmd_t pmd) · 16 unmodified lines | ||
| 478 | 484 | |
| 479 | 485 | static inline pmd_t pmd_mkdirty(pmd_t pmd) |
| 480 | 486 | { |
| 481 | − pmd_val(pmd) |= (_PAGE_DIRTY | _PAGE_MODIFIED); | |
| 487 | + pmd_val(pmd) |= _PAGE_MODIFIED; | |
| 488 | + if (pmd_val(pmd) & _PAGE_WRITE) | |
| 489 | + pmd_val(pmd) |= _PAGE_DIRTY; | |
| 482 | 490 | return pmd; |
| 483 | 491 | } |
| 484 | 492 | |
| 493 | +#define pmd_young pmd_young | |
| 485 | 494 | static inline int pmd_young(pmd_t pmd) |
| 486 | 495 | { |
| 487 | 496 | return !!(pmd_val(pmd) & _PAGE_ACCESSED); |
| @@ -19,21 +19,21 @@ extern cpumask_t cpu_sibling_map[]; · 18 unmodified lines | ||
| 19 | 19 | extern cpumask_t cpu_core_map[]; |
| 20 | 20 | extern cpumask_t cpu_foreign_map[]; |
| 21 | 21 | |
| 22 | −void loongson3_smp_setup(void); | |
| 23 | −void loongson3_prepare_cpus(unsigned int max_cpus); | |
| 24 | −void loongson3_boot_secondary(int cpu, struct task_struct *idle); | |
| 25 | −void loongson3_init_secondary(void); | |
| 26 | −void loongson3_smp_finish(void); | |
| 27 | −void loongson3_send_ipi_single(int cpu, unsigned int action); | |
| 28 | −void loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action); | |
| 22 | +void loongson_smp_setup(void); | |
| 23 | +void loongson_prepare_cpus(unsigned int max_cpus); | |
| 24 | +void loongson_boot_secondary(int cpu, struct task_struct *idle); | |
| 25 | +void loongson_init_secondary(void); | |
| 26 | +void loongson_smp_finish(void); | |
| 27 | +void loongson_send_ipi_single(int cpu, unsigned int action); | |
| 28 | +void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int action); | |
| 29 | 29 | #ifdef CONFIG_HOTPLUG_CPU |
| 30 | −int loongson3_cpu_disable(void); | |
| 31 | −void loongson3_cpu_die(unsigned int cpu); | |
| 30 | +int loongson_cpu_disable(void); | |
| 31 | +void loongson_cpu_die(unsigned int cpu); | |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | 34 | static inline void plat_smp_setup(void) |
| 35 | 35 | { |
| 36 | − loongson3_smp_setup(); | |
| 36 | + loongson_smp_setup(); | |
| 37 | 37 | } |
| 38 | 38 | |
| 39 | 39 | static inline int raw_smp_processor_id(void) |
| @@ -85,28 +85,28 @@ extern void show_ipi_list(struct seq_file *p, int prec); · 45 unmodified lines | ||
| 85 | 85 | */ |
| 86 | 86 | static inline void smp_send_reschedule(int cpu) |
| 87 | 87 | { |
| 88 | − loongson3_send_ipi_single(cpu, SMP_RESCHEDULE); | |
| 88 | + loongson_send_ipi_single(cpu, SMP_RESCHEDULE); | |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | static inline void arch_send_call_function_single_ipi(int cpu) |
| 92 | 92 | { |
| 93 | − loongson3_send_ipi_single(cpu, SMP_CALL_FUNCTION); | |
| 93 | + loongson_send_ipi_single(cpu, SMP_CALL_FUNCTION); | |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | static inline void arch_send_call_function_ipi_mask(const struct cpumask *mask) |
| 97 | 97 | { |
| 98 | − loongson3_send_ipi_mask(mask, SMP_CALL_FUNCTION); | |
| 98 | + loongson_send_ipi_mask(mask, SMP_CALL_FUNCTION); | |
| 99 | 99 | } |
| 100 | 100 | |
| 101 | 101 | #ifdef CONFIG_HOTPLUG_CPU |
| 102 | 102 | static inline int __cpu_disable(void) |
| 103 | 103 | { |
| 104 | − return loongson3_cpu_disable(); | |
| 104 | + return loongson_cpu_disable(); | |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | static inline void __cpu_die(unsigned int cpu) |
| 108 | 108 | { |
| 109 | − loongson3_cpu_die(cpu); | |
| 109 | + loongson_cpu_die(cpu); | |
| 110 | 110 | } |
| 111 | 111 | |
| 112 | 112 | extern void play_dead(void); |
| @@ -56,23 +56,6 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size) · 55 unmodified lines | ||
| 56 | 56 | return ioremap_cache(phys, size); |
| 57 | 57 | } |
| 58 | 58 | |
| 59 | −void __init acpi_boot_table_init(void) | |
| 60 | −{ | |
| 61 | − /* | |
| 62 | − * If acpi_disabled, bail out | |
| 63 | − */ | |
| 64 | − if (acpi_disabled) | |
| 65 | − return; | |
| 66 | − | |
| 67 | − /* | |
| 68 | − * Initialize the ACPI boot-time table parser. | |
| 69 | − */ | |
| 70 | − if (acpi_table_init()) { | |
| 71 | − disable_acpi(); | |
| 72 | − return; | |
| 73 | − } | |
| 74 | −} | |
| 75 | − | |
| 76 | 59 | #ifdef CONFIG_SMP |
| 77 | 60 | static int set_processor_mask(u32 id, u32 flags) |
| 78 | 61 | { |
| @@ -156,13 +139,21 @@ static void __init acpi_process_madt(void) · 77 unmodified lines | ||
| 156 | 139 | loongson_sysconf.nr_cpus = num_processors; |
| 157 | 140 | } |
| 158 | 141 | |
| 159 | −int __init acpi_boot_init(void) | |
| 142 | +void __init acpi_boot_table_init(void) | |
| 160 | 143 | { |
| 161 | 144 | /* |
| 162 | 145 | * If acpi_disabled, bail out |
| 163 | 146 | */ |
| 164 | 147 | if (acpi_disabled) |
| 165 | − return -1; | |
| 148 | + return; | |
| 149 | + | |
| 150 | + /* | |
| 151 | + * Initialize the ACPI boot-time table parser. | |
| 152 | + */ | |
| 153 | + if (acpi_table_init()) { | |
| 154 | + disable_acpi(); | |
| 155 | + return; | |
| 156 | + } | |
| 166 | 157 | |
| 167 | 158 | loongson_sysconf.boot_cpu_id = read_csr_cpuid(); |
| 168 | 159 | |
| @@ -173,8 +164,6 @@ int __init acpi_boot_init(void) · 4 unmodified lines | ||
| 173 | 164 | |
| 174 | 165 | /* Do not enable ACPI SPCR console by default */ |
| 175 | 166 | acpi_parse_spcr(earlycon_acpi_spcr_enable, false); |
| 176 | − | |
| 177 | − return 0; | |
| 178 | 167 | } |
| 179 | 168 | |
| 180 | 169 | #ifdef CONFIG_ACPI_NUMA |
| @@ -117,7 +117,7 @@ void __init init_IRQ(void) · 116 unmodified lines | ||
| 117 | 117 | if (ipi_irq < 0) |
| 118 | 118 | panic("IPI IRQ mapping failed\n"); |
| 119 | 119 | irq_set_percpu_devid(ipi_irq); |
| 120 | − r = request_percpu_irq(ipi_irq, loongson3_ipi_interrupt, "IPI", &ipi_dummy_dev); | |
| 120 | + r = request_percpu_irq(ipi_irq, loongson_ipi_interrupt, "IPI", &ipi_dummy_dev); | |
| 121 | 121 | if (r < 0) |
| 122 | 122 | panic("IPI IRQ request failed\n"); |
| 123 | 123 | #endif |
| @@ -152,7 +152,7 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) · 151 unmodified lines | ||
| 152 | 152 | childregs->csr_crmd = p->thread.csr_crmd; |
| 153 | 153 | childregs->csr_prmd = p->thread.csr_prmd; |
| 154 | 154 | childregs->csr_ecfg = p->thread.csr_ecfg; |
| 155 | − return 0; | |
| 155 | + goto out; | |
| 156 | 156 | } |
| 157 | 157 | |
| 158 | 158 | /* user thread */ |
| @@ -171,14 +171,15 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) · 12 unmodified lines | ||
| 171 | 171 | */ |
| 172 | 172 | childregs->csr_euen = 0; |
| 173 | 173 | |
| 174 | + if (clone_flags & CLONE_SETTLS) | |
| 175 | + childregs->regs[2] = tls; | |
| 176 | + | |
| 177 | +out: | |
| 174 | 178 | clear_tsk_thread_flag(p, TIF_USEDFPU); |
| 175 | 179 | clear_tsk_thread_flag(p, TIF_USEDSIMD); |
| 176 | 180 | clear_tsk_thread_flag(p, TIF_LSX_CTX_LIVE); |
| 177 | 181 | clear_tsk_thread_flag(p, TIF_LASX_CTX_LIVE); |
| 178 | 182 | |
| 179 | − if (clone_flags & CLONE_SETTLS) | |
| 180 | − childregs->regs[2] = tls; | |
| 181 | − | |
| 182 | 183 | return 0; |
| 183 | 184 | } |
| 184 | 185 | |
| @@ -257,7 +257,6 @@ void __init platform_init(void) · 256 unmodified lines | ||
| 257 | 257 | #ifdef CONFIG_ACPI |
| 258 | 258 | acpi_gbl_use_default_register_widths = false; |
| 259 | 259 | acpi_boot_table_init(); |
| 260 | − acpi_boot_init(); | |
| 261 | 260 | #endif |
| 262 | 261 | |
| 263 | 262 | #ifdef CONFIG_NUMA |
| @@ -136,12 +136,12 @@ static void ipi_write_action(int cpu, u32 action) · 135 unmodified lines | ||
| 136 | 136 | } |
| 137 | 137 | } |
| 138 | 138 | |
| 139 | −void loongson3_send_ipi_single(int cpu, unsigned int action) | |
| 139 | +void loongson_send_ipi_single(int cpu, unsigned int action) | |
| 140 | 140 | { |
| 141 | 141 | ipi_write_action(cpu_logical_map(cpu), (u32)action); |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | −void loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |
| 144 | +void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |
| 145 | 145 | { |
| 146 | 146 | unsigned int i; |
| 147 | 147 | |
| @@ -149,7 +149,7 @@ void loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action) · 1 unmodified line | ||
| 149 | 149 | ipi_write_action(cpu_logical_map(i), (u32)action); |
| 150 | 150 | } |
| 151 | 151 | |
| 152 | −irqreturn_t loongson3_ipi_interrupt(int irq, void *dev) | |
| 152 | +irqreturn_t loongson_ipi_interrupt(int irq, void *dev) | |
| 153 | 153 | { |
| 154 | 154 | unsigned int action; |
| 155 | 155 | unsigned int cpu = smp_processor_id(); |
| @@ -169,7 +169,7 @@ irqreturn_t loongson3_ipi_interrupt(int irq, void *dev) · 13 unmodified lines | ||
| 169 | 169 | return IRQ_HANDLED; |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | −void __init loongson3_smp_setup(void) | |
| 172 | +void __init loongson_smp_setup(void) | |
| 173 | 173 | { |
| 174 | 174 | cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package; |
| 175 | 175 | cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package; |
| @@ -178,7 +178,7 @@ void __init loongson3_smp_setup(void) · 2 unmodified lines | ||
| 178 | 178 | pr_info("Detected %i available CPU(s)\n", loongson_sysconf.nr_cpus); |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | −void __init loongson3_prepare_cpus(unsigned int max_cpus) | |
| 181 | +void __init loongson_prepare_cpus(unsigned int max_cpus) | |
| 182 | 182 | { |
| 183 | 183 | int i = 0; |
| 184 | 184 | |
| @@ -193,7 +193,7 @@ void __init loongson3_prepare_cpus(unsigned int max_cpus) · 8 unmodified lines | ||
| 193 | 193 | /* |
| 194 | 194 | * Setup the PC, SP, and TP of a secondary processor and start it running! |
| 195 | 195 | */ |
| 196 | −void loongson3_boot_secondary(int cpu, struct task_struct *idle) | |
| 196 | +void loongson_boot_secondary(int cpu, struct task_struct *idle) | |
| 197 | 197 | { |
| 198 | 198 | unsigned long entry; |
| 199 | 199 | |
| @@ -205,13 +205,13 @@ void loongson3_boot_secondary(int cpu, struct task_struct *idle) · 5 unmodified lines | ||
| 205 | 205 | |
| 206 | 206 | csr_mail_send(entry, cpu_logical_map(cpu), 0); |
| 207 | 207 | |
| 208 | − loongson3_send_ipi_single(cpu, SMP_BOOT_CPU); | |
| 208 | + loongson_send_ipi_single(cpu, SMP_BOOT_CPU); | |
| 209 | 209 | } |
| 210 | 210 | |
| 211 | 211 | /* |
| 212 | 212 | * SMP init and finish on secondary CPUs |
| 213 | 213 | */ |
| 214 | −void loongson3_init_secondary(void) | |
| 214 | +void loongson_init_secondary(void) | |
| 215 | 215 | { |
| 216 | 216 | unsigned int cpu = smp_processor_id(); |
| 217 | 217 | unsigned int imask = ECFGF_IP0 | ECFGF_IP1 | ECFGF_IP2 | |
| @@ -231,7 +231,7 @@ void loongson3_init_secondary(void) · 13 unmodified lines | ||
| 231 | 231 | cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; |
| 232 | 232 | } |
| 233 | 233 | |
| 234 | −void loongson3_smp_finish(void) | |
| 234 | +void loongson_smp_finish(void) | |
| 235 | 235 | { |
| 236 | 236 | local_irq_enable(); |
| 237 | 237 | iocsr_write64(0, LOONGARCH_IOCSR_MBUF0); |
| @@ -240,7 +240,7 @@ void loongson3_smp_finish(void) · 2 unmodified lines | ||
| 240 | 240 | |
| 241 | 241 | #ifdef CONFIG_HOTPLUG_CPU |
| 242 | 242 | |
| 243 | −int loongson3_cpu_disable(void) | |
| 243 | +int loongson_cpu_disable(void) | |
| 244 | 244 | { |
| 245 | 245 | unsigned long flags; |
| 246 | 246 | unsigned int cpu = smp_processor_id(); |
| @@ -262,7 +262,7 @@ int loongson3_cpu_disable(void) · 15 unmodified lines | ||
| 262 | 262 | return 0; |
| 263 | 263 | } |
| 264 | 264 | |
| 265 | −void loongson3_cpu_die(unsigned int cpu) | |
| 265 | +void loongson_cpu_die(unsigned int cpu) | |
| 266 | 266 | { |
| 267 | 267 | while (per_cpu(cpu_state, cpu) != CPU_DEAD) |
| 268 | 268 | cpu_relax(); |
| @@ -300,19 +300,19 @@ void play_dead(void) · 31 unmodified lines | ||
| 300 | 300 | */ |
| 301 | 301 | #ifdef CONFIG_PM |
| 302 | 302 | |
| 303 | −static int loongson3_ipi_suspend(void) | |
| 303 | +static int loongson_ipi_suspend(void) | |
| 304 | 304 | { |
| 305 | 305 | return 0; |
| 306 | 306 | } |
| 307 | 307 | |
| 308 | −static void loongson3_ipi_resume(void) | |
| 308 | +static void loongson_ipi_resume(void) | |
| 309 | 309 | { |
| 310 | 310 | iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN); |
| 311 | 311 | } |
| 312 | 312 | |
| 313 | −static struct syscore_ops loongson3_ipi_syscore_ops = { | |
| 314 | − .resume = loongson3_ipi_resume, | |
| 315 | − .suspend = loongson3_ipi_suspend, | |
| 313 | +static struct syscore_ops loongson_ipi_syscore_ops = { | |
| 314 | + .resume = loongson_ipi_resume, | |
| 315 | + .suspend = loongson_ipi_suspend, | |
| 316 | 316 | }; |
| 317 | 317 | |
| 318 | 318 | /* |
| @@ -321,7 +321,7 @@ static struct syscore_ops loongson3_ipi_syscore_ops = { · 2 unmodified lines | ||
| 321 | 321 | */ |
| 322 | 322 | static int __init ipi_pm_init(void) |
| 323 | 323 | { |
| 324 | − register_syscore_ops(&loongson3_ipi_syscore_ops); | |
| 324 | + register_syscore_ops(&loongson_ipi_syscore_ops); | |
| 325 | 325 | return 0; |
| 326 | 326 | } |
| 327 | 327 | |
| @@ -425,7 +425,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) · 97 unmodified lines | ||
| 425 | 425 | { |
| 426 | 426 | init_new_context(current, &init_mm); |
| 427 | 427 | current_thread_info()->cpu = 0; |
| 428 | − loongson3_prepare_cpus(max_cpus); | |
| 428 | + loongson_prepare_cpus(max_cpus); | |
| 429 | 429 | set_cpu_sibling_map(0); |
| 430 | 430 | set_cpu_core_map(0); |
| 431 | 431 | calculate_cpu_foreign_map(); |
| @@ -436,7 +436,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) · 4 unmodified lines | ||
| 436 | 436 | |
| 437 | 437 | int __cpu_up(unsigned int cpu, struct task_struct *tidle) |
| 438 | 438 | { |
| 439 | − loongson3_boot_secondary(cpu, tidle); | |
| 439 | + loongson_boot_secondary(cpu, tidle); | |
| 440 | 440 | |
| 441 | 441 | /* Wait for CPU to start and be ready to sync counters */ |
| 442 | 442 | if (!wait_for_completion_timeout(&cpu_starting, |
| @@ -465,7 +465,7 @@ asmlinkage void start_secondary(void) · 22 unmodified lines | ||
| 465 | 465 | |
| 466 | 466 | cpu_probe(); |
| 467 | 467 | constant_clockevent_init(); |
| 468 | − loongson3_init_secondary(); | |
| 468 | + loongson_init_secondary(); | |
| 469 | 469 | |
| 470 | 470 | set_cpu_sibling_map(cpu); |
| 471 | 471 | set_cpu_core_map(cpu); |
| @@ -487,11 +487,11 @@ asmlinkage void start_secondary(void) · 15 unmodified lines | ||
| 487 | 487 | complete(&cpu_running); |
| 488 | 488 | |
| 489 | 489 | /* |
| 490 | − * irq will be enabled in loongson3_smp_finish(), enabling it too | |
| 490 | + * irq will be enabled in loongson_smp_finish(), enabling it too | |
| 491 | 491 | * early is dangerous. |
| 492 | 492 | */ |
| 493 | 493 | WARN_ON_ONCE(!irqs_disabled()); |
| 494 | − loongson3_smp_finish(); | |
| 494 | + loongson_smp_finish(); | |
| 495 | 495 | |
| 496 | 496 | cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); |
| 497 | 497 | } |
| @@ -43,7 +43,8 @@ static bool unwind_by_prologue(struct unwind_state *state) · 42 unmodified lines | ||
| 43 | 43 | { |
| 44 | 44 | struct stack_info *info = &state->stack_info; |
| 45 | 45 | union loongarch_instruction *ip, *ip_end; |
| 46 | − unsigned long frame_size = 0, frame_ra = -1; | |
| 46 | + long frame_ra = -1; | |
| 47 | + unsigned long frame_size = 0; | |
| 47 | 48 | unsigned long size, offset, pc = state->pc; |
| 48 | 49 | |
| 49 | 50 | if (state->sp >= info->end || state->sp < info->begin) |
| @@ -67,12 +67,12 @@ linux.bin.ub linux.bin.gz: linux.bin · 66 unmodified lines | ||
| 67 | 67 | linux.bin: vmlinux |
| 68 | 68 | linux.bin linux.bin.gz linux.bin.ub: |
| 69 | 69 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ |
| 70 | − @echo 'Kernel: $(boot)/$@ is ready' ' (#'`cat .version`')' | |
| 70 | + @echo 'Kernel: $(boot)/$@ is ready' ' (#'$(or $(KBUILD_BUILD_VERSION),`cat .version`)')' | |
| 71 | 71 | |
| 72 | 72 | PHONY += simpleImage.$(DTB) |
| 73 | 73 | simpleImage.$(DTB): vmlinux |
| 74 | 74 | $(Q)$(MAKE) $(build)=$(boot) $(addprefix $(boot)/$@., ub unstrip strip) |
| 75 | − @echo 'Kernel: $(boot)/$@ is ready' ' (#'`cat .version`')' | |
| 75 | + @echo 'Kernel: $(boot)/$@ is ready' ' (#'$(or $(KBUILD_BUILD_VERSION),`cat .version`)')' | |
| 76 | 76 | |
| 77 | 77 | define archhelp |
| 78 | 78 | echo '* linux.bin - Create raw binary' |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #include <linux/init.h> |
| 32 | 32 | #include <linux/kernel.h> |
| 33 | 33 | #include <linux/types.h> |
| 34 | −#include <linux/gpio.h> | |
| 34 | +#include <linux/gpio/driver.h> | |
| 35 | 35 | #include <asm/mach-au1x00/gpio-au1000.h> |
| 36 | 36 | #include <asm/mach-au1x00/gpio-au1300.h> |
| 37 | 37 | |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #define DISABLE_BRANCH_PROFILING |
| 11 | 11 | |
| 12 | +#define __NO_FORTIFY | |
| 12 | 13 | #include <linux/types.h> |
| 13 | 14 | #include <linux/kernel.h> |
| 14 | 15 | #include <linux/string.h> |
| @@ -26,6 +26,6 @@ extern char *fw_getcmdline(void); · 25 unmodified lines | ||
| 26 | 26 | extern void fw_meminit(void); |
| 27 | 27 | extern char *fw_getenv(char *name); |
| 28 | 28 | extern unsigned long fw_getenvl(char *name); |
| 29 | −extern void fw_init_early_console(char port); | |
| 29 | +extern void fw_init_early_console(void); | |
| 30 | 30 | |
| 31 | 31 | #endif /* __ASM_FW_H_ */ |
| @@ -622,6 +622,7 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd) · 621 unmodified lines | ||
| 622 | 622 | return pmd; |
| 623 | 623 | } |
| 624 | 624 | |
| 625 | +#define pmd_young pmd_young | |
| 625 | 626 | static inline int pmd_young(pmd_t pmd) |
| 626 | 627 | { |
| 627 | 628 | return !!(pmd_val(pmd) & _PAGE_ACCESSED); |
| @@ -56,7 +56,7 @@ void arch_jump_label_transform(struct jump_entry *e, · 55 unmodified lines | ||
| 56 | 56 | * The branch offset must fit in the instruction's 26 |
| 57 | 57 | * bit field. |
| 58 | 58 | */ |
| 59 | − WARN_ON((offset >= BIT(25)) || | |
| 59 | + WARN_ON((offset >= (long)BIT(25)) || | |
| 60 | 60 | (offset < -(long)BIT(25))); |
| 61 | 61 | |
| 62 | 62 | insn.j_format.opcode = bc6_op; |
| @@ -145,8 +145,7 @@ LEAF(kexec_smp_wait) · 144 unmodified lines | ||
| 145 | 145 | * kexec_args[0..3] are used to prepare register values. |
| 146 | 146 | */ |
| 147 | 147 | |
| 148 | −kexec_args: | |
| 149 | − EXPORT(kexec_args) | |
| 148 | +EXPORT(kexec_args) | |
| 150 | 149 | arg0: PTR_WD 0x0 |
| 151 | 150 | arg1: PTR_WD 0x0 |
| 152 | 151 | arg2: PTR_WD 0x0 |
| @@ -159,8 +158,7 @@ arg3: PTR_WD 0x0 · 6 unmodified lines | ||
| 159 | 158 | * their registers a0-a3. secondary_kexec_args[0..3] are used |
| 160 | 159 | * to prepare register values. |
| 161 | 160 | */ |
| 162 | −secondary_kexec_args: | |
| 163 | − EXPORT(secondary_kexec_args) | |
| 161 | +EXPORT(secondary_kexec_args) | |
| 164 | 162 | s_arg0: PTR_WD 0x0 |
| 165 | 163 | s_arg1: PTR_WD 0x0 |
| 166 | 164 | s_arg2: PTR_WD 0x0 |
| @@ -171,19 +169,16 @@ kexec_flag: · 4 unmodified lines | ||
| 171 | 169 | |
| 172 | 170 | #endif |
| 173 | 171 | |
| 174 | −kexec_start_address: | |
| 175 | − EXPORT(kexec_start_address) | |
| 172 | +EXPORT(kexec_start_address) | |
| 176 | 173 | PTR_WD 0x0 |
| 177 | 174 | .size kexec_start_address, PTRSIZE |
| 178 | 175 | |
| 179 | −kexec_indirection_page: | |
| 180 | − EXPORT(kexec_indirection_page) | |
| 176 | +EXPORT(kexec_indirection_page) | |
| 181 | 177 | PTR_WD 0 |
| 182 | 178 | .size kexec_indirection_page, PTRSIZE |
| 183 | 179 | |
| 184 | 180 | relocate_new_kernel_end: |
| 185 | 181 | |
| 186 | −relocate_new_kernel_size: | |
| 187 | − EXPORT(relocate_new_kernel_size) | |
| 182 | +EXPORT(relocate_new_kernel_size) | |
| 188 | 183 | PTR_WD relocate_new_kernel_end - relocate_new_kernel |
| 189 | 184 | .size relocate_new_kernel_size, PTRSIZE |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <asm/bootinfo.h> |
| 17 | 17 | #include <asm/idle.h> |
| 18 | 18 | #include <asm/reboot.h> |
| 19 | +#include <asm/bug.h> | |
| 19 | 20 | |
| 20 | 21 | #include <loongson.h> |
| 21 | 22 | #include <boot_param.h> |
| @@ -159,8 +160,17 @@ static int __init mips_reboot_setup(void) · 137 unmodified lines | ||
| 159 | 160 | |
| 160 | 161 | #ifdef CONFIG_KEXEC |
| 161 | 162 | kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL); |
| 163 | + if (WARN_ON(!kexec_argv)) | |
| 164 | + return -ENOMEM; | |
| 165 | + | |
| 162 | 166 | kdump_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL); |
| 167 | + if (WARN_ON(!kdump_argv)) | |
| 168 | + return -ENOMEM; | |
| 169 | + | |
| 163 | 170 | kexec_envp = kmalloc(KEXEC_ENVP_SIZE, GFP_KERNEL); |
| 171 | + if (WARN_ON(!kexec_envp)) | |
| 172 | + return -ENOMEM; | |
| 173 | + | |
| 164 | 174 | fw_arg1 = KEXEC_ARGV_ADDR; |
| 165 | 175 | memcpy(kexec_envp, (void *)fw_arg2, KEXEC_ENVP_SIZE); |
| 166 | 176 | |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #define U_BRG(x) (UART_BASE(x) + 0x40) |
| 28 | 28 | |
| 29 | 29 | static void __iomem *uart_base; |
| 30 | −static char console_port = -1; | |
| 30 | +static int console_port = -1; | |
| 31 | 31 | |
| 32 | 32 | static int __init configure_uart_pins(int port) |
| 33 | 33 | { |
| @@ -47,7 +47,7 @@ static int __init configure_uart_pins(int port) · 13 unmodified lines | ||
| 47 | 47 | return 0; |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | −static void __init configure_uart(char port, int baud) | |
| 50 | +static void __init configure_uart(int port, int baud) | |
| 51 | 51 | { |
| 52 | 52 | u32 pbclk; |
| 53 | 53 | |
| @@ -60,7 +60,7 @@ static void __init configure_uart(char port, int baud) · 6 unmodified lines | ||
| 60 | 60 | uart_base + PIC32_SET(U_STA(port))); |
| 61 | 61 | } |
| 62 | 62 | |
| 63 | −static void __init setup_early_console(char port, int baud) | |
| 63 | +static void __init setup_early_console(int port, int baud) | |
| 64 | 64 | { |
| 65 | 65 | if (configure_uart_pins(port)) |
| 66 | 66 | return; |
| @@ -130,16 +130,15 @@ _out: · 63 unmodified lines | ||
| 130 | 130 | return baud; |
| 131 | 131 | } |
| 132 | 132 | |
| 133 | −void __init fw_init_early_console(char port) | |
| 133 | +void __init fw_init_early_console(void) | |
| 134 | 134 | { |
| 135 | 135 | char *arch_cmdline = pic32_getcmdline(); |
| 136 | − int baud = -1; | |
| 136 | + int baud, port; | |
| 137 | 137 | |
| 138 | 138 | uart_base = ioremap(PIC32_BASE_UART, 0xc00); |
| 139 | 139 | |
| 140 | 140 | baud = get_baud_from_cmdline(arch_cmdline); |
| 141 | − if (port == -1) | |
| 142 | − port = get_port_from_cmdline(arch_cmdline); | |
| 141 | + port = get_port_from_cmdline(arch_cmdline); | |
| 143 | 142 | |
| 144 | 143 | if (port == -1) |
| 145 | 144 | port = EARLY_CONSOLE_PORT; |
| @@ -47,7 +47,7 @@ void __init plat_mem_setup(void) · 46 unmodified lines | ||
| 47 | 47 | strscpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); |
| 48 | 48 | |
| 49 | 49 | #ifdef CONFIG_EARLY_PRINTK |
| 50 | − fw_init_early_console(-1); | |
| 50 | + fw_init_early_console(); | |
| 51 | 51 | #endif |
| 52 | 52 | pic32_config_init(); |
| 53 | 53 | } |
| @@ -20,7 +20,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE · 19 unmodified lines | ||
| 20 | 20 | $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE |
| 21 | 21 | $(call if_changed,gzip) |
| 22 | 22 | |
| 23 | −$(obj)/vmImage: $(obj)/vmlinux.gz | |
| 23 | +$(obj)/vmImage: $(obj)/vmlinux.gz FORCE | |
| 24 | 24 | $(call if_changed,uimage) |
| 25 | 25 | @$(kecho) 'Kernel: $@ is ready' |
| 26 | 26 | |
| @@ -10,12 +10,12 @@ · 9 unmodified lines | ||
| 10 | 10 | #define SVERSION_ANY_ID PA_SVERSION_ANY_ID |
| 11 | 11 | |
| 12 | 12 | struct hp_hardware { |
| 13 | − unsigned short hw_type:5; /* HPHW_xxx */ | |
| 14 | − unsigned short hversion; | |
| 15 | − unsigned long sversion:28; | |
| 16 | − unsigned short opt; | |
| 17 | − const char name[80]; /* The hardware description */ | |
| 18 | −}; | |
| 13 | + unsigned int hw_type:8; /* HPHW_xxx */ | |
| 14 | + unsigned int hversion:12; | |
| 15 | + unsigned int sversion:12; | |
| 16 | + unsigned char opt; | |
| 17 | + unsigned char name[59]; /* The hardware description */ | |
| 18 | +} __packed; | |
| 19 | 19 | |
| 20 | 20 | struct parisc_device; |
| 21 | 21 | |
| @@ -363,20 +363,25 @@ · 362 unmodified lines | ||
| 363 | 363 | |
| 364 | 364 | #if !defined(__ASSEMBLY__) |
| 365 | 365 | |
| 366 | −/* flags of the device_path */ | |
| 366 | +/* flags for hardware_path */ | |
| 367 | 367 | #define PF_AUTOBOOT 0x80 |
| 368 | 368 | #define PF_AUTOSEARCH 0x40 |
| 369 | 369 | #define PF_TIMER 0x0F |
| 370 | 370 | |
| 371 | −struct device_path { /* page 1-69 */ | |
| 372 | − unsigned char flags; /* flags see above! */ | |
| 373 | − unsigned char bc[6]; /* bus converter routing info */ | |
| 374 | − unsigned char mod; | |
| 375 | − unsigned int layers[6];/* device-specific layer-info */ | |
| 376 | −} __attribute__((aligned(8))) ; | |
| 371 | +struct hardware_path { | |
| 372 | + unsigned char flags; /* see bit definitions below */ | |
| 373 | + signed char bc[6]; /* Bus Converter routing info to a specific */ | |
| 374 | + /* I/O adaptor (< 0 means none, > 63 resvd) */ | |
| 375 | + signed char mod; /* fixed field of specified module */ | |
| 376 | +}; | |
| 377 | + | |
| 378 | +struct pdc_module_path { /* page 1-69 */ | |
| 379 | + struct hardware_path path; | |
| 380 | + unsigned int layers[6]; /* device-specific info (ctlr #, unit # ...) */ | |
| 381 | +} __attribute__((aligned(8))); | |
| 377 | 382 | |
| 378 | 383 | struct pz_device { |
| 379 | − struct device_path dp; /* see above */ | |
| 384 | + struct pdc_module_path dp; /* see above */ | |
| 380 | 385 | /* struct iomod *hpa; */ |
| 381 | 386 | unsigned int hpa; /* HPA base address */ |
| 382 | 387 | /* char *spa; */ |
| @@ -611,21 +616,6 @@ struct pdc_initiator { /* PDC_INITIATOR */ · 228 unmodified lines | ||
| 611 | 616 | int mode; |
| 612 | 617 | }; |
| 613 | 618 | |
| 614 | −struct hardware_path { | |
| 615 | − char flags; /* see bit definitions below */ | |
| 616 | − char bc[6]; /* Bus Converter routing info to a specific */ | |
| 617 | − /* I/O adaptor (< 0 means none, > 63 resvd) */ | |
| 618 | − char mod; /* fixed field of specified module */ | |
| 619 | −}; | |
| 620 | − | |
| 621 | −/* | |
| 622 | − * Device path specifications used by PDC. | |
| 623 | − */ | |
| 624 | −struct pdc_module_path { | |
| 625 | − struct hardware_path path; | |
| 626 | − unsigned int layers[6]; /* device-specific info (ctlr #, unit # ...) */ | |
| 627 | −}; | |
| 628 | − | |
| 629 | 619 | /* Only used on some pre-PA2.0 boxes */ |
| 630 | 620 | struct pdc_memory_map { /* PDC_MEMORY_MAP */ |
| 631 | 621 | unsigned long hpa; /* mod's register set address */ |
| @@ -882,15 +882,13 @@ void __init walk_central_bus(void) · 881 unmodified lines | ||
| 882 | 882 | &root); |
| 883 | 883 | } |
| 884 | 884 | |
| 885 | −static void print_parisc_device(struct parisc_device *dev) | |
| 885 | +static __init void print_parisc_device(struct parisc_device *dev) | |
| 886 | 886 | { |
| 887 | − char hw_path[64]; | |
| 888 | − static int count; | |
| 887 | + static int count __initdata; | |
| 889 | 888 | |
| 890 | − print_pa_hwpath(dev, hw_path); | |
| 891 | − pr_info("%d. %s at %pap [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }", | |
| 892 | − ++count, dev->name, &(dev->hpa.start), hw_path, dev->id.hw_type, | |
| 893 | − dev->id.hversion_rev, dev->id.hversion, dev->id.sversion); | |
| 889 | + pr_info("%d. %s at %pap { type:%d, hv:%#x, sv:%#x, rev:%#x }", | |
| 890 | + ++count, dev->name, &(dev->hpa.start), dev->id.hw_type, | |
| 891 | + dev->id.hversion, dev->id.sversion, dev->id.hversion_rev); | |
| 894 | 892 | |
| 895 | 893 | if (dev->num_addrs) { |
| 896 | 894 | int k; |
| @@ -1079,7 +1077,7 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data) · 182 unmodified lines | ||
| 1079 | 1077 | |
| 1080 | 1078 | |
| 1081 | 1079 | |
| 1082 | −static int print_one_device(struct device * dev, void * data) | |
| 1080 | +static __init int print_one_device(struct device * dev, void * data) | |
| 1083 | 1081 | { |
| 1084 | 1082 | struct parisc_device * pdev = to_parisc_device(dev); |
| 1085 | 1083 | |
| @@ -147,6 +147,7 @@ config PPC · 146 unmodified lines | ||
| 147 | 147 | select ARCH_MIGHT_HAVE_PC_SERIO |
| 148 | 148 | select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX |
| 149 | 149 | select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT |
| 150 | + select ARCH_SPLIT_ARG64 if PPC32 | |
| 150 | 151 | select ARCH_STACKWALK |
| 151 | 152 | select ARCH_SUPPORTS_ATOMIC_RMW |
| 152 | 153 | select ARCH_SUPPORTS_DEBUG_PAGEALLOC if PPC_BOOK3S || PPC_8xx || 40x |
| @@ -285,7 +286,7 @@ config PPC · 132 unmodified lines | ||
| 285 | 286 | # |
| 286 | 287 | |
| 287 | 288 | config PPC_LONG_DOUBLE_128 |
| 288 | − depends on PPC64 | |
| 289 | + depends on PPC64 && ALTIVEC | |
| 289 | 290 | def_bool $(success,test "$(shell,echo __LONG_DOUBLE_128__ | $(CC) -E -P -)" = 1) |
| 290 | 291 | |
| 291 | 292 | config PPC_BARRIER_NOSPEC |
| @@ -602,6 +602,7 @@ ____##func(struct pt_regs *regs) · 601 unmodified lines | ||
| 602 | 602 | /* kernel/traps.c */ |
| 603 | 603 | DECLARE_INTERRUPT_HANDLER_NMI(system_reset_exception); |
| 604 | 604 | #ifdef CONFIG_PPC_BOOK3S_64 |
| 605 | +DECLARE_INTERRUPT_HANDLER_RAW(machine_check_early_boot); | |
| 605 | 606 | DECLARE_INTERRUPT_HANDLER_ASYNC(machine_check_exception_async); |
| 606 | 607 | #endif |
| 607 | 608 | DECLARE_INTERRUPT_HANDLER_NMI(machine_check_exception); |
| @@ -104,6 +104,13 @@ long sys_ppc_ftruncate64(unsigned int fd, u32 reg4, · 103 unmodified lines | ||
| 104 | 104 | unsigned long len1, unsigned long len2); |
| 105 | 105 | long sys_ppc32_fadvise64(int fd, u32 unused, u32 offset1, u32 offset2, |
| 106 | 106 | size_t len, int advice); |
| 107 | +long sys_ppc_sync_file_range2(int fd, unsigned int flags, | |
| 108 | + unsigned int offset1, | |
| 109 | + unsigned int offset2, | |
| 110 | + unsigned int nbytes1, | |
| 111 | + unsigned int nbytes2); | |
| 112 | +long sys_ppc_fallocate(int fd, int mode, u32 offset1, u32 offset2, | |
| 113 | + u32 len1, u32 len2); | |
| 107 | 114 | #endif |
| 108 | 115 | #ifdef CONFIG_COMPAT |
| 109 | 116 | long compat_sys_mmap2(unsigned long addr, size_t len, |
| @@ -112,7 +112,7 @@ PPC32_SYSCALL_DEFINE6(ppc32_fadvise64, · 111 unmodified lines | ||
| 112 | 112 | advice); |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | −COMPAT_SYSCALL_DEFINE6(ppc_sync_file_range2, | |
| 115 | +PPC32_SYSCALL_DEFINE6(ppc_sync_file_range2, | |
| 116 | 116 | int, fd, unsigned int, flags, |
| 117 | 117 | unsigned int, offset1, unsigned int, offset2, |
| 118 | 118 | unsigned int, nbytes1, unsigned int, nbytes2) |
| @@ -122,3 +122,14 @@ COMPAT_SYSCALL_DEFINE6(ppc_sync_file_range2, · 3 unmodified lines | ||
| 122 | 122 | |
| 123 | 123 | return ksys_sync_file_range(fd, offset, nbytes, flags); |
| 124 | 124 | } |
| 125 | + | |
| 126 | +#ifdef CONFIG_PPC32 | |
| 127 | +SYSCALL_DEFINE6(ppc_fallocate, | |
| 128 | + int, fd, int, mode, | |
| 129 | + u32, offset1, u32, offset2, u32, len1, u32, len2) | |
| 130 | +{ | |
| 131 | + return ksys_fallocate(fd, mode, | |
| 132 | + merge_64(offset1, offset2), | |
| 133 | + merge_64(len1, len2)); | |
| 134 | +} | |
| 135 | +#endif | |
| @@ -394,8 +394,11 @@ · 393 unmodified lines | ||
| 394 | 394 | 305 common signalfd sys_signalfd compat_sys_signalfd |
| 395 | 395 | 306 common timerfd_create sys_timerfd_create |
| 396 | 396 | 307 common eventfd sys_eventfd |
| 397 | −308 common sync_file_range2 sys_sync_file_range2 compat_sys_ppc_sync_file_range2 | |
| 398 | −309 nospu fallocate sys_fallocate compat_sys_fallocate | |
| 397 | +308 32 sync_file_range2 sys_ppc_sync_file_range2 compat_sys_ppc_sync_file_range2 | |
| 398 | +308 64 sync_file_range2 sys_sync_file_range2 | |
| 399 | +308 spu sync_file_range2 sys_sync_file_range2 | |
| 400 | +309 32 fallocate sys_ppc_fallocate compat_sys_fallocate | |
| 401 | +309 64 fallocate sys_fallocate | |
| 399 | 402 | 310 nospu subpage_prot sys_subpage_prot |
| 400 | 403 | 311 32 timerfd_settime sys_timerfd_settime32 |
| 401 | 404 | 311 64 timerfd_settime sys_timerfd_settime |
| @@ -142,7 +142,7 @@ SECTIONS · 141 unmodified lines | ||
| 142 | 142 | #endif |
| 143 | 143 | |
| 144 | 144 | .data.rel.ro : AT(ADDR(.data.rel.ro) - LOAD_OFFSET) { |
| 145 | − *(.data.rel.ro*) | |
| 145 | + *(.data.rel.ro .data.rel.ro.*) | |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | 148 | .branch_lt : AT(ADDR(.branch_lt) - LOAD_OFFSET) { |
| @@ -113,23 +113,19 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx) · 112 unmodified lines | ||
| 113 | 113 | { |
| 114 | 114 | int i; |
| 115 | 115 | |
| 116 | − /* First arg comes in as a 32 bits pointer. */ | |
| 117 | − EMIT(PPC_RAW_MR(bpf_to_ppc(BPF_REG_1), _R3)); | |
| 118 | − EMIT(PPC_RAW_LI(bpf_to_ppc(BPF_REG_1) - 1, 0)); | |
| 116 | + /* Initialize tail_call_cnt, to be skipped if we do tail calls. */ | |
| 117 | + EMIT(PPC_RAW_LI(_R4, 0)); | |
| 118 | + | |
| 119 | +#define BPF_TAILCALL_PROLOGUE_SIZE 4 | |
| 120 | + | |
| 119 | 121 | EMIT(PPC_RAW_STWU(_R1, _R1, -BPF_PPC_STACKFRAME(ctx))); |
| 120 | 122 | |
| 121 | − /* | |
| 122 | − * Initialize tail_call_cnt in stack frame if we do tail calls. | |
| 123 | − * Otherwise, put in NOPs so that it can be skipped when we are | |
| 124 | − * invoked through a tail call. | |
| 125 | − */ | |
| 126 | 123 | if (ctx->seen & SEEN_TAILCALL) |
| 127 | − EMIT(PPC_RAW_STW(bpf_to_ppc(BPF_REG_1) - 1, _R1, | |
| 128 | − bpf_jit_stack_offsetof(ctx, BPF_PPC_TC))); | |
| 129 | − else | |
| 130 | − EMIT(PPC_RAW_NOP()); | |
| 124 | + EMIT(PPC_RAW_STW(_R4, _R1, bpf_jit_stack_offsetof(ctx, BPF_PPC_TC))); | |
| 131 | 125 | |
| 132 | −#define BPF_TAILCALL_PROLOGUE_SIZE 16 | |
| 126 | + /* First arg comes in as a 32 bits pointer. */ | |
| 127 | + EMIT(PPC_RAW_MR(bpf_to_ppc(BPF_REG_1), _R3)); | |
| 128 | + EMIT(PPC_RAW_LI(bpf_to_ppc(BPF_REG_1) - 1, 0)); | |
| 133 | 129 | |
| 134 | 130 | /* |
| 135 | 131 | * We need a stack frame, but we don't necessarily need to |
| @@ -170,24 +166,24 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx · 34 unmodified lines | ||
| 170 | 166 | for (i = BPF_PPC_NVR_MIN; i <= 31; i++) |
| 171 | 167 | if (bpf_is_seen_register(ctx, i)) |
| 172 | 168 | EMIT(PPC_RAW_LWZ(i, _R1, bpf_jit_stack_offsetof(ctx, i))); |
| 173 | −} | |
| 174 | − | |
| 175 | −void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) | |
| 176 | −{ | |
| 177 | − EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0))); | |
| 178 | − | |
| 179 | − bpf_jit_emit_common_epilogue(image, ctx); | |
| 180 | − | |
| 181 | − /* Tear down our stack frame */ | |
| 182 | 169 | |
| 183 | 170 | if (ctx->seen & SEEN_FUNC) |
| 184 | 171 | EMIT(PPC_RAW_LWZ(_R0, _R1, BPF_PPC_STACKFRAME(ctx) + PPC_LR_STKOFF)); |
| 185 | 172 | |
| 173 | + /* Tear down our stack frame */ | |
| 186 | 174 | EMIT(PPC_RAW_ADDI(_R1, _R1, BPF_PPC_STACKFRAME(ctx))); |
| 187 | 175 | |
| 188 | 176 | if (ctx->seen & SEEN_FUNC) |
| 189 | 177 | EMIT(PPC_RAW_MTLR(_R0)); |
| 190 | 178 | |
| 179 | +} | |
| 180 | + | |
| 181 | +void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) | |
| 182 | +{ | |
| 183 | + EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0))); | |
| 184 | + | |
| 185 | + bpf_jit_emit_common_epilogue(image, ctx); | |
| 186 | + | |
| 191 | 187 | EMIT(PPC_RAW_BLR()); |
| 192 | 188 | } |
| 193 | 189 | |
| @@ -244,7 +240,6 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o · 50 unmodified lines | ||
| 244 | 240 | EMIT(PPC_RAW_RLWINM(_R3, b2p_index, 2, 0, 29)); |
| 245 | 241 | EMIT(PPC_RAW_ADD(_R3, _R3, b2p_bpf_array)); |
| 246 | 242 | EMIT(PPC_RAW_LWZ(_R3, _R3, offsetof(struct bpf_array, ptrs))); |
| 247 | − EMIT(PPC_RAW_STW(_R0, _R1, bpf_jit_stack_offsetof(ctx, BPF_PPC_TC))); | |
| 248 | 243 | |
| 249 | 244 | /* |
| 250 | 245 | * if (prog == NULL) |
| @@ -255,19 +250,14 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o · 4 unmodified lines | ||
| 255 | 250 | |
| 256 | 251 | /* goto *(prog->bpf_func + prologue_size); */ |
| 257 | 252 | EMIT(PPC_RAW_LWZ(_R3, _R3, offsetof(struct bpf_prog, bpf_func))); |
| 258 | − | |
| 259 | − if (ctx->seen & SEEN_FUNC) | |
| 260 | − EMIT(PPC_RAW_LWZ(_R0, _R1, BPF_PPC_STACKFRAME(ctx) + PPC_LR_STKOFF)); | |
| 261 | − | |
| 262 | 253 | EMIT(PPC_RAW_ADDIC(_R3, _R3, BPF_TAILCALL_PROLOGUE_SIZE)); |
| 263 | − | |
| 264 | − if (ctx->seen & SEEN_FUNC) | |
| 265 | − EMIT(PPC_RAW_MTLR(_R0)); | |
| 266 | − | |
| 267 | 254 | EMIT(PPC_RAW_MTCTR(_R3)); |
| 268 | 255 | |
| 269 | 256 | EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_1))); |
| 270 | 257 | |
| 258 | + /* Put tail_call_cnt in r4 */ | |
| 259 | + EMIT(PPC_RAW_MR(_R4, _R0)); | |
| 260 | + | |
| 271 | 261 | /* tear restore NVRs, ... */ |
| 272 | 262 | bpf_jit_emit_common_epilogue(image, ctx); |
| 273 | 263 | |
| @@ -317,9 +317,9 @@ config SMP · 316 unmodified lines | ||
| 317 | 317 | config NR_CPUS |
| 318 | 318 | int "Maximum number of CPUs (2-512)" |
| 319 | 319 | depends on SMP |
| 320 | − range 2 512 if !SBI_V01 | |
| 321 | − range 2 32 if SBI_V01 && 32BIT | |
| 322 | − range 2 64 if SBI_V01 && 64BIT | |
| 320 | + range 2 512 if !RISCV_SBI_V01 | |
| 321 | + range 2 32 if RISCV_SBI_V01 && 32BIT | |
| 322 | + range 2 64 if RISCV_SBI_V01 && 64BIT | |
| 323 | 323 | default "32" if 32BIT |
| 324 | 324 | default "64" if 64BIT |
| 325 | 325 | |
| @@ -3,6 +3,8 @@ · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | #include "fu540-c000.dtsi" |
| 5 | 5 | #include <dt-bindings/gpio/gpio.h> |
| 6 | +#include <dt-bindings/leds/common.h> | |
| 7 | +#include <dt-bindings/pwm/pwm.h> | |
| 6 | 8 | |
| 7 | 9 | /* Clock frequency (in Hz) of the PCB crystal for rtcclk */ |
| 8 | 10 | #define RTCCLK_FREQ 1000000 |
| @@ -42,6 +44,42 @@ · 33 unmodified lines | ||
| 42 | 44 | compatible = "gpio-restart"; |
| 43 | 45 | gpios = <&gpio 10 GPIO_ACTIVE_LOW>; |
| 44 | 46 | }; |
| 47 | + | |
| 48 | + led-controller { | |
| 49 | + compatible = "pwm-leds"; | |
| 50 | + | |
| 51 | + led-d1 { | |
| 52 | + pwms = <&pwm0 0 7812500 PWM_POLARITY_INVERTED>; | |
| 53 | + active-low; | |
| 54 | + color = <LED_COLOR_ID_GREEN>; | |
| 55 | + max-brightness = <255>; | |
| 56 | + label = "d1"; | |
| 57 | + }; | |
| 58 | + | |
| 59 | + led-d2 { | |
| 60 | + pwms = <&pwm0 1 7812500 PWM_POLARITY_INVERTED>; | |
| 61 | + active-low; | |
| 62 | + color = <LED_COLOR_ID_GREEN>; | |
| 63 | + max-brightness = <255>; | |
| 64 | + label = "d2"; | |
| 65 | + }; | |
| 66 | + | |
| 67 | + led-d3 { | |
| 68 | + pwms = <&pwm0 2 7812500 PWM_POLARITY_INVERTED>; | |
| 69 | + active-low; | |
| 70 | + color = <LED_COLOR_ID_GREEN>; | |
| 71 | + max-brightness = <255>; | |
| 72 | + label = "d3"; | |
| 73 | + }; | |
| 74 | + | |
| 75 | + led-d4 { | |
| 76 | + pwms = <&pwm0 3 7812500 PWM_POLARITY_INVERTED>; | |
| 77 | + active-low; | |
| 78 | + color = <LED_COLOR_ID_GREEN>; | |
| 79 | + max-brightness = <255>; | |
| 80 | + label = "d4"; | |
| 81 | + }; | |
| 82 | + }; | |
| 45 | 83 | }; |
| 46 | 84 | |
| 47 | 85 | &uart0 { |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #define REG_L __REG_SEL(ld, lw) |
| 24 | 24 | #define REG_S __REG_SEL(sd, sw) |
| 25 | 25 | #define REG_SC __REG_SEL(sc.d, sc.w) |
| 26 | +#define REG_AMOSWAP_AQ __REG_SEL(amoswap.d.aq, amoswap.w.aq) | |
| 26 | 27 | #define REG_ASM __REG_SEL(.dword, .word) |
| 27 | 28 | #define SZREG __REG_SEL(8, 4) |
| 28 | 29 | #define LGREG __REG_SEL(3, 2) |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <asm/mmu_context.h> |
| 11 | 11 | #include <asm/ptrace.h> |
| 12 | 12 | #include <asm/tlbflush.h> |
| 13 | +#include <asm/pgalloc.h> | |
| 13 | 14 | |
| 14 | 15 | #ifdef CONFIG_EFI |
| 15 | 16 | extern void efi_init(void); |
| @@ -20,7 +21,10 @@ extern void efi_init(void); · 4 unmodified lines | ||
| 20 | 21 | int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); |
| 21 | 22 | int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); |
| 22 | 23 | |
| 23 | −#define arch_efi_call_virt_setup() efi_virtmap_load() | |
| 24 | +#define arch_efi_call_virt_setup() ({ \ | |
| 25 | + sync_kernel_mappings(efi_mm.pgd); \ | |
| 26 | + efi_virtmap_load(); \ | |
| 27 | + }) | |
| 24 | 28 | #define arch_efi_call_virt_teardown() efi_virtmap_unload() |
| 25 | 29 | |
| 26 | 30 | #define ARCH_EFI_IRQ_FLAGS_MASK (SR_IE | SR_SPIE) |
| @@ -127,6 +127,13 @@ static inline void p4d_free(struct mm_struct *mm, p4d_t *p4d) · 126 unmodified lines | ||
| 127 | 127 | #define __p4d_free_tlb(tlb, p4d, addr) p4d_free((tlb)->mm, p4d) |
| 128 | 128 | #endif /* __PAGETABLE_PMD_FOLDED */ |
| 129 | 129 | |
| 130 | +static inline void sync_kernel_mappings(pgd_t *pgd) | |
| 131 | +{ | |
| 132 | + memcpy(pgd + USER_PTRS_PER_PGD, | |
| 133 | + init_mm.pgd + USER_PTRS_PER_PGD, | |
| 134 | + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); | |
| 135 | +} | |
| 136 | + | |
| 130 | 137 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
| 131 | 138 | { |
| 132 | 139 | pgd_t *pgd; |
| @@ -135,9 +142,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) · 2 unmodified lines | ||
| 135 | 142 | if (likely(pgd != NULL)) { |
| 136 | 143 | memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); |
| 137 | 144 | /* Copy kernel mappings */ |
| 138 | − memcpy(pgd + USER_PTRS_PER_PGD, | |
| 139 | − init_mm.pgd + USER_PTRS_PER_PGD, | |
| 140 | − (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); | |
| 145 | + sync_kernel_mappings(pgd); | |
| 141 | 146 | } |
| 142 | 147 | return pgd; |
| 143 | 148 | } |
| @@ -600,6 +600,7 @@ static inline int pmd_dirty(pmd_t pmd) · 599 unmodified lines | ||
| 600 | 600 | return pte_dirty(pmd_pte(pmd)); |
| 601 | 601 | } |
| 602 | 602 | |
| 603 | +#define pmd_young pmd_young | |
| 603 | 604 | static inline int pmd_young(pmd_t pmd) |
| 604 | 605 | { |
| 605 | 606 | return pte_young(pmd_pte(pmd)); |
| @@ -50,6 +50,9 @@ void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops); · 49 unmodified lines | ||
| 50 | 50 | /* Clear IPI for current CPU */ |
| 51 | 51 | void riscv_clear_ipi(void); |
| 52 | 52 | |
| 53 | +/* Check other CPUs stop or not */ | |
| 54 | +bool smp_crash_stop_failed(void); | |
| 55 | + | |
| 53 | 56 | /* Secondary hart entry */ |
| 54 | 57 | asmlinkage void smp_callin(void); |
| 55 | 58 | |
| @@ -404,6 +404,19 @@ handle_syscall_trace_exit: · 403 unmodified lines | ||
| 404 | 404 | |
| 405 | 405 | #ifdef CONFIG_VMAP_STACK |
| 406 | 406 | handle_kernel_stack_overflow: |
| 407 | + /* | |
| 408 | + * Takes the psuedo-spinlock for the shadow stack, in case multiple | |
| 409 | + * harts are concurrently overflowing their kernel stacks. We could | |
| 410 | + * store any value here, but since we're overflowing the kernel stack | |
| 411 | + * already we only have SP to use as a scratch register. So we just | |
| 412 | + * swap in the address of the spinlock, as that's definately non-zero. | |
| 413 | + * | |
| 414 | + * Pairs with a store_release in handle_bad_stack(). | |
| 415 | + */ | |
| 416 | +1: la sp, spin_shadow_stack | |
| 417 | + REG_AMOSWAP_AQ sp, sp, (sp) | |
| 418 | + bnez sp, 1b | |
| 419 | + | |
| 407 | 420 | la sp, shadow_stack |
| 408 | 421 | addi sp, sp, SHADOW_OVERFLOW_STACK_SIZE |
| 409 | 422 | |
| @@ -15,6 +15,8 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/compiler.h> /* For unreachable() */ |
| 16 | 16 | #include <linux/cpu.h> /* For cpu_down() */ |
| 17 | 17 | #include <linux/reboot.h> |
| 18 | +#include <linux/interrupt.h> | |
| 19 | +#include <linux/irq.h> | |
| 18 | 20 | |
| 19 | 21 | /* |
| 20 | 22 | * kexec_image_info - Print received image details |
| @@ -138,20 +140,35 @@ void machine_shutdown(void) · 117 unmodified lines | ||
| 138 | 140 | #endif |
| 139 | 141 | } |
| 140 | 142 | |
| 141 | −/* Override the weak function in kernel/panic.c */ | |
| 142 | −void crash_smp_send_stop(void) | |
| 143 | +static void machine_kexec_mask_interrupts(void) | |
| 143 | 144 | { |
| 144 | − static int cpus_stopped; | |
| 145 | + unsigned int i; | |
| 146 | + struct irq_desc *desc; | |
| 145 | 147 | |
| 146 | − /* | |
| 147 | − * This function can be called twice in panic path, but obviously | |
| 148 | − * we execute this only once. | |
| 149 | − */ | |
| 150 | − if (cpus_stopped) | |
| 151 | − return; | |
| 148 | + for_each_irq_desc(i, desc) { | |
| 149 | + struct irq_chip *chip; | |
| 150 | + int ret; | |
| 151 | + | |
| 152 | + chip = irq_desc_get_chip(desc); | |
| 153 | + if (!chip) | |
| 154 | + continue; | |
| 155 | + | |
| 156 | + /* | |
| 157 | + * First try to remove the active state. If this | |
| 158 | + * fails, try to EOI the interrupt. | |
| 159 | + */ | |
| 160 | + ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false); | |
| 161 | + | |
| 162 | + if (ret && irqd_irq_inprogress(&desc->irq_data) && | |
| 163 | + chip->irq_eoi) | |
| 164 | + chip->irq_eoi(&desc->irq_data); | |
| 152 | 165 | |
| 153 | − smp_send_stop(); | |
| 154 | − cpus_stopped = 1; | |
| 166 | + if (chip->irq_mask) | |
| 167 | + chip->irq_mask(&desc->irq_data); | |
| 168 | + | |
| 169 | + if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) | |
| 170 | + chip->irq_disable(&desc->irq_data); | |
| 171 | + } | |
| 155 | 172 | } |
| 156 | 173 | |
| 157 | 174 | /* |
| @@ -169,6 +186,8 @@ machine_crash_shutdown(struct pt_regs *regs) · 11 unmodified lines | ||
| 169 | 186 | crash_smp_send_stop(); |
| 170 | 187 | |
| 171 | 188 | crash_save_cpu(regs, smp_processor_id()); |
| 189 | + machine_kexec_mask_interrupts(); | |
| 190 | + | |
| 172 | 191 | pr_info("Starting crashdump kernel...\n"); |
| 173 | 192 | } |
| 174 | 193 | |
| @@ -195,6 +214,11 @@ machine_kexec(struct kimage *image) · 20 unmodified lines | ||
| 195 | 214 | void *control_code_buffer = page_address(image->control_code_page); |
| 196 | 215 | riscv_kexec_method kexec_method = NULL; |
| 197 | 216 | |
| 217 | +#ifdef CONFIG_SMP | |
| 218 | + WARN(smp_crash_stop_failed(), | |
| 219 | + "Some CPUs may be stale, kdump will be unreliable.\n"); | |
| 220 | +#endif | |
| 221 | + | |
| 198 | 222 | if (image->type != KEXEC_TYPE_CRASH) |
| 199 | 223 | kexec_method = control_code_buffer; |
| 200 | 224 | else |
| @@ -164,6 +164,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) · 163 unmodified lines | ||
| 164 | 164 | unsigned long tls = args->tls; |
| 165 | 165 | struct pt_regs *childregs = task_pt_regs(p); |
| 166 | 166 | |
| 167 | + memset(&p->thread.s, 0, sizeof(p->thread.s)); | |
| 168 | + | |
| 167 | 169 | /* p->thread holds context to be restored by __switch_to() */ |
| 168 | 170 | if (unlikely(args->fn)) { |
| 169 | 171 | /* Kernel thread */ |
| @@ -283,6 +283,7 @@ void __init setup_arch(char **cmdline_p) · 282 unmodified lines | ||
| 283 | 283 | else |
| 284 | 284 | pr_err("No DTB found in kernel mappings\n"); |
| 285 | 285 | #endif |
| 286 | + early_init_fdt_scan_reserved_mem(); | |
| 286 | 287 | misc_mem_init(); |
| 287 | 288 | |
| 288 | 289 | init_resources(); |
| @@ -321,10 +322,11 @@ subsys_initcall(topology_init); · 32 unmodified lines | ||
| 321 | 322 | |
| 322 | 323 | void free_initmem(void) |
| 323 | 324 | { |
| 324 | − if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) | |
| 325 | − set_kernel_memory(lm_alias(__init_begin), lm_alias(__init_end), | |
| 326 | − IS_ENABLED(CONFIG_64BIT) ? | |
| 327 | − set_memory_rw : set_memory_rw_nx); | |
| 325 | + if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) { | |
| 326 | + set_kernel_memory(lm_alias(__init_begin), lm_alias(__init_end), set_memory_rw_nx); | |
| 327 | + if (IS_ENABLED(CONFIG_64BIT)) | |
| 328 | + set_kernel_memory(__init_begin, __init_end, set_memory_nx); | |
| 329 | + } | |
| 328 | 330 | |
| 329 | 331 | free_initmem_default(POISON_FREE_INITMEM); |
| 330 | 332 | } |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/clockchips.h> |
| 13 | 13 | #include <linux/interrupt.h> |
| 14 | 14 | #include <linux/module.h> |
| 15 | +#include <linux/kexec.h> | |
| 15 | 16 | #include <linux/profile.h> |
| 16 | 17 | #include <linux/smp.h> |
| 17 | 18 | #include <linux/sched.h> |
| @@ -22,11 +23,13 @@ · 4 unmodified lines | ||
| 22 | 23 | #include <asm/sbi.h> |
| 23 | 24 | #include <asm/tlbflush.h> |
| 24 | 25 | #include <asm/cacheflush.h> |
| 26 | +#include <asm/cpu_ops.h> | |
| 25 | 27 | |
| 26 | 28 | enum ipi_message_type { |
| 27 | 29 | IPI_RESCHEDULE, |
| 28 | 30 | IPI_CALL_FUNC, |
| 29 | 31 | IPI_CPU_STOP, |
| 32 | + IPI_CPU_CRASH_STOP, | |
| 30 | 33 | IPI_IRQ_WORK, |
| 31 | 34 | IPI_TIMER, |
| 32 | 35 | IPI_MAX |
| @@ -71,6 +74,32 @@ static void ipi_stop(void) · 38 unmodified lines | ||
| 71 | 74 | wait_for_interrupt(); |
| 72 | 75 | } |
| 73 | 76 | |
| 77 | +#ifdef CONFIG_KEXEC_CORE | |
| 78 | +static atomic_t waiting_for_crash_ipi = ATOMIC_INIT(0); | |
| 79 | + | |
| 80 | +static inline void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs) | |
| 81 | +{ | |
| 82 | + crash_save_cpu(regs, cpu); | |
| 83 | + | |
| 84 | + atomic_dec(&waiting_for_crash_ipi); | |
| 85 | + | |
| 86 | + local_irq_disable(); | |
| 87 | + | |
| 88 | +#ifdef CONFIG_HOTPLUG_CPU | |
| 89 | + if (cpu_has_hotplug(cpu)) | |
| 90 | + cpu_ops[cpu]->cpu_stop(); | |
| 91 | +#endif | |
| 92 | + | |
| 93 | + for(;;) | |
| 94 | + wait_for_interrupt(); | |
| 95 | +} | |
| 96 | +#else | |
| 97 | +static inline void ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs) | |
| 98 | +{ | |
| 99 | + unreachable(); | |
| 100 | +} | |
| 101 | +#endif | |
| 102 | + | |
| 74 | 103 | static const struct riscv_ipi_ops *ipi_ops __ro_after_init; |
| 75 | 104 | |
| 76 | 105 | void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops) |
| @@ -124,8 +153,9 @@ void arch_irq_work_raise(void) · 47 unmodified lines | ||
| 124 | 153 | |
| 125 | 154 | void handle_IPI(struct pt_regs *regs) |
| 126 | 155 | { |
| 127 | − unsigned long *pending_ipis = &ipi_data[smp_processor_id()].bits; | |
| 128 | − unsigned long *stats = ipi_data[smp_processor_id()].stats; | |
| 156 | + unsigned int cpu = smp_processor_id(); | |
| 157 | + unsigned long *pending_ipis = &ipi_data[cpu].bits; | |
| 158 | + unsigned long *stats = ipi_data[cpu].stats; | |
| 129 | 159 | |
| 130 | 160 | riscv_clear_ipi(); |
| 131 | 161 | |
| @@ -154,6 +184,10 @@ void handle_IPI(struct pt_regs *regs) · 22 unmodified lines | ||
| 154 | 184 | ipi_stop(); |
| 155 | 185 | } |
| 156 | 186 | |
| 187 | + if (ops & (1 << IPI_CPU_CRASH_STOP)) { | |
| 188 | + ipi_cpu_crash_stop(cpu, get_irq_regs()); | |
| 189 | + } | |
| 190 | + | |
| 157 | 191 | if (ops & (1 << IPI_IRQ_WORK)) { |
| 158 | 192 | stats[IPI_IRQ_WORK]++; |
| 159 | 193 | irq_work_run(); |
| @@ -176,6 +210,7 @@ static const char * const ipi_names[] = { · 16 unmodified lines | ||
| 176 | 210 | [IPI_RESCHEDULE] = "Rescheduling interrupts", |
| 177 | 211 | [IPI_CALL_FUNC] = "Function call interrupts", |
| 178 | 212 | [IPI_CPU_STOP] = "CPU stop interrupts", |
| 213 | + [IPI_CPU_CRASH_STOP] = "CPU stop (for crash dump) interrupts", | |
| 179 | 214 | [IPI_IRQ_WORK] = "IRQ work interrupts", |
| 180 | 215 | [IPI_TIMER] = "Timer broadcast interrupts", |
| 181 | 216 | }; |
| @@ -235,6 +270,64 @@ void smp_send_stop(void) · 53 unmodified lines | ||
| 235 | 270 | cpumask_pr_args(cpu_online_mask)); |
| 236 | 271 | } |
| 237 | 272 | |
| 273 | +#ifdef CONFIG_KEXEC_CORE | |
| 274 | +/* | |
| 275 | + * The number of CPUs online, not counting this CPU (which may not be | |
| 276 | + * fully online and so not counted in num_online_cpus()). | |
| 277 | + */ | |
| 278 | +static inline unsigned int num_other_online_cpus(void) | |
| 279 | +{ | |
| 280 | + unsigned int this_cpu_online = cpu_online(smp_processor_id()); | |
| 281 | + | |
| 282 | + return num_online_cpus() - this_cpu_online; | |
| 283 | +} | |
| 284 | + | |
| 285 | +void crash_smp_send_stop(void) | |
| 286 | +{ | |
| 287 | + static int cpus_stopped; | |
| 288 | + cpumask_t mask; | |
| 289 | + unsigned long timeout; | |
| 290 | + | |
| 291 | + /* | |
| 292 | + * This function can be called twice in panic path, but obviously | |
| 293 | + * we execute this only once. | |
| 294 | + */ | |
| 295 | + if (cpus_stopped) | |
| 296 | + return; | |
| 297 | + | |
| 298 | + cpus_stopped = 1; | |
| 299 | + | |
| 300 | + /* | |
| 301 | + * If this cpu is the only one alive at this point in time, online or | |
| 302 | + * not, there are no stop messages to be sent around, so just back out. | |
| 303 | + */ | |
| 304 | + if (num_other_online_cpus() == 0) | |
| 305 | + return; | |
| 306 | + | |
| 307 | + cpumask_copy(&mask, cpu_online_mask); | |
| 308 | + cpumask_clear_cpu(smp_processor_id(), &mask); | |
| 309 | + | |
| 310 | + atomic_set(&waiting_for_crash_ipi, num_other_online_cpus()); | |
| 311 | + | |
| 312 | + pr_crit("SMP: stopping secondary CPUs\n"); | |
| 313 | + send_ipi_mask(&mask, IPI_CPU_CRASH_STOP); | |
| 314 | + | |
| 315 | + /* Wait up to one second for other CPUs to stop */ | |
| 316 | + timeout = USEC_PER_SEC; | |
| 317 | + while ((atomic_read(&waiting_for_crash_ipi) > 0) && timeout--) | |
| 318 | + udelay(1); | |
| 319 | + | |
| 320 | + if (atomic_read(&waiting_for_crash_ipi) > 0) | |
| 321 | + pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", | |
| 322 | + cpumask_pr_args(&mask)); | |
| 323 | +} | |
| 324 | + | |
| 325 | +bool smp_crash_stop_failed(void) | |
| 326 | +{ | |
| 327 | + return (atomic_read(&waiting_for_crash_ipi) > 0); | |
| 328 | +} | |
| 329 | +#endif | |
| 330 | + | |
| 238 | 331 | void smp_send_reschedule(int cpu) |
| 239 | 332 | { |
| 240 | 333 | send_ipi_single(cpu, IPI_RESCHEDULE); |
| @@ -221,11 +221,29 @@ asmlinkage unsigned long get_overflow_stack(void) · 220 unmodified lines | ||
| 221 | 221 | OVERFLOW_STACK_SIZE; |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | +/* | |
| 225 | + * A pseudo spinlock to protect the shadow stack from being used by multiple | |
| 226 | + * harts concurrently. This isn't a real spinlock because the lock side must | |
| 227 | + * be taken without a valid stack and only a single register, it's only taken | |
| 228 | + * while in the process of panicing anyway so the performance and error | |
| 229 | + * checking a proper spinlock gives us doesn't matter. | |
| 230 | + */ | |
| 231 | +unsigned long spin_shadow_stack; | |
| 232 | + | |
| 224 | 233 | asmlinkage void handle_bad_stack(struct pt_regs *regs) |
| 225 | 234 | { |
| 226 | 235 | unsigned long tsk_stk = (unsigned long)current->stack; |
| 227 | 236 | unsigned long ovf_stk = (unsigned long)this_cpu_ptr(overflow_stack); |
| 228 | 237 | |
| 238 | + /* | |
| 239 | + * We're done with the shadow stack by this point, as we're on the | |
| 240 | + * overflow stack. Tell any other concurrent overflowing harts that | |
| 241 | + * they can proceed with panicing by releasing the pseudo-spinlock. | |
| 242 | + * | |
| 243 | + * This pairs with an amoswap.aq in handle_kernel_stack_overflow. | |
| 244 | + */ | |
| 245 | + smp_store_release(&spin_shadow_stack, 0); | |
| 246 | + | |
| 229 | 247 | console_verbose(); |
| 230 | 248 | |
| 231 | 249 | pr_emerg("Insufficient stack space to handle exception!\n"); |
| @@ -17,6 +17,7 @@ vdso-syms += flush_icache · 16 unmodified lines | ||
| 17 | 17 | obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o |
| 18 | 18 | |
| 19 | 19 | ccflags-y := -fno-stack-protector |
| 20 | +ccflags-y += -DDISABLE_BRANCH_PROFILING | |
| 20 | 21 | |
| 21 | 22 | ifneq ($(c-gettimeofday-y),) |
| 22 | 23 | CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y) |
| @@ -28,9 +29,12 @@ obj-vdso := $(addprefix $(obj)/, $(obj-vdso)) · 5 unmodified lines | ||
| 28 | 29 | |
| 29 | 30 | obj-y += vdso.o |
| 30 | 31 | CPPFLAGS_vdso.lds += -P -C -U$(ARCH) |
| 32 | +ifneq ($(filter vgettimeofday, $(vdso-syms)),) | |
| 33 | +CPPFLAGS_vdso.lds += -DHAS_VGETTIMEOFDAY | |
| 34 | +endif | |
| 31 | 35 | |
| 32 | 36 | # Disable -pg to prevent insert call site |
| 33 | −CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os | |
| 37 | +CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) | |
| 34 | 38 | |
| 35 | 39 | # Disable profiling and instrumentation for VDSO code |
| 36 | 40 | GCOV_PROFILE := n |
| @@ -68,9 +68,11 @@ VERSION · 67 unmodified lines | ||
| 68 | 68 | LINUX_4.15 { |
| 69 | 69 | global: |
| 70 | 70 | __vdso_rt_sigreturn; |
| 71 | +#ifdef HAS_VGETTIMEOFDAY | |
| 71 | 72 | __vdso_gettimeofday; |
| 72 | 73 | __vdso_clock_gettime; |
| 73 | 74 | __vdso_clock_getres; |
| 75 | +#endif | |
| 74 | 76 | __vdso_getcpu; |
| 75 | 77 | __vdso_flush_icache; |
| 76 | 78 | local: *; |
| @@ -262,7 +262,6 @@ static void __init setup_bootmem(void) · 261 unmodified lines | ||
| 262 | 262 | memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va)); |
| 263 | 263 | } |
| 264 | 264 | |
| 265 | − early_init_fdt_scan_reserved_mem(); | |
| 266 | 265 | dma_contiguous_reserve(dma32_phys_limit); |
| 267 | 266 | if (IS_ENABLED(CONFIG_64BIT)) |
| 268 | 267 | hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT); |
| @@ -568,8 +568,7 @@ config EXPOLINE_FULL · 567 unmodified lines | ||
| 568 | 568 | endchoice |
| 569 | 569 | |
| 570 | 570 | config RELOCATABLE |
| 571 | − bool "Build a relocatable kernel" | |
| 572 | − default y | |
| 571 | + def_bool y | |
| 573 | 572 | help |
| 574 | 573 | This builds a kernel image that retains relocation information |
| 575 | 574 | so it can be loaded at an arbitrary address. |
| @@ -578,10 +577,11 @@ config RELOCATABLE · 2 unmodified lines | ||
| 578 | 577 | bootup process. |
| 579 | 578 | The relocations make the kernel image about 15% larger (compressed |
| 580 | 579 | 10%), but are discarded at runtime. |
| 580 | + Note: this option exists only for documentation purposes, please do | |
| 581 | + not remove it. | |
| 581 | 582 | |
| 582 | 583 | config RANDOMIZE_BASE |
| 583 | 584 | bool "Randomize the address of the kernel image (KASLR)" |
| 584 | − depends on RELOCATABLE | |
| 585 | 585 | default y |
| 586 | 586 | help |
| 587 | 587 | In support of Kernel Address Space Layout Randomization (KASLR), |
| @@ -14,10 +14,8 @@ KBUILD_AFLAGS_MODULE += -fPIC · 13 unmodified lines | ||
| 14 | 14 | KBUILD_CFLAGS_MODULE += -fPIC |
| 15 | 15 | KBUILD_AFLAGS += -m64 |
| 16 | 16 | KBUILD_CFLAGS += -m64 |
| 17 | −ifeq ($(CONFIG_RELOCATABLE),y) | |
| 18 | 17 | KBUILD_CFLAGS += -fPIE |
| 19 | 18 | LDFLAGS_vmlinux := -pie |
| 20 | −endif | |
| 21 | 19 | aflags_dwarf := -Wa,-gdwarf-2 |
| 22 | 20 | KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__ |
| 23 | 21 | ifndef CONFIG_AS_IS_LLVM |
| @@ -37,9 +37,8 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o |
| 39 | 39 | obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o |
| 40 | −obj-y += version.o pgm_check_info.o ctype.o ipl_data.o | |
| 40 | +obj-y += version.o pgm_check_info.o ctype.o ipl_data.o machine_kexec_reloc.o | |
| 41 | 41 | obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o |
| 42 | −obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o | |
| 43 | 42 | obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o |
| 44 | 43 | obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o |
| 45 | 44 | obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o |
| @@ -291,8 +291,7 @@ void startup_kernel(void) · 290 unmodified lines | ||
| 291 | 291 | |
| 292 | 292 | clear_bss_section(); |
| 293 | 293 | copy_bootdata(); |
| 294 | − if (IS_ENABLED(CONFIG_RELOCATABLE)) | |
| 295 | − handle_relocs(__kaslr_offset); | |
| 294 | + handle_relocs(__kaslr_offset); | |
| 296 | 295 | |
| 297 | 296 | if (__kaslr_offset) { |
| 298 | 297 | /* |
| @@ -0,0 +1 @@ | ||
| 1 | +CONFIG_DEBUG_INFO_BTF=y | |
| @@ -723,52 +723,42 @@ CONFIG_CRYPTO_ECDSA=m · 722 unmodified lines | ||
| 723 | 723 | CONFIG_CRYPTO_ECRDSA=m |
| 724 | 724 | CONFIG_CRYPTO_SM2=m |
| 725 | 725 | CONFIG_CRYPTO_CURVE25519=m |
| 726 | −CONFIG_CRYPTO_GCM=y | |
| 727 | −CONFIG_CRYPTO_CHACHA20POLY1305=m | |
| 728 | −CONFIG_CRYPTO_AEGIS128=m | |
| 729 | −CONFIG_CRYPTO_SEQIV=y | |
| 730 | −CONFIG_CRYPTO_CFB=m | |
| 731 | −CONFIG_CRYPTO_LRW=m | |
| 732 | −CONFIG_CRYPTO_PCBC=m | |
| 733 | −CONFIG_CRYPTO_KEYWRAP=m | |
| 734 | −CONFIG_CRYPTO_ADIANTUM=m | |
| 735 | −CONFIG_CRYPTO_HCTR2=m | |
| 736 | −CONFIG_CRYPTO_XCBC=m | |
| 737 | −CONFIG_CRYPTO_VMAC=m | |
| 738 | −CONFIG_CRYPTO_CRC32=m | |
| 739 | −CONFIG_CRYPTO_CRC32_S390=y | |
| 740 | −CONFIG_CRYPTO_MD4=m | |
| 741 | −CONFIG_CRYPTO_MD5=y | |
| 742 | −CONFIG_CRYPTO_MICHAEL_MIC=m | |
| 743 | −CONFIG_CRYPTO_RMD160=m | |
| 744 | −CONFIG_CRYPTO_SHA512_S390=m | |
| 745 | −CONFIG_CRYPTO_SHA1_S390=m | |
| 746 | −CONFIG_CRYPTO_SHA256_S390=m | |
| 747 | −CONFIG_CRYPTO_SHA3=m | |
| 748 | −CONFIG_CRYPTO_SHA3_256_S390=m | |
| 749 | −CONFIG_CRYPTO_SHA3_512_S390=m | |
| 750 | −CONFIG_CRYPTO_SM3_GENERIC=m | |
| 751 | −CONFIG_CRYPTO_WP512=m | |
| 752 | −CONFIG_CRYPTO_GHASH_S390=m | |
| 753 | 726 | CONFIG_CRYPTO_AES_TI=m |
| 754 | −CONFIG_CRYPTO_AES_S390=m | |
| 755 | 727 | CONFIG_CRYPTO_ANUBIS=m |
| 756 | −CONFIG_CRYPTO_ARC4=m | |
| 728 | +CONFIG_CRYPTO_ARIA=m | |
| 757 | 729 | CONFIG_CRYPTO_BLOWFISH=m |
| 758 | 730 | CONFIG_CRYPTO_CAMELLIA=m |
| 759 | 731 | CONFIG_CRYPTO_CAST5=m |
| 760 | 732 | CONFIG_CRYPTO_CAST6=m |
| 761 | 733 | CONFIG_CRYPTO_DES=m |
| 762 | −CONFIG_CRYPTO_DES_S390=m | |
| 763 | 734 | CONFIG_CRYPTO_FCRYPT=m |
| 764 | 735 | CONFIG_CRYPTO_KHAZAD=m |
| 765 | −CONFIG_CRYPTO_CHACHA_S390=m | |
| 766 | 736 | CONFIG_CRYPTO_SEED=m |
| 767 | −CONFIG_CRYPTO_ARIA=m | |
| 768 | 737 | CONFIG_CRYPTO_SERPENT=m |
| 769 | 738 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 770 | 739 | CONFIG_CRYPTO_TEA=m |
| 771 | 740 | CONFIG_CRYPTO_TWOFISH=m |
| 741 | +CONFIG_CRYPTO_ADIANTUM=m | |
| 742 | +CONFIG_CRYPTO_ARC4=m | |
| 743 | +CONFIG_CRYPTO_CFB=m | |
| 744 | +CONFIG_CRYPTO_HCTR2=m | |
| 745 | +CONFIG_CRYPTO_KEYWRAP=m | |
| 746 | +CONFIG_CRYPTO_LRW=m | |
| 747 | +CONFIG_CRYPTO_PCBC=m | |
| 748 | +CONFIG_CRYPTO_AEGIS128=m | |
| 749 | +CONFIG_CRYPTO_CHACHA20POLY1305=m | |
| 750 | +CONFIG_CRYPTO_GCM=y | |
| 751 | +CONFIG_CRYPTO_SEQIV=y | |
| 752 | +CONFIG_CRYPTO_MD4=m | |
| 753 | +CONFIG_CRYPTO_MD5=y | |
| 754 | +CONFIG_CRYPTO_MICHAEL_MIC=m | |
| 755 | +CONFIG_CRYPTO_RMD160=m | |
| 756 | +CONFIG_CRYPTO_SHA3=m | |
| 757 | +CONFIG_CRYPTO_SM3_GENERIC=m | |
| 758 | +CONFIG_CRYPTO_VMAC=m | |
| 759 | +CONFIG_CRYPTO_WP512=m | |
| 760 | +CONFIG_CRYPTO_XCBC=m | |
| 761 | +CONFIG_CRYPTO_CRC32=m | |
| 772 | 762 | CONFIG_CRYPTO_842=m |
| 773 | 763 | CONFIG_CRYPTO_LZ4=m |
| 774 | 764 | CONFIG_CRYPTO_LZ4HC=m |
| @@ -779,6 +769,16 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m · 4 unmodified lines | ||
| 779 | 769 | CONFIG_CRYPTO_USER_API_RNG=m |
| 780 | 770 | CONFIG_CRYPTO_USER_API_AEAD=m |
| 781 | 771 | CONFIG_CRYPTO_STATS=y |
| 772 | +CONFIG_CRYPTO_CRC32_S390=y | |
| 773 | +CONFIG_CRYPTO_SHA512_S390=m | |
| 774 | +CONFIG_CRYPTO_SHA1_S390=m | |
| 775 | +CONFIG_CRYPTO_SHA256_S390=m | |
| 776 | +CONFIG_CRYPTO_SHA3_256_S390=m | |
| 777 | +CONFIG_CRYPTO_SHA3_512_S390=m | |
| 778 | +CONFIG_CRYPTO_GHASH_S390=m | |
| 779 | +CONFIG_CRYPTO_AES_S390=m | |
| 780 | +CONFIG_CRYPTO_DES_S390=m | |
| 781 | +CONFIG_CRYPTO_CHACHA_S390=m | |
| 782 | 782 | CONFIG_ZCRYPT=m |
| 783 | 783 | CONFIG_PKEY=m |
| 784 | 784 | CONFIG_CRYPTO_PAES_S390=m |
| @@ -797,7 +797,6 @@ CONFIG_CMA_SIZE_MBYTES=0 · 12 unmodified lines | ||
| 797 | 797 | CONFIG_PRINTK_TIME=y |
| 798 | 798 | CONFIG_DYNAMIC_DEBUG=y |
| 799 | 799 | CONFIG_DEBUG_INFO_DWARF4=y |
| 800 | −CONFIG_DEBUG_INFO_BTF=y | |
| 801 | 800 | CONFIG_GDB_SCRIPTS=y |
| 802 | 801 | CONFIG_HEADERS_INSTALL=y |
| 803 | 802 | CONFIG_DEBUG_SECTION_MISMATCH=y |
| @@ -707,53 +707,43 @@ CONFIG_CRYPTO_ECDSA=m · 706 unmodified lines | ||
| 707 | 707 | CONFIG_CRYPTO_ECRDSA=m |
| 708 | 708 | CONFIG_CRYPTO_SM2=m |
| 709 | 709 | CONFIG_CRYPTO_CURVE25519=m |
| 710 | −CONFIG_CRYPTO_GCM=y | |
| 711 | −CONFIG_CRYPTO_CHACHA20POLY1305=m | |
| 712 | −CONFIG_CRYPTO_AEGIS128=m | |
| 713 | −CONFIG_CRYPTO_SEQIV=y | |
| 714 | −CONFIG_CRYPTO_CFB=m | |
| 715 | −CONFIG_CRYPTO_LRW=m | |
| 716 | −CONFIG_CRYPTO_OFB=m | |
| 717 | −CONFIG_CRYPTO_PCBC=m | |
| 718 | −CONFIG_CRYPTO_KEYWRAP=m | |
| 719 | −CONFIG_CRYPTO_ADIANTUM=m | |
| 720 | −CONFIG_CRYPTO_HCTR2=m | |
| 721 | −CONFIG_CRYPTO_XCBC=m | |
| 722 | −CONFIG_CRYPTO_VMAC=m | |
| 723 | −CONFIG_CRYPTO_CRC32=m | |
| 724 | −CONFIG_CRYPTO_CRC32_S390=y | |
| 725 | −CONFIG_CRYPTO_MD4=m | |
| 726 | −CONFIG_CRYPTO_MD5=y | |
| 727 | −CONFIG_CRYPTO_MICHAEL_MIC=m | |
| 728 | −CONFIG_CRYPTO_RMD160=m | |
| 729 | −CONFIG_CRYPTO_SHA512_S390=m | |
| 730 | −CONFIG_CRYPTO_SHA1_S390=m | |
| 731 | −CONFIG_CRYPTO_SHA256_S390=m | |
| 732 | −CONFIG_CRYPTO_SHA3=m | |
| 733 | −CONFIG_CRYPTO_SHA3_256_S390=m | |
| 734 | −CONFIG_CRYPTO_SHA3_512_S390=m | |
| 735 | −CONFIG_CRYPTO_SM3_GENERIC=m | |
| 736 | −CONFIG_CRYPTO_WP512=m | |
| 737 | −CONFIG_CRYPTO_GHASH_S390=m | |
| 738 | 710 | CONFIG_CRYPTO_AES_TI=m |
| 739 | −CONFIG_CRYPTO_AES_S390=m | |
| 740 | 711 | CONFIG_CRYPTO_ANUBIS=m |
| 741 | −CONFIG_CRYPTO_ARC4=m | |
| 712 | +CONFIG_CRYPTO_ARIA=m | |
| 742 | 713 | CONFIG_CRYPTO_BLOWFISH=m |
| 743 | 714 | CONFIG_CRYPTO_CAMELLIA=m |
| 744 | 715 | CONFIG_CRYPTO_CAST5=m |
| 745 | 716 | CONFIG_CRYPTO_CAST6=m |
| 746 | 717 | CONFIG_CRYPTO_DES=m |
| 747 | −CONFIG_CRYPTO_DES_S390=m | |
| 748 | 718 | CONFIG_CRYPTO_FCRYPT=m |
| 749 | 719 | CONFIG_CRYPTO_KHAZAD=m |
| 750 | −CONFIG_CRYPTO_CHACHA_S390=m | |
| 751 | 720 | CONFIG_CRYPTO_SEED=m |
| 752 | −CONFIG_CRYPTO_ARIA=m | |
| 753 | 721 | CONFIG_CRYPTO_SERPENT=m |
| 754 | 722 | CONFIG_CRYPTO_SM4_GENERIC=m |
| 755 | 723 | CONFIG_CRYPTO_TEA=m |
| 756 | 724 | CONFIG_CRYPTO_TWOFISH=m |
| 725 | +CONFIG_CRYPTO_ADIANTUM=m | |
| 726 | +CONFIG_CRYPTO_ARC4=m | |
| 727 | +CONFIG_CRYPTO_CFB=m | |
| 728 | +CONFIG_CRYPTO_HCTR2=m | |
| 729 | +CONFIG_CRYPTO_KEYWRAP=m | |
| 730 | +CONFIG_CRYPTO_LRW=m | |
| 731 | +CONFIG_CRYPTO_OFB=m | |
| 732 | +CONFIG_CRYPTO_PCBC=m | |
| 733 | +CONFIG_CRYPTO_AEGIS128=m | |
| 734 | +CONFIG_CRYPTO_CHACHA20POLY1305=m | |
| 735 | +CONFIG_CRYPTO_GCM=y | |
| 736 | +CONFIG_CRYPTO_SEQIV=y | |
| 737 | +CONFIG_CRYPTO_MD4=m | |
| 738 | +CONFIG_CRYPTO_MD5=y | |
| 739 | +CONFIG_CRYPTO_MICHAEL_MIC=m | |
| 740 | +CONFIG_CRYPTO_RMD160=m | |
| 741 | +CONFIG_CRYPTO_SHA3=m | |
| 742 | +CONFIG_CRYPTO_SM3_GENERIC=m | |
| 743 | +CONFIG_CRYPTO_VMAC=m | |
| 744 | +CONFIG_CRYPTO_WP512=m | |
| 745 | +CONFIG_CRYPTO_XCBC=m | |
| 746 | +CONFIG_CRYPTO_CRC32=m | |
| 757 | 747 | CONFIG_CRYPTO_842=m |
| 758 | 748 | CONFIG_CRYPTO_LZ4=m |
| 759 | 749 | CONFIG_CRYPTO_LZ4HC=m |
| @@ -764,6 +754,16 @@ CONFIG_CRYPTO_USER_API_SKCIPHER=m · 4 unmodified lines | ||
| 764 | 754 | CONFIG_CRYPTO_USER_API_RNG=m |
| 765 | 755 | CONFIG_CRYPTO_USER_API_AEAD=m |
| 766 | 756 | CONFIG_CRYPTO_STATS=y |
| 757 | +CONFIG_CRYPTO_CRC32_S390=y | |
| 758 | +CONFIG_CRYPTO_SHA512_S390=m | |
| 759 | +CONFIG_CRYPTO_SHA1_S390=m | |
| 760 | +CONFIG_CRYPTO_SHA256_S390=m | |
| 761 | +CONFIG_CRYPTO_SHA3_256_S390=m | |
| 762 | +CONFIG_CRYPTO_SHA3_512_S390=m | |
| 763 | +CONFIG_CRYPTO_GHASH_S390=m | |
| 764 | +CONFIG_CRYPTO_AES_S390=m | |
| 765 | +CONFIG_CRYPTO_DES_S390=m | |
| 766 | +CONFIG_CRYPTO_CHACHA_S390=m | |
| 767 | 767 | CONFIG_ZCRYPT=m |
| 768 | 768 | CONFIG_PKEY=m |
| 769 | 769 | CONFIG_CRYPTO_PAES_S390=m |
| @@ -781,7 +781,6 @@ CONFIG_CMA_SIZE_MBYTES=0 · 11 unmodified lines | ||
| 781 | 781 | CONFIG_PRINTK_TIME=y |
| 782 | 782 | CONFIG_DYNAMIC_DEBUG=y |
| 783 | 783 | CONFIG_DEBUG_INFO_DWARF4=y |
| 784 | −CONFIG_DEBUG_INFO_BTF=y | |
| 785 | 784 | CONFIG_GDB_SCRIPTS=y |
| 786 | 785 | CONFIG_DEBUG_SECTION_MISMATCH=y |
| 787 | 786 | CONFIG_MAGIC_SYSRQ=y |
| @@ -0,0 +1,3 @@ | ||
| 1 | +CONFIG_KASAN=y | |
| 2 | +CONFIG_KASAN_INLINE=y | |
| 3 | +CONFIG_KASAN_VMALLOC=y | |
| @@ -74,7 +74,6 @@ CONFIG_PRINTK_TIME=y · 73 unmodified lines | ||
| 74 | 74 | # CONFIG_SYMBOLIC_ERRNAME is not set |
| 75 | 75 | CONFIG_DEBUG_KERNEL=y |
| 76 | 76 | CONFIG_DEBUG_INFO_DWARF4=y |
| 77 | −CONFIG_DEBUG_INFO_BTF=y | |
| 78 | 77 | CONFIG_DEBUG_FS=y |
| 79 | 78 | CONFIG_PANIC_ON_OOPS=y |
| 80 | 79 | # CONFIG_SCHED_DEBUG is not set |
| @@ -763,6 +763,7 @@ static inline int pmd_dirty(pmd_t pmd) · 762 unmodified lines | ||
| 763 | 763 | return (pmd_val(pmd) & _SEGMENT_ENTRY_DIRTY) != 0; |
| 764 | 764 | } |
| 765 | 765 | |
| 766 | +#define pmd_young pmd_young | |
| 766 | 767 | static inline int pmd_young(pmd_t pmd) |
| 767 | 768 | { |
| 768 | 769 | return (pmd_val(pmd) & _SEGMENT_ENTRY_YOUNG) != 0; |
| @@ -199,7 +199,16 @@ unsigned long __get_wchan(struct task_struct *p); · 198 unmodified lines | ||
| 199 | 199 | /* Has task runtime instrumentation enabled ? */ |
| 200 | 200 | #define is_ri_task(tsk) (!!(tsk)->thread.ri_cb) |
| 201 | 201 | |
| 202 | −register unsigned long current_stack_pointer asm("r15"); | |
| 202 | +/* avoid using global register due to gcc bug in versions < 8.4 */ | |
| 203 | +#define current_stack_pointer (__current_stack_pointer()) | |
| 204 | + | |
| 205 | +static __always_inline unsigned long __current_stack_pointer(void) | |
| 206 | +{ | |
| 207 | + unsigned long sp; | |
| 208 | + | |
| 209 | + asm volatile("lgr %0,15" : "=d" (sp)); | |
| 210 | + return sp; | |
| 211 | +} | |
| 203 | 212 | |
| 204 | 213 | static __always_inline unsigned short stap(void) |
| 205 | 214 | { |
| @@ -46,7 +46,7 @@ struct save_area { · 45 unmodified lines | ||
| 46 | 46 | u64 fprs[16]; |
| 47 | 47 | u32 fpc; |
| 48 | 48 | u32 prefix; |
| 49 | − u64 todpreg; | |
| 49 | + u32 todpreg; | |
| 50 | 50 | u64 timer; |
| 51 | 51 | u64 todcmp; |
| 52 | 52 | u64 vxrs_low[16]; |
| @@ -1207,6 +1207,8 @@ static int kvm_s390_vm_get_migration(struct kvm *kvm, · 1206 unmodified lines | ||
| 1207 | 1207 | return 0; |
| 1208 | 1208 | } |
| 1209 | 1209 | |
| 1210 | +static void __kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod); | |
| 1211 | + | |
| 1210 | 1212 | static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr) |
| 1211 | 1213 | { |
| 1212 | 1214 | struct kvm_s390_vm_tod_clock gtod; |
| @@ -1216,7 +1218,7 @@ static int kvm_s390_set_tod_ext(struct kvm *kvm, struct kvm_device_attr *attr) · 3 unmodified lines | ||
| 1216 | 1218 | |
| 1217 | 1219 | if (!test_kvm_facility(kvm, 139) && gtod.epoch_idx) |
| 1218 | 1220 | return -EINVAL; |
| 1219 | − kvm_s390_set_tod_clock(kvm, >od); | |
| 1221 | + __kvm_s390_set_tod_clock(kvm, >od); | |
| 1220 | 1222 | |
| 1221 | 1223 | VM_EVENT(kvm, 3, "SET: TOD extension: 0x%x, TOD base: 0x%llx", |
| 1222 | 1224 | gtod.epoch_idx, gtod.tod); |
| @@ -1247,7 +1249,7 @@ static int kvm_s390_set_tod_low(struct kvm *kvm, struct kvm_device_attr *attr) · 24 unmodified lines | ||
| 1247 | 1249 | sizeof(gtod.tod))) |
| 1248 | 1250 | return -EFAULT; |
| 1249 | 1251 | |
| 1250 | − kvm_s390_set_tod_clock(kvm, >od); | |
| 1252 | + __kvm_s390_set_tod_clock(kvm, >od); | |
| 1251 | 1253 | VM_EVENT(kvm, 3, "SET: TOD base: 0x%llx", gtod.tod); |
| 1252 | 1254 | return 0; |
| 1253 | 1255 | } |
| @@ -1259,6 +1261,16 @@ static int kvm_s390_set_tod(struct kvm *kvm, struct kvm_device_attr *attr) · 5 unmodified lines | ||
| 1259 | 1261 | if (attr->flags) |
| 1260 | 1262 | return -EINVAL; |
| 1261 | 1263 | |
| 1264 | + mutex_lock(&kvm->lock); | |
| 1265 | + /* | |
| 1266 | + * For protected guests, the TOD is managed by the ultravisor, so trying | |
| 1267 | + * to change it will never bring the expected results. | |
| 1268 | + */ | |
| 1269 | + if (kvm_s390_pv_is_protected(kvm)) { | |
| 1270 | + ret = -EOPNOTSUPP; | |
| 1271 | + goto out_unlock; | |
| 1272 | + } | |
| 1273 | + | |
| 1262 | 1274 | switch (attr->attr) { |
| 1263 | 1275 | case KVM_S390_VM_TOD_EXT: |
| 1264 | 1276 | ret = kvm_s390_set_tod_ext(kvm, attr); |
| @@ -1273,6 +1285,9 @@ static int kvm_s390_set_tod(struct kvm *kvm, struct kvm_device_attr *attr) · 8 unmodified lines | ||
| 1273 | 1285 | ret = -ENXIO; |
| 1274 | 1286 | break; |
| 1275 | 1287 | } |
| 1288 | + | |
| 1289 | +out_unlock: | |
| 1290 | + mutex_unlock(&kvm->lock); | |
| 1276 | 1291 | return ret; |
| 1277 | 1292 | } |
| 1278 | 1293 | |
| @@ -4377,13 +4392,6 @@ static void __kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_t · 3098 unmodified lines | ||
| 4377 | 4392 | preempt_enable(); |
| 4378 | 4393 | } |
| 4379 | 4394 | |
| 4380 | −void kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod) | |
| 4381 | −{ | |
| 4382 | − mutex_lock(&kvm->lock); | |
| 4383 | − __kvm_s390_set_tod_clock(kvm, gtod); | |
| 4384 | − mutex_unlock(&kvm->lock); | |
| 4385 | −} | |
| 4386 | − | |
| 4387 | 4395 | int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod) |
| 4388 | 4396 | { |
| 4389 | 4397 | if (!mutex_trylock(&kvm->lock)) |
| @@ -363,7 +363,6 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu); · 362 unmodified lines | ||
| 363 | 363 | int kvm_s390_handle_sigp_pei(struct kvm_vcpu *vcpu); |
| 364 | 364 | |
| 365 | 365 | /* implemented in kvm-s390.c */ |
| 366 | −void kvm_s390_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod); | |
| 367 | 366 | int kvm_s390_try_set_tod_clock(struct kvm *kvm, const struct kvm_s390_vm_tod_clock *gtod); |
| 368 | 367 | long kvm_arch_fault_in_page(struct kvm_vcpu *vcpu, gpa_t gpa, int writable); |
| 369 | 368 | int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); |
| @@ -126,7 +126,7 @@ int kvm_s390_pci_aen_init(u8 nisc) · 125 unmodified lines | ||
| 126 | 126 | return -EPERM; |
| 127 | 127 | |
| 128 | 128 | mutex_lock(&aift->aift_lock); |
| 129 | − aift->kzdev = kcalloc(ZPCI_NR_DEVICES, sizeof(struct kvm_zdev), | |
| 129 | + aift->kzdev = kcalloc(ZPCI_NR_DEVICES, sizeof(struct kvm_zdev *), | |
| 130 | 130 | GFP_KERNEL); |
| 131 | 131 | if (!aift->kzdev) { |
| 132 | 132 | rc = -ENOMEM; |
| @@ -693,6 +693,7 @@ static inline unsigned long pmd_dirty(pmd_t pmd) · 692 unmodified lines | ||
| 693 | 693 | return pte_dirty(pte); |
| 694 | 694 | } |
| 695 | 695 | |
| 696 | +#define pmd_young pmd_young | |
| 696 | 697 | static inline unsigned long pmd_young(pmd_t pmd) |
| 697 | 698 | { |
| 698 | 699 | pte_t pte = __pte(pmd_val(pmd)); |
| @@ -83,7 +83,7 @@ cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin \ · 82 unmodified lines | ||
| 83 | 83 | |
| 84 | 84 | $(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE |
| 85 | 85 | $(call if_changed,image) |
| 86 | − @$(kecho) 'Kernel: $@ is ready' ' (#'`cat .version`')' | |
| 86 | + @$(kecho) 'Kernel: $@ is ready' ' (#'$(or $(KBUILD_BUILD_VERSION),`cat .version`)')' | |
| 87 | 87 | |
| 88 | 88 | OBJCOPYFLAGS_vmlinux.bin := -O binary -R .note -R .comment -S |
| 89 | 89 | $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE |
| @@ -34,6 +34,8 @@ · 33 unmodified lines | ||
| 34 | 34 | #define VE_GET_PORT_NUM(e) ((e) >> 16) |
| 35 | 35 | #define VE_IS_IO_STRING(e) ((e) & BIT(4)) |
| 36 | 36 | |
| 37 | +#define ATTR_SEPT_VE_DISABLE BIT(28) | |
| 38 | + | |
| 37 | 39 | /* |
| 38 | 40 | * Wrapper for standard use of __tdx_hypercall with no output aside from |
| 39 | 41 | * return code. |
| @@ -98,10 +100,11 @@ static inline void tdx_module_call(u64 fn, u64 rcx, u64 rdx, u64 r8, u64 r9, · 58 unmodified lines | ||
| 98 | 100 | panic("TDCALL %lld failed (Buggy TDX module!)\n", fn); |
| 99 | 101 | } |
| 100 | 102 | |
| 101 | −static u64 get_cc_mask(void) | |
| 103 | +static void tdx_parse_tdinfo(u64 *cc_mask) | |
| 102 | 104 | { |
| 103 | 105 | struct tdx_module_output out; |
| 104 | 106 | unsigned int gpa_width; |
| 107 | + u64 td_attr; | |
| 105 | 108 | |
| 106 | 109 | /* |
| 107 | 110 | * TDINFO TDX module call is used to get the TD execution environment |
| @@ -109,19 +112,27 @@ static u64 get_cc_mask(void) · 1 unmodified line | ||
| 109 | 112 | * information, etc. More details about the ABI can be found in TDX |
| 110 | 113 | * Guest-Host-Communication Interface (GHCI), section 2.4.2 TDCALL |
| 111 | 114 | * [TDG.VP.INFO]. |
| 115 | + */ | |
| 116 | + tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out); | |
| 117 | + | |
| 118 | + /* | |
| 119 | + * The highest bit of a guest physical address is the "sharing" bit. | |
| 120 | + * Set it for shared pages and clear it for private pages. | |
| 112 | 121 | * |
| 113 | 122 | * The GPA width that comes out of this call is critical. TDX guests |
| 114 | 123 | * can not meaningfully run without it. |
| 115 | 124 | */ |
| 116 | − tdx_module_call(TDX_GET_INFO, 0, 0, 0, 0, &out); | |
| 117 | − | |
| 118 | 125 | gpa_width = out.rcx & GENMASK(5, 0); |
| 126 | + *cc_mask = BIT_ULL(gpa_width - 1); | |
| 119 | 127 | |
| 120 | 128 | /* |
| 121 | − * The highest bit of a guest physical address is the "sharing" bit. | |
| 122 | − * Set it for shared pages and clear it for private pages. | |
| 129 | + * The kernel can not handle #VE's when accessing normal kernel | |
| 130 | + * memory. Ensure that no #VE will be delivered for accesses to | |
| 131 | + * TD-private memory. Only VMM-shared memory (MMIO) will #VE. | |
| 123 | 132 | */ |
| 124 | − return BIT_ULL(gpa_width - 1); | |
| 133 | + td_attr = out.rdx; | |
| 134 | + if (!(td_attr & ATTR_SEPT_VE_DISABLE)) | |
| 135 | + panic("TD misconfiguration: SEPT_VE_DISABLE attibute must be set.\n"); | |
| 125 | 136 | } |
| 126 | 137 | |
| 127 | 138 | /* |
| @@ -758,7 +769,7 @@ void __init tdx_early_init(void) · 630 unmodified lines | ||
| 758 | 769 | setup_force_cpu_cap(X86_FEATURE_TDX_GUEST); |
| 759 | 770 | |
| 760 | 771 | cc_set_vendor(CC_VENDOR_INTEL); |
| 761 | − cc_mask = get_cc_mask(); | |
| 772 | + tdx_parse_tdinfo(&cc_mask); | |
| 762 | 773 | cc_set_mask(cc_mask); |
| 763 | 774 | |
| 764 | 775 | /* |
| @@ -861,8 +861,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs) · 860 unmodified lines | ||
| 861 | 861 | pmu_enabled = cpuc->enabled; |
| 862 | 862 | cpuc->enabled = 0; |
| 863 | 863 | |
| 864 | − /* stop everything (includes BRS) */ | |
| 865 | − amd_pmu_disable_all(); | |
| 864 | + amd_brs_disable_all(); | |
| 866 | 865 | |
| 867 | 866 | /* Drain BRS is in use (could be inactive) */ |
| 868 | 867 | if (cpuc->lbr_users) |
| @@ -873,7 +872,7 @@ static int amd_pmu_handle_irq(struct pt_regs *regs) · 4 unmodified lines | ||
| 873 | 872 | |
| 874 | 873 | cpuc->enabled = pmu_enabled; |
| 875 | 874 | if (pmu_enabled) |
| 876 | − amd_pmu_enable_all(0); | |
| 875 | + amd_brs_enable_all(); | |
| 877 | 876 | |
| 878 | 877 | return amd_pmu_adjust_nmi_window(handled); |
| 879 | 878 | } |
| @@ -553,6 +553,7 @@ static void uncore_clean_online(void) · 552 unmodified lines | ||
| 553 | 553 | |
| 554 | 554 | hlist_for_each_entry_safe(uncore, n, &uncore_unused_list, node) { |
| 555 | 555 | hlist_del(&uncore->node); |
| 556 | + kfree(uncore->events); | |
| 556 | 557 | kfree(uncore); |
| 557 | 558 | } |
| 558 | 559 | } |
| @@ -4911,6 +4911,7 @@ static const struct x86_cpu_desc isolation_ucodes[] = { · 4910 unmodified lines | ||
| 4911 | 4911 | INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 5, 0x00000000), |
| 4912 | 4912 | INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 6, 0x00000000), |
| 4913 | 4913 | INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 7, 0x00000000), |
| 4914 | + INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_X, 11, 0x00000000), | |
| 4914 | 4915 | INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE_L, 3, 0x0000007c), |
| 4915 | 4916 | INTEL_CPU_DESC(INTEL_FAM6_SKYLAKE, 3, 0x0000007c), |
| 4916 | 4917 | INTEL_CPU_DESC(INTEL_FAM6_KABYLAKE, 9, 0x0000004e), |
| @@ -982,8 +982,13 @@ struct event_constraint intel_icl_pebs_event_constraints[] = { · 981 unmodified lines | ||
| 982 | 982 | INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL), /* SLOTS */ |
| 983 | 983 | |
| 984 | 984 | INTEL_PLD_CONSTRAINT(0x1cd, 0xff), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ |
| 985 | − INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x1d0, 0xf), /* MEM_INST_RETIRED.LOAD */ | |
| 986 | − INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x2d0, 0xf), /* MEM_INST_RETIRED.STORE */ | |
| 985 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */ | |
| 986 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */ | |
| 987 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */ | |
| 988 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */ | |
| 989 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */ | |
| 990 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */ | |
| 991 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */ | |
| 987 | 992 | |
| 988 | 993 | INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf), /* MEM_LOAD_*_RETIRED.* */ |
| 989 | 994 | |
| @@ -1004,8 +1009,13 @@ struct event_constraint intel_spr_pebs_event_constraints[] = { · 14 unmodified lines | ||
| 1004 | 1009 | INTEL_FLAGS_EVENT_CONSTRAINT(0xc0, 0xfe), |
| 1005 | 1010 | INTEL_PLD_CONSTRAINT(0x1cd, 0xfe), |
| 1006 | 1011 | INTEL_PSD_CONSTRAINT(0x2cd, 0x1), |
| 1007 | − INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x1d0, 0xf), | |
| 1008 | − INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x2d0, 0xf), | |
| 1012 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_LOADS */ | |
| 1013 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_INST_RETIRED.STLB_MISS_STORES */ | |
| 1014 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_INST_RETIRED.LOCK_LOADS */ | |
| 1015 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_INST_RETIRED.SPLIT_LOADS */ | |
| 1016 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_INST_RETIRED.SPLIT_STORES */ | |
| 1017 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_INST_RETIRED.ALL_LOADS */ | |
| 1018 | + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_INST_RETIRED.ALL_STORES */ | |
| 1009 | 1019 | |
| 1010 | 1020 | INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf), |
| 1011 | 1021 | |
| @@ -1263,6 +1263,15 @@ static int pt_buffer_try_single(struct pt_buffer *buf, int nr_pages) · 1262 unmodified lines | ||
| 1263 | 1263 | if (1 << order != nr_pages) |
| 1264 | 1264 | goto out; |
| 1265 | 1265 | |
| 1266 | + /* | |
| 1267 | + * Some processors cannot always support single range for more than | |
| 1268 | + * 4KB - refer errata TGL052, ADL037 and RPL017. Future processors might | |
| 1269 | + * also be affected, so for now rather than trying to keep track of | |
| 1270 | + * which ones, just disable it for all. | |
| 1271 | + */ | |
| 1272 | + if (nr_pages > 1) | |
| 1273 | + goto out; | |
| 1274 | + | |
| 1266 | 1275 | buf->single = true; |
| 1267 | 1276 | buf->nr_pages = nr_pages; |
| 1268 | 1277 | ret = 0; |
| @@ -619,12 +619,8 @@ static int rapl_check_hw_unit(struct rapl_model *rm) · 618 unmodified lines | ||
| 619 | 619 | case RAPL_UNIT_QUIRK_INTEL_HSW: |
| 620 | 620 | rapl_hw_unit[PERF_RAPL_RAM] = 16; |
| 621 | 621 | break; |
| 622 | − /* | |
| 623 | − * SPR shares the same DRAM domain energy unit as HSW, plus it | |
| 624 | − * also has a fixed energy unit for Psys domain. | |
| 625 | − */ | |
| 622 | + /* SPR uses a fixed energy unit for Psys domain. */ | |
| 626 | 623 | case RAPL_UNIT_QUIRK_INTEL_SPR: |
| 627 | − rapl_hw_unit[PERF_RAPL_RAM] = 16; | |
| 628 | 624 | rapl_hw_unit[PERF_RAPL_PSYS] = 0; |
| 629 | 625 | break; |
| 630 | 626 | default: |
| @@ -77,7 +77,7 @@ static int hyperv_init_ghcb(void) · 76 unmodified lines | ||
| 77 | 77 | static int hv_cpu_init(unsigned int cpu) |
| 78 | 78 | { |
| 79 | 79 | union hv_vp_assist_msr_contents msr = { 0 }; |
| 80 | − struct hv_vp_assist_page **hvp = &hv_vp_assist_page[smp_processor_id()]; | |
| 80 | + struct hv_vp_assist_page **hvp = &hv_vp_assist_page[cpu]; | |
| 81 | 81 | int ret; |
| 82 | 82 | |
| 83 | 83 | ret = hv_common_cpu_init(cpu); |
| @@ -87,34 +87,32 @@ static int hv_cpu_init(unsigned int cpu) · 3 unmodified lines | ||
| 87 | 87 | if (!hv_vp_assist_page) |
| 88 | 88 | return 0; |
| 89 | 89 | |
| 90 | − if (!*hvp) { | |
| 91 | − if (hv_root_partition) { | |
| 92 | − /* | |
| 93 | − * For root partition we get the hypervisor provided VP assist | |
| 94 | − * page, instead of allocating a new page. | |
| 95 | − */ | |
| 96 | − rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); | |
| 97 | − *hvp = memremap(msr.pfn << | |
| 98 | − HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT, | |
| 99 | − PAGE_SIZE, MEMREMAP_WB); | |
| 100 | − } else { | |
| 101 | − /* | |
| 102 | − * The VP assist page is an "overlay" page (see Hyper-V TLFS's | |
| 103 | − * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed | |
| 104 | − * out to make sure we always write the EOI MSR in | |
| 105 | − * hv_apic_eoi_write() *after* the EOI optimization is disabled | |
| 106 | − * in hv_cpu_die(), otherwise a CPU may not be stopped in the | |
| 107 | − * case of CPU offlining and the VM will hang. | |
| 108 | − */ | |
| 90 | + if (hv_root_partition) { | |
| 91 | + /* | |
| 92 | + * For root partition we get the hypervisor provided VP assist | |
| 93 | + * page, instead of allocating a new page. | |
| 94 | + */ | |
| 95 | + rdmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); | |
| 96 | + *hvp = memremap(msr.pfn << HV_X64_MSR_VP_ASSIST_PAGE_ADDRESS_SHIFT, | |
| 97 | + PAGE_SIZE, MEMREMAP_WB); | |
| 98 | + } else { | |
| 99 | + /* | |
| 100 | + * The VP assist page is an "overlay" page (see Hyper-V TLFS's | |
| 101 | + * Section 5.2.1 "GPA Overlay Pages"). Here it must be zeroed | |
| 102 | + * out to make sure we always write the EOI MSR in | |
| 103 | + * hv_apic_eoi_write() *after* the EOI optimization is disabled | |
| 104 | + * in hv_cpu_die(), otherwise a CPU may not be stopped in the | |
| 105 | + * case of CPU offlining and the VM will hang. | |
| 106 | + */ | |
| 107 | + if (!*hvp) | |
| 109 | 108 | *hvp = __vmalloc(PAGE_SIZE, GFP_KERNEL | __GFP_ZERO); |
| 110 | − if (*hvp) | |
| 111 | − msr.pfn = vmalloc_to_pfn(*hvp); | |
| 112 | − } | |
| 113 | − WARN_ON(!(*hvp)); | |
| 114 | − if (*hvp) { | |
| 115 | − msr.enable = 1; | |
| 116 | − wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); | |
| 117 | − } | |
| 109 | + if (*hvp) | |
| 110 | + msr.pfn = vmalloc_to_pfn(*hvp); | |
| 111 | + | |
| 112 | + } | |
| 113 | + if (!WARN_ON(!(*hvp))) { | |
| 114 | + msr.enable = 1; | |
| 115 | + wrmsrl(HV_X64_MSR_VP_ASSIST_PAGE, msr.as_uint64); | |
| 118 | 116 | } |
| 119 | 117 | |
| 120 | 118 | return hyperv_init_ghcb(); |
| @@ -444,7 +442,7 @@ void __init hyperv_init(void) · 323 unmodified lines | ||
| 444 | 442 | |
| 445 | 443 | if (hv_root_partition) { |
| 446 | 444 | struct page *pg; |
| 447 | − void *src, *dst; | |
| 445 | + void *src; | |
| 448 | 446 | |
| 449 | 447 | /* |
| 450 | 448 | * For the root partition, the hypervisor will set up its |
| @@ -459,13 +457,11 @@ void __init hyperv_init(void) · 8 unmodified lines | ||
| 459 | 457 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| 460 | 458 | |
| 461 | 459 | pg = vmalloc_to_page(hv_hypercall_pg); |
| 462 | − dst = kmap_local_page(pg); | |
| 463 | 460 | src = memremap(hypercall_msr.guest_physical_address << PAGE_SHIFT, PAGE_SIZE, |
| 464 | 461 | MEMREMAP_WB); |
| 465 | − BUG_ON(!(src && dst)); | |
| 466 | − memcpy(dst, src, HV_HYP_PAGE_SIZE); | |
| 462 | + BUG_ON(!src); | |
| 463 | + memcpy_to_page(pg, 0, src, HV_HYP_PAGE_SIZE); | |
| 467 | 464 | memunmap(src); |
| 468 | − kunmap_local(dst); | |
| 469 | 465 | } else { |
| 470 | 466 | hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg); |
| 471 | 467 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| @@ -537,6 +533,7 @@ common_free: · 65 unmodified lines | ||
| 537 | 533 | void hyperv_cleanup(void) |
| 538 | 534 | { |
| 539 | 535 | union hv_x64_msr_hypercall_contents hypercall_msr; |
| 536 | + union hv_reference_tsc_msr tsc_msr; | |
| 540 | 537 | |
| 541 | 538 | unregister_syscore_ops(&hv_syscore_ops); |
| 542 | 539 | |
| @@ -552,12 +549,14 @@ void hyperv_cleanup(void) · 9 unmodified lines | ||
| 552 | 549 | hv_hypercall_pg = NULL; |
| 553 | 550 | |
| 554 | 551 | /* Reset the hypercall page */ |
| 555 | − hypercall_msr.as_uint64 = 0; | |
| 556 | − wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); | |
| 552 | + hypercall_msr.as_uint64 = hv_get_register(HV_X64_MSR_HYPERCALL); | |
| 553 | + hypercall_msr.enable = 0; | |
| 554 | + hv_set_register(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); | |
| 557 | 555 | |
| 558 | 556 | /* Reset the TSC page */ |
| 559 | − hypercall_msr.as_uint64 = 0; | |
| 560 | − wrmsrl(HV_X64_MSR_REFERENCE_TSC, hypercall_msr.as_uint64); | |
| 557 | + tsc_msr.as_uint64 = hv_get_register(HV_X64_MSR_REFERENCE_TSC); | |
| 558 | + tsc_msr.enable = 0; | |
| 559 | + hv_set_register(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64); | |
| 561 | 560 | } |
| 562 | 561 | |
| 563 | 562 | void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die) |
| @@ -305,6 +305,9 @@ · 304 unmodified lines | ||
| 305 | 305 | #define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */ |
| 306 | 306 | #define X86_FEATURE_RSB_VMEXIT_LITE (11*32+17) /* "" Fill RSB on VM exit when EIBRS is enabled */ |
| 307 | 307 | |
| 308 | + | |
| 309 | +#define X86_FEATURE_MSR_TSX_CTRL (11*32+20) /* "" MSR IA32_TSX_CTRL (Intel) implemented */ | |
| 310 | + | |
| 308 | 311 | /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ |
| 309 | 312 | #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */ |
| 310 | 313 | #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ |
| @@ -107,6 +107,11 @@ · 106 unmodified lines | ||
| 107 | 107 | |
| 108 | 108 | #define INTEL_FAM6_SAPPHIRERAPIDS_X 0x8F /* Golden Cove */ |
| 109 | 109 | |
| 110 | +#define INTEL_FAM6_EMERALDRAPIDS_X 0xCF | |
| 111 | + | |
| 112 | +#define INTEL_FAM6_GRANITERAPIDS_X 0xAD | |
| 113 | +#define INTEL_FAM6_GRANITERAPIDS_D 0xAE | |
| 114 | + | |
| 110 | 115 | #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ |
| 111 | 116 | #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */ |
| 112 | 117 | #define INTEL_FAM6_ALDERLAKE_N 0xBE |
| @@ -118,7 +123,7 @@ · 5 unmodified lines | ||
| 118 | 123 | #define INTEL_FAM6_METEORLAKE 0xAC |
| 119 | 124 | #define INTEL_FAM6_METEORLAKE_L 0xAA |
| 120 | 125 | |
| 121 | −/* "Small Core" Processors (Atom) */ | |
| 126 | +/* "Small Core" Processors (Atom/E-Core) */ | |
| 122 | 127 | |
| 123 | 128 | #define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */ |
| 124 | 129 | #define INTEL_FAM6_ATOM_BONNELL_MID 0x26 /* Silverthorne, Lincroft */ |
| @@ -145,6 +150,10 @@ · 20 unmodified lines | ||
| 145 | 150 | #define INTEL_FAM6_ATOM_TREMONT 0x96 /* Elkhart Lake */ |
| 146 | 151 | #define INTEL_FAM6_ATOM_TREMONT_L 0x9C /* Jasper Lake */ |
| 147 | 152 | |
| 153 | +#define INTEL_FAM6_SIERRAFOREST_X 0xAF | |
| 154 | + | |
| 155 | +#define INTEL_FAM6_GRANDRIDGE 0xB6 | |
| 156 | + | |
| 148 | 157 | /* Xeon Phi */ |
| 149 | 158 | |
| 150 | 159 | #define INTEL_FAM6_XEON_PHI_KNL 0x57 /* Knights Landing */ |
| @@ -501,7 +501,12 @@ struct kvm_pmc { · 500 unmodified lines | ||
| 501 | 501 | bool intr; |
| 502 | 502 | }; |
| 503 | 503 | |
| 504 | +/* More counters may conflict with other existing Architectural MSRs */ | |
| 505 | +#define KVM_INTEL_PMC_MAX_GENERIC 8 | |
| 506 | +#define MSR_ARCH_PERFMON_PERFCTR_MAX (MSR_ARCH_PERFMON_PERFCTR0 + KVM_INTEL_PMC_MAX_GENERIC - 1) | |
| 507 | +#define MSR_ARCH_PERFMON_EVENTSEL_MAX (MSR_ARCH_PERFMON_EVENTSEL0 + KVM_INTEL_PMC_MAX_GENERIC - 1) | |
| 504 | 508 | #define KVM_PMC_MAX_FIXED 3 |
| 509 | +#define KVM_AMD_PMC_MAX_GENERIC 6 | |
| 505 | 510 | struct kvm_pmu { |
| 506 | 511 | unsigned nr_arch_gp_counters; |
| 507 | 512 | unsigned nr_arch_fixed_counters; |
| @@ -516,7 +521,7 @@ struct kvm_pmu { · 8 unmodified lines | ||
| 516 | 521 | u64 reserved_bits; |
| 517 | 522 | u64 raw_event_mask; |
| 518 | 523 | u8 version; |
| 519 | − struct kvm_pmc gp_counters[INTEL_PMC_MAX_GENERIC]; | |
| 524 | + struct kvm_pmc gp_counters[KVM_INTEL_PMC_MAX_GENERIC]; | |
| 520 | 525 | struct kvm_pmc fixed_counters[KVM_PMC_MAX_FIXED]; |
| 521 | 526 | struct irq_work irq_work; |
| 522 | 527 | DECLARE_BITMAP(reprogram_pmi, X86_PMC_IDX_MAX); |
| @@ -535,6 +535,11 @@ · 534 unmodified lines | ||
| 535 | 535 | #define MSR_AMD64_CPUID_FN_1 0xc0011004 |
| 536 | 536 | #define MSR_AMD64_LS_CFG 0xc0011020 |
| 537 | 537 | #define MSR_AMD64_DC_CFG 0xc0011022 |
| 538 | + | |
| 539 | +#define MSR_AMD64_DE_CFG 0xc0011029 | |
| 540 | +#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT 1 | |
| 541 | +#define MSR_AMD64_DE_CFG_LFENCE_SERIALIZE BIT_ULL(MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT) | |
| 542 | + | |
| 538 | 543 | #define MSR_AMD64_BU_CFG2 0xc001102a |
| 539 | 544 | #define MSR_AMD64_IBSFETCHCTL 0xc0011030 |
| 540 | 545 | #define MSR_AMD64_IBSFETCHLINAD 0xc0011031 |
| @@ -640,9 +645,6 @@ · 99 unmodified lines | ||
| 640 | 645 | #define FAM10H_MMIO_CONF_BASE_MASK 0xfffffffULL |
| 641 | 646 | #define FAM10H_MMIO_CONF_BASE_SHIFT 20 |
| 642 | 647 | #define MSR_FAM10H_NODE_ID 0xc001100c |
| 643 | −#define MSR_F10H_DECFG 0xc0011029 | |
| 644 | −#define MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT 1 | |
| 645 | −#define MSR_F10H_DECFG_LFENCE_SERIALIZE BIT_ULL(MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT) | |
| 646 | 648 | |
| 647 | 649 | /* K8 MSRs */ |
| 648 | 650 | #define MSR_K8_TOP_MEM1 0xc001001a |
| @@ -321,7 +321,7 @@ static inline void indirect_branch_prediction_barrier(void) · 320 unmodified lines | ||
| 321 | 321 | /* The Intel SPEC CTRL MSR base value cache */ |
| 322 | 322 | extern u64 x86_spec_ctrl_base; |
| 323 | 323 | DECLARE_PER_CPU(u64, x86_spec_ctrl_current); |
| 324 | −extern void write_spec_ctrl_current(u64 val, bool force); | |
| 324 | +extern void update_spec_ctrl_cond(u64 val); | |
| 325 | 325 | extern u64 spec_ctrl_current(void); |
| 326 | 326 | |
| 327 | 327 | /* |
| @@ -139,6 +139,7 @@ static inline int pmd_dirty(pmd_t pmd) · 138 unmodified lines | ||
| 139 | 139 | return pmd_flags(pmd) & _PAGE_DIRTY; |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | +#define pmd_young pmd_young | |
| 142 | 143 | static inline int pmd_young(pmd_t pmd) |
| 143 | 144 | { |
| 144 | 145 | return pmd_flags(pmd) & _PAGE_ACCESSED; |
| @@ -1438,6 +1439,14 @@ static inline bool arch_has_hw_pte_young(void) · 1293 unmodified lines | ||
| 1438 | 1439 | return true; |
| 1439 | 1440 | } |
| 1440 | 1441 | |
| 1442 | +#ifdef CONFIG_XEN_PV | |
| 1443 | +#define arch_has_hw_nonleaf_pmd_young arch_has_hw_nonleaf_pmd_young | |
| 1444 | +static inline bool arch_has_hw_nonleaf_pmd_young(void) | |
| 1445 | +{ | |
| 1446 | + return !cpu_feature_enabled(X86_FEATURE_XENPV); | |
| 1447 | +} | |
| 1448 | +#endif | |
| 1449 | + | |
| 1441 | 1450 | #ifdef CONFIG_PAGE_TABLE_CHECK |
| 1442 | 1451 | static inline bool pte_user_accessible_page(pte_t pte) |
| 1443 | 1452 | { |
| @@ -37,7 +37,7 @@ __PV_CALLEE_SAVE_REGS_THUNK(__pv_queued_spin_unlock_slowpath, ".spinlock.text"); · 36 unmodified lines | ||
| 37 | 37 | * rsi = lockval (second argument) |
| 38 | 38 | * rdx = internal variable (set to 0) |
| 39 | 39 | */ |
| 40 | −asm (".pushsection .spinlock.text;" | |
| 40 | +asm (".pushsection .spinlock.text, \"ax\";" | |
| 41 | 41 | ".globl " PV_UNLOCK ";" |
| 42 | 42 | ".type " PV_UNLOCK ", @function;" |
| 43 | 43 | ".align 4,0x90;" |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | * Takes the guest view of SPEC_CTRL MSR as a parameter and also |
| 14 | 14 | * the guest's version of VIRT_SPEC_CTRL, if emulated. |
| 15 | 15 | */ |
| 16 | −extern void x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool guest); | |
| 16 | +extern void x86_virt_spec_ctrl(u64 guest_virt_spec_ctrl, bool guest); | |
| 17 | 17 | |
| 18 | 18 | /** |
| 19 | 19 | * x86_spec_ctrl_set_guest - Set speculation control registers for the guest |
| @@ -24,9 +24,9 @@ extern void x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bo · 4 unmodified lines | ||
| 24 | 24 | * Avoids writing to the MSR if the content/bits are the same |
| 25 | 25 | */ |
| 26 | 26 | static inline |
| 27 | −void x86_spec_ctrl_set_guest(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) | |
| 27 | +void x86_spec_ctrl_set_guest(u64 guest_virt_spec_ctrl) | |
| 28 | 28 | { |
| 29 | − x86_virt_spec_ctrl(guest_spec_ctrl, guest_virt_spec_ctrl, true); | |
| 29 | + x86_virt_spec_ctrl(guest_virt_spec_ctrl, true); | |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | 32 | /** |
| @@ -38,9 +38,9 @@ void x86_spec_ctrl_set_guest(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) · 5 unmodified lines | ||
| 38 | 38 | * Avoids writing to the MSR if the content/bits are the same |
| 39 | 39 | */ |
| 40 | 40 | static inline |
| 41 | −void x86_spec_ctrl_restore_host(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) | |
| 41 | +void x86_spec_ctrl_restore_host(u64 guest_virt_spec_ctrl) | |
| 42 | 42 | { |
| 43 | − x86_virt_spec_ctrl(guest_spec_ctrl, guest_virt_spec_ctrl, false); | |
| 43 | + x86_virt_spec_ctrl(guest_virt_spec_ctrl, false); | |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | 46 | /* AMD specific Speculative Store Bypass MSR data */ |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #ifndef _ASM_X86_SYSCALL_WRAPPER_H |
| 7 | 7 | #define _ASM_X86_SYSCALL_WRAPPER_H |
| 8 | 8 | |
| 9 | −struct pt_regs; | |
| 9 | +#include <asm/ptrace.h> | |
| 10 | 10 | |
| 11 | 11 | extern long __x64_sys_ni_syscall(const struct pt_regs *regs); |
| 12 | 12 | extern long __ia32_sys_ni_syscall(const struct pt_regs *regs); |
| @@ -19,7 +19,6 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <asm/suspend.h> |
| 20 | 20 | #include <asm/tlbflush.h> |
| 21 | 21 | #include <asm/tdx.h> |
| 22 | −#include "../kvm/vmx/vmx.h" | |
| 23 | 22 | |
| 24 | 23 | #ifdef CONFIG_XEN |
| 25 | 24 | #include <xen/interface/xen.h> |
| @@ -108,9 +107,4 @@ static void __used common(void) · 82 unmodified lines | ||
| 108 | 107 | OFFSET(TSS_sp0, tss_struct, x86_tss.sp0); |
| 109 | 108 | OFFSET(TSS_sp1, tss_struct, x86_tss.sp1); |
| 110 | 109 | OFFSET(TSS_sp2, tss_struct, x86_tss.sp2); |
| 111 | − | |
| 112 | − if (IS_ENABLED(CONFIG_KVM_INTEL)) { | |
| 113 | − BLANK(); | |
| 114 | − OFFSET(VMX_spec_ctrl, vcpu_vmx, spec_ctrl); | |
| 115 | − } | |
| 116 | 110 | } |
| @@ -770,8 +770,6 @@ static void init_amd_gh(struct cpuinfo_x86 *c) · 769 unmodified lines | ||
| 770 | 770 | set_cpu_bug(c, X86_BUG_AMD_TLB_MMATCH); |
| 771 | 771 | } |
| 772 | 772 | |
| 773 | −#define MSR_AMD64_DE_CFG 0xC0011029 | |
| 774 | − | |
| 775 | 773 | static void init_amd_ln(struct cpuinfo_x86 *c) |
| 776 | 774 | { |
| 777 | 775 | /* |
| @@ -965,8 +963,8 @@ static void init_amd(struct cpuinfo_x86 *c) · 187 unmodified lines | ||
| 965 | 963 | * msr_set_bit() uses the safe accessors, too, even if the MSR |
| 966 | 964 | * is not present. |
| 967 | 965 | */ |
| 968 | − msr_set_bit(MSR_F10H_DECFG, | |
| 969 | − MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT); | |
| 966 | + msr_set_bit(MSR_AMD64_DE_CFG, | |
| 967 | + MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT); | |
| 970 | 968 | |
| 971 | 969 | /* A serializing LFENCE stops RDTSC speculation */ |
| 972 | 970 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); |
| @@ -60,11 +60,18 @@ EXPORT_SYMBOL_GPL(x86_spec_ctrl_current); · 59 unmodified lines | ||
| 60 | 60 | |
| 61 | 61 | static DEFINE_MUTEX(spec_ctrl_mutex); |
| 62 | 62 | |
| 63 | +/* Update SPEC_CTRL MSR and its cached copy unconditionally */ | |
| 64 | +static void update_spec_ctrl(u64 val) | |
| 65 | +{ | |
| 66 | + this_cpu_write(x86_spec_ctrl_current, val); | |
| 67 | + wrmsrl(MSR_IA32_SPEC_CTRL, val); | |
| 68 | +} | |
| 69 | + | |
| 63 | 70 | /* |
| 64 | 71 | * Keep track of the SPEC_CTRL MSR value for the current task, which may differ |
| 65 | 72 | * from x86_spec_ctrl_base due to STIBP/SSB in __speculation_ctrl_update(). |
| 66 | 73 | */ |
| 67 | −void write_spec_ctrl_current(u64 val, bool force) | |
| 74 | +void update_spec_ctrl_cond(u64 val) | |
| 68 | 75 | { |
| 69 | 76 | if (this_cpu_read(x86_spec_ctrl_current) == val) |
| 70 | 77 | return; |
| @@ -75,7 +82,7 @@ void write_spec_ctrl_current(u64 val, bool force) · 4 unmodified lines | ||
| 75 | 82 | * When KERNEL_IBRS this MSR is written on return-to-user, unless |
| 76 | 83 | * forced the update can be delayed until that time. |
| 77 | 84 | */ |
| 78 | − if (force || !cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS)) | |
| 85 | + if (!cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS)) | |
| 79 | 86 | wrmsrl(MSR_IA32_SPEC_CTRL, val); |
| 80 | 87 | } |
| 81 | 88 | |
| @@ -196,22 +203,15 @@ void __init check_bugs(void) · 114 unmodified lines | ||
| 196 | 203 | } |
| 197 | 204 | |
| 198 | 205 | /* |
| 199 | − * NOTE: This function is *only* called for SVM. VMX spec_ctrl handling is | |
| 200 | − * done in vmenter.S. | |
| 206 | + * NOTE: This function is *only* called for SVM, since Intel uses | |
| 207 | + * MSR_IA32_SPEC_CTRL for SSBD. | |
| 201 | 208 | */ |
| 202 | 209 | void |
| 203 | −x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest) | |
| 210 | +x86_virt_spec_ctrl(u64 guest_virt_spec_ctrl, bool setguest) | |
| 204 | 211 | { |
| 205 | − u64 msrval, guestval = guest_spec_ctrl, hostval = spec_ctrl_current(); | |
| 212 | + u64 guestval, hostval; | |
| 206 | 213 | struct thread_info *ti = current_thread_info(); |
| 207 | 214 | |
| 208 | − if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { | |
| 209 | − if (hostval != guestval) { | |
| 210 | − msrval = setguest ? guestval : hostval; | |
| 211 | − wrmsrl(MSR_IA32_SPEC_CTRL, msrval); | |
| 212 | − } | |
| 213 | − } | |
| 214 | − | |
| 215 | 215 | /* |
| 216 | 216 | * If SSBD is not handled in MSR_SPEC_CTRL on AMD, update |
| 217 | 217 | * MSR_AMD64_L2_CFG or MSR_VIRT_SPEC_CTRL if supported. |
| @@ -1335,7 +1335,7 @@ static void __init spec_ctrl_disable_kernel_rrsba(void) · 1117 unmodified lines | ||
| 1335 | 1335 | |
| 1336 | 1336 | if (ia32_cap & ARCH_CAP_RRSBA) { |
| 1337 | 1337 | x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S; |
| 1338 | − write_spec_ctrl_current(x86_spec_ctrl_base, true); | |
| 1338 | + update_spec_ctrl(x86_spec_ctrl_base); | |
| 1339 | 1339 | } |
| 1340 | 1340 | } |
| 1341 | 1341 | |
| @@ -1457,7 +1457,7 @@ static void __init spectre_v2_select_mitigation(void) · 115 unmodified lines | ||
| 1457 | 1457 | |
| 1458 | 1458 | if (spectre_v2_in_ibrs_mode(mode)) { |
| 1459 | 1459 | x86_spec_ctrl_base |= SPEC_CTRL_IBRS; |
| 1460 | − write_spec_ctrl_current(x86_spec_ctrl_base, true); | |
| 1460 | + update_spec_ctrl(x86_spec_ctrl_base); | |
| 1461 | 1461 | } |
| 1462 | 1462 | |
| 1463 | 1463 | switch (mode) { |
| @@ -1571,7 +1571,7 @@ static void __init spectre_v2_select_mitigation(void) · 107 unmodified lines | ||
| 1571 | 1571 | static void update_stibp_msr(void * __unused) |
| 1572 | 1572 | { |
| 1573 | 1573 | u64 val = spec_ctrl_current() | (x86_spec_ctrl_base & SPEC_CTRL_STIBP); |
| 1574 | − write_spec_ctrl_current(val, true); | |
| 1574 | + update_spec_ctrl(val); | |
| 1575 | 1575 | } |
| 1576 | 1576 | |
| 1577 | 1577 | /* Update x86_spec_ctrl_base in case SMT state changed. */ |
| @@ -1804,7 +1804,7 @@ static enum ssb_mitigation __init __ssb_select_mitigation(void) · 226 unmodified lines | ||
| 1804 | 1804 | x86_amd_ssb_disable(); |
| 1805 | 1805 | } else { |
| 1806 | 1806 | x86_spec_ctrl_base |= SPEC_CTRL_SSBD; |
| 1807 | − write_spec_ctrl_current(x86_spec_ctrl_base, true); | |
| 1807 | + update_spec_ctrl(x86_spec_ctrl_base); | |
| 1808 | 1808 | } |
| 1809 | 1809 | } |
| 1810 | 1810 | |
| @@ -2055,7 +2055,7 @@ int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) · 244 unmodified lines | ||
| 2055 | 2055 | void x86_spec_ctrl_setup_ap(void) |
| 2056 | 2056 | { |
| 2057 | 2057 | if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) |
| 2058 | − write_spec_ctrl_current(x86_spec_ctrl_base, true); | |
| 2058 | + update_spec_ctrl(x86_spec_ctrl_base); | |
| 2059 | 2059 | |
| 2060 | 2060 | if (ssb_mode == SPEC_STORE_BYPASS_DISABLE) |
| 2061 | 2061 | x86_amd_ssb_disable(); |
| @@ -326,8 +326,8 @@ static void init_hygon(struct cpuinfo_x86 *c) · 325 unmodified lines | ||
| 326 | 326 | * msr_set_bit() uses the safe accessors, too, even if the MSR |
| 327 | 327 | * is not present. |
| 328 | 328 | */ |
| 329 | − msr_set_bit(MSR_F10H_DECFG, | |
| 330 | − MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT); | |
| 329 | + msr_set_bit(MSR_AMD64_DE_CFG, | |
| 330 | + MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT); | |
| 331 | 331 | |
| 332 | 332 | /* A serializing LFENCE stops RDTSC speculation */ |
| 333 | 333 | set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); |
| @@ -356,6 +356,9 @@ static int sgx_validate_offset_length(struct sgx_encl *encl, · 355 unmodified lines | ||
| 356 | 356 | if (!length || !IS_ALIGNED(length, PAGE_SIZE)) |
| 357 | 357 | return -EINVAL; |
| 358 | 358 | |
| 359 | + if (offset + length < offset) | |
| 360 | + return -EINVAL; | |
| 361 | + | |
| 359 | 362 | if (offset + length - PAGE_SIZE >= encl->size) |
| 360 | 363 | return -EINVAL; |
| 361 | 364 | |
| @@ -58,24 +58,6 @@ static void tsx_enable(void) · 57 unmodified lines | ||
| 58 | 58 | wrmsrl(MSR_IA32_TSX_CTRL, tsx); |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | −static bool tsx_ctrl_is_supported(void) | |
| 62 | −{ | |
| 63 | − u64 ia32_cap = x86_read_arch_cap_msr(); | |
| 64 | − | |
| 65 | − /* | |
| 66 | − * TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this | |
| 67 | − * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES. | |
| 68 | − * | |
| 69 | − * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a | |
| 70 | − * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES | |
| 71 | − * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get | |
| 72 | − * MSR_IA32_TSX_CTRL support even after a microcode update. Thus, | |
| 73 | − * tsx= cmdline requests will do nothing on CPUs without | |
| 74 | − * MSR_IA32_TSX_CTRL support. | |
| 75 | − */ | |
| 76 | − return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR); | |
| 77 | −} | |
| 78 | − | |
| 79 | 61 | static enum tsx_ctrl_states x86_get_tsx_auto_mode(void) |
| 80 | 62 | { |
| 81 | 63 | if (boot_cpu_has_bug(X86_BUG_TAA)) |
| @@ -135,7 +117,7 @@ static void tsx_clear_cpuid(void) · 53 unmodified lines | ||
| 135 | 117 | rdmsrl(MSR_TSX_FORCE_ABORT, msr); |
| 136 | 118 | msr |= MSR_TFA_TSX_CPUID_CLEAR; |
| 137 | 119 | wrmsrl(MSR_TSX_FORCE_ABORT, msr); |
| 138 | − } else if (tsx_ctrl_is_supported()) { | |
| 120 | + } else if (cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL)) { | |
| 139 | 121 | rdmsrl(MSR_IA32_TSX_CTRL, msr); |
| 140 | 122 | msr |= TSX_CTRL_CPUID_CLEAR; |
| 141 | 123 | wrmsrl(MSR_IA32_TSX_CTRL, msr); |
| @@ -158,7 +140,8 @@ static void tsx_dev_mode_disable(void) · 16 unmodified lines | ||
| 158 | 140 | u64 mcu_opt_ctrl; |
| 159 | 141 | |
| 160 | 142 | /* Check if RTM_ALLOW exists */ |
| 161 | − if (!boot_cpu_has_bug(X86_BUG_TAA) || !tsx_ctrl_is_supported() || | |
| 143 | + if (!boot_cpu_has_bug(X86_BUG_TAA) || | |
| 144 | + !cpu_feature_enabled(X86_FEATURE_MSR_TSX_CTRL) || | |
| 162 | 145 | !cpu_feature_enabled(X86_FEATURE_SRBDS_CTRL)) |
| 163 | 146 | return; |
| 164 | 147 | |
| @@ -191,7 +174,20 @@ void __init tsx_init(void) · 26 unmodified lines | ||
| 191 | 174 | return; |
| 192 | 175 | } |
| 193 | 176 | |
| 194 | − if (!tsx_ctrl_is_supported()) { | |
| 177 | + /* | |
| 178 | + * TSX is controlled via MSR_IA32_TSX_CTRL. However, support for this | |
| 179 | + * MSR is enumerated by ARCH_CAP_TSX_MSR bit in MSR_IA32_ARCH_CAPABILITIES. | |
| 180 | + * | |
| 181 | + * TSX control (aka MSR_IA32_TSX_CTRL) is only available after a | |
| 182 | + * microcode update on CPUs that have their MSR_IA32_ARCH_CAPABILITIES | |
| 183 | + * bit MDS_NO=1. CPUs with MDS_NO=0 are not planned to get | |
| 184 | + * MSR_IA32_TSX_CTRL support even after a microcode update. Thus, | |
| 185 | + * tsx= cmdline requests will do nothing on CPUs without | |
| 186 | + * MSR_IA32_TSX_CTRL support. | |
| 187 | + */ | |
| 188 | + if (x86_read_arch_cap_msr() & ARCH_CAP_TSX_CTRL_MSR) { | |
| 189 | + setup_force_cpu_cap(X86_FEATURE_MSR_TSX_CTRL); | |
| 190 | + } else { | |
| 195 | 191 | tsx_ctrl_state = TSX_CTRL_NOT_SUPPORTED; |
| 196 | 192 | return; |
| 197 | 193 | } |
| @@ -605,9 +605,9 @@ int fpu_clone(struct task_struct *dst, unsigned long clone_flags, bool minimal) · 604 unmodified lines | ||
| 605 | 605 | if (test_thread_flag(TIF_NEED_FPU_LOAD)) |
| 606 | 606 | fpregs_restore_userregs(); |
| 607 | 607 | save_fpregs_to_fpstate(dst_fpu); |
| 608 | + fpregs_unlock(); | |
| 608 | 609 | if (!(clone_flags & CLONE_THREAD)) |
| 609 | 610 | fpu_inherit_perms(dst_fpu); |
| 610 | − fpregs_unlock(); | |
| 611 | 611 | |
| 612 | 612 | /* |
| 613 | 613 | * Children never inherit PASID state. |
| @@ -600,7 +600,7 @@ static __always_inline void __speculation_ctrl_update(unsigned long tifp, · 599 unmodified lines | ||
| 600 | 600 | } |
| 601 | 601 | |
| 602 | 602 | if (updmsr) |
| 603 | − write_spec_ctrl_current(msr, false); | |
| 603 | + update_spec_ctrl_cond(msr); | |
| 604 | 604 | } |
| 605 | 605 | |
| 606 | 606 | static unsigned long speculation_ctrl_update_tif(struct task_struct *tsk) |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/context_tracking.h> |
| 16 | 16 | #include <linux/interrupt.h> |
| 17 | 17 | #include <linux/kallsyms.h> |
| 18 | +#include <linux/kmsan.h> | |
| 18 | 19 | #include <linux/spinlock.h> |
| 19 | 20 | #include <linux/kprobes.h> |
| 20 | 21 | #include <linux/uaccess.h> |
| @@ -301,6 +302,12 @@ static noinstr bool handle_bug(struct pt_regs *regs) · 280 unmodified lines | ||
| 301 | 302 | { |
| 302 | 303 | bool handled = false; |
| 303 | 304 | |
| 305 | + /* | |
| 306 | + * Normally @regs are unpoisoned by irqentry_enter(), but handle_bug() | |
| 307 | + * is a rare case that uses @regs without passing them to | |
| 308 | + * irqentry_enter(). | |
| 309 | + */ | |
| 310 | + kmsan_unpoison_entry_regs(regs); | |
| 304 | 311 | if (!is_valid_bugaddr(regs->ip)) |
| 305 | 312 | return handled; |
| 306 | 313 | |
| @@ -0,0 +1,2 @@ | ||
| 1 | +/kvm-asm-offsets.s | |
| 2 | +/kvm-asm-offsets.h | |
| @@ -34,3 +34,15 @@ endif · 33 unmodified lines | ||
| 34 | 34 | obj-$(CONFIG_KVM) += kvm.o |
| 35 | 35 | obj-$(CONFIG_KVM_INTEL) += kvm-intel.o |
| 36 | 36 | obj-$(CONFIG_KVM_AMD) += kvm-amd.o |
| 37 | + | |
| 38 | +AFLAGS_svm/vmenter.o := -iquote $(obj) | |
| 39 | +$(obj)/svm/vmenter.o: $(obj)/kvm-asm-offsets.h | |
| 40 | + | |
| 41 | +AFLAGS_vmx/vmenter.o := -iquote $(obj) | |
| 42 | +$(obj)/vmx/vmenter.o: $(obj)/kvm-asm-offsets.h | |
| 43 | + | |
| 44 | +$(obj)/kvm-asm-offsets.h: $(obj)/kvm-asm-offsets.s FORCE | |
| 45 | + $(call filechk,offsets,__KVM_ASM_OFFSETS_H__) | |
| 46 | + | |
| 47 | +targets += kvm-asm-offsets.s | |
| 48 | +clean-files += kvm-asm-offsets.h | |
| @@ -1133,11 +1133,13 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 1132 unmodified lines | ||
| 1133 | 1133 | entry->eax = max(entry->eax, 0x80000021); |
| 1134 | 1134 | break; |
| 1135 | 1135 | case 0x80000001: |
| 1136 | + entry->ebx &= ~GENMASK(27, 16); | |
| 1136 | 1137 | cpuid_entry_override(entry, CPUID_8000_0001_EDX); |
| 1137 | 1138 | cpuid_entry_override(entry, CPUID_8000_0001_ECX); |
| 1138 | 1139 | break; |
| 1139 | 1140 | case 0x80000006: |
| 1140 | − /* L2 cache and TLB: pass through host info. */ | |
| 1141 | + /* Drop reserved bits, pass host L2 cache and TLB info. */ | |
| 1142 | + entry->edx &= ~GENMASK(17, 16); | |
| 1141 | 1143 | break; |
| 1142 | 1144 | case 0x80000007: /* Advanced power management */ |
| 1143 | 1145 | /* invariant TSC is CPUID.80000007H:EDX[8] */ |
| @@ -1167,6 +1169,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 23 unmodified lines | ||
| 1167 | 1169 | g_phys_as = phys_as; |
| 1168 | 1170 | |
| 1169 | 1171 | entry->eax = g_phys_as | (virt_as << 8); |
| 1172 | + entry->ecx &= ~(GENMASK(31, 16) | GENMASK(11, 8)); | |
| 1170 | 1173 | entry->edx = 0; |
| 1171 | 1174 | cpuid_entry_override(entry, CPUID_8000_0008_EBX); |
| 1172 | 1175 | break; |
| @@ -1186,6 +1189,9 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 13 unmodified lines | ||
| 1186 | 1189 | entry->ecx = entry->edx = 0; |
| 1187 | 1190 | break; |
| 1188 | 1191 | case 0x8000001a: |
| 1192 | + entry->eax &= GENMASK(2, 0); | |
| 1193 | + entry->ebx = entry->ecx = entry->edx = 0; | |
| 1194 | + break; | |
| 1189 | 1195 | case 0x8000001e: |
| 1190 | 1196 | break; |
| 1191 | 1197 | case 0x8000001F: |
| @@ -1193,7 +1199,8 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 1 unmodified line | ||
| 1193 | 1199 | entry->eax = entry->ebx = entry->ecx = entry->edx = 0; |
| 1194 | 1200 | } else { |
| 1195 | 1201 | cpuid_entry_override(entry, CPUID_8000_001F_EAX); |
| 1196 | − | |
| 1202 | + /* Clear NumVMPL since KVM does not support VMPL. */ | |
| 1203 | + entry->ebx &= ~GENMASK(31, 12); | |
| 1197 | 1204 | /* |
| 1198 | 1205 | * Enumerate '0' for "PA bits reduction", the adjusted |
| 1199 | 1206 | * MAXPHYADDR is enumerated directly (see 0x80000008). |
| @@ -1331,7 +1338,7 @@ int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid, · 131 unmodified lines | ||
| 1331 | 1338 | if (sanity_check_entries(entries, cpuid->nent, type)) |
| 1332 | 1339 | return -EINVAL; |
| 1333 | 1340 | |
| 1334 | − array.entries = kvcalloc(sizeof(struct kvm_cpuid_entry2), cpuid->nent, GFP_KERNEL); | |
| 1341 | + array.entries = kvcalloc(cpuid->nent, sizeof(struct kvm_cpuid_entry2), GFP_KERNEL); | |
| 1335 | 1342 | if (!array.entries) |
| 1336 | 1343 | return -ENOMEM; |
| 1337 | 1344 | |
| @@ -158,11 +158,16 @@ out: · 157 unmodified lines | ||
| 158 | 158 | static int kvm_mmu_rmaps_stat_open(struct inode *inode, struct file *file) |
| 159 | 159 | { |
| 160 | 160 | struct kvm *kvm = inode->i_private; |
| 161 | + int r; | |
| 161 | 162 | |
| 162 | 163 | if (!kvm_get_kvm_safe(kvm)) |
| 163 | 164 | return -ENOENT; |
| 164 | 165 | |
| 165 | − return single_open(file, kvm_mmu_rmaps_stat_show, kvm); | |
| 166 | + r = single_open(file, kvm_mmu_rmaps_stat_show, kvm); | |
| 167 | + if (r < 0) | |
| 168 | + kvm_put_kvm(kvm); | |
| 169 | + | |
| 170 | + return r; | |
| 166 | 171 | } |
| 167 | 172 | |
| 168 | 173 | static int kvm_mmu_rmaps_stat_release(struct inode *inode, struct file *file) |
| @@ -791,8 +791,7 @@ static int linearize(struct x86_emulate_ctxt *ctxt, · 790 unmodified lines | ||
| 791 | 791 | ctxt->mode, linear); |
| 792 | 792 | } |
| 793 | 793 | |
| 794 | −static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst, | |
| 795 | − enum x86emul_mode mode) | |
| 794 | +static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst) | |
| 796 | 795 | { |
| 797 | 796 | ulong linear; |
| 798 | 797 | int rc; |
| @@ -802,41 +801,71 @@ static inline int assign_eip(struct x86_emulate_ctxt *ctxt, ulong dst, · 3 unmodified lines | ||
| 802 | 801 | |
| 803 | 802 | if (ctxt->op_bytes != sizeof(unsigned long)) |
| 804 | 803 | addr.ea = dst & ((1UL << (ctxt->op_bytes << 3)) - 1); |
| 805 | − rc = __linearize(ctxt, addr, &max_size, 1, false, true, mode, &linear); | |
| 804 | + rc = __linearize(ctxt, addr, &max_size, 1, false, true, ctxt->mode, &linear); | |
| 806 | 805 | if (rc == X86EMUL_CONTINUE) |
| 807 | 806 | ctxt->_eip = addr.ea; |
| 808 | 807 | return rc; |
| 809 | 808 | } |
| 810 | 809 | |
| 810 | +static inline int emulator_recalc_and_set_mode(struct x86_emulate_ctxt *ctxt) | |
| 811 | +{ | |
| 812 | + u64 efer; | |
| 813 | + struct desc_struct cs; | |
| 814 | + u16 selector; | |
| 815 | + u32 base3; | |
| 816 | + | |
| 817 | + ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); | |
| 818 | + | |
| 819 | + if (!(ctxt->ops->get_cr(ctxt, 0) & X86_CR0_PE)) { | |
| 820 | + /* Real mode. cpu must not have long mode active */ | |
| 821 | + if (efer & EFER_LMA) | |
| 822 | + return X86EMUL_UNHANDLEABLE; | |
| 823 | + ctxt->mode = X86EMUL_MODE_REAL; | |
| 824 | + return X86EMUL_CONTINUE; | |
| 825 | + } | |
| 826 | + | |
| 827 | + if (ctxt->eflags & X86_EFLAGS_VM) { | |
| 828 | + /* Protected/VM86 mode. cpu must not have long mode active */ | |
| 829 | + if (efer & EFER_LMA) | |
| 830 | + return X86EMUL_UNHANDLEABLE; | |
| 831 | + ctxt->mode = X86EMUL_MODE_VM86; | |
| 832 | + return X86EMUL_CONTINUE; | |
| 833 | + } | |
| 834 | + | |
| 835 | + if (!ctxt->ops->get_segment(ctxt, &selector, &cs, &base3, VCPU_SREG_CS)) | |
| 836 | + return X86EMUL_UNHANDLEABLE; | |
| 837 | + | |
| 838 | + if (efer & EFER_LMA) { | |
| 839 | + if (cs.l) { | |
| 840 | + /* Proper long mode */ | |
| 841 | + ctxt->mode = X86EMUL_MODE_PROT64; | |
| 842 | + } else if (cs.d) { | |
| 843 | + /* 32 bit compatibility mode*/ | |
| 844 | + ctxt->mode = X86EMUL_MODE_PROT32; | |
| 845 | + } else { | |
| 846 | + ctxt->mode = X86EMUL_MODE_PROT16; | |
| 847 | + } | |
| 848 | + } else { | |
| 849 | + /* Legacy 32 bit / 16 bit mode */ | |
| 850 | + ctxt->mode = cs.d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; | |
| 851 | + } | |
| 852 | + | |
| 853 | + return X86EMUL_CONTINUE; | |
| 854 | +} | |
| 855 | + | |
| 811 | 856 | static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst) |
| 812 | 857 | { |
| 813 | − return assign_eip(ctxt, dst, ctxt->mode); | |
| 858 | + return assign_eip(ctxt, dst); | |
| 814 | 859 | } |
| 815 | 860 | |
| 816 | −static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst, | |
| 817 | − const struct desc_struct *cs_desc) | |
| 861 | +static int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst) | |
| 818 | 862 | { |
| 819 | − enum x86emul_mode mode = ctxt->mode; | |
| 820 | − int rc; | |
| 863 | + int rc = emulator_recalc_and_set_mode(ctxt); | |
| 821 | 864 | |
| 822 | −#ifdef CONFIG_X86_64 | |
| 823 | − if (ctxt->mode >= X86EMUL_MODE_PROT16) { | |
| 824 | − if (cs_desc->l) { | |
| 825 | − u64 efer = 0; | |
| 865 | + if (rc != X86EMUL_CONTINUE) | |
| 866 | + return rc; | |
| 826 | 867 | |
| 827 | − ctxt->ops->get_msr(ctxt, MSR_EFER, &efer); | |
| 828 | − if (efer & EFER_LMA) | |
| 829 | − mode = X86EMUL_MODE_PROT64; | |
| 830 | − } else | |
| 831 | − mode = X86EMUL_MODE_PROT32; /* temporary value */ | |
| 832 | − } | |
| 833 | −#endif | |
| 834 | − if (mode == X86EMUL_MODE_PROT16 || mode == X86EMUL_MODE_PROT32) | |
| 835 | − mode = cs_desc->d ? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; | |
| 836 | − rc = assign_eip(ctxt, dst, mode); | |
| 837 | − if (rc == X86EMUL_CONTINUE) | |
| 838 | − ctxt->mode = mode; | |
| 839 | − return rc; | |
| 868 | + return assign_eip(ctxt, dst); | |
| 840 | 869 | } |
| 841 | 870 | |
| 842 | 871 | static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) |
| @@ -2172,7 +2201,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt) · 1329 unmodified lines | ||
| 2172 | 2201 | if (rc != X86EMUL_CONTINUE) |
| 2173 | 2202 | return rc; |
| 2174 | 2203 | |
| 2175 | − rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); | |
| 2204 | + rc = assign_eip_far(ctxt, ctxt->src.val); | |
| 2176 | 2205 | /* Error handling is not implemented. */ |
| 2177 | 2206 | if (rc != X86EMUL_CONTINUE) |
| 2178 | 2207 | return X86EMUL_UNHANDLEABLE; |
| @@ -2250,7 +2279,7 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt) · 71 unmodified lines | ||
| 2250 | 2279 | &new_desc); |
| 2251 | 2280 | if (rc != X86EMUL_CONTINUE) |
| 2252 | 2281 | return rc; |
| 2253 | − rc = assign_eip_far(ctxt, eip, &new_desc); | |
| 2282 | + rc = assign_eip_far(ctxt, eip); | |
| 2254 | 2283 | /* Error handling is not implemented. */ |
| 2255 | 2284 | if (rc != X86EMUL_CONTINUE) |
| 2256 | 2285 | return X86EMUL_UNHANDLEABLE; |
| @@ -2432,7 +2461,7 @@ static int rsm_load_state_32(struct x86_emulate_ctxt *ctxt, · 175 unmodified lines | ||
| 2432 | 2461 | ctxt->eflags = GET_SMSTATE(u32, smstate, 0x7ff4) | X86_EFLAGS_FIXED; |
| 2433 | 2462 | ctxt->_eip = GET_SMSTATE(u32, smstate, 0x7ff0); |
| 2434 | 2463 | |
| 2435 | − for (i = 0; i < NR_EMULATOR_GPRS; i++) | |
| 2464 | + for (i = 0; i < 8; i++) | |
| 2436 | 2465 | *reg_write(ctxt, i) = GET_SMSTATE(u32, smstate, 0x7fd0 + i * 4); |
| 2437 | 2466 | |
| 2438 | 2467 | val = GET_SMSTATE(u32, smstate, 0x7fcc); |
| @@ -2489,7 +2518,7 @@ static int rsm_load_state_64(struct x86_emulate_ctxt *ctxt, · 50 unmodified lines | ||
| 2489 | 2518 | u16 selector; |
| 2490 | 2519 | int i, r; |
| 2491 | 2520 | |
| 2492 | − for (i = 0; i < NR_EMULATOR_GPRS; i++) | |
| 2521 | + for (i = 0; i < 16; i++) | |
| 2493 | 2522 | *reg_write(ctxt, i) = GET_SMSTATE(u64, smstate, 0x7ff8 - i * 8); |
| 2494 | 2523 | |
| 2495 | 2524 | ctxt->_eip = GET_SMSTATE(u64, smstate, 0x7f78); |
| @@ -2633,7 +2662,7 @@ static int em_rsm(struct x86_emulate_ctxt *ctxt) · 137 unmodified lines | ||
| 2633 | 2662 | * those side effects need to be explicitly handled for both success |
| 2634 | 2663 | * and shutdown. |
| 2635 | 2664 | */ |
| 2636 | − return X86EMUL_CONTINUE; | |
| 2665 | + return emulator_recalc_and_set_mode(ctxt); | |
| 2637 | 2666 | |
| 2638 | 2667 | emulate_shutdown: |
| 2639 | 2668 | ctxt->ops->triple_fault(ctxt); |
| @@ -2876,6 +2905,7 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt) · 236 unmodified lines | ||
| 2876 | 2905 | ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS); |
| 2877 | 2906 | |
| 2878 | 2907 | ctxt->_eip = rdx; |
| 2908 | + ctxt->mode = usermode; | |
| 2879 | 2909 | *reg_write(ctxt, VCPU_REGS_RSP) = rcx; |
| 2880 | 2910 | |
| 2881 | 2911 | return X86EMUL_CONTINUE; |
| @@ -3469,7 +3499,7 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt) · 587 unmodified lines | ||
| 3469 | 3499 | if (rc != X86EMUL_CONTINUE) |
| 3470 | 3500 | return rc; |
| 3471 | 3501 | |
| 3472 | − rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc); | |
| 3502 | + rc = assign_eip_far(ctxt, ctxt->src.val); | |
| 3473 | 3503 | if (rc != X86EMUL_CONTINUE) |
| 3474 | 3504 | goto fail; |
| 3475 | 3505 | |
| @@ -3611,11 +3641,25 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt) · 135 unmodified lines | ||
| 3611 | 3641 | |
| 3612 | 3642 | static int em_cr_write(struct x86_emulate_ctxt *ctxt) |
| 3613 | 3643 | { |
| 3614 | − if (ctxt->ops->set_cr(ctxt, ctxt->modrm_reg, ctxt->src.val)) | |
| 3644 | + int cr_num = ctxt->modrm_reg; | |
| 3645 | + int r; | |
| 3646 | + | |
| 3647 | + if (ctxt->ops->set_cr(ctxt, cr_num, ctxt->src.val)) | |
| 3615 | 3648 | return emulate_gp(ctxt, 0); |
| 3616 | 3649 | |
| 3617 | 3650 | /* Disable writeback. */ |
| 3618 | 3651 | ctxt->dst.type = OP_NONE; |
| 3652 | + | |
| 3653 | + if (cr_num == 0) { | |
| 3654 | + /* | |
| 3655 | + * CR0 write might have updated CR0.PE and/or CR0.PG | |
| 3656 | + * which can affect the cpu's execution mode. | |
| 3657 | + */ | |
| 3658 | + r = emulator_recalc_and_set_mode(ctxt); | |
| 3659 | + if (r != X86EMUL_CONTINUE) | |
| 3660 | + return r; | |
| 3661 | + } | |
| 3662 | + | |
| 3619 | 3663 | return X86EMUL_CONTINUE; |
| 3620 | 3664 | } |
| 3621 | 3665 | |
| @@ -0,0 +1,29 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0 | |
| 2 | +/* | |
| 3 | + * Generate definitions needed by assembly language modules. | |
| 4 | + * This code generates raw asm output which is post-processed to extract | |
| 5 | + * and format the required data. | |
| 6 | + */ | |
| 7 | +#define COMPILE_OFFSETS | |
| 8 | + | |
| 9 | +#include <linux/kbuild.h> | |
| 10 | +#include "vmx/vmx.h" | |
| 11 | +#include "svm/svm.h" | |
| 12 | + | |
| 13 | +static void __used common(void) | |
| 14 | +{ | |
| 15 | + if (IS_ENABLED(CONFIG_KVM_AMD)) { | |
| 16 | + BLANK(); | |
| 17 | + OFFSET(SVM_vcpu_arch_regs, vcpu_svm, vcpu.arch.regs); | |
| 18 | + OFFSET(SVM_current_vmcb, vcpu_svm, current_vmcb); | |
| 19 | + OFFSET(SVM_spec_ctrl, vcpu_svm, spec_ctrl); | |
| 20 | + OFFSET(SVM_vmcb01, vcpu_svm, vmcb01); | |
| 21 | + OFFSET(KVM_VMCB_pa, kvm_vmcb_info, pa); | |
| 22 | + OFFSET(SD_save_area_pa, svm_cpu_data, save_area_pa); | |
| 23 | + } | |
| 24 | + | |
| 25 | + if (IS_ENABLED(CONFIG_KVM_INTEL)) { | |
| 26 | + BLANK(); | |
| 27 | + OFFSET(VMX_spec_ctrl, vcpu_vmx, spec_ctrl); | |
| 28 | + } | |
| 29 | +} | |
| @@ -2443,6 +2443,7 @@ static bool __kvm_mmu_prepare_zap_page(struct kvm *kvm, · 2442 unmodified lines | ||
| 2443 | 2443 | { |
| 2444 | 2444 | bool list_unstable, zapped_root = false; |
| 2445 | 2445 | |
| 2446 | + lockdep_assert_held_write(&kvm->mmu_lock); | |
| 2446 | 2447 | trace_kvm_mmu_prepare_zap_page(sp); |
| 2447 | 2448 | ++kvm->stat.mmu_shadow_zapped; |
| 2448 | 2449 | *nr_zapped = mmu_zap_unsync_children(kvm, sp, invalid_list); |
| @@ -4262,14 +4263,14 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault · 1813 unmodified lines | ||
| 4262 | 4263 | if (is_page_fault_stale(vcpu, fault, mmu_seq)) |
| 4263 | 4264 | goto out_unlock; |
| 4264 | 4265 | |
| 4265 | − r = make_mmu_pages_available(vcpu); | |
| 4266 | − if (r) | |
| 4267 | − goto out_unlock; | |
| 4268 | − | |
| 4269 | − if (is_tdp_mmu_fault) | |
| 4266 | + if (is_tdp_mmu_fault) { | |
| 4270 | 4267 | r = kvm_tdp_mmu_map(vcpu, fault); |
| 4271 | − else | |
| 4268 | + } else { | |
| 4269 | + r = make_mmu_pages_available(vcpu); | |
| 4270 | + if (r) | |
| 4271 | + goto out_unlock; | |
| 4272 | 4272 | r = __direct_map(vcpu, fault); |
| 4273 | + } | |
| 4273 | 4274 | |
| 4274 | 4275 | out_unlock: |
| 4275 | 4276 | if (is_tdp_mmu_fault) |
| @@ -6056,7 +6057,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) · 1780 unmodified lines | ||
| 6056 | 6057 | |
| 6057 | 6058 | write_lock(&kvm->mmu_lock); |
| 6058 | 6059 | |
| 6059 | − kvm_mmu_invalidate_begin(kvm, gfn_start, gfn_end); | |
| 6060 | + kvm_mmu_invalidate_begin(kvm, 0, -1ul); | |
| 6060 | 6061 | |
| 6061 | 6062 | flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end); |
| 6062 | 6063 | |
| @@ -6070,7 +6071,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) · 7 unmodified lines | ||
| 6070 | 6071 | kvm_flush_remote_tlbs_with_address(kvm, gfn_start, |
| 6071 | 6072 | gfn_end - gfn_start); |
| 6072 | 6073 | |
| 6073 | − kvm_mmu_invalidate_end(kvm, gfn_start, gfn_end); | |
| 6074 | + kvm_mmu_invalidate_end(kvm, 0, -1ul); | |
| 6074 | 6075 | |
| 6075 | 6076 | write_unlock(&kvm->mmu_lock); |
| 6076 | 6077 | } |
| @@ -56,7 +56,7 @@ static const struct x86_cpu_id vmx_icl_pebs_cpu[] = { · 55 unmodified lines | ||
| 56 | 56 | * code. Each pmc, stored in kvm_pmc.idx field, is unique across |
| 57 | 57 | * all perf counters (both gp and fixed). The mapping relationship |
| 58 | 58 | * between pmc and perf counters is as the following: |
| 59 | − * * Intel: [0 .. INTEL_PMC_MAX_GENERIC-1] <=> gp counters | |
| 59 | + * * Intel: [0 .. KVM_INTEL_PMC_MAX_GENERIC-1] <=> gp counters | |
| 60 | 60 | * [INTEL_PMC_IDX_FIXED .. INTEL_PMC_IDX_FIXED + 2] <=> fixed |
| 61 | 61 | * * AMD: [0 .. AMD64_NUM_COUNTERS-1] and, for families 15H |
| 62 | 62 | * and later, [0 .. AMD64_NUM_COUNTERS_CORE-1] <=> gp counters |
| @@ -1091,6 +1091,12 @@ int nested_svm_vmexit(struct vcpu_svm *svm) · 1090 unmodified lines | ||
| 1091 | 1091 | |
| 1092 | 1092 | static void nested_svm_triple_fault(struct kvm_vcpu *vcpu) |
| 1093 | 1093 | { |
| 1094 | + struct vcpu_svm *svm = to_svm(vcpu); | |
| 1095 | + | |
| 1096 | + if (!vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_SHUTDOWN)) | |
| 1097 | + return; | |
| 1098 | + | |
| 1099 | + kvm_clear_request(KVM_REQ_TRIPLE_FAULT, vcpu); | |
| 1094 | 1100 | nested_svm_simple_vmexit(to_svm(vcpu), SVM_EXIT_SHUTDOWN); |
| 1095 | 1101 | } |
| 1096 | 1102 | |
| @@ -1125,6 +1131,9 @@ void svm_free_nested(struct vcpu_svm *svm) · 28 unmodified lines | ||
| 1125 | 1131 | if (!svm->nested.initialized) |
| 1126 | 1132 | return; |
| 1127 | 1133 | |
| 1134 | + if (WARN_ON_ONCE(svm->vmcb != svm->vmcb01.ptr)) | |
| 1135 | + svm_switch_vmcb(svm, &svm->vmcb01); | |
| 1136 | + | |
| 1128 | 1137 | svm_vcpu_free_msrpm(svm->nested.msrpm); |
| 1129 | 1138 | svm->nested.msrpm = NULL; |
| 1130 | 1139 | |
| @@ -1143,9 +1152,6 @@ void svm_free_nested(struct vcpu_svm *svm) · 12 unmodified lines | ||
| 1143 | 1152 | svm->nested.initialized = false; |
| 1144 | 1153 | } |
| 1145 | 1154 | |
| 1146 | −/* | |
| 1147 | − * Forcibly leave nested mode in order to be able to reset the VCPU later on. | |
| 1148 | − */ | |
| 1149 | 1155 | void svm_leave_nested(struct kvm_vcpu *vcpu) |
| 1150 | 1156 | { |
| 1151 | 1157 | struct vcpu_svm *svm = to_svm(vcpu); |
| @@ -192,9 +192,10 @@ static void amd_pmu_init(struct kvm_vcpu *vcpu) · 191 unmodified lines | ||
| 192 | 192 | struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); |
| 193 | 193 | int i; |
| 194 | 194 | |
| 195 | − BUILD_BUG_ON(AMD64_NUM_COUNTERS_CORE > INTEL_PMC_MAX_GENERIC); | |
| 195 | + BUILD_BUG_ON(KVM_AMD_PMC_MAX_GENERIC > AMD64_NUM_COUNTERS_CORE); | |
| 196 | + BUILD_BUG_ON(KVM_AMD_PMC_MAX_GENERIC > INTEL_PMC_MAX_GENERIC); | |
| 196 | 197 | |
| 197 | − for (i = 0; i < AMD64_NUM_COUNTERS_CORE ; i++) { | |
| 198 | + for (i = 0; i < KVM_AMD_PMC_MAX_GENERIC ; i++) { | |
| 198 | 199 | pmu->gp_counters[i].type = KVM_PMC_GP; |
| 199 | 200 | pmu->gp_counters[i].vcpu = vcpu; |
| 200 | 201 | pmu->gp_counters[i].idx = i; |
| @@ -207,7 +208,7 @@ static void amd_pmu_reset(struct kvm_vcpu *vcpu) · 6 unmodified lines | ||
| 207 | 208 | struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); |
| 208 | 209 | int i; |
| 209 | 210 | |
| 210 | − for (i = 0; i < AMD64_NUM_COUNTERS_CORE; i++) { | |
| 211 | + for (i = 0; i < KVM_AMD_PMC_MAX_GENERIC; i++) { | |
| 211 | 212 | struct kvm_pmc *pmc = &pmu->gp_counters[i]; |
| 212 | 213 | |
| 213 | 214 | pmc_stop_counter(pmc); |
| @@ -196,7 +196,7 @@ static void sev_asid_free(struct kvm_sev_info *sev) · 195 unmodified lines | ||
| 196 | 196 | __set_bit(sev->asid, sev_reclaim_asid_bitmap); |
| 197 | 197 | |
| 198 | 198 | for_each_possible_cpu(cpu) { |
| 199 | − sd = per_cpu(svm_data, cpu); | |
| 199 | + sd = per_cpu_ptr(&svm_data, cpu); | |
| 200 | 200 | sd->sev_vmcbs[sev->asid] = NULL; |
| 201 | 201 | } |
| 202 | 202 | |
| @@ -605,7 +605,7 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm) · 402 unmodified lines | ||
| 605 | 605 | save->dr6 = svm->vcpu.arch.dr6; |
| 606 | 606 | |
| 607 | 607 | pr_debug("Virtual Machine Save Area (VMSA):\n"); |
| 608 | − print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false); | |
| 608 | + print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false); | |
| 609 | 609 | |
| 610 | 610 | return 0; |
| 611 | 611 | } |
| @@ -2600,7 +2600,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm) · 1988 unmodified lines | ||
| 2600 | 2600 | |
| 2601 | 2601 | void pre_sev_run(struct vcpu_svm *svm, int cpu) |
| 2602 | 2602 | { |
| 2603 | − struct svm_cpu_data *sd = per_cpu(svm_data, cpu); | |
| 2603 | + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); | |
| 2604 | 2604 | int asid = sev_get_asid(svm->vcpu.kvm); |
| 2605 | 2605 | |
| 2606 | 2606 | /* Assign the asid allocated with this SEV guest */ |
| @@ -245,7 +245,7 @@ struct kvm_ldttss_desc { · 244 unmodified lines | ||
| 245 | 245 | u32 zero1; |
| 246 | 246 | } __attribute__((packed)); |
| 247 | 247 | |
| 248 | −DEFINE_PER_CPU(struct svm_cpu_data *, svm_data); | |
| 248 | +DEFINE_PER_CPU(struct svm_cpu_data, svm_data); | |
| 249 | 249 | |
| 250 | 250 | /* |
| 251 | 251 | * Only MSR_TSC_AUX is switched via the user return hook. EFER is switched via |
| @@ -346,12 +346,6 @@ int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) · 94 unmodified lines | ||
| 346 | 346 | return 0; |
| 347 | 347 | } |
| 348 | 348 | |
| 349 | −static int is_external_interrupt(u32 info) | |
| 350 | −{ | |
| 351 | − info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID; | |
| 352 | − return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR); | |
| 353 | −} | |
| 354 | − | |
| 355 | 349 | static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu) |
| 356 | 350 | { |
| 357 | 351 | struct vcpu_svm *svm = to_svm(vcpu); |
| @@ -581,12 +575,7 @@ static int svm_hardware_enable(void) · 223 unmodified lines | ||
| 581 | 575 | pr_err("%s: err EOPNOTSUPP on %d\n", __func__, me); |
| 582 | 576 | return -EINVAL; |
| 583 | 577 | } |
| 584 | − sd = per_cpu(svm_data, me); | |
| 585 | − if (!sd) { | |
| 586 | − pr_err("%s: svm_data is NULL on %d\n", __func__, me); | |
| 587 | − return -EINVAL; | |
| 588 | − } | |
| 589 | − | |
| 578 | + sd = per_cpu_ptr(&svm_data, me); | |
| 590 | 579 | sd->asid_generation = 1; |
| 591 | 580 | sd->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; |
| 592 | 581 | sd->next_asid = sd->max_asid + 1; |
| @@ -597,7 +586,7 @@ static int svm_hardware_enable(void) · 4 unmodified lines | ||
| 597 | 586 | |
| 598 | 587 | wrmsrl(MSR_EFER, efer | EFER_SVME); |
| 599 | 588 | |
| 600 | − wrmsrl(MSR_VM_HSAVE_PA, __sme_page_pa(sd->save_area)); | |
| 589 | + wrmsrl(MSR_VM_HSAVE_PA, sd->save_area_pa); | |
| 601 | 590 | |
| 602 | 591 | if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) { |
| 603 | 592 | /* |
| @@ -646,42 +635,37 @@ static int svm_hardware_enable(void) · 42 unmodified lines | ||
| 646 | 635 | |
| 647 | 636 | static void svm_cpu_uninit(int cpu) |
| 648 | 637 | { |
| 649 | − struct svm_cpu_data *sd = per_cpu(svm_data, cpu); | |
| 638 | + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); | |
| 650 | 639 | |
| 651 | − if (!sd) | |
| 640 | + if (!sd->save_area) | |
| 652 | 641 | return; |
| 653 | 642 | |
| 654 | − per_cpu(svm_data, cpu) = NULL; | |
| 655 | 643 | kfree(sd->sev_vmcbs); |
| 656 | 644 | __free_page(sd->save_area); |
| 657 | − kfree(sd); | |
| 645 | + sd->save_area_pa = 0; | |
| 646 | + sd->save_area = NULL; | |
| 658 | 647 | } |
| 659 | 648 | |
| 660 | 649 | static int svm_cpu_init(int cpu) |
| 661 | 650 | { |
| 662 | − struct svm_cpu_data *sd; | |
| 651 | + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); | |
| 663 | 652 | int ret = -ENOMEM; |
| 664 | 653 | |
| 665 | − sd = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL); | |
| 666 | − if (!sd) | |
| 667 | − return ret; | |
| 668 | − sd->cpu = cpu; | |
| 654 | + memset(sd, 0, sizeof(struct svm_cpu_data)); | |
| 669 | 655 | sd->save_area = alloc_page(GFP_KERNEL | __GFP_ZERO); |
| 670 | 656 | if (!sd->save_area) |
| 671 | − goto free_cpu_data; | |
| 657 | + return ret; | |
| 672 | 658 | |
| 673 | 659 | ret = sev_cpu_init(sd); |
| 674 | 660 | if (ret) |
| 675 | 661 | goto free_save_area; |
| 676 | 662 | |
| 677 | − per_cpu(svm_data, cpu) = sd; | |
| 678 | − | |
| 663 | + sd->save_area_pa = __sme_page_pa(sd->save_area); | |
| 679 | 664 | return 0; |
| 680 | 665 | |
| 681 | 666 | free_save_area: |
| 682 | 667 | __free_page(sd->save_area); |
| 683 | −free_cpu_data: | |
| 684 | − kfree(sd); | |
| 668 | + sd->save_area = NULL; | |
| 685 | 669 | return ret; |
| 686 | 670 | |
| 687 | 671 | } |
| @@ -730,6 +714,15 @@ static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr) · 42 unmodified lines | ||
| 730 | 714 | u32 offset; |
| 731 | 715 | u32 *msrpm; |
| 732 | 716 | |
| 717 | + /* | |
| 718 | + * For non-nested case: | |
| 719 | + * If the L01 MSR bitmap does not intercept the MSR, then we need to | |
| 720 | + * save it. | |
| 721 | + * | |
| 722 | + * For nested case: | |
| 723 | + * If the L02 MSR bitmap does not intercept the MSR, then we need to | |
| 724 | + * save it. | |
| 725 | + */ | |
| 733 | 726 | msrpm = is_guest_mode(vcpu) ? to_svm(vcpu)->nested.msrpm: |
| 734 | 727 | to_svm(vcpu)->msrpm; |
| 735 | 728 | |
| @@ -1425,7 +1418,7 @@ static void svm_clear_current_vmcb(struct vmcb *vmcb) · 689 unmodified lines | ||
| 1425 | 1418 | int i; |
| 1426 | 1419 | |
| 1427 | 1420 | for_each_online_cpu(i) |
| 1428 | − cmpxchg(&per_cpu(svm_data, i)->current_vmcb, vmcb, NULL); | |
| 1421 | + cmpxchg(per_cpu_ptr(&svm_data.current_vmcb, i), vmcb, NULL); | |
| 1429 | 1422 | } |
| 1430 | 1423 | |
| 1431 | 1424 | static void svm_vcpu_free(struct kvm_vcpu *vcpu) |
| @@ -1439,6 +1432,7 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu) · 7 unmodified lines | ||
| 1439 | 1432 | */ |
| 1440 | 1433 | svm_clear_current_vmcb(svm->vmcb); |
| 1441 | 1434 | |
| 1435 | + svm_leave_nested(vcpu); | |
| 1442 | 1436 | svm_free_nested(svm); |
| 1443 | 1437 | |
| 1444 | 1438 | sev_free_vcpu(vcpu); |
| @@ -1450,7 +1444,7 @@ static void svm_vcpu_free(struct kvm_vcpu *vcpu) · 5 unmodified lines | ||
| 1450 | 1444 | static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) |
| 1451 | 1445 | { |
| 1452 | 1446 | struct vcpu_svm *svm = to_svm(vcpu); |
| 1453 | − struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu); | |
| 1447 | + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu); | |
| 1454 | 1448 | |
| 1455 | 1449 | if (sev_es_guest(vcpu->kvm)) |
| 1456 | 1450 | sev_es_unmap_ghcb(svm); |
| @@ -1462,7 +1456,7 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu) · 5 unmodified lines | ||
| 1462 | 1456 | * Save additional host state that will be restored on VMEXIT (sev-es) |
| 1463 | 1457 | * or subsequent vmload of host save area. |
| 1464 | 1458 | */ |
| 1465 | − vmsave(__sme_page_pa(sd->save_area)); | |
| 1459 | + vmsave(sd->save_area_pa); | |
| 1466 | 1460 | if (sev_es_guest(vcpu->kvm)) { |
| 1467 | 1461 | struct sev_es_save_area *hostsa; |
| 1468 | 1462 | hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400); |
| @@ -1487,7 +1481,7 @@ static void svm_prepare_host_switch(struct kvm_vcpu *vcpu) · 18 unmodified lines | ||
| 1487 | 1481 | static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
| 1488 | 1482 | { |
| 1489 | 1483 | struct vcpu_svm *svm = to_svm(vcpu); |
| 1490 | − struct svm_cpu_data *sd = per_cpu(svm_data, cpu); | |
| 1484 | + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu); | |
| 1491 | 1485 | |
| 1492 | 1486 | if (sd->current_vmcb != svm->vmcb) { |
| 1493 | 1487 | sd->current_vmcb = svm->vmcb; |
| @@ -2710,9 +2704,9 @@ static int svm_get_msr_feature(struct kvm_msr_entry *msr) · 1216 unmodified lines | ||
| 2710 | 2704 | msr->data = 0; |
| 2711 | 2705 | |
| 2712 | 2706 | switch (msr->index) { |
| 2713 | − case MSR_F10H_DECFG: | |
| 2714 | − if (boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) | |
| 2715 | − msr->data |= MSR_F10H_DECFG_LFENCE_SERIALIZE; | |
| 2707 | + case MSR_AMD64_DE_CFG: | |
| 2708 | + if (cpu_feature_enabled(X86_FEATURE_LFENCE_RDTSC)) | |
| 2709 | + msr->data |= MSR_AMD64_DE_CFG_LFENCE_SERIALIZE; | |
| 2716 | 2710 | break; |
| 2717 | 2711 | case MSR_IA32_PERF_CAPABILITIES: |
| 2718 | 2712 | return 0; |
| @@ -2813,7 +2807,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 94 unmodified lines | ||
| 2813 | 2807 | msr_info->data = 0x1E; |
| 2814 | 2808 | } |
| 2815 | 2809 | break; |
| 2816 | − case MSR_F10H_DECFG: | |
| 2810 | + case MSR_AMD64_DE_CFG: | |
| 2817 | 2811 | msr_info->data = svm->msr_decfg; |
| 2818 | 2812 | break; |
| 2819 | 2813 | default: |
| @@ -3042,7 +3036,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) · 222 unmodified lines | ||
| 3042 | 3036 | case MSR_VM_IGNNE: |
| 3043 | 3037 | vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data); |
| 3044 | 3038 | break; |
| 3045 | − case MSR_F10H_DECFG: { | |
| 3039 | + case MSR_AMD64_DE_CFG: { | |
| 3046 | 3040 | struct kvm_msr_entry msr_entry; |
| 3047 | 3041 | |
| 3048 | 3042 | msr_entry.index = msr->index; |
| @@ -3426,15 +3420,6 @@ static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) · 377 unmodified lines | ||
| 3426 | 3420 | return 0; |
| 3427 | 3421 | } |
| 3428 | 3422 | |
| 3429 | − if (is_external_interrupt(svm->vmcb->control.exit_int_info) && | |
| 3430 | − exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR && | |
| 3431 | − exit_code != SVM_EXIT_NPF && exit_code != SVM_EXIT_TASK_SWITCH && | |
| 3432 | − exit_code != SVM_EXIT_INTR && exit_code != SVM_EXIT_NMI) | |
| 3433 | − printk(KERN_ERR "%s: unexpected exit_int_info 0x%x " | |
| 3434 | − "exit_code 0x%x\n", | |
| 3435 | − __func__, svm->vmcb->control.exit_int_info, | |
| 3436 | − exit_code); | |
| 3437 | − | |
| 3438 | 3423 | if (exit_fastpath != EXIT_FASTPATH_NONE) |
| 3439 | 3424 | return 1; |
| 3440 | 3425 | |
| @@ -3443,7 +3428,7 @@ static int svm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) · 2 unmodified lines | ||
| 3443 | 3428 | |
| 3444 | 3429 | static void reload_tss(struct kvm_vcpu *vcpu) |
| 3445 | 3430 | { |
| 3446 | − struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu); | |
| 3431 | + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu); | |
| 3447 | 3432 | |
| 3448 | 3433 | sd->tss_desc->type = 9; /* available 32/64-bit TSS */ |
| 3449 | 3434 | load_TR_desc(); |
| @@ -3451,7 +3436,7 @@ static void reload_tss(struct kvm_vcpu *vcpu) · 1 unmodified line | ||
| 3451 | 3436 | |
| 3452 | 3437 | static void pre_svm_run(struct kvm_vcpu *vcpu) |
| 3453 | 3438 | { |
| 3454 | − struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu); | |
| 3439 | + struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, vcpu->cpu); | |
| 3455 | 3440 | struct vcpu_svm *svm = to_svm(vcpu); |
| 3456 | 3441 | |
| 3457 | 3442 | /* |
| @@ -3911,30 +3896,16 @@ static fastpath_t svm_exit_handlers_fastpath(struct kvm_vcpu *vcpu) · 453 unmodified lines | ||
| 3911 | 3896 | return EXIT_FASTPATH_NONE; |
| 3912 | 3897 | } |
| 3913 | 3898 | |
| 3914 | −static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu) | |
| 3899 | +static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, bool spec_ctrl_intercepted) | |
| 3915 | 3900 | { |
| 3916 | 3901 | struct vcpu_svm *svm = to_svm(vcpu); |
| 3917 | − unsigned long vmcb_pa = svm->current_vmcb->pa; | |
| 3918 | 3902 | |
| 3919 | 3903 | guest_state_enter_irqoff(); |
| 3920 | 3904 | |
| 3921 | − if (sev_es_guest(vcpu->kvm)) { | |
| 3922 | − __svm_sev_es_vcpu_run(vmcb_pa); | |
| 3923 | − } else { | |
| 3924 | − struct svm_cpu_data *sd = per_cpu(svm_data, vcpu->cpu); | |
| 3925 | − | |
| 3926 | − /* | |
| 3927 | − * Use a single vmcb (vmcb01 because it's always valid) for | |
| 3928 | − * context switching guest state via VMLOAD/VMSAVE, that way | |
| 3929 | − * the state doesn't need to be copied between vmcb01 and | |
| 3930 | − * vmcb02 when switching vmcbs for nested virtualization. | |
| 3931 | − */ | |
| 3932 | − vmload(svm->vmcb01.pa); | |
| 3933 | − __svm_vcpu_run(vmcb_pa, (unsigned long *)&vcpu->arch.regs); | |
| 3934 | − vmsave(svm->vmcb01.pa); | |
| 3935 | − | |
| 3936 | − vmload(__sme_page_pa(sd->save_area)); | |
| 3937 | − } | |
| 3905 | + if (sev_es_guest(vcpu->kvm)) | |
| 3906 | + __svm_sev_es_vcpu_run(svm, spec_ctrl_intercepted); | |
| 3907 | + else | |
| 3908 | + __svm_vcpu_run(svm, spec_ctrl_intercepted); | |
| 3938 | 3909 | |
| 3939 | 3910 | guest_state_exit_irqoff(); |
| 3940 | 3911 | } |
| @@ -3942,6 +3913,7 @@ static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu) · 1 unmodified line | ||
| 3942 | 3913 | static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) |
| 3943 | 3914 | { |
| 3944 | 3915 | struct vcpu_svm *svm = to_svm(vcpu); |
| 3916 | + bool spec_ctrl_intercepted = msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL); | |
| 3945 | 3917 | |
| 3946 | 3918 | trace_kvm_entry(vcpu); |
| 3947 | 3919 | |
| @@ -3998,34 +3970,15 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu) · 50 unmodified lines | ||
| 3998 | 3970 | * being speculatively taken. |
| 3999 | 3971 | */ |
| 4000 | 3972 | if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL)) |
| 4001 | − x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl); | |
| 4002 | − | |
| 4003 | − svm_vcpu_enter_exit(vcpu); | |
| 3973 | + x86_spec_ctrl_set_guest(svm->virt_spec_ctrl); | |
| 4004 | 3974 | |
| 4005 | − /* | |
| 4006 | − * We do not use IBRS in the kernel. If this vCPU has used the | |
| 4007 | − * SPEC_CTRL MSR it may have left it on; save the value and | |
| 4008 | − * turn it off. This is much more efficient than blindly adding | |
| 4009 | − * it to the atomic save/restore list. Especially as the former | |
| 4010 | − * (Saving guest MSRs on vmexit) doesn't even exist in KVM. | |
| 4011 | − * | |
| 4012 | − * For non-nested case: | |
| 4013 | − * If the L01 MSR bitmap does not intercept the MSR, then we need to | |
| 4014 | − * save it. | |
| 4015 | − * | |
| 4016 | − * For nested case: | |
| 4017 | − * If the L02 MSR bitmap does not intercept the MSR, then we need to | |
| 4018 | − * save it. | |
| 4019 | − */ | |
| 4020 | − if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL) && | |
| 4021 | − unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))) | |
| 4022 | − svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL); | |
| 3975 | + svm_vcpu_enter_exit(vcpu, spec_ctrl_intercepted); | |
| 4023 | 3976 | |
| 4024 | 3977 | if (!sev_es_guest(vcpu->kvm)) |
| 4025 | 3978 | reload_tss(vcpu); |
| 4026 | 3979 | |
| 4027 | 3980 | if (!static_cpu_has(X86_FEATURE_V_SPEC_CTRL)) |
| 4028 | − x86_spec_ctrl_restore_host(svm->spec_ctrl, svm->virt_spec_ctrl); | |
| 3981 | + x86_spec_ctrl_restore_host(svm->virt_spec_ctrl); | |
| 4029 | 3982 | |
| 4030 | 3983 | if (!sev_es_guest(vcpu->kvm)) { |
| 4031 | 3984 | vcpu->arch.cr2 = svm->vmcb->save.cr2; |
| @@ -209,7 +209,6 @@ struct vcpu_svm { · 208 unmodified lines | ||
| 209 | 209 | struct vmcb *vmcb; |
| 210 | 210 | struct kvm_vmcb_info vmcb01; |
| 211 | 211 | struct kvm_vmcb_info *current_vmcb; |
| 212 | − struct svm_cpu_data *svm_data; | |
| 213 | 212 | u32 asid; |
| 214 | 213 | u32 sysenter_esp_hi; |
| 215 | 214 | u32 sysenter_eip_hi; |
| @@ -281,8 +280,6 @@ struct vcpu_svm { · 65 unmodified lines | ||
| 281 | 280 | }; |
| 282 | 281 | |
| 283 | 282 | struct svm_cpu_data { |
| 284 | − int cpu; | |
| 285 | − | |
| 286 | 283 | u64 asid_generation; |
| 287 | 284 | u32 max_asid; |
| 288 | 285 | u32 next_asid; |
| @@ -290,13 +287,15 @@ struct svm_cpu_data { · 1 unmodified line | ||
| 290 | 287 | struct kvm_ldttss_desc *tss_desc; |
| 291 | 288 | |
| 292 | 289 | struct page *save_area; |
| 290 | + unsigned long save_area_pa; | |
| 291 | + | |
| 293 | 292 | struct vmcb *current_vmcb; |
| 294 | 293 | |
| 295 | 294 | /* index = sev_asid, value = vmcb pointer */ |
| 296 | 295 | struct vmcb **sev_vmcbs; |
| 297 | 296 | }; |
| 298 | 297 | |
| 299 | −DECLARE_PER_CPU(struct svm_cpu_data *, svm_data); | |
| 298 | +DECLARE_PER_CPU(struct svm_cpu_data, svm_data); | |
| 300 | 299 | |
| 301 | 300 | void recalc_intercepts(struct vcpu_svm *svm); |
| 302 | 301 | |
| @@ -683,7 +682,7 @@ void sev_es_unmap_ghcb(struct vcpu_svm *svm); · 380 unmodified lines | ||
| 683 | 682 | |
| 684 | 683 | /* vmenter.S */ |
| 685 | 684 | |
| 686 | −void __svm_sev_es_vcpu_run(unsigned long vmcb_pa); | |
| 687 | −void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs); | |
| 685 | +void __svm_sev_es_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted); | |
| 686 | +void __svm_vcpu_run(struct vcpu_svm *svm, bool spec_ctrl_intercepted); | |
| 688 | 687 | |
| 689 | 688 | #endif |
| @@ -61,9 +61,4 @@ static __always_inline void vmsave(unsigned long pa) · 60 unmodified lines | ||
| 61 | 61 | svm_asm1(vmsave, "a" (pa), "memory"); |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | −static __always_inline void vmload(unsigned long pa) | |
| 65 | −{ | |
| 66 | − svm_asm1(vmload, "a" (pa), "memory"); | |
| 67 | −} | |
| 68 | − | |
| 69 | 64 | #endif /* __KVM_X86_SVM_OPS_H */ |
| @@ -4,35 +4,97 @@ · 3 unmodified lines | ||
| 4 | 4 | #include <asm/bitsperlong.h> |
| 5 | 5 | #include <asm/kvm_vcpu_regs.h> |
| 6 | 6 | #include <asm/nospec-branch.h> |
| 7 | +#include "kvm-asm-offsets.h" | |
| 7 | 8 | |
| 8 | 9 | #define WORD_SIZE (BITS_PER_LONG / 8) |
| 9 | 10 | |
| 10 | 11 | /* Intentionally omit RAX as it's context switched by hardware */ |
| 11 | −#define VCPU_RCX __VCPU_REGS_RCX * WORD_SIZE | |
| 12 | −#define VCPU_RDX __VCPU_REGS_RDX * WORD_SIZE | |
| 13 | −#define VCPU_RBX __VCPU_REGS_RBX * WORD_SIZE | |
| 12 | +#define VCPU_RCX (SVM_vcpu_arch_regs + __VCPU_REGS_RCX * WORD_SIZE) | |
| 13 | +#define VCPU_RDX (SVM_vcpu_arch_regs + __VCPU_REGS_RDX * WORD_SIZE) | |
| 14 | +#define VCPU_RBX (SVM_vcpu_arch_regs + __VCPU_REGS_RBX * WORD_SIZE) | |
| 14 | 15 | /* Intentionally omit RSP as it's context switched by hardware */ |
| 15 | −#define VCPU_RBP __VCPU_REGS_RBP * WORD_SIZE | |
| 16 | −#define VCPU_RSI __VCPU_REGS_RSI * WORD_SIZE | |
| 17 | −#define VCPU_RDI __VCPU_REGS_RDI * WORD_SIZE | |
| 16 | +#define VCPU_RBP (SVM_vcpu_arch_regs + __VCPU_REGS_RBP * WORD_SIZE) | |
| 17 | +#define VCPU_RSI (SVM_vcpu_arch_regs + __VCPU_REGS_RSI * WORD_SIZE) | |
| 18 | +#define VCPU_RDI (SVM_vcpu_arch_regs + __VCPU_REGS_RDI * WORD_SIZE) | |
| 18 | 19 | |
| 19 | 20 | #ifdef CONFIG_X86_64 |
| 20 | −#define VCPU_R8 __VCPU_REGS_R8 * WORD_SIZE | |
| 21 | −#define VCPU_R9 __VCPU_REGS_R9 * WORD_SIZE | |
| 22 | −#define VCPU_R10 __VCPU_REGS_R10 * WORD_SIZE | |
| 23 | −#define VCPU_R11 __VCPU_REGS_R11 * WORD_SIZE | |
| 24 | −#define VCPU_R12 __VCPU_REGS_R12 * WORD_SIZE | |
| 25 | −#define VCPU_R13 __VCPU_REGS_R13 * WORD_SIZE | |
| 26 | −#define VCPU_R14 __VCPU_REGS_R14 * WORD_SIZE | |
| 27 | −#define VCPU_R15 __VCPU_REGS_R15 * WORD_SIZE | |
| 21 | +#define VCPU_R8 (SVM_vcpu_arch_regs + __VCPU_REGS_R8 * WORD_SIZE) | |
| 22 | +#define VCPU_R9 (SVM_vcpu_arch_regs + __VCPU_REGS_R9 * WORD_SIZE) | |
| 23 | +#define VCPU_R10 (SVM_vcpu_arch_regs + __VCPU_REGS_R10 * WORD_SIZE) | |
| 24 | +#define VCPU_R11 (SVM_vcpu_arch_regs + __VCPU_REGS_R11 * WORD_SIZE) | |
| 25 | +#define VCPU_R12 (SVM_vcpu_arch_regs + __VCPU_REGS_R12 * WORD_SIZE) | |
| 26 | +#define VCPU_R13 (SVM_vcpu_arch_regs + __VCPU_REGS_R13 * WORD_SIZE) | |
| 27 | +#define VCPU_R14 (SVM_vcpu_arch_regs + __VCPU_REGS_R14 * WORD_SIZE) | |
| 28 | +#define VCPU_R15 (SVM_vcpu_arch_regs + __VCPU_REGS_R15 * WORD_SIZE) | |
| 28 | 29 | #endif |
| 29 | 30 | |
| 31 | +#define SVM_vmcb01_pa (SVM_vmcb01 + KVM_VMCB_pa) | |
| 32 | + | |
| 30 | 33 | .section .noinstr.text, "ax" |
| 31 | 34 | |
| 35 | +.macro RESTORE_GUEST_SPEC_CTRL | |
| 36 | + /* No need to do anything if SPEC_CTRL is unset or V_SPEC_CTRL is set */ | |
| 37 | + ALTERNATIVE_2 "", \ | |
| 38 | + "jmp 800f", X86_FEATURE_MSR_SPEC_CTRL, \ | |
| 39 | + "", X86_FEATURE_V_SPEC_CTRL | |
| 40 | +801: | |
| 41 | +.endm | |
| 42 | +.macro RESTORE_GUEST_SPEC_CTRL_BODY | |
| 43 | +800: | |
| 44 | + /* | |
| 45 | + * SPEC_CTRL handling: if the guest's SPEC_CTRL value differs from the | |
| 46 | + * host's, write the MSR. This is kept out-of-line so that the common | |
| 47 | + * case does not have to jump. | |
| 48 | + * | |
| 49 | + * IMPORTANT: To avoid RSB underflow attacks and any other nastiness, | |
| 50 | + * there must not be any returns or indirect branches between this code | |
| 51 | + * and vmentry. | |
| 52 | + */ | |
| 53 | + movl SVM_spec_ctrl(%_ASM_DI), %eax | |
| 54 | + cmp PER_CPU_VAR(x86_spec_ctrl_current), %eax | |
| 55 | + je 801b | |
| 56 | + mov $MSR_IA32_SPEC_CTRL, %ecx | |
| 57 | + xor %edx, %edx | |
| 58 | + wrmsr | |
| 59 | + jmp 801b | |
| 60 | +.endm | |
| 61 | + | |
| 62 | +.macro RESTORE_HOST_SPEC_CTRL | |
| 63 | + /* No need to do anything if SPEC_CTRL is unset or V_SPEC_CTRL is set */ | |
| 64 | + ALTERNATIVE_2 "", \ | |
| 65 | + "jmp 900f", X86_FEATURE_MSR_SPEC_CTRL, \ | |
| 66 | + "", X86_FEATURE_V_SPEC_CTRL | |
| 67 | +901: | |
| 68 | +.endm | |
| 69 | +.macro RESTORE_HOST_SPEC_CTRL_BODY | |
| 70 | +900: | |
| 71 | + /* Same for after vmexit. */ | |
| 72 | + mov $MSR_IA32_SPEC_CTRL, %ecx | |
| 73 | + | |
| 74 | + /* | |
| 75 | + * Load the value that the guest had written into MSR_IA32_SPEC_CTRL, | |
| 76 | + * if it was not intercepted during guest execution. | |
| 77 | + */ | |
| 78 | + cmpb $0, (%_ASM_SP) | |
| 79 | + jnz 998f | |
| 80 | + rdmsr | |
| 81 | + movl %eax, SVM_spec_ctrl(%_ASM_DI) | |
| 82 | +998: | |
| 83 | + | |
| 84 | + /* Now restore the host value of the MSR if different from the guest's. */ | |
| 85 | + movl PER_CPU_VAR(x86_spec_ctrl_current), %eax | |
| 86 | + cmp SVM_spec_ctrl(%_ASM_DI), %eax | |
| 87 | + je 901b | |
| 88 | + xor %edx, %edx | |
| 89 | + wrmsr | |
| 90 | + jmp 901b | |
| 91 | +.endm | |
| 92 | + | |
| 93 | + | |
| 32 | 94 | /** |
| 33 | 95 | * __svm_vcpu_run - Run a vCPU via a transition to SVM guest mode |
| 34 | − * @vmcb_pa: unsigned long | |
| 35 | − * @regs: unsigned long * (to guest registers) | |
| 96 | + * @svm: struct vcpu_svm * | |
| 97 | + * @spec_ctrl_intercepted: bool | |
| 36 | 98 | */ |
| 37 | 99 | SYM_FUNC_START(__svm_vcpu_run) |
| 38 | 100 | push %_ASM_BP |
| @@ -47,49 +109,71 @@ SYM_FUNC_START(__svm_vcpu_run) · 8 unmodified lines | ||
| 47 | 109 | #endif |
| 48 | 110 | push %_ASM_BX |
| 49 | 111 | |
| 50 | − /* Save @regs. */ | |
| 112 | + /* | |
| 113 | + * Save variables needed after vmexit on the stack, in inverse | |
| 114 | + * order compared to when they are needed. | |
| 115 | + */ | |
| 116 | + | |
| 117 | + /* Accessed directly from the stack in RESTORE_HOST_SPEC_CTRL. */ | |
| 51 | 118 | push %_ASM_ARG2 |
| 52 | 119 | |
| 53 | − /* Save @vmcb. */ | |
| 120 | + /* Needed to restore access to percpu variables. */ | |
| 121 | + __ASM_SIZE(push) PER_CPU_VAR(svm_data + SD_save_area_pa) | |
| 122 | + | |
| 123 | + /* Finally save @svm. */ | |
| 54 | 124 | push %_ASM_ARG1 |
| 55 | 125 | |
| 56 | − /* Move @regs to RAX. */ | |
| 57 | − mov %_ASM_ARG2, %_ASM_AX | |
| 126 | +.ifnc _ASM_ARG1, _ASM_DI | |
| 127 | + /* | |
| 128 | + * Stash @svm in RDI early. On 32-bit, arguments are in RAX, RCX | |
| 129 | + * and RDX which are clobbered by RESTORE_GUEST_SPEC_CTRL. | |
| 130 | + */ | |
| 131 | + mov %_ASM_ARG1, %_ASM_DI | |
| 132 | +.endif | |
| 133 | + | |
| 134 | + /* Clobbers RAX, RCX, RDX. */ | |
| 135 | + RESTORE_GUEST_SPEC_CTRL | |
| 136 | + | |
| 137 | + /* | |
| 138 | + * Use a single vmcb (vmcb01 because it's always valid) for | |
| 139 | + * context switching guest state via VMLOAD/VMSAVE, that way | |
| 140 | + * the state doesn't need to be copied between vmcb01 and | |
| 141 | + * vmcb02 when switching vmcbs for nested virtualization. | |
| 142 | + */ | |
| 143 | + mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX | |
| 144 | +1: vmload %_ASM_AX | |
| 145 | +2: | |
| 146 | + | |
| 147 | + /* Get svm->current_vmcb->pa into RAX. */ | |
| 148 | + mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX | |
| 149 | + mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX | |
| 58 | 150 | |
| 59 | 151 | /* Load guest registers. */ |
| 60 | − mov VCPU_RCX(%_ASM_AX), %_ASM_CX | |
| 61 | − mov VCPU_RDX(%_ASM_AX), %_ASM_DX | |
| 62 | − mov VCPU_RBX(%_ASM_AX), %_ASM_BX | |
| 63 | − mov VCPU_RBP(%_ASM_AX), %_ASM_BP | |
| 64 | − mov VCPU_RSI(%_ASM_AX), %_ASM_SI | |
| 65 | − mov VCPU_RDI(%_ASM_AX), %_ASM_DI | |
| 152 | + mov VCPU_RCX(%_ASM_DI), %_ASM_CX | |
| 153 | + mov VCPU_RDX(%_ASM_DI), %_ASM_DX | |
| 154 | + mov VCPU_RBX(%_ASM_DI), %_ASM_BX | |
| 155 | + mov VCPU_RBP(%_ASM_DI), %_ASM_BP | |
| 156 | + mov VCPU_RSI(%_ASM_DI), %_ASM_SI | |
| 66 | 157 | #ifdef CONFIG_X86_64 |
| 67 | − mov VCPU_R8 (%_ASM_AX), %r8 | |
| 68 | − mov VCPU_R9 (%_ASM_AX), %r9 | |
| 69 | − mov VCPU_R10(%_ASM_AX), %r10 | |
| 70 | − mov VCPU_R11(%_ASM_AX), %r11 | |
| 71 | − mov VCPU_R12(%_ASM_AX), %r12 | |
| 72 | − mov VCPU_R13(%_ASM_AX), %r13 | |
| 73 | − mov VCPU_R14(%_ASM_AX), %r14 | |
| 74 | − mov VCPU_R15(%_ASM_AX), %r15 | |
| 158 | + mov VCPU_R8 (%_ASM_DI), %r8 | |
| 159 | + mov VCPU_R9 (%_ASM_DI), %r9 | |
| 160 | + mov VCPU_R10(%_ASM_DI), %r10 | |
| 161 | + mov VCPU_R11(%_ASM_DI), %r11 | |
| 162 | + mov VCPU_R12(%_ASM_DI), %r12 | |
| 163 | + mov VCPU_R13(%_ASM_DI), %r13 | |
| 164 | + mov VCPU_R14(%_ASM_DI), %r14 | |
| 165 | + mov VCPU_R15(%_ASM_DI), %r15 | |
| 75 | 166 | #endif |
| 76 | − | |
| 77 | − /* "POP" @vmcb to RAX. */ | |
| 78 | − pop %_ASM_AX | |
| 167 | + mov VCPU_RDI(%_ASM_DI), %_ASM_DI | |
| 79 | 168 | |
| 80 | 169 | /* Enter guest mode */ |
| 81 | 170 | sti |
| 82 | 171 | |
| 83 | −1: vmrun %_ASM_AX | |
| 84 | − | |
| 85 | −2: cli | |
| 86 | − | |
| 87 | −#ifdef CONFIG_RETPOLINE | |
| 88 | − /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ | |
| 89 | − FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE | |
| 90 | −#endif | |
| 172 | +3: vmrun %_ASM_AX | |
| 173 | +4: | |
| 174 | + cli | |
| 91 | 175 | |
| 92 | − /* "POP" @regs to RAX. */ | |
| 176 | + /* Pop @svm to RAX while it's the only available register. */ | |
| 93 | 177 | pop %_ASM_AX |
| 94 | 178 | |
| 95 | 179 | /* Save all guest registers. */ |
| @@ -110,6 +194,26 @@ SYM_FUNC_START(__svm_vcpu_run) · 14 unmodified lines | ||
| 110 | 194 | mov %r15, VCPU_R15(%_ASM_AX) |
| 111 | 195 | #endif |
| 112 | 196 | |
| 197 | + /* @svm can stay in RDI from now on. */ | |
| 198 | + mov %_ASM_AX, %_ASM_DI | |
| 199 | + | |
| 200 | + mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX | |
| 201 | +5: vmsave %_ASM_AX | |
| 202 | +6: | |
| 203 | + | |
| 204 | + /* Restores GSBASE among other things, allowing access to percpu data. */ | |
| 205 | + pop %_ASM_AX | |
| 206 | +7: vmload %_ASM_AX | |
| 207 | +8: | |
| 208 | + | |
| 209 | +#ifdef CONFIG_RETPOLINE | |
| 210 | + /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ | |
| 211 | + FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE | |
| 212 | +#endif | |
| 213 | + | |
| 214 | + /* Clobbers RAX, RCX, RDX. */ | |
| 215 | + RESTORE_HOST_SPEC_CTRL | |
| 216 | + | |
| 113 | 217 | /* |
| 114 | 218 | * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be |
| 115 | 219 | * untrained as soon as we exit the VM and are back to the |
| @@ -145,6 +249,9 @@ SYM_FUNC_START(__svm_vcpu_run) · 29 unmodified lines | ||
| 145 | 249 | xor %r15d, %r15d |
| 146 | 250 | #endif |
| 147 | 251 | |
| 252 | + /* "Pop" @spec_ctrl_intercepted. */ | |
| 253 | + pop %_ASM_BX | |
| 254 | + | |
| 148 | 255 | pop %_ASM_BX |
| 149 | 256 | |
| 150 | 257 | #ifdef CONFIG_X86_64 |
| @@ -159,17 +266,33 @@ SYM_FUNC_START(__svm_vcpu_run) · 8 unmodified lines | ||
| 159 | 266 | pop %_ASM_BP |
| 160 | 267 | RET |
| 161 | 268 | |
| 162 | −3: cmpb $0, kvm_rebooting | |
| 269 | + RESTORE_GUEST_SPEC_CTRL_BODY | |
| 270 | + RESTORE_HOST_SPEC_CTRL_BODY | |
| 271 | + | |
| 272 | +10: cmpb $0, kvm_rebooting | |
| 163 | 273 | jne 2b |
| 164 | 274 | ud2 |
| 275 | +30: cmpb $0, kvm_rebooting | |
| 276 | + jne 4b | |
| 277 | + ud2 | |
| 278 | +50: cmpb $0, kvm_rebooting | |
| 279 | + jne 6b | |
| 280 | + ud2 | |
| 281 | +70: cmpb $0, kvm_rebooting | |
| 282 | + jne 8b | |
| 283 | + ud2 | |
| 165 | 284 | |
| 166 | − _ASM_EXTABLE(1b, 3b) | |
| 285 | + _ASM_EXTABLE(1b, 10b) | |
| 286 | + _ASM_EXTABLE(3b, 30b) | |
| 287 | + _ASM_EXTABLE(5b, 50b) | |
| 288 | + _ASM_EXTABLE(7b, 70b) | |
| 167 | 289 | |
| 168 | 290 | SYM_FUNC_END(__svm_vcpu_run) |
| 169 | 291 | |
| 170 | 292 | /** |
| 171 | 293 | * __svm_sev_es_vcpu_run - Run a SEV-ES vCPU via a transition to SVM guest mode |
| 172 | − * @vmcb_pa: unsigned long | |
| 294 | + * @svm: struct vcpu_svm * | |
| 295 | + * @spec_ctrl_intercepted: bool | |
| 173 | 296 | */ |
| 174 | 297 | SYM_FUNC_START(__svm_sev_es_vcpu_run) |
| 175 | 298 | push %_ASM_BP |
| @@ -184,8 +307,31 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run) · 8 unmodified lines | ||
| 184 | 307 | #endif |
| 185 | 308 | push %_ASM_BX |
| 186 | 309 | |
| 187 | − /* Move @vmcb to RAX. */ | |
| 188 | − mov %_ASM_ARG1, %_ASM_AX | |
| 310 | + /* | |
| 311 | + * Save variables needed after vmexit on the stack, in inverse | |
| 312 | + * order compared to when they are needed. | |
| 313 | + */ | |
| 314 | + | |
| 315 | + /* Accessed directly from the stack in RESTORE_HOST_SPEC_CTRL. */ | |
| 316 | + push %_ASM_ARG2 | |
| 317 | + | |
| 318 | + /* Save @svm. */ | |
| 319 | + push %_ASM_ARG1 | |
| 320 | + | |
| 321 | +.ifnc _ASM_ARG1, _ASM_DI | |
| 322 | + /* | |
| 323 | + * Stash @svm in RDI early. On 32-bit, arguments are in RAX, RCX | |
| 324 | + * and RDX which are clobbered by RESTORE_GUEST_SPEC_CTRL. | |
| 325 | + */ | |
| 326 | + mov %_ASM_ARG1, %_ASM_DI | |
| 327 | +.endif | |
| 328 | + | |
| 329 | + /* Clobbers RAX, RCX, RDX. */ | |
| 330 | + RESTORE_GUEST_SPEC_CTRL | |
| 331 | + | |
| 332 | + /* Get svm->current_vmcb->pa into RAX. */ | |
| 333 | + mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX | |
| 334 | + mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX | |
| 189 | 335 | |
| 190 | 336 | /* Enter guest mode */ |
| 191 | 337 | sti |
| @@ -194,11 +340,17 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run) · 2 unmodified lines | ||
| 194 | 340 | |
| 195 | 341 | 2: cli |
| 196 | 342 | |
| 343 | + /* Pop @svm to RDI, guest registers have been saved already. */ | |
| 344 | + pop %_ASM_DI | |
| 345 | + | |
| 197 | 346 | #ifdef CONFIG_RETPOLINE |
| 198 | 347 | /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */ |
| 199 | 348 | FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE |
| 200 | 349 | #endif |
| 201 | 350 | |
| 351 | + /* Clobbers RAX, RCX, RDX. */ | |
| 352 | + RESTORE_HOST_SPEC_CTRL | |
| 353 | + | |
| 202 | 354 | /* |
| 203 | 355 | * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be |
| 204 | 356 | * untrained as soon as we exit the VM and are back to the |
| @@ -208,6 +360,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run) · 3 unmodified lines | ||
| 208 | 360 | */ |
| 209 | 361 | UNTRAIN_RET |
| 210 | 362 | |
| 363 | + /* "Pop" @spec_ctrl_intercepted. */ | |
| 364 | + pop %_ASM_BX | |
| 365 | + | |
| 211 | 366 | pop %_ASM_BX |
| 212 | 367 | |
| 213 | 368 | #ifdef CONFIG_X86_64 |
| @@ -222,6 +377,9 @@ SYM_FUNC_START(__svm_sev_es_vcpu_run) · 8 unmodified lines | ||
| 222 | 377 | pop %_ASM_BP |
| 223 | 378 | RET |
| 224 | 379 | |
| 380 | + RESTORE_GUEST_SPEC_CTRL_BODY | |
| 381 | + RESTORE_HOST_SPEC_CTRL_BODY | |
| 382 | + | |
| 225 | 383 | 3: cmpb $0, kvm_rebooting |
| 226 | 384 | jne 2b |
| 227 | 385 | ud2 |
| @@ -24,8 +24,6 @@ extern int __read_mostly pt_mode; · 23 unmodified lines | ||
| 24 | 24 | #define PMU_CAP_FW_WRITES (1ULL << 13) |
| 25 | 25 | #define PMU_CAP_LBR_FMT 0x3f |
| 26 | 26 | |
| 27 | −#define DEBUGCTLMSR_LBR_MASK (DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI) | |
| 28 | − | |
| 29 | 27 | struct nested_vmx_msrs { |
| 30 | 28 | /* |
| 31 | 29 | * We only store the "true" versions of the VMX capability MSRs. We |
| @@ -400,6 +398,7 @@ static inline bool vmx_pebs_supported(void) · 368 unmodified lines | ||
| 400 | 398 | static inline u64 vmx_get_perf_capabilities(void) |
| 401 | 399 | { |
| 402 | 400 | u64 perf_cap = PMU_CAP_FW_WRITES; |
| 401 | + struct x86_pmu_lbr lbr; | |
| 403 | 402 | u64 host_perf_cap = 0; |
| 404 | 403 | |
| 405 | 404 | if (!enable_pmu) |
| @@ -408,7 +407,8 @@ static inline u64 vmx_get_perf_capabilities(void) · 2 unmodified lines | ||
| 408 | 407 | if (boot_cpu_has(X86_FEATURE_PDCM)) |
| 409 | 408 | rdmsrl(MSR_IA32_PERF_CAPABILITIES, host_perf_cap); |
| 410 | 409 | |
| 411 | − perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT; | |
| 410 | + if (x86_perf_get_lbr(&lbr) >= 0 && lbr.nr) | |
| 411 | + perf_cap |= host_perf_cap & PMU_CAP_LBR_FMT; | |
| 412 | 412 | |
| 413 | 413 | if (vmx_pebs_supported()) { |
| 414 | 414 | perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK; |
| @@ -419,19 +419,6 @@ static inline u64 vmx_get_perf_capabilities(void) · 4 unmodified lines | ||
| 419 | 419 | return perf_cap; |
| 420 | 420 | } |
| 421 | 421 | |
| 422 | −static inline u64 vmx_supported_debugctl(void) | |
| 423 | −{ | |
| 424 | − u64 debugctl = 0; | |
| 425 | − | |
| 426 | − if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT)) | |
| 427 | − debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT; | |
| 428 | − | |
| 429 | − if (vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT) | |
| 430 | − debugctl |= DEBUGCTLMSR_LBR_MASK; | |
| 431 | − | |
| 432 | − return debugctl; | |
| 433 | −} | |
| 434 | − | |
| 435 | 422 | static inline bool cpu_has_notify_vmexit(void) |
| 436 | 423 | { |
| 437 | 424 | return vmcs_config.cpu_based_2nd_exec_ctrl & |
| @@ -4854,6 +4854,7 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 vm_exit_reason, · 4853 unmodified lines | ||
| 4854 | 4854 | |
| 4855 | 4855 | static void nested_vmx_triple_fault(struct kvm_vcpu *vcpu) |
| 4856 | 4856 | { |
| 4857 | + kvm_clear_request(KVM_REQ_TRIPLE_FAULT, vcpu); | |
| 4857 | 4858 | nested_vmx_vmexit(vcpu, EXIT_REASON_TRIPLE_FAULT, 0, 0); |
| 4858 | 4859 | } |
| 4859 | 4860 | |
| @@ -6440,9 +6441,6 @@ out: · 1580 unmodified lines | ||
| 6440 | 6441 | return kvm_state.size; |
| 6441 | 6442 | } |
| 6442 | 6443 | |
| 6443 | −/* | |
| 6444 | − * Forcibly leave nested mode in order to be able to reset the VCPU later on. | |
| 6445 | − */ | |
| 6446 | 6444 | void vmx_leave_nested(struct kvm_vcpu *vcpu) |
| 6447 | 6445 | { |
| 6448 | 6446 | if (is_guest_mode(vcpu)) { |
| @@ -617,7 +617,7 @@ static void intel_pmu_init(struct kvm_vcpu *vcpu) · 616 unmodified lines | ||
| 617 | 617 | struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); |
| 618 | 618 | struct lbr_desc *lbr_desc = vcpu_to_lbr_desc(vcpu); |
| 619 | 619 | |
| 620 | − for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) { | |
| 620 | + for (i = 0; i < KVM_INTEL_PMC_MAX_GENERIC; i++) { | |
| 621 | 621 | pmu->gp_counters[i].type = KVM_PMC_GP; |
| 622 | 622 | pmu->gp_counters[i].vcpu = vcpu; |
| 623 | 623 | pmu->gp_counters[i].idx = i; |
| @@ -643,7 +643,7 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu) · 19 unmodified lines | ||
| 643 | 643 | struct kvm_pmc *pmc = NULL; |
| 644 | 644 | int i; |
| 645 | 645 | |
| 646 | − for (i = 0; i < INTEL_PMC_MAX_GENERIC; i++) { | |
| 646 | + for (i = 0; i < KVM_INTEL_PMC_MAX_GENERIC; i++) { | |
| 647 | 647 | pmc = &pmu->gp_counters[i]; |
| 648 | 648 | |
| 649 | 649 | pmc_stop_counter(pmc); |
| @@ -1,12 +1,12 @@ | ||
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 2 | #include <linux/linkage.h> |
| 3 | 3 | #include <asm/asm.h> |
| 4 | −#include <asm/asm-offsets.h> | |
| 5 | 4 | #include <asm/bitsperlong.h> |
| 6 | 5 | #include <asm/kvm_vcpu_regs.h> |
| 7 | 6 | #include <asm/nospec-branch.h> |
| 8 | 7 | #include <asm/percpu.h> |
| 9 | 8 | #include <asm/segment.h> |
| 9 | +#include "kvm-asm-offsets.h" | |
| 10 | 10 | #include "run_flags.h" |
| 11 | 11 | |
| 12 | 12 | #define WORD_SIZE (BITS_PER_LONG / 8) |
| @@ -2021,15 +2021,17 @@ static u64 nested_vmx_truncate_sysenter_addr(struct kvm_vcpu *vcpu, · 2020 unmodified lines | ||
| 2021 | 2021 | return (unsigned long)data; |
| 2022 | 2022 | } |
| 2023 | 2023 | |
| 2024 | −static u64 vcpu_supported_debugctl(struct kvm_vcpu *vcpu) | |
| 2024 | +static u64 vmx_get_supported_debugctl(struct kvm_vcpu *vcpu, bool host_initiated) | |
| 2025 | 2025 | { |
| 2026 | − u64 debugctl = vmx_supported_debugctl(); | |
| 2026 | + u64 debugctl = 0; | |
| 2027 | 2027 | |
| 2028 | − if (!intel_pmu_lbr_is_enabled(vcpu)) | |
| 2029 | − debugctl &= ~DEBUGCTLMSR_LBR_MASK; | |
| 2028 | + if (boot_cpu_has(X86_FEATURE_BUS_LOCK_DETECT) && | |
| 2029 | + (host_initiated || guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT))) | |
| 2030 | + debugctl |= DEBUGCTLMSR_BUS_LOCK_DETECT; | |
| 2030 | 2031 | |
| 2031 | − if (!guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT)) | |
| 2032 | − debugctl &= ~DEBUGCTLMSR_BUS_LOCK_DETECT; | |
| 2032 | + if ((vmx_get_perf_capabilities() & PMU_CAP_LBR_FMT) && | |
| 2033 | + (host_initiated || intel_pmu_lbr_is_enabled(vcpu))) | |
| 2034 | + debugctl |= DEBUGCTLMSR_LBR | DEBUGCTLMSR_FREEZE_LBRS_ON_PMI; | |
| 2033 | 2035 | |
| 2034 | 2036 | return debugctl; |
| 2035 | 2037 | } |
| @@ -2103,7 +2105,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 67 unmodified lines | ||
| 2103 | 2105 | vmcs_writel(GUEST_SYSENTER_ESP, data); |
| 2104 | 2106 | break; |
| 2105 | 2107 | case MSR_IA32_DEBUGCTLMSR: { |
| 2106 | − u64 invalid = data & ~vcpu_supported_debugctl(vcpu); | |
| 2108 | + u64 invalid; | |
| 2109 | + | |
| 2110 | + invalid = data & ~vmx_get_supported_debugctl(vcpu, msr_info->host_initiated); | |
| 2107 | 2111 | if (invalid & (DEBUGCTLMSR_BTF|DEBUGCTLMSR_LBR)) { |
| 2108 | 2112 | if (report_ignored_msrs) |
| 2109 | 2113 | vcpu_unimpl(vcpu, "%s: BTF|LBR in IA32_DEBUGCTLMSR 0x%llx, nop\n", |
| @@ -8263,6 +8267,11 @@ static __init int hardware_setup(void) · 6153 unmodified lines | ||
| 8263 | 8267 | if (!cpu_has_virtual_nmis()) |
| 8264 | 8268 | enable_vnmi = 0; |
| 8265 | 8269 | |
| 8270 | +#ifdef CONFIG_X86_SGX_KVM | |
| 8271 | + if (!cpu_has_vmx_encls_vmexit()) | |
| 8272 | + enable_sgx = false; | |
| 8273 | +#endif | |
| 8274 | + | |
| 8266 | 8275 | /* |
| 8267 | 8276 | * set_apic_access_page_addr() is used to reload apic access |
| 8268 | 8277 | * page upon invalidation. No need to do anything if not |
| @@ -628,6 +628,12 @@ static void kvm_queue_exception_vmexit(struct kvm_vcpu *vcpu, unsigned int vecto · 627 unmodified lines | ||
| 628 | 628 | ex->payload = payload; |
| 629 | 629 | } |
| 630 | 630 | |
| 631 | +/* Forcibly leave the nested mode in cases like a vCPU reset */ | |
| 632 | +static void kvm_leave_nested(struct kvm_vcpu *vcpu) | |
| 633 | +{ | |
| 634 | + kvm_x86_ops.nested_ops->leave_nested(vcpu); | |
| 635 | +} | |
| 636 | + | |
| 631 | 637 | static void kvm_multiple_exception(struct kvm_vcpu *vcpu, |
| 632 | 638 | unsigned nr, bool has_error, u32 error_code, |
| 633 | 639 | bool has_payload, unsigned long payload, bool reinject) |
| @@ -1438,32 +1444,27 @@ static const u32 msrs_to_save_all[] = { · 804 unmodified lines | ||
| 1438 | 1444 | MSR_ARCH_PERFMON_FIXED_CTR0 + 2, |
| 1439 | 1445 | MSR_CORE_PERF_FIXED_CTR_CTRL, MSR_CORE_PERF_GLOBAL_STATUS, |
| 1440 | 1446 | MSR_CORE_PERF_GLOBAL_CTRL, MSR_CORE_PERF_GLOBAL_OVF_CTRL, |
| 1447 | + MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG, | |
| 1448 | + | |
| 1449 | + /* This part of MSRs should match KVM_INTEL_PMC_MAX_GENERIC. */ | |
| 1441 | 1450 | MSR_ARCH_PERFMON_PERFCTR0, MSR_ARCH_PERFMON_PERFCTR1, |
| 1442 | 1451 | MSR_ARCH_PERFMON_PERFCTR0 + 2, MSR_ARCH_PERFMON_PERFCTR0 + 3, |
| 1443 | 1452 | MSR_ARCH_PERFMON_PERFCTR0 + 4, MSR_ARCH_PERFMON_PERFCTR0 + 5, |
| 1444 | 1453 | MSR_ARCH_PERFMON_PERFCTR0 + 6, MSR_ARCH_PERFMON_PERFCTR0 + 7, |
| 1445 | − MSR_ARCH_PERFMON_PERFCTR0 + 8, MSR_ARCH_PERFMON_PERFCTR0 + 9, | |
| 1446 | − MSR_ARCH_PERFMON_PERFCTR0 + 10, MSR_ARCH_PERFMON_PERFCTR0 + 11, | |
| 1447 | − MSR_ARCH_PERFMON_PERFCTR0 + 12, MSR_ARCH_PERFMON_PERFCTR0 + 13, | |
| 1448 | − MSR_ARCH_PERFMON_PERFCTR0 + 14, MSR_ARCH_PERFMON_PERFCTR0 + 15, | |
| 1449 | − MSR_ARCH_PERFMON_PERFCTR0 + 16, MSR_ARCH_PERFMON_PERFCTR0 + 17, | |
| 1450 | 1454 | MSR_ARCH_PERFMON_EVENTSEL0, MSR_ARCH_PERFMON_EVENTSEL1, |
| 1451 | 1455 | MSR_ARCH_PERFMON_EVENTSEL0 + 2, MSR_ARCH_PERFMON_EVENTSEL0 + 3, |
| 1452 | 1456 | MSR_ARCH_PERFMON_EVENTSEL0 + 4, MSR_ARCH_PERFMON_EVENTSEL0 + 5, |
| 1453 | 1457 | MSR_ARCH_PERFMON_EVENTSEL0 + 6, MSR_ARCH_PERFMON_EVENTSEL0 + 7, |
| 1454 | − MSR_ARCH_PERFMON_EVENTSEL0 + 8, MSR_ARCH_PERFMON_EVENTSEL0 + 9, | |
| 1455 | − MSR_ARCH_PERFMON_EVENTSEL0 + 10, MSR_ARCH_PERFMON_EVENTSEL0 + 11, | |
| 1456 | − MSR_ARCH_PERFMON_EVENTSEL0 + 12, MSR_ARCH_PERFMON_EVENTSEL0 + 13, | |
| 1457 | − MSR_ARCH_PERFMON_EVENTSEL0 + 14, MSR_ARCH_PERFMON_EVENTSEL0 + 15, | |
| 1458 | − MSR_ARCH_PERFMON_EVENTSEL0 + 16, MSR_ARCH_PERFMON_EVENTSEL0 + 17, | |
| 1459 | − MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG, | |
| 1460 | 1458 | |
| 1461 | 1459 | MSR_K7_EVNTSEL0, MSR_K7_EVNTSEL1, MSR_K7_EVNTSEL2, MSR_K7_EVNTSEL3, |
| 1462 | 1460 | MSR_K7_PERFCTR0, MSR_K7_PERFCTR1, MSR_K7_PERFCTR2, MSR_K7_PERFCTR3, |
| 1461 | + | |
| 1462 | + /* This part of MSRs should match KVM_AMD_PMC_MAX_GENERIC. */ | |
| 1463 | 1463 | MSR_F15H_PERF_CTL0, MSR_F15H_PERF_CTL1, MSR_F15H_PERF_CTL2, |
| 1464 | 1464 | MSR_F15H_PERF_CTL3, MSR_F15H_PERF_CTL4, MSR_F15H_PERF_CTL5, |
| 1465 | 1465 | MSR_F15H_PERF_CTR0, MSR_F15H_PERF_CTR1, MSR_F15H_PERF_CTR2, |
| 1466 | 1466 | MSR_F15H_PERF_CTR3, MSR_F15H_PERF_CTR4, MSR_F15H_PERF_CTR5, |
| 1467 | + | |
| 1467 | 1468 | MSR_IA32_XFD, MSR_IA32_XFD_ERR, |
| 1468 | 1469 | }; |
| 1469 | 1470 | |
| @@ -1562,7 +1563,7 @@ static const u32 msr_based_features_all[] = { · 92 unmodified lines | ||
| 1562 | 1563 | MSR_IA32_VMX_EPT_VPID_CAP, |
| 1563 | 1564 | MSR_IA32_VMX_VMFUNC, |
| 1564 | 1565 | |
| 1565 | − MSR_F10H_DECFG, | |
| 1566 | + MSR_AMD64_DE_CFG, | |
| 1566 | 1567 | MSR_IA32_UCODE_REV, |
| 1567 | 1568 | MSR_IA32_ARCH_CAPABILITIES, |
| 1568 | 1569 | MSR_IA32_PERF_CAPABILITIES, |
| @@ -2315,11 +2316,11 @@ static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time, · 746 unmodified lines | ||
| 2315 | 2316 | |
| 2316 | 2317 | /* we verify if the enable bit is set... */ |
| 2317 | 2318 | if (system_time & 1) { |
| 2318 | − kvm_gfn_to_pfn_cache_init(vcpu->kvm, &vcpu->arch.pv_time, vcpu, | |
| 2319 | − KVM_HOST_USES_PFN, system_time & ~1ULL, | |
| 2320 | − sizeof(struct pvclock_vcpu_time_info)); | |
| 2319 | + kvm_gpc_activate(vcpu->kvm, &vcpu->arch.pv_time, vcpu, | |
| 2320 | + KVM_HOST_USES_PFN, system_time & ~1ULL, | |
| 2321 | + sizeof(struct pvclock_vcpu_time_info)); | |
| 2321 | 2322 | } else { |
| 2322 | − kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.pv_time); | |
| 2323 | + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.pv_time); | |
| 2323 | 2324 | } |
| 2324 | 2325 | |
| 2325 | 2326 | return; |
| @@ -3388,7 +3389,7 @@ static int kvm_pv_enable_async_pf_int(struct kvm_vcpu *vcpu, u64 data) · 1062 unmodified lines | ||
| 3388 | 3389 | |
| 3389 | 3390 | static void kvmclock_reset(struct kvm_vcpu *vcpu) |
| 3390 | 3391 | { |
| 3391 | − kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.pv_time); | |
| 3392 | + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.pv_time); | |
| 3392 | 3393 | vcpu->arch.time = 0; |
| 3393 | 3394 | } |
| 3394 | 3395 | |
| @@ -5200,7 +5201,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, · 1805 unmodified lines | ||
| 5200 | 5201 | |
| 5201 | 5202 | if (events->flags & KVM_VCPUEVENT_VALID_SMM) { |
| 5202 | 5203 | if (!!(vcpu->arch.hflags & HF_SMM_MASK) != events->smi.smm) { |
| 5203 | − kvm_x86_ops.nested_ops->leave_nested(vcpu); | |
| 5204 | + kvm_leave_nested(vcpu); | |
| 5204 | 5205 | kvm_smm_changed(vcpu, events->smi.smm); |
| 5205 | 5206 | } |
| 5206 | 5207 | |
| @@ -7041,14 +7042,14 @@ static void kvm_init_msr_list(void) · 1834 unmodified lines | ||
| 7041 | 7042 | intel_pt_validate_hw_cap(PT_CAP_num_address_ranges) * 2) |
| 7042 | 7043 | continue; |
| 7043 | 7044 | break; |
| 7044 | − case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 17: | |
| 7045 | + case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR_MAX: | |
| 7045 | 7046 | if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_PERFCTR0 >= |
| 7046 | − min(INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp)) | |
| 7047 | + min(KVM_INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp)) | |
| 7047 | 7048 | continue; |
| 7048 | 7049 | break; |
| 7049 | − case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 17: | |
| 7050 | + case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL_MAX: | |
| 7050 | 7051 | if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_EVENTSEL0 >= |
| 7051 | − min(INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp)) | |
| 7052 | + min(KVM_INTEL_PMC_MAX_GENERIC, kvm_pmu_cap.num_counters_gp)) | |
| 7052 | 7053 | continue; |
| 7053 | 7054 | break; |
| 7054 | 7055 | case MSR_IA32_XFD: |
| @@ -9810,7 +9811,7 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu) · 2755 unmodified lines | ||
| 9810 | 9811 | |
| 9811 | 9812 | int kvm_check_nested_events(struct kvm_vcpu *vcpu) |
| 9812 | 9813 | { |
| 9813 | − if (kvm_check_request(KVM_REQ_TRIPLE_FAULT, vcpu)) { | |
| 9814 | + if (kvm_test_request(KVM_REQ_TRIPLE_FAULT, vcpu)) { | |
| 9814 | 9815 | kvm_x86_ops.nested_ops->triple_fault(vcpu); |
| 9815 | 9816 | return 1; |
| 9816 | 9817 | } |
| @@ -10044,7 +10045,20 @@ static int kvm_check_and_inject_events(struct kvm_vcpu *vcpu, · 227 unmodified lines | ||
| 10044 | 10045 | kvm_x86_ops.nested_ops->has_events(vcpu)) |
| 10045 | 10046 | *req_immediate_exit = true; |
| 10046 | 10047 | |
| 10047 | − WARN_ON(kvm_is_exception_pending(vcpu)); | |
| 10048 | + /* | |
| 10049 | + * KVM must never queue a new exception while injecting an event; KVM | |
| 10050 | + * is done emulating and should only propagate the to-be-injected event | |
| 10051 | + * to the VMCS/VMCB. Queueing a new exception can put the vCPU into an | |
| 10052 | + * infinite loop as KVM will bail from VM-Enter to inject the pending | |
| 10053 | + * exception and start the cycle all over. | |
| 10054 | + * | |
| 10055 | + * Exempt triple faults as they have special handling and won't put the | |
| 10056 | + * vCPU into an infinite loop. Triple fault can be queued when running | |
| 10057 | + * VMX without unrestricted guest, as that requires KVM to emulate Real | |
| 10058 | + * Mode events (see kvm_inject_realmode_interrupt()). | |
| 10059 | + */ | |
| 10060 | + WARN_ON_ONCE(vcpu->arch.exception.pending || | |
| 10061 | + vcpu->arch.exception_vmexit.pending); | |
| 10048 | 10062 | return 0; |
| 10049 | 10063 | |
| 10050 | 10064 | out: |
| @@ -10391,7 +10405,10 @@ void __kvm_set_or_clear_apicv_inhibit(struct kvm *kvm, · 340 unmodified lines | ||
| 10391 | 10405 | kvm->arch.apicv_inhibit_reasons = new; |
| 10392 | 10406 | if (new) { |
| 10393 | 10407 | unsigned long gfn = gpa_to_gfn(APIC_DEFAULT_PHYS_BASE); |
| 10408 | + int idx = srcu_read_lock(&kvm->srcu); | |
| 10409 | + | |
| 10394 | 10410 | kvm_zap_gfn_range(kvm, gfn, gfn+1); |
| 10411 | + srcu_read_unlock(&kvm->srcu, idx); | |
| 10395 | 10412 | } |
| 10396 | 10413 | } else { |
| 10397 | 10414 | kvm->arch.apicv_inhibit_reasons = new; |
| @@ -10549,15 +10566,16 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 151 unmodified lines | ||
| 10549 | 10566 | r = 0; |
| 10550 | 10567 | goto out; |
| 10551 | 10568 | } |
| 10552 | − if (kvm_check_request(KVM_REQ_TRIPLE_FAULT, vcpu)) { | |
| 10553 | − if (is_guest_mode(vcpu)) { | |
| 10569 | + if (kvm_test_request(KVM_REQ_TRIPLE_FAULT, vcpu)) { | |
| 10570 | + if (is_guest_mode(vcpu)) | |
| 10554 | 10571 | kvm_x86_ops.nested_ops->triple_fault(vcpu); |
| 10555 | − } else { | |
| 10572 | + | |
| 10573 | + if (kvm_check_request(KVM_REQ_TRIPLE_FAULT, vcpu)) { | |
| 10556 | 10574 | vcpu->run->exit_reason = KVM_EXIT_SHUTDOWN; |
| 10557 | 10575 | vcpu->mmio_needed = 0; |
| 10558 | 10576 | r = 0; |
| 10559 | − goto out; | |
| 10560 | 10577 | } |
| 10578 | + goto out; | |
| 10561 | 10579 | } |
| 10562 | 10580 | if (kvm_check_request(KVM_REQ_APF_HALT, vcpu)) { |
| 10563 | 10581 | /* Page is swapped out. Do synthetic halt */ |
| @@ -11816,6 +11834,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · 1252 unmodified lines | ||
| 11816 | 11834 | vcpu->arch.regs_avail = ~0; |
| 11817 | 11835 | vcpu->arch.regs_dirty = ~0; |
| 11818 | 11836 | |
| 11837 | + kvm_gpc_init(&vcpu->arch.pv_time); | |
| 11838 | + | |
| 11819 | 11839 | if (!irqchip_in_kernel(vcpu->kvm) || kvm_vcpu_is_reset_bsp(vcpu)) |
| 11820 | 11840 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
| 11821 | 11841 | else |
| @@ -11984,8 +12004,18 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 162 unmodified lines | ||
| 11984 | 12004 | WARN_ON_ONCE(!init_event && |
| 11985 | 12005 | (old_cr0 || kvm_read_cr3(vcpu) || kvm_read_cr4(vcpu))); |
| 11986 | 12006 | |
| 12007 | + /* | |
| 12008 | + * SVM doesn't unconditionally VM-Exit on INIT and SHUTDOWN, thus it's | |
| 12009 | + * possible to INIT the vCPU while L2 is active. Force the vCPU back | |
| 12010 | + * into L1 as EFER.SVME is cleared on INIT (along with all other EFER | |
| 12011 | + * bits), i.e. virtualization is disabled. | |
| 12012 | + */ | |
| 12013 | + if (is_guest_mode(vcpu)) | |
| 12014 | + kvm_leave_nested(vcpu); | |
| 12015 | + | |
| 11987 | 12016 | kvm_lapic_reset(vcpu, init_event); |
| 11988 | 12017 | |
| 12018 | + WARN_ON_ONCE(is_guest_mode(vcpu) || is_smm(vcpu)); | |
| 11989 | 12019 | vcpu->arch.hflags = 0; |
| 11990 | 12020 | |
| 11991 | 12021 | vcpu->arch.smi_pending = 0; |
| @@ -42,13 +42,13 @@ static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn) · 41 unmodified lines | ||
| 42 | 42 | int idx = srcu_read_lock(&kvm->srcu); |
| 43 | 43 | |
| 44 | 44 | if (gfn == GPA_INVALID) { |
| 45 | − kvm_gfn_to_pfn_cache_destroy(kvm, gpc); | |
| 45 | + kvm_gpc_deactivate(kvm, gpc); | |
| 46 | 46 | goto out; |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | 49 | do { |
| 50 | − ret = kvm_gfn_to_pfn_cache_init(kvm, gpc, NULL, KVM_HOST_USES_PFN, | |
| 51 | − gpa, PAGE_SIZE); | |
| 50 | + ret = kvm_gpc_activate(kvm, gpc, NULL, KVM_HOST_USES_PFN, gpa, | |
| 51 | + PAGE_SIZE); | |
| 52 | 52 | if (ret) |
| 53 | 53 | goto out; |
| 54 | 54 | |
| @@ -554,15 +554,15 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) · 499 unmodified lines | ||
| 554 | 554 | offsetof(struct compat_vcpu_info, time)); |
| 555 | 555 | |
| 556 | 556 | if (data->u.gpa == GPA_INVALID) { |
| 557 | − kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache); | |
| 557 | + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache); | |
| 558 | 558 | r = 0; |
| 559 | 559 | break; |
| 560 | 560 | } |
| 561 | 561 | |
| 562 | − r = kvm_gfn_to_pfn_cache_init(vcpu->kvm, | |
| 563 | − &vcpu->arch.xen.vcpu_info_cache, | |
| 564 | − NULL, KVM_HOST_USES_PFN, data->u.gpa, | |
| 565 | − sizeof(struct vcpu_info)); | |
| 562 | + r = kvm_gpc_activate(vcpu->kvm, | |
| 563 | + &vcpu->arch.xen.vcpu_info_cache, NULL, | |
| 564 | + KVM_HOST_USES_PFN, data->u.gpa, | |
| 565 | + sizeof(struct vcpu_info)); | |
| 566 | 566 | if (!r) |
| 567 | 567 | kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); |
| 568 | 568 | |
| @@ -570,16 +570,16 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) · 1 unmodified line | ||
| 570 | 570 | |
| 571 | 571 | case KVM_XEN_VCPU_ATTR_TYPE_VCPU_TIME_INFO: |
| 572 | 572 | if (data->u.gpa == GPA_INVALID) { |
| 573 | − kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, | |
| 574 | − &vcpu->arch.xen.vcpu_time_info_cache); | |
| 573 | + kvm_gpc_deactivate(vcpu->kvm, | |
| 574 | + &vcpu->arch.xen.vcpu_time_info_cache); | |
| 575 | 575 | r = 0; |
| 576 | 576 | break; |
| 577 | 577 | } |
| 578 | 578 | |
| 579 | − r = kvm_gfn_to_pfn_cache_init(vcpu->kvm, | |
| 580 | − &vcpu->arch.xen.vcpu_time_info_cache, | |
| 581 | − NULL, KVM_HOST_USES_PFN, data->u.gpa, | |
| 582 | − sizeof(struct pvclock_vcpu_time_info)); | |
| 579 | + r = kvm_gpc_activate(vcpu->kvm, | |
| 580 | + &vcpu->arch.xen.vcpu_time_info_cache, | |
| 581 | + NULL, KVM_HOST_USES_PFN, data->u.gpa, | |
| 582 | + sizeof(struct pvclock_vcpu_time_info)); | |
| 583 | 583 | if (!r) |
| 584 | 584 | kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); |
| 585 | 585 | break; |
| @@ -590,16 +590,15 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data) · 4 unmodified lines | ||
| 590 | 590 | break; |
| 591 | 591 | } |
| 592 | 592 | if (data->u.gpa == GPA_INVALID) { |
| 593 | − kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, | |
| 594 | − &vcpu->arch.xen.runstate_cache); | |
| 593 | + kvm_gpc_deactivate(vcpu->kvm, | |
| 594 | + &vcpu->arch.xen.runstate_cache); | |
| 595 | 595 | r = 0; |
| 596 | 596 | break; |
| 597 | 597 | } |
| 598 | 598 | |
| 599 | − r = kvm_gfn_to_pfn_cache_init(vcpu->kvm, | |
| 600 | − &vcpu->arch.xen.runstate_cache, | |
| 601 | − NULL, KVM_HOST_USES_PFN, data->u.gpa, | |
| 602 | − sizeof(struct vcpu_runstate_info)); | |
| 599 | + r = kvm_gpc_activate(vcpu->kvm, &vcpu->arch.xen.runstate_cache, | |
| 600 | + NULL, KVM_HOST_USES_PFN, data->u.gpa, | |
| 601 | + sizeof(struct vcpu_runstate_info)); | |
| 603 | 602 | break; |
| 604 | 603 | |
| 605 | 604 | case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT: |
| @@ -955,6 +954,14 @@ static int kvm_xen_hypercall_complete_userspace(struct kvm_vcpu *vcpu) · 349 unmodified lines | ||
| 955 | 954 | return kvm_xen_hypercall_set_result(vcpu, run->xen.u.hcall.result); |
| 956 | 955 | } |
| 957 | 956 | |
| 957 | +static inline int max_evtchn_port(struct kvm *kvm) | |
| 958 | +{ | |
| 959 | + if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) | |
| 960 | + return EVTCHN_2L_NR_CHANNELS; | |
| 961 | + else | |
| 962 | + return COMPAT_EVTCHN_2L_NR_CHANNELS; | |
| 963 | +} | |
| 964 | + | |
| 958 | 965 | static bool wait_pending_event(struct kvm_vcpu *vcpu, int nr_ports, |
| 959 | 966 | evtchn_port_t *ports) |
| 960 | 967 | { |
| @@ -1043,6 +1050,10 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode, · 82 unmodified lines | ||
| 1043 | 1050 | *r = -EFAULT; |
| 1044 | 1051 | goto out; |
| 1045 | 1052 | } |
| 1053 | + if (ports[i] >= max_evtchn_port(vcpu->kvm)) { | |
| 1054 | + *r = -EINVAL; | |
| 1055 | + goto out; | |
| 1056 | + } | |
| 1046 | 1057 | } |
| 1047 | 1058 | |
| 1048 | 1059 | if (sched_poll.nr_ports == 1) |
| @@ -1216,6 +1227,7 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 167 unmodified lines | ||
| 1216 | 1227 | bool longmode; |
| 1217 | 1228 | u64 input, params[6], r = -ENOSYS; |
| 1218 | 1229 | bool handled = false; |
| 1230 | + u8 cpl; | |
| 1219 | 1231 | |
| 1220 | 1232 | input = (u64)kvm_register_read(vcpu, VCPU_REGS_RAX); |
| 1221 | 1233 | |
| @@ -1243,9 +1255,17 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 21 unmodified lines | ||
| 1243 | 1255 | params[5] = (u64)kvm_r9_read(vcpu); |
| 1244 | 1256 | } |
| 1245 | 1257 | #endif |
| 1258 | + cpl = static_call(kvm_x86_get_cpl)(vcpu); | |
| 1246 | 1259 | trace_kvm_xen_hypercall(input, params[0], params[1], params[2], |
| 1247 | 1260 | params[3], params[4], params[5]); |
| 1248 | 1261 | |
| 1262 | + /* | |
| 1263 | + * Only allow hypercall acceleration for CPL0. The rare hypercalls that | |
| 1264 | + * are permitted in guest userspace can be handled by the VMM. | |
| 1265 | + */ | |
| 1266 | + if (unlikely(cpl > 0)) | |
| 1267 | + goto handle_in_userspace; | |
| 1268 | + | |
| 1249 | 1269 | switch (input) { |
| 1250 | 1270 | case __HYPERVISOR_xen_version: |
| 1251 | 1271 | if (params[0] == XENVER_version && vcpu->kvm->arch.xen.xen_version) { |
| @@ -1280,10 +1300,11 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 28 unmodified lines | ||
| 1280 | 1300 | if (handled) |
| 1281 | 1301 | return kvm_xen_hypercall_set_result(vcpu, r); |
| 1282 | 1302 | |
| 1303 | +handle_in_userspace: | |
| 1283 | 1304 | vcpu->run->exit_reason = KVM_EXIT_XEN; |
| 1284 | 1305 | vcpu->run->xen.type = KVM_EXIT_XEN_HCALL; |
| 1285 | 1306 | vcpu->run->xen.u.hcall.longmode = longmode; |
| 1286 | − vcpu->run->xen.u.hcall.cpl = static_call(kvm_x86_get_cpl)(vcpu); | |
| 1307 | + vcpu->run->xen.u.hcall.cpl = cpl; | |
| 1287 | 1308 | vcpu->run->xen.u.hcall.input = input; |
| 1288 | 1309 | vcpu->run->xen.u.hcall.params[0] = params[0]; |
| 1289 | 1310 | vcpu->run->xen.u.hcall.params[1] = params[1]; |
| @@ -1298,14 +1319,6 @@ int kvm_xen_hypercall(struct kvm_vcpu *vcpu) · 8 unmodified lines | ||
| 1298 | 1319 | return 0; |
| 1299 | 1320 | } |
| 1300 | 1321 | |
| 1301 | −static inline int max_evtchn_port(struct kvm *kvm) | |
| 1302 | −{ | |
| 1303 | − if (IS_ENABLED(CONFIG_64BIT) && kvm->arch.xen.long_mode) | |
| 1304 | − return EVTCHN_2L_NR_CHANNELS; | |
| 1305 | − else | |
| 1306 | − return COMPAT_EVTCHN_2L_NR_CHANNELS; | |
| 1307 | −} | |
| 1308 | − | |
| 1309 | 1322 | static void kvm_xen_check_poller(struct kvm_vcpu *vcpu, int port) |
| 1310 | 1323 | { |
| 1311 | 1324 | int poll_evtchn = vcpu->arch.xen.poll_evtchn; |
| @@ -1667,18 +1680,18 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm, · 355 unmodified lines | ||
| 1667 | 1680 | case EVTCHNSTAT_ipi: |
| 1668 | 1681 | /* IPI must map back to the same port# */ |
| 1669 | 1682 | if (data->u.evtchn.deliver.port.port != data->u.evtchn.send_port) |
| 1670 | − goto out; /* -EINVAL */ | |
| 1683 | + goto out_noeventfd; /* -EINVAL */ | |
| 1671 | 1684 | break; |
| 1672 | 1685 | |
| 1673 | 1686 | case EVTCHNSTAT_interdomain: |
| 1674 | 1687 | if (data->u.evtchn.deliver.port.port) { |
| 1675 | 1688 | if (data->u.evtchn.deliver.port.port >= max_evtchn_port(kvm)) |
| 1676 | − goto out; /* -EINVAL */ | |
| 1689 | + goto out_noeventfd; /* -EINVAL */ | |
| 1677 | 1690 | } else { |
| 1678 | 1691 | eventfd = eventfd_ctx_fdget(data->u.evtchn.deliver.eventfd.fd); |
| 1679 | 1692 | if (IS_ERR(eventfd)) { |
| 1680 | 1693 | ret = PTR_ERR(eventfd); |
| 1681 | − goto out; | |
| 1694 | + goto out_noeventfd; | |
| 1682 | 1695 | } |
| 1683 | 1696 | } |
| 1684 | 1697 | break; |
| @@ -1718,6 +1731,7 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm, · 33 unmodified lines | ||
| 1718 | 1731 | out: |
| 1719 | 1732 | if (eventfd) |
| 1720 | 1733 | eventfd_ctx_put(eventfd); |
| 1734 | +out_noeventfd: | |
| 1721 | 1735 | kfree(evtchnfd); |
| 1722 | 1736 | return ret; |
| 1723 | 1737 | } |
| @@ -1816,7 +1830,12 @@ void kvm_xen_init_vcpu(struct kvm_vcpu *vcpu) · 92 unmodified lines | ||
| 1816 | 1830 | { |
| 1817 | 1831 | vcpu->arch.xen.vcpu_id = vcpu->vcpu_idx; |
| 1818 | 1832 | vcpu->arch.xen.poll_evtchn = 0; |
| 1833 | + | |
| 1819 | 1834 | timer_setup(&vcpu->arch.xen.poll_timer, cancel_evtchn_poll, 0); |
| 1835 | + | |
| 1836 | + kvm_gpc_init(&vcpu->arch.xen.runstate_cache); | |
| 1837 | + kvm_gpc_init(&vcpu->arch.xen.vcpu_info_cache); | |
| 1838 | + kvm_gpc_init(&vcpu->arch.xen.vcpu_time_info_cache); | |
| 1820 | 1839 | } |
| 1821 | 1840 | |
| 1822 | 1841 | void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu) |
| @@ -1824,18 +1843,17 @@ void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu) · 1 unmodified line | ||
| 1824 | 1843 | if (kvm_xen_timer_enabled(vcpu)) |
| 1825 | 1844 | kvm_xen_stop_timer(vcpu); |
| 1826 | 1845 | |
| 1827 | − kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, | |
| 1828 | − &vcpu->arch.xen.runstate_cache); | |
| 1829 | − kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, | |
| 1830 | − &vcpu->arch.xen.vcpu_info_cache); | |
| 1831 | − kvm_gfn_to_pfn_cache_destroy(vcpu->kvm, | |
| 1832 | − &vcpu->arch.xen.vcpu_time_info_cache); | |
| 1846 | + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.runstate_cache); | |
| 1847 | + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_info_cache); | |
| 1848 | + kvm_gpc_deactivate(vcpu->kvm, &vcpu->arch.xen.vcpu_time_info_cache); | |
| 1849 | + | |
| 1833 | 1850 | del_timer_sync(&vcpu->arch.xen.poll_timer); |
| 1834 | 1851 | } |
| 1835 | 1852 | |
| 1836 | 1853 | void kvm_xen_init_vm(struct kvm *kvm) |
| 1837 | 1854 | { |
| 1838 | 1855 | idr_init(&kvm->arch.xen.evtchn_ports); |
| 1856 | + kvm_gpc_init(&kvm->arch.xen.shinfo_cache); | |
| 1839 | 1857 | } |
| 1840 | 1858 | |
| 1841 | 1859 | void kvm_xen_destroy_vm(struct kvm *kvm) |
| @@ -1843,7 +1861,7 @@ void kvm_xen_destroy_vm(struct kvm *kvm) · 1 unmodified line | ||
| 1843 | 1861 | struct evtchnfd *evtchnfd; |
| 1844 | 1862 | int i; |
| 1845 | 1863 | |
| 1846 | − kvm_gfn_to_pfn_cache_destroy(kvm, &kvm->arch.xen.shinfo_cache); | |
| 1864 | + kvm_gpc_deactivate(kvm, &kvm->arch.xen.shinfo_cache); | |
| 1847 | 1865 | |
| 1848 | 1866 | idr_for_each_entry(&kvm->arch.xen.evtchn_ports, evtchnfd, i) { |
| 1849 | 1867 | if (!evtchnfd->deliver.port.port) |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | #include <linux/uaccess.h> |
| 8 | 8 | #include <linux/export.h> |
| 9 | +#include <linux/instrumented.h> | |
| 9 | 10 | |
| 10 | 11 | #include <asm/tlbflush.h> |
| 11 | 12 | |
| @@ -44,7 +45,9 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n) · 32 unmodified lines | ||
| 44 | 45 | * called from other contexts. |
| 45 | 46 | */ |
| 46 | 47 | pagefault_disable(); |
| 48 | + instrument_copy_from_user_before(to, from, n); | |
| 47 | 49 | ret = raw_copy_from_user(to, from, n); |
| 50 | + instrument_copy_from_user_after(to, from, n, ret); | |
| 48 | 51 | pagefault_enable(); |
| 49 | 52 | |
| 50 | 53 | return ret; |
| @@ -37,8 +37,12 @@ int pmd_huge(pmd_t pmd) · 36 unmodified lines | ||
| 37 | 37 | */ |
| 38 | 38 | int pud_huge(pud_t pud) |
| 39 | 39 | { |
| 40 | +#if CONFIG_PGTABLE_LEVELS > 2 | |
| 40 | 41 | return !pud_none(pud) && |
| 41 | 42 | (pud_val(pud) & (_PAGE_PRESENT|_PAGE_PSE)) != _PAGE_PRESENT; |
| 43 | +#else | |
| 44 | + return 0; | |
| 45 | +#endif | |
| 42 | 46 | } |
| 43 | 47 | |
| 44 | 48 | #ifdef CONFIG_HUGETLB_PAGE |
| @@ -217,9 +217,15 @@ __ioremap_caller(resource_size_t phys_addr, unsigned long size, · 216 unmodified lines | ||
| 217 | 217 | * Mappings have to be page-aligned |
| 218 | 218 | */ |
| 219 | 219 | offset = phys_addr & ~PAGE_MASK; |
| 220 | − phys_addr &= PHYSICAL_PAGE_MASK; | |
| 220 | + phys_addr &= PAGE_MASK; | |
| 221 | 221 | size = PAGE_ALIGN(last_addr+1) - phys_addr; |
| 222 | 222 | |
| 223 | + /* | |
| 224 | + * Mask out any bits not part of the actual physical | |
| 225 | + * address, like memory encryption bits. | |
| 226 | + */ | |
| 227 | + phys_addr &= PHYSICAL_PAGE_MASK; | |
| 228 | + | |
| 223 | 229 | retval = memtype_reserve(phys_addr, (u64)phys_addr + size, |
| 224 | 230 | pcm, &new_pcm); |
| 225 | 231 | if (retval) { |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/bpf.h> |
| 12 | 12 | #include <linux/memory.h> |
| 13 | 13 | #include <linux/sort.h> |
| 14 | −#include <linux/init.h> | |
| 15 | 14 | #include <asm/extable.h> |
| 16 | 15 | #include <asm/set_memory.h> |
| 17 | 16 | #include <asm/nospec-branch.h> |
| @@ -389,18 +388,6 @@ out: · 371 unmodified lines | ||
| 389 | 388 | return ret; |
| 390 | 389 | } |
| 391 | 390 | |
| 392 | −int __init bpf_arch_init_dispatcher_early(void *ip) | |
| 393 | −{ | |
| 394 | − const u8 *nop_insn = x86_nops[5]; | |
| 395 | − | |
| 396 | − if (is_endbr(*(u32 *)ip)) | |
| 397 | − ip += ENDBR_INSN_SIZE; | |
| 398 | − | |
| 399 | − if (memcmp(ip, nop_insn, X86_PATCH_SIZE)) | |
| 400 | − text_poke_early(ip, nop_insn, X86_PATCH_SIZE); | |
| 401 | − return 0; | |
| 402 | −} | |
| 403 | − | |
| 404 | 391 | int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, |
| 405 | 392 | void *old_addr, void *new_addr) |
| 406 | 393 | { |
| @@ -513,15 +513,23 @@ static int pm_cpu_check(const struct x86_cpu_id *c) · 512 unmodified lines | ||
| 513 | 513 | |
| 514 | 514 | static void pm_save_spec_msr(void) |
| 515 | 515 | { |
| 516 | − u32 spec_msr_id[] = { | |
| 517 | − MSR_IA32_SPEC_CTRL, | |
| 518 | − MSR_IA32_TSX_CTRL, | |
| 519 | − MSR_TSX_FORCE_ABORT, | |
| 520 | − MSR_IA32_MCU_OPT_CTRL, | |
| 521 | − MSR_AMD64_LS_CFG, | |
| 516 | + struct msr_enumeration { | |
| 517 | + u32 msr_no; | |
| 518 | + u32 feature; | |
| 519 | + } msr_enum[] = { | |
| 520 | + { MSR_IA32_SPEC_CTRL, X86_FEATURE_MSR_SPEC_CTRL }, | |
| 521 | + { MSR_IA32_TSX_CTRL, X86_FEATURE_MSR_TSX_CTRL }, | |
| 522 | + { MSR_TSX_FORCE_ABORT, X86_FEATURE_TSX_FORCE_ABORT }, | |
| 523 | + { MSR_IA32_MCU_OPT_CTRL, X86_FEATURE_SRBDS_CTRL }, | |
| 524 | + { MSR_AMD64_LS_CFG, X86_FEATURE_LS_CFG_SSBD }, | |
| 525 | + { MSR_AMD64_DE_CFG, X86_FEATURE_LFENCE_RDTSC }, | |
| 522 | 526 | }; |
| 527 | + int i; | |
| 523 | 528 | |
| 524 | − msr_build_context(spec_msr_id, ARRAY_SIZE(spec_msr_id)); | |
| 529 | + for (i = 0; i < ARRAY_SIZE(msr_enum); i++) { | |
| 530 | + if (boot_cpu_has(msr_enum[i].feature)) | |
| 531 | + msr_build_context(&msr_enum[i].msr_no, 1); | |
| 532 | + } | |
| 525 | 533 | } |
| 526 | 534 | |
| 527 | 535 | static int pm_check_save_msr(void) |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/start_kernel.h> |
| 24 | 24 | #include <linux/sched.h> |
| 25 | 25 | #include <linux/kprobes.h> |
| 26 | +#include <linux/kstrtox.h> | |
| 26 | 27 | #include <linux/memblock.h> |
| 27 | 28 | #include <linux/export.h> |
| 28 | 29 | #include <linux/mm.h> |
| @@ -113,7 +114,7 @@ static __read_mostly bool xen_msr_safe = IS_ENABLED(CONFIG_XEN_PV_MSR_SAFE); · 84 unmodified lines | ||
| 113 | 114 | static int __init parse_xen_msr_safe(char *str) |
| 114 | 115 | { |
| 115 | 116 | if (str) |
| 116 | − return strtobool(str, &xen_msr_safe); | |
| 117 | + return kstrtobool(str, &xen_msr_safe); | |
| 117 | 118 | return -EINVAL; |
| 118 | 119 | } |
| 119 | 120 | early_param("xen_msr_safe", parse_xen_msr_safe); |
| @@ -302,7 +302,7 @@ static bool xen_amd_pmu_emulate(unsigned int msr, u64 *val, bool is_read) · 301 unmodified lines | ||
| 302 | 302 | static bool pmu_msr_chk_emulated(unsigned int msr, uint64_t *val, bool is_read, |
| 303 | 303 | bool *emul) |
| 304 | 304 | { |
| 305 | − int type, index; | |
| 305 | + int type, index = 0; | |
| 306 | 306 | |
| 307 | 307 | if (is_amd_pmu_msr(msr)) |
| 308 | 308 | *emul = xen_amd_pmu_emulate(msr, val, is_read); |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include <linux/init.h> |
| 9 | 9 | #include <linux/sched.h> |
| 10 | +#include <linux/kstrtox.h> | |
| 10 | 11 | #include <linux/mm.h> |
| 11 | 12 | #include <linux/pm.h> |
| 12 | 13 | #include <linux/memblock.h> |
| @@ -85,7 +86,7 @@ static void __init xen_parse_512gb(void) · 72 unmodified lines | ||
| 85 | 86 | arg = strstr(xen_start_info->cmd_line, "xen_512gb_limit="); |
| 86 | 87 | if (!arg) |
| 87 | 88 | val = true; |
| 88 | − else if (strtobool(arg + strlen("xen_512gb_limit="), &val)) | |
| 89 | + else if (kstrtobool(arg + strlen("xen_512gb_limit="), &val)) | |
| 89 | 90 | return; |
| 90 | 91 | |
| 91 | 92 | xen_512gb_limit = val; |
| @@ -910,17 +911,9 @@ static int register_callback(unsigned type, const void *func) · 818 unmodified lines | ||
| 910 | 911 | |
| 911 | 912 | void xen_enable_sysenter(void) |
| 912 | 913 | { |
| 913 | − int ret; | |
| 914 | − unsigned sysenter_feature; | |
| 915 | − | |
| 916 | − sysenter_feature = X86_FEATURE_SYSENTER32; | |
| 917 | − | |
| 918 | − if (!boot_cpu_has(sysenter_feature)) | |
| 919 | − return; | |
| 920 | − | |
| 921 | − ret = register_callback(CALLBACKTYPE_sysenter, xen_entry_SYSENTER_compat); | |
| 922 | − if(ret != 0) | |
| 923 | − setup_clear_cpu_cap(sysenter_feature); | |
| 914 | + if (cpu_feature_enabled(X86_FEATURE_SYSENTER32) && | |
| 915 | + register_callback(CALLBACKTYPE_sysenter, xen_entry_SYSENTER_compat)) | |
| 916 | + setup_clear_cpu_cap(X86_FEATURE_SYSENTER32); | |
| 924 | 917 | } |
| 925 | 918 | |
| 926 | 919 | void xen_enable_syscall(void) |
| @@ -934,12 +927,9 @@ void xen_enable_syscall(void) · 7 unmodified lines | ||
| 934 | 927 | mechanism for syscalls. */ |
| 935 | 928 | } |
| 936 | 929 | |
| 937 | − if (boot_cpu_has(X86_FEATURE_SYSCALL32)) { | |
| 938 | − ret = register_callback(CALLBACKTYPE_syscall32, | |
| 939 | − xen_entry_SYSCALL_compat); | |
| 940 | − if (ret != 0) | |
| 941 | − setup_clear_cpu_cap(X86_FEATURE_SYSCALL32); | |
| 942 | − } | |
| 930 | + if (cpu_feature_enabled(X86_FEATURE_SYSCALL32) && | |
| 931 | + register_callback(CALLBACKTYPE_syscall32, xen_entry_SYSCALL_compat)) | |
| 932 | + setup_clear_cpu_cap(X86_FEATURE_SYSCALL32); | |
| 943 | 933 | } |
| 944 | 934 | |
| 945 | 935 | static void __init xen_pvmmu_arch_setup(void) |
| @@ -610,6 +610,10 @@ struct bfq_group *bfq_bio_bfqg(struct bfq_data *bfqd, struct bio *bio) · 609 unmodified lines | ||
| 610 | 610 | struct bfq_group *bfqg; |
| 611 | 611 | |
| 612 | 612 | while (blkg) { |
| 613 | + if (!blkg->online) { | |
| 614 | + blkg = blkg->parent; | |
| 615 | + continue; | |
| 616 | + } | |
| 613 | 617 | bfqg = blkg_to_bfqg(blkg); |
| 614 | 618 | if (bfqg->online) { |
| 615 | 619 | bio_associate_blkg_from_css(bio, &blkg->blkcg->css); |
| @@ -1213,7 +1213,7 @@ static int blkcg_css_online(struct cgroup_subsys_state *css) · 1212 unmodified lines | ||
| 1213 | 1213 | * parent so that offline always happens towards the root. |
| 1214 | 1214 | */ |
| 1215 | 1215 | if (parent) |
| 1216 | − blkcg_pin_online(css); | |
| 1216 | + blkcg_pin_online(&parent->css); | |
| 1217 | 1217 | return 0; |
| 1218 | 1218 | } |
| 1219 | 1219 | |
| @@ -425,7 +425,6 @@ struct request_queue *blk_alloc_queue(int node_id, bool alloc_srcu) · 424 unmodified lines | ||
| 425 | 425 | PERCPU_REF_INIT_ATOMIC, GFP_KERNEL)) |
| 426 | 426 | goto fail_stats; |
| 427 | 427 | |
| 428 | − blk_queue_dma_alignment(q, 511); | |
| 429 | 428 | blk_set_default_limits(&q->limits); |
| 430 | 429 | q->nr_requests = BLKDEV_DEFAULT_RQ; |
| 431 | 430 | |
| @@ -1262,6 +1262,7 @@ static void blk_add_rq_to_plug(struct blk_plug *plug, struct request *rq) · 1261 unmodified lines | ||
| 1262 | 1262 | (!blk_queue_nomerges(rq->q) && |
| 1263 | 1263 | blk_rq_bytes(last) >= BLK_PLUG_FLUSH_SIZE)) { |
| 1264 | 1264 | blk_mq_flush_plug_list(plug, false); |
| 1265 | + last = NULL; | |
| 1265 | 1266 | trace_block_plug(rq->q); |
| 1266 | 1267 | } |
| 1267 | 1268 | |
| @@ -4044,9 +4045,14 @@ EXPORT_SYMBOL(__blk_mq_alloc_disk); · 2776 unmodified lines | ||
| 4044 | 4045 | struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q, |
| 4045 | 4046 | struct lock_class_key *lkclass) |
| 4046 | 4047 | { |
| 4048 | + struct gendisk *disk; | |
| 4049 | + | |
| 4047 | 4050 | if (!blk_get_queue(q)) |
| 4048 | 4051 | return NULL; |
| 4049 | − return __alloc_disk_node(q, NUMA_NO_NODE, lkclass); | |
| 4052 | + disk = __alloc_disk_node(q, NUMA_NO_NODE, lkclass); | |
| 4053 | + if (!disk) | |
| 4054 | + blk_put_queue(q); | |
| 4055 | + return disk; | |
| 4050 | 4056 | } |
| 4051 | 4057 | EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue); |
| 4052 | 4058 | |
| @@ -4193,9 +4199,7 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, · 140 unmodified lines | ||
| 4193 | 4199 | return 0; |
| 4194 | 4200 | |
| 4195 | 4201 | err_hctxs: |
| 4196 | − xa_destroy(&q->hctx_table); | |
| 4197 | − q->nr_hw_queues = 0; | |
| 4198 | − blk_mq_sysfs_deinit(q); | |
| 4202 | + blk_mq_release(q); | |
| 4199 | 4203 | err_poll: |
| 4200 | 4204 | blk_stat_free_callback(q->poll_cb); |
| 4201 | 4205 | q->poll_cb = NULL; |
| @@ -57,8 +57,8 @@ void blk_set_default_limits(struct queue_limits *lim) · 56 unmodified lines | ||
| 57 | 57 | lim->misaligned = 0; |
| 58 | 58 | lim->zoned = BLK_ZONED_NONE; |
| 59 | 59 | lim->zone_write_granularity = 0; |
| 60 | + lim->dma_alignment = 511; | |
| 60 | 61 | } |
| 61 | −EXPORT_SYMBOL(blk_set_default_limits); | |
| 62 | 62 | |
| 63 | 63 | /** |
| 64 | 64 | * blk_set_stacking_limits - set default limits for stacking devices |
| @@ -600,6 +600,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, · 535 unmodified lines | ||
| 600 | 600 | |
| 601 | 601 | t->io_min = max(t->io_min, b->io_min); |
| 602 | 602 | t->io_opt = lcm_not_zero(t->io_opt, b->io_opt); |
| 603 | + t->dma_alignment = max(t->dma_alignment, b->dma_alignment); | |
| 603 | 604 | |
| 604 | 605 | /* Set non-power-of-2 compatible chunk_sectors boundary */ |
| 605 | 606 | if (b->chunk_sectors) |
| @@ -773,7 +774,7 @@ EXPORT_SYMBOL(blk_queue_virt_boundary); · 167 unmodified lines | ||
| 773 | 774 | **/ |
| 774 | 775 | void blk_queue_dma_alignment(struct request_queue *q, int mask) |
| 775 | 776 | { |
| 776 | − q->dma_alignment = mask; | |
| 777 | + q->limits.dma_alignment = mask; | |
| 777 | 778 | } |
| 778 | 779 | EXPORT_SYMBOL(blk_queue_dma_alignment); |
| 779 | 780 | |
| @@ -795,8 +796,8 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask) · 15 unmodified lines | ||
| 795 | 796 | { |
| 796 | 797 | BUG_ON(mask > PAGE_SIZE); |
| 797 | 798 | |
| 798 | − if (mask > q->dma_alignment) | |
| 799 | − q->dma_alignment = mask; | |
| 799 | + if (mask > q->limits.dma_alignment) | |
| 800 | + q->limits.dma_alignment = mask; | |
| 800 | 801 | } |
| 801 | 802 | EXPORT_SYMBOL(blk_queue_update_dma_alignment); |
| 802 | 803 | |
| @@ -331,6 +331,7 @@ void blk_rq_set_mixed_merge(struct request *rq); · 330 unmodified lines | ||
| 331 | 331 | bool blk_rq_merge_ok(struct request *rq, struct bio *bio); |
| 332 | 332 | enum elv_merge blk_try_merge(struct request *rq, struct bio *bio); |
| 333 | 333 | |
| 334 | +void blk_set_default_limits(struct queue_limits *lim); | |
| 334 | 335 | int blk_dev_init(void); |
| 335 | 336 | |
| 336 | 337 | /* |
| @@ -527,6 +527,7 @@ out_unregister_bdi: · 526 unmodified lines | ||
| 527 | 527 | bdi_unregister(disk->bdi); |
| 528 | 528 | out_unregister_queue: |
| 529 | 529 | blk_unregister_queue(disk); |
| 530 | + rq_qos_exit(disk->queue); | |
| 530 | 531 | out_put_slave_dir: |
| 531 | 532 | kobject_put(disk->slave_dir); |
| 532 | 533 | out_put_holder_dir: |
| @@ -87,8 +87,8 @@ struct opal_dev { · 86 unmodified lines | ||
| 87 | 87 | u64 lowest_lba; |
| 88 | 88 | |
| 89 | 89 | size_t pos; |
| 90 | − u8 cmd[IO_BUFFER_LENGTH]; | |
| 91 | − u8 resp[IO_BUFFER_LENGTH]; | |
| 90 | + u8 *cmd; | |
| 91 | + u8 *resp; | |
| 92 | 92 | |
| 93 | 93 | struct parsed_resp parsed; |
| 94 | 94 | size_t prev_d_len; |
| @@ -2175,6 +2175,8 @@ void free_opal_dev(struct opal_dev *dev) · 2080 unmodified lines | ||
| 2175 | 2175 | return; |
| 2176 | 2176 | |
| 2177 | 2177 | clean_opal_dev(dev); |
| 2178 | + kfree(dev->resp); | |
| 2179 | + kfree(dev->cmd); | |
| 2178 | 2180 | kfree(dev); |
| 2179 | 2181 | } |
| 2180 | 2182 | EXPORT_SYMBOL(free_opal_dev); |
| @@ -2187,6 +2189,18 @@ struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv) · 6 unmodified lines | ||
| 2187 | 2189 | if (!dev) |
| 2188 | 2190 | return NULL; |
| 2189 | 2191 | |
| 2192 | + /* | |
| 2193 | + * Presumably DMA-able buffers must be cache-aligned. Kmalloc makes | |
| 2194 | + * sure the allocated buffer is DMA-safe in that regard. | |
| 2195 | + */ | |
| 2196 | + dev->cmd = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL); | |
| 2197 | + if (!dev->cmd) | |
| 2198 | + goto err_free_dev; | |
| 2199 | + | |
| 2200 | + dev->resp = kmalloc(IO_BUFFER_LENGTH, GFP_KERNEL); | |
| 2201 | + if (!dev->resp) | |
| 2202 | + goto err_free_cmd; | |
| 2203 | + | |
| 2190 | 2204 | INIT_LIST_HEAD(&dev->unlk_lst); |
| 2191 | 2205 | mutex_init(&dev->dev_lock); |
| 2192 | 2206 | dev->flags = 0; |
| @@ -2194,11 +2208,21 @@ struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv) · 1 unmodified line | ||
| 2194 | 2208 | dev->send_recv = send_recv; |
| 2195 | 2209 | if (check_opal_support(dev) != 0) { |
| 2196 | 2210 | pr_debug("Opal is not supported on this device\n"); |
| 2197 | − kfree(dev); | |
| 2198 | − return NULL; | |
| 2211 | + goto err_free_resp; | |
| 2199 | 2212 | } |
| 2200 | 2213 | |
| 2201 | 2214 | return dev; |
| 2215 | + | |
| 2216 | +err_free_resp: | |
| 2217 | + kfree(dev->resp); | |
| 2218 | + | |
| 2219 | +err_free_cmd: | |
| 2220 | + kfree(dev->cmd); | |
| 2221 | + | |
| 2222 | +err_free_dev: | |
| 2223 | + kfree(dev); | |
| 2224 | + | |
| 2225 | + return NULL; | |
| 2202 | 2226 | } |
| 2203 | 2227 | EXPORT_SYMBOL(init_opal_dev); |
| 2204 | 2228 | |
| @@ -1778,7 +1778,7 @@ static void speakup_con_update(struct vc_data *vc) · 1777 unmodified lines | ||
| 1778 | 1778 | { |
| 1779 | 1779 | unsigned long flags; |
| 1780 | 1780 | |
| 1781 | − if (!speakup_console[vc->vc_num] || spk_parked) | |
| 1781 | + if (!speakup_console[vc->vc_num] || spk_parked || !synth) | |
| 1782 | 1782 | return; |
| 1783 | 1783 | if (!spin_trylock_irqsave(&speakup_info.spinlock, flags)) |
| 1784 | 1784 | /* Speakup output, discard */ |
| @@ -54,7 +54,7 @@ static inline int oops(const char *msg, const char *info) · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | static inline struct st_key *hash_name(char *name) |
| 56 | 56 | { |
| 57 | − u_char *pn = (u_char *)name; | |
| 57 | + unsigned char *pn = (unsigned char *)name; | |
| 58 | 58 | int hash = 0; |
| 59 | 59 | |
| 60 | 60 | while (*pn) { |
| @@ -562,17 +562,26 @@ static int initiator_cmp(void *priv, const struct list_head *a, · 561 unmodified lines | ||
| 562 | 562 | { |
| 563 | 563 | struct memory_initiator *ia; |
| 564 | 564 | struct memory_initiator *ib; |
| 565 | − unsigned long *p_nodes = priv; | |
| 566 | 565 | |
| 567 | 566 | ia = list_entry(a, struct memory_initiator, node); |
| 568 | 567 | ib = list_entry(b, struct memory_initiator, node); |
| 569 | 568 | |
| 570 | − set_bit(ia->processor_pxm, p_nodes); | |
| 571 | − set_bit(ib->processor_pxm, p_nodes); | |
| 572 | − | |
| 573 | 569 | return ia->processor_pxm - ib->processor_pxm; |
| 574 | 570 | } |
| 575 | 571 | |
| 572 | +static int initiators_to_nodemask(unsigned long *p_nodes) | |
| 573 | +{ | |
| 574 | + struct memory_initiator *initiator; | |
| 575 | + | |
| 576 | + if (list_empty(&initiators)) | |
| 577 | + return -ENXIO; | |
| 578 | + | |
| 579 | + list_for_each_entry(initiator, &initiators, node) | |
| 580 | + set_bit(initiator->processor_pxm, p_nodes); | |
| 581 | + | |
| 582 | + return 0; | |
| 583 | +} | |
| 584 | + | |
| 576 | 585 | static void hmat_register_target_initiators(struct memory_target *target) |
| 577 | 586 | { |
| 578 | 587 | static DECLARE_BITMAP(p_nodes, MAX_NUMNODES); |
| @@ -609,7 +618,10 @@ static void hmat_register_target_initiators(struct memory_target *target) · 30 unmodified lines | ||
| 609 | 618 | * initiators. |
| 610 | 619 | */ |
| 611 | 620 | bitmap_zero(p_nodes, MAX_NUMNODES); |
| 612 | − list_sort(p_nodes, &initiators, initiator_cmp); | |
| 621 | + list_sort(NULL, &initiators, initiator_cmp); | |
| 622 | + if (initiators_to_nodemask(p_nodes) < 0) | |
| 623 | + return; | |
| 624 | + | |
| 613 | 625 | if (!access0done) { |
| 614 | 626 | for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) { |
| 615 | 627 | loc = localities_types[i]; |
| @@ -643,8 +655,9 @@ static void hmat_register_target_initiators(struct memory_target *target) · 27 unmodified lines | ||
| 643 | 655 | |
| 644 | 656 | /* Access 1 ignores Generic Initiators */ |
| 645 | 657 | bitmap_zero(p_nodes, MAX_NUMNODES); |
| 646 | − list_sort(p_nodes, &initiators, initiator_cmp); | |
| 647 | − best = 0; | |
| 658 | + if (initiators_to_nodemask(p_nodes) < 0) | |
| 659 | + return; | |
| 660 | + | |
| 648 | 661 | for (i = WRITE_LATENCY; i <= READ_BANDWIDTH; i++) { |
| 649 | 662 | loc = localities_types[i]; |
| 650 | 663 | if (!loc) |
| @@ -327,6 +327,7 @@ static int __init acpi_parse_cfmws(union acpi_subtable_headers *header, · 326 unmodified lines | ||
| 327 | 327 | pr_warn("ACPI NUMA: Failed to add memblk for CFMWS node %d [mem %#llx-%#llx]\n", |
| 328 | 328 | node, start, end); |
| 329 | 329 | } |
| 330 | + node_set(node, numa_nodes_parsed); | |
| 330 | 331 | |
| 331 | 332 | /* Set the next available fake_pxm value */ |
| 332 | 333 | (*fake_pxm)++; |
| @@ -645,6 +645,20 @@ static const struct dmi_system_id video_detect_dmi_table[] = { · 644 unmodified lines | ||
| 645 | 645 | }, |
| 646 | 646 | }, |
| 647 | 647 | |
| 648 | + /* | |
| 649 | + * Models which have nvidia-ec-wmi support, but should not use it. | |
| 650 | + * Note this indicates a likely firmware bug on these models and should | |
| 651 | + * be revisited if/when Linux gets support for dynamic mux mode. | |
| 652 | + */ | |
| 653 | + { | |
| 654 | + .callback = video_detect_force_native, | |
| 655 | + /* Dell G15 5515 */ | |
| 656 | + .matches = { | |
| 657 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 658 | + DMI_MATCH(DMI_PRODUCT_NAME, "Dell G15 5515"), | |
| 659 | + }, | |
| 660 | + }, | |
| 661 | + | |
| 648 | 662 | /* |
| 649 | 663 | * Desktops which falsely report a backlight and which our heuristics |
| 650 | 664 | * for this do not catch. |
| @@ -670,7 +684,7 @@ static const struct dmi_system_id video_detect_dmi_table[] = { · 19 unmodified lines | ||
| 670 | 684 | |
| 671 | 685 | static bool google_cros_ec_present(void) |
| 672 | 686 | { |
| 673 | − return acpi_dev_found("GOOG0004"); | |
| 687 | + return acpi_dev_found("GOOG0004") || acpi_dev_found("GOOG000C"); | |
| 674 | 688 | } |
| 675 | 689 | |
| 676 | 690 | /* |
| @@ -718,6 +732,10 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) · 41 unmodified lines | ||
| 718 | 732 | if (apple_gmux_present()) |
| 719 | 733 | return acpi_backlight_apple_gmux; |
| 720 | 734 | |
| 735 | + /* Chromebooks should always prefer native backlight control. */ | |
| 736 | + if (google_cros_ec_present() && native_available) | |
| 737 | + return acpi_backlight_native; | |
| 738 | + | |
| 721 | 739 | /* On systems with ACPI video use either native or ACPI video. */ |
| 722 | 740 | if (video_caps & ACPI_VIDEO_BACKLIGHT) { |
| 723 | 741 | /* |
| @@ -735,13 +753,6 @@ static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native) · 11 unmodified lines | ||
| 735 | 753 | return acpi_backlight_video; |
| 736 | 754 | } |
| 737 | 755 | |
| 738 | − /* | |
| 739 | − * Chromebooks that don't have backlight handle in ACPI table | |
| 740 | − * are supposed to use native backlight if it's available. | |
| 741 | − */ | |
| 742 | − if (google_cros_ec_present() && native_available) | |
| 743 | − return acpi_backlight_native; | |
| 744 | − | |
| 745 | 756 | /* No ACPI video (old hw), use vendor specific fw methods. */ |
| 746 | 757 | return acpi_backlight_vendor; |
| 747 | 758 | } |
| @@ -754,6 +765,18 @@ EXPORT_SYMBOL(acpi_video_get_backlight_type); · 6 unmodified lines | ||
| 754 | 765 | |
| 755 | 766 | bool acpi_video_backlight_use_native(void) |
| 756 | 767 | { |
| 757 | − return __acpi_video_get_backlight_type(true) == acpi_backlight_native; | |
| 768 | + /* | |
| 769 | + * Call __acpi_video_get_backlight_type() to let it know that | |
| 770 | + * a native backlight is available. | |
| 771 | + */ | |
| 772 | + __acpi_video_get_backlight_type(true); | |
| 773 | + | |
| 774 | + /* | |
| 775 | + * For now just always return true. There is a whole bunch of laptop | |
| 776 | + * models where (video_caps & ACPI_VIDEO_BACKLIGHT) is false causing | |
| 777 | + * __acpi_video_get_backlight_type() to return vendor, while these | |
| 778 | + * models only have a native backlight control. | |
| 779 | + */ | |
| 780 | + return true; | |
| 758 | 781 | } |
| 759 | 782 | EXPORT_SYMBOL(acpi_video_backlight_use_native); |
| @@ -219,6 +219,12 @@ static const struct dmi_system_id force_storage_d3_dmi[] = { · 218 unmodified lines | ||
| 219 | 219 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14 7425 2-in-1"), |
| 220 | 220 | } |
| 221 | 221 | }, |
| 222 | + { | |
| 223 | + .matches = { | |
| 224 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 225 | + DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 16 5625"), | |
| 226 | + } | |
| 227 | + }, | |
| 222 | 228 | {} |
| 223 | 229 | }; |
| 224 | 230 | |
| @@ -739,6 +739,12 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc, · 738 unmodified lines | ||
| 739 | 739 | const char *failure_string; |
| 740 | 740 | struct binder_buffer *buffer; |
| 741 | 741 | |
| 742 | + if (unlikely(vma->vm_mm != alloc->mm)) { | |
| 743 | + ret = -EINVAL; | |
| 744 | + failure_string = "invalid vma->vm_mm"; | |
| 745 | + goto err_invalid_mm; | |
| 746 | + } | |
| 747 | + | |
| 742 | 748 | mutex_lock(&binder_alloc_mmap_lock); |
| 743 | 749 | if (alloc->buffer_size) { |
| 744 | 750 | ret = -EBUSY; |
| @@ -785,6 +791,7 @@ err_alloc_pages_failed: · 40 unmodified lines | ||
| 785 | 791 | alloc->buffer_size = 0; |
| 786 | 792 | err_already_mapped: |
| 787 | 793 | mutex_unlock(&binder_alloc_mmap_lock); |
| 794 | +err_invalid_mm: | |
| 788 | 795 | binder_alloc_debug(BINDER_DEBUG_USER_ERROR, |
| 789 | 796 | "%s: %d %lx-%lx %s failed %d\n", __func__, |
| 790 | 797 | alloc->pid, vma->vm_start, vma->vm_end, |
| @@ -3264,6 +3264,7 @@ static unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf) · 3263 unmodified lines | ||
| 3264 | 3264 | case REPORT_LUNS: |
| 3265 | 3265 | case REQUEST_SENSE: |
| 3266 | 3266 | case SYNCHRONIZE_CACHE: |
| 3267 | + case SYNCHRONIZE_CACHE_16: | |
| 3267 | 3268 | case REZERO_UNIT: |
| 3268 | 3269 | case SEEK_6: |
| 3269 | 3270 | case SEEK_10: |
| @@ -3922,6 +3923,7 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) · 652 unmodified lines | ||
| 3922 | 3923 | return ata_scsi_write_same_xlat; |
| 3923 | 3924 | |
| 3924 | 3925 | case SYNCHRONIZE_CACHE: |
| 3926 | + case SYNCHRONIZE_CACHE_16: | |
| 3925 | 3927 | if (ata_try_flush_cache(dev)) |
| 3926 | 3928 | return ata_scsi_flush_xlat; |
| 3927 | 3929 | break; |
| @@ -3962,9 +3964,19 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) · 34 unmodified lines | ||
| 3962 | 3964 | |
| 3963 | 3965 | int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev) |
| 3964 | 3966 | { |
| 3967 | + struct ata_port *ap = dev->link->ap; | |
| 3965 | 3968 | u8 scsi_op = scmd->cmnd[0]; |
| 3966 | 3969 | ata_xlat_func_t xlat_func; |
| 3967 | 3970 | |
| 3971 | + /* | |
| 3972 | + * scsi_queue_rq() will defer commands if scsi_host_in_recovery(). | |
| 3973 | + * However, this check is done without holding the ap->lock (a libata | |
| 3974 | + * specific lock), so we can have received an error irq since then, | |
| 3975 | + * therefore we must check if EH is pending, while holding ap->lock. | |
| 3976 | + */ | |
| 3977 | + if (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS)) | |
| 3978 | + return SCSI_MLQUEUE_DEVICE_BUSY; | |
| 3979 | + | |
| 3968 | 3980 | if (unlikely(!scmd->cmd_len)) |
| 3969 | 3981 | goto bad_cdb_len; |
| 3970 | 3982 | |
| @@ -4145,6 +4157,7 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) · 174 unmodified lines | ||
| 4145 | 4157 | * turning this into a no-op. |
| 4146 | 4158 | */ |
| 4147 | 4159 | case SYNCHRONIZE_CACHE: |
| 4160 | + case SYNCHRONIZE_CACHE_16: | |
| 4148 | 4161 | fallthrough; |
| 4149 | 4162 | |
| 4150 | 4163 | /* no-op's, complete with success */ |
| @@ -301,7 +301,9 @@ int ata_tport_add(struct device *parent, · 300 unmodified lines | ||
| 301 | 301 | pm_runtime_enable(dev); |
| 302 | 302 | pm_runtime_forbid(dev); |
| 303 | 303 | |
| 304 | − transport_add_device(dev); | |
| 304 | + error = transport_add_device(dev); | |
| 305 | + if (error) | |
| 306 | + goto tport_transport_add_err; | |
| 305 | 307 | transport_configure_device(dev); |
| 306 | 308 | |
| 307 | 309 | error = ata_tlink_add(&ap->link); |
| @@ -312,12 +314,12 @@ int ata_tport_add(struct device *parent, · 4 unmodified lines | ||
| 312 | 314 | |
| 313 | 315 | tport_link_err: |
| 314 | 316 | transport_remove_device(dev); |
| 317 | + tport_transport_add_err: | |
| 315 | 318 | device_del(dev); |
| 316 | 319 | |
| 317 | 320 | tport_err: |
| 318 | 321 | transport_destroy_device(dev); |
| 319 | 322 | put_device(dev); |
| 320 | − ata_host_put(ap->host); | |
| 321 | 323 | return error; |
| 322 | 324 | } |
| 323 | 325 | |
| @@ -456,7 +458,9 @@ int ata_tlink_add(struct ata_link *link) · 132 unmodified lines | ||
| 456 | 458 | goto tlink_err; |
| 457 | 459 | } |
| 458 | 460 | |
| 459 | − transport_add_device(dev); | |
| 461 | + error = transport_add_device(dev); | |
| 462 | + if (error) | |
| 463 | + goto tlink_transport_err; | |
| 460 | 464 | transport_configure_device(dev); |
| 461 | 465 | |
| 462 | 466 | ata_for_each_dev(ata_dev, link, ALL) { |
| @@ -471,6 +475,7 @@ int ata_tlink_add(struct ata_link *link) · 8 unmodified lines | ||
| 471 | 475 | ata_tdev_delete(ata_dev); |
| 472 | 476 | } |
| 473 | 477 | transport_remove_device(dev); |
| 478 | + tlink_transport_err: | |
| 474 | 479 | device_del(dev); |
| 475 | 480 | tlink_err: |
| 476 | 481 | transport_destroy_device(dev); |
| @@ -708,7 +713,13 @@ static int ata_tdev_add(struct ata_device *ata_dev) · 231 unmodified lines | ||
| 708 | 713 | return error; |
| 709 | 714 | } |
| 710 | 715 | |
| 711 | − transport_add_device(dev); | |
| 716 | + error = transport_add_device(dev); | |
| 717 | + if (error) { | |
| 718 | + device_del(dev); | |
| 719 | + ata_tdev_free(ata_dev); | |
| 720 | + return error; | |
| 721 | + } | |
| 722 | + | |
| 712 | 723 | transport_configure_device(dev); |
| 713 | 724 | return 0; |
| 714 | 725 | } |
| @@ -315,9 +315,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) · 314 unmodified lines | ||
| 315 | 315 | outb(inb(0x1F4) & 0x07, 0x1F4); |
| 316 | 316 | |
| 317 | 317 | rt = inb(0x1F3); |
| 318 | − rt &= 0x07 << (3 * adev->devno); | |
| 318 | + rt &= ~(0x07 << (3 * !adev->devno)); | |
| 319 | 319 | if (pio) |
| 320 | − rt |= (1 + 3 * pio) << (3 * adev->devno); | |
| 320 | + rt |= (1 + 3 * pio) << (3 * !adev->devno); | |
| 321 | + outb(rt, 0x1F3); | |
| 321 | 322 | |
| 322 | 323 | udelay(100); |
| 323 | 324 | outb(inb(0x1F2) | 0x01, 0x1F2); |
| @@ -63,8 +63,8 @@ static int palmld_pata_probe(struct platform_device *pdev) · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | /* remap drive's physical memory address */ |
| 65 | 65 | mem = devm_platform_ioremap_resource(pdev, 0); |
| 66 | − if (!mem) | |
| 67 | − return -ENOMEM; | |
| 66 | + if (IS_ERR(mem)) | |
| 67 | + return PTR_ERR(mem); | |
| 68 | 68 | |
| 69 | 69 | /* request and activate power and reset GPIOs */ |
| 70 | 70 | lda->power = devm_gpiod_get(dev, "power", GPIOD_OUT_HIGH); |
| @@ -408,6 +408,12 @@ config BLK_DEV_UBLK · 407 unmodified lines | ||
| 408 | 408 | definition isn't finalized yet, and might change according to future |
| 409 | 409 | requirement, so mark is as experimental now. |
| 410 | 410 | |
| 411 | + Say Y if you want to get better performance because task_work_add() | |
| 412 | + can be used in IO path for replacing io_uring cmd, which will become | |
| 413 | + shared between IO tasks and ubq daemon, meantime task_work_add() can | |
| 414 | + can handle batch more effectively, but task_work_add() isn't exported | |
| 415 | + for module, so ublk has to be built to kernel. | |
| 416 | + | |
| 411 | 417 | source "drivers/block/rnbd/Kconfig" |
| 412 | 418 | |
| 413 | 419 | endif # BLK_DEV |
| @@ -2672,7 +2672,7 @@ static int init_submitter(struct drbd_device *device) · 2671 unmodified lines | ||
| 2672 | 2672 | enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor) |
| 2673 | 2673 | { |
| 2674 | 2674 | struct drbd_resource *resource = adm_ctx->resource; |
| 2675 | − struct drbd_connection *connection; | |
| 2675 | + struct drbd_connection *connection, *n; | |
| 2676 | 2676 | struct drbd_device *device; |
| 2677 | 2677 | struct drbd_peer_device *peer_device, *tmp_peer_device; |
| 2678 | 2678 | struct gendisk *disk; |
| @@ -2789,7 +2789,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig · 110 unmodified lines | ||
| 2789 | 2789 | return NO_ERROR; |
| 2790 | 2790 | |
| 2791 | 2791 | out_idr_remove_from_resource: |
| 2792 | − for_each_connection(connection, resource) { | |
| 2792 | + for_each_connection_safe(connection, n, resource) { | |
| 2793 | 2793 | peer_device = idr_remove(&connection->peer_devices, vnr); |
| 2794 | 2794 | if (peer_device) |
| 2795 | 2795 | kref_put(&connection->kref, drbd_destroy_connection); |
| @@ -57,11 +57,12 @@ · 56 unmodified lines | ||
| 57 | 57 | #define UBLK_PARAM_TYPE_ALL (UBLK_PARAM_TYPE_BASIC | UBLK_PARAM_TYPE_DISCARD) |
| 58 | 58 | |
| 59 | 59 | struct ublk_rq_data { |
| 60 | + struct llist_node node; | |
| 60 | 61 | struct callback_head work; |
| 61 | 62 | }; |
| 62 | 63 | |
| 63 | 64 | struct ublk_uring_cmd_pdu { |
| 64 | − struct request *req; | |
| 65 | + struct ublk_queue *ubq; | |
| 65 | 66 | }; |
| 66 | 67 | |
| 67 | 68 | /* |
| @@ -119,6 +120,8 @@ struct ublk_queue { · 51 unmodified lines | ||
| 119 | 120 | struct task_struct *ubq_daemon; |
| 120 | 121 | char *io_cmd_buf; |
| 121 | 122 | |
| 123 | + struct llist_head io_cmds; | |
| 124 | + | |
| 122 | 125 | unsigned long io_addr; /* mapped vm address */ |
| 123 | 126 | unsigned int max_io_sz; |
| 124 | 127 | bool force_abort; |
| @@ -761,11 +764,31 @@ static inline void __ublk_rq_task_work(struct request *req) · 636 unmodified lines | ||
| 761 | 764 | ubq_complete_io_cmd(io, UBLK_IO_RES_OK); |
| 762 | 765 | } |
| 763 | 766 | |
| 767 | +static inline void ublk_forward_io_cmds(struct ublk_queue *ubq) | |
| 768 | +{ | |
| 769 | + struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds); | |
| 770 | + struct ublk_rq_data *data, *tmp; | |
| 771 | + | |
| 772 | + io_cmds = llist_reverse_order(io_cmds); | |
| 773 | + llist_for_each_entry_safe(data, tmp, io_cmds, node) | |
| 774 | + __ublk_rq_task_work(blk_mq_rq_from_pdu(data)); | |
| 775 | +} | |
| 776 | + | |
| 777 | +static inline void ublk_abort_io_cmds(struct ublk_queue *ubq) | |
| 778 | +{ | |
| 779 | + struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds); | |
| 780 | + struct ublk_rq_data *data, *tmp; | |
| 781 | + | |
| 782 | + llist_for_each_entry_safe(data, tmp, io_cmds, node) | |
| 783 | + __ublk_abort_rq(ubq, blk_mq_rq_from_pdu(data)); | |
| 784 | +} | |
| 785 | + | |
| 764 | 786 | static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd) |
| 765 | 787 | { |
| 766 | 788 | struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); |
| 789 | + struct ublk_queue *ubq = pdu->ubq; | |
| 767 | 790 | |
| 768 | − __ublk_rq_task_work(pdu->req); | |
| 791 | + ublk_forward_io_cmds(ubq); | |
| 769 | 792 | } |
| 770 | 793 | |
| 771 | 794 | static void ublk_rq_task_work_fn(struct callback_head *work) |
| @@ -773,8 +796,45 @@ static void ublk_rq_task_work_fn(struct callback_head *work) · 1 unmodified line | ||
| 773 | 796 | struct ublk_rq_data *data = container_of(work, |
| 774 | 797 | struct ublk_rq_data, work); |
| 775 | 798 | struct request *req = blk_mq_rq_from_pdu(data); |
| 799 | + struct ublk_queue *ubq = req->mq_hctx->driver_data; | |
| 800 | + | |
| 801 | + ublk_forward_io_cmds(ubq); | |
| 802 | +} | |
| 776 | 803 | |
| 777 | − __ublk_rq_task_work(req); | |
| 804 | +static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq) | |
| 805 | +{ | |
| 806 | + struct ublk_rq_data *data = blk_mq_rq_to_pdu(rq); | |
| 807 | + struct ublk_io *io; | |
| 808 | + | |
| 809 | + if (!llist_add(&data->node, &ubq->io_cmds)) | |
| 810 | + return; | |
| 811 | + | |
| 812 | + io = &ubq->ios[rq->tag]; | |
| 813 | + /* | |
| 814 | + * If the check pass, we know that this is a re-issued request aborted | |
| 815 | + * previously in monitor_work because the ubq_daemon(cmd's task) is | |
| 816 | + * PF_EXITING. We cannot call io_uring_cmd_complete_in_task() anymore | |
| 817 | + * because this ioucmd's io_uring context may be freed now if no inflight | |
| 818 | + * ioucmd exists. Otherwise we may cause null-deref in ctx->fallback_work. | |
| 819 | + * | |
| 820 | + * Note: monitor_work sets UBLK_IO_FLAG_ABORTED and ends this request(releasing | |
| 821 | + * the tag). Then the request is re-started(allocating the tag) and we are here. | |
| 822 | + * Since releasing/allocating a tag implies smp_mb(), finding UBLK_IO_FLAG_ABORTED | |
| 823 | + * guarantees that here is a re-issued request aborted previously. | |
| 824 | + */ | |
| 825 | + if (unlikely(io->flags & UBLK_IO_FLAG_ABORTED)) { | |
| 826 | + ublk_abort_io_cmds(ubq); | |
| 827 | + } else if (ublk_can_use_task_work(ubq)) { | |
| 828 | + if (task_work_add(ubq->ubq_daemon, &data->work, | |
| 829 | + TWA_SIGNAL_NO_IPI)) | |
| 830 | + ublk_abort_io_cmds(ubq); | |
| 831 | + } else { | |
| 832 | + struct io_uring_cmd *cmd = io->cmd; | |
| 833 | + struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); | |
| 834 | + | |
| 835 | + pdu->ubq = ubq; | |
| 836 | + io_uring_cmd_complete_in_task(cmd, ublk_rq_task_work_cb); | |
| 837 | + } | |
| 778 | 838 | } |
| 779 | 839 | |
| 780 | 840 | static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx, |
| @@ -788,6 +848,7 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx, · 7 unmodified lines | ||
| 788 | 848 | res = ublk_setup_iod(ubq, rq); |
| 789 | 849 | if (unlikely(res != BLK_STS_OK)) |
| 790 | 850 | return BLK_STS_IOERR; |
| 851 | + | |
| 791 | 852 | /* With recovery feature enabled, force_abort is set in |
| 792 | 853 | * ublk_stop_dev() before calling del_gendisk(). We have to |
| 793 | 854 | * abort all requeued and new rqs here to let del_gendisk() |
| @@ -803,53 +864,15 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx, · 9 unmodified lines | ||
| 803 | 864 | blk_mq_start_request(bd->rq); |
| 804 | 865 | |
| 805 | 866 | if (unlikely(ubq_daemon_is_dying(ubq))) { |
| 806 | − fail: | |
| 807 | 867 | __ublk_abort_rq(ubq, rq); |
| 808 | 868 | return BLK_STS_OK; |
| 809 | 869 | } |
| 810 | 870 | |
| 811 | − if (ublk_can_use_task_work(ubq)) { | |
| 812 | − struct ublk_rq_data *data = blk_mq_rq_to_pdu(rq); | |
| 813 | − enum task_work_notify_mode notify_mode = bd->last ? | |
| 814 | − TWA_SIGNAL_NO_IPI : TWA_NONE; | |
| 815 | − | |
| 816 | − if (task_work_add(ubq->ubq_daemon, &data->work, notify_mode)) | |
| 817 | − goto fail; | |
| 818 | − } else { | |
| 819 | − struct ublk_io *io = &ubq->ios[rq->tag]; | |
| 820 | − struct io_uring_cmd *cmd = io->cmd; | |
| 821 | − struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); | |
| 822 | − | |
| 823 | − /* | |
| 824 | − * If the check pass, we know that this is a re-issued request aborted | |
| 825 | − * previously in monitor_work because the ubq_daemon(cmd's task) is | |
| 826 | − * PF_EXITING. We cannot call io_uring_cmd_complete_in_task() anymore | |
| 827 | − * because this ioucmd's io_uring context may be freed now if no inflight | |
| 828 | − * ioucmd exists. Otherwise we may cause null-deref in ctx->fallback_work. | |
| 829 | − * | |
| 830 | − * Note: monitor_work sets UBLK_IO_FLAG_ABORTED and ends this request(releasing | |
| 831 | − * the tag). Then the request is re-started(allocating the tag) and we are here. | |
| 832 | − * Since releasing/allocating a tag implies smp_mb(), finding UBLK_IO_FLAG_ABORTED | |
| 833 | − * guarantees that here is a re-issued request aborted previously. | |
| 834 | − */ | |
| 835 | − if ((io->flags & UBLK_IO_FLAG_ABORTED)) | |
| 836 | − goto fail; | |
| 837 | − | |
| 838 | − pdu->req = rq; | |
| 839 | − io_uring_cmd_complete_in_task(cmd, ublk_rq_task_work_cb); | |
| 840 | − } | |
| 871 | + ublk_queue_cmd(ubq, rq); | |
| 841 | 872 | |
| 842 | 873 | return BLK_STS_OK; |
| 843 | 874 | } |
| 844 | 875 | |
| 845 | −static void ublk_commit_rqs(struct blk_mq_hw_ctx *hctx) | |
| 846 | −{ | |
| 847 | − struct ublk_queue *ubq = hctx->driver_data; | |
| 848 | − | |
| 849 | − if (ublk_can_use_task_work(ubq)) | |
| 850 | − __set_notify_signal(ubq->ubq_daemon); | |
| 851 | −} | |
| 852 | − | |
| 853 | 876 | static int ublk_init_hctx(struct blk_mq_hw_ctx *hctx, void *driver_data, |
| 854 | 877 | unsigned int hctx_idx) |
| 855 | 878 | { |
| @@ -871,7 +894,6 @@ static int ublk_init_rq(struct blk_mq_tag_set *set, struct request *req, · 15 unmodified lines | ||
| 871 | 894 | |
| 872 | 895 | static const struct blk_mq_ops ublk_mq_ops = { |
| 873 | 896 | .queue_rq = ublk_queue_rq, |
| 874 | − .commit_rqs = ublk_commit_rqs, | |
| 875 | 897 | .init_hctx = ublk_init_hctx, |
| 876 | 898 | .init_request = ublk_init_rq, |
| 877 | 899 | }; |
| @@ -1164,22 +1186,12 @@ static void ublk_mark_io_ready(struct ublk_device *ub, struct ublk_queue *ubq) · 286 unmodified lines | ||
| 1164 | 1186 | } |
| 1165 | 1187 | |
| 1166 | 1188 | static void ublk_handle_need_get_data(struct ublk_device *ub, int q_id, |
| 1167 | − int tag, struct io_uring_cmd *cmd) | |
| 1189 | + int tag) | |
| 1168 | 1190 | { |
| 1169 | 1191 | struct ublk_queue *ubq = ublk_get_queue(ub, q_id); |
| 1170 | 1192 | struct request *req = blk_mq_tag_to_rq(ub->tag_set.tags[q_id], tag); |
| 1171 | 1193 | |
| 1172 | − if (ublk_can_use_task_work(ubq)) { | |
| 1173 | − struct ublk_rq_data *data = blk_mq_rq_to_pdu(req); | |
| 1174 | − | |
| 1175 | − /* should not fail since we call it just in ubq->ubq_daemon */ | |
| 1176 | − task_work_add(ubq->ubq_daemon, &data->work, TWA_SIGNAL_NO_IPI); | |
| 1177 | − } else { | |
| 1178 | − struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); | |
| 1179 | − | |
| 1180 | − pdu->req = req; | |
| 1181 | − io_uring_cmd_complete_in_task(cmd, ublk_rq_task_work_cb); | |
| 1182 | − } | |
| 1194 | + ublk_queue_cmd(ubq, req); | |
| 1183 | 1195 | } |
| 1184 | 1196 | |
| 1185 | 1197 | static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) |
| @@ -1267,7 +1279,7 @@ static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) · 81 unmodified lines | ||
| 1267 | 1279 | io->addr = ub_cmd->addr; |
| 1268 | 1280 | io->cmd = cmd; |
| 1269 | 1281 | io->flags |= UBLK_IO_FLAG_ACTIVE; |
| 1270 | − ublk_handle_need_get_data(ub, ub_cmd->q_id, ub_cmd->tag, cmd); | |
| 1282 | + ublk_handle_need_get_data(ub, ub_cmd->q_id, ub_cmd->tag); | |
| 1271 | 1283 | break; |
| 1272 | 1284 | default: |
| 1273 | 1285 | goto out; |
| @@ -1658,6 +1670,9 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) · 384 unmodified lines | ||
| 1658 | 1670 | */ |
| 1659 | 1671 | ub->dev_info.flags &= UBLK_F_ALL; |
| 1660 | 1672 | |
| 1673 | + if (!IS_BUILTIN(CONFIG_BLK_DEV_UBLK)) | |
| 1674 | + ub->dev_info.flags |= UBLK_F_URING_CMD_COMP_IN_TASK; | |
| 1675 | + | |
| 1661 | 1676 | /* We are not ready to support zero copy */ |
| 1662 | 1677 | ub->dev_info.flags &= ~UBLK_F_SUPPORT_ZERO_COPY; |
| 1663 | 1678 | |
| @@ -219,7 +219,7 @@ static void virtbt_rx_work(struct work_struct *work) · 218 unmodified lines | ||
| 219 | 219 | if (!skb) |
| 220 | 220 | return; |
| 221 | 221 | |
| 222 | − skb->len = len; | |
| 222 | + skb_put(skb, len); | |
| 223 | 223 | virtbt_rx_handle(vbt, skb); |
| 224 | 224 | |
| 225 | 225 | if (virtbt_add_inbuf(vbt) < 0) |
| @@ -49,7 +49,7 @@ · 48 unmodified lines | ||
| 49 | 49 | #define IXP4XX_EXP_SIZE_SHIFT 10 |
| 50 | 50 | #define IXP4XX_EXP_CNFG_0 BIT(9) /* Always zero */ |
| 51 | 51 | #define IXP43X_EXP_SYNC_INTEL BIT(8) /* Only on IXP43x */ |
| 52 | −#define IXP43X_EXP_EXP_CHIP BIT(7) /* Only on IXP43x */ | |
| 52 | +#define IXP43X_EXP_EXP_CHIP BIT(7) /* Only on IXP43x, dangerous to touch on IXP42x */ | |
| 53 | 53 | #define IXP4XX_EXP_BYTE_RD16 BIT(6) |
| 54 | 54 | #define IXP4XX_EXP_HRDY_POL BIT(5) /* Only on IXP42x */ |
| 55 | 55 | #define IXP4XX_EXP_MUX_EN BIT(4) |
| @@ -57,8 +57,6 @@ · 1 unmodified line | ||
| 57 | 57 | #define IXP4XX_EXP_WORD BIT(2) /* Always zero */ |
| 58 | 58 | #define IXP4XX_EXP_WR_EN BIT(1) |
| 59 | 59 | #define IXP4XX_EXP_BYTE_EN BIT(0) |
| 60 | −#define IXP42X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(8)|BIT(7)|IXP4XX_EXP_WORD) | |
| 61 | −#define IXP43X_RESERVED (BIT(30)|IXP4XX_EXP_CNFG_0|BIT(5)|IXP4XX_EXP_WORD) | |
| 62 | 60 | |
| 63 | 61 | #define IXP4XX_EXP_CNFG0 0x20 |
| 64 | 62 | #define IXP4XX_EXP_CNFG0_MEM_MAP BIT(31) |
| @@ -252,10 +250,9 @@ static void ixp4xx_exp_setup_chipselect(struct ixp4xx_eb *eb, · 187 unmodified lines | ||
| 252 | 250 | cs_cfg |= val << IXP4XX_EXP_CYC_TYPE_SHIFT; |
| 253 | 251 | } |
| 254 | 252 | |
| 255 | − if (eb->is_42x) | |
| 256 | − cs_cfg &= ~IXP42X_RESERVED; | |
| 257 | 253 | if (eb->is_43x) { |
| 258 | − cs_cfg &= ~IXP43X_RESERVED; | |
| 254 | + /* Should always be zero */ | |
| 255 | + cs_cfg &= ~IXP4XX_EXP_WORD; | |
| 259 | 256 | /* |
| 260 | 257 | * This bit for Intel strata flash is currently unused, but let's |
| 261 | 258 | * report it if we find one. |
| @@ -267,6 +267,9 @@ EXPORT_SYMBOL_GPL(sunxi_rsb_driver_register); · 266 unmodified lines | ||
| 267 | 267 | /* common code that starts a transfer */ |
| 268 | 268 | static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) |
| 269 | 269 | { |
| 270 | + u32 int_mask, status; | |
| 271 | + bool timeout; | |
| 272 | + | |
| 270 | 273 | if (readl(rsb->regs + RSB_CTRL) & RSB_CTRL_START_TRANS) { |
| 271 | 274 | dev_dbg(rsb->dev, "RSB transfer still in progress\n"); |
| 272 | 275 | return -EBUSY; |
| @@ -274,13 +277,23 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) · 1 unmodified line | ||
| 274 | 277 | |
| 275 | 278 | reinit_completion(&rsb->complete); |
| 276 | 279 | |
| 277 | − writel(RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER, | |
| 278 | − rsb->regs + RSB_INTE); | |
| 280 | + int_mask = RSB_INTS_LOAD_BSY | RSB_INTS_TRANS_ERR | RSB_INTS_TRANS_OVER; | |
| 281 | + writel(int_mask, rsb->regs + RSB_INTE); | |
| 279 | 282 | writel(RSB_CTRL_START_TRANS | RSB_CTRL_GLOBAL_INT_ENB, |
| 280 | 283 | rsb->regs + RSB_CTRL); |
| 281 | 284 | |
| 282 | − if (!wait_for_completion_io_timeout(&rsb->complete, | |
| 283 | − msecs_to_jiffies(100))) { | |
| 285 | + if (irqs_disabled()) { | |
| 286 | + timeout = readl_poll_timeout_atomic(rsb->regs + RSB_INTS, | |
| 287 | + status, (status & int_mask), | |
| 288 | + 10, 100000); | |
| 289 | + writel(status, rsb->regs + RSB_INTS); | |
| 290 | + } else { | |
| 291 | + timeout = !wait_for_completion_io_timeout(&rsb->complete, | |
| 292 | + msecs_to_jiffies(100)); | |
| 293 | + status = rsb->status; | |
| 294 | + } | |
| 295 | + | |
| 296 | + if (timeout) { | |
| 284 | 297 | dev_dbg(rsb->dev, "RSB timeout\n"); |
| 285 | 298 | |
| 286 | 299 | /* abort the transfer */ |
| @@ -292,18 +305,18 @@ static int _sunxi_rsb_run_xfer(struct sunxi_rsb *rsb) · 5 unmodified lines | ||
| 292 | 305 | return -ETIMEDOUT; |
| 293 | 306 | } |
| 294 | 307 | |
| 295 | − if (rsb->status & RSB_INTS_LOAD_BSY) { | |
| 308 | + if (status & RSB_INTS_LOAD_BSY) { | |
| 296 | 309 | dev_dbg(rsb->dev, "RSB busy\n"); |
| 297 | 310 | return -EBUSY; |
| 298 | 311 | } |
| 299 | 312 | |
| 300 | − if (rsb->status & RSB_INTS_TRANS_ERR) { | |
| 301 | − if (rsb->status & RSB_INTS_TRANS_ERR_ACK) { | |
| 313 | + if (status & RSB_INTS_TRANS_ERR) { | |
| 314 | + if (status & RSB_INTS_TRANS_ERR_ACK) { | |
| 302 | 315 | dev_dbg(rsb->dev, "RSB slave nack\n"); |
| 303 | 316 | return -EINVAL; |
| 304 | 317 | } |
| 305 | 318 | |
| 306 | − if (rsb->status & RSB_INTS_TRANS_ERR_DATA) { | |
| 319 | + if (status & RSB_INTS_TRANS_ERR_DATA) { | |
| 307 | 320 | dev_dbg(rsb->dev, "RSB transfer data error\n"); |
| 308 | 321 | return -EIO; |
| 309 | 322 | } |
| @@ -812,14 +825,6 @@ static int sunxi_rsb_remove(struct platform_device *pdev) · 502 unmodified lines | ||
| 812 | 825 | return 0; |
| 813 | 826 | } |
| 814 | 827 | |
| 815 | −static void sunxi_rsb_shutdown(struct platform_device *pdev) | |
| 816 | −{ | |
| 817 | − struct sunxi_rsb *rsb = platform_get_drvdata(pdev); | |
| 818 | − | |
| 819 | − pm_runtime_disable(&pdev->dev); | |
| 820 | − sunxi_rsb_hw_exit(rsb); | |
| 821 | −} | |
| 822 | − | |
| 823 | 828 | static const struct dev_pm_ops sunxi_rsb_dev_pm_ops = { |
| 824 | 829 | SET_RUNTIME_PM_OPS(sunxi_rsb_runtime_suspend, |
| 825 | 830 | sunxi_rsb_runtime_resume, NULL) |
| @@ -835,7 +840,6 @@ MODULE_DEVICE_TABLE(of, sunxi_rsb_of_match_table); · 9 unmodified lines | ||
| 835 | 840 | static struct platform_driver sunxi_rsb_driver = { |
| 836 | 841 | .probe = sunxi_rsb_probe, |
| 837 | 842 | .remove = sunxi_rsb_remove, |
| 838 | − .shutdown = sunxi_rsb_shutdown, | |
| 839 | 843 | .driver = { |
| 840 | 844 | .name = RSB_CTRL_NAME, |
| 841 | 845 | .of_match_table = sunxi_rsb_of_match_table, |
| @@ -401,13 +401,14 @@ int tpm_pm_suspend(struct device *dev) · 400 unmodified lines | ||
| 401 | 401 | !pm_suspend_via_firmware()) |
| 402 | 402 | goto suspended; |
| 403 | 403 | |
| 404 | − if (!tpm_chip_start(chip)) { | |
| 404 | + rc = tpm_try_get_ops(chip); | |
| 405 | + if (!rc) { | |
| 405 | 406 | if (chip->flags & TPM_CHIP_FLAG_TPM2) |
| 406 | 407 | tpm2_shutdown(chip, TPM2_SU_STATE); |
| 407 | 408 | else |
| 408 | 409 | rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); |
| 409 | 410 | |
| 410 | − tpm_chip_stop(chip); | |
| 411 | + tpm_put_ops(chip); | |
| 411 | 412 | } |
| 412 | 413 | |
| 413 | 414 | suspended: |
| @@ -40,7 +40,7 @@ static const struct clk_pll_characteristics rm9200_pll_characteristics = { · 39 unmodified lines | ||
| 40 | 40 | }; |
| 41 | 41 | |
| 42 | 42 | static const struct sck at91rm9200_systemck[] = { |
| 43 | − { .n = "udpck", .p = "usbck", .id = 2 }, | |
| 43 | + { .n = "udpck", .p = "usbck", .id = 1 }, | |
| 44 | 44 | { .n = "uhpck", .p = "usbck", .id = 4 }, |
| 45 | 45 | { .n = "pck0", .p = "prog0", .id = 8 }, |
| 46 | 46 | { .n = "pck1", .p = "prog1", .id = 9 }, |
| @@ -90,13 +90,66 @@ static const struct regmap_access_table rs9_writeable_table = { · 89 unmodified lines | ||
| 90 | 90 | .n_yes_ranges = ARRAY_SIZE(rs9_writeable_ranges), |
| 91 | 91 | }; |
| 92 | 92 | |
| 93 | +static int rs9_regmap_i2c_write(void *context, | |
| 94 | + unsigned int reg, unsigned int val) | |
| 95 | +{ | |
| 96 | + struct i2c_client *i2c = context; | |
| 97 | + const u8 data[3] = { reg, 1, val }; | |
| 98 | + const int count = ARRAY_SIZE(data); | |
| 99 | + int ret; | |
| 100 | + | |
| 101 | + ret = i2c_master_send(i2c, data, count); | |
| 102 | + if (ret == count) | |
| 103 | + return 0; | |
| 104 | + else if (ret < 0) | |
| 105 | + return ret; | |
| 106 | + else | |
| 107 | + return -EIO; | |
| 108 | +} | |
| 109 | + | |
| 110 | +static int rs9_regmap_i2c_read(void *context, | |
| 111 | + unsigned int reg, unsigned int *val) | |
| 112 | +{ | |
| 113 | + struct i2c_client *i2c = context; | |
| 114 | + struct i2c_msg xfer[2]; | |
| 115 | + u8 txdata = reg; | |
| 116 | + u8 rxdata[2]; | |
| 117 | + int ret; | |
| 118 | + | |
| 119 | + xfer[0].addr = i2c->addr; | |
| 120 | + xfer[0].flags = 0; | |
| 121 | + xfer[0].len = 1; | |
| 122 | + xfer[0].buf = (void *)&txdata; | |
| 123 | + | |
| 124 | + xfer[1].addr = i2c->addr; | |
| 125 | + xfer[1].flags = I2C_M_RD; | |
| 126 | + xfer[1].len = 2; | |
| 127 | + xfer[1].buf = (void *)rxdata; | |
| 128 | + | |
| 129 | + ret = i2c_transfer(i2c->adapter, xfer, 2); | |
| 130 | + if (ret < 0) | |
| 131 | + return ret; | |
| 132 | + if (ret != 2) | |
| 133 | + return -EIO; | |
| 134 | + | |
| 135 | + /* | |
| 136 | + * Byte 0 is transfer length, which is always 1 due | |
| 137 | + * to BCP register programming to 1 in rs9_probe(), | |
| 138 | + * ignore it and use data from Byte 1. | |
| 139 | + */ | |
| 140 | + *val = rxdata[1]; | |
| 141 | + return 0; | |
| 142 | +} | |
| 143 | + | |
| 93 | 144 | static const struct regmap_config rs9_regmap_config = { |
| 94 | 145 | .reg_bits = 8, |
| 95 | 146 | .val_bits = 8, |
| 96 | − .cache_type = REGCACHE_FLAT, | |
| 97 | − .max_register = 0x8, | |
| 147 | + .cache_type = REGCACHE_NONE, | |
| 148 | + .max_register = RS9_REG_BCP, | |
| 98 | 149 | .rd_table = &rs9_readable_table, |
| 99 | 150 | .wr_table = &rs9_writeable_table, |
| 151 | + .reg_write = rs9_regmap_i2c_write, | |
| 152 | + .reg_read = rs9_regmap_i2c_read, | |
| 100 | 153 | }; |
| 101 | 154 | |
| 102 | 155 | static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx) |
| @@ -242,11 +295,17 @@ static int rs9_probe(struct i2c_client *client) · 139 unmodified lines | ||
| 242 | 295 | return ret; |
| 243 | 296 | } |
| 244 | 297 | |
| 245 | − rs9->regmap = devm_regmap_init_i2c(client, &rs9_regmap_config); | |
| 298 | + rs9->regmap = devm_regmap_init(&client->dev, NULL, | |
| 299 | + client, &rs9_regmap_config); | |
| 246 | 300 | if (IS_ERR(rs9->regmap)) |
| 247 | 301 | return dev_err_probe(&client->dev, PTR_ERR(rs9->regmap), |
| 248 | 302 | "Failed to allocate register map\n"); |
| 249 | 303 | |
| 304 | + /* Always read back 1 Byte via I2C */ | |
| 305 | + ret = regmap_write(rs9->regmap, RS9_REG_BCP, 1); | |
| 306 | + if (ret < 0) | |
| 307 | + return ret; | |
| 308 | + | |
| 250 | 309 | /* Register clock */ |
| 251 | 310 | for (i = 0; i < rs9->chip_info->num_clks; i++) { |
| 252 | 311 | snprintf(name, 5, "DIF%d", i); |
| @@ -1459,10 +1459,14 @@ static void clk_core_init_rate_req(struct clk_core * const core, · 1458 unmodified lines | ||
| 1459 | 1459 | { |
| 1460 | 1460 | struct clk_core *parent; |
| 1461 | 1461 | |
| 1462 | − if (WARN_ON(!core || !req)) | |
| 1462 | + if (WARN_ON(!req)) | |
| 1463 | 1463 | return; |
| 1464 | 1464 | |
| 1465 | 1465 | memset(req, 0, sizeof(*req)); |
| 1466 | + req->max_rate = ULONG_MAX; | |
| 1467 | + | |
| 1468 | + if (!core) | |
| 1469 | + return; | |
| 1466 | 1470 | |
| 1467 | 1471 | req->rate = rate; |
| 1468 | 1472 | clk_core_get_boundaries(core, &req->min_rate, &req->max_rate); |
| @@ -1270,8 +1270,10 @@ static int clk_mt8195_topck_probe(struct platform_device *pdev) · 1269 unmodified lines | ||
| 1270 | 1270 | hw = devm_clk_hw_register_mux(&pdev->dev, "mfg_ck_fast_ref", mfg_fast_parents, |
| 1271 | 1271 | ARRAY_SIZE(mfg_fast_parents), CLK_SET_RATE_PARENT, |
| 1272 | 1272 | (base + 0x250), 8, 1, 0, &mt8195_clk_lock); |
| 1273 | − if (IS_ERR(hw)) | |
| 1273 | + if (IS_ERR(hw)) { | |
| 1274 | + r = PTR_ERR(hw); | |
| 1274 | 1275 | goto unregister_muxes; |
| 1276 | + } | |
| 1275 | 1277 | top_clk_data->hws[CLK_TOP_MFG_CK_FAST_REF] = hw; |
| 1276 | 1278 | |
| 1277 | 1279 | r = clk_mt8195_reg_mfg_mux_notifier(&pdev->dev, |
| @@ -3467,6 +3467,7 @@ static int gcc_sc7280_probe(struct platform_device *pdev) · 3466 unmodified lines | ||
| 3467 | 3467 | regmap_update_bits(regmap, 0x28004, BIT(0), BIT(0)); |
| 3468 | 3468 | regmap_update_bits(regmap, 0x28014, BIT(0), BIT(0)); |
| 3469 | 3469 | regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0)); |
| 3470 | + regmap_update_bits(regmap, 0x7100C, BIT(13), BIT(13)); | |
| 3470 | 3471 | |
| 3471 | 3472 | ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks, |
| 3472 | 3473 | ARRAY_SIZE(gcc_dfs_clocks)); |
| @@ -5364,6 +5364,8 @@ static struct clk_branch gcc_ufs_1_card_clkref_clk = { · 5363 unmodified lines | ||
| 5364 | 5364 | .enable_mask = BIT(0), |
| 5365 | 5365 | .hw.init = &(const struct clk_init_data) { |
| 5366 | 5366 | .name = "gcc_ufs_1_card_clkref_clk", |
| 5367 | + .parent_data = &gcc_parent_data_tcxo, | |
| 5368 | + .num_parents = 1, | |
| 5367 | 5369 | .ops = &clk_branch2_ops, |
| 5368 | 5370 | }, |
| 5369 | 5371 | }, |
| @@ -5432,6 +5434,8 @@ static struct clk_branch gcc_ufs_card_clkref_clk = { · 62 unmodified lines | ||
| 5432 | 5434 | .enable_mask = BIT(0), |
| 5433 | 5435 | .hw.init = &(const struct clk_init_data) { |
| 5434 | 5436 | .name = "gcc_ufs_card_clkref_clk", |
| 5437 | + .parent_data = &gcc_parent_data_tcxo, | |
| 5438 | + .num_parents = 1, | |
| 5435 | 5439 | .ops = &clk_branch2_ops, |
| 5436 | 5440 | }, |
| 5437 | 5441 | }, |
| @@ -5848,6 +5852,8 @@ static struct clk_branch gcc_ufs_ref_clkref_clk = { · 410 unmodified lines | ||
| 5848 | 5852 | .enable_mask = BIT(0), |
| 5849 | 5853 | .hw.init = &(const struct clk_init_data) { |
| 5850 | 5854 | .name = "gcc_ufs_ref_clkref_clk", |
| 5855 | + .parent_data = &gcc_parent_data_tcxo, | |
| 5856 | + .num_parents = 1, | |
| 5851 | 5857 | .ops = &clk_branch2_ops, |
| 5852 | 5858 | }, |
| 5853 | 5859 | }, |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/kernel.h> |
| 12 | 12 | #include <linux/ktime.h> |
| 13 | 13 | #include <linux/pm_domain.h> |
| 14 | −#include <linux/pm_runtime.h> | |
| 15 | 14 | #include <linux/regmap.h> |
| 16 | 15 | #include <linux/regulator/consumer.h> |
| 17 | 16 | #include <linux/reset-controller.h> |
| @@ -56,22 +55,6 @@ enum gdsc_status { · 38 unmodified lines | ||
| 56 | 55 | GDSC_ON |
| 57 | 56 | }; |
| 58 | 57 | |
| 59 | −static int gdsc_pm_runtime_get(struct gdsc *sc) | |
| 60 | −{ | |
| 61 | − if (!sc->dev) | |
| 62 | − return 0; | |
| 63 | − | |
| 64 | − return pm_runtime_resume_and_get(sc->dev); | |
| 65 | −} | |
| 66 | − | |
| 67 | −static int gdsc_pm_runtime_put(struct gdsc *sc) | |
| 68 | −{ | |
| 69 | − if (!sc->dev) | |
| 70 | − return 0; | |
| 71 | − | |
| 72 | − return pm_runtime_put_sync(sc->dev); | |
| 73 | −} | |
| 74 | − | |
| 75 | 58 | /* Returns 1 if GDSC status is status, 0 if not, and < 0 on error */ |
| 76 | 59 | static int gdsc_check_status(struct gdsc *sc, enum gdsc_status status) |
| 77 | 60 | { |
| @@ -271,8 +254,9 @@ static void gdsc_retain_ff_on(struct gdsc *sc) · 193 unmodified lines | ||
| 271 | 254 | regmap_update_bits(sc->regmap, sc->gdscr, mask, mask); |
| 272 | 255 | } |
| 273 | 256 | |
| 274 | −static int _gdsc_enable(struct gdsc *sc) | |
| 257 | +static int gdsc_enable(struct generic_pm_domain *domain) | |
| 275 | 258 | { |
| 259 | + struct gdsc *sc = domain_to_gdsc(domain); | |
| 276 | 260 | int ret; |
| 277 | 261 | |
| 278 | 262 | if (sc->pwrsts == PWRSTS_ON) |
| @@ -328,22 +312,11 @@ static int _gdsc_enable(struct gdsc *sc) · 49 unmodified lines | ||
| 328 | 312 | return 0; |
| 329 | 313 | } |
| 330 | 314 | |
| 331 | −static int gdsc_enable(struct generic_pm_domain *domain) | |
| 315 | +static int gdsc_disable(struct generic_pm_domain *domain) | |
| 332 | 316 | { |
| 333 | 317 | struct gdsc *sc = domain_to_gdsc(domain); |
| 334 | 318 | int ret; |
| 335 | 319 | |
| 336 | − ret = gdsc_pm_runtime_get(sc); | |
| 337 | − if (ret) | |
| 338 | − return ret; | |
| 339 | − | |
| 340 | − return _gdsc_enable(sc); | |
| 341 | −} | |
| 342 | − | |
| 343 | −static int _gdsc_disable(struct gdsc *sc) | |
| 344 | −{ | |
| 345 | − int ret; | |
| 346 | − | |
| 347 | 320 | if (sc->pwrsts == PWRSTS_ON) |
| 348 | 321 | return gdsc_assert_reset(sc); |
| 349 | 322 | |
| @@ -388,18 +361,6 @@ static int _gdsc_disable(struct gdsc *sc) · 38 unmodified lines | ||
| 388 | 361 | return 0; |
| 389 | 362 | } |
| 390 | 363 | |
| 391 | −static int gdsc_disable(struct generic_pm_domain *domain) | |
| 392 | −{ | |
| 393 | − struct gdsc *sc = domain_to_gdsc(domain); | |
| 394 | − int ret; | |
| 395 | − | |
| 396 | − ret = _gdsc_disable(sc); | |
| 397 | − | |
| 398 | − gdsc_pm_runtime_put(sc); | |
| 399 | − | |
| 400 | − return ret; | |
| 401 | −} | |
| 402 | − | |
| 403 | 364 | static int gdsc_init(struct gdsc *sc) |
| 404 | 365 | { |
| 405 | 366 | u32 mask, val; |
| @@ -447,11 +408,6 @@ static int gdsc_init(struct gdsc *sc) · 41 unmodified lines | ||
| 447 | 408 | return ret; |
| 448 | 409 | } |
| 449 | 410 | |
| 450 | − /* ...and the power-domain */ | |
| 451 | − ret = gdsc_pm_runtime_get(sc); | |
| 452 | − if (ret) | |
| 453 | − goto err_disable_supply; | |
| 454 | − | |
| 455 | 411 | /* |
| 456 | 412 | * Votable GDSCs can be ON due to Vote from other masters. |
| 457 | 413 | * If a Votable GDSC is ON, make sure we have a Vote. |
| @@ -459,14 +415,14 @@ static int gdsc_init(struct gdsc *sc) · 1 unmodified line | ||
| 459 | 415 | if (sc->flags & VOTABLE) { |
| 460 | 416 | ret = gdsc_update_collapse_bit(sc, false); |
| 461 | 417 | if (ret) |
| 462 | − goto err_put_rpm; | |
| 418 | + goto err_disable_supply; | |
| 463 | 419 | } |
| 464 | 420 | |
| 465 | 421 | /* Turn on HW trigger mode if supported */ |
| 466 | 422 | if (sc->flags & HW_CTRL) { |
| 467 | 423 | ret = gdsc_hwctrl(sc, true); |
| 468 | 424 | if (ret < 0) |
| 469 | − goto err_put_rpm; | |
| 425 | + goto err_disable_supply; | |
| 470 | 426 | } |
| 471 | 427 | |
| 472 | 428 | /* |
| @@ -496,13 +452,10 @@ static int gdsc_init(struct gdsc *sc) · 23 unmodified lines | ||
| 496 | 452 | |
| 497 | 453 | ret = pm_genpd_init(&sc->pd, NULL, !on); |
| 498 | 454 | if (ret) |
| 499 | − goto err_put_rpm; | |
| 455 | + goto err_disable_supply; | |
| 500 | 456 | |
| 501 | 457 | return 0; |
| 502 | 458 | |
| 503 | −err_put_rpm: | |
| 504 | − if (on) | |
| 505 | − gdsc_pm_runtime_put(sc); | |
| 506 | 459 | err_disable_supply: |
| 507 | 460 | if (on && sc->rsupply) |
| 508 | 461 | regulator_disable(sc->rsupply); |
| @@ -541,8 +494,6 @@ int gdsc_register(struct gdsc_desc *desc, · 32 unmodified lines | ||
| 541 | 494 | for (i = 0; i < num; i++) { |
| 542 | 495 | if (!scs[i]) |
| 543 | 496 | continue; |
| 544 | − if (pm_runtime_enabled(dev)) | |
| 545 | − scs[i]->dev = dev; | |
| 546 | 497 | scs[i]->regmap = regmap; |
| 547 | 498 | scs[i]->rcdev = rcdev; |
| 548 | 499 | ret = gdsc_init(scs[i]); |
| @@ -30,7 +30,6 @@ struct reset_controller_dev; · 29 unmodified lines | ||
| 30 | 30 | * @resets: ids of resets associated with this gdsc |
| 31 | 31 | * @reset_count: number of @resets |
| 32 | 32 | * @rcdev: reset controller |
| 33 | − * @dev: the device holding the GDSC, used for pm_runtime calls | |
| 34 | 33 | */ |
| 35 | 34 | struct gdsc { |
| 36 | 35 | struct generic_pm_domain pd; |
| @@ -74,7 +73,6 @@ struct gdsc { · 37 unmodified lines | ||
| 74 | 73 | |
| 75 | 74 | const char *supply; |
| 76 | 75 | struct regulator *rsupply; |
| 77 | − struct device *dev; | |
| 78 | 76 | }; |
| 79 | 77 | |
| 80 | 78 | struct gdsc_desc { |
| @@ -463,6 +463,7 @@ static int gpu_cc_sc7280_probe(struct platform_device *pdev) · 462 unmodified lines | ||
| 463 | 463 | */ |
| 464 | 464 | regmap_update_bits(regmap, 0x1170, BIT(0), BIT(0)); |
| 465 | 465 | regmap_update_bits(regmap, 0x1098, BIT(0), BIT(0)); |
| 466 | + regmap_update_bits(regmap, 0x1098, BIT(13), BIT(13)); | |
| 466 | 467 | |
| 467 | 468 | return qcom_cc_really_probe(pdev, &gpu_cc_sc7280_desc, regmap); |
| 468 | 469 | } |
| @@ -47,6 +47,7 @@ enum clk_ids { · 46 unmodified lines | ||
| 47 | 47 | CLK_S0_VIO, |
| 48 | 48 | CLK_S0_VC, |
| 49 | 49 | CLK_S0_HSC, |
| 50 | + CLK_SASYNCPER, | |
| 50 | 51 | CLK_SV_VIP, |
| 51 | 52 | CLK_SV_IR, |
| 52 | 53 | CLK_SDSRC, |
| @@ -84,6 +85,7 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = { · 31 unmodified lines | ||
| 84 | 85 | DEF_FIXED(".s0_vio", CLK_S0_VIO, CLK_PLL1_DIV2, 2, 1), |
| 85 | 86 | DEF_FIXED(".s0_vc", CLK_S0_VC, CLK_PLL1_DIV2, 2, 1), |
| 86 | 87 | DEF_FIXED(".s0_hsc", CLK_S0_HSC, CLK_PLL1_DIV2, 2, 1), |
| 88 | + DEF_FIXED(".sasyncper", CLK_SASYNCPER, CLK_PLL5_DIV4, 3, 1), | |
| 87 | 89 | DEF_FIXED(".sv_vip", CLK_SV_VIP, CLK_PLL1, 5, 1), |
| 88 | 90 | DEF_FIXED(".sv_ir", CLK_SV_IR, CLK_PLL1, 5, 1), |
| 89 | 91 | DEF_BASE(".sdsrc", CLK_SDSRC, CLK_TYPE_GEN4_SDSRC, CLK_PLL5), |
| @@ -128,6 +130,9 @@ static const struct cpg_core_clk r8a779g0_core_clks[] __initconst = { · 38 unmodified lines | ||
| 128 | 130 | DEF_FIXED("s0d4_hsc", R8A779G0_CLK_S0D4_HSC, CLK_S0_HSC, 4, 1), |
| 129 | 131 | DEF_FIXED("cl16m_hsc", R8A779G0_CLK_CL16M_HSC, CLK_S0_HSC, 48, 1), |
| 130 | 132 | DEF_FIXED("s0d2_cc", R8A779G0_CLK_S0D2_CC, CLK_S0, 2, 1), |
| 133 | + DEF_FIXED("sasyncperd1",R8A779G0_CLK_SASYNCPERD1, CLK_SASYNCPER,1, 1), | |
| 134 | + DEF_FIXED("sasyncperd2",R8A779G0_CLK_SASYNCPERD2, CLK_SASYNCPER,2, 1), | |
| 135 | + DEF_FIXED("sasyncperd4",R8A779G0_CLK_SASYNCPERD4, CLK_SASYNCPER,4, 1), | |
| 131 | 136 | DEF_FIXED("svd1_ir", R8A779G0_CLK_SVD1_IR, CLK_SV_IR, 1, 1), |
| 132 | 137 | DEF_FIXED("svd2_ir", R8A779G0_CLK_SVD2_IR, CLK_SV_IR, 2, 1), |
| 133 | 138 | DEF_FIXED("svd1_vip", R8A779G0_CLK_SVD1_VIP, CLK_SV_VIP, 1, 1), |
| @@ -153,10 +158,10 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = { · 19 unmodified lines | ||
| 153 | 158 | DEF_MOD("avb0", 211, R8A779G0_CLK_S0D4_HSC), |
| 154 | 159 | DEF_MOD("avb1", 212, R8A779G0_CLK_S0D4_HSC), |
| 155 | 160 | DEF_MOD("avb2", 213, R8A779G0_CLK_S0D4_HSC), |
| 156 | − DEF_MOD("hscif0", 514, R8A779G0_CLK_S0D3_PER), | |
| 157 | − DEF_MOD("hscif1", 515, R8A779G0_CLK_S0D3_PER), | |
| 158 | − DEF_MOD("hscif2", 516, R8A779G0_CLK_S0D3_PER), | |
| 159 | − DEF_MOD("hscif3", 517, R8A779G0_CLK_S0D3_PER), | |
| 161 | + DEF_MOD("hscif0", 514, R8A779G0_CLK_SASYNCPERD1), | |
| 162 | + DEF_MOD("hscif1", 515, R8A779G0_CLK_SASYNCPERD1), | |
| 163 | + DEF_MOD("hscif2", 516, R8A779G0_CLK_SASYNCPERD1), | |
| 164 | + DEF_MOD("hscif3", 517, R8A779G0_CLK_SASYNCPERD1), | |
| 160 | 165 | DEF_MOD("i2c0", 518, R8A779G0_CLK_S0D6_PER), |
| 161 | 166 | DEF_MOD("i2c1", 519, R8A779G0_CLK_S0D6_PER), |
| 162 | 167 | DEF_MOD("i2c2", 520, R8A779G0_CLK_S0D6_PER), |
| @@ -81,17 +81,19 @@ MODULE_DEVICE_TABLE(of, exynos_clkout_ids); · 80 unmodified lines | ||
| 81 | 81 | static int exynos_clkout_match_parent_dev(struct device *dev, u32 *mux_mask) |
| 82 | 82 | { |
| 83 | 83 | const struct exynos_clkout_variant *variant; |
| 84 | + const struct of_device_id *match; | |
| 84 | 85 | |
| 85 | 86 | if (!dev->parent) { |
| 86 | 87 | dev_err(dev, "not instantiated from MFD\n"); |
| 87 | 88 | return -EINVAL; |
| 88 | 89 | } |
| 89 | 90 | |
| 90 | − variant = of_device_get_match_data(dev->parent); | |
| 91 | − if (!variant) { | |
| 91 | + match = of_match_device(exynos_clkout_ids, dev->parent); | |
| 92 | + if (!match) { | |
| 92 | 93 | dev_err(dev, "cannot match parent device\n"); |
| 93 | 94 | return -EINVAL; |
| 94 | 95 | } |
| 96 | + variant = match->data; | |
| 95 | 97 | |
| 96 | 98 | *mux_mask = variant->mux_mask; |
| 97 | 99 | |
| @@ -231,7 +231,7 @@ static const struct samsung_div_clock top_div_clks[] __initconst = { · 230 unmodified lines | ||
| 231 | 231 | CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1), |
| 232 | 232 | DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "fout_shared0_pll", |
| 233 | 233 | CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2), |
| 234 | − DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "fout_shared0_pll", | |
| 234 | + DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2", | |
| 235 | 235 | CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1), |
| 236 | 236 | DIV(CLK_DOUT_SHARED0_DIV5, "dout_shared0_div5", "fout_shared0_pll", |
| 237 | 237 | CLK_CON_DIV_PLL_SHARED0_DIV5, 0, 3), |
| @@ -239,7 +239,7 @@ static const struct samsung_div_clock top_div_clks[] __initconst = { · 1 unmodified line | ||
| 239 | 239 | CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1), |
| 240 | 240 | DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "fout_shared1_pll", |
| 241 | 241 | CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2), |
| 242 | − DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "fout_shared1_pll", | |
| 242 | + DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2", | |
| 243 | 243 | CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1), |
| 244 | 244 | |
| 245 | 245 | /* CORE */ |
| @@ -2,7 +2,8 @@ · 1 unmodified line | ||
| 2 | 2 | |
| 3 | 3 | menuconfig CLK_SIFIVE |
| 4 | 4 | bool "SiFive SoC driver support" |
| 5 | − depends on RISCV || COMPILE_TEST | |
| 5 | + depends on SOC_SIFIVE || COMPILE_TEST | |
| 6 | + default SOC_SIFIVE | |
| 6 | 7 | help |
| 7 | 8 | SoC drivers for SiFive Linux-capable SoCs. |
| 8 | 9 | |
| @@ -10,6 +11,7 @@ if CLK_SIFIVE · 1 unmodified line | ||
| 10 | 11 | |
| 11 | 12 | config CLK_SIFIVE_PRCI |
| 12 | 13 | bool "PRCI driver for SiFive SoCs" |
| 14 | + default SOC_SIFIVE | |
| 13 | 15 | select RESET_CONTROLLER |
| 14 | 16 | select RESET_SIMPLE |
| 15 | 17 | select CLK_ANALOGBITS_WRPLL_CLN28HPC |
| @@ -806,6 +806,9 @@ static u64 __arch_timer_check_delta(void) · 805 unmodified lines | ||
| 806 | 806 | /* |
| 807 | 807 | * XGene-1 implements CVAL in terms of TVAL, meaning |
| 808 | 808 | * that the maximum timer range is 32bit. Shame on them. |
| 809 | + * | |
| 810 | + * Note that TVAL is signed, thus has only 31 of its | |
| 811 | + * 32 bits to express magnitude. | |
| 809 | 812 | */ |
| 810 | 813 | MIDR_ALL_VERSIONS(MIDR_CPU_MODEL(ARM_CPU_IMP_APM, |
| 811 | 814 | APM_CPU_PART_POTENZA)), |
| @@ -813,8 +816,8 @@ static u64 __arch_timer_check_delta(void) · 1 unmodified line | ||
| 813 | 816 | }; |
| 814 | 817 | |
| 815 | 818 | if (is_midr_in_range_list(read_cpuid_id(), broken_cval_midrs)) { |
| 816 | − pr_warn_once("Broken CNTx_CVAL_EL1, limiting width to 32bits"); | |
| 817 | − return CLOCKSOURCE_MASK(32); | |
| 819 | + pr_warn_once("Broken CNTx_CVAL_EL1, using 31 bit TVAL instead.\n"); | |
| 820 | + return CLOCKSOURCE_MASK(31); | |
| 818 | 821 | } |
| 819 | 822 | #endif |
| 820 | 823 | return CLOCKSOURCE_MASK(arch_counter_get_width()); |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/interrupt.h> |
| 22 | 22 | #include <linux/irq.h> |
| 23 | 23 | #include <linux/acpi.h> |
| 24 | +#include <linux/hyperv.h> | |
| 24 | 25 | #include <clocksource/hyperv_timer.h> |
| 25 | 26 | #include <asm/hyperv-tlfs.h> |
| 26 | 27 | #include <asm/mshyperv.h> |
| @@ -395,25 +396,25 @@ static u64 notrace read_hv_sched_clock_tsc(void) · 368 unmodified lines | ||
| 395 | 396 | |
| 396 | 397 | static void suspend_hv_clock_tsc(struct clocksource *arg) |
| 397 | 398 | { |
| 398 | − u64 tsc_msr; | |
| 399 | + union hv_reference_tsc_msr tsc_msr; | |
| 399 | 400 | |
| 400 | 401 | /* Disable the TSC page */ |
| 401 | − tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC); | |
| 402 | − tsc_msr &= ~BIT_ULL(0); | |
| 403 | − hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr); | |
| 402 | + tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); | |
| 403 | + tsc_msr.enable = 0; | |
| 404 | + hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); | |
| 404 | 405 | } |
| 405 | 406 | |
| 406 | 407 | |
| 407 | 408 | static void resume_hv_clock_tsc(struct clocksource *arg) |
| 408 | 409 | { |
| 409 | 410 | phys_addr_t phys_addr = virt_to_phys(&tsc_pg); |
| 410 | − u64 tsc_msr; | |
| 411 | + union hv_reference_tsc_msr tsc_msr; | |
| 411 | 412 | |
| 412 | 413 | /* Re-enable the TSC page */ |
| 413 | − tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC); | |
| 414 | − tsc_msr &= GENMASK_ULL(11, 0); | |
| 415 | − tsc_msr |= BIT_ULL(0) | (u64)phys_addr; | |
| 416 | − hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr); | |
| 414 | + tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); | |
| 415 | + tsc_msr.enable = 1; | |
| 416 | + tsc_msr.pfn = HVPFN_DOWN(phys_addr); | |
| 417 | + hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); | |
| 417 | 418 | } |
| 418 | 419 | |
| 419 | 420 | #ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK |
| @@ -495,7 +496,7 @@ static __always_inline void hv_setup_sched_clock(void *sched_clock) {} · 75 unmodified lines | ||
| 495 | 496 | |
| 496 | 497 | static bool __init hv_init_tsc_clocksource(void) |
| 497 | 498 | { |
| 498 | − u64 tsc_msr; | |
| 499 | + union hv_reference_tsc_msr tsc_msr; | |
| 499 | 500 | phys_addr_t phys_addr; |
| 500 | 501 | |
| 501 | 502 | if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE)) |
| @@ -530,10 +531,10 @@ static bool __init hv_init_tsc_clocksource(void) · 28 unmodified lines | ||
| 530 | 531 | * (which already has at least the low 12 bits set to zero since |
| 531 | 532 | * it is page aligned). Also set the "enable" bit, which is bit 0. |
| 532 | 533 | */ |
| 533 | − tsc_msr = hv_get_register(HV_REGISTER_REFERENCE_TSC); | |
| 534 | − tsc_msr &= GENMASK_ULL(11, 0); | |
| 535 | − tsc_msr = tsc_msr | 0x1 | (u64)phys_addr; | |
| 536 | − hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr); | |
| 534 | + tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC); | |
| 535 | + tsc_msr.enable = 1; | |
| 536 | + tsc_msr.pfn = HVPFN_DOWN(phys_addr); | |
| 537 | + hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64); | |
| 537 | 538 | |
| 538 | 539 | clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100); |
| 539 | 540 | |
| @@ -51,7 +51,7 @@ static int riscv_clock_next_event(unsigned long delta, · 50 unmodified lines | ||
| 51 | 51 | static unsigned int riscv_clock_event_irq; |
| 52 | 52 | static DEFINE_PER_CPU(struct clock_event_device, riscv_clock_event) = { |
| 53 | 53 | .name = "riscv_timer_clockevent", |
| 54 | − .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP, | |
| 54 | + .features = CLOCK_EVT_FEAT_ONESHOT, | |
| 55 | 55 | .rating = 100, |
| 56 | 56 | .set_next_event = riscv_clock_next_event, |
| 57 | 57 | }; |
| @@ -35,7 +35,7 @@ config X86_PCC_CPUFREQ · 34 unmodified lines | ||
| 35 | 35 | If in doubt, say N. |
| 36 | 36 | |
| 37 | 37 | config X86_AMD_PSTATE |
| 38 | − tristate "AMD Processor P-State driver" | |
| 38 | + bool "AMD Processor P-State driver" | |
| 39 | 39 | depends on X86 && ACPI |
| 40 | 40 | select ACPI_PROCESSOR |
| 41 | 41 | select ACPI_CPPC_LIB if X86_64 |
| @@ -59,12 +59,8 @@ · 58 unmodified lines | ||
| 59 | 59 | * we disable it by default to go acpi-cpufreq on these processors and add a |
| 60 | 60 | * module parameter to be able to enable it manually for debugging. |
| 61 | 61 | */ |
| 62 | −static bool shared_mem = false; | |
| 63 | −module_param(shared_mem, bool, 0444); | |
| 64 | −MODULE_PARM_DESC(shared_mem, | |
| 65 | − "enable amd-pstate on processors with shared memory solution (false = disabled (default), true = enabled)"); | |
| 66 | − | |
| 67 | 62 | static struct cpufreq_driver amd_pstate_driver; |
| 63 | +static int cppc_load __initdata; | |
| 68 | 64 | |
| 69 | 65 | static inline int pstate_enable(bool enable) |
| 70 | 66 | { |
| @@ -424,12 +420,22 @@ static void amd_pstate_boost_init(struct amd_cpudata *cpudata) · 353 unmodified lines | ||
| 424 | 420 | amd_pstate_driver.boost_enabled = true; |
| 425 | 421 | } |
| 426 | 422 | |
| 423 | +static void amd_perf_ctl_reset(unsigned int cpu) | |
| 424 | +{ | |
| 425 | + wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0); | |
| 426 | +} | |
| 427 | + | |
| 427 | 428 | static int amd_pstate_cpu_init(struct cpufreq_policy *policy) |
| 428 | 429 | { |
| 429 | 430 | int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret; |
| 430 | 431 | struct device *dev; |
| 431 | 432 | struct amd_cpudata *cpudata; |
| 432 | 433 | |
| 434 | + /* | |
| 435 | + * Resetting PERF_CTL_MSR will put the CPU in P0 frequency, | |
| 436 | + * which is ideal for initialization process. | |
| 437 | + */ | |
| 438 | + amd_perf_ctl_reset(policy->cpu); | |
| 433 | 439 | dev = get_cpu_device(policy->cpu); |
| 434 | 440 | if (!dev) |
| 435 | 441 | return -ENODEV; |
| @@ -616,6 +622,15 @@ static int __init amd_pstate_init(void) · 180 unmodified lines | ||
| 616 | 622 | |
| 617 | 623 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) |
| 618 | 624 | return -ENODEV; |
| 625 | + /* | |
| 626 | + * by default the pstate driver is disabled to load | |
| 627 | + * enable the amd_pstate passive mode driver explicitly | |
| 628 | + * with amd_pstate=passive in kernel command line | |
| 629 | + */ | |
| 630 | + if (!cppc_load) { | |
| 631 | + pr_debug("driver load is disabled, boot with amd_pstate=passive to enable this\n"); | |
| 632 | + return -ENODEV; | |
| 633 | + } | |
| 619 | 634 | |
| 620 | 635 | if (!acpi_cpc_valid()) { |
| 621 | 636 | pr_warn_once("the _CPC object is not present in SBIOS or ACPI disabled\n"); |
| @@ -630,13 +645,11 @@ static int __init amd_pstate_init(void) · 8 unmodified lines | ||
| 630 | 645 | if (boot_cpu_has(X86_FEATURE_CPPC)) { |
| 631 | 646 | pr_debug("AMD CPPC MSR based functionality is supported\n"); |
| 632 | 647 | amd_pstate_driver.adjust_perf = amd_pstate_adjust_perf; |
| 633 | − } else if (shared_mem) { | |
| 648 | + } else { | |
| 649 | + pr_debug("AMD CPPC shared memory based functionality is supported\n"); | |
| 634 | 650 | static_call_update(amd_pstate_enable, cppc_enable); |
| 635 | 651 | static_call_update(amd_pstate_init_perf, cppc_init_perf); |
| 636 | 652 | static_call_update(amd_pstate_update_perf, cppc_update_perf); |
| 637 | − } else { | |
| 638 | − pr_info("This processor supports shared memory solution, you can enable it with amd_pstate.shared_mem=1\n"); | |
| 639 | − return -ENODEV; | |
| 640 | 653 | } |
| 641 | 654 | |
| 642 | 655 | /* enable amd pstate feature */ |
| @@ -653,16 +666,22 @@ static int __init amd_pstate_init(void) · 10 unmodified lines | ||
| 653 | 666 | |
| 654 | 667 | return ret; |
| 655 | 668 | } |
| 669 | +device_initcall(amd_pstate_init); | |
| 656 | 670 | |
| 657 | −static void __exit amd_pstate_exit(void) | |
| 671 | +static int __init amd_pstate_param(char *str) | |
| 658 | 672 | { |
| 659 | − cpufreq_unregister_driver(&amd_pstate_driver); | |
| 673 | + if (!str) | |
| 674 | + return -EINVAL; | |
| 660 | 675 | |
| 661 | − amd_pstate_enable(false); | |
| 662 | −} | |
| 676 | + if (!strcmp(str, "disable")) { | |
| 677 | + cppc_load = 0; | |
| 678 | + pr_info("driver is explicitly disabled\n"); | |
| 679 | + } else if (!strcmp(str, "passive")) | |
| 680 | + cppc_load = 1; | |
| 663 | 681 | |
| 664 | −module_init(amd_pstate_init); | |
| 665 | −module_exit(amd_pstate_exit); | |
| 682 | + return 0; | |
| 683 | +} | |
| 684 | +early_param("amd_pstate", amd_pstate_param); | |
| 666 | 685 | |
| 667 | 686 | MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>"); |
| 668 | 687 | MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver"); |
| @@ -174,7 +174,7 @@ int cxl_mbox_send_cmd(struct cxl_dev_state *cxlds, u16 opcode, void *in, · 173 unmodified lines | ||
| 174 | 174 | }; |
| 175 | 175 | int rc; |
| 176 | 176 | |
| 177 | − if (out_size > cxlds->payload_size) | |
| 177 | + if (in_size > cxlds->payload_size || out_size > cxlds->payload_size) | |
| 178 | 178 | return -E2BIG; |
| 179 | 179 | |
| 180 | 180 | rc = cxlds->mbox_send(cxlds, &mbox_cmd); |
| @@ -188,6 +188,7 @@ static void cxl_nvdimm_release(struct device *dev) · 187 unmodified lines | ||
| 188 | 188 | { |
| 189 | 189 | struct cxl_nvdimm *cxl_nvd = to_cxl_nvdimm(dev); |
| 190 | 190 | |
| 191 | + xa_destroy(&cxl_nvd->pmem_regions); | |
| 191 | 192 | kfree(cxl_nvd); |
| 192 | 193 | } |
| 193 | 194 | |
| @@ -230,6 +231,7 @@ static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_memdev *cxlmd) · 36 unmodified lines | ||
| 230 | 231 | |
| 231 | 232 | dev = &cxl_nvd->dev; |
| 232 | 233 | cxl_nvd->cxlmd = cxlmd; |
| 234 | + xa_init(&cxl_nvd->pmem_regions); | |
| 233 | 235 | device_initialize(dev); |
| 234 | 236 | lockdep_set_class(&dev->mutex, &cxl_nvdimm_key); |
| 235 | 237 | device_set_pm_not_required(dev); |
| @@ -811,6 +811,7 @@ static struct cxl_dport *find_dport(struct cxl_port *port, int id) · 810 unmodified lines | ||
| 811 | 811 | static int add_dport(struct cxl_port *port, struct cxl_dport *new) |
| 812 | 812 | { |
| 813 | 813 | struct cxl_dport *dup; |
| 814 | + int rc; | |
| 814 | 815 | |
| 815 | 816 | device_lock_assert(&port->dev); |
| 816 | 817 | dup = find_dport(port, new->port_id); |
| @@ -821,8 +822,14 @@ static int add_dport(struct cxl_port *port, struct cxl_dport *new) · 4 unmodified lines | ||
| 821 | 822 | dev_name(dup->dport)); |
| 822 | 823 | return -EBUSY; |
| 823 | 824 | } |
| 824 | − return xa_insert(&port->dports, (unsigned long)new->dport, new, | |
| 825 | − GFP_KERNEL); | |
| 825 | + | |
| 826 | + rc = xa_insert(&port->dports, (unsigned long)new->dport, new, | |
| 827 | + GFP_KERNEL); | |
| 828 | + if (rc) | |
| 829 | + return rc; | |
| 830 | + | |
| 831 | + port->nr_dports++; | |
| 832 | + return 0; | |
| 826 | 833 | } |
| 827 | 834 | |
| 828 | 835 | /* |
| @@ -174,7 +174,8 @@ static int cxl_region_decode_commit(struct cxl_region *cxlr) · 173 unmodified lines | ||
| 174 | 174 | iter = to_cxl_port(iter->dev.parent)) { |
| 175 | 175 | cxl_rr = cxl_rr_load(iter, cxlr); |
| 176 | 176 | cxld = cxl_rr->decoder; |
| 177 | − rc = cxld->commit(cxld); | |
| 177 | + if (cxld->commit) | |
| 178 | + rc = cxld->commit(cxld); | |
| 178 | 179 | if (rc) |
| 179 | 180 | break; |
| 180 | 181 | } |
| @@ -657,6 +658,9 @@ static struct cxl_region_ref *alloc_region_ref(struct cxl_port *port, · 476 unmodified lines | ||
| 657 | 658 | xa_for_each(&port->regions, index, iter) { |
| 658 | 659 | struct cxl_region_params *ip = &iter->region->params; |
| 659 | 660 | |
| 661 | + if (!ip->res) | |
| 662 | + continue; | |
| 663 | + | |
| 660 | 664 | if (ip->res->start > p->res->start) { |
| 661 | 665 | dev_dbg(&cxlr->dev, |
| 662 | 666 | "%s: HPA order violation %s:%pr vs %pr\n", |
| @@ -686,18 +690,27 @@ static struct cxl_region_ref *alloc_region_ref(struct cxl_port *port, · 23 unmodified lines | ||
| 686 | 690 | return cxl_rr; |
| 687 | 691 | } |
| 688 | 692 | |
| 689 | −static void free_region_ref(struct cxl_region_ref *cxl_rr) | |
| 693 | +static void cxl_rr_free_decoder(struct cxl_region_ref *cxl_rr) | |
| 690 | 694 | { |
| 691 | − struct cxl_port *port = cxl_rr->port; | |
| 692 | 695 | struct cxl_region *cxlr = cxl_rr->region; |
| 693 | 696 | struct cxl_decoder *cxld = cxl_rr->decoder; |
| 694 | 697 | |
| 698 | + if (!cxld) | |
| 699 | + return; | |
| 700 | + | |
| 695 | 701 | dev_WARN_ONCE(&cxlr->dev, cxld->region != cxlr, "region mismatch\n"); |
| 696 | 702 | if (cxld->region == cxlr) { |
| 697 | 703 | cxld->region = NULL; |
| 698 | 704 | put_device(&cxlr->dev); |
| 699 | 705 | } |
| 706 | +} | |
| 700 | 707 | |
| 708 | +static void free_region_ref(struct cxl_region_ref *cxl_rr) | |
| 709 | +{ | |
| 710 | + struct cxl_port *port = cxl_rr->port; | |
| 711 | + struct cxl_region *cxlr = cxl_rr->region; | |
| 712 | + | |
| 713 | + cxl_rr_free_decoder(cxl_rr); | |
| 701 | 714 | xa_erase(&port->regions, (unsigned long)cxlr); |
| 702 | 715 | xa_destroy(&cxl_rr->endpoints); |
| 703 | 716 | kfree(cxl_rr); |
| @@ -728,6 +741,33 @@ static int cxl_rr_ep_add(struct cxl_region_ref *cxl_rr, · 24 unmodified lines | ||
| 728 | 741 | return 0; |
| 729 | 742 | } |
| 730 | 743 | |
| 744 | +static int cxl_rr_alloc_decoder(struct cxl_port *port, struct cxl_region *cxlr, | |
| 745 | + struct cxl_endpoint_decoder *cxled, | |
| 746 | + struct cxl_region_ref *cxl_rr) | |
| 747 | +{ | |
| 748 | + struct cxl_decoder *cxld; | |
| 749 | + | |
| 750 | + if (port == cxled_to_port(cxled)) | |
| 751 | + cxld = &cxled->cxld; | |
| 752 | + else | |
| 753 | + cxld = cxl_region_find_decoder(port, cxlr); | |
| 754 | + if (!cxld) { | |
| 755 | + dev_dbg(&cxlr->dev, "%s: no decoder available\n", | |
| 756 | + dev_name(&port->dev)); | |
| 757 | + return -EBUSY; | |
| 758 | + } | |
| 759 | + | |
| 760 | + if (cxld->region) { | |
| 761 | + dev_dbg(&cxlr->dev, "%s: %s already attached to %s\n", | |
| 762 | + dev_name(&port->dev), dev_name(&cxld->dev), | |
| 763 | + dev_name(&cxld->region->dev)); | |
| 764 | + return -EBUSY; | |
| 765 | + } | |
| 766 | + | |
| 767 | + cxl_rr->decoder = cxld; | |
| 768 | + return 0; | |
| 769 | +} | |
| 770 | + | |
| 731 | 771 | /** |
| 732 | 772 | * cxl_port_attach_region() - track a region's interest in a port by endpoint |
| 733 | 773 | * @port: port to add a new region reference 'struct cxl_region_ref' |
| @@ -794,12 +834,6 @@ static int cxl_port_attach_region(struct cxl_port *port, · 60 unmodified lines | ||
| 794 | 834 | cxl_rr->nr_targets++; |
| 795 | 835 | nr_targets_inc = true; |
| 796 | 836 | } |
| 797 | − | |
| 798 | − /* | |
| 799 | − * The decoder for @cxlr was allocated when the region was first | |
| 800 | − * attached to @port. | |
| 801 | − */ | |
| 802 | − cxld = cxl_rr->decoder; | |
| 803 | 837 | } else { |
| 804 | 838 | cxl_rr = alloc_region_ref(port, cxlr); |
| 805 | 839 | if (IS_ERR(cxl_rr)) { |
| @@ -810,26 +844,11 @@ static int cxl_port_attach_region(struct cxl_port *port, · 4 unmodified lines | ||
| 810 | 844 | } |
| 811 | 845 | nr_targets_inc = true; |
| 812 | 846 | |
| 813 | − if (port == cxled_to_port(cxled)) | |
| 814 | − cxld = &cxled->cxld; | |
| 815 | − else | |
| 816 | − cxld = cxl_region_find_decoder(port, cxlr); | |
| 817 | − if (!cxld) { | |
| 818 | − dev_dbg(&cxlr->dev, "%s: no decoder available\n", | |
| 819 | − dev_name(&port->dev)); | |
| 820 | − goto out_erase; | |
| 821 | − } | |
| 822 | − | |
| 823 | − if (cxld->region) { | |
| 824 | − dev_dbg(&cxlr->dev, "%s: %s already attached to %s\n", | |
| 825 | − dev_name(&port->dev), dev_name(&cxld->dev), | |
| 826 | − dev_name(&cxld->region->dev)); | |
| 827 | − rc = -EBUSY; | |
| 847 | + rc = cxl_rr_alloc_decoder(port, cxlr, cxled, cxl_rr); | |
| 848 | + if (rc) | |
| 828 | 849 | goto out_erase; |
| 829 | − } | |
| 830 | − | |
| 831 | − cxl_rr->decoder = cxld; | |
| 832 | 850 | } |
| 851 | + cxld = cxl_rr->decoder; | |
| 833 | 852 | |
| 834 | 853 | rc = cxl_rr_ep_add(cxl_rr, cxled); |
| 835 | 854 | if (rc) { |
| @@ -971,7 +990,14 @@ static int cxl_port_setup_targets(struct cxl_port *port, · 135 unmodified lines | ||
| 971 | 990 | if (cxl_rr->nr_targets_set) { |
| 972 | 991 | int i, distance; |
| 973 | 992 | |
| 974 | − distance = p->nr_targets / cxl_rr->nr_targets; | |
| 993 | + /* | |
| 994 | + * Passthrough ports impose no distance requirements between | |
| 995 | + * peers | |
| 996 | + */ | |
| 997 | + if (port->nr_dports == 1) | |
| 998 | + distance = 0; | |
| 999 | + else | |
| 1000 | + distance = p->nr_targets / cxl_rr->nr_targets; | |
| 975 | 1001 | for (i = 0; i < cxl_rr->nr_targets_set; i++) |
| 976 | 1002 | if (ep->dport == cxlsd->target[i]) { |
| 977 | 1003 | rc = check_last_peer(cxled, ep, cxl_rr, |
| @@ -1508,9 +1534,24 @@ static const struct attribute_group *region_groups[] = { · 530 unmodified lines | ||
| 1508 | 1534 | |
| 1509 | 1535 | static void cxl_region_release(struct device *dev) |
| 1510 | 1536 | { |
| 1537 | + struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev->parent); | |
| 1511 | 1538 | struct cxl_region *cxlr = to_cxl_region(dev); |
| 1539 | + int id = atomic_read(&cxlrd->region_id); | |
| 1540 | + | |
| 1541 | + /* | |
| 1542 | + * Try to reuse the recently idled id rather than the cached | |
| 1543 | + * next id to prevent the region id space from increasing | |
| 1544 | + * unnecessarily. | |
| 1545 | + */ | |
| 1546 | + if (cxlr->id < id) | |
| 1547 | + if (atomic_try_cmpxchg(&cxlrd->region_id, &id, cxlr->id)) { | |
| 1548 | + memregion_free(id); | |
| 1549 | + goto out; | |
| 1550 | + } | |
| 1512 | 1551 | |
| 1513 | 1552 | memregion_free(cxlr->id); |
| 1553 | +out: | |
| 1554 | + put_device(dev->parent); | |
| 1514 | 1555 | kfree(cxlr); |
| 1515 | 1556 | } |
| 1516 | 1557 | |
| @@ -1538,8 +1579,19 @@ static struct cxl_region *to_cxl_region(struct device *dev) · 21 unmodified lines | ||
| 1538 | 1579 | static void unregister_region(void *dev) |
| 1539 | 1580 | { |
| 1540 | 1581 | struct cxl_region *cxlr = to_cxl_region(dev); |
| 1582 | + struct cxl_region_params *p = &cxlr->params; | |
| 1583 | + int i; | |
| 1541 | 1584 | |
| 1542 | 1585 | device_del(dev); |
| 1586 | + | |
| 1587 | + /* | |
| 1588 | + * Now that region sysfs is shutdown, the parameter block is now | |
| 1589 | + * read-only, so no need to hold the region rwsem to access the | |
| 1590 | + * region parameters. | |
| 1591 | + */ | |
| 1592 | + for (i = 0; i < p->interleave_ways; i++) | |
| 1593 | + detach_target(cxlr, i); | |
| 1594 | + | |
| 1543 | 1595 | cxl_region_iomem_release(cxlr); |
| 1544 | 1596 | put_device(dev); |
| 1545 | 1597 | } |
| @@ -1561,6 +1613,11 @@ static struct cxl_region *cxl_region_alloc(struct cxl_root_decoder *cxlrd, int i · 15 unmodified lines | ||
| 1561 | 1613 | device_initialize(dev); |
| 1562 | 1614 | lockdep_set_class(&dev->mutex, &cxl_region_key); |
| 1563 | 1615 | dev->parent = &cxlrd->cxlsd.cxld.dev; |
| 1616 | + /* | |
| 1617 | + * Keep root decoder pinned through cxl_region_release to fixup | |
| 1618 | + * region id allocations | |
| 1619 | + */ | |
| 1620 | + get_device(dev->parent); | |
| 1564 | 1621 | device_set_pm_not_required(dev); |
| 1565 | 1622 | dev->bus = &cxl_bus_type; |
| 1566 | 1623 | dev->type = &cxl_region_type; |
| @@ -423,7 +423,7 @@ struct cxl_nvdimm { · 422 unmodified lines | ||
| 423 | 423 | struct device dev; |
| 424 | 424 | struct cxl_memdev *cxlmd; |
| 425 | 425 | struct cxl_nvdimm_bridge *bridge; |
| 426 | − struct cxl_pmem_region *region; | |
| 426 | + struct xarray pmem_regions; | |
| 427 | 427 | }; |
| 428 | 428 | |
| 429 | 429 | struct cxl_pmem_region_mapping { |
| @@ -457,6 +457,7 @@ struct cxl_pmem_region { · 27 unmodified lines | ||
| 457 | 457 | * @regions: cxl_region_ref instances, regions mapped by this port |
| 458 | 458 | * @parent_dport: dport that points to this port in the parent |
| 459 | 459 | * @decoder_ida: allocator for decoder ids |
| 460 | + * @nr_dports: number of entries in @dports | |
| 460 | 461 | * @hdm_end: track last allocated HDM decoder instance for allocation ordering |
| 461 | 462 | * @commit_end: cursor to track highest committed decoder for commit ordering |
| 462 | 463 | * @component_reg_phys: component register capability base address (optional) |
| @@ -475,6 +476,7 @@ struct cxl_port { · 12 unmodified lines | ||
| 475 | 476 | struct xarray regions; |
| 476 | 477 | struct cxl_dport *parent_dport; |
| 477 | 478 | struct ida decoder_ida; |
| 479 | + int nr_dports; | |
| 478 | 480 | int hdm_end; |
| 479 | 481 | int commit_end; |
| 480 | 482 | resource_size_t component_reg_phys; |
| @@ -30,17 +30,20 @@ static void unregister_nvdimm(void *nvdimm) · 29 unmodified lines | ||
| 30 | 30 | struct cxl_nvdimm *cxl_nvd = nvdimm_provider_data(nvdimm); |
| 31 | 31 | struct cxl_nvdimm_bridge *cxl_nvb = cxl_nvd->bridge; |
| 32 | 32 | struct cxl_pmem_region *cxlr_pmem; |
| 33 | + unsigned long index; | |
| 33 | 34 | |
| 34 | 35 | device_lock(&cxl_nvb->dev); |
| 35 | − cxlr_pmem = cxl_nvd->region; | |
| 36 | 36 | dev_set_drvdata(&cxl_nvd->dev, NULL); |
| 37 | − cxl_nvd->region = NULL; | |
| 38 | − device_unlock(&cxl_nvb->dev); | |
| 37 | + xa_for_each(&cxl_nvd->pmem_regions, index, cxlr_pmem) { | |
| 38 | + get_device(&cxlr_pmem->dev); | |
| 39 | + device_unlock(&cxl_nvb->dev); | |
| 39 | 40 | |
| 40 | − if (cxlr_pmem) { | |
| 41 | 41 | device_release_driver(&cxlr_pmem->dev); |
| 42 | 42 | put_device(&cxlr_pmem->dev); |
| 43 | + | |
| 44 | + device_lock(&cxl_nvb->dev); | |
| 43 | 45 | } |
| 46 | + device_unlock(&cxl_nvb->dev); | |
| 44 | 47 | |
| 45 | 48 | nvdimm_delete(nvdimm); |
| 46 | 49 | cxl_nvd->bridge = NULL; |
| @@ -107,7 +110,7 @@ static int cxl_pmem_get_config_size(struct cxl_dev_state *cxlds, · 60 unmodified lines | ||
| 107 | 110 | |
| 108 | 111 | *cmd = (struct nd_cmd_get_config_size) { |
| 109 | 112 | .config_size = cxlds->lsa_size, |
| 110 | − .max_xfer = cxlds->payload_size, | |
| 113 | + .max_xfer = cxlds->payload_size - sizeof(struct cxl_mbox_set_lsa), | |
| 111 | 114 | }; |
| 112 | 115 | |
| 113 | 116 | return 0; |
| @@ -148,7 +151,7 @@ static int cxl_pmem_set_config_data(struct cxl_dev_state *cxlds, · 34 unmodified lines | ||
| 148 | 151 | return -EINVAL; |
| 149 | 152 | |
| 150 | 153 | /* 4-byte status follows the input data in the payload */ |
| 151 | − if (struct_size(cmd, in_buf, cmd->in_length) + 4 > buf_len) | |
| 154 | + if (size_add(struct_size(cmd, in_buf, cmd->in_length), 4) > buf_len) | |
| 152 | 155 | return -EINVAL; |
| 153 | 156 | |
| 154 | 157 | set_lsa = |
| @@ -366,25 +369,49 @@ static int match_cxl_nvdimm(struct device *dev, void *data) · 211 unmodified lines | ||
| 366 | 369 | |
| 367 | 370 | static void unregister_nvdimm_region(void *nd_region) |
| 368 | 371 | { |
| 369 | − struct cxl_nvdimm_bridge *cxl_nvb; | |
| 370 | − struct cxl_pmem_region *cxlr_pmem; | |
| 372 | + nvdimm_region_delete(nd_region); | |
| 373 | +} | |
| 374 | + | |
| 375 | +static int cxl_nvdimm_add_region(struct cxl_nvdimm *cxl_nvd, | |
| 376 | + struct cxl_pmem_region *cxlr_pmem) | |
| 377 | +{ | |
| 378 | + int rc; | |
| 379 | + | |
| 380 | + rc = xa_insert(&cxl_nvd->pmem_regions, (unsigned long)cxlr_pmem, | |
| 381 | + cxlr_pmem, GFP_KERNEL); | |
| 382 | + if (rc) | |
| 383 | + return rc; | |
| 384 | + | |
| 385 | + get_device(&cxlr_pmem->dev); | |
| 386 | + return 0; | |
| 387 | +} | |
| 388 | + | |
| 389 | +static void cxl_nvdimm_del_region(struct cxl_nvdimm *cxl_nvd, | |
| 390 | + struct cxl_pmem_region *cxlr_pmem) | |
| 391 | +{ | |
| 392 | + /* | |
| 393 | + * It is possible this is called without a corresponding | |
| 394 | + * cxl_nvdimm_add_region for @cxlr_pmem | |
| 395 | + */ | |
| 396 | + cxlr_pmem = xa_erase(&cxl_nvd->pmem_regions, (unsigned long)cxlr_pmem); | |
| 397 | + if (cxlr_pmem) | |
| 398 | + put_device(&cxlr_pmem->dev); | |
| 399 | +} | |
| 400 | + | |
| 401 | +static void release_mappings(void *data) | |
| 402 | +{ | |
| 371 | 403 | int i; |
| 404 | + struct cxl_pmem_region *cxlr_pmem = data; | |
| 405 | + struct cxl_nvdimm_bridge *cxl_nvb = cxlr_pmem->bridge; | |
| 372 | 406 | |
| 373 | − cxlr_pmem = nd_region_provider_data(nd_region); | |
| 374 | − cxl_nvb = cxlr_pmem->bridge; | |
| 375 | 407 | device_lock(&cxl_nvb->dev); |
| 376 | 408 | for (i = 0; i < cxlr_pmem->nr_mappings; i++) { |
| 377 | 409 | struct cxl_pmem_region_mapping *m = &cxlr_pmem->mapping[i]; |
| 378 | 410 | struct cxl_nvdimm *cxl_nvd = m->cxl_nvd; |
| 379 | 411 | |
| 380 | − if (cxl_nvd->region) { | |
| 381 | − put_device(&cxlr_pmem->dev); | |
| 382 | − cxl_nvd->region = NULL; | |
| 383 | − } | |
| 412 | + cxl_nvdimm_del_region(cxl_nvd, cxlr_pmem); | |
| 384 | 413 | } |
| 385 | 414 | device_unlock(&cxl_nvb->dev); |
| 386 | − | |
| 387 | − nvdimm_region_delete(nd_region); | |
| 388 | 415 | } |
| 389 | 416 | |
| 390 | 417 | static void cxlr_pmem_remove_resource(void *res) |
| @@ -422,7 +449,7 @@ static int cxl_pmem_region_probe(struct device *dev) · 31 unmodified lines | ||
| 422 | 449 | if (!cxl_nvb->nvdimm_bus) { |
| 423 | 450 | dev_dbg(dev, "nvdimm bus not found\n"); |
| 424 | 451 | rc = -ENXIO; |
| 425 | − goto err; | |
| 452 | + goto out_nvb; | |
| 426 | 453 | } |
| 427 | 454 | |
| 428 | 455 | memset(&mappings, 0, sizeof(mappings)); |
| @@ -431,7 +458,7 @@ static int cxl_pmem_region_probe(struct device *dev) · 2 unmodified lines | ||
| 431 | 458 | res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL); |
| 432 | 459 | if (!res) { |
| 433 | 460 | rc = -ENOMEM; |
| 434 | − goto err; | |
| 461 | + goto out_nvb; | |
| 435 | 462 | } |
| 436 | 463 | |
| 437 | 464 | res->name = "Persistent Memory"; |
| @@ -442,11 +469,11 @@ static int cxl_pmem_region_probe(struct device *dev) · 4 unmodified lines | ||
| 442 | 469 | |
| 443 | 470 | rc = insert_resource(&iomem_resource, res); |
| 444 | 471 | if (rc) |
| 445 | − goto err; | |
| 472 | + goto out_nvb; | |
| 446 | 473 | |
| 447 | 474 | rc = devm_add_action_or_reset(dev, cxlr_pmem_remove_resource, res); |
| 448 | 475 | if (rc) |
| 449 | − goto err; | |
| 476 | + goto out_nvb; | |
| 450 | 477 | |
| 451 | 478 | ndr_desc.res = res; |
| 452 | 479 | ndr_desc.provider_data = cxlr_pmem; |
| @@ -462,7 +489,7 @@ static int cxl_pmem_region_probe(struct device *dev) · 9 unmodified lines | ||
| 462 | 489 | nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL); |
| 463 | 490 | if (!nd_set) { |
| 464 | 491 | rc = -ENOMEM; |
| 465 | − goto err; | |
| 492 | + goto out_nvb; | |
| 466 | 493 | } |
| 467 | 494 | |
| 468 | 495 | ndr_desc.memregion = cxlr->id; |
| @@ -472,9 +499,13 @@ static int cxl_pmem_region_probe(struct device *dev) · 3 unmodified lines | ||
| 472 | 499 | info = kmalloc_array(cxlr_pmem->nr_mappings, sizeof(*info), GFP_KERNEL); |
| 473 | 500 | if (!info) { |
| 474 | 501 | rc = -ENOMEM; |
| 475 | − goto err; | |
| 502 | + goto out_nvb; | |
| 476 | 503 | } |
| 477 | 504 | |
| 505 | + rc = devm_add_action_or_reset(dev, release_mappings, cxlr_pmem); | |
| 506 | + if (rc) | |
| 507 | + goto out_nvd; | |
| 508 | + | |
| 478 | 509 | for (i = 0; i < cxlr_pmem->nr_mappings; i++) { |
| 479 | 510 | struct cxl_pmem_region_mapping *m = &cxlr_pmem->mapping[i]; |
| 480 | 511 | struct cxl_memdev *cxlmd = m->cxlmd; |
| @@ -486,7 +517,7 @@ static int cxl_pmem_region_probe(struct device *dev) · 5 unmodified lines | ||
| 486 | 517 | dev_dbg(dev, "[%d]: %s: no cxl_nvdimm found\n", i, |
| 487 | 518 | dev_name(&cxlmd->dev)); |
| 488 | 519 | rc = -ENODEV; |
| 489 | − goto err; | |
| 520 | + goto out_nvd; | |
| 490 | 521 | } |
| 491 | 522 | |
| 492 | 523 | /* safe to drop ref now with bridge lock held */ |
| @@ -498,10 +529,17 @@ static int cxl_pmem_region_probe(struct device *dev) · 5 unmodified lines | ||
| 498 | 529 | dev_dbg(dev, "[%d]: %s: no nvdimm found\n", i, |
| 499 | 530 | dev_name(&cxlmd->dev)); |
| 500 | 531 | rc = -ENODEV; |
| 501 | − goto err; | |
| 532 | + goto out_nvd; | |
| 502 | 533 | } |
| 503 | − cxl_nvd->region = cxlr_pmem; | |
| 504 | − get_device(&cxlr_pmem->dev); | |
| 534 | + | |
| 535 | + /* | |
| 536 | + * Pin the region per nvdimm device as those may be released | |
| 537 | + * out-of-order with respect to the region, and a single nvdimm | |
| 538 | + * maybe associated with multiple regions | |
| 539 | + */ | |
| 540 | + rc = cxl_nvdimm_add_region(cxl_nvd, cxlr_pmem); | |
| 541 | + if (rc) | |
| 542 | + goto out_nvd; | |
| 505 | 543 | m->cxl_nvd = cxl_nvd; |
| 506 | 544 | mappings[i] = (struct nd_mapping_desc) { |
| 507 | 545 | .nvdimm = nvdimm, |
| @@ -527,27 +565,18 @@ static int cxl_pmem_region_probe(struct device *dev) · 19 unmodified lines | ||
| 527 | 565 | nvdimm_pmem_region_create(cxl_nvb->nvdimm_bus, &ndr_desc); |
| 528 | 566 | if (!cxlr_pmem->nd_region) { |
| 529 | 567 | rc = -ENOMEM; |
| 530 | − goto err; | |
| 568 | + goto out_nvd; | |
| 531 | 569 | } |
| 532 | 570 | |
| 533 | 571 | rc = devm_add_action_or_reset(dev, unregister_nvdimm_region, |
| 534 | 572 | cxlr_pmem->nd_region); |
| 535 | −out: | |
| 573 | +out_nvd: | |
| 536 | 574 | kfree(info); |
| 575 | +out_nvb: | |
| 537 | 576 | device_unlock(&cxl_nvb->dev); |
| 538 | 577 | put_device(&cxl_nvb->dev); |
| 539 | 578 | |
| 540 | 579 | return rc; |
| 541 | − | |
| 542 | −err: | |
| 543 | − dev_dbg(dev, "failed to create nvdimm region\n"); | |
| 544 | − for (i--; i >= 0; i--) { | |
| 545 | − nvdimm = mappings[i].nvdimm; | |
| 546 | − cxl_nvd = nvdimm_provider_data(nvdimm); | |
| 547 | − put_device(&cxl_nvd->region->dev); | |
| 548 | − cxl_nvd->region = NULL; | |
| 549 | − } | |
| 550 | − goto out; | |
| 551 | 580 | } |
| 552 | 581 | |
| 553 | 582 | static struct cxl_driver cxl_pmem_region_driver = { |
| @@ -8,6 +8,13 @@ · 7 unmodified lines | ||
| 8 | 8 | static bool nohmem; |
| 9 | 9 | module_param_named(disable, nohmem, bool, 0444); |
| 10 | 10 | |
| 11 | +static struct resource hmem_active = { | |
| 12 | + .name = "HMEM devices", | |
| 13 | + .start = 0, | |
| 14 | + .end = -1, | |
| 15 | + .flags = IORESOURCE_MEM, | |
| 16 | +}; | |
| 17 | + | |
| 11 | 18 | void hmem_register_device(int target_nid, struct resource *r) |
| 12 | 19 | { |
| 13 | 20 | /* define a clean / non-busy resource for the platform device */ |
| @@ -41,6 +48,12 @@ void hmem_register_device(int target_nid, struct resource *r) · 27 unmodified lines | ||
| 41 | 48 | goto out_pdev; |
| 42 | 49 | } |
| 43 | 50 | |
| 51 | + if (!__request_region(&hmem_active, res.start, resource_size(&res), | |
| 52 | + dev_name(&pdev->dev), 0)) { | |
| 53 | + dev_dbg(&pdev->dev, "hmem range %pr already active\n", &res); | |
| 54 | + goto out_active; | |
| 55 | + } | |
| 56 | + | |
| 44 | 57 | pdev->dev.numa_node = numa_map_to_online_node(target_nid); |
| 45 | 58 | info = (struct memregion_info) { |
| 46 | 59 | .target_node = target_nid, |
| @@ -66,6 +79,8 @@ void hmem_register_device(int target_nid, struct resource *r) · 19 unmodified lines | ||
| 66 | 79 | return; |
| 67 | 80 | |
| 68 | 81 | out_resource: |
| 82 | + __release_region(&hmem_active, res.start, resource_size(&res)); | |
| 83 | +out_active: | |
| 69 | 84 | platform_device_put(pdev); |
| 70 | 85 | out_pdev: |
| 71 | 86 | memregion_free(id); |
| @@ -73,15 +88,6 @@ out_pdev: · 1 unmodified line | ||
| 73 | 88 | |
| 74 | 89 | static __init int hmem_register_one(struct resource *res, void *data) |
| 75 | 90 | { |
| 76 | − /* | |
| 77 | − * If the resource is not a top-level resource it was already | |
| 78 | − * assigned to a device by the HMAT parsing. | |
| 79 | − */ | |
| 80 | − if (res->parent != &iomem_resource) { | |
| 81 | − pr_info("HMEM: skip %pr, already claimed\n", res); | |
| 82 | − return 0; | |
| 83 | − } | |
| 84 | − | |
| 85 | 91 | hmem_register_device(phys_to_target_node(res->start), res); |
| 86 | 92 | |
| 87 | 93 | return 0; |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/slab.h> |
| 16 | 16 | #include <linux/dma-buf.h> |
| 17 | 17 | #include <linux/dma-fence.h> |
| 18 | +#include <linux/dma-fence-unwrap.h> | |
| 18 | 19 | #include <linux/anon_inodes.h> |
| 19 | 20 | #include <linux/export.h> |
| 20 | 21 | #include <linux/debugfs.h> |
| @@ -391,8 +392,10 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf, · 370 unmodified lines | ||
| 391 | 392 | const void __user *user_data) |
| 392 | 393 | { |
| 393 | 394 | struct dma_buf_import_sync_file arg; |
| 394 | − struct dma_fence *fence; | |
| 395 | + struct dma_fence *fence, *f; | |
| 395 | 396 | enum dma_resv_usage usage; |
| 397 | + struct dma_fence_unwrap iter; | |
| 398 | + unsigned int num_fences; | |
| 396 | 399 | int ret = 0; |
| 397 | 400 | |
| 398 | 401 | if (copy_from_user(&arg, user_data, sizeof(arg))) |
| @@ -411,13 +414,21 @@ static long dma_buf_import_sync_file(struct dma_buf *dmabuf, · 12 unmodified lines | ||
| 411 | 414 | usage = (arg.flags & DMA_BUF_SYNC_WRITE) ? DMA_RESV_USAGE_WRITE : |
| 412 | 415 | DMA_RESV_USAGE_READ; |
| 413 | 416 | |
| 414 | − dma_resv_lock(dmabuf->resv, NULL); | |
| 417 | + num_fences = 0; | |
| 418 | + dma_fence_unwrap_for_each(f, &iter, fence) | |
| 419 | + ++num_fences; | |
| 415 | 420 | |
| 416 | − ret = dma_resv_reserve_fences(dmabuf->resv, 1); | |
| 417 | − if (!ret) | |
| 418 | − dma_resv_add_fence(dmabuf->resv, fence, usage); | |
| 421 | + if (num_fences > 0) { | |
| 422 | + dma_resv_lock(dmabuf->resv, NULL); | |
| 419 | 423 | |
| 420 | − dma_resv_unlock(dmabuf->resv); | |
| 424 | + ret = dma_resv_reserve_fences(dmabuf->resv, num_fences); | |
| 425 | + if (!ret) { | |
| 426 | + dma_fence_unwrap_for_each(f, &iter, fence) | |
| 427 | + dma_resv_add_fence(dmabuf->resv, f, usage); | |
| 428 | + } | |
| 429 | + | |
| 430 | + dma_resv_unlock(dmabuf->resv); | |
| 431 | + } | |
| 421 | 432 | |
| 422 | 433 | dma_fence_put(fence); |
| 423 | 434 | |
| @@ -233,18 +233,6 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) · 232 unmodified lines | ||
| 233 | 233 | return ERR_PTR(-EINVAL); |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | − /* check the name is unique */ | |
| 237 | − mutex_lock(&heap_list_lock); | |
| 238 | − list_for_each_entry(h, &heap_list, list) { | |
| 239 | − if (!strcmp(h->name, exp_info->name)) { | |
| 240 | − mutex_unlock(&heap_list_lock); | |
| 241 | − pr_err("dma_heap: Already registered heap named %s\n", | |
| 242 | − exp_info->name); | |
| 243 | − return ERR_PTR(-EINVAL); | |
| 244 | − } | |
| 245 | − } | |
| 246 | − mutex_unlock(&heap_list_lock); | |
| 247 | − | |
| 248 | 236 | heap = kzalloc(sizeof(*heap), GFP_KERNEL); |
| 249 | 237 | if (!heap) |
| 250 | 238 | return ERR_PTR(-ENOMEM); |
| @@ -283,13 +271,27 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) · 32 unmodified lines | ||
| 283 | 271 | err_ret = ERR_CAST(dev_ret); |
| 284 | 272 | goto err2; |
| 285 | 273 | } |
| 286 | − /* Add heap to the list */ | |
| 274 | + | |
| 287 | 275 | mutex_lock(&heap_list_lock); |
| 276 | + /* check the name is unique */ | |
| 277 | + list_for_each_entry(h, &heap_list, list) { | |
| 278 | + if (!strcmp(h->name, exp_info->name)) { | |
| 279 | + mutex_unlock(&heap_list_lock); | |
| 280 | + pr_err("dma_heap: Already registered heap named %s\n", | |
| 281 | + exp_info->name); | |
| 282 | + err_ret = ERR_PTR(-EINVAL); | |
| 283 | + goto err3; | |
| 284 | + } | |
| 285 | + } | |
| 286 | + | |
| 287 | + /* Add heap to the list */ | |
| 288 | 288 | list_add(&heap->list, &heap_list); |
| 289 | 289 | mutex_unlock(&heap_list_lock); |
| 290 | 290 | |
| 291 | 291 | return heap; |
| 292 | 292 | |
| 293 | +err3: | |
| 294 | + device_destroy(dma_heap_class, heap->heap_devt); | |
| 293 | 295 | err2: |
| 294 | 296 | cdev_del(&heap->heap_cdev); |
| 295 | 297 | err1: |
| @@ -493,7 +493,7 @@ static struct dma_chan *admac_dma_of_xlate(struct of_phandle_args *dma_spec, · 492 unmodified lines | ||
| 493 | 493 | return NULL; |
| 494 | 494 | } |
| 495 | 495 | |
| 496 | − return &ad->channels[index].chan; | |
| 496 | + return dma_get_slave_channel(&ad->channels[index].chan); | |
| 497 | 497 | } |
| 498 | 498 | |
| 499 | 499 | static int admac_drain_reports(struct admac_data *ad, int channo) |
| @@ -256,6 +256,8 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first) · 255 unmodified lines | ||
| 256 | 256 | ATC_SPIP_BOUNDARY(first->boundary)); |
| 257 | 257 | channel_writel(atchan, DPIP, ATC_DPIP_HOLE(first->dst_hole) | |
| 258 | 258 | ATC_DPIP_BOUNDARY(first->boundary)); |
| 259 | + /* Don't allow CPU to reorder channel enable. */ | |
| 260 | + wmb(); | |
| 259 | 261 | dma_writel(atdma, CHER, atchan->mask); |
| 260 | 262 | |
| 261 | 263 | vdbg_dump_regs(atchan); |
| @@ -316,7 +318,8 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie) · 54 unmodified lines | ||
| 316 | 318 | struct at_desc *desc_first = atc_first_active(atchan); |
| 317 | 319 | struct at_desc *desc; |
| 318 | 320 | int ret; |
| 319 | − u32 ctrla, dscr, trials; | |
| 321 | + u32 ctrla, dscr; | |
| 322 | + unsigned int i; | |
| 320 | 323 | |
| 321 | 324 | /* |
| 322 | 325 | * If the cookie doesn't match to the currently running transfer then |
| @@ -386,7 +389,7 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie) · 63 unmodified lines | ||
| 386 | 389 | dscr = channel_readl(atchan, DSCR); |
| 387 | 390 | rmb(); /* ensure DSCR is read before CTRLA */ |
| 388 | 391 | ctrla = channel_readl(atchan, CTRLA); |
| 389 | − for (trials = 0; trials < ATC_MAX_DSCR_TRIALS; ++trials) { | |
| 392 | + for (i = 0; i < ATC_MAX_DSCR_TRIALS; ++i) { | |
| 390 | 393 | u32 new_dscr; |
| 391 | 394 | |
| 392 | 395 | rmb(); /* ensure DSCR is read after CTRLA */ |
| @@ -412,7 +415,7 @@ static int atc_get_bytes_left(struct dma_chan *chan, dma_cookie_t cookie) · 19 unmodified lines | ||
| 412 | 415 | rmb(); /* ensure DSCR is read before CTRLA */ |
| 413 | 416 | ctrla = channel_readl(atchan, CTRLA); |
| 414 | 417 | } |
| 415 | − if (unlikely(trials >= ATC_MAX_DSCR_TRIALS)) | |
| 418 | + if (unlikely(i == ATC_MAX_DSCR_TRIALS)) | |
| 416 | 419 | return -ETIMEDOUT; |
| 417 | 420 | |
| 418 | 421 | /* for the first descriptor we can be more accurate */ |
| @@ -462,18 +465,6 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) · 43 unmodified lines | ||
| 462 | 465 | if (!atc_chan_is_cyclic(atchan)) |
| 463 | 466 | dma_cookie_complete(txd); |
| 464 | 467 | |
| 465 | − /* If the transfer was a memset, free our temporary buffer */ | |
| 466 | − if (desc->memset_buffer) { | |
| 467 | − dma_pool_free(atdma->memset_pool, desc->memset_vaddr, | |
| 468 | − desc->memset_paddr); | |
| 469 | − desc->memset_buffer = false; | |
| 470 | − } | |
| 471 | − | |
| 472 | − /* move children to free_list */ | |
| 473 | − list_splice_init(&desc->tx_list, &atchan->free_list); | |
| 474 | − /* move myself to free_list */ | |
| 475 | − list_move(&desc->desc_node, &atchan->free_list); | |
| 476 | − | |
| 477 | 468 | spin_unlock_irqrestore(&atchan->lock, flags); |
| 478 | 469 | |
| 479 | 470 | dma_descriptor_unmap(txd); |
| @@ -483,42 +474,20 @@ atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc) · 3 unmodified lines | ||
| 483 | 474 | dmaengine_desc_get_callback_invoke(txd, NULL); |
| 484 | 475 | |
| 485 | 476 | dma_run_dependencies(txd); |
| 486 | −} | |
| 487 | − | |
| 488 | −/** | |
| 489 | − * atc_complete_all - finish work for all transactions | |
| 490 | − * @atchan: channel to complete transactions for | |
| 491 | − * | |
| 492 | − * Eventually submit queued descriptors if any | |
| 493 | − * | |
| 494 | − * Assume channel is idle while calling this function | |
| 495 | − * Called with atchan->lock held and bh disabled | |
| 496 | − */ | |
| 497 | −static void atc_complete_all(struct at_dma_chan *atchan) | |
| 498 | −{ | |
| 499 | − struct at_desc *desc, *_desc; | |
| 500 | − LIST_HEAD(list); | |
| 501 | − unsigned long flags; | |
| 502 | − | |
| 503 | − dev_vdbg(chan2dev(&atchan->chan_common), "complete all\n"); | |
| 504 | 477 | |
| 505 | 478 | spin_lock_irqsave(&atchan->lock, flags); |
| 506 | − | |
| 507 | − /* | |
| 508 | − * Submit queued descriptors ASAP, i.e. before we go through | |
| 509 | − * the completed ones. | |
| 510 | − */ | |
| 511 | − if (!list_empty(&atchan->queue)) | |
| 512 | − atc_dostart(atchan, atc_first_queued(atchan)); | |
| 513 | − /* empty active_list now it is completed */ | |
| 514 | − list_splice_init(&atchan->active_list, &list); | |
| 515 | − /* empty queue list by moving descriptors (if any) to active_list */ | |
| 516 | − list_splice_init(&atchan->queue, &atchan->active_list); | |
| 517 | − | |
| 479 | + /* move children to free_list */ | |
| 480 | + list_splice_init(&desc->tx_list, &atchan->free_list); | |
| 481 | + /* add myself to free_list */ | |
| 482 | + list_add(&desc->desc_node, &atchan->free_list); | |
| 518 | 483 | spin_unlock_irqrestore(&atchan->lock, flags); |
| 519 | 484 | |
| 520 | − list_for_each_entry_safe(desc, _desc, &list, desc_node) | |
| 521 | − atc_chain_complete(atchan, desc); | |
| 485 | + /* If the transfer was a memset, free our temporary buffer */ | |
| 486 | + if (desc->memset_buffer) { | |
| 487 | + dma_pool_free(atdma->memset_pool, desc->memset_vaddr, | |
| 488 | + desc->memset_paddr); | |
| 489 | + desc->memset_buffer = false; | |
| 490 | + } | |
| 522 | 491 | } |
| 523 | 492 | |
| 524 | 493 | /** |
| @@ -527,26 +496,28 @@ static void atc_complete_all(struct at_dma_chan *atchan) · 2 unmodified lines | ||
| 527 | 496 | */ |
| 528 | 497 | static void atc_advance_work(struct at_dma_chan *atchan) |
| 529 | 498 | { |
| 499 | + struct at_desc *desc; | |
| 530 | 500 | unsigned long flags; |
| 531 | − int ret; | |
| 532 | 501 | |
| 533 | 502 | dev_vdbg(chan2dev(&atchan->chan_common), "advance_work\n"); |
| 534 | 503 | |
| 535 | 504 | spin_lock_irqsave(&atchan->lock, flags); |
| 536 | − ret = atc_chan_is_enabled(atchan); | |
| 537 | − spin_unlock_irqrestore(&atchan->lock, flags); | |
| 538 | − if (ret) | |
| 539 | − return; | |
| 540 | − | |
| 541 | − if (list_empty(&atchan->active_list) || | |
| 542 | − list_is_singular(&atchan->active_list)) | |
| 543 | − return atc_complete_all(atchan); | |
| 505 | + if (atc_chan_is_enabled(atchan) || list_empty(&atchan->active_list)) | |
| 506 | + return spin_unlock_irqrestore(&atchan->lock, flags); | |
| 544 | 507 | |
| 545 | − atc_chain_complete(atchan, atc_first_active(atchan)); | |
| 508 | + desc = atc_first_active(atchan); | |
| 509 | + /* Remove the transfer node from the active list. */ | |
| 510 | + list_del_init(&desc->desc_node); | |
| 511 | + spin_unlock_irqrestore(&atchan->lock, flags); | |
| 512 | + atc_chain_complete(atchan, desc); | |
| 546 | 513 | |
| 547 | 514 | /* advance work */ |
| 548 | 515 | spin_lock_irqsave(&atchan->lock, flags); |
| 549 | − atc_dostart(atchan, atc_first_active(atchan)); | |
| 516 | + if (!list_empty(&atchan->active_list)) { | |
| 517 | + desc = atc_first_queued(atchan); | |
| 518 | + list_move_tail(&desc->desc_node, &atchan->active_list); | |
| 519 | + atc_dostart(atchan, desc); | |
| 520 | + } | |
| 550 | 521 | spin_unlock_irqrestore(&atchan->lock, flags); |
| 551 | 522 | } |
| 552 | 523 | |
| @@ -558,6 +529,7 @@ static void atc_advance_work(struct at_dma_chan *atchan) · 5 unmodified lines | ||
| 558 | 529 | static void atc_handle_error(struct at_dma_chan *atchan) |
| 559 | 530 | { |
| 560 | 531 | struct at_desc *bad_desc; |
| 532 | + struct at_desc *desc; | |
| 561 | 533 | struct at_desc *child; |
| 562 | 534 | unsigned long flags; |
| 563 | 535 | |
| @@ -570,13 +542,12 @@ static void atc_handle_error(struct at_dma_chan *atchan) · 6 unmodified lines | ||
| 570 | 542 | bad_desc = atc_first_active(atchan); |
| 571 | 543 | list_del_init(&bad_desc->desc_node); |
| 572 | 544 | |
| 573 | − /* As we are stopped, take advantage to push queued descriptors | |
| 574 | − * in active_list */ | |
| 575 | − list_splice_init(&atchan->queue, atchan->active_list.prev); | |
| 576 | − | |
| 577 | 545 | /* Try to restart the controller */ |
| 578 | − if (!list_empty(&atchan->active_list)) | |
| 579 | − atc_dostart(atchan, atc_first_active(atchan)); | |
| 546 | + if (!list_empty(&atchan->active_list)) { | |
| 547 | + desc = atc_first_queued(atchan); | |
| 548 | + list_move_tail(&desc->desc_node, &atchan->active_list); | |
| 549 | + atc_dostart(atchan, desc); | |
| 550 | + } | |
| 580 | 551 | |
| 581 | 552 | /* |
| 582 | 553 | * KERN_CRITICAL may seem harsh, but since this only happens |
| @@ -691,19 +662,11 @@ static dma_cookie_t atc_tx_submit(struct dma_async_tx_descriptor *tx) · 108 unmodified lines | ||
| 691 | 662 | spin_lock_irqsave(&atchan->lock, flags); |
| 692 | 663 | cookie = dma_cookie_assign(tx); |
| 693 | 664 | |
| 694 | − if (list_empty(&atchan->active_list)) { | |
| 695 | − dev_vdbg(chan2dev(tx->chan), "tx_submit: started %u\n", | |
| 696 | − desc->txd.cookie); | |
| 697 | − atc_dostart(atchan, desc); | |
| 698 | − list_add_tail(&desc->desc_node, &atchan->active_list); | |
| 699 | − } else { | |
| 700 | − dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n", | |
| 701 | − desc->txd.cookie); | |
| 702 | − list_add_tail(&desc->desc_node, &atchan->queue); | |
| 703 | − } | |
| 704 | − | |
| 665 | + list_add_tail(&desc->desc_node, &atchan->queue); | |
| 705 | 666 | spin_unlock_irqrestore(&atchan->lock, flags); |
| 706 | 667 | |
| 668 | + dev_vdbg(chan2dev(tx->chan), "tx_submit: queued %u\n", | |
| 669 | + desc->txd.cookie); | |
| 707 | 670 | return cookie; |
| 708 | 671 | } |
| 709 | 672 | |
| @@ -1445,11 +1408,8 @@ static int atc_terminate_all(struct dma_chan *chan) · 735 unmodified lines | ||
| 1445 | 1408 | struct at_dma_chan *atchan = to_at_dma_chan(chan); |
| 1446 | 1409 | struct at_dma *atdma = to_at_dma(chan->device); |
| 1447 | 1410 | int chan_id = atchan->chan_common.chan_id; |
| 1448 | − struct at_desc *desc, *_desc; | |
| 1449 | 1411 | unsigned long flags; |
| 1450 | 1412 | |
| 1451 | − LIST_HEAD(list); | |
| 1452 | − | |
| 1453 | 1413 | dev_vdbg(chan2dev(chan), "%s\n", __func__); |
| 1454 | 1414 | |
| 1455 | 1415 | /* |
| @@ -1468,19 +1428,15 @@ static int atc_terminate_all(struct dma_chan *chan) · 12 unmodified lines | ||
| 1468 | 1428 | cpu_relax(); |
| 1469 | 1429 | |
| 1470 | 1430 | /* active_list entries will end up before queued entries */ |
| 1471 | − list_splice_init(&atchan->queue, &list); | |
| 1472 | − list_splice_init(&atchan->active_list, &list); | |
| 1473 | − | |
| 1474 | − spin_unlock_irqrestore(&atchan->lock, flags); | |
| 1475 | − | |
| 1476 | − /* Flush all pending and queued descriptors */ | |
| 1477 | − list_for_each_entry_safe(desc, _desc, &list, desc_node) | |
| 1478 | − atc_chain_complete(atchan, desc); | |
| 1431 | + list_splice_tail_init(&atchan->queue, &atchan->free_list); | |
| 1432 | + list_splice_tail_init(&atchan->active_list, &atchan->free_list); | |
| 1479 | 1433 | |
| 1480 | 1434 | clear_bit(ATC_IS_PAUSED, &atchan->status); |
| 1481 | 1435 | /* if channel dedicated to cyclic operations, free it */ |
| 1482 | 1436 | clear_bit(ATC_IS_CYCLIC, &atchan->status); |
| 1483 | 1437 | |
| 1438 | + spin_unlock_irqrestore(&atchan->lock, flags); | |
| 1439 | + | |
| 1484 | 1440 | return 0; |
| 1485 | 1441 | } |
| 1486 | 1442 | |
| @@ -1535,20 +1491,26 @@ atc_tx_status(struct dma_chan *chan, · 48 unmodified lines | ||
| 1535 | 1491 | } |
| 1536 | 1492 | |
| 1537 | 1493 | /** |
| 1538 | − * atc_issue_pending - try to finish work | |
| 1494 | + * atc_issue_pending - takes the first transaction descriptor in the pending | |
| 1495 | + * queue and starts the transfer. | |
| 1539 | 1496 | * @chan: target DMA channel |
| 1540 | 1497 | */ |
| 1541 | 1498 | static void atc_issue_pending(struct dma_chan *chan) |
| 1542 | 1499 | { |
| 1543 | − struct at_dma_chan *atchan = to_at_dma_chan(chan); | |
| 1500 | + struct at_dma_chan *atchan = to_at_dma_chan(chan); | |
| 1501 | + struct at_desc *desc; | |
| 1502 | + unsigned long flags; | |
| 1544 | 1503 | |
| 1545 | 1504 | dev_vdbg(chan2dev(chan), "issue_pending\n"); |
| 1546 | 1505 | |
| 1547 | − /* Not needed for cyclic transfers */ | |
| 1548 | − if (atc_chan_is_cyclic(atchan)) | |
| 1549 | − return; | |
| 1506 | + spin_lock_irqsave(&atchan->lock, flags); | |
| 1507 | + if (atc_chan_is_enabled(atchan) || list_empty(&atchan->queue)) | |
| 1508 | + return spin_unlock_irqrestore(&atchan->lock, flags); | |
| 1550 | 1509 | |
| 1551 | − atc_advance_work(atchan); | |
| 1510 | + desc = atc_first_queued(atchan); | |
| 1511 | + list_move_tail(&desc->desc_node, &atchan->active_list); | |
| 1512 | + atc_dostart(atchan, desc); | |
| 1513 | + spin_unlock_irqrestore(&atchan->lock, flags); | |
| 1552 | 1514 | } |
| 1553 | 1515 | |
| 1554 | 1516 | /** |
| @@ -1966,7 +1928,11 @@ static int __init at_dma_probe(struct platform_device *pdev) · 411 unmodified lines | ||
| 1966 | 1928 | dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ? "slave " : "", |
| 1967 | 1929 | plat_dat->nr_channels); |
| 1968 | 1930 | |
| 1969 | − dma_async_device_register(&atdma->dma_common); | |
| 1931 | + err = dma_async_device_register(&atdma->dma_common); | |
| 1932 | + if (err) { | |
| 1933 | + dev_err(&pdev->dev, "Unable to register: %d.\n", err); | |
| 1934 | + goto err_dma_async_device_register; | |
| 1935 | + } | |
| 1970 | 1936 | |
| 1971 | 1937 | /* |
| 1972 | 1938 | * Do not return an error if the dmac node is not present in order to |
| @@ -1986,6 +1952,7 @@ static int __init at_dma_probe(struct platform_device *pdev) · 13 unmodified lines | ||
| 1986 | 1952 | |
| 1987 | 1953 | err_of_dma_controller_register: |
| 1988 | 1954 | dma_async_device_unregister(&atdma->dma_common); |
| 1955 | +err_dma_async_device_register: | |
| 1989 | 1956 | dma_pool_destroy(atdma->memset_pool); |
| 1990 | 1957 | err_memset_pool_create: |
| 1991 | 1958 | dma_pool_destroy(atdma->dma_desc_pool); |
| @@ -186,13 +186,13 @@ · 185 unmodified lines | ||
| 186 | 186 | /* LLI == Linked List Item; aka DMA buffer descriptor */ |
| 187 | 187 | struct at_lli { |
| 188 | 188 | /* values that are not changed by hardware */ |
| 189 | − dma_addr_t saddr; | |
| 190 | − dma_addr_t daddr; | |
| 189 | + u32 saddr; | |
| 190 | + u32 daddr; | |
| 191 | 191 | /* value that may get written back: */ |
| 192 | − u32 ctrla; | |
| 192 | + u32 ctrla; | |
| 193 | 193 | /* more values that are not changed by hardware */ |
| 194 | − u32 ctrlb; | |
| 195 | − dma_addr_t dscr; /* chain to next lli */ | |
| 194 | + u32 ctrlb; | |
| 195 | + u32 dscr; /* chain to next lli */ | |
| 196 | 196 | }; |
| 197 | 197 | |
| 198 | 198 | /** |
| @@ -312,6 +312,24 @@ static int idxd_user_drv_probe(struct idxd_dev *idxd_dev) · 311 unmodified lines | ||
| 312 | 312 | if (idxd->state != IDXD_DEV_ENABLED) |
| 313 | 313 | return -ENXIO; |
| 314 | 314 | |
| 315 | + /* | |
| 316 | + * User type WQ is enabled only when SVA is enabled for two reasons: | |
| 317 | + * - If no IOMMU or IOMMU Passthrough without SVA, userspace | |
| 318 | + * can directly access physical address through the WQ. | |
| 319 | + * - The IDXD cdev driver does not provide any ways to pin | |
| 320 | + * user pages and translate the address from user VA to IOVA or | |
| 321 | + * PA without IOMMU SVA. Therefore the application has no way | |
| 322 | + * to instruct the device to perform DMA function. This makes | |
| 323 | + * the cdev not usable for normal application usage. | |
| 324 | + */ | |
| 325 | + if (!device_user_pasid_enabled(idxd)) { | |
| 326 | + idxd->cmd_status = IDXD_SCMD_WQ_USER_NO_IOMMU; | |
| 327 | + dev_dbg(&idxd->pdev->dev, | |
| 328 | + "User type WQ cannot be enabled without SVA.\n"); | |
| 329 | + | |
| 330 | + return -EOPNOTSUPP; | |
| 331 | + } | |
| 332 | + | |
| 315 | 333 | mutex_lock(&wq->wq_lock); |
| 316 | 334 | wq->type = IDXD_WQT_USER; |
| 317 | 335 | rc = drv_enable_wq(wq); |
| @@ -390,7 +390,7 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq) · 389 unmodified lines | ||
| 390 | 390 | clear_bit(WQ_FLAG_ATS_DISABLE, &wq->flags); |
| 391 | 391 | memset(wq->name, 0, WQ_NAME_SIZE); |
| 392 | 392 | wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER; |
| 393 | − wq->max_batch_size = WQ_DEFAULT_MAX_BATCH; | |
| 393 | + idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH); | |
| 394 | 394 | if (wq->opcap_bmap) |
| 395 | 395 | bitmap_copy(wq->opcap_bmap, idxd->opcap_bmap, IDXD_MAX_OPCAP_BITS); |
| 396 | 396 | } |
| @@ -730,13 +730,21 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd) · 333 unmodified lines | ||
| 730 | 730 | |
| 731 | 731 | void idxd_device_clear_state(struct idxd_device *idxd) |
| 732 | 732 | { |
| 733 | − if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) | |
| 734 | − return; | |
| 733 | + /* IDXD is always disabled. Other states are cleared only when IDXD is configurable. */ | |
| 734 | + if (test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) { | |
| 735 | + /* | |
| 736 | + * Clearing wq state is protected by wq lock. | |
| 737 | + * So no need to be protected by device lock. | |
| 738 | + */ | |
| 739 | + idxd_device_wqs_clear_state(idxd); | |
| 740 | + | |
| 741 | + spin_lock(&idxd->dev_lock); | |
| 742 | + idxd_groups_clear_state(idxd); | |
| 743 | + idxd_engines_clear_state(idxd); | |
| 744 | + } else { | |
| 745 | + spin_lock(&idxd->dev_lock); | |
| 746 | + } | |
| 735 | 747 | |
| 736 | − idxd_device_wqs_clear_state(idxd); | |
| 737 | − spin_lock(&idxd->dev_lock); | |
| 738 | − idxd_groups_clear_state(idxd); | |
| 739 | − idxd_engines_clear_state(idxd); | |
| 740 | 748 | idxd->state = IDXD_DEV_DISABLED; |
| 741 | 749 | spin_unlock(&idxd->dev_lock); |
| 742 | 750 | } |
| @@ -869,7 +877,7 @@ static int idxd_wq_config_write(struct idxd_wq *wq) · 126 unmodified lines | ||
| 869 | 877 | |
| 870 | 878 | /* bytes 12-15 */ |
| 871 | 879 | wq->wqcfg->max_xfer_shift = ilog2(wq->max_xfer_bytes); |
| 872 | − wq->wqcfg->max_batch_shift = ilog2(wq->max_batch_size); | |
| 880 | + idxd_wqcfg_set_max_batch_shift(idxd->data->type, wq->wqcfg, ilog2(wq->max_batch_size)); | |
| 873 | 881 | |
| 874 | 882 | /* bytes 32-63 */ |
| 875 | 883 | if (idxd->hw.wq_cap.op_config && wq->opcap_bmap) { |
| @@ -1051,7 +1059,7 @@ static int idxd_wq_load_config(struct idxd_wq *wq) · 175 unmodified lines | ||
| 1051 | 1059 | wq->priority = wq->wqcfg->priority; |
| 1052 | 1060 | |
| 1053 | 1061 | wq->max_xfer_bytes = 1ULL << wq->wqcfg->max_xfer_shift; |
| 1054 | − wq->max_batch_size = 1ULL << wq->wqcfg->max_batch_shift; | |
| 1062 | + idxd_wq_set_max_batch_size(idxd->data->type, wq, 1U << wq->wqcfg->max_batch_shift); | |
| 1055 | 1063 | |
| 1056 | 1064 | for (i = 0; i < WQCFG_STRIDES(idxd); i++) { |
| 1057 | 1065 | wqcfg_offset = WQCFG_OFFSET(idxd, wq->id, i); |
| @@ -548,6 +548,38 @@ static inline int idxd_wq_refcount(struct idxd_wq *wq) · 547 unmodified lines | ||
| 548 | 548 | return wq->client_count; |
| 549 | 549 | }; |
| 550 | 550 | |
| 551 | +/* | |
| 552 | + * Intel IAA does not support batch processing. | |
| 553 | + * The max batch size of device, max batch size of wq and | |
| 554 | + * max batch shift of wqcfg should be always 0 on IAA. | |
| 555 | + */ | |
| 556 | +static inline void idxd_set_max_batch_size(int idxd_type, struct idxd_device *idxd, | |
| 557 | + u32 max_batch_size) | |
| 558 | +{ | |
| 559 | + if (idxd_type == IDXD_TYPE_IAX) | |
| 560 | + idxd->max_batch_size = 0; | |
| 561 | + else | |
| 562 | + idxd->max_batch_size = max_batch_size; | |
| 563 | +} | |
| 564 | + | |
| 565 | +static inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq, | |
| 566 | + u32 max_batch_size) | |
| 567 | +{ | |
| 568 | + if (idxd_type == IDXD_TYPE_IAX) | |
| 569 | + wq->max_batch_size = 0; | |
| 570 | + else | |
| 571 | + wq->max_batch_size = max_batch_size; | |
| 572 | +} | |
| 573 | + | |
| 574 | +static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg, | |
| 575 | + u32 max_batch_shift) | |
| 576 | +{ | |
| 577 | + if (idxd_type == IDXD_TYPE_IAX) | |
| 578 | + wqcfg->max_batch_shift = 0; | |
| 579 | + else | |
| 580 | + wqcfg->max_batch_shift = max_batch_shift; | |
| 581 | +} | |
| 582 | + | |
| 551 | 583 | int __must_check __idxd_driver_register(struct idxd_device_driver *idxd_drv, |
| 552 | 584 | struct module *module, const char *mod_name); |
| 553 | 585 | #define idxd_driver_register(driver) \ |
| @@ -183,7 +183,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd) · 182 unmodified lines | ||
| 183 | 183 | init_completion(&wq->wq_dead); |
| 184 | 184 | init_completion(&wq->wq_resurrect); |
| 185 | 185 | wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER; |
| 186 | − wq->max_batch_size = WQ_DEFAULT_MAX_BATCH; | |
| 186 | + idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH); | |
| 187 | 187 | wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES; |
| 188 | 188 | wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev)); |
| 189 | 189 | if (!wq->wqcfg) { |
| @@ -418,7 +418,7 @@ static void idxd_read_caps(struct idxd_device *idxd) · 228 unmodified lines | ||
| 418 | 418 | |
| 419 | 419 | idxd->max_xfer_bytes = 1ULL << idxd->hw.gen_cap.max_xfer_shift; |
| 420 | 420 | dev_dbg(dev, "max xfer size: %llu bytes\n", idxd->max_xfer_bytes); |
| 421 | − idxd->max_batch_size = 1U << idxd->hw.gen_cap.max_batch_shift; | |
| 421 | + idxd_set_max_batch_size(idxd->data->type, idxd, 1U << idxd->hw.gen_cap.max_batch_shift); | |
| 422 | 422 | dev_dbg(dev, "max batch size: %u\n", idxd->max_batch_size); |
| 423 | 423 | if (idxd->hw.gen_cap.config_en) |
| 424 | 424 | set_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags); |
| @@ -1046,7 +1046,7 @@ static ssize_t wq_max_batch_size_store(struct device *dev, struct device_attribu · 1045 unmodified lines | ||
| 1046 | 1046 | if (batch_size > idxd->max_batch_size) |
| 1047 | 1047 | return -EINVAL; |
| 1048 | 1048 | |
| 1049 | − wq->max_batch_size = (u32)batch_size; | |
| 1049 | + idxd_wq_set_max_batch_size(idxd->data->type, wq, (u32)batch_size); | |
| 1050 | 1050 | |
| 1051 | 1051 | return count; |
| 1052 | 1052 | } |
| @@ -893,6 +893,7 @@ static int mv_xor_v2_remove(struct platform_device *pdev) · 892 unmodified lines | ||
| 893 | 893 | tasklet_kill(&xor_dev->irq_tasklet); |
| 894 | 894 | |
| 895 | 895 | clk_disable_unprepare(xor_dev->clk); |
| 896 | + clk_disable_unprepare(xor_dev->reg_clk); | |
| 896 | 897 | |
| 897 | 898 | return 0; |
| 898 | 899 | } |
| @@ -1247,14 +1247,14 @@ static int pxad_init_phys(struct platform_device *op, · 1246 unmodified lines | ||
| 1247 | 1247 | return -ENOMEM; |
| 1248 | 1248 | |
| 1249 | 1249 | for (i = 0; i < nb_phy_chans; i++) |
| 1250 | − if (platform_get_irq(op, i) > 0) | |
| 1250 | + if (platform_get_irq_optional(op, i) > 0) | |
| 1251 | 1251 | nr_irq++; |
| 1252 | 1252 | |
| 1253 | 1253 | for (i = 0; i < nb_phy_chans; i++) { |
| 1254 | 1254 | phy = &pdev->phys[i]; |
| 1255 | 1255 | phy->base = pdev->base; |
| 1256 | 1256 | phy->idx = i; |
| 1257 | − irq = platform_get_irq(op, i); | |
| 1257 | + irq = platform_get_irq_optional(op, i); | |
| 1258 | 1258 | if ((nr_irq > 1) && (irq > 0)) |
| 1259 | 1259 | ret = devm_request_irq(&op->dev, irq, |
| 1260 | 1260 | pxad_chan_handler, |
| @@ -675,6 +675,8 @@ static void stm32_dma_handle_chan_paused(struct stm32_dma_chan *chan) · 674 unmodified lines | ||
| 675 | 675 | |
| 676 | 676 | chan->chan_reg.dma_sndtr = stm32_dma_read(dmadev, STM32_DMA_SNDTR(chan->id)); |
| 677 | 677 | |
| 678 | + chan->status = DMA_PAUSED; | |
| 679 | + | |
| 678 | 680 | dev_dbg(chan2dev(chan), "vchan %pK: paused\n", &chan->vchan); |
| 679 | 681 | } |
| 680 | 682 | |
| @@ -789,9 +791,7 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid) · 108 unmodified lines | ||
| 789 | 791 | if (status & STM32_DMA_TCI) { |
| 790 | 792 | stm32_dma_irq_clear(chan, STM32_DMA_TCI); |
| 791 | 793 | if (scr & STM32_DMA_SCR_TCIE) { |
| 792 | − if (chan->status == DMA_PAUSED && !(scr & STM32_DMA_SCR_EN)) | |
| 793 | − stm32_dma_handle_chan_paused(chan); | |
| 794 | − else | |
| 794 | + if (chan->status != DMA_PAUSED) | |
| 795 | 795 | stm32_dma_handle_chan_done(chan, scr); |
| 796 | 796 | } |
| 797 | 797 | status &= ~STM32_DMA_TCI; |
| @@ -838,13 +838,11 @@ static int stm32_dma_pause(struct dma_chan *c) · 40 unmodified lines | ||
| 838 | 838 | return -EPERM; |
| 839 | 839 | |
| 840 | 840 | spin_lock_irqsave(&chan->vchan.lock, flags); |
| 841 | + | |
| 841 | 842 | ret = stm32_dma_disable_chan(chan); |
| 842 | − /* | |
| 843 | − * A transfer complete flag is set to indicate the end of transfer due to the stream | |
| 844 | − * interruption, so wait for interrupt | |
| 845 | − */ | |
| 846 | 843 | if (!ret) |
| 847 | − chan->status = DMA_PAUSED; | |
| 844 | + stm32_dma_handle_chan_paused(chan); | |
| 845 | + | |
| 848 | 846 | spin_unlock_irqrestore(&chan->vchan.lock, flags); |
| 849 | 847 | |
| 850 | 848 | return ret; |
| @@ -1539,6 +1539,7 @@ static struct dma_chan *stm32_mdma_of_xlate(struct of_phandle_args *dma_spec, · 1538 unmodified lines | ||
| 1539 | 1539 | return NULL; |
| 1540 | 1540 | } |
| 1541 | 1541 | |
| 1542 | + memset(&config, 0, sizeof(config)); | |
| 1542 | 1543 | config.request = dma_spec->args[0]; |
| 1543 | 1544 | config.priority_level = dma_spec->args[1]; |
| 1544 | 1545 | config.transfer_config = dma_spec->args[2]; |
| @@ -299,6 +299,7 @@ struct k3_udma_glue_tx_channel *k3_udma_glue_request_tx_chn(struct device *dev, · 298 unmodified lines | ||
| 299 | 299 | ret = device_register(&tx_chn->common.chan_dev); |
| 300 | 300 | if (ret) { |
| 301 | 301 | dev_err(dev, "Channel Device registration failed %d\n", ret); |
| 302 | + put_device(&tx_chn->common.chan_dev); | |
| 302 | 303 | tx_chn->common.chan_dev.parent = NULL; |
| 303 | 304 | goto err; |
| 304 | 305 | } |
| @@ -917,6 +918,7 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, const char *name, · 612 unmodified lines | ||
| 917 | 918 | ret = device_register(&rx_chn->common.chan_dev); |
| 918 | 919 | if (ret) { |
| 919 | 920 | dev_err(dev, "Channel Device registration failed %d\n", ret); |
| 921 | + put_device(&rx_chn->common.chan_dev); | |
| 920 | 922 | rx_chn->common.chan_dev.parent = NULL; |
| 921 | 923 | goto err; |
| 922 | 924 | } |
| @@ -1048,6 +1050,7 @@ k3_udma_glue_request_remote_rx_chn(struct device *dev, const char *name, · 125 unmodified lines | ||
| 1048 | 1050 | ret = device_register(&rx_chn->common.chan_dev); |
| 1049 | 1051 | if (ret) { |
| 1050 | 1052 | dev_err(dev, "Channel Device registration failed %d\n", ret); |
| 1053 | + put_device(&rx_chn->common.chan_dev); | |
| 1051 | 1054 | rx_chn->common.chan_dev.parent = NULL; |
| 1052 | 1055 | goto err; |
| 1053 | 1056 | } |
| @@ -327,7 +327,13 @@ static irqreturn_t tusb320_irq_handler(int irq, void *dev_id) · 326 unmodified lines | ||
| 327 | 327 | return IRQ_NONE; |
| 328 | 328 | |
| 329 | 329 | tusb320_extcon_irq_handler(priv, reg); |
| 330 | − tusb320_typec_irq_handler(priv, reg); | |
| 330 | + | |
| 331 | + /* | |
| 332 | + * Type-C support is optional. Only call the Type-C handler if a | |
| 333 | + * port had been registered previously. | |
| 334 | + */ | |
| 335 | + if (priv->port) | |
| 336 | + tusb320_typec_irq_handler(priv, reg); | |
| 331 | 337 | |
| 332 | 338 | regmap_write(priv->regmap, TUSB320_REG9, reg); |
| 333 | 339 | |
| @@ -216,9 +216,20 @@ void scmi_device_destroy(struct scmi_device *scmi_dev) · 215 unmodified lines | ||
| 216 | 216 | device_unregister(&scmi_dev->dev); |
| 217 | 217 | } |
| 218 | 218 | |
| 219 | +void scmi_device_link_add(struct device *consumer, struct device *supplier) | |
| 220 | +{ | |
| 221 | + struct device_link *link; | |
| 222 | + | |
| 223 | + link = device_link_add(consumer, supplier, DL_FLAG_AUTOREMOVE_CONSUMER); | |
| 224 | + | |
| 225 | + WARN_ON(!link); | |
| 226 | +} | |
| 227 | + | |
| 219 | 228 | void scmi_set_handle(struct scmi_device *scmi_dev) |
| 220 | 229 | { |
| 221 | 230 | scmi_dev->handle = scmi_handle_get(&scmi_dev->dev); |
| 231 | + if (scmi_dev->handle) | |
| 232 | + scmi_device_link_add(&scmi_dev->dev, scmi_dev->handle->dev); | |
| 222 | 233 | } |
| 223 | 234 | |
| 224 | 235 | int scmi_protocol_register(const struct scmi_protocol *proto) |
| @@ -97,6 +97,7 @@ static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr) · 96 unmodified lines | ||
| 97 | 97 | struct scmi_revision_info * |
| 98 | 98 | scmi_revision_area_get(const struct scmi_protocol_handle *ph); |
| 99 | 99 | int scmi_handle_put(const struct scmi_handle *handle); |
| 100 | +void scmi_device_link_add(struct device *consumer, struct device *supplier); | |
| 100 | 101 | struct scmi_handle *scmi_handle_get(struct device *dev); |
| 101 | 102 | void scmi_set_handle(struct scmi_device *scmi_dev); |
| 102 | 103 | void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph, |
| @@ -117,6 +118,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id); · 14 unmodified lines | ||
| 117 | 118 | * |
| 118 | 119 | * @dev: Reference to device in the SCMI hierarchy corresponding to this |
| 119 | 120 | * channel |
| 121 | + * @rx_timeout_ms: The configured RX timeout in milliseconds. | |
| 120 | 122 | * @handle: Pointer to SCMI entity handle |
| 121 | 123 | * @no_completion_irq: Flag to indicate that this channel has no completion |
| 122 | 124 | * interrupt mechanism for synchronous commands. |
| @@ -126,6 +128,7 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id); · 3 unmodified lines | ||
| 126 | 128 | */ |
| 127 | 129 | struct scmi_chan_info { |
| 128 | 130 | struct device *dev; |
| 131 | + unsigned int rx_timeout_ms; | |
| 129 | 132 | struct scmi_handle *handle; |
| 130 | 133 | bool no_completion_irq; |
| 131 | 134 | void *transport_info; |
| @@ -232,7 +235,7 @@ void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id); · 100 unmodified lines | ||
| 232 | 235 | struct scmi_shared_mem; |
| 233 | 236 | |
| 234 | 237 | void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem, |
| 235 | − struct scmi_xfer *xfer); | |
| 238 | + struct scmi_xfer *xfer, struct scmi_chan_info *cinfo); | |
| 236 | 239 | u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem); |
| 237 | 240 | void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, |
| 238 | 241 | struct scmi_xfer *xfer); |
| @@ -2013,6 +2013,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev, · 2012 unmodified lines | ||
| 2013 | 2013 | return -ENOMEM; |
| 2014 | 2014 | |
| 2015 | 2015 | cinfo->dev = dev; |
| 2016 | + cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms; | |
| 2016 | 2017 | |
| 2017 | 2018 | ret = info->desc->ops->chan_setup(cinfo, info->dev, tx); |
| 2018 | 2019 | if (ret) |
| @@ -2044,8 +2045,12 @@ scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id) · 25 unmodified lines | ||
| 2044 | 2045 | { |
| 2045 | 2046 | int ret = scmi_chan_setup(info, dev, prot_id, true); |
| 2046 | 2047 | |
| 2047 | − if (!ret) /* Rx is optional, hence no error check */ | |
| 2048 | − scmi_chan_setup(info, dev, prot_id, false); | |
| 2048 | + if (!ret) { | |
| 2049 | + /* Rx is optional, report only memory errors */ | |
| 2050 | + ret = scmi_chan_setup(info, dev, prot_id, false); | |
| 2051 | + if (ret && ret != -ENOMEM) | |
| 2052 | + ret = 0; | |
| 2053 | + } | |
| 2049 | 2054 | |
| 2050 | 2055 | return ret; |
| 2051 | 2056 | } |
| @@ -2273,10 +2278,16 @@ int scmi_protocol_device_request(const struct scmi_device_id *id_table) · 221 unmodified lines | ||
| 2273 | 2278 | sdev = scmi_get_protocol_device(child, info, |
| 2274 | 2279 | id_table->protocol_id, |
| 2275 | 2280 | id_table->name); |
| 2276 | − /* Set handle if not already set: device existed */ | |
| 2277 | − if (sdev && !sdev->handle) | |
| 2278 | − sdev->handle = | |
| 2279 | − scmi_handle_get_from_info_unlocked(info); | |
| 2281 | + if (sdev) { | |
| 2282 | + /* Set handle if not already set: device existed */ | |
| 2283 | + if (!sdev->handle) | |
| 2284 | + sdev->handle = | |
| 2285 | + scmi_handle_get_from_info_unlocked(info); | |
| 2286 | + /* Relink consumer and suppliers */ | |
| 2287 | + if (sdev->handle) | |
| 2288 | + scmi_device_link_add(&sdev->dev, | |
| 2289 | + sdev->handle->dev); | |
| 2290 | + } | |
| 2280 | 2291 | } else { |
| 2281 | 2292 | dev_err(info->dev, |
| 2282 | 2293 | "Failed. SCMI protocol %d not active.\n", |
| @@ -2475,20 +2486,17 @@ void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id) · 192 unmodified lines | ||
| 2475 | 2486 | |
| 2476 | 2487 | static int scmi_remove(struct platform_device *pdev) |
| 2477 | 2488 | { |
| 2478 | − int ret = 0, id; | |
| 2489 | + int ret, id; | |
| 2479 | 2490 | struct scmi_info *info = platform_get_drvdata(pdev); |
| 2480 | 2491 | struct device_node *child; |
| 2481 | 2492 | |
| 2482 | 2493 | mutex_lock(&scmi_list_mutex); |
| 2483 | 2494 | if (info->users) |
| 2484 | − ret = -EBUSY; | |
| 2485 | − else | |
| 2486 | − list_del(&info->node); | |
| 2495 | + dev_warn(&pdev->dev, | |
| 2496 | + "Still active SCMI users will be forcibly unbound.\n"); | |
| 2497 | + list_del(&info->node); | |
| 2487 | 2498 | mutex_unlock(&scmi_list_mutex); |
| 2488 | 2499 | |
| 2489 | − if (ret) | |
| 2490 | − return ret; | |
| 2491 | − | |
| 2492 | 2500 | scmi_notification_exit(&info->handle); |
| 2493 | 2501 | |
| 2494 | 2502 | mutex_lock(&info->protocols_mtx); |
| @@ -2500,7 +2508,11 @@ static int scmi_remove(struct platform_device *pdev) · 5 unmodified lines | ||
| 2500 | 2508 | idr_destroy(&info->active_protocols); |
| 2501 | 2509 | |
| 2502 | 2510 | /* Safe to free channels since no more users */ |
| 2503 | − return scmi_cleanup_txrx_channels(info); | |
| 2511 | + ret = scmi_cleanup_txrx_channels(info); | |
| 2512 | + if (ret) | |
| 2513 | + dev_warn(&pdev->dev, "Failed to cleanup SCMI channels.\n"); | |
| 2514 | + | |
| 2515 | + return 0; | |
| 2504 | 2516 | } |
| 2505 | 2517 | |
| 2506 | 2518 | static ssize_t protocol_version_show(struct device *dev, |
| @@ -2571,6 +2583,7 @@ MODULE_DEVICE_TABLE(of, scmi_of_match); · 64 unmodified lines | ||
| 2571 | 2583 | static struct platform_driver scmi_driver = { |
| 2572 | 2584 | .driver = { |
| 2573 | 2585 | .name = "arm-scmi", |
| 2586 | + .suppress_bind_attrs = true, | |
| 2574 | 2587 | .of_match_table = scmi_of_match, |
| 2575 | 2588 | .dev_groups = versions_groups, |
| 2576 | 2589 | }, |
| @@ -36,7 +36,7 @@ static void tx_prepare(struct mbox_client *cl, void *m) · 35 unmodified lines | ||
| 36 | 36 | { |
| 37 | 37 | struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl); |
| 38 | 38 | |
| 39 | − shmem_tx_prepare(smbox->shmem, m); | |
| 39 | + shmem_tx_prepare(smbox->shmem, m, smbox->cinfo); | |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | 42 | static void rx_callback(struct mbox_client *cl, void *m) |
| @@ -498,7 +498,7 @@ static int scmi_optee_send_message(struct scmi_chan_info *cinfo, · 497 unmodified lines | ||
| 498 | 498 | msg_tx_prepare(channel->req.msg, xfer); |
| 499 | 499 | ret = invoke_process_msg_channel(channel, msg_command_size(xfer)); |
| 500 | 500 | } else { |
| 501 | − shmem_tx_prepare(channel->req.shmem, xfer); | |
| 501 | + shmem_tx_prepare(channel->req.shmem, xfer, cinfo); | |
| 502 | 502 | ret = invoke_process_smt_channel(channel); |
| 503 | 503 | } |
| 504 | 504 | |
| @@ -5,10 +5,13 @@ · 4 unmodified lines | ||
| 5 | 5 | * Copyright (C) 2019 ARM Ltd. |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | +#include <linux/ktime.h> | |
| 8 | 9 | #include <linux/io.h> |
| 9 | 10 | #include <linux/processor.h> |
| 10 | 11 | #include <linux/types.h> |
| 11 | 12 | |
| 13 | +#include <asm-generic/bug.h> | |
| 14 | + | |
| 12 | 15 | #include "common.h" |
| 13 | 16 | |
| 14 | 17 | /* |
| @@ -30,16 +33,36 @@ struct scmi_shared_mem { · 15 unmodified lines | ||
| 30 | 33 | }; |
| 31 | 34 | |
| 32 | 35 | void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem, |
| 33 | − struct scmi_xfer *xfer) | |
| 36 | + struct scmi_xfer *xfer, struct scmi_chan_info *cinfo) | |
| 34 | 37 | { |
| 38 | + ktime_t stop; | |
| 39 | + | |
| 35 | 40 | /* |
| 36 | 41 | * Ideally channel must be free by now unless OS timeout last |
| 37 | 42 | * request and platform continued to process the same, wait |
| 38 | 43 | * until it releases the shared memory, otherwise we may endup |
| 39 | − * overwriting its response with new message payload or vice-versa | |
| 44 | + * overwriting its response with new message payload or vice-versa. | |
| 45 | + * Giving up anyway after twice the expected channel timeout so as | |
| 46 | + * not to bail-out on intermittent issues where the platform is | |
| 47 | + * occasionally a bit slower to answer. | |
| 48 | + * | |
| 49 | + * Note that after a timeout is detected we bail-out and carry on but | |
| 50 | + * the transport functionality is probably permanently compromised: | |
| 51 | + * this is just to ease debugging and avoid complete hangs on boot | |
| 52 | + * due to a misbehaving SCMI firmware. | |
| 40 | 53 | */ |
| 41 | − spin_until_cond(ioread32(&shmem->channel_status) & | |
| 42 | − SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); | |
| 54 | + stop = ktime_add_ms(ktime_get(), 2 * cinfo->rx_timeout_ms); | |
| 55 | + spin_until_cond((ioread32(&shmem->channel_status) & | |
| 56 | + SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE) || | |
| 57 | + ktime_after(ktime_get(), stop)); | |
| 58 | + if (!(ioread32(&shmem->channel_status) & | |
| 59 | + SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)) { | |
| 60 | + WARN_ON_ONCE(1); | |
| 61 | + dev_err(cinfo->dev, | |
| 62 | + "Timeout waiting for a free TX channel !\n"); | |
| 63 | + return; | |
| 64 | + } | |
| 65 | + | |
| 43 | 66 | /* Mark channel busy + clear error */ |
| 44 | 67 | iowrite32(0x0, &shmem->channel_status); |
| 45 | 68 | iowrite32(xfer->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED, |
| @@ -188,7 +188,7 @@ static int smc_send_message(struct scmi_chan_info *cinfo, · 187 unmodified lines | ||
| 188 | 188 | */ |
| 189 | 189 | smc_channel_lock_acquire(scmi_info, xfer); |
| 190 | 190 | |
| 191 | − shmem_tx_prepare(scmi_info->shmem, xfer); | |
| 191 | + shmem_tx_prepare(scmi_info->shmem, xfer, cinfo); | |
| 192 | 192 | |
| 193 | 193 | arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res); |
| 194 | 194 | |
| @@ -148,7 +148,6 @@ static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch) · 147 unmodified lines | ||
| 148 | 148 | { |
| 149 | 149 | unsigned long flags; |
| 150 | 150 | DECLARE_COMPLETION_ONSTACK(vioch_shutdown_done); |
| 151 | − void *deferred_wq = NULL; | |
| 152 | 151 | |
| 153 | 152 | /* |
| 154 | 153 | * Prepare to wait for the last release if not already released |
| @@ -162,16 +161,11 @@ static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch) · 7 unmodified lines | ||
| 162 | 161 | |
| 163 | 162 | vioch->shutdown_done = &vioch_shutdown_done; |
| 164 | 163 | virtio_break_device(vioch->vqueue->vdev); |
| 165 | − if (!vioch->is_rx && vioch->deferred_tx_wq) { | |
| 166 | − deferred_wq = vioch->deferred_tx_wq; | |
| 164 | + if (!vioch->is_rx && vioch->deferred_tx_wq) | |
| 167 | 165 | /* Cannot be kicked anymore after this...*/ |
| 168 | 166 | vioch->deferred_tx_wq = NULL; |
| 169 | − } | |
| 170 | 167 | spin_unlock_irqrestore(&vioch->lock, flags); |
| 171 | 168 | |
| 172 | − if (deferred_wq) | |
| 173 | − destroy_workqueue(deferred_wq); | |
| 174 | − | |
| 175 | 169 | scmi_vio_channel_release(vioch); |
| 176 | 170 | |
| 177 | 171 | /* Let any possibly concurrent RX path release the channel */ |
| @@ -416,6 +410,11 @@ static bool virtio_chan_available(struct device *dev, int idx) · 238 unmodified lines | ||
| 416 | 410 | return vioch && !vioch->cinfo; |
| 417 | 411 | } |
| 418 | 412 | |
| 413 | +static void scmi_destroy_tx_workqueue(void *deferred_tx_wq) | |
| 414 | +{ | |
| 415 | + destroy_workqueue(deferred_tx_wq); | |
| 416 | +} | |
| 417 | + | |
| 419 | 418 | static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, |
| 420 | 419 | bool tx) |
| 421 | 420 | { |
| @@ -430,6 +429,8 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 8 unmodified lines | ||
| 430 | 429 | |
| 431 | 430 | /* Setup a deferred worker for polling. */ |
| 432 | 431 | if (tx && !vioch->deferred_tx_wq) { |
| 432 | + int ret; | |
| 433 | + | |
| 433 | 434 | vioch->deferred_tx_wq = |
| 434 | 435 | alloc_workqueue(dev_name(&scmi_vdev->dev), |
| 435 | 436 | WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS, |
| @@ -437,6 +438,11 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 1 unmodified line | ||
| 437 | 438 | if (!vioch->deferred_tx_wq) |
| 438 | 439 | return -ENOMEM; |
| 439 | 440 | |
| 441 | + ret = devm_add_action_or_reset(dev, scmi_destroy_tx_workqueue, | |
| 442 | + vioch->deferred_tx_wq); | |
| 443 | + if (ret) | |
| 444 | + return ret; | |
| 445 | + | |
| 440 | 446 | INIT_WORK(&vioch->deferred_tx_work, |
| 441 | 447 | scmi_vio_deferred_tx_worker); |
| 442 | 448 | } |
| @@ -444,12 +450,12 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 1 unmodified line | ||
| 444 | 450 | for (i = 0; i < vioch->max_msg; i++) { |
| 445 | 451 | struct scmi_vio_msg *msg; |
| 446 | 452 | |
| 447 | − msg = devm_kzalloc(cinfo->dev, sizeof(*msg), GFP_KERNEL); | |
| 453 | + msg = devm_kzalloc(dev, sizeof(*msg), GFP_KERNEL); | |
| 448 | 454 | if (!msg) |
| 449 | 455 | return -ENOMEM; |
| 450 | 456 | |
| 451 | 457 | if (tx) { |
| 452 | − msg->request = devm_kzalloc(cinfo->dev, | |
| 458 | + msg->request = devm_kzalloc(dev, | |
| 453 | 459 | VIRTIO_SCMI_MAX_PDU_SIZE, |
| 454 | 460 | GFP_KERNEL); |
| 455 | 461 | if (!msg->request) |
| @@ -458,7 +464,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 2 unmodified lines | ||
| 458 | 464 | refcount_set(&msg->users, 1); |
| 459 | 465 | } |
| 460 | 466 | |
| 461 | − msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE, | |
| 467 | + msg->input = devm_kzalloc(dev, VIRTIO_SCMI_MAX_PDU_SIZE, | |
| 462 | 468 | GFP_KERNEL); |
| 463 | 469 | if (!msg->input) |
| 464 | 470 | return -ENOMEM; |
| @@ -611,7 +611,7 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables, · 610 unmodified lines | ||
| 611 | 611 | |
| 612 | 612 | seed = early_memremap(efi_rng_seed, sizeof(*seed)); |
| 613 | 613 | if (seed != NULL) { |
| 614 | − size = READ_ONCE(seed->size); | |
| 614 | + size = min(seed->size, EFI_RANDOM_SEED_SIZE); | |
| 615 | 615 | early_memunmap(seed, sizeof(*seed)); |
| 616 | 616 | } else { |
| 617 | 617 | pr_err("Could not map UEFI random seed!\n"); |
| @@ -82,7 +82,7 @@ $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE · 81 unmodified lines | ||
| 82 | 82 | lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o |
| 83 | 83 | |
| 84 | 84 | lib-$(CONFIG_ARM) += arm32-stub.o |
| 85 | −lib-$(CONFIG_ARM64) += arm64-stub.o | |
| 85 | +lib-$(CONFIG_ARM64) += arm64-stub.o smbios.o | |
| 86 | 86 | lib-$(CONFIG_X86) += x86-stub.o |
| 87 | 87 | lib-$(CONFIG_RISCV) += riscv-stub.o |
| 88 | 88 | lib-$(CONFIG_LOONGARCH) += loongarch-stub.o |
| @@ -15,6 +15,21 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | #include "efistub.h" |
| 17 | 17 | |
| 18 | +static bool system_needs_vamap(void) | |
| 19 | +{ | |
| 20 | + const u8 *type1_family = efi_get_smbios_string(1, family); | |
| 21 | + | |
| 22 | + /* | |
| 23 | + * Ampere Altra machines crash in SetTime() if SetVirtualAddressMap() | |
| 24 | + * has not been called prior. | |
| 25 | + */ | |
| 26 | + if (!type1_family || strcmp(type1_family, "Altra")) | |
| 27 | + return false; | |
| 28 | + | |
| 29 | + efi_warn("Working around broken SetVirtualAddressMap()\n"); | |
| 30 | + return true; | |
| 31 | +} | |
| 32 | + | |
| 18 | 33 | efi_status_t check_platform_features(void) |
| 19 | 34 | { |
| 20 | 35 | u64 tg; |
| @@ -24,7 +39,7 @@ efi_status_t check_platform_features(void) · 3 unmodified lines | ||
| 24 | 39 | * UEFI runtime regions 1:1 and so calling SetVirtualAddressMap() is |
| 25 | 40 | * unnecessary. |
| 26 | 41 | */ |
| 27 | − if (VA_BITS_MIN >= 48) | |
| 42 | + if (VA_BITS_MIN >= 48 && !system_needs_vamap()) | |
| 28 | 43 | efi_novamap = true; |
| 29 | 44 | |
| 30 | 45 | /* UEFI mandates support for 4 KB granularity, no need to check */ |
| @@ -975,4 +975,32 @@ efi_enable_reset_attack_mitigation(void) { } · 974 unmodified lines | ||
| 975 | 975 | |
| 976 | 976 | void efi_retrieve_tpm2_eventlog(void); |
| 977 | 977 | |
| 978 | +struct efi_smbios_record { | |
| 979 | + u8 type; | |
| 980 | + u8 length; | |
| 981 | + u16 handle; | |
| 982 | +}; | |
| 983 | + | |
| 984 | +struct efi_smbios_type1_record { | |
| 985 | + struct efi_smbios_record header; | |
| 986 | + | |
| 987 | + u8 manufacturer; | |
| 988 | + u8 product_name; | |
| 989 | + u8 version; | |
| 990 | + u8 serial_number; | |
| 991 | + efi_guid_t uuid; | |
| 992 | + u8 wakeup_type; | |
| 993 | + u8 sku_number; | |
| 994 | + u8 family; | |
| 995 | +}; | |
| 996 | + | |
| 997 | +#define efi_get_smbios_string(__type, __name) ({ \ | |
| 998 | + int size = sizeof(struct efi_smbios_type ## __type ## _record); \ | |
| 999 | + int off = offsetof(struct efi_smbios_type ## __type ## _record, \ | |
| 1000 | + __name); \ | |
| 1001 | + __efi_get_smbios_string(__type, off, size); \ | |
| 1002 | +}) | |
| 1003 | + | |
| 1004 | +const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize); | |
| 1005 | + | |
| 978 | 1006 | #endif |
| @@ -75,7 +75,12 @@ efi_status_t efi_random_get_seed(void) · 74 unmodified lines | ||
| 75 | 75 | if (status != EFI_SUCCESS) |
| 76 | 76 | return status; |
| 77 | 77 | |
| 78 | − status = efi_bs_call(allocate_pool, EFI_RUNTIME_SERVICES_DATA, | |
| 78 | + /* | |
| 79 | + * Use EFI_ACPI_RECLAIM_MEMORY here so that it is guaranteed that the | |
| 80 | + * allocation will survive a kexec reboot (although we refresh the seed | |
| 81 | + * beforehand) | |
| 82 | + */ | |
| 83 | + status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY, | |
| 79 | 84 | sizeof(*seed) + EFI_RANDOM_SEED_SIZE, |
| 80 | 85 | (void **)&seed); |
| 81 | 86 | if (status != EFI_SUCCESS) |
| @@ -0,0 +1,48 @@ | ||
| 1 | +// SPDX-License-Identifier: GPL-2.0-only | |
| 2 | +// Copyright 2022 Google LLC | |
| 3 | +// Author: Ard Biesheuvel <ardb@google.com> | |
| 4 | + | |
| 5 | +#include <linux/efi.h> | |
| 6 | + | |
| 7 | +#include "efistub.h" | |
| 8 | + | |
| 9 | +typedef struct efi_smbios_protocol efi_smbios_protocol_t; | |
| 10 | + | |
| 11 | +struct efi_smbios_protocol { | |
| 12 | + efi_status_t (__efiapi *add)(efi_smbios_protocol_t *, efi_handle_t, | |
| 13 | + u16 *, struct efi_smbios_record *); | |
| 14 | + efi_status_t (__efiapi *update_string)(efi_smbios_protocol_t *, u16 *, | |
| 15 | + unsigned long *, u8 *); | |
| 16 | + efi_status_t (__efiapi *remove)(efi_smbios_protocol_t *, u16); | |
| 17 | + efi_status_t (__efiapi *get_next)(efi_smbios_protocol_t *, u16 *, u8 *, | |
| 18 | + struct efi_smbios_record **, | |
| 19 | + efi_handle_t *); | |
| 20 | + | |
| 21 | + u8 major_version; | |
| 22 | + u8 minor_version; | |
| 23 | +}; | |
| 24 | + | |
| 25 | +const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize) | |
| 26 | +{ | |
| 27 | + struct efi_smbios_record *record; | |
| 28 | + efi_smbios_protocol_t *smbios; | |
| 29 | + efi_status_t status; | |
| 30 | + u16 handle = 0xfffe; | |
| 31 | + const u8 *strtable; | |
| 32 | + | |
| 33 | + status = efi_bs_call(locate_protocol, &EFI_SMBIOS_PROTOCOL_GUID, NULL, | |
| 34 | + (void **)&smbios) ?: | |
| 35 | + efi_call_proto(smbios, get_next, &handle, &type, &record, NULL); | |
| 36 | + if (status != EFI_SUCCESS) | |
| 37 | + return NULL; | |
| 38 | + | |
| 39 | + strtable = (u8 *)record + recsize; | |
| 40 | + for (int i = 1; i < ((u8 *)record)[offset]; i++) { | |
| 41 | + int len = strlen(strtable); | |
| 42 | + | |
| 43 | + if (!len) | |
| 44 | + return NULL; | |
| 45 | + strtable += len + 1; | |
| 46 | + } | |
| 47 | + return strtable; | |
| 48 | +} | |
| @@ -97,7 +97,7 @@ int __init efi_tpm_eventlog_init(void) · 96 unmodified lines | ||
| 97 | 97 | goto out_calc; |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | − memblock_reserve((unsigned long)final_tbl, | |
| 100 | + memblock_reserve(efi.tpm_final_log, | |
| 101 | 101 | tbl_size + sizeof(*final_tbl)); |
| 102 | 102 | efi_tpm_final_log_size = tbl_size; |
| 103 | 103 | |
| @@ -21,29 +21,22 @@ static struct efivars *__efivars; · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | static DEFINE_SEMAPHORE(efivars_lock); |
| 23 | 23 | |
| 24 | −static efi_status_t check_var_size(u32 attributes, unsigned long size) | |
| 25 | −{ | |
| 26 | − const struct efivar_operations *fops; | |
| 27 | − | |
| 28 | − fops = __efivars->ops; | |
| 29 | − | |
| 30 | − if (!fops->query_variable_store) | |
| 31 | − return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES; | |
| 32 | − | |
| 33 | − return fops->query_variable_store(attributes, size, false); | |
| 34 | −} | |
| 35 | − | |
| 36 | −static | |
| 37 | −efi_status_t check_var_size_nonblocking(u32 attributes, unsigned long size) | |
| 24 | +static efi_status_t check_var_size(bool nonblocking, u32 attributes, | |
| 25 | + unsigned long size) | |
| 38 | 26 | { |
| 39 | 27 | const struct efivar_operations *fops; |
| 28 | + efi_status_t status; | |
| 40 | 29 | |
| 41 | 30 | fops = __efivars->ops; |
| 42 | 31 | |
| 43 | 32 | if (!fops->query_variable_store) |
| 33 | + status = EFI_UNSUPPORTED; | |
| 34 | + else | |
| 35 | + status = fops->query_variable_store(attributes, size, | |
| 36 | + nonblocking); | |
| 37 | + if (status == EFI_UNSUPPORTED) | |
| 44 | 38 | return (size <= SZ_64K) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES; |
| 45 | − | |
| 46 | − return fops->query_variable_store(attributes, size, true); | |
| 39 | + return status; | |
| 47 | 40 | } |
| 48 | 41 | |
| 49 | 42 | /** |
| @@ -195,26 +188,6 @@ efi_status_t efivar_get_next_variable(unsigned long *name_size, · 145 unmodified lines | ||
| 195 | 188 | } |
| 196 | 189 | EXPORT_SYMBOL_NS_GPL(efivar_get_next_variable, EFIVAR); |
| 197 | 190 | |
| 198 | −/* | |
| 199 | − * efivar_set_variable_blocking() - local helper function for set_variable | |
| 200 | − * | |
| 201 | − * Must be called with efivars_lock held. | |
| 202 | − */ | |
| 203 | −static efi_status_t | |
| 204 | −efivar_set_variable_blocking(efi_char16_t *name, efi_guid_t *vendor, | |
| 205 | − u32 attr, unsigned long data_size, void *data) | |
| 206 | −{ | |
| 207 | − efi_status_t status; | |
| 208 | − | |
| 209 | − if (data_size > 0) { | |
| 210 | − status = check_var_size(attr, data_size + | |
| 211 | − ucs2_strsize(name, 1024)); | |
| 212 | − if (status != EFI_SUCCESS) | |
| 213 | − return status; | |
| 214 | − } | |
| 215 | − return __efivars->ops->set_variable(name, vendor, attr, data_size, data); | |
| 216 | −} | |
| 217 | − | |
| 218 | 191 | /* |
| 219 | 192 | * efivar_set_variable_locked() - set a variable identified by name/vendor |
| 220 | 193 | * |
| @@ -228,23 +201,21 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor, · 7 unmodified lines | ||
| 228 | 201 | efi_set_variable_t *setvar; |
| 229 | 202 | efi_status_t status; |
| 230 | 203 | |
| 231 | − if (!nonblocking) | |
| 232 | − return efivar_set_variable_blocking(name, vendor, attr, | |
| 233 | − data_size, data); | |
| 204 | + if (data_size > 0) { | |
| 205 | + status = check_var_size(nonblocking, attr, | |
| 206 | + data_size + ucs2_strsize(name, 1024)); | |
| 207 | + if (status != EFI_SUCCESS) | |
| 208 | + return status; | |
| 209 | + } | |
| 234 | 210 | |
| 235 | 211 | /* |
| 236 | 212 | * If no _nonblocking variant exists, the ordinary one |
| 237 | 213 | * is assumed to be non-blocking. |
| 238 | 214 | */ |
| 239 | − setvar = __efivars->ops->set_variable_nonblocking ?: | |
| 240 | − __efivars->ops->set_variable; | |
| 215 | + setvar = __efivars->ops->set_variable_nonblocking; | |
| 216 | + if (!setvar || !nonblocking) | |
| 217 | + setvar = __efivars->ops->set_variable; | |
| 241 | 218 | |
| 242 | − if (data_size > 0) { | |
| 243 | − status = check_var_size_nonblocking(attr, data_size + | |
| 244 | − ucs2_strsize(name, 1024)); | |
| 245 | − if (status != EFI_SUCCESS) | |
| 246 | − return status; | |
| 247 | − } | |
| 248 | 219 | return setvar(name, vendor, attr, data_size, data); |
| 249 | 220 | } |
| 250 | 221 | EXPORT_SYMBOL_NS_GPL(efivar_set_variable_locked, EFIVAR); |
| @@ -264,7 +235,8 @@ efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor, · 13 unmodified lines | ||
| 264 | 235 | if (efivar_lock()) |
| 265 | 236 | return EFI_ABORTED; |
| 266 | 237 | |
| 267 | − status = efivar_set_variable_blocking(name, vendor, attr, data_size, data); | |
| 238 | + status = efivar_set_variable_locked(name, vendor, attr, data_size, | |
| 239 | + data, false); | |
| 268 | 240 | efivar_unlock(); |
| 269 | 241 | return status; |
| 270 | 242 | } |
| @@ -149,12 +149,8 @@ static int coreboot_table_probe(struct platform_device *pdev) · 148 unmodified lines | ||
| 149 | 149 | if (!ptr) |
| 150 | 150 | return -ENOMEM; |
| 151 | 151 | |
| 152 | − ret = bus_register(&coreboot_bus_type); | |
| 153 | − if (!ret) { | |
| 154 | − ret = coreboot_table_populate(dev, ptr); | |
| 155 | − if (ret) | |
| 156 | − bus_unregister(&coreboot_bus_type); | |
| 157 | − } | |
| 152 | + ret = coreboot_table_populate(dev, ptr); | |
| 153 | + | |
| 158 | 154 | memunmap(ptr); |
| 159 | 155 | |
| 160 | 156 | return ret; |
| @@ -169,7 +165,6 @@ static int __cb_dev_unregister(struct device *dev, void *dummy) · 8 unmodified lines | ||
| 169 | 165 | static int coreboot_table_remove(struct platform_device *pdev) |
| 170 | 166 | { |
| 171 | 167 | bus_for_each_dev(&coreboot_bus_type, NULL, NULL, __cb_dev_unregister); |
| 172 | − bus_unregister(&coreboot_bus_type); | |
| 173 | 168 | return 0; |
| 174 | 169 | } |
| 175 | 170 | |
| @@ -199,6 +194,32 @@ static struct platform_driver coreboot_table_driver = { · 23 unmodified lines | ||
| 199 | 194 | .of_match_table = of_match_ptr(coreboot_of_match), |
| 200 | 195 | }, |
| 201 | 196 | }; |
| 202 | −module_platform_driver(coreboot_table_driver); | |
| 197 | + | |
| 198 | +static int __init coreboot_table_driver_init(void) | |
| 199 | +{ | |
| 200 | + int ret; | |
| 201 | + | |
| 202 | + ret = bus_register(&coreboot_bus_type); | |
| 203 | + if (ret) | |
| 204 | + return ret; | |
| 205 | + | |
| 206 | + ret = platform_driver_register(&coreboot_table_driver); | |
| 207 | + if (ret) { | |
| 208 | + bus_unregister(&coreboot_bus_type); | |
| 209 | + return ret; | |
| 210 | + } | |
| 211 | + | |
| 212 | + return 0; | |
| 213 | +} | |
| 214 | + | |
| 215 | +static void __exit coreboot_table_driver_exit(void) | |
| 216 | +{ | |
| 217 | + platform_driver_unregister(&coreboot_table_driver); | |
| 218 | + bus_unregister(&coreboot_bus_type); | |
| 219 | +} | |
| 220 | + | |
| 221 | +module_init(coreboot_table_driver_init); | |
| 222 | +module_exit(coreboot_table_driver_exit); | |
| 223 | + | |
| 203 | 224 | MODULE_AUTHOR("Google, Inc."); |
| 204 | 225 | MODULE_LICENSE("GPL"); |
| @@ -246,7 +246,9 @@ config FPGA_MGR_VERSAL_FPGA · 245 unmodified lines | ||
| 246 | 246 | |
| 247 | 247 | config FPGA_M10_BMC_SEC_UPDATE |
| 248 | 248 | tristate "Intel MAX10 BMC Secure Update driver" |
| 249 | − depends on MFD_INTEL_M10_BMC && FW_UPLOAD | |
| 249 | + depends on MFD_INTEL_M10_BMC | |
| 250 | + select FW_LOADER | |
| 251 | + select FW_UPLOAD | |
| 250 | 252 | help |
| 251 | 253 | Secure update support for the Intel MAX10 board management |
| 252 | 254 | controller. |
| @@ -1293,6 +1293,7 @@ void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev, · 1292 unmodified lines | ||
| 1293 | 1293 | u32 reg, u32 v); |
| 1294 | 1294 | struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev, |
| 1295 | 1295 | struct dma_fence *gang); |
| 1296 | +bool amdgpu_device_has_display_hardware(struct amdgpu_device *adev); | |
| 1296 | 1297 | |
| 1297 | 1298 | /* atpx handler */ |
| 1298 | 1299 | #if defined(CONFIG_VGA_SWITCHEROO) |
| @@ -706,6 +706,13 @@ err: · 705 unmodified lines | ||
| 706 | 706 | |
| 707 | 707 | void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle) |
| 708 | 708 | { |
| 709 | + /* Temporary workaround to fix issues observed in some | |
| 710 | + * compute applications when GFXOFF is enabled on GFX11. | |
| 711 | + */ | |
| 712 | + if (IP_VERSION_MAJ(adev->ip_versions[GC_HWIP][0]) == 11) { | |
| 713 | + pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled"); | |
| 714 | + amdgpu_gfx_off_ctrl(adev, idle); | |
| 715 | + } | |
| 709 | 716 | amdgpu_dpm_switch_power_profile(adev, |
| 710 | 717 | PP_SMC_POWER_PROFILE_COMPUTE, |
| 711 | 718 | !idle); |
| @@ -41,5 +41,6 @@ const struct kfd2kgd_calls aldebaran_kfd2kgd = { · 40 unmodified lines | ||
| 41 | 41 | .get_atc_vmid_pasid_mapping_info = |
| 42 | 42 | kgd_gfx_v9_get_atc_vmid_pasid_mapping_info, |
| 43 | 43 | .set_vm_context_page_table_base = kgd_gfx_v9_set_vm_context_page_table_base, |
| 44 | + .get_cu_occupancy = kgd_gfx_v9_get_cu_occupancy, | |
| 44 | 45 | .program_trap_handler_settings = kgd_gfx_v9_program_trap_handler_settings |
| 45 | 46 | }; |
| @@ -171,9 +171,7 @@ int amdgpu_amdkfd_reserve_mem_limit(struct amdgpu_device *adev, · 170 unmodified lines | ||
| 171 | 171 | (kfd_mem_limit.ttm_mem_used + ttm_mem_needed > |
| 172 | 172 | kfd_mem_limit.max_ttm_mem_limit) || |
| 173 | 173 | (adev && adev->kfd.vram_used + vram_needed > |
| 174 | − adev->gmc.real_vram_size - | |
| 175 | − atomic64_read(&adev->vram_pin_size) - | |
| 176 | − reserved_for_pt)) { | |
| 174 | + adev->gmc.real_vram_size - reserved_for_pt)) { | |
| 177 | 175 | ret = -ENOMEM; |
| 178 | 176 | goto release; |
| 179 | 177 | } |
| @@ -988,6 +986,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr, · 808 unmodified lines | ||
| 988 | 986 | struct amdkfd_process_info *process_info = mem->process_info; |
| 989 | 987 | struct amdgpu_bo *bo = mem->bo; |
| 990 | 988 | struct ttm_operation_ctx ctx = { true, false }; |
| 989 | + struct hmm_range *range; | |
| 991 | 990 | int ret = 0; |
| 992 | 991 | |
| 993 | 992 | mutex_lock(&process_info->lock); |
| @@ -1017,7 +1016,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr, · 23 unmodified lines | ||
| 1017 | 1016 | return 0; |
| 1018 | 1017 | } |
| 1019 | 1018 | |
| 1020 | − ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); | |
| 1019 | + ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages, &range); | |
| 1021 | 1020 | if (ret) { |
| 1022 | 1021 | pr_err("%s: Failed to get user pages: %d\n", __func__, ret); |
| 1023 | 1022 | goto unregister_out; |
| @@ -1035,7 +1034,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr, · 11 unmodified lines | ||
| 1035 | 1034 | amdgpu_bo_unreserve(bo); |
| 1036 | 1035 | |
| 1037 | 1036 | release_out: |
| 1038 | − amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); | |
| 1037 | + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range); | |
| 1039 | 1038 | unregister_out: |
| 1040 | 1039 | if (ret) |
| 1041 | 1040 | amdgpu_mn_unregister(bo); |
| @@ -2372,6 +2371,8 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info, · 1330 unmodified lines | ||
| 2372 | 2371 | /* Go through userptr_inval_list and update any invalid user_pages */ |
| 2373 | 2372 | list_for_each_entry(mem, &process_info->userptr_inval_list, |
| 2374 | 2373 | validate_list.head) { |
| 2374 | + struct hmm_range *range; | |
| 2375 | + | |
| 2375 | 2376 | invalid = atomic_read(&mem->invalid); |
| 2376 | 2377 | if (!invalid) |
| 2377 | 2378 | /* BO hasn't been invalidated since the last |
| @@ -2382,7 +2383,8 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info, · 4 unmodified lines | ||
| 2382 | 2383 | bo = mem->bo; |
| 2383 | 2384 | |
| 2384 | 2385 | /* Get updated user pages */ |
| 2385 | − ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); | |
| 2386 | + ret = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages, | |
| 2387 | + &range); | |
| 2386 | 2388 | if (ret) { |
| 2387 | 2389 | pr_debug("Failed %d to get user pages\n", ret); |
| 2388 | 2390 | |
| @@ -2401,7 +2403,7 @@ static int update_invalid_user_pages(struct amdkfd_process_info *process_info, · 12 unmodified lines | ||
| 2401 | 2403 | * FIXME: Cannot ignore the return code, must hold |
| 2402 | 2404 | * notifier_lock |
| 2403 | 2405 | */ |
| 2404 | − amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); | |
| 2406 | + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range); | |
| 2405 | 2407 | } |
| 2406 | 2408 | |
| 2407 | 2409 | /* Mark the BO as valid unless it was invalidated |
| @@ -209,6 +209,7 @@ void amdgpu_bo_list_get_list(struct amdgpu_bo_list *list, · 208 unmodified lines | ||
| 209 | 209 | list_add_tail(&e->tv.head, &bucket[priority]); |
| 210 | 210 | |
| 211 | 211 | e->user_pages = NULL; |
| 212 | + e->range = NULL; | |
| 212 | 213 | } |
| 213 | 214 | |
| 214 | 215 | /* Connect the sorted buckets in the output list. */ |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <drm/ttm/ttm_execbuf_util.h> |
| 27 | 27 | #include <drm/amdgpu_drm.h> |
| 28 | 28 | |
| 29 | +struct hmm_range; | |
| 30 | + | |
| 29 | 31 | struct amdgpu_device; |
| 30 | 32 | struct amdgpu_bo; |
| 31 | 33 | struct amdgpu_bo_va; |
| @@ -36,6 +38,7 @@ struct amdgpu_bo_list_entry { · 4 unmodified lines | ||
| 36 | 38 | struct amdgpu_bo_va *bo_va; |
| 37 | 39 | uint32_t priority; |
| 38 | 40 | struct page **user_pages; |
| 41 | + struct hmm_range *range; | |
| 39 | 42 | bool user_invalidated; |
| 40 | 43 | }; |
| 41 | 44 | |
| @@ -328,7 +328,6 @@ static void amdgpu_connector_free_edid(struct drm_connector *connector) · 327 unmodified lines | ||
| 328 | 328 | |
| 329 | 329 | kfree(amdgpu_connector->edid); |
| 330 | 330 | amdgpu_connector->edid = NULL; |
| 331 | − drm_connector_update_edid_property(connector, NULL); | |
| 332 | 331 | } |
| 333 | 332 | |
| 334 | 333 | static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector) |
| @@ -109,6 +109,7 @@ static int amdgpu_cs_p1_ib(struct amdgpu_cs_parser *p, · 108 unmodified lines | ||
| 109 | 109 | return r; |
| 110 | 110 | |
| 111 | 111 | ++(num_ibs[r]); |
| 112 | + p->gang_leader_idx = r; | |
| 112 | 113 | return 0; |
| 113 | 114 | } |
| 114 | 115 | |
| @@ -287,8 +288,10 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, · 172 unmodified lines | ||
| 287 | 288 | } |
| 288 | 289 | } |
| 289 | 290 | |
| 290 | − if (!p->gang_size) | |
| 291 | − return -EINVAL; | |
| 291 | + if (!p->gang_size) { | |
| 292 | + ret = -EINVAL; | |
| 293 | + goto free_partial_kdata; | |
| 294 | + } | |
| 292 | 295 | |
| 293 | 296 | for (i = 0; i < p->gang_size; ++i) { |
| 294 | 297 | ret = amdgpu_job_alloc(p->adev, num_ibs[i], &p->jobs[i], vm); |
| @@ -300,7 +303,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, · 5 unmodified lines | ||
| 300 | 303 | if (ret) |
| 301 | 304 | goto free_all_kdata; |
| 302 | 305 | } |
| 303 | − p->gang_leader = p->jobs[p->gang_size - 1]; | |
| 306 | + p->gang_leader = p->jobs[p->gang_leader_idx]; | |
| 304 | 307 | |
| 305 | 308 | if (p->ctx->vram_lost_counter != p->gang_leader->vram_lost_counter) { |
| 306 | 309 | ret = -ECANCELED; |
| @@ -910,7 +913,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, · 603 unmodified lines | ||
| 910 | 913 | goto out_free_user_pages; |
| 911 | 914 | } |
| 912 | 915 | |
| 913 | − r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages); | |
| 916 | + r = amdgpu_ttm_tt_get_user_pages(bo, e->user_pages, &e->range); | |
| 914 | 917 | if (r) { |
| 915 | 918 | kvfree(e->user_pages); |
| 916 | 919 | e->user_pages = NULL; |
| @@ -988,10 +991,12 @@ out_free_user_pages: · 71 unmodified lines | ||
| 988 | 991 | |
| 989 | 992 | if (!e->user_pages) |
| 990 | 993 | continue; |
| 991 | − amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); | |
| 994 | + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range); | |
| 992 | 995 | kvfree(e->user_pages); |
| 993 | 996 | e->user_pages = NULL; |
| 997 | + e->range = NULL; | |
| 994 | 998 | } |
| 999 | + mutex_unlock(&p->bo_list->bo_list_mutex); | |
| 995 | 1000 | return r; |
| 996 | 1001 | } |
| 997 | 1002 | |
| @@ -1194,16 +1199,18 @@ static int amdgpu_cs_sync_rings(struct amdgpu_cs_parser *p) · 196 unmodified lines | ||
| 1194 | 1199 | return r; |
| 1195 | 1200 | } |
| 1196 | 1201 | |
| 1197 | − for (i = 0; i < p->gang_size - 1; ++i) { | |
| 1202 | + for (i = 0; i < p->gang_size; ++i) { | |
| 1203 | + if (p->jobs[i] == leader) | |
| 1204 | + continue; | |
| 1205 | + | |
| 1198 | 1206 | r = amdgpu_sync_clone(&leader->sync, &p->jobs[i]->sync); |
| 1199 | 1207 | if (r) |
| 1200 | 1208 | return r; |
| 1201 | 1209 | } |
| 1202 | 1210 | |
| 1203 | − r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entities[p->gang_size - 1]); | |
| 1211 | + r = amdgpu_ctx_wait_prev_fence(p->ctx, p->entities[p->gang_leader_idx]); | |
| 1204 | 1212 | if (r && r != -ERESTARTSYS) |
| 1205 | 1213 | DRM_ERROR("amdgpu_ctx_wait_prev_fence failed.\n"); |
| 1206 | − | |
| 1207 | 1214 | return r; |
| 1208 | 1215 | } |
| 1209 | 1216 | |
| @@ -1237,9 +1244,12 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 27 unmodified lines | ||
| 1237 | 1244 | for (i = 0; i < p->gang_size; ++i) |
| 1238 | 1245 | drm_sched_job_arm(&p->jobs[i]->base); |
| 1239 | 1246 | |
| 1240 | − for (i = 0; i < (p->gang_size - 1); ++i) { | |
| 1247 | + for (i = 0; i < p->gang_size; ++i) { | |
| 1241 | 1248 | struct dma_fence *fence; |
| 1242 | 1249 | |
| 1250 | + if (p->jobs[i] == leader) | |
| 1251 | + continue; | |
| 1252 | + | |
| 1243 | 1253 | fence = &p->jobs[i]->base.s_fence->scheduled; |
| 1244 | 1254 | r = amdgpu_sync_fence(&leader->sync, fence); |
| 1245 | 1255 | if (r) |
| @@ -1264,7 +1274,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 18 unmodified lines | ||
| 1264 | 1274 | amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { |
| 1265 | 1275 | struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo); |
| 1266 | 1276 | |
| 1267 | − r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); | |
| 1277 | + r |= !amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, e->range); | |
| 1278 | + e->range = NULL; | |
| 1268 | 1279 | } |
| 1269 | 1280 | if (r) { |
| 1270 | 1281 | r = -EAGAIN; |
| @@ -1275,7 +1286,10 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 4 unmodified lines | ||
| 1275 | 1286 | list_for_each_entry(e, &p->validated, tv.head) { |
| 1276 | 1287 | |
| 1277 | 1288 | /* Everybody except for the gang leader uses READ */ |
| 1278 | − for (i = 0; i < (p->gang_size - 1); ++i) { | |
| 1289 | + for (i = 0; i < p->gang_size; ++i) { | |
| 1290 | + if (p->jobs[i] == leader) | |
| 1291 | + continue; | |
| 1292 | + | |
| 1279 | 1293 | dma_resv_add_fence(e->tv.bo->base.resv, |
| 1280 | 1294 | &p->jobs[i]->base.s_fence->finished, |
| 1281 | 1295 | DMA_RESV_USAGE_READ); |
| @@ -1285,7 +1299,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, · 3 unmodified lines | ||
| 1285 | 1299 | e->tv.num_shared = 0; |
| 1286 | 1300 | } |
| 1287 | 1301 | |
| 1288 | − seq = amdgpu_ctx_add_fence(p->ctx, p->entities[p->gang_size - 1], | |
| 1302 | + seq = amdgpu_ctx_add_fence(p->ctx, p->entities[p->gang_leader_idx], | |
| 1289 | 1303 | p->fence); |
| 1290 | 1304 | amdgpu_cs_post_dependencies(p); |
| 1291 | 1305 | |
| @@ -54,6 +54,7 @@ struct amdgpu_cs_parser { · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | /* scheduler job objects */ |
| 56 | 56 | unsigned int gang_size; |
| 57 | + unsigned int gang_leader_idx; | |
| 57 | 58 | struct drm_sched_entity *entities[AMDGPU_CS_GANG_SIZE]; |
| 58 | 59 | struct amdgpu_job *jobs[AMDGPU_CS_GANG_SIZE]; |
| 59 | 60 | struct amdgpu_job *gang_leader; |
| @@ -4060,15 +4060,18 @@ void amdgpu_device_fini_sw(struct amdgpu_device *adev) · 4059 unmodified lines | ||
| 4060 | 4060 | * at suspend time. |
| 4061 | 4061 | * |
| 4062 | 4062 | */ |
| 4063 | −static void amdgpu_device_evict_resources(struct amdgpu_device *adev) | |
| 4063 | +static int amdgpu_device_evict_resources(struct amdgpu_device *adev) | |
| 4064 | 4064 | { |
| 4065 | + int ret; | |
| 4066 | + | |
| 4065 | 4067 | /* No need to evict vram on APUs for suspend to ram or s2idle */ |
| 4066 | 4068 | if ((adev->in_s3 || adev->in_s0ix) && (adev->flags & AMD_IS_APU)) |
| 4067 | − return; | |
| 4069 | + return 0; | |
| 4068 | 4070 | |
| 4069 | − if (amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM)) | |
| 4071 | + ret = amdgpu_ttm_evict_resources(adev, TTM_PL_VRAM); | |
| 4072 | + if (ret) | |
| 4070 | 4073 | DRM_WARN("evicting device resources failed\n"); |
| 4071 | − | |
| 4074 | + return ret; | |
| 4072 | 4075 | } |
| 4073 | 4076 | |
| 4074 | 4077 | /* |
| @@ -4118,7 +4121,9 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) · 43 unmodified lines | ||
| 4118 | 4121 | if (!adev->in_s0ix) |
| 4119 | 4122 | amdgpu_amdkfd_suspend(adev, adev->in_runpm); |
| 4120 | 4123 | |
| 4121 | − amdgpu_device_evict_resources(adev); | |
| 4124 | + r = amdgpu_device_evict_resources(adev); | |
| 4125 | + if (r) | |
| 4126 | + return r; | |
| 4122 | 4127 | |
| 4123 | 4128 | amdgpu_fence_driver_hw_fini(adev); |
| 4124 | 4129 | |
| @@ -6039,3 +6044,44 @@ struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev, · 1914 unmodified lines | ||
| 6039 | 6044 | dma_fence_put(old); |
| 6040 | 6045 | return NULL; |
| 6041 | 6046 | } |
| 6047 | + | |
| 6048 | +bool amdgpu_device_has_display_hardware(struct amdgpu_device *adev) | |
| 6049 | +{ | |
| 6050 | + switch (adev->asic_type) { | |
| 6051 | +#ifdef CONFIG_DRM_AMDGPU_SI | |
| 6052 | + case CHIP_HAINAN: | |
| 6053 | +#endif | |
| 6054 | + case CHIP_TOPAZ: | |
| 6055 | + /* chips with no display hardware */ | |
| 6056 | + return false; | |
| 6057 | +#ifdef CONFIG_DRM_AMDGPU_SI | |
| 6058 | + case CHIP_TAHITI: | |
| 6059 | + case CHIP_PITCAIRN: | |
| 6060 | + case CHIP_VERDE: | |
| 6061 | + case CHIP_OLAND: | |
| 6062 | +#endif | |
| 6063 | +#ifdef CONFIG_DRM_AMDGPU_CIK | |
| 6064 | + case CHIP_BONAIRE: | |
| 6065 | + case CHIP_HAWAII: | |
| 6066 | + case CHIP_KAVERI: | |
| 6067 | + case CHIP_KABINI: | |
| 6068 | + case CHIP_MULLINS: | |
| 6069 | +#endif | |
| 6070 | + case CHIP_TONGA: | |
| 6071 | + case CHIP_FIJI: | |
| 6072 | + case CHIP_POLARIS10: | |
| 6073 | + case CHIP_POLARIS11: | |
| 6074 | + case CHIP_POLARIS12: | |
| 6075 | + case CHIP_VEGAM: | |
| 6076 | + case CHIP_CARRIZO: | |
| 6077 | + case CHIP_STONEY: | |
| 6078 | + /* chips with display hardware */ | |
| 6079 | + return true; | |
| 6080 | + default: | |
| 6081 | + /* IP discovery */ | |
| 6082 | + if (!adev->ip_versions[DCE_HWIP][0] || | |
| 6083 | + (adev->harvest_ip_mask & AMD_HARVEST_IP_DMU_MASK)) | |
| 6084 | + return false; | |
| 6085 | + return true; | |
| 6086 | + } | |
| 6087 | +} | |
| @@ -2201,7 +2201,8 @@ amdgpu_pci_remove(struct pci_dev *pdev) · 2200 unmodified lines | ||
| 2201 | 2201 | pm_runtime_forbid(dev->dev); |
| 2202 | 2202 | } |
| 2203 | 2203 | |
| 2204 | − if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2)) { | |
| 2204 | + if (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 2) && | |
| 2205 | + !amdgpu_sriov_vf(adev)) { | |
| 2205 | 2206 | bool need_to_reset_gpu = false; |
| 2206 | 2207 | |
| 2207 | 2208 | if (adev->gmc.xgmi.num_physical_nodes > 1) { |
| @@ -378,6 +378,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, · 377 unmodified lines | ||
| 378 | 378 | struct amdgpu_device *adev = drm_to_adev(dev); |
| 379 | 379 | struct drm_amdgpu_gem_userptr *args = data; |
| 380 | 380 | struct drm_gem_object *gobj; |
| 381 | + struct hmm_range *range; | |
| 381 | 382 | struct amdgpu_bo *bo; |
| 382 | 383 | uint32_t handle; |
| 383 | 384 | int r; |
| @@ -413,14 +414,13 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, · 29 unmodified lines | ||
| 413 | 414 | if (r) |
| 414 | 415 | goto release_object; |
| 415 | 416 | |
| 416 | − if (args->flags & AMDGPU_GEM_USERPTR_REGISTER) { | |
| 417 | − r = amdgpu_mn_register(bo, args->addr); | |
| 418 | − if (r) | |
| 419 | − goto release_object; | |
| 420 | − } | |
| 417 | + r = amdgpu_mn_register(bo, args->addr); | |
| 418 | + if (r) | |
| 419 | + goto release_object; | |
| 421 | 420 | |
| 422 | 421 | if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) { |
| 423 | − r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages); | |
| 422 | + r = amdgpu_ttm_tt_get_user_pages(bo, bo->tbo.ttm->pages, | |
| 423 | + &range); | |
| 424 | 424 | if (r) |
| 425 | 425 | goto release_object; |
| 426 | 426 | |
| @@ -443,7 +443,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, · 16 unmodified lines | ||
| 443 | 443 | |
| 444 | 444 | user_pages_done: |
| 445 | 445 | if (args->flags & AMDGPU_GEM_USERPTR_VALIDATE) |
| 446 | − amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); | |
| 446 | + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm, range); | |
| 447 | 447 | |
| 448 | 448 | release_object: |
| 449 | 449 | drm_gem_object_put(gobj); |
| @@ -479,6 +479,12 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev) · 478 unmodified lines | ||
| 479 | 479 | unsigned i; |
| 480 | 480 | unsigned vmhub, inv_eng; |
| 481 | 481 | |
| 482 | + if (adev->enable_mes) { | |
| 483 | + /* reserve engine 5 for firmware */ | |
| 484 | + for (vmhub = 0; vmhub < AMDGPU_MAX_VMHUBS; vmhub++) | |
| 485 | + vm_inv_engs[vmhub] &= ~(1 << 5); | |
| 486 | + } | |
| 487 | + | |
| 482 | 488 | for (i = 0; i < adev->num_rings; ++i) { |
| 483 | 489 | ring = adev->rings[i]; |
| 484 | 490 | vmhub = ring->funcs->vmhub; |
| @@ -656,7 +662,7 @@ void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device *adev) · 171 unmodified lines | ||
| 656 | 662 | } |
| 657 | 663 | |
| 658 | 664 | if (amdgpu_sriov_vf(adev) || |
| 659 | − !amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_DCE)) { | |
| 665 | + !amdgpu_device_has_display_hardware(adev)) { | |
| 660 | 666 | size = 0; |
| 661 | 667 | } else { |
| 662 | 668 | size = amdgpu_gmc_get_vbios_fb_size(adev); |
| @@ -169,7 +169,11 @@ static void amdgpu_job_free_cb(struct drm_sched_job *s_job) · 168 unmodified lines | ||
| 169 | 169 | amdgpu_sync_free(&job->sync); |
| 170 | 170 | amdgpu_sync_free(&job->sched_sync); |
| 171 | 171 | |
| 172 | − dma_fence_put(&job->hw_fence); | |
| 172 | + /* only put the hw fence if has embedded fence */ | |
| 173 | + if (!job->hw_fence.ops) | |
| 174 | + kfree(job); | |
| 175 | + else | |
| 176 | + dma_fence_put(&job->hw_fence); | |
| 173 | 177 | } |
| 174 | 178 | |
| 175 | 179 | void amdgpu_job_set_gang_leader(struct amdgpu_job *job, |
| @@ -254,6 +258,9 @@ static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job, · 78 unmodified lines | ||
| 254 | 258 | DRM_ERROR("Error adding fence (%d)\n", r); |
| 255 | 259 | } |
| 256 | 260 | |
| 261 | + if (!fence && job->gang_submit) | |
| 262 | + fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit); | |
| 263 | + | |
| 257 | 264 | while (fence == NULL && vm && !job->vmid) { |
| 258 | 265 | r = amdgpu_vmid_grab(vm, ring, &job->sync, |
| 259 | 266 | &job->base.s_fence->finished, |
| @@ -264,9 +271,6 @@ static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job, · 4 unmodified lines | ||
| 264 | 271 | fence = amdgpu_sync_get_fence(&job->sync); |
| 265 | 272 | } |
| 266 | 273 | |
| 267 | − if (!fence && job->gang_submit) | |
| 268 | − fence = amdgpu_device_switch_gang(ring->adev, job->gang_submit); | |
| 269 | − | |
| 270 | 274 | return fence; |
| 271 | 275 | } |
| 272 | 276 | |
| @@ -337,12 +337,14 @@ static int amdgpu_firmware_info(struct drm_amdgpu_info_firmware *fw_info, · 336 unmodified lines | ||
| 337 | 337 | fw_info->feature = adev->psp.cap_feature_version; |
| 338 | 338 | break; |
| 339 | 339 | case AMDGPU_INFO_FW_MES_KIQ: |
| 340 | − fw_info->ver = adev->mes.ucode_fw_version[0]; | |
| 341 | − fw_info->feature = 0; | |
| 340 | + fw_info->ver = adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK; | |
| 341 | + fw_info->feature = (adev->mes.kiq_version & AMDGPU_MES_FEAT_VERSION_MASK) | |
| 342 | + >> AMDGPU_MES_FEAT_VERSION_SHIFT; | |
| 342 | 343 | break; |
| 343 | 344 | case AMDGPU_INFO_FW_MES: |
| 344 | − fw_info->ver = adev->mes.ucode_fw_version[1]; | |
| 345 | − fw_info->feature = 0; | |
| 345 | + fw_info->ver = adev->mes.sched_version & AMDGPU_MES_VERSION_MASK; | |
| 346 | + fw_info->feature = (adev->mes.sched_version & AMDGPU_MES_FEAT_VERSION_MASK) | |
| 347 | + >> AMDGPU_MES_FEAT_VERSION_SHIFT; | |
| 346 | 348 | break; |
| 347 | 349 | case AMDGPU_INFO_FW_IMU: |
| 348 | 350 | fw_info->ver = adev->gfx.imu_fw_version; |
| @@ -172,6 +172,7 @@ void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx) · 171 unmodified lines | ||
| 172 | 172 | { |
| 173 | 173 | amdgpu_bo_free_kernel(&mem_ctx->shared_bo, &mem_ctx->shared_mc_addr, |
| 174 | 174 | &mem_ctx->shared_buf); |
| 175 | + mem_ctx->shared_bo = NULL; | |
| 175 | 176 | } |
| 176 | 177 | |
| 177 | 178 | static void psp_free_shared_bufs(struct psp_context *psp) |
| @@ -182,6 +183,7 @@ static void psp_free_shared_bufs(struct psp_context *psp) · 4 unmodified lines | ||
| 182 | 183 | /* free TMR memory buffer */ |
| 183 | 184 | pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; |
| 184 | 185 | amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, pptr); |
| 186 | + psp->tmr_bo = NULL; | |
| 185 | 187 | |
| 186 | 188 | /* free xgmi shared memory */ |
| 187 | 189 | psp_ta_free_shared_buf(&psp->xgmi_context.context.mem_context); |
| @@ -743,7 +745,7 @@ static int psp_load_toc(struct psp_context *psp, · 555 unmodified lines | ||
| 743 | 745 | /* Set up Trusted Memory Region */ |
| 744 | 746 | static int psp_tmr_init(struct psp_context *psp) |
| 745 | 747 | { |
| 746 | − int ret; | |
| 748 | + int ret = 0; | |
| 747 | 749 | int tmr_size; |
| 748 | 750 | void *tmr_buf; |
| 749 | 751 | void **pptr; |
| @@ -770,10 +772,12 @@ static int psp_tmr_init(struct psp_context *psp) · 20 unmodified lines | ||
| 770 | 772 | } |
| 771 | 773 | } |
| 772 | 774 | |
| 773 | − pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; | |
| 774 | − ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT, | |
| 775 | − AMDGPU_GEM_DOMAIN_VRAM, | |
| 776 | − &psp->tmr_bo, &psp->tmr_mc_addr, pptr); | |
| 775 | + if (!psp->tmr_bo) { | |
| 776 | + pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; | |
| 777 | + ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_ALIGNMENT, | |
| 778 | + AMDGPU_GEM_DOMAIN_VRAM, | |
| 779 | + &psp->tmr_bo, &psp->tmr_mc_addr, pptr); | |
| 780 | + } | |
| 777 | 781 | |
| 778 | 782 | return ret; |
| 779 | 783 | } |
| @@ -2732,8 +2736,6 @@ static int psp_suspend(void *handle) · 1952 unmodified lines | ||
| 2732 | 2736 | } |
| 2733 | 2737 | |
| 2734 | 2738 | out: |
| 2735 | − psp_free_shared_bufs(psp); | |
| 2736 | − | |
| 2737 | 2739 | return ret; |
| 2738 | 2740 | } |
| 2739 | 2741 | |
| @@ -643,9 +643,6 @@ struct amdgpu_ttm_tt { · 642 unmodified lines | ||
| 643 | 643 | struct task_struct *usertask; |
| 644 | 644 | uint32_t userflags; |
| 645 | 645 | bool bound; |
| 646 | −#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR) | |
| 647 | − struct hmm_range *range; | |
| 648 | −#endif | |
| 649 | 646 | }; |
| 650 | 647 | |
| 651 | 648 | #define ttm_to_amdgpu_ttm_tt(ptr) container_of(ptr, struct amdgpu_ttm_tt, ttm) |
| @@ -658,7 +655,8 @@ struct amdgpu_ttm_tt { · 6 unmodified lines | ||
| 658 | 655 | * Calling function must call amdgpu_ttm_tt_userptr_range_done() once and only |
| 659 | 656 | * once afterwards to stop HMM tracking |
| 660 | 657 | */ |
| 661 | −int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages) | |
| 658 | +int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages, | |
| 659 | + struct hmm_range **range) | |
| 662 | 660 | { |
| 663 | 661 | struct ttm_tt *ttm = bo->tbo.ttm; |
| 664 | 662 | struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm); |
| @@ -668,16 +666,15 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages) · 3 unmodified lines | ||
| 668 | 666 | bool readonly; |
| 669 | 667 | int r = 0; |
| 670 | 668 | |
| 669 | + /* Make sure get_user_pages_done() can cleanup gracefully */ | |
| 670 | + *range = NULL; | |
| 671 | + | |
| 671 | 672 | mm = bo->notifier.mm; |
| 672 | 673 | if (unlikely(!mm)) { |
| 673 | 674 | DRM_DEBUG_DRIVER("BO is not registered?\n"); |
| 674 | 675 | return -EFAULT; |
| 675 | 676 | } |
| 676 | 677 | |
| 677 | − /* Another get_user_pages is running at the same time?? */ | |
| 678 | − if (WARN_ON(gtt->range)) | |
| 679 | − return -EFAULT; | |
| 680 | − | |
| 681 | 678 | if (!mmget_not_zero(mm)) /* Happens during process shutdown */ |
| 682 | 679 | return -ESRCH; |
| 683 | 680 | |
| @@ -695,7 +692,7 @@ int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages) · 11 unmodified lines | ||
| 695 | 692 | |
| 696 | 693 | readonly = amdgpu_ttm_tt_is_readonly(ttm); |
| 697 | 694 | r = amdgpu_hmm_range_get_pages(&bo->notifier, mm, pages, start, |
| 698 | − ttm->num_pages, >t->range, readonly, | |
| 695 | + ttm->num_pages, range, readonly, | |
| 699 | 696 | true, NULL); |
| 700 | 697 | out_unlock: |
| 701 | 698 | mmap_read_unlock(mm); |
| @@ -713,30 +710,24 @@ out_unlock: · 11 unmodified lines | ||
| 713 | 710 | * |
| 714 | 711 | * Returns: true if pages are still valid |
| 715 | 712 | */ |
| 716 | −bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm) | |
| 713 | +bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm, | |
| 714 | + struct hmm_range *range) | |
| 717 | 715 | { |
| 718 | 716 | struct amdgpu_ttm_tt *gtt = ttm_to_amdgpu_ttm_tt(ttm); |
| 719 | − bool r = false; | |
| 720 | 717 | |
| 721 | − if (!gtt || !gtt->userptr) | |
| 718 | + if (!gtt || !gtt->userptr || !range) | |
| 722 | 719 | return false; |
| 723 | 720 | |
| 724 | 721 | DRM_DEBUG_DRIVER("user_pages_done 0x%llx pages 0x%x\n", |
| 725 | 722 | gtt->userptr, ttm->num_pages); |
| 726 | 723 | |
| 727 | − WARN_ONCE(!gtt->range || !gtt->range->hmm_pfns, | |
| 728 | − "No user pages to check\n"); | |
| 724 | + WARN_ONCE(!range->hmm_pfns, "No user pages to check\n"); | |
| 729 | 725 | |
| 730 | − if (gtt->range) { | |
| 731 | − /* | |
| 732 | − * FIXME: Must always hold notifier_lock for this, and must | |
| 733 | − * not ignore the return code. | |
| 734 | − */ | |
| 735 | − r = amdgpu_hmm_range_get_pages_done(gtt->range); | |
| 736 | − gtt->range = NULL; | |
| 737 | − } | |
| 738 | − | |
| 739 | − return !r; | |
| 726 | + /* | |
| 727 | + * FIXME: Must always hold notifier_lock for this, and must | |
| 728 | + * not ignore the return code. | |
| 729 | + */ | |
| 730 | + return !amdgpu_hmm_range_get_pages_done(range); | |
| 740 | 731 | } |
| 741 | 732 | #endif |
| 742 | 733 | |
| @@ -813,20 +804,6 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_device *bdev, · 70 unmodified lines | ||
| 813 | 804 | /* unmap the pages mapped to the device */ |
| 814 | 805 | dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0); |
| 815 | 806 | sg_free_table(ttm->sg); |
| 816 | − | |
| 817 | −#if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR) | |
| 818 | − if (gtt->range) { | |
| 819 | − unsigned long i; | |
| 820 | − | |
| 821 | − for (i = 0; i < ttm->num_pages; i++) { | |
| 822 | − if (ttm->pages[i] != | |
| 823 | − hmm_pfn_to_page(gtt->range->hmm_pfns[i])) | |
| 824 | − break; | |
| 825 | − } | |
| 826 | − | |
| 827 | − WARN((i == ttm->num_pages), "Missing get_user_page_done\n"); | |
| 828 | − } | |
| 829 | −#endif | |
| 830 | 807 | } |
| 831 | 808 | |
| 832 | 809 | static void amdgpu_ttm_gart_bind(struct amdgpu_device *adev, |
| @@ -39,6 +39,8 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #define AMDGPU_POISON 0xd0bed0be |
| 41 | 41 | |
| 42 | +struct hmm_range; | |
| 43 | + | |
| 42 | 44 | struct amdgpu_gtt_mgr { |
| 43 | 45 | struct ttm_resource_manager manager; |
| 44 | 46 | struct drm_mm mm; |
| @@ -149,15 +151,19 @@ void amdgpu_ttm_recover_gart(struct ttm_buffer_object *tbo); · 104 unmodified lines | ||
| 149 | 151 | uint64_t amdgpu_ttm_domain_start(struct amdgpu_device *adev, uint32_t type); |
| 150 | 152 | |
| 151 | 153 | #if IS_ENABLED(CONFIG_DRM_AMDGPU_USERPTR) |
| 152 | −int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages); | |
| 153 | −bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm); | |
| 154 | +int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, struct page **pages, | |
| 155 | + struct hmm_range **range); | |
| 156 | +bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm, | |
| 157 | + struct hmm_range *range); | |
| 154 | 158 | #else |
| 155 | 159 | static inline int amdgpu_ttm_tt_get_user_pages(struct amdgpu_bo *bo, |
| 156 | − struct page **pages) | |
| 160 | + struct page **pages, | |
| 161 | + struct hmm_range **range) | |
| 157 | 162 | { |
| 158 | 163 | return -EPERM; |
| 159 | 164 | } |
| 160 | −static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm) | |
| 165 | +static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm, | |
| 166 | + struct hmm_range *range) | |
| 161 | 167 | { |
| 162 | 168 | return false; |
| 163 | 169 | } |
| @@ -156,6 +156,9 @@ int amdgpu_vcn_sw_init(struct amdgpu_device *adev) · 155 unmodified lines | ||
| 156 | 156 | break; |
| 157 | 157 | case IP_VERSION(3, 0, 2): |
| 158 | 158 | fw_name = FIRMWARE_VANGOGH; |
| 159 | + if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) && | |
| 160 | + (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)) | |
| 161 | + adev->vcn.indirect_sram = true; | |
| 159 | 162 | break; |
| 160 | 163 | case IP_VERSION(3, 0, 16): |
| 161 | 164 | fw_name = FIRMWARE_DIMGREY_CAVEFISH; |
| @@ -500,6 +500,8 @@ static int amdgpu_vkms_sw_init(void *handle) · 499 unmodified lines | ||
| 500 | 500 | |
| 501 | 501 | adev_to_drm(adev)->mode_config.fb_base = adev->gmc.aper_base; |
| 502 | 502 | |
| 503 | + adev_to_drm(adev)->mode_config.fb_modifiers_not_supported = true; | |
| 504 | + | |
| 503 | 505 | r = amdgpu_display_modeset_create_props(adev); |
| 504 | 506 | if (r) |
| 505 | 507 | return r; |
| @@ -143,32 +143,6 @@ int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm, · 142 unmodified lines | ||
| 143 | 143 | return 0; |
| 144 | 144 | } |
| 145 | 145 | |
| 146 | −/* | |
| 147 | − * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS | |
| 148 | − * happens while holding this lock anywhere to prevent deadlocks when | |
| 149 | − * an MMU notifier runs in reclaim-FS context. | |
| 150 | − */ | |
| 151 | −static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm) | |
| 152 | −{ | |
| 153 | − mutex_lock(&vm->eviction_lock); | |
| 154 | − vm->saved_flags = memalloc_noreclaim_save(); | |
| 155 | −} | |
| 156 | − | |
| 157 | −static inline int amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm) | |
| 158 | −{ | |
| 159 | − if (mutex_trylock(&vm->eviction_lock)) { | |
| 160 | − vm->saved_flags = memalloc_noreclaim_save(); | |
| 161 | − return 1; | |
| 162 | − } | |
| 163 | − return 0; | |
| 164 | −} | |
| 165 | − | |
| 166 | −static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm) | |
| 167 | −{ | |
| 168 | − memalloc_noreclaim_restore(vm->saved_flags); | |
| 169 | − mutex_unlock(&vm->eviction_lock); | |
| 170 | −} | |
| 171 | − | |
| 172 | 146 | /** |
| 173 | 147 | * amdgpu_vm_bo_evicted - vm_bo is evicted |
| 174 | 148 | * |
| @@ -492,7 +492,48 @@ void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m); · 491 unmodified lines | ||
| 492 | 492 | */ |
| 493 | 493 | static inline uint64_t amdgpu_vm_tlb_seq(struct amdgpu_vm *vm) |
| 494 | 494 | { |
| 495 | + unsigned long flags; | |
| 496 | + spinlock_t *lock; | |
| 497 | + | |
| 498 | + /* | |
| 499 | + * Workaround to stop racing between the fence signaling and handling | |
| 500 | + * the cb. The lock is static after initially setting it up, just make | |
| 501 | + * sure that the dma_fence structure isn't freed up. | |
| 502 | + */ | |
| 503 | + rcu_read_lock(); | |
| 504 | + lock = vm->last_tlb_flush->lock; | |
| 505 | + rcu_read_unlock(); | |
| 506 | + | |
| 507 | + spin_lock_irqsave(lock, flags); | |
| 508 | + spin_unlock_irqrestore(lock, flags); | |
| 509 | + | |
| 495 | 510 | return atomic64_read(&vm->tlb_seq); |
| 496 | 511 | } |
| 497 | 512 | |
| 513 | +/* | |
| 514 | + * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS | |
| 515 | + * happens while holding this lock anywhere to prevent deadlocks when | |
| 516 | + * an MMU notifier runs in reclaim-FS context. | |
| 517 | + */ | |
| 518 | +static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm) | |
| 519 | +{ | |
| 520 | + mutex_lock(&vm->eviction_lock); | |
| 521 | + vm->saved_flags = memalloc_noreclaim_save(); | |
| 522 | +} | |
| 523 | + | |
| 524 | +static inline bool amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm) | |
| 525 | +{ | |
| 526 | + if (mutex_trylock(&vm->eviction_lock)) { | |
| 527 | + vm->saved_flags = memalloc_noreclaim_save(); | |
| 528 | + return true; | |
| 529 | + } | |
| 530 | + return false; | |
| 531 | +} | |
| 532 | + | |
| 533 | +static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm) | |
| 534 | +{ | |
| 535 | + memalloc_noreclaim_restore(vm->saved_flags); | |
| 536 | + mutex_unlock(&vm->eviction_lock); | |
| 537 | +} | |
| 538 | + | |
| 498 | 539 | #endif |
| @@ -597,7 +597,9 @@ static int amdgpu_vm_pt_alloc(struct amdgpu_device *adev, · 596 unmodified lines | ||
| 597 | 597 | if (entry->bo) |
| 598 | 598 | return 0; |
| 599 | 599 | |
| 600 | + amdgpu_vm_eviction_unlock(vm); | |
| 600 | 601 | r = amdgpu_vm_pt_create(adev, vm, cursor->level, immediate, &pt); |
| 602 | + amdgpu_vm_eviction_lock(vm); | |
| 601 | 603 | if (r) |
| 602 | 604 | return r; |
| 603 | 605 | |
| @@ -435,7 +435,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man, · 434 unmodified lines | ||
| 435 | 435 | if (place->flags & TTM_PL_FLAG_TOPDOWN) |
| 436 | 436 | vres->flags |= DRM_BUDDY_TOPDOWN_ALLOCATION; |
| 437 | 437 | |
| 438 | − if (fpfn || lpfn != man->size) | |
| 438 | + if (fpfn || lpfn != mgr->mm.size) | |
| 439 | 439 | /* Allocate blocks in desired range */ |
| 440 | 440 | vres->flags |= DRM_BUDDY_RANGE_ALLOCATION; |
| 441 | 441 | |
| @@ -32,7 +32,6 @@ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | #define RB_ENABLED (1 << 0) |
| 34 | 34 | #define RB4_ENABLED (1 << 1) |
| 35 | −#define MMSCH_DOORBELL_OFFSET 0x8 | |
| 36 | 35 | |
| 37 | 36 | #define MMSCH_VF_ENGINE_STATUS__PASS 0x1 |
| 38 | 37 | |
| @@ -45,6 +45,7 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin"); · 44 unmodified lines | ||
| 45 | 45 | MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin"); |
| 46 | 46 | MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin"); |
| 47 | 47 | MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin"); |
| 48 | +MODULE_FIRMWARE("amdgpu/psp_13_0_10_ta.bin"); | |
| 48 | 49 | |
| 49 | 50 | /* For large FW files the time to complete can be very long */ |
| 50 | 51 | #define USBC_PD_POLLING_LIMIT_S 240 |
| @@ -100,7 +100,6 @@ static int vcn_v4_0_sw_init(void *handle) · 99 unmodified lines | ||
| 100 | 100 | struct amdgpu_ring *ring; |
| 101 | 101 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 102 | 102 | int i, r; |
| 103 | − int vcn_doorbell_index = 0; | |
| 104 | 103 | |
| 105 | 104 | r = amdgpu_vcn_sw_init(adev); |
| 106 | 105 | if (r) |
| @@ -112,12 +111,6 @@ static int vcn_v4_0_sw_init(void *handle) · 5 unmodified lines | ||
| 112 | 111 | if (r) |
| 113 | 112 | return r; |
| 114 | 113 | |
| 115 | − if (amdgpu_sriov_vf(adev)) { | |
| 116 | − vcn_doorbell_index = adev->doorbell_index.vcn.vcn_ring0_1 - MMSCH_DOORBELL_OFFSET; | |
| 117 | − /* get DWORD offset */ | |
| 118 | − vcn_doorbell_index = vcn_doorbell_index << 1; | |
| 119 | − } | |
| 120 | − | |
| 121 | 114 | for (i = 0; i < adev->vcn.num_vcn_inst; i++) { |
| 122 | 115 | volatile struct amdgpu_vcn4_fw_shared *fw_shared; |
| 123 | 116 | |
| @@ -135,7 +128,7 @@ static int vcn_v4_0_sw_init(void *handle) · 11 unmodified lines | ||
| 135 | 128 | ring = &adev->vcn.inst[i].ring_enc[0]; |
| 136 | 129 | ring->use_doorbell = true; |
| 137 | 130 | if (amdgpu_sriov_vf(adev)) |
| 138 | − ring->doorbell_index = vcn_doorbell_index + i * (adev->vcn.num_enc_rings + 1) + 1; | |
| 131 | + ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + i * (adev->vcn.num_enc_rings + 1) + 1; | |
| 139 | 132 | else |
| 140 | 133 | ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + 8 * i; |
| 141 | 134 | |
| @@ -2495,442 +2495,444 @@ static const uint32_t cwsr_trap_gfx10_hex[] = { · 2494 unmodified lines | ||
| 2495 | 2495 | 0xbf9f0000, 0x00000000, |
| 2496 | 2496 | }; |
| 2497 | 2497 | static const uint32_t cwsr_trap_gfx11_hex[] = { |
| 2498 | − 0xbfa00001, 0xbfa0021e, | |
| 2498 | + 0xbfa00001, 0xbfa00221, | |
| 2499 | 2499 | 0xb0804006, 0xb8f8f802, |
| 2500 | 2500 | 0x9178ff78, 0x00020006, |
| 2501 | − 0xb8fbf803, 0xbf0d9f6d, | |
| 2502 | − 0xbfa20006, 0x8b6eff78, | |
| 2503 | − 0x00002000, 0xbfa10009, | |
| 2504 | − 0x8b6eff6d, 0x00ff0000, | |
| 2505 | − 0xbfa2001e, 0x8b6eff7b, | |
| 2506 | − 0x00000400, 0xbfa20041, | |
| 2507 | − 0xbf830010, 0xb8fbf803, | |
| 2508 | − 0xbfa0fffa, 0x8b6eff7b, | |
| 2509 | − 0x00000900, 0xbfa20015, | |
| 2510 | − 0x8b6eff7b, 0x000071ff, | |
| 2511 | − 0xbfa10008, 0x8b6fff7b, | |
| 2512 | − 0x00007080, 0xbfa10001, | |
| 2513 | − 0xbeee1287, 0xb8eff801, | |
| 2514 | − 0x846e8c6e, 0x8b6e6f6e, | |
| 2515 | − 0xbfa2000a, 0x8b6eff6d, | |
| 2516 | − 0x00ff0000, 0xbfa20007, | |
| 2517 | − 0xb8eef801, 0x8b6eff6e, | |
| 2518 | − 0x00000800, 0xbfa20003, | |
| 2501 | + 0xb8fbf803, 0xbf0d9e6d, | |
| 2502 | + 0xbfa10001, 0xbfbd0000, | |
| 2503 | + 0xbf0d9f6d, 0xbfa20006, | |
| 2504 | + 0x8b6eff78, 0x00002000, | |
| 2505 | + 0xbfa10009, 0x8b6eff6d, | |
| 2506 | + 0x00ff0000, 0xbfa2001e, | |
| 2519 | 2507 | 0x8b6eff7b, 0x00000400, |
| 2520 | − 0xbfa20026, 0xbefa4d82, | |
| 2521 | − 0xbf89fc07, 0x84fa887a, | |
| 2522 | − 0xf4005bbd, 0xf8000010, | |
| 2523 | − 0xbf89fc07, 0x846e976e, | |
| 2524 | − 0x9177ff77, 0x00800000, | |
| 2525 | − 0x8c776e77, 0xf4045bbd, | |
| 2526 | − 0xf8000000, 0xbf89fc07, | |
| 2527 | − 0xf4045ebd, 0xf8000008, | |
| 2528 | − 0xbf89fc07, 0x8bee6e6e, | |
| 2529 | − 0xbfa10001, 0xbe80486e, | |
| 2530 | − 0x8b6eff6d, 0x01ff0000, | |
| 2531 | − 0xbfa20005, 0x8c78ff78, | |
| 2532 | − 0x00002000, 0x80ec886c, | |
| 2533 | − 0x82ed806d, 0xbfa00005, | |
| 2534 | − 0x8b6eff6d, 0x01000000, | |
| 2535 | − 0xbfa20002, 0x806c846c, | |
| 2536 | − 0x826d806d, 0x8b6dff6d, | |
| 2537 | − 0x0000ffff, 0x8bfe7e7e, | |
| 2538 | − 0x8bea6a6a, 0xb978f802, | |
| 2539 | − 0xbe804a6c, 0x8b6dff6d, | |
| 2540 | − 0x0000ffff, 0xbefa0080, | |
| 2541 | − 0xb97a0283, 0xbeee007e, | |
| 2542 | − 0xbeef007f, 0xbefe0180, | |
| 2543 | − 0xbefe4d84, 0xbf89fc07, | |
| 2544 | − 0x8b7aff7f, 0x04000000, | |
| 2545 | − 0x847a857a, 0x8c6d7a6d, | |
| 2546 | − 0xbefa007e, 0x8b7bff7f, | |
| 2547 | − 0x0000ffff, 0xbefe00c1, | |
| 2548 | − 0xbeff00c1, 0xdca6c000, | |
| 2549 | − 0x007a0000, 0x7e000280, | |
| 2550 | − 0xbefe007a, 0xbeff007b, | |
| 2551 | − 0xb8fb02dc, 0x847b997b, | |
| 2552 | − 0xb8fa3b05, 0x807a817a, | |
| 2553 | − 0xbf0d997b, 0xbfa20002, | |
| 2554 | − 0x847a897a, 0xbfa00001, | |
| 2555 | − 0x847a8a7a, 0xb8fb1e06, | |
| 2556 | − 0x847b8a7b, 0x807a7b7a, | |
| 2508 | + 0xbfa20041, 0xbf830010, | |
| 2509 | + 0xb8fbf803, 0xbfa0fffa, | |
| 2510 | + 0x8b6eff7b, 0x00000900, | |
| 2511 | + 0xbfa20015, 0x8b6eff7b, | |
| 2512 | + 0x000071ff, 0xbfa10008, | |
| 2513 | + 0x8b6fff7b, 0x00007080, | |
| 2514 | + 0xbfa10001, 0xbeee1287, | |
| 2515 | + 0xb8eff801, 0x846e8c6e, | |
| 2516 | + 0x8b6e6f6e, 0xbfa2000a, | |
| 2517 | + 0x8b6eff6d, 0x00ff0000, | |
| 2518 | + 0xbfa20007, 0xb8eef801, | |
| 2519 | + 0x8b6eff6e, 0x00000800, | |
| 2520 | + 0xbfa20003, 0x8b6eff7b, | |
| 2521 | + 0x00000400, 0xbfa20026, | |
| 2522 | + 0xbefa4d82, 0xbf89fc07, | |
| 2523 | + 0x84fa887a, 0xf4005bbd, | |
| 2524 | + 0xf8000010, 0xbf89fc07, | |
| 2525 | + 0x846e976e, 0x9177ff77, | |
| 2526 | + 0x00800000, 0x8c776e77, | |
| 2527 | + 0xf4045bbd, 0xf8000000, | |
| 2528 | + 0xbf89fc07, 0xf4045ebd, | |
| 2529 | + 0xf8000008, 0xbf89fc07, | |
| 2530 | + 0x8bee6e6e, 0xbfa10001, | |
| 2531 | + 0xbe80486e, 0x8b6eff6d, | |
| 2532 | + 0x01ff0000, 0xbfa20005, | |
| 2533 | + 0x8c78ff78, 0x00002000, | |
| 2534 | + 0x80ec886c, 0x82ed806d, | |
| 2535 | + 0xbfa00005, 0x8b6eff6d, | |
| 2536 | + 0x01000000, 0xbfa20002, | |
| 2537 | + 0x806c846c, 0x826d806d, | |
| 2538 | + 0x8b6dff6d, 0x0000ffff, | |
| 2539 | + 0x8bfe7e7e, 0x8bea6a6a, | |
| 2540 | + 0xb978f802, 0xbe804a6c, | |
| 2541 | + 0x8b6dff6d, 0x0000ffff, | |
| 2542 | + 0xbefa0080, 0xb97a0283, | |
| 2543 | + 0xbeee007e, 0xbeef007f, | |
| 2544 | + 0xbefe0180, 0xbefe4d84, | |
| 2545 | + 0xbf89fc07, 0x8b7aff7f, | |
| 2546 | + 0x04000000, 0x847a857a, | |
| 2547 | + 0x8c6d7a6d, 0xbefa007e, | |
| 2557 | 2548 | 0x8b7bff7f, 0x0000ffff, |
| 2558 | − 0x807aff7a, 0x00000200, | |
| 2559 | − 0x807a7e7a, 0x827b807b, | |
| 2560 | − 0xd7610000, 0x00010870, | |
| 2561 | − 0xd7610000, 0x00010a71, | |
| 2562 | − 0xd7610000, 0x00010c72, | |
| 2563 | − 0xd7610000, 0x00010e73, | |
| 2564 | − 0xd7610000, 0x00011074, | |
| 2565 | − 0xd7610000, 0x00011275, | |
| 2566 | − 0xd7610000, 0x00011476, | |
| 2567 | − 0xd7610000, 0x00011677, | |
| 2568 | − 0xd7610000, 0x00011a79, | |
| 2569 | − 0xd7610000, 0x00011c7e, | |
| 2570 | − 0xd7610000, 0x00011e7f, | |
| 2571 | − 0xbefe00ff, 0x00003fff, | |
| 2572 | − 0xbeff0080, 0xdca6c040, | |
| 2573 | − 0x007a0000, 0xd760007a, | |
| 2574 | − 0x00011d00, 0xd760007b, | |
| 2575 | − 0x00011f00, 0xbefe007a, | |
| 2576 | − 0xbeff007b, 0xbef4007e, | |
| 2577 | − 0x8b75ff7f, 0x0000ffff, | |
| 2578 | − 0x8c75ff75, 0x00040000, | |
| 2579 | − 0xbef60080, 0xbef700ff, | |
| 2580 | − 0x10807fac, 0xbef1007d, | |
| 2581 | − 0xbef00080, 0xb8f302dc, | |
| 2582 | − 0x84739973, 0xbefe00c1, | |
| 2583 | − 0x857d9973, 0x8b7d817d, | |
| 2584 | − 0xbf06817d, 0xbfa20002, | |
| 2585 | − 0xbeff0080, 0xbfa00002, | |
| 2586 | − 0xbeff00c1, 0xbfa00009, | |
| 2549 | + 0xbefe00c1, 0xbeff00c1, | |
| 2550 | + 0xdca6c000, 0x007a0000, | |
| 2551 | + 0x7e000280, 0xbefe007a, | |
| 2552 | + 0xbeff007b, 0xb8fb02dc, | |
| 2553 | + 0x847b997b, 0xb8fa3b05, | |
| 2554 | + 0x807a817a, 0xbf0d997b, | |
| 2555 | + 0xbfa20002, 0x847a897a, | |
| 2556 | + 0xbfa00001, 0x847a8a7a, | |
| 2557 | + 0xb8fb1e06, 0x847b8a7b, | |
| 2558 | + 0x807a7b7a, 0x8b7bff7f, | |
| 2559 | + 0x0000ffff, 0x807aff7a, | |
| 2560 | + 0x00000200, 0x807a7e7a, | |
| 2561 | + 0x827b807b, 0xd7610000, | |
| 2562 | + 0x00010870, 0xd7610000, | |
| 2563 | + 0x00010a71, 0xd7610000, | |
| 2564 | + 0x00010c72, 0xd7610000, | |
| 2565 | + 0x00010e73, 0xd7610000, | |
| 2566 | + 0x00011074, 0xd7610000, | |
| 2567 | + 0x00011275, 0xd7610000, | |
| 2568 | + 0x00011476, 0xd7610000, | |
| 2569 | + 0x00011677, 0xd7610000, | |
| 2570 | + 0x00011a79, 0xd7610000, | |
| 2571 | + 0x00011c7e, 0xd7610000, | |
| 2572 | + 0x00011e7f, 0xbefe00ff, | |
| 2573 | + 0x00003fff, 0xbeff0080, | |
| 2574 | + 0xdca6c040, 0x007a0000, | |
| 2575 | + 0xd760007a, 0x00011d00, | |
| 2576 | + 0xd760007b, 0x00011f00, | |
| 2577 | + 0xbefe007a, 0xbeff007b, | |
| 2578 | + 0xbef4007e, 0x8b75ff7f, | |
| 2579 | + 0x0000ffff, 0x8c75ff75, | |
| 2580 | + 0x00040000, 0xbef60080, | |
| 2581 | + 0xbef700ff, 0x10807fac, | |
| 2582 | + 0xbef1007d, 0xbef00080, | |
| 2583 | + 0xb8f302dc, 0x84739973, | |
| 2584 | + 0xbefe00c1, 0x857d9973, | |
| 2585 | + 0x8b7d817d, 0xbf06817d, | |
| 2586 | + 0xbfa20002, 0xbeff0080, | |
| 2587 | + 0xbfa00002, 0xbeff00c1, | |
| 2588 | + 0xbfa00009, 0xbef600ff, | |
| 2589 | + 0x01000000, 0xe0685080, | |
| 2590 | + 0x701d0100, 0xe0685100, | |
| 2591 | + 0x701d0200, 0xe0685180, | |
| 2592 | + 0x701d0300, 0xbfa00008, | |
| 2587 | 2593 | 0xbef600ff, 0x01000000, |
| 2588 | − 0xe0685080, 0x701d0100, | |
| 2589 | − 0xe0685100, 0x701d0200, | |
| 2590 | − 0xe0685180, 0x701d0300, | |
| 2591 | − 0xbfa00008, 0xbef600ff, | |
| 2592 | − 0x01000000, 0xe0685100, | |
| 2593 | − 0x701d0100, 0xe0685200, | |
| 2594 | − 0x701d0200, 0xe0685300, | |
| 2595 | − 0x701d0300, 0xb8f03b05, | |
| 2596 | − 0x80708170, 0xbf0d9973, | |
| 2597 | − 0xbfa20002, 0x84708970, | |
| 2598 | − 0xbfa00001, 0x84708a70, | |
| 2599 | − 0xb8fa1e06, 0x847a8a7a, | |
| 2600 | − 0x80707a70, 0x8070ff70, | |
| 2601 | − 0x00000200, 0xbef600ff, | |
| 2602 | − 0x01000000, 0x7e000280, | |
| 2603 | − 0x7e020280, 0x7e040280, | |
| 2604 | − 0xbefd0080, 0xd7610002, | |
| 2605 | − 0x0000fa71, 0x807d817d, | |
| 2606 | − 0xd7610002, 0x0000fa6c, | |
| 2607 | − 0x807d817d, 0x917aff6d, | |
| 2608 | − 0x80000000, 0xd7610002, | |
| 2609 | − 0x0000fa7a, 0x807d817d, | |
| 2610 | − 0xd7610002, 0x0000fa6e, | |
| 2611 | − 0x807d817d, 0xd7610002, | |
| 2612 | − 0x0000fa6f, 0x807d817d, | |
| 2613 | − 0xd7610002, 0x0000fa78, | |
| 2614 | − 0x807d817d, 0xb8faf803, | |
| 2615 | − 0xd7610002, 0x0000fa7a, | |
| 2616 | − 0x807d817d, 0xd7610002, | |
| 2617 | − 0x0000fa7b, 0x807d817d, | |
| 2618 | − 0xb8f1f801, 0xd7610002, | |
| 2619 | − 0x0000fa71, 0x807d817d, | |
| 2620 | − 0xb8f1f814, 0xd7610002, | |
| 2621 | − 0x0000fa71, 0x807d817d, | |
| 2622 | − 0xb8f1f815, 0xd7610002, | |
| 2623 | − 0x0000fa71, 0x807d817d, | |
| 2624 | − 0xbefe00ff, 0x0000ffff, | |
| 2625 | − 0xbeff0080, 0xe0685000, | |
| 2626 | − 0x701d0200, 0xbefe00c1, | |
| 2594 | + 0xe0685100, 0x701d0100, | |
| 2595 | + 0xe0685200, 0x701d0200, | |
| 2596 | + 0xe0685300, 0x701d0300, | |
| 2627 | 2597 | 0xb8f03b05, 0x80708170, |
| 2628 | 2598 | 0xbf0d9973, 0xbfa20002, |
| 2629 | 2599 | 0x84708970, 0xbfa00001, |
| 2630 | 2600 | 0x84708a70, 0xb8fa1e06, |
| 2631 | 2601 | 0x847a8a7a, 0x80707a70, |
| 2602 | + 0x8070ff70, 0x00000200, | |
| 2632 | 2603 | 0xbef600ff, 0x01000000, |
| 2633 | − 0xbef90080, 0xbefd0080, | |
| 2634 | − 0xbf800000, 0xbe804100, | |
| 2635 | − 0xbe824102, 0xbe844104, | |
| 2636 | − 0xbe864106, 0xbe884108, | |
| 2637 | − 0xbe8a410a, 0xbe8c410c, | |
| 2638 | − 0xbe8e410e, 0xd7610002, | |
| 2639 | − 0x0000f200, 0x80798179, | |
| 2640 | − 0xd7610002, 0x0000f201, | |
| 2604 | + 0x7e000280, 0x7e020280, | |
| 2605 | + 0x7e040280, 0xbefd0080, | |
| 2606 | + 0xd7610002, 0x0000fa71, | |
| 2607 | + 0x807d817d, 0xd7610002, | |
| 2608 | + 0x0000fa6c, 0x807d817d, | |
| 2609 | + 0x917aff6d, 0x80000000, | |
| 2610 | + 0xd7610002, 0x0000fa7a, | |
| 2611 | + 0x807d817d, 0xd7610002, | |
| 2612 | + 0x0000fa6e, 0x807d817d, | |
| 2613 | + 0xd7610002, 0x0000fa6f, | |
| 2614 | + 0x807d817d, 0xd7610002, | |
| 2615 | + 0x0000fa78, 0x807d817d, | |
| 2616 | + 0xb8faf803, 0xd7610002, | |
| 2617 | + 0x0000fa7a, 0x807d817d, | |
| 2618 | + 0xd7610002, 0x0000fa7b, | |
| 2619 | + 0x807d817d, 0xb8f1f801, | |
| 2620 | + 0xd7610002, 0x0000fa71, | |
| 2621 | + 0x807d817d, 0xb8f1f814, | |
| 2622 | + 0xd7610002, 0x0000fa71, | |
| 2623 | + 0x807d817d, 0xb8f1f815, | |
| 2624 | + 0xd7610002, 0x0000fa71, | |
| 2625 | + 0x807d817d, 0xbefe00ff, | |
| 2626 | + 0x0000ffff, 0xbeff0080, | |
| 2627 | + 0xe0685000, 0x701d0200, | |
| 2628 | + 0xbefe00c1, 0xb8f03b05, | |
| 2629 | + 0x80708170, 0xbf0d9973, | |
| 2630 | + 0xbfa20002, 0x84708970, | |
| 2631 | + 0xbfa00001, 0x84708a70, | |
| 2632 | + 0xb8fa1e06, 0x847a8a7a, | |
| 2633 | + 0x80707a70, 0xbef600ff, | |
| 2634 | + 0x01000000, 0xbef90080, | |
| 2635 | + 0xbefd0080, 0xbf800000, | |
| 2636 | + 0xbe804100, 0xbe824102, | |
| 2637 | + 0xbe844104, 0xbe864106, | |
| 2638 | + 0xbe884108, 0xbe8a410a, | |
| 2639 | + 0xbe8c410c, 0xbe8e410e, | |
| 2640 | + 0xd7610002, 0x0000f200, | |
| 2641 | 2641 | 0x80798179, 0xd7610002, |
| 2642 | − 0x0000f202, 0x80798179, | |
| 2643 | − 0xd7610002, 0x0000f203, | |
| 2642 | + 0x0000f201, 0x80798179, | |
| 2643 | + 0xd7610002, 0x0000f202, | |
| 2644 | 2644 | 0x80798179, 0xd7610002, |
| 2645 | − 0x0000f204, 0x80798179, | |
| 2646 | − 0xd7610002, 0x0000f205, | |
| 2645 | + 0x0000f203, 0x80798179, | |
| 2646 | + 0xd7610002, 0x0000f204, | |
| 2647 | 2647 | 0x80798179, 0xd7610002, |
| 2648 | − 0x0000f206, 0x80798179, | |
| 2649 | − 0xd7610002, 0x0000f207, | |
| 2648 | + 0x0000f205, 0x80798179, | |
| 2649 | + 0xd7610002, 0x0000f206, | |
| 2650 | 2650 | 0x80798179, 0xd7610002, |
| 2651 | − 0x0000f208, 0x80798179, | |
| 2652 | − 0xd7610002, 0x0000f209, | |
| 2651 | + 0x0000f207, 0x80798179, | |
| 2652 | + 0xd7610002, 0x0000f208, | |
| 2653 | 2653 | 0x80798179, 0xd7610002, |
| 2654 | − 0x0000f20a, 0x80798179, | |
| 2655 | − 0xd7610002, 0x0000f20b, | |
| 2654 | + 0x0000f209, 0x80798179, | |
| 2655 | + 0xd7610002, 0x0000f20a, | |
| 2656 | 2656 | 0x80798179, 0xd7610002, |
| 2657 | − 0x0000f20c, 0x80798179, | |
| 2658 | − 0xd7610002, 0x0000f20d, | |
| 2657 | + 0x0000f20b, 0x80798179, | |
| 2658 | + 0xd7610002, 0x0000f20c, | |
| 2659 | 2659 | 0x80798179, 0xd7610002, |
| 2660 | − 0x0000f20e, 0x80798179, | |
| 2661 | − 0xd7610002, 0x0000f20f, | |
| 2662 | − 0x80798179, 0xbf06a079, | |
| 2663 | − 0xbfa10006, 0xe0685000, | |
| 2664 | − 0x701d0200, 0x8070ff70, | |
| 2665 | − 0x00000080, 0xbef90080, | |
| 2666 | − 0x7e040280, 0x807d907d, | |
| 2667 | − 0xbf0aff7d, 0x00000060, | |
| 2668 | − 0xbfa2ffbc, 0xbe804100, | |
| 2669 | − 0xbe824102, 0xbe844104, | |
| 2670 | − 0xbe864106, 0xbe884108, | |
| 2671 | − 0xbe8a410a, 0xd7610002, | |
| 2672 | − 0x0000f200, 0x80798179, | |
| 2673 | − 0xd7610002, 0x0000f201, | |
| 2660 | + 0x0000f20d, 0x80798179, | |
| 2661 | + 0xd7610002, 0x0000f20e, | |
| 2674 | 2662 | 0x80798179, 0xd7610002, |
| 2675 | − 0x0000f202, 0x80798179, | |
| 2676 | − 0xd7610002, 0x0000f203, | |
| 2663 | + 0x0000f20f, 0x80798179, | |
| 2664 | + 0xbf06a079, 0xbfa10006, | |
| 2665 | + 0xe0685000, 0x701d0200, | |
| 2666 | + 0x8070ff70, 0x00000080, | |
| 2667 | + 0xbef90080, 0x7e040280, | |
| 2668 | + 0x807d907d, 0xbf0aff7d, | |
| 2669 | + 0x00000060, 0xbfa2ffbc, | |
| 2670 | + 0xbe804100, 0xbe824102, | |
| 2671 | + 0xbe844104, 0xbe864106, | |
| 2672 | + 0xbe884108, 0xbe8a410a, | |
| 2673 | + 0xd7610002, 0x0000f200, | |
| 2677 | 2674 | 0x80798179, 0xd7610002, |
| 2678 | − 0x0000f204, 0x80798179, | |
| 2679 | − 0xd7610002, 0x0000f205, | |
| 2675 | + 0x0000f201, 0x80798179, | |
| 2676 | + 0xd7610002, 0x0000f202, | |
| 2680 | 2677 | 0x80798179, 0xd7610002, |
| 2681 | − 0x0000f206, 0x80798179, | |
| 2682 | − 0xd7610002, 0x0000f207, | |
| 2678 | + 0x0000f203, 0x80798179, | |
| 2679 | + 0xd7610002, 0x0000f204, | |
| 2683 | 2680 | 0x80798179, 0xd7610002, |
| 2684 | − 0x0000f208, 0x80798179, | |
| 2685 | − 0xd7610002, 0x0000f209, | |
| 2681 | + 0x0000f205, 0x80798179, | |
| 2682 | + 0xd7610002, 0x0000f206, | |
| 2686 | 2683 | 0x80798179, 0xd7610002, |
| 2687 | − 0x0000f20a, 0x80798179, | |
| 2688 | − 0xd7610002, 0x0000f20b, | |
| 2689 | − 0x80798179, 0xe0685000, | |
| 2690 | − 0x701d0200, 0xbefe00c1, | |
| 2691 | − 0x857d9973, 0x8b7d817d, | |
| 2692 | − 0xbf06817d, 0xbfa20002, | |
| 2693 | − 0xbeff0080, 0xbfa00001, | |
| 2694 | − 0xbeff00c1, 0xb8fb4306, | |
| 2695 | − 0x8b7bc17b, 0xbfa10044, | |
| 2696 | − 0xbfbd0000, 0x8b7aff6d, | |
| 2697 | − 0x80000000, 0xbfa10040, | |
| 2698 | − 0x847b867b, 0x847b827b, | |
| 2699 | − 0xbef6007b, 0xb8f03b05, | |
| 2700 | − 0x80708170, 0xbf0d9973, | |
| 2701 | − 0xbfa20002, 0x84708970, | |
| 2702 | − 0xbfa00001, 0x84708a70, | |
| 2703 | − 0xb8fa1e06, 0x847a8a7a, | |
| 2704 | − 0x80707a70, 0x8070ff70, | |
| 2705 | − 0x00000200, 0x8070ff70, | |
| 2706 | − 0x00000080, 0xbef600ff, | |
| 2707 | − 0x01000000, 0xd71f0000, | |
| 2708 | − 0x000100c1, 0xd7200000, | |
| 2709 | − 0x000200c1, 0x16000084, | |
| 2710 | − 0x857d9973, 0x8b7d817d, | |
| 2711 | − 0xbf06817d, 0xbefd0080, | |
| 2712 | − 0xbfa20012, 0xbe8300ff, | |
| 2713 | − 0x00000080, 0xbf800000, | |
| 2714 | − 0xbf800000, 0xbf800000, | |
| 2715 | − 0xd8d80000, 0x01000000, | |
| 2716 | − 0xbf890000, 0xe0685000, | |
| 2717 | − 0x701d0100, 0x807d037d, | |
| 2718 | − 0x80700370, 0xd5250000, | |
| 2719 | − 0x0001ff00, 0x00000080, | |
| 2720 | − 0xbf0a7b7d, 0xbfa2fff4, | |
| 2721 | − 0xbfa00011, 0xbe8300ff, | |
| 2722 | − 0x00000100, 0xbf800000, | |
| 2723 | − 0xbf800000, 0xbf800000, | |
| 2724 | − 0xd8d80000, 0x01000000, | |
| 2725 | − 0xbf890000, 0xe0685000, | |
| 2726 | − 0x701d0100, 0x807d037d, | |
| 2727 | − 0x80700370, 0xd5250000, | |
| 2728 | − 0x0001ff00, 0x00000100, | |
| 2729 | − 0xbf0a7b7d, 0xbfa2fff4, | |
| 2684 | + 0x0000f207, 0x80798179, | |
| 2685 | + 0xd7610002, 0x0000f208, | |
| 2686 | + 0x80798179, 0xd7610002, | |
| 2687 | + 0x0000f209, 0x80798179, | |
| 2688 | + 0xd7610002, 0x0000f20a, | |
| 2689 | + 0x80798179, 0xd7610002, | |
| 2690 | + 0x0000f20b, 0x80798179, | |
| 2691 | + 0xe0685000, 0x701d0200, | |
| 2730 | 2692 | 0xbefe00c1, 0x857d9973, |
| 2731 | 2693 | 0x8b7d817d, 0xbf06817d, |
| 2732 | − 0xbfa20004, 0xbef000ff, | |
| 2733 | − 0x00000200, 0xbeff0080, | |
| 2734 | − 0xbfa00003, 0xbef000ff, | |
| 2735 | − 0x00000400, 0xbeff00c1, | |
| 2736 | − 0xb8fb3b05, 0x807b817b, | |
| 2737 | − 0x847b827b, 0x857d9973, | |
| 2694 | + 0xbfa20002, 0xbeff0080, | |
| 2695 | + 0xbfa00001, 0xbeff00c1, | |
| 2696 | + 0xb8fb4306, 0x8b7bc17b, | |
| 2697 | + 0xbfa10044, 0xbfbd0000, | |
| 2698 | + 0x8b7aff6d, 0x80000000, | |
| 2699 | + 0xbfa10040, 0x847b867b, | |
| 2700 | + 0x847b827b, 0xbef6007b, | |
| 2701 | + 0xb8f03b05, 0x80708170, | |
| 2702 | + 0xbf0d9973, 0xbfa20002, | |
| 2703 | + 0x84708970, 0xbfa00001, | |
| 2704 | + 0x84708a70, 0xb8fa1e06, | |
| 2705 | + 0x847a8a7a, 0x80707a70, | |
| 2706 | + 0x8070ff70, 0x00000200, | |
| 2707 | + 0x8070ff70, 0x00000080, | |
| 2708 | + 0xbef600ff, 0x01000000, | |
| 2709 | + 0xd71f0000, 0x000100c1, | |
| 2710 | + 0xd7200000, 0x000200c1, | |
| 2711 | + 0x16000084, 0x857d9973, | |
| 2738 | 2712 | 0x8b7d817d, 0xbf06817d, |
| 2739 | − 0xbfa20017, 0xbef600ff, | |
| 2740 | − 0x01000000, 0xbefd0084, | |
| 2741 | − 0xbf0a7b7d, 0xbfa10037, | |
| 2742 | − 0x7e008700, 0x7e028701, | |
| 2743 | − 0x7e048702, 0x7e068703, | |
| 2744 | − 0xe0685000, 0x701d0000, | |
| 2745 | − 0xe0685080, 0x701d0100, | |
| 2746 | − 0xe0685100, 0x701d0200, | |
| 2747 | − 0xe0685180, 0x701d0300, | |
| 2748 | − 0x807d847d, 0x8070ff70, | |
| 2749 | − 0x00000200, 0xbf0a7b7d, | |
| 2750 | − 0xbfa2ffef, 0xbfa00025, | |
| 2713 | + 0xbefd0080, 0xbfa20012, | |
| 2714 | + 0xbe8300ff, 0x00000080, | |
| 2715 | + 0xbf800000, 0xbf800000, | |
| 2716 | + 0xbf800000, 0xd8d80000, | |
| 2717 | + 0x01000000, 0xbf890000, | |
| 2718 | + 0xe0685000, 0x701d0100, | |
| 2719 | + 0x807d037d, 0x80700370, | |
| 2720 | + 0xd5250000, 0x0001ff00, | |
| 2721 | + 0x00000080, 0xbf0a7b7d, | |
| 2722 | + 0xbfa2fff4, 0xbfa00011, | |
| 2723 | + 0xbe8300ff, 0x00000100, | |
| 2724 | + 0xbf800000, 0xbf800000, | |
| 2725 | + 0xbf800000, 0xd8d80000, | |
| 2726 | + 0x01000000, 0xbf890000, | |
| 2727 | + 0xe0685000, 0x701d0100, | |
| 2728 | + 0x807d037d, 0x80700370, | |
| 2729 | + 0xd5250000, 0x0001ff00, | |
| 2730 | + 0x00000100, 0xbf0a7b7d, | |
| 2731 | + 0xbfa2fff4, 0xbefe00c1, | |
| 2732 | + 0x857d9973, 0x8b7d817d, | |
| 2733 | + 0xbf06817d, 0xbfa20004, | |
| 2734 | + 0xbef000ff, 0x00000200, | |
| 2735 | + 0xbeff0080, 0xbfa00003, | |
| 2736 | + 0xbef000ff, 0x00000400, | |
| 2737 | + 0xbeff00c1, 0xb8fb3b05, | |
| 2738 | + 0x807b817b, 0x847b827b, | |
| 2739 | + 0x857d9973, 0x8b7d817d, | |
| 2740 | + 0xbf06817d, 0xbfa20017, | |
| 2751 | 2741 | 0xbef600ff, 0x01000000, |
| 2752 | 2742 | 0xbefd0084, 0xbf0a7b7d, |
| 2753 | − 0xbfa10011, 0x7e008700, | |
| 2743 | + 0xbfa10037, 0x7e008700, | |
| 2754 | 2744 | 0x7e028701, 0x7e048702, |
| 2755 | 2745 | 0x7e068703, 0xe0685000, |
| 2756 | − 0x701d0000, 0xe0685100, | |
| 2757 | − 0x701d0100, 0xe0685200, | |
| 2758 | − 0x701d0200, 0xe0685300, | |
| 2746 | + 0x701d0000, 0xe0685080, | |
| 2747 | + 0x701d0100, 0xe0685100, | |
| 2748 | + 0x701d0200, 0xe0685180, | |
| 2759 | 2749 | 0x701d0300, 0x807d847d, |
| 2760 | − 0x8070ff70, 0x00000400, | |
| 2750 | + 0x8070ff70, 0x00000200, | |
| 2761 | 2751 | 0xbf0a7b7d, 0xbfa2ffef, |
| 2762 | − 0xb8fb1e06, 0x8b7bc17b, | |
| 2763 | − 0xbfa1000c, 0x847b837b, | |
| 2764 | − 0x807b7d7b, 0xbefe00c1, | |
| 2765 | − 0xbeff0080, 0x7e008700, | |
| 2752 | + 0xbfa00025, 0xbef600ff, | |
| 2753 | + 0x01000000, 0xbefd0084, | |
| 2754 | + 0xbf0a7b7d, 0xbfa10011, | |
| 2755 | + 0x7e008700, 0x7e028701, | |
| 2756 | + 0x7e048702, 0x7e068703, | |
| 2766 | 2757 | 0xe0685000, 0x701d0000, |
| 2767 | − 0x807d817d, 0x8070ff70, | |
| 2768 | − 0x00000080, 0xbf0a7b7d, | |
| 2769 | − 0xbfa2fff8, 0xbfa00146, | |
| 2770 | − 0xbef4007e, 0x8b75ff7f, | |
| 2771 | − 0x0000ffff, 0x8c75ff75, | |
| 2772 | − 0x00040000, 0xbef60080, | |
| 2773 | − 0xbef700ff, 0x10807fac, | |
| 2774 | − 0xb8f202dc, 0x84729972, | |
| 2775 | − 0x8b6eff7f, 0x04000000, | |
| 2776 | − 0xbfa1003a, 0xbefe00c1, | |
| 2777 | − 0x857d9972, 0x8b7d817d, | |
| 2778 | − 0xbf06817d, 0xbfa20002, | |
| 2779 | − 0xbeff0080, 0xbfa00001, | |
| 2780 | − 0xbeff00c1, 0xb8ef4306, | |
| 2781 | − 0x8b6fc16f, 0xbfa1002f, | |
| 2782 | − 0x846f866f, 0x846f826f, | |
| 2783 | − 0xbef6006f, 0xb8f83b05, | |
| 2784 | − 0x80788178, 0xbf0d9972, | |
| 2785 | − 0xbfa20002, 0x84788978, | |
| 2786 | − 0xbfa00001, 0x84788a78, | |
| 2787 | − 0xb8ee1e06, 0x846e8a6e, | |
| 2788 | − 0x80786e78, 0x8078ff78, | |
| 2789 | − 0x00000200, 0x8078ff78, | |
| 2790 | − 0x00000080, 0xbef600ff, | |
| 2791 | − 0x01000000, 0x857d9972, | |
| 2792 | − 0x8b7d817d, 0xbf06817d, | |
| 2793 | − 0xbefd0080, 0xbfa2000c, | |
| 2794 | − 0xe0500000, 0x781d0000, | |
| 2795 | − 0xbf8903f7, 0xdac00000, | |
| 2796 | − 0x00000000, 0x807dff7d, | |
| 2797 | − 0x00000080, 0x8078ff78, | |
| 2798 | − 0x00000080, 0xbf0a6f7d, | |
| 2799 | − 0xbfa2fff5, 0xbfa0000b, | |
| 2800 | − 0xe0500000, 0x781d0000, | |
| 2801 | − 0xbf8903f7, 0xdac00000, | |
| 2802 | − 0x00000000, 0x807dff7d, | |
| 2803 | − 0x00000100, 0x8078ff78, | |
| 2804 | − 0x00000100, 0xbf0a6f7d, | |
| 2805 | − 0xbfa2fff5, 0xbef80080, | |
| 2758 | + 0xe0685100, 0x701d0100, | |
| 2759 | + 0xe0685200, 0x701d0200, | |
| 2760 | + 0xe0685300, 0x701d0300, | |
| 2761 | + 0x807d847d, 0x8070ff70, | |
| 2762 | + 0x00000400, 0xbf0a7b7d, | |
| 2763 | + 0xbfa2ffef, 0xb8fb1e06, | |
| 2764 | + 0x8b7bc17b, 0xbfa1000c, | |
| 2765 | + 0x847b837b, 0x807b7d7b, | |
| 2766 | + 0xbefe00c1, 0xbeff0080, | |
| 2767 | + 0x7e008700, 0xe0685000, | |
| 2768 | + 0x701d0000, 0x807d817d, | |
| 2769 | + 0x8070ff70, 0x00000080, | |
| 2770 | + 0xbf0a7b7d, 0xbfa2fff8, | |
| 2771 | + 0xbfa00146, 0xbef4007e, | |
| 2772 | + 0x8b75ff7f, 0x0000ffff, | |
| 2773 | + 0x8c75ff75, 0x00040000, | |
| 2774 | + 0xbef60080, 0xbef700ff, | |
| 2775 | + 0x10807fac, 0xb8f202dc, | |
| 2776 | + 0x84729972, 0x8b6eff7f, | |
| 2777 | + 0x04000000, 0xbfa1003a, | |
| 2806 | 2778 | 0xbefe00c1, 0x857d9972, |
| 2807 | 2779 | 0x8b7d817d, 0xbf06817d, |
| 2808 | 2780 | 0xbfa20002, 0xbeff0080, |
| 2809 | 2781 | 0xbfa00001, 0xbeff00c1, |
| 2810 | − 0xb8ef3b05, 0x806f816f, | |
| 2811 | − 0x846f826f, 0x857d9972, | |
| 2812 | − 0x8b7d817d, 0xbf06817d, | |
| 2813 | − 0xbfa20024, 0xbef600ff, | |
| 2814 | − 0x01000000, 0xbeee0078, | |
| 2782 | + 0xb8ef4306, 0x8b6fc16f, | |
| 2783 | + 0xbfa1002f, 0x846f866f, | |
| 2784 | + 0x846f826f, 0xbef6006f, | |
| 2785 | + 0xb8f83b05, 0x80788178, | |
| 2786 | + 0xbf0d9972, 0xbfa20002, | |
| 2787 | + 0x84788978, 0xbfa00001, | |
| 2788 | + 0x84788a78, 0xb8ee1e06, | |
| 2789 | + 0x846e8a6e, 0x80786e78, | |
| 2815 | 2790 | 0x8078ff78, 0x00000200, |
| 2816 | − 0xbefd0084, 0xbf0a6f7d, | |
| 2817 | − 0xbfa10050, 0xe0505000, | |
| 2818 | − 0x781d0000, 0xe0505080, | |
| 2819 | − 0x781d0100, 0xe0505100, | |
| 2820 | − 0x781d0200, 0xe0505180, | |
| 2821 | − 0x781d0300, 0xbf8903f7, | |
| 2822 | − 0x7e008500, 0x7e028501, | |
| 2823 | − 0x7e048502, 0x7e068503, | |
| 2824 | − 0x807d847d, 0x8078ff78, | |
| 2825 | − 0x00000200, 0xbf0a6f7d, | |
| 2826 | − 0xbfa2ffee, 0xe0505000, | |
| 2827 | − 0x6e1d0000, 0xe0505080, | |
| 2828 | − 0x6e1d0100, 0xe0505100, | |
| 2829 | − 0x6e1d0200, 0xe0505180, | |
| 2830 | − 0x6e1d0300, 0xbf8903f7, | |
| 2831 | − 0xbfa00034, 0xbef600ff, | |
| 2832 | − 0x01000000, 0xbeee0078, | |
| 2833 | − 0x8078ff78, 0x00000400, | |
| 2834 | − 0xbefd0084, 0xbf0a6f7d, | |
| 2835 | − 0xbfa10012, 0xe0505000, | |
| 2836 | − 0x781d0000, 0xe0505100, | |
| 2837 | − 0x781d0100, 0xe0505200, | |
| 2838 | − 0x781d0200, 0xe0505300, | |
| 2839 | − 0x781d0300, 0xbf8903f7, | |
| 2840 | − 0x7e008500, 0x7e028501, | |
| 2841 | − 0x7e048502, 0x7e068503, | |
| 2842 | − 0x807d847d, 0x8078ff78, | |
| 2843 | − 0x00000400, 0xbf0a6f7d, | |
| 2844 | − 0xbfa2ffee, 0xb8ef1e06, | |
| 2845 | − 0x8b6fc16f, 0xbfa1000e, | |
| 2846 | − 0x846f836f, 0x806f7d6f, | |
| 2847 | − 0xbefe00c1, 0xbeff0080, | |
| 2791 | + 0x8078ff78, 0x00000080, | |
| 2792 | + 0xbef600ff, 0x01000000, | |
| 2793 | + 0x857d9972, 0x8b7d817d, | |
| 2794 | + 0xbf06817d, 0xbefd0080, | |
| 2795 | + 0xbfa2000c, 0xe0500000, | |
| 2796 | + 0x781d0000, 0xbf8903f7, | |
| 2797 | + 0xdac00000, 0x00000000, | |
| 2798 | + 0x807dff7d, 0x00000080, | |
| 2799 | + 0x8078ff78, 0x00000080, | |
| 2800 | + 0xbf0a6f7d, 0xbfa2fff5, | |
| 2801 | + 0xbfa0000b, 0xe0500000, | |
| 2802 | + 0x781d0000, 0xbf8903f7, | |
| 2803 | + 0xdac00000, 0x00000000, | |
| 2804 | + 0x807dff7d, 0x00000100, | |
| 2805 | + 0x8078ff78, 0x00000100, | |
| 2806 | + 0xbf0a6f7d, 0xbfa2fff5, | |
| 2807 | + 0xbef80080, 0xbefe00c1, | |
| 2808 | + 0x857d9972, 0x8b7d817d, | |
| 2809 | + 0xbf06817d, 0xbfa20002, | |
| 2810 | + 0xbeff0080, 0xbfa00001, | |
| 2811 | + 0xbeff00c1, 0xb8ef3b05, | |
| 2812 | + 0x806f816f, 0x846f826f, | |
| 2813 | + 0x857d9972, 0x8b7d817d, | |
| 2814 | + 0xbf06817d, 0xbfa20024, | |
| 2815 | + 0xbef600ff, 0x01000000, | |
| 2816 | + 0xbeee0078, 0x8078ff78, | |
| 2817 | + 0x00000200, 0xbefd0084, | |
| 2818 | + 0xbf0a6f7d, 0xbfa10050, | |
| 2848 | 2819 | 0xe0505000, 0x781d0000, |
| 2820 | + 0xe0505080, 0x781d0100, | |
| 2821 | + 0xe0505100, 0x781d0200, | |
| 2822 | + 0xe0505180, 0x781d0300, | |
| 2849 | 2823 | 0xbf8903f7, 0x7e008500, |
| 2850 | − 0x807d817d, 0x8078ff78, | |
| 2851 | − 0x00000080, 0xbf0a6f7d, | |
| 2852 | − 0xbfa2fff7, 0xbeff00c1, | |
| 2824 | + 0x7e028501, 0x7e048502, | |
| 2825 | + 0x7e068503, 0x807d847d, | |
| 2826 | + 0x8078ff78, 0x00000200, | |
| 2827 | + 0xbf0a6f7d, 0xbfa2ffee, | |
| 2853 | 2828 | 0xe0505000, 0x6e1d0000, |
| 2854 | − 0xe0505100, 0x6e1d0100, | |
| 2855 | − 0xe0505200, 0x6e1d0200, | |
| 2856 | − 0xe0505300, 0x6e1d0300, | |
| 2857 | − 0xbf8903f7, 0xb8f83b05, | |
| 2858 | − 0x80788178, 0xbf0d9972, | |
| 2859 | − 0xbfa20002, 0x84788978, | |
| 2860 | − 0xbfa00001, 0x84788a78, | |
| 2861 | − 0xb8ee1e06, 0x846e8a6e, | |
| 2862 | − 0x80786e78, 0x8078ff78, | |
| 2863 | − 0x00000200, 0x80f8ff78, | |
| 2864 | − 0x00000050, 0xbef600ff, | |
| 2865 | − 0x01000000, 0xbefd00ff, | |
| 2866 | − 0x0000006c, 0x80f89078, | |
| 2867 | − 0xf428403a, 0xf0000000, | |
| 2868 | − 0xbf89fc07, 0x80fd847d, | |
| 2869 | − 0xbf800000, 0xbe804300, | |
| 2870 | − 0xbe824302, 0x80f8a078, | |
| 2871 | − 0xf42c403a, 0xf0000000, | |
| 2872 | − 0xbf89fc07, 0x80fd887d, | |
| 2873 | − 0xbf800000, 0xbe804300, | |
| 2874 | − 0xbe824302, 0xbe844304, | |
| 2875 | − 0xbe864306, 0x80f8c078, | |
| 2876 | − 0xf430403a, 0xf0000000, | |
| 2877 | − 0xbf89fc07, 0x80fd907d, | |
| 2878 | − 0xbf800000, 0xbe804300, | |
| 2879 | − 0xbe824302, 0xbe844304, | |
| 2880 | − 0xbe864306, 0xbe884308, | |
| 2881 | − 0xbe8a430a, 0xbe8c430c, | |
| 2882 | − 0xbe8e430e, 0xbf06807d, | |
| 2883 | − 0xbfa1fff0, 0xb980f801, | |
| 2884 | − 0x00000000, 0xbfbd0000, | |
| 2829 | + 0xe0505080, 0x6e1d0100, | |
| 2830 | + 0xe0505100, 0x6e1d0200, | |
| 2831 | + 0xe0505180, 0x6e1d0300, | |
| 2832 | + 0xbf8903f7, 0xbfa00034, | |
| 2833 | + 0xbef600ff, 0x01000000, | |
| 2834 | + 0xbeee0078, 0x8078ff78, | |
| 2835 | + 0x00000400, 0xbefd0084, | |
| 2836 | + 0xbf0a6f7d, 0xbfa10012, | |
| 2837 | + 0xe0505000, 0x781d0000, | |
| 2838 | + 0xe0505100, 0x781d0100, | |
| 2839 | + 0xe0505200, 0x781d0200, | |
| 2840 | + 0xe0505300, 0x781d0300, | |
| 2841 | + 0xbf8903f7, 0x7e008500, | |
| 2842 | + 0x7e028501, 0x7e048502, | |
| 2843 | + 0x7e068503, 0x807d847d, | |
| 2844 | + 0x8078ff78, 0x00000400, | |
| 2845 | + 0xbf0a6f7d, 0xbfa2ffee, | |
| 2846 | + 0xb8ef1e06, 0x8b6fc16f, | |
| 2847 | + 0xbfa1000e, 0x846f836f, | |
| 2848 | + 0x806f7d6f, 0xbefe00c1, | |
| 2849 | + 0xbeff0080, 0xe0505000, | |
| 2850 | + 0x781d0000, 0xbf8903f7, | |
| 2851 | + 0x7e008500, 0x807d817d, | |
| 2852 | + 0x8078ff78, 0x00000080, | |
| 2853 | + 0xbf0a6f7d, 0xbfa2fff7, | |
| 2854 | + 0xbeff00c1, 0xe0505000, | |
| 2855 | + 0x6e1d0000, 0xe0505100, | |
| 2856 | + 0x6e1d0100, 0xe0505200, | |
| 2857 | + 0x6e1d0200, 0xe0505300, | |
| 2858 | + 0x6e1d0300, 0xbf8903f7, | |
| 2885 | 2859 | 0xb8f83b05, 0x80788178, |
| 2886 | 2860 | 0xbf0d9972, 0xbfa20002, |
| 2887 | 2861 | 0x84788978, 0xbfa00001, |
| 2888 | 2862 | 0x84788a78, 0xb8ee1e06, |
| 2889 | 2863 | 0x846e8a6e, 0x80786e78, |
| 2890 | 2864 | 0x8078ff78, 0x00000200, |
| 2865 | + 0x80f8ff78, 0x00000050, | |
| 2891 | 2866 | 0xbef600ff, 0x01000000, |
| 2892 | − 0xf4205bfa, 0xf0000000, | |
| 2893 | − 0x80788478, 0xf4205b3a, | |
| 2867 | + 0xbefd00ff, 0x0000006c, | |
| 2868 | + 0x80f89078, 0xf428403a, | |
| 2869 | + 0xf0000000, 0xbf89fc07, | |
| 2870 | + 0x80fd847d, 0xbf800000, | |
| 2871 | + 0xbe804300, 0xbe824302, | |
| 2872 | + 0x80f8a078, 0xf42c403a, | |
| 2873 | + 0xf0000000, 0xbf89fc07, | |
| 2874 | + 0x80fd887d, 0xbf800000, | |
| 2875 | + 0xbe804300, 0xbe824302, | |
| 2876 | + 0xbe844304, 0xbe864306, | |
| 2877 | + 0x80f8c078, 0xf430403a, | |
| 2878 | + 0xf0000000, 0xbf89fc07, | |
| 2879 | + 0x80fd907d, 0xbf800000, | |
| 2880 | + 0xbe804300, 0xbe824302, | |
| 2881 | + 0xbe844304, 0xbe864306, | |
| 2882 | + 0xbe884308, 0xbe8a430a, | |
| 2883 | + 0xbe8c430c, 0xbe8e430e, | |
| 2884 | + 0xbf06807d, 0xbfa1fff0, | |
| 2885 | + 0xb980f801, 0x00000000, | |
| 2886 | + 0xbfbd0000, 0xb8f83b05, | |
| 2887 | + 0x80788178, 0xbf0d9972, | |
| 2888 | + 0xbfa20002, 0x84788978, | |
| 2889 | + 0xbfa00001, 0x84788a78, | |
| 2890 | + 0xb8ee1e06, 0x846e8a6e, | |
| 2891 | + 0x80786e78, 0x8078ff78, | |
| 2892 | + 0x00000200, 0xbef600ff, | |
| 2893 | + 0x01000000, 0xf4205bfa, | |
| 2894 | 2894 | 0xf0000000, 0x80788478, |
| 2895 | − 0xf4205b7a, 0xf0000000, | |
| 2896 | − 0x80788478, 0xf4205c3a, | |
| 2895 | + 0xf4205b3a, 0xf0000000, | |
| 2896 | + 0x80788478, 0xf4205b7a, | |
| 2897 | 2897 | 0xf0000000, 0x80788478, |
| 2898 | − 0xf4205c7a, 0xf0000000, | |
| 2899 | − 0x80788478, 0xf4205eba, | |
| 2898 | + 0xf4205c3a, 0xf0000000, | |
| 2899 | + 0x80788478, 0xf4205c7a, | |
| 2900 | 2900 | 0xf0000000, 0x80788478, |
| 2901 | − 0xf4205efa, 0xf0000000, | |
| 2902 | − 0x80788478, 0xf4205e7a, | |
| 2901 | + 0xf4205eba, 0xf0000000, | |
| 2902 | + 0x80788478, 0xf4205efa, | |
| 2903 | 2903 | 0xf0000000, 0x80788478, |
| 2904 | − 0xf4205cfa, 0xf0000000, | |
| 2905 | − 0x80788478, 0xf4205bba, | |
| 2904 | + 0xf4205e7a, 0xf0000000, | |
| 2905 | + 0x80788478, 0xf4205cfa, | |
| 2906 | 2906 | 0xf0000000, 0x80788478, |
| 2907 | − 0xbf89fc07, 0xb96ef814, | |
| 2908 | 2907 | 0xf4205bba, 0xf0000000, |
| 2909 | 2908 | 0x80788478, 0xbf89fc07, |
| 2910 | − 0xb96ef815, 0xbefd006f, | |
| 2911 | − 0xbefe0070, 0xbeff0071, | |
| 2912 | − 0x8b6f7bff, 0x000003ff, | |
| 2913 | − 0xb96f4803, 0x8b6f7bff, | |
| 2914 | − 0xfffff800, 0x856f8b6f, | |
| 2915 | − 0xb96fa2c3, 0xb973f801, | |
| 2916 | − 0xb8ee3b05, 0x806e816e, | |
| 2917 | − 0xbf0d9972, 0xbfa20002, | |
| 2918 | − 0x846e896e, 0xbfa00001, | |
| 2919 | − 0x846e8a6e, 0xb8ef1e06, | |
| 2920 | − 0x846f8a6f, 0x806e6f6e, | |
| 2921 | − 0x806eff6e, 0x00000200, | |
| 2922 | − 0x806e746e, 0x826f8075, | |
| 2923 | − 0x8b6fff6f, 0x0000ffff, | |
| 2924 | − 0xf4085c37, 0xf8000050, | |
| 2925 | − 0xf4085d37, 0xf8000060, | |
| 2926 | − 0xf4005e77, 0xf8000074, | |
| 2927 | − 0xbf89fc07, 0x8b6dff6d, | |
| 2928 | − 0x0000ffff, 0x8bfe7e7e, | |
| 2929 | − 0x8bea6a6a, 0xb8eef802, | |
| 2930 | − 0xbf0d866e, 0xbfa20002, | |
| 2931 | − 0xb97af802, 0xbe80486c, | |
| 2932 | − 0xb97af802, 0xbe804a6c, | |
| 2933 | − 0xbfb00000, 0xbf9f0000, | |
| 2909 | + 0xb96ef814, 0xf4205bba, | |
| 2910 | + 0xf0000000, 0x80788478, | |
| 2911 | + 0xbf89fc07, 0xb96ef815, | |
| 2912 | + 0xbefd006f, 0xbefe0070, | |
| 2913 | + 0xbeff0071, 0x8b6f7bff, | |
| 2914 | + 0x000003ff, 0xb96f4803, | |
| 2915 | + 0x8b6f7bff, 0xfffff800, | |
| 2916 | + 0x856f8b6f, 0xb96fa2c3, | |
| 2917 | + 0xb973f801, 0xb8ee3b05, | |
| 2918 | + 0x806e816e, 0xbf0d9972, | |
| 2919 | + 0xbfa20002, 0x846e896e, | |
| 2920 | + 0xbfa00001, 0x846e8a6e, | |
| 2921 | + 0xb8ef1e06, 0x846f8a6f, | |
| 2922 | + 0x806e6f6e, 0x806eff6e, | |
| 2923 | + 0x00000200, 0x806e746e, | |
| 2924 | + 0x826f8075, 0x8b6fff6f, | |
| 2925 | + 0x0000ffff, 0xf4085c37, | |
| 2926 | + 0xf8000050, 0xf4085d37, | |
| 2927 | + 0xf8000060, 0xf4005e77, | |
| 2928 | + 0xf8000074, 0xbf89fc07, | |
| 2929 | + 0x8b6dff6d, 0x0000ffff, | |
| 2930 | + 0x8bfe7e7e, 0x8bea6a6a, | |
| 2931 | + 0xb8eef802, 0xbf0d866e, | |
| 2932 | + 0xbfa20002, 0xb97af802, | |
| 2933 | + 0xbe80486c, 0xb97af802, | |
| 2934 | + 0xbe804a6c, 0xbfb00000, | |
| 2934 | 2935 | 0xbf9f0000, 0xbf9f0000, |
| 2935 | 2936 | 0xbf9f0000, 0xbf9f0000, |
| 2937 | + 0xbf9f0000, 0x00000000, | |
| 2936 | 2938 | }; |
| @@ -186,6 +186,12 @@ L_SKIP_RESTORE: · 185 unmodified lines | ||
| 186 | 186 | s_getreg_b32 s_save_trapsts, hwreg(HW_REG_TRAPSTS) |
| 187 | 187 | |
| 188 | 188 | #if SW_SA_TRAP |
| 189 | + // If ttmp1[30] is set then issue s_barrier to unblock dependent waves. | |
| 190 | + s_bitcmp1_b32 s_save_pc_hi, 30 | |
| 191 | + s_cbranch_scc0 L_TRAP_NO_BARRIER | |
| 192 | + s_barrier | |
| 193 | + | |
| 194 | +L_TRAP_NO_BARRIER: | |
| 189 | 195 | // If ttmp1[31] is set then trap may occur early. |
| 190 | 196 | // Spin wait until SAVECTX exception is raised. |
| 191 | 197 | s_bitcmp1_b32 s_save_pc_hi, 31 |
| @@ -1950,7 +1950,7 @@ static int criu_checkpoint(struct file *filep, · 1949 unmodified lines | ||
| 1950 | 1950 | { |
| 1951 | 1951 | int ret; |
| 1952 | 1952 | uint32_t num_devices, num_bos, num_objects; |
| 1953 | − uint64_t priv_size, priv_offset = 0; | |
| 1953 | + uint64_t priv_size, priv_offset = 0, bo_priv_offset; | |
| 1954 | 1954 | |
| 1955 | 1955 | if (!args->devices || !args->bos || !args->priv_data) |
| 1956 | 1956 | return -EINVAL; |
| @@ -1994,38 +1994,34 @@ static int criu_checkpoint(struct file *filep, · 37 unmodified lines | ||
| 1994 | 1994 | if (ret) |
| 1995 | 1995 | goto exit_unlock; |
| 1996 | 1996 | |
| 1997 | − ret = criu_checkpoint_bos(p, num_bos, (uint8_t __user *)args->bos, | |
| 1998 | − (uint8_t __user *)args->priv_data, &priv_offset); | |
| 1999 | − if (ret) | |
| 2000 | − goto exit_unlock; | |
| 1997 | + /* Leave room for BOs in the private data. They need to be restored | |
| 1998 | + * before events, but we checkpoint them last to simplify the error | |
| 1999 | + * handling. | |
| 2000 | + */ | |
| 2001 | + bo_priv_offset = priv_offset; | |
| 2002 | + priv_offset += num_bos * sizeof(struct kfd_criu_bo_priv_data); | |
| 2001 | 2003 | |
| 2002 | 2004 | if (num_objects) { |
| 2003 | 2005 | ret = kfd_criu_checkpoint_queues(p, (uint8_t __user *)args->priv_data, |
| 2004 | 2006 | &priv_offset); |
| 2005 | 2007 | if (ret) |
| 2006 | − goto close_bo_fds; | |
| 2008 | + goto exit_unlock; | |
| 2007 | 2009 | |
| 2008 | 2010 | ret = kfd_criu_checkpoint_events(p, (uint8_t __user *)args->priv_data, |
| 2009 | 2011 | &priv_offset); |
| 2010 | 2012 | if (ret) |
| 2011 | − goto close_bo_fds; | |
| 2013 | + goto exit_unlock; | |
| 2012 | 2014 | |
| 2013 | 2015 | ret = kfd_criu_checkpoint_svm(p, (uint8_t __user *)args->priv_data, &priv_offset); |
| 2014 | 2016 | if (ret) |
| 2015 | − goto close_bo_fds; | |
| 2017 | + goto exit_unlock; | |
| 2016 | 2018 | } |
| 2017 | 2019 | |
| 2018 | −close_bo_fds: | |
| 2019 | − if (ret) { | |
| 2020 | − /* If IOCTL returns err, user assumes all FDs opened in criu_dump_bos are closed */ | |
| 2021 | − uint32_t i; | |
| 2022 | − struct kfd_criu_bo_bucket *bo_buckets = (struct kfd_criu_bo_bucket *) args->bos; | |
| 2023 | − | |
| 2024 | − for (i = 0; i < num_bos; i++) { | |
| 2025 | − if (bo_buckets[i].alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) | |
| 2026 | − close_fd(bo_buckets[i].dmabuf_fd); | |
| 2027 | − } | |
| 2028 | − } | |
| 2020 | + /* This must be the last thing in this function that can fail. | |
| 2021 | + * Otherwise we leak dmabuf file descriptors. | |
| 2022 | + */ | |
| 2023 | + ret = criu_checkpoint_bos(p, num_bos, (uint8_t __user *)args->bos, | |
| 2024 | + (uint8_t __user *)args->priv_data, &bo_priv_offset); | |
| 2029 | 2025 | |
| 2030 | 2026 | exit_unlock: |
| 2031 | 2027 | mutex_unlock(&p->mutex); |
| @@ -506,6 +506,7 @@ int kfd_criu_restore_event(struct file *devkfd, · 505 unmodified lines | ||
| 506 | 506 | ret = create_other_event(p, ev, &ev_priv->event_id); |
| 507 | 507 | break; |
| 508 | 508 | } |
| 509 | + mutex_unlock(&p->event_mutex); | |
| 509 | 510 | |
| 510 | 511 | exit: |
| 511 | 512 | if (ret) |
| @@ -513,8 +514,6 @@ exit: · 1 unmodified line | ||
| 513 | 514 | |
| 514 | 515 | kfree(ev_priv); |
| 515 | 516 | |
| 516 | − mutex_unlock(&p->event_mutex); | |
| 517 | − | |
| 518 | 517 | return ret; |
| 519 | 518 | } |
| 520 | 519 | |
| @@ -973,12 +973,10 @@ out_unlock_prange: · 972 unmodified lines | ||
| 973 | 973 | out_unlock_svms: |
| 974 | 974 | mutex_unlock(&p->svms.lock); |
| 975 | 975 | out_unref_process: |
| 976 | + pr_debug("CPU fault svms 0x%p address 0x%lx done\n", &p->svms, addr); | |
| 976 | 977 | kfd_unref_process(p); |
| 977 | 978 | out_mmput: |
| 978 | 979 | mmput(mm); |
| 979 | − | |
| 980 | − pr_debug("CPU fault svms 0x%p address 0x%lx done\n", &p->svms, addr); | |
| 981 | − | |
| 982 | 980 | return r ? VM_FAULT_SIGBUS : 0; |
| 983 | 981 | } |
| 984 | 982 | |
| @@ -5,6 +5,7 @@ menu "Display Engine Configuration" · 4 unmodified lines | ||
| 5 | 5 | config DRM_AMD_DC |
| 6 | 6 | bool "AMD DC - Enable new display engine" |
| 7 | 7 | default y |
| 8 | + depends on BROKEN || !CC_IS_CLANG || X86_64 || SPARC64 || ARM64 | |
| 8 | 9 | select SND_HDA_COMPONENT if SND_HDA_CORE |
| 9 | 10 | select DRM_AMD_DC_DCN if (X86 || PPC_LONG_DOUBLE_128) |
| 10 | 11 | help |
| @@ -12,6 +13,12 @@ config DRM_AMD_DC · 1 unmodified line | ||
| 12 | 13 | support for AMDGPU. This adds required support for Vega and |
| 13 | 14 | Raven ASICs. |
| 14 | 15 | |
| 16 | + calculate_bandwidth() is presently broken on all !(X86_64 || SPARC64 || ARM64) | |
| 17 | + architectures built with Clang (all released versions), whereby the stack | |
| 18 | + frame gets blown up to well over 5k. This would cause an immediate kernel | |
| 19 | + panic on most architectures. We'll revert this when the following bug report | |
| 20 | + has been resolved: https://github.com/llvm/llvm-project/issues/41896. | |
| 21 | + | |
| 15 | 22 | config DRM_AMD_DC_DCN |
| 16 | 23 | def_bool n |
| 17 | 24 | help |
| @@ -147,6 +147,14 @@ MODULE_FIRMWARE(FIRMWARE_NAVI12_DMCU); · 146 unmodified lines | ||
| 147 | 147 | /* Number of bytes in PSP footer for firmware. */ |
| 148 | 148 | #define PSP_FOOTER_BYTES 0x100 |
| 149 | 149 | |
| 150 | +/* | |
| 151 | + * DMUB Async to Sync Mechanism Status | |
| 152 | + */ | |
| 153 | +#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1 | |
| 154 | +#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2 | |
| 155 | +#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3 | |
| 156 | +#define DMUB_ASYNC_TO_SYNC_ACCESS_INVALID 4 | |
| 157 | + | |
| 150 | 158 | /** |
| 151 | 159 | * DOC: overview |
| 152 | 160 | * |
| @@ -1364,7 +1372,44 @@ static const struct dmi_system_id hpd_disconnect_quirk_table[] = { · 1211 unmodified lines | ||
| 1364 | 1372 | DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"), |
| 1365 | 1373 | }, |
| 1366 | 1374 | }, |
| 1375 | + { | |
| 1376 | + .matches = { | |
| 1377 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 1378 | + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"), | |
| 1379 | + }, | |
| 1380 | + }, | |
| 1381 | + { | |
| 1382 | + .matches = { | |
| 1383 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 1384 | + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"), | |
| 1385 | + }, | |
| 1386 | + }, | |
| 1387 | + { | |
| 1388 | + .matches = { | |
| 1389 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 1390 | + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"), | |
| 1391 | + }, | |
| 1392 | + }, | |
| 1393 | + { | |
| 1394 | + .matches = { | |
| 1395 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 1396 | + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"), | |
| 1397 | + }, | |
| 1398 | + }, | |
| 1399 | + { | |
| 1400 | + .matches = { | |
| 1401 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 1402 | + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"), | |
| 1403 | + }, | |
| 1404 | + }, | |
| 1405 | + { | |
| 1406 | + .matches = { | |
| 1407 | + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 1408 | + DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"), | |
| 1409 | + }, | |
| 1410 | + }, | |
| 1367 | 1411 | {} |
| 1412 | + /* TODO: refactor this from a fixed table to a dynamic option */ | |
| 1368 | 1413 | }; |
| 1369 | 1414 | |
| 1370 | 1415 | static void retrieve_dmi_info(struct amdgpu_display_manager *dm) |
| @@ -1549,6 +1594,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 178 unmodified lines | ||
| 1549 | 1594 | |
| 1550 | 1595 | adev->dm.dc->debug.visual_confirm = amdgpu_dc_visual_confirm; |
| 1551 | 1596 | |
| 1597 | + /* TODO: Remove after DP2 receiver gets proper support of Cable ID feature */ | |
| 1598 | + adev->dm.dc->debug.ignore_cable_id = true; | |
| 1599 | + | |
| 1552 | 1600 | r = dm_dmub_hw_init(adev); |
| 1553 | 1601 | if (r) { |
| 1554 | 1602 | DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r); |
| @@ -1634,12 +1682,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 79 unmodified lines | ||
| 1634 | 1682 | } |
| 1635 | 1683 | } |
| 1636 | 1684 | |
| 1637 | − if (amdgpu_dm_initialize_drm_device(adev)) { | |
| 1638 | − DRM_ERROR( | |
| 1639 | − "amdgpu: failed to initialize sw for display support.\n"); | |
| 1640 | − goto error; | |
| 1641 | − } | |
| 1642 | − | |
| 1643 | 1685 | /* Enable outbox notification only after IRQ handlers are registered and DMUB is alive. |
| 1644 | 1686 | * It is expected that DMUB will resend any pending notifications at this point, for |
| 1645 | 1687 | * example HPD from DPIA. |
| @@ -1647,6 +1689,12 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) · 1 unmodified line | ||
| 1647 | 1689 | if (dc_is_dmub_outbox_supported(adev->dm.dc)) |
| 1648 | 1690 | dc_enable_dmub_outbox(adev->dm.dc); |
| 1649 | 1691 | |
| 1692 | + if (amdgpu_dm_initialize_drm_device(adev)) { | |
| 1693 | + DRM_ERROR( | |
| 1694 | + "amdgpu: failed to initialize sw for display support.\n"); | |
| 1695 | + goto error; | |
| 1696 | + } | |
| 1697 | + | |
| 1650 | 1698 | /* create fake encoders for MST */ |
| 1651 | 1699 | dm_dp_create_fake_mst_encoders(adev); |
| 1652 | 1700 | |
| @@ -6464,7 +6512,7 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, · 4811 unmodified lines | ||
| 6464 | 6512 | struct drm_connector_state *new_con_state; |
| 6465 | 6513 | struct amdgpu_dm_connector *aconnector; |
| 6466 | 6514 | struct dm_connector_state *dm_conn_state; |
| 6467 | − int i, j; | |
| 6515 | + int i, j, ret; | |
| 6468 | 6516 | int vcpi, pbn_div, pbn, slot_num = 0; |
| 6469 | 6517 | |
| 6470 | 6518 | for_each_new_connector_in_state(state, connector, new_con_state, i) { |
| @@ -6511,8 +6559,11 @@ static int dm_update_mst_vcpi_slots_for_dsc(struct drm_atomic_state *state, · 40 unmodified lines | ||
| 6511 | 6559 | dm_conn_state->pbn = pbn; |
| 6512 | 6560 | dm_conn_state->vcpi_slots = slot_num; |
| 6513 | 6561 | |
| 6514 | − drm_dp_mst_atomic_enable_dsc(state, aconnector->port, dm_conn_state->pbn, | |
| 6515 | − false); | |
| 6562 | + ret = drm_dp_mst_atomic_enable_dsc(state, aconnector->port, | |
| 6563 | + dm_conn_state->pbn, false); | |
| 6564 | + if (ret < 0) | |
| 6565 | + return ret; | |
| 6566 | + | |
| 6516 | 6567 | continue; |
| 6517 | 6568 | } |
| 6518 | 6569 | |
| @@ -7619,9 +7670,10 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 1100 unmodified lines | ||
| 7619 | 7670 | bundle->surface_updates[planes_count].plane_info = |
| 7620 | 7671 | &bundle->plane_infos[planes_count]; |
| 7621 | 7672 | |
| 7622 | − fill_dc_dirty_rects(plane, old_plane_state, new_plane_state, | |
| 7623 | − new_crtc_state, | |
| 7624 | − &bundle->flip_addrs[planes_count]); | |
| 7673 | + if (acrtc_state->stream->link->psr_settings.psr_feature_enabled) | |
| 7674 | + fill_dc_dirty_rects(plane, old_plane_state, | |
| 7675 | + new_plane_state, new_crtc_state, | |
| 7676 | + &bundle->flip_addrs[planes_count]); | |
| 7625 | 7677 | |
| 7626 | 7678 | /* |
| 7627 | 7679 | * Only allow immediate flips for fast updates that don't |
| @@ -9525,10 +9577,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 1897 unmodified lines | ||
| 9525 | 9577 | |
| 9526 | 9578 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 9527 | 9579 | if (dc_resource_is_dsc_encoding_supported(dc)) { |
| 9528 | − if (!pre_validate_dsc(state, &dm_state, vars)) { | |
| 9529 | − ret = -EINVAL; | |
| 9580 | + ret = pre_validate_dsc(state, &dm_state, vars); | |
| 9581 | + if (ret != 0) | |
| 9530 | 9582 | goto fail; |
| 9531 | − } | |
| 9532 | 9583 | } |
| 9533 | 9584 | #endif |
| 9534 | 9585 | |
| @@ -9623,9 +9674,9 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 88 unmodified lines | ||
| 9623 | 9674 | } |
| 9624 | 9675 | |
| 9625 | 9676 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| 9626 | − if (!compute_mst_dsc_configs_for_state(state, dm_state->context, vars)) { | |
| 9677 | + ret = compute_mst_dsc_configs_for_state(state, dm_state->context, vars); | |
| 9678 | + if (ret) { | |
| 9627 | 9679 | DRM_DEBUG_DRIVER("compute_mst_dsc_configs_for_state() failed\n"); |
| 9628 | − ret = -EINVAL; | |
| 9629 | 9680 | goto fail; |
| 9630 | 9681 | } |
| 9631 | 9682 | |
| @@ -10105,6 +10156,8 @@ static int amdgpu_dm_set_dmub_async_sync_status(bool is_cmd_aux, · 473 unmodified lines | ||
| 10105 | 10156 | *operation_result = AUX_RET_ERROR_TIMEOUT; |
| 10106 | 10157 | } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_FAIL) { |
| 10107 | 10158 | *operation_result = AUX_RET_ERROR_ENGINE_ACQUIRE; |
| 10159 | + } else if (status_type == DMUB_ASYNC_TO_SYNC_ACCESS_INVALID) { | |
| 10160 | + *operation_result = AUX_RET_ERROR_INVALID_REPLY; | |
| 10108 | 10161 | } else { |
| 10109 | 10162 | *operation_result = AUX_RET_ERROR_UNKNOWN; |
| 10110 | 10163 | } |
| @@ -10152,6 +10205,16 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(bool is_cmd_aux, struct dc_context · 41 unmodified lines | ||
| 10152 | 10205 | payload->reply[0] = adev->dm.dmub_notify->aux_reply.command; |
| 10153 | 10206 | if (!payload->write && adev->dm.dmub_notify->aux_reply.length && |
| 10154 | 10207 | payload->reply[0] == AUX_TRANSACTION_REPLY_AUX_ACK) { |
| 10208 | + | |
| 10209 | + if (payload->length != adev->dm.dmub_notify->aux_reply.length) { | |
| 10210 | + DRM_WARN("invalid read from DPIA AUX %x(%d) got length %d!\n", | |
| 10211 | + payload->address, payload->length, | |
| 10212 | + adev->dm.dmub_notify->aux_reply.length); | |
| 10213 | + return amdgpu_dm_set_dmub_async_sync_status(is_cmd_aux, ctx, | |
| 10214 | + DMUB_ASYNC_TO_SYNC_ACCESS_INVALID, | |
| 10215 | + (uint32_t *)operation_result); | |
| 10216 | + } | |
| 10217 | + | |
| 10155 | 10218 | memcpy(payload->data, adev->dm.dmub_notify->aux_reply.data, |
| 10156 | 10219 | adev->dm.dmub_notify->aux_reply.length); |
| 10157 | 10220 | } |
| @@ -50,12 +50,6 @@ · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | #define AMDGPU_DMUB_NOTIFICATION_MAX 5 |
| 52 | 52 | |
| 53 | −/* | |
| 54 | − * DMUB Async to Sync Mechanism Status | |
| 55 | − */ | |
| 56 | −#define DMUB_ASYNC_TO_SYNC_ACCESS_FAIL 1 | |
| 57 | −#define DMUB_ASYNC_TO_SYNC_ACCESS_TIMEOUT 2 | |
| 58 | −#define DMUB_ASYNC_TO_SYNC_ACCESS_SUCCESS 3 | |
| 59 | 53 | /* |
| 60 | 54 | #include "include/amdgpu_dal_power_if.h" |
| 61 | 55 | #include "amdgpu_dm_irq.h" |
| @@ -412,7 +412,7 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, · 411 unmodified lines | ||
| 412 | 412 | { |
| 413 | 413 | struct amdgpu_crtc *acrtc = NULL; |
| 414 | 414 | struct drm_plane *cursor_plane; |
| 415 | − | |
| 415 | + bool is_dcn; | |
| 416 | 416 | int res = -ENOMEM; |
| 417 | 417 | |
| 418 | 418 | cursor_plane = kzalloc(sizeof(*cursor_plane), GFP_KERNEL); |
| @@ -450,8 +450,14 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, · 31 unmodified lines | ||
| 450 | 450 | acrtc->otg_inst = -1; |
| 451 | 451 | |
| 452 | 452 | dm->adev->mode_info.crtcs[crtc_index] = acrtc; |
| 453 | − drm_crtc_enable_color_mgmt(&acrtc->base, MAX_COLOR_LUT_ENTRIES, | |
| 453 | + | |
| 454 | + /* Don't enable DRM CRTC degamma property for DCE since it doesn't | |
| 455 | + * support programmable degamma anywhere. | |
| 456 | + */ | |
| 457 | + is_dcn = dm->adev->dm.dc->caps.color.dpp.dcn_arch; | |
| 458 | + drm_crtc_enable_color_mgmt(&acrtc->base, is_dcn ? MAX_COLOR_LUT_ENTRIES : 0, | |
| 454 | 459 | true, MAX_COLOR_LUT_ENTRIES); |
| 460 | + | |
| 455 | 461 | drm_mode_crtc_set_gamma_size(&acrtc->base, MAX_COLOR_LEGACY_LUT_ENTRIES); |
| 456 | 462 | |
| 457 | 463 | return 0; |
| @@ -703,13 +703,13 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn) · 702 unmodified lines | ||
| 703 | 703 | return dsc_config.bits_per_pixel; |
| 704 | 704 | } |
| 705 | 705 | |
| 706 | −static bool increase_dsc_bpp(struct drm_atomic_state *state, | |
| 707 | − struct drm_dp_mst_topology_state *mst_state, | |
| 708 | − struct dc_link *dc_link, | |
| 709 | − struct dsc_mst_fairness_params *params, | |
| 710 | − struct dsc_mst_fairness_vars *vars, | |
| 711 | − int count, | |
| 712 | − int k) | |
| 706 | +static int increase_dsc_bpp(struct drm_atomic_state *state, | |
| 707 | + struct drm_dp_mst_topology_state *mst_state, | |
| 708 | + struct dc_link *dc_link, | |
| 709 | + struct dsc_mst_fairness_params *params, | |
| 710 | + struct dsc_mst_fairness_vars *vars, | |
| 711 | + int count, | |
| 712 | + int k) | |
| 713 | 713 | { |
| 714 | 714 | int i; |
| 715 | 715 | bool bpp_increased[MAX_PIPES]; |
| @@ -719,6 +719,7 @@ static bool increase_dsc_bpp(struct drm_atomic_state *state, · 3 unmodified lines | ||
| 719 | 719 | int remaining_to_increase = 0; |
| 720 | 720 | int link_timeslots_used; |
| 721 | 721 | int fair_pbn_alloc; |
| 722 | + int ret = 0; | |
| 722 | 723 | |
| 723 | 724 | for (i = 0; i < count; i++) { |
| 724 | 725 | if (vars[i + k].dsc_enabled) { |
| @@ -757,52 +758,60 @@ static bool increase_dsc_bpp(struct drm_atomic_state *state, · 32 unmodified lines | ||
| 757 | 758 | |
| 758 | 759 | if (initial_slack[next_index] > fair_pbn_alloc) { |
| 759 | 760 | vars[next_index].pbn += fair_pbn_alloc; |
| 760 | − if (drm_dp_atomic_find_time_slots(state, | |
| 761 | − params[next_index].port->mgr, | |
| 762 | − params[next_index].port, | |
| 763 | − vars[next_index].pbn) < 0) | |
| 764 | − return false; | |
| 765 | − if (!drm_dp_mst_atomic_check(state)) { | |
| 761 | + ret = drm_dp_atomic_find_time_slots(state, | |
| 762 | + params[next_index].port->mgr, | |
| 763 | + params[next_index].port, | |
| 764 | + vars[next_index].pbn); | |
| 765 | + if (ret < 0) | |
| 766 | + return ret; | |
| 767 | + | |
| 768 | + ret = drm_dp_mst_atomic_check(state); | |
| 769 | + if (ret == 0) { | |
| 766 | 770 | vars[next_index].bpp_x16 = bpp_x16_from_pbn(params[next_index], vars[next_index].pbn); |
| 767 | 771 | } else { |
| 768 | 772 | vars[next_index].pbn -= fair_pbn_alloc; |
| 769 | − if (drm_dp_atomic_find_time_slots(state, | |
| 770 | − params[next_index].port->mgr, | |
| 771 | − params[next_index].port, | |
| 772 | − vars[next_index].pbn) < 0) | |
| 773 | − return false; | |
| 773 | + ret = drm_dp_atomic_find_time_slots(state, | |
| 774 | + params[next_index].port->mgr, | |
| 775 | + params[next_index].port, | |
| 776 | + vars[next_index].pbn); | |
| 777 | + if (ret < 0) | |
| 778 | + return ret; | |
| 774 | 779 | } |
| 775 | 780 | } else { |
| 776 | 781 | vars[next_index].pbn += initial_slack[next_index]; |
| 777 | − if (drm_dp_atomic_find_time_slots(state, | |
| 778 | − params[next_index].port->mgr, | |
| 779 | − params[next_index].port, | |
| 780 | − vars[next_index].pbn) < 0) | |
| 781 | − return false; | |
| 782 | − if (!drm_dp_mst_atomic_check(state)) { | |
| 782 | + ret = drm_dp_atomic_find_time_slots(state, | |
| 783 | + params[next_index].port->mgr, | |
| 784 | + params[next_index].port, | |
| 785 | + vars[next_index].pbn); | |
| 786 | + if (ret < 0) | |
| 787 | + return ret; | |
| 788 | + | |
| 789 | + ret = drm_dp_mst_atomic_check(state); | |
| 790 | + if (ret == 0) { | |
| 783 | 791 | vars[next_index].bpp_x16 = params[next_index].bw_range.max_target_bpp_x16; |
| 784 | 792 | } else { |
| 785 | 793 | vars[next_index].pbn -= initial_slack[next_index]; |
| 786 | − if (drm_dp_atomic_find_time_slots(state, | |
| 787 | − params[next_index].port->mgr, | |
| 788 | − params[next_index].port, | |
| 789 | − vars[next_index].pbn) < 0) | |
| 790 | − return false; | |
| 794 | + ret = drm_dp_atomic_find_time_slots(state, | |
| 795 | + params[next_index].port->mgr, | |
| 796 | + params[next_index].port, | |
| 797 | + vars[next_index].pbn); | |
| 798 | + if (ret < 0) | |
| 799 | + return ret; | |
| 791 | 800 | } |
| 792 | 801 | } |
| 793 | 802 | |
| 794 | 803 | bpp_increased[next_index] = true; |
| 795 | 804 | remaining_to_increase--; |
| 796 | 805 | } |
| 797 | − return true; | |
| 806 | + return 0; | |
| 798 | 807 | } |
| 799 | 808 | |
| 800 | −static bool try_disable_dsc(struct drm_atomic_state *state, | |
| 801 | − struct dc_link *dc_link, | |
| 802 | − struct dsc_mst_fairness_params *params, | |
| 803 | − struct dsc_mst_fairness_vars *vars, | |
| 804 | − int count, | |
| 805 | − int k) | |
| 809 | +static int try_disable_dsc(struct drm_atomic_state *state, | |
| 810 | + struct dc_link *dc_link, | |
| 811 | + struct dsc_mst_fairness_params *params, | |
| 812 | + struct dsc_mst_fairness_vars *vars, | |
| 813 | + int count, | |
| 814 | + int k) | |
| 806 | 815 | { |
| 807 | 816 | int i; |
| 808 | 817 | bool tried[MAX_PIPES]; |
| @@ -810,6 +819,7 @@ static bool try_disable_dsc(struct drm_atomic_state *state, · 1 unmodified line | ||
| 810 | 819 | int max_kbps_increase; |
| 811 | 820 | int next_index; |
| 812 | 821 | int remaining_to_try = 0; |
| 822 | + int ret; | |
| 813 | 823 | |
| 814 | 824 | for (i = 0; i < count; i++) { |
| 815 | 825 | if (vars[i + k].dsc_enabled |
| @@ -840,49 +850,52 @@ static bool try_disable_dsc(struct drm_atomic_state *state, · 24 unmodified lines | ||
| 840 | 850 | break; |
| 841 | 851 | |
| 842 | 852 | vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps); |
| 843 | − if (drm_dp_atomic_find_time_slots(state, | |
| 844 | − params[next_index].port->mgr, | |
| 845 | − params[next_index].port, | |
| 846 | − vars[next_index].pbn) < 0) | |
| 847 | − return false; | |
| 853 | + ret = drm_dp_atomic_find_time_slots(state, | |
| 854 | + params[next_index].port->mgr, | |
| 855 | + params[next_index].port, | |
| 856 | + vars[next_index].pbn); | |
| 857 | + if (ret < 0) | |
| 858 | + return ret; | |
| 848 | 859 | |
| 849 | − if (!drm_dp_mst_atomic_check(state)) { | |
| 860 | + ret = drm_dp_mst_atomic_check(state); | |
| 861 | + if (ret == 0) { | |
| 850 | 862 | vars[next_index].dsc_enabled = false; |
| 851 | 863 | vars[next_index].bpp_x16 = 0; |
| 852 | 864 | } else { |
| 853 | 865 | vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps); |
| 854 | − if (drm_dp_atomic_find_time_slots(state, | |
| 855 | − params[next_index].port->mgr, | |
| 856 | − params[next_index].port, | |
| 857 | − vars[next_index].pbn) < 0) | |
| 858 | − return false; | |
| 866 | + ret = drm_dp_atomic_find_time_slots(state, | |
| 867 | + params[next_index].port->mgr, | |
| 868 | + params[next_index].port, | |
| 869 | + vars[next_index].pbn); | |
| 870 | + if (ret < 0) | |
| 871 | + return ret; | |
| 859 | 872 | } |
| 860 | 873 | |
| 861 | 874 | tried[next_index] = true; |
| 862 | 875 | remaining_to_try--; |
| 863 | 876 | } |
| 864 | − return true; | |
| 877 | + return 0; | |
| 865 | 878 | } |
| 866 | 879 | |
| 867 | −static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, | |
| 868 | − struct dc_state *dc_state, | |
| 869 | − struct dc_link *dc_link, | |
| 870 | − struct dsc_mst_fairness_vars *vars, | |
| 871 | − struct drm_dp_mst_topology_mgr *mgr, | |
| 872 | − int *link_vars_start_index) | |
| 880 | +static int compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, | |
| 881 | + struct dc_state *dc_state, | |
| 882 | + struct dc_link *dc_link, | |
| 883 | + struct dsc_mst_fairness_vars *vars, | |
| 884 | + struct drm_dp_mst_topology_mgr *mgr, | |
| 885 | + int *link_vars_start_index) | |
| 873 | 886 | { |
| 874 | 887 | struct dc_stream_state *stream; |
| 875 | 888 | struct dsc_mst_fairness_params params[MAX_PIPES]; |
| 876 | 889 | struct amdgpu_dm_connector *aconnector; |
| 877 | 890 | struct drm_dp_mst_topology_state *mst_state = drm_atomic_get_mst_topology_state(state, mgr); |
| 878 | 891 | int count = 0; |
| 879 | − int i, k; | |
| 892 | + int i, k, ret; | |
| 880 | 893 | bool debugfs_overwrite = false; |
| 881 | 894 | |
| 882 | 895 | memset(params, 0, sizeof(params)); |
| 883 | 896 | |
| 884 | 897 | if (IS_ERR(mst_state)) |
| 885 | − return false; | |
| 898 | + return PTR_ERR(mst_state); | |
| 886 | 899 | |
| 887 | 900 | mst_state->pbn_div = dm_mst_get_pbn_divider(dc_link); |
| 888 | 901 | #if defined(CONFIG_DRM_AMD_DC_DCN) |
| @@ -933,7 +946,7 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, · 44 unmodified lines | ||
| 933 | 946 | |
| 934 | 947 | if (count == 0) { |
| 935 | 948 | ASSERT(0); |
| 936 | − return true; | |
| 949 | + return 0; | |
| 937 | 950 | } |
| 938 | 951 | |
| 939 | 952 | /* k is start index of vars for current phy link used by mst hub */ |
| @@ -947,13 +960,17 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, · 7 unmodified lines | ||
| 947 | 960 | vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); |
| 948 | 961 | vars[i + k].dsc_enabled = false; |
| 949 | 962 | vars[i + k].bpp_x16 = 0; |
| 950 | − if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port, | |
| 951 | − vars[i + k].pbn) < 0) | |
| 952 | − return false; | |
| 963 | + ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, params[i].port, | |
| 964 | + vars[i + k].pbn); | |
| 965 | + if (ret < 0) | |
| 966 | + return ret; | |
| 953 | 967 | } |
| 954 | − if (!drm_dp_mst_atomic_check(state) && !debugfs_overwrite) { | |
| 968 | + ret = drm_dp_mst_atomic_check(state); | |
| 969 | + if (ret == 0 && !debugfs_overwrite) { | |
| 955 | 970 | set_dsc_configs_from_fairness_vars(params, vars, count, k); |
| 956 | − return true; | |
| 971 | + return 0; | |
| 972 | + } else if (ret != -ENOSPC) { | |
| 973 | + return ret; | |
| 957 | 974 | } |
| 958 | 975 | |
| 959 | 976 | /* Try max compression */ |
| @@ -962,31 +979,36 @@ static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, · 2 unmodified lines | ||
| 962 | 979 | vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps); |
| 963 | 980 | vars[i + k].dsc_enabled = true; |
| 964 | 981 | vars[i + k].bpp_x16 = params[i].bw_range.min_target_bpp_x16; |
| 965 | − if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr, | |
| 966 | − params[i].port, vars[i + k].pbn) < 0) | |
| 967 | − return false; | |
| 982 | + ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, | |
| 983 | + params[i].port, vars[i + k].pbn); | |
| 984 | + if (ret < 0) | |
| 985 | + return ret; | |
| 968 | 986 | } else { |
| 969 | 987 | vars[i + k].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); |
| 970 | 988 | vars[i + k].dsc_enabled = false; |
| 971 | 989 | vars[i + k].bpp_x16 = 0; |
| 972 | − if (drm_dp_atomic_find_time_slots(state, params[i].port->mgr, | |
| 973 | − params[i].port, vars[i + k].pbn) < 0) | |
| 974 | − return false; | |
| 990 | + ret = drm_dp_atomic_find_time_slots(state, params[i].port->mgr, | |
| 991 | + params[i].port, vars[i + k].pbn); | |
| 992 | + if (ret < 0) | |
| 993 | + return ret; | |
| 975 | 994 | } |
| 976 | 995 | } |
| 977 | − if (drm_dp_mst_atomic_check(state)) | |
| 978 | − return false; | |
| 996 | + ret = drm_dp_mst_atomic_check(state); | |
| 997 | + if (ret != 0) | |
| 998 | + return ret; | |
| 979 | 999 | |
| 980 | 1000 | /* Optimize degree of compression */ |
| 981 | − if (!increase_dsc_bpp(state, mst_state, dc_link, params, vars, count, k)) | |
| 982 | − return false; | |
| 1001 | + ret = increase_dsc_bpp(state, mst_state, dc_link, params, vars, count, k); | |
| 1002 | + if (ret < 0) | |
| 1003 | + return ret; | |
| 983 | 1004 | |
| 984 | − if (!try_disable_dsc(state, dc_link, params, vars, count, k)) | |
| 985 | − return false; | |
| 1005 | + ret = try_disable_dsc(state, dc_link, params, vars, count, k); | |
| 1006 | + if (ret < 0) | |
| 1007 | + return ret; | |
| 986 | 1008 | |
| 987 | 1009 | set_dsc_configs_from_fairness_vars(params, vars, count, k); |
| 988 | 1010 | |
| 989 | − return true; | |
| 1011 | + return 0; | |
| 990 | 1012 | } |
| 991 | 1013 | |
| 992 | 1014 | static bool is_dsc_need_re_compute( |
| @@ -1087,15 +1109,17 @@ static bool is_dsc_need_re_compute( · 94 unmodified lines | ||
| 1087 | 1109 | return is_dsc_need_re_compute; |
| 1088 | 1110 | } |
| 1089 | 1111 | |
| 1090 | −bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, | |
| 1091 | − struct dc_state *dc_state, | |
| 1092 | − struct dsc_mst_fairness_vars *vars) | |
| 1112 | +int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, | |
| 1113 | + struct dc_state *dc_state, | |
| 1114 | + struct dsc_mst_fairness_vars *vars) | |
| 1093 | 1115 | { |
| 1094 | 1116 | int i, j; |
| 1095 | 1117 | struct dc_stream_state *stream; |
| 1096 | 1118 | bool computed_streams[MAX_PIPES]; |
| 1097 | 1119 | struct amdgpu_dm_connector *aconnector; |
| 1120 | + struct drm_dp_mst_topology_mgr *mst_mgr; | |
| 1098 | 1121 | int link_vars_start_index = 0; |
| 1122 | + int ret = 0; | |
| 1099 | 1123 | |
| 1100 | 1124 | for (i = 0; i < dc_state->stream_count; i++) |
| 1101 | 1125 | computed_streams[i] = false; |
| @@ -1108,7 +1132,7 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, · 6 unmodified lines | ||
| 1108 | 1132 | |
| 1109 | 1133 | aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; |
| 1110 | 1134 | |
| 1111 | − if (!aconnector || !aconnector->dc_sink) | |
| 1135 | + if (!aconnector || !aconnector->dc_sink || !aconnector->port) | |
| 1112 | 1136 | continue; |
| 1113 | 1137 | |
| 1114 | 1138 | if (!aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported) |
| @@ -1118,19 +1142,16 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, · 3 unmodified lines | ||
| 1118 | 1142 | continue; |
| 1119 | 1143 | |
| 1120 | 1144 | if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK) |
| 1121 | − return false; | |
| 1145 | + return -EINVAL; | |
| 1122 | 1146 | |
| 1123 | 1147 | if (!is_dsc_need_re_compute(state, dc_state, stream->link)) |
| 1124 | 1148 | continue; |
| 1125 | 1149 | |
| 1126 | − mutex_lock(&aconnector->mst_mgr.lock); | |
| 1127 | − if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars, | |
| 1128 | − &aconnector->mst_mgr, | |
| 1129 | − &link_vars_start_index)) { | |
| 1130 | − mutex_unlock(&aconnector->mst_mgr.lock); | |
| 1131 | − return false; | |
| 1132 | − } | |
| 1133 | − mutex_unlock(&aconnector->mst_mgr.lock); | |
| 1150 | + mst_mgr = aconnector->port->mgr; | |
| 1151 | + ret = compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars, mst_mgr, | |
| 1152 | + &link_vars_start_index); | |
| 1153 | + if (ret != 0) | |
| 1154 | + return ret; | |
| 1134 | 1155 | |
| 1135 | 1156 | for (j = 0; j < dc_state->stream_count; j++) { |
| 1136 | 1157 | if (dc_state->streams[j]->link == stream->link) |
| @@ -1143,22 +1164,23 @@ bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, · 6 unmodified lines | ||
| 1143 | 1164 | |
| 1144 | 1165 | if (stream->timing.flags.DSC == 1) |
| 1145 | 1166 | if (dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream) != DC_OK) |
| 1146 | − return false; | |
| 1167 | + return -EINVAL; | |
| 1147 | 1168 | } |
| 1148 | 1169 | |
| 1149 | − return true; | |
| 1170 | + return ret; | |
| 1150 | 1171 | } |
| 1151 | 1172 | |
| 1152 | −static bool | |
| 1153 | − pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, | |
| 1154 | − struct dc_state *dc_state, | |
| 1155 | − struct dsc_mst_fairness_vars *vars) | |
| 1173 | +static int pre_compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, | |
| 1174 | + struct dc_state *dc_state, | |
| 1175 | + struct dsc_mst_fairness_vars *vars) | |
| 1156 | 1176 | { |
| 1157 | 1177 | int i, j; |
| 1158 | 1178 | struct dc_stream_state *stream; |
| 1159 | 1179 | bool computed_streams[MAX_PIPES]; |
| 1160 | 1180 | struct amdgpu_dm_connector *aconnector; |
| 1181 | + struct drm_dp_mst_topology_mgr *mst_mgr; | |
| 1161 | 1182 | int link_vars_start_index = 0; |
| 1183 | + int ret = 0; | |
| 1162 | 1184 | |
| 1163 | 1185 | for (i = 0; i < dc_state->stream_count; i++) |
| 1164 | 1186 | computed_streams[i] = false; |
| @@ -1171,7 +1193,7 @@ static bool · 6 unmodified lines | ||
| 1171 | 1193 | |
| 1172 | 1194 | aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; |
| 1173 | 1195 | |
| 1174 | − if (!aconnector || !aconnector->dc_sink) | |
| 1196 | + if (!aconnector || !aconnector->dc_sink || !aconnector->port) | |
| 1175 | 1197 | continue; |
| 1176 | 1198 | |
| 1177 | 1199 | if (!aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported) |
| @@ -1183,14 +1205,11 @@ static bool · 5 unmodified lines | ||
| 1183 | 1205 | if (!is_dsc_need_re_compute(state, dc_state, stream->link)) |
| 1184 | 1206 | continue; |
| 1185 | 1207 | |
| 1186 | − mutex_lock(&aconnector->mst_mgr.lock); | |
| 1187 | − if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars, | |
| 1188 | − &aconnector->mst_mgr, | |
| 1189 | − &link_vars_start_index)) { | |
| 1190 | − mutex_unlock(&aconnector->mst_mgr.lock); | |
| 1191 | − return false; | |
| 1192 | − } | |
| 1193 | − mutex_unlock(&aconnector->mst_mgr.lock); | |
| 1208 | + mst_mgr = aconnector->port->mgr; | |
| 1209 | + ret = compute_mst_dsc_configs_for_link(state, dc_state, stream->link, vars, mst_mgr, | |
| 1210 | + &link_vars_start_index); | |
| 1211 | + if (ret != 0) | |
| 1212 | + return ret; | |
| 1194 | 1213 | |
| 1195 | 1214 | for (j = 0; j < dc_state->stream_count; j++) { |
| 1196 | 1215 | if (dc_state->streams[j]->link == stream->link) |
| @@ -1198,7 +1217,7 @@ static bool · 1 unmodified line | ||
| 1198 | 1217 | } |
| 1199 | 1218 | } |
| 1200 | 1219 | |
| 1201 | − return true; | |
| 1220 | + return ret; | |
| 1202 | 1221 | } |
| 1203 | 1222 | |
| 1204 | 1223 | static int find_crtc_index_in_state_by_stream(struct drm_atomic_state *state, |
| @@ -1253,9 +1272,9 @@ static bool is_dsc_precompute_needed(struct drm_atomic_state *state) · 48 unmodified lines | ||
| 1253 | 1272 | return ret; |
| 1254 | 1273 | } |
| 1255 | 1274 | |
| 1256 | −bool pre_validate_dsc(struct drm_atomic_state *state, | |
| 1257 | − struct dm_atomic_state **dm_state_ptr, | |
| 1258 | − struct dsc_mst_fairness_vars *vars) | |
| 1275 | +int pre_validate_dsc(struct drm_atomic_state *state, | |
| 1276 | + struct dm_atomic_state **dm_state_ptr, | |
| 1277 | + struct dsc_mst_fairness_vars *vars) | |
| 1259 | 1278 | { |
| 1260 | 1279 | int i; |
| 1261 | 1280 | struct dm_atomic_state *dm_state; |
| @@ -1264,11 +1283,12 @@ bool pre_validate_dsc(struct drm_atomic_state *state, · 2 unmodified lines | ||
| 1264 | 1283 | |
| 1265 | 1284 | if (!is_dsc_precompute_needed(state)) { |
| 1266 | 1285 | DRM_INFO_ONCE("DSC precompute is not needed.\n"); |
| 1267 | − return true; | |
| 1286 | + return 0; | |
| 1268 | 1287 | } |
| 1269 | − if (dm_atomic_get_state(state, dm_state_ptr)) { | |
| 1288 | + ret = dm_atomic_get_state(state, dm_state_ptr); | |
| 1289 | + if (ret != 0) { | |
| 1270 | 1290 | DRM_INFO_ONCE("dm_atomic_get_state() failed\n"); |
| 1271 | − return false; | |
| 1291 | + return ret; | |
| 1272 | 1292 | } |
| 1273 | 1293 | dm_state = *dm_state_ptr; |
| 1274 | 1294 | |
| @@ -1280,7 +1300,7 @@ bool pre_validate_dsc(struct drm_atomic_state *state, · 5 unmodified lines | ||
| 1280 | 1300 | |
| 1281 | 1301 | local_dc_state = kmemdup(dm_state->context, sizeof(struct dc_state), GFP_KERNEL); |
| 1282 | 1302 | if (!local_dc_state) |
| 1283 | − return false; | |
| 1303 | + return -ENOMEM; | |
| 1284 | 1304 | |
| 1285 | 1305 | for (i = 0; i < local_dc_state->stream_count; i++) { |
| 1286 | 1306 | struct dc_stream_state *stream = dm_state->context->streams[i]; |
| @@ -1316,9 +1336,9 @@ bool pre_validate_dsc(struct drm_atomic_state *state, · 29 unmodified lines | ||
| 1316 | 1336 | if (ret != 0) |
| 1317 | 1337 | goto clean_exit; |
| 1318 | 1338 | |
| 1319 | − if (!pre_compute_mst_dsc_configs_for_state(state, local_dc_state, vars)) { | |
| 1339 | + ret = pre_compute_mst_dsc_configs_for_state(state, local_dc_state, vars); | |
| 1340 | + if (ret != 0) { | |
| 1320 | 1341 | DRM_INFO_ONCE("pre_compute_mst_dsc_configs_for_state() failed\n"); |
| 1321 | − ret = -EINVAL; | |
| 1322 | 1342 | goto clean_exit; |
| 1323 | 1343 | } |
| 1324 | 1344 | |
| @@ -1349,7 +1369,7 @@ clean_exit: · 24 unmodified lines | ||
| 1349 | 1369 | |
| 1350 | 1370 | kfree(local_dc_state); |
| 1351 | 1371 | |
| 1352 | − return (ret == 0); | |
| 1372 | + return ret; | |
| 1353 | 1373 | } |
| 1354 | 1374 | |
| 1355 | 1375 | static unsigned int kbps_from_pbn(unsigned int pbn) |
| @@ -1392,6 +1412,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( · 36 unmodified lines | ||
| 1392 | 1412 | unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0; |
| 1393 | 1413 | unsigned int max_compressed_bw_in_kbps = 0; |
| 1394 | 1414 | struct dc_dsc_bw_range bw_range = {0}; |
| 1415 | + struct drm_dp_mst_topology_mgr *mst_mgr; | |
| 1395 | 1416 | |
| 1396 | 1417 | /* |
| 1397 | 1418 | * check if the mode could be supported if DSC pass-through is supported |
| @@ -1400,7 +1421,8 @@ enum dc_status dm_dp_mst_is_port_support_mode( · 2 unmodified lines | ||
| 1400 | 1421 | */ |
| 1401 | 1422 | if (is_dsc_common_config_possible(stream, &bw_range) && |
| 1402 | 1423 | aconnector->port->passthrough_aux) { |
| 1403 | − mutex_lock(&aconnector->mst_mgr.lock); | |
| 1424 | + mst_mgr = aconnector->port->mgr; | |
| 1425 | + mutex_lock(&mst_mgr->lock); | |
| 1404 | 1426 | |
| 1405 | 1427 | cur_link_settings = stream->link->verified_link_cap; |
| 1406 | 1428 | |
| @@ -1413,7 +1435,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( · 6 unmodified lines | ||
| 1413 | 1435 | end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps, |
| 1414 | 1436 | down_link_bw_in_kbps); |
| 1415 | 1437 | |
| 1416 | − mutex_unlock(&aconnector->mst_mgr.lock); | |
| 1438 | + mutex_unlock(&mst_mgr->lock); | |
| 1417 | 1439 | |
| 1418 | 1440 | /* |
| 1419 | 1441 | * use the maximum dsc compression bandwidth as the required |
| @@ -53,15 +53,15 @@ struct dsc_mst_fairness_vars { · 52 unmodified lines | ||
| 53 | 53 | struct amdgpu_dm_connector *aconnector; |
| 54 | 54 | }; |
| 55 | 55 | |
| 56 | −bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, | |
| 57 | − struct dc_state *dc_state, | |
| 58 | − struct dsc_mst_fairness_vars *vars); | |
| 56 | +int compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, | |
| 57 | + struct dc_state *dc_state, | |
| 58 | + struct dsc_mst_fairness_vars *vars); | |
| 59 | 59 | |
| 60 | 60 | bool needs_dsc_aux_workaround(struct dc_link *link); |
| 61 | 61 | |
| 62 | −bool pre_validate_dsc(struct drm_atomic_state *state, | |
| 63 | − struct dm_atomic_state **dm_state_ptr, | |
| 64 | − struct dsc_mst_fairness_vars *vars); | |
| 62 | +int pre_validate_dsc(struct drm_atomic_state *state, | |
| 63 | + struct dm_atomic_state **dm_state_ptr, | |
| 64 | + struct dsc_mst_fairness_vars *vars); | |
| 65 | 65 | |
| 66 | 66 | enum dc_status dm_dp_mst_is_port_support_mode( |
| 67 | 67 | struct amdgpu_dm_connector *aconnector, |
| @@ -2393,6 +2393,26 @@ static enum bp_result get_vram_info_v25( · 2392 unmodified lines | ||
| 2393 | 2393 | return result; |
| 2394 | 2394 | } |
| 2395 | 2395 | |
| 2396 | +static enum bp_result get_vram_info_v30( | |
| 2397 | + struct bios_parser *bp, | |
| 2398 | + struct dc_vram_info *info) | |
| 2399 | +{ | |
| 2400 | + struct atom_vram_info_header_v3_0 *info_v30; | |
| 2401 | + enum bp_result result = BP_RESULT_OK; | |
| 2402 | + | |
| 2403 | + info_v30 = GET_IMAGE(struct atom_vram_info_header_v3_0, | |
| 2404 | + DATA_TABLES(vram_info)); | |
| 2405 | + | |
| 2406 | + if (info_v30 == NULL) | |
| 2407 | + return BP_RESULT_BADBIOSTABLE; | |
| 2408 | + | |
| 2409 | + info->num_chans = info_v30->channel_num; | |
| 2410 | + info->dram_channel_width_bytes = (1 << info_v30->channel_width) / 8; | |
| 2411 | + | |
| 2412 | + return result; | |
| 2413 | +} | |
| 2414 | + | |
| 2415 | + | |
| 2396 | 2416 | /* |
| 2397 | 2417 | * get_integrated_info_v11 |
| 2398 | 2418 | * |
| @@ -3060,6 +3080,16 @@ static enum bp_result bios_parser_get_vram_info( · 661 unmodified lines | ||
| 3060 | 3080 | } |
| 3061 | 3081 | break; |
| 3062 | 3082 | |
| 3083 | + case 3: | |
| 3084 | + switch (revision.minor) { | |
| 3085 | + case 0: | |
| 3086 | + result = get_vram_info_v30(bp, info); | |
| 3087 | + break; | |
| 3088 | + default: | |
| 3089 | + break; | |
| 3090 | + } | |
| 3091 | + break; | |
| 3092 | + | |
| 3063 | 3093 | default: |
| 3064 | 3094 | return result; |
| 3065 | 3095 | } |
| @@ -363,32 +363,32 @@ static struct wm_table ddr5_wm_table = { · 362 unmodified lines | ||
| 363 | 363 | .wm_inst = WM_A, |
| 364 | 364 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 365 | 365 | .pstate_latency_us = 11.72, |
| 366 | − .sr_exit_time_us = 9, | |
| 367 | − .sr_enter_plus_exit_time_us = 11, | |
| 366 | + .sr_exit_time_us = 12.5, | |
| 367 | + .sr_enter_plus_exit_time_us = 14.5, | |
| 368 | 368 | .valid = true, |
| 369 | 369 | }, |
| 370 | 370 | { |
| 371 | 371 | .wm_inst = WM_B, |
| 372 | 372 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 373 | 373 | .pstate_latency_us = 11.72, |
| 374 | − .sr_exit_time_us = 9, | |
| 375 | − .sr_enter_plus_exit_time_us = 11, | |
| 374 | + .sr_exit_time_us = 12.5, | |
| 375 | + .sr_enter_plus_exit_time_us = 14.5, | |
| 376 | 376 | .valid = true, |
| 377 | 377 | }, |
| 378 | 378 | { |
| 379 | 379 | .wm_inst = WM_C, |
| 380 | 380 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 381 | 381 | .pstate_latency_us = 11.72, |
| 382 | − .sr_exit_time_us = 9, | |
| 383 | − .sr_enter_plus_exit_time_us = 11, | |
| 382 | + .sr_exit_time_us = 12.5, | |
| 383 | + .sr_enter_plus_exit_time_us = 14.5, | |
| 384 | 384 | .valid = true, |
| 385 | 385 | }, |
| 386 | 386 | { |
| 387 | 387 | .wm_inst = WM_D, |
| 388 | 388 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 389 | 389 | .pstate_latency_us = 11.72, |
| 390 | − .sr_exit_time_us = 9, | |
| 391 | − .sr_enter_plus_exit_time_us = 11, | |
| 390 | + .sr_exit_time_us = 12.5, | |
| 391 | + .sr_enter_plus_exit_time_us = 14.5, | |
| 392 | 392 | .valid = true, |
| 393 | 393 | }, |
| 394 | 394 | } |
| @@ -400,32 +400,32 @@ static struct wm_table lpddr5_wm_table = { · 5 unmodified lines | ||
| 400 | 400 | .wm_inst = WM_A, |
| 401 | 401 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 402 | 402 | .pstate_latency_us = 11.65333, |
| 403 | − .sr_exit_time_us = 11.5, | |
| 404 | − .sr_enter_plus_exit_time_us = 14.5, | |
| 403 | + .sr_exit_time_us = 16.5, | |
| 404 | + .sr_enter_plus_exit_time_us = 18.5, | |
| 405 | 405 | .valid = true, |
| 406 | 406 | }, |
| 407 | 407 | { |
| 408 | 408 | .wm_inst = WM_B, |
| 409 | 409 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 410 | 410 | .pstate_latency_us = 11.65333, |
| 411 | − .sr_exit_time_us = 11.5, | |
| 412 | − .sr_enter_plus_exit_time_us = 14.5, | |
| 411 | + .sr_exit_time_us = 16.5, | |
| 412 | + .sr_enter_plus_exit_time_us = 18.5, | |
| 413 | 413 | .valid = true, |
| 414 | 414 | }, |
| 415 | 415 | { |
| 416 | 416 | .wm_inst = WM_C, |
| 417 | 417 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 418 | 418 | .pstate_latency_us = 11.65333, |
| 419 | − .sr_exit_time_us = 11.5, | |
| 420 | − .sr_enter_plus_exit_time_us = 14.5, | |
| 419 | + .sr_exit_time_us = 16.5, | |
| 420 | + .sr_enter_plus_exit_time_us = 18.5, | |
| 421 | 421 | .valid = true, |
| 422 | 422 | }, |
| 423 | 423 | { |
| 424 | 424 | .wm_inst = WM_D, |
| 425 | 425 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 426 | 426 | .pstate_latency_us = 11.65333, |
| 427 | − .sr_exit_time_us = 11.5, | |
| 428 | − .sr_enter_plus_exit_time_us = 14.5, | |
| 427 | + .sr_exit_time_us = 16.5, | |
| 428 | + .sr_enter_plus_exit_time_us = 18.5, | |
| 429 | 429 | .valid = true, |
| 430 | 430 | }, |
| 431 | 431 | } |
| @@ -123,9 +123,10 @@ static int dcn314_smu_send_msg_with_param(struct clk_mgr_internal *clk_mgr, · 122 unmodified lines | ||
| 123 | 123 | uint32_t result; |
| 124 | 124 | |
| 125 | 125 | result = dcn314_smu_wait_for_response(clk_mgr, 10, 200000); |
| 126 | − ASSERT(result == VBIOSSMC_Result_OK); | |
| 127 | 126 | |
| 128 | − smu_print("SMU response after wait: %d\n", result); | |
| 127 | + if (result != VBIOSSMC_Result_OK) | |
| 128 | + smu_print("SMU Response was not OK. SMU response after wait received is: %d\n", | |
| 129 | + result); | |
| 129 | 130 | |
| 130 | 131 | if (result == VBIOSSMC_Status_BUSY) |
| 131 | 132 | return -1; |
| @@ -216,6 +217,12 @@ int dcn314_smu_set_hard_min_dcfclk(struct clk_mgr_internal *clk_mgr, int request · 84 unmodified lines | ||
| 216 | 217 | VBIOSSMC_MSG_SetHardMinDcfclkByFreq, |
| 217 | 218 | khz_to_mhz_ceil(requested_dcfclk_khz)); |
| 218 | 219 | |
| 220 | +#ifdef DBG | |
| 221 | + smu_print("actual_dcfclk_set_mhz %d is set to : %d\n", | |
| 222 | + actual_dcfclk_set_mhz, | |
| 223 | + actual_dcfclk_set_mhz * 1000); | |
| 224 | +#endif | |
| 225 | + | |
| 219 | 226 | return actual_dcfclk_set_mhz * 1000; |
| 220 | 227 | } |
| 221 | 228 | |
| @@ -157,6 +157,7 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base) · 156 unmodified lines | ||
| 157 | 157 | struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); |
| 158 | 158 | unsigned int num_levels; |
| 159 | 159 | struct clk_limit_num_entries *num_entries_per_clk = &clk_mgr_base->bw_params->clk_table.num_entries_per_clk; |
| 160 | + unsigned int i; | |
| 160 | 161 | |
| 161 | 162 | memset(&(clk_mgr_base->clks), 0, sizeof(struct dc_clocks)); |
| 162 | 163 | clk_mgr_base->clks.p_state_change_support = true; |
| @@ -205,18 +206,17 @@ void dcn32_init_clocks(struct clk_mgr *clk_mgr_base) · 42 unmodified lines | ||
| 205 | 206 | clk_mgr->dpm_present = true; |
| 206 | 207 | |
| 207 | 208 | if (clk_mgr_base->ctx->dc->debug.min_disp_clk_khz) { |
| 208 | − unsigned int i; | |
| 209 | − | |
| 210 | 209 | for (i = 0; i < num_levels; i++) |
| 211 | 210 | if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz |
| 212 | 211 | < khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz)) |
| 213 | 212 | clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz |
| 214 | 213 | = khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_disp_clk_khz); |
| 215 | 214 | } |
| 215 | + for (i = 0; i < num_levels; i++) | |
| 216 | + if (clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz > 1950) | |
| 217 | + clk_mgr_base->bw_params->clk_table.entries[i].dispclk_mhz = 1950; | |
| 216 | 218 | |
| 217 | 219 | if (clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz) { |
| 218 | − unsigned int i; | |
| 219 | − | |
| 220 | 220 | for (i = 0; i < num_levels; i++) |
| 221 | 221 | if (clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz |
| 222 | 222 | < khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz)) |
| @@ -669,6 +669,9 @@ static void dcn32_get_memclk_states_from_smu(struct clk_mgr *clk_mgr_base) · 446 unmodified lines | ||
| 669 | 669 | &clk_mgr_base->bw_params->clk_table.entries[0].memclk_mhz, |
| 670 | 670 | &num_entries_per_clk->num_memclk_levels); |
| 671 | 671 | |
| 672 | + /* memclk must have at least one level */ | |
| 673 | + num_entries_per_clk->num_memclk_levels = num_entries_per_clk->num_memclk_levels ? num_entries_per_clk->num_memclk_levels : 1; | |
| 674 | + | |
| 672 | 675 | dcn32_init_single_clock(clk_mgr, PPCLK_FCLK, |
| 673 | 676 | &clk_mgr_base->bw_params->clk_table.entries[0].fclk_mhz, |
| 674 | 677 | &num_entries_per_clk->num_fclk_levels); |
| @@ -852,6 +852,8 @@ struct dc_debug_options { · 851 unmodified lines | ||
| 852 | 852 | bool enable_double_buffered_dsc_pg_support; |
| 853 | 853 | bool enable_dp_dig_pixel_rate_div_policy; |
| 854 | 854 | enum lttpr_mode lttpr_mode_override; |
| 855 | + unsigned int dsc_delay_factor_wa_x1000; | |
| 856 | + unsigned int min_prefetch_in_strobe_ns; | |
| 855 | 857 | }; |
| 856 | 858 | |
| 857 | 859 | struct gpu_info_soc_bounding_box_v1_0; |
| @@ -359,7 +359,8 @@ static const struct dce_audio_registers audio_regs[] = { · 358 unmodified lines | ||
| 359 | 359 | audio_regs(2), |
| 360 | 360 | audio_regs(3), |
| 361 | 361 | audio_regs(4), |
| 362 | − audio_regs(5) | |
| 362 | + audio_regs(5), | |
| 363 | + audio_regs(6), | |
| 363 | 364 | }; |
| 364 | 365 | |
| 365 | 366 | #define DCE120_AUD_COMMON_MASK_SH_LIST(mask_sh)\ |
| @@ -436,34 +436,48 @@ void dpp1_set_cursor_position( · 435 unmodified lines | ||
| 436 | 436 | uint32_t height) |
| 437 | 437 | { |
| 438 | 438 | struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base); |
| 439 | − int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; | |
| 440 | − int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y; | |
| 439 | + int x_pos = pos->x - param->viewport.x; | |
| 440 | + int y_pos = pos->y - param->viewport.y; | |
| 441 | + int x_hotspot = pos->x_hotspot; | |
| 442 | + int y_hotspot = pos->y_hotspot; | |
| 443 | + int src_x_offset = x_pos - pos->x_hotspot; | |
| 444 | + int src_y_offset = y_pos - pos->y_hotspot; | |
| 445 | + int cursor_height = (int)height; | |
| 446 | + int cursor_width = (int)width; | |
| 441 | 447 | uint32_t cur_en = pos->enable ? 1 : 0; |
| 442 | 448 | |
| 443 | − // Cursor width/height and hotspots need to be rotated for offset calculation | |
| 449 | + // Transform cursor width / height and hotspots for offset calculations | |
| 444 | 450 | if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { |
| 445 | − swap(width, height); | |
| 451 | + swap(cursor_height, cursor_width); | |
| 452 | + swap(x_hotspot, y_hotspot); | |
| 453 | + | |
| 446 | 454 | if (param->rotation == ROTATION_ANGLE_90) { |
| 447 | − src_x_offset = pos->x - pos->y_hotspot - param->viewport.x; | |
| 448 | − src_y_offset = pos->y - pos->x_hotspot - param->viewport.y; | |
| 455 | + // hotspot = (-y, x) | |
| 456 | + src_x_offset = x_pos - (cursor_width - x_hotspot); | |
| 457 | + src_y_offset = y_pos - y_hotspot; | |
| 458 | + } else if (param->rotation == ROTATION_ANGLE_270) { | |
| 459 | + // hotspot = (y, -x) | |
| 460 | + src_x_offset = x_pos - x_hotspot; | |
| 461 | + src_y_offset = y_pos - (cursor_height - y_hotspot); | |
| 449 | 462 | } |
| 450 | 463 | } else if (param->rotation == ROTATION_ANGLE_180) { |
| 464 | + // hotspot = (-x, -y) | |
| 451 | 465 | if (!param->mirror) |
| 452 | − src_x_offset = pos->x - param->viewport.x; | |
| 466 | + src_x_offset = x_pos - (cursor_width - x_hotspot); | |
| 453 | 467 | |
| 454 | − src_y_offset = pos->y - param->viewport.y; | |
| 468 | + src_y_offset = y_pos - (cursor_height - y_hotspot); | |
| 455 | 469 | } |
| 456 | 470 | |
| 457 | 471 | if (src_x_offset >= (int)param->viewport.width) |
| 458 | 472 | cur_en = 0; /* not visible beyond right edge*/ |
| 459 | 473 | |
| 460 | − if (src_x_offset + (int)width <= 0) | |
| 474 | + if (src_x_offset + cursor_width <= 0) | |
| 461 | 475 | cur_en = 0; /* not visible beyond left edge*/ |
| 462 | 476 | |
| 463 | 477 | if (src_y_offset >= (int)param->viewport.height) |
| 464 | 478 | cur_en = 0; /* not visible beyond bottom edge*/ |
| 465 | 479 | |
| 466 | − if (src_y_offset + (int)height <= 0) | |
| 480 | + if (src_y_offset + cursor_height <= 0) | |
| 467 | 481 | cur_en = 0; /* not visible beyond top edge*/ |
| 468 | 482 | |
| 469 | 483 | REG_UPDATE(CURSOR0_CONTROL, |
| @@ -1179,10 +1179,12 @@ void hubp1_cursor_set_position( · 1178 unmodified lines | ||
| 1179 | 1179 | const struct dc_cursor_mi_param *param) |
| 1180 | 1180 | { |
| 1181 | 1181 | struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp); |
| 1182 | − int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; | |
| 1183 | − int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y; | |
| 1182 | + int x_pos = pos->x - param->viewport.x; | |
| 1183 | + int y_pos = pos->y - param->viewport.y; | |
| 1184 | 1184 | int x_hotspot = pos->x_hotspot; |
| 1185 | 1185 | int y_hotspot = pos->y_hotspot; |
| 1186 | + int src_x_offset = x_pos - pos->x_hotspot; | |
| 1187 | + int src_y_offset = y_pos - pos->y_hotspot; | |
| 1186 | 1188 | int cursor_height = (int)hubp->curs_attr.height; |
| 1187 | 1189 | int cursor_width = (int)hubp->curs_attr.width; |
| 1188 | 1190 | uint32_t dst_x_offset; |
| @@ -1200,18 +1202,26 @@ void hubp1_cursor_set_position( · 11 unmodified lines | ||
| 1200 | 1202 | if (hubp->curs_attr.address.quad_part == 0) |
| 1201 | 1203 | return; |
| 1202 | 1204 | |
| 1203 | − // Rotated cursor width/height and hotspots tweaks for offset calculation | |
| 1205 | + // Transform cursor width / height and hotspots for offset calculations | |
| 1204 | 1206 | if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { |
| 1205 | 1207 | swap(cursor_height, cursor_width); |
| 1208 | + swap(x_hotspot, y_hotspot); | |
| 1209 | + | |
| 1206 | 1210 | if (param->rotation == ROTATION_ANGLE_90) { |
| 1207 | − src_x_offset = pos->x - pos->y_hotspot - param->viewport.x; | |
| 1208 | − src_y_offset = pos->y - pos->x_hotspot - param->viewport.y; | |
| 1211 | + // hotspot = (-y, x) | |
| 1212 | + src_x_offset = x_pos - (cursor_width - x_hotspot); | |
| 1213 | + src_y_offset = y_pos - y_hotspot; | |
| 1214 | + } else if (param->rotation == ROTATION_ANGLE_270) { | |
| 1215 | + // hotspot = (y, -x) | |
| 1216 | + src_x_offset = x_pos - x_hotspot; | |
| 1217 | + src_y_offset = y_pos - (cursor_height - y_hotspot); | |
| 1209 | 1218 | } |
| 1210 | 1219 | } else if (param->rotation == ROTATION_ANGLE_180) { |
| 1220 | + // hotspot = (-x, -y) | |
| 1211 | 1221 | if (!param->mirror) |
| 1212 | − src_x_offset = pos->x - param->viewport.x; | |
| 1222 | + src_x_offset = x_pos - (cursor_width - x_hotspot); | |
| 1213 | 1223 | |
| 1214 | − src_y_offset = pos->y - param->viewport.y; | |
| 1224 | + src_y_offset = y_pos - (cursor_height - y_hotspot); | |
| 1215 | 1225 | } |
| 1216 | 1226 | |
| 1217 | 1227 | dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; |
| @@ -1248,8 +1258,8 @@ void hubp1_cursor_set_position( · 30 unmodified lines | ||
| 1248 | 1258 | CURSOR_Y_POSITION, pos->y); |
| 1249 | 1259 | |
| 1250 | 1260 | REG_SET_2(CURSOR_HOT_SPOT, 0, |
| 1251 | − CURSOR_HOT_SPOT_X, x_hotspot, | |
| 1252 | − CURSOR_HOT_SPOT_Y, y_hotspot); | |
| 1261 | + CURSOR_HOT_SPOT_X, pos->x_hotspot, | |
| 1262 | + CURSOR_HOT_SPOT_Y, pos->y_hotspot); | |
| 1253 | 1263 | |
| 1254 | 1264 | REG_SET(CURSOR_DST_OFFSET, 0, |
| 1255 | 1265 | CURSOR_DST_X_OFFSET, dst_x_offset); |
| @@ -623,6 +623,10 @@ void hubp2_cursor_set_attributes( · 622 unmodified lines | ||
| 623 | 623 | hubp->att.size.bits.width = attr->width; |
| 624 | 624 | hubp->att.size.bits.height = attr->height; |
| 625 | 625 | hubp->att.cur_ctl.bits.mode = attr->color_format; |
| 626 | + | |
| 627 | + hubp->cur_rect.w = attr->width; | |
| 628 | + hubp->cur_rect.h = attr->height; | |
| 629 | + | |
| 626 | 630 | hubp->att.cur_ctl.bits.pitch = hw_pitch; |
| 627 | 631 | hubp->att.cur_ctl.bits.line_per_chunk = lpc; |
| 628 | 632 | hubp->att.cur_ctl.bits.cur_2x_magnify = attr->attribute_flags.bits.ENABLE_MAGNIFICATION; |
| @@ -969,10 +973,12 @@ void hubp2_cursor_set_position( · 340 unmodified lines | ||
| 969 | 973 | const struct dc_cursor_mi_param *param) |
| 970 | 974 | { |
| 971 | 975 | struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); |
| 972 | − int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x; | |
| 973 | − int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y; | |
| 976 | + int x_pos = pos->x - param->viewport.x; | |
| 977 | + int y_pos = pos->y - param->viewport.y; | |
| 974 | 978 | int x_hotspot = pos->x_hotspot; |
| 975 | 979 | int y_hotspot = pos->y_hotspot; |
| 980 | + int src_x_offset = x_pos - pos->x_hotspot; | |
| 981 | + int src_y_offset = y_pos - pos->y_hotspot; | |
| 976 | 982 | int cursor_height = (int)hubp->curs_attr.height; |
| 977 | 983 | int cursor_width = (int)hubp->curs_attr.width; |
| 978 | 984 | uint32_t dst_x_offset; |
| @@ -990,18 +996,26 @@ void hubp2_cursor_set_position( · 11 unmodified lines | ||
| 990 | 996 | if (hubp->curs_attr.address.quad_part == 0) |
| 991 | 997 | return; |
| 992 | 998 | |
| 993 | − // Rotated cursor width/height and hotspots tweaks for offset calculation | |
| 999 | + // Transform cursor width / height and hotspots for offset calculations | |
| 994 | 1000 | if (param->rotation == ROTATION_ANGLE_90 || param->rotation == ROTATION_ANGLE_270) { |
| 995 | 1001 | swap(cursor_height, cursor_width); |
| 1002 | + swap(x_hotspot, y_hotspot); | |
| 1003 | + | |
| 996 | 1004 | if (param->rotation == ROTATION_ANGLE_90) { |
| 997 | − src_x_offset = pos->x - pos->y_hotspot - param->viewport.x; | |
| 998 | − src_y_offset = pos->y - pos->x_hotspot - param->viewport.y; | |
| 1005 | + // hotspot = (-y, x) | |
| 1006 | + src_x_offset = x_pos - (cursor_width - x_hotspot); | |
| 1007 | + src_y_offset = y_pos - y_hotspot; | |
| 1008 | + } else if (param->rotation == ROTATION_ANGLE_270) { | |
| 1009 | + // hotspot = (y, -x) | |
| 1010 | + src_x_offset = x_pos - x_hotspot; | |
| 1011 | + src_y_offset = y_pos - (cursor_height - y_hotspot); | |
| 999 | 1012 | } |
| 1000 | 1013 | } else if (param->rotation == ROTATION_ANGLE_180) { |
| 1014 | + // hotspot = (-x, -y) | |
| 1001 | 1015 | if (!param->mirror) |
| 1002 | − src_x_offset = pos->x - param->viewport.x; | |
| 1016 | + src_x_offset = x_pos - (cursor_width - x_hotspot); | |
| 1003 | 1017 | |
| 1004 | − src_y_offset = pos->y - param->viewport.y; | |
| 1018 | + src_y_offset = y_pos - (cursor_height - y_hotspot); | |
| 1005 | 1019 | } |
| 1006 | 1020 | |
| 1007 | 1021 | dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; |
| @@ -1038,8 +1052,8 @@ void hubp2_cursor_set_position( · 30 unmodified lines | ||
| 1038 | 1052 | CURSOR_Y_POSITION, pos->y); |
| 1039 | 1053 | |
| 1040 | 1054 | REG_SET_2(CURSOR_HOT_SPOT, 0, |
| 1041 | − CURSOR_HOT_SPOT_X, x_hotspot, | |
| 1042 | − CURSOR_HOT_SPOT_Y, y_hotspot); | |
| 1055 | + CURSOR_HOT_SPOT_X, pos->x_hotspot, | |
| 1056 | + CURSOR_HOT_SPOT_Y, pos->y_hotspot); | |
| 1043 | 1057 | |
| 1044 | 1058 | REG_SET(CURSOR_DST_OFFSET, 0, |
| 1045 | 1059 | CURSOR_DST_X_OFFSET, dst_x_offset); |
| @@ -1048,8 +1062,8 @@ void hubp2_cursor_set_position( · 2 unmodified lines | ||
| 1048 | 1062 | hubp->pos.cur_ctl.bits.cur_enable = cur_en; |
| 1049 | 1063 | hubp->pos.position.bits.x_pos = pos->x; |
| 1050 | 1064 | hubp->pos.position.bits.y_pos = pos->y; |
| 1051 | − hubp->pos.hot_spot.bits.x_hot = x_hotspot; | |
| 1052 | − hubp->pos.hot_spot.bits.y_hot = y_hotspot; | |
| 1065 | + hubp->pos.hot_spot.bits.x_hot = pos->x_hotspot; | |
| 1066 | + hubp->pos.hot_spot.bits.y_hot = pos->y_hotspot; | |
| 1053 | 1067 | hubp->pos.dst_offset.bits.dst_x_offset = dst_x_offset; |
| 1054 | 1068 | /* Cursor Rectangle Cache |
| 1055 | 1069 | * Cursor bitmaps have different hotspot values |
| @@ -87,6 +87,7 @@ static struct hubp_funcs dcn31_hubp_funcs = { · 86 unmodified lines | ||
| 87 | 87 | .hubp_init = hubp3_init, |
| 88 | 88 | .set_unbounded_requesting = hubp31_set_unbounded_requesting, |
| 89 | 89 | .hubp_soft_reset = hubp31_soft_reset, |
| 90 | + .hubp_set_flip_int = hubp1_set_flip_int, | |
| 90 | 91 | .hubp_in_blank = hubp1_in_blank, |
| 91 | 92 | .program_extended_blank = hubp31_program_extended_blank, |
| 92 | 93 | }; |
| @@ -96,6 +96,13 @@ static void dccg314_set_pixel_rate_div( · 95 unmodified lines | ||
| 96 | 96 | struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); |
| 97 | 97 | enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA; |
| 98 | 98 | |
| 99 | + // Don't program 0xF into the register field. Not valid since | |
| 100 | + // K1 / K2 field is only 1 / 2 bits wide | |
| 101 | + if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) { | |
| 102 | + BREAK_TO_DEBUGGER(); | |
| 103 | + return; | |
| 104 | + } | |
| 105 | + | |
| 99 | 106 | dccg314_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2); |
| 100 | 107 | if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA || (k1 == cur_k1 && k2 == cur_k2)) |
| 101 | 108 | return; |
| @@ -49,18 +49,30 @@ · 48 unmodified lines | ||
| 49 | 49 | #define CTX \ |
| 50 | 50 | enc1->base.ctx |
| 51 | 51 | |
| 52 | +static void enc314_reset_fifo(struct stream_encoder *enc, bool reset) | |
| 53 | +{ | |
| 54 | + struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); | |
| 55 | + uint32_t reset_val = reset ? 1 : 0; | |
| 56 | + uint32_t is_symclk_on; | |
| 57 | + | |
| 58 | + REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, reset_val); | |
| 59 | + REG_GET(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, &is_symclk_on); | |
| 60 | + | |
| 61 | + if (is_symclk_on) | |
| 62 | + REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, reset_val, 10, 5000); | |
| 63 | + else | |
| 64 | + udelay(10); | |
| 65 | +} | |
| 52 | 66 | |
| 53 | 67 | static void enc314_enable_fifo(struct stream_encoder *enc) |
| 54 | 68 | { |
| 55 | 69 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
| 56 | 70 | |
| 57 | − /* TODO: Confirm if we need to wait for DIG_SYMCLK_FE_ON */ | |
| 58 | − REG_WAIT(DIG_FE_CNTL, DIG_SYMCLK_FE_ON, 1, 10, 5000); | |
| 59 | 71 | REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7); |
| 60 | − REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 1); | |
| 61 | − REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 1, 10, 5000); | |
| 62 | − REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_RESET, 0); | |
| 63 | − REG_WAIT(DIG_FIFO_CTRL0, DIG_FIFO_RESET_DONE, 0, 10, 5000); | |
| 72 | + | |
| 73 | + enc314_reset_fifo(enc, true); | |
| 74 | + enc314_reset_fifo(enc, false); | |
| 75 | + | |
| 64 | 76 | REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 1); |
| 65 | 77 | } |
| 66 | 78 | |
| @@ -348,10 +348,8 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig · 347 unmodified lines | ||
| 348 | 348 | two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing); |
| 349 | 349 | odm_combine_factor = get_odm_config(pipe_ctx, NULL); |
| 350 | 350 | |
| 351 | − if (pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL) | |
| 352 | − return odm_combine_factor; | |
| 353 | − | |
| 354 | 351 | if (is_dp_128b_132b_signal(pipe_ctx)) { |
| 352 | + *k1_div = PIXEL_RATE_DIV_BY_1; | |
| 355 | 353 | *k2_div = PIXEL_RATE_DIV_BY_1; |
| 356 | 354 | } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) { |
| 357 | 355 | *k1_div = PIXEL_RATE_DIV_BY_1; |
| @@ -359,7 +357,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig · 1 unmodified line | ||
| 359 | 357 | *k2_div = PIXEL_RATE_DIV_BY_2; |
| 360 | 358 | else |
| 361 | 359 | *k2_div = PIXEL_RATE_DIV_BY_4; |
| 362 | − } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) { | |
| 360 | + } else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) { | |
| 363 | 361 | if (two_pix_per_container) { |
| 364 | 362 | *k1_div = PIXEL_RATE_DIV_BY_1; |
| 365 | 363 | *k2_div = PIXEL_RATE_DIV_BY_2; |
| @@ -237,7 +237,7 @@ static struct timing_generator_funcs dcn314_tg_funcs = { · 236 unmodified lines | ||
| 237 | 237 | .clear_optc_underflow = optc1_clear_optc_underflow, |
| 238 | 238 | .setup_global_swap_lock = NULL, |
| 239 | 239 | .get_crc = optc1_get_crc, |
| 240 | − .configure_crc = optc2_configure_crc, | |
| 240 | + .configure_crc = optc1_configure_crc, | |
| 241 | 241 | .set_dsc_config = optc3_set_dsc_config, |
| 242 | 242 | .get_dsc_status = optc2_get_dsc_status, |
| 243 | 243 | .set_dwb_source = NULL, |
| @@ -847,7 +847,7 @@ static const struct resource_caps res_cap_dcn314 = { · 846 unmodified lines | ||
| 847 | 847 | .num_ddc = 5, |
| 848 | 848 | .num_vmid = 16, |
| 849 | 849 | .num_mpc_3dlut = 2, |
| 850 | − .num_dsc = 3, | |
| 850 | + .num_dsc = 4, | |
| 851 | 851 | }; |
| 852 | 852 | |
| 853 | 853 | static const struct dc_plane_cap plane_cap = { |
| @@ -96,8 +96,10 @@ static void dccg32_set_pixel_rate_div( · 95 unmodified lines | ||
| 96 | 96 | |
| 97 | 97 | // Don't program 0xF into the register field. Not valid since |
| 98 | 98 | // K1 / K2 field is only 1 / 2 bits wide |
| 99 | − if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) | |
| 99 | + if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) { | |
| 100 | + BREAK_TO_DEBUGGER(); | |
| 100 | 101 | return; |
| 102 | + } | |
| 101 | 103 | |
| 102 | 104 | dccg32_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2); |
| 103 | 105 | if (k1 == cur_k1 && k2 == cur_k2) |
| @@ -283,8 +283,7 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c · 282 unmodified lines | ||
| 283 | 283 | using the max for calculation */ |
| 284 | 284 | |
| 285 | 285 | if (hubp->curs_attr.width > 0) { |
| 286 | − // Round cursor width to next multiple of 64 | |
| 287 | − cursor_size = (((hubp->curs_attr.width + 63) / 64) * 64) * hubp->curs_attr.height; | |
| 286 | + cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height; | |
| 288 | 287 | |
| 289 | 288 | switch (pipe->stream->cursor_attributes.color_format) { |
| 290 | 289 | case CURSOR_MODE_MONO: |
| @@ -309,9 +308,9 @@ static uint32_t dcn32_calculate_cab_allocation(struct dc *dc, struct dc_state *c · 18 unmodified lines | ||
| 309 | 308 | cursor_size > 16384) { |
| 310 | 309 | /* cursor_num_mblk = CEILING(num_cursors*cursor_width*cursor_width*cursor_Bpe/mblk_bytes, 1) |
| 311 | 310 | */ |
| 312 | − cache_lines_used += (((hubp->curs_attr.width * hubp->curs_attr.height * cursor_bpp + | |
| 313 | − DCN3_2_MALL_MBLK_SIZE_BYTES - 1) / DCN3_2_MALL_MBLK_SIZE_BYTES) * | |
| 314 | − DCN3_2_MALL_MBLK_SIZE_BYTES) / dc->caps.cache_line_size + 2; | |
| 311 | + cache_lines_used += (((cursor_size + DCN3_2_MALL_MBLK_SIZE_BYTES - 1) / | |
| 312 | + DCN3_2_MALL_MBLK_SIZE_BYTES) * DCN3_2_MALL_MBLK_SIZE_BYTES) / | |
| 313 | + dc->caps.cache_line_size + 2; | |
| 315 | 314 | } |
| 316 | 315 | break; |
| 317 | 316 | } |
| @@ -727,10 +726,7 @@ void dcn32_update_mall_sel(struct dc *dc, struct dc_state *context) · 409 unmodified lines | ||
| 727 | 726 | struct hubp *hubp = pipe->plane_res.hubp; |
| 728 | 727 | |
| 729 | 728 | if (pipe->stream && pipe->plane_state && hubp && hubp->funcs->hubp_update_mall_sel) { |
| 730 | − //Round cursor width up to next multiple of 64 | |
| 731 | − int cursor_width = ((hubp->curs_attr.width + 63) / 64) * 64; | |
| 732 | − int cursor_height = hubp->curs_attr.height; | |
| 733 | − int cursor_size = cursor_width * cursor_height; | |
| 729 | + int cursor_size = hubp->curs_attr.pitch * hubp->curs_attr.height; | |
| 734 | 730 | |
| 735 | 731 | switch (hubp->curs_attr.color_format) { |
| 736 | 732 | case CURSOR_MODE_MONO: |
| @@ -1175,10 +1171,8 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign · 438 unmodified lines | ||
| 1175 | 1171 | two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing); |
| 1176 | 1172 | odm_combine_factor = get_odm_config(pipe_ctx, NULL); |
| 1177 | 1173 | |
| 1178 | − if (pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL) | |
| 1179 | − return odm_combine_factor; | |
| 1180 | − | |
| 1181 | 1174 | if (is_dp_128b_132b_signal(pipe_ctx)) { |
| 1175 | + *k1_div = PIXEL_RATE_DIV_BY_1; | |
| 1182 | 1176 | *k2_div = PIXEL_RATE_DIV_BY_1; |
| 1183 | 1177 | } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) { |
| 1184 | 1178 | *k1_div = PIXEL_RATE_DIV_BY_1; |
| @@ -724,6 +724,7 @@ static const struct dc_debug_options debug_defaults_drv = { · 723 unmodified lines | ||
| 724 | 724 | .enable_dp_dig_pixel_rate_div_policy = 1, |
| 725 | 725 | .allow_sw_cursor_fallback = false, |
| 726 | 726 | .alloc_extra_way_for_cursor = true, |
| 727 | + .min_prefetch_in_strobe_ns = 60000, // 60us | |
| 727 | 728 | }; |
| 728 | 729 | |
| 729 | 730 | static const struct dc_debug_options debug_defaults_diags = { |
| @@ -111,7 +111,7 @@ uint32_t dcn32_helper_calculate_num_ways_for_subvp(struct dc *dc, struct dc_stat · 110 unmodified lines | ||
| 111 | 111 | mall_alloc_width_blk_aligned = full_vp_width_blk_aligned; |
| 112 | 112 | |
| 113 | 113 | /* mall_alloc_height_blk_aligned_l/c = CEILING(sub_vp_height_l/c - 1, blk_height_l/c) + blk_height_l/c */ |
| 114 | − mall_alloc_height_blk_aligned = (pipe->stream->timing.v_addressable - 1 + mblk_height - 1) / | |
| 114 | + mall_alloc_height_blk_aligned = (pipe->plane_res.scl_data.viewport.height - 1 + mblk_height - 1) / | |
| 115 | 115 | mblk_height * mblk_height + mblk_height; |
| 116 | 116 | |
| 117 | 117 | /* full_mblk_width_ub_l/c = mall_alloc_width_blk_aligned_l/c; |
| @@ -722,6 +722,7 @@ static const struct dc_debug_options debug_defaults_drv = { · 721 unmodified lines | ||
| 722 | 722 | .enable_dp_dig_pixel_rate_div_policy = 1, |
| 723 | 723 | .allow_sw_cursor_fallback = false, |
| 724 | 724 | .alloc_extra_way_for_cursor = true, |
| 725 | + .min_prefetch_in_strobe_ns = 60000, // 60us | |
| 725 | 726 | }; |
| 726 | 727 | |
| 727 | 728 | static const struct dc_debug_options debug_defaults_diags = { |
| @@ -1228,6 +1228,7 @@ int dcn20_populate_dml_pipes_from_context( · 1227 unmodified lines | ||
| 1228 | 1228 | pipes[pipe_cnt].pipe.src.dcc = false; |
| 1229 | 1229 | pipes[pipe_cnt].pipe.src.dcc_rate = 1; |
| 1230 | 1230 | pipes[pipe_cnt].pipe.dest.synchronized_vblank_all_planes = synchronized_vblank; |
| 1231 | + pipes[pipe_cnt].pipe.dest.synchronize_timings = synchronized_vblank; | |
| 1231 | 1232 | pipes[pipe_cnt].pipe.dest.hblank_start = timing->h_total - timing->h_front_porch; |
| 1232 | 1233 | pipes[pipe_cnt].pipe.dest.hblank_end = pipes[pipe_cnt].pipe.dest.hblank_start |
| 1233 | 1234 | - timing->h_addressable |
| @@ -146,8 +146,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_14_soc = { · 145 unmodified lines | ||
| 146 | 146 | }, |
| 147 | 147 | }, |
| 148 | 148 | .num_states = 5, |
| 149 | − .sr_exit_time_us = 9.0, | |
| 150 | − .sr_enter_plus_exit_time_us = 11.0, | |
| 149 | + .sr_exit_time_us = 16.5, | |
| 150 | + .sr_enter_plus_exit_time_us = 18.5, | |
| 151 | 151 | .sr_exit_z8_time_us = 442.0, |
| 152 | 152 | .sr_enter_plus_exit_z8_time_us = 560.0, |
| 153 | 153 | .writeback_latency_us = 12.0, |
| @@ -157,7 +157,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_2_soc = { · 156 unmodified lines | ||
| 157 | 157 | .dispclk_dppclk_vco_speed_mhz = 4300.0, |
| 158 | 158 | .do_urgent_latency_adjustment = true, |
| 159 | 159 | .urgent_latency_adjustment_fabric_clock_component_us = 1.0, |
| 160 | − .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000, | |
| 160 | + .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000, | |
| 161 | 161 | }; |
| 162 | 162 | |
| 163 | 163 | void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr) |
| @@ -211,7 +211,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr) · 47 unmodified lines | ||
| 211 | 211 | /* 'DalDummyClockChangeLatencyNs' registry key option set to 0x7FFFFFFF can be used to disable Set C for dummy p-state */ |
| 212 | 212 | if (clk_mgr->base.ctx->dc->bb_overrides.dummy_clock_change_latency_ns != 0x7FFFFFFF) { |
| 213 | 213 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].valid = true; |
| 214 | − clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 38; | |
| 214 | + clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.pstate_latency_us = 50; | |
| 215 | 215 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.fclk_change_latency_us = fclk_change_latency_us; |
| 216 | 216 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us = sr_exit_time_us; |
| 217 | 217 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us = sr_enter_plus_exit_time_us; |
| @@ -221,7 +221,7 @@ void dcn32_build_wm_range_table_fpu(struct clk_mgr_internal *clk_mgr) · 3 unmodified lines | ||
| 221 | 221 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.min_uclk = min_uclk_mhz; |
| 222 | 222 | clk_mgr->base.bw_params->wm_table.nv_entries[WM_C].pmfw_breakdown.max_uclk = 0xFFFF; |
| 223 | 223 | clk_mgr->base.bw_params->dummy_pstate_table[0].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz * 16; |
| 224 | − clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 38; | |
| 224 | + clk_mgr->base.bw_params->dummy_pstate_table[0].dummy_pstate_latency_us = 50; | |
| 225 | 225 | clk_mgr->base.bw_params->dummy_pstate_table[1].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[1].memclk_mhz * 16; |
| 226 | 226 | clk_mgr->base.bw_params->dummy_pstate_table[1].dummy_pstate_latency_us = 9; |
| 227 | 227 | clk_mgr->base.bw_params->dummy_pstate_table[2].dram_speed_mts = clk_mgr->base.bw_params->clk_table.entries[2].memclk_mhz * 16; |
| @@ -1803,6 +1803,12 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, · 1575 unmodified lines | ||
| 1803 | 1803 | */ |
| 1804 | 1804 | context->bw_ctx.dml.soc.dram_clock_change_latency_us = |
| 1805 | 1805 | dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; |
| 1806 | + /* For DCN32/321 need to validate with fclk pstate change latency equal to dummy so | |
| 1807 | + * prefetch is scheduled correctly to account for dummy pstate. | |
| 1808 | + */ | |
| 1809 | + if (dummy_latency_index == 0) | |
| 1810 | + context->bw_ctx.dml.soc.fclk_change_latency_us = | |
| 1811 | + dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us; | |
| 1806 | 1812 | dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, false); |
| 1807 | 1813 | maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb; |
| 1808 | 1814 | dcfclk_from_fw_based_mclk_switching = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; |
| @@ -1904,7 +1910,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, · 95 unmodified lines | ||
| 1904 | 1910 | |
| 1905 | 1911 | if (context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] == |
| 1906 | 1912 | dm_dram_clock_change_unsupported) { |
| 1907 | − int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries - 1; | |
| 1913 | + int min_dram_speed_mts_offset = dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels - 1; | |
| 1908 | 1914 | |
| 1909 | 1915 | min_dram_speed_mts = |
| 1910 | 1916 | dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16; |
| @@ -1990,6 +1996,10 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, · 79 unmodified lines | ||
| 1990 | 1996 | |
| 1991 | 1997 | context->perf_params.stutter_period_us = context->bw_ctx.dml.vba.StutterPeriod; |
| 1992 | 1998 | |
| 1999 | + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && dummy_latency_index == 0) | |
| 2000 | + context->bw_ctx.dml.soc.fclk_change_latency_us = | |
| 2001 | + dc->clk_mgr->bw_params->dummy_pstate_table[dummy_latency_index].dummy_pstate_latency_us; | |
| 2002 | + | |
| 1993 | 2003 | dcn32_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel); |
| 1994 | 2004 | |
| 1995 | 2005 | if (!pstate_en) |
| @@ -1997,8 +2007,12 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, · 1 unmodified line | ||
| 1997 | 2007 | context->bw_ctx.dml.soc.dram_clock_change_latency_us = |
| 1998 | 2008 | dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us; |
| 1999 | 2009 | |
| 2000 | − if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) | |
| 2010 | + if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { | |
| 2001 | 2011 | dcn30_setup_mclk_switch_using_fw_based_vblank_stretch(dc, context); |
| 2012 | + if (dummy_latency_index == 0) | |
| 2013 | + context->bw_ctx.dml.soc.fclk_change_latency_us = | |
| 2014 | + dc->clk_mgr->bw_params->wm_table.nv_entries[WM_A].dml_input.fclk_change_latency_us; | |
| 2015 | + } | |
| 2002 | 2016 | } |
| 2003 | 2017 | |
| 2004 | 2018 | static void dcn32_get_optimal_dcfclk_fclk_for_uclk(unsigned int uclk_mts, |
| @@ -2359,9 +2373,13 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa · 354 unmodified lines | ||
| 2359 | 2373 | |
| 2360 | 2374 | if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes) |
| 2361 | 2375 | dcn3_2_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes; |
| 2362 | − | |
| 2363 | 2376 | } |
| 2364 | 2377 | |
| 2378 | + /* DML DSC delay factor workaround */ | |
| 2379 | + dcn3_2_ip.dsc_delay_factor_wa = dc->debug.dsc_delay_factor_wa_x1000 / 1000.0; | |
| 2380 | + | |
| 2381 | + dcn3_2_ip.min_prefetch_in_strobe_us = dc->debug.min_prefetch_in_strobe_ns / 1000.0; | |
| 2382 | + | |
| 2365 | 2383 | /* Override dispclk_dppclk_vco_speed_mhz from Clk Mgr */ |
| 2366 | 2384 | dcn3_2_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; |
| 2367 | 2385 | dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; |
| @@ -364,10 +364,11 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman · 363 unmodified lines | ||
| 364 | 364 | for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) { |
| 365 | 365 | v->DSCDelay[k] = dml32_DSCDelayRequirement(mode_lib->vba.DSCEnabled[k], |
| 366 | 366 | mode_lib->vba.ODMCombineEnabled[k], mode_lib->vba.DSCInputBitPerComponent[k], |
| 367 | − mode_lib->vba.OutputBpp[k], mode_lib->vba.HActive[k], mode_lib->vba.HTotal[k], | |
| 367 | + mode_lib->vba.OutputBppPerState[mode_lib->vba.VoltageLevel][k], | |
| 368 | + mode_lib->vba.HActive[k], mode_lib->vba.HTotal[k], | |
| 368 | 369 | mode_lib->vba.NumberOfDSCSlices[k], mode_lib->vba.OutputFormat[k], |
| 369 | 370 | mode_lib->vba.Output[k], mode_lib->vba.PixelClock[k], |
| 370 | − mode_lib->vba.PixelClockBackEnd[k]); | |
| 371 | + mode_lib->vba.PixelClockBackEnd[k], mode_lib->vba.ip.dsc_delay_factor_wa); | |
| 371 | 372 | } |
| 372 | 373 | |
| 373 | 374 | for (k = 0; k < mode_lib->vba.NumberOfActiveSurfaces; ++k) |
| @@ -717,6 +718,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman · 343 unmodified lines | ||
| 717 | 718 | |
| 718 | 719 | do { |
| 719 | 720 | MaxTotalRDBandwidth = 0; |
| 721 | + DestinationLineTimesForPrefetchLessThan2 = false; | |
| 722 | + VRatioPrefetchMoreThanMax = false; | |
| 720 | 723 | #ifdef __DML_VBA_DEBUG__ |
| 721 | 724 | dml_print("DML::%s: Start loop: VStartup = %d\n", __func__, mode_lib->vba.VStartupLines); |
| 722 | 725 | #endif |
| @@ -785,6 +788,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman · 62 unmodified lines | ||
| 785 | 788 | v->SwathHeightY[k], |
| 786 | 789 | v->SwathHeightC[k], |
| 787 | 790 | TWait, |
| 791 | + v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ ? | |
| 792 | + mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, | |
| 788 | 793 | /* Output */ |
| 789 | 794 | &v->DSTXAfterScaler[k], |
| 790 | 795 | &v->DSTYAfterScaler[k], |
| @@ -1627,7 +1632,7 @@ static void mode_support_configuration(struct vba_vars_st *v, · 836 unmodified lines | ||
| 1627 | 1632 | && !mode_lib->vba.MSOOrODMSplitWithNonDPLink |
| 1628 | 1633 | && !mode_lib->vba.NotEnoughLanesForMSO |
| 1629 | 1634 | && mode_lib->vba.LinkCapacitySupport[i] == true && !mode_lib->vba.P2IWith420 |
| 1630 | − && !mode_lib->vba.DSCOnlyIfNecessaryWithBPP | |
| 1635 | + //&& !mode_lib->vba.DSCOnlyIfNecessaryWithBPP | |
| 1631 | 1636 | && !mode_lib->vba.DSC422NativeNotSupported |
| 1632 | 1637 | && !mode_lib->vba.MPCCombineMethodIncompatible |
| 1633 | 1638 | && mode_lib->vba.ODMCombine2To1SupportCheckOK[i] == true |
| @@ -2475,7 +2480,8 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 841 unmodified lines | ||
| 2475 | 2480 | mode_lib->vba.OutputBppPerState[i][k], mode_lib->vba.HActive[k], |
| 2476 | 2481 | mode_lib->vba.HTotal[k], mode_lib->vba.NumberOfDSCSlices[k], |
| 2477 | 2482 | mode_lib->vba.OutputFormat[k], mode_lib->vba.Output[k], |
| 2478 | − mode_lib->vba.PixelClock[k], mode_lib->vba.PixelClockBackEnd[k]); | |
| 2483 | + mode_lib->vba.PixelClock[k], mode_lib->vba.PixelClockBackEnd[k], | |
| 2484 | + mode_lib->vba.ip.dsc_delay_factor_wa); | |
| 2479 | 2485 | } |
| 2480 | 2486 | |
| 2481 | 2487 | for (k = 0; k <= mode_lib->vba.NumberOfActiveSurfaces - 1; k++) { |
| @@ -3190,6 +3196,7 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 708 unmodified lines | ||
| 3190 | 3196 | mode_lib->vba.FCLKChangeLatency, mode_lib->vba.UrgLatency[i], |
| 3191 | 3197 | mode_lib->vba.SREnterPlusExitTime); |
| 3192 | 3198 | |
| 3199 | + memset(&v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull, 0, sizeof(DmlPipe)); | |
| 3193 | 3200 | v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.Dppclk = mode_lib->vba.RequiredDPPCLK[i][j][k]; |
| 3194 | 3201 | v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.Dispclk = mode_lib->vba.RequiredDISPCLK[i][j]; |
| 3195 | 3202 | v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.myPipe.PixelClock = mode_lib->vba.PixelClock[k]; |
| @@ -3242,6 +3249,8 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l · 46 unmodified lines | ||
| 3242 | 3249 | v->swath_width_chroma_ub_this_state[k], |
| 3243 | 3250 | v->SwathHeightYThisState[k], |
| 3244 | 3251 | v->SwathHeightCThisState[k], v->TWait, |
| 3252 | + v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ ? | |
| 3253 | + mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, | |
| 3245 | 3254 | |
| 3246 | 3255 | /* Output */ |
| 3247 | 3256 | &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.DSTXAfterScaler[k], |
| @@ -46,9 +46,14 @@ · 45 unmodified lines | ||
| 46 | 46 | // Prefetch schedule max vratio |
| 47 | 47 | #define __DML_MAX_VRATIO_PRE__ 4.0 |
| 48 | 48 | |
| 49 | +#define __DML_VBA_MAX_DST_Y_PRE__ 63.75 | |
| 50 | + | |
| 49 | 51 | #define BPP_INVALID 0 |
| 50 | 52 | #define BPP_BLENDED_PIPE 0xffffffff |
| 51 | 53 | |
| 54 | +#define MEM_STROBE_FREQ_MHZ 1600 | |
| 55 | +#define MEM_STROBE_MAX_DELIVERY_TIME_US 60.0 | |
| 56 | + | |
| 52 | 57 | struct display_mode_lib; |
| 53 | 58 | |
| 54 | 59 | void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib); |
| @@ -1726,7 +1726,8 @@ unsigned int dml32_DSCDelayRequirement(bool DSCEnabled, · 1725 unmodified lines | ||
| 1726 | 1726 | enum output_format_class OutputFormat, |
| 1727 | 1727 | enum output_encoder_class Output, |
| 1728 | 1728 | double PixelClock, |
| 1729 | − double PixelClockBackEnd) | |
| 1729 | + double PixelClockBackEnd, | |
| 1730 | + double dsc_delay_factor_wa) | |
| 1730 | 1731 | { |
| 1731 | 1732 | unsigned int DSCDelayRequirement_val; |
| 1732 | 1733 | |
| @@ -1746,7 +1747,7 @@ unsigned int dml32_DSCDelayRequirement(bool DSCEnabled, · 13 unmodified lines | ||
| 1746 | 1747 | } |
| 1747 | 1748 | |
| 1748 | 1749 | DSCDelayRequirement_val = DSCDelayRequirement_val + (HTotal - HActive) * |
| 1749 | − dml_ceil(DSCDelayRequirement_val / HActive, 1); | |
| 1750 | + dml_ceil((double)DSCDelayRequirement_val / HActive, 1); | |
| 1750 | 1751 | |
| 1751 | 1752 | DSCDelayRequirement_val = DSCDelayRequirement_val * PixelClock / PixelClockBackEnd; |
| 1752 | 1753 | |
| @@ -1764,7 +1765,7 @@ unsigned int dml32_DSCDelayRequirement(bool DSCEnabled, · 11 unmodified lines | ||
| 1764 | 1765 | dml_print("DML::%s: DSCDelayRequirement_val = %d\n", __func__, DSCDelayRequirement_val); |
| 1765 | 1766 | #endif |
| 1766 | 1767 | |
| 1767 | − return DSCDelayRequirement_val; | |
| 1768 | + return dml_ceil(DSCDelayRequirement_val * dsc_delay_factor_wa, 1); | |
| 1768 | 1769 | } |
| 1769 | 1770 | |
| 1770 | 1771 | void dml32_CalculateSurfaceSizeInMall( |
| @@ -3416,6 +3417,7 @@ bool dml32_CalculatePrefetchSchedule( · 1645 unmodified lines | ||
| 3416 | 3417 | unsigned int SwathHeightY, |
| 3417 | 3418 | unsigned int SwathHeightC, |
| 3418 | 3419 | double TWait, |
| 3420 | + double TPreReq, | |
| 3419 | 3421 | /* Output */ |
| 3420 | 3422 | double *DSTXAfterScaler, |
| 3421 | 3423 | double *DSTYAfterScaler, |
| @@ -3666,6 +3668,7 @@ bool dml32_CalculatePrefetchSchedule( · 244 unmodified lines | ||
| 3666 | 3668 | dst_y_prefetch_equ = VStartup - (*TSetup + dml_max(TWait + TCalc, *Tdmdl)) / LineTime - |
| 3667 | 3669 | (*DSTYAfterScaler + (double) *DSTXAfterScaler / (double) myPipe->HTotal); |
| 3668 | 3670 | |
| 3671 | + dst_y_prefetch_equ = dml_min(dst_y_prefetch_equ, __DML_VBA_MAX_DST_Y_PRE__); | |
| 3669 | 3672 | #ifdef __DML_VBA_DEBUG__ |
| 3670 | 3673 | dml_print("DML::%s: HTotal = %d\n", __func__, myPipe->HTotal); |
| 3671 | 3674 | dml_print("DML::%s: min_Lsw = %f\n", __func__, min_Lsw); |
| @@ -3725,7 +3728,8 @@ bool dml32_CalculatePrefetchSchedule( · 53 unmodified lines | ||
| 3725 | 3728 | *VRatioPrefetchY = 0; |
| 3726 | 3729 | *VRatioPrefetchC = 0; |
| 3727 | 3730 | *RequiredPrefetchPixDataBWLuma = 0; |
| 3728 | − if (dst_y_prefetch_equ > 1) { | |
| 3731 | + if (dst_y_prefetch_equ > 1 && | |
| 3732 | + (Tpre_rounded >= TPreReq || dst_y_prefetch_equ == __DML_VBA_MAX_DST_Y_PRE__)) { | |
| 3729 | 3733 | double PrefetchBandwidth1; |
| 3730 | 3734 | double PrefetchBandwidth2; |
| 3731 | 3735 | double PrefetchBandwidth3; |
| @@ -3871,7 +3875,11 @@ bool dml32_CalculatePrefetchSchedule( · 139 unmodified lines | ||
| 3871 | 3875 | } |
| 3872 | 3876 | |
| 3873 | 3877 | if (dst_y_prefetch_oto < dst_y_prefetch_equ) { |
| 3874 | − *DestinationLinesForPrefetch = dst_y_prefetch_oto; | |
| 3878 | + if (dst_y_prefetch_oto * LineTime < TPreReq) { | |
| 3879 | + *DestinationLinesForPrefetch = dst_y_prefetch_equ; | |
| 3880 | + } else { | |
| 3881 | + *DestinationLinesForPrefetch = dst_y_prefetch_oto; | |
| 3882 | + } | |
| 3875 | 3883 | TimeForFetchingMetaPTE = Tvm_oto; |
| 3876 | 3884 | TimeForFetchingRowInVBlank = Tr0_oto; |
| 3877 | 3885 | *PrefetchBandwidth = prefetch_bw_oto; |
| @@ -4396,7 +4404,7 @@ void dml32_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport( · 518 unmodified lines | ||
| 4396 | 4404 | |
| 4397 | 4405 | if (v->NumberOfActiveSurfaces > 1) { |
| 4398 | 4406 | ActiveClockChangeLatencyHidingY = ActiveClockChangeLatencyHidingY |
| 4399 | − - (1 - 1 / v->NumberOfActiveSurfaces) * SwathHeightY[k] * v->HTotal[k] | |
| 4407 | + - (1.0 - 1.0 / v->NumberOfActiveSurfaces) * SwathHeightY[k] * v->HTotal[k] | |
| 4400 | 4408 | / v->PixelClock[k] / v->VRatio[k]; |
| 4401 | 4409 | } |
| 4402 | 4410 | |
| @@ -30,7 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #include "os_types.h" |
| 31 | 31 | #include "../dc_features.h" |
| 32 | 32 | #include "../display_mode_structs.h" |
| 33 | −#include "dml/display_mode_vba.h" | |
| 33 | +#include "../display_mode_vba.h" | |
| 34 | 34 | |
| 35 | 35 | unsigned int dml32_dscceComputeDelay( |
| 36 | 36 | unsigned int bpc, |
| @@ -327,7 +327,8 @@ unsigned int dml32_DSCDelayRequirement(bool DSCEnabled, · 290 unmodified lines | ||
| 327 | 327 | enum output_format_class OutputFormat, |
| 328 | 328 | enum output_encoder_class Output, |
| 329 | 329 | double PixelClock, |
| 330 | − double PixelClockBackEnd); | |
| 330 | + double PixelClockBackEnd, | |
| 331 | + double dsc_delay_factor_wa); | |
| 331 | 332 | |
| 332 | 333 | void dml32_CalculateSurfaceSizeInMall( |
| 333 | 334 | unsigned int NumberOfActiveSurfaces, |
| @@ -742,6 +743,7 @@ bool dml32_CalculatePrefetchSchedule( · 408 unmodified lines | ||
| 742 | 743 | unsigned int SwathHeightY, |
| 743 | 744 | unsigned int SwathHeightC, |
| 744 | 745 | double TWait, |
| 746 | + double TPreReq, | |
| 745 | 747 | /* Output */ |
| 746 | 748 | double *DSTXAfterScaler, |
| 747 | 749 | double *DSTYAfterScaler, |
| @@ -291,8 +291,8 @@ void dml32_rq_dlg_get_dlg_reg(struct display_mode_lib *mode_lib, · 290 unmodified lines | ||
| 291 | 291 | |
| 292 | 292 | dml_print("DML_DLG: %s: vready_after_vcount0 = %d\n", __func__, dlg_regs->vready_after_vcount0); |
| 293 | 293 | |
| 294 | − dst_x_after_scaler = get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); | |
| 295 | − dst_y_after_scaler = get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx); | |
| 294 | + dst_x_after_scaler = dml_ceil(get_dst_x_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx), 1); | |
| 295 | + dst_y_after_scaler = dml_ceil(get_dst_y_after_scaler(mode_lib, e2e_pipe_param, num_pipes, pipe_idx), 1); | |
| 296 | 296 | |
| 297 | 297 | // do some adjustment on the dst_after scaler to account for odm combine mode |
| 298 | 298 | dml_print("DML_DLG: %s: input dst_x_after_scaler = %d\n", __func__, dst_x_after_scaler); |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include "dcn321_fpu.h" |
| 30 | 30 | #include "dcn32/dcn32_resource.h" |
| 31 | 31 | #include "dcn321/dcn321_resource.h" |
| 32 | +#include "dml/dcn32/display_mode_vba_util_32.h" | |
| 32 | 33 | |
| 33 | 34 | #define DCN3_2_DEFAULT_DET_SIZE 256 |
| 34 | 35 | |
| @@ -119,15 +120,15 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = { · 84 unmodified lines | ||
| 119 | 120 | }, |
| 120 | 121 | }, |
| 121 | 122 | .num_states = 1, |
| 122 | − .sr_exit_time_us = 12.36, | |
| 123 | − .sr_enter_plus_exit_time_us = 16.72, | |
| 123 | + .sr_exit_time_us = 19.95, | |
| 124 | + .sr_enter_plus_exit_time_us = 24.36, | |
| 124 | 125 | .sr_exit_z8_time_us = 285.0, |
| 125 | 126 | .sr_enter_plus_exit_z8_time_us = 320, |
| 126 | 127 | .writeback_latency_us = 12.0, |
| 127 | 128 | .round_trip_ping_latency_dcfclk_cycles = 263, |
| 128 | − .urgent_latency_pixel_data_only_us = 4.0, | |
| 129 | − .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, | |
| 130 | − .urgent_latency_vm_data_only_us = 4.0, | |
| 129 | + .urgent_latency_pixel_data_only_us = 4, | |
| 130 | + .urgent_latency_pixel_mixed_with_vm_data_us = 4, | |
| 131 | + .urgent_latency_vm_data_only_us = 4, | |
| 131 | 132 | .fclk_change_latency_us = 20, |
| 132 | 133 | .usr_retraining_latency_us = 2, |
| 133 | 134 | .smn_latency_us = 2, |
| @@ -155,7 +156,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_21_soc = { · 21 unmodified lines | ||
| 155 | 156 | .dispclk_dppclk_vco_speed_mhz = 4300.0, |
| 156 | 157 | .do_urgent_latency_adjustment = true, |
| 157 | 158 | .urgent_latency_adjustment_fabric_clock_component_us = 1.0, |
| 158 | − .urgent_latency_adjustment_fabric_clock_reference_mhz = 1000, | |
| 159 | + .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000, | |
| 159 | 160 | }; |
| 160 | 161 | |
| 161 | 162 | static void get_optimal_ntuple(struct _vcs_dpi_voltage_scaling_st *entry) |
| @@ -538,9 +539,13 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p · 376 unmodified lines | ||
| 538 | 539 | |
| 539 | 540 | if (dc->ctx->dc_bios->vram_info.dram_channel_width_bytes) |
| 540 | 541 | dcn3_21_soc.dram_channel_width_bytes = dc->ctx->dc_bios->vram_info.dram_channel_width_bytes; |
| 541 | − | |
| 542 | 542 | } |
| 543 | 543 | |
| 544 | + /* DML DSC delay factor workaround */ | |
| 545 | + dcn3_21_ip.dsc_delay_factor_wa = dc->debug.dsc_delay_factor_wa_x1000 / 1000.0; | |
| 546 | + | |
| 547 | + dcn3_21_ip.min_prefetch_in_strobe_us = dc->debug.min_prefetch_in_strobe_ns / 1000.0; | |
| 548 | + | |
| 544 | 549 | /* Override dispclk_dppclk_vco_speed_mhz from Clk Mgr */ |
| 545 | 550 | dcn3_21_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; |
| 546 | 551 | dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; |
| @@ -364,6 +364,10 @@ struct _vcs_dpi_ip_params_st { · 363 unmodified lines | ||
| 364 | 364 | unsigned int max_num_dp2p0_outputs; |
| 365 | 365 | unsigned int max_num_dp2p0_streams; |
| 366 | 366 | unsigned int VBlankNomDefaultUS; |
| 367 | + | |
| 368 | + /* DM workarounds */ | |
| 369 | + double dsc_delay_factor_wa; // TODO: Remove after implementing root cause fix | |
| 370 | + double min_prefetch_in_strobe_us; | |
| 367 | 371 | }; |
| 368 | 372 | |
| 369 | 373 | struct _vcs_dpi_display_xfc_params_st { |
| @@ -625,7 +625,7 @@ static void fetch_pipe_params(struct display_mode_lib *mode_lib) · 624 unmodified lines | ||
| 625 | 625 | mode_lib->vba.skip_dio_check[mode_lib->vba.NumberOfActivePlanes] = |
| 626 | 626 | dout->is_virtual; |
| 627 | 627 | |
| 628 | − if (!dout->dsc_enable) | |
| 628 | + if (dout->dsc_enable) | |
| 629 | 629 | mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = dout->output_bpp; |
| 630 | 630 | else |
| 631 | 631 | mode_lib->vba.ForcedOutputLinkBPP[mode_lib->vba.NumberOfActivePlanes] = 0.0; |
| @@ -107,6 +107,13 @@ static const struct ddc_registers ddc_data_regs_dcn[] = { · 106 unmodified lines | ||
| 107 | 107 | ddc_data_regs_dcn2(3), |
| 108 | 108 | ddc_data_regs_dcn2(4), |
| 109 | 109 | ddc_data_regs_dcn2(5), |
| 110 | + { | |
| 111 | + // add a dummy entry for cases no such port | |
| 112 | + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, | |
| 113 | + .ddc_setup = 0, | |
| 114 | + .phy_aux_cntl = 0, | |
| 115 | + .dc_gpio_aux_ctrl_5 = 0 | |
| 116 | + }, | |
| 110 | 117 | { |
| 111 | 118 | DDC_GPIO_VGA_REG_LIST(DATA), |
| 112 | 119 | .ddc_setup = 0, |
| @@ -121,6 +128,13 @@ static const struct ddc_registers ddc_clk_regs_dcn[] = { · 8 unmodified lines | ||
| 121 | 128 | ddc_clk_regs_dcn2(3), |
| 122 | 129 | ddc_clk_regs_dcn2(4), |
| 123 | 130 | ddc_clk_regs_dcn2(5), |
| 131 | + { | |
| 132 | + // add a dummy entry for cases no such port | |
| 133 | + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, | |
| 134 | + .ddc_setup = 0, | |
| 135 | + .phy_aux_cntl = 0, | |
| 136 | + .dc_gpio_aux_ctrl_5 = 0 | |
| 137 | + }, | |
| 124 | 138 | { |
| 125 | 139 | DDC_GPIO_VGA_REG_LIST(CLK), |
| 126 | 140 | .ddc_setup = 0, |
| @@ -94,11 +94,14 @@ static enum gpio_result set_config( · 93 unmodified lines | ||
| 94 | 94 | * is required for detection of AUX mode */ |
| 95 | 95 | if (hw_gpio->base.en != GPIO_DDC_LINE_VIP_PAD) { |
| 96 | 96 | if (!ddc_data_pd_en || !ddc_clk_pd_en) { |
| 97 | − | |
| 98 | − REG_SET_2(gpio.MASK_reg, regval, | |
| 97 | + if (hw_gpio->base.en == GPIO_DDC_LINE_DDC_VGA) { | |
| 98 | + // bit 4 of mask has different usage in some cases | |
| 99 | + REG_SET(gpio.MASK_reg, regval, DC_GPIO_DDC1DATA_PD_EN, 1); | |
| 100 | + } else { | |
| 101 | + REG_SET_2(gpio.MASK_reg, regval, | |
| 99 | 102 | DC_GPIO_DDC1DATA_PD_EN, 1, |
| 100 | 103 | DC_GPIO_DDC1CLK_PD_EN, 1); |
| 101 | − | |
| 104 | + } | |
| 102 | 105 | if (config_data->type == |
| 103 | 106 | GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE) |
| 104 | 107 | msleep(3); |
| @@ -67,22 +67,21 @@ int vega10_fan_ctrl_get_fan_speed_info(struct pp_hwmgr *hwmgr, · 66 unmodified lines | ||
| 67 | 67 | int vega10_fan_ctrl_get_fan_speed_pwm(struct pp_hwmgr *hwmgr, |
| 68 | 68 | uint32_t *speed) |
| 69 | 69 | { |
| 70 | − uint32_t current_rpm; | |
| 71 | − uint32_t percent = 0; | |
| 72 | − | |
| 73 | − if (hwmgr->thermal_controller.fanInfo.bNoFan) | |
| 74 | − return 0; | |
| 70 | + struct amdgpu_device *adev = hwmgr->adev; | |
| 71 | + uint32_t duty100, duty; | |
| 72 | + uint64_t tmp64; | |
| 75 | 73 | |
| 76 | − if (vega10_get_current_rpm(hwmgr, ¤t_rpm)) | |
| 77 | − return -1; | |
| 74 | + duty100 = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_FDO_CTRL1), | |
| 75 | + CG_FDO_CTRL1, FMAX_DUTY100); | |
| 76 | + duty = REG_GET_FIELD(RREG32_SOC15(THM, 0, mmCG_THERMAL_STATUS), | |
| 77 | + CG_THERMAL_STATUS, FDO_PWM_DUTY); | |
| 78 | 78 | |
| 79 | − if (hwmgr->thermal_controller. | |
| 80 | − advanceFanControlParameters.usMaxFanRPM != 0) | |
| 81 | − percent = current_rpm * 255 / | |
| 82 | − hwmgr->thermal_controller. | |
| 83 | − advanceFanControlParameters.usMaxFanRPM; | |
| 79 | + if (!duty100) | |
| 80 | + return -EINVAL; | |
| 84 | 81 | |
| 85 | − *speed = MIN(percent, 255); | |
| 82 | + tmp64 = (uint64_t)duty * 255; | |
| 83 | + do_div(tmp64, duty100); | |
| 84 | + *speed = MIN((uint32_t)tmp64, 255); | |
| 86 | 85 | |
| 87 | 86 | return 0; |
| 88 | 87 | } |
| @@ -1156,22 +1156,21 @@ static int smu_smc_hw_setup(struct smu_context *smu) · 1155 unmodified lines | ||
| 1156 | 1156 | uint64_t features_supported; |
| 1157 | 1157 | int ret = 0; |
| 1158 | 1158 | |
| 1159 | − if (adev->in_suspend && smu_is_dpm_running(smu)) { | |
| 1160 | − dev_info(adev->dev, "dpm has been enabled\n"); | |
| 1161 | − /* this is needed specifically */ | |
| 1162 | − switch (adev->ip_versions[MP1_HWIP][0]) { | |
| 1163 | − case IP_VERSION(11, 0, 7): | |
| 1164 | − case IP_VERSION(11, 0, 11): | |
| 1165 | − case IP_VERSION(11, 5, 0): | |
| 1166 | − case IP_VERSION(11, 0, 12): | |
| 1159 | + switch (adev->ip_versions[MP1_HWIP][0]) { | |
| 1160 | + case IP_VERSION(11, 0, 7): | |
| 1161 | + case IP_VERSION(11, 0, 11): | |
| 1162 | + case IP_VERSION(11, 5, 0): | |
| 1163 | + case IP_VERSION(11, 0, 12): | |
| 1164 | + if (adev->in_suspend && smu_is_dpm_running(smu)) { | |
| 1165 | + dev_info(adev->dev, "dpm has been enabled\n"); | |
| 1167 | 1166 | ret = smu_system_features_control(smu, true); |
| 1168 | 1167 | if (ret) |
| 1169 | 1168 | dev_err(adev->dev, "Failed system features control!\n"); |
| 1170 | − break; | |
| 1171 | − default: | |
| 1172 | − break; | |
| 1169 | + return ret; | |
| 1173 | 1170 | } |
| 1174 | − return ret; | |
| 1171 | + break; | |
| 1172 | + default: | |
| 1173 | + break; | |
| 1175 | 1174 | } |
| 1176 | 1175 | |
| 1177 | 1176 | ret = smu_init_display_count(smu, 0); |
| @@ -1388,6 +1388,14 @@ enum smu_cmn2asic_mapping_type { · 1387 unmodified lines | ||
| 1388 | 1388 | CMN2ASIC_MAPPING_WORKLOAD, |
| 1389 | 1389 | }; |
| 1390 | 1390 | |
| 1391 | +enum smu_baco_seq { | |
| 1392 | + BACO_SEQ_BACO = 0, | |
| 1393 | + BACO_SEQ_MSR, | |
| 1394 | + BACO_SEQ_BAMACO, | |
| 1395 | + BACO_SEQ_ULPS, | |
| 1396 | + BACO_SEQ_COUNT, | |
| 1397 | +}; | |
| 1398 | + | |
| 1391 | 1399 | #define MSG_MAP(msg, index, valid_in_vf) \ |
| 1392 | 1400 | [SMU_MSG_##msg] = {1, (index), (valid_in_vf)} |
| 1393 | 1401 | |
| @@ -25,10 +25,10 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | // *** IMPORTANT *** |
| 27 | 27 | // PMFW TEAM: Always increment the interface version on any change to this file |
| 28 | −#define SMU13_DRIVER_IF_VERSION 0x2C | |
| 28 | +#define SMU13_DRIVER_IF_VERSION 0x35 | |
| 29 | 29 | |
| 30 | 30 | //Increment this version if SkuTable_t or BoardTable_t change |
| 31 | −#define PPTABLE_VERSION 0x20 | |
| 31 | +#define PPTABLE_VERSION 0x27 | |
| 32 | 32 | |
| 33 | 33 | #define NUM_GFXCLK_DPM_LEVELS 16 |
| 34 | 34 | #define NUM_SOCCLK_DPM_LEVELS 8 |
| @@ -96,7 +96,7 @@ · 61 unmodified lines | ||
| 96 | 96 | #define FEATURE_MEM_TEMP_READ_BIT 47 |
| 97 | 97 | #define FEATURE_ATHUB_MMHUB_PG_BIT 48 |
| 98 | 98 | #define FEATURE_SOC_PCC_BIT 49 |
| 99 | −#define FEATURE_SPARE_50_BIT 50 | |
| 99 | +#define FEATURE_EDC_PWRBRK_BIT 50 | |
| 100 | 100 | #define FEATURE_SPARE_51_BIT 51 |
| 101 | 101 | #define FEATURE_SPARE_52_BIT 52 |
| 102 | 102 | #define FEATURE_SPARE_53_BIT 53 |
| @@ -282,15 +282,15 @@ typedef enum { · 179 unmodified lines | ||
| 282 | 282 | } I2cControllerPort_e; |
| 283 | 283 | |
| 284 | 284 | typedef enum { |
| 285 | − I2C_CONTROLLER_NAME_VR_GFX = 0, | |
| 286 | − I2C_CONTROLLER_NAME_VR_SOC, | |
| 287 | − I2C_CONTROLLER_NAME_VR_VMEMP, | |
| 288 | − I2C_CONTROLLER_NAME_VR_VDDIO, | |
| 289 | − I2C_CONTROLLER_NAME_LIQUID0, | |
| 290 | − I2C_CONTROLLER_NAME_LIQUID1, | |
| 291 | − I2C_CONTROLLER_NAME_PLX, | |
| 292 | − I2C_CONTROLLER_NAME_OTHER, | |
| 293 | − I2C_CONTROLLER_NAME_COUNT, | |
| 285 | + I2C_CONTROLLER_NAME_VR_GFX = 0, | |
| 286 | + I2C_CONTROLLER_NAME_VR_SOC, | |
| 287 | + I2C_CONTROLLER_NAME_VR_VMEMP, | |
| 288 | + I2C_CONTROLLER_NAME_VR_VDDIO, | |
| 289 | + I2C_CONTROLLER_NAME_LIQUID0, | |
| 290 | + I2C_CONTROLLER_NAME_LIQUID1, | |
| 291 | + I2C_CONTROLLER_NAME_PLX, | |
| 292 | + I2C_CONTROLLER_NAME_FAN_INTAKE, | |
| 293 | + I2C_CONTROLLER_NAME_COUNT, | |
| 294 | 294 | } I2cControllerName_e; |
| 295 | 295 | |
| 296 | 296 | typedef enum { |
| @@ -302,6 +302,7 @@ typedef enum { · 5 unmodified lines | ||
| 302 | 302 | I2C_CONTROLLER_THROTTLER_LIQUID0, |
| 303 | 303 | I2C_CONTROLLER_THROTTLER_LIQUID1, |
| 304 | 304 | I2C_CONTROLLER_THROTTLER_PLX, |
| 305 | + I2C_CONTROLLER_THROTTLER_FAN_INTAKE, | |
| 305 | 306 | I2C_CONTROLLER_THROTTLER_INA3221, |
| 306 | 307 | I2C_CONTROLLER_THROTTLER_COUNT, |
| 307 | 308 | } I2cControllerThrottler_e; |
| @@ -309,8 +310,9 @@ typedef enum { · 1 unmodified line | ||
| 309 | 310 | typedef enum { |
| 310 | 311 | I2C_CONTROLLER_PROTOCOL_VR_XPDE132G5, |
| 311 | 312 | I2C_CONTROLLER_PROTOCOL_VR_IR35217, |
| 312 | − I2C_CONTROLLER_PROTOCOL_TMP_TMP102A, | |
| 313 | + I2C_CONTROLLER_PROTOCOL_TMP_MAX31875, | |
| 313 | 314 | I2C_CONTROLLER_PROTOCOL_INA3221, |
| 315 | + I2C_CONTROLLER_PROTOCOL_TMP_MAX6604, | |
| 314 | 316 | I2C_CONTROLLER_PROTOCOL_COUNT, |
| 315 | 317 | } I2cControllerProtocol_e; |
| 316 | 318 | |
| @@ -690,6 +692,9 @@ typedef struct { · 373 unmodified lines | ||
| 690 | 692 | #define PP_OD_FEATURE_UCLK_BIT 8 |
| 691 | 693 | #define PP_OD_FEATURE_ZERO_FAN_BIT 9 |
| 692 | 694 | #define PP_OD_FEATURE_TEMPERATURE_BIT 10 |
| 695 | +#define PP_OD_FEATURE_POWER_FEATURE_CTRL_BIT 11 | |
| 696 | +#define PP_OD_FEATURE_ASIC_TDC_BIT 12 | |
| 697 | +#define PP_OD_FEATURE_COUNT 13 | |
| 693 | 698 | |
| 694 | 699 | typedef enum { |
| 695 | 700 | PP_OD_POWER_FEATURE_ALWAYS_ENABLED, |
| @@ -697,6 +702,11 @@ typedef enum { · 1 unmodified line | ||
| 697 | 702 | PP_OD_POWER_FEATURE_ALWAYS_DISABLED, |
| 698 | 703 | } PP_OD_POWER_FEATURE_e; |
| 699 | 704 | |
| 705 | +typedef enum { | |
| 706 | + FAN_MODE_AUTO = 0, | |
| 707 | + FAN_MODE_MANUAL_LINEAR, | |
| 708 | +} FanMode_e; | |
| 709 | + | |
| 700 | 710 | typedef struct { |
| 701 | 711 | uint32_t FeatureCtrlMask; |
| 702 | 712 | |
| @@ -708,8 +718,8 @@ typedef struct { · 5 unmodified lines | ||
| 708 | 718 | uint8_t RuntimePwrSavingFeaturesCtrl; |
| 709 | 719 | |
| 710 | 720 | //Frequency changes |
| 711 | − int16_t GfxclkFmin; // MHz | |
| 712 | − int16_t GfxclkFmax; // MHz | |
| 721 | + int16_t GfxclkFmin; // MHz | |
| 722 | + int16_t GfxclkFmax; // MHz | |
| 713 | 723 | uint16_t UclkFmin; // MHz |
| 714 | 724 | uint16_t UclkFmax; // MHz |
| 715 | 725 | |
| @@ -730,7 +740,12 @@ typedef struct { · 14 unmodified lines | ||
| 730 | 740 | uint8_t MaxOpTemp; |
| 731 | 741 | uint8_t Padding[4]; |
| 732 | 742 | |
| 733 | − uint32_t Spare[12]; | |
| 743 | + uint16_t GfxVoltageFullCtrlMode; | |
| 744 | + uint16_t GfxclkFullCtrlMode; | |
| 745 | + uint16_t UclkFullCtrlMode; | |
| 746 | + int16_t AsicTdc; | |
| 747 | + | |
| 748 | + uint32_t Spare[10]; | |
| 734 | 749 | uint32_t MmHubPadding[8]; // SMU internal use. Adding here instead of external as a workaround |
| 735 | 750 | } OverDriveTable_t; |
| 736 | 751 | |
| @@ -748,8 +763,8 @@ typedef struct { · 11 unmodified lines | ||
| 748 | 763 | uint8_t IdlePwrSavingFeaturesCtrl; |
| 749 | 764 | uint8_t RuntimePwrSavingFeaturesCtrl; |
| 750 | 765 | |
| 751 | − uint16_t GfxclkFmin; // MHz | |
| 752 | − uint16_t GfxclkFmax; // MHz | |
| 766 | + int16_t GfxclkFmin; // MHz | |
| 767 | + int16_t GfxclkFmax; // MHz | |
| 753 | 768 | uint16_t UclkFmin; // MHz |
| 754 | 769 | uint16_t UclkFmax; // MHz |
| 755 | 770 | |
| @@ -769,7 +784,12 @@ typedef struct { · 13 unmodified lines | ||
| 769 | 784 | uint8_t MaxOpTemp; |
| 770 | 785 | uint8_t Padding[4]; |
| 771 | 786 | |
| 772 | − uint32_t Spare[12]; | |
| 787 | + uint16_t GfxVoltageFullCtrlMode; | |
| 788 | + uint16_t GfxclkFullCtrlMode; | |
| 789 | + uint16_t UclkFullCtrlMode; | |
| 790 | + int16_t AsicTdc; | |
| 791 | + | |
| 792 | + uint32_t Spare[10]; | |
| 773 | 793 | |
| 774 | 794 | } OverDriveLimits_t; |
| 775 | 795 | |
| @@ -903,7 +923,8 @@ typedef struct { · 127 unmodified lines | ||
| 903 | 923 | uint16_t FanStartTempMin; |
| 904 | 924 | uint16_t FanStartTempMax; |
| 905 | 925 | |
| 906 | − uint32_t Spare[12]; | |
| 926 | + uint16_t PowerMinPpt0[POWER_SOURCE_COUNT]; | |
| 927 | + uint32_t Spare[11]; | |
| 907 | 928 | |
| 908 | 929 | } MsgLimits_t; |
| 909 | 930 | |
| @@ -1086,11 +1107,13 @@ typedef struct { · 176 unmodified lines | ||
| 1086 | 1107 | uint32_t GfxoffSpare[15]; |
| 1087 | 1108 | |
| 1088 | 1109 | // GFX GPO |
| 1089 | − float DfllBtcMasterScalerM; | |
| 1110 | + uint32_t DfllBtcMasterScalerM; | |
| 1090 | 1111 | int32_t DfllBtcMasterScalerB; |
| 1091 | − float DfllBtcSlaveScalerM; | |
| 1112 | + uint32_t DfllBtcSlaveScalerM; | |
| 1092 | 1113 | int32_t DfllBtcSlaveScalerB; |
| 1093 | − uint32_t GfxGpoSpare[12]; | |
| 1114 | + uint32_t DfllPccAsWaitCtrl; //GDFLL_AS_WAIT_CTRL_PCC register value to be passed to RLC msg | |
| 1115 | + uint32_t DfllPccAsStepCtrl; //GDFLL_AS_STEP_CTRL_PCC register value to be passed to RLC msg | |
| 1116 | + uint32_t GfxGpoSpare[10]; | |
| 1094 | 1117 | |
| 1095 | 1118 | // GFX DCS |
| 1096 | 1119 | |
| @@ -1106,7 +1129,10 @@ typedef struct { · 9 unmodified lines | ||
| 1106 | 1129 | uint16_t DcsTimeout; //This is the amount of time SMU FW waits for RLC to put GFX into GFXOFF before reverting to the fallback mechanism of throttling GFXCLK to Fmin. |
| 1107 | 1130 | |
| 1108 | 1131 | |
| 1109 | − uint32_t DcsSpare[16]; | |
| 1132 | + uint32_t DcsSpare[14]; | |
| 1133 | + | |
| 1134 | + // UCLK section | |
| 1135 | + uint16_t ShadowFreqTableUclk[NUM_UCLK_DPM_LEVELS]; // In MHz | |
| 1110 | 1136 | |
| 1111 | 1137 | // UCLK section |
| 1112 | 1138 | uint8_t UseStrobeModeOptimizations; //Set to indicate that FW should use strobe mode optimizations |
| @@ -1163,13 +1189,14 @@ typedef struct { · 50 unmodified lines | ||
| 1163 | 1189 | uint16_t IntakeTempHighIntakeAcousticLimit; |
| 1164 | 1190 | uint16_t IntakeTempAcouticLimitReleaseRate; |
| 1165 | 1191 | |
| 1166 | − uint16_t FanStalledTempLimitOffset; | |
| 1192 | + int16_t FanAbnormalTempLimitOffset; | |
| 1167 | 1193 | uint16_t FanStalledTriggerRpm; |
| 1168 | − uint16_t FanAbnormalTriggerRpm; | |
| 1169 | − uint16_t FanPadding; | |
| 1170 | − | |
| 1171 | − uint32_t FanSpare[14]; | |
| 1194 | + uint16_t FanAbnormalTriggerRpmCoeff; | |
| 1195 | + uint16_t FanAbnormalDetectionEnable; | |
| 1172 | 1196 | |
| 1197 | + uint8_t FanIntakeSensorSupport; | |
| 1198 | + uint8_t FanIntakePadding[3]; | |
| 1199 | + uint32_t FanSpare[13]; | |
| 1173 | 1200 | // SECTION: VDD_GFX AVFS |
| 1174 | 1201 | |
| 1175 | 1202 | uint8_t OverrideGfxAvfsFuses; |
| @@ -1193,7 +1220,6 @@ typedef struct { · 17 unmodified lines | ||
| 1193 | 1220 | uint32_t dGbV_dT_vmin; |
| 1194 | 1221 | uint32_t dGbV_dT_vmax; |
| 1195 | 1222 | |
| 1196 | − //Unused: PMFW-9370 | |
| 1197 | 1223 | uint32_t V2F_vmin_range_low; |
| 1198 | 1224 | uint32_t V2F_vmin_range_high; |
| 1199 | 1225 | uint32_t V2F_vmax_range_low; |
| @@ -1238,8 +1264,21 @@ typedef struct { · 38 unmodified lines | ||
| 1238 | 1264 | // SECTION: Advanced Options |
| 1239 | 1265 | uint32_t DebugOverrides; |
| 1240 | 1266 | |
| 1267 | + // Section: Total Board Power idle vs active coefficients | |
| 1268 | + uint8_t TotalBoardPowerSupport; | |
| 1269 | + uint8_t TotalBoardPowerPadding[3]; | |
| 1270 | + | |
| 1271 | + int16_t TotalIdleBoardPowerM; | |
| 1272 | + int16_t TotalIdleBoardPowerB; | |
| 1273 | + int16_t TotalBoardPowerM; | |
| 1274 | + int16_t TotalBoardPowerB; | |
| 1275 | + | |
| 1276 | + QuadraticInt_t qFeffCoeffGameClock[POWER_SOURCE_COUNT]; | |
| 1277 | + QuadraticInt_t qFeffCoeffBaseClock[POWER_SOURCE_COUNT]; | |
| 1278 | + QuadraticInt_t qFeffCoeffBoostClock[POWER_SOURCE_COUNT]; | |
| 1279 | + | |
| 1241 | 1280 | // SECTION: Sku Reserved |
| 1242 | − uint32_t Spare[64]; | |
| 1281 | + uint32_t Spare[43]; | |
| 1243 | 1282 | |
| 1244 | 1283 | // Padding for MMHUB - do not modify this |
| 1245 | 1284 | uint32_t MmHubPadding[8]; |
| @@ -1304,7 +1343,8 @@ typedef struct { · 58 unmodified lines | ||
| 1304 | 1343 | // SECTION: Clock Spread Spectrum |
| 1305 | 1344 | |
| 1306 | 1345 | // UCLK Spread Spectrum |
| 1307 | − uint16_t UclkSpreadPadding; | |
| 1346 | + uint8_t UclkTrainingModeSpreadPercent; // Q4.4 | |
| 1347 | + uint8_t UclkSpreadPadding; | |
| 1308 | 1348 | uint16_t UclkSpreadFreq; // kHz |
| 1309 | 1349 | |
| 1310 | 1350 | // UCLK Spread Spectrum |
| @@ -1317,11 +1357,7 @@ typedef struct { · 6 unmodified lines | ||
| 1317 | 1357 | |
| 1318 | 1358 | // Section: Memory Config |
| 1319 | 1359 | uint8_t DramWidth; // Width of interface to the channel for each DRAM module. See DRAM_BIT_WIDTH_TYPE_e |
| 1320 | − uint8_t PaddingMem1[3]; | |
| 1321 | − | |
| 1322 | − // Section: Total Board Power | |
| 1323 | − uint16_t TotalBoardPower; //Only needed for TCP Estimated case, where TCP = TGP+Total Board Power | |
| 1324 | − uint16_t BoardPowerPadding; | |
| 1360 | + uint8_t PaddingMem1[7]; | |
| 1325 | 1361 | |
| 1326 | 1362 | // SECTION: UMC feature flags |
| 1327 | 1363 | uint8_t HsrEnabled; |
| @@ -1423,8 +1459,11 @@ typedef struct { · 95 unmodified lines | ||
| 1423 | 1459 | uint16_t Vcn1ActivityPercentage ; |
| 1424 | 1460 | |
| 1425 | 1461 | uint32_t EnergyAccumulator; |
| 1426 | − uint16_t AverageSocketPower ; | |
| 1462 | + uint16_t AverageSocketPower; | |
| 1463 | + uint16_t AverageTotalBoardPower; | |
| 1464 | + | |
| 1427 | 1465 | uint16_t AvgTemperature[TEMP_COUNT]; |
| 1466 | + uint16_t AvgTemperatureFanIntake; | |
| 1428 | 1467 | |
| 1429 | 1468 | uint8_t PcieRate ; |
| 1430 | 1469 | uint8_t PcieWidth ; |
| @@ -1592,5 +1631,7 @@ typedef struct { · 161 unmodified lines | ||
| 1592 | 1631 | #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D0 0x5 |
| 1593 | 1632 | #define IH_INTERRUPT_CONTEXT_ID_AUDIO_D3 0x6 |
| 1594 | 1633 | #define IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING 0x7 |
| 1634 | +#define IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL 0x8 | |
| 1635 | +#define IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY 0x9 | |
| 1595 | 1636 | |
| 1596 | 1637 | #endif |
| @@ -54,14 +54,14 @@ · 53 unmodified lines | ||
| 54 | 54 | #define PPSMC_MSG_TestMessage 0x01 ///< To check if PMFW is alive and responding. Requirement specified by PMFW team |
| 55 | 55 | #define PPSMC_MSG_GetPmfwVersion 0x02 ///< Get PMFW version |
| 56 | 56 | #define PPSMC_MSG_GetDriverIfVersion 0x03 ///< Get PMFW_DRIVER_IF version |
| 57 | −#define PPSMC_MSG_EnableGfxOff 0x04 ///< Enable GFXOFF | |
| 58 | −#define PPSMC_MSG_DisableGfxOff 0x05 ///< Disable GFXOFF | |
| 57 | +#define PPSMC_MSG_SPARE0 0x04 ///< SPARE | |
| 58 | +#define PPSMC_MSG_SPARE1 0x05 ///< SPARE | |
| 59 | 59 | #define PPSMC_MSG_PowerDownVcn 0x06 ///< Power down VCN |
| 60 | 60 | #define PPSMC_MSG_PowerUpVcn 0x07 ///< Power up VCN; VCN is power gated by default |
| 61 | 61 | #define PPSMC_MSG_SetHardMinVcn 0x08 ///< For wireless display |
| 62 | 62 | #define PPSMC_MSG_SetSoftMinGfxclk 0x09 ///< Set SoftMin for GFXCLK, argument is frequency in MHz |
| 63 | −#define PPSMC_MSG_ActiveProcessNotify 0x0A ///< Needs update | |
| 64 | −#define PPSMC_MSG_ForcePowerDownGfx 0x0B ///< Force power down GFX, i.e. enter GFXOFF | |
| 63 | +#define PPSMC_MSG_SPARE2 0x0A ///< SPARE | |
| 64 | +#define PPSMC_MSG_SPARE3 0x0B ///< SPARE | |
| 65 | 65 | #define PPSMC_MSG_PrepareMp1ForUnload 0x0C ///< Prepare PMFW for GFX driver unload |
| 66 | 66 | #define PPSMC_MSG_SetDriverDramAddrHigh 0x0D ///< Set high 32 bits of DRAM address for Driver table transfer |
| 67 | 67 | #define PPSMC_MSG_SetDriverDramAddrLow 0x0E ///< Set low 32 bits of DRAM address for Driver table transfer |
| @@ -73,8 +73,7 @@ · 5 unmodified lines | ||
| 73 | 73 | #define PPSMC_MSG_SetSoftMinFclk 0x14 ///< Set hard min for FCLK |
| 74 | 74 | #define PPSMC_MSG_SetSoftMinVcn 0x15 ///< Set soft min for VCN clocks (VCLK and DCLK) |
| 75 | 75 | |
| 76 | − | |
| 77 | −#define PPSMC_MSG_EnableGfxImu 0x16 ///< Needs update | |
| 76 | +#define PPSMC_MSG_EnableGfxImu 0x16 ///< Enable GFX IMU | |
| 78 | 77 | |
| 79 | 78 | #define PPSMC_MSG_GetGfxclkFrequency 0x17 ///< Get GFX clock frequency |
| 80 | 79 | #define PPSMC_MSG_GetFclkFrequency 0x18 ///< Get FCLK frequency |
| @@ -102,8 +101,8 @@ · 21 unmodified lines | ||
| 102 | 101 | #define PPSMC_MSG_SetHardMinIspxclkByFreq 0x2C ///< Set HardMin by frequency for ISPXCLK |
| 103 | 102 | #define PPSMC_MSG_PowerDownUmsch 0x2D ///< Power down VCN.UMSCH (aka VSCH) scheduler |
| 104 | 103 | #define PPSMC_MSG_PowerUpUmsch 0x2E ///< Power up VCN.UMSCH (aka VSCH) scheduler |
| 105 | −#define PPSMC_Message_IspStutterOn_MmhubPgDis 0x2F ///< ISP StutterOn mmHub PgDis | |
| 106 | −#define PPSMC_Message_IspStutterOff_MmhubPgEn 0x30 ///< ISP StufferOff mmHub PgEn | |
| 104 | +#define PPSMC_MSG_IspStutterOn_MmhubPgDis 0x2F ///< ISP StutterOn mmHub PgDis | |
| 105 | +#define PPSMC_MSG_IspStutterOff_MmhubPgEn 0x30 ///< ISP StufferOff mmHub PgEn | |
| 107 | 106 | |
| 108 | 107 | #define PPSMC_Message_Count 0x31 ///< Total number of PPSMC messages |
| 109 | 108 | /** @}*/ |
| @@ -147,14 +147,6 @@ struct smu_11_5_power_context { · 146 unmodified lines | ||
| 147 | 147 | uint32_t max_fast_ppt_limit; |
| 148 | 148 | }; |
| 149 | 149 | |
| 150 | −enum smu_v11_0_baco_seq { | |
| 151 | − BACO_SEQ_BACO = 0, | |
| 152 | − BACO_SEQ_MSR, | |
| 153 | − BACO_SEQ_BAMACO, | |
| 154 | − BACO_SEQ_ULPS, | |
| 155 | − BACO_SEQ_COUNT, | |
| 156 | −}; | |
| 157 | − | |
| 158 | 150 | #if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3) |
| 159 | 151 | |
| 160 | 152 | int smu_v11_0_init_microcode(struct smu_context *smu); |
| @@ -257,7 +249,7 @@ int smu_v11_0_baco_enter(struct smu_context *smu); · 96 unmodified lines | ||
| 257 | 249 | int smu_v11_0_baco_exit(struct smu_context *smu); |
| 258 | 250 | |
| 259 | 251 | int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu, |
| 260 | − enum smu_v11_0_baco_seq baco_seq); | |
| 252 | + enum smu_baco_seq baco_seq); | |
| 261 | 253 | |
| 262 | 254 | int smu_v11_0_mode1_reset(struct smu_context *smu); |
| 263 | 255 | |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07 |
| 32 | 32 | #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04 |
| 33 | 33 | #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32 |
| 34 | −#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x2C | |
| 34 | +#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_7 0x35 | |
| 35 | 35 | #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_10 0x1D |
| 36 | 36 | |
| 37 | 37 | #define SMU13_MODE1_RESET_WAIT_TIME_IN_MS 500 //500ms |
| @@ -124,14 +124,6 @@ struct smu_13_0_power_context { · 86 unmodified lines | ||
| 124 | 124 | enum smu_13_0_power_state power_state; |
| 125 | 125 | }; |
| 126 | 126 | |
| 127 | −enum smu_v13_0_baco_seq { | |
| 128 | − BACO_SEQ_BACO = 0, | |
| 129 | − BACO_SEQ_MSR, | |
| 130 | − BACO_SEQ_BAMACO, | |
| 131 | − BACO_SEQ_ULPS, | |
| 132 | − BACO_SEQ_COUNT, | |
| 133 | −}; | |
| 134 | − | |
| 135 | 127 | #if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3) |
| 136 | 128 | |
| 137 | 129 | int smu_v13_0_init_microcode(struct smu_context *smu); |
| @@ -218,6 +210,9 @@ int smu_v13_0_set_azalia_d3_pme(struct smu_context *smu); · 80 unmodified lines | ||
| 218 | 210 | int smu_v13_0_get_max_sustainable_clocks_by_dc(struct smu_context *smu, |
| 219 | 211 | struct pp_smu_nv_clock_table *max_clocks); |
| 220 | 212 | |
| 213 | +int smu_v13_0_baco_set_armd3_sequence(struct smu_context *smu, | |
| 214 | + enum smu_baco_seq baco_seq); | |
| 215 | + | |
| 221 | 216 | bool smu_v13_0_baco_is_support(struct smu_context *smu); |
| 222 | 217 | |
| 223 | 218 | enum smu_baco_state smu_v13_0_baco_get_state(struct smu_context *smu); |
| @@ -377,7 +377,13 @@ static void sienna_cichlid_check_bxco_support(struct smu_context *smu) · 376 unmodified lines | ||
| 377 | 377 | if (((adev->pdev->device == 0x73A1) && |
| 378 | 378 | (adev->pdev->revision == 0x00)) || |
| 379 | 379 | ((adev->pdev->device == 0x73BF) && |
| 380 | − (adev->pdev->revision == 0xCF))) | |
| 380 | + (adev->pdev->revision == 0xCF)) || | |
| 381 | + ((adev->pdev->device == 0x7422) && | |
| 382 | + (adev->pdev->revision == 0x00)) || | |
| 383 | + ((adev->pdev->device == 0x73A3) && | |
| 384 | + (adev->pdev->revision == 0x00)) || | |
| 385 | + ((adev->pdev->device == 0x73E3) && | |
| 386 | + (adev->pdev->revision == 0x00))) | |
| 381 | 387 | smu_baco->platform_support = false; |
| 382 | 388 | |
| 383 | 389 | } |
| @@ -1576,7 +1576,7 @@ int smu_v11_0_set_azalia_d3_pme(struct smu_context *smu) · 1575 unmodified lines | ||
| 1576 | 1576 | } |
| 1577 | 1577 | |
| 1578 | 1578 | int smu_v11_0_baco_set_armd3_sequence(struct smu_context *smu, |
| 1579 | − enum smu_v11_0_baco_seq baco_seq) | |
| 1579 | + enum smu_baco_seq baco_seq) | |
| 1580 | 1580 | { |
| 1581 | 1581 | return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ArmD3, baco_seq, NULL); |
| 1582 | 1582 | } |
| @@ -2230,6 +2230,15 @@ int smu_v13_0_gfx_ulv_control(struct smu_context *smu, · 2229 unmodified lines | ||
| 2230 | 2230 | return ret; |
| 2231 | 2231 | } |
| 2232 | 2232 | |
| 2233 | +int smu_v13_0_baco_set_armd3_sequence(struct smu_context *smu, | |
| 2234 | + enum smu_baco_seq baco_seq) | |
| 2235 | +{ | |
| 2236 | + return smu_cmn_send_smc_msg_with_param(smu, | |
| 2237 | + SMU_MSG_ArmD3, | |
| 2238 | + baco_seq, | |
| 2239 | + NULL); | |
| 2240 | +} | |
| 2241 | + | |
| 2233 | 2242 | bool smu_v13_0_baco_is_support(struct smu_context *smu) |
| 2234 | 2243 | { |
| 2235 | 2244 | struct smu_baco_context *smu_baco = &smu->smu_baco; |
| @@ -120,6 +120,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] = · 119 unmodified lines | ||
| 120 | 120 | MSG_MAP(Mode1Reset, PPSMC_MSG_Mode1Reset, 0), |
| 121 | 121 | MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0), |
| 122 | 122 | MSG_MAP(DFCstateControl, PPSMC_MSG_SetExternalClientDfCstateAllow, 0), |
| 123 | + MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0), | |
| 123 | 124 | }; |
| 124 | 125 | |
| 125 | 126 | static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = { |
| @@ -1566,6 +1567,31 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, · 1440 unmodified lines | ||
| 1566 | 1567 | NULL); |
| 1567 | 1568 | } |
| 1568 | 1569 | |
| 1570 | +static int smu_v13_0_0_baco_enter(struct smu_context *smu) | |
| 1571 | +{ | |
| 1572 | + struct smu_baco_context *smu_baco = &smu->smu_baco; | |
| 1573 | + struct amdgpu_device *adev = smu->adev; | |
| 1574 | + | |
| 1575 | + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) | |
| 1576 | + return smu_v13_0_baco_set_armd3_sequence(smu, | |
| 1577 | + smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO); | |
| 1578 | + else | |
| 1579 | + return smu_v13_0_baco_enter(smu); | |
| 1580 | +} | |
| 1581 | + | |
| 1582 | +static int smu_v13_0_0_baco_exit(struct smu_context *smu) | |
| 1583 | +{ | |
| 1584 | + struct amdgpu_device *adev = smu->adev; | |
| 1585 | + | |
| 1586 | + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) { | |
| 1587 | + /* Wait for PMFW handling for the Dstate change */ | |
| 1588 | + usleep_range(10000, 11000); | |
| 1589 | + return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS); | |
| 1590 | + } else { | |
| 1591 | + return smu_v13_0_baco_exit(smu); | |
| 1592 | + } | |
| 1593 | +} | |
| 1594 | + | |
| 1569 | 1595 | static bool smu_v13_0_0_is_mode1_reset_supported(struct smu_context *smu) |
| 1570 | 1596 | { |
| 1571 | 1597 | struct amdgpu_device *adev = smu->adev; |
| @@ -1827,8 +1853,8 @@ static const struct pptable_funcs smu_v13_0_0_ppt_funcs = { · 255 unmodified lines | ||
| 1827 | 1853 | .baco_is_support = smu_v13_0_baco_is_support, |
| 1828 | 1854 | .baco_get_state = smu_v13_0_baco_get_state, |
| 1829 | 1855 | .baco_set_state = smu_v13_0_baco_set_state, |
| 1830 | − .baco_enter = smu_v13_0_baco_enter, | |
| 1831 | − .baco_exit = smu_v13_0_baco_exit, | |
| 1856 | + .baco_enter = smu_v13_0_0_baco_enter, | |
| 1857 | + .baco_exit = smu_v13_0_0_baco_exit, | |
| 1832 | 1858 | .mode1_reset_is_support = smu_v13_0_0_is_mode1_reset_supported, |
| 1833 | 1859 | .mode1_reset = smu_v13_0_mode1_reset, |
| 1834 | 1860 | .set_mp1_state = smu_v13_0_0_set_mp1_state, |
| @@ -122,6 +122,7 @@ static struct cmn2asic_msg_mapping smu_v13_0_7_message_map[SMU_MSG_MAX_COUNT] = · 121 unmodified lines | ||
| 122 | 122 | MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0), |
| 123 | 123 | MSG_MAP(SetMGpuFanBoostLimitRpm, PPSMC_MSG_SetMGpuFanBoostLimitRpm, 0), |
| 124 | 124 | MSG_MAP(DFCstateControl, PPSMC_MSG_SetExternalClientDfCstateAllow, 0), |
| 125 | + MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0), | |
| 125 | 126 | }; |
| 126 | 127 | |
| 127 | 128 | static struct cmn2asic_mapping smu_v13_0_7_clk_map[SMU_CLK_COUNT] = { |
| @@ -1578,6 +1579,31 @@ static int smu_v13_0_7_set_mp1_state(struct smu_context *smu, · 1450 unmodified lines | ||
| 1578 | 1579 | return ret; |
| 1579 | 1580 | } |
| 1580 | 1581 | |
| 1582 | +static int smu_v13_0_7_baco_enter(struct smu_context *smu) | |
| 1583 | +{ | |
| 1584 | + struct smu_baco_context *smu_baco = &smu->smu_baco; | |
| 1585 | + struct amdgpu_device *adev = smu->adev; | |
| 1586 | + | |
| 1587 | + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) | |
| 1588 | + return smu_v13_0_baco_set_armd3_sequence(smu, | |
| 1589 | + smu_baco->maco_support ? BACO_SEQ_BAMACO : BACO_SEQ_BACO); | |
| 1590 | + else | |
| 1591 | + return smu_v13_0_baco_enter(smu); | |
| 1592 | +} | |
| 1593 | + | |
| 1594 | +static int smu_v13_0_7_baco_exit(struct smu_context *smu) | |
| 1595 | +{ | |
| 1596 | + struct amdgpu_device *adev = smu->adev; | |
| 1597 | + | |
| 1598 | + if (adev->in_runpm && smu_cmn_is_audio_func_enabled(adev)) { | |
| 1599 | + /* Wait for PMFW handling for the Dstate change */ | |
| 1600 | + usleep_range(10000, 11000); | |
| 1601 | + return smu_v13_0_baco_set_armd3_sequence(smu, BACO_SEQ_ULPS); | |
| 1602 | + } else { | |
| 1603 | + return smu_v13_0_baco_exit(smu); | |
| 1604 | + } | |
| 1605 | +} | |
| 1606 | + | |
| 1581 | 1607 | static bool smu_v13_0_7_is_mode1_reset_supported(struct smu_context *smu) |
| 1582 | 1608 | { |
| 1583 | 1609 | struct amdgpu_device *adev = smu->adev; |
| @@ -1655,8 +1681,8 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { · 71 unmodified lines | ||
| 1655 | 1681 | .baco_is_support = smu_v13_0_baco_is_support, |
| 1656 | 1682 | .baco_get_state = smu_v13_0_baco_get_state, |
| 1657 | 1683 | .baco_set_state = smu_v13_0_baco_set_state, |
| 1658 | − .baco_enter = smu_v13_0_baco_enter, | |
| 1659 | − .baco_exit = smu_v13_0_baco_exit, | |
| 1684 | + .baco_enter = smu_v13_0_7_baco_enter, | |
| 1685 | + .baco_exit = smu_v13_0_7_baco_exit, | |
| 1660 | 1686 | .mode1_reset_is_support = smu_v13_0_7_is_mode1_reset_supported, |
| 1661 | 1687 | .mode1_reset = smu_v13_0_mode1_reset, |
| 1662 | 1688 | .set_mp1_state = smu_v13_0_7_set_mp1_state, |
| @@ -63,23 +63,45 @@ · 62 unmodified lines | ||
| 63 | 63 | ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter, |
| 64 | 64 | u8 offset, void *buffer, size_t size) |
| 65 | 65 | { |
| 66 | + u8 zero = 0; | |
| 67 | + char *tmpbuf = NULL; | |
| 68 | + /* | |
| 69 | + * As sub-addressing is not supported by all adaptors, | |
| 70 | + * always explicitly read from the start and discard | |
| 71 | + * any bytes that come before the requested offset. | |
| 72 | + * This way, no matter whether the adaptor supports it | |
| 73 | + * or not, we'll end up reading the proper data. | |
| 74 | + */ | |
| 66 | 75 | struct i2c_msg msgs[] = { |
| 67 | 76 | { |
| 68 | 77 | .addr = DP_DUAL_MODE_SLAVE_ADDRESS, |
| 69 | 78 | .flags = 0, |
| 70 | 79 | .len = 1, |
| 71 | − .buf = &offset, | |
| 80 | + .buf = &zero, | |
| 72 | 81 | }, |
| 73 | 82 | { |
| 74 | 83 | .addr = DP_DUAL_MODE_SLAVE_ADDRESS, |
| 75 | 84 | .flags = I2C_M_RD, |
| 76 | − .len = size, | |
| 85 | + .len = size + offset, | |
| 77 | 86 | .buf = buffer, |
| 78 | 87 | }, |
| 79 | 88 | }; |
| 80 | 89 | int ret; |
| 81 | 90 | |
| 91 | + if (offset) { | |
| 92 | + tmpbuf = kmalloc(size + offset, GFP_KERNEL); | |
| 93 | + if (!tmpbuf) | |
| 94 | + return -ENOMEM; | |
| 95 | + | |
| 96 | + msgs[1].buf = tmpbuf; | |
| 97 | + } | |
| 98 | + | |
| 82 | 99 | ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs)); |
| 100 | + if (tmpbuf) | |
| 101 | + memcpy(buffer, tmpbuf + offset, size); | |
| 102 | + | |
| 103 | + kfree(tmpbuf); | |
| 104 | + | |
| 83 | 105 | if (ret < 0) |
| 84 | 106 | return ret; |
| 85 | 107 | if (ret != ARRAY_SIZE(msgs)) |
| @@ -208,18 +230,6 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev, · 122 unmodified lines | ||
| 208 | 230 | if (ret) |
| 209 | 231 | return DRM_DP_DUAL_MODE_UNKNOWN; |
| 210 | 232 | |
| 211 | − /* | |
| 212 | − * Sigh. Some (maybe all?) type 1 adaptors are broken and ack | |
| 213 | − * the offset but ignore it, and instead they just always return | |
| 214 | − * data from the start of the HDMI ID buffer. So for a broken | |
| 215 | − * type 1 HDMI adaptor a single byte read will always give us | |
| 216 | − * 0x44, and for a type 1 DVI adaptor it should give 0x00 | |
| 217 | − * (assuming it implements any registers). Fortunately neither | |
| 218 | − * of those values will match the type 2 signature of the | |
| 219 | − * DP_DUAL_MODE_ADAPTOR_ID register so we can proceed with | |
| 220 | − * the type 2 adaptor detection safely even in the presence | |
| 221 | − * of broken type 1 adaptors. | |
| 222 | − */ | |
| 223 | 233 | ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID, |
| 224 | 234 | &adaptor_id, sizeof(adaptor_id)); |
| 225 | 235 | drm_dbg_kms(dev, "DP dual mode adaptor ID: %02x (err %zd)\n", adaptor_id, ret); |
| @@ -233,11 +243,10 @@ enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(const struct drm_device *dev, · 7 unmodified lines | ||
| 233 | 243 | return DRM_DP_DUAL_MODE_TYPE2_DVI; |
| 234 | 244 | } |
| 235 | 245 | /* |
| 236 | − * If neither a proper type 1 ID nor a broken type 1 adaptor | |
| 237 | − * as described above, assume type 1, but let the user know | |
| 238 | − * that we may have misdetected the type. | |
| 246 | + * If not a proper type 1 ID, still assume type 1, but let | |
| 247 | + * the user know that we may have misdetected the type. | |
| 239 | 248 | */ |
| 240 | − if (!is_type1_adaptor(adaptor_id) && adaptor_id != hdmi_id[0]) | |
| 249 | + if (!is_type1_adaptor(adaptor_id)) | |
| 241 | 250 | drm_err(dev, "Unexpected DP dual mode adaptor ID %02x\n", adaptor_id); |
| 242 | 251 | |
| 243 | 252 | } |
| @@ -343,10 +352,8 @@ EXPORT_SYMBOL(drm_dp_dual_mode_get_tmds_output); · 99 unmodified lines | ||
| 343 | 352 | * @enable: enable (as opposed to disable) the TMDS output buffers |
| 344 | 353 | * |
| 345 | 354 | * Set the state of the TMDS output buffers in the adaptor. For |
| 346 | − * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. As | |
| 347 | − * some type 1 adaptors have problems with registers (see comments | |
| 348 | − * in drm_dp_dual_mode_detect()) we avoid touching the register, | |
| 349 | − * making this function a no-op on type 1 adaptors. | |
| 355 | + * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. | |
| 356 | + * Type1 adaptors do not support any register writes. | |
| 350 | 357 | * |
| 351 | 358 | * Returns: |
| 352 | 359 | * 0 on success, negative error code on failure |
| @@ -5186,7 +5186,7 @@ int drm_dp_mst_add_affected_dsc_crtcs(struct drm_atomic_state *state, struct drm · 5185 unmodified lines | ||
| 5186 | 5186 | mst_state = drm_atomic_get_mst_topology_state(state, mgr); |
| 5187 | 5187 | |
| 5188 | 5188 | if (IS_ERR(mst_state)) |
| 5189 | − return -EINVAL; | |
| 5189 | + return PTR_ERR(mst_state); | |
| 5190 | 5190 | |
| 5191 | 5191 | list_for_each_entry(pos, &mst_state->payloads, next) { |
| 5192 | 5192 | |
| @@ -615,7 +615,7 @@ static int drm_dev_init(struct drm_device *dev, · 614 unmodified lines | ||
| 615 | 615 | mutex_init(&dev->clientlist_mutex); |
| 616 | 616 | mutex_init(&dev->master_mutex); |
| 617 | 617 | |
| 618 | − ret = drmm_add_action(dev, drm_dev_init_release, NULL); | |
| 618 | + ret = drmm_add_action_or_reset(dev, drm_dev_init_release, NULL); | |
| 619 | 619 | if (ret) |
| 620 | 620 | return ret; |
| 621 | 621 | |
| @@ -807,6 +807,38 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t · 806 unmodified lines | ||
| 807 | 807 | return false; |
| 808 | 808 | } |
| 809 | 809 | |
| 810 | +static const uint32_t conv_from_xrgb8888[] = { | |
| 811 | + DRM_FORMAT_XRGB8888, | |
| 812 | + DRM_FORMAT_ARGB8888, | |
| 813 | + DRM_FORMAT_XRGB2101010, | |
| 814 | + DRM_FORMAT_ARGB2101010, | |
| 815 | + DRM_FORMAT_RGB565, | |
| 816 | + DRM_FORMAT_RGB888, | |
| 817 | +}; | |
| 818 | + | |
| 819 | +static const uint32_t conv_from_rgb565_888[] = { | |
| 820 | + DRM_FORMAT_XRGB8888, | |
| 821 | + DRM_FORMAT_ARGB8888, | |
| 822 | +}; | |
| 823 | + | |
| 824 | +static bool is_conversion_supported(uint32_t from, uint32_t to) | |
| 825 | +{ | |
| 826 | + switch (from) { | |
| 827 | + case DRM_FORMAT_XRGB8888: | |
| 828 | + case DRM_FORMAT_ARGB8888: | |
| 829 | + return is_listed_fourcc(conv_from_xrgb8888, ARRAY_SIZE(conv_from_xrgb8888), to); | |
| 830 | + case DRM_FORMAT_RGB565: | |
| 831 | + case DRM_FORMAT_RGB888: | |
| 832 | + return is_listed_fourcc(conv_from_rgb565_888, ARRAY_SIZE(conv_from_rgb565_888), to); | |
| 833 | + case DRM_FORMAT_XRGB2101010: | |
| 834 | + return to == DRM_FORMAT_ARGB2101010; | |
| 835 | + case DRM_FORMAT_ARGB2101010: | |
| 836 | + return to == DRM_FORMAT_XRGB2101010; | |
| 837 | + default: | |
| 838 | + return false; | |
| 839 | + } | |
| 840 | +} | |
| 841 | + | |
| 810 | 842 | /** |
| 811 | 843 | * drm_fb_build_fourcc_list - Filters a list of supported color formats against |
| 812 | 844 | * the device's native formats |
| @@ -827,7 +859,9 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t · 14 unmodified lines | ||
| 827 | 859 | * be handed over to drm_universal_plane_init() et al. Native formats |
| 828 | 860 | * will go before emulated formats. Other heuristics might be applied |
| 829 | 861 | * to optimize the order. Formats near the beginning of the list are |
| 830 | − * usually preferred over formats near the end of the list. | |
| 862 | + * usually preferred over formats near the end of the list. Formats | |
| 863 | + * without conversion helpers will be skipped. New drivers should only | |
| 864 | + * pass in XRGB8888 and avoid exposing additional emulated formats. | |
| 831 | 865 | * |
| 832 | 866 | * Returns: |
| 833 | 867 | * The number of color-formats 4CC codes returned in @fourccs_out. |
| @@ -839,7 +873,7 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, · 5 unmodified lines | ||
| 839 | 873 | { |
| 840 | 874 | u32 *fourccs = fourccs_out; |
| 841 | 875 | const u32 *fourccs_end = fourccs_out + nfourccs_out; |
| 842 | − bool found_native = false; | |
| 876 | + uint32_t native_format = 0; | |
| 843 | 877 | size_t i; |
| 844 | 878 | |
| 845 | 879 | /* |
| @@ -858,26 +892,18 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, · 12 unmodified lines | ||
| 858 | 892 | |
| 859 | 893 | drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc); |
| 860 | 894 | |
| 861 | − if (!found_native) | |
| 862 | − found_native = is_listed_fourcc(driver_fourccs, driver_nfourccs, fourcc); | |
| 895 | + /* | |
| 896 | + * There should only be one native format with the current API. | |
| 897 | + * This API needs to be refactored to correctly support arbitrary | |
| 898 | + * sets of native formats, since it needs to report which native | |
| 899 | + * format to use for each emulated format. | |
| 900 | + */ | |
| 901 | + if (!native_format) | |
| 902 | + native_format = fourcc; | |
| 863 | 903 | *fourccs = fourcc; |
| 864 | 904 | ++fourccs; |
| 865 | 905 | } |
| 866 | 906 | |
| 867 | − /* | |
| 868 | − * The plane's atomic_update helper converts the framebuffer's color format | |
| 869 | − * to a native format when copying to device memory. | |
| 870 | − * | |
| 871 | − * If there is not a single format supported by both, device and | |
| 872 | − * driver, the native formats are likely not supported by the conversion | |
| 873 | − * helpers. Therefore *only* support the native formats and add a | |
| 874 | − * conversion helper ASAP. | |
| 875 | − */ | |
| 876 | − if (!found_native) { | |
| 877 | − drm_warn(dev, "Format conversion helpers required to add extra formats.\n"); | |
| 878 | − goto out; | |
| 879 | − } | |
| 880 | − | |
| 881 | 907 | /* |
| 882 | 908 | * The extra formats, emulated by the driver, go second. |
| 883 | 909 | */ |
| @@ -890,6 +916,9 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, · 6 unmodified lines | ||
| 890 | 916 | } else if (fourccs == fourccs_end) { |
| 891 | 917 | drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc); |
| 892 | 918 | continue; /* end of available output buffer */ |
| 919 | + } else if (!is_conversion_supported(fourcc, native_format)) { | |
| 920 | + drm_dbg_kms(dev, "Unsupported emulated format %p4cc\n", &fourcc); | |
| 921 | + continue; /* format is not supported for conversion */ | |
| 893 | 922 | } |
| 894 | 923 | |
| 895 | 924 | drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc); |
| @@ -898,7 +927,6 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, · 2 unmodified lines | ||
| 898 | 927 | ++fourccs; |
| 899 | 928 | } |
| 900 | 929 | |
| 901 | −out: | |
| 902 | 930 | return fourccs - fourccs_out; |
| 903 | 931 | } |
| 904 | 932 | EXPORT_SYMBOL(drm_fb_build_fourcc_list); |
| @@ -104,7 +104,8 @@ static inline void drm_vblank_flush_worker(struct drm_vblank_crtc *vblank) · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | static inline void drm_vblank_destroy_worker(struct drm_vblank_crtc *vblank) |
| 106 | 106 | { |
| 107 | − kthread_destroy_worker(vblank->worker); | |
| 107 | + if (vblank->worker) | |
| 108 | + kthread_destroy_worker(vblank->worker); | |
| 108 | 109 | } |
| 109 | 110 | |
| 110 | 111 | int drm_vblank_worker_init(struct drm_vblank_crtc *vblank); |
| @@ -151,9 +151,6 @@ int drm_mode_getresources(struct drm_device *dev, void *data, · 150 unmodified lines | ||
| 151 | 151 | count = 0; |
| 152 | 152 | connector_id = u64_to_user_ptr(card_res->connector_id_ptr); |
| 153 | 153 | drm_for_each_connector_iter(connector, &conn_iter) { |
| 154 | − if (connector->registration_state != DRM_CONNECTOR_REGISTERED) | |
| 155 | − continue; | |
| 156 | − | |
| 157 | 154 | /* only expose writeback connectors if userspace understands them */ |
| 158 | 155 | if (!file_priv->writeback_connectors && |
| 159 | 156 | (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)) |
| @@ -134,6 +134,12 @@ static const struct dmi_system_id orientation_data[] = { · 133 unmodified lines | ||
| 134 | 134 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), |
| 135 | 135 | }, |
| 136 | 136 | .driver_data = (void *)&lcd800x1280_rightside_up, |
| 137 | + }, { /* Acer Switch V 10 (SW5-017) */ | |
| 138 | + .matches = { | |
| 139 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), | |
| 140 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SW5-017"), | |
| 141 | + }, | |
| 142 | + .driver_data = (void *)&lcd800x1280_rightside_up, | |
| 137 | 143 | }, { /* Anbernic Win600 */ |
| 138 | 144 | .matches = { |
| 139 | 145 | DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Anbernic"), |
| @@ -319,6 +325,12 @@ static const struct dmi_system_id orientation_data[] = { · 179 unmodified lines | ||
| 319 | 325 | DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"), |
| 320 | 326 | }, |
| 321 | 327 | .driver_data = (void *)&lcd1200x1920_rightside_up, |
| 328 | + }, { /* Nanote UMPC-01 */ | |
| 329 | + .matches = { | |
| 330 | + DMI_MATCH(DMI_SYS_VENDOR, "RWC CO.,LTD"), | |
| 331 | + DMI_MATCH(DMI_PRODUCT_NAME, "UMPC-01"), | |
| 332 | + }, | |
| 333 | + .driver_data = (void *)&lcd1200x1920_rightside_up, | |
| 322 | 334 | }, { /* OneGX1 Pro */ |
| 323 | 335 | .matches = { |
| 324 | 336 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"), |
| @@ -282,6 +282,7 @@ i915-y += \ · 281 unmodified lines | ||
| 282 | 282 | display/intel_ddi.o \ |
| 283 | 283 | display/intel_ddi_buf_trans.o \ |
| 284 | 284 | display/intel_display_trace.o \ |
| 285 | + display/intel_dkl_phy.o \ | |
| 285 | 286 | display/intel_dp.o \ |
| 286 | 287 | display/intel_dp_aux.o \ |
| 287 | 288 | display/intel_dp_aux_backlight.o \ |
| @@ -43,6 +43,7 @@ · 42 unmodified lines | ||
| 43 | 43 | #include "intel_de.h" |
| 44 | 44 | #include "intel_display_power.h" |
| 45 | 45 | #include "intel_display_types.h" |
| 46 | +#include "intel_dkl_phy.h" | |
| 46 | 47 | #include "intel_dp.h" |
| 47 | 48 | #include "intel_dp_link_training.h" |
| 48 | 49 | #include "intel_dp_mst.h" |
| @@ -1262,33 +1263,30 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, · 1213 unmodified lines | ||
| 1262 | 1263 | for (ln = 0; ln < 2; ln++) { |
| 1263 | 1264 | int level; |
| 1264 | 1265 | |
| 1265 | − intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), | |
| 1266 | − HIP_INDEX_VAL(tc_port, ln)); | |
| 1267 | − | |
| 1268 | − intel_de_write(dev_priv, DKL_TX_PMD_LANE_SUS(tc_port), 0); | |
| 1266 | + intel_dkl_phy_write(dev_priv, DKL_TX_PMD_LANE_SUS(tc_port), ln, 0); | |
| 1269 | 1267 | |
| 1270 | 1268 | level = intel_ddi_level(encoder, crtc_state, 2*ln+0); |
| 1271 | 1269 | |
| 1272 | − intel_de_rmw(dev_priv, DKL_TX_DPCNTL0(tc_port), | |
| 1273 | − DKL_TX_PRESHOOT_COEFF_MASK | | |
| 1274 | − DKL_TX_DE_EMPAHSIS_COEFF_MASK | | |
| 1275 | − DKL_TX_VSWING_CONTROL_MASK, | |
| 1276 | − DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) | | |
| 1277 | − DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) | | |
| 1278 | − DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing)); | |
| 1270 | + intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL0(tc_port), ln, | |
| 1271 | + DKL_TX_PRESHOOT_COEFF_MASK | | |
| 1272 | + DKL_TX_DE_EMPAHSIS_COEFF_MASK | | |
| 1273 | + DKL_TX_VSWING_CONTROL_MASK, | |
| 1274 | + DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) | | |
| 1275 | + DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) | | |
| 1276 | + DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing)); | |
| 1279 | 1277 | |
| 1280 | 1278 | level = intel_ddi_level(encoder, crtc_state, 2*ln+1); |
| 1281 | 1279 | |
| 1282 | − intel_de_rmw(dev_priv, DKL_TX_DPCNTL1(tc_port), | |
| 1283 | − DKL_TX_PRESHOOT_COEFF_MASK | | |
| 1284 | − DKL_TX_DE_EMPAHSIS_COEFF_MASK | | |
| 1285 | − DKL_TX_VSWING_CONTROL_MASK, | |
| 1286 | − DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) | | |
| 1287 | − DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) | | |
| 1288 | − DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing)); | |
| 1280 | + intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL1(tc_port), ln, | |
| 1281 | + DKL_TX_PRESHOOT_COEFF_MASK | | |
| 1282 | + DKL_TX_DE_EMPAHSIS_COEFF_MASK | | |
| 1283 | + DKL_TX_VSWING_CONTROL_MASK, | |
| 1284 | + DKL_TX_PRESHOOT_COEFF(trans->entries[level].dkl.preshoot) | | |
| 1285 | + DKL_TX_DE_EMPHASIS_COEFF(trans->entries[level].dkl.de_emphasis) | | |
| 1286 | + DKL_TX_VSWING_CONTROL(trans->entries[level].dkl.vswing)); | |
| 1289 | 1287 | |
| 1290 | − intel_de_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port), | |
| 1291 | − DKL_TX_DP20BITMODE, 0); | |
| 1288 | + intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port), ln, | |
| 1289 | + DKL_TX_DP20BITMODE, 0); | |
| 1292 | 1290 | |
| 1293 | 1291 | if (IS_ALDERLAKE_P(dev_priv)) { |
| 1294 | 1292 | u32 val; |
| @@ -1306,10 +1304,10 @@ static void tgl_dkl_phy_set_signal_levels(struct intel_encoder *encoder, · 11 unmodified lines | ||
| 1306 | 1304 | val |= DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2(0); |
| 1307 | 1305 | } |
| 1308 | 1306 | |
| 1309 | − intel_de_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port), | |
| 1310 | − DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK | | |
| 1311 | − DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, | |
| 1312 | − val); | |
| 1307 | + intel_dkl_phy_rmw(dev_priv, DKL_TX_DPCNTL2(tc_port), ln, | |
| 1308 | + DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX1_MASK | | |
| 1309 | + DKL_TX_DPCNTL2_CFG_LOADGENSELECT_TX2_MASK, | |
| 1310 | + val); | |
| 1313 | 1311 | } |
| 1314 | 1312 | } |
| 1315 | 1313 | } |
| @@ -2019,12 +2017,8 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port, · 703 unmodified lines | ||
| 2019 | 2017 | return; |
| 2020 | 2018 | |
| 2021 | 2019 | if (DISPLAY_VER(dev_priv) >= 12) { |
| 2022 | − intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), | |
| 2023 | − HIP_INDEX_VAL(tc_port, 0x0)); | |
| 2024 | − ln0 = intel_de_read(dev_priv, DKL_DP_MODE(tc_port)); | |
| 2025 | − intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), | |
| 2026 | − HIP_INDEX_VAL(tc_port, 0x1)); | |
| 2027 | − ln1 = intel_de_read(dev_priv, DKL_DP_MODE(tc_port)); | |
| 2020 | + ln0 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port), 0); | |
| 2021 | + ln1 = intel_dkl_phy_read(dev_priv, DKL_DP_MODE(tc_port), 1); | |
| 2028 | 2022 | } else { |
| 2029 | 2023 | ln0 = intel_de_read(dev_priv, MG_DP_MODE(0, tc_port)); |
| 2030 | 2024 | ln1 = intel_de_read(dev_priv, MG_DP_MODE(1, tc_port)); |
| @@ -2085,12 +2079,8 @@ icl_program_mg_dp_mode(struct intel_digital_port *dig_port, · 54 unmodified lines | ||
| 2085 | 2079 | } |
| 2086 | 2080 | |
| 2087 | 2081 | if (DISPLAY_VER(dev_priv) >= 12) { |
| 2088 | − intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), | |
| 2089 | − HIP_INDEX_VAL(tc_port, 0x0)); | |
| 2090 | − intel_de_write(dev_priv, DKL_DP_MODE(tc_port), ln0); | |
| 2091 | − intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), | |
| 2092 | − HIP_INDEX_VAL(tc_port, 0x1)); | |
| 2093 | − intel_de_write(dev_priv, DKL_DP_MODE(tc_port), ln1); | |
| 2082 | + intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port), 0, ln0); | |
| 2083 | + intel_dkl_phy_write(dev_priv, DKL_DP_MODE(tc_port), 1, ln1); | |
| 2094 | 2084 | } else { |
| 2095 | 2085 | intel_de_write(dev_priv, MG_DP_MODE(0, tc_port), ln0); |
| 2096 | 2086 | intel_de_write(dev_priv, MG_DP_MODE(1, tc_port), ln1); |
| @@ -3094,10 +3084,8 @@ static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder) · 997 unmodified lines | ||
| 3094 | 3084 | enum tc_port tc_port = intel_port_to_tc(i915, encoder->port); |
| 3095 | 3085 | int ln; |
| 3096 | 3086 | |
| 3097 | − for (ln = 0; ln < 2; ln++) { | |
| 3098 | − intel_de_write(i915, HIP_INDEX_REG(tc_port), HIP_INDEX_VAL(tc_port, ln)); | |
| 3099 | − intel_de_rmw(i915, DKL_PCS_DW5(tc_port), DKL_PCS_DW5_CORE_SOFTRESET, 0); | |
| 3100 | − } | |
| 3087 | + for (ln = 0; ln < 2; ln++) | |
| 3088 | + intel_dkl_phy_rmw(i915, DKL_PCS_DW5(tc_port), ln, DKL_PCS_DW5_CORE_SOFTRESET, 0); | |
| 3101 | 3089 | } |
| 3102 | 3090 | |
| 3103 | 3091 | static void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp, |
| @@ -3723,12 +3723,16 @@ out: · 3722 unmodified lines | ||
| 3723 | 3723 | |
| 3724 | 3724 | static u8 bigjoiner_pipes(struct drm_i915_private *i915) |
| 3725 | 3725 | { |
| 3726 | + u8 pipes; | |
| 3727 | + | |
| 3726 | 3728 | if (DISPLAY_VER(i915) >= 12) |
| 3727 | − return BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D); | |
| 3729 | + pipes = BIT(PIPE_A) | BIT(PIPE_B) | BIT(PIPE_C) | BIT(PIPE_D); | |
| 3728 | 3730 | else if (DISPLAY_VER(i915) >= 11) |
| 3729 | − return BIT(PIPE_B) | BIT(PIPE_C); | |
| 3731 | + pipes = BIT(PIPE_B) | BIT(PIPE_C); | |
| 3730 | 3732 | else |
| 3731 | − return 0; | |
| 3733 | + pipes = 0; | |
| 3734 | + | |
| 3735 | + return pipes & RUNTIME_INFO(i915)->pipe_mask; | |
| 3732 | 3736 | } |
| 3733 | 3737 | |
| 3734 | 3738 | static bool transcoder_ddi_func_is_enabled(struct drm_i915_private *dev_priv, |
| @@ -315,6 +315,14 @@ struct intel_display { · 314 unmodified lines | ||
| 315 | 315 | struct intel_global_obj obj; |
| 316 | 316 | } dbuf; |
| 317 | 317 | |
| 318 | + struct { | |
| 319 | + /* | |
| 320 | + * dkl.phy_lock protects against concurrent access of the | |
| 321 | + * Dekel TypeC PHYs. | |
| 322 | + */ | |
| 323 | + spinlock_t phy_lock; | |
| 324 | + } dkl; | |
| 325 | + | |
| 318 | 326 | struct { |
| 319 | 327 | /* VLV/CHV/BXT/GLK DSI MMIO register base address */ |
| 320 | 328 | u32 mmio_base; |
| @@ -2434,7 +2434,7 @@ intel_display_power_ddi_io_domain(struct drm_i915_private *i915, enum port port) · 2433 unmodified lines | ||
| 2434 | 2434 | { |
| 2435 | 2435 | const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port); |
| 2436 | 2436 | |
| 2437 | − if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_io == POWER_DOMAIN_INVALID) | |
| 2437 | + if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_io == POWER_DOMAIN_INVALID)) | |
| 2438 | 2438 | return POWER_DOMAIN_PORT_DDI_IO_A; |
| 2439 | 2439 | |
| 2440 | 2440 | return domains->ddi_io + (int)(port - domains->port_start); |
| @@ -2445,7 +2445,7 @@ intel_display_power_ddi_lanes_domain(struct drm_i915_private *i915, enum port po · 4 unmodified lines | ||
| 2445 | 2445 | { |
| 2446 | 2446 | const struct intel_ddi_port_domains *domains = intel_port_domains_for_port(i915, port); |
| 2447 | 2447 | |
| 2448 | − if (drm_WARN_ON(&i915->drm, !domains) || domains->ddi_lanes == POWER_DOMAIN_INVALID) | |
| 2448 | + if (drm_WARN_ON(&i915->drm, !domains || domains->ddi_lanes == POWER_DOMAIN_INVALID)) | |
| 2449 | 2449 | return POWER_DOMAIN_PORT_DDI_LANES_A; |
| 2450 | 2450 | |
| 2451 | 2451 | return domains->ddi_lanes + (int)(port - domains->port_start); |
| @@ -2471,7 +2471,7 @@ intel_display_power_legacy_aux_domain(struct drm_i915_private *i915, enum aux_ch · 19 unmodified lines | ||
| 2471 | 2471 | { |
| 2472 | 2472 | const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch); |
| 2473 | 2473 | |
| 2474 | − if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID) | |
| 2474 | + if (drm_WARN_ON(&i915->drm, !domains || domains->aux_legacy_usbc == POWER_DOMAIN_INVALID)) | |
| 2475 | 2475 | return POWER_DOMAIN_AUX_A; |
| 2476 | 2476 | |
| 2477 | 2477 | return domains->aux_legacy_usbc + (int)(aux_ch - domains->aux_ch_start); |
| @@ -2482,7 +2482,7 @@ intel_display_power_tbt_aux_domain(struct drm_i915_private *i915, enum aux_ch au · 4 unmodified lines | ||
| 2482 | 2482 | { |
| 2483 | 2483 | const struct intel_ddi_port_domains *domains = intel_port_domains_for_aux_ch(i915, aux_ch); |
| 2484 | 2484 | |
| 2485 | − if (drm_WARN_ON(&i915->drm, !domains) || domains->aux_tbt == POWER_DOMAIN_INVALID) | |
| 2485 | + if (drm_WARN_ON(&i915->drm, !domains || domains->aux_tbt == POWER_DOMAIN_INVALID)) | |
| 2486 | 2486 | return POWER_DOMAIN_AUX_TBT1; |
| 2487 | 2487 | |
| 2488 | 2488 | return domains->aux_tbt + (int)(aux_ch - domains->aux_ch_start); |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include "intel_de.h" |
| 13 | 13 | #include "intel_display_power_well.h" |
| 14 | 14 | #include "intel_display_types.h" |
| 15 | +#include "intel_dkl_phy.h" | |
| 15 | 16 | #include "intel_dmc.h" |
| 16 | 17 | #include "intel_dpio_phy.h" |
| 17 | 18 | #include "intel_dpll.h" |
| @@ -529,11 +530,9 @@ icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv, · 511 unmodified lines | ||
| 529 | 530 | enum tc_port tc_port; |
| 530 | 531 | |
| 531 | 532 | tc_port = TGL_AUX_PW_TO_TC_PORT(i915_power_well_instance(power_well)->hsw.idx); |
| 532 | − intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), | |
| 533 | − HIP_INDEX_VAL(tc_port, 0x2)); | |
| 534 | 533 | |
| 535 | − if (intel_de_wait_for_set(dev_priv, DKL_CMN_UC_DW_27(tc_port), | |
| 536 | − DKL_CMN_UC_DW27_UC_HEALTH, 1)) | |
| 534 | + if (wait_for(intel_dkl_phy_read(dev_priv, DKL_CMN_UC_DW_27(tc_port), 2) & | |
| 535 | + DKL_CMN_UC_DW27_UC_HEALTH, 1)) | |
| 537 | 536 | drm_warn(&dev_priv->drm, |
| 538 | 537 | "Timeout waiting TC uC health\n"); |
| 539 | 538 | } |
| @@ -0,0 +1,109 @@ | ||
| 1 | +// SPDX-License-Identifier: MIT | |
| 2 | +/* | |
| 3 | + * Copyright © 2022 Intel Corporation | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#include "i915_drv.h" | |
| 7 | +#include "i915_reg.h" | |
| 8 | + | |
| 9 | +#include "intel_de.h" | |
| 10 | +#include "intel_display.h" | |
| 11 | +#include "intel_dkl_phy.h" | |
| 12 | + | |
| 13 | +static void | |
| 14 | +dkl_phy_set_hip_idx(struct drm_i915_private *i915, i915_reg_t reg, int idx) | |
| 15 | +{ | |
| 16 | + enum tc_port tc_port = DKL_REG_TC_PORT(reg); | |
| 17 | + | |
| 18 | + drm_WARN_ON(&i915->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS); | |
| 19 | + | |
| 20 | + intel_de_write(i915, | |
| 21 | + HIP_INDEX_REG(tc_port), | |
| 22 | + HIP_INDEX_VAL(tc_port, idx)); | |
| 23 | +} | |
| 24 | + | |
| 25 | +/** | |
| 26 | + * intel_dkl_phy_read - read a Dekel PHY register | |
| 27 | + * @i915: i915 device instance | |
| 28 | + * @reg: Dekel PHY register | |
| 29 | + * @ln: lane instance of @reg | |
| 30 | + * | |
| 31 | + * Read the @reg Dekel PHY register. | |
| 32 | + * | |
| 33 | + * Returns the read value. | |
| 34 | + */ | |
| 35 | +u32 | |
| 36 | +intel_dkl_phy_read(struct drm_i915_private *i915, i915_reg_t reg, int ln) | |
| 37 | +{ | |
| 38 | + u32 val; | |
| 39 | + | |
| 40 | + spin_lock(&i915->display.dkl.phy_lock); | |
| 41 | + | |
| 42 | + dkl_phy_set_hip_idx(i915, reg, ln); | |
| 43 | + val = intel_de_read(i915, reg); | |
| 44 | + | |
| 45 | + spin_unlock(&i915->display.dkl.phy_lock); | |
| 46 | + | |
| 47 | + return val; | |
| 48 | +} | |
| 49 | + | |
| 50 | +/** | |
| 51 | + * intel_dkl_phy_write - write a Dekel PHY register | |
| 52 | + * @i915: i915 device instance | |
| 53 | + * @reg: Dekel PHY register | |
| 54 | + * @ln: lane instance of @reg | |
| 55 | + * @val: value to write | |
| 56 | + * | |
| 57 | + * Write @val to the @reg Dekel PHY register. | |
| 58 | + */ | |
| 59 | +void | |
| 60 | +intel_dkl_phy_write(struct drm_i915_private *i915, i915_reg_t reg, int ln, u32 val) | |
| 61 | +{ | |
| 62 | + spin_lock(&i915->display.dkl.phy_lock); | |
| 63 | + | |
| 64 | + dkl_phy_set_hip_idx(i915, reg, ln); | |
| 65 | + intel_de_write(i915, reg, val); | |
| 66 | + | |
| 67 | + spin_unlock(&i915->display.dkl.phy_lock); | |
| 68 | +} | |
| 69 | + | |
| 70 | +/** | |
| 71 | + * intel_dkl_phy_rmw - read-modify-write a Dekel PHY register | |
| 72 | + * @i915: i915 device instance | |
| 73 | + * @reg: Dekel PHY register | |
| 74 | + * @ln: lane instance of @reg | |
| 75 | + * @clear: mask to clear | |
| 76 | + * @set: mask to set | |
| 77 | + * | |
| 78 | + * Read the @reg Dekel PHY register, clearing then setting the @clear/@set bits in it, and writing | |
| 79 | + * this value back to the register if the value differs from the read one. | |
| 80 | + */ | |
| 81 | +void | |
| 82 | +intel_dkl_phy_rmw(struct drm_i915_private *i915, i915_reg_t reg, int ln, u32 clear, u32 set) | |
| 83 | +{ | |
| 84 | + spin_lock(&i915->display.dkl.phy_lock); | |
| 85 | + | |
| 86 | + dkl_phy_set_hip_idx(i915, reg, ln); | |
| 87 | + intel_de_rmw(i915, reg, clear, set); | |
| 88 | + | |
| 89 | + spin_unlock(&i915->display.dkl.phy_lock); | |
| 90 | +} | |
| 91 | + | |
| 92 | +/** | |
| 93 | + * intel_dkl_phy_posting_read - do a posting read from a Dekel PHY register | |
| 94 | + * @i915: i915 device instance | |
| 95 | + * @reg: Dekel PHY register | |
| 96 | + * @ln: lane instance of @reg | |
| 97 | + * | |
| 98 | + * Read the @reg Dekel PHY register without returning the read value. | |
| 99 | + */ | |
| 100 | +void | |
| 101 | +intel_dkl_phy_posting_read(struct drm_i915_private *i915, i915_reg_t reg, int ln) | |
| 102 | +{ | |
| 103 | + spin_lock(&i915->display.dkl.phy_lock); | |
| 104 | + | |
| 105 | + dkl_phy_set_hip_idx(i915, reg, ln); | |
| 106 | + intel_de_posting_read(i915, reg); | |
| 107 | + | |
| 108 | + spin_unlock(&i915->display.dkl.phy_lock); | |
| 109 | +} | |
| @@ -0,0 +1,24 @@ | ||
| 1 | +/* SPDX-License-Identifier: MIT */ | |
| 2 | +/* | |
| 3 | + * Copyright © 2022 Intel Corporation | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#ifndef __INTEL_DKL_PHY_H__ | |
| 7 | +#define __INTEL_DKL_PHY_H__ | |
| 8 | + | |
| 9 | +#include <linux/types.h> | |
| 10 | + | |
| 11 | +#include "i915_reg_defs.h" | |
| 12 | + | |
| 13 | +struct drm_i915_private; | |
| 14 | + | |
| 15 | +u32 | |
| 16 | +intel_dkl_phy_read(struct drm_i915_private *i915, i915_reg_t reg, int ln); | |
| 17 | +void | |
| 18 | +intel_dkl_phy_write(struct drm_i915_private *i915, i915_reg_t reg, int ln, u32 val); | |
| 19 | +void | |
| 20 | +intel_dkl_phy_rmw(struct drm_i915_private *i915, i915_reg_t reg, int ln, u32 clear, u32 set); | |
| 21 | +void | |
| 22 | +intel_dkl_phy_posting_read(struct drm_i915_private *i915, i915_reg_t reg, int ln); | |
| 23 | + | |
| 24 | +#endif /* __INTEL_DKL_PHY_H__ */ | |
| @@ -5276,7 +5276,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, · 5275 unmodified lines | ||
| 5276 | 5276 | encoder->devdata, IS_ERR(edid) ? NULL : edid); |
| 5277 | 5277 | |
| 5278 | 5278 | intel_panel_add_edid_fixed_modes(intel_connector, |
| 5279 | − intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE, | |
| 5279 | + intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE || | |
| 5280 | 5280 | intel_vrr_is_capable(intel_connector)); |
| 5281 | 5281 | |
| 5282 | 5282 | /* MSO requires information from the EDID */ |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #include "intel_de.h" |
| 27 | 27 | #include "intel_display_types.h" |
| 28 | +#include "intel_dkl_phy.h" | |
| 28 | 29 | #include "intel_dpio_phy.h" |
| 29 | 30 | #include "intel_dpll.h" |
| 30 | 31 | #include "intel_dpll_mgr.h" |
| @@ -3508,15 +3509,12 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv, · 3477 unmodified lines | ||
| 3508 | 3509 | * All registers read here have the same HIP_INDEX_REG even though |
| 3509 | 3510 | * they are on different building blocks |
| 3510 | 3511 | */ |
| 3511 | − intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), | |
| 3512 | − HIP_INDEX_VAL(tc_port, 0x2)); | |
| 3513 | − | |
| 3514 | − hw_state->mg_refclkin_ctl = intel_de_read(dev_priv, | |
| 3515 | − DKL_REFCLKIN_CTL(tc_port)); | |
| 3512 | + hw_state->mg_refclkin_ctl = intel_dkl_phy_read(dev_priv, | |
| 3513 | + DKL_REFCLKIN_CTL(tc_port), 2); | |
| 3516 | 3514 | hw_state->mg_refclkin_ctl &= MG_REFCLKIN_CTL_OD_2_MUX_MASK; |
| 3517 | 3515 | |
| 3518 | 3516 | hw_state->mg_clktop2_hsclkctl = |
| 3519 | − intel_de_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port)); | |
| 3517 | + intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), 2); | |
| 3520 | 3518 | hw_state->mg_clktop2_hsclkctl &= |
| 3521 | 3519 | MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK | |
| 3522 | 3520 | MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK | |
| @@ -3524,32 +3522,32 @@ static bool dkl_pll_get_hw_state(struct drm_i915_private *dev_priv, · 1 unmodified line | ||
| 3524 | 3522 | MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK; |
| 3525 | 3523 | |
| 3526 | 3524 | hw_state->mg_clktop2_coreclkctl1 = |
| 3527 | − intel_de_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port)); | |
| 3525 | + intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), 2); | |
| 3528 | 3526 | hw_state->mg_clktop2_coreclkctl1 &= |
| 3529 | 3527 | MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK; |
| 3530 | 3528 | |
| 3531 | − hw_state->mg_pll_div0 = intel_de_read(dev_priv, DKL_PLL_DIV0(tc_port)); | |
| 3529 | + hw_state->mg_pll_div0 = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV0(tc_port), 2); | |
| 3532 | 3530 | val = DKL_PLL_DIV0_MASK; |
| 3533 | 3531 | if (dev_priv->display.vbt.override_afc_startup) |
| 3534 | 3532 | val |= DKL_PLL_DIV0_AFC_STARTUP_MASK; |
| 3535 | 3533 | hw_state->mg_pll_div0 &= val; |
| 3536 | 3534 | |
| 3537 | − hw_state->mg_pll_div1 = intel_de_read(dev_priv, DKL_PLL_DIV1(tc_port)); | |
| 3535 | + hw_state->mg_pll_div1 = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV1(tc_port), 2); | |
| 3538 | 3536 | hw_state->mg_pll_div1 &= (DKL_PLL_DIV1_IREF_TRIM_MASK | |
| 3539 | 3537 | DKL_PLL_DIV1_TDC_TARGET_CNT_MASK); |
| 3540 | 3538 | |
| 3541 | − hw_state->mg_pll_ssc = intel_de_read(dev_priv, DKL_PLL_SSC(tc_port)); | |
| 3539 | + hw_state->mg_pll_ssc = intel_dkl_phy_read(dev_priv, DKL_PLL_SSC(tc_port), 2); | |
| 3542 | 3540 | hw_state->mg_pll_ssc &= (DKL_PLL_SSC_IREF_NDIV_RATIO_MASK | |
| 3543 | 3541 | DKL_PLL_SSC_STEP_LEN_MASK | |
| 3544 | 3542 | DKL_PLL_SSC_STEP_NUM_MASK | |
| 3545 | 3543 | DKL_PLL_SSC_EN); |
| 3546 | 3544 | |
| 3547 | − hw_state->mg_pll_bias = intel_de_read(dev_priv, DKL_PLL_BIAS(tc_port)); | |
| 3545 | + hw_state->mg_pll_bias = intel_dkl_phy_read(dev_priv, DKL_PLL_BIAS(tc_port), 2); | |
| 3548 | 3546 | hw_state->mg_pll_bias &= (DKL_PLL_BIAS_FRAC_EN_H | |
| 3549 | 3547 | DKL_PLL_BIAS_FBDIV_FRAC_MASK); |
| 3550 | 3548 | |
| 3551 | 3549 | hw_state->mg_pll_tdc_coldst_bias = |
| 3552 | − intel_de_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port)); | |
| 3550 | + intel_dkl_phy_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), 2); | |
| 3553 | 3551 | hw_state->mg_pll_tdc_coldst_bias &= (DKL_PLL_TDC_SSC_STEP_SIZE_MASK | |
| 3554 | 3552 | DKL_PLL_TDC_FEED_FWD_GAIN_MASK); |
| 3555 | 3553 | |
| @@ -3737,61 +3735,58 @@ static void dkl_pll_write(struct drm_i915_private *dev_priv, · 181 unmodified lines | ||
| 3737 | 3735 | * All registers programmed here have the same HIP_INDEX_REG even |
| 3738 | 3736 | * though on different building block |
| 3739 | 3737 | */ |
| 3740 | − intel_de_write(dev_priv, HIP_INDEX_REG(tc_port), | |
| 3741 | − HIP_INDEX_VAL(tc_port, 0x2)); | |
| 3742 | − | |
| 3743 | 3738 | /* All the registers are RMW */ |
| 3744 | − val = intel_de_read(dev_priv, DKL_REFCLKIN_CTL(tc_port)); | |
| 3739 | + val = intel_dkl_phy_read(dev_priv, DKL_REFCLKIN_CTL(tc_port), 2); | |
| 3745 | 3740 | val &= ~MG_REFCLKIN_CTL_OD_2_MUX_MASK; |
| 3746 | 3741 | val |= hw_state->mg_refclkin_ctl; |
| 3747 | − intel_de_write(dev_priv, DKL_REFCLKIN_CTL(tc_port), val); | |
| 3742 | + intel_dkl_phy_write(dev_priv, DKL_REFCLKIN_CTL(tc_port), 2, val); | |
| 3748 | 3743 | |
| 3749 | − val = intel_de_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port)); | |
| 3744 | + val = intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), 2); | |
| 3750 | 3745 | val &= ~MG_CLKTOP2_CORECLKCTL1_A_DIVRATIO_MASK; |
| 3751 | 3746 | val |= hw_state->mg_clktop2_coreclkctl1; |
| 3752 | − intel_de_write(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), val); | |
| 3747 | + intel_dkl_phy_write(dev_priv, DKL_CLKTOP2_CORECLKCTL1(tc_port), 2, val); | |
| 3753 | 3748 | |
| 3754 | − val = intel_de_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port)); | |
| 3749 | + val = intel_dkl_phy_read(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), 2); | |
| 3755 | 3750 | val &= ~(MG_CLKTOP2_HSCLKCTL_TLINEDRV_CLKSEL_MASK | |
| 3756 | 3751 | MG_CLKTOP2_HSCLKCTL_CORE_INPUTSEL_MASK | |
| 3757 | 3752 | MG_CLKTOP2_HSCLKCTL_HSDIV_RATIO_MASK | |
| 3758 | 3753 | MG_CLKTOP2_HSCLKCTL_DSDIV_RATIO_MASK); |
| 3759 | 3754 | val |= hw_state->mg_clktop2_hsclkctl; |
| 3760 | − intel_de_write(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), val); | |
| 3755 | + intel_dkl_phy_write(dev_priv, DKL_CLKTOP2_HSCLKCTL(tc_port), 2, val); | |
| 3761 | 3756 | |
| 3762 | 3757 | val = DKL_PLL_DIV0_MASK; |
| 3763 | 3758 | if (dev_priv->display.vbt.override_afc_startup) |
| 3764 | 3759 | val |= DKL_PLL_DIV0_AFC_STARTUP_MASK; |
| 3765 | − intel_de_rmw(dev_priv, DKL_PLL_DIV0(tc_port), val, | |
| 3766 | − hw_state->mg_pll_div0); | |
| 3760 | + intel_dkl_phy_rmw(dev_priv, DKL_PLL_DIV0(tc_port), 2, val, | |
| 3761 | + hw_state->mg_pll_div0); | |
| 3767 | 3762 | |
| 3768 | − val = intel_de_read(dev_priv, DKL_PLL_DIV1(tc_port)); | |
| 3763 | + val = intel_dkl_phy_read(dev_priv, DKL_PLL_DIV1(tc_port), 2); | |
| 3769 | 3764 | val &= ~(DKL_PLL_DIV1_IREF_TRIM_MASK | |
| 3770 | 3765 | DKL_PLL_DIV1_TDC_TARGET_CNT_MASK); |
| 3771 | 3766 | val |= hw_state->mg_pll_div1; |
| 3772 | − intel_de_write(dev_priv, DKL_PLL_DIV1(tc_port), val); | |
| 3767 | + intel_dkl_phy_write(dev_priv, DKL_PLL_DIV1(tc_port), 2, val); | |
| 3773 | 3768 | |
| 3774 | − val = intel_de_read(dev_priv, DKL_PLL_SSC(tc_port)); | |
| 3769 | + val = intel_dkl_phy_read(dev_priv, DKL_PLL_SSC(tc_port), 2); | |
| 3775 | 3770 | val &= ~(DKL_PLL_SSC_IREF_NDIV_RATIO_MASK | |
| 3776 | 3771 | DKL_PLL_SSC_STEP_LEN_MASK | |
| 3777 | 3772 | DKL_PLL_SSC_STEP_NUM_MASK | |
| 3778 | 3773 | DKL_PLL_SSC_EN); |
| 3779 | 3774 | val |= hw_state->mg_pll_ssc; |
| 3780 | − intel_de_write(dev_priv, DKL_PLL_SSC(tc_port), val); | |
| 3775 | + intel_dkl_phy_write(dev_priv, DKL_PLL_SSC(tc_port), 2, val); | |
| 3781 | 3776 | |
| 3782 | − val = intel_de_read(dev_priv, DKL_PLL_BIAS(tc_port)); | |
| 3777 | + val = intel_dkl_phy_read(dev_priv, DKL_PLL_BIAS(tc_port), 2); | |
| 3783 | 3778 | val &= ~(DKL_PLL_BIAS_FRAC_EN_H | |
| 3784 | 3779 | DKL_PLL_BIAS_FBDIV_FRAC_MASK); |
| 3785 | 3780 | val |= hw_state->mg_pll_bias; |
| 3786 | − intel_de_write(dev_priv, DKL_PLL_BIAS(tc_port), val); | |
| 3781 | + intel_dkl_phy_write(dev_priv, DKL_PLL_BIAS(tc_port), 2, val); | |
| 3787 | 3782 | |
| 3788 | − val = intel_de_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port)); | |
| 3783 | + val = intel_dkl_phy_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), 2); | |
| 3789 | 3784 | val &= ~(DKL_PLL_TDC_SSC_STEP_SIZE_MASK | |
| 3790 | 3785 | DKL_PLL_TDC_FEED_FWD_GAIN_MASK); |
| 3791 | 3786 | val |= hw_state->mg_pll_tdc_coldst_bias; |
| 3792 | − intel_de_write(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), val); | |
| 3787 | + intel_dkl_phy_write(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), 2, val); | |
| 3793 | 3788 | |
| 3794 | − intel_de_posting_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port)); | |
| 3789 | + intel_dkl_phy_posting_read(dev_priv, DKL_PLL_TDC_COLDST_BIAS(tc_port), 2); | |
| 3795 | 3790 | } |
| 3796 | 3791 | |
| 3797 | 3792 | static void icl_pll_power_enable(struct drm_i915_private *dev_priv, |
| @@ -972,8 +972,7 @@ void intel_lvds_init(struct drm_i915_private *dev_priv) · 971 unmodified lines | ||
| 972 | 972 | |
| 973 | 973 | /* Try EDID first */ |
| 974 | 974 | intel_panel_add_edid_fixed_modes(intel_connector, |
| 975 | − intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE, | |
| 976 | − false); | |
| 975 | + intel_connector->panel.vbt.drrs_type != DRRS_TYPE_NONE); | |
| 977 | 976 | |
| 978 | 977 | /* Failed to get EDID, what about VBT? */ |
| 979 | 978 | if (!intel_panel_preferred_fixed_mode(intel_connector)) |
| @@ -254,10 +254,10 @@ static void intel_panel_destroy_probed_modes(struct intel_connector *connector) · 253 unmodified lines | ||
| 254 | 254 | } |
| 255 | 255 | |
| 256 | 256 | void intel_panel_add_edid_fixed_modes(struct intel_connector *connector, |
| 257 | − bool has_drrs, bool has_vrr) | |
| 257 | + bool use_alt_fixed_modes) | |
| 258 | 258 | { |
| 259 | 259 | intel_panel_add_edid_preferred_mode(connector); |
| 260 | − if (intel_panel_preferred_fixed_mode(connector) && (has_drrs || has_vrr)) | |
| 260 | + if (intel_panel_preferred_fixed_mode(connector) && use_alt_fixed_modes) | |
| 261 | 261 | intel_panel_add_edid_alt_fixed_modes(connector); |
| 262 | 262 | intel_panel_destroy_probed_modes(connector); |
| 263 | 263 | } |
| @@ -44,7 +44,7 @@ int intel_panel_fitting(struct intel_crtc_state *crtc_state, · 43 unmodified lines | ||
| 44 | 44 | int intel_panel_compute_config(struct intel_connector *connector, |
| 45 | 45 | struct drm_display_mode *adjusted_mode); |
| 46 | 46 | void intel_panel_add_edid_fixed_modes(struct intel_connector *connector, |
| 47 | − bool has_drrs, bool has_vrr); | |
| 47 | + bool use_alt_fixed_modes); | |
| 48 | 48 | void intel_panel_add_vbt_lfp_fixed_mode(struct intel_connector *connector); |
| 49 | 49 | void intel_panel_add_vbt_sdvo_fixed_mode(struct intel_connector *connector); |
| 50 | 50 | void intel_panel_add_encoder_fixed_mode(struct intel_connector *connector, |
| @@ -2201,8 +2201,11 @@ static void _psr_invalidate_handle(struct intel_dp *intel_dp) · 2200 unmodified lines | ||
| 2201 | 2201 | if (intel_dp->psr.psr2_sel_fetch_enabled) { |
| 2202 | 2202 | u32 val; |
| 2203 | 2203 | |
| 2204 | − if (intel_dp->psr.psr2_sel_fetch_cff_enabled) | |
| 2204 | + if (intel_dp->psr.psr2_sel_fetch_cff_enabled) { | |
| 2205 | + /* Send one update otherwise lag is observed in screen */ | |
| 2206 | + intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0); | |
| 2205 | 2207 | return; |
| 2208 | + } | |
| 2206 | 2209 | |
| 2207 | 2210 | val = man_trk_ctl_enable_bit_get(dev_priv) | |
| 2208 | 2211 | man_trk_ctl_partial_frame_bit_get(dev_priv) | |
| @@ -2747,13 +2747,10 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) · 2746 unmodified lines | ||
| 2747 | 2747 | if (!intel_sdvo_connector) |
| 2748 | 2748 | return false; |
| 2749 | 2749 | |
| 2750 | − if (device == 0) { | |
| 2751 | − intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0; | |
| 2750 | + if (device == 0) | |
| 2752 | 2751 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; |
| 2753 | − } else if (device == 1) { | |
| 2754 | − intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1; | |
| 2752 | + else if (device == 1) | |
| 2755 | 2753 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; |
| 2756 | − } | |
| 2757 | 2754 | |
| 2758 | 2755 | intel_connector = &intel_sdvo_connector->base; |
| 2759 | 2756 | connector = &intel_connector->base; |
| @@ -2808,7 +2805,6 @@ intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) · 48 unmodified lines | ||
| 2808 | 2805 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; |
| 2809 | 2806 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
| 2810 | 2807 | |
| 2811 | − intel_sdvo->controlled_output |= type; | |
| 2812 | 2808 | intel_sdvo_connector->output_flag = type; |
| 2813 | 2809 | |
| 2814 | 2810 | if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { |
| @@ -2849,13 +2845,10 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) · 34 unmodified lines | ||
| 2849 | 2845 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
| 2850 | 2846 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
| 2851 | 2847 | |
| 2852 | − if (device == 0) { | |
| 2853 | − intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; | |
| 2848 | + if (device == 0) | |
| 2854 | 2849 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; |
| 2855 | − } else if (device == 1) { | |
| 2856 | − intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; | |
| 2850 | + else if (device == 1) | |
| 2857 | 2851 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
| 2858 | − } | |
| 2859 | 2852 | |
| 2860 | 2853 | if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { |
| 2861 | 2854 | kfree(intel_sdvo_connector); |
| @@ -2885,13 +2878,10 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) · 23 unmodified lines | ||
| 2885 | 2878 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
| 2886 | 2879 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
| 2887 | 2880 | |
| 2888 | − if (device == 0) { | |
| 2889 | − intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; | |
| 2881 | + if (device == 0) | |
| 2890 | 2882 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; |
| 2891 | − } else if (device == 1) { | |
| 2892 | − intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; | |
| 2883 | + else if (device == 1) | |
| 2893 | 2884 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
| 2894 | − } | |
| 2895 | 2885 | |
| 2896 | 2886 | if (intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo) < 0) { |
| 2897 | 2887 | kfree(intel_sdvo_connector); |
| @@ -2910,8 +2900,12 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) · 12 unmodified lines | ||
| 2910 | 2900 | intel_panel_add_vbt_sdvo_fixed_mode(intel_connector); |
| 2911 | 2901 | |
| 2912 | 2902 | if (!intel_panel_preferred_fixed_mode(intel_connector)) { |
| 2903 | + mutex_lock(&i915->drm.mode_config.mutex); | |
| 2904 | + | |
| 2913 | 2905 | intel_ddc_get_modes(connector, &intel_sdvo->ddc); |
| 2914 | − intel_panel_add_edid_fixed_modes(intel_connector, false, false); | |
| 2906 | + intel_panel_add_edid_fixed_modes(intel_connector, false); | |
| 2907 | + | |
| 2908 | + mutex_unlock(&i915->drm.mode_config.mutex); | |
| 2915 | 2909 | } |
| 2916 | 2910 | |
| 2917 | 2911 | intel_panel_init(intel_connector); |
| @@ -2926,16 +2920,39 @@ err: · 8 unmodified lines | ||
| 2926 | 2920 | return false; |
| 2927 | 2921 | } |
| 2928 | 2922 | |
| 2923 | +static u16 intel_sdvo_filter_output_flags(u16 flags) | |
| 2924 | +{ | |
| 2925 | + flags &= SDVO_OUTPUT_MASK; | |
| 2926 | + | |
| 2927 | + /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ | |
| 2928 | + if (!(flags & SDVO_OUTPUT_TMDS0)) | |
| 2929 | + flags &= ~SDVO_OUTPUT_TMDS1; | |
| 2930 | + | |
| 2931 | + if (!(flags & SDVO_OUTPUT_RGB0)) | |
| 2932 | + flags &= ~SDVO_OUTPUT_RGB1; | |
| 2933 | + | |
| 2934 | + if (!(flags & SDVO_OUTPUT_LVDS0)) | |
| 2935 | + flags &= ~SDVO_OUTPUT_LVDS1; | |
| 2936 | + | |
| 2937 | + return flags; | |
| 2938 | +} | |
| 2939 | + | |
| 2929 | 2940 | static bool |
| 2930 | 2941 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags) |
| 2931 | 2942 | { |
| 2932 | − /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ | |
| 2943 | + struct drm_i915_private *i915 = to_i915(intel_sdvo->base.base.dev); | |
| 2944 | + | |
| 2945 | + flags = intel_sdvo_filter_output_flags(flags); | |
| 2946 | + | |
| 2947 | + intel_sdvo->controlled_output = flags; | |
| 2948 | + | |
| 2949 | + intel_sdvo_select_ddc_bus(i915, intel_sdvo); | |
| 2933 | 2950 | |
| 2934 | 2951 | if (flags & SDVO_OUTPUT_TMDS0) |
| 2935 | 2952 | if (!intel_sdvo_dvi_init(intel_sdvo, 0)) |
| 2936 | 2953 | return false; |
| 2937 | 2954 | |
| 2938 | − if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) | |
| 2955 | + if (flags & SDVO_OUTPUT_TMDS1) | |
| 2939 | 2956 | if (!intel_sdvo_dvi_init(intel_sdvo, 1)) |
| 2940 | 2957 | return false; |
| 2941 | 2958 | |
| @@ -2956,7 +2973,7 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags) · 14 unmodified lines | ||
| 2956 | 2973 | if (!intel_sdvo_analog_init(intel_sdvo, 0)) |
| 2957 | 2974 | return false; |
| 2958 | 2975 | |
| 2959 | − if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) | |
| 2976 | + if (flags & SDVO_OUTPUT_RGB1) | |
| 2960 | 2977 | if (!intel_sdvo_analog_init(intel_sdvo, 1)) |
| 2961 | 2978 | return false; |
| 2962 | 2979 | |
| @@ -2964,14 +2981,13 @@ intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, u16 flags) · 1 unmodified line | ||
| 2964 | 2981 | if (!intel_sdvo_lvds_init(intel_sdvo, 0)) |
| 2965 | 2982 | return false; |
| 2966 | 2983 | |
| 2967 | − if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) | |
| 2984 | + if (flags & SDVO_OUTPUT_LVDS1) | |
| 2968 | 2985 | if (!intel_sdvo_lvds_init(intel_sdvo, 1)) |
| 2969 | 2986 | return false; |
| 2970 | 2987 | |
| 2971 | − if ((flags & SDVO_OUTPUT_MASK) == 0) { | |
| 2988 | + if (flags == 0) { | |
| 2972 | 2989 | unsigned char bytes[2]; |
| 2973 | 2990 | |
| 2974 | − intel_sdvo->controlled_output = 0; | |
| 2975 | 2991 | memcpy(bytes, &intel_sdvo->caps.output_flags, 2); |
| 2976 | 2992 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", |
| 2977 | 2993 | SDVO_NAME(intel_sdvo), |
| @@ -3383,8 +3399,6 @@ bool intel_sdvo_init(struct drm_i915_private *dev_priv, · 405 unmodified lines | ||
| 3383 | 3399 | */ |
| 3384 | 3400 | intel_sdvo->base.cloneable = 0; |
| 3385 | 3401 | |
| 3386 | − intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo); | |
| 3387 | − | |
| 3388 | 3402 | /* Set the input timing to the screen. Assume always input 0. */ |
| 3389 | 3403 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
| 3390 | 3404 | goto err_output; |
| @@ -40,13 +40,13 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme · 39 unmodified lines | ||
| 40 | 40 | goto err; |
| 41 | 41 | } |
| 42 | 42 | |
| 43 | − ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL); | |
| 43 | + ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL); | |
| 44 | 44 | if (ret) |
| 45 | 45 | goto err_free; |
| 46 | 46 | |
| 47 | 47 | src = obj->mm.pages->sgl; |
| 48 | 48 | dst = st->sgl; |
| 49 | − for (i = 0; i < obj->mm.pages->nents; i++) { | |
| 49 | + for (i = 0; i < obj->mm.pages->orig_nents; i++) { | |
| 50 | 50 | sg_set_page(dst, sg_page(src), src->length, 0); |
| 51 | 51 | dst = sg_next(dst); |
| 52 | 52 | src = sg_next(src); |
| @@ -6,7 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | #include <linux/scatterlist.h> |
| 8 | 8 | #include <linux/slab.h> |
| 9 | −#include <linux/swiotlb.h> | |
| 10 | 9 | |
| 11 | 10 | #include "i915_drv.h" |
| 12 | 11 | #include "i915_gem.h" |
| @@ -38,22 +37,12 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) · 25 unmodified lines | ||
| 38 | 37 | struct scatterlist *sg; |
| 39 | 38 | unsigned int sg_page_sizes; |
| 40 | 39 | unsigned int npages; |
| 41 | − int max_order; | |
| 40 | + int max_order = MAX_ORDER; | |
| 41 | + unsigned int max_segment; | |
| 42 | 42 | gfp_t gfp; |
| 43 | 43 | |
| 44 | − max_order = MAX_ORDER; | |
| 45 | −#ifdef CONFIG_SWIOTLB | |
| 46 | − if (is_swiotlb_active(obj->base.dev->dev)) { | |
| 47 | − unsigned int max_segment; | |
| 48 | − | |
| 49 | − max_segment = swiotlb_max_segment(); | |
| 50 | − if (max_segment) { | |
| 51 | − max_segment = max_t(unsigned int, max_segment, | |
| 52 | − PAGE_SIZE) >> PAGE_SHIFT; | |
| 53 | − max_order = min(max_order, ilog2(max_segment)); | |
| 54 | − } | |
| 55 | − } | |
| 56 | −#endif | |
| 44 | + max_segment = i915_sg_segment_size(i915->drm.dev) >> PAGE_SHIFT; | |
| 45 | + max_order = min(max_order, get_order(max_segment)); | |
| 57 | 46 | |
| 58 | 47 | gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_RECLAIMABLE; |
| 59 | 48 | if (IS_I965GM(i915) || IS_I965G(i915)) { |
| @@ -194,7 +194,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) · 193 unmodified lines | ||
| 194 | 194 | struct intel_memory_region *mem = obj->mm.region; |
| 195 | 195 | struct address_space *mapping = obj->base.filp->f_mapping; |
| 196 | 196 | const unsigned long page_count = obj->base.size / PAGE_SIZE; |
| 197 | − unsigned int max_segment = i915_sg_segment_size(); | |
| 197 | + unsigned int max_segment = i915_sg_segment_size(i915->drm.dev); | |
| 198 | 198 | struct sg_table *st; |
| 199 | 199 | struct sgt_iter sgt_iter; |
| 200 | 200 | struct page *page; |
| @@ -369,14 +369,14 @@ __i915_gem_object_release_shmem(struct drm_i915_gem_object *obj, · 168 unmodified lines | ||
| 369 | 369 | |
| 370 | 370 | __start_cpu_write(obj); |
| 371 | 371 | /* |
| 372 | − * On non-LLC platforms, force the flush-on-acquire if this is ever | |
| 372 | + * On non-LLC igfx platforms, force the flush-on-acquire if this is ever | |
| 373 | 373 | * swapped-in. Our async flush path is not trust worthy enough yet(and |
| 374 | 374 | * happens in the wrong order), and with some tricks it's conceivable |
| 375 | 375 | * for userspace to change the cache-level to I915_CACHE_NONE after the |
| 376 | 376 | * pages are swapped-in, and since execbuf binds the object before doing |
| 377 | 377 | * the async flush, we have a race window. |
| 378 | 378 | */ |
| 379 | − if (!HAS_LLC(i915)) | |
| 379 | + if (!HAS_LLC(i915) && !IS_DGFX(i915)) | |
| 380 | 380 | obj->cache_dirty = true; |
| 381 | 381 | } |
| 382 | 382 | |
| @@ -189,7 +189,7 @@ static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev, · 188 unmodified lines | ||
| 189 | 189 | struct drm_i915_private *i915 = container_of(bdev, typeof(*i915), bdev); |
| 190 | 190 | struct intel_memory_region *mr = i915->mm.regions[INTEL_MEMORY_SYSTEM]; |
| 191 | 191 | struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm); |
| 192 | − const unsigned int max_segment = i915_sg_segment_size(); | |
| 192 | + const unsigned int max_segment = i915_sg_segment_size(i915->drm.dev); | |
| 193 | 193 | const size_t size = (size_t)ttm->num_pages << PAGE_SHIFT; |
| 194 | 194 | struct file *filp = i915_tt->filp; |
| 195 | 195 | struct sgt_iter sgt_iter; |
| @@ -538,7 +538,7 @@ static struct i915_refct_sgt *i915_ttm_tt_get_st(struct ttm_tt *ttm) · 342 unmodified lines | ||
| 538 | 538 | ret = sg_alloc_table_from_pages_segment(st, |
| 539 | 539 | ttm->pages, ttm->num_pages, |
| 540 | 540 | 0, (unsigned long)ttm->num_pages << PAGE_SHIFT, |
| 541 | − i915_sg_segment_size(), GFP_KERNEL); | |
| 541 | + i915_sg_segment_size(i915_tt->dev), GFP_KERNEL); | |
| 542 | 542 | if (ret) { |
| 543 | 543 | st->sgl = NULL; |
| 544 | 544 | return ERR_PTR(ret); |
| @@ -612,6 +612,10 @@ static int i915_ttm_truncate(struct drm_i915_gem_object *obj) · 67 unmodified lines | ||
| 612 | 612 | |
| 613 | 613 | WARN_ON_ONCE(obj->mm.madv == I915_MADV_WILLNEED); |
| 614 | 614 | |
| 615 | + err = ttm_bo_wait(bo, true, false); | |
| 616 | + if (err) | |
| 617 | + return err; | |
| 618 | + | |
| 615 | 619 | err = i915_ttm_move_notify(bo); |
| 616 | 620 | if (err) |
| 617 | 621 | return err; |
| @@ -1013,9 +1017,6 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf) · 395 unmodified lines | ||
| 1013 | 1017 | return VM_FAULT_SIGBUS; |
| 1014 | 1018 | } |
| 1015 | 1019 | |
| 1016 | − if (i915_ttm_cpu_maps_iomem(bo->resource)) | |
| 1017 | − wakeref = intel_runtime_pm_get(&to_i915(obj->base.dev)->runtime_pm); | |
| 1018 | − | |
| 1019 | 1020 | if (!i915_ttm_resource_mappable(bo->resource)) { |
| 1020 | 1021 | int err = -ENODEV; |
| 1021 | 1022 | int i; |
| @@ -1042,6 +1043,9 @@ static vm_fault_t vm_fault_ttm(struct vm_fault *vmf) · 20 unmodified lines | ||
| 1042 | 1043 | } |
| 1043 | 1044 | } |
| 1044 | 1045 | |
| 1046 | + if (i915_ttm_cpu_maps_iomem(bo->resource)) | |
| 1047 | + wakeref = intel_runtime_pm_get(&to_i915(obj->base.dev)->runtime_pm); | |
| 1048 | + | |
| 1045 | 1049 | if (drm_dev_enter(dev, &idx)) { |
| 1046 | 1050 | ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot, |
| 1047 | 1051 | TTM_BO_VM_NUM_PREFAULT); |
| @@ -129,7 +129,7 @@ static void i915_gem_object_userptr_drop_ref(struct drm_i915_gem_object *obj) · 128 unmodified lines | ||
| 129 | 129 | static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) |
| 130 | 130 | { |
| 131 | 131 | const unsigned long num_pages = obj->base.size >> PAGE_SHIFT; |
| 132 | − unsigned int max_segment = i915_sg_segment_size(); | |
| 132 | + unsigned int max_segment = i915_sg_segment_size(obj->base.dev->dev); | |
| 133 | 133 | struct sg_table *st; |
| 134 | 134 | unsigned int sg_page_sizes; |
| 135 | 135 | struct page **pvec; |
| @@ -428,9 +428,10 @@ probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len) · 292 unmodified lines | ||
| 428 | 428 | { |
| 429 | 429 | VMA_ITERATOR(vmi, mm, addr); |
| 430 | 430 | struct vm_area_struct *vma; |
| 431 | + unsigned long end = addr + len; | |
| 431 | 432 | |
| 432 | 433 | mmap_read_lock(mm); |
| 433 | − for_each_vma_range(vmi, vma, addr + len) { | |
| 434 | + for_each_vma_range(vmi, vma, end) { | |
| 434 | 435 | /* Check for holes, note that we also update the addr below */ |
| 435 | 436 | if (vma->vm_start > addr) |
| 436 | 437 | break; |
| @@ -442,7 +443,7 @@ probe_range(struct mm_struct *mm, unsigned long addr, unsigned long len) · 5 unmodified lines | ||
| 442 | 443 | } |
| 443 | 444 | mmap_read_unlock(mm); |
| 444 | 445 | |
| 445 | − if (vma) | |
| 446 | + if (vma || addr < end) | |
| 446 | 447 | return -EFAULT; |
| 447 | 448 | return 0; |
| 448 | 449 | } |
| @@ -625,8 +625,13 @@ int intel_gt_wait_for_idle(struct intel_gt *gt, long timeout) · 624 unmodified lines | ||
| 625 | 625 | return -EINTR; |
| 626 | 626 | } |
| 627 | 627 | |
| 628 | − return timeout ? timeout : intel_uc_wait_for_idle(>->uc, | |
| 629 | − remaining_timeout); | |
| 628 | + if (timeout) | |
| 629 | + return timeout; | |
| 630 | + | |
| 631 | + if (remaining_timeout < 0) | |
| 632 | + remaining_timeout = 0; | |
| 633 | + | |
| 634 | + return intel_uc_wait_for_idle(>->uc, remaining_timeout); | |
| 630 | 635 | } |
| 631 | 636 | |
| 632 | 637 | int intel_gt_init(struct intel_gt *gt) |
| @@ -1017,6 +1022,11 @@ static void mmio_invalidate_full(struct intel_gt *gt) · 384 unmodified lines | ||
| 1017 | 1022 | if (!i915_mmio_reg_offset(rb.reg)) |
| 1018 | 1023 | continue; |
| 1019 | 1024 | |
| 1025 | + if (GRAPHICS_VER(i915) == 12 && (engine->class == VIDEO_DECODE_CLASS || | |
| 1026 | + engine->class == VIDEO_ENHANCEMENT_CLASS || | |
| 1027 | + engine->class == COMPUTE_CLASS)) | |
| 1028 | + rb.bit = _MASKED_BIT_ENABLE(rb.bit); | |
| 1029 | + | |
| 1020 | 1030 | intel_uncore_write_fw(uncore, rb.reg, rb.bit); |
| 1021 | 1031 | awake |= engine->mask; |
| 1022 | 1032 | } |
| @@ -199,7 +199,7 @@ out_active: spin_lock(&timelines->lock); · 198 unmodified lines | ||
| 199 | 199 | if (remaining_timeout) |
| 200 | 200 | *remaining_timeout = timeout; |
| 201 | 201 | |
| 202 | − return active_count ? timeout : 0; | |
| 202 | + return active_count ? timeout ?: -ETIME : 0; | |
| 203 | 203 | } |
| 204 | 204 | |
| 205 | 205 | static void retire_work_handler(struct work_struct *work) |
| @@ -664,8 +664,6 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev) · 663 unmodified lines | ||
| 664 | 664 | return -ESRCH; |
| 665 | 665 | } |
| 666 | 666 | |
| 667 | − kvm_get_kvm(vgpu->vfio_device.kvm); | |
| 668 | − | |
| 669 | 667 | if (__kvmgt_vgpu_exist(vgpu)) |
| 670 | 668 | return -EEXIST; |
| 671 | 669 | |
| @@ -676,6 +674,7 @@ static int intel_vgpu_open_device(struct vfio_device *vfio_dev) · 4 unmodified lines | ||
| 676 | 674 | |
| 677 | 675 | vgpu->track_node.track_write = kvmgt_page_track_write; |
| 678 | 676 | vgpu->track_node.track_flush_slot = kvmgt_page_track_flush_slot; |
| 677 | + kvm_get_kvm(vgpu->vfio_device.kvm); | |
| 679 | 678 | kvm_page_track_register_notifier(vgpu->vfio_device.kvm, |
| 680 | 679 | &vgpu->track_node); |
| 681 | 680 | |
| @@ -715,15 +714,14 @@ static void intel_vgpu_close_device(struct vfio_device *vfio_dev) · 33 unmodified lines | ||
| 715 | 714 | |
| 716 | 715 | kvm_page_track_unregister_notifier(vgpu->vfio_device.kvm, |
| 717 | 716 | &vgpu->track_node); |
| 717 | + kvm_put_kvm(vgpu->vfio_device.kvm); | |
| 718 | + | |
| 718 | 719 | kvmgt_protect_table_destroy(vgpu); |
| 719 | 720 | gvt_cache_destroy(vgpu); |
| 720 | 721 | |
| 721 | 722 | intel_vgpu_release_msi_eventfd_ctx(vgpu); |
| 722 | 723 | |
| 723 | 724 | vgpu->attached = false; |
| 724 | − | |
| 725 | − if (vgpu->vfio_device.kvm) | |
| 726 | − kvm_put_kvm(vgpu->vfio_device.kvm); | |
| 727 | 725 | } |
| 728 | 726 | |
| 729 | 727 | static u64 intel_vgpu_get_bar_addr(struct intel_vgpu *vgpu, int bar) |
| @@ -353,6 +353,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) · 352 unmodified lines | ||
| 353 | 353 | mutex_init(&dev_priv->display.wm.wm_mutex); |
| 354 | 354 | mutex_init(&dev_priv->display.pps.mutex); |
| 355 | 355 | mutex_init(&dev_priv->display.hdcp.comp_mutex); |
| 356 | + spin_lock_init(&dev_priv->display.dkl.phy_lock); | |
| 356 | 357 | |
| 357 | 358 | i915_memcpy_init_early(dev_priv); |
| 358 | 359 | intel_runtime_pm_init_early(&dev_priv->runtime_pm); |
| @@ -7420,6 +7420,9 @@ enum skl_power_gate { · 7419 unmodified lines | ||
| 7420 | 7420 | #define _DKL_PHY5_BASE 0x16C000 |
| 7421 | 7421 | #define _DKL_PHY6_BASE 0x16D000 |
| 7422 | 7422 | |
| 7423 | +#define DKL_REG_TC_PORT(__reg) \ | |
| 7424 | + (TC_PORT_1 + ((__reg).reg - _DKL_PHY1_BASE) / (_DKL_PHY2_BASE - _DKL_PHY1_BASE)) | |
| 7425 | + | |
| 7423 | 7426 | /* DEKEL PHY MMIO Address = Phy base + (internal address & ~index_mask) */ |
| 7424 | 7427 | #define _DKL_PCS_DW5 0x14 |
| 7425 | 7428 | #define DKL_PCS_DW5(tc_port) _MMIO(_PORT(tc_port, _DKL_PHY1_BASE, \ |
| @@ -9,7 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | #include <linux/pfn.h> |
| 11 | 11 | #include <linux/scatterlist.h> |
| 12 | −#include <linux/swiotlb.h> | |
| 12 | +#include <linux/dma-mapping.h> | |
| 13 | +#include <xen/xen.h> | |
| 13 | 14 | |
| 14 | 15 | #include "i915_gem.h" |
| 15 | 16 | |
| @@ -127,19 +128,26 @@ static inline unsigned int i915_sg_dma_sizes(struct scatterlist *sg) · 111 unmodified lines | ||
| 127 | 128 | return page_sizes; |
| 128 | 129 | } |
| 129 | 130 | |
| 130 | −static inline unsigned int i915_sg_segment_size(void) | |
| 131 | +static inline unsigned int i915_sg_segment_size(struct device *dev) | |
| 131 | 132 | { |
| 132 | − unsigned int size = swiotlb_max_segment(); | |
| 133 | − | |
| 134 | − if (size == 0) | |
| 135 | − size = UINT_MAX; | |
| 136 | − | |
| 137 | − size = rounddown(size, PAGE_SIZE); | |
| 138 | − /* swiotlb_max_segment_size can return 1 byte when it means one page. */ | |
| 139 | − if (size < PAGE_SIZE) | |
| 140 | − size = PAGE_SIZE; | |
| 141 | − | |
| 142 | − return size; | |
| 133 | + size_t max = min_t(size_t, UINT_MAX, dma_max_mapping_size(dev)); | |
| 134 | + | |
| 135 | + /* | |
| 136 | + * For Xen PV guests pages aren't contiguous in DMA (machine) address | |
| 137 | + * space. The DMA API takes care of that both in dma_alloc_* (by | |
| 138 | + * calling into the hypervisor to make the pages contiguous) and in | |
| 139 | + * dma_map_* (by bounce buffering). But i915 abuses ignores the | |
| 140 | + * coherency aspects of the DMA API and thus can't cope with bounce | |
| 141 | + * buffering actually happening, so add a hack here to force small | |
| 142 | + * allocations and mappings when running in PV mode on Xen. | |
| 143 | + * | |
| 144 | + * Note this will still break if bounce buffering is required for other | |
| 145 | + * reasons, like confidential computing hypervisors or PCIe root ports | |
| 146 | + * with addressing limitations. | |
| 147 | + */ | |
| 148 | + if (xen_pv_domain()) | |
| 149 | + max = PAGE_SIZE; | |
| 150 | + return round_down(max, PAGE_SIZE); | |
| 143 | 151 | } |
| 144 | 152 | |
| 145 | 153 | bool i915_sg_trim(struct sg_table *orig_st); |
| @@ -471,8 +471,7 @@ static int xelpdp_get_dram_info(struct drm_i915_private *i915) · 470 unmodified lines | ||
| 471 | 471 | u32 val = intel_uncore_read(&i915->uncore, MTL_MEM_SS_INFO_GLOBAL); |
| 472 | 472 | struct dram_info *dram_info = &i915->dram_info; |
| 473 | 473 | |
| 474 | − val = REG_FIELD_GET(MTL_DDR_TYPE_MASK, val); | |
| 475 | − switch (val) { | |
| 474 | + switch (REG_FIELD_GET(MTL_DDR_TYPE_MASK, val)) { | |
| 476 | 475 | case 0: |
| 477 | 476 | dram_info->type = INTEL_DRAM_DDR4; |
| 478 | 477 | break; |
| @@ -4,7 +4,6 @@ config DRM_IMX · 3 unmodified lines | ||
| 4 | 4 | select DRM_KMS_HELPER |
| 5 | 5 | select VIDEOMODE_HELPERS |
| 6 | 6 | select DRM_GEM_DMA_HELPER |
| 7 | − select DRM_KMS_HELPER | |
| 8 | 7 | depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM || COMPILE_TEST) |
| 9 | 8 | depends on IMX_IPUV3_CORE |
| 10 | 9 | help |
| @@ -218,8 +218,9 @@ static int imx_tve_connector_get_modes(struct drm_connector *connector) · 217 unmodified lines | ||
| 218 | 218 | return ret; |
| 219 | 219 | } |
| 220 | 220 | |
| 221 | −static int imx_tve_connector_mode_valid(struct drm_connector *connector, | |
| 222 | − struct drm_display_mode *mode) | |
| 221 | +static enum drm_mode_status | |
| 222 | +imx_tve_connector_mode_valid(struct drm_connector *connector, | |
| 223 | + struct drm_display_mode *mode) | |
| 223 | 224 | { |
| 224 | 225 | struct imx_tve *tve = con_to_tve(connector); |
| 225 | 226 | unsigned long rate; |
| @@ -112,11 +112,6 @@ int lima_devfreq_init(struct lima_device *ldev) · 111 unmodified lines | ||
| 112 | 112 | unsigned long cur_freq; |
| 113 | 113 | int ret; |
| 114 | 114 | const char *regulator_names[] = { "mali", NULL }; |
| 115 | − const char *clk_names[] = { "core", NULL }; | |
| 116 | − struct dev_pm_opp_config config = { | |
| 117 | − .regulator_names = regulator_names, | |
| 118 | − .clk_names = clk_names, | |
| 119 | − }; | |
| 120 | 115 | |
| 121 | 116 | if (!device_property_present(dev, "operating-points-v2")) |
| 122 | 117 | /* Optional, continue without devfreq */ |
| @@ -124,7 +119,15 @@ int lima_devfreq_init(struct lima_device *ldev) · 1 unmodified line | ||
| 124 | 119 | |
| 125 | 120 | spin_lock_init(&ldevfreq->lock); |
| 126 | 121 | |
| 127 | − ret = devm_pm_opp_set_config(dev, &config); | |
| 122 | + /* | |
| 123 | + * clkname is set separately so it is not affected by the optional | |
| 124 | + * regulator setting which may return error. | |
| 125 | + */ | |
| 126 | + ret = devm_pm_opp_set_clkname(dev, "core"); | |
| 127 | + if (ret) | |
| 128 | + return ret; | |
| 129 | + | |
| 130 | + ret = devm_pm_opp_set_regulators(dev, regulator_names); | |
| 128 | 131 | if (ret) { |
| 129 | 132 | /* Continue if the optional regulator is missing */ |
| 130 | 133 | if (ret != -ENODEV) |
| @@ -2500,6 +2500,7 @@ static const struct display_timing logictechno_lt161010_2nh_timing = { · 2499 unmodified lines | ||
| 2500 | 2500 | static const struct panel_desc logictechno_lt161010_2nh = { |
| 2501 | 2501 | .timings = &logictechno_lt161010_2nh_timing, |
| 2502 | 2502 | .num_timings = 1, |
| 2503 | + .bpc = 6, | |
| 2503 | 2504 | .size = { |
| 2504 | 2505 | .width = 154, |
| 2505 | 2506 | .height = 86, |
| @@ -2529,6 +2530,7 @@ static const struct display_timing logictechno_lt170410_2whc_timing = { · 23 unmodified lines | ||
| 2529 | 2530 | static const struct panel_desc logictechno_lt170410_2whc = { |
| 2530 | 2531 | .timings = &logictechno_lt170410_2whc_timing, |
| 2531 | 2532 | .num_timings = 1, |
| 2533 | + .bpc = 8, | |
| 2532 | 2534 | .size = { |
| 2533 | 2535 | .width = 217, |
| 2534 | 2536 | .height = 136, |
| @@ -250,13 +250,22 @@ void panfrost_mmu_reset(struct panfrost_device *pfdev) · 249 unmodified lines | ||
| 250 | 250 | |
| 251 | 251 | static size_t get_pgsize(u64 addr, size_t size, size_t *count) |
| 252 | 252 | { |
| 253 | + /* | |
| 254 | + * io-pgtable only operates on multiple pages within a single table | |
| 255 | + * entry, so we need to split at boundaries of the table size, i.e. | |
| 256 | + * the next block size up. The distance from address A to the next | |
| 257 | + * boundary of block size B is logically B - A % B, but in unsigned | |
| 258 | + * two's complement where B is a power of two we get the equivalence | |
| 259 | + * B - A % B == (B - A) % B == (n * B - A) % B, and choose n = 0 :) | |
| 260 | + */ | |
| 253 | 261 | size_t blk_offset = -addr % SZ_2M; |
| 254 | 262 | |
| 255 | 263 | if (blk_offset || size < SZ_2M) { |
| 256 | 264 | *count = min_not_zero(blk_offset, size) / SZ_4K; |
| 257 | 265 | return SZ_4K; |
| 258 | 266 | } |
| 259 | − *count = size / SZ_2M; | |
| 267 | + blk_offset = -addr % SZ_1G ?: SZ_1G; | |
| 268 | + *count = min(blk_offset, size) / SZ_2M; | |
| 260 | 269 | return SZ_2M; |
| 261 | 270 | } |
| 262 | 271 | |
| @@ -44,13 +44,18 @@ config DRM_RCAR_LVDS · 43 unmodified lines | ||
| 44 | 44 | select OF_FLATTREE |
| 45 | 45 | select OF_OVERLAY |
| 46 | 46 | |
| 47 | −config DRM_RCAR_MIPI_DSI | |
| 48 | − tristate "R-Car DU MIPI DSI Encoder Support" | |
| 49 | − depends on DRM && DRM_BRIDGE && OF | |
| 50 | − select DRM_MIPI_DSI | |
| 47 | +config DRM_RCAR_USE_MIPI_DSI | |
| 48 | + bool "R-Car DU MIPI DSI Encoder Support" | |
| 49 | + depends on DRM_BRIDGE && OF | |
| 50 | + default DRM_RCAR_DU | |
| 51 | 51 | help |
| 52 | 52 | Enable support for the R-Car Display Unit embedded MIPI DSI encoders. |
| 53 | 53 | |
| 54 | +config DRM_RCAR_MIPI_DSI | |
| 55 | + def_tristate DRM_RCAR_DU | |
| 56 | + depends on DRM_RCAR_USE_MIPI_DSI | |
| 57 | + select DRM_MIPI_DSI | |
| 58 | + | |
| 54 | 59 | config DRM_RCAR_VSP |
| 55 | 60 | bool "R-Car DU VSP Compositor Support" if ARM |
| 56 | 61 | default y if ARM64 |
| @@ -752,7 +752,7 @@ static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi) · 751 unmodified lines | ||
| 752 | 752 | static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi, |
| 753 | 753 | int mux) |
| 754 | 754 | { |
| 755 | − if (dsi->cdata->lcdsel_grf_reg < 0) | |
| 755 | + if (dsi->cdata->lcdsel_grf_reg) | |
| 756 | 756 | regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg, |
| 757 | 757 | mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big); |
| 758 | 758 | } |
| @@ -1051,23 +1051,31 @@ static int dw_mipi_dsi_rockchip_host_attach(void *priv_data, · 292 unmodified lines | ||
| 1051 | 1051 | if (ret) { |
| 1052 | 1052 | DRM_DEV_ERROR(dsi->dev, "Failed to register component: %d\n", |
| 1053 | 1053 | ret); |
| 1054 | − return ret; | |
| 1054 | + goto out; | |
| 1055 | 1055 | } |
| 1056 | 1056 | |
| 1057 | 1057 | second = dw_mipi_dsi_rockchip_find_second(dsi); |
| 1058 | − if (IS_ERR(second)) | |
| 1059 | − return PTR_ERR(second); | |
| 1058 | + if (IS_ERR(second)) { | |
| 1059 | + ret = PTR_ERR(second); | |
| 1060 | + goto out; | |
| 1061 | + } | |
| 1060 | 1062 | if (second) { |
| 1061 | 1063 | ret = component_add(second, &dw_mipi_dsi_rockchip_ops); |
| 1062 | 1064 | if (ret) { |
| 1063 | 1065 | DRM_DEV_ERROR(second, |
| 1064 | 1066 | "Failed to register component: %d\n", |
| 1065 | 1067 | ret); |
| 1066 | − return ret; | |
| 1068 | + goto out; | |
| 1067 | 1069 | } |
| 1068 | 1070 | } |
| 1069 | 1071 | |
| 1070 | 1072 | return 0; |
| 1073 | + | |
| 1074 | +out: | |
| 1075 | + mutex_lock(&dsi->usage_mutex); | |
| 1076 | + dsi->usage_mode = DW_DSI_USAGE_IDLE; | |
| 1077 | + mutex_unlock(&dsi->usage_mutex); | |
| 1078 | + return ret; | |
| 1071 | 1079 | } |
| 1072 | 1080 | |
| 1073 | 1081 | static int dw_mipi_dsi_rockchip_host_detach(void *priv_data, |
| @@ -1635,7 +1643,6 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = { · 561 unmodified lines | ||
| 1635 | 1643 | static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = { |
| 1636 | 1644 | { |
| 1637 | 1645 | .reg = 0xfe060000, |
| 1638 | − .lcdsel_grf_reg = -1, | |
| 1639 | 1646 | .lanecfg1_grf_reg = RK3568_GRF_VO_CON2, |
| 1640 | 1647 | .lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI0_SKEWCALHS | |
| 1641 | 1648 | RK3568_DSI0_FORCETXSTOPMODE | |
| @@ -1645,7 +1652,6 @@ static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = { · 3 unmodified lines | ||
| 1645 | 1652 | }, |
| 1646 | 1653 | { |
| 1647 | 1654 | .reg = 0xfe070000, |
| 1648 | − .lcdsel_grf_reg = -1, | |
| 1649 | 1655 | .lanecfg1_grf_reg = RK3568_GRF_VO_CON3, |
| 1650 | 1656 | .lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI1_SKEWCALHS | |
| 1651 | 1657 | RK3568_DSI1_FORCETXSTOPMODE | |
| @@ -1681,5 +1687,11 @@ struct platform_driver dw_mipi_dsi_rockchip_driver = { · 29 unmodified lines | ||
| 1681 | 1687 | .of_match_table = dw_mipi_dsi_rockchip_dt_ids, |
| 1682 | 1688 | .pm = &dw_mipi_dsi_rockchip_pm_ops, |
| 1683 | 1689 | .name = "dw-mipi-dsi-rockchip", |
| 1690 | + /* | |
| 1691 | + * For dual-DSI display, one DSI pokes at the other DSI's | |
| 1692 | + * drvdata in dw_mipi_dsi_rockchip_find_second(). This is not | |
| 1693 | + * safe for asynchronous probe. | |
| 1694 | + */ | |
| 1695 | + .probe_type = PROBE_FORCE_SYNCHRONOUS, | |
| 1684 | 1696 | }, |
| 1685 | 1697 | }; |
| @@ -565,7 +565,8 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master, · 564 unmodified lines | ||
| 565 | 565 | |
| 566 | 566 | ret = rockchip_hdmi_parse_dt(hdmi); |
| 567 | 567 | if (ret) { |
| 568 | − DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n"); | |
| 568 | + if (ret != -EPROBE_DEFER) | |
| 569 | + DRM_DEV_ERROR(hdmi->dev, "Unable to parse OF data\n"); | |
| 569 | 570 | return ret; |
| 570 | 571 | } |
| 571 | 572 | |
| @@ -364,9 +364,12 @@ rockchip_gem_create_with_handle(struct drm_file *file_priv, · 363 unmodified lines | ||
| 364 | 364 | { |
| 365 | 365 | struct rockchip_gem_object *rk_obj; |
| 366 | 366 | struct drm_gem_object *obj; |
| 367 | + bool is_framebuffer; | |
| 367 | 368 | int ret; |
| 368 | 369 | |
| 369 | − rk_obj = rockchip_gem_create_object(drm, size, false); | |
| 370 | + is_framebuffer = drm->fb_helper && file_priv == drm->fb_helper->client.file; | |
| 371 | + | |
| 372 | + rk_obj = rockchip_gem_create_object(drm, size, is_framebuffer); | |
| 370 | 373 | if (IS_ERR(rk_obj)) |
| 371 | 374 | return ERR_CAST(rk_obj); |
| 372 | 375 | |
| @@ -877,10 +877,14 @@ static void vop2_crtc_atomic_disable(struct drm_crtc *crtc, · 876 unmodified lines | ||
| 877 | 877 | { |
| 878 | 878 | struct vop2_video_port *vp = to_vop2_video_port(crtc); |
| 879 | 879 | struct vop2 *vop2 = vp->vop2; |
| 880 | + struct drm_crtc_state *old_crtc_state; | |
| 880 | 881 | int ret; |
| 881 | 882 | |
| 882 | 883 | vop2_lock(vop2); |
| 883 | 884 | |
| 885 | + old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc); | |
| 886 | + drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); | |
| 887 | + | |
| 884 | 888 | drm_crtc_vblank_off(crtc); |
| 885 | 889 | |
| 886 | 890 | /* |
| @@ -996,13 +1000,15 @@ static int vop2_plane_atomic_check(struct drm_plane *plane, · 109 unmodified lines | ||
| 996 | 1000 | static void vop2_plane_atomic_disable(struct drm_plane *plane, |
| 997 | 1001 | struct drm_atomic_state *state) |
| 998 | 1002 | { |
| 999 | − struct drm_plane_state *old_pstate = drm_atomic_get_old_plane_state(state, plane); | |
| 1003 | + struct drm_plane_state *old_pstate = NULL; | |
| 1000 | 1004 | struct vop2_win *win = to_vop2_win(plane); |
| 1001 | 1005 | struct vop2 *vop2 = win->vop2; |
| 1002 | 1006 | |
| 1003 | 1007 | drm_dbg(vop2->drm, "%s disable\n", win->data->name); |
| 1004 | 1008 | |
| 1005 | − if (!old_pstate->crtc) | |
| 1009 | + if (state) | |
| 1010 | + old_pstate = drm_atomic_get_old_plane_state(state, plane); | |
| 1011 | + if (old_pstate && !old_pstate->crtc) | |
| 1006 | 1012 | return; |
| 1007 | 1013 | |
| 1008 | 1014 | vop2_win_disable(win); |
| @@ -1093,6 +1093,10 @@ static bool host1x_drm_wants_iommu(struct host1x_device *dev) · 1092 unmodified lines | ||
| 1093 | 1093 | struct host1x *host1x = dev_get_drvdata(dev->dev.parent); |
| 1094 | 1094 | struct iommu_domain *domain; |
| 1095 | 1095 | |
| 1096 | + /* Our IOMMU usage policy doesn't currently play well with GART */ | |
| 1097 | + if (of_machine_is_compatible("nvidia,tegra20")) | |
| 1098 | + return false; | |
| 1099 | + | |
| 1096 | 1100 | /* |
| 1097 | 1101 | * If the Tegra DRM clients are backed by an IOMMU, push buffers are |
| 1098 | 1102 | * likely to be allocated beyond the 32-bit boundary if sufficient |
| @@ -476,7 +476,12 @@ static int __init vc4_drm_register(void) · 475 unmodified lines | ||
| 476 | 476 | if (ret) |
| 477 | 477 | return ret; |
| 478 | 478 | |
| 479 | − return platform_driver_register(&vc4_platform_driver); | |
| 479 | + ret = platform_driver_register(&vc4_platform_driver); | |
| 480 | + if (ret) | |
| 481 | + platform_unregister_drivers(component_drivers, | |
| 482 | + ARRAY_SIZE(component_drivers)); | |
| 483 | + | |
| 484 | + return ret; | |
| 480 | 485 | } |
| 481 | 486 | |
| 482 | 487 | static void __exit vc4_drm_unregister(void) |
| @@ -349,27 +349,40 @@ static int vc4_hdmi_reset_link(struct drm_connector *connector, · 348 unmodified lines | ||
| 349 | 349 | if (!crtc_state->active) |
| 350 | 350 | return 0; |
| 351 | 351 | |
| 352 | − if (!vc4_hdmi_supports_scrambling(encoder)) | |
| 352 | + mutex_lock(&vc4_hdmi->mutex); | |
| 353 | + | |
| 354 | + if (!vc4_hdmi_supports_scrambling(encoder)) { | |
| 355 | + mutex_unlock(&vc4_hdmi->mutex); | |
| 353 | 356 | return 0; |
| 357 | + } | |
| 354 | 358 | |
| 355 | 359 | scrambling_needed = vc4_hdmi_mode_needs_scrambling(&vc4_hdmi->saved_adjusted_mode, |
| 356 | 360 | vc4_hdmi->output_bpc, |
| 357 | 361 | vc4_hdmi->output_format); |
| 358 | − if (!scrambling_needed) | |
| 362 | + if (!scrambling_needed) { | |
| 363 | + mutex_unlock(&vc4_hdmi->mutex); | |
| 359 | 364 | return 0; |
| 365 | + } | |
| 360 | 366 | |
| 361 | 367 | if (conn_state->commit && |
| 362 | − !try_wait_for_completion(&conn_state->commit->hw_done)) | |
| 368 | + !try_wait_for_completion(&conn_state->commit->hw_done)) { | |
| 369 | + mutex_unlock(&vc4_hdmi->mutex); | |
| 363 | 370 | return 0; |
| 371 | + } | |
| 364 | 372 | |
| 365 | 373 | ret = drm_scdc_readb(connector->ddc, SCDC_TMDS_CONFIG, &config); |
| 366 | 374 | if (ret < 0) { |
| 367 | 375 | drm_err(drm, "Failed to read TMDS config: %d\n", ret); |
| 376 | + mutex_unlock(&vc4_hdmi->mutex); | |
| 368 | 377 | return 0; |
| 369 | 378 | } |
| 370 | 379 | |
| 371 | − if (!!(config & SCDC_SCRAMBLING_ENABLE) == scrambling_needed) | |
| 380 | + if (!!(config & SCDC_SCRAMBLING_ENABLE) == scrambling_needed) { | |
| 381 | + mutex_unlock(&vc4_hdmi->mutex); | |
| 372 | 382 | return 0; |
| 383 | + } | |
| 384 | + | |
| 385 | + mutex_unlock(&vc4_hdmi->mutex); | |
| 373 | 386 | |
| 374 | 387 | /* |
| 375 | 388 | * HDMI 2.0 says that one should not send scrambled data |
| @@ -397,9 +410,8 @@ static void vc4_hdmi_handle_hotplug(struct vc4_hdmi *vc4_hdmi, · 21 unmodified lines | ||
| 397 | 410 | * .adap_enable, which leads to that funtion being called with |
| 398 | 411 | * our mutex held. |
| 399 | 412 | * |
| 400 | − * A similar situation occurs with | |
| 401 | − * drm_atomic_helper_connector_hdmi_reset_link() that will call | |
| 402 | − * into our KMS hooks if the scrambling was enabled. | |
| 413 | + * A similar situation occurs with vc4_hdmi_reset_link() that | |
| 414 | + * will call into our KMS hooks if the scrambling was enabled. | |
| 403 | 415 | * |
| 404 | 416 | * Concurrency isn't an issue at the moment since we don't share |
| 405 | 417 | * any state with any of the other frameworks so we can ignore |
| @@ -3160,9 +3172,16 @@ static int vc4_hdmi_init_resources(struct drm_device *drm, · 2754 unmodified lines | ||
| 3160 | 3172 | DRM_ERROR("Failed to get HDMI state machine clock\n"); |
| 3161 | 3173 | return PTR_ERR(vc4_hdmi->hsm_clock); |
| 3162 | 3174 | } |
| 3175 | + | |
| 3163 | 3176 | vc4_hdmi->audio_clock = vc4_hdmi->hsm_clock; |
| 3164 | 3177 | vc4_hdmi->cec_clock = vc4_hdmi->hsm_clock; |
| 3165 | 3178 | |
| 3179 | + vc4_hdmi->hsm_rpm_clock = devm_clk_get(dev, "hdmi"); | |
| 3180 | + if (IS_ERR(vc4_hdmi->hsm_rpm_clock)) { | |
| 3181 | + DRM_ERROR("Failed to get HDMI state machine clock\n"); | |
| 3182 | + return PTR_ERR(vc4_hdmi->hsm_rpm_clock); | |
| 3183 | + } | |
| 3184 | + | |
| 3166 | 3185 | return 0; |
| 3167 | 3186 | } |
| 3168 | 3187 | |
| @@ -3245,6 +3264,12 @@ static int vc5_hdmi_init_resources(struct drm_device *drm, · 76 unmodified lines | ||
| 3245 | 3264 | return PTR_ERR(vc4_hdmi->hsm_clock); |
| 3246 | 3265 | } |
| 3247 | 3266 | |
| 3267 | + vc4_hdmi->hsm_rpm_clock = devm_clk_get(dev, "hdmi"); | |
| 3268 | + if (IS_ERR(vc4_hdmi->hsm_rpm_clock)) { | |
| 3269 | + DRM_ERROR("Failed to get HDMI state machine clock\n"); | |
| 3270 | + return PTR_ERR(vc4_hdmi->hsm_rpm_clock); | |
| 3271 | + } | |
| 3272 | + | |
| 3248 | 3273 | vc4_hdmi->pixel_bvb_clock = devm_clk_get(dev, "bvb"); |
| 3249 | 3274 | if (IS_ERR(vc4_hdmi->pixel_bvb_clock)) { |
| 3250 | 3275 | DRM_ERROR("Failed to get pixel bvb clock\n"); |
| @@ -3308,7 +3333,7 @@ static int vc4_hdmi_runtime_suspend(struct device *dev) · 57 unmodified lines | ||
| 3308 | 3333 | { |
| 3309 | 3334 | struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); |
| 3310 | 3335 | |
| 3311 | − clk_disable_unprepare(vc4_hdmi->hsm_clock); | |
| 3336 | + clk_disable_unprepare(vc4_hdmi->hsm_rpm_clock); | |
| 3312 | 3337 | |
| 3313 | 3338 | return 0; |
| 3314 | 3339 | } |
| @@ -3326,11 +3351,11 @@ static int vc4_hdmi_runtime_resume(struct device *dev) · 11 unmodified lines | ||
| 3326 | 3351 | * its frequency while the power domain is active so that it |
| 3327 | 3352 | * keeps its rate. |
| 3328 | 3353 | */ |
| 3329 | − ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ); | |
| 3354 | + ret = clk_set_min_rate(vc4_hdmi->hsm_rpm_clock, HSM_MIN_CLOCK_FREQ); | |
| 3330 | 3355 | if (ret) |
| 3331 | 3356 | return ret; |
| 3332 | 3357 | |
| 3333 | − ret = clk_prepare_enable(vc4_hdmi->hsm_clock); | |
| 3358 | + ret = clk_prepare_enable(vc4_hdmi->hsm_rpm_clock); | |
| 3334 | 3359 | if (ret) |
| 3335 | 3360 | return ret; |
| 3336 | 3361 | |
| @@ -3343,7 +3368,7 @@ static int vc4_hdmi_runtime_resume(struct device *dev) · 6 unmodified lines | ||
| 3343 | 3368 | * case, it will lead to a silent CPU stall. Let's make sure we |
| 3344 | 3369 | * prevent such a case. |
| 3345 | 3370 | */ |
| 3346 | − rate = clk_get_rate(vc4_hdmi->hsm_clock); | |
| 3371 | + rate = clk_get_rate(vc4_hdmi->hsm_rpm_clock); | |
| 3347 | 3372 | if (!rate) { |
| 3348 | 3373 | ret = -EINVAL; |
| 3349 | 3374 | goto err_disable_clk; |
| @@ -172,6 +172,7 @@ struct vc4_hdmi { · 171 unmodified lines | ||
| 172 | 172 | struct clk *cec_clock; |
| 173 | 173 | struct clk *pixel_clock; |
| 174 | 174 | struct clk *hsm_clock; |
| 175 | + struct clk *hsm_rpm_clock; | |
| 175 | 176 | struct clk *audio_clock; |
| 176 | 177 | struct clk *pixel_bvb_clock; |
| 177 | 178 | |
| @@ -197,8 +197,8 @@ vc4_hvs_get_new_global_state(struct drm_atomic_state *state) · 196 unmodified lines | ||
| 197 | 197 | struct drm_private_state *priv_state; |
| 198 | 198 | |
| 199 | 199 | priv_state = drm_atomic_get_new_private_obj_state(state, &vc4->hvs_channels); |
| 200 | − if (IS_ERR(priv_state)) | |
| 201 | − return ERR_CAST(priv_state); | |
| 200 | + if (!priv_state) | |
| 201 | + return ERR_PTR(-EINVAL); | |
| 202 | 202 | |
| 203 | 203 | return to_vc4_hvs_state(priv_state); |
| 204 | 204 | } |
| @@ -210,8 +210,8 @@ vc4_hvs_get_old_global_state(struct drm_atomic_state *state) · 5 unmodified lines | ||
| 210 | 210 | struct drm_private_state *priv_state; |
| 211 | 211 | |
| 212 | 212 | priv_state = drm_atomic_get_old_private_obj_state(state, &vc4->hvs_channels); |
| 213 | − if (IS_ERR(priv_state)) | |
| 214 | − return ERR_CAST(priv_state); | |
| 213 | + if (!priv_state) | |
| 214 | + return ERR_PTR(-EINVAL); | |
| 215 | 215 | |
| 216 | 216 | return to_vc4_hvs_state(priv_state); |
| 217 | 217 | } |
| @@ -292,6 +292,10 @@ static void host1x_setup_virtualization_tables(struct host1x *host) · 291 unmodified lines | ||
| 292 | 292 | |
| 293 | 293 | static bool host1x_wants_iommu(struct host1x *host1x) |
| 294 | 294 | { |
| 295 | + /* Our IOMMU usage policy doesn't currently play well with GART */ | |
| 296 | + if (of_machine_is_compatible("nvidia,tegra20")) | |
| 297 | + return false; | |
| 298 | + | |
| 295 | 299 | /* |
| 296 | 300 | * If we support addressing a maximum of 32 bits of physical memory |
| 297 | 301 | * and if the host1x firewall is enabled, there's no need to enable |
| @@ -219,14 +219,13 @@ static void asus_report_tool_width(struct asus_drvdata *drvdat) · 218 unmodified lines | ||
| 219 | 219 | { |
| 220 | 220 | struct input_mt *mt = drvdat->input->mt; |
| 221 | 221 | struct input_mt_slot *oldest; |
| 222 | − int oldid, count, i; | |
| 222 | + int oldid, i; | |
| 223 | 223 | |
| 224 | 224 | if (drvdat->tp->contact_size < 5) |
| 225 | 225 | return; |
| 226 | 226 | |
| 227 | 227 | oldest = NULL; |
| 228 | 228 | oldid = mt->trkid; |
| 229 | − count = 0; | |
| 230 | 229 | |
| 231 | 230 | for (i = 0; i < mt->num_slots; ++i) { |
| 232 | 231 | struct input_mt_slot *ps = &mt->slots[i]; |
| @@ -238,7 +237,6 @@ static void asus_report_tool_width(struct asus_drvdata *drvdat) · 5 unmodified lines | ||
| 238 | 237 | oldest = ps; |
| 239 | 238 | oldid = id; |
| 240 | 239 | } |
| 241 | − count++; | |
| 242 | 240 | } |
| 243 | 241 | |
| 244 | 242 | if (oldest) { |
| @@ -499,7 +499,7 @@ static int mousevsc_probe(struct hv_device *device, · 498 unmodified lines | ||
| 499 | 499 | |
| 500 | 500 | ret = hid_add_device(hid_dev); |
| 501 | 501 | if (ret) |
| 502 | − goto probe_err1; | |
| 502 | + goto probe_err2; | |
| 503 | 503 | |
| 504 | 504 | |
| 505 | 505 | ret = hid_parse(hid_dev); |
| @@ -2520,11 +2520,12 @@ static void wacom_wac_pen_report(struct hid_device *hdev, · 2519 unmodified lines | ||
| 2520 | 2520 | |
| 2521 | 2521 | if (!delay_pen_events(wacom_wac) && wacom_wac->tool[0]) { |
| 2522 | 2522 | int id = wacom_wac->id[0]; |
| 2523 | − if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3 && | |
| 2524 | − wacom_wac->hid_data.barrelswitch & wacom_wac->hid_data.barrelswitch2) { | |
| 2525 | − wacom_wac->hid_data.barrelswitch = 0; | |
| 2526 | − wacom_wac->hid_data.barrelswitch2 = 0; | |
| 2527 | − wacom_wac->hid_data.barrelswitch3 = 1; | |
| 2523 | + if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3) { | |
| 2524 | + int sw_state = wacom_wac->hid_data.barrelswitch | | |
| 2525 | + (wacom_wac->hid_data.barrelswitch2 << 1); | |
| 2526 | + wacom_wac->hid_data.barrelswitch = sw_state == 1; | |
| 2527 | + wacom_wac->hid_data.barrelswitch2 = sw_state == 2; | |
| 2528 | + wacom_wac->hid_data.barrelswitch3 = sw_state == 3; | |
| 2528 | 2529 | } |
| 2529 | 2530 | input_report_key(input, BTN_STYLUS, wacom_wac->hid_data.barrelswitch); |
| 2530 | 2531 | input_report_key(input, BTN_STYLUS2, wacom_wac->hid_data.barrelswitch2); |
| @@ -533,13 +533,17 @@ static void vmbus_add_channel_work(struct work_struct *work) · 532 unmodified lines | ||
| 533 | 533 | * Add the new device to the bus. This will kick off device-driver |
| 534 | 534 | * binding which eventually invokes the device driver's AddDevice() |
| 535 | 535 | * method. |
| 536 | + * | |
| 537 | + * If vmbus_device_register() fails, the 'device_obj' is freed in | |
| 538 | + * vmbus_device_release() as called by device_unregister() in the | |
| 539 | + * error path of vmbus_device_register(). In the outside error | |
| 540 | + * path, there's no need to free it. | |
| 536 | 541 | */ |
| 537 | 542 | ret = vmbus_device_register(newchannel->device_obj); |
| 538 | 543 | |
| 539 | 544 | if (ret != 0) { |
| 540 | 545 | pr_err("unable to add child device object (relid %d)\n", |
| 541 | 546 | newchannel->offermsg.child_relid); |
| 542 | − kfree(newchannel->device_obj); | |
| 543 | 547 | goto err_deq_chan; |
| 544 | 548 | } |
| 545 | 549 | |
| @@ -905,7 +905,7 @@ static unsigned long handle_pg_range(unsigned long pg_start, · 904 unmodified lines | ||
| 905 | 905 | * We have some residual hot add range |
| 906 | 906 | * that needs to be hot added; hot add |
| 907 | 907 | * it now. Hot add a multiple of |
| 908 | − * of HA_CHUNK that fully covers the pages | |
| 908 | + * HA_CHUNK that fully covers the pages | |
| 909 | 909 | * we have. |
| 910 | 910 | */ |
| 911 | 911 | size = (has->end_pfn - has->ha_end_pfn); |
| @@ -2082,6 +2082,7 @@ int vmbus_device_register(struct hv_device *child_device_obj) · 2081 unmodified lines | ||
| 2082 | 2082 | ret = device_register(&child_device_obj->device); |
| 2083 | 2083 | if (ret) { |
| 2084 | 2084 | pr_err("Unable to register child device\n"); |
| 2085 | + put_device(&child_device_obj->device); | |
| 2085 | 2086 | return ret; |
| 2086 | 2087 | } |
| 2087 | 2088 | |
| @@ -938,6 +938,8 @@ static int asus_ec_probe(struct platform_device *pdev) · 937 unmodified lines | ||
| 938 | 938 | ec_data->nr_sensors = hweight_long(ec_data->board_info->sensors); |
| 939 | 939 | ec_data->sensors = devm_kcalloc(dev, ec_data->nr_sensors, |
| 940 | 940 | sizeof(struct ec_sensor), GFP_KERNEL); |
| 941 | + if (!ec_data->sensors) | |
| 942 | + return -ENOMEM; | |
| 941 | 943 | |
| 942 | 944 | status = setup_lock_data(dev); |
| 943 | 945 | if (status) { |
| @@ -242,10 +242,13 @@ static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) · 241 unmodified lines | ||
| 242 | 242 | */ |
| 243 | 243 | if (host_bridge && host_bridge->vendor == PCI_VENDOR_ID_INTEL) { |
| 244 | 244 | for (i = 0; i < ARRAY_SIZE(tjmax_pci_table); i++) { |
| 245 | − if (host_bridge->device == tjmax_pci_table[i].device) | |
| 245 | + if (host_bridge->device == tjmax_pci_table[i].device) { | |
| 246 | + pci_dev_put(host_bridge); | |
| 246 | 247 | return tjmax_pci_table[i].tjmax; |
| 248 | + } | |
| 247 | 249 | } |
| 248 | 250 | } |
| 251 | + pci_dev_put(host_bridge); | |
| 249 | 252 | |
| 250 | 253 | for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) { |
| 251 | 254 | if (strstr(c->x86_model_id, tjmax_table[i].id)) |
| @@ -533,6 +536,10 @@ static void coretemp_remove_core(struct platform_data *pdata, int indx) · 281 unmodified lines | ||
| 533 | 536 | { |
| 534 | 537 | struct temp_data *tdata = pdata->core_data[indx]; |
| 535 | 538 | |
| 539 | + /* if we errored on add then this is already gone */ | |
| 540 | + if (!tdata) | |
| 541 | + return; | |
| 542 | + | |
| 536 | 543 | /* Remove the sysfs attributes */ |
| 537 | 544 | sysfs_remove_group(&pdata->hwmon_dev->kobj, &tdata->attr_group); |
| 538 | 545 | |
| @@ -117,7 +117,7 @@ static int i5500_temp_probe(struct pci_dev *pdev, · 116 unmodified lines | ||
| 117 | 117 | u32 tstimer; |
| 118 | 118 | s8 tsfsc; |
| 119 | 119 | |
| 120 | − err = pci_enable_device(pdev); | |
| 120 | + err = pcim_enable_device(pdev); | |
| 121 | 121 | if (err) { |
| 122 | 122 | dev_err(&pdev->dev, "Failed to enable device\n"); |
| 123 | 123 | return err; |
| @@ -502,6 +502,7 @@ static void ibmpex_register_bmc(int iface, struct device *dev) · 501 unmodified lines | ||
| 502 | 502 | return; |
| 503 | 503 | |
| 504 | 504 | out_register: |
| 505 | + list_del(&data->list); | |
| 505 | 506 | hwmon_device_unregister(data->hwmon_dev); |
| 506 | 507 | out_user: |
| 507 | 508 | ipmi_destroy_user(data->user); |
| @@ -228,7 +228,7 @@ static int ina3221_read_value(struct ina3221_data *ina, unsigned int reg, · 227 unmodified lines | ||
| 228 | 228 | * Shunt Voltage Sum register has 14-bit value with 1-bit shift |
| 229 | 229 | * Other Shunt Voltage registers have 12 bits with 3-bit shift |
| 230 | 230 | */ |
| 231 | − if (reg == INA3221_SHUNT_SUM) | |
| 231 | + if (reg == INA3221_SHUNT_SUM || reg == INA3221_CRIT_SUM) | |
| 232 | 232 | *val = sign_extend32(regval >> 1, 14); |
| 233 | 233 | else |
| 234 | 234 | *val = sign_extend32(regval >> 3, 12); |
| @@ -465,7 +465,7 @@ static int ina3221_write_curr(struct device *dev, u32 attr, · 230 unmodified lines | ||
| 465 | 465 | * SHUNT_SUM: (1 / 40uV) << 1 = 1 / 20uV |
| 466 | 466 | * SHUNT[1-3]: (1 / 40uV) << 3 = 1 / 5uV |
| 467 | 467 | */ |
| 468 | − if (reg == INA3221_SHUNT_SUM) | |
| 468 | + if (reg == INA3221_SHUNT_SUM || reg == INA3221_CRIT_SUM) | |
| 469 | 469 | regval = DIV_ROUND_CLOSEST(voltage_uv, 20) & 0xfffe; |
| 470 | 470 | else |
| 471 | 471 | regval = DIV_ROUND_CLOSEST(voltage_uv, 5) & 0xfff8; |
| @@ -396,7 +396,7 @@ static int ltc2947_read_temp(struct device *dev, const u32 attr, long *val, · 395 unmodified lines | ||
| 396 | 396 | return ret; |
| 397 | 397 | |
| 398 | 398 | /* in milidegrees celcius, temp is given by: */ |
| 399 | − *val = (__val * 204) + 550; | |
| 399 | + *val = (__val * 204) + 5500; | |
| 400 | 400 | |
| 401 | 401 | return 0; |
| 402 | 402 | } |
| @@ -467,7 +467,6 @@ extern const struct regulator_ops pmbus_regulator_ops; · 466 unmodified lines | ||
| 467 | 467 | #define PMBUS_REGULATOR_STEP(_name, _id, _voltages, _step) \ |
| 468 | 468 | [_id] = { \ |
| 469 | 469 | .name = (_name # _id), \ |
| 470 | − .supply_name = "vin", \ | |
| 471 | 470 | .id = (_id), \ |
| 472 | 471 | .of_match = of_match_ptr(_name # _id), \ |
| 473 | 472 | .regulators_node = of_match_ptr("regulators"), \ |
| @@ -20,6 +20,11 @@ struct scmi_sensors { · 19 unmodified lines | ||
| 20 | 20 | const struct scmi_sensor_info **info[hwmon_max]; |
| 21 | 21 | }; |
| 22 | 22 | |
| 23 | +struct scmi_thermal_sensor { | |
| 24 | + const struct scmi_protocol_handle *ph; | |
| 25 | + const struct scmi_sensor_info *info; | |
| 26 | +}; | |
| 27 | + | |
| 23 | 28 | static inline u64 __pow10(u8 x) |
| 24 | 29 | { |
| 25 | 30 | u64 r = 1; |
| @@ -64,16 +69,14 @@ static int scmi_hwmon_scale(const struct scmi_sensor_info *sensor, u64 *value) · 38 unmodified lines | ||
| 64 | 69 | return 0; |
| 65 | 70 | } |
| 66 | 71 | |
| 67 | −static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type, | |
| 68 | − u32 attr, int channel, long *val) | |
| 72 | +static int scmi_hwmon_read_scaled_value(const struct scmi_protocol_handle *ph, | |
| 73 | + const struct scmi_sensor_info *sensor, | |
| 74 | + long *val) | |
| 69 | 75 | { |
| 70 | 76 | int ret; |
| 71 | 77 | u64 value; |
| 72 | − const struct scmi_sensor_info *sensor; | |
| 73 | − struct scmi_sensors *scmi_sensors = dev_get_drvdata(dev); | |
| 74 | 78 | |
| 75 | − sensor = *(scmi_sensors->info[type] + channel); | |
| 76 | − ret = sensor_ops->reading_get(scmi_sensors->ph, sensor->id, &value); | |
| 79 | + ret = sensor_ops->reading_get(ph, sensor->id, &value); | |
| 77 | 80 | if (ret) |
| 78 | 81 | return ret; |
| 79 | 82 | |
| @@ -84,6 +87,17 @@ static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type, · 4 unmodified lines | ||
| 84 | 87 | return ret; |
| 85 | 88 | } |
| 86 | 89 | |
| 90 | +static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type, | |
| 91 | + u32 attr, int channel, long *val) | |
| 92 | +{ | |
| 93 | + const struct scmi_sensor_info *sensor; | |
| 94 | + struct scmi_sensors *scmi_sensors = dev_get_drvdata(dev); | |
| 95 | + | |
| 96 | + sensor = *(scmi_sensors->info[type] + channel); | |
| 97 | + | |
| 98 | + return scmi_hwmon_read_scaled_value(scmi_sensors->ph, sensor, val); | |
| 99 | +} | |
| 100 | + | |
| 87 | 101 | static int |
| 88 | 102 | scmi_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type, |
| 89 | 103 | u32 attr, int channel, const char **str) |
| @@ -122,6 +136,25 @@ static struct hwmon_chip_info scmi_chip_info = { · 32 unmodified lines | ||
| 122 | 136 | .info = NULL, |
| 123 | 137 | }; |
| 124 | 138 | |
| 139 | +static int scmi_hwmon_thermal_get_temp(struct thermal_zone_device *tz, | |
| 140 | + int *temp) | |
| 141 | +{ | |
| 142 | + int ret; | |
| 143 | + long value; | |
| 144 | + struct scmi_thermal_sensor *th_sensor = tz->devdata; | |
| 145 | + | |
| 146 | + ret = scmi_hwmon_read_scaled_value(th_sensor->ph, th_sensor->info, | |
| 147 | + &value); | |
| 148 | + if (!ret) | |
| 149 | + *temp = value; | |
| 150 | + | |
| 151 | + return ret; | |
| 152 | +} | |
| 153 | + | |
| 154 | +static const struct thermal_zone_device_ops scmi_hwmon_thermal_ops = { | |
| 155 | + .get_temp = scmi_hwmon_thermal_get_temp, | |
| 156 | +}; | |
| 157 | + | |
| 125 | 158 | static int scmi_hwmon_add_chan_info(struct hwmon_channel_info *scmi_hwmon_chan, |
| 126 | 159 | struct device *dev, int num, |
| 127 | 160 | enum hwmon_sensor_types type, u32 config) |
| @@ -149,7 +182,6 @@ static enum hwmon_sensor_types scmi_types[] = { · 21 unmodified lines | ||
| 149 | 182 | }; |
| 150 | 183 | |
| 151 | 184 | static u32 hwmon_attributes[hwmon_max] = { |
| 152 | − [hwmon_chip] = HWMON_C_REGISTER_TZ, | |
| 153 | 185 | [hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL, |
| 154 | 186 | [hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL, |
| 155 | 187 | [hwmon_curr] = HWMON_C_INPUT | HWMON_C_LABEL, |
| @@ -157,6 +189,43 @@ static u32 hwmon_attributes[hwmon_max] = { · 1 unmodified line | ||
| 157 | 189 | [hwmon_energy] = HWMON_E_INPUT | HWMON_E_LABEL, |
| 158 | 190 | }; |
| 159 | 191 | |
| 192 | +static int scmi_thermal_sensor_register(struct device *dev, | |
| 193 | + const struct scmi_protocol_handle *ph, | |
| 194 | + const struct scmi_sensor_info *sensor) | |
| 195 | +{ | |
| 196 | + struct scmi_thermal_sensor *th_sensor; | |
| 197 | + struct thermal_zone_device *tzd; | |
| 198 | + | |
| 199 | + th_sensor = devm_kzalloc(dev, sizeof(*th_sensor), GFP_KERNEL); | |
| 200 | + if (!th_sensor) | |
| 201 | + return -ENOMEM; | |
| 202 | + | |
| 203 | + th_sensor->ph = ph; | |
| 204 | + th_sensor->info = sensor; | |
| 205 | + | |
| 206 | + /* | |
| 207 | + * Try to register a temperature sensor with the Thermal Framework: | |
| 208 | + * skip sensors not defined as part of any thermal zone (-ENODEV) but | |
| 209 | + * report any other errors related to misconfigured zones/sensors. | |
| 210 | + */ | |
| 211 | + tzd = devm_thermal_of_zone_register(dev, th_sensor->info->id, th_sensor, | |
| 212 | + &scmi_hwmon_thermal_ops); | |
| 213 | + if (IS_ERR(tzd)) { | |
| 214 | + devm_kfree(dev, th_sensor); | |
| 215 | + | |
| 216 | + if (PTR_ERR(tzd) != -ENODEV) | |
| 217 | + return PTR_ERR(tzd); | |
| 218 | + | |
| 219 | + dev_dbg(dev, "Sensor '%s' not attached to any thermal zone.\n", | |
| 220 | + sensor->name); | |
| 221 | + } else { | |
| 222 | + dev_dbg(dev, "Sensor '%s' attached to thermal zone ID:%d\n", | |
| 223 | + sensor->name, tzd->id); | |
| 224 | + } | |
| 225 | + | |
| 226 | + return 0; | |
| 227 | +} | |
| 228 | + | |
| 160 | 229 | static int scmi_hwmon_probe(struct scmi_device *sdev) |
| 161 | 230 | { |
| 162 | 231 | int i, idx; |
| @@ -164,7 +233,7 @@ static int scmi_hwmon_probe(struct scmi_device *sdev) · 1 unmodified line | ||
| 164 | 233 | enum hwmon_sensor_types type; |
| 165 | 234 | struct scmi_sensors *scmi_sensors; |
| 166 | 235 | const struct scmi_sensor_info *sensor; |
| 167 | − int nr_count[hwmon_max] = {0}, nr_types = 0; | |
| 236 | + int nr_count[hwmon_max] = {0}, nr_types = 0, nr_count_temp = 0; | |
| 168 | 237 | const struct hwmon_chip_info *chip_info; |
| 169 | 238 | struct device *hwdev, *dev = &sdev->dev; |
| 170 | 239 | struct hwmon_channel_info *scmi_hwmon_chan; |
| @@ -208,10 +277,8 @@ static int scmi_hwmon_probe(struct scmi_device *sdev) · 37 unmodified lines | ||
| 208 | 277 | } |
| 209 | 278 | } |
| 210 | 279 | |
| 211 | − if (nr_count[hwmon_temp]) { | |
| 212 | − nr_count[hwmon_chip]++; | |
| 213 | − nr_types++; | |
| 214 | − } | |
| 280 | + if (nr_count[hwmon_temp]) | |
| 281 | + nr_count_temp = nr_count[hwmon_temp]; | |
| 215 | 282 | |
| 216 | 283 | scmi_hwmon_chan = devm_kcalloc(dev, nr_types, sizeof(*scmi_hwmon_chan), |
| 217 | 284 | GFP_KERNEL); |
| @@ -262,8 +329,31 @@ static int scmi_hwmon_probe(struct scmi_device *sdev) · 44 unmodified lines | ||
| 262 | 329 | hwdev = devm_hwmon_device_register_with_info(dev, "scmi_sensors", |
| 263 | 330 | scmi_sensors, chip_info, |
| 264 | 331 | NULL); |
| 332 | + if (IS_ERR(hwdev)) | |
| 333 | + return PTR_ERR(hwdev); | |
| 265 | 334 | |
| 266 | − return PTR_ERR_OR_ZERO(hwdev); | |
| 335 | + for (i = 0; i < nr_count_temp; i++) { | |
| 336 | + int ret; | |
| 337 | + | |
| 338 | + sensor = *(scmi_sensors->info[hwmon_temp] + i); | |
| 339 | + if (!sensor) | |
| 340 | + continue; | |
| 341 | + | |
| 342 | + /* | |
| 343 | + * Warn on any misconfiguration related to thermal zones but | |
| 344 | + * bail out of probing only on memory errors. | |
| 345 | + */ | |
| 346 | + ret = scmi_thermal_sensor_register(dev, ph, sensor); | |
| 347 | + if (ret) { | |
| 348 | + if (ret == -ENOMEM) | |
| 349 | + return ret; | |
| 350 | + dev_warn(dev, | |
| 351 | + "Thermal zone misconfigured for %s. err=%d\n", | |
| 352 | + sensor->name, ret); | |
| 353 | + } | |
| 354 | + } | |
| 355 | + | |
| 356 | + return 0; | |
| 267 | 357 | } |
| 268 | 358 | |
| 269 | 359 | static const struct scmi_device_id scmi_id_table[] = { |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | struct qcom_hwspinlock_of_data { |
| 23 | 23 | u32 offset; |
| 24 | 24 | u32 stride; |
| 25 | + const struct regmap_config *regmap_config; | |
| 25 | 26 | }; |
| 26 | 27 | |
| 27 | 28 | static int qcom_hwspinlock_trylock(struct hwspinlock *lock) |
| @@ -73,15 +74,42 @@ static const struct qcom_hwspinlock_of_data of_sfpb_mutex = { · 45 unmodified lines | ||
| 73 | 74 | .stride = 0x4, |
| 74 | 75 | }; |
| 75 | 76 | |
| 76 | −/* All modern platform has offset 0 and stride of 4k */ | |
| 77 | +static const struct regmap_config tcsr_msm8226_mutex_config = { | |
| 78 | + .reg_bits = 32, | |
| 79 | + .reg_stride = 4, | |
| 80 | + .val_bits = 32, | |
| 81 | + .max_register = 0x1000, | |
| 82 | + .fast_io = true, | |
| 83 | +}; | |
| 84 | + | |
| 85 | +static const struct qcom_hwspinlock_of_data of_msm8226_tcsr_mutex = { | |
| 86 | + .offset = 0, | |
| 87 | + .stride = 0x80, | |
| 88 | + .regmap_config = &tcsr_msm8226_mutex_config, | |
| 89 | +}; | |
| 90 | + | |
| 91 | +static const struct regmap_config tcsr_mutex_config = { | |
| 92 | + .reg_bits = 32, | |
| 93 | + .reg_stride = 4, | |
| 94 | + .val_bits = 32, | |
| 95 | + .max_register = 0x20000, | |
| 96 | + .fast_io = true, | |
| 97 | +}; | |
| 98 | + | |
| 77 | 99 | static const struct qcom_hwspinlock_of_data of_tcsr_mutex = { |
| 78 | 100 | .offset = 0, |
| 79 | 101 | .stride = 0x1000, |
| 102 | + .regmap_config = &tcsr_mutex_config, | |
| 80 | 103 | }; |
| 81 | 104 | |
| 82 | 105 | static const struct of_device_id qcom_hwspinlock_of_match[] = { |
| 83 | 106 | { .compatible = "qcom,sfpb-mutex", .data = &of_sfpb_mutex }, |
| 84 | 107 | { .compatible = "qcom,tcsr-mutex", .data = &of_tcsr_mutex }, |
| 108 | + { .compatible = "qcom,apq8084-tcsr-mutex", .data = &of_msm8226_tcsr_mutex }, | |
| 109 | + { .compatible = "qcom,ipq6018-tcsr-mutex", .data = &of_msm8226_tcsr_mutex }, | |
| 110 | + { .compatible = "qcom,msm8226-tcsr-mutex", .data = &of_msm8226_tcsr_mutex }, | |
| 111 | + { .compatible = "qcom,msm8974-tcsr-mutex", .data = &of_msm8226_tcsr_mutex }, | |
| 112 | + { .compatible = "qcom,msm8994-tcsr-mutex", .data = &of_msm8226_tcsr_mutex }, | |
| 85 | 113 | { } |
| 86 | 114 | }; |
| 87 | 115 | MODULE_DEVICE_TABLE(of, qcom_hwspinlock_of_match); |
| @@ -117,14 +145,6 @@ static struct regmap *qcom_hwspinlock_probe_syscon(struct platform_device *pdev, · 29 unmodified lines | ||
| 117 | 145 | return regmap; |
| 118 | 146 | } |
| 119 | 147 | |
| 120 | −static const struct regmap_config tcsr_mutex_config = { | |
| 121 | − .reg_bits = 32, | |
| 122 | − .reg_stride = 4, | |
| 123 | − .val_bits = 32, | |
| 124 | − .max_register = 0x40000, | |
| 125 | − .fast_io = true, | |
| 126 | −}; | |
| 127 | − | |
| 128 | 148 | static struct regmap *qcom_hwspinlock_probe_mmio(struct platform_device *pdev, |
| 129 | 149 | u32 *offset, u32 *stride) |
| 130 | 150 | { |
| @@ -133,6 +153,8 @@ static struct regmap *qcom_hwspinlock_probe_mmio(struct platform_device *pdev, · 2 unmodified lines | ||
| 133 | 153 | void __iomem *base; |
| 134 | 154 | |
| 135 | 155 | data = of_device_get_match_data(dev); |
| 156 | + if (!data->regmap_config) | |
| 157 | + return ERR_PTR(-EINVAL); | |
| 136 | 158 | |
| 137 | 159 | *offset = data->offset; |
| 138 | 160 | *stride = data->stride; |
| @@ -141,7 +163,7 @@ static struct regmap *qcom_hwspinlock_probe_mmio(struct platform_device *pdev, · 2 unmodified lines | ||
| 141 | 163 | if (IS_ERR(base)) |
| 142 | 164 | return ERR_CAST(base); |
| 143 | 165 | |
| 144 | − return devm_regmap_init_mmio(dev, base, &tcsr_mutex_config); | |
| 166 | + return devm_regmap_init_mmio(dev, base, data->regmap_config); | |
| 145 | 167 | } |
| 146 | 168 | |
| 147 | 169 | static int qcom_hwspinlock_probe(struct platform_device *pdev) |
| @@ -852,7 +852,8 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, · 851 unmodified lines | ||
| 852 | 852 | CDNS_I2C_POLL_US, CDNS_I2C_TIMEOUT_US); |
| 853 | 853 | if (ret) { |
| 854 | 854 | ret = -EAGAIN; |
| 855 | − i2c_recover_bus(adap); | |
| 855 | + if (id->adap.bus_recovery_info) | |
| 856 | + i2c_recover_bus(adap); | |
| 856 | 857 | goto out; |
| 857 | 858 | } |
| 858 | 859 | |
| @@ -1263,8 +1264,13 @@ static int cdns_i2c_probe(struct platform_device *pdev) · 404 unmodified lines | ||
| 1263 | 1264 | |
| 1264 | 1265 | id->rinfo.pinctrl = devm_pinctrl_get(&pdev->dev); |
| 1265 | 1266 | if (IS_ERR(id->rinfo.pinctrl)) { |
| 1267 | + int err = PTR_ERR(id->rinfo.pinctrl); | |
| 1268 | + | |
| 1266 | 1269 | dev_info(&pdev->dev, "can't get pinctrl, bus recovery not supported\n"); |
| 1267 | − return PTR_ERR(id->rinfo.pinctrl); | |
| 1270 | + if (err != -ENODEV) | |
| 1271 | + return err; | |
| 1272 | + } else { | |
| 1273 | + id->adap.bus_recovery_info = &id->rinfo; | |
| 1268 | 1274 | } |
| 1269 | 1275 | |
| 1270 | 1276 | id->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &r_mem); |
| @@ -1283,7 +1289,6 @@ static int cdns_i2c_probe(struct platform_device *pdev) · 12 unmodified lines | ||
| 1283 | 1289 | id->adap.retries = 3; /* Default retry value. */ |
| 1284 | 1290 | id->adap.algo_data = id; |
| 1285 | 1291 | id->adap.dev.parent = &pdev->dev; |
| 1286 | − id->adap.bus_recovery_info = &id->rinfo; | |
| 1287 | 1292 | init_completion(&id->xfer_done); |
| 1288 | 1293 | snprintf(id->adap.name, sizeof(id->adap.name), |
| 1289 | 1294 | "Cadence I2C at %08lx", (unsigned long)r_mem->start); |
| @@ -1243,6 +1243,7 @@ static const struct { · 1242 unmodified lines | ||
| 1243 | 1243 | */ |
| 1244 | 1244 | { "Latitude 5480", 0x29 }, |
| 1245 | 1245 | { "Vostro V131", 0x1d }, |
| 1246 | + { "Vostro 5568", 0x29 }, | |
| 1246 | 1247 | }; |
| 1247 | 1248 | |
| 1248 | 1249 | static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv) |
| @@ -1132,7 +1132,8 @@ static int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs, · 1131 unmodified lines | ||
| 1132 | 1132 | int i, result; |
| 1133 | 1133 | unsigned int temp; |
| 1134 | 1134 | int block_data = msgs->flags & I2C_M_RECV_LEN; |
| 1135 | − int use_dma = i2c_imx->dma && msgs->len >= DMA_THRESHOLD && !block_data; | |
| 1135 | + int use_dma = i2c_imx->dma && msgs->flags & I2C_M_DMA_SAFE && | |
| 1136 | + msgs->len >= DMA_THRESHOLD && !block_data; | |
| 1136 | 1137 | |
| 1137 | 1138 | dev_dbg(&i2c_imx->adapter.dev, |
| 1138 | 1139 | "<%s> write slave address: addr=0x%x\n", |
| @@ -1298,7 +1299,8 @@ static int i2c_imx_xfer_common(struct i2c_adapter *adapter, · 159 unmodified lines | ||
| 1298 | 1299 | result = i2c_imx_read(i2c_imx, &msgs[i], is_lastmsg, atomic); |
| 1299 | 1300 | } else { |
| 1300 | 1301 | if (!atomic && |
| 1301 | − i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD) | |
| 1302 | + i2c_imx->dma && msgs[i].len >= DMA_THRESHOLD && | |
| 1303 | + msgs[i].flags & I2C_M_DMA_SAFE) | |
| 1302 | 1304 | result = i2c_imx_dma_write(i2c_imx, &msgs[i]); |
| 1303 | 1305 | else |
| 1304 | 1306 | result = i2c_imx_write(i2c_imx, &msgs[i], atomic); |
| @@ -2393,8 +2393,17 @@ static struct platform_driver npcm_i2c_bus_driver = { · 2392 unmodified lines | ||
| 2393 | 2393 | |
| 2394 | 2394 | static int __init npcm_i2c_init(void) |
| 2395 | 2395 | { |
| 2396 | + int ret; | |
| 2397 | + | |
| 2396 | 2398 | npcm_i2c_debugfs_dir = debugfs_create_dir("npcm_i2c", NULL); |
| 2397 | − return platform_driver_register(&npcm_i2c_bus_driver); | |
| 2399 | + | |
| 2400 | + ret = platform_driver_register(&npcm_i2c_bus_driver); | |
| 2401 | + if (ret) { | |
| 2402 | + debugfs_remove_recursive(npcm_i2c_debugfs_dir); | |
| 2403 | + return ret; | |
| 2404 | + } | |
| 2405 | + | |
| 2406 | + return 0; | |
| 2398 | 2407 | } |
| 2399 | 2408 | module_init(npcm_i2c_init); |
| 2400 | 2409 | |
| @@ -1080,6 +1080,7 @@ static int piix4_probe(struct pci_dev *dev, const struct pci_device_id *id) · 1079 unmodified lines | ||
| 1080 | 1080 | "", &piix4_main_adapters[0]); |
| 1081 | 1081 | if (retval < 0) |
| 1082 | 1082 | return retval; |
| 1083 | + piix4_adapter_count = 1; | |
| 1083 | 1084 | } |
| 1084 | 1085 | |
| 1085 | 1086 | /* Check for auxiliary SMBus on some AMD chipsets */ |
| @@ -626,7 +626,6 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i · 625 unmodified lines | ||
| 626 | 626 | dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d addr:0x%x\n", |
| 627 | 627 | gi2c->cur->flags, gi2c->cur->addr); |
| 628 | 628 | gi2c->err = -ETIMEDOUT; |
| 629 | − goto err; | |
| 630 | 629 | } |
| 631 | 630 | |
| 632 | 631 | if (gi2c->err) { |
| @@ -284,6 +284,7 @@ struct tegra_i2c_dev { · 283 unmodified lines | ||
| 284 | 284 | struct dma_chan *tx_dma_chan; |
| 285 | 285 | struct dma_chan *rx_dma_chan; |
| 286 | 286 | unsigned int dma_buf_size; |
| 287 | + struct device *dma_dev; | |
| 287 | 288 | dma_addr_t dma_phys; |
| 288 | 289 | void *dma_buf; |
| 289 | 290 | |
| @@ -420,7 +421,7 @@ static int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len) · 130 unmodified lines | ||
| 420 | 421 | static void tegra_i2c_release_dma(struct tegra_i2c_dev *i2c_dev) |
| 421 | 422 | { |
| 422 | 423 | if (i2c_dev->dma_buf) { |
| 423 | − dma_free_coherent(i2c_dev->dev, i2c_dev->dma_buf_size, | |
| 424 | + dma_free_coherent(i2c_dev->dma_dev, i2c_dev->dma_buf_size, | |
| 424 | 425 | i2c_dev->dma_buf, i2c_dev->dma_phys); |
| 425 | 426 | i2c_dev->dma_buf = NULL; |
| 426 | 427 | } |
| @@ -472,10 +473,13 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev) · 45 unmodified lines | ||
| 472 | 473 | |
| 473 | 474 | i2c_dev->tx_dma_chan = chan; |
| 474 | 475 | |
| 476 | + WARN_ON(i2c_dev->tx_dma_chan->device != i2c_dev->rx_dma_chan->device); | |
| 477 | + i2c_dev->dma_dev = chan->device->dev; | |
| 478 | + | |
| 475 | 479 | i2c_dev->dma_buf_size = i2c_dev->hw->quirks->max_write_len + |
| 476 | 480 | I2C_PACKET_HEADER_SIZE; |
| 477 | 481 | |
| 478 | − dma_buf = dma_alloc_coherent(i2c_dev->dev, i2c_dev->dma_buf_size, | |
| 482 | + dma_buf = dma_alloc_coherent(i2c_dev->dma_dev, i2c_dev->dma_buf_size, | |
| 479 | 483 | &dma_phys, GFP_KERNEL | __GFP_NOWARN); |
| 480 | 484 | if (!dma_buf) { |
| 481 | 485 | dev_err(i2c_dev->dev, "failed to allocate DMA buffer\n"); |
| @@ -1272,7 +1276,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, · 790 unmodified lines | ||
| 1272 | 1276 | |
| 1273 | 1277 | if (i2c_dev->dma_mode) { |
| 1274 | 1278 | if (i2c_dev->msg_read) { |
| 1275 | − dma_sync_single_for_device(i2c_dev->dev, | |
| 1279 | + dma_sync_single_for_device(i2c_dev->dma_dev, | |
| 1276 | 1280 | i2c_dev->dma_phys, |
| 1277 | 1281 | xfer_size, DMA_FROM_DEVICE); |
| 1278 | 1282 | |
| @@ -1280,7 +1284,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, · 1 unmodified line | ||
| 1280 | 1284 | if (err) |
| 1281 | 1285 | return err; |
| 1282 | 1286 | } else { |
| 1283 | − dma_sync_single_for_cpu(i2c_dev->dev, | |
| 1287 | + dma_sync_single_for_cpu(i2c_dev->dma_dev, | |
| 1284 | 1288 | i2c_dev->dma_phys, |
| 1285 | 1289 | xfer_size, DMA_TO_DEVICE); |
| 1286 | 1290 | } |
| @@ -1293,7 +1297,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, · 6 unmodified lines | ||
| 1293 | 1297 | memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE, |
| 1294 | 1298 | msg->buf, msg->len); |
| 1295 | 1299 | |
| 1296 | − dma_sync_single_for_device(i2c_dev->dev, | |
| 1300 | + dma_sync_single_for_device(i2c_dev->dma_dev, | |
| 1297 | 1301 | i2c_dev->dma_phys, |
| 1298 | 1302 | xfer_size, DMA_TO_DEVICE); |
| 1299 | 1303 | |
| @@ -1344,7 +1348,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, · 44 unmodified lines | ||
| 1344 | 1348 | } |
| 1345 | 1349 | |
| 1346 | 1350 | if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE) { |
| 1347 | − dma_sync_single_for_cpu(i2c_dev->dev, | |
| 1351 | + dma_sync_single_for_cpu(i2c_dev->dma_dev, | |
| 1348 | 1352 | i2c_dev->dma_phys, |
| 1349 | 1353 | xfer_size, DMA_FROM_DEVICE); |
| 1350 | 1354 | |
| @@ -467,6 +467,7 @@ static int i2c_device_probe(struct device *dev) · 466 unmodified lines | ||
| 467 | 467 | { |
| 468 | 468 | struct i2c_client *client = i2c_verify_client(dev); |
| 469 | 469 | struct i2c_driver *driver; |
| 470 | + bool do_power_on; | |
| 470 | 471 | int status; |
| 471 | 472 | |
| 472 | 473 | if (!client) |
| @@ -545,8 +546,8 @@ static int i2c_device_probe(struct device *dev) · 72 unmodified lines | ||
| 545 | 546 | if (status < 0) |
| 546 | 547 | goto err_clear_wakeup_irq; |
| 547 | 548 | |
| 548 | − status = dev_pm_domain_attach(&client->dev, | |
| 549 | − !i2c_acpi_waive_d0_probe(dev)); | |
| 549 | + do_power_on = !i2c_acpi_waive_d0_probe(dev); | |
| 550 | + status = dev_pm_domain_attach(&client->dev, do_power_on); | |
| 550 | 551 | if (status) |
| 551 | 552 | goto err_clear_wakeup_irq; |
| 552 | 553 | |
| @@ -585,7 +586,7 @@ static int i2c_device_probe(struct device *dev) · 32 unmodified lines | ||
| 585 | 586 | err_release_driver_resources: |
| 586 | 587 | devres_release_group(&client->dev, client->devres_group_id); |
| 587 | 588 | err_detach_pm_domain: |
| 588 | − dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); | |
| 589 | + dev_pm_domain_detach(&client->dev, do_power_on); | |
| 589 | 590 | err_clear_wakeup_irq: |
| 590 | 591 | dev_pm_clear_wake_irq(&client->dev); |
| 591 | 592 | device_init_wakeup(&client->dev, false); |
| @@ -610,7 +611,7 @@ static void i2c_device_remove(struct device *dev) · 18 unmodified lines | ||
| 610 | 611 | |
| 611 | 612 | devres_release_group(&client->dev, client->devres_group_id); |
| 612 | 613 | |
| 613 | − dev_pm_domain_detach(&client->dev, !i2c_acpi_waive_d0_probe(dev)); | |
| 614 | + dev_pm_domain_detach(&client->dev, true); | |
| 614 | 615 | |
| 615 | 616 | dev_pm_clear_wake_irq(&client->dev); |
| 616 | 617 | device_init_wakeup(&client->dev, false); |
| @@ -805,8 +805,10 @@ static int bma400_get_steps_reg(struct bma400_data *data, int *val) · 804 unmodified lines | ||
| 805 | 805 | |
| 806 | 806 | ret = regmap_bulk_read(data->regmap, BMA400_STEP_CNT0_REG, |
| 807 | 807 | steps_raw, BMA400_STEP_RAW_LEN); |
| 808 | − if (ret) | |
| 808 | + if (ret) { | |
| 809 | + kfree(steps_raw); | |
| 809 | 810 | return ret; |
| 811 | + } | |
| 810 | 812 | *val = get_unaligned_le24(steps_raw); |
| 811 | 813 | kfree(steps_raw); |
| 812 | 814 | return IIO_VAL_INT; |
| @@ -869,18 +871,6 @@ static int bma400_init(struct bma400_data *data) · 56 unmodified lines | ||
| 869 | 871 | unsigned int val; |
| 870 | 872 | int ret; |
| 871 | 873 | |
| 872 | − /* Try to read chip_id register. It must return 0x90. */ | |
| 873 | − ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val); | |
| 874 | − if (ret) { | |
| 875 | − dev_err(data->dev, "Failed to read chip id register\n"); | |
| 876 | − return ret; | |
| 877 | − } | |
| 878 | − | |
| 879 | − if (val != BMA400_ID_REG_VAL) { | |
| 880 | − dev_err(data->dev, "Chip ID mismatch\n"); | |
| 881 | − return -ENODEV; | |
| 882 | − } | |
| 883 | − | |
| 884 | 874 | data->regulators[BMA400_VDD_REGULATOR].supply = "vdd"; |
| 885 | 875 | data->regulators[BMA400_VDDIO_REGULATOR].supply = "vddio"; |
| 886 | 876 | ret = devm_regulator_bulk_get(data->dev, |
| @@ -906,6 +896,18 @@ static int bma400_init(struct bma400_data *data) · 19 unmodified lines | ||
| 906 | 896 | if (ret) |
| 907 | 897 | return ret; |
| 908 | 898 | |
| 899 | + /* Try to read chip_id register. It must return 0x90. */ | |
| 900 | + ret = regmap_read(data->regmap, BMA400_CHIP_ID_REG, &val); | |
| 901 | + if (ret) { | |
| 902 | + dev_err(data->dev, "Failed to read chip id register\n"); | |
| 903 | + return ret; | |
| 904 | + } | |
| 905 | + | |
| 906 | + if (val != BMA400_ID_REG_VAL) { | |
| 907 | + dev_err(data->dev, "Chip ID mismatch\n"); | |
| 908 | + return -ENODEV; | |
| 909 | + } | |
| 910 | + | |
| 909 | 911 | ret = bma400_get_power_mode(data); |
| 910 | 912 | if (ret) { |
| 911 | 913 | dev_err(data->dev, "Failed to get the initial power-mode\n"); |
| @@ -202,6 +202,8 @@ static int aspeed_adc_set_trim_data(struct iio_dev *indio_dev) · 201 unmodified lines | ||
| 202 | 202 | ((scu_otp) & |
| 203 | 203 | (data->model_data->trim_locate->field)) >> |
| 204 | 204 | __ffs(data->model_data->trim_locate->field); |
| 205 | + if (!trimming_val) | |
| 206 | + trimming_val = 0x8; | |
| 205 | 207 | } |
| 206 | 208 | dev_dbg(data->dev, |
| 207 | 209 | "trimming val = %d, offset = %08x, fields = %08x\n", |
| @@ -563,12 +565,9 @@ static int aspeed_adc_probe(struct platform_device *pdev) · 355 unmodified lines | ||
| 563 | 565 | if (ret) |
| 564 | 566 | return ret; |
| 565 | 567 | |
| 566 | − if (of_find_property(data->dev->of_node, "aspeed,trim-data-valid", | |
| 567 | − NULL)) { | |
| 568 | − ret = aspeed_adc_set_trim_data(indio_dev); | |
| 569 | − if (ret) | |
| 570 | − return ret; | |
| 571 | − } | |
| 568 | + ret = aspeed_adc_set_trim_data(indio_dev); | |
| 569 | + if (ret) | |
| 570 | + return ret; | |
| 572 | 571 | |
| 573 | 572 | if (of_find_property(data->dev->of_node, "aspeed,battery-sensing", |
| 574 | 573 | NULL)) { |
| @@ -2307,11 +2307,9 @@ static int at91_adc_temp_sensor_init(struct at91_adc_state *st, · 2306 unmodified lines | ||
| 2307 | 2307 | clb->p6 = buf[AT91_ADC_TS_CLB_IDX_P6]; |
| 2308 | 2308 | |
| 2309 | 2309 | /* |
| 2310 | − * We prepare here the conversion to milli and also add constant | |
| 2311 | − * factor (5 degrees Celsius) to p1 here to avoid doing it on | |
| 2312 | − * hotpath. | |
| 2310 | + * We prepare here the conversion to milli to avoid doing it on hotpath. | |
| 2313 | 2311 | */ |
| 2314 | − clb->p1 = clb->p1 * 1000 + 5000; | |
| 2312 | + clb->p1 = clb->p1 * 1000; | |
| 2315 | 2313 | |
| 2316 | 2314 | free_buf: |
| 2317 | 2315 | kfree(buf); |
| @@ -634,8 +634,10 @@ static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *idev, · 633 unmodified lines | ||
| 634 | 634 | trig->ops = &at91_adc_trigger_ops; |
| 635 | 635 | |
| 636 | 636 | ret = iio_trigger_register(trig); |
| 637 | − if (ret) | |
| 637 | + if (ret) { | |
| 638 | + iio_trigger_free(trig); | |
| 638 | 639 | return NULL; |
| 640 | + } | |
| 639 | 641 | |
| 640 | 642 | return trig; |
| 641 | 643 | } |
| @@ -57,7 +57,8 @@ static struct iio_map mp2629_adc_maps[] = { · 56 unmodified lines | ||
| 57 | 57 | MP2629_MAP(SYSTEM_VOLT, "system-volt"), |
| 58 | 58 | MP2629_MAP(INPUT_VOLT, "input-volt"), |
| 59 | 59 | MP2629_MAP(BATT_CURRENT, "batt-current"), |
| 60 | − MP2629_MAP(INPUT_CURRENT, "input-current") | |
| 60 | + MP2629_MAP(INPUT_CURRENT, "input-current"), | |
| 61 | + { } | |
| 61 | 62 | }; |
| 62 | 63 | |
| 63 | 64 | static int mp2629_read_raw(struct iio_dev *indio_dev, |
| @@ -74,7 +75,7 @@ static int mp2629_read_raw(struct iio_dev *indio_dev, · 10 unmodified lines | ||
| 74 | 75 | if (ret) |
| 75 | 76 | return ret; |
| 76 | 77 | |
| 77 | − if (chan->address == MP2629_INPUT_VOLT) | |
| 78 | + if (chan->channel == MP2629_INPUT_VOLT) | |
| 78 | 79 | rval &= GENMASK(6, 0); |
| 79 | 80 | *val = rval; |
| 80 | 81 | return IIO_VAL_INT; |
| @@ -245,14 +245,14 @@ static int afe4403_read_raw(struct iio_dev *indio_dev, · 244 unmodified lines | ||
| 245 | 245 | int *val, int *val2, long mask) |
| 246 | 246 | { |
| 247 | 247 | struct afe4403_data *afe = iio_priv(indio_dev); |
| 248 | − unsigned int reg = afe4403_channel_values[chan->address]; | |
| 249 | − unsigned int field = afe4403_channel_leds[chan->address]; | |
| 248 | + unsigned int reg, field; | |
| 250 | 249 | int ret; |
| 251 | 250 | |
| 252 | 251 | switch (chan->type) { |
| 253 | 252 | case IIO_INTENSITY: |
| 254 | 253 | switch (mask) { |
| 255 | 254 | case IIO_CHAN_INFO_RAW: |
| 255 | + reg = afe4403_channel_values[chan->address]; | |
| 256 | 256 | ret = afe4403_read(afe, reg, val); |
| 257 | 257 | if (ret) |
| 258 | 258 | return ret; |
| @@ -262,6 +262,7 @@ static int afe4403_read_raw(struct iio_dev *indio_dev, · 3 unmodified lines | ||
| 262 | 262 | case IIO_CURRENT: |
| 263 | 263 | switch (mask) { |
| 264 | 264 | case IIO_CHAN_INFO_RAW: |
| 265 | + field = afe4403_channel_leds[chan->address]; | |
| 265 | 266 | ret = regmap_field_read(afe->fields[field], val); |
| 266 | 267 | if (ret) |
| 267 | 268 | return ret; |
| @@ -250,20 +250,20 @@ static int afe4404_read_raw(struct iio_dev *indio_dev, · 249 unmodified lines | ||
| 250 | 250 | int *val, int *val2, long mask) |
| 251 | 251 | { |
| 252 | 252 | struct afe4404_data *afe = iio_priv(indio_dev); |
| 253 | − unsigned int value_reg = afe4404_channel_values[chan->address]; | |
| 254 | − unsigned int led_field = afe4404_channel_leds[chan->address]; | |
| 255 | − unsigned int offdac_field = afe4404_channel_offdacs[chan->address]; | |
| 253 | + unsigned int value_reg, led_field, offdac_field; | |
| 256 | 254 | int ret; |
| 257 | 255 | |
| 258 | 256 | switch (chan->type) { |
| 259 | 257 | case IIO_INTENSITY: |
| 260 | 258 | switch (mask) { |
| 261 | 259 | case IIO_CHAN_INFO_RAW: |
| 260 | + value_reg = afe4404_channel_values[chan->address]; | |
| 262 | 261 | ret = regmap_read(afe->regmap, value_reg, val); |
| 263 | 262 | if (ret) |
| 264 | 263 | return ret; |
| 265 | 264 | return IIO_VAL_INT; |
| 266 | 265 | case IIO_CHAN_INFO_OFFSET: |
| 266 | + offdac_field = afe4404_channel_offdacs[chan->address]; | |
| 267 | 267 | ret = regmap_field_read(afe->fields[offdac_field], val); |
| 268 | 268 | if (ret) |
| 269 | 269 | return ret; |
| @@ -273,6 +273,7 @@ static int afe4404_read_raw(struct iio_dev *indio_dev, · 3 unmodified lines | ||
| 273 | 273 | case IIO_CURRENT: |
| 274 | 274 | switch (mask) { |
| 275 | 275 | case IIO_CHAN_INFO_RAW: |
| 276 | + led_field = afe4404_channel_leds[chan->address]; | |
| 276 | 277 | ret = regmap_field_read(afe->fields[led_field], val); |
| 277 | 278 | if (ret) |
| 278 | 279 | return ret; |
| @@ -295,19 +296,20 @@ static int afe4404_write_raw(struct iio_dev *indio_dev, · 16 unmodified lines | ||
| 295 | 296 | int val, int val2, long mask) |
| 296 | 297 | { |
| 297 | 298 | struct afe4404_data *afe = iio_priv(indio_dev); |
| 298 | − unsigned int led_field = afe4404_channel_leds[chan->address]; | |
| 299 | − unsigned int offdac_field = afe4404_channel_offdacs[chan->address]; | |
| 299 | + unsigned int led_field, offdac_field; | |
| 300 | 300 | |
| 301 | 301 | switch (chan->type) { |
| 302 | 302 | case IIO_INTENSITY: |
| 303 | 303 | switch (mask) { |
| 304 | 304 | case IIO_CHAN_INFO_OFFSET: |
| 305 | + offdac_field = afe4404_channel_offdacs[chan->address]; | |
| 305 | 306 | return regmap_field_write(afe->fields[offdac_field], val); |
| 306 | 307 | } |
| 307 | 308 | break; |
| 308 | 309 | case IIO_CURRENT: |
| 309 | 310 | switch (mask) { |
| 310 | 311 | case IIO_CHAN_INFO_RAW: |
| 312 | + led_field = afe4404_channel_leds[chan->address]; | |
| 311 | 313 | return regmap_field_write(afe->fields[led_field], val); |
| 312 | 314 | } |
| 313 | 315 | break; |
| @@ -632,7 +632,7 @@ static int bno055_set_regmask(struct bno055_priv *priv, int val, int val2, · 631 unmodified lines | ||
| 632 | 632 | return -EINVAL; |
| 633 | 633 | } |
| 634 | 634 | delta = abs(tbl_val - req_val); |
| 635 | − if (delta < best_delta || first) { | |
| 635 | + if (first || delta < best_delta) { | |
| 636 | 636 | best_delta = delta; |
| 637 | 637 | hwval = i; |
| 638 | 638 | first = false; |
| @@ -58,8 +58,12 @@ int iio_register_sw_trigger_type(struct iio_sw_trigger_type *t) · 57 unmodified lines | ||
| 58 | 58 | |
| 59 | 59 | t->group = configfs_register_default_group(iio_triggers_group, t->name, |
| 60 | 60 | &iio_trigger_type_group_type); |
| 61 | − if (IS_ERR(t->group)) | |
| 61 | + if (IS_ERR(t->group)) { | |
| 62 | + mutex_lock(&iio_trigger_types_lock); | |
| 63 | + list_del(&t->list); | |
| 64 | + mutex_unlock(&iio_trigger_types_lock); | |
| 62 | 65 | ret = PTR_ERR(t->group); |
| 66 | + } | |
| 63 | 67 | |
| 64 | 68 | return ret; |
| 65 | 69 | } |
| @@ -293,6 +293,8 @@ config RPR0521 · 292 unmodified lines | ||
| 293 | 293 | tristate "ROHM RPR0521 ALS and proximity sensor driver" |
| 294 | 294 | depends on I2C |
| 295 | 295 | select REGMAP_I2C |
| 296 | + select IIO_BUFFER | |
| 297 | + select IIO_TRIGGERED_BUFFER | |
| 296 | 298 | help |
| 297 | 299 | Say Y here if you want to build support for ROHM's RPR0521 |
| 298 | 300 | ambient light and proximity sensor device. |
| @@ -54,9 +54,6 @@ · 53 unmodified lines | ||
| 54 | 54 | #define APDS9960_REG_CONTROL_PGAIN_MASK_SHIFT 2 |
| 55 | 55 | |
| 56 | 56 | #define APDS9960_REG_CONFIG_2 0x90 |
| 57 | −#define APDS9960_REG_CONFIG_2_GGAIN_MASK 0x60 | |
| 58 | −#define APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT 5 | |
| 59 | − | |
| 60 | 57 | #define APDS9960_REG_ID 0x92 |
| 61 | 58 | |
| 62 | 59 | #define APDS9960_REG_STATUS 0x93 |
| @@ -77,6 +74,9 @@ · 14 unmodified lines | ||
| 77 | 74 | #define APDS9960_REG_GCONF_1_GFIFO_THRES_MASK_SHIFT 6 |
| 78 | 75 | |
| 79 | 76 | #define APDS9960_REG_GCONF_2 0xa3 |
| 77 | +#define APDS9960_REG_GCONF_2_GGAIN_MASK 0x60 | |
| 78 | +#define APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT 5 | |
| 79 | + | |
| 80 | 80 | #define APDS9960_REG_GOFFSET_U 0xa4 |
| 81 | 81 | #define APDS9960_REG_GOFFSET_D 0xa5 |
| 82 | 82 | #define APDS9960_REG_GPULSE 0xa6 |
| @@ -396,9 +396,9 @@ static int apds9960_set_pxs_gain(struct apds9960_data *data, int val) · 313 unmodified lines | ||
| 396 | 396 | } |
| 397 | 397 | |
| 398 | 398 | ret = regmap_update_bits(data->regmap, |
| 399 | − APDS9960_REG_CONFIG_2, | |
| 400 | − APDS9960_REG_CONFIG_2_GGAIN_MASK, | |
| 401 | − idx << APDS9960_REG_CONFIG_2_GGAIN_MASK_SHIFT); | |
| 399 | + APDS9960_REG_GCONF_2, | |
| 400 | + APDS9960_REG_GCONF_2_GGAIN_MASK, | |
| 401 | + idx << APDS9960_REG_GCONF_2_GGAIN_MASK_SHIFT); | |
| 402 | 402 | if (!ret) |
| 403 | 403 | data->pxs_gain = idx; |
| 404 | 404 | mutex_unlock(&data->lock); |
| @@ -25,13 +25,6 @@ enum { · 24 unmodified lines | ||
| 25 | 25 | MS5607, |
| 26 | 26 | }; |
| 27 | 27 | |
| 28 | −struct ms5611_chip_info { | |
| 29 | − u16 prom[MS5611_PROM_WORDS_NB]; | |
| 30 | − | |
| 31 | − int (*temp_and_pressure_compensate)(struct ms5611_chip_info *chip_info, | |
| 32 | − s32 *temp, s32 *pressure); | |
| 33 | −}; | |
| 34 | − | |
| 35 | 28 | /* |
| 36 | 29 | * OverSampling Rate descriptor. |
| 37 | 30 | * Warning: cmd MUST be kept aligned on a word boundary (see |
| @@ -50,12 +43,15 @@ struct ms5611_state { · 12 unmodified lines | ||
| 50 | 43 | const struct ms5611_osr *pressure_osr; |
| 51 | 44 | const struct ms5611_osr *temp_osr; |
| 52 | 45 | |
| 46 | + u16 prom[MS5611_PROM_WORDS_NB]; | |
| 47 | + | |
| 53 | 48 | int (*reset)(struct ms5611_state *st); |
| 54 | 49 | int (*read_prom_word)(struct ms5611_state *st, int index, u16 *word); |
| 55 | 50 | int (*read_adc_temp_and_pressure)(struct ms5611_state *st, |
| 56 | 51 | s32 *temp, s32 *pressure); |
| 57 | 52 | |
| 58 | − struct ms5611_chip_info *chip_info; | |
| 53 | + int (*compensate_temp_and_pressure)(struct ms5611_state *st, s32 *temp, | |
| 54 | + s32 *pressure); | |
| 59 | 55 | struct regulator *vdd; |
| 60 | 56 | }; |
| 61 | 57 | |
| @@ -85,7 +85,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev) · 84 unmodified lines | ||
| 85 | 85 | struct ms5611_state *st = iio_priv(indio_dev); |
| 86 | 86 | |
| 87 | 87 | for (i = 0; i < MS5611_PROM_WORDS_NB; i++) { |
| 88 | − ret = st->read_prom_word(st, i, &st->chip_info->prom[i]); | |
| 88 | + ret = st->read_prom_word(st, i, &st->prom[i]); | |
| 89 | 89 | if (ret < 0) { |
| 90 | 90 | dev_err(&indio_dev->dev, |
| 91 | 91 | "failed to read prom at %d\n", i); |
| @@ -93,7 +93,7 @@ static int ms5611_read_prom(struct iio_dev *indio_dev) · 1 unmodified line | ||
| 93 | 93 | } |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | − if (!ms5611_prom_is_valid(st->chip_info->prom, MS5611_PROM_WORDS_NB)) { | |
| 96 | + if (!ms5611_prom_is_valid(st->prom, MS5611_PROM_WORDS_NB)) { | |
| 97 | 97 | dev_err(&indio_dev->dev, "PROM integrity check failed\n"); |
| 98 | 98 | return -ENODEV; |
| 99 | 99 | } |
| @@ -114,21 +114,20 @@ static int ms5611_read_temp_and_pressure(struct iio_dev *indio_dev, · 14 unmodified lines | ||
| 114 | 114 | return ret; |
| 115 | 115 | } |
| 116 | 116 | |
| 117 | − return st->chip_info->temp_and_pressure_compensate(st->chip_info, | |
| 118 | − temp, pressure); | |
| 117 | + return st->compensate_temp_and_pressure(st, temp, pressure); | |
| 119 | 118 | } |
| 120 | 119 | |
| 121 | −static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, | |
| 120 | +static int ms5611_temp_and_pressure_compensate(struct ms5611_state *st, | |
| 122 | 121 | s32 *temp, s32 *pressure) |
| 123 | 122 | { |
| 124 | 123 | s32 t = *temp, p = *pressure; |
| 125 | 124 | s64 off, sens, dt; |
| 126 | 125 | |
| 127 | − dt = t - (chip_info->prom[5] << 8); | |
| 128 | − off = ((s64)chip_info->prom[2] << 16) + ((chip_info->prom[4] * dt) >> 7); | |
| 129 | − sens = ((s64)chip_info->prom[1] << 15) + ((chip_info->prom[3] * dt) >> 8); | |
| 126 | + dt = t - (st->prom[5] << 8); | |
| 127 | + off = ((s64)st->prom[2] << 16) + ((st->prom[4] * dt) >> 7); | |
| 128 | + sens = ((s64)st->prom[1] << 15) + ((st->prom[3] * dt) >> 8); | |
| 130 | 129 | |
| 131 | − t = 2000 + ((chip_info->prom[6] * dt) >> 23); | |
| 130 | + t = 2000 + ((st->prom[6] * dt) >> 23); | |
| 132 | 131 | if (t < 2000) { |
| 133 | 132 | s64 off2, sens2, t2; |
| 134 | 133 | |
| @@ -154,17 +153,17 @@ static int ms5611_temp_and_pressure_compensate(struct ms5611_chip_info *chip_inf · 19 unmodified lines | ||
| 154 | 153 | return 0; |
| 155 | 154 | } |
| 156 | 155 | |
| 157 | −static int ms5607_temp_and_pressure_compensate(struct ms5611_chip_info *chip_info, | |
| 156 | +static int ms5607_temp_and_pressure_compensate(struct ms5611_state *st, | |
| 158 | 157 | s32 *temp, s32 *pressure) |
| 159 | 158 | { |
| 160 | 159 | s32 t = *temp, p = *pressure; |
| 161 | 160 | s64 off, sens, dt; |
| 162 | 161 | |
| 163 | − dt = t - (chip_info->prom[5] << 8); | |
| 164 | − off = ((s64)chip_info->prom[2] << 17) + ((chip_info->prom[4] * dt) >> 6); | |
| 165 | − sens = ((s64)chip_info->prom[1] << 16) + ((chip_info->prom[3] * dt) >> 7); | |
| 162 | + dt = t - (st->prom[5] << 8); | |
| 163 | + off = ((s64)st->prom[2] << 17) + ((st->prom[4] * dt) >> 6); | |
| 164 | + sens = ((s64)st->prom[1] << 16) + ((st->prom[3] * dt) >> 7); | |
| 166 | 165 | |
| 167 | − t = 2000 + ((chip_info->prom[6] * dt) >> 23); | |
| 166 | + t = 2000 + ((st->prom[6] * dt) >> 23); | |
| 168 | 167 | if (t < 2000) { |
| 169 | 168 | s64 off2, sens2, t2, tmp; |
| 170 | 169 | |
| @@ -342,15 +341,6 @@ static int ms5611_write_raw(struct iio_dev *indio_dev, · 171 unmodified lines | ||
| 342 | 341 | |
| 343 | 342 | static const unsigned long ms5611_scan_masks[] = {0x3, 0}; |
| 344 | 343 | |
| 345 | −static struct ms5611_chip_info chip_info_tbl[] = { | |
| 346 | − [MS5611] = { | |
| 347 | − .temp_and_pressure_compensate = ms5611_temp_and_pressure_compensate, | |
| 348 | − }, | |
| 349 | − [MS5607] = { | |
| 350 | − .temp_and_pressure_compensate = ms5607_temp_and_pressure_compensate, | |
| 351 | − } | |
| 352 | −}; | |
| 353 | − | |
| 354 | 344 | static const struct iio_chan_spec ms5611_channels[] = { |
| 355 | 345 | { |
| 356 | 346 | .type = IIO_PRESSURE, |
| @@ -433,7 +423,20 @@ int ms5611_probe(struct iio_dev *indio_dev, struct device *dev, · 76 unmodified lines | ||
| 433 | 423 | struct ms5611_state *st = iio_priv(indio_dev); |
| 434 | 424 | |
| 435 | 425 | mutex_init(&st->lock); |
| 436 | − st->chip_info = &chip_info_tbl[type]; | |
| 426 | + | |
| 427 | + switch (type) { | |
| 428 | + case MS5611: | |
| 429 | + st->compensate_temp_and_pressure = | |
| 430 | + ms5611_temp_and_pressure_compensate; | |
| 431 | + break; | |
| 432 | + case MS5607: | |
| 433 | + st->compensate_temp_and_pressure = | |
| 434 | + ms5607_temp_and_pressure_compensate; | |
| 435 | + break; | |
| 436 | + default: | |
| 437 | + return -EINVAL; | |
| 438 | + } | |
| 439 | + | |
| 437 | 440 | st->temp_osr = |
| 438 | 441 | &ms5611_avail_temp_osr[ARRAY_SIZE(ms5611_avail_temp_osr) - 1]; |
| 439 | 442 | st->pressure_osr = |
| @@ -91,7 +91,7 @@ static int ms5611_spi_probe(struct spi_device *spi) · 90 unmodified lines | ||
| 91 | 91 | spi_set_drvdata(spi, indio_dev); |
| 92 | 92 | |
| 93 | 93 | spi->mode = SPI_MODE_0; |
| 94 | − spi->max_speed_hz = 20000000; | |
| 94 | + spi->max_speed_hz = min(spi->max_speed_hz, 20000000U); | |
| 95 | 95 | spi->bits_per_word = 8; |
| 96 | 96 | ret = spi_setup(spi); |
| 97 | 97 | if (ret < 0) |
| @@ -203,9 +203,13 @@ static int iio_sysfs_trigger_remove(int id) · 202 unmodified lines | ||
| 203 | 203 | |
| 204 | 204 | static int __init iio_sysfs_trig_init(void) |
| 205 | 205 | { |
| 206 | + int ret; | |
| 206 | 207 | device_initialize(&iio_sysfs_trig_dev); |
| 207 | 208 | dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger"); |
| 208 | − return device_add(&iio_sysfs_trig_dev); | |
| 209 | + ret = device_add(&iio_sysfs_trig_dev); | |
| 210 | + if (ret) | |
| 211 | + put_device(&iio_sysfs_trig_dev); | |
| 212 | + return ret; | |
| 209 | 213 | } |
| 210 | 214 | module_init(iio_sysfs_trig_init); |
| 211 | 215 | |
| @@ -1556,7 +1556,7 @@ static bool validate_ipv4_net_dev(struct net_device *net_dev, · 1555 unmodified lines | ||
| 1556 | 1556 | return false; |
| 1557 | 1557 | |
| 1558 | 1558 | memset(&fl4, 0, sizeof(fl4)); |
| 1559 | − fl4.flowi4_iif = net_dev->ifindex; | |
| 1559 | + fl4.flowi4_oif = net_dev->ifindex; | |
| 1560 | 1560 | fl4.daddr = daddr; |
| 1561 | 1561 | fl4.saddr = saddr; |
| 1562 | 1562 | |
| @@ -2817,10 +2817,18 @@ static int __init ib_core_init(void) · 2816 unmodified lines | ||
| 2817 | 2817 | |
| 2818 | 2818 | nldev_init(); |
| 2819 | 2819 | rdma_nl_register(RDMA_NL_LS, ibnl_ls_cb_table); |
| 2820 | − roce_gid_mgmt_init(); | |
| 2820 | + ret = roce_gid_mgmt_init(); | |
| 2821 | + if (ret) { | |
| 2822 | + pr_warn("Couldn't init RoCE GID management\n"); | |
| 2823 | + goto err_parent; | |
| 2824 | + } | |
| 2821 | 2825 | |
| 2822 | 2826 | return 0; |
| 2823 | 2827 | |
| 2828 | +err_parent: | |
| 2829 | + rdma_nl_unregister(RDMA_NL_LS); | |
| 2830 | + nldev_exit(); | |
| 2831 | + unregister_pernet_device(&rdma_dev_net_ops); | |
| 2824 | 2832 | err_compat: |
| 2825 | 2833 | unregister_blocking_lsm_notifier(&ibdev_lsm_nb); |
| 2826 | 2834 | err_sa: |
| @@ -2567,7 +2567,7 @@ void __init nldev_init(void) · 2566 unmodified lines | ||
| 2567 | 2567 | rdma_nl_register(RDMA_NL_NLDEV, nldev_cb_table); |
| 2568 | 2568 | } |
| 2569 | 2569 | |
| 2570 | −void __exit nldev_exit(void) | |
| 2570 | +void nldev_exit(void) | |
| 2571 | 2571 | { |
| 2572 | 2572 | rdma_nl_unregister(RDMA_NL_NLDEV); |
| 2573 | 2573 | } |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause |
| 2 | 2 | /* |
| 3 | − * Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All rights reserved. | |
| 3 | + * Copyright 2018-2022 Amazon.com, Inc. or its affiliates. All rights reserved. | |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | #include <linux/module.h> |
| @@ -14,10 +14,12 @@ · 7 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | #define PCI_DEV_ID_EFA0_VF 0xefa0 |
| 16 | 16 | #define PCI_DEV_ID_EFA1_VF 0xefa1 |
| 17 | +#define PCI_DEV_ID_EFA2_VF 0xefa2 | |
| 17 | 18 | |
| 18 | 19 | static const struct pci_device_id efa_pci_tbl[] = { |
| 19 | 20 | { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA0_VF) }, |
| 20 | 21 | { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA1_VF) }, |
| 22 | + { PCI_VDEVICE(AMAZON, PCI_DEV_ID_EFA2_VF) }, | |
| 21 | 23 | { } |
| 22 | 24 | }; |
| 23 | 25 | |
| @@ -913,8 +913,7 @@ void sc_disable(struct send_context *sc) · 912 unmodified lines | ||
| 913 | 913 | spin_unlock(&sc->release_lock); |
| 914 | 914 | |
| 915 | 915 | write_seqlock(&sc->waitlock); |
| 916 | − if (!list_empty(&sc->piowait)) | |
| 917 | − list_move(&sc->piowait, &wake_list); | |
| 916 | + list_splice_init(&sc->piowait, &wake_list); | |
| 918 | 917 | write_sequnlock(&sc->waitlock); |
| 919 | 918 | while (!list_empty(&wake_list)) { |
| 920 | 919 | struct iowait *wait; |
| @@ -118,7 +118,6 @@ static const u32 hns_roce_op_code[] = { · 117 unmodified lines | ||
| 118 | 118 | HR_OPC_MAP(ATOMIC_CMP_AND_SWP, ATOM_CMP_AND_SWAP), |
| 119 | 119 | HR_OPC_MAP(ATOMIC_FETCH_AND_ADD, ATOM_FETCH_AND_ADD), |
| 120 | 120 | HR_OPC_MAP(SEND_WITH_INV, SEND_WITH_INV), |
| 121 | − HR_OPC_MAP(LOCAL_INV, LOCAL_INV), | |
| 122 | 121 | HR_OPC_MAP(MASKED_ATOMIC_CMP_AND_SWP, ATOM_MSK_CMP_AND_SWAP), |
| 123 | 122 | HR_OPC_MAP(MASKED_ATOMIC_FETCH_AND_ADD, ATOM_MSK_FETCH_AND_ADD), |
| 124 | 123 | HR_OPC_MAP(REG_MR, FAST_REG_PMR), |
| @@ -558,9 +557,6 @@ static int set_rc_opcode(struct hns_roce_dev *hr_dev, · 433 unmodified lines | ||
| 558 | 557 | else |
| 559 | 558 | ret = -EOPNOTSUPP; |
| 560 | 559 | break; |
| 561 | − case IB_WR_LOCAL_INV: | |
| 562 | − hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_SO); | |
| 563 | − fallthrough; | |
| 564 | 560 | case IB_WR_SEND_WITH_INV: |
| 565 | 561 | rc_sq_wqe->inv_key = cpu_to_le32(wr->ex.invalidate_rkey); |
| 566 | 562 | break; |
| @@ -2921,8 +2917,12 @@ static int free_mr_modify_qp(struct hns_roce_dev *hr_dev) · 2354 unmodified lines | ||
| 2921 | 2917 | |
| 2922 | 2918 | static int free_mr_init(struct hns_roce_dev *hr_dev) |
| 2923 | 2919 | { |
| 2920 | + struct hns_roce_v2_priv *priv = hr_dev->priv; | |
| 2921 | + struct hns_roce_v2_free_mr *free_mr = &priv->free_mr; | |
| 2924 | 2922 | int ret; |
| 2925 | 2923 | |
| 2924 | + mutex_init(&free_mr->mutex); | |
| 2925 | + | |
| 2926 | 2926 | ret = free_mr_alloc_res(hr_dev); |
| 2927 | 2927 | if (ret) |
| 2928 | 2928 | return ret; |
| @@ -3339,7 +3339,6 @@ static int hns_roce_v2_write_mtpt(struct hns_roce_dev *hr_dev, · 410 unmodified lines | ||
| 3339 | 3339 | |
| 3340 | 3340 | hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_VALID); |
| 3341 | 3341 | hr_reg_write(mpt_entry, MPT_PD, mr->pd); |
| 3342 | − hr_reg_enable(mpt_entry, MPT_L_INV_EN); | |
| 3343 | 3342 | |
| 3344 | 3343 | hr_reg_write_bool(mpt_entry, MPT_BIND_EN, |
| 3345 | 3344 | mr->access & IB_ACCESS_MW_BIND); |
| @@ -3430,7 +3429,6 @@ static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev, · 84 unmodified lines | ||
| 3430 | 3429 | |
| 3431 | 3430 | hr_reg_enable(mpt_entry, MPT_RA_EN); |
| 3432 | 3431 | hr_reg_enable(mpt_entry, MPT_R_INV_EN); |
| 3433 | − hr_reg_enable(mpt_entry, MPT_L_INV_EN); | |
| 3434 | 3432 | |
| 3435 | 3433 | hr_reg_enable(mpt_entry, MPT_FRE); |
| 3436 | 3434 | hr_reg_clear(mpt_entry, MPT_MR_MW); |
| @@ -3462,7 +3460,6 @@ static int hns_roce_v2_mw_write_mtpt(void *mb_buf, struct hns_roce_mw *mw) · 25 unmodified lines | ||
| 3462 | 3460 | hr_reg_write(mpt_entry, MPT_PD, mw->pdn); |
| 3463 | 3461 | |
| 3464 | 3462 | hr_reg_enable(mpt_entry, MPT_R_INV_EN); |
| 3465 | − hr_reg_enable(mpt_entry, MPT_L_INV_EN); | |
| 3466 | 3463 | hr_reg_enable(mpt_entry, MPT_LW_EN); |
| 3467 | 3464 | |
| 3468 | 3465 | hr_reg_enable(mpt_entry, MPT_MR_MW); |
| @@ -3911,7 +3908,6 @@ static const u32 wc_send_op_map[] = { · 442 unmodified lines | ||
| 3911 | 3908 | HR_WC_OP_MAP(RDMA_READ, RDMA_READ), |
| 3912 | 3909 | HR_WC_OP_MAP(RDMA_WRITE, RDMA_WRITE), |
| 3913 | 3910 | HR_WC_OP_MAP(RDMA_WRITE_WITH_IMM, RDMA_WRITE), |
| 3914 | − HR_WC_OP_MAP(LOCAL_INV, LOCAL_INV), | |
| 3915 | 3911 | HR_WC_OP_MAP(ATOM_CMP_AND_SWAP, COMP_SWAP), |
| 3916 | 3912 | HR_WC_OP_MAP(ATOM_FETCH_AND_ADD, FETCH_ADD), |
| 3917 | 3913 | HR_WC_OP_MAP(ATOM_MSK_CMP_AND_SWAP, MASKED_COMP_SWAP), |
| @@ -3961,9 +3957,6 @@ static void fill_send_wc(struct ib_wc *wc, struct hns_roce_v2_cqe *cqe) · 43 unmodified lines | ||
| 3961 | 3957 | case HNS_ROCE_V2_WQE_OP_RDMA_WRITE_WITH_IMM: |
| 3962 | 3958 | wc->wc_flags |= IB_WC_WITH_IMM; |
| 3963 | 3959 | break; |
| 3964 | − case HNS_ROCE_V2_WQE_OP_LOCAL_INV: | |
| 3965 | − wc->wc_flags |= IB_WC_WITH_INVALIDATE; | |
| 3966 | − break; | |
| 3967 | 3960 | case HNS_ROCE_V2_WQE_OP_ATOM_CMP_AND_SWAP: |
| 3968 | 3961 | case HNS_ROCE_V2_WQE_OP_ATOM_FETCH_AND_ADD: |
| 3969 | 3962 | case HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP: |
| @@ -179,7 +179,6 @@ enum { · 178 unmodified lines | ||
| 179 | 179 | HNS_ROCE_V2_WQE_OP_ATOM_MSK_CMP_AND_SWAP = 0x8, |
| 180 | 180 | HNS_ROCE_V2_WQE_OP_ATOM_MSK_FETCH_AND_ADD = 0x9, |
| 181 | 181 | HNS_ROCE_V2_WQE_OP_FAST_REG_PMR = 0xa, |
| 182 | − HNS_ROCE_V2_WQE_OP_LOCAL_INV = 0xb, | |
| 183 | 182 | HNS_ROCE_V2_WQE_OP_BIND_MW = 0xc, |
| 184 | 183 | HNS_ROCE_V2_WQE_OP_MASK = 0x1f, |
| 185 | 184 | }; |
| @@ -920,7 +919,6 @@ struct hns_roce_v2_rc_send_wqe { · 734 unmodified lines | ||
| 920 | 919 | #define RC_SEND_WQE_OWNER RC_SEND_WQE_FIELD_LOC(7, 7) |
| 921 | 920 | #define RC_SEND_WQE_CQE RC_SEND_WQE_FIELD_LOC(8, 8) |
| 922 | 921 | #define RC_SEND_WQE_FENCE RC_SEND_WQE_FIELD_LOC(9, 9) |
| 923 | −#define RC_SEND_WQE_SO RC_SEND_WQE_FIELD_LOC(10, 10) | |
| 924 | 922 | #define RC_SEND_WQE_SE RC_SEND_WQE_FIELD_LOC(11, 11) |
| 925 | 923 | #define RC_SEND_WQE_INLINE RC_SEND_WQE_FIELD_LOC(12, 12) |
| 926 | 924 | #define RC_SEND_WQE_WQE_INDEX RC_SEND_WQE_FIELD_LOC(30, 15) |
| @@ -344,6 +344,10 @@ static int qedr_alloc_resources(struct qedr_dev *dev) · 343 unmodified lines | ||
| 344 | 344 | if (IS_IWARP(dev)) { |
| 345 | 345 | xa_init(&dev->qps); |
| 346 | 346 | dev->iwarp_wq = create_singlethread_workqueue("qedr_iwarpq"); |
| 347 | + if (!dev->iwarp_wq) { | |
| 348 | + rc = -ENOMEM; | |
| 349 | + goto err1; | |
| 350 | + } | |
| 347 | 351 | } |
| 348 | 352 | |
| 349 | 353 | /* Allocate Status blocks for CNQ */ |
| @@ -351,7 +355,7 @@ static int qedr_alloc_resources(struct qedr_dev *dev) · 1 unmodified line | ||
| 351 | 355 | GFP_KERNEL); |
| 352 | 356 | if (!dev->sb_array) { |
| 353 | 357 | rc = -ENOMEM; |
| 354 | − goto err1; | |
| 358 | + goto err_destroy_wq; | |
| 355 | 359 | } |
| 356 | 360 | |
| 357 | 361 | dev->cnq_array = kcalloc(dev->num_cnq, |
| @@ -402,6 +406,9 @@ err3: · 44 unmodified lines | ||
| 402 | 406 | kfree(dev->cnq_array); |
| 403 | 407 | err2: |
| 404 | 408 | kfree(dev->sb_array); |
| 409 | +err_destroy_wq: | |
| 410 | + if (IS_IWARP(dev)) | |
| 411 | + destroy_workqueue(dev->iwarp_wq); | |
| 405 | 412 | err1: |
| 406 | 413 | kfree(dev->sgid_tbl); |
| 407 | 414 | return rc; |
| @@ -879,8 +879,10 @@ static enum resp_states read_reply(struct rxe_qp *qp, · 878 unmodified lines | ||
| 879 | 879 | |
| 880 | 880 | skb = prepare_ack_packet(qp, &ack_pkt, opcode, payload, |
| 881 | 881 | res->cur_psn, AETH_ACK_UNLIMITED); |
| 882 | − if (!skb) | |
| 882 | + if (!skb) { | |
| 883 | + rxe_put(mr); | |
| 883 | 884 | return RESPST_ERR_RNR; |
| 885 | + } | |
| 884 | 886 | |
| 885 | 887 | err = rxe_mr_copy(mr, res->read.va, payload_addr(&ack_pkt), |
| 886 | 888 | payload, RXE_FROM_MR_OBJ); |
| @@ -273,22 +273,22 @@ int iforce_init_device(struct device *parent, u16 bustype, · 272 unmodified lines | ||
| 273 | 273 | * Get device info. |
| 274 | 274 | */ |
| 275 | 275 | |
| 276 | − if (!iforce_get_id_packet(iforce, 'M', buf, &len) || len < 3) | |
| 276 | + if (!iforce_get_id_packet(iforce, 'M', buf, &len) && len >= 3) | |
| 277 | 277 | input_dev->id.vendor = get_unaligned_le16(buf + 1); |
| 278 | 278 | else |
| 279 | 279 | dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n"); |
| 280 | 280 | |
| 281 | − if (!iforce_get_id_packet(iforce, 'P', buf, &len) || len < 3) | |
| 281 | + if (!iforce_get_id_packet(iforce, 'P', buf, &len) && len >= 3) | |
| 282 | 282 | input_dev->id.product = get_unaligned_le16(buf + 1); |
| 283 | 283 | else |
| 284 | 284 | dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n"); |
| 285 | 285 | |
| 286 | − if (!iforce_get_id_packet(iforce, 'B', buf, &len) || len < 3) | |
| 286 | + if (!iforce_get_id_packet(iforce, 'B', buf, &len) && len >= 3) | |
| 287 | 287 | iforce->device_memory.end = get_unaligned_le16(buf + 1); |
| 288 | 288 | else |
| 289 | 289 | dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n"); |
| 290 | 290 | |
| 291 | − if (!iforce_get_id_packet(iforce, 'N', buf, &len) || len < 2) | |
| 291 | + if (!iforce_get_id_packet(iforce, 'N', buf, &len) && len >= 2) | |
| 292 | 292 | ff_effects = buf[1]; |
| 293 | 293 | else |
| 294 | 294 | dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n"); |
| @@ -18,6 +18,10 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/gpio.h> |
| 19 | 19 | #include <linux/platform_device.h> |
| 20 | 20 | |
| 21 | +static bool use_low_level_irq; | |
| 22 | +module_param(use_low_level_irq, bool, 0444); | |
| 23 | +MODULE_PARM_DESC(use_low_level_irq, "Use low-level triggered IRQ instead of edge triggered"); | |
| 24 | + | |
| 21 | 25 | struct soc_button_info { |
| 22 | 26 | const char *name; |
| 23 | 27 | int acpi_index; |
| @@ -73,6 +77,13 @@ static const struct dmi_system_id dmi_use_low_level_irq[] = { · 49 unmodified lines | ||
| 73 | 77 | DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), |
| 74 | 78 | }, |
| 75 | 79 | }, |
| 80 | + { | |
| 81 | + /* Acer Switch V 10 SW5-017, same issue as Acer Switch 10 SW5-012. */ | |
| 82 | + .matches = { | |
| 83 | + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | |
| 84 | + DMI_MATCH(DMI_PRODUCT_NAME, "SW5-017"), | |
| 85 | + }, | |
| 86 | + }, | |
| 76 | 87 | { |
| 77 | 88 | /* |
| 78 | 89 | * Acer One S1003. _LID method messes with power-button GPIO |
| @@ -164,7 +175,8 @@ soc_button_device_create(struct platform_device *pdev, · 85 unmodified lines | ||
| 164 | 175 | } |
| 165 | 176 | |
| 166 | 177 | /* See dmi_use_low_level_irq[] comment */ |
| 167 | − if (!autorepeat && dmi_check_system(dmi_use_low_level_irq)) { | |
| 178 | + if (!autorepeat && (use_low_level_irq || | |
| 179 | + dmi_check_system(dmi_use_low_level_irq))) { | |
| 168 | 180 | irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); |
| 169 | 181 | gpio_keys[n_buttons].irq = irq; |
| 170 | 182 | gpio_keys[n_buttons].gpio = -ENOENT; |
| @@ -192,6 +192,7 @@ static const char * const smbus_pnp_ids[] = { · 191 unmodified lines | ||
| 192 | 192 | "SYN3221", /* HP 15-ay000 */ |
| 193 | 193 | "SYN323d", /* HP Spectre X360 13-w013dx */ |
| 194 | 194 | "SYN3257", /* HP Envy 13-ad105ng */ |
| 195 | + "SYN3286", /* HP Laptop 15-da3001TU */ | |
| 195 | 196 | NULL |
| 196 | 197 | }; |
| 197 | 198 | |
| @@ -115,18 +115,18 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = { · 114 unmodified lines | ||
| 115 | 115 | .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_NEVER) |
| 116 | 116 | }, |
| 117 | 117 | { |
| 118 | − /* ASUS ZenBook UX425UA */ | |
| 118 | + /* ASUS ZenBook UX425UA/QA */ | |
| 119 | 119 | .matches = { |
| 120 | 120 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 121 | − DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA"), | |
| 121 | + DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425"), | |
| 122 | 122 | }, |
| 123 | 123 | .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) |
| 124 | 124 | }, |
| 125 | 125 | { |
| 126 | − /* ASUS ZenBook UM325UA */ | |
| 126 | + /* ASUS ZenBook UM325UA/QA */ | |
| 127 | 127 | .matches = { |
| 128 | 128 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 129 | − DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325UA_UM325UA"), | |
| 129 | + DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX325"), | |
| 130 | 130 | }, |
| 131 | 131 | .driver_data = (void *)(SERIO_QUIRK_PROBE_DEFER | SERIO_QUIRK_RESET_NEVER) |
| 132 | 132 | }, |
| @@ -1543,8 +1543,6 @@ static int i8042_probe(struct platform_device *dev) · 1542 unmodified lines | ||
| 1543 | 1543 | { |
| 1544 | 1544 | int error; |
| 1545 | 1545 | |
| 1546 | − i8042_platform_device = dev; | |
| 1547 | − | |
| 1548 | 1546 | if (i8042_reset == I8042_RESET_ALWAYS) { |
| 1549 | 1547 | error = i8042_controller_selftest(); |
| 1550 | 1548 | if (error) |
| @@ -1582,7 +1580,6 @@ static int i8042_probe(struct platform_device *dev) · 31 unmodified lines | ||
| 1582 | 1580 | i8042_free_aux_ports(); /* in case KBD failed but AUX not */ |
| 1583 | 1581 | i8042_free_irqs(); |
| 1584 | 1582 | i8042_controller_reset(false); |
| 1585 | − i8042_platform_device = NULL; | |
| 1586 | 1583 | |
| 1587 | 1584 | return error; |
| 1588 | 1585 | } |
| @@ -1592,7 +1589,6 @@ static int i8042_remove(struct platform_device *dev) · 3 unmodified lines | ||
| 1592 | 1589 | i8042_unregister_ports(); |
| 1593 | 1590 | i8042_free_irqs(); |
| 1594 | 1591 | i8042_controller_reset(false); |
| 1595 | − i8042_platform_device = NULL; | |
| 1596 | 1592 | |
| 1597 | 1593 | return 0; |
| 1598 | 1594 | } |
| @@ -1158,6 +1158,7 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) · 1157 unmodified lines | ||
| 1158 | 1158 | input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); |
| 1159 | 1159 | input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); |
| 1160 | 1160 | |
| 1161 | +retry_read_config: | |
| 1161 | 1162 | /* Read configuration and apply touchscreen parameters */ |
| 1162 | 1163 | goodix_read_config(ts); |
| 1163 | 1164 | |
| @@ -1165,6 +1166,16 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) · 1 unmodified line | ||
| 1165 | 1166 | touchscreen_parse_properties(ts->input_dev, true, &ts->prop); |
| 1166 | 1167 | |
| 1167 | 1168 | if (!ts->prop.max_x || !ts->prop.max_y || !ts->max_touch_num) { |
| 1169 | + if (!ts->reset_controller_at_probe && | |
| 1170 | + ts->irq_pin_access_method != IRQ_PIN_ACCESS_NONE) { | |
| 1171 | + dev_info(&ts->client->dev, "Config not set, resetting controller\n"); | |
| 1172 | + /* Retry after a controller reset */ | |
| 1173 | + ts->reset_controller_at_probe = true; | |
| 1174 | + error = goodix_reset(ts); | |
| 1175 | + if (error) | |
| 1176 | + return error; | |
| 1177 | + goto retry_read_config; | |
| 1178 | + } | |
| 1168 | 1179 | dev_err(&ts->client->dev, |
| 1169 | 1180 | "Invalid config (%d, %d, %d), using defaults\n", |
| 1170 | 1181 | ts->prop.max_x, ts->prop.max_y, ts->max_touch_num); |
| @@ -211,12 +211,14 @@ static int raydium_i2c_send(struct i2c_client *client, · 210 unmodified lines | ||
| 211 | 211 | |
| 212 | 212 | error = raydium_i2c_xfer(client, addr, xfer, ARRAY_SIZE(xfer)); |
| 213 | 213 | if (likely(!error)) |
| 214 | − return 0; | |
| 214 | + goto out; | |
| 215 | 215 | |
| 216 | 216 | msleep(RM_RETRY_DELAY_MS); |
| 217 | 217 | } while (++tries < RM_MAX_RETRIES); |
| 218 | 218 | |
| 219 | 219 | dev_err(&client->dev, "%s failed: %d\n", __func__, error); |
| 220 | +out: | |
| 221 | + kfree(tx_buf); | |
| 220 | 222 | return error; |
| 221 | 223 | } |
| 222 | 224 | |
| @@ -820,6 +820,7 @@ int __init dmar_dev_scope_init(void) · 819 unmodified lines | ||
| 820 | 820 | info = dmar_alloc_pci_notify_info(dev, |
| 821 | 821 | BUS_NOTIFY_ADD_DEVICE); |
| 822 | 822 | if (!info) { |
| 823 | + pci_dev_put(dev); | |
| 823 | 824 | return dmar_dev_scope_status; |
| 824 | 825 | } else { |
| 825 | 826 | dmar_pci_bus_add_dev(info); |
| @@ -959,11 +959,9 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain, · 958 unmodified lines | ||
| 959 | 959 | |
| 960 | 960 | domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE); |
| 961 | 961 | pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE; |
| 962 | − if (domain_use_first_level(domain)) { | |
| 963 | − pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US; | |
| 964 | − if (iommu_is_dma_domain(&domain->domain)) | |
| 965 | − pteval |= DMA_FL_PTE_ACCESS; | |
| 966 | − } | |
| 962 | + if (domain_use_first_level(domain)) | |
| 963 | + pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US | DMA_FL_PTE_ACCESS; | |
| 964 | + | |
| 967 | 965 | if (cmpxchg64(&pte->val, 0ULL, pteval)) |
| 968 | 966 | /* Someone else set it while we were thinking; use theirs. */ |
| 969 | 967 | free_pgtable_page(tmp_page); |
| @@ -1398,6 +1396,24 @@ static void domain_update_iotlb(struct dmar_domain *domain) · 428 unmodified lines | ||
| 1398 | 1396 | spin_unlock_irqrestore(&domain->lock, flags); |
| 1399 | 1397 | } |
| 1400 | 1398 | |
| 1399 | +/* | |
| 1400 | + * The extra devTLB flush quirk impacts those QAT devices with PCI device | |
| 1401 | + * IDs ranging from 0x4940 to 0x4943. It is exempted from risky_device() | |
| 1402 | + * check because it applies only to the built-in QAT devices and it doesn't | |
| 1403 | + * grant additional privileges. | |
| 1404 | + */ | |
| 1405 | +#define BUGGY_QAT_DEVID_MASK 0x494c | |
| 1406 | +static bool dev_needs_extra_dtlb_flush(struct pci_dev *pdev) | |
| 1407 | +{ | |
| 1408 | + if (pdev->vendor != PCI_VENDOR_ID_INTEL) | |
| 1409 | + return false; | |
| 1410 | + | |
| 1411 | + if ((pdev->device & 0xfffc) != BUGGY_QAT_DEVID_MASK) | |
| 1412 | + return false; | |
| 1413 | + | |
| 1414 | + return true; | |
| 1415 | +} | |
| 1416 | + | |
| 1401 | 1417 | static void iommu_enable_pci_caps(struct device_domain_info *info) |
| 1402 | 1418 | { |
| 1403 | 1419 | struct pci_dev *pdev; |
| @@ -1480,6 +1496,7 @@ static void __iommu_flush_dev_iotlb(struct device_domain_info *info, · 76 unmodified lines | ||
| 1480 | 1496 | qdep = info->ats_qdep; |
| 1481 | 1497 | qi_flush_dev_iotlb(info->iommu, sid, info->pfsid, |
| 1482 | 1498 | qdep, addr, mask); |
| 1499 | + quirk_extra_dev_tlb_flush(info, addr, mask, PASID_RID2PASID, qdep); | |
| 1483 | 1500 | } |
| 1484 | 1501 | |
| 1485 | 1502 | static void iommu_flush_dev_iotlb(struct dmar_domain *domain, |
| @@ -3856,8 +3873,10 @@ static inline bool has_external_pci(void) · 2370 unmodified lines | ||
| 3856 | 3873 | struct pci_dev *pdev = NULL; |
| 3857 | 3874 | |
| 3858 | 3875 | for_each_pci_dev(pdev) |
| 3859 | − if (pdev->external_facing) | |
| 3876 | + if (pdev->external_facing) { | |
| 3877 | + pci_dev_put(pdev); | |
| 3860 | 3878 | return true; |
| 3879 | + } | |
| 3861 | 3880 | |
| 3862 | 3881 | return false; |
| 3863 | 3882 | } |
| @@ -4492,9 +4511,10 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev) · 628 unmodified lines | ||
| 4492 | 4511 | if (dev_is_pci(dev)) { |
| 4493 | 4512 | if (ecap_dev_iotlb_support(iommu->ecap) && |
| 4494 | 4513 | pci_ats_supported(pdev) && |
| 4495 | − dmar_ats_supported(pdev, iommu)) | |
| 4514 | + dmar_ats_supported(pdev, iommu)) { | |
| 4496 | 4515 | info->ats_supported = 1; |
| 4497 | − | |
| 4516 | + info->dtlb_extra_inval = dev_needs_extra_dtlb_flush(pdev); | |
| 4517 | + } | |
| 4498 | 4518 | if (sm_supported(iommu)) { |
| 4499 | 4519 | if (pasid_supported(iommu)) { |
| 4500 | 4520 | int features = pci_pasid_features(pdev); |
| @@ -4933,3 +4953,48 @@ static void __init check_tylersburg_isoch(void) · 432 unmodified lines | ||
| 4933 | 4953 | pr_warn("Recommended TLB entries for ISOCH unit is 16; your BIOS set %d\n", |
| 4934 | 4954 | vtisochctrl); |
| 4935 | 4955 | } |
| 4956 | + | |
| 4957 | +/* | |
| 4958 | + * Here we deal with a device TLB defect where device may inadvertently issue ATS | |
| 4959 | + * invalidation completion before posted writes initiated with translated address | |
| 4960 | + * that utilized translations matching the invalidation address range, violating | |
| 4961 | + * the invalidation completion ordering. | |
| 4962 | + * Therefore, any use cases that cannot guarantee DMA is stopped before unmap is | |
| 4963 | + * vulnerable to this defect. In other words, any dTLB invalidation initiated not | |
| 4964 | + * under the control of the trusted/privileged host device driver must use this | |
| 4965 | + * quirk. | |
| 4966 | + * Device TLBs are invalidated under the following six conditions: | |
| 4967 | + * 1. Device driver does DMA API unmap IOVA | |
| 4968 | + * 2. Device driver unbind a PASID from a process, sva_unbind_device() | |
| 4969 | + * 3. PASID is torn down, after PASID cache is flushed. e.g. process | |
| 4970 | + * exit_mmap() due to crash | |
| 4971 | + * 4. Under SVA usage, called by mmu_notifier.invalidate_range() where | |
| 4972 | + * VM has to free pages that were unmapped | |
| 4973 | + * 5. Userspace driver unmaps a DMA buffer | |
| 4974 | + * 6. Cache invalidation in vSVA usage (upcoming) | |
| 4975 | + * | |
| 4976 | + * For #1 and #2, device drivers are responsible for stopping DMA traffic | |
| 4977 | + * before unmap/unbind. For #3, iommu driver gets mmu_notifier to | |
| 4978 | + * invalidate TLB the same way as normal user unmap which will use this quirk. | |
| 4979 | + * The dTLB invalidation after PASID cache flush does not need this quirk. | |
| 4980 | + * | |
| 4981 | + * As a reminder, #6 will *NEED* this quirk as we enable nested translation. | |
| 4982 | + */ | |
| 4983 | +void quirk_extra_dev_tlb_flush(struct device_domain_info *info, | |
| 4984 | + unsigned long address, unsigned long mask, | |
| 4985 | + u32 pasid, u16 qdep) | |
| 4986 | +{ | |
| 4987 | + u16 sid; | |
| 4988 | + | |
| 4989 | + if (likely(!info->dtlb_extra_inval)) | |
| 4990 | + return; | |
| 4991 | + | |
| 4992 | + sid = PCI_DEVID(info->bus, info->devfn); | |
| 4993 | + if (pasid == PASID_RID2PASID) { | |
| 4994 | + qi_flush_dev_iotlb(info->iommu, sid, info->pfsid, | |
| 4995 | + qdep, address, mask); | |
| 4996 | + } else { | |
| 4997 | + qi_flush_dev_iotlb_pasid(info->iommu, sid, info->pfsid, | |
| 4998 | + pasid, qdep, address, mask); | |
| 4999 | + } | |
| 5000 | +} | |
| @@ -623,6 +623,7 @@ struct device_domain_info { · 622 unmodified lines | ||
| 623 | 623 | u8 pri_enabled:1; |
| 624 | 624 | u8 ats_supported:1; |
| 625 | 625 | u8 ats_enabled:1; |
| 626 | + u8 dtlb_extra_inval:1; /* Quirk for devices need extra flush */ | |
| 626 | 627 | u8 ats_qdep; |
| 627 | 628 | struct device *dev; /* it's NULL for PCIe-to-PCI bridge */ |
| 628 | 629 | struct intel_iommu *iommu; /* IOMMU used by this device */ |
| @@ -728,6 +729,9 @@ void qi_flush_piotlb(struct intel_iommu *iommu, u16 did, u32 pasid, u64 addr, · 99 unmodified lines | ||
| 728 | 729 | void qi_flush_dev_iotlb_pasid(struct intel_iommu *iommu, u16 sid, u16 pfsid, |
| 729 | 730 | u32 pasid, u16 qdep, u64 addr, |
| 730 | 731 | unsigned int size_order); |
| 732 | +void quirk_extra_dev_tlb_flush(struct device_domain_info *info, | |
| 733 | + unsigned long address, unsigned long pages, | |
| 734 | + u32 pasid, u16 qdep); | |
| 731 | 735 | void qi_flush_pasid_cache(struct intel_iommu *iommu, u16 did, u64 granu, |
| 732 | 736 | u32 pasid); |
| 733 | 737 | |
| @@ -642,7 +642,7 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu, · 641 unmodified lines | ||
| 642 | 642 | * Since it is a second level only translation setup, we should |
| 643 | 643 | * set SRE bit as well (addresses are expected to be GPAs). |
| 644 | 644 | */ |
| 645 | − if (pasid != PASID_RID2PASID) | |
| 645 | + if (pasid != PASID_RID2PASID && ecap_srs(iommu->ecap)) | |
| 646 | 646 | pasid_set_sre(pte); |
| 647 | 647 | pasid_set_present(pte); |
| 648 | 648 | spin_unlock(&iommu->lock); |
| @@ -685,7 +685,8 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu, · 36 unmodified lines | ||
| 685 | 685 | * We should set SRE bit as well since the addresses are expected |
| 686 | 686 | * to be GPAs. |
| 687 | 687 | */ |
| 688 | − pasid_set_sre(pte); | |
| 688 | + if (ecap_srs(iommu->ecap)) | |
| 689 | + pasid_set_sre(pte); | |
| 689 | 690 | pasid_set_present(pte); |
| 690 | 691 | spin_unlock(&iommu->lock); |
| 691 | 692 | |
| @@ -184,10 +184,13 @@ static void __flush_svm_range_dev(struct intel_svm *svm, · 183 unmodified lines | ||
| 184 | 184 | return; |
| 185 | 185 | |
| 186 | 186 | qi_flush_piotlb(sdev->iommu, sdev->did, svm->pasid, address, pages, ih); |
| 187 | − if (info->ats_enabled) | |
| 187 | + if (info->ats_enabled) { | |
| 188 | 188 | qi_flush_dev_iotlb_pasid(sdev->iommu, sdev->sid, info->pfsid, |
| 189 | 189 | svm->pasid, sdev->qdep, address, |
| 190 | 190 | order_base_2(pages)); |
| 191 | + quirk_extra_dev_tlb_flush(info, address, order_base_2(pages), | |
| 192 | + svm->pasid, sdev->qdep); | |
| 193 | + } | |
| 191 | 194 | } |
| 192 | 195 | |
| 193 | 196 | static void intel_flush_svm_range_dev(struct intel_svm *svm, |
| @@ -745,12 +748,16 @@ bad_req: · 551 unmodified lines | ||
| 745 | 748 | * If prq is to be handled outside iommu driver via receiver of |
| 746 | 749 | * the fault notifiers, we skip the page response here. |
| 747 | 750 | */ |
| 748 | − if (!pdev || intel_svm_prq_report(iommu, &pdev->dev, req)) | |
| 749 | − handle_bad_prq_event(iommu, req, QI_RESP_INVALID); | |
| 751 | + if (!pdev) | |
| 752 | + goto bad_req; | |
| 750 | 753 | |
| 751 | − trace_prq_report(iommu, &pdev->dev, req->qw_0, req->qw_1, | |
| 752 | − req->priv_data[0], req->priv_data[1], | |
| 753 | − iommu->prq_seq_number++); | |
| 754 | + if (intel_svm_prq_report(iommu, &pdev->dev, req)) | |
| 755 | + handle_bad_prq_event(iommu, req, QI_RESP_INVALID); | |
| 756 | + else | |
| 757 | + trace_prq_report(iommu, &pdev->dev, req->qw_0, req->qw_1, | |
| 758 | + req->priv_data[0], req->priv_data[1], | |
| 759 | + iommu->prq_seq_number++); | |
| 760 | + pci_dev_put(pdev); | |
| 754 | 761 | prq_advance: |
| 755 | 762 | head = (head + sizeof(*req)) & PRQ_RING_MASK; |
| 756 | 763 | } |
| @@ -956,7 +956,7 @@ nj_release(struct tiger_hw *card) · 955 unmodified lines | ||
| 956 | 956 | } |
| 957 | 957 | if (card->irq > 0) |
| 958 | 958 | free_irq(card->irq, card); |
| 959 | − if (card->isac.dch.dev.dev.class) | |
| 959 | + if (device_is_registered(&card->isac.dch.dev.dev)) | |
| 960 | 960 | mISDN_unregister_device(&card->isac.dch.dev); |
| 961 | 961 | |
| 962 | 962 | for (i = 0; i < 2; i++) { |
| @@ -222,7 +222,7 @@ mISDN_register_device(struct mISDNdevice *dev, · 221 unmodified lines | ||
| 222 | 222 | |
| 223 | 223 | err = get_free_devid(); |
| 224 | 224 | if (err < 0) |
| 225 | − goto error1; | |
| 225 | + return err; | |
| 226 | 226 | dev->id = err; |
| 227 | 227 | |
| 228 | 228 | device_initialize(&dev->dev); |
| @@ -233,11 +233,12 @@ mISDN_register_device(struct mISDNdevice *dev, · 4 unmodified lines | ||
| 233 | 233 | if (debug & DEBUG_CORE) |
| 234 | 234 | printk(KERN_DEBUG "mISDN_register %s %d\n", |
| 235 | 235 | dev_name(&dev->dev), dev->id); |
| 236 | + dev->dev.class = &mISDN_class; | |
| 237 | + | |
| 236 | 238 | err = create_stack(dev); |
| 237 | 239 | if (err) |
| 238 | 240 | goto error1; |
| 239 | 241 | |
| 240 | − dev->dev.class = &mISDN_class; | |
| 241 | 242 | dev->dev.platform_data = dev; |
| 242 | 243 | dev->dev.parent = parent; |
| 243 | 244 | dev_set_drvdata(&dev->dev, dev); |
| @@ -249,8 +250,8 @@ mISDN_register_device(struct mISDNdevice *dev, · 5 unmodified lines | ||
| 249 | 250 | |
| 250 | 251 | error3: |
| 251 | 252 | delete_stack(dev); |
| 252 | − return err; | |
| 253 | 253 | error1: |
| 254 | + put_device(&dev->dev); | |
| 254 | 255 | return err; |
| 255 | 256 | |
| 256 | 257 | } |
| @@ -77,6 +77,7 @@ int mISDN_dsp_element_register(struct mISDN_dsp_element *elem) · 76 unmodified lines | ||
| 77 | 77 | if (!entry) |
| 78 | 78 | return -ENOMEM; |
| 79 | 79 | |
| 80 | + INIT_LIST_HEAD(&entry->list); | |
| 80 | 81 | entry->elem = elem; |
| 81 | 82 | |
| 82 | 83 | entry->dev.class = elements_class; |
| @@ -107,7 +108,7 @@ err2: · 24 unmodified lines | ||
| 107 | 108 | device_unregister(&entry->dev); |
| 108 | 109 | return ret; |
| 109 | 110 | err1: |
| 110 | − kfree(entry); | |
| 111 | + put_device(&entry->dev); | |
| 111 | 112 | return ret; |
| 112 | 113 | } |
| 113 | 114 | EXPORT_SYMBOL(mISDN_dsp_element_register); |
| @@ -1858,6 +1858,8 @@ bad: · 1857 unmodified lines | ||
| 1858 | 1858 | dm_io_client_destroy(c->dm_io); |
| 1859 | 1859 | bad_dm_io: |
| 1860 | 1860 | mutex_destroy(&c->lock); |
| 1861 | + if (c->no_sleep) | |
| 1862 | + static_branch_dec(&no_sleep_enabled); | |
| 1861 | 1863 | kfree(c); |
| 1862 | 1864 | bad_client: |
| 1863 | 1865 | return ERR_PTR(r); |
| @@ -3630,6 +3630,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits) · 3629 unmodified lines | ||
| 3630 | 3630 | limits->physical_block_size = |
| 3631 | 3631 | max_t(unsigned, limits->physical_block_size, cc->sector_size); |
| 3632 | 3632 | limits->io_min = max_t(unsigned, limits->io_min, cc->sector_size); |
| 3633 | + limits->dma_alignment = limits->logical_block_size - 1; | |
| 3633 | 3634 | } |
| 3634 | 3635 | |
| 3635 | 3636 | static struct target_type crypt_target = { |
| @@ -263,6 +263,7 @@ struct dm_integrity_c { · 262 unmodified lines | ||
| 263 | 263 | |
| 264 | 264 | struct completion crypto_backoff; |
| 265 | 265 | |
| 266 | + bool wrote_to_journal; | |
| 266 | 267 | bool journal_uptodate; |
| 267 | 268 | bool just_formatted; |
| 268 | 269 | bool recalculate_flag; |
| @@ -2375,6 +2376,8 @@ static void integrity_commit(struct work_struct *w) · 2106 unmodified lines | ||
| 2375 | 2376 | if (!commit_sections) |
| 2376 | 2377 | goto release_flush_bios; |
| 2377 | 2378 | |
| 2379 | + ic->wrote_to_journal = true; | |
| 2380 | + | |
| 2378 | 2381 | i = commit_start; |
| 2379 | 2382 | for (n = 0; n < commit_sections; n++) { |
| 2380 | 2383 | for (j = 0; j < ic->journal_section_entries; j++) { |
| @@ -2591,10 +2594,6 @@ static void integrity_writer(struct work_struct *w) · 210 unmodified lines | ||
| 2591 | 2594 | |
| 2592 | 2595 | unsigned prev_free_sectors; |
| 2593 | 2596 | |
| 2594 | − /* the following test is not needed, but it tests the replay code */ | |
| 2595 | − if (unlikely(dm_post_suspending(ic->ti)) && !ic->meta_dev) | |
| 2596 | − return; | |
| 2597 | − | |
| 2598 | 2597 | spin_lock_irq(&ic->endio_wait.lock); |
| 2599 | 2598 | write_start = ic->committed_section; |
| 2600 | 2599 | write_sections = ic->n_committed_sections; |
| @@ -3101,10 +3100,17 @@ static void dm_integrity_postsuspend(struct dm_target *ti) · 500 unmodified lines | ||
| 3101 | 3100 | drain_workqueue(ic->commit_wq); |
| 3102 | 3101 | |
| 3103 | 3102 | if (ic->mode == 'J') { |
| 3104 | − if (ic->meta_dev) | |
| 3105 | − queue_work(ic->writer_wq, &ic->writer_work); | |
| 3103 | + queue_work(ic->writer_wq, &ic->writer_work); | |
| 3106 | 3104 | drain_workqueue(ic->writer_wq); |
| 3107 | 3105 | dm_integrity_flush_buffers(ic, true); |
| 3106 | + if (ic->wrote_to_journal) { | |
| 3107 | + init_journal(ic, ic->free_section, | |
| 3108 | + ic->journal_sections - ic->free_section, ic->commit_seq); | |
| 3109 | + if (ic->free_section) { | |
| 3110 | + init_journal(ic, 0, ic->free_section, | |
| 3111 | + next_commit_seq(ic->commit_seq)); | |
| 3112 | + } | |
| 3113 | + } | |
| 3108 | 3114 | } |
| 3109 | 3115 | |
| 3110 | 3116 | if (ic->mode == 'B') { |
| @@ -3132,6 +3138,8 @@ static void dm_integrity_resume(struct dm_target *ti) · 21 unmodified lines | ||
| 3132 | 3138 | |
| 3133 | 3139 | DEBUG_print("resume\n"); |
| 3134 | 3140 | |
| 3141 | + ic->wrote_to_journal = false; | |
| 3142 | + | |
| 3135 | 3143 | if (ic->provided_data_sectors != old_provided_data_sectors) { |
| 3136 | 3144 | if (ic->provided_data_sectors > old_provided_data_sectors && |
| 3137 | 3145 | ic->mode == 'B' && |
| @@ -3370,6 +3378,7 @@ static void dm_integrity_io_hints(struct dm_target *ti, struct queue_limits *lim · 232 unmodified lines | ||
| 3370 | 3378 | limits->logical_block_size = ic->sectors_per_block << SECTOR_SHIFT; |
| 3371 | 3379 | limits->physical_block_size = ic->sectors_per_block << SECTOR_SHIFT; |
| 3372 | 3380 | blk_limits_io_min(limits, ic->sectors_per_block << SECTOR_SHIFT); |
| 3381 | + limits->dma_alignment = limits->logical_block_size - 1; | |
| 3373 | 3382 | } |
| 3374 | 3383 | } |
| 3375 | 3384 | |
| @@ -655,7 +655,7 @@ static void list_version_get_needed(struct target_type *tt, void *needed_param) · 654 unmodified lines | ||
| 655 | 655 | size_t *needed = needed_param; |
| 656 | 656 | |
| 657 | 657 | *needed += sizeof(struct dm_target_versions); |
| 658 | − *needed += strlen(tt->name); | |
| 658 | + *needed += strlen(tt->name) + 1; | |
| 659 | 659 | *needed += ALIGN_MASK; |
| 660 | 660 | } |
| 661 | 661 | |
| @@ -720,7 +720,7 @@ static int __list_versions(struct dm_ioctl *param, size_t param_size, const char · 58 unmodified lines | ||
| 720 | 720 | iter_info.old_vers = NULL; |
| 721 | 721 | iter_info.vers = vers; |
| 722 | 722 | iter_info.flags = 0; |
| 723 | − iter_info.end = (char *)vers+len; | |
| 723 | + iter_info.end = (char *)vers + needed; | |
| 724 | 724 | |
| 725 | 725 | /* |
| 726 | 726 | * Now loop through filling out the names & versions. |
| @@ -875,6 +875,7 @@ static void log_writes_io_hints(struct dm_target *ti, struct queue_limits *limit · 874 unmodified lines | ||
| 875 | 875 | limits->logical_block_size = bdev_logical_block_size(lc->dev->bdev); |
| 876 | 876 | limits->physical_block_size = bdev_physical_block_size(lc->dev->bdev); |
| 877 | 877 | limits->io_min = limits->physical_block_size; |
| 878 | + limits->dma_alignment = limits->logical_block_size - 1; | |
| 878 | 879 | } |
| 879 | 880 | |
| 880 | 881 | #if IS_ENABLED(CONFIG_FS_DAX) |
| @@ -35,11 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | int get_vaddr_frames(unsigned long start, unsigned int nr_frames, |
| 36 | 36 | struct frame_vector *vec) |
| 37 | 37 | { |
| 38 | − struct mm_struct *mm = current->mm; | |
| 39 | − struct vm_area_struct *vma; | |
| 40 | − int ret_pin_user_pages_fast = 0; | |
| 41 | − int ret = 0; | |
| 42 | − int err; | |
| 38 | + int ret; | |
| 43 | 39 | |
| 44 | 40 | if (nr_frames == 0) |
| 45 | 41 | return 0; |
| @@ -52,57 +48,17 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, · 6 unmodified lines | ||
| 52 | 48 | ret = pin_user_pages_fast(start, nr_frames, |
| 53 | 49 | FOLL_FORCE | FOLL_WRITE | FOLL_LONGTERM, |
| 54 | 50 | (struct page **)(vec->ptrs)); |
| 55 | − if (ret > 0) { | |
| 56 | − vec->got_ref = true; | |
| 57 | − vec->is_pfns = false; | |
| 58 | − goto out_unlocked; | |
| 59 | − } | |
| 60 | − ret_pin_user_pages_fast = ret; | |
| 61 | − | |
| 62 | − mmap_read_lock(mm); | |
| 63 | − vec->got_ref = false; | |
| 64 | − vec->is_pfns = true; | |
| 65 | − ret = 0; | |
| 66 | − do { | |
| 67 | − unsigned long *nums = frame_vector_pfns(vec); | |
| 68 | − | |
| 69 | − vma = vma_lookup(mm, start); | |
| 70 | − if (!vma) | |
| 71 | − break; | |
| 72 | − | |
| 73 | − while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) { | |
| 74 | − err = follow_pfn(vma, start, &nums[ret]); | |
| 75 | − if (err) { | |
| 76 | − if (ret) | |
| 77 | − goto out; | |
| 78 | − // If follow_pfn() returns -EINVAL, then this | |
| 79 | − // is not an IO mapping or a raw PFN mapping. | |
| 80 | − // In that case, return the original error from | |
| 81 | − // pin_user_pages_fast(). Otherwise this | |
| 82 | − // function would return -EINVAL when | |
| 83 | − // pin_user_pages_fast() returned -ENOMEM, | |
| 84 | − // which makes debugging hard. | |
| 85 | − if (err == -EINVAL && ret_pin_user_pages_fast) | |
| 86 | − ret = ret_pin_user_pages_fast; | |
| 87 | − else | |
| 88 | − ret = err; | |
| 89 | − goto out; | |
| 90 | − } | |
| 91 | − start += PAGE_SIZE; | |
| 92 | − ret++; | |
| 93 | − } | |
| 94 | − /* Bail out if VMA doesn't completely cover the tail page. */ | |
| 95 | − if (start < vma->vm_end) | |
| 96 | − break; | |
| 97 | − } while (ret < nr_frames); | |
| 98 | −out: | |
| 99 | − mmap_read_unlock(mm); | |
| 100 | −out_unlocked: | |
| 101 | − if (!ret) | |
| 102 | − ret = -EFAULT; | |
| 103 | − if (ret > 0) | |
| 104 | − vec->nr_frames = ret; | |
| 105 | − return ret; | |
| 51 | + vec->got_ref = true; | |
| 52 | + vec->is_pfns = false; | |
| 53 | + vec->nr_frames = ret; | |
| 54 | + | |
| 55 | + if (likely(ret > 0)) | |
| 56 | + return ret; | |
| 57 | + | |
| 58 | + /* This used to (racily) return non-refcounted pfns. Let people know */ | |
| 59 | + WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping"); | |
| 60 | + vec->nr_frames = 0; | |
| 61 | + return ret ? ret : -EFAULT; | |
| 106 | 62 | } |
| 107 | 63 | EXPORT_SYMBOL(get_vaddr_frames); |
| 108 | 64 | |
| @@ -854,6 +854,7 @@ static int qp_notify_peer_local(bool attach, struct vmci_handle handle) · 853 unmodified lines | ||
| 854 | 854 | u32 context_id = vmci_get_context_id(); |
| 855 | 855 | struct vmci_event_qp ev; |
| 856 | 856 | |
| 857 | + memset(&ev, 0, sizeof(ev)); | |
| 857 | 858 | ev.msg.hdr.dst = vmci_make_handle(context_id, VMCI_EVENT_HANDLER); |
| 858 | 859 | ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, |
| 859 | 860 | VMCI_CONTEXT_RESOURCE_ID); |
| @@ -1467,6 +1468,7 @@ static int qp_notify_peer(bool attach, · 607 unmodified lines | ||
| 1467 | 1468 | * kernel. |
| 1468 | 1469 | */ |
| 1469 | 1470 | |
| 1471 | + memset(&ev, 0, sizeof(ev)); | |
| 1470 | 1472 | ev.msg.hdr.dst = vmci_make_handle(peer_id, VMCI_EVENT_HANDLER); |
| 1471 | 1473 | ev.msg.hdr.src = vmci_make_handle(VMCI_HYPERVISOR_CONTEXT_ID, |
| 1472 | 1474 | VMCI_CONTEXT_RESOURCE_ID); |
| @@ -1134,7 +1134,13 @@ u32 mmc_select_voltage(struct mmc_host *host, u32 ocr) · 1133 unmodified lines | ||
| 1134 | 1134 | mmc_power_cycle(host, ocr); |
| 1135 | 1135 | } else { |
| 1136 | 1136 | bit = fls(ocr) - 1; |
| 1137 | − ocr &= 3 << bit; | |
| 1137 | + /* | |
| 1138 | + * The bit variable represents the highest voltage bit set in | |
| 1139 | + * the OCR register. | |
| 1140 | + * To keep a range of 2 values (e.g. 3.2V/3.3V and 3.3V/3.4V), | |
| 1141 | + * we must shift the mask '3' with (bit - 1). | |
| 1142 | + */ | |
| 1143 | + ocr &= 3 << (bit - 1); | |
| 1138 | 1144 | if (bit != host->ios.vdd) |
| 1139 | 1145 | dev_warn(mmc_dev(host), "exceeding card's volts\n"); |
| 1140 | 1146 | } |
| @@ -1478,6 +1484,11 @@ void mmc_init_erase(struct mmc_card *card) · 337 unmodified lines | ||
| 1478 | 1484 | card->pref_erase = 0; |
| 1479 | 1485 | } |
| 1480 | 1486 | |
| 1487 | +static bool is_trim_arg(unsigned int arg) | |
| 1488 | +{ | |
| 1489 | + return (arg & MMC_TRIM_OR_DISCARD_ARGS) && arg != MMC_DISCARD_ARG; | |
| 1490 | +} | |
| 1491 | + | |
| 1481 | 1492 | static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, |
| 1482 | 1493 | unsigned int arg, unsigned int qty) |
| 1483 | 1494 | { |
| @@ -1760,7 +1771,7 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, · 276 unmodified lines | ||
| 1760 | 1771 | !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN)) |
| 1761 | 1772 | return -EOPNOTSUPP; |
| 1762 | 1773 | |
| 1763 | − if (mmc_card_mmc(card) && (arg & MMC_TRIM_ARGS) && | |
| 1774 | + if (mmc_card_mmc(card) && is_trim_arg(arg) && | |
| 1764 | 1775 | !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)) |
| 1765 | 1776 | return -EOPNOTSUPP; |
| 1766 | 1777 | |
| @@ -1790,7 +1801,7 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr, · 23 unmodified lines | ||
| 1790 | 1801 | * identified by the card->eg_boundary flag. |
| 1791 | 1802 | */ |
| 1792 | 1803 | rem = card->erase_size - (from % card->erase_size); |
| 1793 | − if ((arg & MMC_TRIM_ARGS) && (card->eg_boundary) && (nr > rem)) { | |
| 1804 | + if ((arg & MMC_TRIM_OR_DISCARD_ARGS) && card->eg_boundary && nr > rem) { | |
| 1794 | 1805 | err = mmc_do_erase(card, from, from + rem - 1, arg); |
| 1795 | 1806 | from += rem; |
| 1796 | 1807 | if ((err) || (to <= from)) |
| @@ -3179,7 +3179,8 @@ static int __mmc_test_register_dbgfs_file(struct mmc_card *card, · 3178 unmodified lines | ||
| 3179 | 3179 | struct mmc_test_dbgfs_file *df; |
| 3180 | 3180 | |
| 3181 | 3181 | if (card->debugfs_root) |
| 3182 | − debugfs_create_file(name, mode, card->debugfs_root, card, fops); | |
| 3182 | + file = debugfs_create_file(name, mode, card->debugfs_root, | |
| 3183 | + card, fops); | |
| 3183 | 3184 | |
| 3184 | 3185 | df = kmalloc(sizeof(*df), GFP_KERNEL); |
| 3185 | 3186 | if (!df) { |
| @@ -2588,13 +2588,11 @@ static int msdc_of_clock_parse(struct platform_device *pdev, · 2587 unmodified lines | ||
| 2588 | 2588 | return PTR_ERR(host->src_clk_cg); |
| 2589 | 2589 | } |
| 2590 | 2590 | |
| 2591 | − host->sys_clk_cg = devm_clk_get_optional(&pdev->dev, "sys_cg"); | |
| 2591 | + /* If present, always enable for this clock gate */ | |
| 2592 | + host->sys_clk_cg = devm_clk_get_optional_enabled(&pdev->dev, "sys_cg"); | |
| 2592 | 2593 | if (IS_ERR(host->sys_clk_cg)) |
| 2593 | 2594 | host->sys_clk_cg = NULL; |
| 2594 | 2595 | |
| 2595 | − /* If present, always enable for this clock gate */ | |
| 2596 | − clk_prepare_enable(host->sys_clk_cg); | |
| 2597 | − | |
| 2598 | 2596 | host->bulk_clks[0].id = "pclk_cg"; |
| 2599 | 2597 | host->bulk_clks[1].id = "axi_cg"; |
| 2600 | 2598 | host->bulk_clks[2].id = "ahb_cg"; |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/bitops.h> |
| 13 | 13 | #include <linux/delay.h> |
| 14 | 14 | |
| 15 | +#include "sdhci-cqhci.h" | |
| 15 | 16 | #include "sdhci-pltfm.h" |
| 16 | 17 | #include "cqhci.h" |
| 17 | 18 | |
| @@ -55,7 +56,7 @@ static void brcmstb_reset(struct sdhci_host *host, u8 mask) · 37 unmodified lines | ||
| 55 | 56 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 56 | 57 | struct sdhci_brcmstb_priv *priv = sdhci_pltfm_priv(pltfm_host); |
| 57 | 58 | |
| 58 | − sdhci_reset(host, mask); | |
| 59 | + sdhci_and_cqhci_reset(host, mask); | |
| 59 | 60 | |
| 60 | 61 | /* Reset will clear this, so re-enable it */ |
| 61 | 62 | if (priv->flags & BRCMSTB_PRIV_FLAGS_GATE_CLOCK) |
| @@ -0,0 +1,24 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ | |
| 2 | +/* | |
| 3 | + * Copyright 2022 The Chromium OS Authors | |
| 4 | + * | |
| 5 | + * Support that applies to the combination of SDHCI and CQHCI, while not | |
| 6 | + * expressing a dependency between the two modules. | |
| 7 | + */ | |
| 8 | + | |
| 9 | +#ifndef __MMC_HOST_SDHCI_CQHCI_H__ | |
| 10 | +#define __MMC_HOST_SDHCI_CQHCI_H__ | |
| 11 | + | |
| 12 | +#include "cqhci.h" | |
| 13 | +#include "sdhci.h" | |
| 14 | + | |
| 15 | +static inline void sdhci_and_cqhci_reset(struct sdhci_host *host, u8 mask) | |
| 16 | +{ | |
| 17 | + if ((host->mmc->caps2 & MMC_CAP2_CQE) && (mask & SDHCI_RESET_ALL) && | |
| 18 | + host->mmc->cqe_private) | |
| 19 | + cqhci_deactivate(host->mmc); | |
| 20 | + | |
| 21 | + sdhci_reset(host, mask); | |
| 22 | +} | |
| 23 | + | |
| 24 | +#endif /* __MMC_HOST_SDHCI_CQHCI_H__ */ | |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/of_device.h> |
| 26 | 26 | #include <linux/pinctrl/consumer.h> |
| 27 | 27 | #include <linux/pm_runtime.h> |
| 28 | +#include "sdhci-cqhci.h" | |
| 28 | 29 | #include "sdhci-pltfm.h" |
| 29 | 30 | #include "sdhci-esdhc.h" |
| 30 | 31 | #include "cqhci.h" |
| @@ -1288,7 +1289,7 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing) · 1257 unmodified lines | ||
| 1288 | 1289 | |
| 1289 | 1290 | static void esdhc_reset(struct sdhci_host *host, u8 mask) |
| 1290 | 1291 | { |
| 1291 | − sdhci_reset(host, mask); | |
| 1292 | + sdhci_and_cqhci_reset(host, mask); | |
| 1292 | 1293 | |
| 1293 | 1294 | sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); |
| 1294 | 1295 | sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); |
| @@ -1511,7 +1512,7 @@ static void esdhc_cqe_enable(struct mmc_host *mmc) · 216 unmodified lines | ||
| 1511 | 1512 | * system resume back. |
| 1512 | 1513 | */ |
| 1513 | 1514 | cqhci_writel(cq_host, 0, CQHCI_CTL); |
| 1514 | − if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT) | |
| 1515 | + if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) | |
| 1515 | 1516 | dev_err(mmc_dev(host->mmc), |
| 1516 | 1517 | "failed to exit halt state when enable CQE\n"); |
| 1517 | 1518 | |
| @@ -1671,14 +1672,14 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev) · 153 unmodified lines | ||
| 1671 | 1672 | if (imx_data->socdata->flags & ESDHC_FLAG_ERR004536) |
| 1672 | 1673 | host->quirks |= SDHCI_QUIRK_BROKEN_ADMA; |
| 1673 | 1674 | |
| 1674 | − if (host->caps & MMC_CAP_8_BIT_DATA && | |
| 1675 | + if (host->mmc->caps & MMC_CAP_8_BIT_DATA && | |
| 1675 | 1676 | imx_data->socdata->flags & ESDHC_FLAG_HS400) |
| 1676 | 1677 | host->mmc->caps2 |= MMC_CAP2_HS400; |
| 1677 | 1678 | |
| 1678 | 1679 | if (imx_data->socdata->flags & ESDHC_FLAG_BROKEN_AUTO_CMD23) |
| 1679 | 1680 | host->quirks2 |= SDHCI_QUIRK2_ACMD23_BROKEN; |
| 1680 | 1681 | |
| 1681 | − if (host->caps & MMC_CAP_8_BIT_DATA && | |
| 1682 | + if (host->mmc->caps & MMC_CAP_8_BIT_DATA && | |
| 1682 | 1683 | imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) { |
| 1683 | 1684 | host->mmc->caps2 |= MMC_CAP2_HS400_ES; |
| 1684 | 1685 | host->mmc_host_ops.hs400_enhanced_strobe = |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/firmware/xlnx-zynqmp.h> |
| 26 | 26 | |
| 27 | 27 | #include "cqhci.h" |
| 28 | +#include "sdhci-cqhci.h" | |
| 28 | 29 | #include "sdhci-pltfm.h" |
| 29 | 30 | |
| 30 | 31 | #define SDHCI_ARASAN_VENDOR_REGISTER 0x78 |
| @@ -366,7 +367,7 @@ static void sdhci_arasan_reset(struct sdhci_host *host, u8 mask) · 335 unmodified lines | ||
| 366 | 367 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 367 | 368 | struct sdhci_arasan_data *sdhci_arasan = sdhci_pltfm_priv(pltfm_host); |
| 368 | 369 | |
| 369 | − sdhci_reset(host, mask); | |
| 370 | + sdhci_and_cqhci_reset(host, mask); | |
| 370 | 371 | |
| 371 | 372 | if (sdhci_arasan->quirks & SDHCI_ARASAN_QUIRK_FORCE_CDTEST) { |
| 372 | 373 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); |
| @@ -1749,6 +1749,8 @@ static int amd_probe(struct sdhci_pci_chip *chip) · 1748 unmodified lines | ||
| 1749 | 1749 | } |
| 1750 | 1750 | } |
| 1751 | 1751 | |
| 1752 | + pci_dev_put(smbus_dev); | |
| 1753 | + | |
| 1752 | 1754 | if (gen == AMD_CHIPSET_BEFORE_ML || gen == AMD_CHIPSET_CZ) |
| 1753 | 1755 | chip->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD; |
| 1754 | 1756 | |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #define O2_SD_CAPS 0xE0 |
| 33 | 33 | #define O2_SD_ADMA1 0xE2 |
| 34 | 34 | #define O2_SD_ADMA2 0xE7 |
| 35 | +#define O2_SD_MISC_CTRL2 0xF0 | |
| 35 | 36 | #define O2_SD_INF_MOD 0xF1 |
| 36 | 37 | #define O2_SD_MISC_CTRL4 0xFC |
| 37 | 38 | #define O2_SD_MISC_CTRL 0x1C0 |
| @@ -877,6 +878,12 @@ static int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip) · 839 unmodified lines | ||
| 877 | 878 | /* Set Tuning Windows to 5 */ |
| 878 | 879 | pci_write_config_byte(chip->pdev, |
| 879 | 880 | O2_SD_TUNING_CTRL, 0x55); |
| 881 | + //Adjust 1st and 2nd CD debounce time | |
| 882 | + pci_read_config_dword(chip->pdev, O2_SD_MISC_CTRL2, &scratch_32); | |
| 883 | + scratch_32 &= 0xFFE7FFFF; | |
| 884 | + scratch_32 |= 0x00180000; | |
| 885 | + pci_write_config_dword(chip->pdev, O2_SD_MISC_CTRL2, scratch_32); | |
| 886 | + pci_write_config_dword(chip->pdev, O2_SD_DETECT_SETTING, 1); | |
| 880 | 887 | /* Lock WP */ |
| 881 | 888 | ret = pci_read_config_byte(chip->pdev, |
| 882 | 889 | O2_SD_LOCK_WP, &scratch); |
| @@ -470,7 +470,7 @@ static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) · 469 unmodified lines | ||
| 470 | 470 | } |
| 471 | 471 | |
| 472 | 472 | if (IS_ERR(sprd_host->pinctrl)) |
| 473 | − return 0; | |
| 473 | + goto reset; | |
| 474 | 474 | |
| 475 | 475 | switch (ios->signal_voltage) { |
| 476 | 476 | case MMC_SIGNAL_VOLTAGE_180: |
| @@ -498,6 +498,8 @@ static int sdhci_sprd_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios) · 21 unmodified lines | ||
| 498 | 498 | |
| 499 | 499 | /* Wait for 300 ~ 500 us for pin state stable */ |
| 500 | 500 | usleep_range(300, 500); |
| 501 | + | |
| 502 | +reset: | |
| 501 | 503 | sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); |
| 502 | 504 | |
| 503 | 505 | return 0; |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | #include <soc/tegra/common.h> |
| 30 | 30 | |
| 31 | +#include "sdhci-cqhci.h" | |
| 31 | 32 | #include "sdhci-pltfm.h" |
| 32 | 33 | #include "cqhci.h" |
| 33 | 34 | |
| @@ -367,7 +368,7 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask) · 333 unmodified lines | ||
| 367 | 368 | const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data; |
| 368 | 369 | u32 misc_ctrl, clk_ctrl, pad_ctrl; |
| 369 | 370 | |
| 370 | − sdhci_reset(host, mask); | |
| 371 | + sdhci_and_cqhci_reset(host, mask); | |
| 371 | 372 | |
| 372 | 373 | if (!(mask & SDHCI_RESET_ALL)) |
| 373 | 374 | return; |
| @@ -373,6 +373,7 @@ static void sdhci_init(struct sdhci_host *host, int soft) · 372 unmodified lines | ||
| 373 | 373 | if (soft) { |
| 374 | 374 | /* force clock reconfiguration */ |
| 375 | 375 | host->clock = 0; |
| 376 | + host->reinit_uhs = true; | |
| 376 | 377 | mmc->ops->set_ios(mmc, &mmc->ios); |
| 377 | 378 | } |
| 378 | 379 | } |
| @@ -2293,11 +2294,46 @@ void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing) · 1914 unmodified lines | ||
| 2293 | 2294 | } |
| 2294 | 2295 | EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling); |
| 2295 | 2296 | |
| 2297 | +static bool sdhci_timing_has_preset(unsigned char timing) | |
| 2298 | +{ | |
| 2299 | + switch (timing) { | |
| 2300 | + case MMC_TIMING_UHS_SDR12: | |
| 2301 | + case MMC_TIMING_UHS_SDR25: | |
| 2302 | + case MMC_TIMING_UHS_SDR50: | |
| 2303 | + case MMC_TIMING_UHS_SDR104: | |
| 2304 | + case MMC_TIMING_UHS_DDR50: | |
| 2305 | + case MMC_TIMING_MMC_DDR52: | |
| 2306 | + return true; | |
| 2307 | + }; | |
| 2308 | + return false; | |
| 2309 | +} | |
| 2310 | + | |
| 2311 | +static bool sdhci_preset_needed(struct sdhci_host *host, unsigned char timing) | |
| 2312 | +{ | |
| 2313 | + return !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) && | |
| 2314 | + sdhci_timing_has_preset(timing); | |
| 2315 | +} | |
| 2316 | + | |
| 2317 | +static bool sdhci_presetable_values_change(struct sdhci_host *host, struct mmc_ios *ios) | |
| 2318 | +{ | |
| 2319 | + /* | |
| 2320 | + * Preset Values are: Driver Strength, Clock Generator and SDCLK/RCLK | |
| 2321 | + * Frequency. Check if preset values need to be enabled, or the Driver | |
| 2322 | + * Strength needs updating. Note, clock changes are handled separately. | |
| 2323 | + */ | |
| 2324 | + return !host->preset_enabled && | |
| 2325 | + (sdhci_preset_needed(host, ios->timing) || host->drv_type != ios->drv_type); | |
| 2326 | +} | |
| 2327 | + | |
| 2296 | 2328 | void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
| 2297 | 2329 | { |
| 2298 | 2330 | struct sdhci_host *host = mmc_priv(mmc); |
| 2331 | + bool reinit_uhs = host->reinit_uhs; | |
| 2332 | + bool turning_on_clk = false; | |
| 2299 | 2333 | u8 ctrl; |
| 2300 | 2334 | |
| 2335 | + host->reinit_uhs = false; | |
| 2336 | + | |
| 2301 | 2337 | if (ios->power_mode == MMC_POWER_UNDEFINED) |
| 2302 | 2338 | return; |
| 2303 | 2339 | |
| @@ -2323,6 +2359,8 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 19 unmodified lines | ||
| 2323 | 2359 | sdhci_enable_preset_value(host, false); |
| 2324 | 2360 | |
| 2325 | 2361 | if (!ios->clock || ios->clock != host->clock) { |
| 2362 | + turning_on_clk = ios->clock && !host->clock; | |
| 2363 | + | |
| 2326 | 2364 | host->ops->set_clock(host, ios->clock); |
| 2327 | 2365 | host->clock = ios->clock; |
| 2328 | 2366 | |
| @@ -2349,6 +2387,17 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 20 unmodified lines | ||
| 2349 | 2387 | |
| 2350 | 2388 | host->ops->set_bus_width(host, ios->bus_width); |
| 2351 | 2389 | |
| 2390 | + /* | |
| 2391 | + * Special case to avoid multiple clock changes during voltage | |
| 2392 | + * switching. | |
| 2393 | + */ | |
| 2394 | + if (!reinit_uhs && | |
| 2395 | + turning_on_clk && | |
| 2396 | + host->timing == ios->timing && | |
| 2397 | + host->version >= SDHCI_SPEC_300 && | |
| 2398 | + !sdhci_presetable_values_change(host, ios)) | |
| 2399 | + return; | |
| 2400 | + | |
| 2352 | 2401 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); |
| 2353 | 2402 | |
| 2354 | 2403 | if (!(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) { |
| @@ -2392,6 +2441,7 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 37 unmodified lines | ||
| 2392 | 2441 | } |
| 2393 | 2442 | |
| 2394 | 2443 | sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); |
| 2444 | + host->drv_type = ios->drv_type; | |
| 2395 | 2445 | } else { |
| 2396 | 2446 | /* |
| 2397 | 2447 | * According to SDHC Spec v3.00, if the Preset Value |
| @@ -2419,19 +2469,14 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 21 unmodified lines | ||
| 2419 | 2469 | host->ops->set_uhs_signaling(host, ios->timing); |
| 2420 | 2470 | host->timing = ios->timing; |
| 2421 | 2471 | |
| 2422 | − if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) && | |
| 2423 | − ((ios->timing == MMC_TIMING_UHS_SDR12) || | |
| 2424 | − (ios->timing == MMC_TIMING_UHS_SDR25) || | |
| 2425 | − (ios->timing == MMC_TIMING_UHS_SDR50) || | |
| 2426 | − (ios->timing == MMC_TIMING_UHS_SDR104) || | |
| 2427 | − (ios->timing == MMC_TIMING_UHS_DDR50) || | |
| 2428 | − (ios->timing == MMC_TIMING_MMC_DDR52))) { | |
| 2472 | + if (sdhci_preset_needed(host, ios->timing)) { | |
| 2429 | 2473 | u16 preset; |
| 2430 | 2474 | |
| 2431 | 2475 | sdhci_enable_preset_value(host, true); |
| 2432 | 2476 | preset = sdhci_get_preset_value(host); |
| 2433 | 2477 | ios->drv_type = FIELD_GET(SDHCI_PRESET_DRV_MASK, |
| 2434 | 2478 | preset); |
| 2479 | + host->drv_type = ios->drv_type; | |
| 2435 | 2480 | } |
| 2436 | 2481 | |
| 2437 | 2482 | /* Re-enable SD Clock */ |
| @@ -3768,6 +3813,7 @@ int sdhci_resume_host(struct sdhci_host *host) · 1330 unmodified lines | ||
| 3768 | 3813 | sdhci_init(host, 0); |
| 3769 | 3814 | host->pwr = 0; |
| 3770 | 3815 | host->clock = 0; |
| 3816 | + host->reinit_uhs = true; | |
| 3771 | 3817 | mmc->ops->set_ios(mmc, &mmc->ios); |
| 3772 | 3818 | } else { |
| 3773 | 3819 | sdhci_init(host, (mmc->pm_flags & MMC_PM_KEEP_POWER)); |
| @@ -3830,6 +3876,7 @@ int sdhci_runtime_resume_host(struct sdhci_host *host, int soft_reset) · 56 unmodified lines | ||
| 3830 | 3876 | /* Force clock and power re-program */ |
| 3831 | 3877 | host->pwr = 0; |
| 3832 | 3878 | host->clock = 0; |
| 3879 | + host->reinit_uhs = true; | |
| 3833 | 3880 | mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios); |
| 3834 | 3881 | mmc->ops->set_ios(mmc, &mmc->ios); |
| 3835 | 3882 | |
| @@ -524,6 +524,8 @@ struct sdhci_host { · 523 unmodified lines | ||
| 524 | 524 | |
| 525 | 525 | unsigned int clock; /* Current clock (MHz) */ |
| 526 | 526 | u8 pwr; /* Current voltage */ |
| 527 | + u8 drv_type; /* Current UHS-I driver type */ | |
| 528 | + bool reinit_uhs; /* Force UHS-related re-initialization */ | |
| 527 | 529 | |
| 528 | 530 | bool runtime_suspended; /* Host is runtime suspended */ |
| 529 | 531 | bool bus_on; /* Bus power prevents runtime suspend */ |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/sys_soc.h> |
| 16 | 16 | |
| 17 | 17 | #include "cqhci.h" |
| 18 | +#include "sdhci-cqhci.h" | |
| 18 | 19 | #include "sdhci-pltfm.h" |
| 19 | 20 | |
| 20 | 21 | /* CTL_CFG Registers */ |
| @@ -378,7 +379,7 @@ static void sdhci_am654_reset(struct sdhci_host *host, u8 mask) · 357 unmodified lines | ||
| 378 | 379 | struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); |
| 379 | 380 | struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host); |
| 380 | 381 | |
| 381 | − sdhci_reset(host, mask); | |
| 382 | + sdhci_and_cqhci_reset(host, mask); | |
| 382 | 383 | |
| 383 | 384 | if (sdhci_am654->quirks & SDHCI_AM654_QUIRK_FORCE_CDTEST) { |
| 384 | 385 | ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); |
| @@ -464,7 +465,7 @@ static struct sdhci_ops sdhci_am654_ops = { · 79 unmodified lines | ||
| 464 | 465 | .set_clock = sdhci_am654_set_clock, |
| 465 | 466 | .write_b = sdhci_am654_write_b, |
| 466 | 467 | .irq = sdhci_am654_cqhci_irq, |
| 467 | − .reset = sdhci_reset, | |
| 468 | + .reset = sdhci_and_cqhci_reset, | |
| 468 | 469 | }; |
| 469 | 470 | |
| 470 | 471 | static const struct sdhci_pltfm_data sdhci_am654_pdata = { |
| @@ -494,7 +495,7 @@ static struct sdhci_ops sdhci_j721e_8bit_ops = { · 23 unmodified lines | ||
| 494 | 495 | .set_clock = sdhci_am654_set_clock, |
| 495 | 496 | .write_b = sdhci_am654_write_b, |
| 496 | 497 | .irq = sdhci_am654_cqhci_irq, |
| 497 | − .reset = sdhci_reset, | |
| 498 | + .reset = sdhci_and_cqhci_reset, | |
| 498 | 499 | }; |
| 499 | 500 | |
| 500 | 501 | static const struct sdhci_pltfm_data sdhci_j721e_8bit_pdata = { |
| @@ -26,6 +26,7 @@ config MTD_ONENAND_OMAP2 · 25 unmodified lines | ||
| 26 | 26 | tristate "OneNAND on OMAP2/OMAP3 support" |
| 27 | 27 | depends on ARCH_OMAP2 || ARCH_OMAP3 || (COMPILE_TEST && ARM) |
| 28 | 28 | depends on OF || COMPILE_TEST |
| 29 | + depends on OMAP_GPMC | |
| 29 | 30 | help |
| 30 | 31 | Support for a OneNAND flash device connected to an OMAP2/OMAP3 SoC |
| 31 | 32 | via the GPMC memory controller. |
| @@ -5834,7 +5834,7 @@ nand_match_ecc_req(struct nand_chip *chip, · 5833 unmodified lines | ||
| 5834 | 5834 | int req_step = requirements->step_size; |
| 5835 | 5835 | int req_strength = requirements->strength; |
| 5836 | 5836 | int req_corr, step_size, strength, nsteps, ecc_bytes, ecc_bytes_total; |
| 5837 | − int best_step, best_strength, best_ecc_bytes; | |
| 5837 | + int best_step = 0, best_strength = 0, best_ecc_bytes = 0; | |
| 5838 | 5838 | int best_ecc_bytes_total = INT_MAX; |
| 5839 | 5839 | int i, j; |
| 5840 | 5840 | |
| @@ -5915,7 +5915,7 @@ nand_maximize_ecc(struct nand_chip *chip, · 74 unmodified lines | ||
| 5915 | 5915 | int step_size, strength, nsteps, ecc_bytes, corr; |
| 5916 | 5916 | int best_corr = 0; |
| 5917 | 5917 | int best_step = 0; |
| 5918 | − int best_strength, best_ecc_bytes; | |
| 5918 | + int best_strength = 0, best_ecc_bytes = 0; | |
| 5919 | 5919 | int i, j; |
| 5920 | 5920 | |
| 5921 | 5921 | for (i = 0; i < caps->nstepinfos; i++) { |
| @@ -3167,16 +3167,18 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc, · 3166 unmodified lines | ||
| 3167 | 3167 | |
| 3168 | 3168 | ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0); |
| 3169 | 3169 | if (ret) |
| 3170 | − nand_cleanup(chip); | |
| 3170 | + goto err; | |
| 3171 | 3171 | |
| 3172 | 3172 | if (nandc->props->use_codeword_fixup) { |
| 3173 | 3173 | ret = qcom_nand_host_parse_boot_partitions(nandc, host, dn); |
| 3174 | − if (ret) { | |
| 3175 | − nand_cleanup(chip); | |
| 3176 | − return ret; | |
| 3177 | − } | |
| 3174 | + if (ret) | |
| 3175 | + goto err; | |
| 3178 | 3176 | } |
| 3179 | 3177 | |
| 3178 | + return 0; | |
| 3179 | + | |
| 3180 | +err: | |
| 3181 | + nand_cleanup(chip); | |
| 3180 | 3182 | return ret; |
| 3181 | 3183 | } |
| 3182 | 3184 | |
| @@ -113,6 +113,7 @@ static int com20020_probe(struct pcmcia_device *p_dev) · 112 unmodified lines | ||
| 113 | 113 | struct com20020_dev *info; |
| 114 | 114 | struct net_device *dev; |
| 115 | 115 | struct arcnet_local *lp; |
| 116 | + int ret = -ENOMEM; | |
| 116 | 117 | |
| 117 | 118 | dev_dbg(&p_dev->dev, "com20020_attach()\n"); |
| 118 | 119 | |
| @@ -142,12 +143,18 @@ static int com20020_probe(struct pcmcia_device *p_dev) · 23 unmodified lines | ||
| 142 | 143 | info->dev = dev; |
| 143 | 144 | p_dev->priv = info; |
| 144 | 145 | |
| 145 | − return com20020_config(p_dev); | |
| 146 | + ret = com20020_config(p_dev); | |
| 147 | + if (ret) | |
| 148 | + goto fail_config; | |
| 149 | + | |
| 150 | + return 0; | |
| 146 | 151 | |
| 152 | +fail_config: | |
| 153 | + free_arcdev(dev); | |
| 147 | 154 | fail_alloc_dev: |
| 148 | 155 | kfree(info); |
| 149 | 156 | fail_alloc_info: |
| 150 | − return -ENOMEM; | |
| 157 | + return ret; | |
| 151 | 158 | } /* com20020_attach */ |
| 152 | 159 | |
| 153 | 160 | static void com20020_detach(struct pcmcia_device *link) |
| @@ -3231,16 +3231,23 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond, · 3230 unmodified lines | ||
| 3231 | 3231 | struct slave *slave) |
| 3232 | 3232 | { |
| 3233 | 3233 | struct slave *curr_active_slave, *curr_arp_slave; |
| 3234 | − struct icmp6hdr *hdr = icmp6_hdr(skb); | |
| 3235 | 3234 | struct in6_addr *saddr, *daddr; |
| 3235 | + struct { | |
| 3236 | + struct ipv6hdr ip6; | |
| 3237 | + struct icmp6hdr icmp6; | |
| 3238 | + } *combined, _combined; | |
| 3236 | 3239 | |
| 3237 | 3240 | if (skb->pkt_type == PACKET_OTHERHOST || |
| 3238 | − skb->pkt_type == PACKET_LOOPBACK || | |
| 3239 | − hdr->icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT) | |
| 3241 | + skb->pkt_type == PACKET_LOOPBACK) | |
| 3242 | + goto out; | |
| 3243 | + | |
| 3244 | + combined = skb_header_pointer(skb, 0, sizeof(_combined), &_combined); | |
| 3245 | + if (!combined || combined->ip6.nexthdr != NEXTHDR_ICMP || | |
| 3246 | + combined->icmp6.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT) | |
| 3240 | 3247 | goto out; |
| 3241 | 3248 | |
| 3242 | − saddr = &ipv6_hdr(skb)->saddr; | |
| 3243 | − daddr = &ipv6_hdr(skb)->daddr; | |
| 3249 | + saddr = &combined->ip6.saddr; | |
| 3250 | + daddr = &combined->ip6.saddr; | |
| 3244 | 3251 | |
| 3245 | 3252 | slave_dbg(bond->dev, slave->dev, "%s: %s/%d av %d sv %d sip %pI6c tip %pI6c\n", |
| 3246 | 3253 | __func__, slave->dev->name, bond_slave_state(slave), |
| @@ -452,7 +452,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev) · 451 unmodified lines | ||
| 452 | 452 | unsigned int mb, prio; |
| 453 | 453 | u32 reg_mid, reg_mcr; |
| 454 | 454 | |
| 455 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 455 | + if (can_dev_dropped_skb(dev, skb)) | |
| 456 | 456 | return NETDEV_TX_OK; |
| 457 | 457 | |
| 458 | 458 | mb = get_tx_next_mb(priv); |
| @@ -457,7 +457,7 @@ static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, · 456 unmodified lines | ||
| 457 | 457 | struct c_can_tx_ring *tx_ring = &priv->tx; |
| 458 | 458 | u32 idx, obj, cmd = IF_COMM_TX; |
| 459 | 459 | |
| 460 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 460 | + if (can_dev_dropped_skb(dev, skb)) | |
| 461 | 461 | return NETDEV_TX_OK; |
| 462 | 462 | |
| 463 | 463 | if (c_can_tx_busy(priv, tx_ring)) |
| @@ -263,8 +263,10 @@ static void can327_feed_frame_to_netdev(struct can327 *elm, struct sk_buff *skb) · 262 unmodified lines | ||
| 263 | 263 | { |
| 264 | 264 | lockdep_assert_held(&elm->lock); |
| 265 | 265 | |
| 266 | − if (!netif_running(elm->dev)) | |
| 266 | + if (!netif_running(elm->dev)) { | |
| 267 | + kfree_skb(skb); | |
| 267 | 268 | return; |
| 269 | + } | |
| 268 | 270 | |
| 269 | 271 | /* Queue for NAPI pickup. |
| 270 | 272 | * rx-offload will update stats and LEDs for us. |
| @@ -813,7 +815,7 @@ static netdev_tx_t can327_netdev_start_xmit(struct sk_buff *skb, · 542 unmodified lines | ||
| 813 | 815 | struct can327 *elm = netdev_priv(dev); |
| 814 | 816 | struct can_frame *frame = (struct can_frame *)skb->data; |
| 815 | 817 | |
| 816 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 818 | + if (can_dev_dropped_skb(dev, skb)) | |
| 817 | 819 | return NETDEV_TX_OK; |
| 818 | 820 | |
| 819 | 821 | /* We shouldn't get here after a hardware fault: |
| @@ -429,7 +429,7 @@ static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev) · 428 unmodified lines | ||
| 429 | 429 | struct cc770_priv *priv = netdev_priv(dev); |
| 430 | 430 | unsigned int mo = obj2msgobj(CC770_OBJ_TX); |
| 431 | 431 | |
| 432 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 432 | + if (can_dev_dropped_skb(dev, skb)) | |
| 433 | 433 | return NETDEV_TX_OK; |
| 434 | 434 | |
| 435 | 435 | netif_stop_queue(dev); |
| @@ -264,22 +264,24 @@ static int cc770_isa_probe(struct platform_device *pdev) · 263 unmodified lines | ||
| 264 | 264 | if (err) { |
| 265 | 265 | dev_err(&pdev->dev, |
| 266 | 266 | "couldn't register device (err=%d)\n", err); |
| 267 | − goto exit_unmap; | |
| 267 | + goto exit_free; | |
| 268 | 268 | } |
| 269 | 269 | |
| 270 | 270 | dev_info(&pdev->dev, "device registered (reg_base=0x%p, irq=%d)\n", |
| 271 | 271 | priv->reg_base, dev->irq); |
| 272 | 272 | return 0; |
| 273 | 273 | |
| 274 | − exit_unmap: | |
| 274 | +exit_free: | |
| 275 | + free_cc770dev(dev); | |
| 276 | +exit_unmap: | |
| 275 | 277 | if (mem[idx]) |
| 276 | 278 | iounmap(base); |
| 277 | − exit_release: | |
| 279 | +exit_release: | |
| 278 | 280 | if (mem[idx]) |
| 279 | 281 | release_mem_region(mem[idx], iosize); |
| 280 | 282 | else |
| 281 | 283 | release_region(port[idx], iosize); |
| 282 | − exit: | |
| 284 | +exit: | |
| 283 | 285 | return err; |
| 284 | 286 | } |
| 285 | 287 | |
| @@ -600,7 +600,7 @@ static netdev_tx_t ctucan_start_xmit(struct sk_buff *skb, struct net_device *nde · 599 unmodified lines | ||
| 600 | 600 | bool ok; |
| 601 | 601 | unsigned long flags; |
| 602 | 602 | |
| 603 | − if (can_dropped_invalid_skb(ndev, skb)) | |
| 603 | + if (can_dev_dropped_skb(ndev, skb)) | |
| 604 | 604 | return NETDEV_TX_OK; |
| 605 | 605 | |
| 606 | 606 | if (unlikely(!CTU_CAN_FD_TXTNF(priv))) { |
| @@ -5,7 +5,6 @@ · 4 unmodified lines | ||
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | #include <linux/can/dev.h> |
| 8 | −#include <linux/can/netlink.h> | |
| 9 | 8 | #include <linux/module.h> |
| 10 | 9 | |
| 11 | 10 | #define MOD_DESC "CAN device driver interface" |
| @@ -337,8 +336,6 @@ static bool can_skb_headroom_valid(struct net_device *dev, struct sk_buff *skb) · 325 unmodified lines | ||
| 337 | 336 | /* Drop a given socketbuffer if it does not contain a valid CAN frame. */ |
| 338 | 337 | bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb) |
| 339 | 338 | { |
| 340 | − struct can_priv *priv = netdev_priv(dev); | |
| 341 | − | |
| 342 | 339 | switch (ntohs(skb->protocol)) { |
| 343 | 340 | case ETH_P_CAN: |
| 344 | 341 | if (!can_is_can_skb(skb)) |
| @@ -359,13 +356,8 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb) · 14 unmodified lines | ||
| 359 | 356 | goto inval_skb; |
| 360 | 357 | } |
| 361 | 358 | |
| 362 | − if (!can_skb_headroom_valid(dev, skb)) { | |
| 359 | + if (!can_skb_headroom_valid(dev, skb)) | |
| 363 | 360 | goto inval_skb; |
| 364 | − } else if (priv->ctrlmode & CAN_CTRLMODE_LISTENONLY) { | |
| 365 | − netdev_info_once(dev, | |
| 366 | − "interface in listen only mode, dropping skb\n"); | |
| 367 | − goto inval_skb; | |
| 368 | − } | |
| 369 | 361 | |
| 370 | 362 | return false; |
| 371 | 363 | |
| @@ -742,7 +742,7 @@ static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *de · 741 unmodified lines | ||
| 742 | 742 | u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_fd_len2dlc(cfd->len)) << 16); |
| 743 | 743 | int i; |
| 744 | 744 | |
| 745 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 745 | + if (can_dev_dropped_skb(dev, skb)) | |
| 746 | 746 | return NETDEV_TX_OK; |
| 747 | 747 | |
| 748 | 748 | netif_stop_queue(dev); |
| @@ -1345,7 +1345,7 @@ static netdev_tx_t grcan_start_xmit(struct sk_buff *skb, · 1344 unmodified lines | ||
| 1345 | 1345 | unsigned long flags; |
| 1346 | 1346 | u32 oneshotmode = priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT; |
| 1347 | 1347 | |
| 1348 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 1348 | + if (can_dev_dropped_skb(dev, skb)) | |
| 1349 | 1349 | return NETDEV_TX_OK; |
| 1350 | 1350 | |
| 1351 | 1351 | /* Trying to transmit in silent mode will generate error interrupts, but |
| @@ -860,7 +860,7 @@ static netdev_tx_t ifi_canfd_start_xmit(struct sk_buff *skb, · 859 unmodified lines | ||
| 860 | 860 | u32 txst, txid, txdlc; |
| 861 | 861 | int i; |
| 862 | 862 | |
| 863 | − if (can_dropped_invalid_skb(ndev, skb)) | |
| 863 | + if (can_dev_dropped_skb(ndev, skb)) | |
| 864 | 864 | return NETDEV_TX_OK; |
| 865 | 865 | |
| 866 | 866 | /* Check if the TX buffer is full */ |
| @@ -1693,7 +1693,7 @@ static netdev_tx_t ican3_xmit(struct sk_buff *skb, struct net_device *ndev) · 1692 unmodified lines | ||
| 1693 | 1693 | void __iomem *desc_addr; |
| 1694 | 1694 | unsigned long flags; |
| 1695 | 1695 | |
| 1696 | − if (can_dropped_invalid_skb(ndev, skb)) | |
| 1696 | + if (can_dev_dropped_skb(ndev, skb)) | |
| 1697 | 1697 | return NETDEV_TX_OK; |
| 1698 | 1698 | |
| 1699 | 1699 | spin_lock_irqsave(&mod->lock, flags); |
| @@ -772,7 +772,7 @@ static netdev_tx_t kvaser_pciefd_start_xmit(struct sk_buff *skb, · 771 unmodified lines | ||
| 772 | 772 | int nwords; |
| 773 | 773 | u8 count; |
| 774 | 774 | |
| 775 | − if (can_dropped_invalid_skb(netdev, skb)) | |
| 775 | + if (can_dev_dropped_skb(netdev, skb)) | |
| 776 | 776 | return NETDEV_TX_OK; |
| 777 | 777 | |
| 778 | 778 | nwords = kvaser_pciefd_prepare_tx_packet(&packet, can, skb); |
| @@ -1721,7 +1721,7 @@ static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, · 1720 unmodified lines | ||
| 1721 | 1721 | { |
| 1722 | 1722 | struct m_can_classdev *cdev = netdev_priv(dev); |
| 1723 | 1723 | |
| 1724 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 1724 | + if (can_dev_dropped_skb(dev, skb)) | |
| 1725 | 1725 | return NETDEV_TX_OK; |
| 1726 | 1726 | |
| 1727 | 1727 | if (cdev->is_peripheral) { |
| @@ -1909,7 +1909,7 @@ int m_can_class_get_clocks(struct m_can_classdev *cdev) · 181 unmodified lines | ||
| 1909 | 1909 | cdev->hclk = devm_clk_get(cdev->dev, "hclk"); |
| 1910 | 1910 | cdev->cclk = devm_clk_get(cdev->dev, "cclk"); |
| 1911 | 1911 | |
| 1912 | − if (IS_ERR(cdev->cclk)) { | |
| 1912 | + if (IS_ERR(cdev->hclk) || IS_ERR(cdev->cclk)) { | |
| 1913 | 1913 | dev_err(cdev->dev, "no clock found\n"); |
| 1914 | 1914 | ret = -ENODEV; |
| 1915 | 1915 | } |
| @@ -120,7 +120,7 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) · 119 unmodified lines | ||
| 120 | 120 | |
| 121 | 121 | ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_ALL_TYPES); |
| 122 | 122 | if (ret < 0) |
| 123 | − return ret; | |
| 123 | + goto err_free_dev; | |
| 124 | 124 | |
| 125 | 125 | mcan_class->dev = &pci->dev; |
| 126 | 126 | mcan_class->net->irq = pci_irq_vector(pci, 0); |
| @@ -132,7 +132,7 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) · 5 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | ret = m_can_class_register(mcan_class); |
| 134 | 134 | if (ret) |
| 135 | − goto err; | |
| 135 | + goto err_free_irq; | |
| 136 | 136 | |
| 137 | 137 | /* Enable interrupt control at CAN wrapper IP */ |
| 138 | 138 | writel(0x1, base + CTL_CSR_INT_CTL_OFFSET); |
| @@ -144,8 +144,10 @@ static int m_can_pci_probe(struct pci_dev *pci, const struct pci_device_id *id) · 5 unmodified lines | ||
| 144 | 144 | |
| 145 | 145 | return 0; |
| 146 | 146 | |
| 147 | −err: | |
| 147 | +err_free_irq: | |
| 148 | 148 | pci_free_irq_vectors(pci); |
| 149 | +err_free_dev: | |
| 150 | + m_can_class_free_dev(mcan_class->net); | |
| 149 | 151 | return ret; |
| 150 | 152 | } |
| 151 | 153 | |
| @@ -161,6 +163,7 @@ static void m_can_pci_remove(struct pci_dev *pci) · 9 unmodified lines | ||
| 161 | 163 | writel(0x0, priv->base + CTL_CSR_INT_CTL_OFFSET); |
| 162 | 164 | |
| 163 | 165 | m_can_class_unregister(mcan_class); |
| 166 | + m_can_class_free_dev(mcan_class->net); | |
| 164 | 167 | pci_free_irq_vectors(pci); |
| 165 | 168 | } |
| 166 | 169 | |
| @@ -191,7 +191,7 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev) · 190 unmodified lines | ||
| 191 | 191 | int i, rtr, buf_id; |
| 192 | 192 | u32 can_id; |
| 193 | 193 | |
| 194 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 194 | + if (can_dev_dropped_skb(dev, skb)) | |
| 195 | 195 | return NETDEV_TX_OK; |
| 196 | 196 | |
| 197 | 197 | out_8(®s->cantier, 0); |
| @@ -882,7 +882,7 @@ static netdev_tx_t pch_xmit(struct sk_buff *skb, struct net_device *ndev) · 881 unmodified lines | ||
| 882 | 882 | int i; |
| 883 | 883 | u32 id2; |
| 884 | 884 | |
| 885 | − if (can_dropped_invalid_skb(ndev, skb)) | |
| 885 | + if (can_dev_dropped_skb(ndev, skb)) | |
| 886 | 886 | return NETDEV_TX_OK; |
| 887 | 887 | |
| 888 | 888 | tx_obj_no = priv->tx_obj; |
| @@ -651,7 +651,7 @@ static netdev_tx_t peak_canfd_start_xmit(struct sk_buff *skb, · 650 unmodified lines | ||
| 651 | 651 | int room_left; |
| 652 | 652 | u8 len; |
| 653 | 653 | |
| 654 | − if (can_dropped_invalid_skb(ndev, skb)) | |
| 654 | + if (can_dev_dropped_skb(ndev, skb)) | |
| 655 | 655 | return NETDEV_TX_OK; |
| 656 | 656 | |
| 657 | 657 | msg_size = ALIGN(sizeof(*msg) + cf->len, 4); |
| @@ -590,7 +590,7 @@ static netdev_tx_t rcar_can_start_xmit(struct sk_buff *skb, · 589 unmodified lines | ||
| 590 | 590 | struct can_frame *cf = (struct can_frame *)skb->data; |
| 591 | 591 | u32 data, i; |
| 592 | 592 | |
| 593 | − if (can_dropped_invalid_skb(ndev, skb)) | |
| 593 | + if (can_dev_dropped_skb(ndev, skb)) | |
| 594 | 594 | return NETDEV_TX_OK; |
| 595 | 595 | |
| 596 | 596 | if (cf->can_id & CAN_EFF_FLAG) /* Extended frame format */ |
| @@ -81,8 +81,7 @@ enum rcanfd_chip_id { · 80 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | /* RSCFDnCFDGERFL / RSCFDnGERFL */ |
| 83 | 83 | #define RCANFD_GERFL_EEF0_7 GENMASK(23, 16) |
| 84 | −#define RCANFD_GERFL_EEF1 BIT(17) | |
| 85 | −#define RCANFD_GERFL_EEF0 BIT(16) | |
| 84 | +#define RCANFD_GERFL_EEF(ch) BIT(16 + (ch)) | |
| 86 | 85 | #define RCANFD_GERFL_CMPOF BIT(3) /* CAN FD only */ |
| 87 | 86 | #define RCANFD_GERFL_THLES BIT(2) |
| 88 | 87 | #define RCANFD_GERFL_MES BIT(1) |
| @@ -90,7 +89,7 @@ enum rcanfd_chip_id { · 1 unmodified line | ||
| 90 | 89 | |
| 91 | 90 | #define RCANFD_GERFL_ERR(gpriv, x) \ |
| 92 | 91 | ((x) & (reg_v3u(gpriv, RCANFD_GERFL_EEF0_7, \ |
| 93 | − RCANFD_GERFL_EEF0 | RCANFD_GERFL_EEF1) | \ | |
| 92 | + RCANFD_GERFL_EEF(0) | RCANFD_GERFL_EEF(1)) | \ | |
| 94 | 93 | RCANFD_GERFL_MES | \ |
| 95 | 94 | ((gpriv)->fdmode ? RCANFD_GERFL_CMPOF : 0))) |
| 96 | 95 | |
| @@ -936,12 +935,8 @@ static void rcar_canfd_global_error(struct net_device *ndev) · 839 unmodified lines | ||
| 936 | 935 | u32 ridx = ch + RCANFD_RFFIFO_IDX; |
| 937 | 936 | |
| 938 | 937 | gerfl = rcar_canfd_read(priv->base, RCANFD_GERFL); |
| 939 | − if ((gerfl & RCANFD_GERFL_EEF0) && (ch == 0)) { | |
| 940 | − netdev_dbg(ndev, "Ch0: ECC Error flag\n"); | |
| 941 | − stats->tx_dropped++; | |
| 942 | − } | |
| 943 | − if ((gerfl & RCANFD_GERFL_EEF1) && (ch == 1)) { | |
| 944 | − netdev_dbg(ndev, "Ch1: ECC Error flag\n"); | |
| 938 | + if (gerfl & RCANFD_GERFL_EEF(ch)) { | |
| 939 | + netdev_dbg(ndev, "Ch%u: ECC Error flag\n", ch); | |
| 945 | 940 | stats->tx_dropped++; |
| 946 | 941 | } |
| 947 | 942 | if (gerfl & RCANFD_GERFL_MES) { |
| @@ -1481,7 +1476,7 @@ static netdev_tx_t rcar_canfd_start_xmit(struct sk_buff *skb, · 533 unmodified lines | ||
| 1481 | 1476 | unsigned long flags; |
| 1482 | 1477 | u32 ch = priv->channel; |
| 1483 | 1478 | |
| 1484 | − if (can_dropped_invalid_skb(ndev, skb)) | |
| 1479 | + if (can_dev_dropped_skb(ndev, skb)) | |
| 1485 | 1480 | return NETDEV_TX_OK; |
| 1486 | 1481 | |
| 1487 | 1482 | if (cf->can_id & CAN_EFF_FLAG) { |
| @@ -291,7 +291,7 @@ static netdev_tx_t sja1000_start_xmit(struct sk_buff *skb, · 290 unmodified lines | ||
| 291 | 291 | u8 cmd_reg_val = 0x00; |
| 292 | 292 | int i; |
| 293 | 293 | |
| 294 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 294 | + if (can_dev_dropped_skb(dev, skb)) | |
| 295 | 295 | return NETDEV_TX_OK; |
| 296 | 296 | |
| 297 | 297 | netif_stop_queue(dev); |
| @@ -202,22 +202,24 @@ static int sja1000_isa_probe(struct platform_device *pdev) · 201 unmodified lines | ||
| 202 | 202 | if (err) { |
| 203 | 203 | dev_err(&pdev->dev, "registering %s failed (err=%d)\n", |
| 204 | 204 | DRV_NAME, err); |
| 205 | − goto exit_unmap; | |
| 205 | + goto exit_free; | |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | 208 | dev_info(&pdev->dev, "%s device registered (reg_base=0x%p, irq=%d)\n", |
| 209 | 209 | DRV_NAME, priv->reg_base, dev->irq); |
| 210 | 210 | return 0; |
| 211 | 211 | |
| 212 | − exit_unmap: | |
| 212 | +exit_free: | |
| 213 | + free_sja1000dev(dev); | |
| 214 | +exit_unmap: | |
| 213 | 215 | if (mem[idx]) |
| 214 | 216 | iounmap(base); |
| 215 | − exit_release: | |
| 217 | +exit_release: | |
| 216 | 218 | if (mem[idx]) |
| 217 | 219 | release_mem_region(mem[idx], iosize); |
| 218 | 220 | else |
| 219 | 221 | release_region(port[idx], iosize); |
| 220 | − exit: | |
| 222 | +exit: | |
| 221 | 223 | return err; |
| 222 | 224 | } |
| 223 | 225 | |
| @@ -594,7 +594,7 @@ static netdev_tx_t slcan_netdev_xmit(struct sk_buff *skb, · 593 unmodified lines | ||
| 594 | 594 | { |
| 595 | 595 | struct slcan *sl = netdev_priv(dev); |
| 596 | 596 | |
| 597 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 597 | + if (can_dev_dropped_skb(dev, skb)) | |
| 598 | 598 | return NETDEV_TX_OK; |
| 599 | 599 | |
| 600 | 600 | spin_lock(&sl->lock); |
| @@ -60,7 +60,7 @@ static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb, · 59 unmodified lines | ||
| 60 | 60 | struct can_frame *cf = (struct can_frame *)skb->data; |
| 61 | 61 | uint8_t buf[DPRAM_TX_SIZE]; |
| 62 | 62 | |
| 63 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 63 | + if (can_dev_dropped_skb(dev, skb)) | |
| 64 | 64 | return NETDEV_TX_OK; |
| 65 | 65 | |
| 66 | 66 | spin_lock(&card->spin); |
| @@ -373,7 +373,7 @@ static netdev_tx_t hi3110_hard_start_xmit(struct sk_buff *skb, · 372 unmodified lines | ||
| 373 | 373 | return NETDEV_TX_BUSY; |
| 374 | 374 | } |
| 375 | 375 | |
| 376 | − if (can_dropped_invalid_skb(net, skb)) | |
| 376 | + if (can_dev_dropped_skb(net, skb)) | |
| 377 | 377 | return NETDEV_TX_OK; |
| 378 | 378 | |
| 379 | 379 | netif_stop_queue(net); |
| @@ -789,7 +789,7 @@ static netdev_tx_t mcp251x_hard_start_xmit(struct sk_buff *skb, · 788 unmodified lines | ||
| 789 | 789 | return NETDEV_TX_BUSY; |
| 790 | 790 | } |
| 791 | 791 | |
| 792 | − if (can_dropped_invalid_skb(net, skb)) | |
| 792 | + if (can_dev_dropped_skb(net, skb)) | |
| 793 | 793 | return NETDEV_TX_OK; |
| 794 | 794 | |
| 795 | 795 | netif_stop_queue(net); |
| @@ -172,7 +172,7 @@ netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb, · 171 unmodified lines | ||
| 172 | 172 | u8 tx_head; |
| 173 | 173 | int err; |
| 174 | 174 | |
| 175 | − if (can_dropped_invalid_skb(ndev, skb)) | |
| 175 | + if (can_dev_dropped_skb(ndev, skb)) | |
| 176 | 176 | return NETDEV_TX_OK; |
| 177 | 177 | |
| 178 | 178 | if (mcp251xfd_tx_busy(priv, tx_ring)) |
| @@ -429,7 +429,7 @@ static netdev_tx_t sun4ican_start_xmit(struct sk_buff *skb, struct net_device *d · 428 unmodified lines | ||
| 429 | 429 | canid_t id; |
| 430 | 430 | int i; |
| 431 | 431 | |
| 432 | − if (can_dropped_invalid_skb(dev, skb)) | |
| 432 | + if (can_dev_dropped_skb(dev, skb)) | |
| 433 | 433 | return NETDEV_TX_OK; |
| 434 | 434 | |
| 435 | 435 | netif_stop_queue(dev); |
| @@ -470,7 +470,7 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev) · 469 unmodified lines | ||
| 470 | 470 | u32 mbxno, mbx_mask, data; |
| 471 | 471 | unsigned long flags; |
| 472 | 472 | |
| 473 | − if (can_dropped_invalid_skb(ndev, skb)) | |
| 473 | + if (can_dev_dropped_skb(ndev, skb)) | |
| 474 | 474 | return NETDEV_TX_OK; |
| 475 | 475 | |
| 476 | 476 | mbxno = get_tx_head_mb(priv); |
| @@ -747,7 +747,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne · 746 unmodified lines | ||
| 747 | 747 | size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN |
| 748 | 748 | + sizeof(struct cpc_can_msg); |
| 749 | 749 | |
| 750 | − if (can_dropped_invalid_skb(netdev, skb)) | |
| 750 | + if (can_dev_dropped_skb(netdev, skb)) | |
| 751 | 751 | return NETDEV_TX_OK; |
| 752 | 752 | |
| 753 | 753 | /* create a URB, and a buffer for it, and copy the data to the URB */ |
| @@ -725,7 +725,7 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, · 724 unmodified lines | ||
| 725 | 725 | int ret = NETDEV_TX_OK; |
| 726 | 726 | size_t size = sizeof(struct esd_usb_msg); |
| 727 | 727 | |
| 728 | − if (can_dropped_invalid_skb(netdev, skb)) | |
| 728 | + if (can_dev_dropped_skb(netdev, skb)) | |
| 729 | 729 | return NETDEV_TX_OK; |
| 730 | 730 | |
| 731 | 731 | /* create a URB, and a buffer for it, and copy the data to the URB */ |
| @@ -1913,7 +1913,7 @@ static netdev_tx_t es58x_start_xmit(struct sk_buff *skb, · 1912 unmodified lines | ||
| 1913 | 1913 | unsigned int frame_len; |
| 1914 | 1914 | int ret; |
| 1915 | 1915 | |
| 1916 | − if (can_dropped_invalid_skb(netdev, skb)) { | |
| 1916 | + if (can_dev_dropped_skb(netdev, skb)) { | |
| 1917 | 1917 | if (priv->tx_urb) |
| 1918 | 1918 | goto xmit_commit; |
| 1919 | 1919 | return NETDEV_TX_OK; |
| @@ -2091,8 +2091,11 @@ static int es58x_init_netdev(struct es58x_device *es58x_dev, int channel_idx) · 171 unmodified lines | ||
| 2091 | 2091 | netdev->dev_port = channel_idx; |
| 2092 | 2092 | |
| 2093 | 2093 | ret = register_candev(netdev); |
| 2094 | − if (ret) | |
| 2094 | + if (ret) { | |
| 2095 | + es58x_dev->netdev[channel_idx] = NULL; | |
| 2096 | + free_candev(netdev); | |
| 2095 | 2097 | return ret; |
| 2098 | + } | |
| 2096 | 2099 | |
| 2097 | 2100 | netdev_queue_set_dql_min_limit(netdev_get_tx_queue(netdev, 0), |
| 2098 | 2101 | es58x_dev->param->dql_min_limit); |
| @@ -723,7 +723,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb, · 722 unmodified lines | ||
| 723 | 723 | unsigned int idx; |
| 724 | 724 | struct gs_tx_context *txc; |
| 725 | 725 | |
| 726 | − if (can_dropped_invalid_skb(netdev, skb)) | |
| 726 | + if (can_dev_dropped_skb(netdev, skb)) | |
| 727 | 727 | return NETDEV_TX_OK; |
| 728 | 728 | |
| 729 | 729 | /* find an empty context to keep track of transmission */ |
| @@ -570,7 +570,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, · 569 unmodified lines | ||
| 570 | 570 | unsigned int i; |
| 571 | 571 | unsigned long flags; |
| 572 | 572 | |
| 573 | − if (can_dropped_invalid_skb(netdev, skb)) | |
| 573 | + if (can_dev_dropped_skb(netdev, skb)) | |
| 574 | 574 | return NETDEV_TX_OK; |
| 575 | 575 | |
| 576 | 576 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
| @@ -47,6 +47,10 @@ · 46 unmodified lines | ||
| 47 | 47 | #define MCBA_VER_REQ_USB 1 |
| 48 | 48 | #define MCBA_VER_REQ_CAN 2 |
| 49 | 49 | |
| 50 | +/* Drive the CAN_RES signal LOW "0" to activate R24 and R25 */ | |
| 51 | +#define MCBA_VER_TERMINATION_ON 0 | |
| 52 | +#define MCBA_VER_TERMINATION_OFF 1 | |
| 53 | + | |
| 50 | 54 | #define MCBA_SIDL_EXID_MASK 0x8 |
| 51 | 55 | #define MCBA_DLC_MASK 0xf |
| 52 | 56 | #define MCBA_DLC_RTR_MASK 0x40 |
| @@ -311,7 +315,7 @@ static netdev_tx_t mcba_usb_start_xmit(struct sk_buff *skb, · 258 unmodified lines | ||
| 311 | 315 | .cmd_id = MBCA_CMD_TRANSMIT_MESSAGE_EV |
| 312 | 316 | }; |
| 313 | 317 | |
| 314 | − if (can_dropped_invalid_skb(netdev, skb)) | |
| 318 | + if (can_dev_dropped_skb(netdev, skb)) | |
| 315 | 319 | return NETDEV_TX_OK; |
| 316 | 320 | |
| 317 | 321 | ctx = mcba_usb_get_free_ctx(priv, cf); |
| @@ -463,7 +467,7 @@ static void mcba_usb_process_ka_usb(struct mcba_priv *priv, · 145 unmodified lines | ||
| 463 | 467 | priv->usb_ka_first_pass = false; |
| 464 | 468 | } |
| 465 | 469 | |
| 466 | − if (msg->termination_state) | |
| 470 | + if (msg->termination_state == MCBA_VER_TERMINATION_ON) | |
| 467 | 471 | priv->can.termination = MCBA_TERMINATION_ENABLED; |
| 468 | 472 | else |
| 469 | 473 | priv->can.termination = MCBA_TERMINATION_DISABLED; |
| @@ -785,9 +789,9 @@ static int mcba_set_termination(struct net_device *netdev, u16 term) · 315 unmodified lines | ||
| 785 | 789 | }; |
| 786 | 790 | |
| 787 | 791 | if (term == MCBA_TERMINATION_ENABLED) |
| 788 | − usb_msg.termination = 1; | |
| 792 | + usb_msg.termination = MCBA_VER_TERMINATION_ON; | |
| 789 | 793 | else |
| 790 | − usb_msg.termination = 0; | |
| 794 | + usb_msg.termination = MCBA_VER_TERMINATION_OFF; | |
| 791 | 795 | |
| 792 | 796 | mcba_usb_xmit_cmd(priv, (struct mcba_usb_msg *)&usb_msg); |
| 793 | 797 | |
| @@ -351,7 +351,7 @@ static netdev_tx_t peak_usb_ndo_start_xmit(struct sk_buff *skb, · 350 unmodified lines | ||
| 351 | 351 | int i, err; |
| 352 | 352 | size_t size = dev->adapter->tx_buffer_size; |
| 353 | 353 | |
| 354 | − if (can_dropped_invalid_skb(netdev, skb)) | |
| 354 | + if (can_dev_dropped_skb(netdev, skb)) | |
| 355 | 355 | return NETDEV_TX_OK; |
| 356 | 356 | |
| 357 | 357 | for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) |
| @@ -1120,7 +1120,7 @@ static netdev_tx_t ucan_start_xmit(struct sk_buff *skb, · 1119 unmodified lines | ||
| 1120 | 1120 | struct can_frame *cf = (struct can_frame *)skb->data; |
| 1121 | 1121 | |
| 1122 | 1122 | /* check skb */ |
| 1123 | − if (can_dropped_invalid_skb(netdev, skb)) | |
| 1123 | + if (can_dev_dropped_skb(netdev, skb)) | |
| 1124 | 1124 | return NETDEV_TX_OK; |
| 1125 | 1125 | |
| 1126 | 1126 | /* allocate a context and slow down tx path, if fifo state is low */ |
| @@ -602,7 +602,7 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb, · 601 unmodified lines | ||
| 602 | 602 | int i, err; |
| 603 | 603 | size_t size = sizeof(struct usb_8dev_tx_msg); |
| 604 | 604 | |
| 605 | − if (can_dropped_invalid_skb(netdev, skb)) | |
| 605 | + if (can_dev_dropped_skb(netdev, skb)) | |
| 606 | 606 | return NETDEV_TX_OK; |
| 607 | 607 | |
| 608 | 608 | /* create a URB, and a buffer for it, and copy the data to the URB */ |
| @@ -743,7 +743,7 @@ static netdev_tx_t xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 742 unmodified lines | ||
| 743 | 743 | struct xcan_priv *priv = netdev_priv(ndev); |
| 744 | 744 | int ret; |
| 745 | 745 | |
| 746 | − if (can_dropped_invalid_skb(ndev, skb)) | |
| 746 | + if (can_dev_dropped_skb(ndev, skb)) | |
| 747 | 747 | return NETDEV_TX_OK; |
| 748 | 748 | |
| 749 | 749 | if (priv->devtype.flags & XCAN_FLAG_TX_MAILBOXES) |
| @@ -376,6 +376,17 @@ static struct mdio_driver dsa_loop_drv = { · 375 unmodified lines | ||
| 376 | 376 | |
| 377 | 377 | #define NUM_FIXED_PHYS (DSA_LOOP_NUM_PORTS - 2) |
| 378 | 378 | |
| 379 | +static void dsa_loop_phydevs_unregister(void) | |
| 380 | +{ | |
| 381 | + unsigned int i; | |
| 382 | + | |
| 383 | + for (i = 0; i < NUM_FIXED_PHYS; i++) | |
| 384 | + if (!IS_ERR(phydevs[i])) { | |
| 385 | + fixed_phy_unregister(phydevs[i]); | |
| 386 | + phy_device_free(phydevs[i]); | |
| 387 | + } | |
| 388 | +} | |
| 389 | + | |
| 379 | 390 | static int __init dsa_loop_init(void) |
| 380 | 391 | { |
| 381 | 392 | struct fixed_phy_status status = { |
| @@ -383,23 +394,23 @@ static int __init dsa_loop_init(void) · 1 unmodified line | ||
| 383 | 394 | .speed = SPEED_100, |
| 384 | 395 | .duplex = DUPLEX_FULL, |
| 385 | 396 | }; |
| 386 | − unsigned int i; | |
| 397 | + unsigned int i, ret; | |
| 387 | 398 | |
| 388 | 399 | for (i = 0; i < NUM_FIXED_PHYS; i++) |
| 389 | 400 | phydevs[i] = fixed_phy_register(PHY_POLL, &status, NULL); |
| 390 | 401 | |
| 391 | − return mdio_driver_register(&dsa_loop_drv); | |
| 402 | + ret = mdio_driver_register(&dsa_loop_drv); | |
| 403 | + if (ret) | |
| 404 | + dsa_loop_phydevs_unregister(); | |
| 405 | + | |
| 406 | + return ret; | |
| 392 | 407 | } |
| 393 | 408 | module_init(dsa_loop_init); |
| 394 | 409 | |
| 395 | 410 | static void __exit dsa_loop_exit(void) |
| 396 | 411 | { |
| 397 | − unsigned int i; | |
| 398 | − | |
| 399 | 412 | mdio_driver_unregister(&dsa_loop_drv); |
| 400 | − for (i = 0; i < NUM_FIXED_PHYS; i++) | |
| 401 | − if (!IS_ERR(phydevs[i])) | |
| 402 | − fixed_phy_unregister(phydevs[i]); | |
| 413 | + dsa_loop_phydevs_unregister(); | |
| 403 | 414 | } |
| 404 | 415 | module_exit(dsa_loop_exit); |
| 405 | 416 | |
| @@ -961,7 +961,7 @@ static const struct lan9303_mib_desc lan9303_mib[] = { · 960 unmodified lines | ||
| 961 | 961 | { .offset = LAN9303_MAC_TX_BRDCST_CNT_0, .name = "TxBroad", }, |
| 962 | 962 | { .offset = LAN9303_MAC_TX_PAUSE_CNT_0, .name = "TxPause", }, |
| 963 | 963 | { .offset = LAN9303_MAC_TX_MULCST_CNT_0, .name = "TxMulti", }, |
| 964 | − { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "TxUnderRun", }, | |
| 964 | + { .offset = LAN9303_MAC_RX_UNDSZE_CNT_0, .name = "RxShort", }, | |
| 965 | 965 | { .offset = LAN9303_MAC_TX_64_CNT_0, .name = "Tx64Byte", }, |
| 966 | 966 | { .offset = LAN9303_MAC_TX_127_CNT_0, .name = "Tx128Byte", }, |
| 967 | 967 | { .offset = LAN9303_MAC_TX_255_CNT_0, .name = "Tx256Byte", }, |
| @@ -256,6 +256,9 @@ static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg) · 255 unmodified lines | ||
| 256 | 256 | u32 tmp; |
| 257 | 257 | int rc; |
| 258 | 258 | |
| 259 | + if (reg & MII_ADDR_C45) | |
| 260 | + return -EOPNOTSUPP; | |
| 261 | + | |
| 259 | 262 | rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg, |
| 260 | 263 | &tmp, NULL); |
| 261 | 264 | if (rc < 0) |
| @@ -272,6 +275,9 @@ static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg, · 10 unmodified lines | ||
| 272 | 275 | const struct sja1105_regs *regs = priv->info->regs; |
| 273 | 276 | u32 tmp = val; |
| 274 | 277 | |
| 278 | + if (reg & MII_ADDR_C45) | |
| 279 | + return -EOPNOTSUPP; | |
| 280 | + | |
| 275 | 281 | return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg, |
| 276 | 282 | &tmp, NULL); |
| 277 | 283 | } |
| @@ -1512,16 +1512,15 @@ static struct notifier_block adin1110_switchdev_notifier = { · 1511 unmodified lines | ||
| 1512 | 1512 | .notifier_call = adin1110_switchdev_event, |
| 1513 | 1513 | }; |
| 1514 | 1514 | |
| 1515 | −static void adin1110_unregister_notifiers(void *data) | |
| 1515 | +static void adin1110_unregister_notifiers(void) | |
| 1516 | 1516 | { |
| 1517 | 1517 | unregister_switchdev_blocking_notifier(&adin1110_switchdev_blocking_notifier); |
| 1518 | 1518 | unregister_switchdev_notifier(&adin1110_switchdev_notifier); |
| 1519 | 1519 | unregister_netdevice_notifier(&adin1110_netdevice_nb); |
| 1520 | 1520 | } |
| 1521 | 1521 | |
| 1522 | −static int adin1110_setup_notifiers(struct adin1110_priv *priv) | |
| 1522 | +static int adin1110_setup_notifiers(void) | |
| 1523 | 1523 | { |
| 1524 | − struct device *dev = &priv->spidev->dev; | |
| 1525 | 1524 | int ret; |
| 1526 | 1525 | |
| 1527 | 1526 | ret = register_netdevice_notifier(&adin1110_netdevice_nb); |
| @@ -1536,13 +1535,14 @@ static int adin1110_setup_notifiers(struct adin1110_priv *priv) · 8 unmodified lines | ||
| 1536 | 1535 | if (ret < 0) |
| 1537 | 1536 | goto err_sdev; |
| 1538 | 1537 | |
| 1539 | − return devm_add_action_or_reset(dev, adin1110_unregister_notifiers, NULL); | |
| 1538 | + return 0; | |
| 1540 | 1539 | |
| 1541 | 1540 | err_sdev: |
| 1542 | 1541 | unregister_switchdev_notifier(&adin1110_switchdev_notifier); |
| 1543 | 1542 | |
| 1544 | 1543 | err_netdev: |
| 1545 | 1544 | unregister_netdevice_notifier(&adin1110_netdevice_nb); |
| 1545 | + | |
| 1546 | 1546 | return ret; |
| 1547 | 1547 | } |
| 1548 | 1548 | |
| @@ -1613,10 +1613,6 @@ static int adin1110_probe_netdevs(struct adin1110_priv *priv) · 64 unmodified lines | ||
| 1613 | 1613 | if (ret < 0) |
| 1614 | 1614 | return ret; |
| 1615 | 1615 | |
| 1616 | − ret = adin1110_setup_notifiers(priv); | |
| 1617 | − if (ret < 0) | |
| 1618 | − return ret; | |
| 1619 | − | |
| 1620 | 1616 | for (i = 0; i < priv->cfg->ports_nr; i++) { |
| 1621 | 1617 | ret = devm_register_netdev(dev, priv->ports[i]->netdev); |
| 1622 | 1618 | if (ret < 0) { |
| @@ -1693,7 +1689,31 @@ static struct spi_driver adin1110_driver = { · 70 unmodified lines | ||
| 1693 | 1689 | .probe = adin1110_probe, |
| 1694 | 1690 | .id_table = adin1110_spi_id, |
| 1695 | 1691 | }; |
| 1696 | −module_spi_driver(adin1110_driver); | |
| 1692 | + | |
| 1693 | +static int __init adin1110_driver_init(void) | |
| 1694 | +{ | |
| 1695 | + int ret; | |
| 1696 | + | |
| 1697 | + ret = adin1110_setup_notifiers(); | |
| 1698 | + if (ret < 0) | |
| 1699 | + return ret; | |
| 1700 | + | |
| 1701 | + ret = spi_register_driver(&adin1110_driver); | |
| 1702 | + if (ret < 0) { | |
| 1703 | + adin1110_unregister_notifiers(); | |
| 1704 | + return ret; | |
| 1705 | + } | |
| 1706 | + | |
| 1707 | + return 0; | |
| 1708 | +} | |
| 1709 | + | |
| 1710 | +static void __exit adin1110_exit(void) | |
| 1711 | +{ | |
| 1712 | + adin1110_unregister_notifiers(); | |
| 1713 | + spi_unregister_driver(&adin1110_driver); | |
| 1714 | +} | |
| 1715 | +module_init(adin1110_driver_init); | |
| 1716 | +module_exit(adin1110_exit); | |
| 1697 | 1717 | |
| 1698 | 1718 | MODULE_DESCRIPTION("ADIN1110 Network driver"); |
| 1699 | 1719 | MODULE_AUTHOR("Alexandru Tachici <alexandru.tachici@analog.com>"); |
| @@ -990,6 +990,7 @@ static int tse_shutdown(struct net_device *dev) · 989 unmodified lines | ||
| 990 | 990 | int ret; |
| 991 | 991 | |
| 992 | 992 | phylink_stop(priv->phylink); |
| 993 | + phylink_disconnect_phy(priv->phylink); | |
| 993 | 994 | netif_stop_queue(dev); |
| 994 | 995 | napi_disable(&priv->napi); |
| 995 | 996 | |
| @@ -4543,13 +4543,19 @@ static struct pci_driver ena_pci_driver = { · 4542 unmodified lines | ||
| 4543 | 4543 | |
| 4544 | 4544 | static int __init ena_init(void) |
| 4545 | 4545 | { |
| 4546 | + int ret; | |
| 4547 | + | |
| 4546 | 4548 | ena_wq = create_singlethread_workqueue(DRV_MODULE_NAME); |
| 4547 | 4549 | if (!ena_wq) { |
| 4548 | 4550 | pr_err("Failed to create workqueue\n"); |
| 4549 | 4551 | return -ENOMEM; |
| 4550 | 4552 | } |
| 4551 | 4553 | |
| 4552 | − return pci_register_driver(&ena_pci_driver); | |
| 4554 | + ret = pci_register_driver(&ena_pci_driver); | |
| 4555 | + if (ret) | |
| 4556 | + destroy_workqueue(ena_wq); | |
| 4557 | + | |
| 4558 | + return ret; | |
| 4553 | 4559 | } |
| 4554 | 4560 | |
| 4555 | 4561 | static void __exit ena_cleanup(void) |
| @@ -1004,8 +1004,10 @@ static int xgene_enet_open(struct net_device *ndev) · 1003 unmodified lines | ||
| 1004 | 1004 | |
| 1005 | 1005 | xgene_enet_napi_enable(pdata); |
| 1006 | 1006 | ret = xgene_enet_register_irq(ndev); |
| 1007 | − if (ret) | |
| 1007 | + if (ret) { | |
| 1008 | + xgene_enet_napi_disable(pdata); | |
| 1008 | 1009 | return ret; |
| 1010 | + } | |
| 1009 | 1011 | |
| 1010 | 1012 | if (ndev->phydev) { |
| 1011 | 1013 | phy_start(ndev->phydev); |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | #include "aq_ptp.h" |
| 14 | 14 | #include "aq_filters.h" |
| 15 | 15 | #include "aq_macsec.h" |
| 16 | +#include "aq_main.h" | |
| 16 | 17 | |
| 17 | 18 | #include <linux/ptp_clock_kernel.h> |
| 18 | 19 | |
| @@ -858,7 +859,7 @@ static int aq_set_ringparam(struct net_device *ndev, · 839 unmodified lines | ||
| 858 | 859 | |
| 859 | 860 | if (netif_running(ndev)) { |
| 860 | 861 | ndev_running = true; |
| 861 | − dev_close(ndev); | |
| 862 | + aq_ndev_close(ndev); | |
| 862 | 863 | } |
| 863 | 864 | |
| 864 | 865 | cfg->rxds = max(ring->rx_pending, hw_caps->rxds_min); |
| @@ -874,7 +875,7 @@ static int aq_set_ringparam(struct net_device *ndev, · 9 unmodified lines | ||
| 874 | 875 | goto err_exit; |
| 875 | 876 | |
| 876 | 877 | if (ndev_running) |
| 877 | − err = dev_open(ndev, NULL); | |
| 878 | + err = aq_ndev_open(ndev); | |
| 878 | 879 | |
| 879 | 880 | err_exit: |
| 880 | 881 | return err; |
| @@ -570,6 +570,7 @@ static int aq_update_txsa(struct aq_nic_s *nic, const unsigned int sc_idx, · 569 unmodified lines | ||
| 570 | 570 | |
| 571 | 571 | ret = aq_mss_set_egress_sakey_record(hw, &key_rec, sa_idx); |
| 572 | 572 | |
| 573 | + memzero_explicit(&key_rec, sizeof(key_rec)); | |
| 573 | 574 | return ret; |
| 574 | 575 | } |
| 575 | 576 | |
| @@ -899,6 +900,7 @@ static int aq_update_rxsa(struct aq_nic_s *nic, const unsigned int sc_idx, · 323 unmodified lines | ||
| 899 | 900 | |
| 900 | 901 | ret = aq_mss_set_ingress_sakey_record(hw, &sa_key_record, sa_idx); |
| 901 | 902 | |
| 903 | + memzero_explicit(&sa_key_record, sizeof(sa_key_record)); | |
| 902 | 904 | return ret; |
| 903 | 905 | } |
| 904 | 906 | |
| @@ -58,7 +58,7 @@ struct net_device *aq_ndev_alloc(void) · 57 unmodified lines | ||
| 58 | 58 | return ndev; |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | −static int aq_ndev_open(struct net_device *ndev) | |
| 61 | +int aq_ndev_open(struct net_device *ndev) | |
| 62 | 62 | { |
| 63 | 63 | struct aq_nic_s *aq_nic = netdev_priv(ndev); |
| 64 | 64 | int err = 0; |
| @@ -88,7 +88,7 @@ err_exit: · 23 unmodified lines | ||
| 88 | 88 | return err; |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | −static int aq_ndev_close(struct net_device *ndev) | |
| 91 | +int aq_ndev_close(struct net_device *ndev) | |
| 92 | 92 | { |
| 93 | 93 | struct aq_nic_s *aq_nic = netdev_priv(ndev); |
| 94 | 94 | int err = 0; |
| @@ -16,5 +16,7 @@ DECLARE_STATIC_KEY_FALSE(aq_xdp_locking_key); · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | void aq_ndev_schedule_work(struct work_struct *work); |
| 18 | 18 | struct net_device *aq_ndev_alloc(void); |
| 19 | +int aq_ndev_open(struct net_device *ndev); | |
| 20 | +int aq_ndev_close(struct net_device *ndev); | |
| 19 | 21 | |
| 20 | 22 | #endif /* AQ_MAIN_H */ |
| @@ -757,6 +757,7 @@ set_ingress_sakey_record(struct aq_hw_s *hw, · 756 unmodified lines | ||
| 757 | 757 | u16 table_index) |
| 758 | 758 | { |
| 759 | 759 | u16 packed_record[18]; |
| 760 | + int ret; | |
| 760 | 761 | |
| 761 | 762 | if (table_index >= NUMROWS_INGRESSSAKEYRECORD) |
| 762 | 763 | return -EINVAL; |
| @@ -789,9 +790,12 @@ set_ingress_sakey_record(struct aq_hw_s *hw, · 26 unmodified lines | ||
| 789 | 790 | |
| 790 | 791 | packed_record[16] = rec->key_len & 0x3; |
| 791 | 792 | |
| 792 | − return set_raw_ingress_record(hw, packed_record, 18, 2, | |
| 793 | − ROWOFFSET_INGRESSSAKEYRECORD + | |
| 794 | − table_index); | |
| 793 | + ret = set_raw_ingress_record(hw, packed_record, 18, 2, | |
| 794 | + ROWOFFSET_INGRESSSAKEYRECORD + | |
| 795 | + table_index); | |
| 796 | + | |
| 797 | + memzero_explicit(packed_record, sizeof(packed_record)); | |
| 798 | + return ret; | |
| 795 | 799 | } |
| 796 | 800 | |
| 797 | 801 | int aq_mss_set_ingress_sakey_record(struct aq_hw_s *hw, |
| @@ -1739,14 +1743,14 @@ static int set_egress_sakey_record(struct aq_hw_s *hw, · 941 unmodified lines | ||
| 1739 | 1743 | ret = set_raw_egress_record(hw, packed_record, 8, 2, |
| 1740 | 1744 | ROWOFFSET_EGRESSSAKEYRECORD + table_index); |
| 1741 | 1745 | if (unlikely(ret)) |
| 1742 | − return ret; | |
| 1746 | + goto clear_key; | |
| 1743 | 1747 | ret = set_raw_egress_record(hw, packed_record + 8, 8, 2, |
| 1744 | 1748 | ROWOFFSET_EGRESSSAKEYRECORD + table_index - |
| 1745 | 1749 | 32); |
| 1746 | − if (unlikely(ret)) | |
| 1747 | − return ret; | |
| 1748 | 1750 | |
| 1749 | − return 0; | |
| 1751 | +clear_key: | |
| 1752 | + memzero_explicit(packed_record, sizeof(packed_record)); | |
| 1753 | + return ret; | |
| 1750 | 1754 | } |
| 1751 | 1755 | |
| 1752 | 1756 | int aq_mss_set_egress_sakey_record(struct aq_hw_s *hw, |
| @@ -1427,7 +1427,7 @@ static int ag71xx_open(struct net_device *ndev) · 1426 unmodified lines | ||
| 1427 | 1427 | if (ret) { |
| 1428 | 1428 | netif_err(ag, link, ndev, "phylink_of_phy_connect filed with err: %i\n", |
| 1429 | 1429 | ret); |
| 1430 | − goto err; | |
| 1430 | + return ret; | |
| 1431 | 1431 | } |
| 1432 | 1432 | |
| 1433 | 1433 | max_frame_len = ag71xx_max_frame_len(ndev->mtu); |
| @@ -1448,6 +1448,7 @@ static int ag71xx_open(struct net_device *ndev) · 14 unmodified lines | ||
| 1448 | 1448 | |
| 1449 | 1449 | err: |
| 1450 | 1450 | ag71xx_rings_cleanup(ag); |
| 1451 | + phylink_disconnect_phy(ag->phylink); | |
| 1451 | 1452 | return ret; |
| 1452 | 1453 | } |
| 1453 | 1454 | |
| @@ -77,7 +77,7 @@ config BCMGENET · 76 unmodified lines | ||
| 77 | 77 | select BCM7XXX_PHY |
| 78 | 78 | select MDIO_BCM_UNIMAC |
| 79 | 79 | select DIMLIB |
| 80 | − select BROADCOM_PHY if ARCH_BCM2835 | |
| 80 | + select BROADCOM_PHY if (ARCH_BCM2835 && PTP_1588_CLOCK_OPTIONAL) | |
| 81 | 81 | help |
| 82 | 82 | This driver supports the built-in Ethernet MACs found in the |
| 83 | 83 | Broadcom BCM7xxx Set Top Box family chipset. |
| @@ -1568,7 +1568,6 @@ void bgmac_enet_remove(struct bgmac *bgmac) · 1567 unmodified lines | ||
| 1568 | 1568 | phy_disconnect(bgmac->net_dev->phydev); |
| 1569 | 1569 | netif_napi_del(&bgmac->napi); |
| 1570 | 1570 | bgmac_dma_free(bgmac); |
| 1571 | − free_netdev(bgmac->net_dev); | |
| 1572 | 1571 | } |
| 1573 | 1572 | EXPORT_SYMBOL_GPL(bgmac_enet_remove); |
| 1574 | 1573 | |
| @@ -795,16 +795,20 @@ static void bnx2x_vf_enable_traffic(struct bnx2x *bp, struct bnx2x_virtf *vf) · 794 unmodified lines | ||
| 795 | 795 | |
| 796 | 796 | static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid) |
| 797 | 797 | { |
| 798 | − struct pci_dev *dev; | |
| 799 | 798 | struct bnx2x_virtf *vf = bnx2x_vf_by_abs_fid(bp, abs_vfid); |
| 799 | + struct pci_dev *dev; | |
| 800 | + bool pending; | |
| 800 | 801 | |
| 801 | 802 | if (!vf) |
| 802 | 803 | return false; |
| 803 | 804 | |
| 804 | 805 | dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn); |
| 805 | − if (dev) | |
| 806 | − return bnx2x_is_pcie_pending(dev); | |
| 807 | − return false; | |
| 806 | + if (!dev) | |
| 807 | + return false; | |
| 808 | + pending = bnx2x_is_pcie_pending(dev); | |
| 809 | + pci_dev_put(dev); | |
| 810 | + | |
| 811 | + return pending; | |
| 808 | 812 | } |
| 809 | 813 | |
| 810 | 814 | int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid) |
| @@ -9983,17 +9983,12 @@ static int bnxt_try_recover_fw(struct bnxt *bp) · 9982 unmodified lines | ||
| 9983 | 9983 | return -ENODEV; |
| 9984 | 9984 | } |
| 9985 | 9985 | |
| 9986 | −int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset) | |
| 9986 | +static void bnxt_clear_reservations(struct bnxt *bp, bool fw_reset) | |
| 9987 | 9987 | { |
| 9988 | 9988 | struct bnxt_hw_resc *hw_resc = &bp->hw_resc; |
| 9989 | − int rc; | |
| 9990 | 9989 | |
| 9991 | 9990 | if (!BNXT_NEW_RM(bp)) |
| 9992 | − return 0; /* no resource reservations required */ | |
| 9993 | − | |
| 9994 | − rc = bnxt_hwrm_func_resc_qcaps(bp, true); | |
| 9995 | − if (rc) | |
| 9996 | − netdev_err(bp->dev, "resc_qcaps failed\n"); | |
| 9991 | + return; /* no resource reservations required */ | |
| 9997 | 9992 | |
| 9998 | 9993 | hw_resc->resv_cp_rings = 0; |
| 9999 | 9994 | hw_resc->resv_stat_ctxs = 0; |
| @@ -10006,6 +10001,20 @@ int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset) · 6 unmodified lines | ||
| 10006 | 10001 | bp->tx_nr_rings = 0; |
| 10007 | 10002 | bp->rx_nr_rings = 0; |
| 10008 | 10003 | } |
| 10004 | +} | |
| 10005 | + | |
| 10006 | +int bnxt_cancel_reservations(struct bnxt *bp, bool fw_reset) | |
| 10007 | +{ | |
| 10008 | + int rc; | |
| 10009 | + | |
| 10010 | + if (!BNXT_NEW_RM(bp)) | |
| 10011 | + return 0; /* no resource reservations required */ | |
| 10012 | + | |
| 10013 | + rc = bnxt_hwrm_func_resc_qcaps(bp, true); | |
| 10014 | + if (rc) | |
| 10015 | + netdev_err(bp->dev, "resc_qcaps failed\n"); | |
| 10016 | + | |
| 10017 | + bnxt_clear_reservations(bp, fw_reset); | |
| 10009 | 10018 | |
| 10010 | 10019 | return rc; |
| 10011 | 10020 | } |
| @@ -12894,8 +12903,8 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, · 2882 unmodified lines | ||
| 12894 | 12903 | rcu_read_lock(); |
| 12895 | 12904 | hlist_for_each_entry_rcu(fltr, head, hash) { |
| 12896 | 12905 | if (bnxt_fltr_match(fltr, new_fltr)) { |
| 12906 | + rc = fltr->sw_id; | |
| 12897 | 12907 | rcu_read_unlock(); |
| 12898 | − rc = 0; | |
| 12899 | 12908 | goto err_free; |
| 12900 | 12909 | } |
| 12901 | 12910 | } |
| @@ -13913,7 +13922,9 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) · 1011 unmodified lines | ||
| 13913 | 13922 | pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT; |
| 13914 | 13923 | struct net_device *netdev = pci_get_drvdata(pdev); |
| 13915 | 13924 | struct bnxt *bp = netdev_priv(netdev); |
| 13916 | − int err = 0, off; | |
| 13925 | + int retry = 0; | |
| 13926 | + int err = 0; | |
| 13927 | + int off; | |
| 13917 | 13928 | |
| 13918 | 13929 | netdev_info(bp->dev, "PCI Slot Reset\n"); |
| 13919 | 13930 | |
| @@ -13941,11 +13952,36 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) · 21 unmodified lines | ||
| 13941 | 13952 | pci_restore_state(pdev); |
| 13942 | 13953 | pci_save_state(pdev); |
| 13943 | 13954 | |
| 13955 | + bnxt_inv_fw_health_reg(bp); | |
| 13956 | + bnxt_try_map_fw_health_reg(bp); | |
| 13957 | + | |
| 13958 | + /* In some PCIe AER scenarios, firmware may take up to | |
| 13959 | + * 10 seconds to become ready in the worst case. | |
| 13960 | + */ | |
| 13961 | + do { | |
| 13962 | + err = bnxt_try_recover_fw(bp); | |
| 13963 | + if (!err) | |
| 13964 | + break; | |
| 13965 | + retry++; | |
| 13966 | + } while (retry < BNXT_FW_SLOT_RESET_RETRY); | |
| 13967 | + | |
| 13968 | + if (err) { | |
| 13969 | + dev_err(&pdev->dev, "Firmware not ready\n"); | |
| 13970 | + goto reset_exit; | |
| 13971 | + } | |
| 13972 | + | |
| 13944 | 13973 | err = bnxt_hwrm_func_reset(bp); |
| 13945 | 13974 | if (!err) |
| 13946 | 13975 | result = PCI_ERS_RESULT_RECOVERED; |
| 13976 | + | |
| 13977 | + bnxt_ulp_irq_stop(bp); | |
| 13978 | + bnxt_clear_int_mode(bp); | |
| 13979 | + err = bnxt_init_int_mode(bp); | |
| 13980 | + bnxt_ulp_irq_restart(bp, err); | |
| 13947 | 13981 | } |
| 13948 | 13982 | |
| 13983 | +reset_exit: | |
| 13984 | + bnxt_clear_reservations(bp, true); | |
| 13949 | 13985 | rtnl_unlock(); |
| 13950 | 13986 | |
| 13951 | 13987 | return result; |
| @@ -14001,8 +14037,16 @@ static struct pci_driver bnxt_pci_driver = { · 49 unmodified lines | ||
| 14001 | 14037 | |
| 14002 | 14038 | static int __init bnxt_init(void) |
| 14003 | 14039 | { |
| 14040 | + int err; | |
| 14041 | + | |
| 14004 | 14042 | bnxt_debug_init(); |
| 14005 | − return pci_register_driver(&bnxt_pci_driver); | |
| 14043 | + err = pci_register_driver(&bnxt_pci_driver); | |
| 14044 | + if (err) { | |
| 14045 | + bnxt_debug_exit(); | |
| 14046 | + return err; | |
| 14047 | + } | |
| 14048 | + | |
| 14049 | + return 0; | |
| 14006 | 14050 | } |
| 14007 | 14051 | |
1 more 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 10 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 12 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 12 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 68 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 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 228 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 17 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 28 lines aren’t shown here.
This diff is large: its 13 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 8 lines aren’t shown here.
This diff is large: its 121 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 32 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 41 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 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 49 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 17 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 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 70 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 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 37 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 10 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 46 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 103 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 45 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 290 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 40 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 153 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 143 lines aren’t shown here.
This diff is large: its 19 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 69 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 22 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 10 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 16 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 29 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 8 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 8 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 117 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 29 lines aren’t shown here.
This diff is large: its 8 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 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 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 149 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 74 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 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 14 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 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 59 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 86 lines aren’t shown here.
This diff is large: its 14 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 13 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 61 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 22 lines aren’t shown here.
This diff is large: its 8 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 191 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 24 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 18 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 8 lines aren’t shown here.
This diff is large: its 8 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 89 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 141 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 21 lines aren’t shown here.
This diff is large: its 29 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 70 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 12 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 12 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 8 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 222 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 11 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 90 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 8 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 8 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 8 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 8 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 8 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 8 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 8 lines aren’t shown here.
This diff is large: its 10 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 11 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 16 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 36 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 39 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 33 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 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 114 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 13 lines aren’t shown here.
This diff is large: its 49 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 10 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 97 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 27 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 23 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 34 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 23 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 283 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
File renamed without changes.
This diff is large: its 16 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 97 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 25 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 93 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 35 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 48 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 114 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 9 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 28 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 97 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 40 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 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 30 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 133 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 25 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 17 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 30 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 22 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 11 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 19 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 38 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 31 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 62 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 52 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 8 lines aren’t shown here.
This diff is large: its 57 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 9 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 88 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 45 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 19 lines aren’t shown here.
This diff is large: its 20 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 26 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 44 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 10 lines aren’t shown here.
This diff is large: its 9 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 21 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 780 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 16 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 11 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 30 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 29 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 171 lines aren’t shown here.
This diff is large: its 12 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 16 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 44 lines aren’t shown here.
This diff is large: its 120 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 17 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 15 lines aren’t shown here.
This diff is large: its 9 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 60 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 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 32 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 36 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 10 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 111 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 12 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 28 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 8 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 9 lines aren’t shown here.
This diff is large: its 40 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 86 lines aren’t shown here.
This diff is large: its 183 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 139 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 28 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 215 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 70 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 36 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 12 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 50 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 40 lines aren’t shown here.
This diff is large: its 220 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 38494 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 63 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 228 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 20 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 65 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 18 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 73 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 174 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 172 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 9 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 17 lines aren’t shown here.
This diff is large: its 196 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 13 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 51 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 55 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 23 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 139 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 19 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 10 lines aren’t shown here.
This diff is large: its 17 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 21 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 15 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 57 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 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 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 27 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 81 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 18 lines aren’t shown here.
This diff is large: its 59 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 14 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 12 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 20 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 103 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 22 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 26 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 10 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 68 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 26 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 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 11 lines aren’t shown here.
This diff is large: its 28 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 13 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 31 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 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 25 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 18 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 26 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 27 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 27 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 9 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 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 26 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 21 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 34 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 50 lines aren’t shown here.
This diff is large: its 10 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 82 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 10 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 188 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 68 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 12 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 444 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 35796 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 26 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 8 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 20 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 199 lines aren’t shown here.
This diff is large: its 23 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 27 lines aren’t shown here.
This diff is large: its 38 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 47 lines aren’t shown here.
This diff is large: its 35 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 45 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.