These two series from Mark and Shun extend RDMA mlx5 API. Mark's series provides c0 register used to match egress traffic sent by local device. Shun's series adds new type for ICM area.
Unified · Split
| @@ -117,6 +117,7 @@ Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com> · 116 unmodified lines | ||
| 117 | 117 | Changbin Du <changbin.du@intel.com> <changbin.du@intel.com> |
| 118 | 118 | Chao Yu <chao@kernel.org> <chao2.yu@samsung.com> |
| 119 | 119 | Chao Yu <chao@kernel.org> <yuchao0@huawei.com> |
| 120 | +Chester Lin <chester62515@gmail.com> <clin@suse.com> | |
| 120 | 121 | Chris Chiu <chris.chiu@canonical.com> <chiu@endlessm.com> |
| 121 | 122 | Chris Chiu <chris.chiu@canonical.com> <chiu@endlessos.org> |
| 122 | 123 | Chris Lew <quic_clew@quicinc.com> <clew@codeaurora.org> |
| @@ -2944,6 +2944,14 @@ D: IPX development and support · 2943 unmodified lines | ||
| 2944 | 2944 | N: Venkatesh Pallipadi (Venki) |
| 2945 | 2945 | D: x86/HPET |
| 2946 | 2946 | |
| 2947 | +N: Antti Palosaari | |
| 2948 | +E: crope@iki.fi | |
| 2949 | +D: Various DVB drivers | |
| 2950 | +W: https://palosaari.fi/linux/ | |
| 2951 | +S: Yliopistokatu 1 D 513 | |
| 2952 | +S: FI-90570 Oulu | |
| 2953 | +S: FINLAND | |
| 2954 | + | |
| 2947 | 2955 | N: Kyungmin Park |
| 2948 | 2956 | E: kyungmin.park@samsung.com |
| 2949 | 2957 | D: Samsung S5Pv210 and Exynos4210 mobile platforms |
| @@ -6,3 +6,12 @@ Description: · 5 unmodified lines | ||
| 6 | 6 | OP-TEE bus provides reference to registered drivers under this directory. The <uuid> |
| 7 | 7 | matches Trusted Application (TA) driver and corresponding TA in secure OS. Drivers |
| 8 | 8 | are free to create needed API under optee-ta-<uuid> directory. |
| 9 | + | |
| 10 | +What: /sys/bus/tee/devices/optee-ta-<uuid>/need_supplicant | |
| 11 | +Date: November 2023 | |
| 12 | +KernelVersion: 6.7 | |
| 13 | +Contact: op-tee@lists.trustedfirmware.org | |
| 14 | +Description: | |
| 15 | + Allows to distinguish whether an OP-TEE based TA/device requires user-space | |
| 16 | + tee-supplicant to function properly or not. This attribute will be present for | |
| 17 | + devices which depend on tee-supplicant to be running. | |
| @@ -59,15 +59,6 @@ Description: · 58 unmodified lines | ||
| 59 | 59 | brightness. Reading this file when no hw brightness change |
| 60 | 60 | event has happened will return an ENODATA error. |
| 61 | 61 | |
| 62 | −What: /sys/class/leds/<led>/color | |
| 63 | −Date: June 2023 | |
| 64 | −KernelVersion: 6.5 | |
| 65 | −Description: | |
| 66 | − Color of the LED. | |
| 67 | − | |
| 68 | − This is a read-only file. Reading this file returns the color | |
| 69 | − of the LED as a string (e.g: "red", "green", "multicolor"). | |
| 70 | − | |
| 71 | 62 | What: /sys/class/leds/<led>/trigger |
| 72 | 63 | Date: March 2006 |
| 73 | 64 | KernelVersion: 2.6.17 |
| @@ -375,9 +375,9 @@ Developer web site of Loongson and LoongArch (Software and Documentation): · 374 unmodified lines | ||
| 375 | 375 | |
| 376 | 376 | Documentation of LoongArch ISA: |
| 377 | 377 | |
| 378 | − https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-CN.pdf (in Chinese) | |
| 378 | + https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-CN.pdf (in Chinese) | |
| 379 | 379 | |
| 380 | − https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-EN.pdf (in English) | |
| 380 | + https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-EN.pdf (in English) | |
| 381 | 381 | |
| 382 | 382 | Documentation of LoongArch ELF psABI: |
| 383 | 383 | |
| @@ -77,7 +77,7 @@ Protocol 2.14 BURNT BY INCORRECT COMMIT · 76 unmodified lines | ||
| 77 | 77 | Protocol 2.15 (Kernel 5.5) Added the kernel_info and kernel_info.setup_type_max. |
| 78 | 78 | ============= ============================================================ |
| 79 | 79 | |
| 80 | −.. note:: | |
| 80 | + .. note:: | |
| 81 | 81 | The protocol version number should be changed only if the setup header |
| 82 | 82 | is changed. There is no need to update the version number if boot_params |
| 83 | 83 | or kernel_info are changed. Additionally, it is recommended to use |
| @@ -9,6 +9,9 @@ title: Analog Devices ADV7533/35 HDMI Encoders · 8 unmodified lines | ||
| 9 | 9 | maintainers: |
| 10 | 10 | - Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
| 11 | 11 | |
| 12 | +allOf: | |
| 13 | + - $ref: /schemas/sound/dai-common.yaml# | |
| 14 | + | |
| 12 | 15 | description: | |
| 13 | 16 | The ADV7533 and ADV7535 are HDMI audio and video transmitters |
| 14 | 17 | compatible with HDMI 1.4 and DVI 1.0. They support color space |
| @@ -89,6 +92,9 @@ properties: · 74 unmodified lines | ||
| 89 | 92 | $ref: /schemas/types.yaml#/definitions/uint32 |
| 90 | 93 | enum: [ 1, 2, 3, 4 ] |
| 91 | 94 | |
| 95 | + "#sound-dai-cells": | |
| 96 | + const: 0 | |
| 97 | + | |
| 92 | 98 | ports: |
| 93 | 99 | description: |
| 94 | 100 | The ADV7533/35 has two video ports and one audio port. |
| @@ -51,7 +51,10 @@ properties: · 50 unmodified lines | ||
| 51 | 51 | minItems: 1 |
| 52 | 52 | |
| 53 | 53 | interrupts: |
| 54 | − maxItems: 1 | |
| 54 | + items: | |
| 55 | + - description: LCDIF DMA interrupt | |
| 56 | + - description: LCDIF Error interrupt | |
| 57 | + minItems: 1 | |
| 55 | 58 | |
| 56 | 59 | power-domains: |
| 57 | 60 | maxItems: 1 |
| @@ -131,6 +134,21 @@ allOf: · 73 unmodified lines | ||
| 131 | 134 | then: |
| 132 | 135 | required: |
| 133 | 136 | - power-domains |
| 137 | + - if: | |
| 138 | + properties: | |
| 139 | + compatible: | |
| 140 | + contains: | |
| 141 | + enum: | |
| 142 | + - fsl,imx23-lcdif | |
| 143 | + then: | |
| 144 | + properties: | |
| 145 | + interrupts: | |
| 146 | + minItems: 2 | |
| 147 | + maxItems: 2 | |
| 148 | + else: | |
| 149 | + properties: | |
| 150 | + interrupts: | |
| 151 | + maxItems: 1 | |
| 134 | 152 | |
| 135 | 153 | examples: |
| 136 | 154 | - | |
| @@ -10,7 +10,6 @@ maintainers: · 9 unmodified lines | ||
| 10 | 10 | - Chun-Kuang Hu <chunkuang.hu@kernel.org> |
| 11 | 11 | - Philipp Zabel <p.zabel@pengutronix.de> |
| 12 | 12 | - Jitao Shi <jitao.shi@mediatek.com> |
| 13 | − - Xinlei Lee <xinlei.lee@mediatek.com> | |
| 14 | 13 | |
| 15 | 14 | description: | |
| 16 | 15 | The MediaTek DSI function block is a sink of the display subsystem and can |
| @@ -62,6 +62,9 @@ properties: · 61 unmodified lines | ||
| 62 | 62 | - description: MPM pin number |
| 63 | 63 | - description: GIC SPI number for the MPM pin |
| 64 | 64 | |
| 65 | + '#power-domain-cells': | |
| 66 | + const: 0 | |
| 67 | + | |
| 65 | 68 | required: |
| 66 | 69 | - compatible |
| 67 | 70 | - reg |
| @@ -93,4 +96,5 @@ examples: · 25 unmodified lines | ||
| 93 | 96 | <86 183>, |
| 94 | 97 | <90 260>, |
| 95 | 98 | <91 260>; |
| 99 | + #power-domain-cells = <0>; | |
| 96 | 100 | }; |
| @@ -275,12 +275,12 @@ allOf: · 274 unmodified lines | ||
| 275 | 275 | properties: |
| 276 | 276 | rx-internal-delay-ps: |
| 277 | 277 | description: |
| 278 | − RGMII Receive Clock Delay defined in pico seconds.This is used for | |
| 278 | + RGMII Receive Clock Delay defined in pico seconds. This is used for | |
| 279 | 279 | controllers that have configurable RX internal delays. If this |
| 280 | 280 | property is present then the MAC applies the RX delay. |
| 281 | 281 | tx-internal-delay-ps: |
| 282 | 282 | description: |
| 283 | − RGMII Transmit Clock Delay defined in pico seconds.This is used for | |
| 283 | + RGMII Transmit Clock Delay defined in pico seconds. This is used for | |
| 284 | 284 | controllers that have configurable TX internal delays. If this |
| 285 | 285 | property is present then the MAC applies the TX delay. |
| 286 | 286 | |
| @@ -90,7 +90,7 @@ properties: · 89 unmodified lines | ||
| 90 | 90 | bitmap of all MHPMCOUNTERx that can monitor the range of events |
| 91 | 91 | |
| 92 | 92 | dependencies: |
| 93 | − "riscv,event-to-mhpmevent": [ "riscv,event-to-mhpmcounters" ] | |
| 93 | + riscv,event-to-mhpmevent: [ "riscv,event-to-mhpmcounters" ] | |
| 94 | 94 | |
| 95 | 95 | required: |
| 96 | 96 | - compatible |
| @@ -9,7 +9,7 @@ title: NXP S32G2 pin controller · 8 unmodified lines | ||
| 9 | 9 | |
| 10 | 10 | maintainers: |
| 11 | 11 | - Ghennadi Procopciuc <Ghennadi.Procopciuc@oss.nxp.com> |
| 12 | − - Chester Lin <clin@suse.com> | |
| 12 | + - Chester Lin <chester62515@gmail.com> | |
| 13 | 13 | |
| 14 | 14 | description: | |
| 15 | 15 | S32G2 pinmux is implemented in SIUL2 (System Integration Unit Lite2), |
| @@ -14,12 +14,10 @@ allOf: · 13 unmodified lines | ||
| 14 | 14 | |
| 15 | 15 | properties: |
| 16 | 16 | "#pwm-cells": |
| 17 | − description: | | |
| 18 | − Should be 2 for i.MX1 and 3 for i.MX27 and newer SoCs. See pwm.yaml | |
| 19 | − in this directory for a description of the cells format. | |
| 20 | − enum: | |
| 21 | − - 2 | |
| 22 | − - 3 | |
| 17 | + description: | |
| 18 | + The only third cell flag supported by this binding is | |
| 19 | + PWM_POLARITY_INVERTED. fsl,imx1-pwm does not support this flags. | |
| 20 | + const: 3 | |
| 23 | 21 | |
| 24 | 22 | compatible: |
| 25 | 23 | oneOf: |
| @@ -233,6 +233,7 @@ allOf: · 232 unmodified lines | ||
| 233 | 233 | - rockchip,rk3399-grf |
| 234 | 234 | - rockchip,rk3399-pmugrf |
| 235 | 235 | - rockchip,rk3568-pmugrf |
| 236 | + - rockchip,rk3588-pmugrf | |
| 236 | 237 | - rockchip,rv1108-grf |
| 237 | 238 | - rockchip,rv1108-pmugrf |
| 238 | 239 | |
| @@ -36,6 +36,7 @@ properties: · 35 unmodified lines | ||
| 36 | 36 | - qcom,sm8350-ufshc |
| 37 | 37 | - qcom,sm8450-ufshc |
| 38 | 38 | - qcom,sm8550-ufshc |
| 39 | + - qcom,sm8650-ufshc | |
| 39 | 40 | - const: qcom,ufshc |
| 40 | 41 | - const: jedec,ufs-2.0 |
| 41 | 42 | |
| @@ -122,6 +123,7 @@ allOf: · 80 unmodified lines | ||
| 122 | 123 | - qcom,sm8350-ufshc |
| 123 | 124 | - qcom,sm8450-ufshc |
| 124 | 125 | - qcom,sm8550-ufshc |
| 126 | + - qcom,sm8650-ufshc | |
| 125 | 127 | then: |
| 126 | 128 | properties: |
| 127 | 129 | clocks: |
| @@ -36,7 +36,11 @@ properties: · 35 unmodified lines | ||
| 36 | 36 | |
| 37 | 37 | vdd-supply: |
| 38 | 38 | description: |
| 39 | − VDD power supply to the hub | |
| 39 | + 3V3 power supply to the hub | |
| 40 | + | |
| 41 | + vdd2-supply: | |
| 42 | + description: | |
| 43 | + 1V2 power supply to the hub | |
| 40 | 44 | |
| 41 | 45 | peer-hub: |
| 42 | 46 | $ref: /schemas/types.yaml#/definitions/phandle |
| @@ -62,6 +66,7 @@ allOf: · 19 unmodified lines | ||
| 62 | 66 | properties: |
| 63 | 67 | reset-gpios: false |
| 64 | 68 | vdd-supply: false |
| 69 | + vdd2-supply: false | |
| 65 | 70 | peer-hub: false |
| 66 | 71 | i2c-bus: false |
| 67 | 72 | else: |
| @@ -521,8 +521,8 @@ examples: · 520 unmodified lines | ||
| 521 | 521 | |
| 522 | 522 | interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, |
| 523 | 523 | <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, |
| 524 | − <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>, | |
| 525 | − <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>; | |
| 524 | + <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>, | |
| 525 | + <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>; | |
| 526 | 526 | interrupt-names = "hs_phy_irq", "ss_phy_irq", |
| 527 | 527 | "dm_hs_phy_irq", "dp_hs_phy_irq"; |
| 528 | 528 | |
| @@ -41,7 +41,7 @@ examples: · 40 unmodified lines | ||
| 41 | 41 | - | |
| 42 | 42 | usb { |
| 43 | 43 | phys = <&usb2_phy1>, <&usb3_phy1>; |
| 44 | − phy-names = "usb"; | |
| 44 | + phy-names = "usb2", "usb3"; | |
| 45 | 45 | #address-cells = <1>; |
| 46 | 46 | #size-cells = <0>; |
| 47 | 47 | |
| @@ -91,6 +91,10 @@ compatibility checking tool (fsck.erofs), and a debugging tool (dump.erofs): · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | - git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs-utils.git |
| 93 | 93 | |
| 94 | +For more information, please also refer to the documentation site: | |
| 95 | + | |
| 96 | +- https://erofs.docs.kernel.org | |
| 97 | + | |
| 94 | 98 | Bugs and patches are welcome, please kindly help us and send to the following |
| 95 | 99 | linux-erofs mailing list: |
| 96 | 100 | |
| @@ -99,7 +99,7 @@ also [6.1]:: · 98 unmodified lines | ||
| 99 | 99 | when it is no longer considered permitted. |
| 100 | 100 | |
| 101 | 101 | Linux TCP-AO will try its best to prevent you from removing a key that's |
| 102 | −being used, considering it a key management failure. But sine keeping | |
| 102 | +being used, considering it a key management failure. But since keeping | |
| 103 | 103 | an outdated key may become a security issue and as a peer may |
| 104 | 104 | unintentionally prevent the removal of an old key by always setting |
| 105 | 105 | it as RNextKeyID - a forced key removal mechanism is provided, where |
| @@ -193,9 +193,23 @@ Review timelines · 192 unmodified lines | ||
| 193 | 193 | Generally speaking, the patches get triaged quickly (in less than |
| 194 | 194 | 48h). But be patient, if your patch is active in patchwork (i.e. it's |
| 195 | 195 | listed on the project's patch list) the chances it was missed are close to zero. |
| 196 | −Asking the maintainer for status updates on your | |
| 197 | −patch is a good way to ensure your patch is ignored or pushed to the | |
| 198 | −bottom of the priority list. | |
| 196 | + | |
| 197 | +The high volume of development on netdev makes reviewers move on | |
| 198 | +from discussions relatively quickly. New comments and replies | |
| 199 | +are very unlikely to arrive after a week of silence. If a patch | |
| 200 | +is no longer active in patchwork and the thread went idle for more | |
| 201 | +than a week - clarify the next steps and/or post the next version. | |
| 202 | + | |
| 203 | +For RFC postings specifically, if nobody responded in a week - reviewers | |
| 204 | +either missed the posting or have no strong opinions. If the code is ready, | |
| 205 | +repost as a PATCH. | |
| 206 | + | |
| 207 | +Emails saying just "ping" or "bump" are considered rude. If you can't figure | |
| 208 | +out the status of the patch from patchwork or where the discussion has | |
| 209 | +landed - describe your best guess and ask if it's correct. For example:: | |
| 210 | + | |
| 211 | + I don't understand what the next steps are. Person X seems to be unhappy | |
| 212 | + with A, should I do B and repost the patches? | |
| 199 | 213 | |
| 200 | 214 | .. _Changes requested: |
| 201 | 215 | |
| @@ -130,7 +130,7 @@ Misc: · 129 unmodified lines | ||
| 130 | 130 | Device Tree Bindings |
| 131 | 131 | -------------------- |
| 132 | 132 | |
| 133 | −See Documentation/devicetree/bindings/arm/arm,coresight-\*.yaml for details. | |
| 133 | +See ``Documentation/devicetree/bindings/arm/arm,coresight-*.yaml`` for details. | |
| 134 | 134 | |
| 135 | 135 | As of this writing drivers for ITM, STMs and CTIs are not provided but are |
| 136 | 136 | expected to be added as the solution matures. |
| @@ -338,9 +338,9 @@ Loongson与LoongArch的开发者网站(软件与文档资源): · 337 unmodified lines | ||
| 338 | 338 | |
| 339 | 339 | LoongArch指令集架构的文档: |
| 340 | 340 | |
| 341 | − https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-CN.pdf (中文版) | |
| 341 | + https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-CN.pdf (中文版) | |
| 342 | 342 | |
| 343 | − https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.02-EN.pdf (英文版) | |
| 343 | + https://github.com/loongson/LoongArch-Documentation/releases/latest/download/LoongArch-Vol1-v1.10-EN.pdf (英文版) | |
| 344 | 344 | |
| 345 | 345 | LoongArch的ELF psABI文档: |
| 346 | 346 | |
| @@ -171,13 +171,10 @@ S: Supported · 170 unmodified lines | ||
| 171 | 171 | F: drivers/soc/fujitsu/a64fx-diag.c |
| 172 | 172 | |
| 173 | 173 | A8293 MEDIA DRIVER |
| 174 | −M: Antti Palosaari <crope@iki.fi> | |
| 175 | 174 | L: linux-media@vger.kernel.org |
| 176 | −S: Maintained | |
| 175 | +S: Orphan | |
| 177 | 176 | W: https://linuxtv.org |
| 178 | −W: http://palosaari.fi/linux/ | |
| 179 | 177 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 180 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 181 | 178 | F: drivers/media/dvb-frontends/a8293* |
| 182 | 179 | |
| 183 | 180 | AACRAID SCSI RAID DRIVER |
| @@ -576,23 +573,17 @@ F: drivers/iio/accel/adxl372_i2c.c · 392 unmodified lines | ||
| 576 | 573 | F: drivers/iio/accel/adxl372_spi.c |
| 577 | 574 | |
| 578 | 575 | AF9013 MEDIA DRIVER |
| 579 | −M: Antti Palosaari <crope@iki.fi> | |
| 580 | 576 | L: linux-media@vger.kernel.org |
| 581 | −S: Maintained | |
| 577 | +S: Orphan | |
| 582 | 578 | W: https://linuxtv.org |
| 583 | −W: http://palosaari.fi/linux/ | |
| 584 | 579 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 585 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 586 | 580 | F: drivers/media/dvb-frontends/af9013* |
| 587 | 581 | |
| 588 | 582 | AF9033 MEDIA DRIVER |
| 589 | −M: Antti Palosaari <crope@iki.fi> | |
| 590 | 583 | L: linux-media@vger.kernel.org |
| 591 | −S: Maintained | |
| 584 | +S: Orphan | |
| 592 | 585 | W: https://linuxtv.org |
| 593 | −W: http://palosaari.fi/linux/ | |
| 594 | 586 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 595 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 596 | 587 | F: drivers/media/dvb-frontends/af9033* |
| 597 | 588 | |
| 598 | 589 | AFFS FILE SYSTEM |
| @@ -650,13 +641,10 @@ F: fs/aio.c · 51 unmodified lines | ||
| 650 | 641 | F: include/linux/*aio*.h |
| 651 | 642 | |
| 652 | 643 | AIRSPY MEDIA DRIVER |
| 653 | −M: Antti Palosaari <crope@iki.fi> | |
| 654 | 644 | L: linux-media@vger.kernel.org |
| 655 | −S: Maintained | |
| 645 | +S: Orphan | |
| 656 | 646 | W: https://linuxtv.org |
| 657 | −W: http://palosaari.fi/linux/ | |
| 658 | 647 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 659 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 660 | 648 | F: drivers/media/usb/airspy/ |
| 661 | 649 | |
| 662 | 650 | ALACRITECH GIGABIT ETHERNET DRIVER |
| @@ -2155,6 +2143,7 @@ S: Maintained · 1492 unmodified lines | ||
| 2155 | 2143 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git |
| 2156 | 2144 | F: arch/arm/boot/dts/nxp/imx/ |
| 2157 | 2145 | F: arch/arm/boot/dts/nxp/mxs/ |
| 2146 | +F: arch/arm64/boot/dts/freescale/ | |
| 2158 | 2147 | X: arch/arm64/boot/dts/freescale/fsl-* |
| 2159 | 2148 | X: arch/arm64/boot/dts/freescale/qoriq-* |
| 2160 | 2149 | X: drivers/media/i2c/ |
| @@ -2535,7 +2524,7 @@ F: drivers/*/*/*wpcm* · 374 unmodified lines | ||
| 2535 | 2524 | F: drivers/*/*wpcm* |
| 2536 | 2525 | |
| 2537 | 2526 | ARM/NXP S32G ARCHITECTURE |
| 2538 | −M: Chester Lin <clin@suse.com> | |
| 2527 | +M: Chester Lin <chester62515@gmail.com> | |
| 2539 | 2528 | R: Andreas Färber <afaerber@suse.de> |
| 2540 | 2529 | R: Matthias Brugger <mbrugger@suse.com> |
| 2541 | 2530 | R: NXP S32 Linux Team <s32@nxp.com> |
| @@ -5076,7 +5065,6 @@ CLANG CONTROL FLOW INTEGRITY SUPPORT · 2534 unmodified lines | ||
| 5076 | 5065 | M: Sami Tolvanen <samitolvanen@google.com> |
| 5077 | 5066 | M: Kees Cook <keescook@chromium.org> |
| 5078 | 5067 | R: Nathan Chancellor <nathan@kernel.org> |
| 5079 | −R: Nick Desaulniers <ndesaulniers@google.com> | |
| 5080 | 5068 | L: llvm@lists.linux.dev |
| 5081 | 5069 | S: Supported |
| 5082 | 5070 | B: https://github.com/ClangBuiltLinux/linux/issues |
| @@ -5091,8 +5079,9 @@ F: .clang-format · 8 unmodified lines | ||
| 5091 | 5079 | |
| 5092 | 5080 | CLANG/LLVM BUILD SUPPORT |
| 5093 | 5081 | M: Nathan Chancellor <nathan@kernel.org> |
| 5094 | −M: Nick Desaulniers <ndesaulniers@google.com> | |
| 5095 | −R: Tom Rix <trix@redhat.com> | |
| 5082 | +R: Nick Desaulniers <ndesaulniers@google.com> | |
| 5083 | +R: Bill Wendling <morbo@google.com> | |
| 5084 | +R: Justin Stitt <justinstitt@google.com> | |
| 5096 | 5085 | L: llvm@lists.linux.dev |
| 5097 | 5086 | S: Supported |
| 5098 | 5087 | W: https://clangbuiltlinux.github.io/ |
| @@ -5242,7 +5231,6 @@ F: drivers/platform/x86/compal-laptop.c · 143 unmodified lines | ||
| 5242 | 5231 | |
| 5243 | 5232 | COMPILER ATTRIBUTES |
| 5244 | 5233 | M: Miguel Ojeda <ojeda@kernel.org> |
| 5245 | −R: Nick Desaulniers <ndesaulniers@google.com> | |
| 5246 | 5234 | S: Maintained |
| 5247 | 5235 | F: include/linux/compiler_attributes.h |
| 5248 | 5236 | |
| @@ -5605,13 +5593,10 @@ F: Documentation/driver-api/media/drivers/cx88* · 356 unmodified lines | ||
| 5605 | 5593 | F: drivers/media/pci/cx88/ |
| 5606 | 5594 | |
| 5607 | 5595 | CXD2820R MEDIA DRIVER |
| 5608 | −M: Antti Palosaari <crope@iki.fi> | |
| 5609 | 5596 | L: linux-media@vger.kernel.org |
| 5610 | −S: Maintained | |
| 5597 | +S: Orphan | |
| 5611 | 5598 | W: https://linuxtv.org |
| 5612 | −W: http://palosaari.fi/linux/ | |
| 5613 | 5599 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 5614 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 5615 | 5600 | F: drivers/media/dvb-frontends/cxd2820r* |
| 5616 | 5601 | |
| 5617 | 5602 | CXGB3 ETHERNET DRIVER (CXGB3) |
| @@ -5724,13 +5709,10 @@ F: Documentation/devicetree/bindings/input/cypress-sf.yaml · 106 unmodified lines | ||
| 5724 | 5709 | F: drivers/input/keyboard/cypress-sf.c |
| 5725 | 5710 | |
| 5726 | 5711 | CYPRESS_FIRMWARE MEDIA DRIVER |
| 5727 | −M: Antti Palosaari <crope@iki.fi> | |
| 5728 | 5712 | L: linux-media@vger.kernel.org |
| 5729 | −S: Maintained | |
| 5713 | +S: Orphan | |
| 5730 | 5714 | W: https://linuxtv.org |
| 5731 | −W: http://palosaari.fi/linux/ | |
| 5732 | 5715 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 5733 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 5734 | 5716 | F: drivers/media/common/cypress_firmware* |
| 5735 | 5717 | |
| 5736 | 5718 | CYTTSP TOUCHSCREEN DRIVER |
| @@ -7320,53 +7302,38 @@ T: git git://linuxtv.org/media_tree.git · 1583 unmodified lines | ||
| 7320 | 7302 | F: drivers/media/pci/dt3155/ |
| 7321 | 7303 | |
| 7322 | 7304 | DVB_USB_AF9015 MEDIA DRIVER |
| 7323 | −M: Antti Palosaari <crope@iki.fi> | |
| 7324 | 7305 | L: linux-media@vger.kernel.org |
| 7325 | −S: Maintained | |
| 7306 | +S: Orphan | |
| 7326 | 7307 | W: https://linuxtv.org |
| 7327 | −W: http://palosaari.fi/linux/ | |
| 7328 | 7308 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7329 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7330 | 7309 | F: drivers/media/usb/dvb-usb-v2/af9015* |
| 7331 | 7310 | |
| 7332 | 7311 | DVB_USB_AF9035 MEDIA DRIVER |
| 7333 | −M: Antti Palosaari <crope@iki.fi> | |
| 7334 | 7312 | L: linux-media@vger.kernel.org |
| 7335 | −S: Maintained | |
| 7313 | +S: Orphan | |
| 7336 | 7314 | W: https://linuxtv.org |
| 7337 | −W: http://palosaari.fi/linux/ | |
| 7338 | 7315 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7339 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7340 | 7316 | F: drivers/media/usb/dvb-usb-v2/af9035* |
| 7341 | 7317 | |
| 7342 | 7318 | DVB_USB_ANYSEE MEDIA DRIVER |
| 7343 | −M: Antti Palosaari <crope@iki.fi> | |
| 7344 | 7319 | L: linux-media@vger.kernel.org |
| 7345 | −S: Maintained | |
| 7320 | +S: Orphan | |
| 7346 | 7321 | W: https://linuxtv.org |
| 7347 | −W: http://palosaari.fi/linux/ | |
| 7348 | 7322 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7349 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7350 | 7323 | F: drivers/media/usb/dvb-usb-v2/anysee* |
| 7351 | 7324 | |
| 7352 | 7325 | DVB_USB_AU6610 MEDIA DRIVER |
| 7353 | −M: Antti Palosaari <crope@iki.fi> | |
| 7354 | 7326 | L: linux-media@vger.kernel.org |
| 7355 | −S: Maintained | |
| 7327 | +S: Orphan | |
| 7356 | 7328 | W: https://linuxtv.org |
| 7357 | −W: http://palosaari.fi/linux/ | |
| 7358 | 7329 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7359 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7360 | 7330 | F: drivers/media/usb/dvb-usb-v2/au6610* |
| 7361 | 7331 | |
| 7362 | 7332 | DVB_USB_CE6230 MEDIA DRIVER |
| 7363 | −M: Antti Palosaari <crope@iki.fi> | |
| 7364 | 7333 | L: linux-media@vger.kernel.org |
| 7365 | −S: Maintained | |
| 7334 | +S: Orphan | |
| 7366 | 7335 | W: https://linuxtv.org |
| 7367 | −W: http://palosaari.fi/linux/ | |
| 7368 | 7336 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7369 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7370 | 7337 | F: drivers/media/usb/dvb-usb-v2/ce6230* |
| 7371 | 7338 | |
| 7372 | 7339 | DVB_USB_CXUSB MEDIA DRIVER |
| @@ -7380,22 +7347,17 @@ T: git git://linuxtv.org/media_tree.git · 7 unmodified lines | ||
| 7380 | 7347 | F: drivers/media/usb/dvb-usb/cxusb* |
| 7381 | 7348 | |
| 7382 | 7349 | DVB_USB_EC168 MEDIA DRIVER |
| 7383 | −M: Antti Palosaari <crope@iki.fi> | |
| 7384 | 7350 | L: linux-media@vger.kernel.org |
| 7385 | −S: Maintained | |
| 7351 | +S: Orphan | |
| 7386 | 7352 | W: https://linuxtv.org |
| 7387 | −W: http://palosaari.fi/linux/ | |
| 7388 | 7353 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7389 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7390 | 7354 | F: drivers/media/usb/dvb-usb-v2/ec168* |
| 7391 | 7355 | |
| 7392 | 7356 | DVB_USB_GL861 MEDIA DRIVER |
| 7393 | −M: Antti Palosaari <crope@iki.fi> | |
| 7394 | 7357 | L: linux-media@vger.kernel.org |
| 7395 | −S: Maintained | |
| 7358 | +S: Orphan | |
| 7396 | 7359 | W: https://linuxtv.org |
| 7397 | 7360 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7398 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7399 | 7361 | F: drivers/media/usb/dvb-usb-v2/gl861* |
| 7400 | 7362 | |
| 7401 | 7363 | DVB_USB_MXL111SF MEDIA DRIVER |
| @@ -7409,23 +7371,18 @@ T: git git://linuxtv.org/mkrufky/mxl111sf.git · 7 unmodified lines | ||
| 7409 | 7371 | F: drivers/media/usb/dvb-usb-v2/mxl111sf* |
| 7410 | 7372 | |
| 7411 | 7373 | DVB_USB_RTL28XXU MEDIA DRIVER |
| 7412 | −M: Antti Palosaari <crope@iki.fi> | |
| 7413 | 7374 | L: linux-media@vger.kernel.org |
| 7414 | −S: Maintained | |
| 7375 | +S: Orphan | |
| 7415 | 7376 | W: https://linuxtv.org |
| 7416 | −W: http://palosaari.fi/linux/ | |
| 7417 | 7377 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7418 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7419 | 7378 | F: drivers/media/usb/dvb-usb-v2/rtl28xxu* |
| 7420 | 7379 | |
| 7421 | 7380 | DVB_USB_V2 MEDIA DRIVER |
| 7422 | −M: Antti Palosaari <crope@iki.fi> | |
| 7423 | 7381 | L: linux-media@vger.kernel.org |
| 7424 | −S: Maintained | |
| 7382 | +S: Orphan | |
| 7425 | 7383 | W: https://linuxtv.org |
| 7426 | 7384 | W: http://palosaari.fi/linux/ |
| 7427 | 7385 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7428 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7429 | 7386 | F: drivers/media/usb/dvb-usb-v2/dvb_usb* |
| 7430 | 7387 | F: drivers/media/usb/dvb-usb-v2/usb_urb.c |
| 7431 | 7388 | |
| @@ -7467,13 +7424,10 @@ F: Documentation/devicetree/bindings/input/e3x0-button.txt · 35 unmodified lines | ||
| 7467 | 7424 | F: drivers/input/misc/e3x0-button.c |
| 7468 | 7425 | |
| 7469 | 7426 | E4000 MEDIA DRIVER |
| 7470 | −M: Antti Palosaari <crope@iki.fi> | |
| 7471 | 7427 | L: linux-media@vger.kernel.org |
| 7472 | −S: Maintained | |
| 7428 | +S: Orphan | |
| 7473 | 7429 | W: https://linuxtv.org |
| 7474 | −W: http://palosaari.fi/linux/ | |
| 7475 | 7430 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7476 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7477 | 7431 | F: drivers/media/tuners/e4000* |
| 7478 | 7432 | |
| 7479 | 7433 | EARTH_PT1 MEDIA DRIVER |
| @@ -7489,13 +7443,10 @@ S: Odd Fixes · 9 unmodified lines | ||
| 7489 | 7443 | F: drivers/media/pci/pt3/ |
| 7490 | 7444 | |
| 7491 | 7445 | EC100 MEDIA DRIVER |
| 7492 | −M: Antti Palosaari <crope@iki.fi> | |
| 7493 | 7446 | L: linux-media@vger.kernel.org |
| 7494 | −S: Maintained | |
| 7447 | +S: Orphan | |
| 7495 | 7448 | W: https://linuxtv.org |
| 7496 | −W: http://palosaari.fi/linux/ | |
| 7497 | 7449 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 7498 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 7499 | 7450 | F: drivers/media/dvb-frontends/ec100* |
| 7500 | 7451 | |
| 7501 | 7452 | ECRYPT FILE SYSTEM |
| @@ -7855,6 +7806,7 @@ R: Yue Hu <huyue2@coolpad.com> · 353 unmodified lines | ||
| 7855 | 7806 | R: Jeffle Xu <jefflexu@linux.alibaba.com> |
| 7856 | 7807 | L: linux-erofs@lists.ozlabs.org |
| 7857 | 7808 | S: Maintained |
| 7809 | +W: https://erofs.docs.kernel.org | |
| 7858 | 7810 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git |
| 7859 | 7811 | F: Documentation/ABI/testing/sysfs-fs-erofs |
| 7860 | 7812 | F: Documentation/filesystems/erofs.rst |
| @@ -8112,13 +8064,10 @@ F: drivers/media/tuners/fc0011.c · 251 unmodified lines | ||
| 8112 | 8064 | F: drivers/media/tuners/fc0011.h |
| 8113 | 8065 | |
| 8114 | 8066 | FC2580 MEDIA DRIVER |
| 8115 | −M: Antti Palosaari <crope@iki.fi> | |
| 8116 | 8067 | L: linux-media@vger.kernel.org |
| 8117 | −S: Maintained | |
| 8068 | +S: Orphan | |
| 8118 | 8069 | W: https://linuxtv.org |
| 8119 | −W: http://palosaari.fi/linux/ | |
| 8120 | 8070 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 8121 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 8122 | 8071 | F: drivers/media/tuners/fc2580* |
| 8123 | 8072 | |
| 8124 | 8073 | FCOE SUBSYSTEM (libfc, libfcoe, fcoe) |
| @@ -8950,7 +8899,6 @@ S: Maintained · 825 unmodified lines | ||
| 8950 | 8899 | F: scripts/get_maintainer.pl |
| 8951 | 8900 | |
| 8952 | 8901 | GFS2 FILE SYSTEM |
| 8953 | −M: Bob Peterson <rpeterso@redhat.com> | |
| 8954 | 8902 | M: Andreas Gruenbacher <agruenba@redhat.com> |
| 8955 | 8903 | L: gfs2@lists.linux.dev |
| 8956 | 8904 | S: Supported |
| @@ -9249,13 +9197,10 @@ F: include/trace/events/habanalabs.h · 292 unmodified lines | ||
| 9249 | 9197 | F: include/uapi/drm/habanalabs_accel.h |
| 9250 | 9198 | |
| 9251 | 9199 | HACKRF MEDIA DRIVER |
| 9252 | −M: Antti Palosaari <crope@iki.fi> | |
| 9253 | 9200 | L: linux-media@vger.kernel.org |
| 9254 | −S: Maintained | |
| 9201 | +S: Orphan | |
| 9255 | 9202 | W: https://linuxtv.org |
| 9256 | −W: http://palosaari.fi/linux/ | |
| 9257 | 9203 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 9258 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 9259 | 9204 | F: drivers/media/usb/hackrf/ |
| 9260 | 9205 | |
| 9261 | 9206 | HANDSHAKE UPCALL FOR TRANSPORT LAYER SECURITY |
| @@ -9628,6 +9573,7 @@ F: drivers/crypto/hisilicon/sgl.c · 366 unmodified lines | ||
| 9628 | 9573 | F: include/linux/hisi_acc_qm.h |
| 9629 | 9574 | |
| 9630 | 9575 | HISILICON ROCE DRIVER |
| 9576 | +M: Chengchang Tang <tangchengchang@huawei.com> | |
| 9631 | 9577 | M: Junxian Huang <huangjunxian6@hisilicon.com> |
| 9632 | 9578 | L: linux-rdma@vger.kernel.org |
| 9633 | 9579 | S: Maintained |
| @@ -11025,7 +10971,6 @@ F: drivers/net/wireless/intel/iwlwifi/ · 1391 unmodified lines | ||
| 11025 | 10971 | |
| 11026 | 10972 | INTEL WMI SLIM BOOTLOADER (SBL) FIRMWARE UPDATE DRIVER |
| 11027 | 10973 | M: Jithu Joseph <jithu.joseph@intel.com> |
| 11028 | −R: Maurice Ma <maurice.ma@intel.com> | |
| 11029 | 10974 | S: Maintained |
| 11030 | 10975 | W: https://slimbootloader.github.io/security/firmware-update.html |
| 11031 | 10976 | F: drivers/platform/x86/intel/wmi/sbl-fw-update.c |
| @@ -11329,13 +11274,10 @@ F: Documentation/hwmon/it87.rst · 297 unmodified lines | ||
| 11329 | 11274 | F: drivers/hwmon/it87.c |
| 11330 | 11275 | |
| 11331 | 11276 | IT913X MEDIA DRIVER |
| 11332 | −M: Antti Palosaari <crope@iki.fi> | |
| 11333 | 11277 | L: linux-media@vger.kernel.org |
| 11334 | −S: Maintained | |
| 11278 | +S: Orphan | |
| 11335 | 11279 | W: https://linuxtv.org |
| 11336 | −W: http://palosaari.fi/linux/ | |
| 11337 | 11280 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 11338 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 11339 | 11281 | F: drivers/media/tuners/it913x* |
| 11340 | 11282 | |
| 11341 | 11283 | ITE IT66121 HDMI BRIDGE DRIVER |
| @@ -11517,7 +11459,6 @@ F: fs/autofs/ · 175 unmodified lines | ||
| 11517 | 11459 | KERNEL BUILD + files below scripts/ (unless maintained elsewhere) |
| 11518 | 11460 | M: Masahiro Yamada <masahiroy@kernel.org> |
| 11519 | 11461 | R: Nathan Chancellor <nathan@kernel.org> |
| 11520 | −R: Nick Desaulniers <ndesaulniers@google.com> | |
| 11521 | 11462 | R: Nicolas Schier <nicolas@fjasle.eu> |
| 11522 | 11463 | L: linux-kbuild@vger.kernel.org |
| 11523 | 11464 | S: Maintained |
| @@ -12209,6 +12150,13 @@ F: include/linux/nd.h · 685 unmodified lines | ||
| 12209 | 12150 | F: include/uapi/linux/ndctl.h |
| 12210 | 12151 | F: tools/testing/nvdimm/ |
| 12211 | 12152 | |
| 12153 | +LIBRARY CODE | |
| 12154 | +M: Andrew Morton <akpm@linux-foundation.org> | |
| 12155 | +L: linux-kernel@vger.kernel.org | |
| 12156 | +S: Supported | |
| 12157 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-nonmm-unstable | |
| 12158 | +F: lib/* | |
| 12159 | + | |
| 12212 | 12160 | LICENSES and SPDX stuff |
| 12213 | 12161 | M: Thomas Gleixner <tglx@linutronix.de> |
| 12214 | 12162 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| @@ -12688,13 +12636,10 @@ W: http://www.tazenda.demon.co.uk/phil/linux-hp · 473 unmodified lines | ||
| 12688 | 12636 | F: arch/m68k/hp300/ |
| 12689 | 12637 | |
| 12690 | 12638 | M88DS3103 MEDIA DRIVER |
| 12691 | −M: Antti Palosaari <crope@iki.fi> | |
| 12692 | 12639 | L: linux-media@vger.kernel.org |
| 12693 | −S: Maintained | |
| 12640 | +S: Orphan | |
| 12694 | 12641 | W: https://linuxtv.org |
| 12695 | −W: http://palosaari.fi/linux/ | |
| 12696 | 12642 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 12697 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 12698 | 12643 | F: drivers/media/dvb-frontends/m88ds3103* |
| 12699 | 12644 | |
| 12700 | 12645 | M88RS2000 MEDIA DRIVER |
| @@ -13779,7 +13724,6 @@ F: drivers/net/ethernet/mellanox/mlxfw/ · 1078 unmodified lines | ||
| 13779 | 13724 | MELLANOX HARDWARE PLATFORM SUPPORT |
| 13780 | 13725 | M: Hans de Goede <hdegoede@redhat.com> |
| 13781 | 13726 | M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> |
| 13782 | −M: Mark Gross <markgross@kernel.org> | |
| 13783 | 13727 | M: Vadim Pasternak <vadimp@nvidia.com> |
| 13784 | 13728 | L: platform-driver-x86@vger.kernel.org |
| 13785 | 13729 | S: Supported |
| @@ -14388,7 +14332,6 @@ F: drivers/platform/surface/surface_gpe.c · 602 unmodified lines | ||
| 14388 | 14332 | MICROSOFT SURFACE HARDWARE PLATFORM SUPPORT |
| 14389 | 14333 | M: Hans de Goede <hdegoede@redhat.com> |
| 14390 | 14334 | M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> |
| 14391 | −M: Mark Gross <markgross@kernel.org> | |
| 14392 | 14335 | M: Maximilian Luz <luzmaximilian@gmail.com> |
| 14393 | 14336 | L: platform-driver-x86@vger.kernel.org |
| 14394 | 14337 | S: Maintained |
| @@ -14590,20 +14533,16 @@ F: include/asm-generic/tlb.h · 195 unmodified lines | ||
| 14590 | 14533 | F: mm/mmu_gather.c |
| 14591 | 14534 | |
| 14592 | 14535 | MN88472 MEDIA DRIVER |
| 14593 | −M: Antti Palosaari <crope@iki.fi> | |
| 14594 | 14536 | L: linux-media@vger.kernel.org |
| 14595 | −S: Maintained | |
| 14537 | +S: Orphan | |
| 14596 | 14538 | W: https://linuxtv.org |
| 14597 | −W: http://palosaari.fi/linux/ | |
| 14598 | 14539 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 14599 | 14540 | F: drivers/media/dvb-frontends/mn88472* |
| 14600 | 14541 | |
| 14601 | 14542 | MN88473 MEDIA DRIVER |
| 14602 | −M: Antti Palosaari <crope@iki.fi> | |
| 14603 | 14543 | L: linux-media@vger.kernel.org |
| 14604 | −S: Maintained | |
| 14544 | +S: Orphan | |
| 14605 | 14545 | W: https://linuxtv.org |
| 14606 | −W: http://palosaari.fi/linux/ | |
| 14607 | 14546 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 14608 | 14547 | F: drivers/media/dvb-frontends/mn88473* |
| 14609 | 14548 | |
| @@ -14691,23 +14630,17 @@ S: Orphan · 81 unmodified lines | ||
| 14691 | 14630 | F: drivers/platform/x86/msi-wmi.c |
| 14692 | 14631 | |
| 14693 | 14632 | MSI001 MEDIA DRIVER |
| 14694 | −M: Antti Palosaari <crope@iki.fi> | |
| 14695 | 14633 | L: linux-media@vger.kernel.org |
| 14696 | −S: Maintained | |
| 14634 | +S: Orphan | |
| 14697 | 14635 | W: https://linuxtv.org |
| 14698 | −W: http://palosaari.fi/linux/ | |
| 14699 | 14636 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 14700 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 14701 | 14637 | F: drivers/media/tuners/msi001* |
| 14702 | 14638 | |
| 14703 | 14639 | MSI2500 MEDIA DRIVER |
| 14704 | −M: Antti Palosaari <crope@iki.fi> | |
| 14705 | 14640 | L: linux-media@vger.kernel.org |
| 14706 | −S: Maintained | |
| 14641 | +S: Orphan | |
| 14707 | 14642 | W: https://linuxtv.org |
| 14708 | −W: http://palosaari.fi/linux/ | |
| 14709 | 14643 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 14710 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 14711 | 14644 | F: drivers/media/usb/msi2500/ |
| 14712 | 14645 | |
| 14713 | 14646 | MSTAR INTERRUPT CONTROLLER DRIVER |
| @@ -14995,6 +14928,7 @@ M: Jakub Kicinski <kuba@kernel.org> · 281 unmodified lines | ||
| 14995 | 14928 | M: Paolo Abeni <pabeni@redhat.com> |
| 14996 | 14929 | L: netdev@vger.kernel.org |
| 14997 | 14930 | S: Maintained |
| 14931 | +P: Documentation/process/maintainer-netdev.rst | |
| 14998 | 14932 | Q: https://patchwork.kernel.org/project/netdevbpf/list/ |
| 14999 | 14933 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| 15000 | 14934 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git |
| @@ -15046,6 +14980,7 @@ M: Jakub Kicinski <kuba@kernel.org> · 45 unmodified lines | ||
| 15046 | 14980 | M: Paolo Abeni <pabeni@redhat.com> |
| 15047 | 14981 | L: netdev@vger.kernel.org |
| 15048 | 14982 | S: Maintained |
| 14983 | +P: Documentation/process/maintainer-netdev.rst | |
| 15049 | 14984 | Q: https://patchwork.kernel.org/project/netdevbpf/list/ |
| 15050 | 14985 | B: mailto:netdev@vger.kernel.org |
| 15051 | 14986 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git |
| @@ -15056,6 +14991,7 @@ F: Documentation/networking/ · 4 unmodified lines | ||
| 15056 | 14991 | F: Documentation/process/maintainer-netdev.rst |
| 15057 | 14992 | F: Documentation/userspace-api/netlink/ |
| 15058 | 14993 | F: include/linux/in.h |
| 14994 | +F: include/linux/indirect_call_wrapper.h | |
| 15059 | 14995 | F: include/linux/net.h |
| 15060 | 14996 | F: include/linux/netdevice.h |
| 15061 | 14997 | F: include/net/ |
| @@ -15068,6 +15004,7 @@ F: lib/random32.c · 6 unmodified lines | ||
| 15068 | 15004 | F: net/ |
| 15069 | 15005 | F: tools/net/ |
| 15070 | 15006 | F: tools/testing/selftests/net/ |
| 15007 | +X: net/9p/ | |
| 15071 | 15008 | X: net/bluetooth/ |
| 15072 | 15009 | |
| 15073 | 15010 | NETWORKING [IPSEC] |
| @@ -17775,13 +17712,10 @@ F: drivers/bus/fsl-mc/ · 2701 unmodified lines | ||
| 17775 | 17712 | F: include/uapi/linux/fsl_mc.h |
| 17776 | 17713 | |
| 17777 | 17714 | QT1010 MEDIA DRIVER |
| 17778 | −M: Antti Palosaari <crope@iki.fi> | |
| 17779 | 17715 | L: linux-media@vger.kernel.org |
| 17780 | −S: Maintained | |
| 17716 | +S: Orphan | |
| 17781 | 17717 | W: https://linuxtv.org |
| 17782 | −W: http://palosaari.fi/linux/ | |
| 17783 | 17718 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 17784 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 17785 | 17719 | F: drivers/media/tuners/qt1010* |
| 17786 | 17720 | |
| 17787 | 17721 | QUALCOMM ATH12K WIRELESS DRIVER |
| @@ -17948,6 +17882,8 @@ L: iommu@lists.linux.dev · 160 unmodified lines | ||
| 17948 | 17882 | L: linux-arm-msm@vger.kernel.org |
| 17949 | 17883 | S: Maintained |
| 17950 | 17884 | F: drivers/iommu/arm/arm-smmu/qcom_iommu.c |
| 17885 | +F: drivers/iommu/arm/arm-smmu/arm-smmu-qcom* | |
| 17886 | +F: drivers/iommu/msm_iommu* | |
| 17951 | 17887 | |
| 17952 | 17888 | QUALCOMM IPC ROUTER (QRTR) DRIVER |
| 17953 | 17889 | M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| @@ -18834,33 +18770,24 @@ S: Maintained · 880 unmodified lines | ||
| 18834 | 18770 | F: drivers/tty/rpmsg_tty.c |
| 18835 | 18771 | |
| 18836 | 18772 | RTL2830 MEDIA DRIVER |
| 18837 | −M: Antti Palosaari <crope@iki.fi> | |
| 18838 | 18773 | L: linux-media@vger.kernel.org |
| 18839 | −S: Maintained | |
| 18774 | +S: Orphan | |
| 18840 | 18775 | W: https://linuxtv.org |
| 18841 | −W: http://palosaari.fi/linux/ | |
| 18842 | 18776 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 18843 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 18844 | 18777 | F: drivers/media/dvb-frontends/rtl2830* |
| 18845 | 18778 | |
| 18846 | 18779 | RTL2832 MEDIA DRIVER |
| 18847 | −M: Antti Palosaari <crope@iki.fi> | |
| 18848 | 18780 | L: linux-media@vger.kernel.org |
| 18849 | −S: Maintained | |
| 18781 | +S: Orphan | |
| 18850 | 18782 | W: https://linuxtv.org |
| 18851 | −W: http://palosaari.fi/linux/ | |
| 18852 | 18783 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 18853 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 18854 | 18784 | F: drivers/media/dvb-frontends/rtl2832* |
| 18855 | 18785 | |
| 18856 | 18786 | RTL2832_SDR MEDIA DRIVER |
| 18857 | −M: Antti Palosaari <crope@iki.fi> | |
| 18858 | 18787 | L: linux-media@vger.kernel.org |
| 18859 | −S: Maintained | |
| 18788 | +S: Orphan | |
| 18860 | 18789 | W: https://linuxtv.org |
| 18861 | −W: http://palosaari.fi/linux/ | |
| 18862 | 18790 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 18863 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 18864 | 18791 | F: drivers/media/dvb-frontends/rtl2832_sdr* |
| 18865 | 18792 | |
| 18866 | 18793 | RTL8180 WIRELESS DRIVER |
| @@ -19670,13 +19597,10 @@ F: drivers/media/platform/renesas/sh_vou.c · 803 unmodified lines | ||
| 19670 | 19597 | F: include/media/drv-intf/sh_vou.h |
| 19671 | 19598 | |
| 19672 | 19599 | SI2157 MEDIA DRIVER |
| 19673 | −M: Antti Palosaari <crope@iki.fi> | |
| 19674 | 19600 | L: linux-media@vger.kernel.org |
| 19675 | −S: Maintained | |
| 19601 | +S: Orphan | |
| 19676 | 19602 | W: https://linuxtv.org |
| 19677 | −W: http://palosaari.fi/linux/ | |
| 19678 | 19603 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 19679 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 19680 | 19604 | F: drivers/media/tuners/si2157* |
| 19681 | 19605 | |
| 19682 | 19606 | SI2165 MEDIA DRIVER |
| @@ -19688,13 +19612,10 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ · 5 unmodified lines | ||
| 19688 | 19612 | F: drivers/media/dvb-frontends/si2165* |
| 19689 | 19613 | |
| 19690 | 19614 | SI2168 MEDIA DRIVER |
| 19691 | −M: Antti Palosaari <crope@iki.fi> | |
| 19692 | 19615 | L: linux-media@vger.kernel.org |
| 19693 | −S: Maintained | |
| 19616 | +S: Orphan | |
| 19694 | 19617 | W: https://linuxtv.org |
| 19695 | −W: http://palosaari.fi/linux/ | |
| 19696 | 19618 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 19697 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 19698 | 19619 | F: drivers/media/dvb-frontends/si2168* |
| 19699 | 19620 | |
| 19700 | 19621 | SI470X FM RADIO RECEIVER I2C DRIVER |
| @@ -21196,33 +21117,24 @@ W: http://tcp-lp-mod.sourceforge.net/ · 1495 unmodified lines | ||
| 21196 | 21117 | F: net/ipv4/tcp_lp.c |
| 21197 | 21118 | |
| 21198 | 21119 | TDA10071 MEDIA DRIVER |
| 21199 | −M: Antti Palosaari <crope@iki.fi> | |
| 21200 | 21120 | L: linux-media@vger.kernel.org |
| 21201 | −S: Maintained | |
| 21121 | +S: Orphan | |
| 21202 | 21122 | W: https://linuxtv.org |
| 21203 | −W: http://palosaari.fi/linux/ | |
| 21204 | 21123 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 21205 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 21206 | 21124 | F: drivers/media/dvb-frontends/tda10071* |
| 21207 | 21125 | |
| 21208 | 21126 | TDA18212 MEDIA DRIVER |
| 21209 | −M: Antti Palosaari <crope@iki.fi> | |
| 21210 | 21127 | L: linux-media@vger.kernel.org |
| 21211 | −S: Maintained | |
| 21128 | +S: Orphan | |
| 21212 | 21129 | W: https://linuxtv.org |
| 21213 | −W: http://palosaari.fi/linux/ | |
| 21214 | 21130 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 21215 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 21216 | 21131 | F: drivers/media/tuners/tda18212* |
| 21217 | 21132 | |
| 21218 | 21133 | TDA18218 MEDIA DRIVER |
| 21219 | −M: Antti Palosaari <crope@iki.fi> | |
| 21220 | 21134 | L: linux-media@vger.kernel.org |
| 21221 | −S: Maintained | |
| 21135 | +S: Orphan | |
| 21222 | 21136 | W: https://linuxtv.org |
| 21223 | −W: http://palosaari.fi/linux/ | |
| 21224 | 21137 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 21225 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 21226 | 21138 | F: drivers/media/tuners/tda18218* |
| 21227 | 21139 | |
| 21228 | 21140 | TDA18250 MEDIA DRIVER |
| @@ -21769,7 +21681,9 @@ F: Documentation/devicetree/bindings/counter/ti-eqep.yaml · 540 unmodified lines | ||
| 21769 | 21681 | F: drivers/counter/ti-eqep.c |
| 21770 | 21682 | |
| 21771 | 21683 | TI ETHERNET SWITCH DRIVER (CPSW) |
| 21772 | −R: Grygorii Strashko <grygorii.strashko@ti.com> | |
| 21684 | +R: Siddharth Vadapalli <s-vadapalli@ti.com> | |
| 21685 | +R: Ravi Gunasekaran <r-gunasekaran@ti.com> | |
| 21686 | +R: Roger Quadros <rogerq@kernel.org> | |
| 21773 | 21687 | L: linux-omap@vger.kernel.org |
| 21774 | 21688 | L: netdev@vger.kernel.org |
| 21775 | 21689 | S: Maintained |
| @@ -21793,6 +21707,15 @@ F: Documentation/devicetree/bindings/media/i2c/ti,ds90* · 17 unmodified lines | ||
| 21793 | 21707 | F: drivers/media/i2c/ds90* |
| 21794 | 21708 | F: include/media/i2c/ds90* |
| 21795 | 21709 | |
| 21710 | +TI ICSSG ETHERNET DRIVER (ICSSG) | |
| 21711 | +R: MD Danish Anwar <danishanwar@ti.com> | |
| 21712 | +R: Roger Quadros <rogerq@kernel.org> | |
| 21713 | +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 21714 | +L: netdev@vger.kernel.org | |
| 21715 | +S: Maintained | |
| 21716 | +F: Documentation/devicetree/bindings/net/ti,icss*.yaml | |
| 21717 | +F: drivers/net/ethernet/ti/icssg/* | |
| 21718 | + | |
| 21796 | 21719 | TI J721E CSI2RX DRIVER |
| 21797 | 21720 | M: Jai Luthra <j-luthra@ti.com> |
| 21798 | 21721 | L: linux-media@vger.kernel.org |
| @@ -22068,6 +21991,7 @@ F: drivers/watchdog/tqmx86_wdt.c · 269 unmodified lines | ||
| 22068 | 21991 | TRACING |
| 22069 | 21992 | M: Steven Rostedt <rostedt@goodmis.org> |
| 22070 | 21993 | M: Masami Hiramatsu <mhiramat@kernel.org> |
| 21994 | +R: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
| 22071 | 21995 | L: linux-kernel@vger.kernel.org |
| 22072 | 21996 | L: linux-trace-kernel@vger.kernel.org |
| 22073 | 21997 | S: Maintained |
| @@ -22146,13 +22070,10 @@ F: include/uapi/linux/serial_core.h · 72 unmodified lines | ||
| 22146 | 22070 | F: include/uapi/linux/tty.h |
| 22147 | 22071 | |
| 22148 | 22072 | TUA9001 MEDIA DRIVER |
| 22149 | −M: Antti Palosaari <crope@iki.fi> | |
| 22150 | 22073 | L: linux-media@vger.kernel.org |
| 22151 | −S: Maintained | |
| 22074 | +S: Orphan | |
| 22152 | 22075 | W: https://linuxtv.org |
| 22153 | −W: http://palosaari.fi/linux/ | |
| 22154 | 22076 | Q: http://patchwork.linuxtv.org/project/linux-media/list/ |
| 22155 | −T: git git://linuxtv.org/anttip/media_tree.git | |
| 22156 | 22077 | F: drivers/media/tuners/tua9001* |
| 22157 | 22078 | |
| 22158 | 22079 | TULIP NETWORK DRIVERS |
| @@ -23654,7 +23575,6 @@ F: drivers/platform/x86/x86-android-tablets/ · 1495 unmodified lines | ||
| 23654 | 23575 | X86 PLATFORM DRIVERS |
| 23655 | 23576 | M: Hans de Goede <hdegoede@redhat.com> |
| 23656 | 23577 | M: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> |
| 23657 | −M: Mark Gross <markgross@kernel.org> | |
| 23658 | 23578 | L: platform-driver-x86@vger.kernel.org |
| 23659 | 23579 | S: Maintained |
| 23660 | 23580 | Q: https://patchwork.kernel.org/project/platform-driver-x86/list/ |
| @@ -23692,6 +23612,20 @@ F: arch/x86/kernel/dumpstack.c · 31 unmodified lines | ||
| 23692 | 23612 | F: arch/x86/kernel/stacktrace.c |
| 23693 | 23613 | F: arch/x86/kernel/unwind_*.c |
| 23694 | 23614 | |
| 23615 | +X86 TRUST DOMAIN EXTENSIONS (TDX) | |
| 23616 | +M: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | |
| 23617 | +R: Dave Hansen <dave.hansen@linux.intel.com> | |
| 23618 | +L: x86@kernel.org | |
| 23619 | +L: linux-coco@lists.linux.dev | |
| 23620 | +S: Supported | |
| 23621 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86/tdx | |
| 23622 | +F: arch/x86/boot/compressed/tdx* | |
| 23623 | +F: arch/x86/coco/tdx/ | |
| 23624 | +F: arch/x86/include/asm/shared/tdx.h | |
| 23625 | +F: arch/x86/include/asm/tdx.h | |
| 23626 | +F: arch/x86/virt/vmx/tdx/ | |
| 23627 | +F: drivers/virt/coco/tdx-guest | |
| 23628 | + | |
| 23695 | 23629 | X86 VDSO |
| 23696 | 23630 | M: Andy Lutomirski <luto@kernel.org> |
| 23697 | 23631 | L: linux-kernel@vger.kernel.org |
| @@ -23872,8 +23806,7 @@ T: git git://git.kernel.org/pub/scm/fs/xfs/xfs-linux.git · 174 unmodified lines | ||
| 23872 | 23806 | P: Documentation/filesystems/xfs-maintainer-entry-profile.rst |
| 23873 | 23807 | F: Documentation/ABI/testing/sysfs-fs-xfs |
| 23874 | 23808 | F: Documentation/admin-guide/xfs.rst |
| 23875 | −F: Documentation/filesystems/xfs-delayed-logging-design.rst | |
| 23876 | −F: Documentation/filesystems/xfs-self-describing-metadata.rst | |
| 23809 | +F: Documentation/filesystems/xfs-* | |
| 23877 | 23810 | F: fs/xfs/ |
| 23878 | 23811 | F: include/uapi/linux/dqblk_xfs.h |
| 23879 | 23812 | F: include/uapi/linux/fsmap.h |
| @@ -24085,20 +24018,16 @@ S: Orphan · 205 unmodified lines | ||
| 24085 | 24018 | F: drivers/net/wireless/zydas/zd1211rw/ |
| 24086 | 24019 | |
| 24087 | 24020 | ZD1301 MEDIA DRIVER |
| 24088 | −M: Antti Palosaari <crope@iki.fi> | |
| 24089 | 24021 | L: linux-media@vger.kernel.org |
| 24090 | −S: Maintained | |
| 24022 | +S: Orphan | |
| 24091 | 24023 | W: https://linuxtv.org/ |
| 24092 | −W: http://palosaari.fi/linux/ | |
| 24093 | 24024 | Q: https://patchwork.linuxtv.org/project/linux-media/list/ |
| 24094 | 24025 | F: drivers/media/usb/dvb-usb-v2/zd1301* |
| 24095 | 24026 | |
| 24096 | 24027 | ZD1301_DEMOD MEDIA DRIVER |
| 24097 | −M: Antti Palosaari <crope@iki.fi> | |
| 24098 | 24028 | L: linux-media@vger.kernel.org |
| 24099 | −S: Maintained | |
| 24029 | +S: Orphan | |
| 24100 | 24030 | W: https://linuxtv.org/ |
| 24101 | −W: http://palosaari.fi/linux/ | |
| 24102 | 24031 | Q: https://patchwork.linuxtv.org/project/linux-media/list/ |
| 24103 | 24032 | F: drivers/media/dvb-frontends/zd1301_demod* |
| 24104 | 24033 | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 6 |
| 3 | 3 | PATCHLEVEL = 7 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc1 | |
| 5 | +EXTRAVERSION = -rc5 | |
| 6 | 6 | NAME = Hurr durr I'ma ninja sloth |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -36,9 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; |
| 37 | 37 | }; |
| 38 | 38 | |
| 39 | −&leds { | |
| 40 | − /delete-node/ led_act; | |
| 41 | −}; | |
| 39 | +/delete-node/ &led_act; | |
| 42 | 40 | |
| 43 | 41 | &pm { |
| 44 | 42 | /delete-property/ system-power-controller; |
| @@ -37,9 +37,9 @@ · 36 unmodified lines | ||
| 37 | 37 | |
| 38 | 38 | &clks { |
| 39 | 39 | assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, |
| 40 | − <&clks IMX6QDL_CLK_LDB_DI1_SEL>; | |
| 40 | + <&clks IMX6QDL_CLK_LDB_DI1_SEL>, <&clks IMX6QDL_CLK_ENET_REF_SEL>; | |
| 41 | 41 | assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, |
| 42 | − <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>; | |
| 42 | + <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, <&clk50m_phy>; | |
| 43 | 43 | }; |
| 44 | 44 | |
| 45 | 45 | &hdmi { |
| @@ -121,6 +121,8 @@ · 120 unmodified lines | ||
| 121 | 121 | max-speed = <100>; |
| 122 | 122 | interrupt-parent = <&gpio5>; |
| 123 | 123 | interrupts = <6 IRQ_TYPE_LEVEL_LOW>; |
| 124 | + clocks = <&clks IMX6UL_CLK_ENET_REF>; | |
| 125 | + clock-names = "rmii-ref"; | |
| 124 | 126 | }; |
| 125 | 127 | }; |
| 126 | 128 | }; |
| @@ -454,7 +454,7 @@ · 453 unmodified lines | ||
| 454 | 454 | }; |
| 455 | 455 | |
| 456 | 456 | gpt1: timer@302d0000 { |
| 457 | − compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; | |
| 457 | + compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; | |
| 458 | 458 | reg = <0x302d0000 0x10000>; |
| 459 | 459 | interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; |
| 460 | 460 | clocks = <&clks IMX7D_GPT1_ROOT_CLK>, |
| @@ -463,7 +463,7 @@ · 2 unmodified lines | ||
| 463 | 463 | }; |
| 464 | 464 | |
| 465 | 465 | gpt2: timer@302e0000 { |
| 466 | − compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; | |
| 466 | + compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; | |
| 467 | 467 | reg = <0x302e0000 0x10000>; |
| 468 | 468 | interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; |
| 469 | 469 | clocks = <&clks IMX7D_GPT2_ROOT_CLK>, |
| @@ -473,7 +473,7 @@ · 3 unmodified lines | ||
| 473 | 473 | }; |
| 474 | 474 | |
| 475 | 475 | gpt3: timer@302f0000 { |
| 476 | − compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; | |
| 476 | + compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; | |
| 477 | 477 | reg = <0x302f0000 0x10000>; |
| 478 | 478 | interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; |
| 479 | 479 | clocks = <&clks IMX7D_GPT3_ROOT_CLK>, |
| @@ -483,7 +483,7 @@ · 3 unmodified lines | ||
| 483 | 483 | }; |
| 484 | 484 | |
| 485 | 485 | gpt4: timer@30300000 { |
| 486 | − compatible = "fsl,imx7d-gpt", "fsl,imx6sx-gpt"; | |
| 486 | + compatible = "fsl,imx7d-gpt", "fsl,imx6dl-gpt"; | |
| 487 | 487 | reg = <0x30300000 0x10000>; |
| 488 | 488 | interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>; |
| 489 | 489 | clocks = <&clks IMX7D_GPT4_ROOT_CLK>, |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include "imx28-lwe.dtsi" |
| 9 | 9 | |
| 10 | 10 | / { |
| 11 | + model = "Liebherr XEA board"; | |
| 11 | 12 | compatible = "lwn,imx28-xea", "fsl,imx28"; |
| 12 | 13 | }; |
| 13 | 14 | |
| @@ -848,7 +848,7 @@ · 847 unmodified lines | ||
| 848 | 848 | }; |
| 849 | 849 | |
| 850 | 850 | sdmmc_pwren: sdmmc-pwren { |
| 851 | − rockchip,pins = <1 RK_PB6 1 &pcfg_pull_default>; | |
| 851 | + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_default>; | |
| 852 | 852 | }; |
| 853 | 853 | |
| 854 | 854 | sdmmc_bus4: sdmmc-bus4 { |
| @@ -215,9 +215,9 @@ · 214 unmodified lines | ||
| 215 | 215 | |
| 216 | 216 | power-domain@RK3228_PD_VOP { |
| 217 | 217 | reg = <RK3228_PD_VOP>; |
| 218 | − clocks =<&cru ACLK_VOP>, | |
| 219 | − <&cru DCLK_VOP>, | |
| 220 | − <&cru HCLK_VOP>; | |
| 218 | + clocks = <&cru ACLK_VOP>, | |
| 219 | + <&cru DCLK_VOP>, | |
| 220 | + <&cru HCLK_VOP>; | |
| 221 | 221 | pm_qos = <&qos_vop>; |
| 222 | 222 | #power-domain-cells = <0>; |
| 223 | 223 | }; |
| @@ -2,8 +2,6 @@ · 1 unmodified line | ||
| 2 | 2 | #ifndef _ARM_KEXEC_H |
| 3 | 3 | #define _ARM_KEXEC_H |
| 4 | 4 | |
| 5 | −#ifdef CONFIG_KEXEC | |
| 6 | − | |
| 7 | 5 | /* Maximum physical address we can use pages from */ |
| 8 | 6 | #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) |
| 9 | 7 | /* Maximum address we can reach in physical address mode */ |
| @@ -82,6 +80,4 @@ static inline struct page *boot_pfn_to_page(unsigned long boot_pfn) · 72 unmodified lines | ||
| 82 | 80 | |
| 83 | 81 | #endif /* __ASSEMBLY__ */ |
| 84 | 82 | |
| 85 | −#endif /* CONFIG_KEXEC */ | |
| 86 | − | |
| 87 | 83 | #endif /* _ARM_KEXEC_H */ |
| @@ -59,7 +59,7 @@ obj-$(CONFIG_FUNCTION_TRACER) += entry-ftrace.o · 58 unmodified lines | ||
| 59 | 59 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o patch.o |
| 60 | 60 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o patch.o |
| 61 | 61 | obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o |
| 62 | −obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o | |
| 62 | +obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o | |
| 63 | 63 | # Main staffs in KPROBES are in arch/arm/probes/ . |
| 64 | 64 | obj-$(CONFIG_KPROBES) += patch.o insn.o |
| 65 | 65 | obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o |
| @@ -501,6 +501,10 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b · 500 unmodified lines | ||
| 501 | 501 | |
| 502 | 502 | name = devm_kasprintf(&pdev->dev, |
| 503 | 503 | GFP_KERNEL, "mmdc%d", ret); |
| 504 | + if (!name) { | |
| 505 | + ret = -ENOMEM; | |
| 506 | + goto pmu_release_id; | |
| 507 | + } | |
| 504 | 508 | |
| 505 | 509 | pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; |
| 506 | 510 | pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data; |
| @@ -523,9 +527,10 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b · 16 unmodified lines | ||
| 523 | 527 | |
| 524 | 528 | pmu_register_err: |
| 525 | 529 | pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret); |
| 526 | − ida_simple_remove(&mmdc_ida, pmu_mmdc->id); | |
| 527 | 530 | cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); |
| 528 | 531 | hrtimer_cancel(&pmu_mmdc->hrtimer); |
| 532 | +pmu_release_id: | |
| 533 | + ida_simple_remove(&mmdc_ida, pmu_mmdc->id); | |
| 529 | 534 | pmu_free: |
| 530 | 535 | kfree(pmu_mmdc); |
| 531 | 536 | return ret; |
| @@ -484,7 +484,8 @@ static int __init xen_guest_init(void) · 483 unmodified lines | ||
| 484 | 484 | * for secondary CPUs as they are brought up. |
| 485 | 485 | * For uniformity we use VCPUOP_register_vcpu_info even on cpu0. |
| 486 | 486 | */ |
| 487 | − xen_vcpu_info = alloc_percpu(struct vcpu_info); | |
| 487 | + xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info), | |
| 488 | + 1 << fls(sizeof(struct vcpu_info) - 1)); | |
| 488 | 489 | if (xen_vcpu_info == NULL) |
| 489 | 490 | return -ENOMEM; |
| 490 | 491 | |
| @@ -158,7 +158,7 @@ endif · 157 unmodified lines | ||
| 158 | 158 | |
| 159 | 159 | all: $(notdir $(KBUILD_IMAGE)) |
| 160 | 160 | |
| 161 | − | |
| 161 | +vmlinuz.efi: Image | |
| 162 | 162 | Image vmlinuz.efi: vmlinux |
| 163 | 163 | $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ |
| 164 | 164 | |
| @@ -82,12 +82,9 @@ · 81 unmodified lines | ||
| 82 | 82 | pinctrl-0 = <&pinctrl_wifi_pdn>; |
| 83 | 83 | gpio = <&lsio_gpio1 28 GPIO_ACTIVE_HIGH>; |
| 84 | 84 | enable-active-high; |
| 85 | + regulator-always-on; | |
| 85 | 86 | regulator-name = "wifi_pwrdn_fake_regulator"; |
| 86 | 87 | regulator-settling-time-us = <100>; |
| 87 | − | |
| 88 | − regulator-state-mem { | |
| 89 | − regulator-off-in-suspend; | |
| 90 | − }; | |
| 91 | 88 | }; |
| 92 | 89 | |
| 93 | 90 | reg_pcie_switch: regulator-pcie-switch { |
| @@ -149,7 +149,7 @@ dma_subsys: bus@5a000000 { · 148 unmodified lines | ||
| 149 | 149 | clock-names = "ipg", "per"; |
| 150 | 150 | assigned-clocks = <&clk IMX_SC_R_LCD_0_PWM_0 IMX_SC_PM_CLK_PER>; |
| 151 | 151 | assigned-clock-rates = <24000000>; |
| 152 | − #pwm-cells = <2>; | |
| 152 | + #pwm-cells = <3>; | |
| 153 | 153 | power-domains = <&pd IMX_SC_R_LCD_0_PWM_0>; |
| 154 | 154 | }; |
| 155 | 155 | |
| @@ -29,7 +29,7 @@ lsio_subsys: bus@5d000000 { · 28 unmodified lines | ||
| 29 | 29 | <&pwm0_lpcg 1>; |
| 30 | 30 | assigned-clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>; |
| 31 | 31 | assigned-clock-rates = <24000000>; |
| 32 | − #pwm-cells = <2>; | |
| 32 | + #pwm-cells = <3>; | |
| 33 | 33 | interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; |
| 34 | 34 | status = "disabled"; |
| 35 | 35 | }; |
| @@ -42,7 +42,7 @@ lsio_subsys: bus@5d000000 { · 6 unmodified lines | ||
| 42 | 42 | <&pwm1_lpcg 1>; |
| 43 | 43 | assigned-clocks = <&clk IMX_SC_R_PWM_1 IMX_SC_PM_CLK_PER>; |
| 44 | 44 | assigned-clock-rates = <24000000>; |
| 45 | − #pwm-cells = <2>; | |
| 45 | + #pwm-cells = <3>; | |
| 46 | 46 | interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; |
| 47 | 47 | status = "disabled"; |
| 48 | 48 | }; |
| @@ -55,7 +55,7 @@ lsio_subsys: bus@5d000000 { · 6 unmodified lines | ||
| 55 | 55 | <&pwm2_lpcg 1>; |
| 56 | 56 | assigned-clocks = <&clk IMX_SC_R_PWM_2 IMX_SC_PM_CLK_PER>; |
| 57 | 57 | assigned-clock-rates = <24000000>; |
| 58 | − #pwm-cells = <2>; | |
| 58 | + #pwm-cells = <3>; | |
| 59 | 59 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; |
| 60 | 60 | status = "disabled"; |
| 61 | 61 | }; |
| @@ -68,7 +68,7 @@ lsio_subsys: bus@5d000000 { · 6 unmodified lines | ||
| 68 | 68 | <&pwm3_lpcg 1>; |
| 69 | 69 | assigned-clocks = <&clk IMX_SC_R_PWM_3 IMX_SC_PM_CLK_PER>; |
| 70 | 70 | assigned-clock-rates = <24000000>; |
| 71 | − #pwm-cells = <2>; | |
| 71 | + #pwm-cells = <3>; | |
| 72 | 72 | interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; |
| 73 | 73 | status = "disabled"; |
| 74 | 74 | }; |
| @@ -2072,6 +2072,7 @@ · 2071 unmodified lines | ||
| 2072 | 2072 | phys = <&usb3_phy0>, <&usb3_phy0>; |
| 2073 | 2073 | phy-names = "usb2-phy", "usb3-phy"; |
| 2074 | 2074 | snps,gfladj-refclk-lpm-sel-quirk; |
| 2075 | + snps,parkmode-disable-ss-quirk; | |
| 2075 | 2076 | }; |
| 2076 | 2077 | |
| 2077 | 2078 | }; |
| @@ -2114,6 +2115,7 @@ · 36 unmodified lines | ||
| 2114 | 2115 | phys = <&usb3_phy1>, <&usb3_phy1>; |
| 2115 | 2116 | phy-names = "usb2-phy", "usb3-phy"; |
| 2116 | 2117 | snps,gfladj-refclk-lpm-sel-quirk; |
| 2118 | + snps,parkmode-disable-ss-quirk; | |
| 2117 | 2119 | }; |
| 2118 | 2120 | }; |
| 2119 | 2121 | |
| @@ -1649,6 +1649,7 @@ · 1648 unmodified lines | ||
| 1649 | 1649 | phys = <&usb3_phy0>, <&usb3_phy0>; |
| 1650 | 1650 | phy-names = "usb2-phy", "usb3-phy"; |
| 1651 | 1651 | power-domains = <&pgc_otg1>; |
| 1652 | + snps,parkmode-disable-ss-quirk; | |
| 1652 | 1653 | status = "disabled"; |
| 1653 | 1654 | }; |
| 1654 | 1655 | |
| @@ -1680,6 +1681,7 @@ · 25 unmodified lines | ||
| 1680 | 1681 | phys = <&usb3_phy1>, <&usb3_phy1>; |
| 1681 | 1682 | phy-names = "usb2-phy", "usb3-phy"; |
| 1682 | 1683 | power-domains = <&pgc_otg2>; |
| 1684 | + snps,parkmode-disable-ss-quirk; | |
| 1683 | 1685 | status = "disabled"; |
| 1684 | 1686 | }; |
| 1685 | 1687 | |
| @@ -96,6 +96,17 @@ · 95 unmodified lines | ||
| 96 | 96 | status = "okay"; |
| 97 | 97 | }; |
| 98 | 98 | |
| 99 | +&edma3 { | |
| 100 | + power-domains = <&pd IMX_SC_R_DMA_1_CH0>, | |
| 101 | + <&pd IMX_SC_R_DMA_1_CH1>, | |
| 102 | + <&pd IMX_SC_R_DMA_1_CH2>, | |
| 103 | + <&pd IMX_SC_R_DMA_1_CH3>, | |
| 104 | + <&pd IMX_SC_R_DMA_1_CH4>, | |
| 105 | + <&pd IMX_SC_R_DMA_1_CH5>, | |
| 106 | + <&pd IMX_SC_R_DMA_1_CH6>, | |
| 107 | + <&pd IMX_SC_R_DMA_1_CH7>; | |
| 108 | +}; | |
| 109 | + | |
| 99 | 110 | &flexcan1 { |
| 100 | 111 | fsl,clk-source = /bits/ 8 <1>; |
| 101 | 112 | }; |
| @@ -483,7 +483,7 @@ · 482 unmodified lines | ||
| 483 | 483 | }; |
| 484 | 484 | }; |
| 485 | 485 | |
| 486 | − gpioe: gpio@2d000080 { | |
| 486 | + gpioe: gpio@2d000000 { | |
| 487 | 487 | compatible = "fsl,imx8ulp-gpio"; |
| 488 | 488 | reg = <0x2d000000 0x1000>; |
| 489 | 489 | gpio-controller; |
| @@ -498,7 +498,7 @@ · 8 unmodified lines | ||
| 498 | 498 | gpio-ranges = <&iomuxc1 0 32 24>; |
| 499 | 499 | }; |
| 500 | 500 | |
| 501 | − gpiof: gpio@2d010080 { | |
| 501 | + gpiof: gpio@2d010000 { | |
| 502 | 502 | compatible = "fsl,imx8ulp-gpio"; |
| 503 | 503 | reg = <0x2d010000 0x1000>; |
| 504 | 504 | gpio-controller; |
| @@ -534,7 +534,7 @@ · 29 unmodified lines | ||
| 534 | 534 | }; |
| 535 | 535 | }; |
| 536 | 536 | |
| 537 | − gpiod: gpio@2e200080 { | |
| 537 | + gpiod: gpio@2e200000 { | |
| 538 | 538 | compatible = "fsl,imx8ulp-gpio"; |
| 539 | 539 | reg = <0x2e200000 0x1000>; |
| 540 | 540 | gpio-controller; |
| @@ -577,7 +577,7 @@ · 576 unmodified lines | ||
| 577 | 577 | fsl,pins = < |
| 578 | 578 | MX93_PAD_UART2_TXD__LPUART2_TX 0x31e |
| 579 | 579 | MX93_PAD_UART2_RXD__LPUART2_RX 0x31e |
| 580 | − MX93_PAD_SAI1_TXD0__LPUART2_RTS_B 0x31e | |
| 580 | + MX93_PAD_SAI1_TXD0__LPUART2_RTS_B 0x51e | |
| 581 | 581 | >; |
| 582 | 582 | }; |
| 583 | 583 | |
| @@ -417,7 +417,7 @@ · 416 unmodified lines | ||
| 417 | 417 | compatible = "fsl,imx93-src-slice"; |
| 418 | 418 | reg = <0x44462400 0x400>, <0x44465800 0x400>; |
| 419 | 419 | #power-domain-cells = <0>; |
| 420 | − clocks = <&clk IMX93_CLK_MEDIA_AXI>, | |
| 420 | + clocks = <&clk IMX93_CLK_NIC_MEDIA_GATE>, | |
| 421 | 421 | <&clk IMX93_CLK_MEDIA_APB>; |
| 422 | 422 | }; |
| 423 | 423 | }; |
| @@ -957,7 +957,7 @@ · 533 unmodified lines | ||
| 957 | 957 | }; |
| 958 | 958 | }; |
| 959 | 959 | |
| 960 | − gpio2: gpio@43810080 { | |
| 960 | + gpio2: gpio@43810000 { | |
| 961 | 961 | compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio"; |
| 962 | 962 | reg = <0x43810000 0x1000>; |
| 963 | 963 | gpio-controller; |
| @@ -972,7 +972,7 @@ · 8 unmodified lines | ||
| 972 | 972 | gpio-ranges = <&iomuxc 0 4 30>; |
| 973 | 973 | }; |
| 974 | 974 | |
| 975 | − gpio3: gpio@43820080 { | |
| 975 | + gpio3: gpio@43820000 { | |
| 976 | 976 | compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio"; |
| 977 | 977 | reg = <0x43820000 0x1000>; |
| 978 | 978 | gpio-controller; |
| @@ -988,7 +988,7 @@ · 9 unmodified lines | ||
| 988 | 988 | <&iomuxc 26 34 2>, <&iomuxc 28 0 4>; |
| 989 | 989 | }; |
| 990 | 990 | |
| 991 | − gpio4: gpio@43830080 { | |
| 991 | + gpio4: gpio@43830000 { | |
| 992 | 992 | compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio"; |
| 993 | 993 | reg = <0x43830000 0x1000>; |
| 994 | 994 | gpio-controller; |
| @@ -1003,7 +1003,7 @@ · 8 unmodified lines | ||
| 1003 | 1003 | gpio-ranges = <&iomuxc 0 38 28>, <&iomuxc 28 36 2>; |
| 1004 | 1004 | }; |
| 1005 | 1005 | |
| 1006 | − gpio1: gpio@47400080 { | |
| 1006 | + gpio1: gpio@47400000 { | |
| 1007 | 1007 | compatible = "fsl,imx93-gpio", "fsl,imx8ulp-gpio"; |
| 1008 | 1008 | reg = <0x47400000 0x1000>; |
| 1009 | 1009 | gpio-controller; |
| @@ -73,7 +73,7 @@ · 72 unmodified lines | ||
| 73 | 73 | }; |
| 74 | 74 | }; |
| 75 | 75 | |
| 76 | − memory { | |
| 76 | + memory@40000000 { | |
| 77 | 77 | reg = <0 0x40000000 0 0x40000000>; |
| 78 | 78 | }; |
| 79 | 79 | |
| @@ -55,7 +55,7 @@ · 54 unmodified lines | ||
| 55 | 55 | }; |
| 56 | 56 | }; |
| 57 | 57 | |
| 58 | − memory { | |
| 58 | + memory@40000000 { | |
| 59 | 59 | reg = <0 0x40000000 0 0x20000000>; |
| 60 | 60 | }; |
| 61 | 61 | |
| @@ -126,6 +126,7 @@ · 125 unmodified lines | ||
| 126 | 126 | compatible = "sff,sfp"; |
| 127 | 127 | i2c-bus = <&i2c_sfp1>; |
| 128 | 128 | los-gpios = <&pio 46 GPIO_ACTIVE_HIGH>; |
| 129 | + maximum-power-milliwatt = <3000>; | |
| 129 | 130 | mod-def0-gpios = <&pio 49 GPIO_ACTIVE_LOW>; |
| 130 | 131 | tx-disable-gpios = <&pio 20 GPIO_ACTIVE_HIGH>; |
| 131 | 132 | tx-fault-gpios = <&pio 7 GPIO_ACTIVE_HIGH>; |
| @@ -137,6 +138,7 @@ · 5 unmodified lines | ||
| 137 | 138 | i2c-bus = <&i2c_sfp2>; |
| 138 | 139 | los-gpios = <&pio 31 GPIO_ACTIVE_HIGH>; |
| 139 | 140 | mod-def0-gpios = <&pio 47 GPIO_ACTIVE_LOW>; |
| 141 | + maximum-power-milliwatt = <3000>; | |
| 140 | 142 | tx-disable-gpios = <&pio 15 GPIO_ACTIVE_HIGH>; |
| 141 | 143 | tx-fault-gpios = <&pio 48 GPIO_ACTIVE_HIGH>; |
| 142 | 144 | }; |
| @@ -150,16 +152,16 @@ · 7 unmodified lines | ||
| 150 | 152 | trip = <&cpu_trip_active_high>; |
| 151 | 153 | }; |
| 152 | 154 | |
| 153 | − cpu-active-low { | |
| 155 | + cpu-active-med { | |
| 154 | 156 | /* active: set fan to cooling level 1 */ |
| 155 | 157 | cooling-device = <&fan 1 1>; |
| 156 | − trip = <&cpu_trip_active_low>; | |
| 158 | + trip = <&cpu_trip_active_med>; | |
| 157 | 159 | }; |
| 158 | 160 | |
| 159 | − cpu-passive { | |
| 160 | − /* passive: set fan to cooling level 0 */ | |
| 161 | + cpu-active-low { | |
| 162 | + /* active: set fan to cooling level 0 */ | |
| 161 | 163 | cooling-device = <&fan 0 0>; |
| 162 | − trip = <&cpu_trip_passive>; | |
| 164 | + trip = <&cpu_trip_active_low>; | |
| 163 | 165 | }; |
| 164 | 166 | }; |
| 165 | 167 | }; |
| @@ -374,6 +374,10 @@ · 373 unmodified lines | ||
| 374 | 374 | reg = <0 0x11230000 0 0x1000>, |
| 375 | 375 | <0 0x11c20000 0 0x1000>; |
| 376 | 376 | interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>; |
| 377 | + assigned-clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>, | |
| 378 | + <&topckgen CLK_TOP_EMMC_250M_SEL>; | |
| 379 | + assigned-clock-parents = <&apmixedsys CLK_APMIXED_MPLL>, | |
| 380 | + <&topckgen CLK_TOP_NET1PLL_D5_D2>; | |
| 377 | 381 | clocks = <&topckgen CLK_TOP_EMMC_416M_SEL>, |
| 378 | 382 | <&infracfg CLK_INFRA_MSDC_HCK_CK>, |
| 379 | 383 | <&infracfg CLK_INFRA_MSDC_CK>, |
| @@ -610,22 +614,34 @@ · 230 unmodified lines | ||
| 610 | 614 | thermal-sensors = <&thermal 0>; |
| 611 | 615 | |
| 612 | 616 | trips { |
| 617 | + cpu_trip_crit: crit { | |
| 618 | + temperature = <125000>; | |
| 619 | + hysteresis = <2000>; | |
| 620 | + type = "critical"; | |
| 621 | + }; | |
| 622 | + | |
| 623 | + cpu_trip_hot: hot { | |
| 624 | + temperature = <120000>; | |
| 625 | + hysteresis = <2000>; | |
| 626 | + type = "hot"; | |
| 627 | + }; | |
| 628 | + | |
| 613 | 629 | cpu_trip_active_high: active-high { |
| 614 | 630 | temperature = <115000>; |
| 615 | 631 | hysteresis = <2000>; |
| 616 | 632 | type = "active"; |
| 617 | 633 | }; |
| 618 | 634 | |
| 619 | − cpu_trip_active_low: active-low { | |
| 635 | + cpu_trip_active_med: active-med { | |
| 620 | 636 | temperature = <85000>; |
| 621 | 637 | hysteresis = <2000>; |
| 622 | 638 | type = "active"; |
| 623 | 639 | }; |
| 624 | 640 | |
| 625 | − cpu_trip_passive: passive { | |
| 626 | − temperature = <40000>; | |
| 641 | + cpu_trip_active_low: active-low { | |
| 642 | + temperature = <60000>; | |
| 627 | 643 | hysteresis = <2000>; |
| 628 | − type = "passive"; | |
| 644 | + type = "active"; | |
| 629 | 645 | }; |
| 630 | 646 | }; |
| 631 | 647 | }; |
| @@ -44,7 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | id-gpio = <&pio 16 GPIO_ACTIVE_HIGH>; |
| 45 | 45 | }; |
| 46 | 46 | |
| 47 | − usb_p1_vbus: regulator@0 { | |
| 47 | + usb_p1_vbus: regulator-usb-p1 { | |
| 48 | 48 | compatible = "regulator-fixed"; |
| 49 | 49 | regulator-name = "usb_vbus"; |
| 50 | 50 | regulator-min-microvolt = <5000000>; |
| @@ -53,7 +53,7 @@ · 2 unmodified lines | ||
| 53 | 53 | enable-active-high; |
| 54 | 54 | }; |
| 55 | 55 | |
| 56 | − usb_p0_vbus: regulator@1 { | |
| 56 | + usb_p0_vbus: regulator-usb-p0 { | |
| 57 | 57 | compatible = "regulator-fixed"; |
| 58 | 58 | regulator-name = "vbus"; |
| 59 | 59 | regulator-min-microvolt = <5000000>; |
| @@ -31,14 +31,14 @@ · 30 unmodified lines | ||
| 31 | 31 | #address-cells = <2>; |
| 32 | 32 | #size-cells = <2>; |
| 33 | 33 | ranges; |
| 34 | − scp_mem_reserved: scp_mem_region { | |
| 34 | + scp_mem_reserved: memory@50000000 { | |
| 35 | 35 | compatible = "shared-dma-pool"; |
| 36 | 36 | reg = <0 0x50000000 0 0x2900000>; |
| 37 | 37 | no-map; |
| 38 | 38 | }; |
| 39 | 39 | }; |
| 40 | 40 | |
| 41 | − ntc@0 { | |
| 41 | + thermal-sensor { | |
| 42 | 42 | compatible = "murata,ncp03wf104"; |
| 43 | 43 | pullup-uv = <1800000>; |
| 44 | 44 | pullup-ohm = <390000>; |
| @@ -91,6 +91,8 @@ · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | &dsi0 { |
| 93 | 93 | status = "okay"; |
| 94 | + /delete-property/#size-cells; | |
| 95 | + /delete-property/#address-cells; | |
| 94 | 96 | /delete-node/panel@0; |
| 95 | 97 | ports { |
| 96 | 98 | port { |
| @@ -441,20 +443,20 @@ · 344 unmodified lines | ||
| 441 | 443 | }; |
| 442 | 444 | |
| 443 | 445 | touchscreen_pins: touchscreen-pins { |
| 444 | − touch_int_odl { | |
| 446 | + touch-int-odl { | |
| 445 | 447 | pinmux = <PINMUX_GPIO155__FUNC_GPIO155>; |
| 446 | 448 | input-enable; |
| 447 | 449 | bias-pull-up; |
| 448 | 450 | }; |
| 449 | 451 | |
| 450 | − touch_rst_l { | |
| 452 | + touch-rst-l { | |
| 451 | 453 | pinmux = <PINMUX_GPIO156__FUNC_GPIO156>; |
| 452 | 454 | output-high; |
| 453 | 455 | }; |
| 454 | 456 | }; |
| 455 | 457 | |
| 456 | 458 | trackpad_pins: trackpad-pins { |
| 457 | − trackpad_int { | |
| 459 | + trackpad-int { | |
| 458 | 460 | pinmux = <PINMUX_GPIO7__FUNC_GPIO7>; |
| 459 | 461 | input-enable; |
| 460 | 462 | bias-disable; /* pulled externally */ |
| @@ -116,7 +116,7 @@ · 115 unmodified lines | ||
| 116 | 116 | #size-cells = <2>; |
| 117 | 117 | ranges; |
| 118 | 118 | |
| 119 | − scp_mem_reserved: scp_mem_region { | |
| 119 | + scp_mem_reserved: memory@50000000 { | |
| 120 | 120 | compatible = "shared-dma-pool"; |
| 121 | 121 | reg = <0 0x50000000 0 0x2900000>; |
| 122 | 122 | no-map; |
| @@ -460,7 +460,7 @@ · 337 unmodified lines | ||
| 460 | 460 | |
| 461 | 461 | &pio { |
| 462 | 462 | aud_pins_default: audiopins { |
| 463 | − pins_bus { | |
| 463 | + pins-bus { | |
| 464 | 464 | pinmux = <PINMUX_GPIO97__FUNC_I2S2_MCK>, |
| 465 | 465 | <PINMUX_GPIO98__FUNC_I2S2_BCK>, |
| 466 | 466 | <PINMUX_GPIO101__FUNC_I2S2_LRCK>, |
| @@ -482,7 +482,7 @@ · 15 unmodified lines | ||
| 482 | 482 | }; |
| 483 | 483 | |
| 484 | 484 | aud_pins_tdm_out_on: audiotdmouton { |
| 485 | − pins_bus { | |
| 485 | + pins-bus { | |
| 486 | 486 | pinmux = <PINMUX_GPIO169__FUNC_TDM_BCK_2ND>, |
| 487 | 487 | <PINMUX_GPIO170__FUNC_TDM_LRCK_2ND>, |
| 488 | 488 | <PINMUX_GPIO171__FUNC_TDM_DATA0_2ND>, |
| @@ -494,7 +494,7 @@ · 5 unmodified lines | ||
| 494 | 494 | }; |
| 495 | 495 | |
| 496 | 496 | aud_pins_tdm_out_off: audiotdmoutoff { |
| 497 | − pins_bus { | |
| 497 | + pins-bus { | |
| 498 | 498 | pinmux = <PINMUX_GPIO169__FUNC_GPIO169>, |
| 499 | 499 | <PINMUX_GPIO170__FUNC_GPIO170>, |
| 500 | 500 | <PINMUX_GPIO171__FUNC_GPIO171>, |
| @@ -508,13 +508,13 @@ · 7 unmodified lines | ||
| 508 | 508 | }; |
| 509 | 509 | |
| 510 | 510 | bt_pins: bt-pins { |
| 511 | − pins_bt_en { | |
| 511 | + pins-bt-en { | |
| 512 | 512 | pinmux = <PINMUX_GPIO120__FUNC_GPIO120>; |
| 513 | 513 | output-low; |
| 514 | 514 | }; |
| 515 | 515 | }; |
| 516 | 516 | |
| 517 | − ec_ap_int_odl: ec_ap_int_odl { | |
| 517 | + ec_ap_int_odl: ec-ap-int-odl { | |
| 518 | 518 | pins1 { |
| 519 | 519 | pinmux = <PINMUX_GPIO151__FUNC_GPIO151>; |
| 520 | 520 | input-enable; |
| @@ -522,7 +522,7 @@ · 1 unmodified line | ||
| 522 | 522 | }; |
| 523 | 523 | }; |
| 524 | 524 | |
| 525 | − h1_int_od_l: h1_int_od_l { | |
| 525 | + h1_int_od_l: h1-int-od-l { | |
| 526 | 526 | pins1 { |
| 527 | 527 | pinmux = <PINMUX_GPIO153__FUNC_GPIO153>; |
| 528 | 528 | input-enable; |
| @@ -530,7 +530,7 @@ · 1 unmodified line | ||
| 530 | 530 | }; |
| 531 | 531 | |
| 532 | 532 | i2c0_pins: i2c0 { |
| 533 | − pins_bus { | |
| 533 | + pins-bus { | |
| 534 | 534 | pinmux = <PINMUX_GPIO82__FUNC_SDA0>, |
| 535 | 535 | <PINMUX_GPIO83__FUNC_SCL0>; |
| 536 | 536 | mediatek,pull-up-adv = <3>; |
| @@ -539,7 +539,7 @@ · 2 unmodified lines | ||
| 539 | 539 | }; |
| 540 | 540 | |
| 541 | 541 | i2c1_pins: i2c1 { |
| 542 | − pins_bus { | |
| 542 | + pins-bus { | |
| 543 | 543 | pinmux = <PINMUX_GPIO81__FUNC_SDA1>, |
| 544 | 544 | <PINMUX_GPIO84__FUNC_SCL1>; |
| 545 | 545 | mediatek,pull-up-adv = <3>; |
| @@ -548,7 +548,7 @@ · 2 unmodified lines | ||
| 548 | 548 | }; |
| 549 | 549 | |
| 550 | 550 | i2c2_pins: i2c2 { |
| 551 | − pins_bus { | |
| 551 | + pins-bus { | |
| 552 | 552 | pinmux = <PINMUX_GPIO103__FUNC_SCL2>, |
| 553 | 553 | <PINMUX_GPIO104__FUNC_SDA2>; |
| 554 | 554 | bias-disable; |
| @@ -557,7 +557,7 @@ · 2 unmodified lines | ||
| 557 | 557 | }; |
| 558 | 558 | |
| 559 | 559 | i2c3_pins: i2c3 { |
| 560 | − pins_bus { | |
| 560 | + pins-bus { | |
| 561 | 561 | pinmux = <PINMUX_GPIO50__FUNC_SCL3>, |
| 562 | 562 | <PINMUX_GPIO51__FUNC_SDA3>; |
| 563 | 563 | mediatek,pull-up-adv = <3>; |
| @@ -566,7 +566,7 @@ · 2 unmodified lines | ||
| 566 | 566 | }; |
| 567 | 567 | |
| 568 | 568 | i2c4_pins: i2c4 { |
| 569 | − pins_bus { | |
| 569 | + pins-bus { | |
| 570 | 570 | pinmux = <PINMUX_GPIO105__FUNC_SCL4>, |
| 571 | 571 | <PINMUX_GPIO106__FUNC_SDA4>; |
| 572 | 572 | bias-disable; |
| @@ -575,7 +575,7 @@ · 2 unmodified lines | ||
| 575 | 575 | }; |
| 576 | 576 | |
| 577 | 577 | i2c5_pins: i2c5 { |
| 578 | − pins_bus { | |
| 578 | + pins-bus { | |
| 579 | 579 | pinmux = <PINMUX_GPIO48__FUNC_SCL5>, |
| 580 | 580 | <PINMUX_GPIO49__FUNC_SDA5>; |
| 581 | 581 | mediatek,pull-up-adv = <3>; |
| @@ -584,7 +584,7 @@ · 2 unmodified lines | ||
| 584 | 584 | }; |
| 585 | 585 | |
| 586 | 586 | i2c6_pins: i2c6 { |
| 587 | − pins_bus { | |
| 587 | + pins-bus { | |
| 588 | 588 | pinmux = <PINMUX_GPIO11__FUNC_SCL6>, |
| 589 | 589 | <PINMUX_GPIO12__FUNC_SDA6>; |
| 590 | 590 | bias-disable; |
| @@ -592,7 +592,7 @@ · 1 unmodified line | ||
| 592 | 592 | }; |
| 593 | 593 | |
| 594 | 594 | mmc0_pins_default: mmc0-pins-default { |
| 595 | − pins_cmd_dat { | |
| 595 | + pins-cmd-dat { | |
| 596 | 596 | pinmux = <PINMUX_GPIO123__FUNC_MSDC0_DAT0>, |
| 597 | 597 | <PINMUX_GPIO128__FUNC_MSDC0_DAT1>, |
| 598 | 598 | <PINMUX_GPIO125__FUNC_MSDC0_DAT2>, |
| @@ -607,13 +607,13 @@ · 8 unmodified lines | ||
| 607 | 607 | mediatek,pull-up-adv = <01>; |
| 608 | 608 | }; |
| 609 | 609 | |
| 610 | − pins_clk { | |
| 610 | + pins-clk { | |
| 611 | 611 | pinmux = <PINMUX_GPIO124__FUNC_MSDC0_CLK>; |
| 612 | 612 | drive-strength = <MTK_DRIVE_14mA>; |
| 613 | 613 | mediatek,pull-down-adv = <10>; |
| 614 | 614 | }; |
| 615 | 615 | |
| 616 | − pins_rst { | |
| 616 | + pins-rst { | |
| 617 | 617 | pinmux = <PINMUX_GPIO133__FUNC_MSDC0_RSTB>; |
| 618 | 618 | drive-strength = <MTK_DRIVE_14mA>; |
| 619 | 619 | mediatek,pull-down-adv = <01>; |
| @@ -621,7 +621,7 @@ · 1 unmodified line | ||
| 621 | 621 | }; |
| 622 | 622 | |
| 623 | 623 | mmc0_pins_uhs: mmc0-pins-uhs { |
| 624 | − pins_cmd_dat { | |
| 624 | + pins-cmd-dat { | |
| 625 | 625 | pinmux = <PINMUX_GPIO123__FUNC_MSDC0_DAT0>, |
| 626 | 626 | <PINMUX_GPIO128__FUNC_MSDC0_DAT1>, |
| 627 | 627 | <PINMUX_GPIO125__FUNC_MSDC0_DAT2>, |
| @@ -636,19 +636,19 @@ · 8 unmodified lines | ||
| 636 | 636 | mediatek,pull-up-adv = <01>; |
| 637 | 637 | }; |
| 638 | 638 | |
| 639 | − pins_clk { | |
| 639 | + pins-clk { | |
| 640 | 640 | pinmux = <PINMUX_GPIO124__FUNC_MSDC0_CLK>; |
| 641 | 641 | drive-strength = <MTK_DRIVE_14mA>; |
| 642 | 642 | mediatek,pull-down-adv = <10>; |
| 643 | 643 | }; |
| 644 | 644 | |
| 645 | − pins_ds { | |
| 645 | + pins-ds { | |
| 646 | 646 | pinmux = <PINMUX_GPIO131__FUNC_MSDC0_DSL>; |
| 647 | 647 | drive-strength = <MTK_DRIVE_14mA>; |
| 648 | 648 | mediatek,pull-down-adv = <10>; |
| 649 | 649 | }; |
| 650 | 650 | |
| 651 | − pins_rst { | |
| 651 | + pins-rst { | |
| 652 | 652 | pinmux = <PINMUX_GPIO133__FUNC_MSDC0_RSTB>; |
| 653 | 653 | drive-strength = <MTK_DRIVE_14mA>; |
| 654 | 654 | mediatek,pull-up-adv = <01>; |
| @@ -656,7 +656,7 @@ · 1 unmodified line | ||
| 656 | 656 | }; |
| 657 | 657 | |
| 658 | 658 | mmc1_pins_default: mmc1-pins-default { |
| 659 | − pins_cmd_dat { | |
| 659 | + pins-cmd-dat { | |
| 660 | 660 | pinmux = <PINMUX_GPIO31__FUNC_MSDC1_CMD>, |
| 661 | 661 | <PINMUX_GPIO32__FUNC_MSDC1_DAT0>, |
| 662 | 662 | <PINMUX_GPIO34__FUNC_MSDC1_DAT1>, |
| @@ -666,7 +666,7 @@ · 3 unmodified lines | ||
| 666 | 666 | mediatek,pull-up-adv = <10>; |
| 667 | 667 | }; |
| 668 | 668 | |
| 669 | − pins_clk { | |
| 669 | + pins-clk { | |
| 670 | 670 | pinmux = <PINMUX_GPIO29__FUNC_MSDC1_CLK>; |
| 671 | 671 | input-enable; |
| 672 | 672 | mediatek,pull-down-adv = <10>; |
| @@ -674,7 +674,7 @@ · 1 unmodified line | ||
| 674 | 674 | }; |
| 675 | 675 | |
| 676 | 676 | mmc1_pins_uhs: mmc1-pins-uhs { |
| 677 | − pins_cmd_dat { | |
| 677 | + pins-cmd-dat { | |
| 678 | 678 | pinmux = <PINMUX_GPIO31__FUNC_MSDC1_CMD>, |
| 679 | 679 | <PINMUX_GPIO32__FUNC_MSDC1_DAT0>, |
| 680 | 680 | <PINMUX_GPIO34__FUNC_MSDC1_DAT1>, |
| @@ -685,7 +685,7 @@ · 4 unmodified lines | ||
| 685 | 685 | mediatek,pull-up-adv = <10>; |
| 686 | 686 | }; |
| 687 | 687 | |
| 688 | − pins_clk { | |
| 688 | + pins-clk { | |
| 689 | 689 | pinmux = <PINMUX_GPIO29__FUNC_MSDC1_CLK>; |
| 690 | 690 | drive-strength = <MTK_DRIVE_8mA>; |
| 691 | 691 | mediatek,pull-down-adv = <10>; |
| @@ -693,15 +693,15 @@ · 1 unmodified line | ||
| 693 | 693 | }; |
| 694 | 694 | }; |
| 695 | 695 | |
| 696 | − panel_pins_default: panel_pins_default { | |
| 697 | − panel_reset { | |
| 696 | + panel_pins_default: panel-pins-default { | |
| 697 | + panel-reset { | |
| 698 | 698 | pinmux = <PINMUX_GPIO45__FUNC_GPIO45>; |
| 699 | 699 | output-low; |
| 700 | 700 | bias-pull-up; |
| 701 | 701 | }; |
| 702 | 702 | }; |
| 703 | 703 | |
| 704 | − pwm0_pin_default: pwm0_pin_default { | |
| 704 | + pwm0_pin_default: pwm0-pin-default { | |
| 705 | 705 | pins1 { |
| 706 | 706 | pinmux = <PINMUX_GPIO176__FUNC_GPIO176>; |
| 707 | 707 | output-high; |
| @@ -713,14 +713,14 @@ · 5 unmodified lines | ||
| 713 | 713 | }; |
| 714 | 714 | |
| 715 | 715 | scp_pins: scp { |
| 716 | − pins_scp_uart { | |
| 716 | + pins-scp-uart { | |
| 717 | 717 | pinmux = <PINMUX_GPIO110__FUNC_TP_URXD1_AO>, |
| 718 | 718 | <PINMUX_GPIO112__FUNC_TP_UTXD1_AO>; |
| 719 | 719 | }; |
| 720 | 720 | }; |
| 721 | 721 | |
| 722 | 722 | spi0_pins: spi0 { |
| 723 | − pins_spi { | |
| 723 | + pins-spi { | |
| 724 | 724 | pinmux = <PINMUX_GPIO85__FUNC_SPI0_MI>, |
| 725 | 725 | <PINMUX_GPIO86__FUNC_GPIO86>, |
| 726 | 726 | <PINMUX_GPIO87__FUNC_SPI0_MO>, |
| @@ -730,7 +730,7 @@ · 3 unmodified lines | ||
| 730 | 730 | }; |
| 731 | 731 | |
| 732 | 732 | spi1_pins: spi1 { |
| 733 | − pins_spi { | |
| 733 | + pins-spi { | |
| 734 | 734 | pinmux = <PINMUX_GPIO161__FUNC_SPI1_A_MI>, |
| 735 | 735 | <PINMUX_GPIO162__FUNC_SPI1_A_CSB>, |
| 736 | 736 | <PINMUX_GPIO163__FUNC_SPI1_A_MO>, |
| @@ -740,20 +740,20 @@ · 3 unmodified lines | ||
| 740 | 740 | }; |
| 741 | 741 | |
| 742 | 742 | spi2_pins: spi2 { |
| 743 | − pins_spi { | |
| 743 | + pins-spi { | |
| 744 | 744 | pinmux = <PINMUX_GPIO0__FUNC_SPI2_CSB>, |
| 745 | 745 | <PINMUX_GPIO1__FUNC_SPI2_MO>, |
| 746 | 746 | <PINMUX_GPIO2__FUNC_SPI2_CLK>; |
| 747 | 747 | bias-disable; |
| 748 | 748 | }; |
| 749 | − pins_spi_mi { | |
| 749 | + pins-spi-mi { | |
| 750 | 750 | pinmux = <PINMUX_GPIO94__FUNC_SPI2_MI>; |
| 751 | 751 | mediatek,pull-down-adv = <00>; |
| 752 | 752 | }; |
| 753 | 753 | }; |
| 754 | 754 | |
| 755 | 755 | spi3_pins: spi3 { |
| 756 | − pins_spi { | |
| 756 | + pins-spi { | |
| 757 | 757 | pinmux = <PINMUX_GPIO21__FUNC_SPI3_MI>, |
| 758 | 758 | <PINMUX_GPIO22__FUNC_SPI3_CSB>, |
| 759 | 759 | <PINMUX_GPIO23__FUNC_SPI3_MO>, |
| @@ -763,7 +763,7 @@ · 3 unmodified lines | ||
| 763 | 763 | }; |
| 764 | 764 | |
| 765 | 765 | spi4_pins: spi4 { |
| 766 | − pins_spi { | |
| 766 | + pins-spi { | |
| 767 | 767 | pinmux = <PINMUX_GPIO17__FUNC_SPI4_MI>, |
| 768 | 768 | <PINMUX_GPIO18__FUNC_SPI4_CSB>, |
| 769 | 769 | <PINMUX_GPIO19__FUNC_SPI4_MO>, |
| @@ -773,7 +773,7 @@ · 3 unmodified lines | ||
| 773 | 773 | }; |
| 774 | 774 | |
| 775 | 775 | spi5_pins: spi5 { |
| 776 | − pins_spi { | |
| 776 | + pins-spi { | |
| 777 | 777 | pinmux = <PINMUX_GPIO13__FUNC_SPI5_MI>, |
| 778 | 778 | <PINMUX_GPIO14__FUNC_SPI5_CSB>, |
| 779 | 779 | <PINMUX_GPIO15__FUNC_SPI5_MO>, |
| @@ -783,63 +783,63 @@ · 3 unmodified lines | ||
| 783 | 783 | }; |
| 784 | 784 | |
| 785 | 785 | uart0_pins_default: uart0-pins-default { |
| 786 | − pins_rx { | |
| 786 | + pins-rx { | |
| 787 | 787 | pinmux = <PINMUX_GPIO95__FUNC_URXD0>; |
| 788 | 788 | input-enable; |
| 789 | 789 | bias-pull-up; |
| 790 | 790 | }; |
| 791 | − pins_tx { | |
| 791 | + pins-tx { | |
| 792 | 792 | pinmux = <PINMUX_GPIO96__FUNC_UTXD0>; |
| 793 | 793 | }; |
| 794 | 794 | }; |
| 795 | 795 | |
| 796 | 796 | uart1_pins_default: uart1-pins-default { |
| 797 | − pins_rx { | |
| 797 | + pins-rx { | |
| 798 | 798 | pinmux = <PINMUX_GPIO121__FUNC_URXD1>; |
| 799 | 799 | input-enable; |
| 800 | 800 | bias-pull-up; |
| 801 | 801 | }; |
| 802 | − pins_tx { | |
| 802 | + pins-tx { | |
| 803 | 803 | pinmux = <PINMUX_GPIO115__FUNC_UTXD1>; |
| 804 | 804 | }; |
| 805 | − pins_rts { | |
| 805 | + pins-rts { | |
| 806 | 806 | pinmux = <PINMUX_GPIO47__FUNC_URTS1>; |
| 807 | 807 | output-enable; |
| 808 | 808 | }; |
| 809 | − pins_cts { | |
| 809 | + pins-cts { | |
| 810 | 810 | pinmux = <PINMUX_GPIO46__FUNC_UCTS1>; |
| 811 | 811 | input-enable; |
| 812 | 812 | }; |
| 813 | 813 | }; |
| 814 | 814 | |
| 815 | 815 | uart1_pins_sleep: uart1-pins-sleep { |
| 816 | − pins_rx { | |
| 816 | + pins-rx { | |
| 817 | 817 | pinmux = <PINMUX_GPIO121__FUNC_GPIO121>; |
| 818 | 818 | input-enable; |
| 819 | 819 | bias-pull-up; |
| 820 | 820 | }; |
| 821 | − pins_tx { | |
| 821 | + pins-tx { | |
| 822 | 822 | pinmux = <PINMUX_GPIO115__FUNC_UTXD1>; |
| 823 | 823 | }; |
| 824 | − pins_rts { | |
| 824 | + pins-rts { | |
| 825 | 825 | pinmux = <PINMUX_GPIO47__FUNC_URTS1>; |
| 826 | 826 | output-enable; |
| 827 | 827 | }; |
| 828 | − pins_cts { | |
| 828 | + pins-cts { | |
| 829 | 829 | pinmux = <PINMUX_GPIO46__FUNC_UCTS1>; |
| 830 | 830 | input-enable; |
| 831 | 831 | }; |
| 832 | 832 | }; |
| 833 | 833 | |
| 834 | 834 | wifi_pins_pwrseq: wifi-pins-pwrseq { |
| 835 | − pins_wifi_enable { | |
| 835 | + pins-wifi-enable { | |
| 836 | 836 | pinmux = <PINMUX_GPIO119__FUNC_GPIO119>; |
| 837 | 837 | output-low; |
| 838 | 838 | }; |
| 839 | 839 | }; |
| 840 | 840 | |
| 841 | 841 | wifi_pins_wakeup: wifi-pins-wakeup { |
| 842 | − pins_wifi_wakeup { | |
| 842 | + pins-wifi-wakeup { | |
| 843 | 843 | pinmux = <PINMUX_GPIO113__FUNC_GPIO113>; |
| 844 | 844 | input-enable; |
| 845 | 845 | }; |
| @@ -1210,127 +1210,6 @@ · 1209 unmodified lines | ||
| 1210 | 1210 | nvmem-cell-names = "calibration-data"; |
| 1211 | 1211 | }; |
| 1212 | 1212 | |
| 1213 | − thermal_zones: thermal-zones { | |
| 1214 | − cpu_thermal: cpu-thermal { | |
| 1215 | − polling-delay-passive = <100>; | |
| 1216 | − polling-delay = <500>; | |
| 1217 | − thermal-sensors = <&thermal 0>; | |
| 1218 | − sustainable-power = <5000>; | |
| 1219 | − | |
| 1220 | − trips { | |
| 1221 | − threshold: trip-point0 { | |
| 1222 | − temperature = <68000>; | |
| 1223 | − hysteresis = <2000>; | |
| 1224 | − type = "passive"; | |
| 1225 | − }; | |
| 1226 | − | |
| 1227 | − target: trip-point1 { | |
| 1228 | − temperature = <80000>; | |
| 1229 | − hysteresis = <2000>; | |
| 1230 | − type = "passive"; | |
| 1231 | − }; | |
| 1232 | − | |
| 1233 | − cpu_crit: cpu-crit { | |
| 1234 | − temperature = <115000>; | |
| 1235 | − hysteresis = <2000>; | |
| 1236 | − type = "critical"; | |
| 1237 | − }; | |
| 1238 | − }; | |
| 1239 | − | |
| 1240 | − cooling-maps { | |
| 1241 | − map0 { | |
| 1242 | − trip = <&target>; | |
| 1243 | − cooling-device = <&cpu0 | |
| 1244 | − THERMAL_NO_LIMIT | |
| 1245 | − THERMAL_NO_LIMIT>, | |
| 1246 | − <&cpu1 | |
| 1247 | − THERMAL_NO_LIMIT | |
| 1248 | − THERMAL_NO_LIMIT>, | |
| 1249 | − <&cpu2 | |
| 1250 | − THERMAL_NO_LIMIT | |
| 1251 | − THERMAL_NO_LIMIT>, | |
| 1252 | − <&cpu3 | |
| 1253 | − THERMAL_NO_LIMIT | |
| 1254 | − THERMAL_NO_LIMIT>; | |
| 1255 | − contribution = <3072>; | |
| 1256 | − }; | |
| 1257 | − map1 { | |
| 1258 | − trip = <&target>; | |
| 1259 | − cooling-device = <&cpu4 | |
| 1260 | − THERMAL_NO_LIMIT | |
| 1261 | − THERMAL_NO_LIMIT>, | |
| 1262 | − <&cpu5 | |
| 1263 | − THERMAL_NO_LIMIT | |
| 1264 | − THERMAL_NO_LIMIT>, | |
| 1265 | − <&cpu6 | |
| 1266 | − THERMAL_NO_LIMIT | |
| 1267 | − THERMAL_NO_LIMIT>, | |
| 1268 | − <&cpu7 | |
| 1269 | − THERMAL_NO_LIMIT | |
| 1270 | − THERMAL_NO_LIMIT>; | |
| 1271 | − contribution = <1024>; | |
| 1272 | − }; | |
| 1273 | − }; | |
| 1274 | − }; | |
| 1275 | − | |
| 1276 | − /* The tzts1 ~ tzts6 don't need to polling */ | |
| 1277 | − /* The tzts1 ~ tzts6 don't need to thermal throttle */ | |
| 1278 | − | |
| 1279 | − tzts1: tzts1 { | |
| 1280 | − polling-delay-passive = <0>; | |
| 1281 | − polling-delay = <0>; | |
| 1282 | − thermal-sensors = <&thermal 1>; | |
| 1283 | − sustainable-power = <5000>; | |
| 1284 | − trips {}; | |
| 1285 | − cooling-maps {}; | |
| 1286 | − }; | |
| 1287 | − | |
| 1288 | − tzts2: tzts2 { | |
| 1289 | − polling-delay-passive = <0>; | |
| 1290 | − polling-delay = <0>; | |
| 1291 | − thermal-sensors = <&thermal 2>; | |
| 1292 | − sustainable-power = <5000>; | |
| 1293 | − trips {}; | |
| 1294 | − cooling-maps {}; | |
| 1295 | − }; | |
| 1296 | − | |
| 1297 | − tzts3: tzts3 { | |
| 1298 | − polling-delay-passive = <0>; | |
| 1299 | − polling-delay = <0>; | |
| 1300 | − thermal-sensors = <&thermal 3>; | |
| 1301 | − sustainable-power = <5000>; | |
| 1302 | − trips {}; | |
| 1303 | − cooling-maps {}; | |
| 1304 | − }; | |
| 1305 | − | |
| 1306 | − tzts4: tzts4 { | |
| 1307 | − polling-delay-passive = <0>; | |
| 1308 | − polling-delay = <0>; | |
| 1309 | − thermal-sensors = <&thermal 4>; | |
| 1310 | − sustainable-power = <5000>; | |
| 1311 | − trips {}; | |
| 1312 | − cooling-maps {}; | |
| 1313 | − }; | |
| 1314 | − | |
| 1315 | − tzts5: tzts5 { | |
| 1316 | − polling-delay-passive = <0>; | |
| 1317 | − polling-delay = <0>; | |
| 1318 | − thermal-sensors = <&thermal 5>; | |
| 1319 | − sustainable-power = <5000>; | |
| 1320 | − trips {}; | |
| 1321 | − cooling-maps {}; | |
| 1322 | − }; | |
| 1323 | − | |
| 1324 | − tztsABB: tztsABB { | |
| 1325 | − polling-delay-passive = <0>; | |
| 1326 | − polling-delay = <0>; | |
| 1327 | − thermal-sensors = <&thermal 6>; | |
| 1328 | − sustainable-power = <5000>; | |
| 1329 | − trips {}; | |
| 1330 | − cooling-maps {}; | |
| 1331 | − }; | |
| 1332 | − }; | |
| 1333 | − | |
| 1334 | 1213 | pwm0: pwm@1100e000 { |
| 1335 | 1214 | compatible = "mediatek,mt8183-disp-pwm"; |
| 1336 | 1215 | reg = <0 0x1100e000 0 0x1000>; |
| @@ -2105,4 +1984,125 @@ · 768 unmodified lines | ||
| 2105 | 1984 | power-domains = <&spm MT8183_POWER_DOMAIN_CAM>; |
| 2106 | 1985 | }; |
| 2107 | 1986 | }; |
| 1987 | + | |
| 1988 | + thermal_zones: thermal-zones { | |
| 1989 | + cpu_thermal: cpu-thermal { | |
| 1990 | + polling-delay-passive = <100>; | |
| 1991 | + polling-delay = <500>; | |
| 1992 | + thermal-sensors = <&thermal 0>; | |
| 1993 | + sustainable-power = <5000>; | |
| 1994 | + | |
| 1995 | + trips { | |
| 1996 | + threshold: trip-point0 { | |
| 1997 | + temperature = <68000>; | |
| 1998 | + hysteresis = <2000>; | |
| 1999 | + type = "passive"; | |
| 2000 | + }; | |
| 2001 | + | |
| 2002 | + target: trip-point1 { | |
| 2003 | + temperature = <80000>; | |
| 2004 | + hysteresis = <2000>; | |
| 2005 | + type = "passive"; | |
| 2006 | + }; | |
| 2007 | + | |
| 2008 | + cpu_crit: cpu-crit { | |
| 2009 | + temperature = <115000>; | |
| 2010 | + hysteresis = <2000>; | |
| 2011 | + type = "critical"; | |
| 2012 | + }; | |
| 2013 | + }; | |
| 2014 | + | |
| 2015 | + cooling-maps { | |
| 2016 | + map0 { | |
| 2017 | + trip = <&target>; | |
| 2018 | + cooling-device = <&cpu0 | |
| 2019 | + THERMAL_NO_LIMIT | |
| 2020 | + THERMAL_NO_LIMIT>, | |
| 2021 | + <&cpu1 | |
| 2022 | + THERMAL_NO_LIMIT | |
| 2023 | + THERMAL_NO_LIMIT>, | |
| 2024 | + <&cpu2 | |
| 2025 | + THERMAL_NO_LIMIT | |
| 2026 | + THERMAL_NO_LIMIT>, | |
| 2027 | + <&cpu3 | |
| 2028 | + THERMAL_NO_LIMIT | |
| 2029 | + THERMAL_NO_LIMIT>; | |
| 2030 | + contribution = <3072>; | |
| 2031 | + }; | |
| 2032 | + map1 { | |
| 2033 | + trip = <&target>; | |
| 2034 | + cooling-device = <&cpu4 | |
| 2035 | + THERMAL_NO_LIMIT | |
| 2036 | + THERMAL_NO_LIMIT>, | |
| 2037 | + <&cpu5 | |
| 2038 | + THERMAL_NO_LIMIT | |
| 2039 | + THERMAL_NO_LIMIT>, | |
| 2040 | + <&cpu6 | |
| 2041 | + THERMAL_NO_LIMIT | |
| 2042 | + THERMAL_NO_LIMIT>, | |
| 2043 | + <&cpu7 | |
| 2044 | + THERMAL_NO_LIMIT | |
| 2045 | + THERMAL_NO_LIMIT>; | |
| 2046 | + contribution = <1024>; | |
| 2047 | + }; | |
| 2048 | + }; | |
| 2049 | + }; | |
| 2050 | + | |
| 2051 | + /* The tzts1 ~ tzts6 don't need to polling */ | |
| 2052 | + /* The tzts1 ~ tzts6 don't need to thermal throttle */ | |
| 2053 | + | |
| 2054 | + tzts1: tzts1 { | |
| 2055 | + polling-delay-passive = <0>; | |
| 2056 | + polling-delay = <0>; | |
| 2057 | + thermal-sensors = <&thermal 1>; | |
| 2058 | + sustainable-power = <5000>; | |
| 2059 | + trips {}; | |
| 2060 | + cooling-maps {}; | |
| 2061 | + }; | |
| 2062 | + | |
| 2063 | + tzts2: tzts2 { | |
| 2064 | + polling-delay-passive = <0>; | |
| 2065 | + polling-delay = <0>; | |
| 2066 | + thermal-sensors = <&thermal 2>; | |
| 2067 | + sustainable-power = <5000>; | |
| 2068 | + trips {}; | |
| 2069 | + cooling-maps {}; | |
| 2070 | + }; | |
| 2071 | + | |
| 2072 | + tzts3: tzts3 { | |
| 2073 | + polling-delay-passive = <0>; | |
| 2074 | + polling-delay = <0>; | |
| 2075 | + thermal-sensors = <&thermal 3>; | |
| 2076 | + sustainable-power = <5000>; | |
| 2077 | + trips {}; | |
| 2078 | + cooling-maps {}; | |
| 2079 | + }; | |
| 2080 | + | |
| 2081 | + tzts4: tzts4 { | |
| 2082 | + polling-delay-passive = <0>; | |
| 2083 | + polling-delay = <0>; | |
| 2084 | + thermal-sensors = <&thermal 4>; | |
| 2085 | + sustainable-power = <5000>; | |
| 2086 | + trips {}; | |
| 2087 | + cooling-maps {}; | |
| 2088 | + }; | |
| 2089 | + | |
| 2090 | + tzts5: tzts5 { | |
| 2091 | + polling-delay-passive = <0>; | |
| 2092 | + polling-delay = <0>; | |
| 2093 | + thermal-sensors = <&thermal 5>; | |
| 2094 | + sustainable-power = <5000>; | |
| 2095 | + trips {}; | |
| 2096 | + cooling-maps {}; | |
| 2097 | + }; | |
| 2098 | + | |
| 2099 | + tztsABB: tztsABB { | |
| 2100 | + polling-delay-passive = <0>; | |
| 2101 | + polling-delay = <0>; | |
| 2102 | + thermal-sensors = <&thermal 6>; | |
| 2103 | + sustainable-power = <5000>; | |
| 2104 | + trips {}; | |
| 2105 | + cooling-maps {}; | |
| 2106 | + }; | |
| 2107 | + }; | |
| 2108 | 2108 | }; |
| @@ -924,7 +924,8 @@ · 923 unmodified lines | ||
| 924 | 924 | reg = <MT8186_POWER_DOMAIN_CSIRX_TOP>; |
| 925 | 925 | clocks = <&topckgen CLK_TOP_SENINF>, |
| 926 | 926 | <&topckgen CLK_TOP_SENINF1>; |
| 927 | − clock-names = "csirx_top0", "csirx_top1"; | |
| 927 | + clock-names = "subsys-csirx-top0", | |
| 928 | + "subsys-csirx-top1"; | |
| 928 | 929 | #power-domain-cells = <0>; |
| 929 | 930 | }; |
| 930 | 931 | |
| @@ -942,7 +943,8 @@ · 11 unmodified lines | ||
| 942 | 943 | reg = <MT8186_POWER_DOMAIN_ADSP_AO>; |
| 943 | 944 | clocks = <&topckgen CLK_TOP_AUDIODSP>, |
| 944 | 945 | <&topckgen CLK_TOP_ADSP_BUS>; |
| 945 | − clock-names = "audioadsp", "adsp_bus"; | |
| 946 | + clock-names = "audioadsp", | |
| 947 | + "subsys-adsp-bus"; | |
| 946 | 948 | #address-cells = <1>; |
| 947 | 949 | #size-cells = <0>; |
| 948 | 950 | #power-domain-cells = <1>; |
| @@ -975,8 +977,11 @@ · 26 unmodified lines | ||
| 975 | 977 | <&mmsys CLK_MM_SMI_COMMON>, |
| 976 | 978 | <&mmsys CLK_MM_SMI_GALS>, |
| 977 | 979 | <&mmsys CLK_MM_SMI_IOMMU>; |
| 978 | − clock-names = "disp", "mdp", "smi_infra", "smi_common", | |
| 979 | − "smi_gals", "smi_iommu"; | |
| 980 | + clock-names = "disp", "mdp", | |
| 981 | + "subsys-smi-infra", | |
| 982 | + "subsys-smi-common", | |
| 983 | + "subsys-smi-gals", | |
| 984 | + "subsys-smi-iommu"; | |
| 980 | 985 | mediatek,infracfg = <&infracfg_ao>; |
| 981 | 986 | #address-cells = <1>; |
| 982 | 987 | #size-cells = <0>; |
| @@ -993,15 +998,17 @@ · 10 unmodified lines | ||
| 993 | 998 | |
| 994 | 999 | power-domain@MT8186_POWER_DOMAIN_CAM { |
| 995 | 1000 | reg = <MT8186_POWER_DOMAIN_CAM>; |
| 996 | − clocks = <&topckgen CLK_TOP_CAM>, | |
| 997 | − <&topckgen CLK_TOP_SENINF>, | |
| 1001 | + clocks = <&topckgen CLK_TOP_SENINF>, | |
| 998 | 1002 | <&topckgen CLK_TOP_SENINF1>, |
| 999 | 1003 | <&topckgen CLK_TOP_SENINF2>, |
| 1000 | 1004 | <&topckgen CLK_TOP_SENINF3>, |
| 1005 | + <&camsys CLK_CAM2MM_GALS>, | |
| 1001 | 1006 | <&topckgen CLK_TOP_CAMTM>, |
| 1002 | − <&camsys CLK_CAM2MM_GALS>; | |
| 1003 | − clock-names = "cam-top", "cam0", "cam1", "cam2", | |
| 1004 | − "cam3", "cam-tm", "gals"; | |
| 1007 | + <&topckgen CLK_TOP_CAM>; | |
| 1008 | + clock-names = "cam0", "cam1", "cam2", | |
| 1009 | + "cam3", "gals", | |
| 1010 | + "subsys-cam-tm", | |
| 1011 | + "subsys-cam-top"; | |
| 1005 | 1012 | mediatek,infracfg = <&infracfg_ao>; |
| 1006 | 1013 | #address-cells = <1>; |
| 1007 | 1014 | #size-cells = <0>; |
| @@ -1020,9 +1027,9 @@ · 12 unmodified lines | ||
| 1020 | 1027 | |
| 1021 | 1028 | power-domain@MT8186_POWER_DOMAIN_IMG { |
| 1022 | 1029 | reg = <MT8186_POWER_DOMAIN_IMG>; |
| 1023 | − clocks = <&topckgen CLK_TOP_IMG1>, | |
| 1024 | − <&imgsys1 CLK_IMG1_GALS_IMG1>; | |
| 1025 | − clock-names = "img-top", "gals"; | |
| 1030 | + clocks = <&imgsys1 CLK_IMG1_GALS_IMG1>, | |
| 1031 | + <&topckgen CLK_TOP_IMG1>; | |
| 1032 | + clock-names = "gals", "subsys-img-top"; | |
| 1026 | 1033 | mediatek,infracfg = <&infracfg_ao>; |
| 1027 | 1034 | #address-cells = <1>; |
| 1028 | 1035 | #size-cells = <0>; |
| @@ -1041,8 +1048,11 @@ · 12 unmodified lines | ||
| 1041 | 1048 | <&ipesys CLK_IPE_LARB20>, |
| 1042 | 1049 | <&ipesys CLK_IPE_SMI_SUBCOM>, |
| 1043 | 1050 | <&ipesys CLK_IPE_GALS_IPE>; |
| 1044 | − clock-names = "ipe-top", "ipe-larb0", "ipe-larb1", | |
| 1045 | − "ipe-smi", "ipe-gals"; | |
| 1051 | + clock-names = "subsys-ipe-top", | |
| 1052 | + "subsys-ipe-larb0", | |
| 1053 | + "subsys-ipe-larb1", | |
| 1054 | + "subsys-ipe-smi", | |
| 1055 | + "subsys-ipe-gals"; | |
| 1046 | 1056 | mediatek,infracfg = <&infracfg_ao>; |
| 1047 | 1057 | #power-domain-cells = <0>; |
| 1048 | 1058 | }; |
| @@ -1061,7 +1071,9 @@ · 12 unmodified lines | ||
| 1061 | 1071 | clocks = <&topckgen CLK_TOP_WPE>, |
| 1062 | 1072 | <&wpesys CLK_WPE_SMI_LARB8_CK_EN>, |
| 1063 | 1073 | <&wpesys CLK_WPE_SMI_LARB8_PCLK_EN>; |
| 1064 | − clock-names = "wpe0", "larb-ck", "larb-pclk"; | |
| 1074 | + clock-names = "wpe0", | |
| 1075 | + "subsys-larb-ck", | |
| 1076 | + "subsys-larb-pclk"; | |
| 1065 | 1077 | mediatek,infracfg = <&infracfg_ao>; |
| 1066 | 1078 | #power-domain-cells = <0>; |
| 1067 | 1079 | }; |
| @@ -1656,7 +1668,7 @@ · 588 unmodified lines | ||
| 1656 | 1668 | #address-cells = <1>; |
| 1657 | 1669 | #size-cells = <1>; |
| 1658 | 1670 | |
| 1659 | − gpu_speedbin: gpu-speed-bin@59c { | |
| 1671 | + gpu_speedbin: gpu-speedbin@59c { | |
| 1660 | 1672 | reg = <0x59c 0x4>; |
| 1661 | 1673 | bits = <0 3>; |
| 1662 | 1674 | }; |
| @@ -389,7 +389,7 @@ · 388 unmodified lines | ||
| 389 | 389 | pinctrl-0 = <&i2c7_pins>; |
| 390 | 390 | |
| 391 | 391 | pmic@34 { |
| 392 | − #interrupt-cells = <1>; | |
| 392 | + #interrupt-cells = <2>; | |
| 393 | 393 | compatible = "mediatek,mt6360"; |
| 394 | 394 | reg = <0x34>; |
| 395 | 395 | interrupt-controller; |
| @@ -627,6 +627,8 @@ · 626 unmodified lines | ||
| 627 | 627 | |
| 628 | 628 | power-domain@MT8195_POWER_DOMAIN_VENC_CORE1 { |
| 629 | 629 | reg = <MT8195_POWER_DOMAIN_VENC_CORE1>; |
| 630 | + clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>; | |
| 631 | + clock-names = "venc1-larb"; | |
| 630 | 632 | mediatek,infracfg = <&infracfg_ao>; |
| 631 | 633 | #power-domain-cells = <0>; |
| 632 | 634 | }; |
| @@ -689,6 +691,8 @@ · 56 unmodified lines | ||
| 689 | 691 | |
| 690 | 692 | power-domain@MT8195_POWER_DOMAIN_VENC { |
| 691 | 693 | reg = <MT8195_POWER_DOMAIN_VENC>; |
| 694 | + clocks = <&vencsys CLK_VENC_LARB>; | |
| 695 | + clock-names = "venc0-larb"; | |
| 692 | 696 | mediatek,infracfg = <&infracfg_ao>; |
| 693 | 697 | #power-domain-cells = <0>; |
| 694 | 698 | }; |
| @@ -2665,7 +2669,7 @@ · 1970 unmodified lines | ||
| 2665 | 2669 | reg = <0 0x1b010000 0 0x1000>; |
| 2666 | 2670 | mediatek,larb-id = <20>; |
| 2667 | 2671 | mediatek,smi = <&smi_common_vpp>; |
| 2668 | − clocks = <&vencsys_core1 CLK_VENC_CORE1_LARB>, | |
| 2672 | + clocks = <&vencsys_core1 CLK_VENC_CORE1_VENC>, | |
| 2669 | 2673 | <&vencsys_core1 CLK_VENC_CORE1_GALS>, |
| 2670 | 2674 | <&vppsys0 CLK_VPP0_GALS_VDO0_VDO1_VENCSYS_CORE1>; |
| 2671 | 2675 | clock-names = "apb", "smi", "gals"; |
| @@ -86,7 +86,7 @@ · 85 unmodified lines | ||
| 86 | 86 | sgtl5000_clk: sgtl5000-oscillator { |
| 87 | 87 | compatible = "fixed-clock"; |
| 88 | 88 | #clock-cells = <0>; |
| 89 | − clock-frequency = <24576000>; | |
| 89 | + clock-frequency = <24576000>; | |
| 90 | 90 | }; |
| 91 | 91 | |
| 92 | 92 | dc_12v: dc-12v-regulator { |
| @@ -668,7 +668,7 @@ · 667 unmodified lines | ||
| 668 | 668 | |
| 669 | 669 | vdec: video-codec@ff360000 { |
| 670 | 670 | compatible = "rockchip,rk3328-vdec", "rockchip,rk3399-vdec"; |
| 671 | − reg = <0x0 0xff360000 0x0 0x400>; | |
| 671 | + reg = <0x0 0xff360000 0x0 0x480>; | |
| 672 | 672 | interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; |
| 673 | 673 | clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>, |
| 674 | 674 | <&cru SCLK_VDEC_CABAC>, <&cru SCLK_VDEC_CORE>; |
| @@ -509,8 +509,7 @@ ap_i2c_tp: &i2c5 { · 508 unmodified lines | ||
| 509 | 509 | &pci_rootport { |
| 510 | 510 | mvl_wifi: wifi@0,0 { |
| 511 | 511 | compatible = "pci1b4b,2b42"; |
| 512 | − reg = <0x83010000 0x0 0x00000000 0x0 0x00100000 | |
| 513 | − 0x83010000 0x0 0x00100000 0x0 0x00100000>; | |
| 512 | + reg = <0x0000 0x0 0x0 0x0 0x0>; | |
| 514 | 513 | interrupt-parent = <&gpio0>; |
| 515 | 514 | interrupts = <8 IRQ_TYPE_LEVEL_LOW>; |
| 516 | 515 | pinctrl-names = "default"; |
| @@ -34,8 +34,8 @@ · 33 unmodified lines | ||
| 34 | 34 | &pci_rootport { |
| 35 | 35 | wifi@0,0 { |
| 36 | 36 | compatible = "qcom,ath10k"; |
| 37 | − reg = <0x00010000 0x0 0x00000000 0x0 0x00000000>, | |
| 38 | − <0x03010010 0x0 0x00000000 0x0 0x00200000>; | |
| 37 | + reg = <0x00000000 0x0 0x00000000 0x0 0x00000000>, | |
| 38 | + <0x03000010 0x0 0x00000000 0x0 0x00200000>; | |
| 39 | 39 | qcom,ath10k-calibration-variant = "GO_DUMO"; |
| 40 | 40 | }; |
| 41 | 41 | }; |
| @@ -489,6 +489,7 @@ ap_i2c_audio: &i2c8 { · 488 unmodified lines | ||
| 489 | 489 | #address-cells = <3>; |
| 490 | 490 | #size-cells = <2>; |
| 491 | 491 | ranges; |
| 492 | + device_type = "pci"; | |
| 492 | 493 | }; |
| 493 | 494 | }; |
| 494 | 495 | |
| @@ -1109,7 +1109,9 @@ · 1108 unmodified lines | ||
| 1109 | 1109 | power-domain@RK3399_PD_VDU { |
| 1110 | 1110 | reg = <RK3399_PD_VDU>; |
| 1111 | 1111 | clocks = <&cru ACLK_VDU>, |
| 1112 | − <&cru HCLK_VDU>; | |
| 1112 | + <&cru HCLK_VDU>, | |
| 1113 | + <&cru SCLK_VDU_CA>, | |
| 1114 | + <&cru SCLK_VDU_CORE>; | |
| 1113 | 1115 | pm_qos = <&qos_video_m1_r>, |
| 1114 | 1116 | <&qos_video_m1_w>; |
| 1115 | 1117 | #power-domain-cells = <0>; |
| @@ -1384,7 +1386,7 @@ · 268 unmodified lines | ||
| 1384 | 1386 | |
| 1385 | 1387 | vdec: video-codec@ff660000 { |
| 1386 | 1388 | compatible = "rockchip,rk3399-vdec"; |
| 1387 | − reg = <0x0 0xff660000 0x0 0x400>; | |
| 1389 | + reg = <0x0 0xff660000 0x0 0x480>; | |
| 1388 | 1390 | interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>; |
| 1389 | 1391 | clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>, |
| 1390 | 1392 | <&cru SCLK_VDU_CA>, <&cru SCLK_VDU_CORE>; |
| @@ -977,7 +977,7 @@ · 976 unmodified lines | ||
| 977 | 977 | <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, |
| 978 | 978 | <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, |
| 979 | 979 | <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; |
| 980 | − interrupt-names = "sys", "pmc", "msi", "legacy", "err"; | |
| 980 | + interrupt-names = "sys", "pmc", "msg", "legacy", "err"; | |
| 981 | 981 | bus-range = <0x0 0xf>; |
| 982 | 982 | clocks = <&cru ACLK_PCIE20_MST>, <&cru ACLK_PCIE20_SLV>, |
| 983 | 983 | <&cru ACLK_PCIE20_DBI>, <&cru PCLK_PCIE20>, |
| @@ -235,13 +235,13 @@ · 234 unmodified lines | ||
| 235 | 235 | &pinctrl { |
| 236 | 236 | fan { |
| 237 | 237 | fan_int: fan-int { |
| 238 | − rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; | |
| 238 | + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>; | |
| 239 | 239 | }; |
| 240 | 240 | }; |
| 241 | 241 | |
| 242 | 242 | hym8563 { |
| 243 | 243 | hym8563_int: hym8563-int { |
| 244 | − rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; | |
| 244 | + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; | |
| 245 | 245 | }; |
| 246 | 246 | }; |
| 247 | 247 | |
| @@ -38,7 +38,7 @@ · 37 unmodified lines | ||
| 38 | 38 | leds { |
| 39 | 39 | compatible = "gpio-leds"; |
| 40 | 40 | pinctrl-names = "default"; |
| 41 | − pinctrl-0 =<&leds_gpio>; | |
| 41 | + pinctrl-0 = <&leds_gpio>; | |
| 42 | 42 | |
| 43 | 43 | led-1 { |
| 44 | 44 | gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>; |
| @@ -369,7 +369,7 @@ · 368 unmodified lines | ||
| 369 | 369 | emmc_data_strobe: emmc-data-strobe { |
| 370 | 370 | rockchip,pins = |
| 371 | 371 | /* emmc_data_strobe */ |
| 372 | − <2 RK_PA2 1 &pcfg_pull_none>; | |
| 372 | + <2 RK_PA2 1 &pcfg_pull_down>; | |
| 373 | 373 | }; |
| 374 | 374 | }; |
| 375 | 375 | |
| @@ -1362,7 +1362,6 @@ · 1361 unmodified lines | ||
| 1362 | 1362 | <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH 0>, |
| 1363 | 1363 | <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH 0>, |
| 1364 | 1364 | <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH 0>; |
| 1365 | − interrupt-names = "ch0", "ch1", "ch2", "ch3"; | |
| 1366 | 1365 | rockchip,pmu = <&pmu1grf>; |
| 1367 | 1366 | }; |
| 1368 | 1367 | |
| @@ -21,9 +21,22 @@ static inline bool arch_parse_debug_rodata(char *arg) · 20 unmodified lines | ||
| 21 | 21 | extern bool rodata_enabled; |
| 22 | 22 | extern bool rodata_full; |
| 23 | 23 | |
| 24 | − if (arg && !strcmp(arg, "full")) { | |
| 24 | + if (!arg) | |
| 25 | + return false; | |
| 26 | + | |
| 27 | + if (!strcmp(arg, "full")) { | |
| 28 | + rodata_enabled = rodata_full = true; | |
| 29 | + return true; | |
| 30 | + } | |
| 31 | + | |
| 32 | + if (!strcmp(arg, "off")) { | |
| 33 | + rodata_enabled = rodata_full = false; | |
| 34 | + return true; | |
| 35 | + } | |
| 36 | + | |
| 37 | + if (!strcmp(arg, "on")) { | |
| 25 | 38 | rodata_enabled = true; |
| 26 | − rodata_full = true; | |
| 39 | + rodata_full = false; | |
| 27 | 40 | return true; |
| 28 | 41 | } |
| 29 | 42 | |
| @@ -1839,6 +1839,10 @@ static int __init __kpti_install_ng_mappings(void *__unused) · 1838 unmodified lines | ||
| 1839 | 1839 | |
| 1840 | 1840 | static void __init kpti_install_ng_mappings(void) |
| 1841 | 1841 | { |
| 1842 | + /* Check whether KPTI is going to be used */ | |
| 1843 | + if (!cpus_have_cap(ARM64_UNMAP_KERNEL_AT_EL0)) | |
| 1844 | + return; | |
| 1845 | + | |
| 1842 | 1846 | /* |
| 1843 | 1847 | * We don't need to rewrite the page-tables if either we've done |
| 1844 | 1848 | * it already or we have KASLR enabled and therefore have not |
| @@ -436,6 +436,10 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq, · 435 unmodified lines | ||
| 436 | 436 | if (ret) |
| 437 | 437 | goto out; |
| 438 | 438 | |
| 439 | + /* Silently exit if the vLPI is already mapped */ | |
| 440 | + if (irq->hw) | |
| 441 | + goto out; | |
| 442 | + | |
| 439 | 443 | /* |
| 440 | 444 | * Emit the mapping request. If it fails, the ITS probably |
| 441 | 445 | * isn't v4 compatible, so let's silently bail out. Holding |
| @@ -29,8 +29,8 @@ bool can_set_direct_map(void) · 28 unmodified lines | ||
| 29 | 29 | * |
| 30 | 30 | * KFENCE pool requires page-granular mapping if initialized late. |
| 31 | 31 | */ |
| 32 | − return (rodata_enabled && rodata_full) || debug_pagealloc_enabled() || | |
| 33 | − arm64_kfence_can_set_direct_map(); | |
| 32 | + return rodata_full || debug_pagealloc_enabled() || | |
| 33 | + arm64_kfence_can_set_direct_map(); | |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | static int change_page_range(pte_t *ptep, unsigned long addr, void *data) |
| @@ -105,8 +105,7 @@ static int change_memory_common(unsigned long addr, int numpages, · 68 unmodified lines | ||
| 105 | 105 | * If we are manipulating read-only permissions, apply the same |
| 106 | 106 | * change to the linear mapping of the pages that back this VM area. |
| 107 | 107 | */ |
| 108 | − if (rodata_enabled && | |
| 109 | − rodata_full && (pgprot_val(set_mask) == PTE_RDONLY || | |
| 108 | + if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY || | |
| 110 | 109 | pgprot_val(clear_mask) == PTE_RDONLY)) { |
| 111 | 110 | for (i = 0; i < area->nr_pages; i++) { |
| 112 | 111 | __change_memory_common((u64)page_address(area->pages[i]), |
| @@ -68,6 +68,7 @@ LDFLAGS_vmlinux += -static -n -nostdlib · 67 unmodified lines | ||
| 68 | 68 | ifdef CONFIG_AS_HAS_EXPLICIT_RELOCS |
| 69 | 69 | cflags-y += $(call cc-option,-mexplicit-relocs) |
| 70 | 70 | KBUILD_CFLAGS_KERNEL += $(call cc-option,-mdirect-extern-access) |
| 71 | +KBUILD_CFLAGS_KERNEL += $(call cc-option,-fdirect-access-external-data) | |
| 71 | 72 | KBUILD_AFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data) |
| 72 | 73 | KBUILD_CFLAGS_MODULE += $(call cc-option,-fno-direct-access-external-data) |
| 73 | 74 | KBUILD_AFLAGS_MODULE += $(call cc-option,-mno-relax) $(call cc-option,-Wa$(comma)-mno-relax) |
| @@ -82,7 +83,7 @@ endif · 8 unmodified lines | ||
| 82 | 83 | |
| 83 | 84 | ifeq ($(CONFIG_RELOCATABLE),y) |
| 84 | 85 | KBUILD_CFLAGS_KERNEL += -fPIE |
| 85 | −LDFLAGS_vmlinux += -static -pie --no-dynamic-linker -z notext | |
| 86 | +LDFLAGS_vmlinux += -static -pie --no-dynamic-linker -z notext $(call ld-option, --apply-dynamic-relocs) | |
| 86 | 87 | endif |
| 87 | 88 | |
| 88 | 89 | cflags-y += $(call cc-option, -mno-check-zero-division) |
| @@ -142,6 +143,8 @@ vdso-install-y += arch/loongarch/vdso/vdso.so.dbg · 53 unmodified lines | ||
| 142 | 143 | |
| 143 | 144 | all: $(notdir $(KBUILD_IMAGE)) |
| 144 | 145 | |
| 146 | +vmlinuz.efi: vmlinux.efi | |
| 147 | + | |
| 145 | 148 | vmlinux.elf vmlinux.efi vmlinuz.efi: vmlinux |
| 146 | 149 | $(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $(boot)/$@ |
| 147 | 150 | |
| @@ -609,8 +609,7 @@ · 608 unmodified lines | ||
| 609 | 609 | lu32i.d \reg, 0 |
| 610 | 610 | lu52i.d \reg, \reg, 0 |
| 611 | 611 | .pushsection ".la_abs", "aw", %progbits |
| 612 | − 768: | |
| 613 | − .dword 768b-766b | |
| 612 | + .dword 766b | |
| 614 | 613 | .dword \sym |
| 615 | 614 | .popsection |
| 616 | 615 | #endif |
| @@ -293,7 +293,7 @@ extern const char *__elf_platform; · 292 unmodified lines | ||
| 293 | 293 | #define ELF_PLAT_INIT(_r, load_addr) do { \ |
| 294 | 294 | _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0; \ |
| 295 | 295 | _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0; \ |
| 296 | − _r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0; \ | |
| 296 | + _r->regs[9] = _r->regs[10] /* syscall n */ = _r->regs[12] = 0; \ | |
| 297 | 297 | _r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0; \ |
| 298 | 298 | _r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0; \ |
| 299 | 299 | _r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0; \ |
| @@ -1098,12 +1098,11 @@ · 1097 unmodified lines | ||
| 1098 | 1098 | |
| 1099 | 1099 | static __always_inline u64 drdtime(void) |
| 1100 | 1100 | { |
| 1101 | − int rID = 0; | |
| 1102 | 1101 | u64 val = 0; |
| 1103 | 1102 | |
| 1104 | 1103 | __asm__ __volatile__( |
| 1105 | − "rdtime.d %0, %1 \n\t" | |
| 1106 | − : "=r"(val), "=r"(rID) | |
| 1104 | + "rdtime.d %0, $zero\n\t" | |
| 1105 | + : "=r"(val) | |
| 1107 | 1106 | : |
| 1108 | 1107 | ); |
| 1109 | 1108 | return val; |
| @@ -40,13 +40,13 @@ static __always_inline unsigned long __percpu_##op(void *ptr, \ · 39 unmodified lines | ||
| 40 | 40 | switch (size) { \ |
| 41 | 41 | case 4: \ |
| 42 | 42 | __asm__ __volatile__( \ |
| 43 | − "am"#asm_op".w" " %[ret], %[val], %[ptr] \n" \ | |
| 43 | + "am"#asm_op".w" " %[ret], %[val], %[ptr] \n" \ | |
| 44 | 44 | : [ret] "=&r" (ret), [ptr] "+ZB"(*(u32 *)ptr) \ |
| 45 | 45 | : [val] "r" (val)); \ |
| 46 | 46 | break; \ |
| 47 | 47 | case 8: \ |
| 48 | 48 | __asm__ __volatile__( \ |
| 49 | − "am"#asm_op".d" " %[ret], %[val], %[ptr] \n" \ | |
| 49 | + "am"#asm_op".d" " %[ret], %[val], %[ptr] \n" \ | |
| 50 | 50 | : [ret] "=&r" (ret), [ptr] "+ZB"(*(u64 *)ptr) \ |
| 51 | 51 | : [val] "r" (val)); \ |
| 52 | 52 | break; \ |
| @@ -63,7 +63,7 @@ PERCPU_OP(and, and, &) · 10 unmodified lines | ||
| 63 | 63 | PERCPU_OP(or, or, |) |
| 64 | 64 | #undef PERCPU_OP |
| 65 | 65 | |
| 66 | −static __always_inline unsigned long __percpu_read(void *ptr, int size) | |
| 66 | +static __always_inline unsigned long __percpu_read(void __percpu *ptr, int size) | |
| 67 | 67 | { |
| 68 | 68 | unsigned long ret; |
| 69 | 69 | |
| @@ -100,7 +100,7 @@ static __always_inline unsigned long __percpu_read(void *ptr, int size) · 30 unmodified lines | ||
| 100 | 100 | return ret; |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | −static __always_inline void __percpu_write(void *ptr, unsigned long val, int size) | |
| 103 | +static __always_inline void __percpu_write(void __percpu *ptr, unsigned long val, int size) | |
| 104 | 104 | { |
| 105 | 105 | switch (size) { |
| 106 | 106 | case 1: |
| @@ -132,8 +132,7 @@ static __always_inline void __percpu_write(void *ptr, unsigned long val, int siz · 25 unmodified lines | ||
| 132 | 132 | } |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | −static __always_inline unsigned long __percpu_xchg(void *ptr, unsigned long val, | |
| 136 | − int size) | |
| 135 | +static __always_inline unsigned long __percpu_xchg(void *ptr, unsigned long val, int size) | |
| 137 | 136 | { |
| 138 | 137 | switch (size) { |
| 139 | 138 | case 1: |
| @@ -25,7 +25,7 @@ extern void set_merr_handler(unsigned long offset, void *addr, unsigned long len · 24 unmodified lines | ||
| 25 | 25 | #ifdef CONFIG_RELOCATABLE |
| 26 | 26 | |
| 27 | 27 | struct rela_la_abs { |
| 28 | − long offset; | |
| 28 | + long pc; | |
| 29 | 29 | long symvalue; |
| 30 | 30 | }; |
| 31 | 31 | |
| @@ -52,7 +52,7 @@ static inline void __init relocate_absolute(long random_offset) · 51 unmodified lines | ||
| 52 | 52 | for (p = begin; (void *)p < end; p++) { |
| 53 | 53 | long v = p->symvalue; |
| 54 | 54 | uint32_t lu12iw, ori, lu32id, lu52id; |
| 55 | − union loongarch_instruction *insn = (void *)p - p->offset; | |
| 55 | + union loongarch_instruction *insn = (void *)p->pc; | |
| 56 | 56 | |
| 57 | 57 | lu12iw = (v >> 12) & 0xfffff; |
| 58 | 58 | ori = v & 0xfff; |
| @@ -102,6 +102,14 @@ static inline __init unsigned long get_random_boot(void) · 43 unmodified lines | ||
| 102 | 102 | return hash; |
| 103 | 103 | } |
| 104 | 104 | |
| 105 | +static int __init nokaslr(char *p) | |
| 106 | +{ | |
| 107 | + pr_info("KASLR is disabled.\n"); | |
| 108 | + | |
| 109 | + return 0; /* Print a notice and silence the boot warning */ | |
| 110 | +} | |
| 111 | +early_param("nokaslr", nokaslr); | |
| 112 | + | |
| 105 | 113 | static inline __init bool kaslr_disabled(void) |
| 106 | 114 | { |
| 107 | 115 | char *str; |
| @@ -32,7 +32,7 @@ void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, · 31 unmodified lines | ||
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | for (unwind_start(&state, task, regs); |
| 35 | − !unwind_done(&state) && !unwind_error(&state); unwind_next_frame(&state)) { | |
| 35 | + !unwind_done(&state); unwind_next_frame(&state)) { | |
| 36 | 36 | addr = unwind_get_return_address(&state); |
| 37 | 37 | if (!addr || !consume_entry(cookie, addr)) |
| 38 | 38 | break; |
| @@ -58,14 +58,16 @@ static int constant_set_state_oneshot(struct clock_event_device *evt) · 57 unmodified lines | ||
| 58 | 58 | return 0; |
| 59 | 59 | } |
| 60 | 60 | |
| 61 | −static int constant_set_state_oneshot_stopped(struct clock_event_device *evt) | |
| 61 | +static int constant_set_state_periodic(struct clock_event_device *evt) | |
| 62 | 62 | { |
| 63 | + unsigned long period; | |
| 63 | 64 | unsigned long timer_config; |
| 64 | 65 | |
| 65 | 66 | raw_spin_lock(&state_lock); |
| 66 | 67 | |
| 67 | − timer_config = csr_read64(LOONGARCH_CSR_TCFG); | |
| 68 | − timer_config &= ~CSR_TCFG_EN; | |
| 68 | + period = const_clock_freq / HZ; | |
| 69 | + timer_config = period & CSR_TCFG_VAL; | |
| 70 | + timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN); | |
| 69 | 71 | csr_write64(timer_config, LOONGARCH_CSR_TCFG); |
| 70 | 72 | |
| 71 | 73 | raw_spin_unlock(&state_lock); |
| @@ -73,16 +75,14 @@ static int constant_set_state_oneshot_stopped(struct clock_event_device *evt) · 1 unmodified line | ||
| 73 | 75 | return 0; |
| 74 | 76 | } |
| 75 | 77 | |
| 76 | −static int constant_set_state_periodic(struct clock_event_device *evt) | |
| 78 | +static int constant_set_state_shutdown(struct clock_event_device *evt) | |
| 77 | 79 | { |
| 78 | − unsigned long period; | |
| 79 | 80 | unsigned long timer_config; |
| 80 | 81 | |
| 81 | 82 | raw_spin_lock(&state_lock); |
| 82 | 83 | |
| 83 | − period = const_clock_freq / HZ; | |
| 84 | − timer_config = period & CSR_TCFG_VAL; | |
| 85 | − timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN); | |
| 84 | + timer_config = csr_read64(LOONGARCH_CSR_TCFG); | |
| 85 | + timer_config &= ~CSR_TCFG_EN; | |
| 86 | 86 | csr_write64(timer_config, LOONGARCH_CSR_TCFG); |
| 87 | 87 | |
| 88 | 88 | raw_spin_unlock(&state_lock); |
| @@ -90,11 +90,6 @@ static int constant_set_state_periodic(struct clock_event_device *evt) · 1 unmodified line | ||
| 90 | 90 | return 0; |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | −static int constant_set_state_shutdown(struct clock_event_device *evt) | |
| 94 | −{ | |
| 95 | − return 0; | |
| 96 | −} | |
| 97 | − | |
| 98 | 93 | static int constant_timer_next_event(unsigned long delta, struct clock_event_device *evt) |
| 99 | 94 | { |
| 100 | 95 | unsigned long timer_config; |
| @@ -161,7 +156,7 @@ int constant_clockevent_init(void) · 60 unmodified lines | ||
| 161 | 156 | cd->rating = 320; |
| 162 | 157 | cd->cpumask = cpumask_of(cpu); |
| 163 | 158 | cd->set_state_oneshot = constant_set_state_oneshot; |
| 164 | − cd->set_state_oneshot_stopped = constant_set_state_oneshot_stopped; | |
| 159 | + cd->set_state_oneshot_stopped = constant_set_state_shutdown; | |
| 165 | 160 | cd->set_state_periodic = constant_set_state_periodic; |
| 166 | 161 | cd->set_state_shutdown = constant_set_state_shutdown; |
| 167 | 162 | cd->set_next_event = constant_timer_next_event; |
| @@ -28,6 +28,5 @@ bool default_next_frame(struct unwind_state *state) · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | } while (!get_stack_info(state->sp, state->task, info)); |
| 30 | 30 | |
| 31 | − state->error = true; | |
| 32 | 31 | return false; |
| 33 | 32 | } |
| @@ -227,7 +227,7 @@ static bool next_frame(struct unwind_state *state) · 226 unmodified lines | ||
| 227 | 227 | } while (!get_stack_info(state->sp, state->task, info)); |
| 228 | 228 | |
| 229 | 229 | out: |
| 230 | − state->error = true; | |
| 230 | + state->stack_info.type = STACK_TYPE_UNKNOWN; | |
| 231 | 231 | return false; |
| 232 | 232 | } |
| 233 | 233 | |
| @@ -13,13 +13,13 @@ struct page *dmw_virt_to_page(unsigned long kaddr) · 12 unmodified lines | ||
| 13 | 13 | { |
| 14 | 14 | return pfn_to_page(virt_to_pfn(kaddr)); |
| 15 | 15 | } |
| 16 | −EXPORT_SYMBOL_GPL(dmw_virt_to_page); | |
| 16 | +EXPORT_SYMBOL(dmw_virt_to_page); | |
| 17 | 17 | |
| 18 | 18 | struct page *tlb_virt_to_page(unsigned long kaddr) |
| 19 | 19 | { |
| 20 | 20 | return pfn_to_page(pte_pfn(*virt_to_kpte(kaddr))); |
| 21 | 21 | } |
| 22 | −EXPORT_SYMBOL_GPL(tlb_virt_to_page); | |
| 22 | +EXPORT_SYMBOL(tlb_virt_to_page); | |
| 23 | 23 | |
| 24 | 24 | pgd_t *pgd_alloc(struct mm_struct *mm) |
| 25 | 25 | { |
| @@ -480,10 +480,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext · 479 unmodified lines | ||
| 480 | 480 | case 8: |
| 481 | 481 | move_reg(ctx, t1, src); |
| 482 | 482 | emit_insn(ctx, extwb, dst, t1); |
| 483 | + emit_zext_32(ctx, dst, is32); | |
| 483 | 484 | break; |
| 484 | 485 | case 16: |
| 485 | 486 | move_reg(ctx, t1, src); |
| 486 | 487 | emit_insn(ctx, extwh, dst, t1); |
| 488 | + emit_zext_32(ctx, dst, is32); | |
| 487 | 489 | break; |
| 488 | 490 | case 32: |
| 489 | 491 | emit_insn(ctx, addw, dst, src, LOONGARCH_GPR_ZERO); |
| @@ -772,8 +774,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext · 282 unmodified lines | ||
| 772 | 774 | break; |
| 773 | 775 | case 32: |
| 774 | 776 | emit_insn(ctx, revb2w, dst, dst); |
| 775 | − /* zero-extend 32 bits into 64 bits */ | |
| 776 | − emit_zext_32(ctx, dst, is32); | |
| 777 | + /* clear the upper 32 bits */ | |
| 778 | + emit_zext_32(ctx, dst, true); | |
| 777 | 779 | break; |
| 778 | 780 | case 64: |
| 779 | 781 | emit_insn(ctx, revbd, dst, dst); |
| @@ -911,8 +913,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext · 131 unmodified lines | ||
| 911 | 913 | |
| 912 | 914 | /* function return */ |
| 913 | 915 | case BPF_JMP | BPF_EXIT: |
| 914 | − emit_sext_32(ctx, regmap[BPF_REG_0], true); | |
| 915 | − | |
| 916 | 916 | if (i == ctx->prog->len - 1) |
| 917 | 917 | break; |
| 918 | 918 | |
| @@ -988,14 +988,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext · 69 unmodified lines | ||
| 988 | 988 | } |
| 989 | 989 | break; |
| 990 | 990 | case BPF_DW: |
| 991 | − if (is_signed_imm12(off)) { | |
| 992 | − emit_insn(ctx, ldd, dst, src, off); | |
| 993 | − } else if (is_signed_imm14(off)) { | |
| 994 | − emit_insn(ctx, ldptrd, dst, src, off); | |
| 995 | − } else { | |
| 996 | − move_imm(ctx, t1, off, is32); | |
| 997 | − emit_insn(ctx, ldxd, dst, src, t1); | |
| 998 | − } | |
| 991 | + move_imm(ctx, t1, off, is32); | |
| 992 | + emit_insn(ctx, ldxd, dst, src, t1); | |
| 999 | 993 | break; |
| 1000 | 994 | } |
| 1001 | 995 | |
| @@ -460,6 +460,7 @@ config MACH_LOONGSON2EF · 459 unmodified lines | ||
| 460 | 460 | |
| 461 | 461 | config MACH_LOONGSON64 |
| 462 | 462 | bool "Loongson 64-bit family of machines" |
| 463 | + select ARCH_DMA_DEFAULT_COHERENT | |
| 463 | 464 | select ARCH_SPARSEMEM_ENABLE |
| 464 | 465 | select ARCH_MIGHT_HAVE_PC_PARPORT |
| 465 | 466 | select ARCH_MIGHT_HAVE_PC_SERIO |
| @@ -1251,6 +1252,7 @@ config CPU_LOONGSON64 · 785 unmodified lines | ||
| 1251 | 1252 | select CPU_SUPPORTS_MSA |
| 1252 | 1253 | select CPU_DIEI_BROKEN if !LOONGSON3_ENHANCEMENT |
| 1253 | 1254 | select CPU_MIPSR2_IRQ_VI |
| 1255 | + select DMA_NONCOHERENT | |
| 1254 | 1256 | select WEAK_ORDERING |
| 1255 | 1257 | select WEAK_REORDERING_BEYOND_LLSC |
| 1256 | 1258 | select MIPS_ASID_BITS_VARIABLE |
| @@ -14,7 +14,11 @@ · 13 unmodified lines | ||
| 14 | 14 | #define ADAPTER_ROM 8 |
| 15 | 15 | #define ACPI_TABLE 9 |
| 16 | 16 | #define SMBIOS_TABLE 10 |
| 17 | −#define MAX_MEMORY_TYPE 11 | |
| 17 | +#define UMA_VIDEO_RAM 11 | |
| 18 | +#define VUMA_VIDEO_RAM 12 | |
| 19 | +#define MAX_MEMORY_TYPE 13 | |
| 20 | + | |
| 21 | +#define MEM_SIZE_IS_IN_BYTES (1 << 31) | |
| 18 | 22 | |
| 19 | 23 | #define LOONGSON3_BOOT_MEM_MAP_MAX 128 |
| 20 | 24 | struct efi_memory_map_loongson { |
| @@ -117,7 +121,8 @@ struct irq_source_routing_table { · 96 unmodified lines | ||
| 117 | 121 | u64 pci_io_start_addr; |
| 118 | 122 | u64 pci_io_end_addr; |
| 119 | 123 | u64 pci_config_addr; |
| 120 | − u32 dma_mask_bits; | |
| 124 | + u16 dma_mask_bits; | |
| 125 | + u16 dma_noncoherent; | |
| 121 | 126 | } __packed; |
| 122 | 127 | |
| 123 | 128 | struct interface_info { |
| @@ -121,6 +121,19 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) · 120 unmodified lines | ||
| 121 | 121 | /* Put the stack after the struct pt_regs. */ |
| 122 | 122 | childksp = (unsigned long) childregs; |
| 123 | 123 | p->thread.cp0_status = (read_c0_status() & ~(ST0_CU2|ST0_CU1)) | ST0_KERNEL_CUMASK; |
| 124 | + | |
| 125 | + /* | |
| 126 | + * New tasks lose permission to use the fpu. This accelerates context | |
| 127 | + * switching for most programs since they don't use the fpu. | |
| 128 | + */ | |
| 129 | + clear_tsk_thread_flag(p, TIF_USEDFPU); | |
| 130 | + clear_tsk_thread_flag(p, TIF_USEDMSA); | |
| 131 | + clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE); | |
| 132 | + | |
| 133 | +#ifdef CONFIG_MIPS_MT_FPAFF | |
| 134 | + clear_tsk_thread_flag(p, TIF_FPUBOUND); | |
| 135 | +#endif /* CONFIG_MIPS_MT_FPAFF */ | |
| 136 | + | |
| 124 | 137 | if (unlikely(args->fn)) { |
| 125 | 138 | /* kernel thread */ |
| 126 | 139 | unsigned long status = p->thread.cp0_status; |
| @@ -149,20 +162,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) · 22 unmodified lines | ||
| 149 | 162 | p->thread.reg29 = (unsigned long) childregs; |
| 150 | 163 | p->thread.reg31 = (unsigned long) ret_from_fork; |
| 151 | 164 | |
| 152 | − /* | |
| 153 | − * New tasks lose permission to use the fpu. This accelerates context | |
| 154 | − * switching for most programs since they don't use the fpu. | |
| 155 | − */ | |
| 156 | 165 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); |
| 157 | 166 | |
| 158 | − clear_tsk_thread_flag(p, TIF_USEDFPU); | |
| 159 | − clear_tsk_thread_flag(p, TIF_USEDMSA); | |
| 160 | − clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE); | |
| 161 | − | |
| 162 | −#ifdef CONFIG_MIPS_MT_FPAFF | |
| 163 | − clear_tsk_thread_flag(p, TIF_FPUBOUND); | |
| 164 | −#endif /* CONFIG_MIPS_MT_FPAFF */ | |
| 165 | − | |
| 166 | 167 | #ifdef CONFIG_MIPS_FP_SUPPORT |
| 167 | 168 | atomic_set(&p->thread.bd_emu_frame, BD_EMUFRAME_NONE); |
| 168 | 169 | #endif |
| @@ -351,10 +351,11 @@ early_initcall(mips_smp_ipi_init); · 350 unmodified lines | ||
| 351 | 351 | */ |
| 352 | 352 | asmlinkage void start_secondary(void) |
| 353 | 353 | { |
| 354 | − unsigned int cpu; | |
| 354 | + unsigned int cpu = raw_smp_processor_id(); | |
| 355 | 355 | |
| 356 | 356 | cpu_probe(); |
| 357 | 357 | per_cpu_trap_init(false); |
| 358 | + rcutree_report_cpu_starting(cpu); | |
| 358 | 359 | mips_clockevent_init(); |
| 359 | 360 | mp_ops->init_secondary(); |
| 360 | 361 | cpu_report(); |
| @@ -366,7 +367,6 @@ asmlinkage void start_secondary(void) · 5 unmodified lines | ||
| 366 | 367 | */ |
| 367 | 368 | |
| 368 | 369 | calibrate_delay(); |
| 369 | − cpu = smp_processor_id(); | |
| 370 | 370 | cpu_data[cpu].udelay_val = loops_per_jiffy; |
| 371 | 371 | |
| 372 | 372 | set_cpu_sibling_map(cpu); |
| @@ -13,6 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | * Copyright (C) 2009 Lemote Inc. |
| 14 | 14 | * Author: Wu Zhangjin, wuzhangjin@gmail.com |
| 15 | 15 | */ |
| 16 | + | |
| 17 | +#include <linux/dma-map-ops.h> | |
| 16 | 18 | #include <linux/export.h> |
| 17 | 19 | #include <linux/pci_ids.h> |
| 18 | 20 | #include <asm/bootinfo.h> |
| @@ -147,8 +149,14 @@ void __init prom_lefi_init_env(void) · 128 unmodified lines | ||
| 147 | 149 | |
| 148 | 150 | loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits; |
| 149 | 151 | if (loongson_sysconf.dma_mask_bits < 32 || |
| 150 | − loongson_sysconf.dma_mask_bits > 64) | |
| 152 | + loongson_sysconf.dma_mask_bits > 64) { | |
| 151 | 153 | loongson_sysconf.dma_mask_bits = 32; |
| 154 | + dma_default_coherent = true; | |
| 155 | + } else { | |
| 156 | + dma_default_coherent = !eirq_source->dma_noncoherent; | |
| 157 | + } | |
| 158 | + | |
| 159 | + pr_info("Firmware: Coherent DMA: %s\n", dma_default_coherent ? "on" : "off"); | |
| 152 | 160 | |
| 153 | 161 | loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm; |
| 154 | 162 | loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; |
| @@ -49,8 +49,7 @@ void virtual_early_config(void) · 48 unmodified lines | ||
| 49 | 49 | void __init szmem(unsigned int node) |
| 50 | 50 | { |
| 51 | 51 | u32 i, mem_type; |
| 52 | − static unsigned long num_physpages; | |
| 53 | − u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size; | |
| 52 | + phys_addr_t node_id, mem_start, mem_size; | |
| 54 | 53 | |
| 55 | 54 | /* Otherwise come from DTB */ |
| 56 | 55 | if (loongson_sysconf.fw_interface != LOONGSON_LEFI) |
| @@ -64,30 +63,46 @@ void __init szmem(unsigned int node) · 7 unmodified lines | ||
| 64 | 63 | |
| 65 | 64 | mem_type = loongson_memmap->map[i].mem_type; |
| 66 | 65 | mem_size = loongson_memmap->map[i].mem_size; |
| 67 | − mem_start = loongson_memmap->map[i].mem_start; | |
| 66 | + | |
| 67 | + /* Memory size comes in MB if MEM_SIZE_IS_IN_BYTES not set */ | |
| 68 | + if (mem_size & MEM_SIZE_IS_IN_BYTES) | |
| 69 | + mem_size &= ~MEM_SIZE_IS_IN_BYTES; | |
| 70 | + else | |
| 71 | + mem_size = mem_size << 20; | |
| 72 | + | |
| 73 | + mem_start = (node_id << 44) | loongson_memmap->map[i].mem_start; | |
| 68 | 74 | |
| 69 | 75 | switch (mem_type) { |
| 70 | 76 | case SYSTEM_RAM_LOW: |
| 71 | 77 | case SYSTEM_RAM_HIGH: |
| 72 | − start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; | |
| 73 | − node_psize = (mem_size << 20) >> PAGE_SHIFT; | |
| 74 | − end_pfn = start_pfn + node_psize; | |
| 75 | − num_physpages += node_psize; | |
| 76 | − pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", | |
| 77 | − (u32)node_id, mem_type, mem_start, mem_size); | |
| 78 | − pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", | |
| 79 | − start_pfn, end_pfn, num_physpages); | |
| 80 | − memblock_add_node(PFN_PHYS(start_pfn), | |
| 81 | − PFN_PHYS(node_psize), node, | |
| 78 | + case UMA_VIDEO_RAM: | |
| 79 | + pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes usable\n", | |
| 80 | + (u32)node_id, mem_type, &mem_start, &mem_size); | |
| 81 | + memblock_add_node(mem_start, mem_size, node, | |
| 82 | 82 | MEMBLOCK_NONE); |
| 83 | 83 | break; |
| 84 | 84 | case SYSTEM_RAM_RESERVED: |
| 85 | − pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", | |
| 86 | − (u32)node_id, mem_type, mem_start, mem_size); | |
| 87 | − memblock_reserve(((node_id << 44) + mem_start), mem_size << 20); | |
| 85 | + case VIDEO_ROM: | |
| 86 | + case ADAPTER_ROM: | |
| 87 | + case ACPI_TABLE: | |
| 88 | + case SMBIOS_TABLE: | |
| 89 | + pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes reserved\n", | |
| 90 | + (u32)node_id, mem_type, &mem_start, &mem_size); | |
| 91 | + memblock_reserve(mem_start, mem_size); | |
| 92 | + break; | |
| 93 | + /* We should not reserve VUMA_VIDEO_RAM as it overlaps with MMIO */ | |
| 94 | + case VUMA_VIDEO_RAM: | |
| 95 | + default: | |
| 96 | + pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes unhandled\n", | |
| 97 | + (u32)node_id, mem_type, &mem_start, &mem_size); | |
| 88 | 98 | break; |
| 89 | 99 | } |
| 90 | 100 | } |
| 101 | + | |
| 102 | + /* Reserve vgabios if it comes from firmware */ | |
| 103 | + if (loongson_sysconf.vgabios_addr) | |
| 104 | + memblock_reserve(virt_to_phys((void *)loongson_sysconf.vgabios_addr), | |
| 105 | + SZ_256K); | |
| 91 | 106 | } |
| 92 | 107 | |
| 93 | 108 | #ifndef CONFIG_NUMA |
| @@ -115,9 +115,12 @@ config ARCH_HAS_ILOG2_U64 · 114 unmodified lines | ||
| 115 | 115 | default n |
| 116 | 116 | |
| 117 | 117 | config GENERIC_BUG |
| 118 | − bool | |
| 119 | − default y | |
| 118 | + def_bool y | |
| 120 | 119 | depends on BUG |
| 120 | + select GENERIC_BUG_RELATIVE_POINTERS if 64BIT | |
| 121 | + | |
| 122 | +config GENERIC_BUG_RELATIVE_POINTERS | |
| 123 | + bool | |
| 121 | 124 | |
| 122 | 125 | config GENERIC_HWEIGHT |
| 123 | 126 | bool |
| @@ -140,11 +143,11 @@ config ARCH_MMAP_RND_COMPAT_BITS_MIN · 16 unmodified lines | ||
| 140 | 143 | default 8 |
| 141 | 144 | |
| 142 | 145 | config ARCH_MMAP_RND_BITS_MAX |
| 143 | − default 24 if 64BIT | |
| 144 | − default 17 | |
| 146 | + default 18 if 64BIT | |
| 147 | + default 13 | |
| 145 | 148 | |
| 146 | 149 | config ARCH_MMAP_RND_COMPAT_BITS_MAX |
| 147 | − default 17 | |
| 150 | + default 13 | |
| 148 | 151 | |
| 149 | 152 | # unless you want to implement ACPI on PA-RISC ... ;-) |
| 150 | 153 | config PM |
| @@ -34,7 +34,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end, · 33 unmodified lines | ||
| 34 | 34 | |
| 35 | 35 | /* Alternative SMP implementation. */ |
| 36 | 36 | #define ALTERNATIVE(cond, replacement) "!0:" \ |
| 37 | − ".section .altinstructions, \"aw\" !" \ | |
| 37 | + ".section .altinstructions, \"a\" !" \ | |
| 38 | + ".align 4 !" \ | |
| 38 | 39 | ".word (0b-4-.) !" \ |
| 39 | 40 | ".hword 1, " __stringify(cond) " !" \ |
| 40 | 41 | ".word " __stringify(replacement) " !" \ |
| @@ -44,7 +45,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end, · 3 unmodified lines | ||
| 44 | 45 | |
| 45 | 46 | /* to replace one single instructions by a new instruction */ |
| 46 | 47 | #define ALTERNATIVE(from, to, cond, replacement)\ |
| 47 | − .section .altinstructions, "aw" ! \ | |
| 48 | + .section .altinstructions, "a" ! \ | |
| 49 | + .align 4 ! \ | |
| 48 | 50 | .word (from - .) ! \ |
| 49 | 51 | .hword (to - from)/4, cond ! \ |
| 50 | 52 | .word replacement ! \ |
| @@ -52,7 +54,8 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end, · 1 unmodified line | ||
| 52 | 54 | |
| 53 | 55 | /* to replace multiple instructions by new code */ |
| 54 | 56 | #define ALTERNATIVE_CODE(from, num_instructions, cond, new_instr_ptr)\ |
| 55 | − .section .altinstructions, "aw" ! \ | |
| 57 | + .section .altinstructions, "a" ! \ | |
| 58 | + .align 4 ! \ | |
| 56 | 59 | .word (from - .) ! \ |
| 57 | 60 | .hword -num_instructions, cond ! \ |
| 58 | 61 | .word (new_instr_ptr - .) ! \ |
| @@ -574,6 +574,7 @@ · 573 unmodified lines | ||
| 574 | 574 | */ |
| 575 | 575 | #define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr) \ |
| 576 | 576 | .section __ex_table,"aw" ! \ |
| 577 | + .align 4 ! \ | |
| 577 | 578 | .word (fault_addr - .), (except_addr - .) ! \ |
| 578 | 579 | .previous |
| 579 | 580 | |
| @@ -17,24 +17,27 @@ · 16 unmodified lines | ||
| 17 | 17 | #define PARISC_BUG_BREAK_ASM "break 0x1f, 0x1fff" |
| 18 | 18 | #define PARISC_BUG_BREAK_INSN 0x03ffe01f /* PARISC_BUG_BREAK_ASM */ |
| 19 | 19 | |
| 20 | −#if defined(CONFIG_64BIT) | |
| 21 | −#define ASM_WORD_INSN ".dword\t" | |
| 20 | +#ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS | |
| 21 | +# define __BUG_REL(val) ".word " __stringify(val) " - ." | |
| 22 | 22 | #else |
| 23 | −#define ASM_WORD_INSN ".word\t" | |
| 23 | +# define __BUG_REL(val) ".word " __stringify(val) | |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | + | |
| 26 | 27 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
| 27 | 28 | #define BUG() \ |
| 28 | 29 | do { \ |
| 29 | 30 | asm volatile("\n" \ |
| 30 | 31 | "1:\t" PARISC_BUG_BREAK_ASM "\n" \ |
| 31 | − "\t.pushsection __bug_table,\"aw\"\n" \ | |
| 32 | − "2:\t" ASM_WORD_INSN "1b, %c0\n" \ | |
| 33 | − "\t.short %c1, %c2\n" \ | |
| 34 | − "\t.org 2b+%c3\n" \ | |
| 32 | + "\t.pushsection __bug_table,\"a\"\n" \ | |
| 33 | + "\t.align 4\n" \ | |
| 34 | + "2:\t" __BUG_REL(1b) "\n" \ | |
| 35 | + "\t" __BUG_REL(%c0) "\n" \ | |
| 36 | + "\t.short %1, %2\n" \ | |
| 37 | + "\t.blockz %3-2*4-2*2\n" \ | |
| 35 | 38 | "\t.popsection" \ |
| 36 | 39 | : : "i" (__FILE__), "i" (__LINE__), \ |
| 37 | − "i" (0), "i" (sizeof(struct bug_entry)) ); \ | |
| 40 | + "i" (0), "i" (sizeof(struct bug_entry)) ); \ | |
| 38 | 41 | unreachable(); \ |
| 39 | 42 | } while(0) |
| 40 | 43 | |
| @@ -51,10 +54,12 @@ · 10 unmodified lines | ||
| 51 | 54 | do { \ |
| 52 | 55 | asm volatile("\n" \ |
| 53 | 56 | "1:\t" PARISC_BUG_BREAK_ASM "\n" \ |
| 54 | − "\t.pushsection __bug_table,\"aw\"\n" \ | |
| 55 | − "2:\t" ASM_WORD_INSN "1b, %c0\n" \ | |
| 56 | − "\t.short %c1, %c2\n" \ | |
| 57 | − "\t.org 2b+%c3\n" \ | |
| 57 | + "\t.pushsection __bug_table,\"a\"\n" \ | |
| 58 | + "\t.align 4\n" \ | |
| 59 | + "2:\t" __BUG_REL(1b) "\n" \ | |
| 60 | + "\t" __BUG_REL(%c0) "\n" \ | |
| 61 | + "\t.short %1, %2\n" \ | |
| 62 | + "\t.blockz %3-2*4-2*2\n" \ | |
| 58 | 63 | "\t.popsection" \ |
| 59 | 64 | : : "i" (__FILE__), "i" (__LINE__), \ |
| 60 | 65 | "i" (BUGFLAG_WARNING|(flags)), \ |
| @@ -65,10 +70,11 @@ · 4 unmodified lines | ||
| 65 | 70 | do { \ |
| 66 | 71 | asm volatile("\n" \ |
| 67 | 72 | "1:\t" PARISC_BUG_BREAK_ASM "\n" \ |
| 68 | − "\t.pushsection __bug_table,\"aw\"\n" \ | |
| 69 | − "2:\t" ASM_WORD_INSN "1b\n" \ | |
| 70 | − "\t.short %c0\n" \ | |
| 71 | − "\t.org 2b+%c1\n" \ | |
| 73 | + "\t.pushsection __bug_table,\"a\"\n" \ | |
| 74 | + "\t.align 4\n" \ | |
| 75 | + "2:\t" __BUG_REL(1b) "\n" \ | |
| 76 | + "\t.short %0\n" \ | |
| 77 | + "\t.blockz %1-4-2\n" \ | |
| 72 | 78 | "\t.popsection" \ |
| 73 | 79 | : : "i" (BUGFLAG_WARNING|(flags)), \ |
| 74 | 80 | "i" (sizeof(struct bug_entry)) ); \ |
| @@ -349,15 +349,7 @@ struct pt_regs; /* forward declaration... */ · 348 unmodified lines | ||
| 349 | 349 | |
| 350 | 350 | #define ELF_HWCAP 0 |
| 351 | 351 | |
| 352 | −/* Masks for stack and mmap randomization */ | |
| 353 | −#define BRK_RND_MASK (is_32bit_task() ? 0x07ffUL : 0x3ffffUL) | |
| 354 | −#define MMAP_RND_MASK (is_32bit_task() ? 0x1fffUL : 0x3ffffUL) | |
| 355 | −#define STACK_RND_MASK MMAP_RND_MASK | |
| 356 | − | |
| 357 | −struct mm_struct; | |
| 358 | −extern unsigned long arch_randomize_brk(struct mm_struct *); | |
| 359 | −#define arch_randomize_brk arch_randomize_brk | |
| 360 | − | |
| 352 | +#define STACK_RND_MASK 0x7ff /* 8MB of VA */ | |
| 361 | 353 | |
| 362 | 354 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 |
| 363 | 355 | struct linux_binprm; |
| @@ -15,10 +15,12 @@ static __always_inline bool arch_static_branch(struct static_key *key, bool bran · 14 unmodified lines | ||
| 15 | 15 | asm_volatile_goto("1:\n\t" |
| 16 | 16 | "nop\n\t" |
| 17 | 17 | ".pushsection __jump_table, \"aw\"\n\t" |
| 18 | + ".align %1\n\t" | |
| 18 | 19 | ".word 1b - ., %l[l_yes] - .\n\t" |
| 19 | 20 | __stringify(ASM_ULONG_INSN) " %c0 - .\n\t" |
| 20 | 21 | ".popsection\n\t" |
| 21 | − : : "i" (&((char *)key)[branch]) : : l_yes); | |
| 22 | + : : "i" (&((char *)key)[branch]), "i" (sizeof(long)) | |
| 23 | + : : l_yes); | |
| 22 | 24 | |
| 23 | 25 | return false; |
| 24 | 26 | l_yes: |
| @@ -30,10 +32,12 @@ static __always_inline bool arch_static_branch_jump(struct static_key *key, bool · 5 unmodified lines | ||
| 30 | 32 | asm_volatile_goto("1:\n\t" |
| 31 | 33 | "b,n %l[l_yes]\n\t" |
| 32 | 34 | ".pushsection __jump_table, \"aw\"\n\t" |
| 35 | + ".align %1\n\t" | |
| 33 | 36 | ".word 1b - ., %l[l_yes] - .\n\t" |
| 34 | 37 | __stringify(ASM_ULONG_INSN) " %c0 - .\n\t" |
| 35 | 38 | ".popsection\n\t" |
| 36 | − : : "i" (&((char *)key)[branch]) : : l_yes); | |
| 39 | + : : "i" (&((char *)key)[branch]), "i" (sizeof(long)) | |
| 40 | + : : l_yes); | |
| 37 | 41 | |
| 38 | 42 | return false; |
| 39 | 43 | l_yes: |
| @@ -55,7 +55,7 @@ · 54 unmodified lines | ||
| 55 | 55 | }) |
| 56 | 56 | |
| 57 | 57 | #ifdef CONFIG_SMP |
| 58 | −# define __lock_aligned __section(".data..lock_aligned") | |
| 58 | +# define __lock_aligned __section(".data..lock_aligned") __aligned(16) | |
| 59 | 59 | #endif |
| 60 | 60 | |
| 61 | 61 | #endif /* __PARISC_LDCW_H */ |
| @@ -47,6 +47,8 @@ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | #ifndef __ASSEMBLY__ |
| 49 | 49 | |
| 50 | +struct rlimit; | |
| 51 | +unsigned long mmap_upper_limit(struct rlimit *rlim_stack); | |
| 50 | 52 | unsigned long calc_max_stack_size(unsigned long stack_max); |
| 51 | 53 | |
| 52 | 54 | /* |
| @@ -41,6 +41,7 @@ struct exception_table_entry { · 40 unmodified lines | ||
| 41 | 41 | |
| 42 | 42 | #define ASM_EXCEPTIONTABLE_ENTRY( fault_addr, except_addr )\ |
| 43 | 43 | ".section __ex_table,\"aw\"\n" \ |
| 44 | + ".align 4\n" \ | |
| 44 | 45 | ".word (" #fault_addr " - .), (" #except_addr " - .)\n\t" \ |
| 45 | 46 | ".previous\n" |
| 46 | 47 | |
| @@ -75,7 +75,6 @@ · 74 unmodified lines | ||
| 75 | 75 | |
| 76 | 76 | /* We now return you to your regularly scheduled HPUX. */ |
| 77 | 77 | |
| 78 | −#define ENOSYM 215 /* symbol does not exist in executable */ | |
| 79 | 78 | #define ENOTSOCK 216 /* Socket operation on non-socket */ |
| 80 | 79 | #define EDESTADDRREQ 217 /* Destination address required */ |
| 81 | 80 | #define EMSGSIZE 218 /* Message too long */ |
| @@ -101,7 +100,6 @@ · 19 unmodified lines | ||
| 101 | 100 | #define ETIMEDOUT 238 /* Connection timed out */ |
| 102 | 101 | #define ECONNREFUSED 239 /* Connection refused */ |
| 103 | 102 | #define EREFUSED ECONNREFUSED /* for HP's NFS apparently */ |
| 104 | −#define EREMOTERELEASE 240 /* Remote peer released connection */ | |
| 105 | 103 | #define EHOSTDOWN 241 /* Host is down */ |
| 106 | 104 | #define EHOSTUNREACH 242 /* No route to host */ |
| 107 | 105 | |
| @@ -383,7 +383,7 @@ show_cpuinfo (struct seq_file *m, void *v) · 382 unmodified lines | ||
| 383 | 383 | char cpu_name[60], *p; |
| 384 | 384 | |
| 385 | 385 | /* strip PA path from CPU name to not confuse lscpu */ |
| 386 | − strlcpy(cpu_name, per_cpu(cpu_data, 0).dev->name, sizeof(cpu_name)); | |
| 386 | + strscpy(cpu_name, per_cpu(cpu_data, 0).dev->name, sizeof(cpu_name)); | |
| 387 | 387 | p = strrchr(cpu_name, '['); |
| 388 | 388 | if (p) |
| 389 | 389 | *(--p) = 0; |
| @@ -77,7 +77,7 @@ unsigned long calc_max_stack_size(unsigned long stack_max) · 76 unmodified lines | ||
| 77 | 77 | * indicating that "current" should be used instead of a passed-in |
| 78 | 78 | * value from the exec bprm as done with arch_pick_mmap_layout(). |
| 79 | 79 | */ |
| 80 | −static unsigned long mmap_upper_limit(struct rlimit *rlim_stack) | |
| 80 | +unsigned long mmap_upper_limit(struct rlimit *rlim_stack) | |
| 81 | 81 | { |
| 82 | 82 | unsigned long stack_base; |
| 83 | 83 | |
| @@ -130,6 +130,7 @@ SECTIONS · 129 unmodified lines | ||
| 130 | 130 | RO_DATA(8) |
| 131 | 131 | |
| 132 | 132 | /* unwind info */ |
| 133 | + . = ALIGN(4); | |
| 133 | 134 | .PARISC.unwind : { |
| 134 | 135 | __start___unwind = .; |
| 135 | 136 | *(.PARISC.unwind) |
| @@ -23,6 +23,15 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <asm/feature-fixups.h> |
| 24 | 24 | |
| 25 | 25 | #ifdef CONFIG_VSX |
| 26 | +#define __REST_1FPVSR(n,c,base) \ | |
| 27 | +BEGIN_FTR_SECTION \ | |
| 28 | + b 2f; \ | |
| 29 | +END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ | |
| 30 | + REST_FPR(n,base); \ | |
| 31 | + b 3f; \ | |
| 32 | +2: REST_VSR(n,c,base); \ | |
| 33 | +3: | |
| 34 | + | |
| 26 | 35 | #define __REST_32FPVSRS(n,c,base) \ |
| 27 | 36 | BEGIN_FTR_SECTION \ |
| 28 | 37 | b 2f; \ |
| @@ -41,9 +50,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX); \ · 12 unmodified lines | ||
| 41 | 50 | 2: SAVE_32VSRS(n,c,base); \ |
| 42 | 51 | 3: |
| 43 | 52 | #else |
| 53 | +#define __REST_1FPVSR(n,b,base) REST_FPR(n, base) | |
| 44 | 54 | #define __REST_32FPVSRS(n,b,base) REST_32FPRS(n, base) |
| 45 | 55 | #define __SAVE_32FPVSRS(n,b,base) SAVE_32FPRS(n, base) |
| 46 | 56 | #endif |
| 57 | +#define REST_1FPVSR(n,c,base) __REST_1FPVSR(n,__REG_##c,__REG_##base) | |
| 47 | 58 | #define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base) |
| 48 | 59 | #define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base) |
| 49 | 60 | |
| @@ -67,6 +78,7 @@ _GLOBAL(store_fp_state) · 17 unmodified lines | ||
| 67 | 78 | SAVE_32FPVSRS(0, R4, R3) |
| 68 | 79 | mffs fr0 |
| 69 | 80 | stfd fr0,FPSTATE_FPSCR(r3) |
| 81 | + REST_1FPVSR(0, R4, R3) | |
| 70 | 82 | blr |
| 71 | 83 | EXPORT_SYMBOL(store_fp_state) |
| 72 | 84 | |
| @@ -138,4 +150,5 @@ _GLOBAL(save_fpu) · 65 unmodified lines | ||
| 138 | 150 | 2: SAVE_32FPVSRS(0, R4, R6) |
| 139 | 151 | mffs fr0 |
| 140 | 152 | stfd fr0,FPSTATE_FPSCR(r6) |
| 153 | + REST_1FPVSR(0, R4, R6) | |
| 141 | 154 | blr |
| @@ -1198,11 +1198,11 @@ void kvmppc_save_user_regs(void) · 1197 unmodified lines | ||
| 1198 | 1198 | |
| 1199 | 1199 | usermsr = current->thread.regs->msr; |
| 1200 | 1200 | |
| 1201 | + /* Caller has enabled FP/VEC/VSX/TM in MSR */ | |
| 1201 | 1202 | if (usermsr & MSR_FP) |
| 1202 | − save_fpu(current); | |
| 1203 | − | |
| 1203 | + __giveup_fpu(current); | |
| 1204 | 1204 | if (usermsr & MSR_VEC) |
| 1205 | − save_altivec(current); | |
| 1205 | + __giveup_altivec(current); | |
| 1206 | 1206 | |
| 1207 | 1207 | #ifdef CONFIG_PPC_TRANSACTIONAL_MEM |
| 1208 | 1208 | if (usermsr & MSR_TM) { |
| @@ -62,7 +62,7 @@ · 61 unmodified lines | ||
| 62 | 62 | .endif |
| 63 | 63 | |
| 64 | 64 | /* Save previous stack pointer (r1) */ |
| 65 | − addi r8, r1, SWITCH_FRAME_SIZE | |
| 65 | + addi r8, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE | |
| 66 | 66 | PPC_STL r8, GPR1(r1) |
| 67 | 67 | |
| 68 | 68 | .if \allregs == 1 |
| @@ -182,7 +182,7 @@ ftrace_no_trace: · 113 unmodified lines | ||
| 182 | 182 | mflr r3 |
| 183 | 183 | mtctr r3 |
| 184 | 184 | REST_GPR(3, r1) |
| 185 | − addi r1, r1, SWITCH_FRAME_SIZE | |
| 185 | + addi r1, r1, SWITCH_FRAME_SIZE+STACK_FRAME_MIN_SIZE | |
| 186 | 186 | mtlr r0 |
| 187 | 187 | bctr |
| 188 | 188 | #endif |
| @@ -33,6 +33,7 @@ _GLOBAL(store_vr_state) · 32 unmodified lines | ||
| 33 | 33 | mfvscr v0 |
| 34 | 34 | li r4, VRSTATE_VSCR |
| 35 | 35 | stvx v0, r4, r3 |
| 36 | + lvx v0, 0, r3 | |
| 36 | 37 | blr |
| 37 | 38 | EXPORT_SYMBOL(store_vr_state) |
| 38 | 39 | |
| @@ -109,6 +110,7 @@ _GLOBAL(save_altivec) · 70 unmodified lines | ||
| 109 | 110 | mfvscr v0 |
| 110 | 111 | li r4,VRSTATE_VSCR |
| 111 | 112 | stvx v0,r4,r7 |
| 113 | + lvx v0,0,r7 | |
| 112 | 114 | blr |
| 113 | 115 | |
| 114 | 116 | #ifdef CONFIG_VSX |
| @@ -8,9 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <dt-bindings/gpio/gpio.h> |
| 9 | 9 | #include <dt-bindings/leds/common.h> |
| 10 | 10 | |
| 11 | −/* Clock frequency (in Hz) of the rtcclk */ | |
| 12 | −#define RTCCLK_FREQ 1000000 | |
| 13 | − | |
| 14 | 11 | / { |
| 15 | 12 | model = "Microchip PolarFire-SoC Icicle Kit"; |
| 16 | 13 | compatible = "microchip,mpfs-icicle-reference-rtlv2210", "microchip,mpfs-icicle-kit", |
| @@ -29,10 +26,6 @@ · 12 unmodified lines | ||
| 29 | 26 | stdout-path = "serial1:115200n8"; |
| 30 | 27 | }; |
| 31 | 28 | |
| 32 | − cpus { | |
| 33 | − timebase-frequency = <RTCCLK_FREQ>; | |
| 34 | − }; | |
| 35 | − | |
| 36 | 29 | leds { |
| 37 | 30 | compatible = "gpio-leds"; |
| 38 | 31 | |
| @@ -10,9 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | #include "mpfs.dtsi" |
| 11 | 11 | #include "mpfs-m100pfs-fabric.dtsi" |
| 12 | 12 | |
| 13 | −/* Clock frequency (in Hz) of the rtcclk */ | |
| 14 | −#define MTIMER_FREQ 1000000 | |
| 15 | − | |
| 16 | 13 | / { |
| 17 | 14 | model = "Aries Embedded M100PFEVPS"; |
| 18 | 15 | compatible = "aries,m100pfsevp", "microchip,mpfs"; |
| @@ -33,10 +30,6 @@ · 14 unmodified lines | ||
| 33 | 30 | stdout-path = "serial1:115200n8"; |
| 34 | 31 | }; |
| 35 | 32 | |
| 36 | − cpus { | |
| 37 | − timebase-frequency = <MTIMER_FREQ>; | |
| 38 | − }; | |
| 39 | − | |
| 40 | 33 | ddrc_cache_lo: memory@80000000 { |
| 41 | 34 | device_type = "memory"; |
| 42 | 35 | reg = <0x0 0x80000000 0x0 0x40000000>; |
| @@ -6,9 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | #include "mpfs.dtsi" |
| 7 | 7 | #include "mpfs-polarberry-fabric.dtsi" |
| 8 | 8 | |
| 9 | −/* Clock frequency (in Hz) of the rtcclk */ | |
| 10 | −#define MTIMER_FREQ 1000000 | |
| 11 | − | |
| 12 | 9 | / { |
| 13 | 10 | model = "Sundance PolarBerry"; |
| 14 | 11 | compatible = "sundance,polarberry", "microchip,mpfs"; |
| @@ -22,10 +19,6 @@ · 7 unmodified lines | ||
| 22 | 19 | stdout-path = "serial0:115200n8"; |
| 23 | 20 | }; |
| 24 | 21 | |
| 25 | − cpus { | |
| 26 | − timebase-frequency = <MTIMER_FREQ>; | |
| 27 | − }; | |
| 28 | − | |
| 29 | 22 | ddrc_cache_lo: memory@80000000 { |
| 30 | 23 | device_type = "memory"; |
| 31 | 24 | reg = <0x0 0x80000000 0x0 0x2e000000>; |
| @@ -6,9 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | #include "mpfs.dtsi" |
| 7 | 7 | #include "mpfs-sev-kit-fabric.dtsi" |
| 8 | 8 | |
| 9 | −/* Clock frequency (in Hz) of the rtcclk */ | |
| 10 | −#define MTIMER_FREQ 1000000 | |
| 11 | − | |
| 12 | 9 | / { |
| 13 | 10 | #address-cells = <2>; |
| 14 | 11 | #size-cells = <2>; |
| @@ -28,10 +25,6 @@ · 13 unmodified lines | ||
| 28 | 25 | stdout-path = "serial1:115200n8"; |
| 29 | 26 | }; |
| 30 | 27 | |
| 31 | − cpus { | |
| 32 | − timebase-frequency = <MTIMER_FREQ>; | |
| 33 | − }; | |
| 34 | − | |
| 35 | 28 | reserved-memory { |
| 36 | 29 | #address-cells = <2>; |
| 37 | 30 | #size-cells = <2>; |
| @@ -11,9 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | #include "mpfs.dtsi" |
| 12 | 12 | #include "mpfs-tysom-m-fabric.dtsi" |
| 13 | 13 | |
| 14 | −/* Clock frequency (in Hz) of the rtcclk */ | |
| 15 | −#define MTIMER_FREQ 1000000 | |
| 16 | − | |
| 17 | 14 | / { |
| 18 | 15 | model = "Aldec TySOM-M-MPFS250T-REV2"; |
| 19 | 16 | compatible = "aldec,tysom-m-mpfs250t-rev2", "microchip,mpfs"; |
| @@ -34,10 +31,6 @@ · 14 unmodified lines | ||
| 34 | 31 | stdout-path = "serial1:115200n8"; |
| 35 | 32 | }; |
| 36 | 33 | |
| 37 | − cpus { | |
| 38 | − timebase-frequency = <MTIMER_FREQ>; | |
| 39 | − }; | |
| 40 | − | |
| 41 | 34 | ddrc_cache_lo: memory@80000000 { |
| 42 | 35 | device_type = "memory"; |
| 43 | 36 | reg = <0x0 0x80000000 0x0 0x30000000>; |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | cpus { |
| 14 | 14 | #address-cells = <1>; |
| 15 | 15 | #size-cells = <0>; |
| 16 | + timebase-frequency = <1000000>; | |
| 16 | 17 | |
| 17 | 18 | cpu0: cpu@0 { |
| 18 | 19 | compatible = "sifive,e51", "sifive,rocket0", "riscv"; |
| @@ -34,7 +34,6 @@ · 33 unmodified lines | ||
| 34 | 34 | cpu0_intc: interrupt-controller { |
| 35 | 35 | compatible = "riscv,cpu-intc"; |
| 36 | 36 | interrupt-controller; |
| 37 | − #address-cells = <0>; | |
| 38 | 37 | #interrupt-cells = <1>; |
| 39 | 38 | }; |
| 40 | 39 | }; |
| @@ -38,29 +38,35 @@ static long ax45mp_iocp_sw_workaround(void) · 37 unmodified lines | ||
| 38 | 38 | return ret.error ? 0 : ret.value; |
| 39 | 39 | } |
| 40 | 40 | |
| 41 | −static bool errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid) | |
| 41 | +static void errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid) | |
| 42 | 42 | { |
| 43 | + static bool done; | |
| 44 | + | |
| 43 | 45 | if (!IS_ENABLED(CONFIG_ERRATA_ANDES_CMO)) |
| 44 | − return false; | |
| 46 | + return; | |
| 47 | + | |
| 48 | + if (done) | |
| 49 | + return; | |
| 50 | + | |
| 51 | + done = true; | |
| 45 | 52 | |
| 46 | 53 | if (arch_id != ANDESTECH_AX45MP_MARCHID || impid != ANDESTECH_AX45MP_MIMPID) |
| 47 | − return false; | |
| 54 | + return; | |
| 48 | 55 | |
| 49 | 56 | if (!ax45mp_iocp_sw_workaround()) |
| 50 | − return false; | |
| 57 | + return; | |
| 51 | 58 | |
| 52 | 59 | /* Set this just to make core cbo code happy */ |
| 53 | 60 | riscv_cbom_block_size = 1; |
| 54 | 61 | riscv_noncoherent_supported(); |
| 55 | − | |
| 56 | − return true; | |
| 57 | 62 | } |
| 58 | 63 | |
| 59 | 64 | void __init_or_module andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, |
| 60 | 65 | unsigned long archid, unsigned long impid, |
| 61 | 66 | unsigned int stage) |
| 62 | 67 | { |
| 63 | − errata_probe_iocp(stage, archid, impid); | |
| 68 | + if (stage == RISCV_ALTERNATIVES_BOOT) | |
| 69 | + errata_probe_iocp(stage, archid, impid); | |
| 64 | 70 | |
| 65 | 71 | /* we have nothing to patch here ATM so just return back */ |
| 66 | 72 | } |
| @@ -154,7 +154,6 @@ secondary_start_sbi: · 153 unmodified lines | ||
| 154 | 154 | XIP_FIXUP_OFFSET a3 |
| 155 | 155 | add a3, a3, a1 |
| 156 | 156 | REG_L sp, (a3) |
| 157 | − scs_load_current | |
| 158 | 157 | |
| 159 | 158 | .Lsecondary_start_common: |
| 160 | 159 | |
| @@ -165,6 +164,7 @@ secondary_start_sbi: · 4 unmodified lines | ||
| 165 | 164 | call relocate_enable_mmu |
| 166 | 165 | #endif |
| 167 | 166 | call .Lsetup_trap_vector |
| 167 | + scs_load_current | |
| 168 | 168 | tail smp_callin |
| 169 | 169 | #endif /* CONFIG_SMP */ |
| 170 | 170 | |
| @@ -40,15 +40,6 @@ struct relocation_handlers { · 39 unmodified lines | ||
| 40 | 40 | long buffer); |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | −unsigned int initialize_relocation_hashtable(unsigned int num_relocations); | |
| 44 | −void process_accumulated_relocations(struct module *me); | |
| 45 | −int add_relocation_to_accumulate(struct module *me, int type, void *location, | |
| 46 | − unsigned int hashtable_bits, Elf_Addr v); | |
| 47 | − | |
| 48 | −struct hlist_head *relocation_hashtable; | |
| 49 | − | |
| 50 | −struct list_head used_buckets_list; | |
| 51 | − | |
| 52 | 43 | /* |
| 53 | 44 | * The auipc+jalr instruction pair can reach any PC-relative offset |
| 54 | 45 | * in the range [-2^31 - 2^11, 2^31 - 2^11) |
| @@ -64,7 +55,7 @@ static bool riscv_insn_valid_32bit_offset(ptrdiff_t val) · 9 unmodified lines | ||
| 64 | 55 | |
| 65 | 56 | static int riscv_insn_rmw(void *location, u32 keep, u32 set) |
| 66 | 57 | { |
| 67 | − u16 *parcel = location; | |
| 58 | + __le16 *parcel = location; | |
| 68 | 59 | u32 insn = (u32)le16_to_cpu(parcel[0]) | (u32)le16_to_cpu(parcel[1]) << 16; |
| 69 | 60 | |
| 70 | 61 | insn &= keep; |
| @@ -77,7 +68,7 @@ static int riscv_insn_rmw(void *location, u32 keep, u32 set) · 6 unmodified lines | ||
| 77 | 68 | |
| 78 | 69 | static int riscv_insn_rvc_rmw(void *location, u16 keep, u16 set) |
| 79 | 70 | { |
| 80 | − u16 *parcel = location; | |
| 71 | + __le16 *parcel = location; | |
| 81 | 72 | u16 insn = le16_to_cpu(*parcel); |
| 82 | 73 | |
| 83 | 74 | insn &= keep; |
| @@ -604,7 +595,10 @@ static const struct relocation_handlers reloc_handlers[] = { · 520 unmodified lines | ||
| 604 | 595 | /* 192-255 nonstandard ABI extensions */ |
| 605 | 596 | }; |
| 606 | 597 | |
| 607 | −void process_accumulated_relocations(struct module *me) | |
| 598 | +static void | |
| 599 | +process_accumulated_relocations(struct module *me, | |
| 600 | + struct hlist_head **relocation_hashtable, | |
| 601 | + struct list_head *used_buckets_list) | |
| 608 | 602 | { |
| 609 | 603 | /* |
| 610 | 604 | * Only ADD/SUB/SET/ULEB128 should end up here. |
| @@ -624,18 +618,25 @@ void process_accumulated_relocations(struct module *me) · 13 unmodified lines | ||
| 624 | 618 | * - Each relocation entry for a location address |
| 625 | 619 | */ |
| 626 | 620 | struct used_bucket *bucket_iter; |
| 621 | + struct used_bucket *bucket_iter_tmp; | |
| 627 | 622 | struct relocation_head *rel_head_iter; |
| 623 | + struct hlist_node *rel_head_iter_tmp; | |
| 628 | 624 | struct relocation_entry *rel_entry_iter; |
| 625 | + struct relocation_entry *rel_entry_iter_tmp; | |
| 629 | 626 | int curr_type; |
| 630 | 627 | void *location; |
| 631 | 628 | long buffer; |
| 632 | 629 | |
| 633 | − list_for_each_entry(bucket_iter, &used_buckets_list, head) { | |
| 634 | − hlist_for_each_entry(rel_head_iter, bucket_iter->bucket, node) { | |
| 630 | + list_for_each_entry_safe(bucket_iter, bucket_iter_tmp, | |
| 631 | + used_buckets_list, head) { | |
| 632 | + hlist_for_each_entry_safe(rel_head_iter, rel_head_iter_tmp, | |
| 633 | + bucket_iter->bucket, node) { | |
| 635 | 634 | buffer = 0; |
| 636 | 635 | location = rel_head_iter->location; |
| 637 | − list_for_each_entry(rel_entry_iter, | |
| 638 | − rel_head_iter->rel_entry, head) { | |
| 636 | + list_for_each_entry_safe(rel_entry_iter, | |
| 637 | + rel_entry_iter_tmp, | |
| 638 | + rel_head_iter->rel_entry, | |
| 639 | + head) { | |
| 639 | 640 | curr_type = rel_entry_iter->type; |
| 640 | 641 | reloc_handlers[curr_type].reloc_handler( |
| 641 | 642 | me, &buffer, rel_entry_iter->value); |
| @@ -648,11 +649,14 @@ void process_accumulated_relocations(struct module *me) · 6 unmodified lines | ||
| 648 | 649 | kfree(bucket_iter); |
| 649 | 650 | } |
| 650 | 651 | |
| 651 | − kfree(relocation_hashtable); | |
| 652 | + kfree(*relocation_hashtable); | |
| 652 | 653 | } |
| 653 | 654 | |
| 654 | −int add_relocation_to_accumulate(struct module *me, int type, void *location, | |
| 655 | − unsigned int hashtable_bits, Elf_Addr v) | |
| 655 | +static int add_relocation_to_accumulate(struct module *me, int type, | |
| 656 | + void *location, | |
| 657 | + unsigned int hashtable_bits, Elf_Addr v, | |
| 658 | + struct hlist_head *relocation_hashtable, | |
| 659 | + struct list_head *used_buckets_list) | |
| 656 | 660 | { |
| 657 | 661 | struct relocation_entry *entry; |
| 658 | 662 | struct relocation_head *rel_head; |
| @@ -661,6 +665,10 @@ int add_relocation_to_accumulate(struct module *me, int type, void *location, · 2 unmodified lines | ||
| 661 | 665 | unsigned long hash; |
| 662 | 666 | |
| 663 | 667 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); |
| 668 | + | |
| 669 | + if (!entry) | |
| 670 | + return -ENOMEM; | |
| 671 | + | |
| 664 | 672 | INIT_LIST_HEAD(&entry->head); |
| 665 | 673 | entry->type = type; |
| 666 | 674 | entry->value = v; |
| @@ -669,7 +677,10 @@ int add_relocation_to_accumulate(struct module *me, int type, void *location, · 2 unmodified lines | ||
| 669 | 677 | |
| 670 | 678 | current_head = &relocation_hashtable[hash]; |
| 671 | 679 | |
| 672 | − /* Find matching location (if any) */ | |
| 680 | + /* | |
| 681 | + * Search for the relocation_head for the relocations that happen at the | |
| 682 | + * provided location | |
| 683 | + */ | |
| 673 | 684 | bool found = false; |
| 674 | 685 | struct relocation_head *rel_head_iter; |
| 675 | 686 | |
| @@ -681,19 +692,45 @@ int add_relocation_to_accumulate(struct module *me, int type, void *location, · 5 unmodified lines | ||
| 681 | 692 | } |
| 682 | 693 | } |
| 683 | 694 | |
| 695 | + /* | |
| 696 | + * If there has not yet been any relocations at the provided location, | |
| 697 | + * create a relocation_head for that location and populate it with this | |
| 698 | + * relocation_entry. | |
| 699 | + */ | |
| 684 | 700 | if (!found) { |
| 685 | 701 | rel_head = kmalloc(sizeof(*rel_head), GFP_KERNEL); |
| 702 | + | |
| 703 | + if (!rel_head) { | |
| 704 | + kfree(entry); | |
| 705 | + return -ENOMEM; | |
| 706 | + } | |
| 707 | + | |
| 686 | 708 | rel_head->rel_entry = |
| 687 | 709 | kmalloc(sizeof(struct list_head), GFP_KERNEL); |
| 710 | + | |
| 711 | + if (!rel_head->rel_entry) { | |
| 712 | + kfree(entry); | |
| 713 | + kfree(rel_head); | |
| 714 | + return -ENOMEM; | |
| 715 | + } | |
| 716 | + | |
| 688 | 717 | INIT_LIST_HEAD(rel_head->rel_entry); |
| 689 | 718 | rel_head->location = location; |
| 690 | 719 | INIT_HLIST_NODE(&rel_head->node); |
| 691 | 720 | if (!current_head->first) { |
| 692 | 721 | bucket = |
| 693 | 722 | kmalloc(sizeof(struct used_bucket), GFP_KERNEL); |
| 723 | + | |
| 724 | + if (!bucket) { | |
| 725 | + kfree(entry); | |
| 726 | + kfree(rel_head); | |
| 727 | + kfree(rel_head->rel_entry); | |
| 728 | + return -ENOMEM; | |
| 729 | + } | |
| 730 | + | |
| 694 | 731 | INIT_LIST_HEAD(&bucket->head); |
| 695 | 732 | bucket->bucket = current_head; |
| 696 | − list_add(&bucket->head, &used_buckets_list); | |
| 733 | + list_add(&bucket->head, used_buckets_list); | |
| 697 | 734 | } |
| 698 | 735 | hlist_add_head(&rel_head->node, current_head); |
| 699 | 736 | } |
| @@ -704,7 +741,9 @@ int add_relocation_to_accumulate(struct module *me, int type, void *location, · 4 unmodified lines | ||
| 704 | 741 | return 0; |
| 705 | 742 | } |
| 706 | 743 | |
| 707 | −unsigned int initialize_relocation_hashtable(unsigned int num_relocations) | |
| 744 | +static unsigned int | |
| 745 | +initialize_relocation_hashtable(unsigned int num_relocations, | |
| 746 | + struct hlist_head **relocation_hashtable) | |
| 708 | 747 | { |
| 709 | 748 | /* Can safely assume that bits is not greater than sizeof(long) */ |
| 710 | 749 | unsigned long hashtable_size = roundup_pow_of_two(num_relocations); |
| @@ -720,12 +759,13 @@ unsigned int initialize_relocation_hashtable(unsigned int num_relocations) · 9 unmodified lines | ||
| 720 | 759 | |
| 721 | 760 | hashtable_size <<= should_double_size; |
| 722 | 761 | |
| 723 | − relocation_hashtable = kmalloc_array(hashtable_size, | |
| 724 | − sizeof(*relocation_hashtable), | |
| 725 | − GFP_KERNEL); | |
| 726 | − __hash_init(relocation_hashtable, hashtable_size); | |
| 762 | + *relocation_hashtable = kmalloc_array(hashtable_size, | |
| 763 | + sizeof(*relocation_hashtable), | |
| 764 | + GFP_KERNEL); | |
| 765 | + if (!*relocation_hashtable) | |
| 766 | + return -ENOMEM; | |
| 727 | 767 | |
| 728 | − INIT_LIST_HEAD(&used_buckets_list); | |
| 768 | + __hash_init(*relocation_hashtable, hashtable_size); | |
| 729 | 769 | |
| 730 | 770 | return hashtable_bits; |
| 731 | 771 | } |
| @@ -742,7 +782,17 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, · 10 unmodified lines | ||
| 742 | 782 | Elf_Addr v; |
| 743 | 783 | int res; |
| 744 | 784 | unsigned int num_relocations = sechdrs[relsec].sh_size / sizeof(*rel); |
| 745 | − unsigned int hashtable_bits = initialize_relocation_hashtable(num_relocations); | |
| 785 | + struct hlist_head *relocation_hashtable; | |
| 786 | + struct list_head used_buckets_list; | |
| 787 | + unsigned int hashtable_bits; | |
| 788 | + | |
| 789 | + hashtable_bits = initialize_relocation_hashtable(num_relocations, | |
| 790 | + &relocation_hashtable); | |
| 791 | + | |
| 792 | + if (hashtable_bits < 0) | |
| 793 | + return hashtable_bits; | |
| 794 | + | |
| 795 | + INIT_LIST_HEAD(&used_buckets_list); | |
| 746 | 796 | |
| 747 | 797 | pr_debug("Applying relocate section %u to %u\n", relsec, |
| 748 | 798 | sechdrs[relsec].sh_info); |
| @@ -823,14 +873,18 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, · 74 unmodified lines | ||
| 823 | 873 | } |
| 824 | 874 | |
| 825 | 875 | if (reloc_handlers[type].accumulate_handler) |
| 826 | − res = add_relocation_to_accumulate(me, type, location, hashtable_bits, v); | |
| 876 | + res = add_relocation_to_accumulate(me, type, location, | |
| 877 | + hashtable_bits, v, | |
| 878 | + relocation_hashtable, | |
| 879 | + &used_buckets_list); | |
| 827 | 880 | else |
| 828 | 881 | res = handler(me, location, v); |
| 829 | 882 | if (res) |
| 830 | 883 | return res; |
| 831 | 884 | } |
| 832 | 885 | |
| 833 | − process_accumulated_relocations(me); | |
| 886 | + process_accumulated_relocations(me, &relocation_hashtable, | |
| 887 | + &used_buckets_list); | |
| 834 | 888 | |
| 835 | 889 | return 0; |
| 836 | 890 | } |
| @@ -169,7 +169,7 @@ static void hwprobe_isa_ext0(struct riscv_hwprobe *pair, · 168 unmodified lines | ||
| 169 | 169 | pair->value &= ~missing; |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | −static bool hwprobe_ext0_has(const struct cpumask *cpus, unsigned long ext) | |
| 172 | +static bool hwprobe_ext0_has(const struct cpumask *cpus, u64 ext) | |
| 173 | 173 | { |
| 174 | 174 | struct riscv_hwprobe pair; |
| 175 | 175 | |
| @@ -6,13 +6,13 @@ · 5 unmodified lines | ||
| 6 | 6 | .text |
| 7 | 7 | .global test_uleb_basic |
| 8 | 8 | test_uleb_basic: |
| 9 | − ld a0, second | |
| 9 | + lw a0, second | |
| 10 | 10 | addi a0, a0, -127 |
| 11 | 11 | ret |
| 12 | 12 | |
| 13 | 13 | .global test_uleb_large |
| 14 | 14 | test_uleb_large: |
| 15 | − ld a0, fourth | |
| 15 | + lw a0, fourth | |
| 16 | 16 | addi a0, a0, -0x07e8 |
| 17 | 17 | ret |
| 18 | 18 | |
| @@ -22,10 +22,10 @@ first: · 3 unmodified lines | ||
| 22 | 22 | second: |
| 23 | 23 | .reloc second, R_RISCV_SET_ULEB128, second |
| 24 | 24 | .reloc second, R_RISCV_SUB_ULEB128, first |
| 25 | − .dword 0 | |
| 25 | + .word 0 | |
| 26 | 26 | third: |
| 27 | 27 | .space 1000 |
| 28 | 28 | fourth: |
| 29 | 29 | .reloc fourth, R_RISCV_SET_ULEB128, fourth |
| 30 | 30 | .reloc fourth, R_RISCV_SUB_ULEB128, third |
| 31 | − .dword 0 | |
| 31 | + .word 0 | |
| @@ -550,16 +550,14 @@ int handle_misaligned_store(struct pt_regs *regs) · 549 unmodified lines | ||
| 550 | 550 | } else if ((insn & INSN_MASK_C_SD) == INSN_MATCH_C_SD) { |
| 551 | 551 | len = 8; |
| 552 | 552 | val.data_ulong = GET_RS2S(insn, regs); |
| 553 | − } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP && | |
| 554 | − ((insn >> SH_RD) & 0x1f)) { | |
| 553 | + } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP) { | |
| 555 | 554 | len = 8; |
| 556 | 555 | val.data_ulong = GET_RS2C(insn, regs); |
| 557 | 556 | #endif |
| 558 | 557 | } else if ((insn & INSN_MASK_C_SW) == INSN_MATCH_C_SW) { |
| 559 | 558 | len = 4; |
| 560 | 559 | val.data_ulong = GET_RS2S(insn, regs); |
| 561 | − } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP && | |
| 562 | − ((insn >> SH_RD) & 0x1f)) { | |
| 560 | + } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP) { | |
| 563 | 561 | len = 4; |
| 564 | 562 | val.data_ulong = GET_RS2C(insn, regs); |
| 565 | 563 | } else if ((insn & INSN_MASK_C_FSD) == INSN_MATCH_C_FSD) { |
| @@ -228,7 +228,6 @@ typedef struct thread_struct thread_struct; · 227 unmodified lines | ||
| 228 | 228 | execve_tail(); \ |
| 229 | 229 | } while (0) |
| 230 | 230 | |
| 231 | −/* Forward declaration, a strange C thing */ | |
| 232 | 231 | struct task_struct; |
| 233 | 232 | struct mm_struct; |
| 234 | 233 | struct seq_file; |
| @@ -666,6 +666,7 @@ static int __init ipl_init(void) · 665 unmodified lines | ||
| 666 | 666 | &ipl_ccw_attr_group_lpar); |
| 667 | 667 | break; |
| 668 | 668 | case IPL_TYPE_ECKD: |
| 669 | + case IPL_TYPE_ECKD_DUMP: | |
| 669 | 670 | rc = sysfs_create_group(&ipl_kset->kobj, &ipl_eckd_attr_group); |
| 670 | 671 | break; |
| 671 | 672 | case IPL_TYPE_FCP: |
| @@ -279,12 +279,6 @@ static int paicrypt_event_init(struct perf_event *event) · 278 unmodified lines | ||
| 279 | 279 | if (IS_ERR(cpump)) |
| 280 | 280 | return PTR_ERR(cpump); |
| 281 | 281 | |
| 282 | − /* Event initialization sets last_tag to 0. When later on the events | |
| 283 | − * are deleted and re-added, do not reset the event count value to zero. | |
| 284 | − * Events are added, deleted and re-added when 2 or more events | |
| 285 | − * are active at the same time. | |
| 286 | − */ | |
| 287 | − event->hw.last_tag = 0; | |
| 288 | 282 | event->destroy = paicrypt_event_destroy; |
| 289 | 283 | |
| 290 | 284 | if (a->sample_period) { |
| @@ -318,6 +312,11 @@ static void paicrypt_start(struct perf_event *event, int flags) · 27 unmodified lines | ||
| 318 | 312 | { |
| 319 | 313 | u64 sum; |
| 320 | 314 | |
| 315 | + /* Event initialization sets last_tag to 0. When later on the events | |
| 316 | + * are deleted and re-added, do not reset the event count value to zero. | |
| 317 | + * Events are added, deleted and re-added when 2 or more events | |
| 318 | + * are active at the same time. | |
| 319 | + */ | |
| 321 | 320 | if (!event->hw.last_tag) { |
| 322 | 321 | event->hw.last_tag = 1; |
| 323 | 322 | sum = paicrypt_getall(event); /* Get current value */ |
| @@ -260,7 +260,6 @@ static int paiext_event_init(struct perf_event *event) · 259 unmodified lines | ||
| 260 | 260 | rc = paiext_alloc(a, event); |
| 261 | 261 | if (rc) |
| 262 | 262 | return rc; |
| 263 | − event->hw.last_tag = 0; | |
| 264 | 263 | event->destroy = paiext_event_destroy; |
| 265 | 264 | |
| 266 | 265 | if (a->sample_period) { |
| @@ -587,10 +587,6 @@ void kvm_s390_vsie_gmap_notifier(struct gmap *gmap, unsigned long start, · 586 unmodified lines | ||
| 587 | 587 | |
| 588 | 588 | if (!gmap_is_shadow(gmap)) |
| 589 | 589 | return; |
| 590 | − if (start >= 1UL << 31) | |
| 591 | − /* We are only interested in prefix pages */ | |
| 592 | − return; | |
| 593 | − | |
| 594 | 590 | /* |
| 595 | 591 | * Only new shadow blocks are added to the list during runtime, |
| 596 | 592 | * therefore we can safely reference them all the time. |
| @@ -756,7 +756,7 @@ void ptep_zap_unused(struct mm_struct *mm, unsigned long addr, · 755 unmodified lines | ||
| 756 | 756 | pte_clear(mm, addr, ptep); |
| 757 | 757 | } |
| 758 | 758 | if (reset) |
| 759 | − pgste_val(pgste) &= ~_PGSTE_GPS_USAGE_MASK; | |
| 759 | + pgste_val(pgste) &= ~(_PGSTE_GPS_USAGE_MASK | _PGSTE_GPS_NODAT); | |
| 760 | 760 | pgste_set_unlock(ptep, pgste); |
| 761 | 761 | preempt_enable(); |
| 762 | 762 | } |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <asm/coco.h> |
| 11 | 11 | #include <asm/tdx.h> |
| 12 | 12 | #include <asm/vmx.h> |
| 13 | +#include <asm/ia32.h> | |
| 13 | 14 | #include <asm/insn.h> |
| 14 | 15 | #include <asm/insn-eval.h> |
| 15 | 16 | #include <asm/pgtable.h> |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <xen/events.h> |
| 27 | 27 | #endif |
| 28 | 28 | |
| 29 | +#include <asm/apic.h> | |
| 29 | 30 | #include <asm/desc.h> |
| 30 | 31 | #include <asm/traps.h> |
| 31 | 32 | #include <asm/vdso.h> |
| @@ -167,7 +168,96 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, int nr) · 135 unmodified lines | ||
| 167 | 168 | } |
| 168 | 169 | } |
| 169 | 170 | |
| 170 | −/* Handles int $0x80 */ | |
| 171 | +#ifdef CONFIG_IA32_EMULATION | |
| 172 | +static __always_inline bool int80_is_external(void) | |
| 173 | +{ | |
| 174 | + const unsigned int offs = (0x80 / 32) * 0x10; | |
| 175 | + const u32 bit = BIT(0x80 % 32); | |
| 176 | + | |
| 177 | + /* The local APIC on XENPV guests is fake */ | |
| 178 | + if (cpu_feature_enabled(X86_FEATURE_XENPV)) | |
| 179 | + return false; | |
| 180 | + | |
| 181 | + /* | |
| 182 | + * If vector 0x80 is set in the APIC ISR then this is an external | |
| 183 | + * interrupt. Either from broken hardware or injected by a VMM. | |
| 184 | + * | |
| 185 | + * Note: In guest mode this is only valid for secure guests where | |
| 186 | + * the secure module fully controls the vAPIC exposed to the guest. | |
| 187 | + */ | |
| 188 | + return apic_read(APIC_ISR + offs) & bit; | |
| 189 | +} | |
| 190 | + | |
| 191 | +/** | |
| 192 | + * int80_emulation - 32-bit legacy syscall entry | |
| 193 | + * | |
| 194 | + * This entry point can be used by 32-bit and 64-bit programs to perform | |
| 195 | + * 32-bit system calls. Instances of INT $0x80 can be found inline in | |
| 196 | + * various programs and libraries. It is also used by the vDSO's | |
| 197 | + * __kernel_vsyscall fallback for hardware that doesn't support a faster | |
| 198 | + * entry method. Restarted 32-bit system calls also fall back to INT | |
| 199 | + * $0x80 regardless of what instruction was originally used to do the | |
| 200 | + * system call. | |
| 201 | + * | |
| 202 | + * This is considered a slow path. It is not used by most libc | |
| 203 | + * implementations on modern hardware except during process startup. | |
| 204 | + * | |
| 205 | + * The arguments for the INT $0x80 based syscall are on stack in the | |
| 206 | + * pt_regs structure: | |
| 207 | + * eax: system call number | |
| 208 | + * ebx, ecx, edx, esi, edi, ebp: arg1 - arg 6 | |
| 209 | + */ | |
| 210 | +DEFINE_IDTENTRY_RAW(int80_emulation) | |
| 211 | +{ | |
| 212 | + int nr; | |
| 213 | + | |
| 214 | + /* Kernel does not use INT $0x80! */ | |
| 215 | + if (unlikely(!user_mode(regs))) { | |
| 216 | + irqentry_enter(regs); | |
| 217 | + instrumentation_begin(); | |
| 218 | + panic("Unexpected external interrupt 0x80\n"); | |
| 219 | + } | |
| 220 | + | |
| 221 | + /* | |
| 222 | + * Establish kernel context for instrumentation, including for | |
| 223 | + * int80_is_external() below which calls into the APIC driver. | |
| 224 | + * Identical for soft and external interrupts. | |
| 225 | + */ | |
| 226 | + enter_from_user_mode(regs); | |
| 227 | + | |
| 228 | + instrumentation_begin(); | |
| 229 | + add_random_kstack_offset(); | |
| 230 | + | |
| 231 | + /* Validate that this is a soft interrupt to the extent possible */ | |
| 232 | + if (unlikely(int80_is_external())) | |
| 233 | + panic("Unexpected external interrupt 0x80\n"); | |
| 234 | + | |
| 235 | + /* | |
| 236 | + * The low level idtentry code pushed -1 into regs::orig_ax | |
| 237 | + * and regs::ax contains the syscall number. | |
| 238 | + * | |
| 239 | + * User tracing code (ptrace or signal handlers) might assume | |
| 240 | + * that the regs::orig_ax contains a 32-bit number on invoking | |
| 241 | + * a 32-bit syscall. | |
| 242 | + * | |
| 243 | + * Establish the syscall convention by saving the 32bit truncated | |
| 244 | + * syscall number in regs::orig_ax and by invalidating regs::ax. | |
| 245 | + */ | |
| 246 | + regs->orig_ax = regs->ax & GENMASK(31, 0); | |
| 247 | + regs->ax = -ENOSYS; | |
| 248 | + | |
| 249 | + nr = syscall_32_enter(regs); | |
| 250 | + | |
| 251 | + local_irq_enable(); | |
| 252 | + nr = syscall_enter_from_user_mode_work(regs, nr); | |
| 253 | + do_syscall_32_irqs_on(regs, nr); | |
| 254 | + | |
| 255 | + instrumentation_end(); | |
| 256 | + syscall_exit_to_user_mode(regs); | |
| 257 | +} | |
| 258 | +#else /* CONFIG_IA32_EMULATION */ | |
| 259 | + | |
| 260 | +/* Handles int $0x80 on a 32bit kernel */ | |
| 171 | 261 | __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) |
| 172 | 262 | { |
| 173 | 263 | int nr = syscall_32_enter(regs); |
| @@ -186,6 +276,7 @@ __visible noinstr void do_int80_syscall_32(struct pt_regs *regs) · 12 unmodified lines | ||
| 186 | 276 | instrumentation_end(); |
| 187 | 277 | syscall_exit_to_user_mode(regs); |
| 188 | 278 | } |
| 279 | +#endif /* !CONFIG_IA32_EMULATION */ | |
| 189 | 280 | |
| 190 | 281 | static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) |
| 191 | 282 | { |
| @@ -275,80 +275,3 @@ SYM_INNER_LABEL(entry_SYSRETL_compat_end, SYM_L_GLOBAL) · 274 unmodified lines | ||
| 275 | 275 | ANNOTATE_NOENDBR |
| 276 | 276 | int3 |
| 277 | 277 | SYM_CODE_END(entry_SYSCALL_compat) |
| 278 | − | |
| 279 | −/* | |
| 280 | − * 32-bit legacy system call entry. | |
| 281 | − * | |
| 282 | − * 32-bit x86 Linux system calls traditionally used the INT $0x80 | |
| 283 | − * instruction. INT $0x80 lands here. | |
| 284 | − * | |
| 285 | − * This entry point can be used by 32-bit and 64-bit programs to perform | |
| 286 | − * 32-bit system calls. Instances of INT $0x80 can be found inline in | |
| 287 | − * various programs and libraries. It is also used by the vDSO's | |
| 288 | − * __kernel_vsyscall fallback for hardware that doesn't support a faster | |
| 289 | − * entry method. Restarted 32-bit system calls also fall back to INT | |
| 290 | − * $0x80 regardless of what instruction was originally used to do the | |
| 291 | − * system call. | |
| 292 | − * | |
| 293 | − * This is considered a slow path. It is not used by most libc | |
| 294 | − * implementations on modern hardware except during process startup. | |
| 295 | − * | |
| 296 | − * Arguments: | |
| 297 | − * eax system call number | |
| 298 | − * ebx arg1 | |
| 299 | − * ecx arg2 | |
| 300 | − * edx arg3 | |
| 301 | − * esi arg4 | |
| 302 | − * edi arg5 | |
| 303 | − * ebp arg6 | |
| 304 | − */ | |
| 305 | −SYM_CODE_START(entry_INT80_compat) | |
| 306 | − UNWIND_HINT_ENTRY | |
| 307 | − ENDBR | |
| 308 | − /* | |
| 309 | − * Interrupts are off on entry. | |
| 310 | − */ | |
| 311 | − ASM_CLAC /* Do this early to minimize exposure */ | |
| 312 | − ALTERNATIVE "swapgs", "", X86_FEATURE_XENPV | |
| 313 | − | |
| 314 | − /* | |
| 315 | − * User tracing code (ptrace or signal handlers) might assume that | |
| 316 | − * the saved RAX contains a 32-bit number when we're invoking a 32-bit | |
| 317 | − * syscall. Just in case the high bits are nonzero, zero-extend | |
| 318 | − * the syscall number. (This could almost certainly be deleted | |
| 319 | − * with no ill effects.) | |
| 320 | − */ | |
| 321 | − movl %eax, %eax | |
| 322 | − | |
| 323 | − /* switch to thread stack expects orig_ax and rdi to be pushed */ | |
| 324 | − pushq %rax /* pt_regs->orig_ax */ | |
| 325 | − | |
| 326 | − /* Need to switch before accessing the thread stack. */ | |
| 327 | − SWITCH_TO_KERNEL_CR3 scratch_reg=%rax | |
| 328 | − | |
| 329 | − /* In the Xen PV case we already run on the thread stack. */ | |
| 330 | − ALTERNATIVE "", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV | |
| 331 | − | |
| 332 | − movq %rsp, %rax | |
| 333 | − movq PER_CPU_VAR(pcpu_hot + X86_top_of_stack), %rsp | |
| 334 | − | |
| 335 | − pushq 5*8(%rax) /* regs->ss */ | |
| 336 | − pushq 4*8(%rax) /* regs->rsp */ | |
| 337 | − pushq 3*8(%rax) /* regs->eflags */ | |
| 338 | − pushq 2*8(%rax) /* regs->cs */ | |
| 339 | − pushq 1*8(%rax) /* regs->ip */ | |
| 340 | − pushq 0*8(%rax) /* regs->orig_ax */ | |
| 341 | −.Lint80_keep_stack: | |
| 342 | − | |
| 343 | − PUSH_AND_CLEAR_REGS rax=$-ENOSYS | |
| 344 | − UNWIND_HINT_REGS | |
| 345 | − | |
| 346 | − cld | |
| 347 | − | |
| 348 | − IBRS_ENTER | |
| 349 | − UNTRAIN_RET | |
| 350 | − | |
| 351 | − movq %rsp, %rdi | |
| 352 | − call do_int80_syscall_32 | |
| 353 | − jmp swapgs_restore_regs_and_return_to_usermode | |
| 354 | −SYM_CODE_END(entry_INT80_compat) | |
| @@ -4660,7 +4660,7 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu) · 4659 unmodified lines | ||
| 4660 | 4660 | if (pmu->intel_cap.pebs_output_pt_available) |
| 4661 | 4661 | pmu->pmu.capabilities |= PERF_PMU_CAP_AUX_OUTPUT; |
| 4662 | 4662 | else |
| 4663 | − pmu->pmu.capabilities |= ~PERF_PMU_CAP_AUX_OUTPUT; | |
| 4663 | + pmu->pmu.capabilities &= ~PERF_PMU_CAP_AUX_OUTPUT; | |
| 4664 | 4664 | |
| 4665 | 4665 | intel_pmu_check_event_constraints(pmu->event_constraints, |
| 4666 | 4666 | pmu->num_counters, |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/io.h> |
| 16 | 16 | #include <asm/apic.h> |
| 17 | 17 | #include <asm/desc.h> |
| 18 | +#include <asm/e820/api.h> | |
| 18 | 19 | #include <asm/sev.h> |
| 19 | 20 | #include <asm/ibt.h> |
| 20 | 21 | #include <asm/hypervisor.h> |
| @@ -286,15 +287,31 @@ static int hv_cpu_die(unsigned int cpu) · 265 unmodified lines | ||
| 286 | 287 | |
| 287 | 288 | static int __init hv_pci_init(void) |
| 288 | 289 | { |
| 289 | − int gen2vm = efi_enabled(EFI_BOOT); | |
| 290 | + bool gen2vm = efi_enabled(EFI_BOOT); | |
| 290 | 291 | |
| 291 | 292 | /* |
| 292 | − * For Generation-2 VM, we exit from pci_arch_init() by returning 0. | |
| 293 | − * The purpose is to suppress the harmless warning: | |
| 293 | + * A Generation-2 VM doesn't support legacy PCI/PCIe, so both | |
| 294 | + * raw_pci_ops and raw_pci_ext_ops are NULL, and pci_subsys_init() -> | |
| 295 | + * pcibios_init() doesn't call pcibios_resource_survey() -> | |
| 296 | + * e820__reserve_resources_late(); as a result, any emulated persistent | |
| 297 | + * memory of E820_TYPE_PRAM (12) via the kernel parameter | |
| 298 | + * memmap=nn[KMG]!ss is not added into iomem_resource and hence can't be | |
| 299 | + * detected by register_e820_pmem(). Fix this by directly calling | |
| 300 | + * e820__reserve_resources_late() here: e820__reserve_resources_late() | |
| 301 | + * depends on e820__reserve_resources(), which has been called earlier | |
| 302 | + * from setup_arch(). Note: e820__reserve_resources_late() also adds | |
| 303 | + * any memory of E820_TYPE_PMEM (7) into iomem_resource, and | |
| 304 | + * acpi_nfit_register_region() -> acpi_nfit_insert_resource() -> | |
| 305 | + * region_intersects() returns REGION_INTERSECTS, so the memory of | |
| 306 | + * E820_TYPE_PMEM won't get added twice. | |
| 307 | + * | |
| 308 | + * We return 0 here so that pci_arch_init() won't print the warning: | |
| 294 | 309 | * "PCI: Fatal: No config space access function found" |
| 295 | 310 | */ |
| 296 | − if (gen2vm) | |
| 311 | + if (gen2vm) { | |
| 312 | + e820__reserve_resources_late(); | |
| 297 | 313 | return 0; |
| 314 | + } | |
| 298 | 315 | |
| 299 | 316 | /* For Generation-1 VM, we'll proceed in pci_arch_init(). */ |
| 300 | 317 | return 1; |
| @@ -16,6 +16,9 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <asm/x86_init.h> |
| 17 | 17 | #include <asm/cpufeature.h> |
| 18 | 18 | #include <asm/irq_vectors.h> |
| 19 | +#include <asm/xen/hypervisor.h> | |
| 20 | + | |
| 21 | +#include <xen/xen.h> | |
| 19 | 22 | |
| 20 | 23 | #ifdef CONFIG_ACPI_APEI |
| 21 | 24 | # include <asm/pgtable_types.h> |
| @@ -127,6 +130,17 @@ static inline void arch_acpi_set_proc_cap_bits(u32 *cap) · 105 unmodified lines | ||
| 127 | 130 | if (!cpu_has(c, X86_FEATURE_MWAIT) || |
| 128 | 131 | boot_option_idle_override == IDLE_NOMWAIT) |
| 129 | 132 | *cap &= ~(ACPI_PROC_CAP_C_C1_FFH | ACPI_PROC_CAP_C_C2C3_FFH); |
| 133 | + | |
| 134 | + if (xen_initial_domain()) { | |
| 135 | + /* | |
| 136 | + * When Linux is running as Xen dom0, the hypervisor is the | |
| 137 | + * entity in charge of the processor power management, and so | |
| 138 | + * Xen needs to check the OS capabilities reported in the | |
| 139 | + * processor capabilities buffer matches what the hypervisor | |
| 140 | + * driver supports. | |
| 141 | + */ | |
| 142 | + xen_sanitize_proc_cap_bits(cap); | |
| 143 | + } | |
| 130 | 144 | } |
| 131 | 145 | |
| 132 | 146 | static inline bool acpi_has_cpu_in_madt(void) |
| @@ -75,6 +75,11 @@ static inline bool ia32_enabled(void) · 74 unmodified lines | ||
| 75 | 75 | return __ia32_enabled; |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | +static inline void ia32_disable(void) | |
| 79 | +{ | |
| 80 | + __ia32_enabled = false; | |
| 81 | +} | |
| 82 | + | |
| 78 | 83 | #else /* !CONFIG_IA32_EMULATION */ |
| 79 | 84 | |
| 80 | 85 | static inline bool ia32_enabled(void) |
| @@ -82,6 +87,8 @@ static inline bool ia32_enabled(void) · 1 unmodified line | ||
| 82 | 87 | return IS_ENABLED(CONFIG_X86_32); |
| 83 | 88 | } |
| 84 | 89 | |
| 90 | +static inline void ia32_disable(void) {} | |
| 91 | + | |
| 85 | 92 | #endif |
| 86 | 93 | |
| 87 | 94 | #endif /* _ASM_X86_IA32_H */ |
| @@ -569,6 +569,10 @@ DECLARE_IDTENTRY_RAW(X86_TRAP_UD, exc_invalid_op); · 568 unmodified lines | ||
| 569 | 569 | DECLARE_IDTENTRY_RAW(X86_TRAP_BP, exc_int3); |
| 570 | 570 | DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_PF, exc_page_fault); |
| 571 | 571 | |
| 572 | +#if defined(CONFIG_IA32_EMULATION) | |
| 573 | +DECLARE_IDTENTRY_RAW(IA32_SYSCALL_VECTOR, int80_emulation); | |
| 574 | +#endif | |
| 575 | + | |
| 572 | 576 | #ifdef CONFIG_X86_MCE |
| 573 | 577 | #ifdef CONFIG_X86_64 |
| 574 | 578 | DECLARE_IDTENTRY_MCE(X86_TRAP_MC, exc_machine_check); |
| @@ -32,10 +32,6 @@ void entry_SYSCALL_compat(void); · 31 unmodified lines | ||
| 32 | 32 | void entry_SYSCALL_compat_safe_stack(void); |
| 33 | 33 | void entry_SYSRETL_compat_unsafe_stack(void); |
| 34 | 34 | void entry_SYSRETL_compat_end(void); |
| 35 | −void entry_INT80_compat(void); | |
| 36 | −#ifdef CONFIG_XEN_PV | |
| 37 | −void xen_entry_INT80_compat(void); | |
| 38 | −#endif | |
| 39 | 35 | #else /* !CONFIG_IA32_EMULATION */ |
| 40 | 36 | #define entry_SYSCALL_compat NULL |
| 41 | 37 | #define entry_SYSENTER_compat NULL |
| @@ -100,4 +100,13 @@ static inline void leave_lazy(enum xen_lazy_mode mode) · 99 unmodified lines | ||
| 100 | 100 | |
| 101 | 101 | enum xen_lazy_mode xen_get_lazy_mode(void); |
| 102 | 102 | |
| 103 | +#if defined(CONFIG_XEN_DOM0) && defined(CONFIG_ACPI) | |
| 104 | +void xen_sanitize_proc_cap_bits(uint32_t *buf); | |
| 105 | +#else | |
| 106 | +static inline void xen_sanitize_proc_cap_bits(uint32_t *buf) | |
| 107 | +{ | |
| 108 | + BUG(); | |
| 109 | +} | |
| 110 | +#endif | |
| 111 | + | |
| 103 | 112 | #endif /* _ASM_X86_XEN_HYPERVISOR_H */ |
| @@ -63,6 +63,7 @@ int acpi_fix_pin2_polarity __initdata; · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | #ifdef CONFIG_X86_LOCAL_APIC |
| 65 | 65 | static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; |
| 66 | +static bool has_lapic_cpus __initdata; | |
| 66 | 67 | static bool acpi_support_online_capable; |
| 67 | 68 | #endif |
| 68 | 69 | |
| @@ -232,6 +233,14 @@ acpi_parse_x2apic(union acpi_subtable_headers *header, const unsigned long end) · 163 unmodified lines | ||
| 232 | 233 | if (!acpi_is_processor_usable(processor->lapic_flags)) |
| 233 | 234 | return 0; |
| 234 | 235 | |
| 236 | + /* | |
| 237 | + * According to https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#processor-local-x2apic-structure | |
| 238 | + * when MADT provides both valid LAPIC and x2APIC entries, the APIC ID | |
| 239 | + * in x2APIC must be equal or greater than 0xff. | |
| 240 | + */ | |
| 241 | + if (has_lapic_cpus && apic_id < 0xff) | |
| 242 | + return 0; | |
| 243 | + | |
| 235 | 244 | /* |
| 236 | 245 | * We need to register disabled CPU as well to permit |
| 237 | 246 | * counting disabled CPUs. This allows us to size |
| @@ -1114,10 +1123,7 @@ static int __init early_acpi_parse_madt_lapic_addr_ovr(void) · 876 unmodified lines | ||
| 1114 | 1123 | |
| 1115 | 1124 | static int __init acpi_parse_madt_lapic_entries(void) |
| 1116 | 1125 | { |
| 1117 | − int count; | |
| 1118 | − int x2count = 0; | |
| 1119 | − int ret; | |
| 1120 | − struct acpi_subtable_proc madt_proc[2]; | |
| 1126 | + int count, x2count = 0; | |
| 1121 | 1127 | |
| 1122 | 1128 | if (!boot_cpu_has(X86_FEATURE_APIC)) |
| 1123 | 1129 | return -ENODEV; |
| @@ -1126,21 +1132,11 @@ static int __init acpi_parse_madt_lapic_entries(void) · 2 unmodified lines | ||
| 1126 | 1132 | acpi_parse_sapic, MAX_LOCAL_APIC); |
| 1127 | 1133 | |
| 1128 | 1134 | if (!count) { |
| 1129 | − memset(madt_proc, 0, sizeof(madt_proc)); | |
| 1130 | − madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC; | |
| 1131 | − madt_proc[0].handler = acpi_parse_lapic; | |
| 1132 | − madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC; | |
| 1133 | − madt_proc[1].handler = acpi_parse_x2apic; | |
| 1134 | − ret = acpi_table_parse_entries_array(ACPI_SIG_MADT, | |
| 1135 | − sizeof(struct acpi_table_madt), | |
| 1136 | − madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC); | |
| 1137 | − if (ret < 0) { | |
| 1138 | − pr_err("Error parsing LAPIC/X2APIC entries\n"); | |
| 1139 | − return ret; | |
| 1140 | − } | |
| 1141 | − | |
| 1142 | − count = madt_proc[0].count; | |
| 1143 | − x2count = madt_proc[1].count; | |
| 1135 | + count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, | |
| 1136 | + acpi_parse_lapic, MAX_LOCAL_APIC); | |
| 1137 | + has_lapic_cpus = count > 0; | |
| 1138 | + x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC, | |
| 1139 | + acpi_parse_x2apic, MAX_LOCAL_APIC); | |
| 1144 | 1140 | } |
| 1145 | 1141 | if (!count && !x2count) { |
| 1146 | 1142 | pr_err("No LAPIC entries present\n"); |
| @@ -1320,6 +1320,9 @@ static void zenbleed_check_cpu(void *unused) · 1319 unmodified lines | ||
| 1320 | 1320 | |
| 1321 | 1321 | void amd_check_microcode(void) |
| 1322 | 1322 | { |
| 1323 | + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) | |
| 1324 | + return; | |
| 1325 | + | |
| 1323 | 1326 | on_each_cpu(zenbleed_check_cpu, NULL, 1); |
| 1324 | 1327 | } |
| 1325 | 1328 | |
| @@ -104,8 +104,6 @@ struct cont_desc { · 103 unmodified lines | ||
| 104 | 104 | size_t size; |
| 105 | 105 | }; |
| 106 | 106 | |
| 107 | −static u32 ucode_new_rev; | |
| 108 | − | |
| 109 | 107 | /* |
| 110 | 108 | * Microcode patch container file is prepended to the initrd in cpio |
| 111 | 109 | * format. See Documentation/arch/x86/microcode.rst |
| @@ -442,12 +440,11 @@ static int __apply_microcode_amd(struct microcode_amd *mc) · 330 unmodified lines | ||
| 442 | 440 | * |
| 443 | 441 | * Returns true if container found (sets @desc), false otherwise. |
| 444 | 442 | */ |
| 445 | −static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size) | |
| 443 | +static bool early_apply_microcode(u32 cpuid_1_eax, u32 old_rev, void *ucode, size_t size) | |
| 446 | 444 | { |
| 447 | 445 | struct cont_desc desc = { 0 }; |
| 448 | 446 | struct microcode_amd *mc; |
| 449 | 447 | bool ret = false; |
| 450 | − u32 rev, dummy; | |
| 451 | 448 | |
| 452 | 449 | desc.cpuid_1_eax = cpuid_1_eax; |
| 453 | 450 | |
| @@ -457,22 +454,15 @@ static bool early_apply_microcode(u32 cpuid_1_eax, void *ucode, size_t size) · 3 unmodified lines | ||
| 457 | 454 | if (!mc) |
| 458 | 455 | return ret; |
| 459 | 456 | |
| 460 | − native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); | |
| 461 | − | |
| 462 | 457 | /* |
| 463 | 458 | * Allow application of the same revision to pick up SMT-specific |
| 464 | 459 | * changes even if the revision of the other SMT thread is already |
| 465 | 460 | * up-to-date. |
| 466 | 461 | */ |
| 467 | − if (rev > mc->hdr.patch_id) | |
| 462 | + if (old_rev > mc->hdr.patch_id) | |
| 468 | 463 | return ret; |
| 469 | 464 | |
| 470 | − if (!__apply_microcode_amd(mc)) { | |
| 471 | − ucode_new_rev = mc->hdr.patch_id; | |
| 472 | − ret = true; | |
| 473 | − } | |
| 474 | − | |
| 475 | − return ret; | |
| 465 | + return !__apply_microcode_amd(mc); | |
| 476 | 466 | } |
| 477 | 467 | |
| 478 | 468 | static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family) |
| @@ -506,9 +496,12 @@ static void __init find_blobs_in_containers(unsigned int cpuid_1_eax, struct cpi · 27 unmodified lines | ||
| 506 | 496 | *ret = cp; |
| 507 | 497 | } |
| 508 | 498 | |
| 509 | −void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax) | |
| 499 | +void __init load_ucode_amd_bsp(struct early_load_data *ed, unsigned int cpuid_1_eax) | |
| 510 | 500 | { |
| 511 | 501 | struct cpio_data cp = { }; |
| 502 | + u32 dummy; | |
| 503 | + | |
| 504 | + native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->old_rev, dummy); | |
| 512 | 505 | |
| 513 | 506 | /* Needed in load_microcode_amd() */ |
| 514 | 507 | ucode_cpu_info[0].cpu_sig.sig = cpuid_1_eax; |
| @@ -517,7 +510,8 @@ void __init load_ucode_amd_bsp(unsigned int cpuid_1_eax) · 2 unmodified lines | ||
| 517 | 510 | if (!(cp.data && cp.size)) |
| 518 | 511 | return; |
| 519 | 512 | |
| 520 | − early_apply_microcode(cpuid_1_eax, cp.data, cp.size); | |
| 513 | + if (early_apply_microcode(cpuid_1_eax, ed->old_rev, cp.data, cp.size)) | |
| 514 | + native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->new_rev, dummy); | |
| 521 | 515 | } |
| 522 | 516 | |
| 523 | 517 | static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size); |
| @@ -625,10 +619,8 @@ void reload_ucode_amd(unsigned int cpu) · 101 unmodified lines | ||
| 625 | 619 | rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy); |
| 626 | 620 | |
| 627 | 621 | if (rev < mc->hdr.patch_id) { |
| 628 | − if (!__apply_microcode_amd(mc)) { | |
| 629 | − ucode_new_rev = mc->hdr.patch_id; | |
| 630 | − pr_info("reload patch_level=0x%08x\n", ucode_new_rev); | |
| 631 | − } | |
| 622 | + if (!__apply_microcode_amd(mc)) | |
| 623 | + pr_info_once("reload revision: 0x%08x\n", mc->hdr.patch_id); | |
| 632 | 624 | } |
| 633 | 625 | } |
| 634 | 626 | |
| @@ -649,8 +641,6 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) · 14 unmodified lines | ||
| 649 | 641 | if (p && (p->patch_id == csig->rev)) |
| 650 | 642 | uci->mc = p->data; |
| 651 | 643 | |
| 652 | − pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev); | |
| 653 | − | |
| 654 | 644 | return 0; |
| 655 | 645 | } |
| 656 | 646 | |
| @@ -691,8 +681,6 @@ static enum ucode_state apply_microcode_amd(int cpu) · 34 unmodified lines | ||
| 691 | 681 | rev = mc_amd->hdr.patch_id; |
| 692 | 682 | ret = UCODE_UPDATED; |
| 693 | 683 | |
| 694 | − pr_info("CPU%d: new patch_level=0x%08x\n", cpu, rev); | |
| 695 | − | |
| 696 | 684 | out: |
| 697 | 685 | uci->cpu_sig.rev = rev; |
| 698 | 686 | c->microcode = rev; |
| @@ -935,11 +923,6 @@ struct microcode_ops * __init init_amd_microcode(void) · 236 unmodified lines | ||
| 935 | 923 | pr_warn("AMD CPU family 0x%x not supported\n", c->x86); |
| 936 | 924 | return NULL; |
| 937 | 925 | } |
| 938 | − | |
| 939 | − if (ucode_new_rev) | |
| 940 | − pr_info_once("microcode updated early to new patch_level=0x%08x\n", | |
| 941 | − ucode_new_rev); | |
| 942 | − | |
| 943 | 926 | return µcode_amd_ops; |
| 944 | 927 | } |
| 945 | 928 | |
| @@ -41,8 +41,6 @@ · 40 unmodified lines | ||
| 41 | 41 | |
| 42 | 42 | #include "internal.h" |
| 43 | 43 | |
| 44 | −#define DRIVER_VERSION "2.2" | |
| 45 | − | |
| 46 | 44 | static struct microcode_ops *microcode_ops; |
| 47 | 45 | bool dis_ucode_ldr = true; |
| 48 | 46 | |
| @@ -77,6 +75,8 @@ static u32 final_levels[] = { · 28 unmodified lines | ||
| 77 | 75 | 0, /* T-101 terminator */ |
| 78 | 76 | }; |
| 79 | 77 | |
| 78 | +struct early_load_data early_data; | |
| 79 | + | |
| 80 | 80 | /* |
| 81 | 81 | * Check the current patch level on this CPU. |
| 82 | 82 | * |
| @@ -155,9 +155,9 @@ void __init load_ucode_bsp(void) · 72 unmodified lines | ||
| 155 | 155 | return; |
| 156 | 156 | |
| 157 | 157 | if (intel) |
| 158 | − load_ucode_intel_bsp(); | |
| 158 | + load_ucode_intel_bsp(&early_data); | |
| 159 | 159 | else |
| 160 | − load_ucode_amd_bsp(cpuid_1_eax); | |
| 160 | + load_ucode_amd_bsp(&early_data, cpuid_1_eax); | |
| 161 | 161 | } |
| 162 | 162 | |
| 163 | 163 | void load_ucode_ap(void) |
| @@ -828,6 +828,11 @@ static int __init microcode_init(void) · 664 unmodified lines | ||
| 828 | 828 | if (!microcode_ops) |
| 829 | 829 | return -ENODEV; |
| 830 | 830 | |
| 831 | + pr_info_once("Current revision: 0x%08x\n", (early_data.new_rev ?: early_data.old_rev)); | |
| 832 | + | |
| 833 | + if (early_data.new_rev) | |
| 834 | + pr_info_once("Updated early from: 0x%08x\n", early_data.old_rev); | |
| 835 | + | |
| 831 | 836 | microcode_pdev = platform_device_register_simple("microcode", -1, NULL, 0); |
| 832 | 837 | if (IS_ERR(microcode_pdev)) |
| 833 | 838 | return PTR_ERR(microcode_pdev); |
| @@ -846,8 +851,6 @@ static int __init microcode_init(void) · 12 unmodified lines | ||
| 846 | 851 | cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/microcode:online", |
| 847 | 852 | mc_cpu_online, mc_cpu_down_prep); |
| 848 | 853 | |
| 849 | − pr_info("Microcode Update Driver: v%s.", DRIVER_VERSION); | |
| 850 | − | |
| 851 | 854 | return 0; |
| 852 | 855 | |
| 853 | 856 | out_pdev: |
| @@ -339,16 +339,9 @@ static enum ucode_state __apply_microcode(struct ucode_cpu_info *uci, · 338 unmodified lines | ||
| 339 | 339 | static enum ucode_state apply_microcode_early(struct ucode_cpu_info *uci) |
| 340 | 340 | { |
| 341 | 341 | struct microcode_intel *mc = uci->mc; |
| 342 | − enum ucode_state ret; | |
| 343 | − u32 cur_rev, date; | |
| 342 | + u32 cur_rev; | |
| 344 | 343 | |
| 345 | − ret = __apply_microcode(uci, mc, &cur_rev); | |
| 346 | − if (ret == UCODE_UPDATED) { | |
| 347 | − date = mc->hdr.date; | |
| 348 | − pr_info_once("updated early: 0x%x -> 0x%x, date = %04x-%02x-%02x\n", | |
| 349 | − cur_rev, mc->hdr.rev, date & 0xffff, date >> 24, (date >> 16) & 0xff); | |
| 350 | − } | |
| 351 | − return ret; | |
| 344 | + return __apply_microcode(uci, mc, &cur_rev); | |
| 352 | 345 | } |
| 353 | 346 | |
| 354 | 347 | static __init bool load_builtin_intel_microcode(struct cpio_data *cp) |
| @@ -413,13 +406,17 @@ static int __init save_builtin_microcode(void) · 58 unmodified lines | ||
| 413 | 406 | early_initcall(save_builtin_microcode); |
| 414 | 407 | |
| 415 | 408 | /* Load microcode on BSP from initrd or builtin blobs */ |
| 416 | −void __init load_ucode_intel_bsp(void) | |
| 409 | +void __init load_ucode_intel_bsp(struct early_load_data *ed) | |
| 417 | 410 | { |
| 418 | 411 | struct ucode_cpu_info uci; |
| 419 | 412 | |
| 413 | + ed->old_rev = intel_get_microcode_revision(); | |
| 414 | + | |
| 420 | 415 | uci.mc = get_microcode_blob(&uci, false); |
| 421 | 416 | if (uci.mc && apply_microcode_early(&uci) == UCODE_UPDATED) |
| 422 | 417 | ucode_patch_va = UCODE_BSP_LOADED; |
| 418 | + | |
| 419 | + ed->new_rev = uci.cpu_sig.rev; | |
| 423 | 420 | } |
| 424 | 421 | |
| 425 | 422 | void load_ucode_intel_ap(void) |
| @@ -37,6 +37,12 @@ struct microcode_ops { · 36 unmodified lines | ||
| 37 | 37 | use_nmi : 1; |
| 38 | 38 | }; |
| 39 | 39 | |
| 40 | +struct early_load_data { | |
| 41 | + u32 old_rev; | |
| 42 | + u32 new_rev; | |
| 43 | +}; | |
| 44 | + | |
| 45 | +extern struct early_load_data early_data; | |
| 40 | 46 | extern struct ucode_cpu_info ucode_cpu_info[]; |
| 41 | 47 | struct cpio_data find_microcode_in_initrd(const char *path); |
| 42 | 48 | |
| @@ -92,14 +98,14 @@ extern bool dis_ucode_ldr; · 49 unmodified lines | ||
| 92 | 98 | extern bool force_minrev; |
| 93 | 99 | |
| 94 | 100 | #ifdef CONFIG_CPU_SUP_AMD |
| 95 | −void load_ucode_amd_bsp(unsigned int family); | |
| 101 | +void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family); | |
| 96 | 102 | void load_ucode_amd_ap(unsigned int family); |
| 97 | 103 | int save_microcode_in_initrd_amd(unsigned int family); |
| 98 | 104 | void reload_ucode_amd(unsigned int cpu); |
| 99 | 105 | struct microcode_ops *init_amd_microcode(void); |
| 100 | 106 | void exit_amd_microcode(void); |
| 101 | 107 | #else /* CONFIG_CPU_SUP_AMD */ |
| 102 | −static inline void load_ucode_amd_bsp(unsigned int family) { } | |
| 108 | +static inline void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family) { } | |
| 103 | 109 | static inline void load_ucode_amd_ap(unsigned int family) { } |
| 104 | 110 | static inline int save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; } |
| 105 | 111 | static inline void reload_ucode_amd(unsigned int cpu) { } |
| @@ -108,12 +114,12 @@ static inline void exit_amd_microcode(void) { } · 2 unmodified lines | ||
| 108 | 114 | #endif /* !CONFIG_CPU_SUP_AMD */ |
| 109 | 115 | |
| 110 | 116 | #ifdef CONFIG_CPU_SUP_INTEL |
| 111 | −void load_ucode_intel_bsp(void); | |
| 117 | +void load_ucode_intel_bsp(struct early_load_data *ed); | |
| 112 | 118 | void load_ucode_intel_ap(void); |
| 113 | 119 | void reload_ucode_intel(void); |
| 114 | 120 | struct microcode_ops *init_intel_microcode(void); |
| 115 | 121 | #else /* CONFIG_CPU_SUP_INTEL */ |
| 116 | −static inline void load_ucode_intel_bsp(void) { } | |
| 122 | +static inline void load_ucode_intel_bsp(struct early_load_data *ed) { } | |
| 117 | 123 | static inline void load_ucode_intel_ap(void) { } |
| 118 | 124 | static inline void reload_ucode_intel(void) { } |
| 119 | 125 | static inline struct microcode_ops *init_intel_microcode(void) { return NULL; } |
| @@ -262,11 +262,14 @@ static uint32_t __init ms_hyperv_platform(void) · 261 unmodified lines | ||
| 262 | 262 | static int hv_nmi_unknown(unsigned int val, struct pt_regs *regs) |
| 263 | 263 | { |
| 264 | 264 | static atomic_t nmi_cpu = ATOMIC_INIT(-1); |
| 265 | + unsigned int old_cpu, this_cpu; | |
| 265 | 266 | |
| 266 | 267 | if (!unknown_nmi_panic) |
| 267 | 268 | return NMI_DONE; |
| 268 | 269 | |
| 269 | − if (atomic_cmpxchg(&nmi_cpu, -1, raw_smp_processor_id()) != -1) | |
| 270 | + old_cpu = -1; | |
| 271 | + this_cpu = raw_smp_processor_id(); | |
| 272 | + if (!atomic_try_cmpxchg(&nmi_cpu, &old_cpu, this_cpu)) | |
| 270 | 273 | return NMI_HANDLED; |
| 271 | 274 | |
| 272 | 275 | return NMI_DONE; |
| @@ -121,7 +121,7 @@ static const __initconst struct idt_data def_idts[] = { · 120 unmodified lines | ||
| 121 | 121 | |
| 122 | 122 | static const struct idt_data ia32_idt[] __initconst = { |
| 123 | 123 | #if defined(CONFIG_IA32_EMULATION) |
| 124 | − SYSG(IA32_SYSCALL_VECTOR, entry_INT80_compat), | |
| 124 | + SYSG(IA32_SYSCALL_VECTOR, asm_int80_emulation), | |
| 125 | 125 | #elif defined(CONFIG_X86_32) |
| 126 | 126 | SYSG(IA32_SYSCALL_VECTOR, entry_INT80_32), |
| 127 | 127 | #endif |
| @@ -1234,10 +1234,6 @@ void setup_ghcb(void) · 1233 unmodified lines | ||
| 1234 | 1234 | if (!cc_platform_has(CC_ATTR_GUEST_STATE_ENCRYPT)) |
| 1235 | 1235 | return; |
| 1236 | 1236 | |
| 1237 | − /* First make sure the hypervisor talks a supported protocol. */ | |
| 1238 | − if (!sev_es_negotiate_protocol()) | |
| 1239 | − sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); | |
| 1240 | − | |
| 1241 | 1237 | /* |
| 1242 | 1238 | * Check whether the runtime #VC exception handler is active. It uses |
| 1243 | 1239 | * the per-CPU GHCB page which is set up by sev_es_init_vc_handling(). |
| @@ -1254,6 +1250,13 @@ void setup_ghcb(void) · 10 unmodified lines | ||
| 1254 | 1250 | return; |
| 1255 | 1251 | } |
| 1256 | 1252 | |
| 1253 | + /* | |
| 1254 | + * Make sure the hypervisor talks a supported protocol. | |
| 1255 | + * This gets called only in the BSP boot phase. | |
| 1256 | + */ | |
| 1257 | + if (!sev_es_negotiate_protocol()) | |
| 1258 | + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); | |
| 1259 | + | |
| 1257 | 1260 | /* |
| 1258 | 1261 | * Clear the boot_ghcb. The first exception comes in before the bss |
| 1259 | 1262 | * section is cleared. |
| @@ -175,9 +175,6 @@ int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) · 174 unmodified lines | ||
| 175 | 175 | frame = get_sigframe(ksig, regs, sizeof(struct rt_sigframe), &fp); |
| 176 | 176 | uc_flags = frame_uc_flags(regs); |
| 177 | 177 | |
| 178 | − if (setup_signal_shadow_stack(ksig)) | |
| 179 | − return -EFAULT; | |
| 180 | − | |
| 181 | 178 | if (!user_access_begin(frame, sizeof(*frame))) |
| 182 | 179 | return -EFAULT; |
| 183 | 180 | |
| @@ -198,6 +195,9 @@ int x64_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) · 14 unmodified lines | ||
| 198 | 195 | return -EFAULT; |
| 199 | 196 | } |
| 200 | 197 | |
| 198 | + if (setup_signal_shadow_stack(ksig)) | |
| 199 | + return -EFAULT; | |
| 200 | + | |
| 201 | 201 | /* Set up registers for signal handler */ |
| 202 | 202 | regs->di = ksig->sig; |
| 203 | 203 | /* In case the signal handler was declared without prototypes */ |
| @@ -182,6 +182,7 @@ static int kvm_mmu_rmaps_stat_release(struct inode *inode, struct file *file) · 181 unmodified lines | ||
| 182 | 182 | } |
| 183 | 183 | |
| 184 | 184 | static const struct file_operations mmu_rmaps_stat_fops = { |
| 185 | + .owner = THIS_MODULE, | |
| 185 | 186 | .open = kvm_mmu_rmaps_stat_open, |
| 186 | 187 | .read = seq_read, |
| 187 | 188 | .llseek = seq_lseek, |
| @@ -1855,15 +1855,17 @@ void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) · 1854 unmodified lines | ||
| 1855 | 1855 | bool old_paging = is_paging(vcpu); |
| 1856 | 1856 | |
| 1857 | 1857 | #ifdef CONFIG_X86_64 |
| 1858 | − if (vcpu->arch.efer & EFER_LME && !vcpu->arch.guest_state_protected) { | |
| 1858 | + if (vcpu->arch.efer & EFER_LME) { | |
| 1859 | 1859 | if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { |
| 1860 | 1860 | vcpu->arch.efer |= EFER_LMA; |
| 1861 | − svm->vmcb->save.efer |= EFER_LMA | EFER_LME; | |
| 1861 | + if (!vcpu->arch.guest_state_protected) | |
| 1862 | + svm->vmcb->save.efer |= EFER_LMA | EFER_LME; | |
| 1862 | 1863 | } |
| 1863 | 1864 | |
| 1864 | 1865 | if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) { |
| 1865 | 1866 | vcpu->arch.efer &= ~EFER_LMA; |
| 1866 | − svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME); | |
| 1867 | + if (!vcpu->arch.guest_state_protected) | |
| 1868 | + svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME); | |
| 1867 | 1869 | } |
| 1868 | 1870 | } |
| 1869 | 1871 | #endif |
| @@ -5518,8 +5518,8 @@ static void kvm_vcpu_ioctl_x86_get_xsave2(struct kvm_vcpu *vcpu, · 5517 unmodified lines | ||
| 5518 | 5518 | static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu, |
| 5519 | 5519 | struct kvm_xsave *guest_xsave) |
| 5520 | 5520 | { |
| 5521 | − return kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region, | |
| 5522 | − sizeof(guest_xsave->region)); | |
| 5521 | + kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region, | |
| 5522 | + sizeof(guest_xsave->region)); | |
| 5523 | 5523 | } |
| 5524 | 5524 | |
| 5525 | 5525 | static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu, |
| @@ -13031,7 +13031,10 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu) · 7505 unmodified lines | ||
| 13031 | 13031 | if (vcpu->arch.guest_state_protected) |
| 13032 | 13032 | return true; |
| 13033 | 13033 | |
| 13034 | − return vcpu->arch.preempted_in_kernel; | |
| 13034 | + if (vcpu != kvm_get_running_vcpu()) | |
| 13035 | + return vcpu->arch.preempted_in_kernel; | |
| 13036 | + | |
| 13037 | + return static_call(kvm_x86_get_cpl)(vcpu) == 0; | |
| 13035 | 13038 | } |
| 13036 | 13039 | |
| 13037 | 13040 | unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu) |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #include <asm/msr.h> |
| 33 | 33 | #include <asm/cmdline.h> |
| 34 | 34 | #include <asm/sev.h> |
| 35 | +#include <asm/ia32.h> | |
| 35 | 36 | |
| 36 | 37 | #include "mm_internal.h" |
| 37 | 38 | |
| @@ -481,6 +482,16 @@ void __init sme_early_init(void) · 443 unmodified lines | ||
| 481 | 482 | */ |
| 482 | 483 | if (sev_status & MSR_AMD64_SEV_ES_ENABLED) |
| 483 | 484 | x86_cpuinit.parallel_bringup = false; |
| 485 | + | |
| 486 | + /* | |
| 487 | + * The VMM is capable of injecting interrupt 0x80 and triggering the | |
| 488 | + * compatibility syscall path. | |
| 489 | + * | |
| 490 | + * By default, the 32-bit emulation is disabled in order to ensure | |
| 491 | + * the safety of the VM. | |
| 492 | + */ | |
| 493 | + if (sev_status & MSR_AMD64_SEV_ENABLED) | |
| 494 | + ia32_disable(); | |
| 484 | 495 | } |
| 485 | 496 | |
| 486 | 497 | void __init mem_encrypt_free_decrypted_mem(void) |
| @@ -3025,3 +3025,49 @@ void arch_bpf_stack_walk(bool (*consume_fn)(void *cookie, u64 ip, u64 sp, u64 bp · 3024 unmodified lines | ||
| 3025 | 3025 | #endif |
| 3026 | 3026 | WARN(1, "verification of programs using bpf_throw should have failed\n"); |
| 3027 | 3027 | } |
| 3028 | + | |
| 3029 | +void bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke, | |
| 3030 | + struct bpf_prog *new, struct bpf_prog *old) | |
| 3031 | +{ | |
| 3032 | + u8 *old_addr, *new_addr, *old_bypass_addr; | |
| 3033 | + int ret; | |
| 3034 | + | |
| 3035 | + old_bypass_addr = old ? NULL : poke->bypass_addr; | |
| 3036 | + old_addr = old ? (u8 *)old->bpf_func + poke->adj_off : NULL; | |
| 3037 | + new_addr = new ? (u8 *)new->bpf_func + poke->adj_off : NULL; | |
| 3038 | + | |
| 3039 | + /* | |
| 3040 | + * On program loading or teardown, the program's kallsym entry | |
| 3041 | + * might not be in place, so we use __bpf_arch_text_poke to skip | |
| 3042 | + * the kallsyms check. | |
| 3043 | + */ | |
| 3044 | + if (new) { | |
| 3045 | + ret = __bpf_arch_text_poke(poke->tailcall_target, | |
| 3046 | + BPF_MOD_JUMP, | |
| 3047 | + old_addr, new_addr); | |
| 3048 | + BUG_ON(ret < 0); | |
| 3049 | + if (!old) { | |
| 3050 | + ret = __bpf_arch_text_poke(poke->tailcall_bypass, | |
| 3051 | + BPF_MOD_JUMP, | |
| 3052 | + poke->bypass_addr, | |
| 3053 | + NULL); | |
| 3054 | + BUG_ON(ret < 0); | |
| 3055 | + } | |
| 3056 | + } else { | |
| 3057 | + ret = __bpf_arch_text_poke(poke->tailcall_bypass, | |
| 3058 | + BPF_MOD_JUMP, | |
| 3059 | + old_bypass_addr, | |
| 3060 | + poke->bypass_addr); | |
| 3061 | + BUG_ON(ret < 0); | |
| 3062 | + /* let other CPUs finish the execution of program | |
| 3063 | + * so that it will not possible to expose them | |
| 3064 | + * to invalid nop, stack unwind, nop state | |
| 3065 | + */ | |
| 3066 | + if (!ret) | |
| 3067 | + synchronize_rcu(); | |
| 3068 | + ret = __bpf_arch_text_poke(poke->tailcall_target, | |
| 3069 | + BPF_MOD_JUMP, | |
| 3070 | + old_addr, NULL); | |
| 3071 | + BUG_ON(ret < 0); | |
| 3072 | + } | |
| 3073 | +} | |
| @@ -33,9 +33,12 @@ EXPORT_SYMBOL_GPL(hypercall_page); · 32 unmodified lines | ||
| 33 | 33 | * and xen_vcpu_setup for details. By default it points to share_info->vcpu_info |
| 34 | 34 | * but during boot it is switched to point to xen_vcpu_info. |
| 35 | 35 | * The pointer is used in xen_evtchn_do_upcall to acknowledge pending events. |
| 36 | + * Make sure that xen_vcpu_info doesn't cross a page boundary by making it | |
| 37 | + * cache-line aligned (the struct is guaranteed to have a size of 64 bytes, | |
| 38 | + * which matches the cache line size of 64-bit x86 processors). | |
| 36 | 39 | */ |
| 37 | 40 | DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); |
| 38 | −DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); | |
| 41 | +DEFINE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info); | |
| 39 | 42 | |
| 40 | 43 | /* Linux <-> Xen vCPU id mapping */ |
| 41 | 44 | DEFINE_PER_CPU(uint32_t, xen_vcpu_id); |
| @@ -160,6 +163,7 @@ void xen_vcpu_setup(int cpu) · 118 unmodified lines | ||
| 160 | 163 | int err; |
| 161 | 164 | struct vcpu_info *vcpup; |
| 162 | 165 | |
| 166 | + BUILD_BUG_ON(sizeof(*vcpup) > SMP_CACHE_BYTES); | |
| 163 | 167 | BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info); |
| 164 | 168 | |
| 165 | 169 | /* |
| @@ -704,7 +704,7 @@ static struct trap_array_entry trap_array[] = { · 703 unmodified lines | ||
| 704 | 704 | TRAP_ENTRY(exc_int3, false ), |
| 705 | 705 | TRAP_ENTRY(exc_overflow, false ), |
| 706 | 706 | #ifdef CONFIG_IA32_EMULATION |
| 707 | − { entry_INT80_compat, xen_entry_INT80_compat, false }, | |
| 707 | + TRAP_ENTRY(int80_emulation, false ), | |
| 708 | 708 | #endif |
| 709 | 709 | TRAP_ENTRY(exc_page_fault, false ), |
| 710 | 710 | TRAP_ENTRY(exc_divide_error, false ), |
| @@ -156,7 +156,7 @@ xen_pv_trap asm_xenpv_exc_machine_check · 155 unmodified lines | ||
| 156 | 156 | #endif /* CONFIG_X86_MCE */ |
| 157 | 157 | xen_pv_trap asm_exc_simd_coprocessor_error |
| 158 | 158 | #ifdef CONFIG_IA32_EMULATION |
| 159 | −xen_pv_trap entry_INT80_compat | |
| 159 | +xen_pv_trap asm_int80_emulation | |
| 160 | 160 | #endif |
| 161 | 161 | xen_pv_trap asm_exc_xen_unknown_trap |
| 162 | 162 | xen_pv_trap asm_exc_xen_hypervisor_callback |
| @@ -21,7 +21,7 @@ extern void *xen_initial_gdt; · 20 unmodified lines | ||
| 21 | 21 | struct trap_info; |
| 22 | 22 | void xen_copy_trap_info(struct trap_info *traps); |
| 23 | 23 | |
| 24 | −DECLARE_PER_CPU(struct vcpu_info, xen_vcpu_info); | |
| 24 | +DECLARE_PER_CPU_ALIGNED(struct vcpu_info, xen_vcpu_info); | |
| 25 | 25 | DECLARE_PER_CPU(unsigned long, xen_cr3); |
| 26 | 26 | DECLARE_PER_CPU(unsigned long, xen_current_cr3); |
| 27 | 27 | |
| @@ -425,6 +425,8 @@ void bdev_set_nr_sectors(struct block_device *bdev, sector_t sectors) · 424 unmodified lines | ||
| 425 | 425 | |
| 426 | 426 | void bdev_add(struct block_device *bdev, dev_t dev) |
| 427 | 427 | { |
| 428 | + if (bdev_stable_writes(bdev)) | |
| 429 | + mapping_set_stable_writes(bdev->bd_inode->i_mapping); | |
| 428 | 430 | bdev->bd_dev = dev; |
| 429 | 431 | bdev->bd_inode->i_rdev = dev; |
| 430 | 432 | bdev->bd_inode->i_ino = dev; |
| @@ -577,6 +577,7 @@ static void blkg_destroy_all(struct gendisk *disk) · 576 unmodified lines | ||
| 577 | 577 | struct request_queue *q = disk->queue; |
| 578 | 578 | struct blkcg_gq *blkg, *n; |
| 579 | 579 | int count = BLKG_DESTROY_BATCH_SIZE; |
| 580 | + int i; | |
| 580 | 581 | |
| 581 | 582 | restart: |
| 582 | 583 | spin_lock_irq(&q->queue_lock); |
| @@ -602,6 +603,18 @@ restart: · 19 unmodified lines | ||
| 602 | 603 | } |
| 603 | 604 | } |
| 604 | 605 | |
| 606 | + /* | |
| 607 | + * Mark policy deactivated since policy offline has been done, and | |
| 608 | + * the free is scheduled, so future blkcg_deactivate_policy() can | |
| 609 | + * be bypassed | |
| 610 | + */ | |
| 611 | + for (i = 0; i < BLKCG_MAX_POLS; i++) { | |
| 612 | + struct blkcg_policy *pol = blkcg_policy[i]; | |
| 613 | + | |
| 614 | + if (pol) | |
| 615 | + __clear_bit(pol->plid, q->blkcg_pols); | |
| 616 | + } | |
| 617 | + | |
| 605 | 618 | q->root_blkg = NULL; |
| 606 | 619 | spin_unlock_irq(&q->queue_lock); |
| 607 | 620 | } |
| @@ -249,8 +249,6 @@ static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, · 248 unmodified lines | ||
| 249 | 249 | { |
| 250 | 250 | struct blkcg_gq *blkg; |
| 251 | 251 | |
| 252 | − WARN_ON_ONCE(!rcu_read_lock_held()); | |
| 253 | − | |
| 254 | 252 | if (blkcg == &blkcg_root) |
| 255 | 253 | return q->root_blkg; |
| 256 | 254 | |
| @@ -501,9 +501,17 @@ static inline void bio_check_ro(struct bio *bio) · 500 unmodified lines | ||
| 501 | 501 | if (op_is_write(bio_op(bio)) && bdev_read_only(bio->bi_bdev)) { |
| 502 | 502 | if (op_is_flush(bio->bi_opf) && !bio_sectors(bio)) |
| 503 | 503 | return; |
| 504 | − pr_warn_ratelimited("Trying to write to read-only block-device %pg\n", | |
| 505 | − bio->bi_bdev); | |
| 506 | − /* Older lvm-tools actually trigger this */ | |
| 504 | + | |
| 505 | + if (bio->bi_bdev->bd_ro_warned) | |
| 506 | + return; | |
| 507 | + | |
| 508 | + bio->bi_bdev->bd_ro_warned = true; | |
| 509 | + /* | |
| 510 | + * Use ioctl to set underlying disk of raid/dm to read-only | |
| 511 | + * will trigger this. | |
| 512 | + */ | |
| 513 | + pr_warn("Trying to write to read-only block-device %pg\n", | |
| 514 | + bio->bi_bdev); | |
| 507 | 515 | } |
| 508 | 516 | } |
| 509 | 517 | |
| @@ -1512,14 +1512,26 @@ void blk_mq_delay_kick_requeue_list(struct request_queue *q, · 1511 unmodified lines | ||
| 1512 | 1512 | } |
| 1513 | 1513 | EXPORT_SYMBOL(blk_mq_delay_kick_requeue_list); |
| 1514 | 1514 | |
| 1515 | +static bool blk_is_flush_data_rq(struct request *rq) | |
| 1516 | +{ | |
| 1517 | + return (rq->rq_flags & RQF_FLUSH_SEQ) && !is_flush_rq(rq); | |
| 1518 | +} | |
| 1519 | + | |
| 1515 | 1520 | static bool blk_mq_rq_inflight(struct request *rq, void *priv) |
| 1516 | 1521 | { |
| 1517 | 1522 | /* |
| 1518 | 1523 | * If we find a request that isn't idle we know the queue is busy |
| 1519 | 1524 | * as it's checked in the iter. |
| 1520 | 1525 | * Return false to stop the iteration. |
| 1526 | + * | |
| 1527 | + * In case of queue quiesce, if one flush data request is completed, | |
| 1528 | + * don't count it as inflight given the flush sequence is suspended, | |
| 1529 | + * and the original flush data request is invisible to driver, just | |
| 1530 | + * like other pending requests because of quiesce | |
| 1521 | 1531 | */ |
| 1522 | − if (blk_mq_request_started(rq)) { | |
| 1532 | + if (blk_mq_request_started(rq) && !(blk_queue_quiesced(rq->q) && | |
| 1533 | + blk_is_flush_data_rq(rq) && | |
| 1534 | + blk_mq_request_completed(rq))) { | |
| 1523 | 1535 | bool *busy = priv; |
| 1524 | 1536 | |
| 1525 | 1537 | *busy = true; |
| @@ -2858,11 +2870,8 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q, · 1332 unmodified lines | ||
| 2858 | 2870 | }; |
| 2859 | 2871 | struct request *rq; |
| 2860 | 2872 | |
| 2861 | − if (unlikely(bio_queue_enter(bio))) | |
| 2862 | − return NULL; | |
| 2863 | − | |
| 2864 | 2873 | if (blk_mq_attempt_bio_merge(q, bio, nsegs)) |
| 2865 | − goto queue_exit; | |
| 2874 | + return NULL; | |
| 2866 | 2875 | |
| 2867 | 2876 | rq_qos_throttle(q, bio); |
| 2868 | 2877 | |
| @@ -2878,35 +2887,23 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q, · 9 unmodified lines | ||
| 2878 | 2887 | rq_qos_cleanup(q, bio); |
| 2879 | 2888 | if (bio->bi_opf & REQ_NOWAIT) |
| 2880 | 2889 | bio_wouldblock_error(bio); |
| 2881 | −queue_exit: | |
| 2882 | − blk_queue_exit(q); | |
| 2883 | 2890 | return NULL; |
| 2884 | 2891 | } |
| 2885 | 2892 | |
| 2886 | −static inline struct request *blk_mq_get_cached_request(struct request_queue *q, | |
| 2887 | − struct blk_plug *plug, struct bio **bio, unsigned int nsegs) | |
| 2893 | +/* return true if this @rq can be used for @bio */ | |
| 2894 | +static bool blk_mq_can_use_cached_rq(struct request *rq, struct blk_plug *plug, | |
| 2895 | + struct bio *bio) | |
| 2888 | 2896 | { |
| 2889 | − struct request *rq; | |
| 2890 | − enum hctx_type type, hctx_type; | |
| 2897 | + enum hctx_type type = blk_mq_get_hctx_type(bio->bi_opf); | |
| 2898 | + enum hctx_type hctx_type = rq->mq_hctx->type; | |
| 2891 | 2899 | |
| 2892 | − if (!plug) | |
| 2893 | − return NULL; | |
| 2894 | − rq = rq_list_peek(&plug->cached_rq); | |
| 2895 | − if (!rq || rq->q != q) | |
| 2896 | − return NULL; | |
| 2897 | − | |
| 2898 | − if (blk_mq_attempt_bio_merge(q, *bio, nsegs)) { | |
| 2899 | − *bio = NULL; | |
| 2900 | − return NULL; | |
| 2901 | − } | |
| 2900 | + WARN_ON_ONCE(rq_list_peek(&plug->cached_rq) != rq); | |
| 2902 | 2901 | |
| 2903 | − type = blk_mq_get_hctx_type((*bio)->bi_opf); | |
| 2904 | − hctx_type = rq->mq_hctx->type; | |
| 2905 | 2902 | if (type != hctx_type && |
| 2906 | 2903 | !(type == HCTX_TYPE_READ && hctx_type == HCTX_TYPE_DEFAULT)) |
| 2907 | − return NULL; | |
| 2908 | − if (op_is_flush(rq->cmd_flags) != op_is_flush((*bio)->bi_opf)) | |
| 2909 | − return NULL; | |
| 2904 | + return false; | |
| 2905 | + if (op_is_flush(rq->cmd_flags) != op_is_flush(bio->bi_opf)) | |
| 2906 | + return false; | |
| 2910 | 2907 | |
| 2911 | 2908 | /* |
| 2912 | 2909 | * If any qos ->throttle() end up blocking, we will have flushed the |
| @@ -2914,12 +2911,12 @@ static inline struct request *blk_mq_get_cached_request(struct request_queue *q, · 1 unmodified line | ||
| 2914 | 2911 | * before we throttle. |
| 2915 | 2912 | */ |
| 2916 | 2913 | plug->cached_rq = rq_list_next(rq); |
| 2917 | − rq_qos_throttle(q, *bio); | |
| 2914 | + rq_qos_throttle(rq->q, bio); | |
| 2918 | 2915 | |
| 2919 | 2916 | blk_mq_rq_time_init(rq, 0); |
| 2920 | − rq->cmd_flags = (*bio)->bi_opf; | |
| 2917 | + rq->cmd_flags = bio->bi_opf; | |
| 2921 | 2918 | INIT_LIST_HEAD(&rq->queuelist); |
| 2922 | − return rq; | |
| 2919 | + return true; | |
| 2923 | 2920 | } |
| 2924 | 2921 | |
| 2925 | 2922 | static void bio_set_ioprio(struct bio *bio) |
| @@ -2949,7 +2946,7 @@ void blk_mq_submit_bio(struct bio *bio) · 23 unmodified lines | ||
| 2949 | 2946 | struct blk_plug *plug = blk_mq_plug(bio); |
| 2950 | 2947 | const int is_sync = op_is_sync(bio->bi_opf); |
| 2951 | 2948 | struct blk_mq_hw_ctx *hctx; |
| 2952 | − struct request *rq; | |
| 2949 | + struct request *rq = NULL; | |
| 2953 | 2950 | unsigned int nr_segs = 1; |
| 2954 | 2951 | blk_status_t ret; |
| 2955 | 2952 | |
| @@ -2960,20 +2957,36 @@ void blk_mq_submit_bio(struct bio *bio) · 4 unmodified lines | ||
| 2960 | 2957 | return; |
| 2961 | 2958 | } |
| 2962 | 2959 | |
| 2963 | − if (!bio_integrity_prep(bio)) | |
| 2964 | − return; | |
| 2965 | − | |
| 2966 | 2960 | bio_set_ioprio(bio); |
| 2967 | 2961 | |
| 2968 | − rq = blk_mq_get_cached_request(q, plug, &bio, nr_segs); | |
| 2969 | − if (!rq) { | |
| 2970 | − if (!bio) | |
| 2962 | + if (plug) { | |
| 2963 | + rq = rq_list_peek(&plug->cached_rq); | |
| 2964 | + if (rq && rq->q != q) | |
| 2965 | + rq = NULL; | |
| 2966 | + } | |
| 2967 | + if (rq) { | |
| 2968 | + if (!bio_integrity_prep(bio)) | |
| 2971 | 2969 | return; |
| 2972 | − rq = blk_mq_get_new_requests(q, plug, bio, nr_segs); | |
| 2973 | − if (unlikely(!rq)) | |
| 2970 | + if (blk_mq_attempt_bio_merge(q, bio, nr_segs)) | |
| 2974 | 2971 | return; |
| 2972 | + if (blk_mq_can_use_cached_rq(rq, plug, bio)) | |
| 2973 | + goto done; | |
| 2974 | + percpu_ref_get(&q->q_usage_counter); | |
| 2975 | + } else { | |
| 2976 | + if (unlikely(bio_queue_enter(bio))) | |
| 2977 | + return; | |
| 2978 | + if (!bio_integrity_prep(bio)) | |
| 2979 | + goto fail; | |
| 2975 | 2980 | } |
| 2976 | 2981 | |
| 2982 | + rq = blk_mq_get_new_requests(q, plug, bio, nr_segs); | |
| 2983 | + if (unlikely(!rq)) { | |
| 2984 | +fail: | |
| 2985 | + blk_queue_exit(q); | |
| 2986 | + return; | |
| 2987 | + } | |
| 2988 | + | |
| 2989 | +done: | |
| 2977 | 2990 | trace_block_getrq(bio); |
| 2978 | 2991 | |
| 2979 | 2992 | rq_qos_track(q, rq, bio); |
| @@ -163,38 +163,15 @@ EXPORT_SYMBOL(blk_pre_runtime_resume); · 162 unmodified lines | ||
| 163 | 163 | * @q: the queue of the device |
| 164 | 164 | * |
| 165 | 165 | * Description: |
| 166 | − * For historical reasons, this routine merely calls blk_set_runtime_active() | |
| 167 | − * to do the real work of restarting the queue. It does this regardless of | |
| 168 | − * whether the device's runtime-resume succeeded; even if it failed the | |
| 166 | + * Restart the queue of a runtime suspended device. It does this regardless | |
| 167 | + * of whether the device's runtime-resume succeeded; even if it failed the | |
| 169 | 168 | * driver or error handler will need to communicate with the device. |
| 170 | 169 | * |
| 171 | 170 | * This function should be called near the end of the device's |
| 172 | − * runtime_resume callback. | |
| 171 | + * runtime_resume callback to correct queue runtime PM status and re-enable | |
| 172 | + * peeking requests from the queue. | |
| 173 | 173 | */ |
| 174 | 174 | void blk_post_runtime_resume(struct request_queue *q) |
| 175 | −{ | |
| 176 | − blk_set_runtime_active(q); | |
| 177 | −} | |
| 178 | −EXPORT_SYMBOL(blk_post_runtime_resume); | |
| 179 | − | |
| 180 | −/** | |
| 181 | − * blk_set_runtime_active - Force runtime status of the queue to be active | |
| 182 | − * @q: the queue of the device | |
| 183 | − * | |
| 184 | − * If the device is left runtime suspended during system suspend the resume | |
| 185 | − * hook typically resumes the device and corrects runtime status | |
| 186 | − * accordingly. However, that does not affect the queue runtime PM status | |
| 187 | − * which is still "suspended". This prevents processing requests from the | |
| 188 | − * queue. | |
| 189 | − * | |
| 190 | − * This function can be used in driver's resume hook to correct queue | |
| 191 | − * runtime PM status and re-enable peeking requests from the queue. It | |
| 192 | − * should be called before first request is added to the queue. | |
| 193 | − * | |
| 194 | − * This function is also called by blk_post_runtime_resume() for | |
| 195 | − * runtime resumes. It does everything necessary to restart the queue. | |
| 196 | − */ | |
| 197 | −void blk_set_runtime_active(struct request_queue *q) | |
| 198 | 175 | { |
| 199 | 176 | int old_status; |
| 200 | 177 | |
| @@ -211,4 +188,4 @@ void blk_set_runtime_active(struct request_queue *q) · 10 unmodified lines | ||
| 211 | 188 | if (old_status != RPM_ACTIVE) |
| 212 | 189 | blk_clear_pm_only(q); |
| 213 | 190 | } |
| 214 | −EXPORT_SYMBOL(blk_set_runtime_active); | |
| 191 | +EXPORT_SYMBOL(blk_post_runtime_resume); | |
| @@ -615,6 +615,7 @@ static ssize_t queue_wb_lat_store(struct request_queue *q, const char *page, · 614 unmodified lines | ||
| 615 | 615 | QUEUE_RW_ENTRY(queue_wb_lat, "wbt_lat_usec"); |
| 616 | 616 | #endif |
| 617 | 617 | |
| 618 | +/* Common attributes for bio-based and request-based queues. */ | |
| 618 | 619 | static struct attribute *queue_attrs[] = { |
| 619 | 620 | &queue_ra_entry.attr, |
| 620 | 621 | &queue_max_hw_sectors_entry.attr, |
| @@ -659,6 +660,7 @@ static struct attribute *queue_attrs[] = { · 38 unmodified lines | ||
| 659 | 660 | NULL, |
| 660 | 661 | }; |
| 661 | 662 | |
| 663 | +/* Request-based queue attributes that are not relevant for bio-based queues. */ | |
| 662 | 664 | static struct attribute *blk_mq_queue_attrs[] = { |
| 663 | 665 | &queue_requests_entry.attr, |
| 664 | 666 | &elv_iosched_entry.attr, |
| @@ -1320,6 +1320,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global) · 1319 unmodified lines | ||
| 1320 | 1320 | tg_bps_limit(tg, READ), tg_bps_limit(tg, WRITE), |
| 1321 | 1321 | tg_iops_limit(tg, READ), tg_iops_limit(tg, WRITE)); |
| 1322 | 1322 | |
| 1323 | + rcu_read_lock(); | |
| 1323 | 1324 | /* |
| 1324 | 1325 | * Update has_rules[] flags for the updated tg's subtree. A tg is |
| 1325 | 1326 | * considered to have rules if either the tg itself or any of its |
| @@ -1347,6 +1348,7 @@ static void tg_conf_updated(struct throtl_grp *tg, bool global) · 21 unmodified lines | ||
| 1347 | 1348 | this_tg->latency_target = max(this_tg->latency_target, |
| 1348 | 1349 | parent_tg->latency_target); |
| 1349 | 1350 | } |
| 1351 | + rcu_read_unlock(); | |
| 1350 | 1352 | |
| 1351 | 1353 | /* |
| 1352 | 1354 | * We're already holding queue_lock and know @tg is valid. Let's |
| @@ -502,6 +502,16 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev) · 501 unmodified lines | ||
| 502 | 502 | return ret; |
| 503 | 503 | } |
| 504 | 504 | |
| 505 | +static int ivpu_boot_pwr_domain_disable(struct ivpu_device *vdev) | |
| 506 | +{ | |
| 507 | + ivpu_boot_dpu_active_drive(vdev, false); | |
| 508 | + ivpu_boot_pwr_island_isolation_drive(vdev, true); | |
| 509 | + ivpu_boot_pwr_island_trickle_drive(vdev, false); | |
| 510 | + ivpu_boot_pwr_island_drive(vdev, false); | |
| 511 | + | |
| 512 | + return ivpu_boot_wait_for_pwr_island_status(vdev, 0x0); | |
| 513 | +} | |
| 514 | + | |
| 505 | 515 | static void ivpu_boot_no_snoop_enable(struct ivpu_device *vdev) |
| 506 | 516 | { |
| 507 | 517 | u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES); |
| @@ -600,25 +610,17 @@ static int ivpu_hw_37xx_info_init(struct ivpu_device *vdev) · 92 unmodified lines | ||
| 600 | 610 | |
| 601 | 611 | static int ivpu_hw_37xx_reset(struct ivpu_device *vdev) |
| 602 | 612 | { |
| 603 | − int ret; | |
| 604 | − u32 val; | |
| 605 | − | |
| 606 | − if (IVPU_WA(punit_disabled)) | |
| 607 | − return 0; | |
| 613 | + int ret = 0; | |
| 608 | 614 | |
| 609 | − ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US); | |
| 610 | − if (ret) { | |
| 611 | − ivpu_err(vdev, "Timed out waiting for TRIGGER bit\n"); | |
| 612 | − return ret; | |
| 615 | + if (ivpu_boot_pwr_domain_disable(vdev)) { | |
| 616 | + ivpu_err(vdev, "Failed to disable power domain\n"); | |
| 617 | + ret = -EIO; | |
| 613 | 618 | } |
| 614 | 619 | |
| 615 | − val = REGB_RD32(VPU_37XX_BUTTRESS_VPU_IP_RESET); | |
| 616 | − val = REG_SET_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, val); | |
| 617 | − REGB_WR32(VPU_37XX_BUTTRESS_VPU_IP_RESET, val); | |
| 618 | − | |
| 619 | − ret = REGB_POLL_FLD(VPU_37XX_BUTTRESS_VPU_IP_RESET, TRIGGER, 0, TIMEOUT_US); | |
| 620 | − if (ret) | |
| 621 | − ivpu_err(vdev, "Timed out waiting for RESET completion\n"); | |
| 620 | + if (ivpu_pll_disable(vdev)) { | |
| 621 | + ivpu_err(vdev, "Failed to disable PLL\n"); | |
| 622 | + ret = -EIO; | |
| 623 | + } | |
| 622 | 624 | |
| 623 | 625 | return ret; |
| 624 | 626 | } |
| @@ -651,10 +653,6 @@ static int ivpu_hw_37xx_power_up(struct ivpu_device *vdev) · 26 unmodified lines | ||
| 651 | 653 | { |
| 652 | 654 | int ret; |
| 653 | 655 | |
| 654 | − ret = ivpu_hw_37xx_reset(vdev); | |
| 655 | − if (ret) | |
| 656 | − ivpu_warn(vdev, "Failed to reset HW: %d\n", ret); | |
| 657 | − | |
| 658 | 656 | ret = ivpu_hw_37xx_d0i3_disable(vdev); |
| 659 | 657 | if (ret) |
| 660 | 658 | ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret); |
| @@ -722,11 +720,11 @@ static int ivpu_hw_37xx_power_down(struct ivpu_device *vdev) · 61 unmodified lines | ||
| 722 | 720 | { |
| 723 | 721 | int ret = 0; |
| 724 | 722 | |
| 725 | − if (!ivpu_hw_37xx_is_idle(vdev) && ivpu_hw_37xx_reset(vdev)) | |
| 726 | − ivpu_err(vdev, "Failed to reset the VPU\n"); | |
| 723 | + if (!ivpu_hw_37xx_is_idle(vdev)) | |
| 724 | + ivpu_warn(vdev, "VPU not idle during power down\n"); | |
| 727 | 725 | |
| 728 | − if (ivpu_pll_disable(vdev)) { | |
| 729 | − ivpu_err(vdev, "Failed to disable PLL\n"); | |
| 726 | + if (ivpu_hw_37xx_reset(vdev)) { | |
| 727 | + ivpu_err(vdev, "Failed to reset VPU\n"); | |
| 730 | 728 | ret = -EIO; |
| 731 | 729 | } |
| 732 | 730 | |
| @@ -250,9 +250,6 @@ int ivpu_rpm_get_if_active(struct ivpu_device *vdev) · 249 unmodified lines | ||
| 250 | 250 | { |
| 251 | 251 | int ret; |
| 252 | 252 | |
| 253 | − ivpu_dbg(vdev, RPM, "rpm_get_if_active count %d\n", | |
| 254 | − atomic_read(&vdev->drm.dev->power.usage_count)); | |
| 255 | − | |
| 256 | 253 | ret = pm_runtime_get_if_active(vdev->drm.dev, false); |
| 257 | 254 | drm_WARN_ON(&vdev->drm, ret < 0); |
| 258 | 255 | |
| @@ -253,8 +253,7 @@ static const struct backlight_ops acpi_backlight_ops = { · 252 unmodified lines | ||
| 253 | 253 | static int video_get_max_state(struct thermal_cooling_device *cooling_dev, |
| 254 | 254 | unsigned long *state) |
| 255 | 255 | { |
| 256 | − struct acpi_device *device = cooling_dev->devdata; | |
| 257 | − struct acpi_video_device *video = acpi_driver_data(device); | |
| 256 | + struct acpi_video_device *video = cooling_dev->devdata; | |
| 258 | 257 | |
| 259 | 258 | *state = video->brightness->count - ACPI_VIDEO_FIRST_LEVEL - 1; |
| 260 | 259 | return 0; |
| @@ -263,8 +262,7 @@ static int video_get_max_state(struct thermal_cooling_device *cooling_dev, · 2 unmodified lines | ||
| 263 | 262 | static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, |
| 264 | 263 | unsigned long *state) |
| 265 | 264 | { |
| 266 | − struct acpi_device *device = cooling_dev->devdata; | |
| 267 | − struct acpi_video_device *video = acpi_driver_data(device); | |
| 265 | + struct acpi_video_device *video = cooling_dev->devdata; | |
| 268 | 266 | unsigned long long level; |
| 269 | 267 | int offset; |
| 270 | 268 | |
| @@ -283,8 +281,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, · 12 unmodified lines | ||
| 283 | 281 | static int |
| 284 | 282 | video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long state) |
| 285 | 283 | { |
| 286 | − struct acpi_device *device = cooling_dev->devdata; | |
| 287 | − struct acpi_video_device *video = acpi_driver_data(device); | |
| 284 | + struct acpi_video_device *video = cooling_dev->devdata; | |
| 288 | 285 | int level; |
| 289 | 286 | |
| 290 | 287 | if (state >= video->brightness->count - ACPI_VIDEO_FIRST_LEVEL) |
| @@ -1125,7 +1122,6 @@ static int acpi_video_bus_get_one_device(struct acpi_device *device, void *arg) · 834 unmodified lines | ||
| 1125 | 1122 | |
| 1126 | 1123 | strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME); |
| 1127 | 1124 | strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); |
| 1128 | − device->driver_data = data; | |
| 1129 | 1125 | |
| 1130 | 1126 | data->device_id = device_id; |
| 1131 | 1127 | data->video = video; |
| @@ -1747,8 +1743,8 @@ static void acpi_video_dev_register_backlight(struct acpi_video_device *device) · 615 unmodified lines | ||
| 1747 | 1743 | device->backlight->props.brightness = |
| 1748 | 1744 | acpi_video_get_brightness(device->backlight); |
| 1749 | 1745 | |
| 1750 | − device->cooling_dev = thermal_cooling_device_register("LCD", | |
| 1751 | − device->dev, &video_cooling_ops); | |
| 1746 | + device->cooling_dev = thermal_cooling_device_register("LCD", device, | |
| 1747 | + &video_cooling_ops); | |
| 1752 | 1748 | if (IS_ERR(device->cooling_dev)) { |
| 1753 | 1749 | /* |
| 1754 | 1750 | * Set cooling_dev to NULL so we don't crash trying to free it. |
| @@ -2031,7 +2027,7 @@ static int acpi_video_bus_add(struct acpi_device *device) · 276 unmodified lines | ||
| 2031 | 2027 | * HP ZBook Fury 16 G10 requires ACPI video's child devices have _PS0 |
| 2032 | 2028 | * evaluated to have functional panel brightness control. |
| 2033 | 2029 | */ |
| 2034 | − acpi_device_fix_up_power_extended(device); | |
| 2030 | + acpi_device_fix_up_power_children(device); | |
| 2035 | 2031 | |
| 2036 | 2032 | pr_info("%s [%s] (multi-head: %s rom: %s post: %s)\n", |
| 2037 | 2033 | ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), |
| @@ -397,6 +397,19 @@ void acpi_device_fix_up_power_extended(struct acpi_device *adev) · 396 unmodified lines | ||
| 397 | 397 | } |
| 398 | 398 | EXPORT_SYMBOL_GPL(acpi_device_fix_up_power_extended); |
| 399 | 399 | |
| 400 | +/** | |
| 401 | + * acpi_device_fix_up_power_children - Force a device's children into D0. | |
| 402 | + * @adev: Parent device object whose children's power state is to be fixed up. | |
| 403 | + * | |
| 404 | + * Call acpi_device_fix_up_power() for @adev's children so long as they | |
| 405 | + * are reported as present and enabled. | |
| 406 | + */ | |
| 407 | +void acpi_device_fix_up_power_children(struct acpi_device *adev) | |
| 408 | +{ | |
| 409 | + acpi_dev_for_each_child(adev, fix_up_power_if_applicable, NULL); | |
| 410 | +} | |
| 411 | +EXPORT_SYMBOL_GPL(acpi_device_fix_up_power_children); | |
| 412 | + | |
| 400 | 413 | int acpi_device_update_power(struct acpi_device *device, int *state_p) |
| 401 | 414 | { |
| 402 | 415 | int state; |
| @@ -592,7 +592,7 @@ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) · 591 unmodified lines | ||
| 592 | 592 | while (1) { |
| 593 | 593 | |
| 594 | 594 | if (cx->entry_method == ACPI_CSTATE_HALT) |
| 595 | − safe_halt(); | |
| 595 | + raw_safe_halt(); | |
| 596 | 596 | else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) { |
| 597 | 597 | io_idle(cx->address); |
| 598 | 598 | } else |
| @@ -447,6 +447,13 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { · 446 unmodified lines | ||
| 447 | 447 | DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"), |
| 448 | 448 | }, |
| 449 | 449 | }, |
| 450 | + { | |
| 451 | + /* Asus ExpertBook B1402CVA */ | |
| 452 | + .matches = { | |
| 453 | + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 454 | + DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"), | |
| 455 | + }, | |
| 456 | + }, | |
| 450 | 457 | { |
| 451 | 458 | /* Asus ExpertBook B1502CBA */ |
| 452 | 459 | .matches = { |
| @@ -1568,17 +1568,22 @@ static const struct iommu_ops *acpi_iommu_configure_id(struct device *dev, · 1567 unmodified lines | ||
| 1568 | 1568 | int err; |
| 1569 | 1569 | const struct iommu_ops *ops; |
| 1570 | 1570 | |
| 1571 | + /* Serialise to make dev->iommu stable under our potential fwspec */ | |
| 1572 | + mutex_lock(&iommu_probe_device_lock); | |
| 1571 | 1573 | /* |
| 1572 | 1574 | * If we already translated the fwspec there is nothing left to do, |
| 1573 | 1575 | * return the iommu_ops. |
| 1574 | 1576 | */ |
| 1575 | 1577 | ops = acpi_iommu_fwspec_ops(dev); |
| 1576 | − if (ops) | |
| 1578 | + if (ops) { | |
| 1579 | + mutex_unlock(&iommu_probe_device_lock); | |
| 1577 | 1580 | return ops; |
| 1581 | + } | |
| 1578 | 1582 | |
| 1579 | 1583 | err = iort_iommu_configure_id(dev, id_in); |
| 1580 | 1584 | if (err && err != -EPROBE_DEFER) |
| 1581 | 1585 | err = viot_iommu_configure(dev); |
| 1586 | + mutex_unlock(&iommu_probe_device_lock); | |
| 1582 | 1587 | |
| 1583 | 1588 | /* |
| 1584 | 1589 | * If we have reason to believe the IOMMU driver missed the initial |
| @@ -399,13 +399,13 @@ acpi_evaluate_reference(acpi_handle handle, · 398 unmodified lines | ||
| 399 | 399 | acpi_handle_debug(list->handles[i], "Found in reference list\n"); |
| 400 | 400 | } |
| 401 | 401 | |
| 402 | −end: | |
| 403 | 402 | if (ACPI_FAILURE(status)) { |
| 404 | 403 | list->count = 0; |
| 405 | 404 | kfree(list->handles); |
| 406 | 405 | list->handles = NULL; |
| 407 | 406 | } |
| 408 | 407 | |
| 408 | +end: | |
| 409 | 409 | kfree(buffer.pointer); |
| 410 | 410 | |
| 411 | 411 | return status; |
| @@ -1055,9 +1055,14 @@ int ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) · 1054 unmodified lines | ||
| 1055 | 1055 | * Ask the sd driver to issue START STOP UNIT on runtime suspend |
| 1056 | 1056 | * and resume and shutdown only. For system level suspend/resume, |
| 1057 | 1057 | * devices power state is handled directly by libata EH. |
| 1058 | + * Given that disks are always spun up on system resume, also | |
| 1059 | + * make sure that the sd driver forces runtime suspended disks | |
| 1060 | + * to be resumed to correctly reflect the power state of the | |
| 1061 | + * device. | |
| 1058 | 1062 | */ |
| 1059 | − sdev->manage_runtime_start_stop = true; | |
| 1060 | − sdev->manage_shutdown = true; | |
| 1063 | + sdev->manage_runtime_start_stop = 1; | |
| 1064 | + sdev->manage_shutdown = 1; | |
| 1065 | + sdev->force_runtime_start_on_system_start = 1; | |
| 1061 | 1066 | } |
| 1062 | 1067 | |
| 1063 | 1068 | /* |
| @@ -82,6 +82,9 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev · 81 unmodified lines | ||
| 82 | 82 | if (pnp_port_valid(idev, 1)) { |
| 83 | 83 | ctl_addr = devm_ioport_map(&idev->dev, |
| 84 | 84 | pnp_port_start(idev, 1), 1); |
| 85 | + if (!ctl_addr) | |
| 86 | + return -ENOMEM; | |
| 87 | + | |
| 85 | 88 | ap->ioaddr.altstatus_addr = ctl_addr; |
| 86 | 89 | ap->ioaddr.ctl_addr = ctl_addr; |
| 87 | 90 | ap->ops = &isapnp_port_ops; |
| @@ -144,7 +144,7 @@ static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store); · 143 unmodified lines | ||
| 144 | 144 | #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */ |
| 145 | 145 | #endif /* CONFIG_HOTPLUG_CPU */ |
| 146 | 146 | |
| 147 | −#ifdef CONFIG_KEXEC | |
| 147 | +#ifdef CONFIG_KEXEC_CORE | |
| 148 | 148 | #include <linux/kexec.h> |
| 149 | 149 | |
| 150 | 150 | static ssize_t crash_notes_show(struct device *dev, |
| @@ -189,14 +189,14 @@ static const struct attribute_group crash_note_cpu_attr_group = { · 38 unmodified lines | ||
| 189 | 189 | #endif |
| 190 | 190 | |
| 191 | 191 | static const struct attribute_group *common_cpu_attr_groups[] = { |
| 192 | −#ifdef CONFIG_KEXEC | |
| 192 | +#ifdef CONFIG_KEXEC_CORE | |
| 193 | 193 | &crash_note_cpu_attr_group, |
| 194 | 194 | #endif |
| 195 | 195 | NULL |
| 196 | 196 | }; |
| 197 | 197 | |
| 198 | 198 | static const struct attribute_group *hotplugable_cpu_attr_groups[] = { |
| 199 | −#ifdef CONFIG_KEXEC | |
| 199 | +#ifdef CONFIG_KEXEC_CORE | |
| 200 | 200 | &crash_note_cpu_attr_group, |
| 201 | 201 | #endif |
| 202 | 202 | NULL |
| @@ -362,6 +362,7 @@ void dev_coredumpm(struct device *dev, struct module *owner, · 361 unmodified lines | ||
| 362 | 362 | devcd->devcd_dev.class = &devcd_class; |
| 363 | 363 | |
| 364 | 364 | mutex_lock(&devcd->mutex); |
| 365 | + dev_set_uevent_suppress(&devcd->devcd_dev, true); | |
| 365 | 366 | if (device_add(&devcd->devcd_dev)) |
| 366 | 367 | goto put_device; |
| 367 | 368 | |
| @@ -376,6 +377,8 @@ void dev_coredumpm(struct device *dev, struct module *owner, · 8 unmodified lines | ||
| 376 | 377 | "devcoredump")) |
| 377 | 378 | dev_warn(dev, "devcoredump create_link failed\n"); |
| 378 | 379 | |
| 380 | + dev_set_uevent_suppress(&devcd->devcd_dev, false); | |
| 381 | + kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD); | |
| 379 | 382 | INIT_DELAYED_WORK(&devcd->del_wk, devcd_del); |
| 380 | 383 | schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT); |
| 381 | 384 | mutex_unlock(&devcd->mutex); |
| @@ -180,6 +180,9 @@ static inline unsigned long memblk_nr_poison(struct memory_block *mem) · 179 unmodified lines | ||
| 180 | 180 | } |
| 181 | 181 | #endif |
| 182 | 182 | |
| 183 | +/* | |
| 184 | + * Must acquire mem_hotplug_lock in write mode. | |
| 185 | + */ | |
| 183 | 186 | static int memory_block_online(struct memory_block *mem) |
| 184 | 187 | { |
| 185 | 188 | unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); |
| @@ -204,10 +207,11 @@ static int memory_block_online(struct memory_block *mem) · 18 unmodified lines | ||
| 204 | 207 | if (mem->altmap) |
| 205 | 208 | nr_vmemmap_pages = mem->altmap->free; |
| 206 | 209 | |
| 210 | + mem_hotplug_begin(); | |
| 207 | 211 | if (nr_vmemmap_pages) { |
| 208 | 212 | ret = mhp_init_memmap_on_memory(start_pfn, nr_vmemmap_pages, zone); |
| 209 | 213 | if (ret) |
| 210 | − return ret; | |
| 214 | + goto out; | |
| 211 | 215 | } |
| 212 | 216 | |
| 213 | 217 | ret = online_pages(start_pfn + nr_vmemmap_pages, |
| @@ -215,7 +219,7 @@ static int memory_block_online(struct memory_block *mem) · 1 unmodified line | ||
| 215 | 219 | if (ret) { |
| 216 | 220 | if (nr_vmemmap_pages) |
| 217 | 221 | mhp_deinit_memmap_on_memory(start_pfn, nr_vmemmap_pages); |
| 218 | − return ret; | |
| 222 | + goto out; | |
| 219 | 223 | } |
| 220 | 224 | |
| 221 | 225 | /* |
| @@ -227,9 +231,14 @@ static int memory_block_online(struct memory_block *mem) · 5 unmodified lines | ||
| 227 | 231 | nr_vmemmap_pages); |
| 228 | 232 | |
| 229 | 233 | mem->zone = zone; |
| 234 | +out: | |
| 235 | + mem_hotplug_done(); | |
| 230 | 236 | return ret; |
| 231 | 237 | } |
| 232 | 238 | |
| 239 | +/* | |
| 240 | + * Must acquire mem_hotplug_lock in write mode. | |
| 241 | + */ | |
| 233 | 242 | static int memory_block_offline(struct memory_block *mem) |
| 234 | 243 | { |
| 235 | 244 | unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr); |
| @@ -247,6 +256,7 @@ static int memory_block_offline(struct memory_block *mem) · 11 unmodified lines | ||
| 247 | 256 | if (mem->altmap) |
| 248 | 257 | nr_vmemmap_pages = mem->altmap->free; |
| 249 | 258 | |
| 259 | + mem_hotplug_begin(); | |
| 250 | 260 | if (nr_vmemmap_pages) |
| 251 | 261 | adjust_present_page_count(pfn_to_page(start_pfn), mem->group, |
| 252 | 262 | -nr_vmemmap_pages); |
| @@ -258,13 +268,15 @@ static int memory_block_offline(struct memory_block *mem) · 5 unmodified lines | ||
| 258 | 268 | if (nr_vmemmap_pages) |
| 259 | 269 | adjust_present_page_count(pfn_to_page(start_pfn), |
| 260 | 270 | mem->group, nr_vmemmap_pages); |
| 261 | − return ret; | |
| 271 | + goto out; | |
| 262 | 272 | } |
| 263 | 273 | |
| 264 | 274 | if (nr_vmemmap_pages) |
| 265 | 275 | mhp_deinit_memmap_on_memory(start_pfn, nr_vmemmap_pages); |
| 266 | 276 | |
| 267 | 277 | mem->zone = NULL; |
| 278 | +out: | |
| 279 | + mem_hotplug_done(); | |
| 268 | 280 | return ret; |
| 269 | 281 | } |
| 270 | 282 | |
| @@ -410,8 +410,7 @@ out: · 409 unmodified lines | ||
| 410 | 410 | rb_entry(node, struct regmap_range_node, node); |
| 411 | 411 | |
| 412 | 412 | /* If there's nothing in the cache there's nothing to sync */ |
| 413 | − ret = regcache_read(map, this->selector_reg, &i); | |
| 414 | − if (ret != 0) | |
| 413 | + if (regcache_read(map, this->selector_reg, &i) != 0) | |
| 415 | 414 | continue; |
| 416 | 415 | |
| 417 | 416 | ret = _regmap_write(map, this->selector_reg, i); |
| @@ -67,6 +67,7 @@ struct nbd_sock { · 66 unmodified lines | ||
| 67 | 67 | struct recv_thread_args { |
| 68 | 68 | struct work_struct work; |
| 69 | 69 | struct nbd_device *nbd; |
| 70 | + struct nbd_sock *nsock; | |
| 70 | 71 | int index; |
| 71 | 72 | }; |
| 72 | 73 | |
| @@ -395,6 +396,22 @@ static u32 req_to_nbd_cmd_type(struct request *req) · 322 unmodified lines | ||
| 395 | 396 | } |
| 396 | 397 | } |
| 397 | 398 | |
| 399 | +static struct nbd_config *nbd_get_config_unlocked(struct nbd_device *nbd) | |
| 400 | +{ | |
| 401 | + if (refcount_inc_not_zero(&nbd->config_refs)) { | |
| 402 | + /* | |
| 403 | + * Add smp_mb__after_atomic to ensure that reading nbd->config_refs | |
| 404 | + * and reading nbd->config is ordered. The pair is the barrier in | |
| 405 | + * nbd_alloc_and_init_config(), avoid nbd->config_refs is set | |
| 406 | + * before nbd->config. | |
| 407 | + */ | |
| 408 | + smp_mb__after_atomic(); | |
| 409 | + return nbd->config; | |
| 410 | + } | |
| 411 | + | |
| 412 | + return NULL; | |
| 413 | +} | |
| 414 | + | |
| 398 | 415 | static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req) |
| 399 | 416 | { |
| 400 | 417 | struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req); |
| @@ -409,13 +426,13 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req) · 8 unmodified lines | ||
| 409 | 426 | return BLK_EH_DONE; |
| 410 | 427 | } |
| 411 | 428 | |
| 412 | − if (!refcount_inc_not_zero(&nbd->config_refs)) { | |
| 429 | + config = nbd_get_config_unlocked(nbd); | |
| 430 | + if (!config) { | |
| 413 | 431 | cmd->status = BLK_STS_TIMEOUT; |
| 414 | 432 | __clear_bit(NBD_CMD_INFLIGHT, &cmd->flags); |
| 415 | 433 | mutex_unlock(&cmd->lock); |
| 416 | 434 | goto done; |
| 417 | 435 | } |
| 418 | − config = nbd->config; | |
| 419 | 436 | |
| 420 | 437 | if (config->num_connections > 1 || |
| 421 | 438 | (config->num_connections == 1 && nbd->tag_set.timeout)) { |
| @@ -489,15 +506,9 @@ done: · 67 unmodified lines | ||
| 489 | 506 | return BLK_EH_DONE; |
| 490 | 507 | } |
| 491 | 508 | |
| 492 | −/* | |
| 493 | − * Send or receive packet. Return a positive value on success and | |
| 494 | − * negtive value on failue, and never return 0. | |
| 495 | − */ | |
| 496 | −static int sock_xmit(struct nbd_device *nbd, int index, int send, | |
| 497 | − struct iov_iter *iter, int msg_flags, int *sent) | |
| 509 | +static int __sock_xmit(struct nbd_device *nbd, struct socket *sock, int send, | |
| 510 | + struct iov_iter *iter, int msg_flags, int *sent) | |
| 498 | 511 | { |
| 499 | − struct nbd_config *config = nbd->config; | |
| 500 | − struct socket *sock = config->socks[index]->sock; | |
| 501 | 512 | int result; |
| 502 | 513 | struct msghdr msg; |
| 503 | 514 | unsigned int noreclaim_flag; |
| @@ -540,6 +551,19 @@ static int sock_xmit(struct nbd_device *nbd, int index, int send, · 36 unmodified lines | ||
| 540 | 551 | return result; |
| 541 | 552 | } |
| 542 | 553 | |
| 554 | +/* | |
| 555 | + * Send or receive packet. Return a positive value on success and | |
| 556 | + * negtive value on failure, and never return 0. | |
| 557 | + */ | |
| 558 | +static int sock_xmit(struct nbd_device *nbd, int index, int send, | |
| 559 | + struct iov_iter *iter, int msg_flags, int *sent) | |
| 560 | +{ | |
| 561 | + struct nbd_config *config = nbd->config; | |
| 562 | + struct socket *sock = config->socks[index]->sock; | |
| 563 | + | |
| 564 | + return __sock_xmit(nbd, sock, send, iter, msg_flags, sent); | |
| 565 | +} | |
| 566 | + | |
| 543 | 567 | /* |
| 544 | 568 | * Different settings for sk->sk_sndtimeo can result in different return values |
| 545 | 569 | * if there is a signal pending when we enter sendmsg, because reasons? |
| @@ -696,7 +720,7 @@ out: · 150 unmodified lines | ||
| 696 | 720 | return 0; |
| 697 | 721 | } |
| 698 | 722 | |
| 699 | −static int nbd_read_reply(struct nbd_device *nbd, int index, | |
| 723 | +static int nbd_read_reply(struct nbd_device *nbd, struct socket *sock, | |
| 700 | 724 | struct nbd_reply *reply) |
| 701 | 725 | { |
| 702 | 726 | struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)}; |
| @@ -705,7 +729,7 @@ static int nbd_read_reply(struct nbd_device *nbd, int index, · 2 unmodified lines | ||
| 705 | 729 | |
| 706 | 730 | reply->magic = 0; |
| 707 | 731 | iov_iter_kvec(&to, ITER_DEST, &iov, 1, sizeof(*reply)); |
| 708 | − result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); | |
| 732 | + result = __sock_xmit(nbd, sock, 0, &to, MSG_WAITALL, NULL); | |
| 709 | 733 | if (result < 0) { |
| 710 | 734 | if (!nbd_disconnected(nbd->config)) |
| 711 | 735 | dev_err(disk_to_dev(nbd->disk), |
| @@ -829,14 +853,14 @@ static void recv_work(struct work_struct *work) · 117 unmodified lines | ||
| 829 | 853 | struct nbd_device *nbd = args->nbd; |
| 830 | 854 | struct nbd_config *config = nbd->config; |
| 831 | 855 | struct request_queue *q = nbd->disk->queue; |
| 832 | − struct nbd_sock *nsock; | |
| 856 | + struct nbd_sock *nsock = args->nsock; | |
| 833 | 857 | struct nbd_cmd *cmd; |
| 834 | 858 | struct request *rq; |
| 835 | 859 | |
| 836 | 860 | while (1) { |
| 837 | 861 | struct nbd_reply reply; |
| 838 | 862 | |
| 839 | − if (nbd_read_reply(nbd, args->index, &reply)) | |
| 863 | + if (nbd_read_reply(nbd, nsock->sock, &reply)) | |
| 840 | 864 | break; |
| 841 | 865 | |
| 842 | 866 | /* |
| @@ -871,7 +895,6 @@ static void recv_work(struct work_struct *work) · 28 unmodified lines | ||
| 871 | 895 | percpu_ref_put(&q->q_usage_counter); |
| 872 | 896 | } |
| 873 | 897 | |
| 874 | − nsock = config->socks[args->index]; | |
| 875 | 898 | mutex_lock(&nsock->tx_lock); |
| 876 | 899 | nbd_mark_nsock_dead(nbd, nsock, 1); |
| 877 | 900 | mutex_unlock(&nsock->tx_lock); |
| @@ -977,12 +1000,12 @@ static int nbd_handle_cmd(struct nbd_cmd *cmd, int index) · 99 unmodified lines | ||
| 977 | 1000 | struct nbd_sock *nsock; |
| 978 | 1001 | int ret; |
| 979 | 1002 | |
| 980 | − if (!refcount_inc_not_zero(&nbd->config_refs)) { | |
| 1003 | + config = nbd_get_config_unlocked(nbd); | |
| 1004 | + if (!config) { | |
| 981 | 1005 | dev_err_ratelimited(disk_to_dev(nbd->disk), |
| 982 | 1006 | "Socks array is empty\n"); |
| 983 | 1007 | return -EINVAL; |
| 984 | 1008 | } |
| 985 | − config = nbd->config; | |
| 986 | 1009 | |
| 987 | 1010 | if (index >= config->num_connections) { |
| 988 | 1011 | dev_err_ratelimited(disk_to_dev(nbd->disk), |
| @@ -1215,6 +1238,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) · 226 unmodified lines | ||
| 1215 | 1238 | INIT_WORK(&args->work, recv_work); |
| 1216 | 1239 | args->index = i; |
| 1217 | 1240 | args->nbd = nbd; |
| 1241 | + args->nsock = nsock; | |
| 1218 | 1242 | nsock->cookie++; |
| 1219 | 1243 | mutex_unlock(&nsock->tx_lock); |
| 1220 | 1244 | sockfd_put(old); |
| @@ -1397,6 +1421,7 @@ static int nbd_start_device(struct nbd_device *nbd) · 176 unmodified lines | ||
| 1397 | 1421 | refcount_inc(&nbd->config_refs); |
| 1398 | 1422 | INIT_WORK(&args->work, recv_work); |
| 1399 | 1423 | args->nbd = nbd; |
| 1424 | + args->nsock = config->socks[i]; | |
| 1400 | 1425 | args->index = i; |
| 1401 | 1426 | queue_work(nbd->recv_workq, &args->work); |
| 1402 | 1427 | } |
| @@ -1530,17 +1555,20 @@ static int nbd_ioctl(struct block_device *bdev, blk_mode_t mode, · 127 unmodified lines | ||
| 1530 | 1555 | return error; |
| 1531 | 1556 | } |
| 1532 | 1557 | |
| 1533 | −static struct nbd_config *nbd_alloc_config(void) | |
| 1558 | +static int nbd_alloc_and_init_config(struct nbd_device *nbd) | |
| 1534 | 1559 | { |
| 1535 | 1560 | struct nbd_config *config; |
| 1536 | 1561 | |
| 1562 | + if (WARN_ON(nbd->config)) | |
| 1563 | + return -EINVAL; | |
| 1564 | + | |
| 1537 | 1565 | if (!try_module_get(THIS_MODULE)) |
| 1538 | − return ERR_PTR(-ENODEV); | |
| 1566 | + return -ENODEV; | |
| 1539 | 1567 | |
| 1540 | 1568 | config = kzalloc(sizeof(struct nbd_config), GFP_NOFS); |
| 1541 | 1569 | if (!config) { |
| 1542 | 1570 | module_put(THIS_MODULE); |
| 1543 | − return ERR_PTR(-ENOMEM); | |
| 1571 | + return -ENOMEM; | |
| 1544 | 1572 | } |
| 1545 | 1573 | |
| 1546 | 1574 | atomic_set(&config->recv_threads, 0); |
| @@ -1548,12 +1576,24 @@ static struct nbd_config *nbd_alloc_config(void) · 1 unmodified line | ||
| 1548 | 1576 | init_waitqueue_head(&config->conn_wait); |
| 1549 | 1577 | config->blksize_bits = NBD_DEF_BLKSIZE_BITS; |
| 1550 | 1578 | atomic_set(&config->live_connections, 0); |
| 1551 | − return config; | |
| 1579 | + | |
| 1580 | + nbd->config = config; | |
| 1581 | + /* | |
| 1582 | + * Order refcount_set(&nbd->config_refs, 1) and nbd->config assignment, | |
| 1583 | + * its pair is the barrier in nbd_get_config_unlocked(). | |
| 1584 | + * So nbd_get_config_unlocked() won't see nbd->config as null after | |
| 1585 | + * refcount_inc_not_zero() succeed. | |
| 1586 | + */ | |
| 1587 | + smp_mb__before_atomic(); | |
| 1588 | + refcount_set(&nbd->config_refs, 1); | |
| 1589 | + | |
| 1590 | + return 0; | |
| 1552 | 1591 | } |
| 1553 | 1592 | |
| 1554 | 1593 | static int nbd_open(struct gendisk *disk, blk_mode_t mode) |
| 1555 | 1594 | { |
| 1556 | 1595 | struct nbd_device *nbd; |
| 1596 | + struct nbd_config *config; | |
| 1557 | 1597 | int ret = 0; |
| 1558 | 1598 | |
| 1559 | 1599 | mutex_lock(&nbd_index_mutex); |
| @@ -1566,27 +1606,25 @@ static int nbd_open(struct gendisk *disk, blk_mode_t mode) · 6 unmodified lines | ||
| 1566 | 1606 | ret = -ENXIO; |
| 1567 | 1607 | goto out; |
| 1568 | 1608 | } |
| 1569 | − if (!refcount_inc_not_zero(&nbd->config_refs)) { | |
| 1570 | − struct nbd_config *config; | |
| 1571 | 1609 | |
| 1610 | + config = nbd_get_config_unlocked(nbd); | |
| 1611 | + if (!config) { | |
| 1572 | 1612 | mutex_lock(&nbd->config_lock); |
| 1573 | 1613 | if (refcount_inc_not_zero(&nbd->config_refs)) { |
| 1574 | 1614 | mutex_unlock(&nbd->config_lock); |
| 1575 | 1615 | goto out; |
| 1576 | 1616 | } |
| 1577 | − config = nbd_alloc_config(); | |
| 1578 | − if (IS_ERR(config)) { | |
| 1579 | − ret = PTR_ERR(config); | |
| 1617 | + ret = nbd_alloc_and_init_config(nbd); | |
| 1618 | + if (ret) { | |
| 1580 | 1619 | mutex_unlock(&nbd->config_lock); |
| 1581 | 1620 | goto out; |
| 1582 | 1621 | } |
| 1583 | − nbd->config = config; | |
| 1584 | − refcount_set(&nbd->config_refs, 1); | |
| 1622 | + | |
| 1585 | 1623 | refcount_inc(&nbd->refs); |
| 1586 | 1624 | mutex_unlock(&nbd->config_lock); |
| 1587 | 1625 | if (max_part) |
| 1588 | 1626 | set_bit(GD_NEED_PART_SCAN, &disk->state); |
| 1589 | − } else if (nbd_disconnected(nbd->config)) { | |
| 1627 | + } else if (nbd_disconnected(config)) { | |
| 1590 | 1628 | if (max_part) |
| 1591 | 1629 | set_bit(GD_NEED_PART_SCAN, &disk->state); |
| 1592 | 1630 | } |
| @@ -1990,22 +2028,17 @@ again: · 397 unmodified lines | ||
| 1990 | 2028 | pr_err("nbd%d already in use\n", index); |
| 1991 | 2029 | return -EBUSY; |
| 1992 | 2030 | } |
| 1993 | − if (WARN_ON(nbd->config)) { | |
| 1994 | − mutex_unlock(&nbd->config_lock); | |
| 1995 | − nbd_put(nbd); | |
| 1996 | − return -EINVAL; | |
| 1997 | − } | |
| 1998 | − config = nbd_alloc_config(); | |
| 1999 | − if (IS_ERR(config)) { | |
| 2031 | + | |
| 2032 | + ret = nbd_alloc_and_init_config(nbd); | |
| 2033 | + if (ret) { | |
| 2000 | 2034 | mutex_unlock(&nbd->config_lock); |
| 2001 | 2035 | nbd_put(nbd); |
| 2002 | 2036 | pr_err("couldn't allocate config\n"); |
| 2003 | − return PTR_ERR(config); | |
| 2037 | + return ret; | |
| 2004 | 2038 | } |
| 2005 | − nbd->config = config; | |
| 2006 | − refcount_set(&nbd->config_refs, 1); | |
| 2007 | − set_bit(NBD_RT_BOUND, &config->runtime_flags); | |
| 2008 | 2039 | |
| 2040 | + config = nbd->config; | |
| 2041 | + set_bit(NBD_RT_BOUND, &config->runtime_flags); | |
| 2009 | 2042 | ret = nbd_genl_size_set(info, nbd); |
| 2010 | 2043 | if (ret) |
| 2011 | 2044 | goto out; |
| @@ -2208,7 +2241,8 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) · 196 unmodified lines | ||
| 2208 | 2241 | } |
| 2209 | 2242 | mutex_unlock(&nbd_index_mutex); |
| 2210 | 2243 | |
| 2211 | − if (!refcount_inc_not_zero(&nbd->config_refs)) { | |
| 2244 | + config = nbd_get_config_unlocked(nbd); | |
| 2245 | + if (!config) { | |
| 2212 | 2246 | dev_err(nbd_to_dev(nbd), |
| 2213 | 2247 | "not configured, cannot reconfigure\n"); |
| 2214 | 2248 | nbd_put(nbd); |
| @@ -2216,7 +2250,6 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info) · 1 unmodified line | ||
| 2216 | 2250 | } |
| 2217 | 2251 | |
| 2218 | 2252 | mutex_lock(&nbd->config_lock); |
| 2219 | − config = nbd->config; | |
| 2220 | 2253 | if (!test_bit(NBD_RT_BOUND, &config->runtime_flags) || |
| 2221 | 2254 | !nbd->pid) { |
| 2222 | 2255 | dev_err(nbd_to_dev(nbd), |
| @@ -1464,19 +1464,13 @@ blk_status_t null_process_cmd(struct nullb_cmd *cmd, enum req_op op, · 1463 unmodified lines | ||
| 1464 | 1464 | return BLK_STS_OK; |
| 1465 | 1465 | } |
| 1466 | 1466 | |
| 1467 | −static blk_status_t null_handle_cmd(struct nullb_cmd *cmd, sector_t sector, | |
| 1468 | − sector_t nr_sectors, enum req_op op) | |
| 1467 | +static void null_handle_cmd(struct nullb_cmd *cmd, sector_t sector, | |
| 1468 | + sector_t nr_sectors, enum req_op op) | |
| 1469 | 1469 | { |
| 1470 | 1470 | struct nullb_device *dev = cmd->nq->dev; |
| 1471 | 1471 | struct nullb *nullb = dev->nullb; |
| 1472 | 1472 | blk_status_t sts; |
| 1473 | 1473 | |
| 1474 | − if (test_bit(NULLB_DEV_FL_THROTTLED, &dev->flags)) { | |
| 1475 | − sts = null_handle_throttled(cmd); | |
| 1476 | − if (sts != BLK_STS_OK) | |
| 1477 | − return sts; | |
| 1478 | − } | |
| 1479 | − | |
| 1480 | 1474 | if (op == REQ_OP_FLUSH) { |
| 1481 | 1475 | cmd->error = errno_to_blk_status(null_handle_flush(nullb)); |
| 1482 | 1476 | goto out; |
| @@ -1493,7 +1487,6 @@ static blk_status_t null_handle_cmd(struct nullb_cmd *cmd, sector_t sector, · 10 unmodified lines | ||
| 1493 | 1487 | |
| 1494 | 1488 | out: |
| 1495 | 1489 | nullb_complete_cmd(cmd); |
| 1496 | − return BLK_STS_OK; | |
| 1497 | 1490 | } |
| 1498 | 1491 | |
| 1499 | 1492 | static enum hrtimer_restart nullb_bwtimer_fn(struct hrtimer *timer) |
| @@ -1724,8 +1717,6 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, · 224 unmodified lines | ||
| 1724 | 1717 | cmd->fake_timeout = should_timeout_request(rq) || |
| 1725 | 1718 | blk_should_fake_timeout(rq->q); |
| 1726 | 1719 | |
| 1727 | − blk_mq_start_request(rq); | |
| 1728 | − | |
| 1729 | 1720 | if (should_requeue_request(rq)) { |
| 1730 | 1721 | /* |
| 1731 | 1722 | * Alternate between hitting the core BUSY path, and the |
| @@ -1738,6 +1729,15 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, · 6 unmodified lines | ||
| 1738 | 1729 | return BLK_STS_OK; |
| 1739 | 1730 | } |
| 1740 | 1731 | |
| 1732 | + if (test_bit(NULLB_DEV_FL_THROTTLED, &nq->dev->flags)) { | |
| 1733 | + blk_status_t sts = null_handle_throttled(cmd); | |
| 1734 | + | |
| 1735 | + if (sts != BLK_STS_OK) | |
| 1736 | + return sts; | |
| 1737 | + } | |
| 1738 | + | |
| 1739 | + blk_mq_start_request(rq); | |
| 1740 | + | |
| 1741 | 1741 | if (is_poll) { |
| 1742 | 1742 | spin_lock(&nq->poll_lock); |
| 1743 | 1743 | list_add_tail(&rq->queuelist, &nq->poll_list); |
| @@ -1747,7 +1747,8 @@ static blk_status_t null_queue_rq(struct blk_mq_hw_ctx *hctx, · 3 unmodified lines | ||
| 1747 | 1747 | if (cmd->fake_timeout) |
| 1748 | 1748 | return BLK_STS_OK; |
| 1749 | 1749 | |
| 1750 | − return null_handle_cmd(cmd, sector, nr_sectors, req_op(rq)); | |
| 1750 | + null_handle_cmd(cmd, sector, nr_sectors, req_op(rq)); | |
| 1751 | + return BLK_STS_OK; | |
| 1751 | 1752 | } |
| 1752 | 1753 | |
| 1753 | 1754 | static void null_queue_rqs(struct request **rqlist) |
| @@ -307,11 +307,11 @@ static int pstate_init_perf(struct amd_cpudata *cpudata) · 306 unmodified lines | ||
| 307 | 307 | highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); |
| 308 | 308 | |
| 309 | 309 | WRITE_ONCE(cpudata->highest_perf, highest_perf); |
| 310 | − | |
| 310 | + WRITE_ONCE(cpudata->max_limit_perf, highest_perf); | |
| 311 | 311 | WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1)); |
| 312 | 312 | WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1)); |
| 313 | 313 | WRITE_ONCE(cpudata->lowest_perf, AMD_CPPC_LOWEST_PERF(cap1)); |
| 314 | − | |
| 314 | + WRITE_ONCE(cpudata->min_limit_perf, AMD_CPPC_LOWEST_PERF(cap1)); | |
| 315 | 315 | return 0; |
| 316 | 316 | } |
| 317 | 317 | |
| @@ -329,11 +329,12 @@ static int cppc_init_perf(struct amd_cpudata *cpudata) · 11 unmodified lines | ||
| 329 | 329 | highest_perf = cppc_perf.highest_perf; |
| 330 | 330 | |
| 331 | 331 | WRITE_ONCE(cpudata->highest_perf, highest_perf); |
| 332 | − | |
| 332 | + WRITE_ONCE(cpudata->max_limit_perf, highest_perf); | |
| 333 | 333 | WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf); |
| 334 | 334 | WRITE_ONCE(cpudata->lowest_nonlinear_perf, |
| 335 | 335 | cppc_perf.lowest_nonlinear_perf); |
| 336 | 336 | WRITE_ONCE(cpudata->lowest_perf, cppc_perf.lowest_perf); |
| 337 | + WRITE_ONCE(cpudata->min_limit_perf, cppc_perf.lowest_perf); | |
| 337 | 338 | |
| 338 | 339 | if (cppc_state == AMD_PSTATE_ACTIVE) |
| 339 | 340 | return 0; |
| @@ -432,6 +433,10 @@ static void amd_pstate_update(struct amd_cpudata *cpudata, u32 min_perf, · 92 unmodified lines | ||
| 432 | 433 | u64 prev = READ_ONCE(cpudata->cppc_req_cached); |
| 433 | 434 | u64 value = prev; |
| 434 | 435 | |
| 436 | + min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf, | |
| 437 | + cpudata->max_limit_perf); | |
| 438 | + max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf, | |
| 439 | + cpudata->max_limit_perf); | |
| 435 | 440 | des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf); |
| 436 | 441 | |
| 437 | 442 | if ((cppc_state == AMD_PSTATE_GUIDED) && (gov_flags & CPUFREQ_GOV_DYNAMIC_SWITCHING)) { |
| @@ -470,6 +475,22 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy) · 32 unmodified lines | ||
| 470 | 475 | return 0; |
| 471 | 476 | } |
| 472 | 477 | |
| 478 | +static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy) | |
| 479 | +{ | |
| 480 | + u32 max_limit_perf, min_limit_perf; | |
| 481 | + struct amd_cpudata *cpudata = policy->driver_data; | |
| 482 | + | |
| 483 | + max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | |
| 484 | + min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | |
| 485 | + | |
| 486 | + WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf); | |
| 487 | + WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf); | |
| 488 | + WRITE_ONCE(cpudata->max_limit_freq, policy->max); | |
| 489 | + WRITE_ONCE(cpudata->min_limit_freq, policy->min); | |
| 490 | + | |
| 491 | + return 0; | |
| 492 | +} | |
| 493 | + | |
| 473 | 494 | static int amd_pstate_update_freq(struct cpufreq_policy *policy, |
| 474 | 495 | unsigned int target_freq, bool fast_switch) |
| 475 | 496 | { |
| @@ -480,6 +501,9 @@ static int amd_pstate_update_freq(struct cpufreq_policy *policy, · 4 unmodified lines | ||
| 480 | 501 | if (!cpudata->max_freq) |
| 481 | 502 | return -ENODEV; |
| 482 | 503 | |
| 504 | + if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq) | |
| 505 | + amd_pstate_update_min_max_limit(policy); | |
| 506 | + | |
| 483 | 507 | cap_perf = READ_ONCE(cpudata->highest_perf); |
| 484 | 508 | min_perf = READ_ONCE(cpudata->lowest_perf); |
| 485 | 509 | max_perf = cap_perf; |
| @@ -518,7 +542,9 @@ static int amd_pstate_target(struct cpufreq_policy *policy, · 32 unmodified lines | ||
| 518 | 542 | static unsigned int amd_pstate_fast_switch(struct cpufreq_policy *policy, |
| 519 | 543 | unsigned int target_freq) |
| 520 | 544 | { |
| 521 | − return amd_pstate_update_freq(policy, target_freq, true); | |
| 545 | + if (!amd_pstate_update_freq(policy, target_freq, true)) | |
| 546 | + return target_freq; | |
| 547 | + return policy->cur; | |
| 522 | 548 | } |
| 523 | 549 | |
| 524 | 550 | static void amd_pstate_adjust_perf(unsigned int cpu, |
| @@ -532,6 +558,10 @@ static void amd_pstate_adjust_perf(unsigned int cpu, · 7 unmodified lines | ||
| 532 | 558 | struct amd_cpudata *cpudata = policy->driver_data; |
| 533 | 559 | unsigned int target_freq; |
| 534 | 560 | |
| 561 | + if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq) | |
| 562 | + amd_pstate_update_min_max_limit(policy); | |
| 563 | + | |
| 564 | + | |
| 535 | 565 | cap_perf = READ_ONCE(cpudata->highest_perf); |
| 536 | 566 | lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf); |
| 537 | 567 | max_freq = READ_ONCE(cpudata->max_freq); |
| @@ -745,6 +775,8 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) · 207 unmodified lines | ||
| 745 | 775 | /* Initial processor data capability frequencies */ |
| 746 | 776 | cpudata->max_freq = max_freq; |
| 747 | 777 | cpudata->min_freq = min_freq; |
| 778 | + cpudata->max_limit_freq = max_freq; | |
| 779 | + cpudata->min_limit_freq = min_freq; | |
| 748 | 780 | cpudata->nominal_freq = nominal_freq; |
| 749 | 781 | cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq; |
| 750 | 782 | |
| @@ -850,11 +882,16 @@ static ssize_t show_energy_performance_available_preferences( · 99 unmodified lines | ||
| 850 | 882 | { |
| 851 | 883 | int i = 0; |
| 852 | 884 | int offset = 0; |
| 885 | + struct amd_cpudata *cpudata = policy->driver_data; | |
| 886 | + | |
| 887 | + if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) | |
| 888 | + return sysfs_emit_at(buf, offset, "%s\n", | |
| 889 | + energy_perf_strings[EPP_INDEX_PERFORMANCE]); | |
| 853 | 890 | |
| 854 | 891 | while (energy_perf_strings[i] != NULL) |
| 855 | 892 | offset += sysfs_emit_at(buf, offset, "%s ", energy_perf_strings[i++]); |
| 856 | 893 | |
| 857 | − sysfs_emit_at(buf, offset, "\n"); | |
| 894 | + offset += sysfs_emit_at(buf, offset, "\n"); | |
| 858 | 895 | |
| 859 | 896 | return offset; |
| 860 | 897 | } |
| @@ -1183,16 +1220,25 @@ static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy) · 322 unmodified lines | ||
| 1183 | 1220 | return 0; |
| 1184 | 1221 | } |
| 1185 | 1222 | |
| 1186 | −static void amd_pstate_epp_init(unsigned int cpu) | |
| 1223 | +static void amd_pstate_epp_update_limit(struct cpufreq_policy *policy) | |
| 1187 | 1224 | { |
| 1188 | − struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); | |
| 1189 | 1225 | struct amd_cpudata *cpudata = policy->driver_data; |
| 1190 | − u32 max_perf, min_perf; | |
| 1226 | + u32 max_perf, min_perf, min_limit_perf, max_limit_perf; | |
| 1191 | 1227 | u64 value; |
| 1192 | 1228 | s16 epp; |
| 1193 | 1229 | |
| 1194 | 1230 | max_perf = READ_ONCE(cpudata->highest_perf); |
| 1195 | 1231 | min_perf = READ_ONCE(cpudata->lowest_perf); |
| 1232 | + max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | |
| 1233 | + min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | |
| 1234 | + | |
| 1235 | + max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf, | |
| 1236 | + cpudata->max_limit_perf); | |
| 1237 | + min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf, | |
| 1238 | + cpudata->max_limit_perf); | |
| 1239 | + | |
| 1240 | + WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf); | |
| 1241 | + WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf); | |
| 1196 | 1242 | |
| 1197 | 1243 | value = READ_ONCE(cpudata->cppc_req_cached); |
| 1198 | 1244 | |
| @@ -1210,9 +1256,6 @@ static void amd_pstate_epp_init(unsigned int cpu) · 11 unmodified lines | ||
| 1210 | 1256 | value &= ~AMD_CPPC_DES_PERF(~0L); |
| 1211 | 1257 | value |= AMD_CPPC_DES_PERF(0); |
| 1212 | 1258 | |
| 1213 | − if (cpudata->epp_policy == cpudata->policy) | |
| 1214 | − goto skip_epp; | |
| 1215 | − | |
| 1216 | 1259 | cpudata->epp_policy = cpudata->policy; |
| 1217 | 1260 | |
| 1218 | 1261 | /* Get BIOS pre-defined epp value */ |
| @@ -1222,7 +1265,7 @@ static void amd_pstate_epp_init(unsigned int cpu) · 3 unmodified lines | ||
| 1222 | 1265 | * This return value can only be negative for shared_memory |
| 1223 | 1266 | * systems where EPP register read/write not supported. |
| 1224 | 1267 | */ |
| 1225 | − goto skip_epp; | |
| 1268 | + return; | |
| 1226 | 1269 | } |
| 1227 | 1270 | |
| 1228 | 1271 | if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) |
| @@ -1236,8 +1279,6 @@ static void amd_pstate_epp_init(unsigned int cpu) · 7 unmodified lines | ||
| 1236 | 1279 | |
| 1237 | 1280 | WRITE_ONCE(cpudata->cppc_req_cached, value); |
| 1238 | 1281 | amd_pstate_set_epp(cpudata, epp); |
| 1239 | −skip_epp: | |
| 1240 | − cpufreq_cpu_put(policy); | |
| 1241 | 1282 | } |
| 1242 | 1283 | |
| 1243 | 1284 | static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy) |
| @@ -1252,7 +1293,7 @@ static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy) · 8 unmodified lines | ||
| 1252 | 1293 | |
| 1253 | 1294 | cpudata->policy = policy->policy; |
| 1254 | 1295 | |
| 1255 | − amd_pstate_epp_init(policy->cpu); | |
| 1296 | + amd_pstate_epp_update_limit(policy); | |
| 1256 | 1297 | |
| 1257 | 1298 | return 0; |
| 1258 | 1299 | } |
| @@ -327,7 +327,7 @@ static int imx6ul_opp_check_speed_grading(struct device *dev) · 326 unmodified lines | ||
| 327 | 327 | imx6x_disable_freq_in_opp(dev, 696000000); |
| 328 | 328 | |
| 329 | 329 | if (of_machine_is_compatible("fsl,imx6ull")) { |
| 330 | − if (val != OCOTP_CFG3_6ULL_SPEED_792MHZ) | |
| 330 | + if (val < OCOTP_CFG3_6ULL_SPEED_792MHZ) | |
| 331 | 331 | imx6x_disable_freq_in_opp(dev, 792000000); |
| 332 | 332 | |
| 333 | 333 | if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ) |
| @@ -23,8 +23,10 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/nvmem-consumer.h> |
| 24 | 24 | #include <linux/of.h> |
| 25 | 25 | #include <linux/platform_device.h> |
| 26 | +#include <linux/pm.h> | |
| 26 | 27 | #include <linux/pm_domain.h> |
| 27 | 28 | #include <linux/pm_opp.h> |
| 29 | +#include <linux/pm_runtime.h> | |
| 28 | 30 | #include <linux/slab.h> |
| 29 | 31 | #include <linux/soc/qcom/smem.h> |
| 30 | 32 | |
| @@ -55,6 +57,7 @@ struct qcom_cpufreq_match_data { · 24 unmodified lines | ||
| 55 | 57 | |
| 56 | 58 | struct qcom_cpufreq_drv_cpu { |
| 57 | 59 | int opp_token; |
| 60 | + struct device **virt_devs; | |
| 58 | 61 | }; |
| 59 | 62 | |
| 60 | 63 | struct qcom_cpufreq_drv { |
| @@ -424,6 +427,30 @@ static const struct qcom_cpufreq_match_data match_data_ipq8074 = { · 363 unmodified lines | ||
| 424 | 427 | .get_version = qcom_cpufreq_ipq8074_name_version, |
| 425 | 428 | }; |
| 426 | 429 | |
| 430 | +static void qcom_cpufreq_suspend_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu) | |
| 431 | +{ | |
| 432 | + const char * const *name = drv->data->genpd_names; | |
| 433 | + int i; | |
| 434 | + | |
| 435 | + if (!drv->cpus[cpu].virt_devs) | |
| 436 | + return; | |
| 437 | + | |
| 438 | + for (i = 0; *name; i++, name++) | |
| 439 | + device_set_awake_path(drv->cpus[cpu].virt_devs[i]); | |
| 440 | +} | |
| 441 | + | |
| 442 | +static void qcom_cpufreq_put_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu) | |
| 443 | +{ | |
| 444 | + const char * const *name = drv->data->genpd_names; | |
| 445 | + int i; | |
| 446 | + | |
| 447 | + if (!drv->cpus[cpu].virt_devs) | |
| 448 | + return; | |
| 449 | + | |
| 450 | + for (i = 0; *name; i++, name++) | |
| 451 | + pm_runtime_put(drv->cpus[cpu].virt_devs[i]); | |
| 452 | +} | |
| 453 | + | |
| 427 | 454 | static int qcom_cpufreq_probe(struct platform_device *pdev) |
| 428 | 455 | { |
| 429 | 456 | struct qcom_cpufreq_drv *drv; |
| @@ -478,6 +505,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) · 48 unmodified lines | ||
| 478 | 505 | of_node_put(np); |
| 479 | 506 | |
| 480 | 507 | for_each_possible_cpu(cpu) { |
| 508 | + struct device **virt_devs = NULL; | |
| 481 | 509 | struct dev_pm_opp_config config = { |
| 482 | 510 | .supported_hw = NULL, |
| 483 | 511 | }; |
| @@ -498,7 +526,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) · 14 unmodified lines | ||
| 498 | 526 | |
| 499 | 527 | if (drv->data->genpd_names) { |
| 500 | 528 | config.genpd_names = drv->data->genpd_names; |
| 501 | − config.virt_devs = NULL; | |
| 529 | + config.virt_devs = &virt_devs; | |
| 502 | 530 | } |
| 503 | 531 | |
| 504 | 532 | if (config.supported_hw || config.genpd_names) { |
| @@ -509,6 +537,27 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) · 4 unmodified lines | ||
| 509 | 537 | goto free_opp; |
| 510 | 538 | } |
| 511 | 539 | } |
| 540 | + | |
| 541 | + if (virt_devs) { | |
| 542 | + const char * const *name = config.genpd_names; | |
| 543 | + int i, j; | |
| 544 | + | |
| 545 | + for (i = 0; *name; i++, name++) { | |
| 546 | + ret = pm_runtime_resume_and_get(virt_devs[i]); | |
| 547 | + if (ret) { | |
| 548 | + dev_err(cpu_dev, "failed to resume %s: %d\n", | |
| 549 | + *name, ret); | |
| 550 | + | |
| 551 | + /* Rollback previous PM runtime calls */ | |
| 552 | + name = config.genpd_names; | |
| 553 | + for (j = 0; *name && j < i; j++, name++) | |
| 554 | + pm_runtime_put(virt_devs[j]); | |
| 555 | + | |
| 556 | + goto free_opp; | |
| 557 | + } | |
| 558 | + } | |
| 559 | + drv->cpus[cpu].virt_devs = virt_devs; | |
| 560 | + } | |
| 512 | 561 | } |
| 513 | 562 | |
| 514 | 563 | cpufreq_dt_pdev = platform_device_register_simple("cpufreq-dt", -1, |
| @@ -522,8 +571,10 @@ static int qcom_cpufreq_probe(struct platform_device *pdev) · 7 unmodified lines | ||
| 522 | 571 | dev_err(cpu_dev, "Failed to register platform device\n"); |
| 523 | 572 | |
| 524 | 573 | free_opp: |
| 525 | − for_each_possible_cpu(cpu) | |
| 574 | + for_each_possible_cpu(cpu) { | |
| 575 | + qcom_cpufreq_put_virt_devs(drv, cpu); | |
| 526 | 576 | dev_pm_opp_clear_config(drv->cpus[cpu].opp_token); |
| 577 | + } | |
| 527 | 578 | return ret; |
| 528 | 579 | } |
| 529 | 580 | |
| @@ -534,15 +585,31 @@ static void qcom_cpufreq_remove(struct platform_device *pdev) · 4 unmodified lines | ||
| 534 | 585 | |
| 535 | 586 | platform_device_unregister(cpufreq_dt_pdev); |
| 536 | 587 | |
| 537 | − for_each_possible_cpu(cpu) | |
| 588 | + for_each_possible_cpu(cpu) { | |
| 589 | + qcom_cpufreq_put_virt_devs(drv, cpu); | |
| 538 | 590 | dev_pm_opp_clear_config(drv->cpus[cpu].opp_token); |
| 591 | + } | |
| 539 | 592 | } |
| 540 | 593 | |
| 594 | +static int qcom_cpufreq_suspend(struct device *dev) | |
| 595 | +{ | |
| 596 | + struct qcom_cpufreq_drv *drv = dev_get_drvdata(dev); | |
| 597 | + unsigned int cpu; | |
| 598 | + | |
| 599 | + for_each_possible_cpu(cpu) | |
| 600 | + qcom_cpufreq_suspend_virt_devs(drv, cpu); | |
| 601 | + | |
| 602 | + return 0; | |
| 603 | +} | |
| 604 | + | |
| 605 | +static DEFINE_SIMPLE_DEV_PM_OPS(qcom_cpufreq_pm_ops, qcom_cpufreq_suspend, NULL); | |
| 606 | + | |
| 541 | 607 | static struct platform_driver qcom_cpufreq_driver = { |
| 542 | 608 | .probe = qcom_cpufreq_probe, |
| 543 | 609 | .remove_new = qcom_cpufreq_remove, |
| 544 | 610 | .driver = { |
| 545 | 611 | .name = "qcom-cpufreq-nvmem", |
| 612 | + .pm = pm_sleep_ptr(&qcom_cpufreq_pm_ops), | |
| 546 | 613 | }, |
| 547 | 614 | }; |
| 548 | 615 | |
| @@ -301,7 +301,7 @@ void dma_resv_add_fence(struct dma_resv *obj, struct dma_fence *fence, · 300 unmodified lines | ||
| 301 | 301 | |
| 302 | 302 | dma_resv_list_entry(fobj, i, obj, &old, &old_usage); |
| 303 | 303 | if ((old->context == fence->context && old_usage >= usage && |
| 304 | − dma_fence_is_later(fence, old)) || | |
| 304 | + dma_fence_is_later_or_same(fence, old)) || | |
| 305 | 305 | dma_fence_is_signaled(old)) { |
| 306 | 306 | dma_resv_list_set(fobj, i, fence, usage); |
| 307 | 307 | dma_fence_put(old); |
| @@ -1093,9 +1093,10 @@ int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info) · 1092 unmodified lines | ||
| 1093 | 1093 | return -ENOMEM; |
| 1094 | 1094 | hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0, |
| 1095 | 1095 | DPLL_CMD_PIN_ID_GET); |
| 1096 | − if (!hdr) | |
| 1096 | + if (!hdr) { | |
| 1097 | + nlmsg_free(msg); | |
| 1097 | 1098 | return -EMSGSIZE; |
| 1098 | − | |
| 1099 | + } | |
| 1099 | 1100 | pin = dpll_pin_find_from_nlattr(info); |
| 1100 | 1101 | if (!IS_ERR(pin)) { |
| 1101 | 1102 | ret = dpll_msg_add_pin_handle(msg, pin); |
| @@ -1123,8 +1124,10 @@ int dpll_nl_pin_get_doit(struct sk_buff *skb, struct genl_info *info) · 21 unmodified lines | ||
| 1123 | 1124 | return -ENOMEM; |
| 1124 | 1125 | hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0, |
| 1125 | 1126 | DPLL_CMD_PIN_GET); |
| 1126 | − if (!hdr) | |
| 1127 | + if (!hdr) { | |
| 1128 | + nlmsg_free(msg); | |
| 1127 | 1129 | return -EMSGSIZE; |
| 1130 | + } | |
| 1128 | 1131 | ret = dpll_cmd_pin_get_one(msg, pin, info->extack); |
| 1129 | 1132 | if (ret) { |
| 1130 | 1133 | nlmsg_free(msg); |
| @@ -1256,8 +1259,10 @@ int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info) · 125 unmodified lines | ||
| 1256 | 1259 | return -ENOMEM; |
| 1257 | 1260 | hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0, |
| 1258 | 1261 | DPLL_CMD_DEVICE_ID_GET); |
| 1259 | − if (!hdr) | |
| 1262 | + if (!hdr) { | |
| 1263 | + nlmsg_free(msg); | |
| 1260 | 1264 | return -EMSGSIZE; |
| 1265 | + } | |
| 1261 | 1266 | |
| 1262 | 1267 | dpll = dpll_device_find_from_nlattr(info); |
| 1263 | 1268 | if (!IS_ERR(dpll)) { |
| @@ -1284,8 +1289,10 @@ int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info) · 20 unmodified lines | ||
| 1284 | 1289 | return -ENOMEM; |
| 1285 | 1290 | hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0, |
| 1286 | 1291 | DPLL_CMD_DEVICE_GET); |
| 1287 | − if (!hdr) | |
| 1292 | + if (!hdr) { | |
| 1293 | + nlmsg_free(msg); | |
| 1288 | 1294 | return -EMSGSIZE; |
| 1295 | + } | |
| 1289 | 1296 | |
| 1290 | 1297 | ret = dpll_device_get_one(dpll, msg, info->extack); |
| 1291 | 1298 | if (ret) { |
| @@ -717,14 +717,11 @@ static void create_units(struct fw_device *device) · 716 unmodified lines | ||
| 717 | 717 | fw_unit_attributes, |
| 718 | 718 | &unit->attribute_group); |
| 719 | 719 | |
| 720 | − if (device_register(&unit->device) < 0) | |
| 721 | − goto skip_unit; | |
| 722 | − | |
| 723 | 720 | fw_device_get(device); |
| 724 | − continue; | |
| 725 | − | |
| 726 | − skip_unit: | |
| 727 | − kfree(unit); | |
| 721 | + if (device_register(&unit->device) < 0) { | |
| 722 | + put_device(&unit->device); | |
| 723 | + continue; | |
| 724 | + } | |
| 728 | 725 | } |
| 729 | 726 | } |
| 730 | 727 | |
| @@ -1519,9 +1519,9 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev) · 1518 unmodified lines | ||
| 1519 | 1519 | sdev->use_10_for_rw = 1; |
| 1520 | 1520 | |
| 1521 | 1521 | if (sbp2_param_exclusive_login) { |
| 1522 | − sdev->manage_system_start_stop = true; | |
| 1523 | − sdev->manage_runtime_start_stop = true; | |
| 1524 | − sdev->manage_shutdown = true; | |
| 1522 | + sdev->manage_system_start_stop = 1; | |
| 1523 | + sdev->manage_runtime_start_stop = 1; | |
| 1524 | + sdev->manage_shutdown = 1; | |
| 1525 | 1525 | } |
| 1526 | 1526 | |
| 1527 | 1527 | if (sdev->type == TYPE_ROM) |
| @@ -131,7 +131,7 @@ config RASPBERRYPI_FIRMWARE · 130 unmodified lines | ||
| 131 | 131 | |
| 132 | 132 | config FW_CFG_SYSFS |
| 133 | 133 | tristate "QEMU fw_cfg device support in sysfs" |
| 134 | − depends on SYSFS && (ARM || ARM64 || PARISC || PPC_PMAC || SPARC || X86) | |
| 134 | + depends on SYSFS && (ARM || ARM64 || PARISC || PPC_PMAC || RISCV || SPARC || X86) | |
| 135 | 135 | depends on HAS_IOPORT_MAP |
| 136 | 136 | default n |
| 137 | 137 | help |
| @@ -99,6 +99,7 @@ struct ffa_drv_info { · 98 unmodified lines | ||
| 99 | 99 | void *tx_buffer; |
| 100 | 100 | bool mem_ops_native; |
| 101 | 101 | bool bitmap_created; |
| 102 | + bool notif_enabled; | |
| 102 | 103 | unsigned int sched_recv_irq; |
| 103 | 104 | unsigned int cpuhp_state; |
| 104 | 105 | struct ffa_pcpu_irq __percpu *irq_pcpu; |
| @@ -782,7 +783,7 @@ static void ffa_notification_info_get(void) · 677 unmodified lines | ||
| 782 | 783 | if (ids_processed >= max_ids - 1) |
| 783 | 784 | break; |
| 784 | 785 | |
| 785 | − part_id = packed_id_list[++ids_processed]; | |
| 786 | + part_id = packed_id_list[ids_processed++]; | |
| 786 | 787 | |
| 787 | 788 | if (!ids_count[list]) { /* Global Notification */ |
| 788 | 789 | __do_sched_recv_cb(part_id, 0, false); |
| @@ -794,7 +795,7 @@ static void ffa_notification_info_get(void) · 5 unmodified lines | ||
| 794 | 795 | if (ids_processed >= max_ids - 1) |
| 795 | 796 | break; |
| 796 | 797 | |
| 797 | − vcpu_id = packed_id_list[++ids_processed]; | |
| 798 | + vcpu_id = packed_id_list[ids_processed++]; | |
| 798 | 799 | |
| 799 | 800 | __do_sched_recv_cb(part_id, vcpu_id, true); |
| 800 | 801 | } |
| @@ -889,6 +890,8 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args) · 88 unmodified lines | ||
| 889 | 890 | |
| 890 | 891 | #define FFA_SECURE_PARTITION_ID_FLAG BIT(15) |
| 891 | 892 | |
| 893 | +#define ffa_notifications_disabled() (!drv_info->notif_enabled) | |
| 894 | + | |
| 892 | 895 | enum notify_type { |
| 893 | 896 | NON_SECURE_VM, |
| 894 | 897 | SECURE_PARTITION, |
| @@ -908,6 +911,9 @@ static int ffa_sched_recv_cb_update(u16 part_id, ffa_sched_recv_cb callback, · 13 unmodified lines | ||
| 908 | 911 | struct ffa_dev_part_info *partition; |
| 909 | 912 | bool cb_valid; |
| 910 | 913 | |
| 914 | + if (ffa_notifications_disabled()) | |
| 915 | + return -EOPNOTSUPP; | |
| 916 | + | |
| 911 | 917 | partition = xa_load(&drv_info->partition_info, part_id); |
| 912 | 918 | write_lock(&partition->rw_lock); |
| 913 | 919 | |
| @@ -1001,6 +1007,9 @@ static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id) · 87 unmodified lines | ||
| 1001 | 1007 | int rc; |
| 1002 | 1008 | enum notify_type type = ffa_notify_type_get(dev->vm_id); |
| 1003 | 1009 | |
| 1010 | + if (ffa_notifications_disabled()) | |
| 1011 | + return -EOPNOTSUPP; | |
| 1012 | + | |
| 1004 | 1013 | if (notify_id >= FFA_MAX_NOTIFICATIONS) |
| 1005 | 1014 | return -EINVAL; |
| 1006 | 1015 | |
| @@ -1027,6 +1036,9 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu, · 20 unmodified lines | ||
| 1027 | 1036 | u32 flags = 0; |
| 1028 | 1037 | enum notify_type type = ffa_notify_type_get(dev->vm_id); |
| 1029 | 1038 | |
| 1039 | + if (ffa_notifications_disabled()) | |
| 1040 | + return -EOPNOTSUPP; | |
| 1041 | + | |
| 1030 | 1042 | if (notify_id >= FFA_MAX_NOTIFICATIONS) |
| 1031 | 1043 | return -EINVAL; |
| 1032 | 1044 | |
| @@ -1057,6 +1069,9 @@ static int ffa_notify_send(struct ffa_device *dev, int notify_id, · 24 unmodified lines | ||
| 1057 | 1069 | { |
| 1058 | 1070 | u32 flags = 0; |
| 1059 | 1071 | |
| 1072 | + if (ffa_notifications_disabled()) | |
| 1073 | + return -EOPNOTSUPP; | |
| 1074 | + | |
| 1060 | 1075 | if (is_per_vcpu) |
| 1061 | 1076 | flags |= (PER_VCPU_NOTIFICATION_FLAG | vcpu << 16); |
| 1062 | 1077 | |
| @@ -1233,7 +1248,7 @@ static void ffa_partitions_cleanup(void) · 170 unmodified lines | ||
| 1233 | 1248 | if (!count) |
| 1234 | 1249 | return; |
| 1235 | 1250 | |
| 1236 | − info = kcalloc(count, sizeof(**info), GFP_KERNEL); | |
| 1251 | + info = kcalloc(count, sizeof(*info), GFP_KERNEL); | |
| 1237 | 1252 | if (!info) |
| 1238 | 1253 | return; |
| 1239 | 1254 | |
| @@ -1311,8 +1326,10 @@ static int ffa_sched_recv_irq_map(void) · 71 unmodified lines | ||
| 1311 | 1326 | |
| 1312 | 1327 | static void ffa_sched_recv_irq_unmap(void) |
| 1313 | 1328 | { |
| 1314 | − if (drv_info->sched_recv_irq) | |
| 1329 | + if (drv_info->sched_recv_irq) { | |
| 1315 | 1330 | irq_dispose_mapping(drv_info->sched_recv_irq); |
| 1331 | + drv_info->sched_recv_irq = 0; | |
| 1332 | + } | |
| 1316 | 1333 | } |
| 1317 | 1334 | |
| 1318 | 1335 | static int ffa_cpuhp_pcpu_irq_enable(unsigned int cpu) |
| @@ -1329,17 +1346,23 @@ static int ffa_cpuhp_pcpu_irq_disable(unsigned int cpu) · 10 unmodified lines | ||
| 1329 | 1346 | |
| 1330 | 1347 | static void ffa_uninit_pcpu_irq(void) |
| 1331 | 1348 | { |
| 1332 | − if (drv_info->cpuhp_state) | |
| 1349 | + if (drv_info->cpuhp_state) { | |
| 1333 | 1350 | cpuhp_remove_state(drv_info->cpuhp_state); |
| 1351 | + drv_info->cpuhp_state = 0; | |
| 1352 | + } | |
| 1334 | 1353 | |
| 1335 | − if (drv_info->notif_pcpu_wq) | |
| 1354 | + if (drv_info->notif_pcpu_wq) { | |
| 1336 | 1355 | destroy_workqueue(drv_info->notif_pcpu_wq); |
| 1356 | + drv_info->notif_pcpu_wq = NULL; | |
| 1357 | + } | |
| 1337 | 1358 | |
| 1338 | 1359 | if (drv_info->sched_recv_irq) |
| 1339 | 1360 | free_percpu_irq(drv_info->sched_recv_irq, drv_info->irq_pcpu); |
| 1340 | 1361 | |
| 1341 | − if (drv_info->irq_pcpu) | |
| 1362 | + if (drv_info->irq_pcpu) { | |
| 1342 | 1363 | free_percpu(drv_info->irq_pcpu); |
| 1364 | + drv_info->irq_pcpu = NULL; | |
| 1365 | + } | |
| 1343 | 1366 | } |
| 1344 | 1367 | |
| 1345 | 1368 | static int ffa_init_pcpu_irq(unsigned int irq) |
| @@ -1388,22 +1411,23 @@ static void ffa_notifications_cleanup(void) · 42 unmodified lines | ||
| 1388 | 1411 | ffa_notification_bitmap_destroy(); |
| 1389 | 1412 | drv_info->bitmap_created = false; |
| 1390 | 1413 | } |
| 1414 | + drv_info->notif_enabled = false; | |
| 1391 | 1415 | } |
| 1392 | 1416 | |
| 1393 | −static int ffa_notifications_setup(void) | |
| 1417 | +static void ffa_notifications_setup(void) | |
| 1394 | 1418 | { |
| 1395 | 1419 | int ret, irq; |
| 1396 | 1420 | |
| 1397 | 1421 | ret = ffa_features(FFA_NOTIFICATION_BITMAP_CREATE, 0, NULL, NULL); |
| 1398 | 1422 | if (ret) { |
| 1399 | − pr_err("Notifications not supported, continuing with it ..\n"); | |
| 1400 | − return 0; | |
| 1423 | + pr_info("Notifications not supported, continuing with it ..\n"); | |
| 1424 | + return; | |
| 1401 | 1425 | } |
| 1402 | 1426 | |
| 1403 | 1427 | ret = ffa_notification_bitmap_create(); |
| 1404 | 1428 | if (ret) { |
| 1405 | − pr_err("notification_bitmap_create error %d\n", ret); | |
| 1406 | − return ret; | |
| 1429 | + pr_info("Notification bitmap create error %d\n", ret); | |
| 1430 | + return; | |
| 1407 | 1431 | } |
| 1408 | 1432 | drv_info->bitmap_created = true; |
| 1409 | 1433 | |
| @@ -1422,14 +1446,11 @@ static int ffa_notifications_setup(void) · 12 unmodified lines | ||
| 1422 | 1446 | hash_init(drv_info->notifier_hash); |
| 1423 | 1447 | mutex_init(&drv_info->notify_lock); |
| 1424 | 1448 | |
| 1425 | − /* Register internal scheduling callback */ | |
| 1426 | − ret = ffa_sched_recv_cb_update(drv_info->vm_id, ffa_self_notif_handle, | |
| 1427 | − drv_info, true); | |
| 1428 | − if (!ret) | |
| 1429 | − return ret; | |
| 1449 | + drv_info->notif_enabled = true; | |
| 1450 | + return; | |
| 1430 | 1451 | cleanup: |
| 1452 | + pr_info("Notification setup failed %d, not enabled\n", ret); | |
| 1431 | 1453 | ffa_notifications_cleanup(); |
| 1432 | − return ret; | |
| 1433 | 1454 | } |
| 1434 | 1455 | |
| 1435 | 1456 | static int __init ffa_init(void) |
| @@ -1483,17 +1504,18 @@ static int __init ffa_init(void) · 47 unmodified lines | ||
| 1483 | 1504 | mutex_init(&drv_info->rx_lock); |
| 1484 | 1505 | mutex_init(&drv_info->tx_lock); |
| 1485 | 1506 | |
| 1486 | − ffa_setup_partitions(); | |
| 1487 | − | |
| 1488 | 1507 | ffa_set_up_mem_ops_native_flag(); |
| 1489 | 1508 | |
| 1490 | − ret = ffa_notifications_setup(); | |
| 1509 | + ffa_notifications_setup(); | |
| 1510 | + | |
| 1511 | + ffa_setup_partitions(); | |
| 1512 | + | |
| 1513 | + ret = ffa_sched_recv_cb_update(drv_info->vm_id, ffa_self_notif_handle, | |
| 1514 | + drv_info, true); | |
| 1491 | 1515 | if (ret) |
| 1492 | − goto partitions_cleanup; | |
| 1516 | + pr_info("Failed to register driver sched callback %d\n", ret); | |
| 1493 | 1517 | |
| 1494 | 1518 | return 0; |
| 1495 | −partitions_cleanup: | |
| 1496 | − ffa_partitions_cleanup(); | |
| 1497 | 1519 | free_pages: |
| 1498 | 1520 | if (drv_info->tx_buffer) |
| 1499 | 1521 | free_pages_exact(drv_info->tx_buffer, RXTX_BUFFER_SIZE); |
| @@ -152,7 +152,7 @@ struct perf_dom_info { · 151 unmodified lines | ||
| 152 | 152 | u32 opp_count; |
| 153 | 153 | u32 sustained_freq_khz; |
| 154 | 154 | u32 sustained_perf_level; |
| 155 | − u32 mult_factor; | |
| 155 | + unsigned long mult_factor; | |
| 156 | 156 | struct scmi_perf_domain_info info; |
| 157 | 157 | struct scmi_opp opp[MAX_OPPS]; |
| 158 | 158 | struct scmi_fc_info *fc_info; |
| @@ -268,13 +268,14 @@ scmi_perf_domain_attributes_get(const struct scmi_protocol_handle *ph, · 109 unmodified lines | ||
| 268 | 268 | dom_info->sustained_perf_level = |
| 269 | 269 | le32_to_cpu(attr->sustained_perf_level); |
| 270 | 270 | if (!dom_info->sustained_freq_khz || |
| 271 | − !dom_info->sustained_perf_level) | |
| 271 | + !dom_info->sustained_perf_level || | |
| 272 | + dom_info->level_indexing_mode) | |
| 272 | 273 | /* CPUFreq converts to kHz, hence default 1000 */ |
| 273 | 274 | dom_info->mult_factor = 1000; |
| 274 | 275 | else |
| 275 | 276 | dom_info->mult_factor = |
| 276 | − (dom_info->sustained_freq_khz * 1000) / | |
| 277 | − dom_info->sustained_perf_level; | |
| 277 | + (dom_info->sustained_freq_khz * 1000UL) | |
| 278 | + / dom_info->sustained_perf_level; | |
| 278 | 279 | strscpy(dom_info->info.name, attr->name, |
| 279 | 280 | SCMI_SHORT_NAME_MAX_SIZE); |
| 280 | 281 | } |
| @@ -798,7 +799,7 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph, · 517 unmodified lines | ||
| 798 | 799 | if (!dom->level_indexing_mode) |
| 799 | 800 | freq = dom->opp[idx].perf * dom->mult_factor; |
| 800 | 801 | else |
| 801 | − freq = dom->opp[idx].indicative_freq * 1000; | |
| 802 | + freq = dom->opp[idx].indicative_freq * dom->mult_factor; | |
| 802 | 803 | |
| 803 | 804 | data.level = dom->opp[idx].perf; |
| 804 | 805 | data.freq = freq; |
| @@ -845,7 +846,8 @@ static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 domain, · 40 unmodified lines | ||
| 845 | 846 | } else { |
| 846 | 847 | struct scmi_opp *opp; |
| 847 | 848 | |
| 848 | − opp = LOOKUP_BY_FREQ(dom->opps_by_freq, freq / 1000); | |
| 849 | + opp = LOOKUP_BY_FREQ(dom->opps_by_freq, | |
| 850 | + freq / dom->mult_factor); | |
| 849 | 851 | if (!opp) |
| 850 | 852 | return -EIO; |
| 851 | 853 | |
| @@ -879,7 +881,7 @@ static int scmi_dvfs_freq_get(const struct scmi_protocol_handle *ph, u32 domain, · 27 unmodified lines | ||
| 879 | 881 | if (!opp) |
| 880 | 882 | return -EIO; |
| 881 | 883 | |
| 882 | − *freq = opp->indicative_freq * 1000; | |
| 884 | + *freq = opp->indicative_freq * dom->mult_factor; | |
| 883 | 885 | } |
| 884 | 886 | |
| 885 | 887 | return ret; |
| @@ -902,7 +904,7 @@ static int scmi_dvfs_est_power_get(const struct scmi_protocol_handle *ph, · 16 unmodified lines | ||
| 902 | 904 | if (!dom->level_indexing_mode) |
| 903 | 905 | opp_freq = opp->perf * dom->mult_factor; |
| 904 | 906 | else |
| 905 | − opp_freq = opp->indicative_freq * 1000; | |
| 907 | + opp_freq = opp->indicative_freq * dom->mult_factor; | |
| 906 | 908 | |
| 907 | 909 | if (opp_freq < *freq) |
| 908 | 910 | continue; |
| @@ -101,7 +101,7 @@ retry: · 100 unmodified lines | ||
| 101 | 101 | * overlap on physical address level. |
| 102 | 102 | */ |
| 103 | 103 | list_for_each_entry(entry, &accepting_list, list) { |
| 104 | − if (entry->end < range.start) | |
| 104 | + if (entry->end <= range.start) | |
| 105 | 105 | continue; |
| 106 | 106 | if (entry->start >= range.end) |
| 107 | 107 | continue; |
| @@ -211,7 +211,7 @@ static void fw_cfg_io_cleanup(void) · 210 unmodified lines | ||
| 211 | 211 | |
| 212 | 212 | /* arch-specific ctrl & data register offsets are not available in ACPI, DT */ |
| 213 | 213 | #if !(defined(FW_CFG_CTRL_OFF) && defined(FW_CFG_DATA_OFF)) |
| 214 | −# if (defined(CONFIG_ARM) || defined(CONFIG_ARM64)) | |
| 214 | +# if (defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_RISCV)) | |
| 215 | 215 | # define FW_CFG_CTRL_OFF 0x08 |
| 216 | 216 | # define FW_CFG_DATA_OFF 0x00 |
| 217 | 217 | # define FW_CFG_DMA_OFF 0x10 |
| @@ -474,14 +474,17 @@ static ssize_t export_store(const struct class *class, · 473 unmodified lines | ||
| 474 | 474 | goto done; |
| 475 | 475 | |
| 476 | 476 | status = gpiod_set_transitory(desc, false); |
| 477 | − if (!status) { | |
| 478 | − status = gpiod_export(desc, true); | |
| 479 | − if (status < 0) | |
| 480 | − gpiod_free(desc); | |
| 481 | − else | |
| 482 | − set_bit(FLAG_SYSFS, &desc->flags); | |
| 477 | + if (status) { | |
| 478 | + gpiod_free(desc); | |
| 479 | + goto done; | |
| 483 | 480 | } |
| 484 | 481 | |
| 482 | + status = gpiod_export(desc, true); | |
| 483 | + if (status < 0) | |
| 484 | + gpiod_free(desc); | |
| 485 | + else | |
| 486 | + set_bit(FLAG_SYSFS, &desc->flags); | |
| 487 | + | |
| 485 | 488 | done: |
| 486 | 489 | if (status) |
| 487 | 490 | pr_debug("%s: status %d\n", __func__, status); |
| @@ -248,6 +248,7 @@ extern int amdgpu_umsch_mm; · 247 unmodified lines | ||
| 248 | 248 | extern int amdgpu_seamless; |
| 249 | 249 | |
| 250 | 250 | extern int amdgpu_user_partt_mode; |
| 251 | +extern int amdgpu_agp; | |
| 251 | 252 | |
| 252 | 253 | #define AMDGPU_VM_MAX_NUM_CTX 4096 |
| 253 | 254 | #define AMDGPU_SG_THRESHOLD (256*1024*1024) |
| @@ -547,7 +547,7 @@ int amdgpu_amdkfd_get_xgmi_bandwidth_mbytes(struct amdgpu_device *dst, · 546 unmodified lines | ||
| 547 | 547 | struct amdgpu_device *adev = dst, *peer_adev; |
| 548 | 548 | int num_links; |
| 549 | 549 | |
| 550 | − if (adev->asic_type != CHIP_ALDEBARAN) | |
| 550 | + if (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(9, 4, 2)) | |
| 551 | 551 | return 0; |
| 552 | 552 | |
| 553 | 553 | if (src) |
| @@ -207,7 +207,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, · 206 unmodified lines | ||
| 207 | 207 | } |
| 208 | 208 | |
| 209 | 209 | for (i = 0; i < p->nchunks; i++) { |
| 210 | − struct drm_amdgpu_cs_chunk __user **chunk_ptr = NULL; | |
| 210 | + struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL; | |
| 211 | 211 | struct drm_amdgpu_cs_chunk user_chunk; |
| 212 | 212 | uint32_t __user *cdata; |
| 213 | 213 | |
| @@ -638,6 +638,9 @@ static ssize_t amdgpu_debugfs_regs_didt_read(struct file *f, char __user *buf, · 637 unmodified lines | ||
| 638 | 638 | if (size & 0x3 || *pos & 0x3) |
| 639 | 639 | return -EINVAL; |
| 640 | 640 | |
| 641 | + if (!adev->didt_rreg) | |
| 642 | + return -EOPNOTSUPP; | |
| 643 | + | |
| 641 | 644 | r = pm_runtime_get_sync(adev_to_drm(adev)->dev); |
| 642 | 645 | if (r < 0) { |
| 643 | 646 | pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); |
| @@ -694,6 +697,9 @@ static ssize_t amdgpu_debugfs_regs_didt_write(struct file *f, const char __user · 50 unmodified lines | ||
| 694 | 697 | if (size & 0x3 || *pos & 0x3) |
| 695 | 698 | return -EINVAL; |
| 696 | 699 | |
| 700 | + if (!adev->didt_wreg) | |
| 701 | + return -EOPNOTSUPP; | |
| 702 | + | |
| 697 | 703 | r = pm_runtime_get_sync(adev_to_drm(adev)->dev); |
| 698 | 704 | if (r < 0) { |
| 699 | 705 | pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); |
| @@ -3791,10 +3791,6 @@ static void amdgpu_device_set_mcbp(struct amdgpu_device *adev) · 3790 unmodified lines | ||
| 3791 | 3791 | adev->gfx.mcbp = true; |
| 3792 | 3792 | else if (amdgpu_mcbp == 0) |
| 3793 | 3793 | adev->gfx.mcbp = false; |
| 3794 | − else if ((amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 0, 0)) && | |
| 3795 | − (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(10, 0, 0)) && | |
| 3796 | − adev->gfx.num_gfx_rings) | |
| 3797 | − adev->gfx.mcbp = true; | |
| 3798 | 3794 | |
| 3799 | 3795 | if (amdgpu_sriov_vf(adev)) |
| 3800 | 3796 | adev->gfx.mcbp = true; |
| @@ -4531,6 +4527,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) · 730 unmodified lines | ||
| 4531 | 4527 | if (r) |
| 4532 | 4528 | return r; |
| 4533 | 4529 | |
| 4530 | + amdgpu_ttm_set_buffer_funcs_status(adev, false); | |
| 4531 | + | |
| 4534 | 4532 | amdgpu_fence_driver_hw_fini(adev); |
| 4535 | 4533 | |
| 4536 | 4534 | amdgpu_device_ip_suspend_phase2(adev); |
| @@ -4538,6 +4536,10 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) · 1 unmodified line | ||
| 4538 | 4536 | if (amdgpu_sriov_vf(adev)) |
| 4539 | 4537 | amdgpu_virt_release_full_gpu(adev, false); |
| 4540 | 4538 | |
| 4539 | + r = amdgpu_dpm_notify_rlc_state(adev, false); | |
| 4540 | + if (r) | |
| 4541 | + return r; | |
| 4542 | + | |
| 4541 | 4543 | return 0; |
| 4542 | 4544 | } |
| 4543 | 4545 | |
| @@ -340,14 +340,11 @@ int amdgpu_display_crtc_set_config(struct drm_mode_set *set, · 339 unmodified lines | ||
| 340 | 340 | adev->have_disp_power_ref = true; |
| 341 | 341 | return ret; |
| 342 | 342 | } |
| 343 | − /* if we have no active crtcs, then drop the power ref | |
| 344 | − * we got before | |
| 343 | + /* if we have no active crtcs, then go to | |
| 344 | + * drop the power ref we got before | |
| 345 | 345 | */ |
| 346 | − if (!active && adev->have_disp_power_ref) { | |
| 347 | − pm_runtime_put_autosuspend(dev->dev); | |
| 346 | + if (!active && adev->have_disp_power_ref) | |
| 348 | 347 | adev->have_disp_power_ref = false; |
| 349 | − } | |
| 350 | − | |
| 351 | 348 | out: |
| 352 | 349 | /* drop the power reference we got coming in here */ |
| 353 | 350 | pm_runtime_put_autosuspend(dev->dev); |
| @@ -207,6 +207,7 @@ int amdgpu_user_partt_mode = AMDGPU_AUTO_COMPUTE_PARTITION_MODE; · 206 unmodified lines | ||
| 207 | 207 | int amdgpu_umsch_mm; |
| 208 | 208 | int amdgpu_seamless = -1; /* auto */ |
| 209 | 209 | uint amdgpu_debug_mask; |
| 210 | +int amdgpu_agp = -1; /* auto */ | |
| 210 | 211 | |
| 211 | 212 | static void amdgpu_drv_delayed_reset_work_handler(struct work_struct *work); |
| 212 | 213 | |
| @@ -961,6 +962,15 @@ module_param_named(seamless, amdgpu_seamless, int, 0444); · 748 unmodified lines | ||
| 961 | 962 | MODULE_PARM_DESC(debug_mask, "debug options for amdgpu, disabled by default"); |
| 962 | 963 | module_param_named(debug_mask, amdgpu_debug_mask, uint, 0444); |
| 963 | 964 | |
| 965 | +/** | |
| 966 | + * DOC: agp (int) | |
| 967 | + * Enable the AGP aperture. This provides an aperture in the GPU's internal | |
| 968 | + * address space for direct access to system memory. Note that these accesses | |
| 969 | + * are non-snooped, so they are only used for access to uncached memory. | |
| 970 | + */ | |
| 971 | +MODULE_PARM_DESC(agp, "AGP (-1 = auto (default), 0 = disable, 1 = enable)"); | |
| 972 | +module_param_named(agp, amdgpu_agp, int, 0444); | |
| 973 | + | |
| 964 | 974 | /* These devices are not supported by amdgpu. |
| 965 | 975 | * They are supported by the mach64, r128, radeon drivers |
| 966 | 976 | */ |
| @@ -2253,6 +2263,8 @@ retry_init: · 1286 unmodified lines | ||
| 2253 | 2263 | pm_runtime_mark_last_busy(ddev->dev); |
| 2254 | 2264 | pm_runtime_put_autosuspend(ddev->dev); |
| 2255 | 2265 | |
| 2266 | + pci_wake_from_d3(pdev, TRUE); | |
| 2267 | + | |
| 2256 | 2268 | /* |
| 2257 | 2269 | * For runpm implemented via BACO, PMFW will handle the |
| 2258 | 2270 | * timing for BACO in and out: |
| @@ -181,6 +181,9 @@ uint64_t amdgpu_gmc_agp_addr(struct ttm_buffer_object *bo) · 180 unmodified lines | ||
| 181 | 181 | { |
| 182 | 182 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); |
| 183 | 183 | |
| 184 | + if (!bo->ttm) | |
| 185 | + return AMDGPU_BO_INVALID_OFFSET; | |
| 186 | + | |
| 184 | 187 | if (bo->ttm->num_pages != 1 || bo->ttm->caching == ttm_cached) |
| 185 | 188 | return AMDGPU_BO_INVALID_OFFSET; |
| 186 | 189 | |
| @@ -46,6 +46,8 @@ · 45 unmodified lines | ||
| 46 | 46 | #define MCA_REG__STATUS__ERRORCODEEXT(x) MCA_REG_FIELD(x, 21, 16) |
| 47 | 47 | #define MCA_REG__STATUS__ERRORCODE(x) MCA_REG_FIELD(x, 15, 0) |
| 48 | 48 | |
| 49 | +#define MCA_REG__SYND__ERRORINFORMATION(x) MCA_REG_FIELD(x, 17, 0) | |
| 50 | + | |
| 49 | 51 | enum amdgpu_mca_ip { |
| 50 | 52 | AMDGPU_MCA_IP_UNKNOW = -1, |
| 51 | 53 | AMDGPU_MCA_IP_PSP = 0, |
| @@ -1527,10 +1527,14 @@ u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo) · 1526 unmodified lines | ||
| 1527 | 1527 | u64 amdgpu_bo_gpu_offset_no_check(struct amdgpu_bo *bo) |
| 1528 | 1528 | { |
| 1529 | 1529 | struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev); |
| 1530 | − uint64_t offset; | |
| 1530 | + uint64_t offset = AMDGPU_BO_INVALID_OFFSET; | |
| 1531 | 1531 | |
| 1532 | − offset = (bo->tbo.resource->start << PAGE_SHIFT) + | |
| 1533 | − amdgpu_ttm_domain_start(adev, bo->tbo.resource->mem_type); | |
| 1532 | + if (bo->tbo.resource->mem_type == TTM_PL_TT) | |
| 1533 | + offset = amdgpu_gmc_agp_addr(&bo->tbo); | |
| 1534 | + | |
| 1535 | + if (offset == AMDGPU_BO_INVALID_OFFSET) | |
| 1536 | + offset = (bo->tbo.resource->start << PAGE_SHIFT) + | |
| 1537 | + amdgpu_ttm_domain_start(adev, bo->tbo.resource->mem_type); | |
| 1534 | 1538 | |
| 1535 | 1539 | return amdgpu_gmc_sign_extend(offset); |
| 1536 | 1540 | } |
| @@ -1473,6 +1473,11 @@ int psp_xgmi_get_topology_info(struct psp_context *psp, · 1472 unmodified lines | ||
| 1473 | 1473 | topology->nodes[i].num_links = (requires_reflection && topology->nodes[i].num_links) ? |
| 1474 | 1474 | topology->nodes[i].num_links : node_num_links; |
| 1475 | 1475 | } |
| 1476 | + /* popluate the connected port num info if supported and available */ | |
| 1477 | + if (ta_port_num_support && topology->nodes[i].num_links) { | |
| 1478 | + memcpy(topology->nodes[i].port_num, link_extend_info_output->nodes[i].port_num, | |
| 1479 | + sizeof(struct xgmi_connected_port_num) * TA_XGMI__MAX_PORT_NUM); | |
| 1480 | + } | |
| 1476 | 1481 | |
| 1477 | 1482 | /* reflect the topology information for bi-directionality */ |
| 1478 | 1483 | if (requires_reflection && topology->nodes[i].num_hops) |
| @@ -150,6 +150,7 @@ struct psp_xgmi_node_info { · 149 unmodified lines | ||
| 150 | 150 | uint8_t is_sharing_enabled; |
| 151 | 151 | enum ta_xgmi_assigned_sdma_engine sdma_engine; |
| 152 | 152 | uint8_t num_links; |
| 153 | + struct xgmi_connected_port_num port_num[TA_XGMI__MAX_PORT_NUM]; | |
| 153 | 154 | }; |
| 154 | 155 | |
| 155 | 156 | struct psp_xgmi_topology_info { |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/reboot.h> |
| 29 | 29 | #include <linux/syscalls.h> |
| 30 | 30 | #include <linux/pm_runtime.h> |
| 31 | +#include <linux/list_sort.h> | |
| 31 | 32 | |
| 32 | 33 | #include "amdgpu.h" |
| 33 | 34 | #include "amdgpu_ras.h" |
| @@ -1188,7 +1189,7 @@ static int amdgpu_ras_query_error_status_helper(struct amdgpu_device *adev, · 1154 unmodified lines | ||
| 1188 | 1189 | } |
| 1189 | 1190 | |
| 1190 | 1191 | if (block_obj->hw_ops->query_ras_error_count) |
| 1191 | − block_obj->hw_ops->query_ras_error_count(adev, &err_data); | |
| 1192 | + block_obj->hw_ops->query_ras_error_count(adev, err_data); | |
| 1192 | 1193 | |
| 1193 | 1194 | if ((info->head.block == AMDGPU_RAS_BLOCK__SDMA) || |
| 1194 | 1195 | (info->head.block == AMDGPU_RAS_BLOCK__GFX) || |
| @@ -3665,6 +3666,21 @@ static struct ras_err_node *amdgpu_ras_error_node_new(void) · 2470 unmodified lines | ||
| 3665 | 3666 | return err_node; |
| 3666 | 3667 | } |
| 3667 | 3668 | |
| 3669 | +static int ras_err_info_cmp(void *priv, const struct list_head *a, const struct list_head *b) | |
| 3670 | +{ | |
| 3671 | + struct ras_err_node *nodea = container_of(a, struct ras_err_node, node); | |
| 3672 | + struct ras_err_node *nodeb = container_of(b, struct ras_err_node, node); | |
| 3673 | + struct amdgpu_smuio_mcm_config_info *infoa = &nodea->err_info.mcm_info; | |
| 3674 | + struct amdgpu_smuio_mcm_config_info *infob = &nodeb->err_info.mcm_info; | |
| 3675 | + | |
| 3676 | + if (unlikely(infoa->socket_id != infob->socket_id)) | |
| 3677 | + return infoa->socket_id - infob->socket_id; | |
| 3678 | + else | |
| 3679 | + return infoa->die_id - infob->die_id; | |
| 3680 | + | |
| 3681 | + return 0; | |
| 3682 | +} | |
| 3683 | + | |
| 3668 | 3684 | static struct ras_err_info *amdgpu_ras_error_get_info(struct ras_err_data *err_data, |
| 3669 | 3685 | struct amdgpu_smuio_mcm_config_info *mcm_info) |
| 3670 | 3686 | { |
| @@ -3682,6 +3698,7 @@ static struct ras_err_info *amdgpu_ras_error_get_info(struct ras_err_data *err_d · 11 unmodified lines | ||
| 3682 | 3698 | |
| 3683 | 3699 | err_data->err_list_count++; |
| 3684 | 3700 | list_add_tail(&err_node->node, &err_data->err_node_list); |
| 3701 | + list_sort(NULL, &err_data->err_node_list, ras_err_info_cmp); | |
| 3685 | 3702 | |
| 3686 | 3703 | return &err_node->err_info; |
| 3687 | 3704 | } |
| @@ -214,6 +214,12 @@ static bool __get_eeprom_i2c_addr(struct amdgpu_device *adev, · 213 unmodified lines | ||
| 214 | 214 | control->i2c_address = EEPROM_I2C_MADDR_0; |
| 215 | 215 | return true; |
| 216 | 216 | case IP_VERSION(13, 0, 0): |
| 217 | + if (strnstr(atom_ctx->vbios_pn, "D707", | |
| 218 | + sizeof(atom_ctx->vbios_pn))) | |
| 219 | + control->i2c_address = EEPROM_I2C_MADDR_0; | |
| 220 | + else | |
| 221 | + control->i2c_address = EEPROM_I2C_MADDR_4; | |
| 222 | + return true; | |
| 217 | 223 | case IP_VERSION(13, 0, 6): |
| 218 | 224 | case IP_VERSION(13, 0, 10): |
| 219 | 225 | control->i2c_address = EEPROM_I2C_MADDR_4; |
| @@ -959,10 +959,8 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) · 958 unmodified lines | ||
| 959 | 959 | return 0; |
| 960 | 960 | |
| 961 | 961 | addr = amdgpu_gmc_agp_addr(bo); |
| 962 | − if (addr != AMDGPU_BO_INVALID_OFFSET) { | |
| 963 | − bo->resource->start = addr >> PAGE_SHIFT; | |
| 962 | + if (addr != AMDGPU_BO_INVALID_OFFSET) | |
| 964 | 963 | return 0; |
| 965 | − } | |
| 966 | 964 | |
| 967 | 965 | /* allocate GART space */ |
| 968 | 966 | placement.num_placement = 1; |
| @@ -398,6 +398,7 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) · 397 unmodified lines | ||
| 398 | 398 | * amdgpu_uvd_entity_init - init entity |
| 399 | 399 | * |
| 400 | 400 | * @adev: amdgpu_device pointer |
| 401 | + * @ring: amdgpu_ring pointer to check | |
| 401 | 402 | * |
| 402 | 403 | * Initialize the entity used for handle management in the kernel driver. |
| 403 | 404 | */ |
| @@ -230,6 +230,7 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev) · 229 unmodified lines | ||
| 230 | 230 | * amdgpu_vce_entity_init - init entity |
| 231 | 231 | * |
| 232 | 232 | * @adev: amdgpu_device pointer |
| 233 | + * @ring: amdgpu_ring pointer to check | |
| 233 | 234 | * |
| 234 | 235 | * Initialize the entity used for handle management in the kernel driver. |
| 235 | 236 | */ |
| @@ -89,6 +89,10 @@ MODULE_FIRMWARE("amdgpu/gc_11_5_0_me.bin"); · 88 unmodified lines | ||
| 89 | 89 | MODULE_FIRMWARE("amdgpu/gc_11_5_0_mec.bin"); |
| 90 | 90 | MODULE_FIRMWARE("amdgpu/gc_11_5_0_rlc.bin"); |
| 91 | 91 | |
| 92 | +static const struct soc15_reg_golden golden_settings_gc_11_0[] = { | |
| 93 | + SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL, 0x20000000, 0x20000000) | |
| 94 | +}; | |
| 95 | + | |
| 92 | 96 | static const struct soc15_reg_golden golden_settings_gc_11_0_1[] = |
| 93 | 97 | { |
| 94 | 98 | SOC15_REG_GOLDEN_VALUE(GC, 0, regCGTT_GS_NGG_CLK_CTRL, 0x9fff8fff, 0x00000010), |
| @@ -304,6 +308,10 @@ static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev) · 209 unmodified lines | ||
| 304 | 308 | default: |
| 305 | 309 | break; |
| 306 | 310 | } |
| 311 | + soc15_program_register_sequence(adev, | |
| 312 | + golden_settings_gc_11_0, | |
| 313 | + (const u32)ARRAY_SIZE(golden_settings_gc_11_0)); | |
| 314 | + | |
| 307 | 315 | } |
| 308 | 316 | |
| 309 | 317 | static void gfx_v11_0_write_data_to_reg(struct amdgpu_ring *ring, int eng_sel, |
| @@ -419,7 +427,7 @@ static int gfx_v11_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 109 unmodified lines | ||
| 419 | 427 | adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); |
| 420 | 428 | cpu_ptr = &adev->wb.wb[index]; |
| 421 | 429 | |
| 422 | − r = amdgpu_ib_get(adev, NULL, 16, AMDGPU_IB_POOL_DIRECT, &ib); | |
| 430 | + r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib); | |
| 423 | 431 | if (r) { |
| 424 | 432 | DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r); |
| 425 | 433 | goto err1; |
| @@ -883,8 +883,8 @@ static int gfx_v8_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 882 unmodified lines | ||
| 883 | 883 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
| 884 | 884 | adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); |
| 885 | 885 | memset(&ib, 0, sizeof(ib)); |
| 886 | − r = amdgpu_ib_get(adev, NULL, 16, | |
| 887 | − AMDGPU_IB_POOL_DIRECT, &ib); | |
| 886 | + | |
| 887 | + r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib); | |
| 888 | 888 | if (r) |
| 889 | 889 | goto err1; |
| 890 | 890 | |
| @@ -1039,8 +1039,8 @@ static int gfx_v9_0_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 1038 unmodified lines | ||
| 1039 | 1039 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
| 1040 | 1040 | adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); |
| 1041 | 1041 | memset(&ib, 0, sizeof(ib)); |
| 1042 | − r = amdgpu_ib_get(adev, NULL, 16, | |
| 1043 | − AMDGPU_IB_POOL_DIRECT, &ib); | |
| 1042 | + | |
| 1043 | + r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib); | |
| 1044 | 1044 | if (r) |
| 1045 | 1045 | goto err1; |
| 1046 | 1046 | |
| @@ -297,8 +297,8 @@ static int gfx_v9_4_3_ring_test_ib(struct amdgpu_ring *ring, long timeout) · 296 unmodified lines | ||
| 297 | 297 | gpu_addr = adev->wb.gpu_addr + (index * 4); |
| 298 | 298 | adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD); |
| 299 | 299 | memset(&ib, 0, sizeof(ib)); |
| 300 | − r = amdgpu_ib_get(adev, NULL, 16, | |
| 301 | − AMDGPU_IB_POOL_DIRECT, &ib); | |
| 300 | + | |
| 301 | + r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib); | |
| 302 | 302 | if (r) |
| 303 | 303 | goto err1; |
| 304 | 304 | |
| @@ -675,7 +675,7 @@ static void gmc_v10_0_vram_gtt_location(struct amdgpu_device *adev, · 674 unmodified lines | ||
| 675 | 675 | amdgpu_gmc_set_agp_default(adev, mc); |
| 676 | 676 | amdgpu_gmc_vram_location(adev, &adev->gmc, base); |
| 677 | 677 | amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT); |
| 678 | − if (!amdgpu_sriov_vf(adev)) | |
| 678 | + if (!amdgpu_sriov_vf(adev) && (amdgpu_agp == 1)) | |
| 679 | 679 | amdgpu_gmc_agp_location(adev, mc); |
| 680 | 680 | |
| 681 | 681 | /* base offset of vram pages */ |
| @@ -640,8 +640,9 @@ static void gmc_v11_0_vram_gtt_location(struct amdgpu_device *adev, · 639 unmodified lines | ||
| 640 | 640 | amdgpu_gmc_set_agp_default(adev, mc); |
| 641 | 641 | amdgpu_gmc_vram_location(adev, &adev->gmc, base); |
| 642 | 642 | amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_HIGH); |
| 643 | − if (!amdgpu_sriov_vf(adev) || | |
| 644 | − (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(11, 5, 0))) | |
| 643 | + if (!amdgpu_sriov_vf(adev) && | |
| 644 | + (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(11, 5, 0)) && | |
| 645 | + (amdgpu_agp == 1)) | |
| 645 | 646 | amdgpu_gmc_agp_location(adev, mc); |
| 646 | 647 | |
| 647 | 648 | /* base offset of vram pages */ |
| @@ -1630,7 +1630,7 @@ static void gmc_v9_0_vram_gtt_location(struct amdgpu_device *adev, · 1629 unmodified lines | ||
| 1630 | 1630 | } else { |
| 1631 | 1631 | amdgpu_gmc_vram_location(adev, mc, base); |
| 1632 | 1632 | amdgpu_gmc_gart_location(adev, mc, AMDGPU_GART_PLACEMENT_BEST_FIT); |
| 1633 | − if (!amdgpu_sriov_vf(adev)) | |
| 1633 | + if (!amdgpu_sriov_vf(adev) && (amdgpu_agp == 1)) | |
| 1634 | 1634 | amdgpu_gmc_agp_location(adev, mc); |
| 1635 | 1635 | } |
| 1636 | 1636 | /* base offset of vram pages */ |
| @@ -2170,8 +2170,6 @@ static int gmc_v9_0_sw_fini(void *handle) · 533 unmodified lines | ||
| 2170 | 2170 | |
| 2171 | 2171 | if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3)) |
| 2172 | 2172 | amdgpu_gmc_sysfs_fini(adev); |
| 2173 | − adev->gmc.num_mem_partitions = 0; | |
| 2174 | − kfree(adev->gmc.mem_partitions); | |
| 2175 | 2173 | |
| 2176 | 2174 | amdgpu_gmc_ras_fini(adev); |
| 2177 | 2175 | amdgpu_gem_force_release(adev); |
| @@ -2185,6 +2183,9 @@ static int gmc_v9_0_sw_fini(void *handle) · 7 unmodified lines | ||
| 2185 | 2183 | amdgpu_bo_free_kernel(&adev->gmc.pdb0_bo, NULL, &adev->gmc.ptr_pdb0); |
| 2186 | 2184 | amdgpu_bo_fini(adev); |
| 2187 | 2185 | |
| 2186 | + adev->gmc.num_mem_partitions = 0; | |
| 2187 | + kfree(adev->gmc.mem_partitions); | |
| 2188 | + | |
| 2188 | 2189 | return 0; |
| 2189 | 2190 | } |
| 2190 | 2191 | |
| @@ -129,6 +129,11 @@ static void hdp_v4_0_get_clockgating_state(struct amdgpu_device *adev, · 128 unmodified lines | ||
| 129 | 129 | { |
| 130 | 130 | int data; |
| 131 | 131 | |
| 132 | + if (amdgpu_ip_version(adev, HDP_HWIP, 0) == IP_VERSION(4, 4, 2)) { | |
| 133 | + /* Default enabled */ | |
| 134 | + *flags |= AMD_CG_SUPPORT_HDP_MGCG; | |
| 135 | + return; | |
| 136 | + } | |
| 132 | 137 | /* AMD_CG_SUPPORT_HDP_LS */ |
| 133 | 138 | data = RREG32(SOC15_REG_OFFSET(HDP, 0, mmHDP_MEM_POWER_LS)); |
| 134 | 139 | if (data & HDP_MEM_POWER_LS__LS_ENABLE_MASK) |
| @@ -130,6 +130,9 @@ static void mmhub_v1_8_init_system_aperture_regs(struct amdgpu_device *adev) · 129 unmodified lines | ||
| 130 | 130 | uint64_t value; |
| 131 | 131 | int i; |
| 132 | 132 | |
| 133 | + if (amdgpu_sriov_vf(adev)) | |
| 134 | + return; | |
| 135 | + | |
| 133 | 136 | inst_mask = adev->aid_mask; |
| 134 | 137 | for_each_inst(i, inst_mask) { |
| 135 | 138 | /* Program the AGP BAR */ |
| @@ -139,9 +142,6 @@ static void mmhub_v1_8_init_system_aperture_regs(struct amdgpu_device *adev) · 3 unmodified lines | ||
| 139 | 142 | WREG32_SOC15(MMHUB, i, regMC_VM_AGP_TOP, |
| 140 | 143 | adev->gmc.agp_end >> 24); |
| 141 | 144 | |
| 142 | − if (amdgpu_sriov_vf(adev)) | |
| 143 | − return; | |
| 144 | − | |
| 145 | 145 | /* Program the system aperture low logical page number. */ |
| 146 | 146 | WREG32_SOC15(MMHUB, i, regMC_VM_SYSTEM_APERTURE_LOW_ADDR, |
| 147 | 147 | min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); |
| @@ -259,17 +259,17 @@ const struct nbio_hdp_flush_reg nbio_v7_11_hdp_flush_reg = { · 258 unmodified lines | ||
| 259 | 259 | |
| 260 | 260 | static void nbio_v7_11_init_registers(struct amdgpu_device *adev) |
| 261 | 261 | { |
| 262 | −/* uint32_t def, data; | |
| 262 | + uint32_t def, data; | |
| 263 | + | |
| 264 | + def = data = RREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3); | |
| 265 | + data = REG_SET_FIELD(data, BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, | |
| 266 | + CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1); | |
| 267 | + data = REG_SET_FIELD(data, BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, | |
| 268 | + CI_SWUS_MAX_READ_REQUEST_SIZE_PRIV, 1); | |
| 263 | 269 | |
| 264 | − def = data = RREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3); | |
| 265 | − data = REG_SET_FIELD(data, BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, | |
| 266 | − CI_SWUS_MAX_READ_REQUEST_SIZE_MODE, 1); | |
| 267 | − data = REG_SET_FIELD(data, BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, | |
| 268 | − CI_SWUS_MAX_READ_REQUEST_SIZE_PRIV, 1); | |
| 270 | + if (def != data) | |
| 271 | + WREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, data); | |
| 269 | 272 | |
| 270 | − if (def != data) | |
| 271 | − WREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, data); | |
| 272 | −*/ | |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | 275 | static void nbio_v7_11_update_medium_grain_clock_gating(struct amdgpu_device *adev, |
| @@ -611,11 +611,6 @@ static void nbio_v7_9_handle_ras_controller_intr_no_bifring(struct amdgpu_device · 610 unmodified lines | ||
| 611 | 611 | |
| 612 | 612 | dev_info(adev->dev, "RAS controller interrupt triggered " |
| 613 | 613 | "by NBIF error\n"); |
| 614 | − | |
| 615 | − /* ras_controller_int is dedicated for nbif ras error, | |
| 616 | − * not the global interrupt for sync flood | |
| 617 | − */ | |
| 618 | − amdgpu_ras_reset_gpu(adev); | |
| 619 | 614 | } |
| 620 | 615 | |
| 621 | 616 | amdgpu_ras_error_data_fini(&err_data); |
| @@ -60,7 +60,7 @@ MODULE_FIRMWARE("amdgpu/psp_14_0_0_ta.bin"); · 59 unmodified lines | ||
| 60 | 60 | #define GFX_CMD_USB_PD_USE_LFB 0x480 |
| 61 | 61 | |
| 62 | 62 | /* Retry times for vmbx ready wait */ |
| 63 | −#define PSP_VMBX_POLLING_LIMIT 20000 | |
| 63 | +#define PSP_VMBX_POLLING_LIMIT 3000 | |
| 64 | 64 | |
| 65 | 65 | /* VBIOS gfl defines */ |
| 66 | 66 | #define MBOX_READY_MASK 0x80000000 |
| @@ -161,14 +161,18 @@ static int psp_v13_0_wait_for_vmbx_ready(struct psp_context *psp) · 94 unmodified lines | ||
| 161 | 161 | static int psp_v13_0_wait_for_bootloader(struct psp_context *psp) |
| 162 | 162 | { |
| 163 | 163 | struct amdgpu_device *adev = psp->adev; |
| 164 | − int retry_loop, ret; | |
| 164 | + int retry_loop, retry_cnt, ret; | |
| 165 | 165 | |
| 166 | + retry_cnt = | |
| 167 | + (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6)) ? | |
| 168 | + PSP_VMBX_POLLING_LIMIT : | |
| 169 | + 10; | |
| 166 | 170 | /* Wait for bootloader to signify that it is ready having bit 31 of |
| 167 | 171 | * C2PMSG_35 set to 1. All other bits are expected to be cleared. |
| 168 | 172 | * If there is an error in processing command, bits[7:0] will be set. |
| 169 | 173 | * This is applicable for PSP v13.0.6 and newer. |
| 170 | 174 | */ |
| 171 | − for (retry_loop = 0; retry_loop < PSP_VMBX_POLLING_LIMIT; retry_loop++) { | |
| 175 | + for (retry_loop = 0; retry_loop < retry_cnt; retry_loop++) { | |
| 172 | 176 | ret = psp_wait_for( |
| 173 | 177 | psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), |
| 174 | 178 | 0x80000000, 0xffffffff, false); |
| @@ -821,7 +825,7 @@ static int psp_v13_0_query_boot_status(struct psp_context *psp) · 646 unmodified lines | ||
| 821 | 825 | if (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 6)) |
| 822 | 826 | return 0; |
| 823 | 827 | |
| 824 | − if (RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_59) < 0x00a10007) | |
| 828 | + if (RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_59) < 0x00a10109) | |
| 825 | 829 | return 0; |
| 826 | 830 | |
| 827 | 831 | for_each_inst(i, inst_mask) { |
| @@ -1161,6 +1161,11 @@ static int soc15_common_early_init(void *handle) · 1160 unmodified lines | ||
| 1161 | 1161 | AMD_PG_SUPPORT_VCN_DPG | |
| 1162 | 1162 | AMD_PG_SUPPORT_JPEG; |
| 1163 | 1163 | adev->external_rev_id = adev->rev_id + 0x46; |
| 1164 | + /* GC 9.4.3 uses MMIO register region hole at a different offset */ | |
| 1165 | + if (!amdgpu_sriov_vf(adev)) { | |
| 1166 | + adev->rmmio_remap.reg_offset = 0x1A000; | |
| 1167 | + adev->rmmio_remap.bus_addr = adev->rmmio_base + 0x1A000; | |
| 1168 | + } | |
| 1164 | 1169 | break; |
| 1165 | 1170 | default: |
| 1166 | 1171 | /* FIXME: not supported yet */ |
| @@ -1418,11 +1423,14 @@ static void soc15_common_get_clockgating_state(void *handle, u64 *flags) · 251 unmodified lines | ||
| 1418 | 1423 | if (amdgpu_sriov_vf(adev)) |
| 1419 | 1424 | *flags = 0; |
| 1420 | 1425 | |
| 1421 | − adev->nbio.funcs->get_clockgating_state(adev, flags); | |
| 1426 | + if (adev->nbio.funcs && adev->nbio.funcs->get_clockgating_state) | |
| 1427 | + adev->nbio.funcs->get_clockgating_state(adev, flags); | |
| 1422 | 1428 | |
| 1423 | − adev->hdp.funcs->get_clock_gating_state(adev, flags); | |
| 1429 | + if (adev->hdp.funcs && adev->hdp.funcs->get_clock_gating_state) | |
| 1430 | + adev->hdp.funcs->get_clock_gating_state(adev, flags); | |
| 1424 | 1431 | |
| 1425 | − if (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 2)) { | |
| 1432 | + if ((amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 2)) && | |
| 1433 | + (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 6))) { | |
| 1426 | 1434 | /* AMD_CG_SUPPORT_DRM_MGCG */ |
| 1427 | 1435 | data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0)); |
| 1428 | 1436 | if (!(data & 0x01000000)) |
| @@ -1435,9 +1443,11 @@ static void soc15_common_get_clockgating_state(void *handle, u64 *flags) · 6 unmodified lines | ||
| 1435 | 1443 | } |
| 1436 | 1444 | |
| 1437 | 1445 | /* AMD_CG_SUPPORT_ROM_MGCG */ |
| 1438 | − adev->smuio.funcs->get_clock_gating_state(adev, flags); | |
| 1446 | + if (adev->smuio.funcs && adev->smuio.funcs->get_clock_gating_state) | |
| 1447 | + adev->smuio.funcs->get_clock_gating_state(adev, flags); | |
| 1439 | 1448 | |
| 1440 | − adev->df.funcs->get_clockgating_state(adev, flags); | |
| 1449 | + if (adev->df.funcs && adev->df.funcs->get_clockgating_state) | |
| 1450 | + adev->df.funcs->get_clockgating_state(adev, flags); | |
| 1441 | 1451 | } |
| 1442 | 1452 | |
| 1443 | 1453 | static int soc15_common_set_powergating_state(void *handle, |
| @@ -1128,7 +1128,7 @@ static inline struct kfd_node *kfd_node_by_irq_ids(struct amdgpu_device *adev, · 1127 unmodified lines | ||
| 1128 | 1128 | struct kfd_dev *dev = adev->kfd.dev; |
| 1129 | 1129 | uint32_t i; |
| 1130 | 1130 | |
| 1131 | − if (adev->ip_versions[GC_HWIP][0] != IP_VERSION(9, 4, 3)) | |
| 1131 | + if (KFD_GC_VERSION(dev) != IP_VERSION(9, 4, 3)) | |
| 1132 | 1132 | return dev->nodes[0]; |
| 1133 | 1133 | |
| 1134 | 1134 | for (i = 0; i < dev->num_nodes; i++) |
| @@ -169,16 +169,43 @@ int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p) · 168 unmodified lines | ||
| 169 | 169 | return 0; |
| 170 | 170 | } |
| 171 | 171 | |
| 172 | +static void pqm_clean_queue_resource(struct process_queue_manager *pqm, | |
| 173 | + struct process_queue_node *pqn) | |
| 174 | +{ | |
| 175 | + struct kfd_node *dev; | |
| 176 | + struct kfd_process_device *pdd; | |
| 177 | + | |
| 178 | + dev = pqn->q->device; | |
| 179 | + | |
| 180 | + pdd = kfd_get_process_device_data(dev, pqm->process); | |
| 181 | + if (!pdd) { | |
| 182 | + pr_err("Process device data doesn't exist\n"); | |
| 183 | + return; | |
| 184 | + } | |
| 185 | + | |
| 186 | + if (pqn->q->gws) { | |
| 187 | + if (KFD_GC_VERSION(pqn->q->device) != IP_VERSION(9, 4, 3) && | |
| 188 | + !dev->kfd->shared_resources.enable_mes) | |
| 189 | + amdgpu_amdkfd_remove_gws_from_process( | |
| 190 | + pqm->process->kgd_process_info, pqn->q->gws); | |
| 191 | + pdd->qpd.num_gws = 0; | |
| 192 | + } | |
| 193 | + | |
| 194 | + if (dev->kfd->shared_resources.enable_mes) { | |
| 195 | + amdgpu_amdkfd_free_gtt_mem(dev->adev, pqn->q->gang_ctx_bo); | |
| 196 | + if (pqn->q->wptr_bo) | |
| 197 | + amdgpu_amdkfd_free_gtt_mem(dev->adev, pqn->q->wptr_bo); | |
| 198 | + } | |
| 199 | +} | |
| 200 | + | |
| 172 | 201 | void pqm_uninit(struct process_queue_manager *pqm) |
| 173 | 202 | { |
| 174 | 203 | struct process_queue_node *pqn, *next; |
| 175 | 204 | |
| 176 | 205 | list_for_each_entry_safe(pqn, next, &pqm->queues, process_queue_list) { |
| 177 | − if (pqn->q && pqn->q->gws && | |
| 178 | − KFD_GC_VERSION(pqn->q->device) != IP_VERSION(9, 4, 3) && | |
| 179 | − !pqn->q->device->kfd->shared_resources.enable_mes) | |
| 180 | − amdgpu_amdkfd_remove_gws_from_process(pqm->process->kgd_process_info, | |
| 181 | − pqn->q->gws); | |
| 206 | + if (pqn->q) | |
| 207 | + pqm_clean_queue_resource(pqm, pqn); | |
| 208 | + | |
| 182 | 209 | kfd_procfs_del_queue(pqn->q); |
| 183 | 210 | uninit_queue(pqn->q); |
| 184 | 211 | list_del(&pqn->process_queue_list); |
| @@ -461,22 +488,7 @@ int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid) · 276 unmodified lines | ||
| 461 | 488 | goto err_destroy_queue; |
| 462 | 489 | } |
| 463 | 490 | |
| 464 | − if (pqn->q->gws) { | |
| 465 | − if (KFD_GC_VERSION(pqn->q->device) != IP_VERSION(9, 4, 3) && | |
| 466 | − !dev->kfd->shared_resources.enable_mes) | |
| 467 | − amdgpu_amdkfd_remove_gws_from_process( | |
| 468 | − pqm->process->kgd_process_info, | |
| 469 | − pqn->q->gws); | |
| 470 | − pdd->qpd.num_gws = 0; | |
| 471 | − } | |
| 472 | − | |
| 473 | − if (dev->kfd->shared_resources.enable_mes) { | |
| 474 | − amdgpu_amdkfd_free_gtt_mem(dev->adev, | |
| 475 | − pqn->q->gang_ctx_bo); | |
| 476 | − if (pqn->q->wptr_bo) | |
| 477 | − amdgpu_amdkfd_free_gtt_mem(dev->adev, pqn->q->wptr_bo); | |
| 478 | − | |
| 479 | − } | |
| 491 | + pqm_clean_queue_resource(pqm, pqn); | |
| 480 | 492 | uninit_queue(pqn->q); |
| 481 | 493 | } |
| 482 | 494 | |
| @@ -2079,7 +2079,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 2078 unmodified lines | ||
| 2079 | 2079 | struct dmub_srv_create_params create_params; |
| 2080 | 2080 | struct dmub_srv_region_params region_params; |
| 2081 | 2081 | struct dmub_srv_region_info region_info; |
| 2082 | − struct dmub_srv_fb_params fb_params; | |
| 2082 | + struct dmub_srv_memory_params memory_params; | |
| 2083 | 2083 | struct dmub_srv_fb_info *fb_info; |
| 2084 | 2084 | struct dmub_srv *dmub_srv; |
| 2085 | 2085 | const struct dmcub_firmware_header_v1_0 *hdr; |
| @@ -2182,6 +2182,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 96 unmodified lines | ||
| 2182 | 2182 | adev->dm.dmub_fw->data + |
| 2183 | 2183 | le32_to_cpu(hdr->header.ucode_array_offset_bytes) + |
| 2184 | 2184 | PSP_HEADER_BYTES; |
| 2185 | + region_params.is_mailbox_in_inbox = false; | |
| 2185 | 2186 | |
| 2186 | 2187 | status = dmub_srv_calc_region_info(dmub_srv, ®ion_params, |
| 2187 | 2188 | ®ion_info); |
| @@ -2205,10 +2206,10 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 17 unmodified lines | ||
| 2205 | 2206 | return r; |
| 2206 | 2207 | |
| 2207 | 2208 | /* Rebase the regions on the framebuffer address. */ |
| 2208 | − memset(&fb_params, 0, sizeof(fb_params)); | |
| 2209 | − fb_params.cpu_addr = adev->dm.dmub_bo_cpu_addr; | |
| 2210 | − fb_params.gpu_addr = adev->dm.dmub_bo_gpu_addr; | |
| 2211 | − fb_params.region_info = ®ion_info; | |
| 2209 | + memset(&memory_params, 0, sizeof(memory_params)); | |
| 2210 | + memory_params.cpu_fb_addr = adev->dm.dmub_bo_cpu_addr; | |
| 2211 | + memory_params.gpu_fb_addr = adev->dm.dmub_bo_gpu_addr; | |
| 2212 | + memory_params.region_info = ®ion_info; | |
| 2212 | 2213 | |
| 2213 | 2214 | adev->dm.dmub_fb_info = |
| 2214 | 2215 | kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL); |
| @@ -2220,7 +2221,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) · 5 unmodified lines | ||
| 2220 | 2221 | return -ENOMEM; |
| 2221 | 2222 | } |
| 2222 | 2223 | |
| 2223 | − status = dmub_srv_calc_fb_info(dmub_srv, &fb_params, fb_info); | |
| 2224 | + status = dmub_srv_calc_mem_info(dmub_srv, &memory_params, fb_info); | |
| 2224 | 2225 | if (status != DMUB_STATUS_OK) { |
| 2225 | 2226 | DRM_ERROR("Error calculating DMUB FB info: %d\n", status); |
| 2226 | 2227 | return -EINVAL; |
| @@ -6266,7 +6267,7 @@ int amdgpu_dm_connector_atomic_set_property(struct drm_connector *connector, · 4039 unmodified lines | ||
| 6266 | 6267 | dm_new_state->underscan_enable = val; |
| 6267 | 6268 | ret = 0; |
| 6268 | 6269 | } else if (property == adev->mode_info.abm_level_property) { |
| 6269 | − dm_new_state->abm_level = val; | |
| 6270 | + dm_new_state->abm_level = val ?: ABM_LEVEL_IMMEDIATE_DISABLE; | |
| 6270 | 6271 | ret = 0; |
| 6271 | 6272 | } |
| 6272 | 6273 | |
| @@ -6311,7 +6312,8 @@ int amdgpu_dm_connector_atomic_get_property(struct drm_connector *connector, · 38 unmodified lines | ||
| 6311 | 6312 | *val = dm_state->underscan_enable; |
| 6312 | 6313 | ret = 0; |
| 6313 | 6314 | } else if (property == adev->mode_info.abm_level_property) { |
| 6314 | − *val = dm_state->abm_level; | |
| 6315 | + *val = (dm_state->abm_level != ABM_LEVEL_IMMEDIATE_DISABLE) ? | |
| 6316 | + dm_state->abm_level : 0; | |
| 6315 | 6317 | ret = 0; |
| 6316 | 6318 | } |
| 6317 | 6319 | |
| @@ -6384,7 +6386,8 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector) · 66 unmodified lines | ||
| 6384 | 6386 | state->pbn = 0; |
| 6385 | 6387 | |
| 6386 | 6388 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) |
| 6387 | − state->abm_level = amdgpu_dm_abm_level; | |
| 6389 | + state->abm_level = amdgpu_dm_abm_level ?: | |
| 6390 | + ABM_LEVEL_IMMEDIATE_DISABLE; | |
| 6388 | 6391 | |
| 6389 | 6392 | __drm_atomic_helper_connector_reset(connector, &state->base); |
| 6390 | 6393 | } |
| @@ -7481,6 +7484,9 @@ static int amdgpu_dm_i2c_xfer(struct i2c_adapter *i2c_adap, · 1090 unmodified lines | ||
| 7481 | 7484 | int i; |
| 7482 | 7485 | int result = -EIO; |
| 7483 | 7486 | |
| 7487 | + if (!ddc_service->ddc_pin || !ddc_service->ddc_pin->hw_info.hw_supported) | |
| 7488 | + return result; | |
| 7489 | + | |
| 7484 | 7490 | cmd.payloads = kcalloc(num, sizeof(struct i2c_payload), GFP_KERNEL); |
| 7485 | 7491 | |
| 7486 | 7492 | if (!cmd.payloads) |
| @@ -9603,14 +9609,14 @@ static bool should_reset_plane(struct drm_atomic_state *state, · 2116 unmodified lines | ||
| 9603 | 9609 | struct drm_plane *other; |
| 9604 | 9610 | struct drm_plane_state *old_other_state, *new_other_state; |
| 9605 | 9611 | struct drm_crtc_state *new_crtc_state; |
| 9612 | + struct amdgpu_device *adev = drm_to_adev(plane->dev); | |
| 9606 | 9613 | int i; |
| 9607 | 9614 | |
| 9608 | 9615 | /* |
| 9609 | − * TODO: Remove this hack once the checks below are sufficient | |
| 9610 | − * enough to determine when we need to reset all the planes on | |
| 9611 | − * the stream. | |
| 9616 | + * TODO: Remove this hack for all asics once it proves that the | |
| 9617 | + * fast updates works fine on DCN3.2+. | |
| 9612 | 9618 | */ |
| 9613 | − if (state->allow_modeset) | |
| 9619 | + if (adev->ip_versions[DCE_HWIP][0] < IP_VERSION(3, 2, 0) && state->allow_modeset) | |
| 9614 | 9620 | return true; |
| 9615 | 9621 | |
| 9616 | 9622 | /* Exit early if we know that we're adding or removing the plane. */ |
| @@ -63,6 +63,12 @@ static void apply_edid_quirks(struct edid *edid, struct dc_edid_caps *edid_caps) · 62 unmodified lines | ||
| 63 | 63 | DRM_DEBUG_DRIVER("Disabling FAMS on monitor with panel id %X\n", panel_id); |
| 64 | 64 | edid_caps->panel_patch.disable_fams = true; |
| 65 | 65 | break; |
| 66 | + /* Workaround for some monitors that do not clear DPCD 0x317 if FreeSync is unsupported */ | |
| 67 | + case drm_edid_encode_panel_id('A', 'U', 'O', 0xA7AB): | |
| 68 | + case drm_edid_encode_panel_id('A', 'U', 'O', 0xE69B): | |
| 69 | + DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id); | |
| 70 | + edid_caps->panel_patch.remove_sink_ext_caps = true; | |
| 71 | + break; | |
| 66 | 72 | default: |
| 67 | 73 | return; |
| 68 | 74 | } |
| @@ -536,11 +542,8 @@ bool dm_helpers_dp_read_dpcd( · 467 unmodified lines | ||
| 536 | 542 | |
| 537 | 543 | struct amdgpu_dm_connector *aconnector = link->priv; |
| 538 | 544 | |
| 539 | − if (!aconnector) { | |
| 540 | − drm_dbg_dp(aconnector->base.dev, | |
| 541 | − "Failed to find connector for link!\n"); | |
| 545 | + if (!aconnector) | |
| 542 | 546 | return false; |
| 543 | − } | |
| 544 | 547 | |
| 545 | 548 | return drm_dp_dpcd_read(&aconnector->dm_dp_aux.aux, address, data, |
| 546 | 549 | size) == size; |
| @@ -1604,31 +1604,31 @@ enum dc_status dm_dp_mst_is_port_support_mode( · 1603 unmodified lines | ||
| 1604 | 1604 | unsigned int upper_link_bw_in_kbps = 0, down_link_bw_in_kbps = 0; |
| 1605 | 1605 | unsigned int max_compressed_bw_in_kbps = 0; |
| 1606 | 1606 | struct dc_dsc_bw_range bw_range = {0}; |
| 1607 | − struct drm_dp_mst_topology_mgr *mst_mgr; | |
| 1607 | + uint16_t full_pbn = aconnector->mst_output_port->full_pbn; | |
| 1608 | 1608 | |
| 1609 | 1609 | /* |
| 1610 | − * check if the mode could be supported if DSC pass-through is supported | |
| 1611 | − * AND check if there enough bandwidth available to support the mode | |
| 1612 | − * with DSC enabled. | |
| 1610 | + * Consider the case with the depth of the mst topology tree is equal or less than 2 | |
| 1611 | + * A. When dsc bitstream can be transmitted along the entire path | |
| 1612 | + * 1. dsc is possible between source and branch/leaf device (common dsc params is possible), AND | |
| 1613 | + * 2. dsc passthrough supported at MST branch, or | |
| 1614 | + * 3. dsc decoding supported at leaf MST device | |
| 1615 | + * Use maximum dsc compression as bw constraint | |
| 1616 | + * B. When dsc bitstream cannot be transmitted along the entire path | |
| 1617 | + * Use native bw as bw constraint | |
| 1613 | 1618 | */ |
| 1614 | 1619 | if (is_dsc_common_config_possible(stream, &bw_range) && |
| 1615 | − aconnector->mst_output_port->passthrough_aux) { | |
| 1616 | − mst_mgr = aconnector->mst_output_port->mgr; | |
| 1617 | − mutex_lock(&mst_mgr->lock); | |
| 1618 | − | |
| 1620 | + (aconnector->mst_output_port->passthrough_aux || | |
| 1621 | + aconnector->dsc_aux == &aconnector->mst_output_port->aux)) { | |
| 1619 | 1622 | cur_link_settings = stream->link->verified_link_cap; |
| 1620 | 1623 | |
| 1621 | 1624 | upper_link_bw_in_kbps = dc_link_bandwidth_kbps(aconnector->dc_link, |
| 1622 | − &cur_link_settings | |
| 1623 | − ); | |
| 1624 | − down_link_bw_in_kbps = kbps_from_pbn(aconnector->mst_output_port->full_pbn); | |
| 1625 | + &cur_link_settings); | |
| 1626 | + down_link_bw_in_kbps = kbps_from_pbn(full_pbn); | |
| 1625 | 1627 | |
| 1626 | 1628 | /* pick the bottleneck */ |
| 1627 | 1629 | end_to_end_bw_in_kbps = min(upper_link_bw_in_kbps, |
| 1628 | 1630 | down_link_bw_in_kbps); |
| 1629 | 1631 | |
| 1630 | − mutex_unlock(&mst_mgr->lock); | |
| 1631 | − | |
| 1632 | 1632 | /* |
| 1633 | 1633 | * use the maximum dsc compression bandwidth as the required |
| 1634 | 1634 | * bandwidth for the mode |
| @@ -1643,8 +1643,7 @@ enum dc_status dm_dp_mst_is_port_support_mode( · 8 unmodified lines | ||
| 1643 | 1643 | /* check if mode could be supported within full_pbn */ |
| 1644 | 1644 | bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3; |
| 1645 | 1645 | pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false); |
| 1646 | − | |
| 1647 | − if (pbn > aconnector->mst_output_port->full_pbn) | |
| 1646 | + if (pbn > full_pbn) | |
| 1648 | 1647 | return DC_FAIL_BANDWIDTH_VALIDATE; |
| 1649 | 1648 | } |
| 1650 | 1649 | |
| @@ -2386,7 +2386,13 @@ static enum bp_result get_vram_info_v30( · 2385 unmodified lines | ||
| 2386 | 2386 | return BP_RESULT_BADBIOSTABLE; |
| 2387 | 2387 | |
| 2388 | 2388 | info->num_chans = info_v30->channel_num; |
| 2389 | − info->dram_channel_width_bytes = (1 << info_v30->channel_width) / 8; | |
| 2389 | + /* As suggested by VBIOS we should always use | |
| 2390 | + * dram_channel_width_bytes = 2 when using VRAM | |
| 2391 | + * table version 3.0. This is because the channel_width | |
| 2392 | + * param in the VRAM info table is changed in 7000 series and | |
| 2393 | + * no longer represents the memory channel width. | |
| 2394 | + */ | |
| 2395 | + info->dram_channel_width_bytes = 2; | |
| 2390 | 2396 | |
| 2391 | 2397 | return result; |
| 2392 | 2398 | } |
| @@ -334,7 +334,7 @@ static struct wm_table lpddr5_wm_table = { · 333 unmodified lines | ||
| 334 | 334 | { |
| 335 | 335 | .wm_inst = WM_A, |
| 336 | 336 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 337 | − .pstate_latency_us = 11.65333, | |
| 337 | + .pstate_latency_us = 129.0, | |
| 338 | 338 | .sr_exit_time_us = 11.5, |
| 339 | 339 | .sr_enter_plus_exit_time_us = 14.5, |
| 340 | 340 | .valid = true, |
| @@ -342,7 +342,7 @@ static struct wm_table lpddr5_wm_table = { · 1 unmodified line | ||
| 342 | 342 | { |
| 343 | 343 | .wm_inst = WM_B, |
| 344 | 344 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 345 | − .pstate_latency_us = 11.65333, | |
| 345 | + .pstate_latency_us = 129.0, | |
| 346 | 346 | .sr_exit_time_us = 11.5, |
| 347 | 347 | .sr_enter_plus_exit_time_us = 14.5, |
| 348 | 348 | .valid = true, |
| @@ -350,7 +350,7 @@ static struct wm_table lpddr5_wm_table = { · 1 unmodified line | ||
| 350 | 350 | { |
| 351 | 351 | .wm_inst = WM_C, |
| 352 | 352 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 353 | − .pstate_latency_us = 11.65333, | |
| 353 | + .pstate_latency_us = 129.0, | |
| 354 | 354 | .sr_exit_time_us = 11.5, |
| 355 | 355 | .sr_enter_plus_exit_time_us = 14.5, |
| 356 | 356 | .valid = true, |
| @@ -358,7 +358,7 @@ static struct wm_table lpddr5_wm_table = { · 1 unmodified line | ||
| 358 | 358 | { |
| 359 | 359 | .wm_inst = WM_D, |
| 360 | 360 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 361 | − .pstate_latency_us = 11.65333, | |
| 361 | + .pstate_latency_us = 129.0, | |
| 362 | 362 | .sr_exit_time_us = 11.5, |
| 363 | 363 | .sr_enter_plus_exit_time_us = 14.5, |
| 364 | 364 | .valid = true, |
| @@ -232,6 +232,10 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base, · 231 unmodified lines | ||
| 232 | 232 | if (dc->work_arounds.skip_clock_update) |
| 233 | 233 | return; |
| 234 | 234 | |
| 235 | + /* DTBCLK is fixed, so set a default if unspecified. */ | |
| 236 | + if (new_clocks->dtbclk_en && !new_clocks->ref_dtbclk_khz) | |
| 237 | + new_clocks->ref_dtbclk_khz = 600000; | |
| 238 | + | |
| 235 | 239 | /* |
| 236 | 240 | * if it is safe to lower, but we are already in the lower state, we don't have to do anything |
| 237 | 241 | * also if safe to lower is false, we just go in the higher state |
| @@ -265,8 +269,10 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base, · 27 unmodified lines | ||
| 265 | 269 | |
| 266 | 270 | if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) { |
| 267 | 271 | dcn35_smu_set_dtbclk(clk_mgr, true); |
| 268 | − dcn35_update_clocks_update_dtb_dto(clk_mgr, context, clk_mgr_base->clks.ref_dtbclk_khz); | |
| 269 | 272 | clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en; |
| 273 | + | |
| 274 | + dcn35_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz); | |
| 275 | + clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz; | |
| 270 | 276 | } |
| 271 | 277 | |
| 272 | 278 | /* check that we're not already in D0 */ |
| @@ -314,17 +320,12 @@ void dcn35_update_clocks(struct clk_mgr *clk_mgr_base, · 41 unmodified lines | ||
| 314 | 320 | update_dispclk = true; |
| 315 | 321 | } |
| 316 | 322 | |
| 317 | − if (!new_clocks->dtbclk_en) { | |
| 318 | − new_clocks->ref_dtbclk_khz = 600000; | |
| 319 | − } | |
| 320 | − | |
| 321 | 323 | /* clock limits are received with MHz precision, divide by 1000 to prevent setting clocks at every call */ |
| 322 | 324 | if (!dc->debug.disable_dtb_ref_clk_switch && |
| 323 | − should_set_clock(safe_to_lower, new_clocks->ref_dtbclk_khz / 1000, clk_mgr_base->clks.ref_dtbclk_khz / 1000)) { | |
| 324 | − /* DCCG requires KHz precision for DTBCLK */ | |
| 325 | − dcn35_smu_set_dtbclk(clk_mgr, true); | |
| 326 | − | |
| 327 | − dcn35_update_clocks_update_dtb_dto(clk_mgr, context, clk_mgr_base->clks.ref_dtbclk_khz); | |
| 325 | + should_set_clock(safe_to_lower, new_clocks->ref_dtbclk_khz / 1000, | |
| 326 | + clk_mgr_base->clks.ref_dtbclk_khz / 1000)) { | |
| 327 | + dcn35_update_clocks_update_dtb_dto(clk_mgr, context, new_clocks->ref_dtbclk_khz); | |
| 328 | + clk_mgr_base->clks.ref_dtbclk_khz = new_clocks->ref_dtbclk_khz; | |
| 328 | 329 | } |
| 329 | 330 | |
| 330 | 331 | if (dpp_clock_lowered) { |
| @@ -443,32 +444,32 @@ static struct wm_table ddr5_wm_table = { · 112 unmodified lines | ||
| 443 | 444 | .wm_inst = WM_A, |
| 444 | 445 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 445 | 446 | .pstate_latency_us = 11.72, |
| 446 | − .sr_exit_time_us = 9, | |
| 447 | − .sr_enter_plus_exit_time_us = 11, | |
| 447 | + .sr_exit_time_us = 14.0, | |
| 448 | + .sr_enter_plus_exit_time_us = 16.0, | |
| 448 | 449 | .valid = true, |
| 449 | 450 | }, |
| 450 | 451 | { |
| 451 | 452 | .wm_inst = WM_B, |
| 452 | 453 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 453 | 454 | .pstate_latency_us = 11.72, |
| 454 | − .sr_exit_time_us = 9, | |
| 455 | − .sr_enter_plus_exit_time_us = 11, | |
| 455 | + .sr_exit_time_us = 14.0, | |
| 456 | + .sr_enter_plus_exit_time_us = 16.0, | |
| 456 | 457 | .valid = true, |
| 457 | 458 | }, |
| 458 | 459 | { |
| 459 | 460 | .wm_inst = WM_C, |
| 460 | 461 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 461 | 462 | .pstate_latency_us = 11.72, |
| 462 | − .sr_exit_time_us = 9, | |
| 463 | − .sr_enter_plus_exit_time_us = 11, | |
| 463 | + .sr_exit_time_us = 14.0, | |
| 464 | + .sr_enter_plus_exit_time_us = 16.0, | |
| 464 | 465 | .valid = true, |
| 465 | 466 | }, |
| 466 | 467 | { |
| 467 | 468 | .wm_inst = WM_D, |
| 468 | 469 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 469 | 470 | .pstate_latency_us = 11.72, |
| 470 | − .sr_exit_time_us = 9, | |
| 471 | − .sr_enter_plus_exit_time_us = 11, | |
| 471 | + .sr_exit_time_us = 14.0, | |
| 472 | + .sr_enter_plus_exit_time_us = 16.0, | |
| 472 | 473 | .valid = true, |
| 473 | 474 | }, |
| 474 | 475 | } |
| @@ -480,32 +481,32 @@ static struct wm_table lpddr5_wm_table = { · 5 unmodified lines | ||
| 480 | 481 | .wm_inst = WM_A, |
| 481 | 482 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 482 | 483 | .pstate_latency_us = 11.65333, |
| 483 | − .sr_exit_time_us = 11.5, | |
| 484 | − .sr_enter_plus_exit_time_us = 14.5, | |
| 484 | + .sr_exit_time_us = 14.0, | |
| 485 | + .sr_enter_plus_exit_time_us = 16.0, | |
| 485 | 486 | .valid = true, |
| 486 | 487 | }, |
| 487 | 488 | { |
| 488 | 489 | .wm_inst = WM_B, |
| 489 | 490 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 490 | 491 | .pstate_latency_us = 11.65333, |
| 491 | − .sr_exit_time_us = 11.5, | |
| 492 | − .sr_enter_plus_exit_time_us = 14.5, | |
| 492 | + .sr_exit_time_us = 14.0, | |
| 493 | + .sr_enter_plus_exit_time_us = 16.0, | |
| 493 | 494 | .valid = true, |
| 494 | 495 | }, |
| 495 | 496 | { |
| 496 | 497 | .wm_inst = WM_C, |
| 497 | 498 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 498 | 499 | .pstate_latency_us = 11.65333, |
| 499 | − .sr_exit_time_us = 11.5, | |
| 500 | − .sr_enter_plus_exit_time_us = 14.5, | |
| 500 | + .sr_exit_time_us = 14.0, | |
| 501 | + .sr_enter_plus_exit_time_us = 16.0, | |
| 501 | 502 | .valid = true, |
| 502 | 503 | }, |
| 503 | 504 | { |
| 504 | 505 | .wm_inst = WM_D, |
| 505 | 506 | .wm_type = WM_TYPE_PSTATE_CHG, |
| 506 | 507 | .pstate_latency_us = 11.65333, |
| 507 | − .sr_exit_time_us = 11.5, | |
| 508 | − .sr_enter_plus_exit_time_us = 14.5, | |
| 508 | + .sr_exit_time_us = 14.0, | |
| 509 | + .sr_enter_plus_exit_time_us = 16.0, | |
| 509 | 510 | .valid = true, |
| 510 | 511 | }, |
| 511 | 512 | } |
| @@ -515,11 +516,6 @@ static DpmClocks_t_dcn35 dummy_clocks; · 3 unmodified lines | ||
| 515 | 516 | |
| 516 | 517 | static struct dcn35_watermarks dummy_wms = { 0 }; |
| 517 | 518 | |
| 518 | −static struct dcn35_ss_info_table ss_info_table = { | |
| 519 | − .ss_divider = 1000, | |
| 520 | − .ss_percentage = {0, 0, 375, 375, 375} | |
| 521 | −}; | |
| 522 | − | |
| 523 | 519 | static void dcn35_build_watermark_ranges(struct clk_bw_params *bw_params, struct dcn35_watermarks *table) |
| 524 | 520 | { |
| 525 | 521 | int i, num_valid_sets; |
| @@ -653,27 +649,47 @@ static unsigned int convert_wck_ratio(uint8_t wck_ratio) · 127 unmodified lines | ||
| 653 | 649 | return 1; |
| 654 | 650 | } |
| 655 | 651 | |
| 652 | +static inline uint32_t calc_dram_speed_mts(const MemPstateTable_t *entry) | |
| 653 | +{ | |
| 654 | + return entry->UClk * convert_wck_ratio(entry->WckRatio) * 2; | |
| 655 | +} | |
| 656 | + | |
| 656 | 657 | static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk_mgr, |
| 657 | 658 | struct integrated_info *bios_info, |
| 658 | 659 | DpmClocks_t_dcn35 *clock_table) |
| 659 | 660 | { |
| 660 | 661 | struct clk_bw_params *bw_params = clk_mgr->base.bw_params; |
| 661 | 662 | struct clk_limit_table_entry def_max = bw_params->clk_table.entries[bw_params->clk_table.num_entries - 1]; |
| 662 | − uint32_t max_pstate = 0, max_uclk = 0, max_fclk = 0; | |
| 663 | − uint32_t min_pstate = 0, max_dispclk = 0, max_dppclk = 0; | |
| 663 | + uint32_t max_fclk = 0, min_pstate = 0, max_dispclk = 0, max_dppclk = 0; | |
| 664 | + uint32_t max_pstate = 0, max_dram_speed_mts = 0, min_dram_speed_mts = 0; | |
| 664 | 665 | int i; |
| 665 | 666 | |
| 667 | + /* Determine min/max p-state values. */ | |
| 666 | 668 | for (i = 0; i < clock_table->NumMemPstatesEnabled; i++) { |
| 667 | − if (is_valid_clock_value(clock_table->MemPstateTable[i].UClk) && | |
| 668 | − clock_table->MemPstateTable[i].UClk > max_uclk) { | |
| 669 | − max_uclk = clock_table->MemPstateTable[i].UClk; | |
| 669 | + uint32_t dram_speed_mts = calc_dram_speed_mts(&clock_table->MemPstateTable[i]); | |
| 670 | + | |
| 671 | + if (is_valid_clock_value(dram_speed_mts) && dram_speed_mts > max_dram_speed_mts) { | |
| 672 | + max_dram_speed_mts = dram_speed_mts; | |
| 670 | 673 | max_pstate = i; |
| 671 | 674 | } |
| 672 | 675 | } |
| 673 | 676 | |
| 674 | − /* We expect the table to contain at least one valid Uclk entry. */ | |
| 675 | − ASSERT(is_valid_clock_value(max_uclk)); | |
| 677 | + min_dram_speed_mts = max_dram_speed_mts; | |
| 678 | + min_pstate = max_pstate; | |
| 679 | + | |
| 680 | + for (i = 0; i < clock_table->NumMemPstatesEnabled; i++) { | |
| 681 | + uint32_t dram_speed_mts = calc_dram_speed_mts(&clock_table->MemPstateTable[i]); | |
| 682 | + | |
| 683 | + if (is_valid_clock_value(dram_speed_mts) && dram_speed_mts < min_dram_speed_mts) { | |
| 684 | + min_dram_speed_mts = dram_speed_mts; | |
| 685 | + min_pstate = i; | |
| 686 | + } | |
| 687 | + } | |
| 676 | 688 | |
| 689 | + /* We expect the table to contain at least one valid P-state entry. */ | |
| 690 | + ASSERT(clock_table->NumMemPstatesEnabled && | |
| 691 | + is_valid_clock_value(max_dram_speed_mts) && | |
| 692 | + is_valid_clock_value(min_dram_speed_mts)); | |
| 677 | 693 | |
| 678 | 694 | /* dispclk and dppclk can be max at any voltage, same number of levels for both */ |
| 679 | 695 | if (clock_table->NumDispClkLevelsEnabled <= NUM_DISPCLK_DPM_LEVELS && |
| @@ -683,47 +699,46 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk · 3 unmodified lines | ||
| 683 | 699 | max_dppclk = find_max_clk_value(clock_table->DppClocks, |
| 684 | 700 | clock_table->NumDispClkLevelsEnabled); |
| 685 | 701 | } else { |
| 702 | + /* Invalid number of entries in the table from PMFW. */ | |
| 686 | 703 | ASSERT(0); |
| 687 | 704 | } |
| 688 | − if (clock_table->NumFclkLevelsEnabled <= NUM_FCLK_DPM_LEVELS) | |
| 689 | − max_fclk = find_max_clk_value(clock_table->FclkClocks_Freq, | |
| 690 | − clock_table->NumFclkLevelsEnabled); | |
| 691 | 705 | |
| 692 | − for (i = 0; i < clock_table->NumMemPstatesEnabled; i++) { | |
| 693 | − uint32_t min_uclk = clock_table->MemPstateTable[0].UClk; | |
| 694 | − int j; | |
| 706 | + /* Base the clock table on dcfclk, need at least one entry regardless of pmfw table */ | |
| 707 | + ASSERT(clock_table->NumDcfClkLevelsEnabled > 0); | |
| 695 | 708 | |
| 696 | − for (j = 1; j < clock_table->NumMemPstatesEnabled; j++) { | |
| 697 | − if (is_valid_clock_value(clock_table->MemPstateTable[j].UClk) && | |
| 698 | − clock_table->MemPstateTable[j].UClk < min_uclk && | |
| 699 | − clock_table->MemPstateTable[j].Voltage <= clock_table->SocVoltage[i]) { | |
| 700 | − min_uclk = clock_table->MemPstateTable[j].UClk; | |
| 701 | − min_pstate = j; | |
| 702 | − } | |
| 703 | − } | |
| 709 | + max_fclk = find_max_clk_value(clock_table->FclkClocks_Freq, clock_table->NumFclkLevelsEnabled); | |
| 710 | + | |
| 711 | + for (i = 0; i < clock_table->NumDcfClkLevelsEnabled; i++) { | |
| 712 | + int j; | |
| 704 | 713 | |
| 714 | + /* First search defaults for the clocks we don't read using closest lower or equal default dcfclk */ | |
| 705 | 715 | for (j = bw_params->clk_table.num_entries - 1; j > 0; j--) |
| 706 | 716 | if (bw_params->clk_table.entries[j].dcfclk_mhz <= clock_table->DcfClocks[i]) |
| 707 | − break; | |
| 717 | + break; | |
| 708 | 718 | |
| 709 | 719 | bw_params->clk_table.entries[i].phyclk_mhz = bw_params->clk_table.entries[j].phyclk_mhz; |
| 710 | 720 | bw_params->clk_table.entries[i].phyclk_d18_mhz = bw_params->clk_table.entries[j].phyclk_d18_mhz; |
| 711 | 721 | bw_params->clk_table.entries[i].dtbclk_mhz = bw_params->clk_table.entries[j].dtbclk_mhz; |
| 712 | − bw_params->clk_table.entries[i].fclk_mhz = max_fclk; | |
| 722 | + | |
| 723 | + /* Now update clocks we do read */ | |
| 713 | 724 | bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemPstateTable[min_pstate].MemClk; |
| 714 | 725 | bw_params->clk_table.entries[i].voltage = clock_table->MemPstateTable[min_pstate].Voltage; |
| 715 | 726 | bw_params->clk_table.entries[i].dcfclk_mhz = clock_table->DcfClocks[i]; |
| 716 | 727 | bw_params->clk_table.entries[i].socclk_mhz = clock_table->SocClocks[i]; |
| 717 | 728 | bw_params->clk_table.entries[i].dispclk_mhz = max_dispclk; |
| 718 | 729 | bw_params->clk_table.entries[i].dppclk_mhz = max_dppclk; |
| 719 | − bw_params->clk_table.entries[i].wck_ratio = convert_wck_ratio( | |
| 720 | − clock_table->MemPstateTable[min_pstate].WckRatio); | |
| 721 | − } | |
| 730 | + bw_params->clk_table.entries[i].wck_ratio = | |
| 731 | + convert_wck_ratio(clock_table->MemPstateTable[min_pstate].WckRatio); | |
| 732 | + | |
| 733 | + /* Dcfclk and Fclk are tied, but at a different ratio */ | |
| 734 | + bw_params->clk_table.entries[i].fclk_mhz = min(max_fclk, 2 * clock_table->DcfClocks[i]); | |
| 735 | + } | |
| 722 | 736 | |
| 723 | 737 | /* Make sure to include at least one entry at highest pstate */ |
| 724 | 738 | if (max_pstate != min_pstate || i == 0) { |
| 725 | 739 | if (i > MAX_NUM_DPM_LVL - 1) |
| 726 | 740 | i = MAX_NUM_DPM_LVL - 1; |
| 741 | + | |
| 727 | 742 | bw_params->clk_table.entries[i].fclk_mhz = max_fclk; |
| 728 | 743 | bw_params->clk_table.entries[i].memclk_mhz = clock_table->MemPstateTable[max_pstate].MemClk; |
| 729 | 744 | bw_params->clk_table.entries[i].voltage = clock_table->MemPstateTable[max_pstate].Voltage; |
| @@ -739,6 +754,7 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk · 9 unmodified lines | ||
| 739 | 754 | } |
| 740 | 755 | bw_params->clk_table.num_entries = i--; |
| 741 | 756 | |
| 757 | + /* Make sure all highest clocks are included*/ | |
| 742 | 758 | bw_params->clk_table.entries[i].socclk_mhz = |
| 743 | 759 | find_max_clk_value(clock_table->SocClocks, NUM_SOCCLK_DPM_LEVELS); |
| 744 | 760 | bw_params->clk_table.entries[i].dispclk_mhz = |
| @@ -757,6 +773,11 @@ static void dcn35_clk_mgr_helper_populate_bw_params(struct clk_mgr_internal *clk · 12 unmodified lines | ||
| 757 | 773 | bw_params->clk_table.num_entries_per_clk.num_fclk_levels = clock_table->NumFclkLevelsEnabled; |
| 758 | 774 | bw_params->clk_table.num_entries_per_clk.num_memclk_levels = clock_table->NumMemPstatesEnabled; |
| 759 | 775 | bw_params->clk_table.num_entries_per_clk.num_socclk_levels = clock_table->NumSocClkLevelsEnabled; |
| 776 | + | |
| 777 | + /* | |
| 778 | + * Set any 0 clocks to max default setting. Not an issue for | |
| 779 | + * power since we aren't doing switching in such case anyway | |
| 780 | + */ | |
| 760 | 781 | for (i = 0; i < bw_params->clk_table.num_entries; i++) { |
| 761 | 782 | if (!bw_params->clk_table.entries[i].fclk_mhz) { |
| 762 | 783 | bw_params->clk_table.entries[i].fclk_mhz = def_max.fclk_mhz; |
| @@ -820,22 +841,22 @@ static void dcn35_set_idle_state(struct clk_mgr *clk_mgr_base, bool allow_idle) · 57 unmodified lines | ||
| 820 | 841 | |
| 821 | 842 | if (dc->config.disable_ips == DMUB_IPS_ENABLE || |
| 822 | 843 | dc->config.disable_ips == DMUB_IPS_DISABLE_DYNAMIC) { |
| 823 | − val |= DMUB_IPS1_ALLOW_MASK; | |
| 824 | − val |= DMUB_IPS2_ALLOW_MASK; | |
| 825 | − } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS1) { | |
| 826 | 844 | val = val & ~DMUB_IPS1_ALLOW_MASK; |
| 827 | 845 | val = val & ~DMUB_IPS2_ALLOW_MASK; |
| 828 | − } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2) { | |
| 829 | − val |= DMUB_IPS1_ALLOW_MASK; | |
| 830 | − val = val & ~DMUB_IPS2_ALLOW_MASK; | |
| 831 | − } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2_Z10) { | |
| 846 | + } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS1) { | |
| 832 | 847 | val |= DMUB_IPS1_ALLOW_MASK; |
| 833 | 848 | val |= DMUB_IPS2_ALLOW_MASK; |
| 849 | + } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2) { | |
| 850 | + val = val & ~DMUB_IPS1_ALLOW_MASK; | |
| 851 | + val |= DMUB_IPS2_ALLOW_MASK; | |
| 852 | + } else if (dc->config.disable_ips == DMUB_IPS_DISABLE_IPS2_Z10) { | |
| 853 | + val = val & ~DMUB_IPS1_ALLOW_MASK; | |
| 854 | + val = val & ~DMUB_IPS2_ALLOW_MASK; | |
| 834 | 855 | } |
| 835 | 856 | |
| 836 | 857 | if (!allow_idle) { |
| 837 | − val = val & ~DMUB_IPS1_ALLOW_MASK; | |
| 838 | − val = val & ~DMUB_IPS2_ALLOW_MASK; | |
| 858 | + val |= DMUB_IPS1_ALLOW_MASK; | |
| 859 | + val |= DMUB_IPS2_ALLOW_MASK; | |
| 839 | 860 | } |
| 840 | 861 | |
| 841 | 862 | dcn35_smu_write_ips_scratch(clk_mgr, val); |
| @@ -965,21 +986,6 @@ struct clk_mgr_funcs dcn35_fpga_funcs = { · 123 unmodified lines | ||
| 965 | 986 | .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz, |
| 966 | 987 | }; |
| 967 | 988 | |
| 968 | −static void dcn35_read_ss_info_from_lut(struct clk_mgr_internal *clk_mgr) | |
| 969 | −{ | |
| 970 | − uint32_t clock_source; | |
| 971 | − struct dc_context *ctx = clk_mgr->base.ctx; | |
| 972 | − | |
| 973 | − REG_GET(CLK1_CLK2_BYPASS_CNTL, CLK2_BYPASS_SEL, &clock_source); | |
| 974 | − | |
| 975 | − clk_mgr->dprefclk_ss_percentage = ss_info_table.ss_percentage[clock_source]; | |
| 976 | − | |
| 977 | − if (clk_mgr->dprefclk_ss_percentage != 0) { | |
| 978 | − clk_mgr->ss_on_dprefclk = true; | |
| 979 | − clk_mgr->dprefclk_ss_divider = ss_info_table.ss_divider; | |
| 980 | − } | |
| 981 | −} | |
| 982 | − | |
| 983 | 989 | void dcn35_clk_mgr_construct( |
| 984 | 990 | struct dc_context *ctx, |
| 985 | 991 | struct clk_mgr_dcn35 *clk_mgr, |
| @@ -1043,17 +1049,11 @@ void dcn35_clk_mgr_construct( · 57 unmodified lines | ||
| 1043 | 1049 | dcn35_dump_clk_registers(&clk_mgr->base.base.boot_snapshot, &clk_mgr->base.base, &log_info); |
| 1044 | 1050 | |
| 1045 | 1051 | clk_mgr->base.base.dprefclk_khz = dcn35_smu_get_dprefclk(&clk_mgr->base); |
| 1046 | − clk_mgr->base.base.clks.ref_dtbclk_khz = dcn35_smu_get_dtbclk(&clk_mgr->base); | |
| 1047 | − | |
| 1048 | − if (!clk_mgr->base.base.clks.ref_dtbclk_khz) | |
| 1049 | − dcn35_smu_set_dtbclk(&clk_mgr->base, true); | |
| 1052 | + clk_mgr->base.base.clks.ref_dtbclk_khz = 600000; | |
| 1050 | 1053 | |
| 1051 | − clk_mgr->base.base.clks.dtbclk_en = true; | |
| 1052 | 1054 | dce_clock_read_ss_info(&clk_mgr->base); |
| 1053 | 1055 | /*when clk src is from FCH, it could have ss, same clock src as DPREF clk*/ |
| 1054 | 1056 | |
| 1055 | − dcn35_read_ss_info_from_lut(&clk_mgr->base); | |
| 1056 | − | |
| 1057 | 1057 | clk_mgr->base.base.bw_params = &dcn35_bw_params; |
| 1058 | 1058 | |
| 1059 | 1059 | if (clk_mgr->base.base.ctx->dc->debug.pstate_enabled) { |
| @@ -1129,7 +1129,6 @@ void dcn35_clk_mgr_construct( · 69 unmodified lines | ||
| 1129 | 1129 | ctx->dc->debug.disable_dpp_power_gate = false; |
| 1130 | 1130 | ctx->dc->debug.disable_hubp_power_gate = false; |
| 1131 | 1131 | ctx->dc->debug.disable_dsc_power_gate = false; |
| 1132 | − ctx->dc->debug.disable_hpo_power_gate = false; | |
| 1133 | 1132 | } else { |
| 1134 | 1133 | /*let's reset the config control flag*/ |
| 1135 | 1134 | ctx->dc->config.disable_ips = DMUB_IPS_DISABLE_ALL; /*pmfw not support it, disable it all*/ |
| @@ -3178,7 +3178,7 @@ static bool update_planes_and_stream_state(struct dc *dc, · 3177 unmodified lines | ||
| 3178 | 3178 | struct pipe_ctx *otg_master = resource_get_otg_master_for_stream(&context->res_ctx, |
| 3179 | 3179 | context->streams[i]); |
| 3180 | 3180 | |
| 3181 | − if (otg_master->stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) | |
| 3181 | + if (otg_master && otg_master->stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) | |
| 3182 | 3182 | resource_build_test_pattern_params(&context->res_ctx, otg_master); |
| 3183 | 3183 | } |
| 3184 | 3184 | } |
| @@ -4934,8 +4934,8 @@ bool dc_dmub_is_ips_idle_state(struct dc *dc) · 1749 unmodified lines | ||
| 4934 | 4934 | if (dc->hwss.get_idle_state) |
| 4935 | 4935 | idle_state = dc->hwss.get_idle_state(dc); |
| 4936 | 4936 | |
| 4937 | − if ((idle_state & DMUB_IPS1_ALLOW_MASK) || | |
| 4938 | − (idle_state & DMUB_IPS2_ALLOW_MASK)) | |
| 4937 | + if (!(idle_state & DMUB_IPS1_ALLOW_MASK) || | |
| 4938 | + !(idle_state & DMUB_IPS2_ALLOW_MASK)) | |
| 4939 | 4939 | return true; |
| 4940 | 4940 | |
| 4941 | 4941 | return false; |
| @@ -5190,6 +5190,9 @@ bool dc_resource_acquire_secondary_pipe_for_mpc_odm_legacy( · 5189 unmodified lines | ||
| 5190 | 5190 | sec_next = sec_pipe->next_odm_pipe; |
| 5191 | 5191 | sec_prev = sec_pipe->prev_odm_pipe; |
| 5192 | 5192 | |
| 5193 | + if (pri_pipe == NULL) | |
| 5194 | + return false; | |
| 5195 | + | |
| 5193 | 5196 | *sec_pipe = *pri_pipe; |
| 5194 | 5197 | |
| 5195 | 5198 | sec_pipe->top_pipe = sec_top; |
| @@ -874,6 +874,7 @@ struct dc_debug_options { · 873 unmodified lines | ||
| 874 | 874 | unsigned int seamless_boot_odm_combine; |
| 875 | 875 | unsigned int force_odm_combine_4to1; //bit vector based on otg inst |
| 876 | 876 | int minimum_z8_residency_time; |
| 877 | + int minimum_z10_residency_time; | |
| 877 | 878 | bool disable_z9_mpc; |
| 878 | 879 | unsigned int force_fclk_khz; |
| 879 | 880 | bool enable_tri_buf; |
| @@ -1608,7 +1609,6 @@ struct dc_link { · 728 unmodified lines | ||
| 1608 | 1609 | enum edp_revision edp_revision; |
| 1609 | 1610 | union dpcd_sink_ext_caps dpcd_sink_ext_caps; |
| 1610 | 1611 | |
| 1611 | − struct backlight_settings backlight_settings; | |
| 1612 | 1612 | struct psr_settings psr_settings; |
| 1613 | 1613 | |
| 1614 | 1614 | struct replay_settings replay_settings; |
| @@ -1202,11 +1202,11 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc) · 1201 unmodified lines | ||
| 1202 | 1202 | allow_state = dc->hwss.get_idle_state(dc); |
| 1203 | 1203 | dc->hwss.set_idle_state(dc, false); |
| 1204 | 1204 | |
| 1205 | − if (allow_state & DMUB_IPS2_ALLOW_MASK) { | |
| 1205 | + if (!(allow_state & DMUB_IPS2_ALLOW_MASK)) { | |
| 1206 | 1206 | // Wait for evaluation time |
| 1207 | 1207 | udelay(dc->debug.ips2_eval_delay_us); |
| 1208 | 1208 | commit_state = dc->hwss.get_idle_state(dc); |
| 1209 | − if (commit_state & DMUB_IPS2_COMMIT_MASK) { | |
| 1209 | + if (!(commit_state & DMUB_IPS2_COMMIT_MASK)) { | |
| 1210 | 1210 | // Tell PMFW to exit low power state |
| 1211 | 1211 | dc->clk_mgr->funcs->exit_low_power_state(dc->clk_mgr); |
| 1212 | 1212 | |
| @@ -1216,7 +1216,7 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc) · 3 unmodified lines | ||
| 1216 | 1216 | |
| 1217 | 1217 | for (i = 0; i < max_num_polls; ++i) { |
| 1218 | 1218 | commit_state = dc->hwss.get_idle_state(dc); |
| 1219 | − if (!(commit_state & DMUB_IPS2_COMMIT_MASK)) | |
| 1219 | + if (commit_state & DMUB_IPS2_COMMIT_MASK) | |
| 1220 | 1220 | break; |
| 1221 | 1221 | |
| 1222 | 1222 | udelay(1); |
| @@ -1235,10 +1235,10 @@ void dc_dmub_srv_exit_low_power_state(const struct dc *dc) · 12 unmodified lines | ||
| 1235 | 1235 | } |
| 1236 | 1236 | |
| 1237 | 1237 | dc_dmub_srv_notify_idle(dc, false); |
| 1238 | − if (allow_state & DMUB_IPS1_ALLOW_MASK) { | |
| 1238 | + if (!(allow_state & DMUB_IPS1_ALLOW_MASK)) { | |
| 1239 | 1239 | for (i = 0; i < max_num_polls; ++i) { |
| 1240 | 1240 | commit_state = dc->hwss.get_idle_state(dc); |
| 1241 | − if (!(commit_state & DMUB_IPS1_COMMIT_MASK)) | |
| 1241 | + if (commit_state & DMUB_IPS1_COMMIT_MASK) | |
| 1242 | 1242 | break; |
| 1243 | 1243 | |
| 1244 | 1244 | udelay(1); |
| @@ -177,6 +177,7 @@ struct dc_panel_patch { · 176 unmodified lines | ||
| 177 | 177 | unsigned int disable_fams; |
| 178 | 178 | unsigned int skip_avmute; |
| 179 | 179 | unsigned int mst_start_top_delay; |
| 180 | + unsigned int remove_sink_ext_caps; | |
| 180 | 181 | }; |
| 181 | 182 | |
| 182 | 183 | struct dc_edid_caps { |
| @@ -990,10 +991,6 @@ struct link_mst_stream_allocation_table { · 807 unmodified lines | ||
| 990 | 991 | struct link_mst_stream_allocation stream_allocations[MAX_CONTROLLER_NUM]; |
| 991 | 992 | }; |
| 992 | 993 | |
| 993 | −struct backlight_settings { | |
| 994 | − uint32_t backlight_millinits; | |
| 995 | −}; | |
| 996 | − | |
| 997 | 994 | /* PSR feature flags */ |
| 998 | 995 | struct psr_settings { |
| 999 | 996 | bool psr_feature_enabled; // PSR is supported by sink |
| @@ -871,7 +871,7 @@ static const struct dc_plane_cap plane_cap = { · 870 unmodified lines | ||
| 871 | 871 | static const struct dc_debug_options debug_defaults_drv = { |
| 872 | 872 | .disable_z10 = false, |
| 873 | 873 | .enable_z9_disable_interface = true, |
| 874 | − .minimum_z8_residency_time = 2000, | |
| 874 | + .minimum_z8_residency_time = 2100, | |
| 875 | 875 | .psr_skip_crtc_disable = true, |
| 876 | 876 | .replay_skip_crtc_disabled = true, |
| 877 | 877 | .disable_dmcu = true, |
| @@ -261,12 +261,6 @@ static void enc35_stream_encoder_enable( · 260 unmodified lines | ||
| 261 | 261 | /* invalid mode ! */ |
| 262 | 262 | ASSERT_CRITICAL(false); |
| 263 | 263 | } |
| 264 | − | |
| 265 | − REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 1); | |
| 266 | − REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 1); | |
| 267 | − } else { | |
| 268 | − REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 0); | |
| 269 | − REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 0); | |
| 270 | 264 | } |
| 271 | 265 | } |
| 272 | 266 | |
| @@ -436,6 +430,8 @@ static void enc35_disable_fifo(struct stream_encoder *enc) · 163 unmodified lines | ||
| 436 | 430 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
| 437 | 431 | |
| 438 | 432 | REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_ENABLE, 0); |
| 433 | + REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 0); | |
| 434 | + REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 0); | |
| 439 | 435 | } |
| 440 | 436 | |
| 441 | 437 | static void enc35_enable_fifo(struct stream_encoder *enc) |
| @@ -443,6 +439,8 @@ static void enc35_enable_fifo(struct stream_encoder *enc) · 1 unmodified line | ||
| 443 | 439 | struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); |
| 444 | 440 | |
| 445 | 441 | REG_UPDATE(DIG_FIFO_CTRL0, DIG_FIFO_READ_START_LEVEL, 0x7); |
| 442 | + REG_UPDATE(DIG_FE_CLK_CNTL, DIG_FE_CLK_EN, 1); | |
| 443 | + REG_UPDATE(DIG_FE_EN_CNTL, DIG_FE_ENABLE, 1); | |
| 446 | 444 | |
| 447 | 445 | enc35_reset_fifo(enc, true); |
| 448 | 446 | enc35_reset_fifo(enc, false); |
| @@ -261,6 +261,7 @@ void pg_cntl35_hpo_pg_control(struct pg_cntl *pg_cntl, bool power_on) · 260 unmodified lines | ||
| 261 | 261 | uint32_t power_gate = power_on ? 0 : 1; |
| 262 | 262 | uint32_t pwr_status = power_on ? 0 : 2; |
| 263 | 263 | uint32_t org_ip_request_cntl; |
| 264 | + uint32_t power_forceon; | |
| 264 | 265 | bool block_enabled; |
| 265 | 266 | |
| 266 | 267 | if (pg_cntl->ctx->dc->debug.ignore_pg || |
| @@ -277,6 +278,10 @@ void pg_cntl35_hpo_pg_control(struct pg_cntl *pg_cntl, bool power_on) · 10 unmodified lines | ||
| 277 | 278 | return; |
| 278 | 279 | } |
| 279 | 280 | |
| 281 | + REG_GET(DOMAIN25_PG_CONFIG, DOMAIN_POWER_FORCEON, &power_forceon); | |
| 282 | + if (power_forceon) | |
| 283 | + return; | |
| 284 | + | |
| 280 | 285 | REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); |
| 281 | 286 | if (org_ip_request_cntl == 0) |
| 282 | 287 | REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); |
| @@ -304,6 +309,7 @@ void pg_cntl35_io_clk_pg_control(struct pg_cntl *pg_cntl, bool power_on) · 21 unmodified lines | ||
| 304 | 309 | uint32_t power_gate = power_on ? 0 : 1; |
| 305 | 310 | uint32_t pwr_status = power_on ? 0 : 2; |
| 306 | 311 | uint32_t org_ip_request_cntl; |
| 312 | + uint32_t power_forceon; | |
| 307 | 313 | bool block_enabled; |
| 308 | 314 | |
| 309 | 315 | if (pg_cntl->ctx->dc->debug.ignore_pg || |
| @@ -319,6 +325,10 @@ void pg_cntl35_io_clk_pg_control(struct pg_cntl *pg_cntl, bool power_on) · 9 unmodified lines | ||
| 319 | 325 | return; |
| 320 | 326 | } |
| 321 | 327 | |
| 328 | + REG_GET(DOMAIN22_PG_CONFIG, DOMAIN_POWER_FORCEON, &power_forceon); | |
| 329 | + if (power_forceon) | |
| 330 | + return; | |
| 331 | + | |
| 322 | 332 | REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); |
| 323 | 333 | if (org_ip_request_cntl == 0) |
| 324 | 334 | REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); |
| @@ -1712,6 +1712,13 @@ static bool dcn35_validate_bandwidth(struct dc *dc, · 1711 unmodified lines | ||
| 1712 | 1712 | |
| 1713 | 1713 | out = dml2_validate(dc, context, fast_validate); |
| 1714 | 1714 | |
| 1715 | + if (fast_validate) | |
| 1716 | + return out; | |
| 1717 | + | |
| 1718 | + DC_FP_START(); | |
| 1719 | + dcn35_decide_zstate_support(dc, context); | |
| 1720 | + DC_FP_END(); | |
| 1721 | + | |
| 1715 | 1722 | return out; |
| 1716 | 1723 | } |
| 1717 | 1724 | |
| @@ -1857,7 +1864,7 @@ static bool dcn35_resource_construct( · 139 unmodified lines | ||
| 1857 | 1864 | |
| 1858 | 1865 | /* Use pipe context based otg sync logic */ |
| 1859 | 1866 | dc->config.use_pipe_ctx_sync_logic = true; |
| 1860 | − dc->config.use_default_clock_table = false; | |
| 1867 | + | |
| 1861 | 1868 | /* read VBIOS LTTPR caps */ |
| 1862 | 1869 | { |
| 1863 | 1870 | if (ctx->dc_bios->funcs->get_lttpr_caps) { |
| @@ -61,8 +61,12 @@ endif · 60 unmodified lines | ||
| 61 | 61 | endif |
| 62 | 62 | |
| 63 | 63 | ifneq ($(CONFIG_FRAME_WARN),0) |
| 64 | +ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)),y) | |
| 65 | +frame_warn_flag := -Wframe-larger-than=3072 | |
| 66 | +else | |
| 64 | 67 | frame_warn_flag := -Wframe-larger-than=2048 |
| 65 | 68 | endif |
| 69 | +endif | |
| 66 | 70 | |
| 67 | 71 | CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_lib.o := $(dml_ccflags) |
| 68 | 72 | CFLAGS_$(AMDDALPATH)/dc/dml/display_mode_vba.o := $(dml_ccflags) |
| @@ -36,7 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | * Define the maximum amount of states supported by the ASIC. Every ASIC has a |
| 37 | 37 | * specific number of states; this macro defines the maximum number of states. |
| 38 | 38 | */ |
| 39 | −#define DC__VOLTAGE_STATES 20 | |
| 39 | +#define DC__VOLTAGE_STATES 40 | |
| 40 | 40 | #define DC__NUM_DPP__4 1 |
| 41 | 41 | #define DC__NUM_DPP__0_PRESENT 1 |
| 42 | 42 | #define DC__NUM_DPP__1_PRESENT 1 |
| @@ -950,10 +950,8 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc · 949 unmodified lines | ||
| 950 | 950 | { |
| 951 | 951 | int plane_count; |
| 952 | 952 | int i; |
| 953 | − unsigned int min_dst_y_next_start_us; | |
| 954 | 953 | |
| 955 | 954 | plane_count = 0; |
| 956 | − min_dst_y_next_start_us = 0; | |
| 957 | 955 | for (i = 0; i < dc->res_pool->pipe_count; i++) { |
| 958 | 956 | if (context->res_ctx.pipe_ctx[i].plane_state) |
| 959 | 957 | plane_count++; |
| @@ -975,26 +973,15 @@ static enum dcn_zstate_support_state decide_zstate_support(struct dc *dc, struc · 15 unmodified lines | ||
| 975 | 973 | else if (context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) { |
| 976 | 974 | struct dc_link *link = context->streams[0]->sink->link; |
| 977 | 975 | struct dc_stream_status *stream_status = &context->stream_status[0]; |
| 978 | − struct dc_stream_state *current_stream = context->streams[0]; | |
| 979 | 976 | int minmum_z8_residency = dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000; |
| 980 | 977 | bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency; |
| 981 | 978 | bool is_pwrseq0 = link->link_index == 0; |
| 982 | − bool isFreesyncVideo; | |
| 983 | − | |
| 984 | − isFreesyncVideo = current_stream->adjust.v_total_min == current_stream->adjust.v_total_max; | |
| 985 | − isFreesyncVideo = isFreesyncVideo && current_stream->timing.v_total < current_stream->adjust.v_total_min; | |
| 986 | − for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 987 | − if (context->res_ctx.pipe_ctx[i].stream == current_stream && isFreesyncVideo) { | |
| 988 | − min_dst_y_next_start_us = context->res_ctx.pipe_ctx[i].dlg_regs.min_dst_y_next_start_us; | |
| 989 | − break; | |
| 990 | − } | |
| 991 | − } | |
| 992 | 979 | |
| 993 | 980 | /* Don't support multi-plane configurations */ |
| 994 | 981 | if (stream_status->plane_count > 1) |
| 995 | 982 | return DCN_ZSTATE_SUPPORT_DISALLOW; |
| 996 | 983 | |
| 997 | − if (is_pwrseq0 && (context->bw_ctx.dml.vba.StutterPeriod > 5000.0 || min_dst_y_next_start_us > 5000)) | |
| 984 | + if (is_pwrseq0 && context->bw_ctx.dml.vba.StutterPeriod > 5000.0) | |
| 998 | 985 | return DCN_ZSTATE_SUPPORT_ALLOW; |
| 999 | 986 | else if (is_pwrseq0 && link->psr_settings.psr_version == DC_PSR_VERSION_1 && !link->panel_config.psr.disable_psr) |
| 1000 | 987 | return allow_z8 ? DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY : DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY; |
| @@ -1192,13 +1192,16 @@ static bool update_pipe_slice_table_with_split_flags( · 1191 unmodified lines | ||
| 1192 | 1192 | */ |
| 1193 | 1193 | struct pipe_ctx *pipe; |
| 1194 | 1194 | bool odm; |
| 1195 | − int i; | |
| 1195 | + int dc_pipe_idx, dml_pipe_idx = 0; | |
| 1196 | 1196 | bool updated = false; |
| 1197 | 1197 | |
| 1198 | − for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 1199 | − pipe = &context->res_ctx.pipe_ctx[i]; | |
| 1198 | + for (dc_pipe_idx = 0; | |
| 1199 | + dc_pipe_idx < dc->res_pool->pipe_count; dc_pipe_idx++) { | |
| 1200 | + pipe = &context->res_ctx.pipe_ctx[dc_pipe_idx]; | |
| 1201 | + if (resource_is_pipe_type(pipe, FREE_PIPE)) | |
| 1202 | + continue; | |
| 1200 | 1203 | |
| 1201 | − if (merge[i]) { | |
| 1204 | + if (merge[dc_pipe_idx]) { | |
| 1202 | 1205 | if (resource_is_pipe_type(pipe, OPP_HEAD)) |
| 1203 | 1206 | /* merging OPP head means reducing ODM slice |
| 1204 | 1207 | * count by 1 |
| @@ -1213,17 +1216,18 @@ static bool update_pipe_slice_table_with_split_flags( · 8 unmodified lines | ||
| 1213 | 1216 | updated = true; |
| 1214 | 1217 | } |
| 1215 | 1218 | |
| 1216 | − if (split[i]) { | |
| 1217 | − odm = vba->ODMCombineEnabled[vba->pipe_plane[i]] != | |
| 1219 | + if (split[dc_pipe_idx]) { | |
| 1220 | + odm = vba->ODMCombineEnabled[vba->pipe_plane[dml_pipe_idx]] != | |
| 1218 | 1221 | dm_odm_combine_mode_disabled; |
| 1219 | 1222 | if (odm && resource_is_pipe_type(pipe, OPP_HEAD)) |
| 1220 | 1223 | update_slice_table_for_stream( |
| 1221 | − table, pipe->stream, split[i] - 1); | |
| 1224 | + table, pipe->stream, split[dc_pipe_idx] - 1); | |
| 1222 | 1225 | else if (!odm && resource_is_pipe_type(pipe, DPP_PIPE)) |
| 1223 | 1226 | update_slice_table_for_plane(table, pipe, |
| 1224 | − pipe->plane_state, split[i] - 1); | |
| 1227 | + pipe->plane_state, split[dc_pipe_idx] - 1); | |
| 1225 | 1228 | updated = true; |
| 1226 | 1229 | } |
| 1230 | + dml_pipe_idx++; | |
| 1227 | 1231 | } |
| 1228 | 1232 | return updated; |
| 1229 | 1233 | } |
| @@ -2231,6 +2235,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, · 1001 unmodified lines | ||
| 2231 | 2235 | int i, pipe_idx, vlevel_temp = 0; |
| 2232 | 2236 | double dcfclk = dcn3_2_soc.clock_limits[0].dcfclk_mhz; |
| 2233 | 2237 | double dcfclk_from_validation = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; |
| 2238 | + double dram_speed_from_validation = context->bw_ctx.dml.vba.DRAMSpeed; | |
| 2234 | 2239 | double dcfclk_from_fw_based_mclk_switching = dcfclk_from_validation; |
| 2235 | 2240 | bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != |
| 2236 | 2241 | dm_dram_clock_change_unsupported; |
| @@ -2418,7 +2423,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context, · 181 unmodified lines | ||
| 2418 | 2423 | } |
| 2419 | 2424 | |
| 2420 | 2425 | if (dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].valid) { |
| 2421 | − min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed; | |
| 2426 | + min_dram_speed_mts = dram_speed_from_validation; | |
| 2422 | 2427 | min_dram_speed_mts_margin = 160; |
| 2423 | 2428 | |
| 2424 | 2429 | context->bw_ctx.dml.soc.dram_clock_change_latency_us = |
| @@ -164,10 +164,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = { · 163 unmodified lines | ||
| 164 | 164 | }, |
| 165 | 165 | }, |
| 166 | 166 | .num_states = 5, |
| 167 | − .sr_exit_time_us = 9.0, | |
| 168 | − .sr_enter_plus_exit_time_us = 11.0, | |
| 169 | − .sr_exit_z8_time_us = 50.0, /*changed from 442.0*/ | |
| 170 | − .sr_enter_plus_exit_z8_time_us = 50.0,/*changed from 560.0*/ | |
| 167 | + .sr_exit_time_us = 14.0, | |
| 168 | + .sr_enter_plus_exit_time_us = 16.0, | |
| 169 | + .sr_exit_z8_time_us = 525.0, | |
| 170 | + .sr_enter_plus_exit_z8_time_us = 715.0, | |
| 171 | 171 | .fclk_change_latency_us = 20.0, |
| 172 | 172 | .usr_retraining_latency_us = 2, |
| 173 | 173 | .writeback_latency_us = 12.0, |
| @@ -329,6 +329,48 @@ void dcn35_update_bw_bounding_box_fpu(struct dc *dc, · 155 unmodified lines | ||
| 329 | 329 | /*temp till dml2 fully work without dml1*/ |
| 330 | 330 | dml_init_instance(&dc->dml, &dcn3_5_soc, &dcn3_5_ip, |
| 331 | 331 | DML_PROJECT_DCN31); |
| 332 | + | |
| 333 | + /*copy to dml2, before dml2_create*/ | |
| 334 | + if (clk_table->num_entries > 2) { | |
| 335 | + | |
| 336 | + for (i = 0; i < clk_table->num_entries; i++) { | |
| 337 | + dc->dml2_options.bbox_overrides.clks_table.num_states = | |
| 338 | + clk_table->num_entries; | |
| 339 | + dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dcfclk_mhz = | |
| 340 | + clock_limits[i].dcfclk_mhz; | |
| 341 | + dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].fclk_mhz = | |
| 342 | + clock_limits[i].fabricclk_mhz; | |
| 343 | + dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dispclk_mhz = | |
| 344 | + clock_limits[i].dispclk_mhz; | |
| 345 | + dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].dppclk_mhz = | |
| 346 | + clock_limits[i].dppclk_mhz; | |
| 347 | + dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].socclk_mhz = | |
| 348 | + clock_limits[i].socclk_mhz; | |
| 349 | + dc->dml2_options.bbox_overrides.clks_table.clk_entries[i].memclk_mhz = | |
| 350 | + clk_table->entries[i].memclk_mhz * clk_table->entries[i].wck_ratio; | |
| 351 | + dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dcfclk_levels = | |
| 352 | + clk_table->num_entries; | |
| 353 | + dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_fclk_levels = | |
| 354 | + clk_table->num_entries; | |
| 355 | + dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dispclk_levels = | |
| 356 | + clk_table->num_entries; | |
| 357 | + dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_dppclk_levels = | |
| 358 | + clk_table->num_entries; | |
| 359 | + dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_socclk_levels = | |
| 360 | + clk_table->num_entries; | |
| 361 | + dc->dml2_options.bbox_overrides.clks_table.num_entries_per_clk.num_memclk_levels = | |
| 362 | + clk_table->num_entries; | |
| 363 | + } | |
| 364 | + } | |
| 365 | + | |
| 366 | + /* Update latency values */ | |
| 367 | + dc->dml2_options.bbox_overrides.dram_clock_change_latency_us = dcn3_5_soc.dram_clock_change_latency_us; | |
| 368 | + | |
| 369 | + dc->dml2_options.bbox_overrides.sr_exit_latency_us = dcn3_5_soc.sr_exit_time_us; | |
| 370 | + dc->dml2_options.bbox_overrides.sr_enter_plus_exit_latency_us = dcn3_5_soc.sr_enter_plus_exit_time_us; | |
| 371 | + | |
| 372 | + dc->dml2_options.bbox_overrides.sr_exit_z8_time_us = dcn3_5_soc.sr_exit_z8_time_us; | |
| 373 | + dc->dml2_options.bbox_overrides.sr_enter_plus_exit_z8_time_us = dcn3_5_soc.sr_enter_plus_exit_z8_time_us; | |
| 332 | 374 | } |
| 333 | 375 | |
| 334 | 376 | static bool is_dual_plane(enum surface_pixel_format format) |
| @@ -507,3 +549,37 @@ int dcn35_populate_dml_pipes_from_context_fpu(struct dc *dc, · 172 unmodified lines | ||
| 507 | 549 | |
| 508 | 550 | return pipe_cnt; |
| 509 | 551 | } |
| 552 | + | |
| 553 | +void dcn35_decide_zstate_support(struct dc *dc, struct dc_state *context) | |
| 554 | +{ | |
| 555 | + enum dcn_zstate_support_state support = DCN_ZSTATE_SUPPORT_DISALLOW; | |
| 556 | + unsigned int i, plane_count = 0; | |
| 557 | + | |
| 558 | + for (i = 0; i < dc->res_pool->pipe_count; i++) { | |
| 559 | + if (context->res_ctx.pipe_ctx[i].plane_state) | |
| 560 | + plane_count++; | |
| 561 | + } | |
| 562 | + | |
| 563 | + if (plane_count == 0) { | |
| 564 | + support = DCN_ZSTATE_SUPPORT_ALLOW; | |
| 565 | + } else if (plane_count == 1 && context->stream_count == 1 && context->streams[0]->signal == SIGNAL_TYPE_EDP) { | |
| 566 | + struct dc_link *link = context->streams[0]->sink->link; | |
| 567 | + bool is_pwrseq0 = link && link->link_index == 0; | |
| 568 | + bool is_psr1 = link && link->psr_settings.psr_version == DC_PSR_VERSION_1 && !link->panel_config.psr.disable_psr; | |
| 569 | + int minmum_z8_residency = | |
| 570 | + dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000; | |
| 571 | + bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency; | |
| 572 | + int minmum_z10_residency = | |
| 573 | + dc->debug.minimum_z10_residency_time > 0 ? dc->debug.minimum_z10_residency_time : 5000; | |
| 574 | + bool allow_z10 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z10_residency; | |
| 575 | + | |
| 576 | + if (is_pwrseq0 && allow_z10) | |
| 577 | + support = DCN_ZSTATE_SUPPORT_ALLOW; | |
| 578 | + else if (is_pwrseq0 && is_psr1) | |
| 579 | + support = allow_z8 ? DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY : DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY; | |
| 580 | + else if (allow_z8) | |
| 581 | + support = DCN_ZSTATE_SUPPORT_ALLOW_Z8_ONLY; | |
| 582 | + } | |
| 583 | + | |
| 584 | + context->bw_ctx.bw.dcn.clk.zstate_support = support; | |
| 585 | +} | |
| @@ -39,4 +39,6 @@ int dcn35_populate_dml_pipes_from_context_fpu(struct dc *dc, · 38 unmodified lines | ||
| 39 | 39 | display_e2e_pipe_params_st *pipes, |
| 40 | 40 | bool fast_validate); |
| 41 | 41 | |
| 42 | +void dcn35_decide_zstate_support(struct dc *dc, struct dc_state *context); | |
| 43 | + | |
| 42 | 44 | #endif |
| @@ -6329,7 +6329,7 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib) · 6328 unmodified lines | ||
| 6329 | 6329 | mode_lib->ms.NoOfDPPThisState, |
| 6330 | 6330 | mode_lib->ms.dpte_group_bytes, |
| 6331 | 6331 | s->HostVMInefficiencyFactor, |
| 6332 | − mode_lib->ms.soc.hostvm_min_page_size_kbytes, | |
| 6332 | + mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024, | |
| 6333 | 6333 | mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels); |
| 6334 | 6334 | |
| 6335 | 6335 | s->NextMaxVStartup = s->MaxVStartupAllPlanes[j]; |
| @@ -6542,7 +6542,7 @@ static void dml_prefetch_check(struct display_mode_lib_st *mode_lib) · 206 unmodified lines | ||
| 6542 | 6542 | mode_lib->ms.cache_display_cfg.plane.HostVMEnable, |
| 6543 | 6543 | mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels, |
| 6544 | 6544 | mode_lib->ms.cache_display_cfg.plane.GPUVMEnable, |
| 6545 | − mode_lib->ms.soc.hostvm_min_page_size_kbytes, | |
| 6545 | + mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024, | |
| 6546 | 6546 | mode_lib->ms.PDEAndMetaPTEBytesPerFrame[j][k], |
| 6547 | 6547 | mode_lib->ms.MetaRowBytes[j][k], |
| 6548 | 6548 | mode_lib->ms.DPTEBytesPerRow[j][k], |
| @@ -7687,7 +7687,7 @@ dml_bool_t dml_core_mode_support(struct display_mode_lib_st *mode_lib) · 1138 unmodified lines | ||
| 7687 | 7687 | CalculateVMRowAndSwath_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels; |
| 7688 | 7688 | CalculateVMRowAndSwath_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels; |
| 7689 | 7689 | CalculateVMRowAndSwath_params->GPUVMMinPageSizeKBytes = mode_lib->ms.cache_display_cfg.plane.GPUVMMinPageSizeKBytes; |
| 7690 | − CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes; | |
| 7690 | + CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024; | |
| 7691 | 7691 | CalculateVMRowAndSwath_params->PTEBufferModeOverrideEn = mode_lib->ms.cache_display_cfg.plane.PTEBufferModeOverrideEn; |
| 7692 | 7692 | CalculateVMRowAndSwath_params->PTEBufferModeOverrideVal = mode_lib->ms.cache_display_cfg.plane.PTEBufferMode; |
| 7693 | 7693 | CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = mode_lib->ms.PTEBufferSizeNotExceededPerState; |
| @@ -7957,7 +7957,7 @@ dml_bool_t dml_core_mode_support(struct display_mode_lib_st *mode_lib) · 263 unmodified lines | ||
| 7957 | 7957 | UseMinimumDCFCLK_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels; |
| 7958 | 7958 | UseMinimumDCFCLK_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable; |
| 7959 | 7959 | UseMinimumDCFCLK_params->NumberOfActiveSurfaces = mode_lib->ms.num_active_planes; |
| 7960 | − UseMinimumDCFCLK_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes; | |
| 7960 | + UseMinimumDCFCLK_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024; | |
| 7961 | 7961 | UseMinimumDCFCLK_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels; |
| 7962 | 7962 | UseMinimumDCFCLK_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled; |
| 7963 | 7963 | UseMinimumDCFCLK_params->ImmediateFlipRequirement = s->ImmediateFlipRequiredFinal; |
| @@ -8699,7 +8699,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc · 735 unmodified lines | ||
| 8699 | 8699 | CalculateVMRowAndSwath_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels; |
| 8700 | 8700 | CalculateVMRowAndSwath_params->GPUVMMaxPageTableLevels = mode_lib->ms.cache_display_cfg.plane.GPUVMMaxPageTableLevels; |
| 8701 | 8701 | CalculateVMRowAndSwath_params->GPUVMMinPageSizeKBytes = mode_lib->ms.cache_display_cfg.plane.GPUVMMinPageSizeKBytes; |
| 8702 | − CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes; | |
| 8702 | + CalculateVMRowAndSwath_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024; | |
| 8703 | 8703 | CalculateVMRowAndSwath_params->PTEBufferModeOverrideEn = mode_lib->ms.cache_display_cfg.plane.PTEBufferModeOverrideEn; |
| 8704 | 8704 | CalculateVMRowAndSwath_params->PTEBufferModeOverrideVal = mode_lib->ms.cache_display_cfg.plane.PTEBufferMode; |
| 8705 | 8705 | CalculateVMRowAndSwath_params->PTEBufferSizeNotExceeded = s->dummy_boolean_array[0]; |
| @@ -8805,7 +8805,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc · 99 unmodified lines | ||
| 8805 | 8805 | mode_lib->ms.cache_display_cfg.hw.DPPPerSurface, |
| 8806 | 8806 | locals->dpte_group_bytes, |
| 8807 | 8807 | s->HostVMInefficiencyFactor, |
| 8808 | − mode_lib->ms.soc.hostvm_min_page_size_kbytes, | |
| 8808 | + mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024, | |
| 8809 | 8809 | mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels); |
| 8810 | 8810 | |
| 8811 | 8811 | locals->TCalc = 24.0 / locals->DCFCLKDeepSleep; |
| @@ -8995,7 +8995,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc · 183 unmodified lines | ||
| 8995 | 8995 | CalculatePrefetchSchedule_params->GPUVMEnable = mode_lib->ms.cache_display_cfg.plane.GPUVMEnable; |
| 8996 | 8996 | CalculatePrefetchSchedule_params->HostVMEnable = mode_lib->ms.cache_display_cfg.plane.HostVMEnable; |
| 8997 | 8997 | CalculatePrefetchSchedule_params->HostVMMaxNonCachedPageTableLevels = mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels; |
| 8998 | − CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes; | |
| 8998 | + CalculatePrefetchSchedule_params->HostVMMinPageSize = mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024; | |
| 8999 | 8999 | CalculatePrefetchSchedule_params->DynamicMetadataEnable = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataEnable[k]; |
| 9000 | 9000 | CalculatePrefetchSchedule_params->DynamicMetadataVMEnabled = mode_lib->ms.ip.dynamic_metadata_vm_enabled; |
| 9001 | 9001 | CalculatePrefetchSchedule_params->DynamicMetadataLinesBeforeActiveRequired = mode_lib->ms.cache_display_cfg.plane.DynamicMetadataLinesBeforeActiveRequired[k]; |
| @@ -9240,7 +9240,7 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc · 238 unmodified lines | ||
| 9240 | 9240 | mode_lib->ms.cache_display_cfg.plane.HostVMEnable, |
| 9241 | 9241 | mode_lib->ms.cache_display_cfg.plane.HostVMMaxPageTableLevels, |
| 9242 | 9242 | mode_lib->ms.cache_display_cfg.plane.GPUVMEnable, |
| 9243 | − mode_lib->ms.soc.hostvm_min_page_size_kbytes, | |
| 9243 | + mode_lib->ms.soc.hostvm_min_page_size_kbytes * 1024, | |
| 9244 | 9244 | locals->PDEAndMetaPTEBytesFrame[k], |
| 9245 | 9245 | locals->MetaRowByte[k], |
| 9246 | 9246 | locals->PixelPTEBytesPerRow[k], |
| @@ -9447,12 +9447,12 @@ void dml_core_mode_programming(struct display_mode_lib_st *mode_lib, const struc · 200 unmodified lines | ||
| 9447 | 9447 | |
| 9448 | 9448 | // Output |
| 9449 | 9449 | CalculateWatermarks_params->Watermark = &s->dummy_watermark; // Watermarks *Watermark |
| 9450 | − CalculateWatermarks_params->DRAMClockChangeSupport = &mode_lib->ms.support.DRAMClockChangeSupport[j]; | |
| 9450 | + CalculateWatermarks_params->DRAMClockChangeSupport = &mode_lib->ms.support.DRAMClockChangeSupport[0]; | |
| 9451 | 9451 | CalculateWatermarks_params->MaxActiveDRAMClockChangeLatencySupported = &s->dummy_single_array[0][0]; // dml_float_t *MaxActiveDRAMClockChangeLatencySupported[] |
| 9452 | 9452 | CalculateWatermarks_params->SubViewportLinesNeededInMALL = &mode_lib->ms.SubViewportLinesNeededInMALL[j]; // dml_uint_t SubViewportLinesNeededInMALL[] |
| 9453 | − CalculateWatermarks_params->FCLKChangeSupport = &mode_lib->ms.support.FCLKChangeSupport[j]; | |
| 9453 | + CalculateWatermarks_params->FCLKChangeSupport = &mode_lib->ms.support.FCLKChangeSupport[0]; | |
| 9454 | 9454 | CalculateWatermarks_params->MaxActiveFCLKChangeLatencySupported = &s->dummy_single[0]; // dml_float_t *MaxActiveFCLKChangeLatencySupported |
| 9455 | − CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->ms.support.USRRetrainingSupport[j]; | |
| 9455 | + CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->ms.support.USRRetrainingSupport[0]; | |
| 9456 | 9456 | |
| 9457 | 9457 | CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport( |
| 9458 | 9458 | &mode_lib->scratch, |
| @@ -341,25 +341,42 @@ void dml2_init_soc_states(struct dml2_context *dml2, const struct dc *in_dc, · 340 unmodified lines | ||
| 341 | 341 | break; |
| 342 | 342 | } |
| 343 | 343 | |
| 344 | − /* Override from passed values, mainly for debugging purposes, if available */ | |
| 345 | − if (dml2->config.bbox_overrides.sr_exit_latency_us) { | |
| 346 | − p->in_states->state_array[0].sr_exit_time_us = dml2->config.bbox_overrides.sr_exit_latency_us; | |
| 347 | − } | |
| 344 | + /* Override from passed values, if available */ | |
| 345 | + for (i = 0; i < p->in_states->num_states; i++) { | |
| 346 | + if (dml2->config.bbox_overrides.sr_exit_latency_us) { | |
| 347 | + p->in_states->state_array[i].sr_exit_time_us = | |
| 348 | + dml2->config.bbox_overrides.sr_exit_latency_us; | |
| 349 | + } | |
| 348 | 350 | |
| 349 | − if (dml2->config.bbox_overrides.sr_enter_plus_exit_latency_us) { | |
| 350 | − p->in_states->state_array[0].sr_enter_plus_exit_time_us = dml2->config.bbox_overrides.sr_enter_plus_exit_latency_us; | |
| 351 | − } | |
| 351 | + if (dml2->config.bbox_overrides.sr_enter_plus_exit_latency_us) { | |
| 352 | + p->in_states->state_array[i].sr_enter_plus_exit_time_us = | |
| 353 | + dml2->config.bbox_overrides.sr_enter_plus_exit_latency_us; | |
| 354 | + } | |
| 352 | 355 | |
| 353 | − if (dml2->config.bbox_overrides.urgent_latency_us) { | |
| 354 | − p->in_states->state_array[0].urgent_latency_pixel_data_only_us = dml2->config.bbox_overrides.urgent_latency_us; | |
| 355 | − } | |
| 356 | + if (dml2->config.bbox_overrides.sr_exit_z8_time_us) { | |
| 357 | + p->in_states->state_array[i].sr_exit_z8_time_us = | |
| 358 | + dml2->config.bbox_overrides.sr_exit_z8_time_us; | |
| 359 | + } | |
| 356 | 360 | |
| 357 | − if (dml2->config.bbox_overrides.dram_clock_change_latency_us) { | |
| 358 | − p->in_states->state_array[0].dram_clock_change_latency_us = dml2->config.bbox_overrides.dram_clock_change_latency_us; | |
| 359 | − } | |
| 361 | + if (dml2->config.bbox_overrides.sr_enter_plus_exit_z8_time_us) { | |
| 362 | + p->in_states->state_array[i].sr_enter_plus_exit_z8_time_us = | |
| 363 | + dml2->config.bbox_overrides.sr_enter_plus_exit_z8_time_us; | |
| 364 | + } | |
| 365 | + | |
| 366 | + if (dml2->config.bbox_overrides.urgent_latency_us) { | |
| 367 | + p->in_states->state_array[i].urgent_latency_pixel_data_only_us = | |
| 368 | + dml2->config.bbox_overrides.urgent_latency_us; | |
| 369 | + } | |
| 360 | 370 | |
| 361 | − if (dml2->config.bbox_overrides.fclk_change_latency_us) { | |
| 362 | − p->in_states->state_array[0].fclk_change_latency_us = dml2->config.bbox_overrides.fclk_change_latency_us; | |
| 371 | + if (dml2->config.bbox_overrides.dram_clock_change_latency_us) { | |
| 372 | + p->in_states->state_array[i].dram_clock_change_latency_us = | |
| 373 | + dml2->config.bbox_overrides.dram_clock_change_latency_us; | |
| 374 | + } | |
| 375 | + | |
| 376 | + if (dml2->config.bbox_overrides.fclk_change_latency_us) { | |
| 377 | + p->in_states->state_array[i].fclk_change_latency_us = | |
| 378 | + dml2->config.bbox_overrides.fclk_change_latency_us; | |
| 379 | + } | |
| 363 | 380 | } |
| 364 | 381 | |
| 365 | 382 | /* DCFCLK stas values are project specific */ |
| @@ -498,8 +515,8 @@ void dml2_translate_socbb_params(const struct dc *in, struct soc_bounding_box_st · 132 unmodified lines | ||
| 498 | 515 | out->do_urgent_latency_adjustment = in_soc_params->do_urgent_latency_adjustment; |
| 499 | 516 | out->dram_channel_width_bytes = (dml_uint_t)in_soc_params->dram_channel_width_bytes; |
| 500 | 517 | out->fabric_datapath_to_dcn_data_return_bytes = (dml_uint_t)in_soc_params->fabric_datapath_to_dcn_data_return_bytes; |
| 501 | − out->gpuvm_min_page_size_kbytes = in_soc_params->gpuvm_min_page_size_bytes * 1024; | |
| 502 | − out->hostvm_min_page_size_kbytes = in_soc_params->hostvm_min_page_size_bytes * 1024; | |
| 518 | + out->gpuvm_min_page_size_kbytes = in_soc_params->gpuvm_min_page_size_bytes / 1024; | |
| 519 | + out->hostvm_min_page_size_kbytes = in_soc_params->hostvm_min_page_size_bytes / 1024; | |
| 503 | 520 | out->mall_allocated_for_dcn_mbytes = (dml_uint_t)in_soc_params->mall_allocated_for_dcn_mbytes; |
| 504 | 521 | out->max_avg_dram_bw_use_normal_percent = in_soc_params->max_avg_dram_bw_use_normal_percent; |
| 505 | 522 | out->max_avg_fabric_bw_use_normal_percent = in_soc_params->max_avg_fabric_bw_use_normal_percent; |
| @@ -1040,9 +1057,12 @@ void map_dc_state_into_dml_display_cfg(struct dml2_context *dml2, struct dc_stat · 534 unmodified lines | ||
| 1040 | 1057 | } |
| 1041 | 1058 | |
| 1042 | 1059 | //Generally these are set by referencing our latest BB/IP params in dcn32_resource.c file |
| 1043 | − dml_dispcfg->plane.GPUVMEnable = true; | |
| 1044 | − dml_dispcfg->plane.GPUVMMaxPageTableLevels = 4; | |
| 1045 | − dml_dispcfg->plane.HostVMEnable = false; | |
| 1060 | + dml_dispcfg->plane.GPUVMEnable = dml2->v20.dml_core_ctx.ip.gpuvm_enable; | |
| 1061 | + dml_dispcfg->plane.GPUVMMaxPageTableLevels = dml2->v20.dml_core_ctx.ip.gpuvm_max_page_table_levels; | |
| 1062 | + dml_dispcfg->plane.HostVMEnable = dml2->v20.dml_core_ctx.ip.hostvm_enable; | |
| 1063 | + dml_dispcfg->plane.HostVMMaxPageTableLevels = dml2->v20.dml_core_ctx.ip.hostvm_max_page_table_levels; | |
| 1064 | + if (dml2->v20.dml_core_ctx.ip.hostvm_enable) | |
| 1065 | + dml2->v20.dml_core_ctx.policy.AllowForPStateChangeOrStutterInVBlankFinal = dml_prefetch_support_uclk_fclk_and_stutter; | |
| 1046 | 1066 | |
| 1047 | 1067 | dml2_populate_pipe_to_plane_index_mapping(dml2, context); |
| 1048 | 1068 | |
| @@ -139,6 +139,8 @@ struct dml2_soc_bbox_overrides { · 138 unmodified lines | ||
| 139 | 139 | double urgent_latency_us; |
| 140 | 140 | double sr_exit_latency_us; |
| 141 | 141 | double sr_enter_plus_exit_latency_us; |
| 142 | + double sr_exit_z8_time_us; | |
| 143 | + double sr_enter_plus_exit_z8_time_us; | |
| 142 | 144 | double dram_clock_change_latency_us; |
| 143 | 145 | double fclk_change_latency_us; |
| 144 | 146 | unsigned int dram_num_chan; |
| @@ -487,8 +487,7 @@ bool dcn32_set_mcm_luts( · 486 unmodified lines | ||
| 487 | 487 | if (plane_state->blend_tf->type == TF_TYPE_HWPWL) |
| 488 | 488 | lut_params = &plane_state->blend_tf->pwl; |
| 489 | 489 | else if (plane_state->blend_tf->type == TF_TYPE_DISTRIBUTED_POINTS) { |
| 490 | − cm_helper_translate_curve_to_hw_format(plane_state->ctx, | |
| 491 | − plane_state->blend_tf, | |
| 490 | + cm3_helper_translate_curve_to_hw_format(plane_state->blend_tf, | |
| 492 | 491 | &dpp_base->regamma_params, false); |
| 493 | 492 | lut_params = &dpp_base->regamma_params; |
| 494 | 493 | } |
| @@ -503,8 +502,7 @@ bool dcn32_set_mcm_luts( · 8 unmodified lines | ||
| 503 | 502 | else if (plane_state->in_shaper_func->type == TF_TYPE_DISTRIBUTED_POINTS) { |
| 504 | 503 | // TODO: dpp_base replace |
| 505 | 504 | ASSERT(false); |
| 506 | − cm_helper_translate_curve_to_hw_format(plane_state->ctx, | |
| 507 | − plane_state->in_shaper_func, | |
| 505 | + cm3_helper_translate_curve_to_hw_format(plane_state->in_shaper_func, | |
| 508 | 506 | &dpp_base->shaper_params, true); |
| 509 | 507 | lut_params = &dpp_base->shaper_params; |
| 510 | 508 | } |
| @@ -879,7 +879,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, · 878 unmodified lines | ||
| 879 | 879 | (link->dpcd_sink_ext_caps.bits.oled == 1)) { |
| 880 | 880 | dpcd_set_source_specific_data(link); |
| 881 | 881 | msleep(post_oui_delay); |
| 882 | − set_cached_brightness_aux(link); | |
| 882 | + set_default_brightness_aux(link); | |
| 883 | 883 | } |
| 884 | 884 | |
| 885 | 885 | return true; |
| @@ -1088,6 +1088,9 @@ static bool detect_link_and_local_sink(struct dc_link *link, · 202 unmodified lines | ||
| 1088 | 1088 | if (sink->edid_caps.panel_patch.skip_scdc_overwrite) |
| 1089 | 1089 | link->ctx->dc->debug.hdmi20_disable = true; |
| 1090 | 1090 | |
| 1091 | + if (sink->edid_caps.panel_patch.remove_sink_ext_caps) | |
| 1092 | + link->dpcd_sink_ext_caps.raw = 0; | |
| 1093 | + | |
| 1091 | 1094 | if (dc_is_hdmi_signal(link->connector_signal)) |
| 1092 | 1095 | read_scdc_caps(link->ddc, link->local_sink); |
| 1093 | 1096 | |
| @@ -2142,8 +2142,7 @@ static enum dc_status enable_link_dp(struct dc_state *state, · 2141 unmodified lines | ||
| 2142 | 2142 | if (link->dpcd_sink_ext_caps.bits.oled == 1 || |
| 2143 | 2143 | link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1 || |
| 2144 | 2144 | link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1) { |
| 2145 | − set_cached_brightness_aux(link); | |
| 2146 | − | |
| 2145 | + set_default_brightness_aux(link); | |
| 2147 | 2146 | if (link->dpcd_sink_ext_caps.bits.oled == 1) |
| 2148 | 2147 | msleep(bl_oled_enable_delay); |
| 2149 | 2148 | edp_backlight_enable_aux(link, true); |
| @@ -115,7 +115,7 @@ static enum link_training_result perform_fixed_vs_pe_nontransparent_training_seq · 114 unmodified lines | ||
| 115 | 115 | lt_settings->cr_pattern_time = 16000; |
| 116 | 116 | |
| 117 | 117 | /* Fixed VS/PE specific: Toggle link rate */ |
| 118 | − apply_toggle_rate_wa = (link->vendor_specific_lttpr_link_rate_wa == target_rate); | |
| 118 | + apply_toggle_rate_wa = ((link->vendor_specific_lttpr_link_rate_wa == target_rate) || (link->vendor_specific_lttpr_link_rate_wa == 0)); | |
| 119 | 119 | target_rate = get_dpcd_link_rate(<_settings->link_settings); |
| 120 | 120 | toggle_rate = (target_rate == 0x6) ? 0xA : 0x6; |
| 121 | 121 | |
| @@ -271,7 +271,7 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence_legacy( · 149 unmodified lines | ||
| 271 | 271 | /* Vendor specific: Toggle link rate */ |
| 272 | 272 | toggle_rate = (rate == 0x6) ? 0xA : 0x6; |
| 273 | 273 | |
| 274 | − if (link->vendor_specific_lttpr_link_rate_wa == rate) { | |
| 274 | + if (link->vendor_specific_lttpr_link_rate_wa == rate || link->vendor_specific_lttpr_link_rate_wa == 0) { | |
| 275 | 275 | core_link_write_dpcd( |
| 276 | 276 | link, |
| 277 | 277 | DP_LINK_BW_SET, |
| @@ -617,7 +617,7 @@ enum link_training_result dp_perform_fixed_vs_pe_training_sequence( · 339 unmodified lines | ||
| 617 | 617 | /* Vendor specific: Toggle link rate */ |
| 618 | 618 | toggle_rate = (rate == 0x6) ? 0xA : 0x6; |
| 619 | 619 | |
| 620 | − if (link->vendor_specific_lttpr_link_rate_wa == rate) { | |
| 620 | + if (link->vendor_specific_lttpr_link_rate_wa == rate || link->vendor_specific_lttpr_link_rate_wa == 0) { | |
| 621 | 621 | core_link_write_dpcd( |
| 622 | 622 | link, |
| 623 | 623 | DP_LINK_BW_SET, |
| @@ -170,7 +170,6 @@ bool edp_set_backlight_level_nits(struct dc_link *link, · 169 unmodified lines | ||
| 170 | 170 | *(uint32_t *)&dpcd_backlight_set.backlight_level_millinits = backlight_millinits; |
| 171 | 171 | *(uint16_t *)&dpcd_backlight_set.backlight_transition_time_ms = (uint16_t)transition_time_in_ms; |
| 172 | 172 | |
| 173 | − link->backlight_settings.backlight_millinits = backlight_millinits; | |
| 174 | 173 | |
| 175 | 174 | if (!link->dpcd_caps.panel_luminance_control) { |
| 176 | 175 | if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL, |
| @@ -288,9 +287,9 @@ bool set_default_brightness_aux(struct dc_link *link) · 111 unmodified lines | ||
| 288 | 287 | if (link && link->dpcd_sink_ext_caps.bits.oled == 1) { |
| 289 | 288 | if (!read_default_bl_aux(link, &default_backlight)) |
| 290 | 289 | default_backlight = 150000; |
| 291 | − // if < 1 nits or > 5000, it might be wrong readback | |
| 292 | − if (default_backlight < 1000 || default_backlight > 5000000) | |
| 293 | − default_backlight = 150000; // | |
| 290 | + // if > 5000, it might be wrong readback | |
| 291 | + if (default_backlight > 5000000) | |
| 292 | + default_backlight = 150000; | |
| 294 | 293 | |
| 295 | 294 | return edp_set_backlight_level_nits(link, true, |
| 296 | 295 | default_backlight, 0); |
| @@ -298,15 +297,6 @@ bool set_default_brightness_aux(struct dc_link *link) · 1 unmodified line | ||
| 298 | 297 | return false; |
| 299 | 298 | } |
| 300 | 299 | |
| 301 | −bool set_cached_brightness_aux(struct dc_link *link) | |
| 302 | −{ | |
| 303 | − if (link->backlight_settings.backlight_millinits) | |
| 304 | − return edp_set_backlight_level_nits(link, true, | |
| 305 | − link->backlight_settings.backlight_millinits, 0); | |
| 306 | − else | |
| 307 | − return set_default_brightness_aux(link); | |
| 308 | − return false; | |
| 309 | −} | |
| 310 | 300 | bool edp_is_ilr_optimization_enabled(struct dc_link *link) |
| 311 | 301 | { |
| 312 | 302 | if (link->dpcd_caps.edp_supported_link_rates_count == 0 || !link->panel_config.ilr.optimize_edp_link_rate) |
| @@ -30,7 +30,6 @@ · 29 unmodified lines | ||
| 30 | 30 | enum dp_panel_mode dp_get_panel_mode(struct dc_link *link); |
| 31 | 31 | void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode); |
| 32 | 32 | bool set_default_brightness_aux(struct dc_link *link); |
| 33 | −bool set_cached_brightness_aux(struct dc_link *link); | |
| 34 | 33 | void edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hpd); |
| 35 | 34 | int edp_get_backlight_level(const struct dc_link *link); |
| 36 | 35 | bool edp_get_backlight_level_nits(struct dc_link *link, |
| @@ -195,6 +195,7 @@ struct dmub_srv_region_params { · 194 unmodified lines | ||
| 195 | 195 | uint32_t vbios_size; |
| 196 | 196 | const uint8_t *fw_inst_const; |
| 197 | 197 | const uint8_t *fw_bss_data; |
| 198 | + bool is_mailbox_in_inbox; | |
| 198 | 199 | }; |
| 199 | 200 | |
| 200 | 201 | /** |
| @@ -214,20 +215,25 @@ struct dmub_srv_region_params { · 13 unmodified lines | ||
| 214 | 215 | */ |
| 215 | 216 | struct dmub_srv_region_info { |
| 216 | 217 | uint32_t fb_size; |
| 218 | + uint32_t inbox_size; | |
| 217 | 219 | uint8_t num_regions; |
| 218 | 220 | struct dmub_region regions[DMUB_WINDOW_TOTAL]; |
| 219 | 221 | }; |
| 220 | 222 | |
| 221 | 223 | /** |
| 222 | − * struct dmub_srv_fb_params - parameters used for driver fb setup | |
| 224 | + * struct dmub_srv_memory_params - parameters used for driver fb setup | |
| 223 | 225 | * @region_info: region info calculated by dmub service |
| 224 | − * @cpu_addr: base cpu address for the framebuffer | |
| 225 | − * @gpu_addr: base gpu virtual address for the framebuffer | |
| 226 | + * @cpu_fb_addr: base cpu address for the framebuffer | |
| 227 | + * @cpu_inbox_addr: base cpu address for the gart | |
| 228 | + * @gpu_fb_addr: base gpu virtual address for the framebuffer | |
| 229 | + * @gpu_inbox_addr: base gpu virtual address for the gart | |
| 226 | 230 | */ |
| 227 | −struct dmub_srv_fb_params { | |
| 231 | +struct dmub_srv_memory_params { | |
| 228 | 232 | const struct dmub_srv_region_info *region_info; |
| 229 | − void *cpu_addr; | |
| 230 | − uint64_t gpu_addr; | |
| 233 | + void *cpu_fb_addr; | |
| 234 | + void *cpu_inbox_addr; | |
| 235 | + uint64_t gpu_fb_addr; | |
| 236 | + uint64_t gpu_inbox_addr; | |
| 231 | 237 | }; |
| 232 | 238 | |
| 233 | 239 | /** |
| @@ -563,8 +569,8 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, · 329 unmodified lines | ||
| 563 | 569 | * DMUB_STATUS_OK - success |
| 564 | 570 | * DMUB_STATUS_INVALID - unspecified error |
| 565 | 571 | */ |
| 566 | −enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, | |
| 567 | − const struct dmub_srv_fb_params *params, | |
| 572 | +enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub, | |
| 573 | + const struct dmub_srv_memory_params *params, | |
| 568 | 574 | struct dmub_srv_fb_info *out); |
| 569 | 575 | |
| 570 | 576 | /** |
| @@ -434,7 +434,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, · 433 unmodified lines | ||
| 434 | 434 | uint32_t fw_state_size = DMUB_FW_STATE_SIZE; |
| 435 | 435 | uint32_t trace_buffer_size = DMUB_TRACE_BUFFER_SIZE; |
| 436 | 436 | uint32_t scratch_mem_size = DMUB_SCRATCH_MEM_SIZE; |
| 437 | − | |
| 437 | + uint32_t previous_top = 0; | |
| 438 | 438 | if (!dmub->sw_init) |
| 439 | 439 | return DMUB_STATUS_INVALID; |
| 440 | 440 | |
| @@ -459,8 +459,15 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, · 18 unmodified lines | ||
| 459 | 459 | bios->base = dmub_align(stack->top, 256); |
| 460 | 460 | bios->top = bios->base + params->vbios_size; |
| 461 | 461 | |
| 462 | − mail->base = dmub_align(bios->top, 256); | |
| 463 | − mail->top = mail->base + DMUB_MAILBOX_SIZE; | |
| 462 | + if (params->is_mailbox_in_inbox) { | |
| 463 | + mail->base = 0; | |
| 464 | + mail->top = mail->base + DMUB_MAILBOX_SIZE; | |
| 465 | + previous_top = bios->top; | |
| 466 | + } else { | |
| 467 | + mail->base = dmub_align(bios->top, 256); | |
| 468 | + mail->top = mail->base + DMUB_MAILBOX_SIZE; | |
| 469 | + previous_top = mail->top; | |
| 470 | + } | |
| 464 | 471 | |
| 465 | 472 | fw_info = dmub_get_fw_meta_info(params); |
| 466 | 473 | |
| @@ -479,7 +486,7 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, · 12 unmodified lines | ||
| 479 | 486 | dmub->fw_version = fw_info->fw_version; |
| 480 | 487 | } |
| 481 | 488 | |
| 482 | − trace_buff->base = dmub_align(mail->top, 256); | |
| 489 | + trace_buff->base = dmub_align(previous_top, 256); | |
| 483 | 490 | trace_buff->top = trace_buff->base + dmub_align(trace_buffer_size, 64); |
| 484 | 491 | |
| 485 | 492 | fw_state->base = dmub_align(trace_buff->top, 256); |
| @@ -490,11 +497,14 @@ dmub_srv_calc_region_info(struct dmub_srv *dmub, · 4 unmodified lines | ||
| 490 | 497 | |
| 491 | 498 | out->fb_size = dmub_align(scratch_mem->top, 4096); |
| 492 | 499 | |
| 500 | + if (params->is_mailbox_in_inbox) | |
| 501 | + out->inbox_size = dmub_align(mail->top, 4096); | |
| 502 | + | |
| 493 | 503 | return DMUB_STATUS_OK; |
| 494 | 504 | } |
| 495 | 505 | |
| 496 | −enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, | |
| 497 | − const struct dmub_srv_fb_params *params, | |
| 506 | +enum dmub_status dmub_srv_calc_mem_info(struct dmub_srv *dmub, | |
| 507 | + const struct dmub_srv_memory_params *params, | |
| 498 | 508 | struct dmub_srv_fb_info *out) |
| 499 | 509 | { |
| 500 | 510 | uint8_t *cpu_base; |
| @@ -509,8 +519,8 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, · 8 unmodified lines | ||
| 509 | 519 | if (params->region_info->num_regions != DMUB_NUM_WINDOWS) |
| 510 | 520 | return DMUB_STATUS_INVALID; |
| 511 | 521 | |
| 512 | − cpu_base = (uint8_t *)params->cpu_addr; | |
| 513 | − gpu_base = params->gpu_addr; | |
| 522 | + cpu_base = (uint8_t *)params->cpu_fb_addr; | |
| 523 | + gpu_base = params->gpu_fb_addr; | |
| 514 | 524 | |
| 515 | 525 | for (i = 0; i < DMUB_NUM_WINDOWS; ++i) { |
| 516 | 526 | const struct dmub_region *reg = |
| @@ -518,6 +528,12 @@ enum dmub_status dmub_srv_calc_fb_info(struct dmub_srv *dmub, · 1 unmodified line | ||
| 518 | 528 | |
| 519 | 529 | out->fb[i].cpu_addr = cpu_base + reg->base; |
| 520 | 530 | out->fb[i].gpu_addr = gpu_base + reg->base; |
| 531 | + | |
| 532 | + if (i == DMUB_WINDOW_4_MAILBOX && params->cpu_inbox_addr != 0) { | |
| 533 | + out->fb[i].cpu_addr = (uint8_t *)params->cpu_inbox_addr + reg->base; | |
| 534 | + out->fb[i].gpu_addr = params->gpu_inbox_addr + reg->base; | |
| 535 | + } | |
| 536 | + | |
| 521 | 537 | out->fb[i].size = reg->top - reg->base; |
| 522 | 538 | } |
| 523 | 539 | |
| @@ -707,9 +723,16 @@ enum dmub_status dmub_srv_sync_inbox1(struct dmub_srv *dmub) · 183 unmodified lines | ||
| 707 | 723 | return DMUB_STATUS_INVALID; |
| 708 | 724 | |
| 709 | 725 | if (dmub->hw_funcs.get_inbox1_rptr && dmub->hw_funcs.get_inbox1_wptr) { |
| 710 | − dmub->inbox1_rb.rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); | |
| 711 | − dmub->inbox1_rb.wrpt = dmub->hw_funcs.get_inbox1_wptr(dmub); | |
| 712 | − dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt; | |
| 726 | + uint32_t rptr = dmub->hw_funcs.get_inbox1_rptr(dmub); | |
| 727 | + uint32_t wptr = dmub->hw_funcs.get_inbox1_wptr(dmub); | |
| 728 | + | |
| 729 | + if (rptr > dmub->inbox1_rb.capacity || wptr > dmub->inbox1_rb.capacity) { | |
| 730 | + return DMUB_STATUS_HW_FAILURE; | |
| 731 | + } else { | |
| 732 | + dmub->inbox1_rb.rptr = rptr; | |
| 733 | + dmub->inbox1_rb.wrpt = wptr; | |
| 734 | + dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt; | |
| 735 | + } | |
| 713 | 736 | } |
| 714 | 737 | |
| 715 | 738 | return DMUB_STATUS_OK; |
| @@ -743,6 +766,11 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub, · 27 unmodified lines | ||
| 743 | 766 | if (!dmub->hw_init) |
| 744 | 767 | return DMUB_STATUS_INVALID; |
| 745 | 768 | |
| 769 | + if (dmub->inbox1_rb.rptr > dmub->inbox1_rb.capacity || | |
| 770 | + dmub->inbox1_rb.wrpt > dmub->inbox1_rb.capacity) { | |
| 771 | + return DMUB_STATUS_HW_FAILURE; | |
| 772 | + } | |
| 773 | + | |
| 746 | 774 | if (dmub_rb_push_front(&dmub->inbox1_rb, cmd)) |
| 747 | 775 | return DMUB_STATUS_OK; |
| 748 | 776 | |
| @@ -1049,6 +1077,7 @@ enum dmub_status dmub_srv_wait_for_inbox0_ack(struct dmub_srv *dmub, uint32_t ti · 300 unmodified lines | ||
| 1049 | 1077 | ack = dmub->hw_funcs.read_inbox0_ack_register(dmub); |
| 1050 | 1078 | if (ack) |
| 1051 | 1079 | return DMUB_STATUS_OK; |
| 1080 | + udelay(1); | |
| 1052 | 1081 | } |
| 1053 | 1082 | return DMUB_STATUS_TIMEOUT; |
| 1054 | 1083 | } |
| @@ -6369,6 +6369,8 @@ · 6368 unmodified lines | ||
| 6369 | 6369 | #define regTCP_INVALIDATE_BASE_IDX 1 |
| 6370 | 6370 | #define regTCP_STATUS 0x19a1 |
| 6371 | 6371 | #define regTCP_STATUS_BASE_IDX 1 |
| 6372 | +#define regTCP_CNTL 0x19a2 | |
| 6373 | +#define regTCP_CNTL_BASE_IDX 1 | |
| 6372 | 6374 | #define regTCP_CNTL2 0x19a3 |
| 6373 | 6375 | #define regTCP_CNTL2_BASE_IDX 1 |
| 6374 | 6376 | #define regTCP_DEBUG_INDEX 0x19a5 |
| @@ -781,6 +781,8 @@ · 780 unmodified lines | ||
| 781 | 781 | #define regBIF_BIF256_CI256_RC3X4_USB4_PCIE_CNTL2_BASE_IDX 5 |
| 782 | 782 | #define regBIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1 0x420187 |
| 783 | 783 | #define regBIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1_BASE_IDX 5 |
| 784 | +#define regBIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3 0x4201c6 | |
| 785 | +#define regBIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3_BASE_IDX 5 | |
| 784 | 786 | |
| 785 | 787 | |
| 786 | 788 | // addressBlock: nbio_nbif0_bif_cfg_dev0_rc_bifcfgdecp |
| @@ -24646,6 +24646,35 @@ · 24645 unmodified lines | ||
| 24646 | 24646 | //BIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1 |
| 24647 | 24647 | #define BIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1__MST_MEM_LS_EN_MASK 0x00000001L |
| 24648 | 24648 | #define BIF_BIF256_CI256_RC3X4_USB4_PCIE_TX_POWER_CTRL_1__REPLAY_MEM_LS_EN_MASK 0x00000008L |
| 24649 | +//BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3 | |
| 24650 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_MAX_PAYLOAD_SIZE_MODE__SHIFT 0x8 | |
| 24651 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_PRIV_MAX_PAYLOAD_SIZE__SHIFT 0x9 | |
| 24652 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_10BIT_TAG_EN_OVERRIDE__SHIFT 0xb | |
| 24653 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_10BIT_TAG_EN_OVERRIDE__SHIFT 0xd | |
| 24654 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__MST_DROP_SYNC_FLOOD_EN__SHIFT 0xf | |
| 24655 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_MAX_PAYLOAD_SIZE_MODE__SHIFT 0x10 | |
| 24656 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_PRIV_MAX_PAYLOAD_SIZE__SHIFT 0x11 | |
| 24657 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_MAX_READ_REQUEST_SIZE_MODE__SHIFT 0x14 | |
| 24658 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_PRIV_MAX_READ_REQUEST_SIZE__SHIFT 0x15 | |
| 24659 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_MAX_READ_SAFE_MODE__SHIFT 0x18 | |
| 24660 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_EXTENDED_TAG_EN_OVERRIDE__SHIFT 0x19 | |
| 24661 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_MAX_READ_REQUEST_SIZE_MODE__SHIFT 0x1b | |
| 24662 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_MAX_READ_REQUEST_SIZE_PRIV__SHIFT 0x1c | |
| 24663 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_EXTENDED_TAG_EN_OVERRIDE__SHIFT 0x1e | |
| 24664 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_MAX_PAYLOAD_SIZE_MODE_MASK 0x00000100L | |
| 24665 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_PRIV_MAX_PAYLOAD_SIZE_MASK 0x00000600L | |
| 24666 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_10BIT_TAG_EN_OVERRIDE_MASK 0x00001800L | |
| 24667 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_10BIT_TAG_EN_OVERRIDE_MASK 0x00006000L | |
| 24668 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__MST_DROP_SYNC_FLOOD_EN_MASK 0x00008000L | |
| 24669 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_MAX_PAYLOAD_SIZE_MODE_MASK 0x00010000L | |
| 24670 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_PRIV_MAX_PAYLOAD_SIZE_MASK 0x000E0000L | |
| 24671 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_MAX_READ_REQUEST_SIZE_MODE_MASK 0x00100000L | |
| 24672 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_PRIV_MAX_READ_REQUEST_SIZE_MASK 0x00E00000L | |
| 24673 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_MAX_READ_SAFE_MODE_MASK 0x01000000L | |
| 24674 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_EXTENDED_TAG_EN_OVERRIDE_MASK 0x06000000L | |
| 24675 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_MAX_READ_REQUEST_SIZE_MODE_MASK 0x08000000L | |
| 24676 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_MAX_READ_REQUEST_SIZE_PRIV_MASK 0x30000000L | |
| 24677 | +#define BIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3__CI_SWUS_EXTENDED_TAG_EN_OVERRIDE_MASK 0xC0000000L | |
| 24649 | 24678 | |
| 24650 | 24679 | // addressBlock: nbio_nbif0_bif_cfg_dev0_rc_bifcfgdecp |
| 24651 | 24680 | //BIF_CFG_DEV0_RC0_VENDOR_ID |
| @@ -444,6 +444,7 @@ struct amd_pm_funcs { · 443 unmodified lines | ||
| 444 | 444 | struct dpm_clocks *clock_table); |
| 445 | 445 | int (*get_smu_prv_buf_details)(void *handle, void **addr, size_t *size); |
| 446 | 446 | void (*pm_compute_clocks)(void *handle); |
| 447 | + int (*notify_rlc_state)(void *handle, bool en); | |
| 447 | 448 | }; |
| 448 | 449 | |
| 449 | 450 | struct metrics_table_header { |
| @@ -1084,6 +1085,10 @@ struct gpu_metrics_v3_0 { · 634 unmodified lines | ||
| 1084 | 1085 | uint16_t average_dram_reads; |
| 1085 | 1086 | /* time filtered DRAM write bandwidth [MB/sec] */ |
| 1086 | 1087 | uint16_t average_dram_writes; |
| 1088 | + /* time filtered IPU read bandwidth [MB/sec] */ | |
| 1089 | + uint16_t average_ipu_reads; | |
| 1090 | + /* time filtered IPU write bandwidth [MB/sec] */ | |
| 1091 | + uint16_t average_ipu_writes; | |
| 1087 | 1092 | |
| 1088 | 1093 | /* Driver attached timestamp (in ns) */ |
| 1089 | 1094 | uint64_t system_clock_counter; |
| @@ -1103,6 +1108,8 @@ struct gpu_metrics_v3_0 { · 13 unmodified lines | ||
| 1103 | 1108 | uint32_t average_all_core_power; |
| 1104 | 1109 | /* calculated core power [mW] */ |
| 1105 | 1110 | uint16_t average_core_power[16]; |
| 1111 | + /* time filtered total system power [mW] */ | |
| 1112 | + uint16_t average_sys_power; | |
| 1106 | 1113 | /* maximum IRM defined STAPM power limit [mW] */ |
| 1107 | 1114 | uint16_t stapm_power_limit; |
| 1108 | 1115 | /* time filtered STAPM power limit [mW] */ |
| @@ -1115,6 +1122,8 @@ struct gpu_metrics_v3_0 { · 6 unmodified lines | ||
| 1115 | 1122 | uint16_t average_ipuclk_frequency; |
| 1116 | 1123 | uint16_t average_fclk_frequency; |
| 1117 | 1124 | uint16_t average_vclk_frequency; |
| 1125 | + uint16_t average_uclk_frequency; | |
| 1126 | + uint16_t average_mpipu_frequency; | |
| 1118 | 1127 | |
| 1119 | 1128 | /* Current clocks */ |
| 1120 | 1129 | /* target core frequency [MHz] */ |
| @@ -1124,6 +1133,15 @@ struct gpu_metrics_v3_0 { · 3 unmodified lines | ||
| 1124 | 1133 | /* GFXCLK frequency limit enforced on GFX [MHz] */ |
| 1125 | 1134 | uint16_t current_gfx_maxfreq; |
| 1126 | 1135 | |
| 1136 | + /* Throttle Residency (ASIC dependent) */ | |
| 1137 | + uint32_t throttle_residency_prochot; | |
| 1138 | + uint32_t throttle_residency_spl; | |
| 1139 | + uint32_t throttle_residency_fppt; | |
| 1140 | + uint32_t throttle_residency_sppt; | |
| 1141 | + uint32_t throttle_residency_thm_core; | |
| 1142 | + uint32_t throttle_residency_thm_gfx; | |
| 1143 | + uint32_t throttle_residency_thm_soc; | |
| 1144 | + | |
| 1127 | 1145 | /* Metrics table alpha filter time constant [us] */ |
| 1128 | 1146 | uint32_t time_filter_alphavalue; |
| 1129 | 1147 | }; |
| @@ -181,6 +181,24 @@ int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev, · 180 unmodified lines | ||
| 181 | 181 | return ret; |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | +int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en) | |
| 185 | +{ | |
| 186 | + int ret = 0; | |
| 187 | + const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | |
| 188 | + | |
| 189 | + if (pp_funcs && pp_funcs->notify_rlc_state) { | |
| 190 | + mutex_lock(&adev->pm.mutex); | |
| 191 | + | |
| 192 | + ret = pp_funcs->notify_rlc_state( | |
| 193 | + adev->powerplay.pp_handle, | |
| 194 | + en); | |
| 195 | + | |
| 196 | + mutex_unlock(&adev->pm.mutex); | |
| 197 | + } | |
| 198 | + | |
| 199 | + return ret; | |
| 200 | +} | |
| 201 | + | |
| 184 | 202 | bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev) |
| 185 | 203 | { |
| 186 | 204 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; |
| @@ -415,6 +415,8 @@ int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev); · 414 unmodified lines | ||
| 415 | 415 | int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev, |
| 416 | 416 | enum pp_mp1_state mp1_state); |
| 417 | 417 | |
| 418 | +int amdgpu_dpm_notify_rlc_state(struct amdgpu_device *adev, bool en); | |
| 419 | + | |
| 418 | 420 | int amdgpu_dpm_set_gfx_power_up_by_imu(struct amdgpu_device *adev); |
| 419 | 421 | |
| 420 | 422 | int amdgpu_dpm_baco_exit(struct amdgpu_device *adev); |
| @@ -1710,6 +1710,16 @@ static int smu_disable_dpms(struct smu_context *smu) · 1709 unmodified lines | ||
| 1710 | 1710 | } |
| 1711 | 1711 | } |
| 1712 | 1712 | |
| 1713 | + /* Notify SMU RLC is going to be off, stop RLC and SMU interaction. | |
| 1714 | + * otherwise SMU will hang while interacting with RLC if RLC is halted | |
| 1715 | + * this is a WA for Vangogh asic which fix the SMU hang issue. | |
| 1716 | + */ | |
| 1717 | + ret = smu_notify_rlc_state(smu, false); | |
| 1718 | + if (ret) { | |
| 1719 | + dev_err(adev->dev, "Fail to notify rlc status!\n"); | |
| 1720 | + return ret; | |
| 1721 | + } | |
| 1722 | + | |
| 1713 | 1723 | if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 4, 2) && |
| 1714 | 1724 | !((adev->flags & AMD_IS_APU) && adev->gfx.imu.funcs) && |
| 1715 | 1725 | !amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs->stop) |
| @@ -1360,6 +1360,11 @@ struct pptable_funcs { · 1359 unmodified lines | ||
| 1360 | 1360 | * management. |
| 1361 | 1361 | */ |
| 1362 | 1362 | int (*dpm_set_umsch_mm_enable)(struct smu_context *smu, bool enable); |
| 1363 | + | |
| 1364 | + /** | |
| 1365 | + * @notify_rlc_state: Notify RLC power state to SMU. | |
| 1366 | + */ | |
| 1367 | + int (*notify_rlc_state)(struct smu_context *smu, bool en); | |
| 1363 | 1368 | }; |
| 1364 | 1369 | |
| 1365 | 1370 | typedef enum { |
| @@ -1403,6 +1408,16 @@ typedef enum { · 37 unmodified lines | ||
| 1403 | 1408 | METRICS_PCIE_WIDTH, |
| 1404 | 1409 | METRICS_CURR_FANPWM, |
| 1405 | 1410 | METRICS_CURR_SOCKETPOWER, |
| 1411 | + METRICS_AVERAGE_VPECLK, | |
| 1412 | + METRICS_AVERAGE_IPUCLK, | |
| 1413 | + METRICS_AVERAGE_MPIPUCLK, | |
| 1414 | + METRICS_THROTTLER_RESIDENCY_PROCHOT, | |
| 1415 | + METRICS_THROTTLER_RESIDENCY_SPL, | |
| 1416 | + METRICS_THROTTLER_RESIDENCY_FPPT, | |
| 1417 | + METRICS_THROTTLER_RESIDENCY_SPPT, | |
| 1418 | + METRICS_THROTTLER_RESIDENCY_THM_CORE, | |
| 1419 | + METRICS_THROTTLER_RESIDENCY_THM_GFX, | |
| 1420 | + METRICS_THROTTLER_RESIDENCY_THM_SOC, | |
| 1406 | 1421 | } MetricsMember_t; |
| 1407 | 1422 | |
| 1408 | 1423 | enum smu_cmn2asic_mapping_type { |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | // *** IMPORTANT *** |
| 28 | 28 | // SMU TEAM: Always increment the interface version if |
| 29 | 29 | // any structure is changed in this file |
| 30 | −#define PMFW_DRIVER_IF_VERSION 6 | |
| 30 | +#define PMFW_DRIVER_IF_VERSION 7 | |
| 31 | 31 | |
| 32 | 32 | typedef struct { |
| 33 | 33 | int32_t value; |
| @@ -150,37 +150,50 @@ typedef struct { · 116 unmodified lines | ||
| 150 | 150 | } DpmClocks_t; |
| 151 | 151 | |
| 152 | 152 | typedef struct { |
| 153 | − uint16_t CoreFrequency[16]; //Target core frequency [MHz] | |
| 154 | − uint16_t CorePower[16]; //CAC calculated core power [mW] | |
| 155 | − uint16_t CoreTemperature[16]; //TSEN measured core temperature [centi-C] | |
| 156 | − uint16_t GfxTemperature; //TSEN measured GFX temperature [centi-C] | |
| 157 | − uint16_t SocTemperature; //TSEN measured SOC temperature [centi-C] | |
| 158 | − uint16_t StapmOpnLimit; //Maximum IRM defined STAPM power limit [mW] | |
| 159 | − uint16_t StapmCurrentLimit; //Time filtered STAPM power limit [mW] | |
| 160 | − uint16_t InfrastructureCpuMaxFreq; //CCLK frequency limit enforced on classic cores [MHz] | |
| 161 | − uint16_t InfrastructureGfxMaxFreq; //GFXCLK frequency limit enforced on GFX [MHz] | |
| 162 | − uint16_t SkinTemp; //Maximum skin temperature reported by APU and HS2 chassis sensors [centi-C] | |
| 163 | − uint16_t GfxclkFrequency; //Time filtered target GFXCLK frequency [MHz] | |
| 164 | − uint16_t FclkFrequency; //Time filtered target FCLK frequency [MHz] | |
| 165 | − uint16_t GfxActivity; //Time filtered GFX busy % [0-100] | |
| 166 | − uint16_t SocclkFrequency; //Time filtered target SOCCLK frequency [MHz] | |
| 167 | − uint16_t VclkFrequency; //Time filtered target VCLK frequency [MHz] | |
| 168 | − uint16_t VcnActivity; //Time filtered VCN busy % [0-100] | |
| 169 | − uint16_t VpeclkFrequency; //Time filtered target VPECLK frequency [MHz] | |
| 170 | − uint16_t IpuclkFrequency; //Time filtered target IPUCLK frequency [MHz] | |
| 171 | − uint16_t IpuBusy[8]; //Time filtered IPU per-column busy % [0-100] | |
| 172 | − uint16_t DRAMReads; //Time filtered DRAM read bandwidth [MB/sec] | |
| 173 | − uint16_t DRAMWrites; //Time filtered DRAM write bandwidth [MB/sec] | |
| 174 | − uint16_t CoreC0Residency[16]; //Time filtered per-core C0 residency % [0-100] | |
| 175 | − uint16_t IpuPower; //Time filtered IPU power [mW] | |
| 176 | − uint32_t ApuPower; //Time filtered APU power [mW] | |
| 177 | − uint32_t GfxPower; //Time filtered GFX power [mW] | |
| 178 | − uint32_t dGpuPower; //Time filtered dGPU power [mW] | |
| 179 | − uint32_t SocketPower; //Time filtered power used for PPT/STAPM [APU+dGPU] [mW] | |
| 180 | − uint32_t AllCorePower; //Time filtered sum of core power across all cores in the socket [mW] | |
| 181 | − uint32_t FilterAlphaValue; //Metrics table alpha filter time constant [us] | |
| 182 | − uint32_t MetricsCounter; //Counter that is incremented on every metrics table update [PM_TIMER cycles] | |
| 183 | − uint32_t spare[16]; | |
| 153 | + uint16_t CoreFrequency[16]; //Target core frequency [MHz] | |
| 154 | + uint16_t CorePower[16]; //CAC calculated core power [mW] | |
| 155 | + uint16_t CoreTemperature[16]; //TSEN measured core temperature [centi-C] | |
| 156 | + uint16_t GfxTemperature; //TSEN measured GFX temperature [centi-C] | |
| 157 | + uint16_t SocTemperature; //TSEN measured SOC temperature [centi-C] | |
| 158 | + uint16_t StapmOpnLimit; //Maximum IRM defined STAPM power limit [mW] | |
| 159 | + uint16_t StapmCurrentLimit; //Time filtered STAPM power limit [mW] | |
| 160 | + uint16_t InfrastructureCpuMaxFreq; //CCLK frequency limit enforced on classic cores [MHz] | |
| 161 | + uint16_t InfrastructureGfxMaxFreq; //GFXCLK frequency limit enforced on GFX [MHz] | |
| 162 | + uint16_t SkinTemp; //Maximum skin temperature reported by APU and HS2 chassis sensors [centi-C] | |
| 163 | + uint16_t GfxclkFrequency; //Time filtered target GFXCLK frequency [MHz] | |
| 164 | + uint16_t FclkFrequency; //Time filtered target FCLK frequency [MHz] | |
| 165 | + uint16_t GfxActivity; //Time filtered GFX busy % [0-100] | |
| 166 | + uint16_t SocclkFrequency; //Time filtered target SOCCLK frequency [MHz] | |
| 167 | + uint16_t VclkFrequency; //Time filtered target VCLK frequency [MHz] | |
| 168 | + uint16_t VcnActivity; //Time filtered VCN busy % [0-100] | |
| 169 | + uint16_t VpeclkFrequency; //Time filtered target VPECLK frequency [MHz] | |
| 170 | + uint16_t IpuclkFrequency; //Time filtered target IPUCLK frequency [MHz] | |
| 171 | + uint16_t IpuBusy[8]; //Time filtered IPU per-column busy % [0-100] | |
| 172 | + uint16_t DRAMReads; //Time filtered DRAM read bandwidth [MB/sec] | |
| 173 | + uint16_t DRAMWrites; //Time filtered DRAM write bandwidth [MB/sec] | |
| 174 | + uint16_t CoreC0Residency[16]; //Time filtered per-core C0 residency % [0-100] | |
| 175 | + uint16_t IpuPower; //Time filtered IPU power [mW] | |
| 176 | + uint32_t ApuPower; //Time filtered APU power [mW] | |
| 177 | + uint32_t GfxPower; //Time filtered GFX power [mW] | |
| 178 | + uint32_t dGpuPower; //Time filtered dGPU power [mW] | |
| 179 | + uint32_t SocketPower; //Time filtered power used for PPT/STAPM [APU+dGPU] [mW] | |
| 180 | + uint32_t AllCorePower; //Time filtered sum of core power across all cores in the socket [mW] | |
| 181 | + uint32_t FilterAlphaValue; //Metrics table alpha filter time constant [us] | |
| 182 | + uint32_t MetricsCounter; //Counter that is incremented on every metrics table update [PM_TIMER cycles] | |
| 183 | + uint16_t MemclkFrequency; //Time filtered target MEMCLK frequency [MHz] | |
| 184 | + uint16_t MpipuclkFrequency; //Time filtered target MPIPUCLK frequency [MHz] | |
| 185 | + uint16_t IpuReads; //Time filtered IPU read bandwidth [MB/sec] | |
| 186 | + uint16_t IpuWrites; //Time filtered IPU write bandwidth [MB/sec] | |
| 187 | + uint32_t ThrottleResidency_PROCHOT; //Counter that is incremented on every metrics table update when PROCHOT was engaged [PM_TIMER cycles] | |
| 188 | + uint32_t ThrottleResidency_SPL; //Counter that is incremented on every metrics table update when SPL was engaged [PM_TIMER cycles] | |
| 189 | + uint32_t ThrottleResidency_FPPT; //Counter that is incremented on every metrics table update when fast PPT was engaged [PM_TIMER cycles] | |
| 190 | + uint32_t ThrottleResidency_SPPT; //Counter that is incremented on every metrics table update when slow PPT was engaged [PM_TIMER cycles] | |
| 191 | + uint32_t ThrottleResidency_THM_CORE; //Counter that is incremented on every metrics table update when CORE thermal throttling was engaged [PM_TIMER cycles] | |
| 192 | + uint32_t ThrottleResidency_THM_GFX; //Counter that is incremented on every metrics table update when GFX thermal throttling was engaged [PM_TIMER cycles] | |
| 193 | + uint32_t ThrottleResidency_THM_SOC; //Counter that is incremented on every metrics table update when SOC thermal throttling was engaged [PM_TIMER cycles] | |
| 194 | + uint16_t Psys; //Time filtered Psys power [mW] | |
| 195 | + uint16_t spare1; | |
| 196 | + uint32_t spare[6]; | |
| 184 | 197 | } SmuMetrics_t; |
| 185 | 198 | |
| 186 | 199 | //ISP tile definitions |
| @@ -123,7 +123,7 @@ typedef enum { · 122 unmodified lines | ||
| 123 | 123 | VOLTAGE_GUARDBAND_COUNT |
| 124 | 124 | } GFX_GUARDBAND_e; |
| 125 | 125 | |
| 126 | −#define SMU_METRICS_TABLE_VERSION 0x8 | |
| 126 | +#define SMU_METRICS_TABLE_VERSION 0x9 | |
| 127 | 127 | |
| 128 | 128 | typedef struct __attribute__((packed, aligned(4))) { |
| 129 | 129 | uint32_t AccumulationCounter; |
| @@ -211,6 +211,14 @@ typedef struct __attribute__((packed, aligned(4))) { · 81 unmodified lines | ||
| 211 | 211 | //XGMI Data tranfser size |
| 212 | 212 | uint64_t XgmiReadDataSizeAcc[8];//in KByte |
| 213 | 213 | uint64_t XgmiWriteDataSizeAcc[8];//in KByte |
| 214 | + | |
| 215 | + //PCIE BW Data and error count | |
| 216 | + uint32_t PcieBandwidth[4]; | |
| 217 | + uint32_t PCIeL0ToRecoveryCountAcc; // The Pcie counter itself is accumulated | |
| 218 | + uint32_t PCIenReplayAAcc; // The Pcie counter itself is accumulated | |
| 219 | + uint32_t PCIenReplayARolloverCountAcc; // The Pcie counter itself is accumulated | |
| 220 | + uint32_t PCIeNAKSentCountAcc; // The Pcie counter itself is accumulated | |
| 221 | + uint32_t PCIeNAKReceivedCountAcc; // The Pcie counter itself is accumulated | |
| 214 | 222 | } MetricsTable_t; |
| 215 | 223 | |
| 216 | 224 | #define SMU_VF_METRICS_TABLE_VERSION 0x3 |
| @@ -2193,8 +2193,7 @@ static int vangogh_get_dpm_clock_table(struct smu_context *smu, struct dpm_clock · 2192 unmodified lines | ||
| 2193 | 2193 | return 0; |
| 2194 | 2194 | } |
| 2195 | 2195 | |
| 2196 | − | |
| 2197 | −static int vangogh_system_features_control(struct smu_context *smu, bool en) | |
| 2196 | +static int vangogh_notify_rlc_state(struct smu_context *smu, bool en) | |
| 2198 | 2197 | { |
| 2199 | 2198 | struct amdgpu_device *adev = smu->adev; |
| 2200 | 2199 | int ret = 0; |
| @@ -2523,7 +2522,7 @@ static const struct pptable_funcs vangogh_ppt_funcs = { · 322 unmodified lines | ||
| 2523 | 2522 | .print_clk_levels = vangogh_common_print_clk_levels, |
| 2524 | 2523 | .set_default_dpm_table = vangogh_set_default_dpm_tables, |
| 2525 | 2524 | .set_fine_grain_gfx_freq_parameters = vangogh_set_fine_grain_gfx_freq_parameters, |
| 2526 | − .system_features_control = vangogh_system_features_control, | |
| 2525 | + .notify_rlc_state = vangogh_notify_rlc_state, | |
| 2527 | 2526 | .feature_is_enabled = smu_cmn_feature_is_enabled, |
| 2528 | 2527 | .set_power_profile_mode = vangogh_set_power_profile_mode, |
| 2529 | 2528 | .get_power_profile_mode = vangogh_get_power_profile_mode, |
| @@ -257,8 +257,11 @@ static int aldebaran_tables_init(struct smu_context *smu) · 256 unmodified lines | ||
| 257 | 257 | } |
| 258 | 258 | |
| 259 | 259 | smu_table->ecc_table = kzalloc(tables[SMU_TABLE_ECCINFO].size, GFP_KERNEL); |
| 260 | − if (!smu_table->ecc_table) | |
| 260 | + if (!smu_table->ecc_table) { | |
| 261 | + kfree(smu_table->metrics_table); | |
| 262 | + kfree(smu_table->gpu_metrics_table); | |
| 261 | 263 | return -ENOMEM; |
| 264 | + } | |
| 262 | 265 | |
| 263 | 266 | return 0; |
| 264 | 267 | } |
| @@ -1454,7 +1454,7 @@ static int smu_v13_0_6_register_irq_handler(struct smu_context *smu) · 1453 unmodified lines | ||
| 1454 | 1454 | |
| 1455 | 1455 | static int smu_v13_0_6_notify_unload(struct smu_context *smu) |
| 1456 | 1456 | { |
| 1457 | − if (smu->smc_fw_version <= 0x553500) | |
| 1457 | + if (amdgpu_in_reset(smu->adev)) | |
| 1458 | 1458 | return 0; |
| 1459 | 1459 | |
| 1460 | 1460 | dev_dbg(smu->adev->dev, "Notify PMFW about driver unload"); |
| @@ -2095,6 +2095,14 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table · 634 unmodified lines | ||
| 2095 | 2095 | smu_v13_0_6_get_current_pcie_link_speed(smu); |
| 2096 | 2096 | gpu_metrics->pcie_bandwidth_acc = |
| 2097 | 2097 | SMUQ10_ROUND(metrics->PcieBandwidthAcc[0]); |
| 2098 | + gpu_metrics->pcie_bandwidth_inst = | |
| 2099 | + SMUQ10_ROUND(metrics->PcieBandwidth[0]); | |
| 2100 | + gpu_metrics->pcie_l0_to_recov_count_acc = | |
| 2101 | + metrics->PCIeL0ToRecoveryCountAcc; | |
| 2102 | + gpu_metrics->pcie_replay_count_acc = | |
| 2103 | + metrics->PCIenReplayAAcc; | |
| 2104 | + gpu_metrics->pcie_replay_rover_count_acc = | |
| 2105 | + metrics->PCIenReplayARolloverCountAcc; | |
| 2098 | 2106 | } |
| 2099 | 2107 | |
| 2100 | 2108 | gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); |
| @@ -2585,13 +2593,20 @@ static bool mca_gfx_smu_bank_is_valid(const struct mca_ras_info *mca_ras, struct · 484 unmodified lines | ||
| 2585 | 2593 | static bool mca_smu_bank_is_valid(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev, |
| 2586 | 2594 | enum amdgpu_mca_error_type type, struct mca_bank_entry *entry) |
| 2587 | 2595 | { |
| 2596 | + struct smu_context *smu = adev->powerplay.pp_handle; | |
| 2588 | 2597 | uint32_t errcode, instlo; |
| 2589 | 2598 | |
| 2590 | 2599 | instlo = REG_GET_FIELD(entry->regs[MCA_REG_IDX_IPID], MCMP1_IPIDT0, InstanceIdLo); |
| 2591 | 2600 | if (instlo != 0x03b30400) |
| 2592 | 2601 | return false; |
| 2593 | 2602 | |
| 2594 | − errcode = REG_GET_FIELD(entry->regs[MCA_REG_IDX_STATUS], MCMP1_STATUST0, ErrorCode); | |
| 2603 | + if (!(adev->flags & AMD_IS_APU) && smu->smc_fw_version >= 0x00555600) { | |
| 2604 | + errcode = MCA_REG__SYND__ERRORINFORMATION(entry->regs[MCA_REG_IDX_SYND]); | |
| 2605 | + errcode &= 0xff; | |
| 2606 | + } else { | |
| 2607 | + errcode = REG_GET_FIELD(entry->regs[MCA_REG_IDX_STATUS], MCMP1_STATUST0, ErrorCode); | |
| 2608 | + } | |
| 2609 | + | |
| 2595 | 2610 | return mca_smu_check_error_code(adev, mca_ras, errcode); |
| 2596 | 2611 | } |
| 2597 | 2612 | |
| @@ -246,11 +246,20 @@ static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu, · 245 unmodified lines | ||
| 246 | 246 | *value = 0; |
| 247 | 247 | break; |
| 248 | 248 | case METRICS_AVERAGE_UCLK: |
| 249 | − *value = 0; | |
| 249 | + *value = metrics->MemclkFrequency; | |
| 250 | 250 | break; |
| 251 | 251 | case METRICS_AVERAGE_FCLK: |
| 252 | 252 | *value = metrics->FclkFrequency; |
| 253 | 253 | break; |
| 254 | + case METRICS_AVERAGE_VPECLK: | |
| 255 | + *value = metrics->VpeclkFrequency; | |
| 256 | + break; | |
| 257 | + case METRICS_AVERAGE_IPUCLK: | |
| 258 | + *value = metrics->IpuclkFrequency; | |
| 259 | + break; | |
| 260 | + case METRICS_AVERAGE_MPIPUCLK: | |
| 261 | + *value = metrics->MpipuclkFrequency; | |
| 262 | + break; | |
| 254 | 263 | case METRICS_AVERAGE_GFXACTIVITY: |
| 255 | 264 | *value = metrics->GfxActivity / 100; |
| 256 | 265 | break; |
| @@ -270,8 +279,26 @@ static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu, · 13 unmodified lines | ||
| 270 | 279 | *value = metrics->SocTemperature / 100 * |
| 271 | 280 | SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; |
| 272 | 281 | break; |
| 273 | − case METRICS_THROTTLER_STATUS: | |
| 274 | − *value = 0; | |
| 282 | + case METRICS_THROTTLER_RESIDENCY_PROCHOT: | |
| 283 | + *value = metrics->ThrottleResidency_PROCHOT; | |
| 284 | + break; | |
| 285 | + case METRICS_THROTTLER_RESIDENCY_SPL: | |
| 286 | + *value = metrics->ThrottleResidency_SPL; | |
| 287 | + break; | |
| 288 | + case METRICS_THROTTLER_RESIDENCY_FPPT: | |
| 289 | + *value = metrics->ThrottleResidency_FPPT; | |
| 290 | + break; | |
| 291 | + case METRICS_THROTTLER_RESIDENCY_SPPT: | |
| 292 | + *value = metrics->ThrottleResidency_SPPT; | |
| 293 | + break; | |
| 294 | + case METRICS_THROTTLER_RESIDENCY_THM_CORE: | |
| 295 | + *value = metrics->ThrottleResidency_THM_CORE; | |
| 296 | + break; | |
| 297 | + case METRICS_THROTTLER_RESIDENCY_THM_GFX: | |
| 298 | + *value = metrics->ThrottleResidency_THM_GFX; | |
| 299 | + break; | |
| 300 | + case METRICS_THROTTLER_RESIDENCY_THM_SOC: | |
| 301 | + *value = metrics->ThrottleResidency_THM_SOC; | |
| 275 | 302 | break; |
| 276 | 303 | case METRICS_VOLTAGE_VDDGFX: |
| 277 | 304 | *value = 0; |
| @@ -498,6 +525,8 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu, · 220 unmodified lines | ||
| 498 | 525 | sizeof(uint16_t) * 16); |
| 499 | 526 | gpu_metrics->average_dram_reads = metrics.DRAMReads; |
| 500 | 527 | gpu_metrics->average_dram_writes = metrics.DRAMWrites; |
| 528 | + gpu_metrics->average_ipu_reads = metrics.IpuReads; | |
| 529 | + gpu_metrics->average_ipu_writes = metrics.IpuWrites; | |
| 501 | 530 | |
| 502 | 531 | gpu_metrics->average_socket_power = metrics.SocketPower; |
| 503 | 532 | gpu_metrics->average_ipu_power = metrics.IpuPower; |
| @@ -505,6 +534,7 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu, · 1 unmodified line | ||
| 505 | 534 | gpu_metrics->average_gfx_power = metrics.GfxPower; |
| 506 | 535 | gpu_metrics->average_dgpu_power = metrics.dGpuPower; |
| 507 | 536 | gpu_metrics->average_all_core_power = metrics.AllCorePower; |
| 537 | + gpu_metrics->average_sys_power = metrics.Psys; | |
| 508 | 538 | memcpy(&gpu_metrics->average_core_power[0], |
| 509 | 539 | &metrics.CorePower[0], |
| 510 | 540 | sizeof(uint16_t) * 16); |
| @@ -515,6 +545,8 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu, · 4 unmodified lines | ||
| 515 | 545 | gpu_metrics->average_fclk_frequency = metrics.FclkFrequency; |
| 516 | 546 | gpu_metrics->average_vclk_frequency = metrics.VclkFrequency; |
| 517 | 547 | gpu_metrics->average_ipuclk_frequency = metrics.IpuclkFrequency; |
| 548 | + gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency; | |
| 549 | + gpu_metrics->average_mpipu_frequency = metrics.MpipuclkFrequency; | |
| 518 | 550 | |
| 519 | 551 | memcpy(&gpu_metrics->current_coreclk[0], |
| 520 | 552 | &metrics.CoreFrequency[0], |
| @@ -522,6 +554,14 @@ static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu, · 1 unmodified line | ||
| 522 | 554 | gpu_metrics->current_core_maxfreq = metrics.InfrastructureCpuMaxFreq; |
| 523 | 555 | gpu_metrics->current_gfx_maxfreq = metrics.InfrastructureGfxMaxFreq; |
| 524 | 556 | |
| 557 | + gpu_metrics->throttle_residency_prochot = metrics.ThrottleResidency_PROCHOT; | |
| 558 | + gpu_metrics->throttle_residency_spl = metrics.ThrottleResidency_SPL; | |
| 559 | + gpu_metrics->throttle_residency_fppt = metrics.ThrottleResidency_FPPT; | |
| 560 | + gpu_metrics->throttle_residency_sppt = metrics.ThrottleResidency_SPPT; | |
| 561 | + gpu_metrics->throttle_residency_thm_core = metrics.ThrottleResidency_THM_CORE; | |
| 562 | + gpu_metrics->throttle_residency_thm_gfx = metrics.ThrottleResidency_THM_GFX; | |
| 563 | + gpu_metrics->throttle_residency_thm_soc = metrics.ThrottleResidency_THM_SOC; | |
| 564 | + | |
| 525 | 565 | gpu_metrics->time_filter_alphavalue = metrics.FilterAlphaValue; |
| 526 | 566 | gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); |
| 527 | 567 | |
| @@ -97,6 +97,7 @@ · 96 unmodified lines | ||
| 97 | 97 | #define smu_get_default_config_table_settings(smu, config_table) smu_ppt_funcs(get_default_config_table_settings, -EOPNOTSUPP, smu, config_table) |
| 98 | 98 | #define smu_set_config_table(smu, config_table) smu_ppt_funcs(set_config_table, -EOPNOTSUPP, smu, config_table) |
| 99 | 99 | #define smu_init_pptable_microcode(smu) smu_ppt_funcs(init_pptable_microcode, 0, smu) |
| 100 | +#define smu_notify_rlc_state(smu, en) smu_ppt_funcs(notify_rlc_state, 0, smu, en) | |
| 100 | 101 | |
| 101 | 102 | #endif |
| 102 | 103 | #endif |
| @@ -174,6 +174,17 @@ to_ast_sil164_connector(struct drm_connector *connector) · 173 unmodified lines | ||
| 174 | 174 | return container_of(connector, struct ast_sil164_connector, base); |
| 175 | 175 | } |
| 176 | 176 | |
| 177 | +struct ast_bmc_connector { | |
| 178 | + struct drm_connector base; | |
| 179 | + struct drm_connector *physical_connector; | |
| 180 | +}; | |
| 181 | + | |
| 182 | +static inline struct ast_bmc_connector * | |
| 183 | +to_ast_bmc_connector(struct drm_connector *connector) | |
| 184 | +{ | |
| 185 | + return container_of(connector, struct ast_bmc_connector, base); | |
| 186 | +} | |
| 187 | + | |
| 177 | 188 | /* |
| 178 | 189 | * Device |
| 179 | 190 | */ |
| @@ -218,7 +229,7 @@ struct ast_device { · 38 unmodified lines | ||
| 218 | 229 | } astdp; |
| 219 | 230 | struct { |
| 220 | 231 | struct drm_encoder encoder; |
| 221 | − struct drm_connector connector; | |
| 232 | + struct ast_bmc_connector bmc_connector; | |
| 222 | 233 | } bmc; |
| 223 | 234 | } output; |
| 224 | 235 | |
| @@ -1767,6 +1767,30 @@ static const struct drm_encoder_funcs ast_bmc_encoder_funcs = { · 1766 unmodified lines | ||
| 1767 | 1767 | .destroy = drm_encoder_cleanup, |
| 1768 | 1768 | }; |
| 1769 | 1769 | |
| 1770 | +static int ast_bmc_connector_helper_detect_ctx(struct drm_connector *connector, | |
| 1771 | + struct drm_modeset_acquire_ctx *ctx, | |
| 1772 | + bool force) | |
| 1773 | +{ | |
| 1774 | + struct ast_bmc_connector *bmc_connector = to_ast_bmc_connector(connector); | |
| 1775 | + struct drm_connector *physical_connector = bmc_connector->physical_connector; | |
| 1776 | + | |
| 1777 | + /* | |
| 1778 | + * Most user-space compositors cannot handle more than one connected | |
| 1779 | + * connector per CRTC. Hence, we only mark the BMC as connected if the | |
| 1780 | + * physical connector is disconnected. If the physical connector's status | |
| 1781 | + * is connected or unknown, the BMC remains disconnected. This has no | |
| 1782 | + * effect on the output of the BMC. | |
| 1783 | + * | |
| 1784 | + * FIXME: Remove this logic once user-space compositors can handle more | |
| 1785 | + * than one connector per CRTC. The BMC should always be connected. | |
| 1786 | + */ | |
| 1787 | + | |
| 1788 | + if (physical_connector && physical_connector->status == connector_status_disconnected) | |
| 1789 | + return connector_status_connected; | |
| 1790 | + | |
| 1791 | + return connector_status_disconnected; | |
| 1792 | +} | |
| 1793 | + | |
| 1770 | 1794 | static int ast_bmc_connector_helper_get_modes(struct drm_connector *connector) |
| 1771 | 1795 | { |
| 1772 | 1796 | return drm_add_modes_noedid(connector, 4096, 4096); |
| @@ -1774,6 +1798,7 @@ static int ast_bmc_connector_helper_get_modes(struct drm_connector *connector) · 1 unmodified line | ||
| 1774 | 1798 | |
| 1775 | 1799 | static const struct drm_connector_helper_funcs ast_bmc_connector_helper_funcs = { |
| 1776 | 1800 | .get_modes = ast_bmc_connector_helper_get_modes, |
| 1801 | + .detect_ctx = ast_bmc_connector_helper_detect_ctx, | |
| 1777 | 1802 | }; |
| 1778 | 1803 | |
| 1779 | 1804 | static const struct drm_connector_funcs ast_bmc_connector_funcs = { |
| @@ -1784,12 +1809,33 @@ static const struct drm_connector_funcs ast_bmc_connector_funcs = { · 4 unmodified lines | ||
| 1784 | 1809 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, |
| 1785 | 1810 | }; |
| 1786 | 1811 | |
| 1787 | −static int ast_bmc_output_init(struct ast_device *ast) | |
| 1812 | +static int ast_bmc_connector_init(struct drm_device *dev, | |
| 1813 | + struct ast_bmc_connector *bmc_connector, | |
| 1814 | + struct drm_connector *physical_connector) | |
| 1815 | +{ | |
| 1816 | + struct drm_connector *connector = &bmc_connector->base; | |
| 1817 | + int ret; | |
| 1818 | + | |
| 1819 | + ret = drm_connector_init(dev, connector, &ast_bmc_connector_funcs, | |
| 1820 | + DRM_MODE_CONNECTOR_VIRTUAL); | |
| 1821 | + if (ret) | |
| 1822 | + return ret; | |
| 1823 | + | |
| 1824 | + drm_connector_helper_add(connector, &ast_bmc_connector_helper_funcs); | |
| 1825 | + | |
| 1826 | + bmc_connector->physical_connector = physical_connector; | |
| 1827 | + | |
| 1828 | + return 0; | |
| 1829 | +} | |
| 1830 | + | |
| 1831 | +static int ast_bmc_output_init(struct ast_device *ast, | |
| 1832 | + struct drm_connector *physical_connector) | |
| 1788 | 1833 | { |
| 1789 | 1834 | struct drm_device *dev = &ast->base; |
| 1790 | 1835 | struct drm_crtc *crtc = &ast->crtc; |
| 1791 | 1836 | struct drm_encoder *encoder = &ast->output.bmc.encoder; |
| 1792 | − struct drm_connector *connector = &ast->output.bmc.connector; | |
| 1837 | + struct ast_bmc_connector *bmc_connector = &ast->output.bmc.bmc_connector; | |
| 1838 | + struct drm_connector *connector = &bmc_connector->base; | |
| 1793 | 1839 | int ret; |
| 1794 | 1840 | |
| 1795 | 1841 | ret = drm_encoder_init(dev, encoder, |
| @@ -1799,13 +1845,10 @@ static int ast_bmc_output_init(struct ast_device *ast) · 3 unmodified lines | ||
| 1799 | 1845 | return ret; |
| 1800 | 1846 | encoder->possible_crtcs = drm_crtc_mask(crtc); |
| 1801 | 1847 | |
| 1802 | − ret = drm_connector_init(dev, connector, &ast_bmc_connector_funcs, | |
| 1803 | − DRM_MODE_CONNECTOR_VIRTUAL); | |
| 1848 | + ret = ast_bmc_connector_init(dev, bmc_connector, physical_connector); | |
| 1804 | 1849 | if (ret) |
| 1805 | 1850 | return ret; |
| 1806 | 1851 | |
| 1807 | − drm_connector_helper_add(connector, &ast_bmc_connector_helper_funcs); | |
| 1808 | − | |
| 1809 | 1852 | ret = drm_connector_attach_encoder(connector, encoder); |
| 1810 | 1853 | if (ret) |
| 1811 | 1854 | return ret; |
| @@ -1864,6 +1907,7 @@ static const struct drm_mode_config_funcs ast_mode_config_funcs = { · 52 unmodified lines | ||
| 1864 | 1907 | int ast_mode_config_init(struct ast_device *ast) |
| 1865 | 1908 | { |
| 1866 | 1909 | struct drm_device *dev = &ast->base; |
| 1910 | + struct drm_connector *physical_connector = NULL; | |
| 1867 | 1911 | int ret; |
| 1868 | 1912 | |
| 1869 | 1913 | ret = drmm_mode_config_init(dev); |
| @@ -1904,23 +1948,27 @@ int ast_mode_config_init(struct ast_device *ast) · 34 unmodified lines | ||
| 1904 | 1948 | ret = ast_vga_output_init(ast); |
| 1905 | 1949 | if (ret) |
| 1906 | 1950 | return ret; |
| 1951 | + physical_connector = &ast->output.vga.vga_connector.base; | |
| 1907 | 1952 | } |
| 1908 | 1953 | if (ast->tx_chip_types & AST_TX_SIL164_BIT) { |
| 1909 | 1954 | ret = ast_sil164_output_init(ast); |
| 1910 | 1955 | if (ret) |
| 1911 | 1956 | return ret; |
| 1957 | + physical_connector = &ast->output.sil164.sil164_connector.base; | |
| 1912 | 1958 | } |
| 1913 | 1959 | if (ast->tx_chip_types & AST_TX_DP501_BIT) { |
| 1914 | 1960 | ret = ast_dp501_output_init(ast); |
| 1915 | 1961 | if (ret) |
| 1916 | 1962 | return ret; |
| 1963 | + physical_connector = &ast->output.dp501.connector; | |
| 1917 | 1964 | } |
| 1918 | 1965 | if (ast->tx_chip_types & AST_TX_ASTDP_BIT) { |
| 1919 | 1966 | ret = ast_astdp_output_init(ast); |
| 1920 | 1967 | if (ret) |
| 1921 | 1968 | return ret; |
| 1969 | + physical_connector = &ast->output.astdp.connector; | |
| 1922 | 1970 | } |
| 1923 | − ret = ast_bmc_output_init(ast); | |
| 1971 | + ret = ast_bmc_output_init(ast, physical_connector); | |
| 1924 | 1972 | if (ret) |
| 1925 | 1973 | return ret; |
| 1926 | 1974 | |
| @@ -313,6 +313,7 @@ config DRM_TOSHIBA_TC358768 · 312 unmodified lines | ||
| 313 | 313 | select REGMAP_I2C |
| 314 | 314 | select DRM_PANEL |
| 315 | 315 | select DRM_MIPI_DSI |
| 316 | + select VIDEOMODE_HELPERS | |
| 316 | 317 | help |
| 317 | 318 | Toshiba TC358768AXBG/TC358778XBG DSI bridge chip driver. |
| 318 | 319 | |
| @@ -4,8 +4,6 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright (C) 2017 Broadcom |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | −#include <linux/device.h> | |
| 8 | − | |
| 9 | 7 | #include <drm/drm_atomic_helper.h> |
| 10 | 8 | #include <drm/drm_bridge.h> |
| 11 | 9 | #include <drm/drm_connector.h> |
| @@ -21,7 +19,6 @@ struct panel_bridge { · 9 unmodified lines | ||
| 21 | 19 | struct drm_bridge bridge; |
| 22 | 20 | struct drm_connector connector; |
| 23 | 21 | struct drm_panel *panel; |
| 24 | − struct device_link *link; | |
| 25 | 22 | u32 connector_type; |
| 26 | 23 | }; |
| 27 | 24 | |
| @@ -63,24 +60,13 @@ static int panel_bridge_attach(struct drm_bridge *bridge, · 35 unmodified lines | ||
| 63 | 60 | { |
| 64 | 61 | struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); |
| 65 | 62 | struct drm_connector *connector = &panel_bridge->connector; |
| 66 | − struct drm_panel *panel = panel_bridge->panel; | |
| 67 | − struct drm_device *drm_dev = bridge->dev; | |
| 68 | 63 | int ret; |
| 69 | 64 | |
| 70 | − panel_bridge->link = device_link_add(drm_dev->dev, panel->dev, | |
| 71 | − DL_FLAG_STATELESS); | |
| 72 | − if (!panel_bridge->link) { | |
| 73 | − DRM_ERROR("Failed to add device link between %s and %s\n", | |
| 74 | − dev_name(drm_dev->dev), dev_name(panel->dev)); | |
| 75 | − return -EINVAL; | |
| 76 | − } | |
| 77 | − | |
| 78 | 65 | if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) |
| 79 | 66 | return 0; |
| 80 | 67 | |
| 81 | 68 | if (!bridge->encoder) { |
| 82 | 69 | DRM_ERROR("Missing encoder\n"); |
| 83 | − device_link_del(panel_bridge->link); | |
| 84 | 70 | return -ENODEV; |
| 85 | 71 | } |
| 86 | 72 | |
| @@ -92,7 +78,6 @@ static int panel_bridge_attach(struct drm_bridge *bridge, · 5 unmodified lines | ||
| 92 | 78 | panel_bridge->connector_type); |
| 93 | 79 | if (ret) { |
| 94 | 80 | DRM_ERROR("Failed to initialize connector\n"); |
| 95 | − device_link_del(panel_bridge->link); | |
| 96 | 81 | return ret; |
| 97 | 82 | } |
| 98 | 83 | |
| @@ -115,8 +100,6 @@ static void panel_bridge_detach(struct drm_bridge *bridge) · 16 unmodified lines | ||
| 115 | 100 | struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge); |
| 116 | 101 | struct drm_connector *connector = &panel_bridge->connector; |
| 117 | 102 | |
| 118 | − device_link_del(panel_bridge->link); | |
| 119 | − | |
| 120 | 103 | /* |
| 121 | 104 | * Cleanup the connector if we know it was initialized. |
| 122 | 105 | * |
| @@ -5,7 +5,7 @@ termcolor==2.3.0 · 4 unmodified lines | ||
| 5 | 5 | certifi==2023.7.22 |
| 6 | 6 | charset-normalizer==3.2.0 |
| 7 | 7 | idna==3.4 |
| 8 | −pip==23.2.1 | |
| 8 | +pip==23.3 | |
| 9 | 9 | python-gitlab==3.15.0 |
| 10 | 10 | requests==2.31.0 |
| 11 | 11 | requests-toolbelt==1.0.0 |
| @@ -13,5 +13,5 @@ ruamel.yaml==0.17.32 · 1 unmodified line | ||
| 13 | 13 | ruamel.yaml.clib==0.2.7 |
| 14 | 14 | setuptools==68.0.0 |
| 15 | 15 | tenacity==8.2.3 |
| 16 | −urllib3==2.0.4 | |
| 17 | −wheel==0.41.1 | |
| 16 | +urllib3==2.0.7 | |
| 17 | +wheel==0.41.1 | |
| @@ -2012,7 +2012,7 @@ int drm_atomic_helper_commit(struct drm_device *dev, · 2011 unmodified lines | ||
| 2012 | 2012 | return ret; |
| 2013 | 2013 | |
| 2014 | 2014 | drm_atomic_helper_async_commit(dev, state); |
| 2015 | − drm_atomic_helper_cleanup_planes(dev, state); | |
| 2015 | + drm_atomic_helper_unprepare_planes(dev, state); | |
| 2016 | 2016 | |
| 2017 | 2017 | return 0; |
| 2018 | 2018 | } |
| @@ -2072,7 +2072,7 @@ int drm_atomic_helper_commit(struct drm_device *dev, · 53 unmodified lines | ||
| 2072 | 2072 | return 0; |
| 2073 | 2073 | |
| 2074 | 2074 | err: |
| 2075 | − drm_atomic_helper_cleanup_planes(dev, state); | |
| 2075 | + drm_atomic_helper_unprepare_planes(dev, state); | |
| 2076 | 2076 | return ret; |
| 2077 | 2077 | } |
| 2078 | 2078 | EXPORT_SYMBOL(drm_atomic_helper_commit); |
| @@ -2650,6 +2650,39 @@ fail_prepare_fb: · 571 unmodified lines | ||
| 2650 | 2650 | } |
| 2651 | 2651 | EXPORT_SYMBOL(drm_atomic_helper_prepare_planes); |
| 2652 | 2652 | |
| 2653 | +/** | |
| 2654 | + * drm_atomic_helper_unprepare_planes - release plane resources on aborts | |
| 2655 | + * @dev: DRM device | |
| 2656 | + * @state: atomic state object with old state structures | |
| 2657 | + * | |
| 2658 | + * This function cleans up plane state, specifically framebuffers, from the | |
| 2659 | + * atomic state. It undoes the effects of drm_atomic_helper_prepare_planes() | |
| 2660 | + * when aborting an atomic commit. For cleaning up after a successful commit | |
| 2661 | + * use drm_atomic_helper_cleanup_planes(). | |
| 2662 | + */ | |
| 2663 | +void drm_atomic_helper_unprepare_planes(struct drm_device *dev, | |
| 2664 | + struct drm_atomic_state *state) | |
| 2665 | +{ | |
| 2666 | + struct drm_plane *plane; | |
| 2667 | + struct drm_plane_state *new_plane_state; | |
| 2668 | + int i; | |
| 2669 | + | |
| 2670 | + for_each_new_plane_in_state(state, plane, new_plane_state, i) { | |
| 2671 | + const struct drm_plane_helper_funcs *funcs = plane->helper_private; | |
| 2672 | + | |
| 2673 | + if (funcs->end_fb_access) | |
| 2674 | + funcs->end_fb_access(plane, new_plane_state); | |
| 2675 | + } | |
| 2676 | + | |
| 2677 | + for_each_new_plane_in_state(state, plane, new_plane_state, i) { | |
| 2678 | + const struct drm_plane_helper_funcs *funcs = plane->helper_private; | |
| 2679 | + | |
| 2680 | + if (funcs->cleanup_fb) | |
| 2681 | + funcs->cleanup_fb(plane, new_plane_state); | |
| 2682 | + } | |
| 2683 | +} | |
| 2684 | +EXPORT_SYMBOL(drm_atomic_helper_unprepare_planes); | |
| 2685 | + | |
| 2653 | 2686 | static bool plane_crtc_active(const struct drm_plane_state *state) |
| 2654 | 2687 | { |
| 2655 | 2688 | return state->crtc && state->crtc->state->active; |
| @@ -2784,6 +2817,17 @@ void drm_atomic_helper_commit_planes(struct drm_device *dev, · 128 unmodified lines | ||
| 2784 | 2817 | |
| 2785 | 2818 | funcs->atomic_flush(crtc, old_state); |
| 2786 | 2819 | } |
| 2820 | + | |
| 2821 | + /* | |
| 2822 | + * Signal end of framebuffer access here before hw_done. After hw_done, | |
| 2823 | + * a later commit might have already released the plane state. | |
| 2824 | + */ | |
| 2825 | + for_each_old_plane_in_state(old_state, plane, old_plane_state, i) { | |
| 2826 | + const struct drm_plane_helper_funcs *funcs = plane->helper_private; | |
| 2827 | + | |
| 2828 | + if (funcs->end_fb_access) | |
| 2829 | + funcs->end_fb_access(plane, old_plane_state); | |
| 2830 | + } | |
| 2787 | 2831 | } |
| 2788 | 2832 | EXPORT_SYMBOL(drm_atomic_helper_commit_planes); |
| 2789 | 2833 | |
| @@ -2911,40 +2955,22 @@ EXPORT_SYMBOL(drm_atomic_helper_disable_planes_on_crtc); · 121 unmodified lines | ||
| 2911 | 2955 | * configuration. Hence the old configuration must be perserved in @old_state to |
| 2912 | 2956 | * be able to call this function. |
| 2913 | 2957 | * |
| 2914 | − * This function must also be called on the new state when the atomic update | |
| 2915 | − * fails at any point after calling drm_atomic_helper_prepare_planes(). | |
| 2958 | + * This function may not be called on the new state when the atomic update | |
| 2959 | + * fails at any point after calling drm_atomic_helper_prepare_planes(). Use | |
| 2960 | + * drm_atomic_helper_unprepare_planes() in this case. | |
| 2916 | 2961 | */ |
| 2917 | 2962 | void drm_atomic_helper_cleanup_planes(struct drm_device *dev, |
| 2918 | 2963 | struct drm_atomic_state *old_state) |
| 2919 | 2964 | { |
| 2920 | 2965 | struct drm_plane *plane; |
| 2921 | − struct drm_plane_state *old_plane_state, *new_plane_state; | |
| 2966 | + struct drm_plane_state *old_plane_state; | |
| 2922 | 2967 | int i; |
| 2923 | 2968 | |
| 2924 | − for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) { | |
| 2969 | + for_each_old_plane_in_state(old_state, plane, old_plane_state, i) { | |
| 2925 | 2970 | const struct drm_plane_helper_funcs *funcs = plane->helper_private; |
| 2926 | 2971 | |
| 2927 | − if (funcs->end_fb_access) | |
| 2928 | − funcs->end_fb_access(plane, new_plane_state); | |
| 2929 | − } | |
| 2930 | − | |
| 2931 | − for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) { | |
| 2932 | − const struct drm_plane_helper_funcs *funcs; | |
| 2933 | − struct drm_plane_state *plane_state; | |
| 2934 | − | |
| 2935 | − /* | |
| 2936 | − * This might be called before swapping when commit is aborted, | |
| 2937 | − * in which case we have to cleanup the new state. | |
| 2938 | − */ | |
| 2939 | − if (old_plane_state == plane->state) | |
| 2940 | − plane_state = new_plane_state; | |
| 2941 | − else | |
| 2942 | − plane_state = old_plane_state; | |
| 2943 | − | |
| 2944 | − funcs = plane->helper_private; | |
| 2945 | − | |
| 2946 | 2972 | if (funcs->cleanup_fb) |
| 2947 | − funcs->cleanup_fb(plane, plane_state); | |
| 2973 | + funcs->cleanup_fb(plane, old_plane_state); | |
| 2948 | 2974 | } |
| 2949 | 2975 | } |
| 2950 | 2976 | EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes); |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 OR MIT | |
| 1 | +// SPDX-License-Identifier: GPL-2.0-only OR MIT | |
| 2 | 2 | /* |
| 3 | 3 | * Copyright (c) 2022 Red Hat. |
| 4 | 4 | * |
| @@ -336,6 +336,12 @@ static const struct dmi_system_id orientation_data[] = { · 335 unmodified lines | ||
| 336 | 336 | DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Duet 3 10IGL5"), |
| 337 | 337 | }, |
| 338 | 338 | .driver_data = (void *)&lcd1200x1920_rightside_up, |
| 339 | + }, { /* Lenovo Legion Go 8APU1 */ | |
| 340 | + .matches = { | |
| 341 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
| 342 | + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Legion Go 8APU1"), | |
| 343 | + }, | |
| 344 | + .driver_data = (void *)&lcd1600x2560_leftside_up, | |
| 339 | 345 | }, { /* Lenovo Yoga Book X90F / X90L */ |
| 340 | 346 | .matches = { |
| 341 | 347 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), |
| @@ -278,7 +278,7 @@ void drm_gem_dmabuf_release(struct dma_buf *dma_buf) · 277 unmodified lines | ||
| 278 | 278 | } |
| 279 | 279 | EXPORT_SYMBOL(drm_gem_dmabuf_release); |
| 280 | 280 | |
| 281 | −/* | |
| 281 | +/** | |
| 282 | 282 | * drm_gem_prime_fd_to_handle - PRIME import function for GEM drivers |
| 283 | 283 | * @dev: drm_device to import into |
| 284 | 284 | * @file_priv: drm file-private structure |
| @@ -292,9 +292,9 @@ EXPORT_SYMBOL(drm_gem_dmabuf_release); · 7 unmodified lines | ||
| 292 | 292 | * |
| 293 | 293 | * Returns 0 on success or a negative error code on failure. |
| 294 | 294 | */ |
| 295 | −static int drm_gem_prime_fd_to_handle(struct drm_device *dev, | |
| 296 | − struct drm_file *file_priv, int prime_fd, | |
| 297 | − uint32_t *handle) | |
| 295 | +int drm_gem_prime_fd_to_handle(struct drm_device *dev, | |
| 296 | + struct drm_file *file_priv, int prime_fd, | |
| 297 | + uint32_t *handle) | |
| 298 | 298 | { |
| 299 | 299 | struct dma_buf *dma_buf; |
| 300 | 300 | struct drm_gem_object *obj; |
| @@ -360,6 +360,7 @@ out_put: · 59 unmodified lines | ||
| 360 | 360 | dma_buf_put(dma_buf); |
| 361 | 361 | return ret; |
| 362 | 362 | } |
| 363 | +EXPORT_SYMBOL(drm_gem_prime_fd_to_handle); | |
| 363 | 364 | |
| 364 | 365 | int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, |
| 365 | 366 | struct drm_file *file_priv) |
| @@ -408,7 +409,7 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, · 42 unmodified lines | ||
| 408 | 409 | return dmabuf; |
| 409 | 410 | } |
| 410 | 411 | |
| 411 | −/* | |
| 412 | +/** | |
| 412 | 413 | * drm_gem_prime_handle_to_fd - PRIME export function for GEM drivers |
| 413 | 414 | * @dev: dev to export the buffer from |
| 414 | 415 | * @file_priv: drm file-private structure |
| @@ -421,10 +422,10 @@ static struct dma_buf *export_and_register_object(struct drm_device *dev, · 6 unmodified lines | ||
| 421 | 422 | * The actual exporting from GEM object to a dma-buf is done through the |
| 422 | 423 | * &drm_gem_object_funcs.export callback. |
| 423 | 424 | */ |
| 424 | −static int drm_gem_prime_handle_to_fd(struct drm_device *dev, | |
| 425 | − struct drm_file *file_priv, uint32_t handle, | |
| 426 | − uint32_t flags, | |
| 427 | − int *prime_fd) | |
| 425 | +int drm_gem_prime_handle_to_fd(struct drm_device *dev, | |
| 426 | + struct drm_file *file_priv, uint32_t handle, | |
| 427 | + uint32_t flags, | |
| 428 | + int *prime_fd) | |
| 428 | 429 | { |
| 429 | 430 | struct drm_gem_object *obj; |
| 430 | 431 | int ret = 0; |
| @@ -506,6 +507,7 @@ out_unlock: · 75 unmodified lines | ||
| 506 | 507 | |
| 507 | 508 | return ret; |
| 508 | 509 | } |
| 510 | +EXPORT_SYMBOL(drm_gem_prime_handle_to_fd); | |
| 509 | 511 | |
| 510 | 512 | int drm_prime_handle_to_fd_ioctl(struct drm_device *dev, void *data, |
| 511 | 513 | struct drm_file *file_priv) |
| @@ -864,9 +866,9 @@ EXPORT_SYMBOL(drm_prime_get_contiguous_size); · 352 unmodified lines | ||
| 864 | 866 | * @obj: GEM object to export |
| 865 | 867 | * @flags: flags like DRM_CLOEXEC and DRM_RDWR |
| 866 | 868 | * |
| 867 | − * This is the implementation of the &drm_gem_object_funcs.export functions | |
| 868 | − * for GEM drivers using the PRIME helpers. It is used as the default for | |
| 869 | − * drivers that do not set their own. | |
| 869 | + * This is the implementation of the &drm_gem_object_funcs.export functions for GEM drivers | |
| 870 | + * using the PRIME helpers. It is used as the default in | |
| 871 | + * drm_gem_prime_handle_to_fd(). | |
| 870 | 872 | */ |
| 871 | 873 | struct dma_buf *drm_gem_prime_export(struct drm_gem_object *obj, |
| 872 | 874 | int flags) |
| @@ -962,9 +964,10 @@ EXPORT_SYMBOL(drm_gem_prime_import_dev); · 89 unmodified lines | ||
| 962 | 964 | * @dev: drm_device to import into |
| 963 | 965 | * @dma_buf: dma-buf object to import |
| 964 | 966 | * |
| 965 | − * This is the implementation of the gem_prime_import functions for GEM | |
| 966 | − * drivers using the PRIME helpers. It is the default for drivers that do | |
| 967 | − * not set their own &drm_driver.gem_prime_import. | |
| 967 | + * This is the implementation of the gem_prime_import functions for GEM drivers | |
| 968 | + * using the PRIME helpers. Drivers can use this as their | |
| 969 | + * &drm_driver.gem_prime_import implementation. It is used as the default | |
| 970 | + * implementation in drm_gem_prime_fd_to_handle(). | |
| 968 | 971 | * |
| 969 | 972 | * Drivers must arrange to call drm_prime_gem_destroy() from their |
| 970 | 973 | * &drm_gem_object_funcs.free hook when using this function. |
| @@ -107,18 +107,16 @@ int exynos_drm_register_dma(struct drm_device *drm, struct device *dev, · 106 unmodified lines | ||
| 107 | 107 | return 0; |
| 108 | 108 | |
| 109 | 109 | if (!priv->mapping) { |
| 110 | − void *mapping; | |
| 110 | + void *mapping = NULL; | |
| 111 | 111 | |
| 112 | 112 | if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) |
| 113 | 113 | mapping = arm_iommu_create_mapping(&platform_bus_type, |
| 114 | 114 | EXYNOS_DEV_ADDR_START, EXYNOS_DEV_ADDR_SIZE); |
| 115 | 115 | else if (IS_ENABLED(CONFIG_IOMMU_DMA)) |
| 116 | 116 | mapping = iommu_get_domain_for_dev(priv->dma_dev); |
| 117 | − else | |
| 118 | − mapping = ERR_PTR(-ENODEV); | |
| 119 | 117 | |
| 120 | − if (IS_ERR(mapping)) | |
| 121 | − return PTR_ERR(mapping); | |
| 118 | + if (!mapping) | |
| 119 | + return -ENODEV; | |
| 122 | 120 | priv->mapping = mapping; |
| 123 | 121 | } |
| 124 | 122 | |
| @@ -1861,6 +1861,8 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) · 1860 unmodified lines | ||
| 1861 | 1861 | return ret; |
| 1862 | 1862 | |
| 1863 | 1863 | crtc = exynos_drm_crtc_get_by_type(drm_dev, EXYNOS_DISPLAY_TYPE_HDMI); |
| 1864 | + if (IS_ERR(crtc)) | |
| 1865 | + return PTR_ERR(crtc); | |
| 1864 | 1866 | crtc->pipe_clk = &hdata->phy_clk; |
| 1865 | 1867 | |
| 1866 | 1868 | ret = hdmi_create_connector(encoder); |
| @@ -1440,6 +1440,13 @@ static void gen11_dsi_post_disable(struct intel_atomic_state *state, · 1439 unmodified lines | ||
| 1440 | 1440 | static enum drm_mode_status gen11_dsi_mode_valid(struct drm_connector *connector, |
| 1441 | 1441 | struct drm_display_mode *mode) |
| 1442 | 1442 | { |
| 1443 | + struct drm_i915_private *i915 = to_i915(connector->dev); | |
| 1444 | + enum drm_mode_status status; | |
| 1445 | + | |
| 1446 | + status = intel_cpu_transcoder_mode_valid(i915, mode); | |
| 1447 | + if (status != MODE_OK) | |
| 1448 | + return status; | |
| 1449 | + | |
| 1443 | 1450 | /* FIXME: DSC? */ |
| 1444 | 1451 | return intel_dsi_mode_valid(connector, mode); |
| 1445 | 1452 | } |
| @@ -348,8 +348,13 @@ intel_crt_mode_valid(struct drm_connector *connector, · 347 unmodified lines | ||
| 348 | 348 | struct drm_device *dev = connector->dev; |
| 349 | 349 | struct drm_i915_private *dev_priv = to_i915(dev); |
| 350 | 350 | int max_dotclk = dev_priv->max_dotclk_freq; |
| 351 | + enum drm_mode_status status; | |
| 351 | 352 | int max_clock; |
| 352 | 353 | |
| 354 | + status = intel_cpu_transcoder_mode_valid(dev_priv, mode); | |
| 355 | + if (status != MODE_OK) | |
| 356 | + return status; | |
| 357 | + | |
| 353 | 358 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
| 354 | 359 | return MODE_NO_DBLESCAN; |
| 355 | 360 | |
| @@ -906,12 +906,18 @@ static bool needs_async_flip_vtd_wa(const struct intel_crtc_state *crtc_state) · 905 unmodified lines | ||
| 906 | 906 | static bool planes_enabling(const struct intel_crtc_state *old_crtc_state, |
| 907 | 907 | const struct intel_crtc_state *new_crtc_state) |
| 908 | 908 | { |
| 909 | + if (!new_crtc_state->hw.active) | |
| 910 | + return false; | |
| 911 | + | |
| 909 | 912 | return is_enabling(active_planes, old_crtc_state, new_crtc_state); |
| 910 | 913 | } |
| 911 | 914 | |
| 912 | 915 | static bool planes_disabling(const struct intel_crtc_state *old_crtc_state, |
| 913 | 916 | const struct intel_crtc_state *new_crtc_state) |
| 914 | 917 | { |
| 918 | + if (!old_crtc_state->hw.active) | |
| 919 | + return false; | |
| 920 | + | |
| 915 | 921 | return is_disabling(active_planes, old_crtc_state, new_crtc_state); |
| 916 | 922 | } |
| 917 | 923 | |
| @@ -928,6 +934,9 @@ static bool vrr_params_changed(const struct intel_crtc_state *old_crtc_state, · 10 unmodified lines | ||
| 928 | 934 | static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state, |
| 929 | 935 | const struct intel_crtc_state *new_crtc_state) |
| 930 | 936 | { |
| 937 | + if (!new_crtc_state->hw.active) | |
| 938 | + return false; | |
| 939 | + | |
| 931 | 940 | return is_enabling(vrr.enable, old_crtc_state, new_crtc_state) || |
| 932 | 941 | (new_crtc_state->vrr.enable && |
| 933 | 942 | (new_crtc_state->update_m_n || new_crtc_state->update_lrr || |
| @@ -937,6 +946,9 @@ static bool vrr_enabling(const struct intel_crtc_state *old_crtc_state, · 3 unmodified lines | ||
| 937 | 946 | static bool vrr_disabling(const struct intel_crtc_state *old_crtc_state, |
| 938 | 947 | const struct intel_crtc_state *new_crtc_state) |
| 939 | 948 | { |
| 949 | + if (!old_crtc_state->hw.active) | |
| 950 | + return false; | |
| 951 | + | |
| 940 | 952 | return is_disabling(vrr.enable, old_crtc_state, new_crtc_state) || |
| 941 | 953 | (old_crtc_state->vrr.enable && |
| 942 | 954 | (new_crtc_state->update_m_n || new_crtc_state->update_lrr || |
| @@ -6853,10 +6865,11 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state) · 5910 unmodified lines | ||
| 6853 | 6865 | if (!intel_crtc_needs_modeset(new_crtc_state)) |
| 6854 | 6866 | continue; |
| 6855 | 6867 | |
| 6868 | + intel_pre_plane_update(state, crtc); | |
| 6869 | + | |
| 6856 | 6870 | if (!old_crtc_state->hw.active) |
| 6857 | 6871 | continue; |
| 6858 | 6872 | |
| 6859 | − intel_pre_plane_update(state, crtc); | |
| 6860 | 6873 | intel_crtc_disable_planes(state, crtc); |
| 6861 | 6874 | } |
| 6862 | 6875 | |
| @@ -7475,7 +7488,7 @@ int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state *_state, · 612 unmodified lines | ||
| 7475 | 7488 | for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) |
| 7476 | 7489 | intel_color_cleanup_commit(new_crtc_state); |
| 7477 | 7490 | |
| 7478 | − drm_atomic_helper_cleanup_planes(dev, &state->base); | |
| 7491 | + drm_atomic_helper_unprepare_planes(dev, &state->base); | |
| 7479 | 7492 | intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref); |
| 7480 | 7493 | return ret; |
| 7481 | 7494 | } |
| @@ -7856,6 +7869,16 @@ enum drm_mode_status intel_mode_valid(struct drm_device *dev, · 374 unmodified lines | ||
| 7856 | 7869 | mode->vtotal > vtotal_max) |
| 7857 | 7870 | return MODE_V_ILLEGAL; |
| 7858 | 7871 | |
| 7872 | + return MODE_OK; | |
| 7873 | +} | |
| 7874 | + | |
| 7875 | +enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *dev_priv, | |
| 7876 | + const struct drm_display_mode *mode) | |
| 7877 | +{ | |
| 7878 | + /* | |
| 7879 | + * Additional transcoder timing limits, | |
| 7880 | + * excluding BXT/GLK DSI transcoders. | |
| 7881 | + */ | |
| 7859 | 7882 | if (DISPLAY_VER(dev_priv) >= 5) { |
| 7860 | 7883 | if (mode->hdisplay < 64 || |
| 7861 | 7884 | mode->htotal - mode->hdisplay < 32) |
| @@ -403,6 +403,9 @@ enum drm_mode_status · 402 unmodified lines | ||
| 403 | 403 | intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, |
| 404 | 404 | const struct drm_display_mode *mode, |
| 405 | 405 | bool bigjoiner); |
| 406 | +enum drm_mode_status | |
| 407 | +intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915, | |
| 408 | + const struct drm_display_mode *mode); | |
| 406 | 409 | enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port); |
| 407 | 410 | bool is_trans_port_sync_mode(const struct intel_crtc_state *state); |
| 408 | 411 | bool is_trans_port_sync_master(const struct intel_crtc_state *state); |
| @@ -1172,6 +1172,10 @@ intel_dp_mode_valid(struct drm_connector *_connector, · 1171 unmodified lines | ||
| 1172 | 1172 | enum drm_mode_status status; |
| 1173 | 1173 | bool dsc = false, bigjoiner = false; |
| 1174 | 1174 | |
| 1175 | + status = intel_cpu_transcoder_mode_valid(dev_priv, mode); | |
| 1176 | + if (status != MODE_OK) | |
| 1177 | + return status; | |
| 1178 | + | |
| 1175 | 1179 | if (mode->flags & DRM_MODE_FLAG_DBLCLK) |
| 1176 | 1180 | return MODE_H_ILLEGAL; |
| 1177 | 1181 | |
| @@ -6037,8 +6041,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, · 4859 unmodified lines | ||
| 6037 | 6041 | * (eg. Acer Chromebook C710), so we'll check it only if multiple |
| 6038 | 6042 | * ports are attempting to use the same AUX CH, according to VBT. |
| 6039 | 6043 | */ |
| 6040 | − if (intel_bios_dp_has_shared_aux_ch(encoder->devdata) && | |
| 6041 | − !intel_digital_port_connected(encoder)) { | |
| 6044 | + if (intel_bios_dp_has_shared_aux_ch(encoder->devdata)) { | |
| 6042 | 6045 | /* |
| 6043 | 6046 | * If this fails, presume the DPCD answer came |
| 6044 | 6047 | * from some other port using the same AUX CH. |
| @@ -6046,10 +6049,27 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, · 1 unmodified line | ||
| 6046 | 6049 | * FIXME maybe cleaner to check this before the |
| 6047 | 6050 | * DPCD read? Would need sort out the VDD handling... |
| 6048 | 6051 | */ |
| 6049 | − drm_info(&dev_priv->drm, | |
| 6050 | − "[ENCODER:%d:%s] HPD is down, disabling eDP\n", | |
| 6051 | − encoder->base.base.id, encoder->base.name); | |
| 6052 | − goto out_vdd_off; | |
| 6052 | + if (!intel_digital_port_connected(encoder)) { | |
| 6053 | + drm_info(&dev_priv->drm, | |
| 6054 | + "[ENCODER:%d:%s] HPD is down, disabling eDP\n", | |
| 6055 | + encoder->base.base.id, encoder->base.name); | |
| 6056 | + goto out_vdd_off; | |
| 6057 | + } | |
| 6058 | + | |
| 6059 | + /* | |
| 6060 | + * Unfortunately even the HPD based detection fails on | |
| 6061 | + * eg. Asus B360M-A (CFL+CNP), so as a last resort fall | |
| 6062 | + * back to checking for a VGA branch device. Only do this | |
| 6063 | + * on known affected platforms to minimize false positives. | |
| 6064 | + */ | |
| 6065 | + if (DISPLAY_VER(dev_priv) == 9 && drm_dp_is_branch(intel_dp->dpcd) && | |
| 6066 | + (intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_TYPE_MASK) == | |
| 6067 | + DP_DWN_STRM_PORT_TYPE_ANALOG) { | |
| 6068 | + drm_info(&dev_priv->drm, | |
| 6069 | + "[ENCODER:%d:%s] VGA converter detected, disabling eDP\n", | |
| 6070 | + encoder->base.base.id, encoder->base.name); | |
| 6071 | + goto out_vdd_off; | |
| 6072 | + } | |
| 6053 | 6073 | } |
| 6054 | 6074 | |
| 6055 | 6075 | mutex_lock(&dev_priv->drm.mode_config.mutex); |
| @@ -959,6 +959,10 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, · 958 unmodified lines | ||
| 959 | 959 | return 0; |
| 960 | 960 | } |
| 961 | 961 | |
| 962 | + *status = intel_cpu_transcoder_mode_valid(dev_priv, mode); | |
| 963 | + if (*status != MODE_OK) | |
| 964 | + return 0; | |
| 965 | + | |
| 962 | 966 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { |
| 963 | 967 | *status = MODE_NO_DBLESCAN; |
| 964 | 968 | return 0; |
| @@ -993,6 +997,10 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, · 28 unmodified lines | ||
| 993 | 997 | if (intel_dp_need_bigjoiner(intel_dp, mode->hdisplay, target_clock)) { |
| 994 | 998 | bigjoiner = true; |
| 995 | 999 | max_dotclk *= 2; |
| 1000 | + | |
| 1001 | + /* TODO: add support for bigjoiner */ | |
| 1002 | + *status = MODE_CLOCK_HIGH; | |
| 1003 | + return 0; | |
| 996 | 1004 | } |
| 997 | 1005 | |
| 998 | 1006 | if (DISPLAY_VER(dev_priv) >= 10 && |
| @@ -1027,11 +1035,15 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, · 28 unmodified lines | ||
| 1027 | 1035 | * Big joiner configuration needs DSC for TGL which is not true for |
| 1028 | 1036 | * XE_LPD where uncompressed joiner is supported. |
| 1029 | 1037 | */ |
| 1030 | − if (DISPLAY_VER(dev_priv) < 13 && bigjoiner && !dsc) | |
| 1031 | − return MODE_CLOCK_HIGH; | |
| 1038 | + if (DISPLAY_VER(dev_priv) < 13 && bigjoiner && !dsc) { | |
| 1039 | + *status = MODE_CLOCK_HIGH; | |
| 1040 | + return 0; | |
| 1041 | + } | |
| 1032 | 1042 | |
| 1033 | − if (mode_rate > max_rate && !dsc) | |
| 1034 | − return MODE_CLOCK_HIGH; | |
| 1043 | + if (mode_rate > max_rate && !dsc) { | |
| 1044 | + *status = MODE_CLOCK_HIGH; | |
| 1045 | + return 0; | |
| 1046 | + } | |
| 1035 | 1047 | |
| 1036 | 1048 | *status = intel_mode_valid_max_plane_size(dev_priv, mode, false); |
| 1037 | 1049 | return 0; |
| @@ -1161,6 +1173,14 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo · 123 unmodified lines | ||
| 1161 | 1173 | intel_connector->port = port; |
| 1162 | 1174 | drm_dp_mst_get_port_malloc(port); |
| 1163 | 1175 | |
| 1176 | + /* | |
| 1177 | + * TODO: set the AUX for the actual MST port decompressing the stream. | |
| 1178 | + * At the moment the driver only supports enabling this globally in the | |
| 1179 | + * first downstream MST branch, via intel_dp's (root port) AUX. | |
| 1180 | + */ | |
| 1181 | + intel_connector->dp.dsc_decompression_aux = &intel_dp->aux; | |
| 1182 | + intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector); | |
| 1183 | + | |
| 1164 | 1184 | connector = &intel_connector->base; |
| 1165 | 1185 | ret = drm_connector_init(dev, connector, &intel_dp_mst_connector_funcs, |
| 1166 | 1186 | DRM_MODE_CONNECTOR_DisplayPort); |
| @@ -1172,14 +1192,6 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo · 5 unmodified lines | ||
| 1172 | 1192 | |
| 1173 | 1193 | drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs); |
| 1174 | 1194 | |
| 1175 | − /* | |
| 1176 | − * TODO: set the AUX for the actual MST port decompressing the stream. | |
| 1177 | − * At the moment the driver only supports enabling this globally in the | |
| 1178 | − * first downstream MST branch, via intel_dp's (root port) AUX. | |
| 1179 | − */ | |
| 1180 | − intel_connector->dp.dsc_decompression_aux = &intel_dp->aux; | |
| 1181 | − intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector); | |
| 1182 | − | |
| 1183 | 1195 | for_each_pipe(dev_priv, pipe) { |
| 1184 | 1196 | struct drm_encoder *enc = |
| 1185 | 1197 | &intel_dp->mst_encoders[pipe]->base.base; |
| @@ -340,7 +340,7 @@ static int intel_dsb_dewake_scanline(const struct intel_crtc_state *crtc_state) · 339 unmodified lines | ||
| 340 | 340 | } |
| 341 | 341 | |
| 342 | 342 | static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl, |
| 343 | − unsigned int dewake_scanline) | |
| 343 | + int dewake_scanline) | |
| 344 | 344 | { |
| 345 | 345 | struct intel_crtc *crtc = dsb->crtc; |
| 346 | 346 | struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); |
| @@ -217,11 +217,17 @@ intel_dvo_mode_valid(struct drm_connector *_connector, · 216 unmodified lines | ||
| 217 | 217 | struct drm_display_mode *mode) |
| 218 | 218 | { |
| 219 | 219 | struct intel_connector *connector = to_intel_connector(_connector); |
| 220 | + struct drm_i915_private *i915 = to_i915(connector->base.dev); | |
| 220 | 221 | struct intel_dvo *intel_dvo = intel_attached_dvo(connector); |
| 221 | 222 | const struct drm_display_mode *fixed_mode = |
| 222 | 223 | intel_panel_fixed_mode(connector, mode); |
| 223 | 224 | int max_dotclk = to_i915(connector->base.dev)->max_dotclk_freq; |
| 224 | 225 | int target_clock = mode->clock; |
| 226 | + enum drm_mode_status status; | |
| 227 | + | |
| 228 | + status = intel_cpu_transcoder_mode_valid(i915, mode); | |
| 229 | + if (status != MODE_OK) | |
| 230 | + return status; | |
| 225 | 231 | |
| 226 | 232 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
| 227 | 233 | return MODE_NO_DBLESCAN; |
| @@ -1983,6 +1983,10 @@ intel_hdmi_mode_valid(struct drm_connector *connector, · 1982 unmodified lines | ||
| 1983 | 1983 | bool ycbcr_420_only; |
| 1984 | 1984 | enum intel_output_format sink_format; |
| 1985 | 1985 | |
| 1986 | + status = intel_cpu_transcoder_mode_valid(dev_priv, mode); | |
| 1987 | + if (status != MODE_OK) | |
| 1988 | + return status; | |
| 1989 | + | |
| 1986 | 1990 | if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING) |
| 1987 | 1991 | clock *= 2; |
| 1988 | 1992 | |
| @@ -389,11 +389,16 @@ intel_lvds_mode_valid(struct drm_connector *_connector, · 388 unmodified lines | ||
| 389 | 389 | struct drm_display_mode *mode) |
| 390 | 390 | { |
| 391 | 391 | struct intel_connector *connector = to_intel_connector(_connector); |
| 392 | + struct drm_i915_private *i915 = to_i915(connector->base.dev); | |
| 392 | 393 | const struct drm_display_mode *fixed_mode = |
| 393 | 394 | intel_panel_fixed_mode(connector, mode); |
| 394 | 395 | int max_pixclk = to_i915(connector->base.dev)->max_dotclk_freq; |
| 395 | 396 | enum drm_mode_status status; |
| 396 | 397 | |
| 398 | + status = intel_cpu_transcoder_mode_valid(i915, mode); | |
| 399 | + if (status != MODE_OK) | |
| 400 | + return status; | |
| 401 | + | |
| 397 | 402 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
| 398 | 403 | return MODE_NO_DBLESCAN; |
| 399 | 404 | |
| @@ -1921,13 +1921,19 @@ static enum drm_mode_status · 1920 unmodified lines | ||
| 1921 | 1921 | intel_sdvo_mode_valid(struct drm_connector *connector, |
| 1922 | 1922 | struct drm_display_mode *mode) |
| 1923 | 1923 | { |
| 1924 | + struct drm_i915_private *i915 = to_i915(connector->dev); | |
| 1924 | 1925 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector)); |
| 1925 | 1926 | struct intel_sdvo_connector *intel_sdvo_connector = |
| 1926 | 1927 | to_intel_sdvo_connector(connector); |
| 1927 | − int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; | |
| 1928 | 1928 | bool has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo_connector, connector->state); |
| 1929 | + int max_dotclk = i915->max_dotclk_freq; | |
| 1930 | + enum drm_mode_status status; | |
| 1929 | 1931 | int clock = mode->clock; |
| 1930 | 1932 | |
| 1933 | + status = intel_cpu_transcoder_mode_valid(i915, mode); | |
| 1934 | + if (status != MODE_OK) | |
| 1935 | + return status; | |
| 1936 | + | |
| 1931 | 1937 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
| 1932 | 1938 | return MODE_NO_DBLESCAN; |
| 1933 | 1939 | |
| @@ -958,8 +958,14 @@ static enum drm_mode_status · 957 unmodified lines | ||
| 958 | 958 | intel_tv_mode_valid(struct drm_connector *connector, |
| 959 | 959 | struct drm_display_mode *mode) |
| 960 | 960 | { |
| 961 | + struct drm_i915_private *i915 = to_i915(connector->dev); | |
| 961 | 962 | const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state); |
| 962 | − int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; | |
| 963 | + int max_dotclk = i915->max_dotclk_freq; | |
| 964 | + enum drm_mode_status status; | |
| 965 | + | |
| 966 | + status = intel_cpu_transcoder_mode_valid(i915, mode); | |
| 967 | + if (status != MODE_OK) | |
| 968 | + return status; | |
| 963 | 969 | |
| 964 | 970 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
| 965 | 971 | return MODE_NO_DBLESCAN; |
| @@ -1541,9 +1541,25 @@ static const struct drm_encoder_funcs intel_dsi_funcs = { · 1540 unmodified lines | ||
| 1541 | 1541 | .destroy = intel_dsi_encoder_destroy, |
| 1542 | 1542 | }; |
| 1543 | 1543 | |
| 1544 | +static enum drm_mode_status vlv_dsi_mode_valid(struct drm_connector *connector, | |
| 1545 | + struct drm_display_mode *mode) | |
| 1546 | +{ | |
| 1547 | + struct drm_i915_private *i915 = to_i915(connector->dev); | |
| 1548 | + | |
| 1549 | + if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { | |
| 1550 | + enum drm_mode_status status; | |
| 1551 | + | |
| 1552 | + status = intel_cpu_transcoder_mode_valid(i915, mode); | |
| 1553 | + if (status != MODE_OK) | |
| 1554 | + return status; | |
| 1555 | + } | |
| 1556 | + | |
| 1557 | + return intel_dsi_mode_valid(connector, mode); | |
| 1558 | +} | |
| 1559 | + | |
| 1544 | 1560 | static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs = { |
| 1545 | 1561 | .get_modes = intel_dsi_get_modes, |
| 1546 | − .mode_valid = intel_dsi_mode_valid, | |
| 1562 | + .mode_valid = vlv_dsi_mode_valid, | |
| 1547 | 1563 | .atomic_check = intel_digital_connector_atomic_check, |
| 1548 | 1564 | }; |
| 1549 | 1565 | |
| @@ -41,12 +41,15 @@ void intel_engine_add_user(struct intel_engine_cs *engine) · 40 unmodified lines | ||
| 41 | 41 | llist_add(&engine->uabi_llist, &engine->i915->uabi_engines_llist); |
| 42 | 42 | } |
| 43 | 43 | |
| 44 | −static const u8 uabi_classes[] = { | |
| 44 | +#define I915_NO_UABI_CLASS ((u16)(-1)) | |
| 45 | + | |
| 46 | +static const u16 uabi_classes[] = { | |
| 45 | 47 | [RENDER_CLASS] = I915_ENGINE_CLASS_RENDER, |
| 46 | 48 | [COPY_ENGINE_CLASS] = I915_ENGINE_CLASS_COPY, |
| 47 | 49 | [VIDEO_DECODE_CLASS] = I915_ENGINE_CLASS_VIDEO, |
| 48 | 50 | [VIDEO_ENHANCEMENT_CLASS] = I915_ENGINE_CLASS_VIDEO_ENHANCE, |
| 49 | 51 | [COMPUTE_CLASS] = I915_ENGINE_CLASS_COMPUTE, |
| 52 | + [OTHER_CLASS] = I915_NO_UABI_CLASS, /* Not exposed to users, no uabi class. */ | |
| 50 | 53 | }; |
| 51 | 54 | |
| 52 | 55 | static int engine_cmp(void *priv, const struct list_head *A, |
| @@ -200,6 +203,7 @@ static void engine_rename(struct intel_engine_cs *engine, const char *name, u16 · 147 unmodified lines | ||
| 200 | 203 | |
| 201 | 204 | void intel_engines_driver_register(struct drm_i915_private *i915) |
| 202 | 205 | { |
| 206 | + u16 name_instance, other_instance = 0; | |
| 203 | 207 | struct legacy_ring ring = {}; |
| 204 | 208 | struct list_head *it, *next; |
| 205 | 209 | struct rb_node **p, *prev; |
| @@ -216,27 +220,28 @@ void intel_engines_driver_register(struct drm_i915_private *i915) · 10 unmodified lines | ||
| 216 | 220 | if (intel_gt_has_unrecoverable_error(engine->gt)) |
| 217 | 221 | continue; /* ignore incomplete engines */ |
| 218 | 222 | |
| 219 | − /* | |
| 220 | − * We don't want to expose the GSC engine to the users, but we | |
| 221 | − * still rename it so it is easier to identify in the debug logs | |
| 222 | − */ | |
| 223 | − if (engine->id == GSC0) { | |
| 224 | − engine_rename(engine, "gsc", 0); | |
| 225 | − continue; | |
| 226 | − } | |
| 227 | − | |
| 228 | 223 | GEM_BUG_ON(engine->class >= ARRAY_SIZE(uabi_classes)); |
| 229 | 224 | engine->uabi_class = uabi_classes[engine->class]; |
| 225 | + if (engine->uabi_class == I915_NO_UABI_CLASS) { | |
| 226 | + name_instance = other_instance++; | |
| 227 | + } else { | |
| 228 | + GEM_BUG_ON(engine->uabi_class >= | |
| 229 | + ARRAY_SIZE(i915->engine_uabi_class_count)); | |
| 230 | + name_instance = | |
| 231 | + i915->engine_uabi_class_count[engine->uabi_class]++; | |
| 232 | + } | |
| 233 | + engine->uabi_instance = name_instance; | |
| 230 | 234 | |
| 231 | − GEM_BUG_ON(engine->uabi_class >= | |
| 232 | − ARRAY_SIZE(i915->engine_uabi_class_count)); | |
| 233 | − engine->uabi_instance = | |
| 234 | − i915->engine_uabi_class_count[engine->uabi_class]++; | |
| 235 | − | |
| 236 | − /* Replace the internal name with the final user facing name */ | |
| 235 | + /* | |
| 236 | + * Replace the internal name with the final user and log facing | |
| 237 | + * name. | |
| 238 | + */ | |
| 237 | 239 | engine_rename(engine, |
| 238 | 240 | intel_engine_class_repr(engine->class), |
| 239 | − engine->uabi_instance); | |
| 241 | + name_instance); | |
| 242 | + | |
| 243 | + if (engine->uabi_class == I915_NO_UABI_CLASS) | |
| 244 | + continue; | |
| 240 | 245 | |
| 241 | 246 | rb_link_node(&engine->uabi_node, prev, p); |
| 242 | 247 | rb_insert_color(&engine->uabi_node, &i915->uabi_engines); |
| @@ -982,8 +982,6 @@ int intel_gt_probe_all(struct drm_i915_private *i915) · 981 unmodified lines | ||
| 982 | 982 | |
| 983 | 983 | err: |
| 984 | 984 | i915_probe_error(i915, "Failed to initialize %s! (%d)\n", gtdef->name, ret); |
| 985 | − intel_gt_release_all(i915); | |
| 986 | − | |
| 987 | 985 | return ret; |
| 988 | 986 | } |
| 989 | 987 | |
| @@ -1002,15 +1000,6 @@ int intel_gt_tiles_init(struct drm_i915_private *i915) · 12 unmodified lines | ||
| 1002 | 1000 | return 0; |
| 1003 | 1001 | } |
| 1004 | 1002 | |
| 1005 | −void intel_gt_release_all(struct drm_i915_private *i915) | |
| 1006 | −{ | |
| 1007 | − struct intel_gt *gt; | |
| 1008 | − unsigned int id; | |
| 1009 | − | |
| 1010 | − for_each_gt(gt, i915, id) | |
| 1011 | − i915->gt[id] = NULL; | |
| 1012 | −} | |
| 1013 | − | |
| 1014 | 1003 | void intel_gt_info_print(const struct intel_gt_info *info, |
| 1015 | 1004 | struct drm_printer *p) |
| 1016 | 1005 | { |
| @@ -782,7 +782,7 @@ int i915_driver_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 781 unmodified lines | ||
| 782 | 782 | |
| 783 | 783 | ret = i915_driver_mmio_probe(i915); |
| 784 | 784 | if (ret < 0) |
| 785 | − goto out_tiles_cleanup; | |
| 785 | + goto out_runtime_pm_put; | |
| 786 | 786 | |
| 787 | 787 | ret = i915_driver_hw_probe(i915); |
| 788 | 788 | if (ret < 0) |
| @@ -842,8 +842,6 @@ out_cleanup_hw: · 53 unmodified lines | ||
| 842 | 842 | i915_ggtt_driver_late_release(i915); |
| 843 | 843 | out_cleanup_mmio: |
| 844 | 844 | i915_driver_mmio_release(i915); |
| 845 | −out_tiles_cleanup: | |
| 846 | − intel_gt_release_all(i915); | |
| 847 | 845 | out_runtime_pm_put: |
| 848 | 846 | enable_rpm_wakeref_asserts(&i915->runtime_pm); |
| 849 | 847 | i915_driver_late_release(i915); |
| @@ -406,6 +406,7 @@ static const struct dpu_perf_cfg sc8280xp_perf_data = { · 405 unmodified lines | ||
| 406 | 406 | .min_llcc_ib = 0, |
| 407 | 407 | .min_dram_ib = 800000, |
| 408 | 408 | .danger_lut_tbl = {0xf, 0xffff, 0x0}, |
| 409 | + .safe_lut_tbl = {0xfe00, 0xfe00, 0xffff}, | |
| 409 | 410 | .qos_lut_tbl = { |
| 410 | 411 | {.nentry = ARRAY_SIZE(sc8180x_qos_linear), |
| 411 | 412 | .entries = sc8180x_qos_linear |
| @@ -844,8 +844,7 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev) · 843 unmodified lines | ||
| 844 | 844 | |
| 845 | 845 | return 0; |
| 846 | 846 | fail: |
| 847 | − if (mdp5_kms) | |
| 848 | − mdp5_destroy(mdp5_kms); | |
| 847 | + mdp5_destroy(mdp5_kms); | |
| 849 | 848 | return ret; |
| 850 | 849 | } |
| 851 | 850 | |
| @@ -365,9 +365,11 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, · 364 unmodified lines | ||
| 365 | 365 | /* reset video pattern flag on disconnect */ |
| 366 | 366 | if (!hpd) { |
| 367 | 367 | dp->panel->video_test = false; |
| 368 | − drm_dp_set_subconnector_property(dp->dp_display.connector, | |
| 369 | − connector_status_disconnected, | |
| 370 | − dp->panel->dpcd, dp->panel->downstream_ports); | |
| 368 | + if (!dp->dp_display.is_edp) | |
| 369 | + drm_dp_set_subconnector_property(dp->dp_display.connector, | |
| 370 | + connector_status_disconnected, | |
| 371 | + dp->panel->dpcd, | |
| 372 | + dp->panel->downstream_ports); | |
| 371 | 373 | } |
| 372 | 374 | |
| 373 | 375 | dp->dp_display.is_connected = hpd; |
| @@ -396,8 +398,11 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) · 22 unmodified lines | ||
| 396 | 398 | |
| 397 | 399 | dp_link_process_request(dp->link); |
| 398 | 400 | |
| 399 | − drm_dp_set_subconnector_property(dp->dp_display.connector, connector_status_connected, | |
| 400 | − dp->panel->dpcd, dp->panel->downstream_ports); | |
| 401 | + if (!dp->dp_display.is_edp) | |
| 402 | + drm_dp_set_subconnector_property(dp->dp_display.connector, | |
| 403 | + connector_status_connected, | |
| 404 | + dp->panel->dpcd, | |
| 405 | + dp->panel->downstream_ports); | |
| 401 | 406 | |
| 402 | 407 | edid = dp->panel->edid; |
| 403 | 408 | |
| @@ -345,6 +345,9 @@ struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct dr · 344 unmodified lines | ||
| 345 | 345 | if (IS_ERR(connector)) |
| 346 | 346 | return connector; |
| 347 | 347 | |
| 348 | + if (!dp_display->is_edp) | |
| 349 | + drm_connector_attach_dp_subconnector_property(connector); | |
| 350 | + | |
| 348 | 351 | drm_connector_attach_encoder(connector, encoder); |
| 349 | 352 | |
| 350 | 353 | return connector; |
| @@ -918,7 +918,7 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, · 917 unmodified lines | ||
| 918 | 918 | if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) { |
| 919 | 919 | if (phy->cphy_mode) { |
| 920 | 920 | vreg_ctrl_0 = 0x45; |
| 921 | − vreg_ctrl_1 = 0x45; | |
| 921 | + vreg_ctrl_1 = 0x41; | |
| 922 | 922 | glbl_rescode_top_ctrl = 0x00; |
| 923 | 923 | glbl_rescode_bot_ctrl = 0x00; |
| 924 | 924 | } else { |
| @@ -288,8 +288,6 @@ static int msm_drm_init(struct device *dev, const struct drm_driver *drv) · 287 unmodified lines | ||
| 288 | 288 | if (ret) |
| 289 | 289 | goto err_msm_uninit; |
| 290 | 290 | |
| 291 | − drm_kms_helper_poll_init(ddev); | |
| 292 | − | |
| 293 | 291 | if (priv->kms_init) { |
| 294 | 292 | drm_kms_helper_poll_init(ddev); |
| 295 | 293 | msm_fbdev_setup(ddev); |
| @@ -2474,7 +2474,7 @@ nv50_disp_atomic_commit(struct drm_device *dev, · 2473 unmodified lines | ||
| 2474 | 2474 | |
| 2475 | 2475 | err_cleanup: |
| 2476 | 2476 | if (ret) |
| 2477 | − drm_atomic_helper_cleanup_planes(dev, state); | |
| 2477 | + drm_atomic_helper_unprepare_planes(dev, state); | |
| 2478 | 2478 | done: |
| 2479 | 2479 | pm_runtime_put_autosuspend(dev->dev); |
| 2480 | 2480 | return ret; |
| @@ -14,7 +14,7 @@ struct nvkm_event { · 13 unmodified lines | ||
| 14 | 14 | int index_nr; |
| 15 | 15 | |
| 16 | 16 | spinlock_t refs_lock; |
| 17 | − spinlock_t list_lock; | |
| 17 | + rwlock_t list_lock; | |
| 18 | 18 | int *refs; |
| 19 | 19 | |
| 20 | 20 | struct list_head ntfy; |
| @@ -38,7 +38,7 @@ nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *subdev, · 17 unmodified lines | ||
| 38 | 38 | int types_nr, int index_nr, struct nvkm_event *event) |
| 39 | 39 | { |
| 40 | 40 | spin_lock_init(&event->refs_lock); |
| 41 | − spin_lock_init(&event->list_lock); | |
| 41 | + rwlock_init(&event->list_lock); | |
| 42 | 42 | return __nvkm_event_init(func, subdev, types_nr, index_nr, event); |
| 43 | 43 | } |
| 44 | 44 | |
| @@ -26,6 +26,49 @@ · 25 unmodified lines | ||
| 26 | 26 | * DEALINGS IN THE SOFTWARE. |
| 27 | 27 | */ |
| 28 | 28 | |
| 29 | +/** | |
| 30 | + * msgqTxHeader -- TX queue data structure | |
| 31 | + * @version: the version of this structure, must be 0 | |
| 32 | + * @size: the size of the entire queue, including this header | |
| 33 | + * @msgSize: the padded size of queue element, 16 is minimum | |
| 34 | + * @msgCount: the number of elements in this queue | |
| 35 | + * @writePtr: head index of this queue | |
| 36 | + * @flags: 1 = swap the RX pointers | |
| 37 | + * @rxHdrOff: offset of readPtr in this structure | |
| 38 | + * @entryOff: offset of beginning of queue (msgqRxHeader), relative to | |
| 39 | + * beginning of this structure | |
| 40 | + * | |
| 41 | + * The command queue is a queue of RPCs that are sent from the driver to the | |
| 42 | + * GSP. The status queue is a queue of messages/responses from GSP-RM to the | |
| 43 | + * driver. Although the driver allocates memory for both queues, the command | |
| 44 | + * queue is owned by the driver and the status queue is owned by GSP-RM. In | |
| 45 | + * addition, the headers of the two queues must not share the same 4K page. | |
| 46 | + * | |
| 47 | + * Each queue is prefixed with this data structure. The idea is that a queue | |
| 48 | + * and its header are written to only by their owner. That is, only the | |
| 49 | + * driver writes to the command queue and command queue header, and only the | |
| 50 | + * GSP writes to the status (receive) queue and its header. | |
| 51 | + * | |
| 52 | + * This is enforced by the concept of "swapping" the RX pointers. This is | |
| 53 | + * why the 'flags' field must be set to 1. 'rxHdrOff' is how the GSP knows | |
| 54 | + * where the where the tail pointer of its status queue. | |
| 55 | + * | |
| 56 | + * When the driver writes a new RPC to the command queue, it updates writePtr. | |
| 57 | + * When it reads a new message from the status queue, it updates readPtr. In | |
| 58 | + * this way, the GSP knows when a new command is in the queue (it polls | |
| 59 | + * writePtr) and it knows how much free space is in the status queue (it | |
| 60 | + * checks readPtr). The driver never cares about how much free space is in | |
| 61 | + * the status queue. | |
| 62 | + * | |
| 63 | + * As usual, producers write to the head pointer, and consumers read from the | |
| 64 | + * tail pointer. When head == tail, the queue is empty. | |
| 65 | + * | |
| 66 | + * So to summarize: | |
| 67 | + * command.writePtr = head of command queue | |
| 68 | + * command.readPtr = tail of status queue | |
| 69 | + * status.writePtr = head of status queue | |
| 70 | + * status.readPtr = tail of command queue | |
| 71 | + */ | |
| 29 | 72 | typedef struct |
| 30 | 73 | { |
| 31 | 74 | NvU32 version; // queue version |
| @@ -38,6 +81,14 @@ typedef struct · 6 unmodified lines | ||
| 38 | 81 | NvU32 entryOff; // Offset of entries from start of backing store. |
| 39 | 82 | } msgqTxHeader; |
| 40 | 83 | |
| 84 | +/** | |
| 85 | + * msgqRxHeader - RX queue data structure | |
| 86 | + * @readPtr: tail index of the other queue | |
| 87 | + * | |
| 88 | + * Although this is a separate struct, it could easily be merged into | |
| 89 | + * msgqTxHeader. msgqTxHeader.rxHdrOff is simply the offset of readPtr | |
| 90 | + * from the beginning of msgqTxHeader. | |
| 91 | + */ | |
| 41 | 92 | typedef struct |
| 42 | 93 | { |
| 43 | 94 | NvU32 readPtr; // message id of last message read |
| @@ -38,7 +38,7 @@ typedef struct PACKED_REGISTRY_TABLE · 37 unmodified lines | ||
| 38 | 38 | { |
| 39 | 39 | NvU32 size; |
| 40 | 40 | NvU32 numEntries; |
| 41 | − PACKED_REGISTRY_ENTRY entries[0]; | |
| 41 | + PACKED_REGISTRY_ENTRY entries[] __counted_by(numEntries); | |
| 42 | 42 | } PACKED_REGISTRY_TABLE; |
| 43 | 43 | |
| 44 | 44 | #endif |
| @@ -318,8 +318,9 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 *size, int *align, u32 domain, · 317 unmodified lines | ||
| 318 | 318 | (!vmm->page[i].host || vmm->page[i].shift > PAGE_SHIFT)) |
| 319 | 319 | continue; |
| 320 | 320 | |
| 321 | − if (pi < 0) | |
| 322 | − pi = i; | |
| 321 | + /* pick the last one as it will be smallest. */ | |
| 322 | + pi = i; | |
| 323 | + | |
| 323 | 324 | /* Stop once the buffer is larger than the current page size. */ |
| 324 | 325 | if (*size >= 1ULL << vmm->page[i].shift) |
| 325 | 326 | break; |
| @@ -726,6 +726,11 @@ nouveau_display_create(struct drm_device *dev) · 725 unmodified lines | ||
| 726 | 726 | |
| 727 | 727 | if (nouveau_modeset != 2) { |
| 728 | 728 | ret = nvif_disp_ctor(&drm->client.device, "kmsDisp", 0, &disp->disp); |
| 729 | + /* no display hw */ | |
| 730 | + if (ret == -ENODEV) { | |
| 731 | + ret = 0; | |
| 732 | + goto disp_create_err; | |
| 733 | + } | |
| 729 | 734 | |
| 730 | 735 | if (!ret && (disp->disp.outp_mask || drm->vbios.dcb.entries)) { |
| 731 | 736 | nouveau_display_create_properties(dev); |
| @@ -81,17 +81,17 @@ nvkm_event_ntfy_state(struct nvkm_event_ntfy *ntfy) · 80 unmodified lines | ||
| 81 | 81 | static void |
| 82 | 82 | nvkm_event_ntfy_remove(struct nvkm_event_ntfy *ntfy) |
| 83 | 83 | { |
| 84 | − spin_lock_irq(&ntfy->event->list_lock); | |
| 84 | + write_lock_irq(&ntfy->event->list_lock); | |
| 85 | 85 | list_del_init(&ntfy->head); |
| 86 | − spin_unlock_irq(&ntfy->event->list_lock); | |
| 86 | + write_unlock_irq(&ntfy->event->list_lock); | |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | 89 | static void |
| 90 | 90 | nvkm_event_ntfy_insert(struct nvkm_event_ntfy *ntfy) |
| 91 | 91 | { |
| 92 | − spin_lock_irq(&ntfy->event->list_lock); | |
| 92 | + write_lock_irq(&ntfy->event->list_lock); | |
| 93 | 93 | list_add_tail(&ntfy->head, &ntfy->event->ntfy); |
| 94 | − spin_unlock_irq(&ntfy->event->list_lock); | |
| 94 | + write_unlock_irq(&ntfy->event->list_lock); | |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | 97 | static void |
| @@ -176,7 +176,7 @@ nvkm_event_ntfy(struct nvkm_event *event, int id, u32 bits) · 78 unmodified lines | ||
| 176 | 176 | return; |
| 177 | 177 | |
| 178 | 178 | nvkm_trace(event->subdev, "event: ntfy %08x on %d\n", bits, id); |
| 179 | − spin_lock_irqsave(&event->list_lock, flags); | |
| 179 | + read_lock_irqsave(&event->list_lock, flags); | |
| 180 | 180 | |
| 181 | 181 | list_for_each_entry_safe(ntfy, ntmp, &event->ntfy, head) { |
| 182 | 182 | if (ntfy->id == id && ntfy->bits & bits) { |
| @@ -185,7 +185,7 @@ nvkm_event_ntfy(struct nvkm_event *event, int id, u32 bits) · 2 unmodified lines | ||
| 185 | 185 | } |
| 186 | 186 | } |
| 187 | 187 | |
| 188 | − spin_unlock_irqrestore(&event->list_lock, flags); | |
| 188 | + read_unlock_irqrestore(&event->list_lock, flags); | |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | 191 | void |
| @@ -539,7 +539,7 @@ r535_fifo_runl_ctor(struct nvkm_fifo *fifo) · 538 unmodified lines | ||
| 539 | 539 | struct nvkm_runl *runl; |
| 540 | 540 | struct nvkm_engn *engn; |
| 541 | 541 | u32 cgids = 2048; |
| 542 | − u32 chids = 2048 / CHID_PER_USERD; | |
| 542 | + u32 chids = 2048; | |
| 543 | 543 | int ret; |
| 544 | 544 | NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS *ctrl; |
| 545 | 545 | |
| @@ -365,10 +365,8 @@ r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *argv, bool wait, u32 repc) · 364 unmodified lines | ||
| 365 | 365 | } |
| 366 | 366 | |
| 367 | 367 | ret = r535_gsp_cmdq_push(gsp, rpc); |
| 368 | − if (ret) { | |
| 369 | − mutex_unlock(&gsp->cmdq.mutex); | |
| 368 | + if (ret) | |
| 370 | 369 | return ERR_PTR(ret); |
| 371 | − } | |
| 372 | 370 | |
| 373 | 371 | if (wait) { |
| 374 | 372 | msg = r535_gsp_msg_recv(gsp, fn, repc); |
| @@ -689,8 +687,8 @@ r535_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 argc) · 314 unmodified lines | ||
| 689 | 687 | struct nvfw_gsp_rpc *rpc; |
| 690 | 688 | |
| 691 | 689 | rpc = r535_gsp_cmdq_get(gsp, ALIGN(sizeof(*rpc) + argc, sizeof(u64))); |
| 692 | − if (!rpc) | |
| 693 | − return NULL; | |
| 690 | + if (IS_ERR(rpc)) | |
| 691 | + return ERR_CAST(rpc); | |
| 694 | 692 | |
| 695 | 693 | rpc->header_version = 0x03000000; |
| 696 | 694 | rpc->signature = ('C' << 24) | ('P' << 16) | ('R' << 8) | 'V'; |
| @@ -1048,7 +1046,7 @@ r535_gsp_rpc_set_registry(struct nvkm_gsp *gsp) · 351 unmodified lines | ||
| 1048 | 1046 | char *strings; |
| 1049 | 1047 | int str_offset; |
| 1050 | 1048 | int i; |
| 1051 | − size_t rpc_size = sizeof(*rpc) + sizeof(rpc->entries[0]) * NV_GSP_REG_NUM_ENTRIES; | |
| 1049 | + size_t rpc_size = struct_size(rpc, entries, NV_GSP_REG_NUM_ENTRIES); | |
| 1052 | 1050 | |
| 1053 | 1051 | /* add strings + null terminator */ |
| 1054 | 1052 | for (i = 0; i < NV_GSP_REG_NUM_ENTRIES; i++) |
| @@ -1159,7 +1157,7 @@ static void · 104 unmodified lines | ||
| 1159 | 1157 | r535_gsp_acpi_mux_id(acpi_handle handle, u32 id, MUX_METHOD_DATA_ELEMENT *mode, |
| 1160 | 1158 | MUX_METHOD_DATA_ELEMENT *part) |
| 1161 | 1159 | { |
| 1162 | − acpi_handle iter = NULL, handle_mux; | |
| 1160 | + acpi_handle iter = NULL, handle_mux = NULL; | |
| 1163 | 1161 | acpi_status status; |
| 1164 | 1162 | unsigned long long value; |
| 1165 | 1163 | |
| @@ -1379,6 +1377,13 @@ r535_gsp_msg_post_event(void *priv, u32 fn, void *repv, u32 repc) · 213 unmodified lines | ||
| 1379 | 1377 | return 0; |
| 1380 | 1378 | } |
| 1381 | 1379 | |
| 1380 | +/** | |
| 1381 | + * r535_gsp_msg_run_cpu_sequencer() -- process I/O commands from the GSP | |
| 1382 | + * | |
| 1383 | + * The GSP sequencer is a list of I/O commands that the GSP can send to | |
| 1384 | + * the driver to perform for various purposes. The most common usage is to | |
| 1385 | + * perform a special mid-initialization reset. | |
| 1386 | + */ | |
| 1382 | 1387 | static int |
| 1383 | 1388 | r535_gsp_msg_run_cpu_sequencer(void *priv, u32 fn, void *repv, u32 repc) |
| 1384 | 1389 | { |
| @@ -1718,6 +1723,23 @@ r535_gsp_libos_id8(const char *name) · 333 unmodified lines | ||
| 1718 | 1723 | return id; |
| 1719 | 1724 | } |
| 1720 | 1725 | |
| 1726 | +/** | |
| 1727 | + * create_pte_array() - creates a PTE array of a physically contiguous buffer | |
| 1728 | + * @ptes: pointer to the array | |
| 1729 | + * @addr: base address of physically contiguous buffer (GSP_PAGE_SIZE aligned) | |
| 1730 | + * @size: size of the buffer | |
| 1731 | + * | |
| 1732 | + * GSP-RM sometimes expects physically-contiguous buffers to have an array of | |
| 1733 | + * "PTEs" for each page in that buffer. Although in theory that allows for | |
| 1734 | + * the buffer to be physically discontiguous, GSP-RM does not currently | |
| 1735 | + * support that. | |
| 1736 | + * | |
| 1737 | + * In this case, the PTEs are DMA addresses of each page of the buffer. Since | |
| 1738 | + * the buffer is physically contiguous, calculating all the PTEs is simple | |
| 1739 | + * math. | |
| 1740 | + * | |
| 1741 | + * See memdescGetPhysAddrsForGpu() | |
| 1742 | + */ | |
| 1721 | 1743 | static void create_pte_array(u64 *ptes, dma_addr_t addr, size_t size) |
| 1722 | 1744 | { |
| 1723 | 1745 | unsigned int num_pages = DIV_ROUND_UP_ULL(size, GSP_PAGE_SIZE); |
| @@ -1727,6 +1749,35 @@ static void create_pte_array(u64 *ptes, dma_addr_t addr, size_t size) · 3 unmodified lines | ||
| 1727 | 1749 | ptes[i] = (u64)addr + (i << GSP_PAGE_SHIFT); |
| 1728 | 1750 | } |
| 1729 | 1751 | |
| 1752 | +/** | |
| 1753 | + * r535_gsp_libos_init() -- create the libos arguments structure | |
| 1754 | + * | |
| 1755 | + * The logging buffers are byte queues that contain encoded printf-like | |
| 1756 | + * messages from GSP-RM. They need to be decoded by a special application | |
| 1757 | + * that can parse the buffers. | |
| 1758 | + * | |
| 1759 | + * The 'loginit' buffer contains logs from early GSP-RM init and | |
| 1760 | + * exception dumps. The 'logrm' buffer contains the subsequent logs. Both are | |
| 1761 | + * written to directly by GSP-RM and can be any multiple of GSP_PAGE_SIZE. | |
| 1762 | + * | |
| 1763 | + * The physical address map for the log buffer is stored in the buffer | |
| 1764 | + * itself, starting with offset 1. Offset 0 contains the "put" pointer. | |
| 1765 | + * | |
| 1766 | + * The GSP only understands 4K pages (GSP_PAGE_SIZE), so even if the kernel is | |
| 1767 | + * configured for a larger page size (e.g. 64K pages), we need to give | |
| 1768 | + * the GSP an array of 4K pages. Fortunately, since the buffer is | |
| 1769 | + * physically contiguous, it's simple math to calculate the addresses. | |
| 1770 | + * | |
| 1771 | + * The buffers must be a multiple of GSP_PAGE_SIZE. GSP-RM also currently | |
| 1772 | + * ignores the @kind field for LOGINIT, LOGINTR, and LOGRM, but expects the | |
| 1773 | + * buffers to be physically contiguous anyway. | |
| 1774 | + * | |
| 1775 | + * The memory allocated for the arguments must remain until the GSP sends the | |
| 1776 | + * init_done RPC. | |
| 1777 | + * | |
| 1778 | + * See _kgspInitLibosLoggingStructures (allocates memory for buffers) | |
| 1779 | + * See kgspSetupLibosInitArgs_IMPL (creates pLibosInitArgs[] array) | |
| 1780 | + */ | |
| 1730 | 1781 | static int |
| 1731 | 1782 | r535_gsp_libos_init(struct nvkm_gsp *gsp) |
| 1732 | 1783 | { |
| @@ -1837,6 +1888,35 @@ nvkm_gsp_radix3_dtor(struct nvkm_gsp *gsp, struct nvkm_gsp_radix3 *rx3) · 104 unmodified lines | ||
| 1837 | 1888 | nvkm_gsp_mem_dtor(gsp, &rx3->mem[i]); |
| 1838 | 1889 | } |
| 1839 | 1890 | |
| 1891 | +/** | |
| 1892 | + * nvkm_gsp_radix3_sg - build a radix3 table from a S/G list | |
| 1893 | + * | |
| 1894 | + * The GSP uses a three-level page table, called radix3, to map the firmware. | |
| 1895 | + * Each 64-bit "pointer" in the table is either the bus address of an entry in | |
| 1896 | + * the next table (for levels 0 and 1) or the bus address of the next page in | |
| 1897 | + * the GSP firmware image itself. | |
| 1898 | + * | |
| 1899 | + * Level 0 contains a single entry in one page that points to the first page | |
| 1900 | + * of level 1. | |
| 1901 | + * | |
| 1902 | + * Level 1, since it's also only one page in size, contains up to 512 entries, | |
| 1903 | + * one for each page in Level 2. | |
| 1904 | + * | |
| 1905 | + * Level 2 can be up to 512 pages in size, and each of those entries points to | |
| 1906 | + * the next page of the firmware image. Since there can be up to 512*512 | |
| 1907 | + * pages, that limits the size of the firmware to 512*512*GSP_PAGE_SIZE = 1GB. | |
| 1908 | + * | |
| 1909 | + * Internally, the GSP has its window into system memory, but the base | |
| 1910 | + * physical address of the aperture is not 0. In fact, it varies depending on | |
| 1911 | + * the GPU architecture. Since the GPU is a PCI device, this window is | |
| 1912 | + * accessed via DMA and is therefore bound by IOMMU translation. The end | |
| 1913 | + * result is that GSP-RM must translate the bus addresses in the table to GSP | |
| 1914 | + * physical addresses. All this should happen transparently. | |
| 1915 | + * | |
| 1916 | + * Returns 0 on success, or negative error code | |
| 1917 | + * | |
| 1918 | + * See kgspCreateRadix3_IMPL | |
| 1919 | + */ | |
| 1840 | 1920 | static int |
| 1841 | 1921 | nvkm_gsp_radix3_sg(struct nvkm_device *device, struct sg_table *sgt, u64 size, |
| 1842 | 1922 | struct nvkm_gsp_radix3 *rx3) |
| @@ -31,7 +31,7 @@ tu102_vmm_flush(struct nvkm_vmm *vmm, int depth) · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | type |= 0x00000001; /* PAGE_ALL */ |
| 33 | 33 | if (atomic_read(&vmm->engref[NVKM_SUBDEV_BAR])) |
| 34 | − type |= 0x00000004; /* HUB_ONLY */ | |
| 34 | + type |= 0x00000006; /* HUB_ONLY | ALL PDB (hack) */ | |
| 35 | 35 | |
| 36 | 36 | mutex_lock(&vmm->mmu->mutex); |
| 37 | 37 | |
| @@ -1709,6 +1709,7 @@ static const struct panel_desc auo_b101uan08_3_desc = { · 1708 unmodified lines | ||
| 1709 | 1709 | .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | |
| 1710 | 1710 | MIPI_DSI_MODE_LPM, |
| 1711 | 1711 | .init_cmds = auo_b101uan08_3_init_cmd, |
| 1712 | + .lp11_before_reset = true, | |
| 1712 | 1713 | }; |
| 1713 | 1714 | |
| 1714 | 1715 | static const struct drm_display_mode boe_tv105wum_nw0_default_mode = { |
| @@ -1763,14 +1764,15 @@ static const struct panel_desc starry_qfh032011_53g_desc = { · 48 unmodified lines | ||
| 1763 | 1764 | .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | |
| 1764 | 1765 | MIPI_DSI_MODE_LPM, |
| 1765 | 1766 | .init_cmds = starry_qfh032011_53g_init_cmd, |
| 1767 | + .lp11_before_reset = true, | |
| 1766 | 1768 | }; |
| 1767 | 1769 | |
| 1768 | 1770 | static const struct drm_display_mode starry_himax83102_j02_default_mode = { |
| 1769 | − .clock = 161600, | |
| 1771 | + .clock = 162850, | |
| 1770 | 1772 | .hdisplay = 1200, |
| 1771 | − .hsync_start = 1200 + 40, | |
| 1772 | − .hsync_end = 1200 + 40 + 20, | |
| 1773 | − .htotal = 1200 + 40 + 20 + 40, | |
| 1773 | + .hsync_start = 1200 + 50, | |
| 1774 | + .hsync_end = 1200 + 50 + 20, | |
| 1775 | + .htotal = 1200 + 50 + 20 + 50, | |
| 1774 | 1776 | .vdisplay = 1920, |
| 1775 | 1777 | .vsync_start = 1920 + 116, |
| 1776 | 1778 | .vsync_end = 1920 + 116 + 8, |
| @@ -1254,9 +1254,9 @@ static int nt36523_probe(struct mipi_dsi_device *dsi) · 1253 unmodified lines | ||
| 1254 | 1254 | return dev_err_probe(dev, -EPROBE_DEFER, "cannot get secondary DSI host\n"); |
| 1255 | 1255 | |
| 1256 | 1256 | pinfo->dsi[1] = mipi_dsi_device_register_full(dsi1_host, info); |
| 1257 | − if (!pinfo->dsi[1]) { | |
| 1257 | + if (IS_ERR(pinfo->dsi[1])) { | |
| 1258 | 1258 | dev_err(dev, "cannot get secondary DSI device\n"); |
| 1259 | − return -ENODEV; | |
| 1259 | + return PTR_ERR(pinfo->dsi[1]); | |
| 1260 | 1260 | } |
| 1261 | 1261 | } |
| 1262 | 1262 | |
| @@ -2379,13 +2379,13 @@ static const struct panel_desc innolux_g070y2_t02 = { · 2378 unmodified lines | ||
| 2379 | 2379 | static const struct display_timing innolux_g101ice_l01_timing = { |
| 2380 | 2380 | .pixelclock = { 60400000, 71100000, 74700000 }, |
| 2381 | 2381 | .hactive = { 1280, 1280, 1280 }, |
| 2382 | − .hfront_porch = { 41, 80, 100 }, | |
| 2383 | − .hback_porch = { 40, 79, 99 }, | |
| 2384 | − .hsync_len = { 1, 1, 1 }, | |
| 2382 | + .hfront_porch = { 30, 60, 70 }, | |
| 2383 | + .hback_porch = { 30, 60, 70 }, | |
| 2384 | + .hsync_len = { 22, 40, 60 }, | |
| 2385 | 2385 | .vactive = { 800, 800, 800 }, |
| 2386 | − .vfront_porch = { 5, 11, 14 }, | |
| 2387 | − .vback_porch = { 4, 11, 14 }, | |
| 2388 | − .vsync_len = { 1, 1, 1 }, | |
| 2386 | + .vfront_porch = { 3, 8, 14 }, | |
| 2387 | + .vback_porch = { 3, 8, 14 }, | |
| 2388 | + .vsync_len = { 4, 7, 12 }, | |
| 2389 | 2389 | .flags = DISPLAY_FLAGS_DE_HIGH, |
| 2390 | 2390 | }; |
| 2391 | 2391 | |
| @@ -2402,6 +2402,7 @@ static const struct panel_desc innolux_g101ice_l01 = { · 10 unmodified lines | ||
| 2402 | 2402 | .disable = 200, |
| 2403 | 2403 | }, |
| 2404 | 2404 | .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, |
| 2405 | + .bus_flags = DRM_BUS_FLAG_DE_HIGH, | |
| 2405 | 2406 | .connector_type = DRM_MODE_CONNECTOR_LVDS, |
| 2406 | 2407 | }; |
| 2407 | 2408 | |
| @@ -29,14 +29,20 @@ static void panfrost_devfreq_update_utilization(struct panfrost_devfreq *pfdevfr · 28 unmodified lines | ||
| 29 | 29 | static int panfrost_devfreq_target(struct device *dev, unsigned long *freq, |
| 30 | 30 | u32 flags) |
| 31 | 31 | { |
| 32 | + struct panfrost_device *ptdev = dev_get_drvdata(dev); | |
| 32 | 33 | struct dev_pm_opp *opp; |
| 34 | + int err; | |
| 33 | 35 | |
| 34 | 36 | opp = devfreq_recommended_opp(dev, freq, flags); |
| 35 | 37 | if (IS_ERR(opp)) |
| 36 | 38 | return PTR_ERR(opp); |
| 37 | 39 | dev_pm_opp_put(opp); |
| 38 | 40 | |
| 39 | − return dev_pm_opp_set_rate(dev, *freq); | |
| 41 | + err = dev_pm_opp_set_rate(dev, *freq); | |
| 42 | + if (!err) | |
| 43 | + ptdev->pfdevfreq.current_frequency = *freq; | |
| 44 | + | |
| 45 | + return err; | |
| 40 | 46 | } |
| 41 | 47 | |
| 42 | 48 | static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq) |
| @@ -58,7 +64,6 @@ static int panfrost_devfreq_get_dev_status(struct device *dev, · 15 unmodified lines | ||
| 58 | 64 | spin_lock_irqsave(&pfdevfreq->lock, irqflags); |
| 59 | 65 | |
| 60 | 66 | panfrost_devfreq_update_utilization(pfdevfreq); |
| 61 | − pfdevfreq->current_frequency = status->current_frequency; | |
| 62 | 67 | |
| 63 | 68 | status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time, |
| 64 | 69 | pfdevfreq->idle_time)); |
| @@ -164,6 +169,14 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) · 99 unmodified lines | ||
| 164 | 169 | |
| 165 | 170 | panfrost_devfreq_profile.initial_freq = cur_freq; |
| 166 | 171 | |
| 172 | + /* | |
| 173 | + * We could wait until panfrost_devfreq_target() to set this value, but | |
| 174 | + * since the simple_ondemand governor works asynchronously, there's a | |
| 175 | + * chance by the time someone opens the device's fdinfo file, current | |
| 176 | + * frequency hasn't been updated yet, so let's just do an early set. | |
| 177 | + */ | |
| 178 | + pfdevfreq->current_frequency = cur_freq; | |
| 179 | + | |
| 167 | 180 | /* |
| 168 | 181 | * Set the recommend OPP this will enable and configure the regulator |
| 169 | 182 | * if any and will avoid a switch off by regulator_late_cleanup() |
| @@ -200,7 +200,7 @@ static enum drm_gem_object_status panfrost_gem_status(struct drm_gem_object *obj · 199 unmodified lines | ||
| 200 | 200 | struct panfrost_gem_object *bo = to_panfrost_bo(obj); |
| 201 | 201 | enum drm_gem_object_status res = 0; |
| 202 | 202 | |
| 203 | − if (bo->base.pages) | |
| 203 | + if (bo->base.base.import_attach || bo->base.pages) | |
| 204 | 204 | res |= DRM_GEM_OBJECT_RESIDENT; |
| 205 | 205 | |
| 206 | 206 | if (bo->base.madv == PANFROST_MADV_DONTNEED) |
| @@ -247,14 +247,22 @@ static inline void vop_cfg_done(struct vop *vop) · 246 unmodified lines | ||
| 247 | 247 | VOP_REG_SET(vop, common, cfg_done, 1); |
| 248 | 248 | } |
| 249 | 249 | |
| 250 | −static bool has_rb_swapped(uint32_t format) | |
| 250 | +static bool has_rb_swapped(uint32_t version, uint32_t format) | |
| 251 | 251 | { |
| 252 | 252 | switch (format) { |
| 253 | 253 | case DRM_FORMAT_XBGR8888: |
| 254 | 254 | case DRM_FORMAT_ABGR8888: |
| 255 | − case DRM_FORMAT_BGR888: | |
| 256 | 255 | case DRM_FORMAT_BGR565: |
| 257 | 256 | return true; |
| 257 | + /* | |
| 258 | + * full framework (IP version 3.x) only need rb swapped for RGB888 and | |
| 259 | + * little framework (IP version 2.x) only need rb swapped for BGR888, | |
| 260 | + * check for 3.x to also only rb swap BGR888 for unknown vop version | |
| 261 | + */ | |
| 262 | + case DRM_FORMAT_RGB888: | |
| 263 | + return VOP_MAJOR(version) == 3; | |
| 264 | + case DRM_FORMAT_BGR888: | |
| 265 | + return VOP_MAJOR(version) != 3; | |
| 258 | 266 | default: |
| 259 | 267 | return false; |
| 260 | 268 | } |
| @@ -1030,7 +1038,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, · 769 unmodified lines | ||
| 1030 | 1038 | VOP_WIN_SET(vop, win, dsp_info, dsp_info); |
| 1031 | 1039 | VOP_WIN_SET(vop, win, dsp_st, dsp_st); |
| 1032 | 1040 | |
| 1033 | − rb_swap = has_rb_swapped(fb->format->format); | |
| 1041 | + rb_swap = has_rb_swapped(vop->data->version, fb->format->format); | |
| 1034 | 1042 | VOP_WIN_SET(vop, win, rb_swap, rb_swap); |
| 1035 | 1043 | |
| 1036 | 1044 | /* |
| @@ -20,6 +20,7 @@ if GREYBUS · 19 unmodified lines | ||
| 20 | 20 | config GREYBUS_BEAGLEPLAY |
| 21 | 21 | tristate "Greybus BeaglePlay driver" |
| 22 | 22 | depends on SERIAL_DEV_BUS |
| 23 | + select CRC_CCITT | |
| 23 | 24 | help |
| 24 | 25 | Select this option if you have a BeaglePlay where CC1352 |
| 25 | 26 | co-processor acts as Greybus SVC. |
| @@ -345,6 +345,8 @@ static const struct apple_non_apple_keyboard non_apple_keyboards[] = { · 344 unmodified lines | ||
| 345 | 345 | { "AONE" }, |
| 346 | 346 | { "GANSS" }, |
| 347 | 347 | { "Hailuck" }, |
| 348 | + { "Jamesdonkey" }, | |
| 349 | + { "A3R" }, | |
| 348 | 350 | }; |
| 349 | 351 | |
| 350 | 352 | static bool apple_is_non_apple_keyboard(struct hid_device *hdev) |
| @@ -381,7 +381,7 @@ static int asus_raw_event(struct hid_device *hdev, · 380 unmodified lines | ||
| 381 | 381 | return 0; |
| 382 | 382 | } |
| 383 | 383 | |
| 384 | −static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size) | |
| 384 | +static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size) | |
| 385 | 385 | { |
| 386 | 386 | unsigned char *dmabuf; |
| 387 | 387 | int ret; |
| @@ -404,7 +404,7 @@ static int asus_kbd_set_report(struct hid_device *hdev, u8 *buf, size_t buf_size · 16 unmodified lines | ||
| 404 | 404 | |
| 405 | 405 | static int asus_kbd_init(struct hid_device *hdev) |
| 406 | 406 | { |
| 407 | − u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, | |
| 407 | + const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54, | |
| 408 | 408 | 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; |
| 409 | 409 | int ret; |
| 410 | 410 | |
| @@ -418,7 +418,7 @@ static int asus_kbd_init(struct hid_device *hdev) · 7 unmodified lines | ||
| 418 | 418 | static int asus_kbd_get_functions(struct hid_device *hdev, |
| 419 | 419 | unsigned char *kbd_func) |
| 420 | 420 | { |
| 421 | − u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; | |
| 421 | + const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0x05, 0x20, 0x31, 0x00, 0x08 }; | |
| 422 | 422 | u8 *readbuf; |
| 423 | 423 | int ret; |
| 424 | 424 | |
| @@ -449,7 +449,7 @@ static int asus_kbd_get_functions(struct hid_device *hdev, · 24 unmodified lines | ||
| 449 | 449 | |
| 450 | 450 | static int rog_nkey_led_init(struct hid_device *hdev) |
| 451 | 451 | { |
| 452 | − u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; | |
| 452 | + const u8 buf_init_start[] = { FEATURE_KBD_LED_REPORT_ID1, 0xB9 }; | |
| 453 | 453 | u8 buf_init2[] = { FEATURE_KBD_LED_REPORT_ID1, 0x41, 0x53, 0x55, 0x53, 0x20, |
| 454 | 454 | 0x54, 0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 }; |
| 455 | 455 | u8 buf_init3[] = { FEATURE_KBD_LED_REPORT_ID1, |
| @@ -1000,6 +1000,24 @@ static int asus_start_multitouch(struct hid_device *hdev) · 544 unmodified lines | ||
| 1000 | 1000 | return 0; |
| 1001 | 1001 | } |
| 1002 | 1002 | |
| 1003 | +static int __maybe_unused asus_resume(struct hid_device *hdev) { | |
| 1004 | + struct asus_drvdata *drvdata = hid_get_drvdata(hdev); | |
| 1005 | + int ret = 0; | |
| 1006 | + | |
| 1007 | + if (drvdata->kbd_backlight) { | |
| 1008 | + const u8 buf[] = { FEATURE_KBD_REPORT_ID, 0xba, 0xc5, 0xc4, | |
| 1009 | + drvdata->kbd_backlight->cdev.brightness }; | |
| 1010 | + ret = asus_kbd_set_report(hdev, buf, sizeof(buf)); | |
| 1011 | + if (ret < 0) { | |
| 1012 | + hid_err(hdev, "Asus failed to set keyboard backlight: %d\n", ret); | |
| 1013 | + goto asus_resume_err; | |
| 1014 | + } | |
| 1015 | + } | |
| 1016 | + | |
| 1017 | +asus_resume_err: | |
| 1018 | + return ret; | |
| 1019 | +} | |
| 1020 | + | |
| 1003 | 1021 | static int __maybe_unused asus_reset_resume(struct hid_device *hdev) |
| 1004 | 1022 | { |
| 1005 | 1023 | struct asus_drvdata *drvdata = hid_get_drvdata(hdev); |
| @@ -1294,6 +1312,7 @@ static struct hid_driver asus_driver = { · 288 unmodified lines | ||
| 1294 | 1312 | .input_configured = asus_input_configured, |
| 1295 | 1313 | #ifdef CONFIG_PM |
| 1296 | 1314 | .reset_resume = asus_reset_resume, |
| 1315 | + .resume = asus_resume, | |
| 1297 | 1316 | #endif |
| 1298 | 1317 | .event = asus_event, |
| 1299 | 1318 | .raw_event = asus_raw_event |
| @@ -702,15 +702,22 @@ static void hid_close_report(struct hid_device *device) · 701 unmodified lines | ||
| 702 | 702 | * Free a device structure, all reports, and all fields. |
| 703 | 703 | */ |
| 704 | 704 | |
| 705 | −static void hid_device_release(struct device *dev) | |
| 705 | +void hiddev_free(struct kref *ref) | |
| 706 | 706 | { |
| 707 | − struct hid_device *hid = to_hid_device(dev); | |
| 707 | + struct hid_device *hid = container_of(ref, struct hid_device, ref); | |
| 708 | 708 | |
| 709 | 709 | hid_close_report(hid); |
| 710 | 710 | kfree(hid->dev_rdesc); |
| 711 | 711 | kfree(hid); |
| 712 | 712 | } |
| 713 | 713 | |
| 714 | +static void hid_device_release(struct device *dev) | |
| 715 | +{ | |
| 716 | + struct hid_device *hid = to_hid_device(dev); | |
| 717 | + | |
| 718 | + kref_put(&hid->ref, hiddev_free); | |
| 719 | +} | |
| 720 | + | |
| 714 | 721 | /* |
| 715 | 722 | * Fetch a report description item from the data stream. We support long |
| 716 | 723 | * items, though they are not used yet. |
| @@ -2846,6 +2853,7 @@ struct hid_device *hid_allocate_device(void) · 2129 unmodified lines | ||
| 2846 | 2853 | spin_lock_init(&hdev->debug_list_lock); |
| 2847 | 2854 | sema_init(&hdev->driver_input_lock, 1); |
| 2848 | 2855 | mutex_init(&hdev->ll_open_lock); |
| 2856 | + kref_init(&hdev->ref); | |
| 2849 | 2857 | |
| 2850 | 2858 | hid_bpf_device_init(hdev); |
| 2851 | 2859 | |
| @@ -1135,6 +1135,7 @@ static int hid_debug_events_open(struct inode *inode, struct file *file) · 1134 unmodified lines | ||
| 1135 | 1135 | goto out; |
| 1136 | 1136 | } |
| 1137 | 1137 | list->hdev = (struct hid_device *) inode->i_private; |
| 1138 | + kref_get(&list->hdev->ref); | |
| 1138 | 1139 | file->private_data = list; |
| 1139 | 1140 | mutex_init(&list->read_mutex); |
| 1140 | 1141 | |
| @@ -1227,6 +1228,8 @@ static int hid_debug_events_release(struct inode *inode, struct file *file) · 86 unmodified lines | ||
| 1227 | 1228 | list_del(&list->node); |
| 1228 | 1229 | spin_unlock_irqrestore(&list->hdev->debug_list_lock, flags); |
| 1229 | 1230 | kfifo_free(&list->hid_debug_fifo); |
| 1231 | + | |
| 1232 | + kref_put(&list->hdev->ref, hiddev_free); | |
| 1230 | 1233 | kfree(list); |
| 1231 | 1234 | |
| 1232 | 1235 | return 0; |
| @@ -21,6 +21,10 @@ MODULE_DESCRIPTION("HID driver for Glorious PC Gaming Race mice"); · 20 unmodified lines | ||
| 21 | 21 | * Glorious Model O and O- specify the const flag in the consumer input |
| 22 | 22 | * report descriptor, which leads to inputs being ignored. Fix this |
| 23 | 23 | * by patching the descriptor. |
| 24 | + * | |
| 25 | + * Glorious Model I incorrectly specifes the Usage Minimum for its | |
| 26 | + * keyboard HID report, causing keycodes to be misinterpreted. | |
| 27 | + * Fix this by setting Usage Minimum to 0 in that report. | |
| 24 | 28 | */ |
| 25 | 29 | static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 26 | 30 | unsigned int *rsize) |
| @@ -32,6 +36,10 @@ static __u8 *glorious_report_fixup(struct hid_device *hdev, __u8 *rdesc, · 5 unmodified lines | ||
| 32 | 36 | rdesc[85] = rdesc[113] = rdesc[141] = \ |
| 33 | 37 | HID_MAIN_ITEM_VARIABLE | HID_MAIN_ITEM_RELATIVE; |
| 34 | 38 | } |
| 39 | + if (*rsize == 156 && rdesc[41] == 1) { | |
| 40 | + hid_info(hdev, "patching Glorious Model I keyboard report descriptor\n"); | |
| 41 | + rdesc[41] = 0; | |
| 42 | + } | |
| 35 | 43 | return rdesc; |
| 36 | 44 | } |
| 37 | 45 | |
| @@ -44,6 +52,8 @@ static void glorious_update_name(struct hid_device *hdev) · 6 unmodified lines | ||
| 44 | 52 | model = "Model O"; break; |
| 45 | 53 | case USB_DEVICE_ID_GLORIOUS_MODEL_D: |
| 46 | 54 | model = "Model D"; break; |
| 55 | + case USB_DEVICE_ID_GLORIOUS_MODEL_I: | |
| 56 | + model = "Model I"; break; | |
| 47 | 57 | } |
| 48 | 58 | |
| 49 | 59 | snprintf(hdev->name, sizeof(hdev->name), "%s %s", "Glorious", model); |
| @@ -66,10 +76,12 @@ static int glorious_probe(struct hid_device *hdev, · 16 unmodified lines | ||
| 66 | 76 | } |
| 67 | 77 | |
| 68 | 78 | static const struct hid_device_id glorious_devices[] = { |
| 69 | − { HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS, | |
| 79 | + { HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH, | |
| 70 | 80 | USB_DEVICE_ID_GLORIOUS_MODEL_O) }, |
| 71 | − { HID_USB_DEVICE(USB_VENDOR_ID_GLORIOUS, | |
| 81 | + { HID_USB_DEVICE(USB_VENDOR_ID_SINOWEALTH, | |
| 72 | 82 | USB_DEVICE_ID_GLORIOUS_MODEL_D) }, |
| 83 | + { HID_USB_DEVICE(USB_VENDOR_ID_LAVIEW, | |
| 84 | + USB_DEVICE_ID_GLORIOUS_MODEL_I) }, | |
| 73 | 85 | { } |
| 74 | 86 | }; |
| 75 | 87 | MODULE_DEVICE_TABLE(hid, glorious_devices); |
| @@ -511,10 +511,6 @@ · 510 unmodified lines | ||
| 511 | 511 | #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a |
| 512 | 512 | #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100 |
| 513 | 513 | |
| 514 | −#define USB_VENDOR_ID_GLORIOUS 0x258a | |
| 515 | −#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033 | |
| 516 | −#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036 | |
| 517 | − | |
| 518 | 514 | #define I2C_VENDOR_ID_GOODIX 0x27c6 |
| 519 | 515 | #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0 |
| 520 | 516 | |
| @@ -745,6 +741,9 @@ · 224 unmodified lines | ||
| 745 | 741 | #define USB_VENDOR_ID_LABTEC 0x1020 |
| 746 | 742 | #define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006 |
| 747 | 743 | |
| 744 | +#define USB_VENDOR_ID_LAVIEW 0x22D4 | |
| 745 | +#define USB_DEVICE_ID_GLORIOUS_MODEL_I 0x1503 | |
| 746 | + | |
| 748 | 747 | #define USB_VENDOR_ID_LCPOWER 0x1241 |
| 749 | 748 | #define USB_DEVICE_ID_LCPOWER_LC1000 0xf767 |
| 750 | 749 | |
| @@ -869,7 +868,6 @@ · 118 unmodified lines | ||
| 869 | 868 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534 |
| 870 | 869 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539 |
| 871 | 870 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f |
| 872 | −#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 0xc547 | |
| 873 | 871 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a |
| 874 | 872 | #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 |
| 875 | 873 | #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 |
| @@ -1160,6 +1158,10 @@ · 284 unmodified lines | ||
| 1160 | 1158 | #define USB_VENDOR_ID_SIGMATEL 0x066F |
| 1161 | 1159 | #define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780 |
| 1162 | 1160 | |
| 1161 | +#define USB_VENDOR_ID_SINOWEALTH 0x258a | |
| 1162 | +#define USB_DEVICE_ID_GLORIOUS_MODEL_D 0x0033 | |
| 1163 | +#define USB_DEVICE_ID_GLORIOUS_MODEL_O 0x0036 | |
| 1164 | + | |
| 1163 | 1165 | #define USB_VENDOR_ID_SIS_TOUCH 0x0457 |
| 1164 | 1166 | #define USB_DEVICE_ID_SIS9200_TOUCH 0x9200 |
| 1165 | 1167 | #define USB_DEVICE_ID_SIS817_TOUCH 0x0817 |
| @@ -1695,12 +1695,11 @@ static int logi_dj_raw_event(struct hid_device *hdev, · 1694 unmodified lines | ||
| 1695 | 1695 | } |
| 1696 | 1696 | /* |
| 1697 | 1697 | * Mouse-only receivers send unnumbered mouse data. The 27 MHz |
| 1698 | − * receiver uses 6 byte packets, the nano receiver 8 bytes, | |
| 1699 | − * the lightspeed receiver (Pro X Superlight) 13 bytes. | |
| 1698 | + * receiver uses 6 byte packets, the nano receiver 8 bytes. | |
| 1700 | 1699 | */ |
| 1701 | 1700 | if (djrcv_dev->unnumbered_application == HID_GD_MOUSE && |
| 1702 | − size <= 13){ | |
| 1703 | − u8 mouse_report[14]; | |
| 1701 | + size <= 8) { | |
| 1702 | + u8 mouse_report[9]; | |
| 1704 | 1703 | |
| 1705 | 1704 | /* Prepend report id */ |
| 1706 | 1705 | mouse_report[0] = REPORT_TYPE_MOUSE; |
| @@ -1984,10 +1983,6 @@ static const struct hid_device_id logi_dj_receivers[] = { · 277 unmodified lines | ||
| 1984 | 1983 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, |
| 1985 | 1984 | USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1), |
| 1986 | 1985 | .driver_data = recvr_type_gaming_hidpp}, |
| 1987 | − { /* Logitech lightspeed receiver (0xc547) */ | |
| 1988 | − HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, | |
| 1989 | − USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2), | |
| 1990 | − .driver_data = recvr_type_gaming_hidpp}, | |
| 1991 | 1986 | |
| 1992 | 1987 | { /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */ |
| 1993 | 1988 | HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER), |
| @@ -1142,6 +1142,8 @@ static int mcp2221_probe(struct hid_device *hdev, · 1141 unmodified lines | ||
| 1142 | 1142 | if (ret) |
| 1143 | 1143 | return ret; |
| 1144 | 1144 | |
| 1145 | + hid_device_io_start(hdev); | |
| 1146 | + | |
| 1145 | 1147 | /* Set I2C bus clock diviser */ |
| 1146 | 1148 | if (i2c_clk_freq > 400) |
| 1147 | 1149 | i2c_clk_freq = 400; |
| @@ -1157,12 +1159,12 @@ static int mcp2221_probe(struct hid_device *hdev, · 9 unmodified lines | ||
| 1157 | 1159 | snprintf(mcp->adapter.name, sizeof(mcp->adapter.name), |
| 1158 | 1160 | "MCP2221 usb-i2c bridge"); |
| 1159 | 1161 | |
| 1162 | + i2c_set_adapdata(&mcp->adapter, mcp); | |
| 1160 | 1163 | ret = devm_i2c_add_adapter(&hdev->dev, &mcp->adapter); |
| 1161 | 1164 | if (ret) { |
| 1162 | 1165 | hid_err(hdev, "can't add usb-i2c adapter: %d\n", ret); |
| 1163 | 1166 | return ret; |
| 1164 | 1167 | } |
| 1165 | − i2c_set_adapdata(&mcp->adapter, mcp); | |
| 1166 | 1168 | |
| 1167 | 1169 | #if IS_REACHABLE(CONFIG_GPIOLIB) |
| 1168 | 1170 | /* Setup GPIO chip */ |
| @@ -2046,6 +2046,11 @@ static const struct hid_device_id mt_devices[] = { · 2045 unmodified lines | ||
| 2046 | 2046 | MT_USB_DEVICE(USB_VENDOR_ID_HANVON_ALT, |
| 2047 | 2047 | USB_DEVICE_ID_HANVON_ALT_MULTITOUCH) }, |
| 2048 | 2048 | |
| 2049 | + /* HONOR GLO-GXXX panel */ | |
| 2050 | + { .driver_data = MT_CLS_VTL, | |
| 2051 | + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | |
| 2052 | + 0x347d, 0x7853) }, | |
| 2053 | + | |
| 2049 | 2054 | /* Ilitek dual touch panel */ |
| 2050 | 2055 | { .driver_data = MT_CLS_NSMU, |
| 2051 | 2056 | MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, |
| @@ -33,6 +33,7 @@ static const struct hid_device_id hid_quirks[] = { · 32 unmodified lines | ||
| 33 | 33 | { HID_USB_DEVICE(USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2), HID_QUIRK_NO_INIT_REPORTS }, |
| 34 | 34 | { HID_USB_DEVICE(USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD), HID_QUIRK_BADPAD }, |
| 35 | 35 | { HID_USB_DEVICE(USB_VENDOR_ID_AMI, USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE), HID_QUIRK_ALWAYS_POLL }, |
| 36 | + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI), HID_QUIRK_ALWAYS_POLL }, | |
| 36 | 37 | { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM), HID_QUIRK_NOGET }, |
| 37 | 38 | { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC), HID_QUIRK_NOGET }, |
| 38 | 39 | { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM), HID_QUIRK_NOGET }, |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #define POWER_METER_CAN_NOTIFY (1 << 3) |
| 32 | 32 | #define POWER_METER_IS_BATTERY (1 << 8) |
| 33 | 33 | #define UNKNOWN_HYSTERESIS 0xFFFFFFFF |
| 34 | +#define UNKNOWN_POWER 0xFFFFFFFF | |
| 34 | 35 | |
| 35 | 36 | #define METER_NOTIFY_CONFIG 0x80 |
| 36 | 37 | #define METER_NOTIFY_TRIP 0x81 |
| @@ -348,6 +349,9 @@ static ssize_t show_power(struct device *dev, · 311 unmodified lines | ||
| 348 | 349 | update_meter(resource); |
| 349 | 350 | mutex_unlock(&resource->lock); |
| 350 | 351 | |
| 352 | + if (resource->power == UNKNOWN_POWER) | |
| 353 | + return -ENODATA; | |
| 354 | + | |
| 351 | 355 | return sprintf(buf, "%llu\n", resource->power * 1000); |
| 352 | 356 | } |
| 353 | 357 | |
| @@ -899,7 +899,23 @@ static struct hid_driver corsairpsu_driver = { · 898 unmodified lines | ||
| 899 | 899 | .reset_resume = corsairpsu_resume, |
| 900 | 900 | #endif |
| 901 | 901 | }; |
| 902 | −module_hid_driver(corsairpsu_driver); | |
| 902 | + | |
| 903 | +static int __init corsair_init(void) | |
| 904 | +{ | |
| 905 | + return hid_register_driver(&corsairpsu_driver); | |
| 906 | +} | |
| 907 | + | |
| 908 | +static void __exit corsair_exit(void) | |
| 909 | +{ | |
| 910 | + hid_unregister_driver(&corsairpsu_driver); | |
| 911 | +} | |
| 912 | + | |
| 913 | +/* | |
| 914 | + * With module_init() the driver would load before the HID bus when | |
| 915 | + * built-in, so use late_initcall() instead. | |
| 916 | + */ | |
| 917 | +late_initcall(corsair_init); | |
| 918 | +module_exit(corsair_exit); | |
| 903 | 919 | |
| 904 | 920 | MODULE_LICENSE("GPL"); |
| 905 | 921 | MODULE_AUTHOR("Wilken Gottwalt <wilken.gottwalt@posteo.net>"); |
| @@ -373,7 +373,7 @@ static int ltc2991_init(struct ltc2991_state *st) · 372 unmodified lines | ||
| 373 | 373 | LTC2991_REPEAT_ACQ_EN); |
| 374 | 374 | if (ret) |
| 375 | 375 | return dev_err_probe(st->dev, ret, |
| 376 | − "Error: Failed to set contiuous mode.\n"); | |
| 376 | + "Error: Failed to set continuous mode.\n"); | |
| 377 | 377 | |
| 378 | 378 | /* Enable all channels and trigger conversions */ |
| 379 | 379 | return regmap_write(st->regmap, LTC2991_CH_EN_TRIGGER, |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <linux/i2c.h> |
| 13 | 13 | #include <linux/mutex.h> |
| 14 | 14 | #include <linux/regmap.h> |
| 15 | +#include <linux/regulator/consumer.h> | |
| 15 | 16 | |
| 16 | 17 | #define MAX31827_T_REG 0x0 |
| 17 | 18 | #define MAX31827_CONFIGURATION_REG 0x2 |
| @@ -161,13 +161,13 @@ static int kraken2_probe(struct hid_device *hdev, · 160 unmodified lines | ||
| 161 | 161 | ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); |
| 162 | 162 | if (ret) { |
| 163 | 163 | hid_err(hdev, "hid hw start failed with %d\n", ret); |
| 164 | − goto fail_and_stop; | |
| 164 | + return ret; | |
| 165 | 165 | } |
| 166 | 166 | |
| 167 | 167 | ret = hid_hw_open(hdev); |
| 168 | 168 | if (ret) { |
| 169 | 169 | hid_err(hdev, "hid hw open failed with %d\n", ret); |
| 170 | − goto fail_and_close; | |
| 170 | + goto fail_and_stop; | |
| 171 | 171 | } |
| 172 | 172 | |
| 173 | 173 | priv->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "kraken2", |
| @@ -493,7 +493,7 @@ static void etm_event_start(struct perf_event *event, int flags) · 492 unmodified lines | ||
| 493 | 493 | goto fail_end_stop; |
| 494 | 494 | |
| 495 | 495 | /* Finally enable the tracer */ |
| 496 | − if (coresight_enable_source(csdev, CS_MODE_PERF, event)) | |
| 496 | + if (source_ops(csdev)->enable(csdev, event, CS_MODE_PERF)) | |
| 497 | 497 | goto fail_disable_path; |
| 498 | 498 | |
| 499 | 499 | /* |
| @@ -587,7 +587,7 @@ static void etm_event_stop(struct perf_event *event, int mode) · 87 unmodified lines | ||
| 587 | 587 | return; |
| 588 | 588 | |
| 589 | 589 | /* stop tracer */ |
| 590 | − coresight_disable_source(csdev, event); | |
| 590 | + source_ops(csdev)->disable(csdev, event); | |
| 591 | 591 | |
| 592 | 592 | /* tell the core */ |
| 593 | 593 | event->hw.state = PERF_HES_STOPPED; |
| @@ -2224,7 +2224,7 @@ static void clear_etmdrvdata(void *info) · 2223 unmodified lines | ||
| 2224 | 2224 | per_cpu(delayed_probe, cpu) = NULL; |
| 2225 | 2225 | } |
| 2226 | 2226 | |
| 2227 | −static void __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) | |
| 2227 | +static void etm4_remove_dev(struct etmv4_drvdata *drvdata) | |
| 2228 | 2228 | { |
| 2229 | 2229 | bool had_delayed_probe; |
| 2230 | 2230 | /* |
| @@ -2253,7 +2253,7 @@ static void __exit etm4_remove_dev(struct etmv4_drvdata *drvdata) · 22 unmodified lines | ||
| 2253 | 2253 | } |
| 2254 | 2254 | } |
| 2255 | 2255 | |
| 2256 | −static void __exit etm4_remove_amba(struct amba_device *adev) | |
| 2256 | +static void etm4_remove_amba(struct amba_device *adev) | |
| 2257 | 2257 | { |
| 2258 | 2258 | struct etmv4_drvdata *drvdata = dev_get_drvdata(&adev->dev); |
| 2259 | 2259 | |
| @@ -2261,7 +2261,7 @@ static void __exit etm4_remove_amba(struct amba_device *adev) · 1 unmodified line | ||
| 2261 | 2261 | etm4_remove_dev(drvdata); |
| 2262 | 2262 | } |
| 2263 | 2263 | |
| 2264 | −static int __exit etm4_remove_platform_dev(struct platform_device *pdev) | |
| 2264 | +static int etm4_remove_platform_dev(struct platform_device *pdev) | |
| 2265 | 2265 | { |
| 2266 | 2266 | struct etmv4_drvdata *drvdata = dev_get_drvdata(&pdev->dev); |
| 2267 | 2267 | |
| @@ -99,7 +99,7 @@ static int smb_open(struct inode *inode, struct file *file) · 98 unmodified lines | ||
| 99 | 99 | struct smb_drv_data, miscdev); |
| 100 | 100 | int ret = 0; |
| 101 | 101 | |
| 102 | − mutex_lock(&drvdata->mutex); | |
| 102 | + spin_lock(&drvdata->spinlock); | |
| 103 | 103 | |
| 104 | 104 | if (drvdata->reading) { |
| 105 | 105 | ret = -EBUSY; |
| @@ -115,7 +115,7 @@ static int smb_open(struct inode *inode, struct file *file) · 9 unmodified lines | ||
| 115 | 115 | |
| 116 | 116 | drvdata->reading = true; |
| 117 | 117 | out: |
| 118 | − mutex_unlock(&drvdata->mutex); | |
| 118 | + spin_unlock(&drvdata->spinlock); | |
| 119 | 119 | |
| 120 | 120 | return ret; |
| 121 | 121 | } |
| @@ -132,10 +132,8 @@ static ssize_t smb_read(struct file *file, char __user *data, size_t len, · 10 unmodified lines | ||
| 132 | 132 | if (!len) |
| 133 | 133 | return 0; |
| 134 | 134 | |
| 135 | − mutex_lock(&drvdata->mutex); | |
| 136 | − | |
| 137 | 135 | if (!sdb->data_size) |
| 138 | − goto out; | |
| 136 | + return 0; | |
| 139 | 137 | |
| 140 | 138 | to_copy = min(sdb->data_size, len); |
| 141 | 139 | |
| @@ -145,20 +143,15 @@ static ssize_t smb_read(struct file *file, char __user *data, size_t len, · 3 unmodified lines | ||
| 145 | 143 | |
| 146 | 144 | if (copy_to_user(data, sdb->buf_base + sdb->buf_rdptr, to_copy)) { |
| 147 | 145 | dev_dbg(dev, "Failed to copy data to user\n"); |
| 148 | − to_copy = -EFAULT; | |
| 149 | − goto out; | |
| 146 | + return -EFAULT; | |
| 150 | 147 | } |
| 151 | 148 | |
| 152 | 149 | *ppos += to_copy; |
| 153 | − | |
| 154 | 150 | smb_update_read_ptr(drvdata, to_copy); |
| 155 | − | |
| 156 | − dev_dbg(dev, "%zu bytes copied\n", to_copy); | |
| 157 | −out: | |
| 158 | 151 | if (!sdb->data_size) |
| 159 | 152 | smb_reset_buffer(drvdata); |
| 160 | − mutex_unlock(&drvdata->mutex); | |
| 161 | 153 | |
| 154 | + dev_dbg(dev, "%zu bytes copied\n", to_copy); | |
| 162 | 155 | return to_copy; |
| 163 | 156 | } |
| 164 | 157 | |
| @@ -167,9 +160,9 @@ static int smb_release(struct inode *inode, struct file *file) · 2 unmodified lines | ||
| 167 | 160 | struct smb_drv_data *drvdata = container_of(file->private_data, |
| 168 | 161 | struct smb_drv_data, miscdev); |
| 169 | 162 | |
| 170 | − mutex_lock(&drvdata->mutex); | |
| 163 | + spin_lock(&drvdata->spinlock); | |
| 171 | 164 | drvdata->reading = false; |
| 172 | − mutex_unlock(&drvdata->mutex); | |
| 165 | + spin_unlock(&drvdata->spinlock); | |
| 173 | 166 | |
| 174 | 167 | return 0; |
| 175 | 168 | } |
| @@ -262,7 +255,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode, · 86 unmodified lines | ||
| 262 | 255 | struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent); |
| 263 | 256 | int ret = 0; |
| 264 | 257 | |
| 265 | − mutex_lock(&drvdata->mutex); | |
| 258 | + spin_lock(&drvdata->spinlock); | |
| 266 | 259 | |
| 267 | 260 | /* Do nothing, the trace data is reading by other interface now */ |
| 268 | 261 | if (drvdata->reading) { |
| @@ -294,7 +287,7 @@ static int smb_enable(struct coresight_device *csdev, enum cs_mode mode, · 25 unmodified lines | ||
| 294 | 287 | |
| 295 | 288 | dev_dbg(&csdev->dev, "Ultrasoc SMB enabled\n"); |
| 296 | 289 | out: |
| 297 | − mutex_unlock(&drvdata->mutex); | |
| 290 | + spin_unlock(&drvdata->spinlock); | |
| 298 | 291 | |
| 299 | 292 | return ret; |
| 300 | 293 | } |
| @@ -304,7 +297,7 @@ static int smb_disable(struct coresight_device *csdev) · 3 unmodified lines | ||
| 304 | 297 | struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent); |
| 305 | 298 | int ret = 0; |
| 306 | 299 | |
| 307 | − mutex_lock(&drvdata->mutex); | |
| 300 | + spin_lock(&drvdata->spinlock); | |
| 308 | 301 | |
| 309 | 302 | if (drvdata->reading) { |
| 310 | 303 | ret = -EBUSY; |
| @@ -327,7 +320,7 @@ static int smb_disable(struct coresight_device *csdev) · 16 unmodified lines | ||
| 327 | 320 | |
| 328 | 321 | dev_dbg(&csdev->dev, "Ultrasoc SMB disabled\n"); |
| 329 | 322 | out: |
| 330 | − mutex_unlock(&drvdata->mutex); | |
| 323 | + spin_unlock(&drvdata->spinlock); | |
| 331 | 324 | |
| 332 | 325 | return ret; |
| 333 | 326 | } |
| @@ -408,7 +401,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev, · 74 unmodified lines | ||
| 408 | 401 | if (!buf) |
| 409 | 402 | return 0; |
| 410 | 403 | |
| 411 | − mutex_lock(&drvdata->mutex); | |
| 404 | + spin_lock(&drvdata->spinlock); | |
| 412 | 405 | |
| 413 | 406 | /* Don't do anything if another tracer is using this sink. */ |
| 414 | 407 | if (atomic_read(&csdev->refcnt) != 1) |
| @@ -432,7 +425,7 @@ static unsigned long smb_update_buffer(struct coresight_device *csdev, · 17 unmodified lines | ||
| 432 | 425 | if (!buf->snapshot && lost) |
| 433 | 426 | perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); |
| 434 | 427 | out: |
| 435 | − mutex_unlock(&drvdata->mutex); | |
| 428 | + spin_unlock(&drvdata->spinlock); | |
| 436 | 429 | |
| 437 | 430 | return data_size; |
| 438 | 431 | } |
| @@ -484,7 +477,6 @@ static int smb_init_data_buffer(struct platform_device *pdev, · 45 unmodified lines | ||
| 484 | 477 | static void smb_init_hw(struct smb_drv_data *drvdata) |
| 485 | 478 | { |
| 486 | 479 | smb_disable_hw(drvdata); |
| 487 | − smb_reset_buffer(drvdata); | |
| 488 | 480 | |
| 489 | 481 | writel(SMB_LB_CFG_LO_DEFAULT, drvdata->base + SMB_LB_CFG_LO_REG); |
| 490 | 482 | writel(SMB_LB_CFG_HI_DEFAULT, drvdata->base + SMB_LB_CFG_HI_REG); |
| @@ -590,37 +582,33 @@ static int smb_probe(struct platform_device *pdev) · 99 unmodified lines | ||
| 590 | 582 | return ret; |
| 591 | 583 | } |
| 592 | 584 | |
| 593 | − mutex_init(&drvdata->mutex); | |
| 585 | + ret = smb_config_inport(dev, true); | |
| 586 | + if (ret) | |
| 587 | + return ret; | |
| 588 | + | |
| 589 | + smb_reset_buffer(drvdata); | |
| 590 | + platform_set_drvdata(pdev, drvdata); | |
| 591 | + spin_lock_init(&drvdata->spinlock); | |
| 594 | 592 | drvdata->pid = -1; |
| 595 | 593 | |
| 596 | 594 | ret = smb_register_sink(pdev, drvdata); |
| 597 | 595 | if (ret) { |
| 596 | + smb_config_inport(&pdev->dev, false); | |
| 598 | 597 | dev_err(dev, "Failed to register SMB sink\n"); |
| 599 | 598 | return ret; |
| 600 | 599 | } |
| 601 | 600 | |
| 602 | − ret = smb_config_inport(dev, true); | |
| 603 | − if (ret) { | |
| 604 | − smb_unregister_sink(drvdata); | |
| 605 | − return ret; | |
| 606 | − } | |
| 607 | − | |
| 608 | − platform_set_drvdata(pdev, drvdata); | |
| 609 | − | |
| 610 | 601 | return 0; |
| 611 | 602 | } |
| 612 | 603 | |
| 613 | 604 | static int smb_remove(struct platform_device *pdev) |
| 614 | 605 | { |
| 615 | 606 | struct smb_drv_data *drvdata = platform_get_drvdata(pdev); |
| 616 | − int ret; | |
| 617 | − | |
| 618 | − ret = smb_config_inport(&pdev->dev, false); | |
| 619 | − if (ret) | |
| 620 | − return ret; | |
| 621 | 607 | |
| 622 | 608 | smb_unregister_sink(drvdata); |
| 623 | 609 | |
| 610 | + smb_config_inport(&pdev->dev, false); | |
| 611 | + | |
| 624 | 612 | return 0; |
| 625 | 613 | } |
| 626 | 614 | |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #define _ULTRASOC_SMB_H |
| 9 | 9 | |
| 10 | 10 | #include <linux/miscdevice.h> |
| 11 | −#include <linux/mutex.h> | |
| 11 | +#include <linux/spinlock.h> | |
| 12 | 12 | |
| 13 | 13 | /* Offset of SMB global registers */ |
| 14 | 14 | #define SMB_GLB_CFG_REG 0x00 |
| @@ -105,7 +105,7 @@ struct smb_data_buffer { · 90 unmodified lines | ||
| 105 | 105 | * @csdev: Component vitals needed by the framework. |
| 106 | 106 | * @sdb: Data buffer for SMB. |
| 107 | 107 | * @miscdev: Specifics to handle "/dev/xyz.smb" entry. |
| 108 | − * @mutex: Control data access to one at a time. | |
| 108 | + * @spinlock: Control data access to one at a time. | |
| 109 | 109 | * @reading: Synchronise user space access to SMB buffer. |
| 110 | 110 | * @pid: Process ID of the process being monitored by the |
| 111 | 111 | * session that is using this component. |
| @@ -116,7 +116,7 @@ struct smb_drv_data { · 4 unmodified lines | ||
| 116 | 116 | struct coresight_device *csdev; |
| 117 | 117 | struct smb_data_buffer sdb; |
| 118 | 118 | struct miscdevice miscdev; |
| 119 | − struct mutex mutex; | |
| 119 | + spinlock_t spinlock; | |
| 120 | 120 | bool reading; |
| 121 | 121 | pid_t pid; |
| 122 | 122 | enum cs_mode mode; |
| @@ -342,9 +342,9 @@ static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt) · 341 unmodified lines | ||
| 342 | 342 | return ret; |
| 343 | 343 | |
| 344 | 344 | hisi_ptt->trace_irq = pci_irq_vector(pdev, HISI_PTT_TRACE_DMA_IRQ); |
| 345 | − ret = devm_request_threaded_irq(&pdev->dev, hisi_ptt->trace_irq, | |
| 346 | − NULL, hisi_ptt_isr, 0, | |
| 347 | − DRV_NAME, hisi_ptt); | |
| 345 | + ret = devm_request_irq(&pdev->dev, hisi_ptt->trace_irq, hisi_ptt_isr, | |
| 346 | + IRQF_NOBALANCING | IRQF_NO_THREAD, DRV_NAME, | |
| 347 | + hisi_ptt); | |
| 348 | 348 | if (ret) { |
| 349 | 349 | pci_err(pdev, "failed to request irq %d, ret = %d\n", |
| 350 | 350 | hisi_ptt->trace_irq, ret); |
| @@ -1000,6 +1000,9 @@ static int hisi_ptt_pmu_event_init(struct perf_event *event) · 649 unmodified lines | ||
| 1000 | 1000 | return -EOPNOTSUPP; |
| 1001 | 1001 | } |
| 1002 | 1002 | |
| 1003 | + if (event->attach_state & PERF_ATTACH_TASK) | |
| 1004 | + return -EOPNOTSUPP; | |
| 1005 | + | |
| 1003 | 1006 | if (event->attr.type != hisi_ptt->hisi_ptt_pmu.type) |
| 1004 | 1007 | return -ENOENT; |
| 1005 | 1008 | |
| @@ -1178,6 +1181,10 @@ static void hisi_ptt_pmu_del(struct perf_event *event, int flags) · 172 unmodified lines | ||
| 1178 | 1181 | hisi_ptt_pmu_stop(event, PERF_EF_UPDATE); |
| 1179 | 1182 | } |
| 1180 | 1183 | |
| 1184 | +static void hisi_ptt_pmu_read(struct perf_event *event) | |
| 1185 | +{ | |
| 1186 | +} | |
| 1187 | + | |
| 1181 | 1188 | static void hisi_ptt_remove_cpuhp_instance(void *hotplug_node) |
| 1182 | 1189 | { |
| 1183 | 1190 | cpuhp_state_remove_instance_nocalls(hisi_ptt_pmu_online, hotplug_node); |
| @@ -1221,6 +1228,7 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt) · 37 unmodified lines | ||
| 1221 | 1228 | .stop = hisi_ptt_pmu_stop, |
| 1222 | 1229 | .add = hisi_ptt_pmu_add, |
| 1223 | 1230 | .del = hisi_ptt_pmu_del, |
| 1231 | + .read = hisi_ptt_pmu_read, | |
| 1224 | 1232 | }; |
| 1225 | 1233 | |
| 1226 | 1234 | reg = readl(hisi_ptt->iobase + HISI_PTT_LOCATION); |
| @@ -63,7 +63,7 @@ static int dw_reg_read(void *context, unsigned int reg, unsigned int *val) · 62 unmodified lines | ||
| 63 | 63 | { |
| 64 | 64 | struct dw_i2c_dev *dev = context; |
| 65 | 65 | |
| 66 | − *val = readl_relaxed(dev->base + reg); | |
| 66 | + *val = readl(dev->base + reg); | |
| 67 | 67 | |
| 68 | 68 | return 0; |
| 69 | 69 | } |
| @@ -72,7 +72,7 @@ static int dw_reg_write(void *context, unsigned int reg, unsigned int val) · 2 unmodified lines | ||
| 72 | 72 | { |
| 73 | 73 | struct dw_i2c_dev *dev = context; |
| 74 | 74 | |
| 75 | − writel_relaxed(val, dev->base + reg); | |
| 75 | + writel(val, dev->base + reg); | |
| 76 | 76 | |
| 77 | 77 | return 0; |
| 78 | 78 | } |
| @@ -81,7 +81,7 @@ static int dw_reg_read_swab(void *context, unsigned int reg, unsigned int *val) · 2 unmodified lines | ||
| 81 | 81 | { |
| 82 | 82 | struct dw_i2c_dev *dev = context; |
| 83 | 83 | |
| 84 | − *val = swab32(readl_relaxed(dev->base + reg)); | |
| 84 | + *val = swab32(readl(dev->base + reg)); | |
| 85 | 85 | |
| 86 | 86 | return 0; |
| 87 | 87 | } |
| @@ -90,7 +90,7 @@ static int dw_reg_write_swab(void *context, unsigned int reg, unsigned int val) · 2 unmodified lines | ||
| 90 | 90 | { |
| 91 | 91 | struct dw_i2c_dev *dev = context; |
| 92 | 92 | |
| 93 | − writel_relaxed(swab32(val), dev->base + reg); | |
| 93 | + writel(swab32(val), dev->base + reg); | |
| 94 | 94 | |
| 95 | 95 | return 0; |
| 96 | 96 | } |
| @@ -99,8 +99,8 @@ static int dw_reg_read_word(void *context, unsigned int reg, unsigned int *val) · 2 unmodified lines | ||
| 99 | 99 | { |
| 100 | 100 | struct dw_i2c_dev *dev = context; |
| 101 | 101 | |
| 102 | − *val = readw_relaxed(dev->base + reg) | | |
| 103 | − (readw_relaxed(dev->base + reg + 2) << 16); | |
| 102 | + *val = readw(dev->base + reg) | | |
| 103 | + (readw(dev->base + reg + 2) << 16); | |
| 104 | 104 | |
| 105 | 105 | return 0; |
| 106 | 106 | } |
| @@ -109,8 +109,8 @@ static int dw_reg_write_word(void *context, unsigned int reg, unsigned int val) · 2 unmodified lines | ||
| 109 | 109 | { |
| 110 | 110 | struct dw_i2c_dev *dev = context; |
| 111 | 111 | |
| 112 | − writew_relaxed(val, dev->base + reg); | |
| 113 | − writew_relaxed(val >> 16, dev->base + reg + 2); | |
| 112 | + writew(val, dev->base + reg); | |
| 113 | + writew(val >> 16, dev->base + reg + 2); | |
| 114 | 114 | |
| 115 | 115 | return 0; |
| 116 | 116 | } |
| @@ -771,8 +771,8 @@ static int ocores_i2c_resume(struct device *dev) · 770 unmodified lines | ||
| 771 | 771 | return ocores_init(dev, i2c); |
| 772 | 772 | } |
| 773 | 773 | |
| 774 | −static DEFINE_SIMPLE_DEV_PM_OPS(ocores_i2c_pm, | |
| 775 | − ocores_i2c_suspend, ocores_i2c_resume); | |
| 774 | +static DEFINE_NOIRQ_DEV_PM_OPS(ocores_i2c_pm, | |
| 775 | + ocores_i2c_suspend, ocores_i2c_resume); | |
| 776 | 776 | |
| 777 | 777 | static struct platform_driver ocores_i2c_driver = { |
| 778 | 778 | .probe = ocores_i2c_probe, |
| @@ -265,6 +265,9 @@ struct pxa_i2c { · 264 unmodified lines | ||
| 265 | 265 | u32 hs_mask; |
| 266 | 266 | |
| 267 | 267 | struct i2c_bus_recovery_info recovery; |
| 268 | + struct pinctrl *pinctrl; | |
| 269 | + struct pinctrl_state *pinctrl_default; | |
| 270 | + struct pinctrl_state *pinctrl_recovery; | |
| 268 | 271 | }; |
| 269 | 272 | |
| 270 | 273 | #define _IBMR(i2c) ((i2c)->reg_ibmr) |
| @@ -1299,12 +1302,13 @@ static void i2c_pxa_prepare_recovery(struct i2c_adapter *adap) · 1028 unmodified lines | ||
| 1299 | 1302 | */ |
| 1300 | 1303 | gpiod_set_value(i2c->recovery.scl_gpiod, ibmr & IBMR_SCLS); |
| 1301 | 1304 | gpiod_set_value(i2c->recovery.sda_gpiod, ibmr & IBMR_SDAS); |
| 1305 | + | |
| 1306 | + WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery)); | |
| 1302 | 1307 | } |
| 1303 | 1308 | |
| 1304 | 1309 | static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap) |
| 1305 | 1310 | { |
| 1306 | 1311 | struct pxa_i2c *i2c = adap->algo_data; |
| 1307 | − struct i2c_bus_recovery_info *bri = adap->bus_recovery_info; | |
| 1308 | 1312 | u32 isr; |
| 1309 | 1313 | |
| 1310 | 1314 | /* |
| @@ -1318,7 +1322,7 @@ static void i2c_pxa_unprepare_recovery(struct i2c_adapter *adap) · 7 unmodified lines | ||
| 1318 | 1322 | i2c_pxa_do_reset(i2c); |
| 1319 | 1323 | } |
| 1320 | 1324 | |
| 1321 | − WARN_ON(pinctrl_select_state(bri->pinctrl, bri->pins_default)); | |
| 1325 | + WARN_ON(pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default)); | |
| 1322 | 1326 | |
| 1323 | 1327 | dev_dbg(&i2c->adap.dev, "recovery: IBMR 0x%08x ISR 0x%08x\n", |
| 1324 | 1328 | readl(_IBMR(i2c)), readl(_ISR(i2c))); |
| @@ -1340,20 +1344,76 @@ static int i2c_pxa_init_recovery(struct pxa_i2c *i2c) · 15 unmodified lines | ||
| 1340 | 1344 | if (IS_ENABLED(CONFIG_I2C_PXA_SLAVE)) |
| 1341 | 1345 | return 0; |
| 1342 | 1346 | |
| 1343 | − bri->pinctrl = devm_pinctrl_get(dev); | |
| 1344 | − if (PTR_ERR(bri->pinctrl) == -ENODEV) { | |
| 1345 | − bri->pinctrl = NULL; | |
| 1347 | + i2c->pinctrl = devm_pinctrl_get(dev); | |
| 1348 | + if (PTR_ERR(i2c->pinctrl) == -ENODEV) | |
| 1349 | + i2c->pinctrl = NULL; | |
| 1350 | + if (IS_ERR(i2c->pinctrl)) | |
| 1351 | + return PTR_ERR(i2c->pinctrl); | |
| 1352 | + | |
| 1353 | + if (!i2c->pinctrl) | |
| 1354 | + return 0; | |
| 1355 | + | |
| 1356 | + i2c->pinctrl_default = pinctrl_lookup_state(i2c->pinctrl, | |
| 1357 | + PINCTRL_STATE_DEFAULT); | |
| 1358 | + i2c->pinctrl_recovery = pinctrl_lookup_state(i2c->pinctrl, "recovery"); | |
| 1359 | + | |
| 1360 | + if (IS_ERR(i2c->pinctrl_default) || IS_ERR(i2c->pinctrl_recovery)) { | |
| 1361 | + dev_info(dev, "missing pinmux recovery information: %ld %ld\n", | |
| 1362 | + PTR_ERR(i2c->pinctrl_default), | |
| 1363 | + PTR_ERR(i2c->pinctrl_recovery)); | |
| 1364 | + return 0; | |
| 1365 | + } | |
| 1366 | + | |
| 1367 | + /* | |
| 1368 | + * Claiming GPIOs can influence the pinmux state, and may glitch the | |
| 1369 | + * I2C bus. Do this carefully. | |
| 1370 | + */ | |
| 1371 | + bri->scl_gpiod = devm_gpiod_get(dev, "scl", GPIOD_OUT_HIGH_OPEN_DRAIN); | |
| 1372 | + if (bri->scl_gpiod == ERR_PTR(-EPROBE_DEFER)) | |
| 1373 | + return -EPROBE_DEFER; | |
| 1374 | + if (IS_ERR(bri->scl_gpiod)) { | |
| 1375 | + dev_info(dev, "missing scl gpio recovery information: %pe\n", | |
| 1376 | + bri->scl_gpiod); | |
| 1377 | + return 0; | |
| 1378 | + } | |
| 1379 | + | |
| 1380 | + /* | |
| 1381 | + * We have SCL. Pull SCL low and wait a bit so that SDA glitches | |
| 1382 | + * have no effect. | |
| 1383 | + */ | |
| 1384 | + gpiod_direction_output(bri->scl_gpiod, 0); | |
| 1385 | + udelay(10); | |
| 1386 | + bri->sda_gpiod = devm_gpiod_get(dev, "sda", GPIOD_OUT_HIGH_OPEN_DRAIN); | |
| 1387 | + | |
| 1388 | + /* Wait a bit in case of a SDA glitch, and then release SCL. */ | |
| 1389 | + udelay(10); | |
| 1390 | + gpiod_direction_output(bri->scl_gpiod, 1); | |
| 1391 | + | |
| 1392 | + if (bri->sda_gpiod == ERR_PTR(-EPROBE_DEFER)) | |
| 1393 | + return -EPROBE_DEFER; | |
| 1394 | + | |
| 1395 | + if (IS_ERR(bri->sda_gpiod)) { | |
| 1396 | + dev_info(dev, "missing sda gpio recovery information: %pe\n", | |
| 1397 | + bri->sda_gpiod); | |
| 1346 | 1398 | return 0; |
| 1347 | 1399 | } |
| 1348 | − if (IS_ERR(bri->pinctrl)) | |
| 1349 | − return PTR_ERR(bri->pinctrl); | |
| 1350 | 1400 | |
| 1351 | 1401 | bri->prepare_recovery = i2c_pxa_prepare_recovery; |
| 1352 | 1402 | bri->unprepare_recovery = i2c_pxa_unprepare_recovery; |
| 1403 | + bri->recover_bus = i2c_generic_scl_recovery; | |
| 1353 | 1404 | |
| 1354 | 1405 | i2c->adap.bus_recovery_info = bri; |
| 1355 | 1406 | |
| 1356 | − return 0; | |
| 1407 | + /* | |
| 1408 | + * Claiming GPIOs can change the pinmux state, which confuses the | |
| 1409 | + * pinctrl since pinctrl's idea of the current setting is unaffected | |
| 1410 | + * by the pinmux change caused by claiming the GPIO. Work around that | |
| 1411 | + * by switching pinctrl to the GPIO state here. We do it this way to | |
| 1412 | + * avoid glitching the I2C bus. | |
| 1413 | + */ | |
| 1414 | + pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_recovery); | |
| 1415 | + | |
| 1416 | + return pinctrl_select_state(i2c->pinctrl, i2c->pinctrl_default); | |
| 1357 | 1417 | } |
| 1358 | 1418 | |
| 1359 | 1419 | static int i2c_pxa_probe(struct platform_device *dev) |
| @@ -96,12 +96,6 @@ unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, · 95 unmodified lines | ||
| 96 | 96 | return page_size; |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | − /* rdma_for_each_block() has a bug if the page size is smaller than the | |
| 100 | − * page size used to build the umem. For now prevent smaller page sizes | |
| 101 | − * from being returned. | |
| 102 | − */ | |
| 103 | − pgsz_bitmap &= GENMASK(BITS_PER_LONG - 1, PAGE_SHIFT); | |
| 104 | − | |
| 105 | 99 | /* The best result is the smallest page size that results in the minimum |
| 106 | 100 | * number of required pages. Compute the largest page size that could |
| 107 | 101 | * work based on VA address bits that don't change. |
| @@ -1971,7 +1971,7 @@ int ib_get_eth_speed(struct ib_device *dev, u32 port_num, u16 *speed, u8 *width) · 1970 unmodified lines | ||
| 1971 | 1971 | int rc; |
| 1972 | 1972 | u32 netdev_speed; |
| 1973 | 1973 | struct net_device *netdev; |
| 1974 | − struct ethtool_link_ksettings lksettings; | |
| 1974 | + struct ethtool_link_ksettings lksettings = {}; | |
| 1975 | 1975 | |
| 1976 | 1976 | if (rdma_port_get_link_layer(dev, port_num) != IB_LINK_LAYER_ETHERNET) |
| 1977 | 1977 | return -EINVAL; |
| @@ -71,7 +71,7 @@ static char version[] = · 70 unmodified lines | ||
| 71 | 71 | BNXT_RE_DESC "\n"; |
| 72 | 72 | |
| 73 | 73 | MODULE_AUTHOR("Eddie Wai <eddie.wai@broadcom.com>"); |
| 74 | −MODULE_DESCRIPTION(BNXT_RE_DESC " Driver"); | |
| 74 | +MODULE_DESCRIPTION(BNXT_RE_DESC); | |
| 75 | 75 | MODULE_LICENSE("Dual BSD/GPL"); |
| 76 | 76 | |
| 77 | 77 | /* globals */ |
| @@ -4776,10 +4776,15 @@ static int check_cong_type(struct ib_qp *ibqp, · 4775 unmodified lines | ||
| 4776 | 4776 | cong_alg->wnd_mode_sel = WND_LIMIT; |
| 4777 | 4777 | break; |
| 4778 | 4778 | default: |
| 4779 | − ibdev_err(&hr_dev->ib_dev, | |
| 4780 | − "error type(%u) for congestion selection.\n", | |
| 4781 | − hr_dev->caps.cong_type); | |
| 4782 | − return -EINVAL; | |
| 4779 | + ibdev_warn(&hr_dev->ib_dev, | |
| 4780 | + "invalid type(%u) for congestion selection.\n", | |
| 4781 | + hr_dev->caps.cong_type); | |
| 4782 | + hr_dev->caps.cong_type = CONG_TYPE_DCQCN; | |
| 4783 | + cong_alg->alg_sel = CONG_DCQCN; | |
| 4784 | + cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL; | |
| 4785 | + cong_alg->dip_vld = DIP_INVALID; | |
| 4786 | + cong_alg->wnd_mode_sel = WND_LIMIT; | |
| 4787 | + break; | |
| 4783 | 4788 | } |
| 4784 | 4789 | |
| 4785 | 4790 | return 0; |
| @@ -321,7 +321,11 @@ static void irdma_process_aeq(struct irdma_pci_f *rf) · 320 unmodified lines | ||
| 321 | 321 | break; |
| 322 | 322 | case IRDMA_AE_QP_SUSPEND_COMPLETE: |
| 323 | 323 | if (iwqp->iwdev->vsi.tc_change_pending) { |
| 324 | − atomic_dec(&iwqp->sc_qp.vsi->qp_suspend_reqs); | |
| 324 | + if (!atomic_dec_return(&qp->vsi->qp_suspend_reqs)) | |
| 325 | + wake_up(&iwqp->iwdev->suspend_wq); | |
| 326 | + } | |
| 327 | + if (iwqp->suspend_pending) { | |
| 328 | + iwqp->suspend_pending = false; | |
| 325 | 329 | wake_up(&iwqp->iwdev->suspend_wq); |
| 326 | 330 | } |
| 327 | 331 | break; |
| @@ -581,9 +585,6 @@ static void irdma_destroy_cqp(struct irdma_pci_f *rf) · 253 unmodified lines | ||
| 581 | 585 | struct irdma_cqp *cqp = &rf->cqp; |
| 582 | 586 | int status = 0; |
| 583 | 587 | |
| 584 | − if (rf->cqp_cmpl_wq) | |
| 585 | − destroy_workqueue(rf->cqp_cmpl_wq); | |
| 586 | − | |
| 587 | 588 | status = irdma_sc_cqp_destroy(dev->cqp); |
| 588 | 589 | if (status) |
| 589 | 590 | ibdev_dbg(to_ibdev(dev), "ERR: Destroy CQP failed %d\n", status); |
| @@ -748,6 +749,9 @@ static void irdma_destroy_ccq(struct irdma_pci_f *rf) · 158 unmodified lines | ||
| 748 | 749 | struct irdma_ccq *ccq = &rf->ccq; |
| 749 | 750 | int status = 0; |
| 750 | 751 | |
| 752 | + if (rf->cqp_cmpl_wq) | |
| 753 | + destroy_workqueue(rf->cqp_cmpl_wq); | |
| 754 | + | |
| 751 | 755 | if (!rf->reset) |
| 752 | 756 | status = irdma_sc_ccq_destroy(dev->ccq, 0, true); |
| 753 | 757 | if (status) |
| @@ -1180,7 +1184,6 @@ static int irdma_create_ceq(struct irdma_pci_f *rf, struct irdma_ceq *iwceq, · 426 unmodified lines | ||
| 1180 | 1184 | int status; |
| 1181 | 1185 | struct irdma_ceq_init_info info = {}; |
| 1182 | 1186 | struct irdma_sc_dev *dev = &rf->sc_dev; |
| 1183 | − u64 scratch; | |
| 1184 | 1187 | u32 ceq_size; |
| 1185 | 1188 | |
| 1186 | 1189 | info.ceq_id = ceq_id; |
| @@ -1201,14 +1204,13 @@ static int irdma_create_ceq(struct irdma_pci_f *rf, struct irdma_ceq *iwceq, · 14 unmodified lines | ||
| 1201 | 1204 | iwceq->sc_ceq.ceq_id = ceq_id; |
| 1202 | 1205 | info.dev = dev; |
| 1203 | 1206 | info.vsi = vsi; |
| 1204 | − scratch = (uintptr_t)&rf->cqp.sc_cqp; | |
| 1205 | 1207 | status = irdma_sc_ceq_init(&iwceq->sc_ceq, &info); |
| 1206 | 1208 | if (!status) { |
| 1207 | 1209 | if (dev->ceq_valid) |
| 1208 | 1210 | status = irdma_cqp_ceq_cmd(&rf->sc_dev, &iwceq->sc_ceq, |
| 1209 | 1211 | IRDMA_OP_CEQ_CREATE); |
| 1210 | 1212 | else |
| 1211 | − status = irdma_sc_cceq_create(&iwceq->sc_ceq, scratch); | |
| 1213 | + status = irdma_sc_cceq_create(&iwceq->sc_ceq, 0); | |
| 1212 | 1214 | } |
| 1213 | 1215 | |
| 1214 | 1216 | if (status) { |
| @@ -48,7 +48,7 @@ static void irdma_prep_tc_change(struct irdma_device *iwdev) · 47 unmodified lines | ||
| 48 | 48 | /* Wait for all qp's to suspend */ |
| 49 | 49 | wait_event_timeout(iwdev->suspend_wq, |
| 50 | 50 | !atomic_read(&iwdev->vsi.qp_suspend_reqs), |
| 51 | − IRDMA_EVENT_TIMEOUT); | |
| 51 | + msecs_to_jiffies(IRDMA_EVENT_TIMEOUT_MS)); | |
| 52 | 52 | irdma_ws_reset(&iwdev->vsi); |
| 53 | 53 | } |
| 54 | 54 | |
| @@ -78,7 +78,7 @@ extern struct auxiliary_driver i40iw_auxiliary_drv; · 77 unmodified lines | ||
| 78 | 78 | |
| 79 | 79 | #define MAX_DPC_ITERATIONS 128 |
| 80 | 80 | |
| 81 | −#define IRDMA_EVENT_TIMEOUT 50000 | |
| 81 | +#define IRDMA_EVENT_TIMEOUT_MS 5000 | |
| 82 | 82 | #define IRDMA_VCHNL_EVENT_TIMEOUT 100000 |
| 83 | 83 | #define IRDMA_RST_TIMEOUT_HZ 4 |
| 84 | 84 | |
| @@ -1157,6 +1157,21 @@ exit: · 1156 unmodified lines | ||
| 1157 | 1157 | return prio; |
| 1158 | 1158 | } |
| 1159 | 1159 | |
| 1160 | +static int irdma_wait_for_suspend(struct irdma_qp *iwqp) | |
| 1161 | +{ | |
| 1162 | + if (!wait_event_timeout(iwqp->iwdev->suspend_wq, | |
| 1163 | + !iwqp->suspend_pending, | |
| 1164 | + msecs_to_jiffies(IRDMA_EVENT_TIMEOUT_MS))) { | |
| 1165 | + iwqp->suspend_pending = false; | |
| 1166 | + ibdev_warn(&iwqp->iwdev->ibdev, | |
| 1167 | + "modify_qp timed out waiting for suspend. qp_id = %d, last_ae = 0x%x\n", | |
| 1168 | + iwqp->ibqp.qp_num, iwqp->last_aeq); | |
| 1169 | + return -EBUSY; | |
| 1170 | + } | |
| 1171 | + | |
| 1172 | + return 0; | |
| 1173 | +} | |
| 1174 | + | |
| 1160 | 1175 | /** |
| 1161 | 1176 | * irdma_modify_qp_roce - modify qp request |
| 1162 | 1177 | * @ibqp: qp's pointer for modify |
| @@ -1420,17 +1435,11 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 257 unmodified lines | ||
| 1420 | 1435 | |
| 1421 | 1436 | info.next_iwarp_state = IRDMA_QP_STATE_SQD; |
| 1422 | 1437 | issue_modify_qp = 1; |
| 1438 | + iwqp->suspend_pending = true; | |
| 1423 | 1439 | break; |
| 1424 | 1440 | case IB_QPS_SQE: |
| 1425 | 1441 | case IB_QPS_ERR: |
| 1426 | 1442 | case IB_QPS_RESET: |
| 1427 | − if (iwqp->iwarp_state == IRDMA_QP_STATE_RTS) { | |
| 1428 | − spin_unlock_irqrestore(&iwqp->lock, flags); | |
| 1429 | − info.next_iwarp_state = IRDMA_QP_STATE_SQD; | |
| 1430 | − irdma_hw_modify_qp(iwdev, iwqp, &info, true); | |
| 1431 | − spin_lock_irqsave(&iwqp->lock, flags); | |
| 1432 | − } | |
| 1433 | − | |
| 1434 | 1443 | if (iwqp->iwarp_state == IRDMA_QP_STATE_ERROR) { |
| 1435 | 1444 | spin_unlock_irqrestore(&iwqp->lock, flags); |
| 1436 | 1445 | if (udata && udata->inlen) { |
| @@ -1467,6 +1476,11 @@ int irdma_modify_qp_roce(struct ib_qp *ibqp, struct ib_qp_attr *attr, · 30 unmodified lines | ||
| 1467 | 1476 | ctx_info->rem_endpoint_idx = udp_info->arp_idx; |
| 1468 | 1477 | if (irdma_hw_modify_qp(iwdev, iwqp, &info, true)) |
| 1469 | 1478 | return -EINVAL; |
| 1479 | + if (info.next_iwarp_state == IRDMA_QP_STATE_SQD) { | |
| 1480 | + ret = irdma_wait_for_suspend(iwqp); | |
| 1481 | + if (ret) | |
| 1482 | + return ret; | |
| 1483 | + } | |
| 1470 | 1484 | spin_lock_irqsave(&iwqp->lock, flags); |
| 1471 | 1485 | if (iwqp->iwarp_state == info.curr_iwarp_state) { |
| 1472 | 1486 | iwqp->iwarp_state = info.next_iwarp_state; |
| @@ -2900,7 +2914,7 @@ static struct irdma_mr *irdma_alloc_iwmr(struct ib_umem *region, · 1427 unmodified lines | ||
| 2900 | 2914 | iwmr->type = reg_type; |
| 2901 | 2915 | |
| 2902 | 2916 | pgsz_bitmap = (reg_type == IRDMA_MEMREG_TYPE_MEM) ? |
| 2903 | − iwdev->rf->sc_dev.hw_attrs.page_size_cap : PAGE_SIZE; | |
| 2917 | + iwdev->rf->sc_dev.hw_attrs.page_size_cap : SZ_4K; | |
| 2904 | 2918 | |
| 2905 | 2919 | iwmr->page_size = ib_umem_find_best_pgsz(region, pgsz_bitmap, virt); |
| 2906 | 2920 | if (unlikely(!iwmr->page_size)) { |
| @@ -2932,6 +2946,11 @@ static int irdma_reg_user_mr_type_qp(struct irdma_mem_reg_req req, · 25 unmodified lines | ||
| 2932 | 2946 | int err; |
| 2933 | 2947 | u8 lvl; |
| 2934 | 2948 | |
| 2949 | + /* iWarp: Catch page not starting on OS page boundary */ | |
| 2950 | + if (!rdma_protocol_roce(&iwdev->ibdev, 1) && | |
| 2951 | + ib_umem_offset(iwmr->region)) | |
| 2952 | + return -EINVAL; | |
| 2953 | + | |
| 2935 | 2954 | total = req.sq_pages + req.rq_pages + 1; |
| 2936 | 2955 | if (total > iwmr->page_cnt) |
| 2937 | 2956 | return -EINVAL; |
| @@ -198,6 +198,7 @@ struct irdma_qp { · 197 unmodified lines | ||
| 198 | 198 | u8 flush_issued : 1; |
| 199 | 199 | u8 sig_all : 1; |
| 200 | 200 | u8 pau_mode : 1; |
| 201 | + u8 suspend_pending : 1; | |
| 201 | 202 | u8 rsvd : 1; |
| 202 | 203 | u8 iwarp_state; |
| 203 | 204 | u16 term_sq_flush_code; |
| @@ -341,6 +341,8 @@ static enum mlx5_sw_icm_type get_icm_type(int uapi_type) · 340 unmodified lines | ||
| 341 | 341 | return MLX5_SW_ICM_TYPE_HEADER_MODIFY; |
| 342 | 342 | case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM: |
| 343 | 343 | return MLX5_SW_ICM_TYPE_HEADER_MODIFY_PATTERN; |
| 344 | + case MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM: | |
| 345 | + return MLX5_SW_ICM_TYPE_SW_ENCAP; | |
| 344 | 346 | case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM: |
| 345 | 347 | default: |
| 346 | 348 | return MLX5_SW_ICM_TYPE_STEERING; |
| @@ -364,6 +366,7 @@ static struct ib_dm *handle_alloc_dm_sw_icm(struct ib_ucontext *ctx, · 17 unmodified lines | ||
| 364 | 366 | switch (type) { |
| 365 | 367 | case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM: |
| 366 | 368 | case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM: |
| 369 | + case MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM: | |
| 367 | 370 | if (!(MLX5_CAP_FLOWTABLE_NIC_RX(dev, sw_owner) || |
| 368 | 371 | MLX5_CAP_FLOWTABLE_NIC_TX(dev, sw_owner) || |
| 369 | 372 | MLX5_CAP_FLOWTABLE_NIC_RX(dev, sw_owner_v2) || |
| @@ -438,6 +441,7 @@ struct ib_dm *mlx5_ib_alloc_dm(struct ib_device *ibdev, · 68 unmodified lines | ||
| 438 | 441 | case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM: |
| 439 | 442 | case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM: |
| 440 | 443 | case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM: |
| 444 | + case MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM: | |
| 441 | 445 | return handle_alloc_dm_sw_icm(context, attr, attrs, type); |
| 442 | 446 | default: |
| 443 | 447 | return ERR_PTR(-EOPNOTSUPP); |
| @@ -491,6 +495,7 @@ static int mlx5_ib_dealloc_dm(struct ib_dm *ibdm, · 47 unmodified lines | ||
| 491 | 495 | case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM: |
| 492 | 496 | case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM: |
| 493 | 497 | case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM: |
| 498 | + case MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM: | |
| 494 | 499 | return mlx5_dm_icm_dealloc(ctx, to_icm(ibdm)); |
| 495 | 500 | default: |
| 496 | 501 | return -EOPNOTSUPP; |
| @@ -818,6 +818,17 @@ static int mlx5_query_node_desc(struct mlx5_ib_dev *dev, char *node_desc) · 817 unmodified lines | ||
| 818 | 818 | MLX5_REG_NODE_DESC, 0, 0); |
| 819 | 819 | } |
| 820 | 820 | |
| 821 | +static void fill_esw_mgr_reg_c0(struct mlx5_core_dev *mdev, | |
| 822 | + struct mlx5_ib_query_device_resp *resp) | |
| 823 | +{ | |
| 824 | + struct mlx5_eswitch *esw = mdev->priv.eswitch; | |
| 825 | + u16 vport = mlx5_eswitch_manager_vport(mdev); | |
| 826 | + | |
| 827 | + resp->reg_c0.value = mlx5_eswitch_get_vport_metadata_for_match(esw, | |
| 828 | + vport); | |
| 829 | + resp->reg_c0.mask = mlx5_eswitch_get_vport_metadata_mask(); | |
| 830 | +} | |
| 831 | + | |
| 821 | 832 | static int mlx5_ib_query_device(struct ib_device *ibdev, |
| 822 | 833 | struct ib_device_attr *props, |
| 823 | 834 | struct ib_udata *uhw) |
| @@ -1209,6 +1220,19 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, · 385 unmodified lines | ||
| 1209 | 1220 | MLX5_CAP_GEN(mdev, log_max_dci_errored_streams); |
| 1210 | 1221 | } |
| 1211 | 1222 | |
| 1223 | + if (offsetofend(typeof(resp), reserved) <= uhw_outlen) | |
| 1224 | + resp.response_length += sizeof(resp.reserved); | |
| 1225 | + | |
| 1226 | + if (offsetofend(typeof(resp), reg_c0) <= uhw_outlen) { | |
| 1227 | + struct mlx5_eswitch *esw = mdev->priv.eswitch; | |
| 1228 | + | |
| 1229 | + resp.response_length += sizeof(resp.reg_c0); | |
| 1230 | + | |
| 1231 | + if (mlx5_eswitch_mode(mdev) == MLX5_ESWITCH_OFFLOADS && | |
| 1232 | + mlx5_eswitch_vport_match_metadata_enabled(esw)) | |
| 1233 | + fill_esw_mgr_reg_c0(mdev, &resp); | |
| 1234 | + } | |
| 1235 | + | |
| 1212 | 1236 | if (uhw_outlen) { |
| 1213 | 1237 | err = ib_copy_to_udata(uhw, &resp, resp.response_length); |
| 1214 | 1238 | |
| @@ -1347,6 +1347,7 @@ struct ib_mr *mlx5_ib_reg_dm_mr(struct ib_pd *pd, struct ib_dm *dm, · 1346 unmodified lines | ||
| 1347 | 1347 | case MLX5_IB_UAPI_DM_TYPE_STEERING_SW_ICM: |
| 1348 | 1348 | case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_SW_ICM: |
| 1349 | 1349 | case MLX5_IB_UAPI_DM_TYPE_HEADER_MODIFY_PATTERN_SW_ICM: |
| 1350 | + case MLX5_IB_UAPI_DM_TYPE_ENCAP_SW_ICM: | |
| 1350 | 1351 | if (attr->access_flags & ~MLX5_IB_DM_SW_ICM_ALLOWED_ACCESS) |
| 1351 | 1352 | return ERR_PTR(-EINVAL); |
| 1352 | 1353 | |
| @@ -384,7 +384,7 @@ static void complete_rdma_req(struct rtrs_clt_io_req *req, int errno, · 383 unmodified lines | ||
| 384 | 384 | struct rtrs_clt_path *clt_path; |
| 385 | 385 | int err; |
| 386 | 386 | |
| 387 | − if (WARN_ON(!req->in_use)) | |
| 387 | + if (!req->in_use) | |
| 388 | 388 | return; |
| 389 | 389 | if (WARN_ON(!req->con)) |
| 390 | 390 | return; |
| @@ -1699,7 +1699,7 @@ static int create_con_cq_qp(struct rtrs_clt_con *con) · 1308 unmodified lines | ||
| 1699 | 1699 | clt_path->s.dev_ref++; |
| 1700 | 1700 | max_send_wr = min_t(int, wr_limit, |
| 1701 | 1701 | /* QD * (REQ + RSP + FR REGS or INVS) + drain */ |
| 1702 | − clt_path->queue_depth * 3 + 1); | |
| 1702 | + clt_path->queue_depth * 4 + 1); | |
| 1703 | 1703 | max_recv_wr = min_t(int, wr_limit, |
| 1704 | 1704 | clt_path->queue_depth * 3 + 1); |
| 1705 | 1705 | max_send_sge = 2; |
| @@ -2350,8 +2350,6 @@ static int init_conns(struct rtrs_clt_path *clt_path) · 644 unmodified lines | ||
| 2350 | 2350 | if (err) |
| 2351 | 2351 | goto destroy; |
| 2352 | 2352 | |
| 2353 | − rtrs_start_hb(&clt_path->s); | |
| 2354 | − | |
| 2355 | 2353 | return 0; |
| 2356 | 2354 | |
| 2357 | 2355 | destroy: |
| @@ -2625,6 +2623,7 @@ static int init_path(struct rtrs_clt_path *clt_path) · 267 unmodified lines | ||
| 2625 | 2623 | goto out; |
| 2626 | 2624 | } |
| 2627 | 2625 | rtrs_clt_path_up(clt_path); |
| 2626 | + rtrs_start_hb(&clt_path->s); | |
| 2628 | 2627 | out: |
| 2629 | 2628 | mutex_unlock(&clt_path->init_mutex); |
| 2630 | 2629 | |
| @@ -65,8 +65,9 @@ static bool rtrs_srv_change_state(struct rtrs_srv_path *srv_path, · 64 unmodified lines | ||
| 65 | 65 | { |
| 66 | 66 | enum rtrs_srv_state old_state; |
| 67 | 67 | bool changed = false; |
| 68 | + unsigned long flags; | |
| 68 | 69 | |
| 69 | − spin_lock_irq(&srv_path->state_lock); | |
| 70 | + spin_lock_irqsave(&srv_path->state_lock, flags); | |
| 70 | 71 | old_state = srv_path->state; |
| 71 | 72 | switch (new_state) { |
| 72 | 73 | case RTRS_SRV_CONNECTED: |
| @@ -87,7 +88,7 @@ static bool rtrs_srv_change_state(struct rtrs_srv_path *srv_path, · 14 unmodified lines | ||
| 87 | 88 | } |
| 88 | 89 | if (changed) |
| 89 | 90 | srv_path->state = new_state; |
| 90 | − spin_unlock_irq(&srv_path->state_lock); | |
| 91 | + spin_unlock_irqrestore(&srv_path->state_lock, flags); | |
| 91 | 92 | |
| 92 | 93 | return changed; |
| 93 | 94 | } |
| @@ -550,7 +551,10 @@ static void unmap_cont_bufs(struct rtrs_srv_path *srv_path) · 456 unmodified lines | ||
| 550 | 551 | struct rtrs_srv_mr *srv_mr; |
| 551 | 552 | |
| 552 | 553 | srv_mr = &srv_path->mrs[i]; |
| 553 | − rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1); | |
| 554 | + | |
| 555 | + if (always_invalidate) | |
| 556 | + rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1); | |
| 557 | + | |
| 554 | 558 | ib_dereg_mr(srv_mr->mr); |
| 555 | 559 | ib_dma_unmap_sg(srv_path->s.dev->ib_dev, srv_mr->sgt.sgl, |
| 556 | 560 | srv_mr->sgt.nents, DMA_BIDIRECTIONAL); |
| @@ -709,20 +713,23 @@ static void rtrs_srv_info_rsp_done(struct ib_cq *cq, struct ib_wc *wc) · 152 unmodified lines | ||
| 709 | 713 | WARN_ON(wc->opcode != IB_WC_SEND); |
| 710 | 714 | } |
| 711 | 715 | |
| 712 | −static void rtrs_srv_path_up(struct rtrs_srv_path *srv_path) | |
| 716 | +static int rtrs_srv_path_up(struct rtrs_srv_path *srv_path) | |
| 713 | 717 | { |
| 714 | 718 | struct rtrs_srv_sess *srv = srv_path->srv; |
| 715 | 719 | struct rtrs_srv_ctx *ctx = srv->ctx; |
| 716 | − int up; | |
| 720 | + int up, ret = 0; | |
| 717 | 721 | |
| 718 | 722 | mutex_lock(&srv->paths_ev_mutex); |
| 719 | 723 | up = ++srv->paths_up; |
| 720 | 724 | if (up == 1) |
| 721 | − ctx->ops.link_ev(srv, RTRS_SRV_LINK_EV_CONNECTED, NULL); | |
| 725 | + ret = ctx->ops.link_ev(srv, RTRS_SRV_LINK_EV_CONNECTED, NULL); | |
| 722 | 726 | mutex_unlock(&srv->paths_ev_mutex); |
| 723 | 727 | |
| 724 | 728 | /* Mark session as established */ |
| 725 | − srv_path->established = true; | |
| 729 | + if (!ret) | |
| 730 | + srv_path->established = true; | |
| 731 | + | |
| 732 | + return ret; | |
| 726 | 733 | } |
| 727 | 734 | |
| 728 | 735 | static void rtrs_srv_path_down(struct rtrs_srv_path *srv_path) |
| @@ -851,7 +858,12 @@ static int process_info_req(struct rtrs_srv_con *con, · 122 unmodified lines | ||
| 851 | 858 | goto iu_free; |
| 852 | 859 | kobject_get(&srv_path->kobj); |
| 853 | 860 | get_device(&srv_path->srv->dev); |
| 854 | − rtrs_srv_change_state(srv_path, RTRS_SRV_CONNECTED); | |
| 861 | + err = rtrs_srv_change_state(srv_path, RTRS_SRV_CONNECTED); | |
| 862 | + if (!err) { | |
| 863 | + rtrs_err(s, "rtrs_srv_change_state(), err: %d\n", err); | |
| 864 | + goto iu_free; | |
| 865 | + } | |
| 866 | + | |
| 855 | 867 | rtrs_srv_start_hb(srv_path); |
| 856 | 868 | |
| 857 | 869 | /* |
| @@ -860,7 +872,11 @@ static int process_info_req(struct rtrs_srv_con *con, · 2 unmodified lines | ||
| 860 | 872 | * all connections are successfully established. Thus, simply notify |
| 861 | 873 | * listener with a proper event if we are the first path. |
| 862 | 874 | */ |
| 863 | − rtrs_srv_path_up(srv_path); | |
| 875 | + err = rtrs_srv_path_up(srv_path); | |
| 876 | + if (err) { | |
| 877 | + rtrs_err(s, "rtrs_srv_path_up(), err: %d\n", err); | |
| 878 | + goto iu_free; | |
| 879 | + } | |
| 864 | 880 | |
| 865 | 881 | ib_dma_sync_single_for_device(srv_path->s.dev->ib_dev, |
| 866 | 882 | tx_iu->dma_addr, |
| @@ -1516,7 +1532,6 @@ static void rtrs_srv_close_work(struct work_struct *work) · 649 unmodified lines | ||
| 1516 | 1532 | |
| 1517 | 1533 | srv_path = container_of(work, typeof(*srv_path), close_work); |
| 1518 | 1534 | |
| 1519 | − rtrs_srv_destroy_path_files(srv_path); | |
| 1520 | 1535 | rtrs_srv_stop_hb(srv_path); |
| 1521 | 1536 | |
| 1522 | 1537 | for (i = 0; i < srv_path->s.con_num; i++) { |
| @@ -1536,6 +1551,8 @@ static void rtrs_srv_close_work(struct work_struct *work) · 13 unmodified lines | ||
| 1536 | 1551 | /* Wait for all completion */ |
| 1537 | 1552 | wait_for_completion(&srv_path->complete_done); |
| 1538 | 1553 | |
| 1554 | + rtrs_srv_destroy_path_files(srv_path); | |
| 1555 | + | |
| 1539 | 1556 | /* Notify upper layer if we are the last path */ |
| 1540 | 1557 | rtrs_srv_path_down(srv_path); |
| 1541 | 1558 | |
| @@ -1522,6 +1522,15 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid, · 1521 unmodified lines | ||
| 1522 | 1522 | { |
| 1523 | 1523 | struct qi_desc desc; |
| 1524 | 1524 | |
| 1525 | + /* | |
| 1526 | + * VT-d spec, section 4.3: | |
| 1527 | + * | |
| 1528 | + * Software is recommended to not submit any Device-TLB invalidation | |
| 1529 | + * requests while address remapping hardware is disabled. | |
| 1530 | + */ | |
| 1531 | + if (!(iommu->gcmd & DMA_GCMD_TE)) | |
| 1532 | + return; | |
| 1533 | + | |
| 1525 | 1534 | if (mask) { |
| 1526 | 1535 | addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1; |
| 1527 | 1536 | desc.qw1 = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE; |
| @@ -1587,6 +1596,15 @@ void qi_flush_dev_iotlb_pasid(struct intel_iommu *iommu, u16 sid, u16 pfsid, · 59 unmodified lines | ||
| 1587 | 1596 | unsigned long mask = 1UL << (VTD_PAGE_SHIFT + size_order - 1); |
| 1588 | 1597 | struct qi_desc desc = {.qw1 = 0, .qw2 = 0, .qw3 = 0}; |
| 1589 | 1598 | |
| 1599 | + /* | |
| 1600 | + * VT-d spec, section 4.3: | |
| 1601 | + * | |
| 1602 | + * Software is recommended to not submit any Device-TLB invalidation | |
| 1603 | + * requests while address remapping hardware is disabled. | |
| 1604 | + */ | |
| 1605 | + if (!(iommu->gcmd & DMA_GCMD_TE)) | |
| 1606 | + return; | |
| 1607 | + | |
| 1590 | 1608 | desc.qw0 = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) | |
| 1591 | 1609 | QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE | |
| 1592 | 1610 | QI_DEV_IOTLB_PFSID(pfsid); |
| @@ -299,7 +299,7 @@ static int iommu_skip_te_disable; · 298 unmodified lines | ||
| 299 | 299 | #define IDENTMAP_AZALIA 4 |
| 300 | 300 | |
| 301 | 301 | const struct iommu_ops intel_iommu_ops; |
| 302 | −const struct iommu_dirty_ops intel_dirty_ops; | |
| 302 | +static const struct iommu_dirty_ops intel_dirty_ops; | |
| 303 | 303 | |
| 304 | 304 | static bool translation_pre_enabled(struct intel_iommu *iommu) |
| 305 | 305 | { |
| @@ -2207,6 +2207,8 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, · 1901 unmodified lines | ||
| 2207 | 2207 | attr |= DMA_FL_PTE_DIRTY; |
| 2208 | 2208 | } |
| 2209 | 2209 | |
| 2210 | + domain->has_mappings = true; | |
| 2211 | + | |
| 2210 | 2212 | pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | attr; |
| 2211 | 2213 | |
| 2212 | 2214 | while (nr_pages > 0) { |
| @@ -2490,7 +2492,8 @@ static int dmar_domain_attach_device(struct dmar_domain *domain, · 277 unmodified lines | ||
| 2490 | 2492 | return ret; |
| 2491 | 2493 | } |
| 2492 | 2494 | |
| 2493 | − iommu_enable_pci_caps(info); | |
| 2495 | + if (sm_supported(info->iommu) || !domain_type_is_si(info->domain)) | |
| 2496 | + iommu_enable_pci_caps(info); | |
| 2494 | 2497 | |
| 2495 | 2498 | return 0; |
| 2496 | 2499 | } |
| @@ -3925,8 +3928,8 @@ static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *op · 1428 unmodified lines | ||
| 3925 | 3928 | */ |
| 3926 | 3929 | static void domain_context_clear(struct device_domain_info *info) |
| 3927 | 3930 | { |
| 3928 | − if (!info->iommu || !info->dev || !dev_is_pci(info->dev)) | |
| 3929 | − return; | |
| 3931 | + if (!dev_is_pci(info->dev)) | |
| 3932 | + domain_context_clear_one(info, info->bus, info->devfn); | |
| 3930 | 3933 | |
| 3931 | 3934 | pci_for_each_dma_alias(to_pci_dev(info->dev), |
| 3932 | 3935 | &domain_context_clear_one_cb, info); |
| @@ -4360,7 +4363,8 @@ static bool intel_iommu_enforce_cache_coherency(struct iommu_domain *domain) · 427 unmodified lines | ||
| 4360 | 4363 | return true; |
| 4361 | 4364 | |
| 4362 | 4365 | spin_lock_irqsave(&dmar_domain->lock, flags); |
| 4363 | − if (!domain_support_force_snooping(dmar_domain)) { | |
| 4366 | + if (!domain_support_force_snooping(dmar_domain) || | |
| 4367 | + (!dmar_domain->use_first_level && dmar_domain->has_mappings)) { | |
| 4364 | 4368 | spin_unlock_irqrestore(&dmar_domain->lock, flags); |
| 4365 | 4369 | return false; |
| 4366 | 4370 | } |
| @@ -4925,7 +4929,7 @@ static int intel_iommu_read_and_clear_dirty(struct iommu_domain *domain, · 558 unmodified lines | ||
| 4925 | 4929 | return 0; |
| 4926 | 4930 | } |
| 4927 | 4931 | |
| 4928 | −const struct iommu_dirty_ops intel_dirty_ops = { | |
| 4932 | +static const struct iommu_dirty_ops intel_dirty_ops = { | |
| 4929 | 4933 | .set_dirty_tracking = intel_iommu_set_dirty_tracking, |
| 4930 | 4934 | .read_and_clear_dirty = intel_iommu_read_and_clear_dirty, |
| 4931 | 4935 | }; |
| @@ -5073,7 +5077,7 @@ static void quirk_igfx_skip_te_disable(struct pci_dev *dev) · 141 unmodified lines | ||
| 5073 | 5077 | ver = (dev->device >> 8) & 0xff; |
| 5074 | 5078 | if (ver != 0x45 && ver != 0x46 && ver != 0x4c && |
| 5075 | 5079 | ver != 0x4e && ver != 0x8a && ver != 0x98 && |
| 5076 | − ver != 0x9a && ver != 0xa7) | |
| 5080 | + ver != 0x9a && ver != 0xa7 && ver != 0x7d) | |
| 5077 | 5081 | return; |
| 5078 | 5082 | |
| 5079 | 5083 | if (risky_device(dev)) |
| @@ -602,6 +602,9 @@ struct dmar_domain { · 601 unmodified lines | ||
| 602 | 602 | */ |
| 603 | 603 | u8 dirty_tracking:1; /* Dirty tracking is enabled */ |
| 604 | 604 | u8 nested_parent:1; /* Has other domains nested on it */ |
| 605 | + u8 has_mappings:1; /* Has mappings configured through | |
| 606 | + * iommu_map() interface. | |
| 607 | + */ | |
| 605 | 608 | |
| 606 | 609 | spinlock_t lock; /* Protect device tracking lists */ |
| 607 | 610 | struct list_head devices; /* all devices' list */ |
| @@ -216,6 +216,27 @@ static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address, · 215 unmodified lines | ||
| 216 | 216 | rcu_read_unlock(); |
| 217 | 217 | } |
| 218 | 218 | |
| 219 | +static void intel_flush_svm_all(struct intel_svm *svm) | |
| 220 | +{ | |
| 221 | + struct device_domain_info *info; | |
| 222 | + struct intel_svm_dev *sdev; | |
| 223 | + | |
| 224 | + rcu_read_lock(); | |
| 225 | + list_for_each_entry_rcu(sdev, &svm->devs, list) { | |
| 226 | + info = dev_iommu_priv_get(sdev->dev); | |
| 227 | + | |
| 228 | + qi_flush_piotlb(sdev->iommu, sdev->did, svm->pasid, 0, -1UL, 0); | |
| 229 | + if (info->ats_enabled) { | |
| 230 | + qi_flush_dev_iotlb_pasid(sdev->iommu, sdev->sid, info->pfsid, | |
| 231 | + svm->pasid, sdev->qdep, | |
| 232 | + 0, 64 - VTD_PAGE_SHIFT); | |
| 233 | + quirk_extra_dev_tlb_flush(info, 0, 64 - VTD_PAGE_SHIFT, | |
| 234 | + svm->pasid, sdev->qdep); | |
| 235 | + } | |
| 236 | + } | |
| 237 | + rcu_read_unlock(); | |
| 238 | +} | |
| 239 | + | |
| 219 | 240 | /* Pages have been freed at this point */ |
| 220 | 241 | static void intel_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn, |
| 221 | 242 | struct mm_struct *mm, |
| @@ -223,6 +244,11 @@ static void intel_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn, · 1 unmodified line | ||
| 223 | 244 | { |
| 224 | 245 | struct intel_svm *svm = container_of(mn, struct intel_svm, notifier); |
| 225 | 246 | |
| 247 | + if (start == 0 && end == -1UL) { | |
| 248 | + intel_flush_svm_all(svm); | |
| 249 | + return; | |
| 250 | + } | |
| 251 | + | |
| 226 | 252 | intel_flush_svm_range(svm, start, |
| 227 | 253 | (end - start + PAGE_SIZE - 1) >> VTD_PAGE_SHIFT, 0); |
| 228 | 254 | } |
| @@ -485,11 +485,12 @@ static void iommu_deinit_device(struct device *dev) · 484 unmodified lines | ||
| 485 | 485 | dev_iommu_free(dev); |
| 486 | 486 | } |
| 487 | 487 | |
| 488 | +DEFINE_MUTEX(iommu_probe_device_lock); | |
| 489 | + | |
| 488 | 490 | static int __iommu_probe_device(struct device *dev, struct list_head *group_list) |
| 489 | 491 | { |
| 490 | 492 | const struct iommu_ops *ops = dev->bus->iommu_ops; |
| 491 | 493 | struct iommu_group *group; |
| 492 | − static DEFINE_MUTEX(iommu_probe_device_lock); | |
| 493 | 494 | struct group_device *gdev; |
| 494 | 495 | int ret; |
| 495 | 496 | |
| @@ -502,17 +503,15 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list · 6 unmodified lines | ||
| 502 | 503 | * probably be able to use device_lock() here to minimise the scope, |
| 503 | 504 | * but for now enforcing a simple global ordering is fine. |
| 504 | 505 | */ |
| 505 | − mutex_lock(&iommu_probe_device_lock); | |
| 506 | + lockdep_assert_held(&iommu_probe_device_lock); | |
| 506 | 507 | |
| 507 | 508 | /* Device is probed already if in a group */ |
| 508 | − if (dev->iommu_group) { | |
| 509 | − ret = 0; | |
| 510 | − goto out_unlock; | |
| 511 | − } | |
| 509 | + if (dev->iommu_group) | |
| 510 | + return 0; | |
| 512 | 511 | |
| 513 | 512 | ret = iommu_init_device(dev, ops); |
| 514 | 513 | if (ret) |
| 515 | − goto out_unlock; | |
| 514 | + return ret; | |
| 516 | 515 | |
| 517 | 516 | group = dev->iommu_group; |
| 518 | 517 | gdev = iommu_group_alloc_device(group, dev); |
| @@ -548,7 +547,6 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list · 29 unmodified lines | ||
| 548 | 547 | list_add_tail(&group->entry, group_list); |
| 549 | 548 | } |
| 550 | 549 | mutex_unlock(&group->mutex); |
| 551 | − mutex_unlock(&iommu_probe_device_lock); | |
| 552 | 550 | |
| 553 | 551 | if (dev_is_pci(dev)) |
| 554 | 552 | iommu_dma_set_pci_32bit_workaround(dev); |
| @@ -562,8 +560,6 @@ err_put_group: · 7 unmodified lines | ||
| 562 | 560 | iommu_deinit_device(dev); |
| 563 | 561 | mutex_unlock(&group->mutex); |
| 564 | 562 | iommu_group_put(group); |
| 565 | −out_unlock: | |
| 566 | − mutex_unlock(&iommu_probe_device_lock); | |
| 567 | 563 | |
| 568 | 564 | return ret; |
| 569 | 565 | } |
| @@ -573,7 +569,9 @@ int iommu_probe_device(struct device *dev) · 3 unmodified lines | ||
| 573 | 569 | const struct iommu_ops *ops; |
| 574 | 570 | int ret; |
| 575 | 571 | |
| 572 | + mutex_lock(&iommu_probe_device_lock); | |
| 576 | 573 | ret = __iommu_probe_device(dev, NULL); |
| 574 | + mutex_unlock(&iommu_probe_device_lock); | |
| 577 | 575 | if (ret) |
| 578 | 576 | return ret; |
| 579 | 577 | |
| @@ -1788,7 +1786,7 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type) · 1208 unmodified lines | ||
| 1788 | 1786 | */ |
| 1789 | 1787 | if (ops->default_domain) { |
| 1790 | 1788 | if (req_type) |
| 1791 | − return NULL; | |
| 1789 | + return ERR_PTR(-EINVAL); | |
| 1792 | 1790 | return ops->default_domain; |
| 1793 | 1791 | } |
| 1794 | 1792 | |
| @@ -1797,15 +1795,15 @@ iommu_group_alloc_default_domain(struct iommu_group *group, int req_type) · 2 unmodified lines | ||
| 1797 | 1795 | |
| 1798 | 1796 | /* The driver gave no guidance on what type to use, try the default */ |
| 1799 | 1797 | dom = __iommu_group_alloc_default_domain(group, iommu_def_domain_type); |
| 1800 | − if (dom) | |
| 1798 | + if (!IS_ERR(dom)) | |
| 1801 | 1799 | return dom; |
| 1802 | 1800 | |
| 1803 | 1801 | /* Otherwise IDENTITY and DMA_FQ defaults will try DMA */ |
| 1804 | 1802 | if (iommu_def_domain_type == IOMMU_DOMAIN_DMA) |
| 1805 | − return NULL; | |
| 1803 | + return ERR_PTR(-EINVAL); | |
| 1806 | 1804 | dom = __iommu_group_alloc_default_domain(group, IOMMU_DOMAIN_DMA); |
| 1807 | − if (!dom) | |
| 1808 | − return NULL; | |
| 1805 | + if (IS_ERR(dom)) | |
| 1806 | + return dom; | |
| 1809 | 1807 | |
| 1810 | 1808 | pr_warn("Failed to allocate default IOMMU domain of type %u for group %s - Falling back to IOMMU_DOMAIN_DMA", |
| 1811 | 1809 | iommu_def_domain_type, group->name); |
| @@ -1822,7 +1820,9 @@ static int probe_iommu_group(struct device *dev, void *data) · 10 unmodified lines | ||
| 1822 | 1820 | struct list_head *group_list = data; |
| 1823 | 1821 | int ret; |
| 1824 | 1822 | |
| 1823 | + mutex_lock(&iommu_probe_device_lock); | |
| 1825 | 1824 | ret = __iommu_probe_device(dev, group_list); |
| 1825 | + mutex_unlock(&iommu_probe_device_lock); | |
| 1826 | 1826 | if (ret == -ENODEV) |
| 1827 | 1827 | ret = 0; |
| 1828 | 1828 | |
| @@ -2094,10 +2094,17 @@ static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops, · 265 unmodified lines | ||
| 2094 | 2094 | else if (ops->domain_alloc) |
| 2095 | 2095 | domain = ops->domain_alloc(alloc_type); |
| 2096 | 2096 | else |
| 2097 | − return NULL; | |
| 2097 | + return ERR_PTR(-EOPNOTSUPP); | |
| 2098 | 2098 | |
| 2099 | + /* | |
| 2100 | + * Many domain_alloc ops now return ERR_PTR, make things easier for the | |
| 2101 | + * driver by accepting ERR_PTR from all domain_alloc ops instead of | |
| 2102 | + * having two rules. | |
| 2103 | + */ | |
| 2104 | + if (IS_ERR(domain)) | |
| 2105 | + return domain; | |
| 2099 | 2106 | if (!domain) |
| 2100 | − return NULL; | |
| 2107 | + return ERR_PTR(-ENOMEM); | |
| 2101 | 2108 | |
| 2102 | 2109 | domain->type = type; |
| 2103 | 2110 | /* |
| @@ -2110,9 +2117,14 @@ static struct iommu_domain *__iommu_domain_alloc(const struct iommu_ops *ops, · 6 unmodified lines | ||
| 2110 | 2117 | if (!domain->ops) |
| 2111 | 2118 | domain->ops = ops->default_domain_ops; |
| 2112 | 2119 | |
| 2113 | − if (iommu_is_dma_domain(domain) && iommu_get_dma_cookie(domain)) { | |
| 2114 | − iommu_domain_free(domain); | |
| 2115 | − domain = NULL; | |
| 2120 | + if (iommu_is_dma_domain(domain)) { | |
| 2121 | + int rc; | |
| 2122 | + | |
| 2123 | + rc = iommu_get_dma_cookie(domain); | |
| 2124 | + if (rc) { | |
| 2125 | + iommu_domain_free(domain); | |
| 2126 | + return ERR_PTR(rc); | |
| 2127 | + } | |
| 2116 | 2128 | } |
| 2117 | 2129 | return domain; |
| 2118 | 2130 | } |
| @@ -2129,10 +2141,15 @@ __iommu_group_domain_alloc(struct iommu_group *group, unsigned int type) · 10 unmodified lines | ||
| 2129 | 2141 | |
| 2130 | 2142 | struct iommu_domain *iommu_domain_alloc(const struct bus_type *bus) |
| 2131 | 2143 | { |
| 2144 | + struct iommu_domain *domain; | |
| 2145 | + | |
| 2132 | 2146 | if (bus == NULL || bus->iommu_ops == NULL) |
| 2133 | 2147 | return NULL; |
| 2134 | − return __iommu_domain_alloc(bus->iommu_ops, NULL, | |
| 2148 | + domain = __iommu_domain_alloc(bus->iommu_ops, NULL, | |
| 2135 | 2149 | IOMMU_DOMAIN_UNMANAGED); |
| 2150 | + if (IS_ERR(domain)) | |
| 2151 | + return NULL; | |
| 2152 | + return domain; | |
| 2136 | 2153 | } |
| 2137 | 2154 | EXPORT_SYMBOL_GPL(iommu_domain_alloc); |
| 2138 | 2155 | |
| @@ -3041,8 +3058,8 @@ static int iommu_setup_default_domain(struct iommu_group *group, · 902 unmodified lines | ||
| 3041 | 3058 | return -EINVAL; |
| 3042 | 3059 | |
| 3043 | 3060 | dom = iommu_group_alloc_default_domain(group, req_type); |
| 3044 | − if (!dom) | |
| 3045 | − return -ENODEV; | |
| 3061 | + if (IS_ERR(dom)) | |
| 3062 | + return PTR_ERR(dom); | |
| 3046 | 3063 | |
| 3047 | 3064 | if (group->default_domain == dom) |
| 3048 | 3065 | return 0; |
| @@ -3243,21 +3260,23 @@ void iommu_device_unuse_default_domain(struct device *dev) · 194 unmodified lines | ||
| 3243 | 3260 | |
| 3244 | 3261 | static int __iommu_group_alloc_blocking_domain(struct iommu_group *group) |
| 3245 | 3262 | { |
| 3263 | + struct iommu_domain *domain; | |
| 3264 | + | |
| 3246 | 3265 | if (group->blocking_domain) |
| 3247 | 3266 | return 0; |
| 3248 | 3267 | |
| 3249 | − group->blocking_domain = | |
| 3250 | − __iommu_group_domain_alloc(group, IOMMU_DOMAIN_BLOCKED); | |
| 3251 | − if (!group->blocking_domain) { | |
| 3268 | + domain = __iommu_group_domain_alloc(group, IOMMU_DOMAIN_BLOCKED); | |
| 3269 | + if (IS_ERR(domain)) { | |
| 3252 | 3270 | /* |
| 3253 | 3271 | * For drivers that do not yet understand IOMMU_DOMAIN_BLOCKED |
| 3254 | 3272 | * create an empty domain instead. |
| 3255 | 3273 | */ |
| 3256 | − group->blocking_domain = __iommu_group_domain_alloc( | |
| 3257 | − group, IOMMU_DOMAIN_UNMANAGED); | |
| 3258 | − if (!group->blocking_domain) | |
| 3259 | − return -EINVAL; | |
| 3274 | + domain = __iommu_group_domain_alloc(group, | |
| 3275 | + IOMMU_DOMAIN_UNMANAGED); | |
| 3276 | + if (IS_ERR(domain)) | |
| 3277 | + return PTR_ERR(domain); | |
| 3260 | 3278 | } |
| 3279 | + group->blocking_domain = domain; | |
| 3261 | 3280 | return 0; |
| 3262 | 3281 | } |
| 3263 | 3282 | |
| @@ -571,7 +571,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev, · 570 unmodified lines | ||
| 571 | 571 | continue; |
| 572 | 572 | destroy_hwpt = (*do_attach)(idev, hwpt); |
| 573 | 573 | if (IS_ERR(destroy_hwpt)) { |
| 574 | − iommufd_put_object(&hwpt->obj); | |
| 574 | + iommufd_put_object(idev->ictx, &hwpt->obj); | |
| 575 | 575 | /* |
| 576 | 576 | * -EINVAL means the domain is incompatible with the |
| 577 | 577 | * device. Other error codes should propagate to |
| @@ -583,7 +583,7 @@ iommufd_device_auto_get_domain(struct iommufd_device *idev, · 5 unmodified lines | ||
| 583 | 583 | goto out_unlock; |
| 584 | 584 | } |
| 585 | 585 | *pt_id = hwpt->obj.id; |
| 586 | − iommufd_put_object(&hwpt->obj); | |
| 586 | + iommufd_put_object(idev->ictx, &hwpt->obj); | |
| 587 | 587 | goto out_unlock; |
| 588 | 588 | } |
| 589 | 589 | |
| @@ -652,7 +652,7 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id, · 62 unmodified lines | ||
| 652 | 652 | destroy_hwpt = ERR_PTR(-EINVAL); |
| 653 | 653 | goto out_put_pt_obj; |
| 654 | 654 | } |
| 655 | − iommufd_put_object(pt_obj); | |
| 655 | + iommufd_put_object(idev->ictx, pt_obj); | |
| 656 | 656 | |
| 657 | 657 | /* This destruction has to be after we unlock everything */ |
| 658 | 658 | if (destroy_hwpt) |
| @@ -660,7 +660,7 @@ static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id, · 1 unmodified line | ||
| 660 | 660 | return 0; |
| 661 | 661 | |
| 662 | 662 | out_put_pt_obj: |
| 663 | − iommufd_put_object(pt_obj); | |
| 663 | + iommufd_put_object(idev->ictx, pt_obj); | |
| 664 | 664 | return PTR_ERR(destroy_hwpt); |
| 665 | 665 | } |
| 666 | 666 | |
| @@ -792,7 +792,7 @@ static int iommufd_access_change_ioas_id(struct iommufd_access *access, u32 id) · 125 unmodified lines | ||
| 792 | 792 | if (IS_ERR(ioas)) |
| 793 | 793 | return PTR_ERR(ioas); |
| 794 | 794 | rc = iommufd_access_change_ioas(access, ioas); |
| 795 | − iommufd_put_object(&ioas->obj); | |
| 795 | + iommufd_put_object(access->ictx, &ioas->obj); | |
| 796 | 796 | return rc; |
| 797 | 797 | } |
| 798 | 798 | |
| @@ -941,7 +941,7 @@ void iommufd_access_notify_unmap(struct io_pagetable *iopt, unsigned long iova, · 142 unmodified lines | ||
| 941 | 941 | |
| 942 | 942 | access->ops->unmap(access->data, iova, length); |
| 943 | 943 | |
| 944 | − iommufd_put_object(&access->obj); | |
| 944 | + iommufd_put_object(access->ictx, &access->obj); | |
| 945 | 945 | xa_lock(&ioas->iopt.access_list); |
| 946 | 946 | } |
| 947 | 947 | xa_unlock(&ioas->iopt.access_list); |
| @@ -1243,6 +1243,6 @@ int iommufd_get_hw_info(struct iommufd_ucmd *ucmd) · 295 unmodified lines | ||
| 1243 | 1243 | out_free: |
| 1244 | 1244 | kfree(data); |
| 1245 | 1245 | out_put: |
| 1246 | − iommufd_put_object(&idev->obj); | |
| 1246 | + iommufd_put_object(ucmd->ictx, &idev->obj); | |
| 1247 | 1247 | return rc; |
| 1248 | 1248 | } |
| @@ -318,9 +318,9 @@ out_unlock: · 317 unmodified lines | ||
| 318 | 318 | if (ioas) |
| 319 | 319 | mutex_unlock(&ioas->mutex); |
| 320 | 320 | out_put_pt: |
| 321 | − iommufd_put_object(pt_obj); | |
| 321 | + iommufd_put_object(ucmd->ictx, pt_obj); | |
| 322 | 322 | out_put_idev: |
| 323 | − iommufd_put_object(&idev->obj); | |
| 323 | + iommufd_put_object(ucmd->ictx, &idev->obj); | |
| 324 | 324 | return rc; |
| 325 | 325 | } |
| 326 | 326 | |
| @@ -345,7 +345,7 @@ int iommufd_hwpt_set_dirty_tracking(struct iommufd_ucmd *ucmd) · 18 unmodified lines | ||
| 345 | 345 | rc = iopt_set_dirty_tracking(&ioas->iopt, hwpt_paging->common.domain, |
| 346 | 346 | enable); |
| 347 | 347 | |
| 348 | − iommufd_put_object(&hwpt_paging->common.obj); | |
| 348 | + iommufd_put_object(ucmd->ictx, &hwpt_paging->common.obj); | |
| 349 | 349 | return rc; |
| 350 | 350 | } |
| 351 | 351 | |
| @@ -368,6 +368,6 @@ int iommufd_hwpt_get_dirty_bitmap(struct iommufd_ucmd *ucmd) · 16 unmodified lines | ||
| 368 | 368 | rc = iopt_read_and_clear_dirty_data( |
| 369 | 369 | &ioas->iopt, hwpt_paging->common.domain, cmd->flags, cmd); |
| 370 | 370 | |
| 371 | − iommufd_put_object(&hwpt_paging->common.obj); | |
| 371 | + iommufd_put_object(ucmd->ictx, &hwpt_paging->common.obj); | |
| 372 | 372 | return rc; |
| 373 | 373 | } |
| @@ -105,7 +105,7 @@ int iommufd_ioas_iova_ranges(struct iommufd_ucmd *ucmd) · 104 unmodified lines | ||
| 105 | 105 | rc = -EMSGSIZE; |
| 106 | 106 | out_put: |
| 107 | 107 | up_read(&ioas->iopt.iova_rwsem); |
| 108 | − iommufd_put_object(&ioas->obj); | |
| 108 | + iommufd_put_object(ucmd->ictx, &ioas->obj); | |
| 109 | 109 | return rc; |
| 110 | 110 | } |
| 111 | 111 | |
| @@ -175,7 +175,7 @@ out_free: · 63 unmodified lines | ||
| 175 | 175 | interval_tree_remove(node, &allowed_iova); |
| 176 | 176 | kfree(container_of(node, struct iopt_allowed, node)); |
| 177 | 177 | } |
| 178 | − iommufd_put_object(&ioas->obj); | |
| 178 | + iommufd_put_object(ucmd->ictx, &ioas->obj); | |
| 179 | 179 | return rc; |
| 180 | 180 | } |
| 181 | 181 | |
| @@ -228,7 +228,7 @@ int iommufd_ioas_map(struct iommufd_ucmd *ucmd) · 46 unmodified lines | ||
| 228 | 228 | cmd->iova = iova; |
| 229 | 229 | rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd)); |
| 230 | 230 | out_put: |
| 231 | − iommufd_put_object(&ioas->obj); | |
| 231 | + iommufd_put_object(ucmd->ictx, &ioas->obj); | |
| 232 | 232 | return rc; |
| 233 | 233 | } |
| 234 | 234 | |
| @@ -258,7 +258,7 @@ int iommufd_ioas_copy(struct iommufd_ucmd *ucmd) · 23 unmodified lines | ||
| 258 | 258 | return PTR_ERR(src_ioas); |
| 259 | 259 | rc = iopt_get_pages(&src_ioas->iopt, cmd->src_iova, cmd->length, |
| 260 | 260 | &pages_list); |
| 261 | − iommufd_put_object(&src_ioas->obj); | |
| 261 | + iommufd_put_object(ucmd->ictx, &src_ioas->obj); | |
| 262 | 262 | if (rc) |
| 263 | 263 | return rc; |
| 264 | 264 | |
| @@ -279,7 +279,7 @@ int iommufd_ioas_copy(struct iommufd_ucmd *ucmd) · 14 unmodified lines | ||
| 279 | 279 | cmd->dst_iova = iova; |
| 280 | 280 | rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd)); |
| 281 | 281 | out_put_dst: |
| 282 | − iommufd_put_object(&dst_ioas->obj); | |
| 282 | + iommufd_put_object(ucmd->ictx, &dst_ioas->obj); | |
| 283 | 283 | out_pages: |
| 284 | 284 | iopt_free_pages_list(&pages_list); |
| 285 | 285 | return rc; |
| @@ -315,7 +315,7 @@ int iommufd_ioas_unmap(struct iommufd_ucmd *ucmd) · 29 unmodified lines | ||
| 315 | 315 | rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd)); |
| 316 | 316 | |
| 317 | 317 | out_put: |
| 318 | − iommufd_put_object(&ioas->obj); | |
| 318 | + iommufd_put_object(ucmd->ictx, &ioas->obj); | |
| 319 | 319 | return rc; |
| 320 | 320 | } |
| 321 | 321 | |
| @@ -393,6 +393,6 @@ int iommufd_ioas_option(struct iommufd_ucmd *ucmd) · 71 unmodified lines | ||
| 393 | 393 | rc = -EOPNOTSUPP; |
| 394 | 394 | } |
| 395 | 395 | |
| 396 | − iommufd_put_object(&ioas->obj); | |
| 396 | + iommufd_put_object(ucmd->ictx, &ioas->obj); | |
| 397 | 397 | return rc; |
| 398 | 398 | } |
| @@ -21,6 +21,7 @@ struct iommufd_ctx { · 20 unmodified lines | ||
| 21 | 21 | struct file *file; |
| 22 | 22 | struct xarray objects; |
| 23 | 23 | struct xarray groups; |
| 24 | + wait_queue_head_t destroy_wait; | |
| 24 | 25 | |
| 25 | 26 | u8 account_mode; |
| 26 | 27 | /* Compatibility with VFIO no iommu */ |
| @@ -135,7 +136,7 @@ enum iommufd_object_type { · 108 unmodified lines | ||
| 135 | 136 | |
| 136 | 137 | /* Base struct for all objects with a userspace ID handle. */ |
| 137 | 138 | struct iommufd_object { |
| 138 | − struct rw_semaphore destroy_rwsem; | |
| 139 | + refcount_t shortterm_users; | |
| 139 | 140 | refcount_t users; |
| 140 | 141 | enum iommufd_object_type type; |
| 141 | 142 | unsigned int id; |
| @@ -143,10 +144,15 @@ struct iommufd_object { · 1 unmodified line | ||
| 143 | 144 | |
| 144 | 145 | static inline bool iommufd_lock_obj(struct iommufd_object *obj) |
| 145 | 146 | { |
| 146 | − if (!down_read_trylock(&obj->destroy_rwsem)) | |
| 147 | + if (!refcount_inc_not_zero(&obj->users)) | |
| 147 | 148 | return false; |
| 148 | − if (!refcount_inc_not_zero(&obj->users)) { | |
| 149 | − up_read(&obj->destroy_rwsem); | |
| 149 | + if (!refcount_inc_not_zero(&obj->shortterm_users)) { | |
| 150 | + /* | |
| 151 | + * If the caller doesn't already have a ref on obj this must be | |
| 152 | + * called under the xa_lock. Otherwise the caller is holding a | |
| 153 | + * ref on users. Thus it cannot be one before this decrement. | |
| 154 | + */ | |
| 155 | + refcount_dec(&obj->users); | |
| 150 | 156 | return false; |
| 151 | 157 | } |
| 152 | 158 | return true; |
| @@ -154,10 +160,16 @@ static inline bool iommufd_lock_obj(struct iommufd_object *obj) · 1 unmodified line | ||
| 154 | 160 | |
| 155 | 161 | struct iommufd_object *iommufd_get_object(struct iommufd_ctx *ictx, u32 id, |
| 156 | 162 | enum iommufd_object_type type); |
| 157 | −static inline void iommufd_put_object(struct iommufd_object *obj) | |
| 163 | +static inline void iommufd_put_object(struct iommufd_ctx *ictx, | |
| 164 | + struct iommufd_object *obj) | |
| 158 | 165 | { |
| 166 | + /* | |
| 167 | + * Users first, then shortterm so that REMOVE_WAIT_SHORTTERM never sees | |
| 168 | + * a spurious !0 users with a 0 shortterm_users. | |
| 169 | + */ | |
| 159 | 170 | refcount_dec(&obj->users); |
| 160 | − up_read(&obj->destroy_rwsem); | |
| 171 | + if (refcount_dec_and_test(&obj->shortterm_users)) | |
| 172 | + wake_up_interruptible_all(&ictx->destroy_wait); | |
| 161 | 173 | } |
| 162 | 174 | |
| 163 | 175 | void iommufd_object_abort(struct iommufd_ctx *ictx, struct iommufd_object *obj); |
| @@ -165,17 +177,49 @@ void iommufd_object_abort_and_destroy(struct iommufd_ctx *ictx, · 1 unmodified line | ||
| 165 | 177 | struct iommufd_object *obj); |
| 166 | 178 | void iommufd_object_finalize(struct iommufd_ctx *ictx, |
| 167 | 179 | struct iommufd_object *obj); |
| 168 | −void __iommufd_object_destroy_user(struct iommufd_ctx *ictx, | |
| 169 | − struct iommufd_object *obj, bool allow_fail); | |
| 180 | + | |
| 181 | +enum { | |
| 182 | + REMOVE_WAIT_SHORTTERM = 1, | |
| 183 | +}; | |
| 184 | +int iommufd_object_remove(struct iommufd_ctx *ictx, | |
| 185 | + struct iommufd_object *to_destroy, u32 id, | |
| 186 | + unsigned int flags); | |
| 187 | + | |
| 188 | +/* | |
| 189 | + * The caller holds a users refcount and wants to destroy the object. At this | |
| 190 | + * point the caller has no shortterm_users reference and at least the xarray | |
| 191 | + * will be holding one. | |
| 192 | + */ | |
| 170 | 193 | static inline void iommufd_object_destroy_user(struct iommufd_ctx *ictx, |
| 171 | 194 | struct iommufd_object *obj) |
| 172 | 195 | { |
| 173 | − __iommufd_object_destroy_user(ictx, obj, false); | |
| 196 | + int ret; | |
| 197 | + | |
| 198 | + ret = iommufd_object_remove(ictx, obj, obj->id, REMOVE_WAIT_SHORTTERM); | |
| 199 | + | |
| 200 | + /* | |
| 201 | + * If there is a bug and we couldn't destroy the object then we did put | |
| 202 | + * back the caller's users refcount and will eventually try to free it | |
| 203 | + * again during close. | |
| 204 | + */ | |
| 205 | + WARN_ON(ret); | |
| 174 | 206 | } |
| 175 | −static inline void iommufd_object_deref_user(struct iommufd_ctx *ictx, | |
| 176 | − struct iommufd_object *obj) | |
| 207 | + | |
| 208 | +/* | |
| 209 | + * The HWPT allocated by autodomains is used in possibly many devices and | |
| 210 | + * is automatically destroyed when its refcount reaches zero. | |
| 211 | + * | |
| 212 | + * If userspace uses the HWPT manually, even for a short term, then it will | |
| 213 | + * disrupt this refcounting and the auto-free in the kernel will not work. | |
| 214 | + * Userspace that tries to use the automatically allocated HWPT must be careful | |
| 215 | + * to ensure that it is consistently destroyed, eg by not racing accesses | |
| 216 | + * and by not attaching an automatic HWPT to a device manually. | |
| 217 | + */ | |
| 218 | +static inline void | |
| 219 | +iommufd_object_put_and_try_destroy(struct iommufd_ctx *ictx, | |
| 220 | + struct iommufd_object *obj) | |
| 177 | 221 | { |
| 178 | − __iommufd_object_destroy_user(ictx, obj, true); | |
| 222 | + iommufd_object_remove(ictx, obj, obj->id, 0); | |
| 179 | 223 | } |
| 180 | 224 | |
| 181 | 225 | struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx, |
| @@ -311,7 +355,7 @@ static inline void iommufd_hw_pagetable_put(struct iommufd_ctx *ictx, · 129 unmodified lines | ||
| 311 | 355 | lockdep_assert_not_held(&hwpt_paging->ioas->mutex); |
| 312 | 356 | |
| 313 | 357 | if (hwpt_paging->auto_domain) { |
| 314 | − iommufd_object_deref_user(ictx, &hwpt->obj); | |
| 358 | + iommufd_object_put_and_try_destroy(ictx, &hwpt->obj); | |
| 315 | 359 | return; |
| 316 | 360 | } |
| 317 | 361 | } |
| @@ -33,7 +33,6 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx, · 32 unmodified lines | ||
| 33 | 33 | size_t size, |
| 34 | 34 | enum iommufd_object_type type) |
| 35 | 35 | { |
| 36 | − static struct lock_class_key obj_keys[IOMMUFD_OBJ_MAX]; | |
| 37 | 36 | struct iommufd_object *obj; |
| 38 | 37 | int rc; |
| 39 | 38 | |
| @@ -41,15 +40,8 @@ struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx, · 1 unmodified line | ||
| 41 | 40 | if (!obj) |
| 42 | 41 | return ERR_PTR(-ENOMEM); |
| 43 | 42 | obj->type = type; |
| 44 | − /* | |
| 45 | − * In most cases the destroy_rwsem is obtained with try so it doesn't | |
| 46 | − * interact with lockdep, however on destroy we have to sleep. This | |
| 47 | − * means if we have to destroy an object while holding a get on another | |
| 48 | − * object it triggers lockdep. Using one locking class per object type | |
| 49 | − * is a simple and reasonable way to avoid this. | |
| 50 | − */ | |
| 51 | − __init_rwsem(&obj->destroy_rwsem, "iommufd_object::destroy_rwsem", | |
| 52 | − &obj_keys[type]); | |
| 43 | + /* Starts out bias'd by 1 until it is removed from the xarray */ | |
| 44 | + refcount_set(&obj->shortterm_users, 1); | |
| 53 | 45 | refcount_set(&obj->users, 1); |
| 54 | 46 | |
| 55 | 47 | /* |
| @@ -129,92 +121,113 @@ struct iommufd_object *iommufd_get_object(struct iommufd_ctx *ictx, u32 id, · 73 unmodified lines | ||
| 129 | 121 | return obj; |
| 130 | 122 | } |
| 131 | 123 | |
| 124 | +static int iommufd_object_dec_wait_shortterm(struct iommufd_ctx *ictx, | |
| 125 | + struct iommufd_object *to_destroy) | |
| 126 | +{ | |
| 127 | + if (refcount_dec_and_test(&to_destroy->shortterm_users)) | |
| 128 | + return 0; | |
| 129 | + | |
| 130 | + if (wait_event_timeout(ictx->destroy_wait, | |
| 131 | + refcount_read(&to_destroy->shortterm_users) == | |
| 132 | + 0, | |
| 133 | + msecs_to_jiffies(10000))) | |
| 134 | + return 0; | |
| 135 | + | |
| 136 | + pr_crit("Time out waiting for iommufd object to become free\n"); | |
| 137 | + refcount_inc(&to_destroy->shortterm_users); | |
| 138 | + return -EBUSY; | |
| 139 | +} | |
| 140 | + | |
| 132 | 141 | /* |
| 133 | 142 | * Remove the given object id from the xarray if the only reference to the |
| 134 | − * object is held by the xarray. The caller must call ops destroy(). | |
| 143 | + * object is held by the xarray. | |
| 135 | 144 | */ |
| 136 | −static struct iommufd_object *iommufd_object_remove(struct iommufd_ctx *ictx, | |
| 137 | − u32 id, bool extra_put) | |
| 145 | +int iommufd_object_remove(struct iommufd_ctx *ictx, | |
| 146 | + struct iommufd_object *to_destroy, u32 id, | |
| 147 | + unsigned int flags) | |
| 138 | 148 | { |
| 139 | 149 | struct iommufd_object *obj; |
| 140 | 150 | XA_STATE(xas, &ictx->objects, id); |
| 141 | − | |
| 142 | − xa_lock(&ictx->objects); | |
| 143 | − obj = xas_load(&xas); | |
| 144 | − if (xa_is_zero(obj) || !obj) { | |
| 145 | − obj = ERR_PTR(-ENOENT); | |
| 146 | − goto out_xa; | |
| 147 | − } | |
| 151 | + bool zerod_shortterm = false; | |
| 152 | + int ret; | |
| 148 | 153 | |
| 149 | 154 | /* |
| 150 | − * If the caller is holding a ref on obj we put it here under the | |
| 151 | − * spinlock. | |
| 155 | + * The purpose of the shortterm_users is to ensure deterministic | |
| 156 | + * destruction of objects used by external drivers and destroyed by this | |
| 157 | + * function. Any temporary increment of the refcount must increment | |
| 158 | + * shortterm_users, such as during ioctl execution. | |
| 152 | 159 | */ |
| 153 | − if (extra_put) | |
| 160 | + if (flags & REMOVE_WAIT_SHORTTERM) { | |
| 161 | + ret = iommufd_object_dec_wait_shortterm(ictx, to_destroy); | |
| 162 | + if (ret) { | |
| 163 | + /* | |
| 164 | + * We have a bug. Put back the callers reference and | |
| 165 | + * defer cleaning this object until close. | |
| 166 | + */ | |
| 167 | + refcount_dec(&to_destroy->users); | |
| 168 | + return ret; | |
| 169 | + } | |
| 170 | + zerod_shortterm = true; | |
| 171 | + } | |
| 172 | + | |
| 173 | + xa_lock(&ictx->objects); | |
| 174 | + obj = xas_load(&xas); | |
| 175 | + if (to_destroy) { | |
| 176 | + /* | |
| 177 | + * If the caller is holding a ref on obj we put it here under | |
| 178 | + * the spinlock. | |
| 179 | + */ | |
| 154 | 180 | refcount_dec(&obj->users); |
| 155 | 181 | |
| 182 | + if (WARN_ON(obj != to_destroy)) { | |
| 183 | + ret = -ENOENT; | |
| 184 | + goto err_xa; | |
| 185 | + } | |
| 186 | + } else if (xa_is_zero(obj) || !obj) { | |
| 187 | + ret = -ENOENT; | |
| 188 | + goto err_xa; | |
| 189 | + } | |
| 190 | + | |
| 156 | 191 | if (!refcount_dec_if_one(&obj->users)) { |
| 157 | − obj = ERR_PTR(-EBUSY); | |
| 158 | − goto out_xa; | |
| 192 | + ret = -EBUSY; | |
| 193 | + goto err_xa; | |
| 159 | 194 | } |
| 160 | 195 | |
| 161 | 196 | xas_store(&xas, NULL); |
| 162 | 197 | if (ictx->vfio_ioas == container_of(obj, struct iommufd_ioas, obj)) |
| 163 | 198 | ictx->vfio_ioas = NULL; |
| 164 | − | |
| 165 | −out_xa: | |
| 166 | 199 | xa_unlock(&ictx->objects); |
| 167 | 200 | |
| 168 | − /* The returned object reference count is zero */ | |
| 169 | − return obj; | |
| 170 | −} | |
| 171 | − | |
| 172 | −/* | |
| 173 | − * The caller holds a users refcount and wants to destroy the object. Returns | |
| 174 | − * true if the object was destroyed. In all cases the caller no longer has a | |
| 175 | − * reference on obj. | |
| 176 | − */ | |
| 177 | −void __iommufd_object_destroy_user(struct iommufd_ctx *ictx, | |
| 178 | − struct iommufd_object *obj, bool allow_fail) | |
| 179 | −{ | |
| 180 | − struct iommufd_object *ret; | |
| 181 | − | |
| 182 | 201 | /* |
| 183 | − * The purpose of the destroy_rwsem is to ensure deterministic | |
| 184 | − * destruction of objects used by external drivers and destroyed by this | |
| 185 | − * function. Any temporary increment of the refcount must hold the read | |
| 186 | − * side of this, such as during ioctl execution. | |
| 187 | − */ | |
| 188 | − down_write(&obj->destroy_rwsem); | |
| 189 | − ret = iommufd_object_remove(ictx, obj->id, true); | |
| 190 | − up_write(&obj->destroy_rwsem); | |
| 191 | − | |
| 192 | − if (allow_fail && IS_ERR(ret)) | |
| 193 | − return; | |
| 194 | − | |
| 195 | − /* | |
| 196 | − * If there is a bug and we couldn't destroy the object then we did put | |
| 197 | − * back the caller's refcount and will eventually try to free it again | |
| 198 | − * during close. | |
| 202 | + * Since users is zero any positive users_shortterm must be racing | |
| 203 | + * iommufd_put_object(), or we have a bug. | |
| 199 | 204 | */ |
| 200 | − if (WARN_ON(IS_ERR(ret))) | |
| 201 | − return; | |
| 205 | + if (!zerod_shortterm) { | |
| 206 | + ret = iommufd_object_dec_wait_shortterm(ictx, obj); | |
| 207 | + if (WARN_ON(ret)) | |
| 208 | + return ret; | |
| 209 | + } | |
| 202 | 210 | |
| 203 | 211 | iommufd_object_ops[obj->type].destroy(obj); |
| 204 | 212 | kfree(obj); |
| 213 | + return 0; | |
| 214 | + | |
| 215 | +err_xa: | |
| 216 | + if (zerod_shortterm) { | |
| 217 | + /* Restore the xarray owned reference */ | |
| 218 | + refcount_set(&obj->shortterm_users, 1); | |
| 219 | + } | |
| 220 | + xa_unlock(&ictx->objects); | |
| 221 | + | |
| 222 | + /* The returned object reference count is zero */ | |
| 223 | + return ret; | |
| 205 | 224 | } |
| 206 | 225 | |
| 207 | 226 | static int iommufd_destroy(struct iommufd_ucmd *ucmd) |
| 208 | 227 | { |
| 209 | 228 | struct iommu_destroy *cmd = ucmd->cmd; |
| 210 | − struct iommufd_object *obj; | |
| 211 | 229 | |
| 212 | − obj = iommufd_object_remove(ucmd->ictx, cmd->id, false); | |
| 213 | − if (IS_ERR(obj)) | |
| 214 | − return PTR_ERR(obj); | |
| 215 | − iommufd_object_ops[obj->type].destroy(obj); | |
| 216 | − kfree(obj); | |
| 217 | − return 0; | |
| 230 | + return iommufd_object_remove(ucmd->ictx, NULL, cmd->id, 0); | |
| 218 | 231 | } |
| 219 | 232 | |
| 220 | 233 | static int iommufd_fops_open(struct inode *inode, struct file *filp) |
| @@ -238,6 +251,7 @@ static int iommufd_fops_open(struct inode *inode, struct file *filp) · 17 unmodified lines | ||
| 238 | 251 | xa_init_flags(&ictx->objects, XA_FLAGS_ALLOC1 | XA_FLAGS_ACCOUNT); |
| 239 | 252 | xa_init(&ictx->groups); |
| 240 | 253 | ictx->file = filp; |
| 254 | + init_waitqueue_head(&ictx->destroy_wait); | |
| 241 | 255 | filp->private_data = ictx; |
| 242 | 256 | return 0; |
| 243 | 257 | } |
| @@ -86,7 +86,7 @@ void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd, · 85 unmodified lines | ||
| 86 | 86 | if (IS_ERR(ioas)) |
| 87 | 87 | return; |
| 88 | 88 | *iova = iommufd_test_syz_conv_iova(&ioas->iopt, iova); |
| 89 | − iommufd_put_object(&ioas->obj); | |
| 89 | + iommufd_put_object(ucmd->ictx, &ioas->obj); | |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | 92 | struct mock_iommu_domain { |
| @@ -500,7 +500,7 @@ get_md_pagetable(struct iommufd_ucmd *ucmd, u32 mockpt_id, · 407 unmodified lines | ||
| 500 | 500 | return hwpt; |
| 501 | 501 | if (hwpt->domain->type != IOMMU_DOMAIN_UNMANAGED || |
| 502 | 502 | hwpt->domain->ops != mock_ops.default_domain_ops) { |
| 503 | − iommufd_put_object(&hwpt->obj); | |
| 503 | + iommufd_put_object(ucmd->ictx, &hwpt->obj); | |
| 504 | 504 | return ERR_PTR(-EINVAL); |
| 505 | 505 | } |
| 506 | 506 | *mock = container_of(hwpt->domain, struct mock_iommu_domain, domain); |
| @@ -518,7 +518,7 @@ get_md_pagetable_nested(struct iommufd_ucmd *ucmd, u32 mockpt_id, · 11 unmodified lines | ||
| 518 | 518 | return hwpt; |
| 519 | 519 | if (hwpt->domain->type != IOMMU_DOMAIN_NESTED || |
| 520 | 520 | hwpt->domain->ops != &domain_nested_ops) { |
| 521 | − iommufd_put_object(&hwpt->obj); | |
| 521 | + iommufd_put_object(ucmd->ictx, &hwpt->obj); | |
| 522 | 522 | return ERR_PTR(-EINVAL); |
| 523 | 523 | } |
| 524 | 524 | *mock_nested = container_of(hwpt->domain, |
| @@ -681,7 +681,7 @@ static int iommufd_test_mock_domain_replace(struct iommufd_ucmd *ucmd, · 156 unmodified lines | ||
| 681 | 681 | rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd)); |
| 682 | 682 | |
| 683 | 683 | out_dev_obj: |
| 684 | − iommufd_put_object(dev_obj); | |
| 684 | + iommufd_put_object(ucmd->ictx, dev_obj); | |
| 685 | 685 | return rc; |
| 686 | 686 | } |
| 687 | 687 | |
| @@ -699,7 +699,7 @@ static int iommufd_test_add_reserved(struct iommufd_ucmd *ucmd, · 11 unmodified lines | ||
| 699 | 699 | down_write(&ioas->iopt.iova_rwsem); |
| 700 | 700 | rc = iopt_reserve_iova(&ioas->iopt, start, start + length - 1, NULL); |
| 701 | 701 | up_write(&ioas->iopt.iova_rwsem); |
| 702 | − iommufd_put_object(&ioas->obj); | |
| 702 | + iommufd_put_object(ucmd->ictx, &ioas->obj); | |
| 703 | 703 | return rc; |
| 704 | 704 | } |
| 705 | 705 | |
| @@ -754,7 +754,7 @@ static int iommufd_test_md_check_pa(struct iommufd_ucmd *ucmd, · 48 unmodified lines | ||
| 754 | 754 | rc = 0; |
| 755 | 755 | |
| 756 | 756 | out_put: |
| 757 | − iommufd_put_object(&hwpt->obj); | |
| 757 | + iommufd_put_object(ucmd->ictx, &hwpt->obj); | |
| 758 | 758 | return rc; |
| 759 | 759 | } |
| 760 | 760 | |
| @@ -1233,7 +1233,7 @@ static int iommufd_test_dirty(struct iommufd_ucmd *ucmd, unsigned int mockpt_id, · 472 unmodified lines | ||
| 1233 | 1233 | out_free: |
| 1234 | 1234 | kvfree(tmp); |
| 1235 | 1235 | out_put: |
| 1236 | − iommufd_put_object(&hwpt->obj); | |
| 1236 | + iommufd_put_object(ucmd->ictx, &hwpt->obj); | |
| 1237 | 1237 | return rc; |
| 1238 | 1238 | } |
| 1239 | 1239 | |
| @@ -41,7 +41,7 @@ int iommufd_vfio_compat_ioas_get_id(struct iommufd_ctx *ictx, u32 *out_ioas_id) · 40 unmodified lines | ||
| 41 | 41 | if (IS_ERR(ioas)) |
| 42 | 42 | return PTR_ERR(ioas); |
| 43 | 43 | *out_ioas_id = ioas->obj.id; |
| 44 | − iommufd_put_object(&ioas->obj); | |
| 44 | + iommufd_put_object(ictx, &ioas->obj); | |
| 45 | 45 | return 0; |
| 46 | 46 | } |
| 47 | 47 | EXPORT_SYMBOL_NS_GPL(iommufd_vfio_compat_ioas_get_id, IOMMUFD_VFIO); |
| @@ -98,7 +98,7 @@ int iommufd_vfio_compat_ioas_create(struct iommufd_ctx *ictx) · 50 unmodified lines | ||
| 98 | 98 | |
| 99 | 99 | if (ictx->vfio_ioas && iommufd_lock_obj(&ictx->vfio_ioas->obj)) { |
| 100 | 100 | ret = 0; |
| 101 | − iommufd_put_object(&ictx->vfio_ioas->obj); | |
| 101 | + iommufd_put_object(ictx, &ictx->vfio_ioas->obj); | |
| 102 | 102 | goto out_abort; |
| 103 | 103 | } |
| 104 | 104 | ictx->vfio_ioas = ioas; |
| @@ -133,7 +133,7 @@ int iommufd_vfio_ioas(struct iommufd_ucmd *ucmd) · 28 unmodified lines | ||
| 133 | 133 | if (IS_ERR(ioas)) |
| 134 | 134 | return PTR_ERR(ioas); |
| 135 | 135 | cmd->ioas_id = ioas->obj.id; |
| 136 | − iommufd_put_object(&ioas->obj); | |
| 136 | + iommufd_put_object(ucmd->ictx, &ioas->obj); | |
| 137 | 137 | return iommufd_ucmd_respond(ucmd, sizeof(*cmd)); |
| 138 | 138 | |
| 139 | 139 | case IOMMU_VFIO_IOAS_SET: |
| @@ -143,7 +143,7 @@ int iommufd_vfio_ioas(struct iommufd_ucmd *ucmd) · 3 unmodified lines | ||
| 143 | 143 | xa_lock(&ucmd->ictx->objects); |
| 144 | 144 | ucmd->ictx->vfio_ioas = ioas; |
| 145 | 145 | xa_unlock(&ucmd->ictx->objects); |
| 146 | − iommufd_put_object(&ioas->obj); | |
| 146 | + iommufd_put_object(ucmd->ictx, &ioas->obj); | |
| 147 | 147 | return 0; |
| 148 | 148 | |
| 149 | 149 | case IOMMU_VFIO_IOAS_CLEAR: |
| @@ -190,7 +190,7 @@ static int iommufd_vfio_map_dma(struct iommufd_ctx *ictx, unsigned int cmd, · 40 unmodified lines | ||
| 190 | 190 | iova = map.iova; |
| 191 | 191 | rc = iopt_map_user_pages(ictx, &ioas->iopt, &iova, u64_to_user_ptr(map.vaddr), |
| 192 | 192 | map.size, iommu_prot, 0); |
| 193 | − iommufd_put_object(&ioas->obj); | |
| 193 | + iommufd_put_object(ictx, &ioas->obj); | |
| 194 | 194 | return rc; |
| 195 | 195 | } |
| 196 | 196 | |
| @@ -249,7 +249,7 @@ static int iommufd_vfio_unmap_dma(struct iommufd_ctx *ictx, unsigned int cmd, · 52 unmodified lines | ||
| 249 | 249 | rc = -EFAULT; |
| 250 | 250 | |
| 251 | 251 | err_put: |
| 252 | − iommufd_put_object(&ioas->obj); | |
| 252 | + iommufd_put_object(ictx, &ioas->obj); | |
| 253 | 253 | return rc; |
| 254 | 254 | } |
| 255 | 255 | |
| @@ -272,7 +272,7 @@ static int iommufd_vfio_cc_iommu(struct iommufd_ctx *ictx) · 16 unmodified lines | ||
| 272 | 272 | } |
| 273 | 273 | mutex_unlock(&ioas->mutex); |
| 274 | 274 | |
| 275 | − iommufd_put_object(&ioas->obj); | |
| 275 | + iommufd_put_object(ictx, &ioas->obj); | |
| 276 | 276 | return rc; |
| 277 | 277 | } |
| 278 | 278 | |
| @@ -349,7 +349,7 @@ static int iommufd_vfio_set_iommu(struct iommufd_ctx *ictx, unsigned long type) · 70 unmodified lines | ||
| 349 | 349 | */ |
| 350 | 350 | if (type == VFIO_TYPE1_IOMMU) |
| 351 | 351 | rc = iopt_disable_large_pages(&ioas->iopt); |
| 352 | − iommufd_put_object(&ioas->obj); | |
| 352 | + iommufd_put_object(ictx, &ioas->obj); | |
| 353 | 353 | return rc; |
| 354 | 354 | } |
| 355 | 355 | |
| @@ -511,7 +511,7 @@ static int iommufd_vfio_iommu_get_info(struct iommufd_ctx *ictx, · 155 unmodified lines | ||
| 511 | 511 | |
| 512 | 512 | out_put: |
| 513 | 513 | up_read(&ioas->iopt.iova_rwsem); |
| 514 | − iommufd_put_object(&ioas->obj); | |
| 514 | + iommufd_put_object(ictx, &ioas->obj); | |
| 515 | 515 | return rc; |
| 516 | 516 | } |
| 517 | 517 | |
| @@ -112,16 +112,20 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, · 111 unmodified lines | ||
| 112 | 112 | const u32 *id) |
| 113 | 113 | { |
| 114 | 114 | const struct iommu_ops *ops = NULL; |
| 115 | − struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); | |
| 115 | + struct iommu_fwspec *fwspec; | |
| 116 | 116 | int err = NO_IOMMU; |
| 117 | 117 | |
| 118 | 118 | if (!master_np) |
| 119 | 119 | return NULL; |
| 120 | 120 | |
| 121 | + /* Serialise to make dev->iommu stable under our potential fwspec */ | |
| 122 | + mutex_lock(&iommu_probe_device_lock); | |
| 123 | + fwspec = dev_iommu_fwspec_get(dev); | |
| 121 | 124 | if (fwspec) { |
| 122 | − if (fwspec->ops) | |
| 125 | + if (fwspec->ops) { | |
| 126 | + mutex_unlock(&iommu_probe_device_lock); | |
| 123 | 127 | return fwspec->ops; |
| 124 | − | |
| 128 | + } | |
| 125 | 129 | /* In the deferred case, start again from scratch */ |
| 126 | 130 | iommu_fwspec_free(dev); |
| 127 | 131 | } |
| @@ -155,6 +159,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, · 27 unmodified lines | ||
| 155 | 159 | fwspec = dev_iommu_fwspec_get(dev); |
| 156 | 160 | ops = fwspec->ops; |
| 157 | 161 | } |
| 162 | + mutex_unlock(&iommu_probe_device_lock); | |
| 163 | + | |
| 158 | 164 | /* |
| 159 | 165 | * If we have reason to believe the IOMMU driver missed the initial |
| 160 | 166 | * probe for dev, replay it to get things in order. |
| @@ -191,7 +197,7 @@ iommu_resv_region_get_type(struct device *dev, · 30 unmodified lines | ||
| 191 | 197 | if (start == phys->start && end == phys->end) |
| 192 | 198 | return IOMMU_RESV_DIRECT; |
| 193 | 199 | |
| 194 | − dev_warn(dev, "treating non-direct mapping [%pr] -> [%pap-%pap] as reservation\n", &phys, | |
| 200 | + dev_warn(dev, "treating non-direct mapping [%pr] -> [%pap-%pap] as reservation\n", phys, | |
| 195 | 201 | &start, &end); |
| 196 | 202 | return IOMMU_RESV_RESERVED; |
| 197 | 203 | } |
| @@ -2379,12 +2379,12 @@ retry_baser: · 2378 unmodified lines | ||
| 2379 | 2379 | break; |
| 2380 | 2380 | } |
| 2381 | 2381 | |
| 2382 | + if (!shr) | |
| 2383 | + gic_flush_dcache_to_poc(base, PAGE_ORDER_TO_SIZE(order)); | |
| 2384 | + | |
| 2382 | 2385 | its_write_baser(its, baser, val); |
| 2383 | 2386 | tmp = baser->val; |
| 2384 | 2387 | |
| 2385 | − if (its->flags & ITS_FLAGS_FORCE_NON_SHAREABLE) | |
| 2386 | − tmp &= ~GITS_BASER_SHAREABILITY_MASK; | |
| 2387 | − | |
| 2388 | 2388 | if ((val ^ tmp) & GITS_BASER_SHAREABILITY_MASK) { |
| 2389 | 2389 | /* |
| 2390 | 2390 | * Shareability didn't stick. Just use |
| @@ -2394,10 +2394,9 @@ retry_baser: · 3 unmodified lines | ||
| 2394 | 2394 | * non-cacheable as well. |
| 2395 | 2395 | */ |
| 2396 | 2396 | shr = tmp & GITS_BASER_SHAREABILITY_MASK; |
| 2397 | − if (!shr) { | |
| 2397 | + if (!shr) | |
| 2398 | 2398 | cache = GITS_BASER_nC; |
| 2399 | − gic_flush_dcache_to_poc(base, PAGE_ORDER_TO_SIZE(order)); | |
| 2400 | − } | |
| 2399 | + | |
| 2401 | 2400 | goto retry_baser; |
| 2402 | 2401 | } |
| 2403 | 2402 | |
| @@ -2609,6 +2608,11 @@ static int its_alloc_tables(struct its_node *its) · 205 unmodified lines | ||
| 2609 | 2608 | /* erratum 24313: ignore memory access type */ |
| 2610 | 2609 | cache = GITS_BASER_nCnB; |
| 2611 | 2610 | |
| 2611 | + if (its->flags & ITS_FLAGS_FORCE_NON_SHAREABLE) { | |
| 2612 | + cache = GITS_BASER_nC; | |
| 2613 | + shr = 0; | |
| 2614 | + } | |
| 2615 | + | |
| 2612 | 2616 | for (i = 0; i < GITS_BASER_NR_REGS; i++) { |
| 2613 | 2617 | struct its_baser *baser = its->tables + i; |
| 2614 | 2618 | u64 val = its_read_baser(its, baser); |
| @@ -75,19 +75,6 @@ static ssize_t max_brightness_show(struct device *dev, · 74 unmodified lines | ||
| 75 | 75 | } |
| 76 | 76 | static DEVICE_ATTR_RO(max_brightness); |
| 77 | 77 | |
| 78 | −static ssize_t color_show(struct device *dev, | |
| 79 | − struct device_attribute *attr, char *buf) | |
| 80 | −{ | |
| 81 | − const char *color_text = "invalid"; | |
| 82 | − struct led_classdev *led_cdev = dev_get_drvdata(dev); | |
| 83 | − | |
| 84 | − if (led_cdev->color < LED_COLOR_ID_MAX) | |
| 85 | − color_text = led_colors[led_cdev->color]; | |
| 86 | − | |
| 87 | − return sysfs_emit(buf, "%s\n", color_text); | |
| 88 | −} | |
| 89 | −static DEVICE_ATTR_RO(color); | |
| 90 | − | |
| 91 | 78 | #ifdef CONFIG_LEDS_TRIGGERS |
| 92 | 79 | static BIN_ATTR(trigger, 0644, led_trigger_read, led_trigger_write, 0); |
| 93 | 80 | static struct bin_attribute *led_trigger_bin_attrs[] = { |
| @@ -102,7 +89,6 @@ static const struct attribute_group led_trigger_group = { · 8 unmodified lines | ||
| 102 | 89 | static struct attribute *led_class_attrs[] = { |
| 103 | 90 | &dev_attr_brightness.attr, |
| 104 | 91 | &dev_attr_max_brightness.attr, |
| 105 | − &dev_attr_color.attr, | |
| 106 | 92 | NULL, |
| 107 | 93 | }; |
| 108 | 94 | |
| @@ -226,6 +226,11 @@ static int set_device_name(struct led_netdev_data *trigger_data, · 225 unmodified lines | ||
| 226 | 226 | |
| 227 | 227 | cancel_delayed_work_sync(&trigger_data->work); |
| 228 | 228 | |
| 229 | + /* | |
| 230 | + * Take RTNL lock before trigger_data lock to prevent potential | |
| 231 | + * deadlock with netdev notifier registration. | |
| 232 | + */ | |
| 233 | + rtnl_lock(); | |
| 229 | 234 | mutex_lock(&trigger_data->lock); |
| 230 | 235 | |
| 231 | 236 | if (trigger_data->net_dev) { |
| @@ -245,16 +250,14 @@ static int set_device_name(struct led_netdev_data *trigger_data, · 13 unmodified lines | ||
| 245 | 250 | trigger_data->carrier_link_up = false; |
| 246 | 251 | trigger_data->link_speed = SPEED_UNKNOWN; |
| 247 | 252 | trigger_data->duplex = DUPLEX_UNKNOWN; |
| 248 | − if (trigger_data->net_dev != NULL) { | |
| 249 | − rtnl_lock(); | |
| 253 | + if (trigger_data->net_dev) | |
| 250 | 254 | get_device_state(trigger_data); |
| 251 | − rtnl_unlock(); | |
| 252 | − } | |
| 253 | 255 | |
| 254 | 256 | trigger_data->last_activity = 0; |
| 255 | 257 | |
| 256 | 258 | set_baseline_state(trigger_data); |
| 257 | 259 | mutex_unlock(&trigger_data->lock); |
| 260 | + rtnl_unlock(); | |
| 258 | 261 | |
| 259 | 262 | return 0; |
| 260 | 263 | } |
| @@ -265,6 +265,7 @@ struct bcache_device { · 264 unmodified lines | ||
| 265 | 265 | #define BCACHE_DEV_WB_RUNNING 3 |
| 266 | 266 | #define BCACHE_DEV_RATE_DW_RUNNING 4 |
| 267 | 267 | int nr_stripes; |
| 268 | +#define BCH_MIN_STRIPE_SZ ((4 << 20) >> SECTOR_SHIFT) | |
| 268 | 269 | unsigned int stripe_size; |
| 269 | 270 | atomic_t *stripe_sectors_dirty; |
| 270 | 271 | unsigned long *full_dirty_stripes; |
| @@ -293,16 +293,16 @@ static void btree_complete_write(struct btree *b, struct btree_write *w) · 292 unmodified lines | ||
| 293 | 293 | w->journal = NULL; |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | −static void btree_node_write_unlock(struct closure *cl) | |
| 296 | +static CLOSURE_CALLBACK(btree_node_write_unlock) | |
| 297 | 297 | { |
| 298 | − struct btree *b = container_of(cl, struct btree, io); | |
| 298 | + closure_type(b, struct btree, io); | |
| 299 | 299 | |
| 300 | 300 | up(&b->io_mutex); |
| 301 | 301 | } |
| 302 | 302 | |
| 303 | −static void __btree_node_write_done(struct closure *cl) | |
| 303 | +static CLOSURE_CALLBACK(__btree_node_write_done) | |
| 304 | 304 | { |
| 305 | − struct btree *b = container_of(cl, struct btree, io); | |
| 305 | + closure_type(b, struct btree, io); | |
| 306 | 306 | struct btree_write *w = btree_prev_write(b); |
| 307 | 307 | |
| 308 | 308 | bch_bbio_free(b->bio, b->c); |
| @@ -315,12 +315,12 @@ static void __btree_node_write_done(struct closure *cl) · 6 unmodified lines | ||
| 315 | 315 | closure_return_with_destructor(cl, btree_node_write_unlock); |
| 316 | 316 | } |
| 317 | 317 | |
| 318 | −static void btree_node_write_done(struct closure *cl) | |
| 318 | +static CLOSURE_CALLBACK(btree_node_write_done) | |
| 319 | 319 | { |
| 320 | − struct btree *b = container_of(cl, struct btree, io); | |
| 320 | + closure_type(b, struct btree, io); | |
| 321 | 321 | |
| 322 | 322 | bio_free_pages(b->bio); |
| 323 | − __btree_node_write_done(cl); | |
| 323 | + __btree_node_write_done(&cl->work); | |
| 324 | 324 | } |
| 325 | 325 | |
| 326 | 326 | static void btree_node_write_endio(struct bio *bio) |
| @@ -1000,6 +1000,9 @@ err: · 673 unmodified lines | ||
| 1000 | 1000 | * |
| 1001 | 1001 | * The btree node will have either a read or a write lock held, depending on |
| 1002 | 1002 | * level and op->lock. |
| 1003 | + * | |
| 1004 | + * Note: Only error code or btree pointer will be returned, it is unncessary | |
| 1005 | + * for callers to check NULL pointer. | |
| 1003 | 1006 | */ |
| 1004 | 1007 | struct btree *bch_btree_node_get(struct cache_set *c, struct btree_op *op, |
| 1005 | 1008 | struct bkey *k, int level, bool write, |
| @@ -1111,6 +1114,10 @@ retry: · 105 unmodified lines | ||
| 1111 | 1114 | mutex_unlock(&b->c->bucket_lock); |
| 1112 | 1115 | } |
| 1113 | 1116 | |
| 1117 | +/* | |
| 1118 | + * Only error code or btree pointer will be returned, it is unncessary for | |
| 1119 | + * callers to check NULL pointer. | |
| 1120 | + */ | |
| 1114 | 1121 | struct btree *__bch_btree_node_alloc(struct cache_set *c, struct btree_op *op, |
| 1115 | 1122 | int level, bool wait, |
| 1116 | 1123 | struct btree *parent) |
| @@ -1368,7 +1375,7 @@ static int btree_gc_coalesce(struct btree *b, struct btree_op *op, · 251 unmodified lines | ||
| 1368 | 1375 | memset(new_nodes, 0, sizeof(new_nodes)); |
| 1369 | 1376 | closure_init_stack(&cl); |
| 1370 | 1377 | |
| 1371 | − while (nodes < GC_MERGE_NODES && !IS_ERR(r[nodes].b)) | |
| 1378 | + while (nodes < GC_MERGE_NODES && !IS_ERR_OR_NULL(r[nodes].b)) | |
| 1372 | 1379 | keys += r[nodes++].keys; |
| 1373 | 1380 | |
| 1374 | 1381 | blocks = btree_default_blocks(b->c) * 2 / 3; |
| @@ -1515,7 +1522,7 @@ out_nocoalesce: · 140 unmodified lines | ||
| 1515 | 1522 | bch_keylist_free(&keylist); |
| 1516 | 1523 | |
| 1517 | 1524 | for (i = 0; i < nodes; i++) |
| 1518 | − if (!IS_ERR(new_nodes[i])) { | |
| 1525 | + if (!IS_ERR_OR_NULL(new_nodes[i])) { | |
| 1519 | 1526 | btree_node_free(new_nodes[i]); |
| 1520 | 1527 | rw_unlock(true, new_nodes[i]); |
| 1521 | 1528 | } |
| @@ -1532,6 +1539,8 @@ static int btree_gc_rewrite_node(struct btree *b, struct btree_op *op, · 10 unmodified lines | ||
| 1532 | 1539 | return 0; |
| 1533 | 1540 | |
| 1534 | 1541 | n = btree_node_alloc_replacement(replace, NULL); |
| 1542 | + if (IS_ERR(n)) | |
| 1543 | + return 0; | |
| 1535 | 1544 | |
| 1536 | 1545 | /* recheck reserve after allocating replacement node */ |
| 1537 | 1546 | if (btree_check_reserve(b, NULL)) { |
| @@ -723,11 +723,11 @@ static void journal_write_endio(struct bio *bio) · 722 unmodified lines | ||
| 723 | 723 | closure_put(&w->c->journal.io); |
| 724 | 724 | } |
| 725 | 725 | |
| 726 | −static void journal_write(struct closure *cl); | |
| 726 | +static CLOSURE_CALLBACK(journal_write); | |
| 727 | 727 | |
| 728 | −static void journal_write_done(struct closure *cl) | |
| 728 | +static CLOSURE_CALLBACK(journal_write_done) | |
| 729 | 729 | { |
| 730 | − struct journal *j = container_of(cl, struct journal, io); | |
| 730 | + closure_type(j, struct journal, io); | |
| 731 | 731 | struct journal_write *w = (j->cur == j->w) |
| 732 | 732 | ? &j->w[1] |
| 733 | 733 | : &j->w[0]; |
| @@ -736,19 +736,19 @@ static void journal_write_done(struct closure *cl) · 2 unmodified lines | ||
| 736 | 736 | continue_at_nobarrier(cl, journal_write, bch_journal_wq); |
| 737 | 737 | } |
| 738 | 738 | |
| 739 | −static void journal_write_unlock(struct closure *cl) | |
| 739 | +static CLOSURE_CALLBACK(journal_write_unlock) | |
| 740 | 740 | __releases(&c->journal.lock) |
| 741 | 741 | { |
| 742 | − struct cache_set *c = container_of(cl, struct cache_set, journal.io); | |
| 742 | + closure_type(c, struct cache_set, journal.io); | |
| 743 | 743 | |
| 744 | 744 | c->journal.io_in_flight = 0; |
| 745 | 745 | spin_unlock(&c->journal.lock); |
| 746 | 746 | } |
| 747 | 747 | |
| 748 | −static void journal_write_unlocked(struct closure *cl) | |
| 748 | +static CLOSURE_CALLBACK(journal_write_unlocked) | |
| 749 | 749 | __releases(c->journal.lock) |
| 750 | 750 | { |
| 751 | − struct cache_set *c = container_of(cl, struct cache_set, journal.io); | |
| 751 | + closure_type(c, struct cache_set, journal.io); | |
| 752 | 752 | struct cache *ca = c->cache; |
| 753 | 753 | struct journal_write *w = c->journal.cur; |
| 754 | 754 | struct bkey *k = &c->journal.key; |
| @@ -823,12 +823,12 @@ static void journal_write_unlocked(struct closure *cl) · 68 unmodified lines | ||
| 823 | 823 | continue_at(cl, journal_write_done, NULL); |
| 824 | 824 | } |
| 825 | 825 | |
| 826 | −static void journal_write(struct closure *cl) | |
| 826 | +static CLOSURE_CALLBACK(journal_write) | |
| 827 | 827 | { |
| 828 | − struct cache_set *c = container_of(cl, struct cache_set, journal.io); | |
| 828 | + closure_type(c, struct cache_set, journal.io); | |
| 829 | 829 | |
| 830 | 830 | spin_lock(&c->journal.lock); |
| 831 | − journal_write_unlocked(cl); | |
| 831 | + journal_write_unlocked(&cl->work); | |
| 832 | 832 | } |
| 833 | 833 | |
| 834 | 834 | static void journal_try_write(struct cache_set *c) |
| @@ -35,16 +35,16 @@ static bool moving_pred(struct keybuf *buf, struct bkey *k) · 34 unmodified lines | ||
| 35 | 35 | |
| 36 | 36 | /* Moving GC - IO loop */ |
| 37 | 37 | |
| 38 | −static void moving_io_destructor(struct closure *cl) | |
| 38 | +static CLOSURE_CALLBACK(moving_io_destructor) | |
| 39 | 39 | { |
| 40 | − struct moving_io *io = container_of(cl, struct moving_io, cl); | |
| 40 | + closure_type(io, struct moving_io, cl); | |
| 41 | 41 | |
| 42 | 42 | kfree(io); |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | −static void write_moving_finish(struct closure *cl) | |
| 45 | +static CLOSURE_CALLBACK(write_moving_finish) | |
| 46 | 46 | { |
| 47 | − struct moving_io *io = container_of(cl, struct moving_io, cl); | |
| 47 | + closure_type(io, struct moving_io, cl); | |
| 48 | 48 | struct bio *bio = &io->bio.bio; |
| 49 | 49 | |
| 50 | 50 | bio_free_pages(bio); |
| @@ -89,9 +89,9 @@ static void moving_init(struct moving_io *io) · 38 unmodified lines | ||
| 89 | 89 | bch_bio_map(bio, NULL); |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | −static void write_moving(struct closure *cl) | |
| 92 | +static CLOSURE_CALLBACK(write_moving) | |
| 93 | 93 | { |
| 94 | − struct moving_io *io = container_of(cl, struct moving_io, cl); | |
| 94 | + closure_type(io, struct moving_io, cl); | |
| 95 | 95 | struct data_insert_op *op = &io->op; |
| 96 | 96 | |
| 97 | 97 | if (!op->status) { |
| @@ -113,9 +113,9 @@ static void write_moving(struct closure *cl) · 15 unmodified lines | ||
| 113 | 113 | continue_at(cl, write_moving_finish, op->wq); |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | −static void read_moving_submit(struct closure *cl) | |
| 116 | +static CLOSURE_CALLBACK(read_moving_submit) | |
| 117 | 117 | { |
| 118 | − struct moving_io *io = container_of(cl, struct moving_io, cl); | |
| 118 | + closure_type(io, struct moving_io, cl); | |
| 119 | 119 | struct bio *bio = &io->bio.bio; |
| 120 | 120 | |
| 121 | 121 | bch_submit_bbio(bio, io->op.c, &io->w->key, 0); |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | struct kmem_cache *bch_search_cache; |
| 27 | 27 | |
| 28 | −static void bch_data_insert_start(struct closure *cl); | |
| 28 | +static CLOSURE_CALLBACK(bch_data_insert_start); | |
| 29 | 29 | |
| 30 | 30 | static unsigned int cache_mode(struct cached_dev *dc) |
| 31 | 31 | { |
| @@ -55,9 +55,9 @@ static void bio_csum(struct bio *bio, struct bkey *k) · 23 unmodified lines | ||
| 55 | 55 | |
| 56 | 56 | /* Insert data into cache */ |
| 57 | 57 | |
| 58 | −static void bch_data_insert_keys(struct closure *cl) | |
| 58 | +static CLOSURE_CALLBACK(bch_data_insert_keys) | |
| 59 | 59 | { |
| 60 | − struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); | |
| 60 | + closure_type(op, struct data_insert_op, cl); | |
| 61 | 61 | atomic_t *journal_ref = NULL; |
| 62 | 62 | struct bkey *replace_key = op->replace ? &op->replace_key : NULL; |
| 63 | 63 | int ret; |
| @@ -136,9 +136,9 @@ out: · 72 unmodified lines | ||
| 136 | 136 | continue_at(cl, bch_data_insert_keys, op->wq); |
| 137 | 137 | } |
| 138 | 138 | |
| 139 | −static void bch_data_insert_error(struct closure *cl) | |
| 139 | +static CLOSURE_CALLBACK(bch_data_insert_error) | |
| 140 | 140 | { |
| 141 | − struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); | |
| 141 | + closure_type(op, struct data_insert_op, cl); | |
| 142 | 142 | |
| 143 | 143 | /* |
| 144 | 144 | * Our data write just errored, which means we've got a bunch of keys to |
| @@ -163,7 +163,7 @@ static void bch_data_insert_error(struct closure *cl) · 18 unmodified lines | ||
| 163 | 163 | |
| 164 | 164 | op->insert_keys.top = dst; |
| 165 | 165 | |
| 166 | − bch_data_insert_keys(cl); | |
| 166 | + bch_data_insert_keys(&cl->work); | |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | 169 | static void bch_data_insert_endio(struct bio *bio) |
| @@ -184,9 +184,9 @@ static void bch_data_insert_endio(struct bio *bio) · 14 unmodified lines | ||
| 184 | 184 | bch_bbio_endio(op->c, bio, bio->bi_status, "writing data to cache"); |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | −static void bch_data_insert_start(struct closure *cl) | |
| 187 | +static CLOSURE_CALLBACK(bch_data_insert_start) | |
| 188 | 188 | { |
| 189 | − struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); | |
| 189 | + closure_type(op, struct data_insert_op, cl); | |
| 190 | 190 | struct bio *bio = op->bio, *n; |
| 191 | 191 | |
| 192 | 192 | if (op->bypass) |
| @@ -305,16 +305,16 @@ err: · 112 unmodified lines | ||
| 305 | 305 | * If op->bypass is true, instead of inserting the data it invalidates the |
| 306 | 306 | * region of the cache represented by op->bio and op->inode. |
| 307 | 307 | */ |
| 308 | −void bch_data_insert(struct closure *cl) | |
| 308 | +CLOSURE_CALLBACK(bch_data_insert) | |
| 309 | 309 | { |
| 310 | − struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); | |
| 310 | + closure_type(op, struct data_insert_op, cl); | |
| 311 | 311 | |
| 312 | 312 | trace_bcache_write(op->c, op->inode, op->bio, |
| 313 | 313 | op->writeback, op->bypass); |
| 314 | 314 | |
| 315 | 315 | bch_keylist_init(&op->insert_keys); |
| 316 | 316 | bio_get(op->bio); |
| 317 | − bch_data_insert_start(cl); | |
| 317 | + bch_data_insert_start(&cl->work); | |
| 318 | 318 | } |
| 319 | 319 | |
| 320 | 320 | /* |
| @@ -575,9 +575,9 @@ static int cache_lookup_fn(struct btree_op *op, struct btree *b, struct bkey *k) · 254 unmodified lines | ||
| 575 | 575 | return n == bio ? MAP_DONE : MAP_CONTINUE; |
| 576 | 576 | } |
| 577 | 577 | |
| 578 | −static void cache_lookup(struct closure *cl) | |
| 578 | +static CLOSURE_CALLBACK(cache_lookup) | |
| 579 | 579 | { |
| 580 | − struct search *s = container_of(cl, struct search, iop.cl); | |
| 580 | + closure_type(s, struct search, iop.cl); | |
| 581 | 581 | struct bio *bio = &s->bio.bio; |
| 582 | 582 | struct cached_dev *dc; |
| 583 | 583 | int ret; |
| @@ -698,9 +698,9 @@ static void do_bio_hook(struct search *s, · 114 unmodified lines | ||
| 698 | 698 | bio_cnt_set(bio, 3); |
| 699 | 699 | } |
| 700 | 700 | |
| 701 | −static void search_free(struct closure *cl) | |
| 701 | +static CLOSURE_CALLBACK(search_free) | |
| 702 | 702 | { |
| 703 | − struct search *s = container_of(cl, struct search, cl); | |
| 703 | + closure_type(s, struct search, cl); | |
| 704 | 704 | |
| 705 | 705 | atomic_dec(&s->iop.c->search_inflight); |
| 706 | 706 | |
| @@ -749,20 +749,20 @@ static inline struct search *search_alloc(struct bio *bio, · 42 unmodified lines | ||
| 749 | 749 | |
| 750 | 750 | /* Cached devices */ |
| 751 | 751 | |
| 752 | −static void cached_dev_bio_complete(struct closure *cl) | |
| 752 | +static CLOSURE_CALLBACK(cached_dev_bio_complete) | |
| 753 | 753 | { |
| 754 | − struct search *s = container_of(cl, struct search, cl); | |
| 754 | + closure_type(s, struct search, cl); | |
| 755 | 755 | struct cached_dev *dc = container_of(s->d, struct cached_dev, disk); |
| 756 | 756 | |
| 757 | 757 | cached_dev_put(dc); |
| 758 | − search_free(cl); | |
| 758 | + search_free(&cl->work); | |
| 759 | 759 | } |
| 760 | 760 | |
| 761 | 761 | /* Process reads */ |
| 762 | 762 | |
| 763 | −static void cached_dev_read_error_done(struct closure *cl) | |
| 763 | +static CLOSURE_CALLBACK(cached_dev_read_error_done) | |
| 764 | 764 | { |
| 765 | − struct search *s = container_of(cl, struct search, cl); | |
| 765 | + closure_type(s, struct search, cl); | |
| 766 | 766 | |
| 767 | 767 | if (s->iop.replace_collision) |
| 768 | 768 | bch_mark_cache_miss_collision(s->iop.c, s->d); |
| @@ -770,12 +770,12 @@ static void cached_dev_read_error_done(struct closure *cl) · 1 unmodified line | ||
| 770 | 770 | if (s->iop.bio) |
| 771 | 771 | bio_free_pages(s->iop.bio); |
| 772 | 772 | |
| 773 | − cached_dev_bio_complete(cl); | |
| 773 | + cached_dev_bio_complete(&cl->work); | |
| 774 | 774 | } |
| 775 | 775 | |
| 776 | −static void cached_dev_read_error(struct closure *cl) | |
| 776 | +static CLOSURE_CALLBACK(cached_dev_read_error) | |
| 777 | 777 | { |
| 778 | − struct search *s = container_of(cl, struct search, cl); | |
| 778 | + closure_type(s, struct search, cl); | |
| 779 | 779 | struct bio *bio = &s->bio.bio; |
| 780 | 780 | |
| 781 | 781 | /* |
| @@ -801,9 +801,9 @@ static void cached_dev_read_error(struct closure *cl) · 19 unmodified lines | ||
| 801 | 801 | continue_at(cl, cached_dev_read_error_done, NULL); |
| 802 | 802 | } |
| 803 | 803 | |
| 804 | −static void cached_dev_cache_miss_done(struct closure *cl) | |
| 804 | +static CLOSURE_CALLBACK(cached_dev_cache_miss_done) | |
| 805 | 805 | { |
| 806 | − struct search *s = container_of(cl, struct search, cl); | |
| 806 | + closure_type(s, struct search, cl); | |
| 807 | 807 | struct bcache_device *d = s->d; |
| 808 | 808 | |
| 809 | 809 | if (s->iop.replace_collision) |
| @@ -812,13 +812,13 @@ static void cached_dev_cache_miss_done(struct closure *cl) · 2 unmodified lines | ||
| 812 | 812 | if (s->iop.bio) |
| 813 | 813 | bio_free_pages(s->iop.bio); |
| 814 | 814 | |
| 815 | − cached_dev_bio_complete(cl); | |
| 815 | + cached_dev_bio_complete(&cl->work); | |
| 816 | 816 | closure_put(&d->cl); |
| 817 | 817 | } |
| 818 | 818 | |
| 819 | −static void cached_dev_read_done(struct closure *cl) | |
| 819 | +static CLOSURE_CALLBACK(cached_dev_read_done) | |
| 820 | 820 | { |
| 821 | − struct search *s = container_of(cl, struct search, cl); | |
| 821 | + closure_type(s, struct search, cl); | |
| 822 | 822 | struct cached_dev *dc = container_of(s->d, struct cached_dev, disk); |
| 823 | 823 | |
| 824 | 824 | /* |
| @@ -858,9 +858,9 @@ static void cached_dev_read_done(struct closure *cl) · 33 unmodified lines | ||
| 858 | 858 | continue_at(cl, cached_dev_cache_miss_done, NULL); |
| 859 | 859 | } |
| 860 | 860 | |
| 861 | −static void cached_dev_read_done_bh(struct closure *cl) | |
| 861 | +static CLOSURE_CALLBACK(cached_dev_read_done_bh) | |
| 862 | 862 | { |
| 863 | − struct search *s = container_of(cl, struct search, cl); | |
| 863 | + closure_type(s, struct search, cl); | |
| 864 | 864 | struct cached_dev *dc = container_of(s->d, struct cached_dev, disk); |
| 865 | 865 | |
| 866 | 866 | bch_mark_cache_accounting(s->iop.c, s->d, |
| @@ -955,13 +955,13 @@ static void cached_dev_read(struct cached_dev *dc, struct search *s) · 88 unmodified lines | ||
| 955 | 955 | |
| 956 | 956 | /* Process writes */ |
| 957 | 957 | |
| 958 | −static void cached_dev_write_complete(struct closure *cl) | |
| 958 | +static CLOSURE_CALLBACK(cached_dev_write_complete) | |
| 959 | 959 | { |
| 960 | − struct search *s = container_of(cl, struct search, cl); | |
| 960 | + closure_type(s, struct search, cl); | |
| 961 | 961 | struct cached_dev *dc = container_of(s->d, struct cached_dev, disk); |
| 962 | 962 | |
| 963 | 963 | up_read_non_owner(&dc->writeback_lock); |
| 964 | − cached_dev_bio_complete(cl); | |
| 964 | + cached_dev_bio_complete(&cl->work); | |
| 965 | 965 | } |
| 966 | 966 | |
| 967 | 967 | static void cached_dev_write(struct cached_dev *dc, struct search *s) |
| @@ -1048,9 +1048,9 @@ insert_data: · 80 unmodified lines | ||
| 1048 | 1048 | continue_at(cl, cached_dev_write_complete, NULL); |
| 1049 | 1049 | } |
| 1050 | 1050 | |
| 1051 | −static void cached_dev_nodata(struct closure *cl) | |
| 1051 | +static CLOSURE_CALLBACK(cached_dev_nodata) | |
| 1052 | 1052 | { |
| 1053 | − struct search *s = container_of(cl, struct search, cl); | |
| 1053 | + closure_type(s, struct search, cl); | |
| 1054 | 1054 | struct bio *bio = &s->bio.bio; |
| 1055 | 1055 | |
| 1056 | 1056 | if (s->iop.flush_journal) |
| @@ -1265,9 +1265,9 @@ static int flash_dev_cache_miss(struct btree *b, struct search *s, · 208 unmodified lines | ||
| 1265 | 1265 | return MAP_CONTINUE; |
| 1266 | 1266 | } |
| 1267 | 1267 | |
| 1268 | −static void flash_dev_nodata(struct closure *cl) | |
| 1268 | +static CLOSURE_CALLBACK(flash_dev_nodata) | |
| 1269 | 1269 | { |
| 1270 | − struct search *s = container_of(cl, struct search, cl); | |
| 1270 | + closure_type(s, struct search, cl); | |
| 1271 | 1271 | |
| 1272 | 1272 | if (s->iop.flush_journal) |
| 1273 | 1273 | bch_journal_meta(s->iop.c, cl); |
| @@ -34,7 +34,7 @@ struct data_insert_op { · 33 unmodified lines | ||
| 34 | 34 | }; |
| 35 | 35 | |
| 36 | 36 | unsigned int bch_get_congested(const struct cache_set *c); |
| 37 | −void bch_data_insert(struct closure *cl); | |
| 37 | +CLOSURE_CALLBACK(bch_data_insert); | |
| 38 | 38 | |
| 39 | 39 | void bch_cached_dev_request_init(struct cached_dev *dc); |
| 40 | 40 | void cached_dev_submit_bio(struct bio *bio); |
| @@ -327,9 +327,9 @@ static void __write_super(struct cache_sb *sb, struct cache_sb_disk *out, · 326 unmodified lines | ||
| 327 | 327 | submit_bio(bio); |
| 328 | 328 | } |
| 329 | 329 | |
| 330 | −static void bch_write_bdev_super_unlock(struct closure *cl) | |
| 330 | +static CLOSURE_CALLBACK(bch_write_bdev_super_unlock) | |
| 331 | 331 | { |
| 332 | − struct cached_dev *dc = container_of(cl, struct cached_dev, sb_write); | |
| 332 | + closure_type(dc, struct cached_dev, sb_write); | |
| 333 | 333 | |
| 334 | 334 | up(&dc->sb_write_mutex); |
| 335 | 335 | } |
| @@ -363,9 +363,9 @@ static void write_super_endio(struct bio *bio) · 27 unmodified lines | ||
| 363 | 363 | closure_put(&ca->set->sb_write); |
| 364 | 364 | } |
| 365 | 365 | |
| 366 | −static void bcache_write_super_unlock(struct closure *cl) | |
| 366 | +static CLOSURE_CALLBACK(bcache_write_super_unlock) | |
| 367 | 367 | { |
| 368 | − struct cache_set *c = container_of(cl, struct cache_set, sb_write); | |
| 368 | + closure_type(c, struct cache_set, sb_write); | |
| 369 | 369 | |
| 370 | 370 | up(&c->sb_write_mutex); |
| 371 | 371 | } |
| @@ -407,9 +407,9 @@ static void uuid_endio(struct bio *bio) · 35 unmodified lines | ||
| 407 | 407 | closure_put(cl); |
| 408 | 408 | } |
| 409 | 409 | |
| 410 | −static void uuid_io_unlock(struct closure *cl) | |
| 410 | +static CLOSURE_CALLBACK(uuid_io_unlock) | |
| 411 | 411 | { |
| 412 | − struct cache_set *c = container_of(cl, struct cache_set, uuid_write); | |
| 412 | + closure_type(c, struct cache_set, uuid_write); | |
| 413 | 413 | |
| 414 | 414 | up(&c->uuid_write_mutex); |
| 415 | 415 | } |
| @@ -905,6 +905,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size, · 489 unmodified lines | ||
| 905 | 905 | |
| 906 | 906 | if (!d->stripe_size) |
| 907 | 907 | d->stripe_size = 1 << 31; |
| 908 | + else if (d->stripe_size < BCH_MIN_STRIPE_SZ) | |
| 909 | + d->stripe_size = roundup(BCH_MIN_STRIPE_SZ, d->stripe_size); | |
| 908 | 910 | |
| 909 | 911 | n = DIV_ROUND_UP_ULL(sectors, d->stripe_size); |
| 910 | 912 | if (!n || n > max_stripes) { |
| @@ -1342,9 +1344,9 @@ void bch_cached_dev_release(struct kobject *kobj) · 431 unmodified lines | ||
| 1342 | 1344 | module_put(THIS_MODULE); |
| 1343 | 1345 | } |
| 1344 | 1346 | |
| 1345 | −static void cached_dev_free(struct closure *cl) | |
| 1347 | +static CLOSURE_CALLBACK(cached_dev_free) | |
| 1346 | 1348 | { |
| 1347 | − struct cached_dev *dc = container_of(cl, struct cached_dev, disk.cl); | |
| 1349 | + closure_type(dc, struct cached_dev, disk.cl); | |
| 1348 | 1350 | |
| 1349 | 1351 | if (test_and_clear_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags)) |
| 1350 | 1352 | cancel_writeback_rate_update_dwork(dc); |
| @@ -1376,9 +1378,9 @@ static void cached_dev_free(struct closure *cl) · 25 unmodified lines | ||
| 1376 | 1378 | kobject_put(&dc->disk.kobj); |
| 1377 | 1379 | } |
| 1378 | 1380 | |
| 1379 | −static void cached_dev_flush(struct closure *cl) | |
| 1381 | +static CLOSURE_CALLBACK(cached_dev_flush) | |
| 1380 | 1382 | { |
| 1381 | − struct cached_dev *dc = container_of(cl, struct cached_dev, disk.cl); | |
| 1383 | + closure_type(dc, struct cached_dev, disk.cl); | |
| 1382 | 1384 | struct bcache_device *d = &dc->disk; |
| 1383 | 1385 | |
| 1384 | 1386 | mutex_lock(&bch_register_lock); |
| @@ -1497,9 +1499,9 @@ void bch_flash_dev_release(struct kobject *kobj) · 112 unmodified lines | ||
| 1497 | 1499 | kfree(d); |
| 1498 | 1500 | } |
| 1499 | 1501 | |
| 1500 | −static void flash_dev_free(struct closure *cl) | |
| 1502 | +static CLOSURE_CALLBACK(flash_dev_free) | |
| 1501 | 1503 | { |
| 1502 | − struct bcache_device *d = container_of(cl, struct bcache_device, cl); | |
| 1504 | + closure_type(d, struct bcache_device, cl); | |
| 1503 | 1505 | |
| 1504 | 1506 | mutex_lock(&bch_register_lock); |
| 1505 | 1507 | atomic_long_sub(bcache_dev_sectors_dirty(d), |
| @@ -1510,9 +1512,9 @@ static void flash_dev_free(struct closure *cl) · 4 unmodified lines | ||
| 1510 | 1512 | kobject_put(&d->kobj); |
| 1511 | 1513 | } |
| 1512 | 1514 | |
| 1513 | −static void flash_dev_flush(struct closure *cl) | |
| 1515 | +static CLOSURE_CALLBACK(flash_dev_flush) | |
| 1514 | 1516 | { |
| 1515 | − struct bcache_device *d = container_of(cl, struct bcache_device, cl); | |
| 1517 | + closure_type(d, struct bcache_device, cl); | |
| 1516 | 1518 | |
| 1517 | 1519 | mutex_lock(&bch_register_lock); |
| 1518 | 1520 | bcache_device_unlink(d); |
| @@ -1668,9 +1670,9 @@ void bch_cache_set_release(struct kobject *kobj) · 149 unmodified lines | ||
| 1668 | 1670 | module_put(THIS_MODULE); |
| 1669 | 1671 | } |
| 1670 | 1672 | |
| 1671 | −static void cache_set_free(struct closure *cl) | |
| 1673 | +static CLOSURE_CALLBACK(cache_set_free) | |
| 1672 | 1674 | { |
| 1673 | − struct cache_set *c = container_of(cl, struct cache_set, cl); | |
| 1675 | + closure_type(c, struct cache_set, cl); | |
| 1674 | 1676 | struct cache *ca; |
| 1675 | 1677 | |
| 1676 | 1678 | debugfs_remove(c->debug); |
| @@ -1709,9 +1711,9 @@ static void cache_set_free(struct closure *cl) · 32 unmodified lines | ||
| 1709 | 1711 | kobject_put(&c->kobj); |
| 1710 | 1712 | } |
| 1711 | 1713 | |
| 1712 | −static void cache_set_flush(struct closure *cl) | |
| 1714 | +static CLOSURE_CALLBACK(cache_set_flush) | |
| 1713 | 1715 | { |
| 1714 | − struct cache_set *c = container_of(cl, struct cache_set, caching); | |
| 1716 | + closure_type(c, struct cache_set, caching); | |
| 1715 | 1717 | struct cache *ca = c->cache; |
| 1716 | 1718 | struct btree *b; |
| 1717 | 1719 | |
| @@ -1806,9 +1808,9 @@ static void conditional_stop_bcache_device(struct cache_set *c, · 88 unmodified lines | ||
| 1806 | 1808 | } |
| 1807 | 1809 | } |
| 1808 | 1810 | |
| 1809 | −static void __cache_set_unregister(struct closure *cl) | |
| 1811 | +static CLOSURE_CALLBACK(__cache_set_unregister) | |
| 1810 | 1812 | { |
| 1811 | − struct cache_set *c = container_of(cl, struct cache_set, caching); | |
| 1813 | + closure_type(c, struct cache_set, caching); | |
| 1812 | 1814 | struct cached_dev *dc; |
| 1813 | 1815 | struct bcache_device *d; |
| 1814 | 1816 | size_t i; |
| @@ -2016,7 +2018,7 @@ static int run_cache_set(struct cache_set *c) · 201 unmodified lines | ||
| 2016 | 2018 | c->root = bch_btree_node_get(c, NULL, k, |
| 2017 | 2019 | j->btree_level, |
| 2018 | 2020 | true, NULL); |
| 2019 | − if (IS_ERR_OR_NULL(c->root)) | |
| 2021 | + if (IS_ERR(c->root)) | |
| 2020 | 2022 | goto err; |
| 2021 | 2023 | |
| 2022 | 2024 | list_del_init(&c->root->list); |
| @@ -1104,7 +1104,7 @@ SHOW(__bch_cache) · 1103 unmodified lines | ||
| 1104 | 1104 | sum += INITIAL_PRIO - cached[i]; |
| 1105 | 1105 | |
| 1106 | 1106 | if (n) |
| 1107 | − do_div(sum, n); | |
| 1107 | + sum = div64_u64(sum, n); | |
| 1108 | 1108 | |
| 1109 | 1109 | for (i = 0; i < ARRAY_SIZE(q); i++) |
| 1110 | 1110 | q[i] = INITIAL_PRIO - cached[n * (i + 1) / |
| @@ -341,16 +341,16 @@ static void dirty_init(struct keybuf_key *w) · 340 unmodified lines | ||
| 341 | 341 | bch_bio_map(bio, NULL); |
| 342 | 342 | } |
| 343 | 343 | |
| 344 | −static void dirty_io_destructor(struct closure *cl) | |
| 344 | +static CLOSURE_CALLBACK(dirty_io_destructor) | |
| 345 | 345 | { |
| 346 | − struct dirty_io *io = container_of(cl, struct dirty_io, cl); | |
| 346 | + closure_type(io, struct dirty_io, cl); | |
| 347 | 347 | |
| 348 | 348 | kfree(io); |
| 349 | 349 | } |
| 350 | 350 | |
| 351 | −static void write_dirty_finish(struct closure *cl) | |
| 351 | +static CLOSURE_CALLBACK(write_dirty_finish) | |
| 352 | 352 | { |
| 353 | − struct dirty_io *io = container_of(cl, struct dirty_io, cl); | |
| 353 | + closure_type(io, struct dirty_io, cl); | |
| 354 | 354 | struct keybuf_key *w = io->bio.bi_private; |
| 355 | 355 | struct cached_dev *dc = io->dc; |
| 356 | 356 | |
| @@ -400,9 +400,9 @@ static void dirty_endio(struct bio *bio) · 43 unmodified lines | ||
| 400 | 400 | closure_put(&io->cl); |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | −static void write_dirty(struct closure *cl) | |
| 403 | +static CLOSURE_CALLBACK(write_dirty) | |
| 404 | 404 | { |
| 405 | − struct dirty_io *io = container_of(cl, struct dirty_io, cl); | |
| 405 | + closure_type(io, struct dirty_io, cl); | |
| 406 | 406 | struct keybuf_key *w = io->bio.bi_private; |
| 407 | 407 | struct cached_dev *dc = io->dc; |
| 408 | 408 | |
| @@ -462,9 +462,9 @@ static void read_dirty_endio(struct bio *bio) · 53 unmodified lines | ||
| 462 | 462 | dirty_endio(bio); |
| 463 | 463 | } |
| 464 | 464 | |
| 465 | −static void read_dirty_submit(struct closure *cl) | |
| 465 | +static CLOSURE_CALLBACK(read_dirty_submit) | |
| 466 | 466 | { |
| 467 | − struct dirty_io *io = container_of(cl, struct dirty_io, cl); | |
| 467 | + closure_type(io, struct dirty_io, cl); | |
| 468 | 468 | |
| 469 | 469 | closure_bio_submit(io->dc->disk.c, &io->bio, cl); |
| 470 | 470 | |
| @@ -913,7 +913,7 @@ static int bch_dirty_init_thread(void *arg) · 442 unmodified lines | ||
| 913 | 913 | int cur_idx, prev_idx, skip_nr; |
| 914 | 914 | |
| 915 | 915 | k = p = NULL; |
| 916 | − cur_idx = prev_idx = 0; | |
| 916 | + prev_idx = 0; | |
| 917 | 917 | |
| 918 | 918 | bch_btree_iter_init(&c->root->keys, &iter, NULL); |
| 919 | 919 | k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad); |
| @@ -977,24 +977,35 @@ static int bch_btre_dirty_init_thread_nr(void) · 57 unmodified lines | ||
| 977 | 977 | void bch_sectors_dirty_init(struct bcache_device *d) |
| 978 | 978 | { |
| 979 | 979 | int i; |
| 980 | + struct btree *b = NULL; | |
| 980 | 981 | struct bkey *k = NULL; |
| 981 | 982 | struct btree_iter iter; |
| 982 | 983 | struct sectors_dirty_init op; |
| 983 | 984 | struct cache_set *c = d->c; |
| 984 | 985 | struct bch_dirty_init_state state; |
| 985 | 986 | |
| 987 | +retry_lock: | |
| 988 | + b = c->root; | |
| 989 | + rw_lock(0, b, b->level); | |
| 990 | + if (b != c->root) { | |
| 991 | + rw_unlock(0, b); | |
| 992 | + goto retry_lock; | |
| 993 | + } | |
| 994 | + | |
| 986 | 995 | /* Just count root keys if no leaf node */ |
| 987 | − rw_lock(0, c->root, c->root->level); | |
| 988 | 996 | if (c->root->level == 0) { |
| 989 | 997 | bch_btree_op_init(&op.op, -1); |
| 990 | 998 | op.inode = d->id; |
| 991 | 999 | op.count = 0; |
| 992 | 1000 | |
| 993 | 1001 | for_each_key_filter(&c->root->keys, |
| 994 | − k, &iter, bch_ptr_invalid) | |
| 1002 | + k, &iter, bch_ptr_invalid) { | |
| 1003 | + if (KEY_INODE(k) != op.inode) | |
| 1004 | + continue; | |
| 995 | 1005 | sectors_dirty_init_fn(&op.op, c->root, k); |
| 1006 | + } | |
| 996 | 1007 | |
| 997 | − rw_unlock(0, c->root); | |
| 1008 | + rw_unlock(0, b); | |
| 998 | 1009 | return; |
| 999 | 1010 | } |
| 1000 | 1011 | |
| @@ -1014,23 +1025,24 @@ void bch_sectors_dirty_init(struct bcache_device *d) · 13 unmodified lines | ||
| 1014 | 1025 | if (atomic_read(&state.enough)) |
| 1015 | 1026 | break; |
| 1016 | 1027 | |
| 1028 | + atomic_inc(&state.started); | |
| 1017 | 1029 | state.infos[i].state = &state; |
| 1018 | 1030 | state.infos[i].thread = |
| 1019 | 1031 | kthread_run(bch_dirty_init_thread, &state.infos[i], |
| 1020 | 1032 | "bch_dirtcnt[%d]", i); |
| 1021 | 1033 | if (IS_ERR(state.infos[i].thread)) { |
| 1022 | 1034 | pr_err("fails to run thread bch_dirty_init[%d]\n", i); |
| 1035 | + atomic_dec(&state.started); | |
| 1023 | 1036 | for (--i; i >= 0; i--) |
| 1024 | 1037 | kthread_stop(state.infos[i].thread); |
| 1025 | 1038 | goto out; |
| 1026 | 1039 | } |
| 1027 | − atomic_inc(&state.started); | |
| 1028 | 1040 | } |
| 1029 | 1041 | |
| 1030 | 1042 | out: |
| 1031 | 1043 | /* Must wait for all threads to stop. */ |
| 1032 | 1044 | wait_event(state.wait, atomic_read(&state.started) == 0); |
| 1033 | − rw_unlock(0, c->root); | |
| 1045 | + rw_unlock(0, b); | |
| 1034 | 1046 | } |
| 1035 | 1047 | |
| 1036 | 1048 | void bch_cached_dev_writeback_init(struct cached_dev *dc) |
| @@ -254,7 +254,7 @@ enum evict_result { · 253 unmodified lines | ||
| 254 | 254 | |
| 255 | 255 | typedef enum evict_result (*le_predicate)(struct lru_entry *le, void *context); |
| 256 | 256 | |
| 257 | −static struct lru_entry *lru_evict(struct lru *lru, le_predicate pred, void *context) | |
| 257 | +static struct lru_entry *lru_evict(struct lru *lru, le_predicate pred, void *context, bool no_sleep) | |
| 258 | 258 | { |
| 259 | 259 | unsigned long tested = 0; |
| 260 | 260 | struct list_head *h = lru->cursor; |
| @@ -295,7 +295,8 @@ static struct lru_entry *lru_evict(struct lru *lru, le_predicate pred, void *con · 34 unmodified lines | ||
| 295 | 295 | |
| 296 | 296 | h = h->next; |
| 297 | 297 | |
| 298 | − cond_resched(); | |
| 298 | + if (!no_sleep) | |
| 299 | + cond_resched(); | |
| 299 | 300 | } |
| 300 | 301 | |
| 301 | 302 | return NULL; |
| @@ -382,7 +383,10 @@ struct dm_buffer { · 80 unmodified lines | ||
| 382 | 383 | */ |
| 383 | 384 | |
| 384 | 385 | struct buffer_tree { |
| 385 | − struct rw_semaphore lock; | |
| 386 | + union { | |
| 387 | + struct rw_semaphore lock; | |
| 388 | + rwlock_t spinlock; | |
| 389 | + } u; | |
| 386 | 390 | struct rb_root root; |
| 387 | 391 | } ____cacheline_aligned_in_smp; |
| 388 | 392 | |
| @@ -393,9 +397,12 @@ struct dm_buffer_cache { · 4 unmodified lines | ||
| 393 | 397 | * on the locks. |
| 394 | 398 | */ |
| 395 | 399 | unsigned int num_locks; |
| 400 | + bool no_sleep; | |
| 396 | 401 | struct buffer_tree trees[]; |
| 397 | 402 | }; |
| 398 | 403 | |
| 404 | +static DEFINE_STATIC_KEY_FALSE(no_sleep_enabled); | |
| 405 | + | |
| 399 | 406 | static inline unsigned int cache_index(sector_t block, unsigned int num_locks) |
| 400 | 407 | { |
| 401 | 408 | return dm_hash_locks_index(block, num_locks); |
| @@ -403,22 +410,34 @@ static inline unsigned int cache_index(sector_t block, unsigned int num_locks) · 1 unmodified line | ||
| 403 | 410 | |
| 404 | 411 | static inline void cache_read_lock(struct dm_buffer_cache *bc, sector_t block) |
| 405 | 412 | { |
| 406 | − down_read(&bc->trees[cache_index(block, bc->num_locks)].lock); | |
| 413 | + if (static_branch_unlikely(&no_sleep_enabled) && bc->no_sleep) | |
| 414 | + read_lock_bh(&bc->trees[cache_index(block, bc->num_locks)].u.spinlock); | |
| 415 | + else | |
| 416 | + down_read(&bc->trees[cache_index(block, bc->num_locks)].u.lock); | |
| 407 | 417 | } |
| 408 | 418 | |
| 409 | 419 | static inline void cache_read_unlock(struct dm_buffer_cache *bc, sector_t block) |
| 410 | 420 | { |
| 411 | − up_read(&bc->trees[cache_index(block, bc->num_locks)].lock); | |
| 421 | + if (static_branch_unlikely(&no_sleep_enabled) && bc->no_sleep) | |
| 422 | + read_unlock_bh(&bc->trees[cache_index(block, bc->num_locks)].u.spinlock); | |
| 423 | + else | |
| 424 | + up_read(&bc->trees[cache_index(block, bc->num_locks)].u.lock); | |
| 412 | 425 | } |
| 413 | 426 | |
| 414 | 427 | static inline void cache_write_lock(struct dm_buffer_cache *bc, sector_t block) |
| 415 | 428 | { |
| 416 | − down_write(&bc->trees[cache_index(block, bc->num_locks)].lock); | |
| 429 | + if (static_branch_unlikely(&no_sleep_enabled) && bc->no_sleep) | |
| 430 | + write_lock_bh(&bc->trees[cache_index(block, bc->num_locks)].u.spinlock); | |
| 431 | + else | |
| 432 | + down_write(&bc->trees[cache_index(block, bc->num_locks)].u.lock); | |
| 417 | 433 | } |
| 418 | 434 | |
| 419 | 435 | static inline void cache_write_unlock(struct dm_buffer_cache *bc, sector_t block) |
| 420 | 436 | { |
| 421 | − up_write(&bc->trees[cache_index(block, bc->num_locks)].lock); | |
| 437 | + if (static_branch_unlikely(&no_sleep_enabled) && bc->no_sleep) | |
| 438 | + write_unlock_bh(&bc->trees[cache_index(block, bc->num_locks)].u.spinlock); | |
| 439 | + else | |
| 440 | + up_write(&bc->trees[cache_index(block, bc->num_locks)].u.lock); | |
| 422 | 441 | } |
| 423 | 442 | |
| 424 | 443 | /* |
| @@ -442,18 +461,32 @@ static void lh_init(struct lock_history *lh, struct dm_buffer_cache *cache, bool · 17 unmodified lines | ||
| 442 | 461 | |
| 443 | 462 | static void __lh_lock(struct lock_history *lh, unsigned int index) |
| 444 | 463 | { |
| 445 | − if (lh->write) | |
| 446 | − down_write(&lh->cache->trees[index].lock); | |
| 447 | − else | |
| 448 | − down_read(&lh->cache->trees[index].lock); | |
| 464 | + if (lh->write) { | |
| 465 | + if (static_branch_unlikely(&no_sleep_enabled) && lh->cache->no_sleep) | |
| 466 | + write_lock_bh(&lh->cache->trees[index].u.spinlock); | |
| 467 | + else | |
| 468 | + down_write(&lh->cache->trees[index].u.lock); | |
| 469 | + } else { | |
| 470 | + if (static_branch_unlikely(&no_sleep_enabled) && lh->cache->no_sleep) | |
| 471 | + read_lock_bh(&lh->cache->trees[index].u.spinlock); | |
| 472 | + else | |
| 473 | + down_read(&lh->cache->trees[index].u.lock); | |
| 474 | + } | |
| 449 | 475 | } |
| 450 | 476 | |
| 451 | 477 | static void __lh_unlock(struct lock_history *lh, unsigned int index) |
| 452 | 478 | { |
| 453 | − if (lh->write) | |
| 454 | − up_write(&lh->cache->trees[index].lock); | |
| 455 | − else | |
| 456 | − up_read(&lh->cache->trees[index].lock); | |
| 479 | + if (lh->write) { | |
| 480 | + if (static_branch_unlikely(&no_sleep_enabled) && lh->cache->no_sleep) | |
| 481 | + write_unlock_bh(&lh->cache->trees[index].u.spinlock); | |
| 482 | + else | |
| 483 | + up_write(&lh->cache->trees[index].u.lock); | |
| 484 | + } else { | |
| 485 | + if (static_branch_unlikely(&no_sleep_enabled) && lh->cache->no_sleep) | |
| 486 | + read_unlock_bh(&lh->cache->trees[index].u.spinlock); | |
| 487 | + else | |
| 488 | + up_read(&lh->cache->trees[index].u.lock); | |
| 489 | + } | |
| 457 | 490 | } |
| 458 | 491 | |
| 459 | 492 | /* |
| @@ -502,14 +535,18 @@ static struct dm_buffer *list_to_buffer(struct list_head *l) · 42 unmodified lines | ||
| 502 | 535 | return le_to_buffer(le); |
| 503 | 536 | } |
| 504 | 537 | |
| 505 | −static void cache_init(struct dm_buffer_cache *bc, unsigned int num_locks) | |
| 538 | +static void cache_init(struct dm_buffer_cache *bc, unsigned int num_locks, bool no_sleep) | |
| 506 | 539 | { |
| 507 | 540 | unsigned int i; |
| 508 | 541 | |
| 509 | 542 | bc->num_locks = num_locks; |
| 543 | + bc->no_sleep = no_sleep; | |
| 510 | 544 | |
| 511 | 545 | for (i = 0; i < bc->num_locks; i++) { |
| 512 | − init_rwsem(&bc->trees[i].lock); | |
| 546 | + if (no_sleep) | |
| 547 | + rwlock_init(&bc->trees[i].u.spinlock); | |
| 548 | + else | |
| 549 | + init_rwsem(&bc->trees[i].u.lock); | |
| 513 | 550 | bc->trees[i].root = RB_ROOT; |
| 514 | 551 | } |
| 515 | 552 | |
| @@ -648,7 +685,7 @@ static struct dm_buffer *__cache_evict(struct dm_buffer_cache *bc, int list_mode · 132 unmodified lines | ||
| 648 | 685 | struct lru_entry *le; |
| 649 | 686 | struct dm_buffer *b; |
| 650 | 687 | |
| 651 | − le = lru_evict(&bc->lru[list_mode], __evict_pred, &w); | |
| 688 | + le = lru_evict(&bc->lru[list_mode], __evict_pred, &w, bc->no_sleep); | |
| 652 | 689 | if (!le) |
| 653 | 690 | return NULL; |
| 654 | 691 | |
| @@ -702,7 +739,7 @@ static void __cache_mark_many(struct dm_buffer_cache *bc, int old_mode, int new_ · 47 unmodified lines | ||
| 702 | 739 | struct evict_wrapper w = {.lh = lh, .pred = pred, .context = context}; |
| 703 | 740 | |
| 704 | 741 | while (true) { |
| 705 | − le = lru_evict(&bc->lru[old_mode], __evict_pred, &w); | |
| 742 | + le = lru_evict(&bc->lru[old_mode], __evict_pred, &w, bc->no_sleep); | |
| 706 | 743 | if (!le) |
| 707 | 744 | break; |
| 708 | 745 | |
| @@ -915,10 +952,11 @@ static void cache_remove_range(struct dm_buffer_cache *bc, · 206 unmodified lines | ||
| 915 | 952 | { |
| 916 | 953 | unsigned int i; |
| 917 | 954 | |
| 955 | + BUG_ON(bc->no_sleep); | |
| 918 | 956 | for (i = 0; i < bc->num_locks; i++) { |
| 919 | − down_write(&bc->trees[i].lock); | |
| 957 | + down_write(&bc->trees[i].u.lock); | |
| 920 | 958 | __remove_range(bc, &bc->trees[i].root, begin, end, pred, release); |
| 921 | − up_write(&bc->trees[i].lock); | |
| 959 | + up_write(&bc->trees[i].u.lock); | |
| 922 | 960 | } |
| 923 | 961 | } |
| 924 | 962 | |
| @@ -979,8 +1017,6 @@ struct dm_bufio_client { · 54 unmodified lines | ||
| 979 | 1017 | struct dm_buffer_cache cache; /* must be last member */ |
| 980 | 1018 | }; |
| 981 | 1019 | |
| 982 | −static DEFINE_STATIC_KEY_FALSE(no_sleep_enabled); | |
| 983 | − | |
| 984 | 1020 | /*----------------------------------------------------------------*/ |
| 985 | 1021 | |
| 986 | 1022 | #define dm_bufio_in_request() (!!current->bio_list) |
| @@ -1871,7 +1907,8 @@ static void *new_read(struct dm_bufio_client *c, sector_t block, · 884 unmodified lines | ||
| 1871 | 1907 | if (need_submit) |
| 1872 | 1908 | submit_io(b, REQ_OP_READ, read_endio); |
| 1873 | 1909 | |
| 1874 | − wait_on_bit_io(&b->state, B_READING, TASK_UNINTERRUPTIBLE); | |
| 1910 | + if (nf != NF_GET) /* we already tested this condition above */ | |
| 1911 | + wait_on_bit_io(&b->state, B_READING, TASK_UNINTERRUPTIBLE); | |
| 1875 | 1912 | |
| 1876 | 1913 | if (b->read_error) { |
| 1877 | 1914 | int error = blk_status_to_errno(b->read_error); |
| @@ -2421,7 +2458,7 @@ struct dm_bufio_client *dm_bufio_client_create(struct block_device *bdev, unsign · 543 unmodified lines | ||
| 2421 | 2458 | r = -ENOMEM; |
| 2422 | 2459 | goto bad_client; |
| 2423 | 2460 | } |
| 2424 | − cache_init(&c->cache, num_locks); | |
| 2461 | + cache_init(&c->cache, num_locks, (flags & DM_BUFIO_CLIENT_NO_SLEEP) != 0); | |
| 2425 | 2462 | |
| 2426 | 2463 | c->bdev = bdev; |
| 2427 | 2464 | c->block_size = block_size; |
| @@ -1673,7 +1673,7 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned int size) · 1672 unmodified lines | ||
| 1673 | 1673 | unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
| 1674 | 1674 | gfp_t gfp_mask = GFP_NOWAIT | __GFP_HIGHMEM; |
| 1675 | 1675 | unsigned int remaining_size; |
| 1676 | − unsigned int order = MAX_ORDER - 1; | |
| 1676 | + unsigned int order = MAX_ORDER; | |
| 1677 | 1677 | |
| 1678 | 1678 | retry: |
| 1679 | 1679 | if (unlikely(gfp_mask & __GFP_DIRECT_RECLAIM)) |
| @@ -33,7 +33,7 @@ struct delay_c { · 32 unmodified lines | ||
| 33 | 33 | struct work_struct flush_expired_bios; |
| 34 | 34 | struct list_head delayed_bios; |
| 35 | 35 | struct task_struct *worker; |
| 36 | − atomic_t may_delay; | |
| 36 | + bool may_delay; | |
| 37 | 37 | |
| 38 | 38 | struct delay_class read; |
| 39 | 39 | struct delay_class write; |
| @@ -73,39 +73,6 @@ static inline bool delay_is_fast(struct delay_c *dc) · 33 unmodified lines | ||
| 73 | 73 | return !!dc->worker; |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | −static void flush_delayed_bios_fast(struct delay_c *dc, bool flush_all) | |
| 77 | −{ | |
| 78 | − struct dm_delay_info *delayed, *next; | |
| 79 | − | |
| 80 | − mutex_lock(&delayed_bios_lock); | |
| 81 | − list_for_each_entry_safe(delayed, next, &dc->delayed_bios, list) { | |
| 82 | − if (flush_all || time_after_eq(jiffies, delayed->expires)) { | |
| 83 | − struct bio *bio = dm_bio_from_per_bio_data(delayed, | |
| 84 | − sizeof(struct dm_delay_info)); | |
| 85 | − list_del(&delayed->list); | |
| 86 | − dm_submit_bio_remap(bio, NULL); | |
| 87 | − delayed->class->ops--; | |
| 88 | − } | |
| 89 | − } | |
| 90 | − mutex_unlock(&delayed_bios_lock); | |
| 91 | −} | |
| 92 | − | |
| 93 | −static int flush_worker_fn(void *data) | |
| 94 | −{ | |
| 95 | − struct delay_c *dc = data; | |
| 96 | − | |
| 97 | − while (1) { | |
| 98 | − flush_delayed_bios_fast(dc, false); | |
| 99 | − if (unlikely(list_empty(&dc->delayed_bios))) { | |
| 100 | − set_current_state(TASK_INTERRUPTIBLE); | |
| 101 | − schedule(); | |
| 102 | − } else | |
| 103 | − cond_resched(); | |
| 104 | − } | |
| 105 | − | |
| 106 | − return 0; | |
| 107 | −} | |
| 108 | − | |
| 109 | 76 | static void flush_bios(struct bio *bio) |
| 110 | 77 | { |
| 111 | 78 | struct bio *n; |
| @@ -118,36 +85,61 @@ static void flush_bios(struct bio *bio) · 6 unmodified lines | ||
| 118 | 85 | } |
| 119 | 86 | } |
| 120 | 87 | |
| 121 | −static struct bio *flush_delayed_bios(struct delay_c *dc, bool flush_all) | |
| 88 | +static void flush_delayed_bios(struct delay_c *dc, bool flush_all) | |
| 122 | 89 | { |
| 123 | 90 | struct dm_delay_info *delayed, *next; |
| 91 | + struct bio_list flush_bio_list; | |
| 124 | 92 | unsigned long next_expires = 0; |
| 125 | − unsigned long start_timer = 0; | |
| 126 | − struct bio_list flush_bios = { }; | |
| 93 | + bool start_timer = false; | |
| 94 | + bio_list_init(&flush_bio_list); | |
| 127 | 95 | |
| 128 | 96 | mutex_lock(&delayed_bios_lock); |
| 129 | 97 | list_for_each_entry_safe(delayed, next, &dc->delayed_bios, list) { |
| 98 | + cond_resched(); | |
| 130 | 99 | if (flush_all || time_after_eq(jiffies, delayed->expires)) { |
| 131 | 100 | struct bio *bio = dm_bio_from_per_bio_data(delayed, |
| 132 | 101 | sizeof(struct dm_delay_info)); |
| 133 | 102 | list_del(&delayed->list); |
| 134 | − bio_list_add(&flush_bios, bio); | |
| 103 | + bio_list_add(&flush_bio_list, bio); | |
| 135 | 104 | delayed->class->ops--; |
| 136 | 105 | continue; |
| 137 | 106 | } |
| 138 | 107 | |
| 139 | − if (!start_timer) { | |
| 140 | − start_timer = 1; | |
| 141 | − next_expires = delayed->expires; | |
| 142 | − } else | |
| 143 | − next_expires = min(next_expires, delayed->expires); | |
| 108 | + if (!delay_is_fast(dc)) { | |
| 109 | + if (!start_timer) { | |
| 110 | + start_timer = true; | |
| 111 | + next_expires = delayed->expires; | |
| 112 | + } else { | |
| 113 | + next_expires = min(next_expires, delayed->expires); | |
| 114 | + } | |
| 115 | + } | |
| 144 | 116 | } |
| 145 | 117 | mutex_unlock(&delayed_bios_lock); |
| 146 | 118 | |
| 147 | 119 | if (start_timer) |
| 148 | 120 | queue_timeout(dc, next_expires); |
| 149 | 121 | |
| 150 | − return bio_list_get(&flush_bios); | |
| 122 | + flush_bios(bio_list_get(&flush_bio_list)); | |
| 123 | +} | |
| 124 | + | |
| 125 | +static int flush_worker_fn(void *data) | |
| 126 | +{ | |
| 127 | + struct delay_c *dc = data; | |
| 128 | + | |
| 129 | + while (!kthread_should_stop()) { | |
| 130 | + flush_delayed_bios(dc, false); | |
| 131 | + mutex_lock(&delayed_bios_lock); | |
| 132 | + if (unlikely(list_empty(&dc->delayed_bios))) { | |
| 133 | + set_current_state(TASK_INTERRUPTIBLE); | |
| 134 | + mutex_unlock(&delayed_bios_lock); | |
| 135 | + schedule(); | |
| 136 | + } else { | |
| 137 | + mutex_unlock(&delayed_bios_lock); | |
| 138 | + cond_resched(); | |
| 139 | + } | |
| 140 | + } | |
| 141 | + | |
| 142 | + return 0; | |
| 151 | 143 | } |
| 152 | 144 | |
| 153 | 145 | static void flush_expired_bios(struct work_struct *work) |
| @@ -155,10 +147,7 @@ static void flush_expired_bios(struct work_struct *work) · 1 unmodified line | ||
| 155 | 147 | struct delay_c *dc; |
| 156 | 148 | |
| 157 | 149 | dc = container_of(work, struct delay_c, flush_expired_bios); |
| 158 | − if (delay_is_fast(dc)) | |
| 159 | − flush_delayed_bios_fast(dc, false); | |
| 160 | − else | |
| 161 | − flush_bios(flush_delayed_bios(dc, false)); | |
| 150 | + flush_delayed_bios(dc, false); | |
| 162 | 151 | } |
| 163 | 152 | |
| 164 | 153 | static void delay_dtr(struct dm_target *ti) |
| @@ -177,8 +166,7 @@ static void delay_dtr(struct dm_target *ti) · 12 unmodified lines | ||
| 177 | 166 | if (dc->worker) |
| 178 | 167 | kthread_stop(dc->worker); |
| 179 | 168 | |
| 180 | − if (!delay_is_fast(dc)) | |
| 181 | − mutex_destroy(&dc->timer_lock); | |
| 169 | + mutex_destroy(&dc->timer_lock); | |
| 182 | 170 | |
| 183 | 171 | kfree(dc); |
| 184 | 172 | } |
| @@ -236,7 +224,8 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) · 51 unmodified lines | ||
| 236 | 224 | |
| 237 | 225 | ti->private = dc; |
| 238 | 226 | INIT_LIST_HEAD(&dc->delayed_bios); |
| 239 | − atomic_set(&dc->may_delay, 1); | |
| 227 | + mutex_init(&dc->timer_lock); | |
| 228 | + dc->may_delay = true; | |
| 240 | 229 | dc->argc = argc; |
| 241 | 230 | |
| 242 | 231 | ret = delay_class_ctr(ti, &dc->read, argv); |
| @@ -282,12 +271,12 @@ out: · 39 unmodified lines | ||
| 282 | 271 | "dm-delay-flush-worker"); |
| 283 | 272 | if (IS_ERR(dc->worker)) { |
| 284 | 273 | ret = PTR_ERR(dc->worker); |
| 274 | + dc->worker = NULL; | |
| 285 | 275 | goto bad; |
| 286 | 276 | } |
| 287 | 277 | } else { |
| 288 | 278 | timer_setup(&dc->delay_timer, handle_delayed_timer, 0); |
| 289 | 279 | INIT_WORK(&dc->flush_expired_bios, flush_expired_bios); |
| 290 | − mutex_init(&dc->timer_lock); | |
| 291 | 280 | dc->kdelayd_wq = alloc_workqueue("kdelayd", WQ_MEM_RECLAIM, 0); |
| 292 | 281 | if (!dc->kdelayd_wq) { |
| 293 | 282 | ret = -EINVAL; |
| @@ -312,7 +301,7 @@ static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio) · 18 unmodified lines | ||
| 312 | 301 | struct dm_delay_info *delayed; |
| 313 | 302 | unsigned long expires = 0; |
| 314 | 303 | |
| 315 | − if (!c->delay || !atomic_read(&dc->may_delay)) | |
| 304 | + if (!c->delay) | |
| 316 | 305 | return DM_MAPIO_REMAPPED; |
| 317 | 306 | |
| 318 | 307 | delayed = dm_per_bio_data(bio, sizeof(struct dm_delay_info)); |
| @@ -321,6 +310,10 @@ static int delay_bio(struct delay_c *dc, struct delay_class *c, struct bio *bio) · 2 unmodified lines | ||
| 321 | 310 | delayed->expires = expires = jiffies + msecs_to_jiffies(c->delay); |
| 322 | 311 | |
| 323 | 312 | mutex_lock(&delayed_bios_lock); |
| 313 | + if (unlikely(!dc->may_delay)) { | |
| 314 | + mutex_unlock(&delayed_bios_lock); | |
| 315 | + return DM_MAPIO_REMAPPED; | |
| 316 | + } | |
| 324 | 317 | c->ops++; |
| 325 | 318 | list_add_tail(&delayed->list, &dc->delayed_bios); |
| 326 | 319 | mutex_unlock(&delayed_bios_lock); |
| @@ -337,21 +330,20 @@ static void delay_presuspend(struct dm_target *ti) · 10 unmodified lines | ||
| 337 | 330 | { |
| 338 | 331 | struct delay_c *dc = ti->private; |
| 339 | 332 | |
| 340 | − atomic_set(&dc->may_delay, 0); | |
| 333 | + mutex_lock(&delayed_bios_lock); | |
| 334 | + dc->may_delay = false; | |
| 335 | + mutex_unlock(&delayed_bios_lock); | |
| 341 | 336 | |
| 342 | − if (delay_is_fast(dc)) | |
| 343 | − flush_delayed_bios_fast(dc, true); | |
| 344 | − else { | |
| 337 | + if (!delay_is_fast(dc)) | |
| 345 | 338 | del_timer_sync(&dc->delay_timer); |
| 346 | − flush_bios(flush_delayed_bios(dc, true)); | |
| 347 | − } | |
| 339 | + flush_delayed_bios(dc, true); | |
| 348 | 340 | } |
| 349 | 341 | |
| 350 | 342 | static void delay_resume(struct dm_target *ti) |
| 351 | 343 | { |
| 352 | 344 | struct delay_c *dc = ti->private; |
| 353 | 345 | |
| 354 | − atomic_set(&dc->may_delay, 1); | |
| 346 | + dc->may_delay = true; | |
| 355 | 347 | } |
| 356 | 348 | |
| 357 | 349 | static int delay_map(struct dm_target *ti, struct bio *bio) |
| @@ -434,7 +434,7 @@ static struct bio *clone_bio(struct dm_target *ti, struct flakey_c *fc, struct b · 433 unmodified lines | ||
| 434 | 434 | |
| 435 | 435 | remaining_size = size; |
| 436 | 436 | |
| 437 | − order = MAX_ORDER - 1; | |
| 437 | + order = MAX_ORDER; | |
| 438 | 438 | while (remaining_size) { |
| 439 | 439 | struct page *pages; |
| 440 | 440 | unsigned size_to_add, to_copy; |
| @@ -24,7 +24,8 @@ bool verity_fec_is_enabled(struct dm_verity *v) · 23 unmodified lines | ||
| 24 | 24 | */ |
| 25 | 25 | static inline struct dm_verity_fec_io *fec_io(struct dm_verity_io *io) |
| 26 | 26 | { |
| 27 | − return (struct dm_verity_fec_io *) verity_io_digest_end(io->v, io); | |
| 27 | + return (struct dm_verity_fec_io *) | |
| 28 | + ((char *)io + io->v->ti->per_io_data_size - sizeof(struct dm_verity_fec_io)); | |
| 28 | 29 | } |
| 29 | 30 | |
| 30 | 31 | /* |
| @@ -185,7 +186,7 @@ static int fec_is_erasure(struct dm_verity *v, struct dm_verity_io *io, · 154 unmodified lines | ||
| 185 | 186 | { |
| 186 | 187 | if (unlikely(verity_hash(v, verity_io_hash_req(v, io), |
| 187 | 188 | data, 1 << v->data_dev_block_bits, |
| 188 | − verity_io_real_digest(v, io)))) | |
| 189 | + verity_io_real_digest(v, io), true))) | |
| 189 | 190 | return 0; |
| 190 | 191 | |
| 191 | 192 | return memcmp(verity_io_real_digest(v, io), want_digest, |
| @@ -386,7 +387,7 @@ static int fec_decode_rsb(struct dm_verity *v, struct dm_verity_io *io, · 194 unmodified lines | ||
| 386 | 387 | /* Always re-validate the corrected block against the expected hash */ |
| 387 | 388 | r = verity_hash(v, verity_io_hash_req(v, io), fio->output, |
| 388 | 389 | 1 << v->data_dev_block_bits, |
| 389 | − verity_io_real_digest(v, io)); | |
| 390 | + verity_io_real_digest(v, io), true); | |
| 390 | 391 | if (unlikely(r < 0)) |
| 391 | 392 | return r; |
| 392 | 393 | |
| @@ -135,20 +135,21 @@ static int verity_hash_update(struct dm_verity *v, struct ahash_request *req, · 134 unmodified lines | ||
| 135 | 135 | * Wrapper for crypto_ahash_init, which handles verity salting. |
| 136 | 136 | */ |
| 137 | 137 | static int verity_hash_init(struct dm_verity *v, struct ahash_request *req, |
| 138 | − struct crypto_wait *wait) | |
| 138 | + struct crypto_wait *wait, bool may_sleep) | |
| 139 | 139 | { |
| 140 | 140 | int r; |
| 141 | 141 | |
| 142 | 142 | ahash_request_set_tfm(req, v->tfm); |
| 143 | − ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP | | |
| 144 | − CRYPTO_TFM_REQ_MAY_BACKLOG, | |
| 145 | − crypto_req_done, (void *)wait); | |
| 143 | + ahash_request_set_callback(req, | |
| 144 | + may_sleep ? CRYPTO_TFM_REQ_MAY_SLEEP | CRYPTO_TFM_REQ_MAY_BACKLOG : 0, | |
| 145 | + crypto_req_done, (void *)wait); | |
| 146 | 146 | crypto_init_wait(wait); |
| 147 | 147 | |
| 148 | 148 | r = crypto_wait_req(crypto_ahash_init(req), wait); |
| 149 | 149 | |
| 150 | 150 | if (unlikely(r < 0)) { |
| 151 | − DMERR("crypto_ahash_init failed: %d", r); | |
| 151 | + if (r != -ENOMEM) | |
| 152 | + DMERR("crypto_ahash_init failed: %d", r); | |
| 152 | 153 | return r; |
| 153 | 154 | } |
| 154 | 155 | |
| @@ -179,12 +180,12 @@ out: · 24 unmodified lines | ||
| 179 | 180 | } |
| 180 | 181 | |
| 181 | 182 | int verity_hash(struct dm_verity *v, struct ahash_request *req, |
| 182 | − const u8 *data, size_t len, u8 *digest) | |
| 183 | + const u8 *data, size_t len, u8 *digest, bool may_sleep) | |
| 183 | 184 | { |
| 184 | 185 | int r; |
| 185 | 186 | struct crypto_wait wait; |
| 186 | 187 | |
| 187 | − r = verity_hash_init(v, req, &wait); | |
| 188 | + r = verity_hash_init(v, req, &wait, may_sleep); | |
| 188 | 189 | if (unlikely(r < 0)) |
| 189 | 190 | goto out; |
| 190 | 191 | |
| @@ -322,7 +323,7 @@ static int verity_verify_level(struct dm_verity *v, struct dm_verity_io *io, · 131 unmodified lines | ||
| 322 | 323 | |
| 323 | 324 | r = verity_hash(v, verity_io_hash_req(v, io), |
| 324 | 325 | data, 1 << v->hash_dev_block_bits, |
| 325 | − verity_io_real_digest(v, io)); | |
| 326 | + verity_io_real_digest(v, io), !io->in_tasklet); | |
| 326 | 327 | if (unlikely(r < 0)) |
| 327 | 328 | goto release_ret_r; |
| 328 | 329 | |
| @@ -556,7 +557,7 @@ static int verity_verify_io(struct dm_verity_io *io) · 227 unmodified lines | ||
| 556 | 557 | continue; |
| 557 | 558 | } |
| 558 | 559 | |
| 559 | − r = verity_hash_init(v, req, &wait); | |
| 560 | + r = verity_hash_init(v, req, &wait, !io->in_tasklet); | |
| 560 | 561 | if (unlikely(r < 0)) |
| 561 | 562 | return r; |
| 562 | 563 | |
| @@ -641,7 +642,6 @@ static void verity_work(struct work_struct *w) · 78 unmodified lines | ||
| 641 | 642 | |
| 642 | 643 | io->in_tasklet = false; |
| 643 | 644 | |
| 644 | − verity_fec_init_io(io); | |
| 645 | 645 | verity_finish_io(io, errno_to_blk_status(verity_verify_io(io))); |
| 646 | 646 | } |
| 647 | 647 | |
| @@ -652,7 +652,7 @@ static void verity_tasklet(unsigned long data) · 4 unmodified lines | ||
| 652 | 652 | |
| 653 | 653 | io->in_tasklet = true; |
| 654 | 654 | err = verity_verify_io(io); |
| 655 | − if (err == -EAGAIN) { | |
| 655 | + if (err == -EAGAIN || err == -ENOMEM) { | |
| 656 | 656 | /* fallback to retrying with work-queue */ |
| 657 | 657 | INIT_WORK(&io->work, verity_work); |
| 658 | 658 | queue_work(io->v->verify_wq, &io->work); |
| @@ -667,7 +667,9 @@ static void verity_end_io(struct bio *bio) · 8 unmodified lines | ||
| 667 | 667 | struct dm_verity_io *io = bio->bi_private; |
| 668 | 668 | |
| 669 | 669 | if (bio->bi_status && |
| 670 | − (!verity_fec_is_enabled(io->v) || verity_is_system_shutting_down())) { | |
| 670 | + (!verity_fec_is_enabled(io->v) || | |
| 671 | + verity_is_system_shutting_down() || | |
| 672 | + (bio->bi_opf & REQ_RAHEAD))) { | |
| 671 | 673 | verity_finish_io(io, bio->bi_status); |
| 672 | 674 | return; |
| 673 | 675 | } |
| @@ -791,6 +793,8 @@ static int verity_map(struct dm_target *ti, struct bio *bio) · 117 unmodified lines | ||
| 791 | 793 | bio->bi_private = io; |
| 792 | 794 | io->iter = bio->bi_iter; |
| 793 | 795 | |
| 796 | + verity_fec_init_io(io); | |
| 797 | + | |
| 794 | 798 | verity_submit_prefetch(v, io); |
| 795 | 799 | |
| 796 | 800 | submit_bio_noacct(bio); |
| @@ -1033,7 +1037,7 @@ static int verity_alloc_zero_digest(struct dm_verity *v) · 236 unmodified lines | ||
| 1033 | 1037 | goto out; |
| 1034 | 1038 | |
| 1035 | 1039 | r = verity_hash(v, req, zero_data, 1 << v->data_dev_block_bits, |
| 1036 | − v->zero_digest); | |
| 1040 | + v->zero_digest, true); | |
| 1037 | 1041 | |
| 1038 | 1042 | out: |
| 1039 | 1043 | kfree(req); |
| @@ -115,12 +115,6 @@ static inline u8 *verity_io_want_digest(struct dm_verity *v, · 114 unmodified lines | ||
| 115 | 115 | return (u8 *)(io + 1) + v->ahash_reqsize + v->digest_size; |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | −static inline u8 *verity_io_digest_end(struct dm_verity *v, | |
| 119 | − struct dm_verity_io *io) | |
| 120 | −{ | |
| 121 | − return verity_io_want_digest(v, io) + v->digest_size; | |
| 122 | −} | |
| 123 | − | |
| 124 | 118 | extern int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io, |
| 125 | 119 | struct bvec_iter *iter, |
| 126 | 120 | int (*process)(struct dm_verity *v, |
| @@ -128,7 +122,7 @@ extern int verity_for_bv_block(struct dm_verity *v, struct dm_verity_io *io, · 1 unmodified line | ||
| 128 | 122 | u8 *data, size_t len)); |
| 129 | 123 | |
| 130 | 124 | extern int verity_hash(struct dm_verity *v, struct ahash_request *req, |
| 131 | − const u8 *data, size_t len, u8 *digest); | |
| 125 | + const u8 *data, size_t len, u8 *digest, bool may_sleep); | |
| 132 | 126 | |
| 133 | 127 | extern int verity_hash_for_block(struct dm_verity *v, struct dm_verity_io *io, |
| 134 | 128 | sector_t block, u8 *digest, bool *is_zero); |
| @@ -490,7 +490,7 @@ int mddev_suspend(struct mddev *mddev, bool interruptible) · 489 unmodified lines | ||
| 490 | 490 | } |
| 491 | 491 | EXPORT_SYMBOL_GPL(mddev_suspend); |
| 492 | 492 | |
| 493 | −void mddev_resume(struct mddev *mddev) | |
| 493 | +static void __mddev_resume(struct mddev *mddev, bool recovery_needed) | |
| 494 | 494 | { |
| 495 | 495 | lockdep_assert_not_held(&mddev->reconfig_mutex); |
| 496 | 496 | |
| @@ -507,12 +507,18 @@ void mddev_resume(struct mddev *mddev) · 10 unmodified lines | ||
| 507 | 507 | percpu_ref_resurrect(&mddev->active_io); |
| 508 | 508 | wake_up(&mddev->sb_wait); |
| 509 | 509 | |
| 510 | − set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | |
| 510 | + if (recovery_needed) | |
| 511 | + set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | |
| 511 | 512 | md_wakeup_thread(mddev->thread); |
| 512 | 513 | md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */ |
| 513 | 514 | |
| 514 | 515 | mutex_unlock(&mddev->suspend_mutex); |
| 515 | 516 | } |
| 517 | + | |
| 518 | +void mddev_resume(struct mddev *mddev) | |
| 519 | +{ | |
| 520 | + return __mddev_resume(mddev, true); | |
| 521 | +} | |
| 516 | 522 | EXPORT_SYMBOL_GPL(mddev_resume); |
| 517 | 523 | |
| 518 | 524 | /* |
| @@ -4840,25 +4846,29 @@ action_show(struct mddev *mddev, char *page) · 4321 unmodified lines | ||
| 4840 | 4846 | return sprintf(page, "%s\n", type); |
| 4841 | 4847 | } |
| 4842 | 4848 | |
| 4843 | −static void stop_sync_thread(struct mddev *mddev) | |
| 4849 | +/** | |
| 4850 | + * stop_sync_thread() - wait for sync_thread to stop if it's running. | |
| 4851 | + * @mddev: the array. | |
| 4852 | + * @locked: if set, reconfig_mutex will still be held after this function | |
| 4853 | + * return; if not set, reconfig_mutex will be released after this | |
| 4854 | + * function return. | |
| 4855 | + * @check_seq: if set, only wait for curent running sync_thread to stop, noted | |
| 4856 | + * that new sync_thread can still start. | |
| 4857 | + */ | |
| 4858 | +static void stop_sync_thread(struct mddev *mddev, bool locked, bool check_seq) | |
| 4844 | 4859 | { |
| 4845 | − if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | |
| 4846 | − return; | |
| 4860 | + int sync_seq; | |
| 4847 | 4861 | |
| 4848 | − if (mddev_lock(mddev)) | |
| 4849 | − return; | |
| 4862 | + if (check_seq) | |
| 4863 | + sync_seq = atomic_read(&mddev->sync_seq); | |
| 4850 | 4864 | |
| 4851 | − /* | |
| 4852 | − * Check again in case MD_RECOVERY_RUNNING is cleared before lock is | |
| 4853 | − * held. | |
| 4854 | − */ | |
| 4855 | 4865 | if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) { |
| 4856 | − mddev_unlock(mddev); | |
| 4866 | + if (!locked) | |
| 4867 | + mddev_unlock(mddev); | |
| 4857 | 4868 | return; |
| 4858 | 4869 | } |
| 4859 | 4870 | |
| 4860 | − if (work_pending(&mddev->del_work)) | |
| 4861 | − flush_workqueue(md_misc_wq); | |
| 4871 | + mddev_unlock(mddev); | |
| 4862 | 4872 | |
| 4863 | 4873 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
| 4864 | 4874 | /* |
| @@ -4866,21 +4876,28 @@ static void stop_sync_thread(struct mddev *mddev) · 1 unmodified line | ||
| 4866 | 4876 | * never happen |
| 4867 | 4877 | */ |
| 4868 | 4878 | md_wakeup_thread_directly(mddev->sync_thread); |
| 4879 | + if (work_pending(&mddev->sync_work)) | |
| 4880 | + flush_work(&mddev->sync_work); | |
| 4869 | 4881 | |
| 4870 | − mddev_unlock(mddev); | |
| 4882 | + wait_event(resync_wait, | |
| 4883 | + !test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) || | |
| 4884 | + (check_seq && sync_seq != atomic_read(&mddev->sync_seq))); | |
| 4885 | + | |
| 4886 | + if (locked) | |
| 4887 | + mddev_lock_nointr(mddev); | |
| 4871 | 4888 | } |
| 4872 | 4889 | |
| 4873 | 4890 | static void idle_sync_thread(struct mddev *mddev) |
| 4874 | 4891 | { |
| 4875 | − int sync_seq = atomic_read(&mddev->sync_seq); | |
| 4876 | − | |
| 4877 | 4892 | mutex_lock(&mddev->sync_mutex); |
| 4878 | 4893 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
| 4879 | − stop_sync_thread(mddev); | |
| 4880 | 4894 | |
| 4881 | − wait_event(resync_wait, sync_seq != atomic_read(&mddev->sync_seq) || | |
| 4882 | − !test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)); | |
| 4895 | + if (mddev_lock(mddev)) { | |
| 4896 | + mutex_unlock(&mddev->sync_mutex); | |
| 4897 | + return; | |
| 4898 | + } | |
| 4883 | 4899 | |
| 4900 | + stop_sync_thread(mddev, false, true); | |
| 4884 | 4901 | mutex_unlock(&mddev->sync_mutex); |
| 4885 | 4902 | } |
| 4886 | 4903 | |
| @@ -4888,11 +4905,13 @@ static void frozen_sync_thread(struct mddev *mddev) · 1 unmodified line | ||
| 4888 | 4905 | { |
| 4889 | 4906 | mutex_lock(&mddev->sync_mutex); |
| 4890 | 4907 | set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
| 4891 | − stop_sync_thread(mddev); | |
| 4892 | 4908 | |
| 4893 | − wait_event(resync_wait, mddev->sync_thread == NULL && | |
| 4894 | − !test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)); | |
| 4909 | + if (mddev_lock(mddev)) { | |
| 4910 | + mutex_unlock(&mddev->sync_mutex); | |
| 4911 | + return; | |
| 4912 | + } | |
| 4895 | 4913 | |
| 4914 | + stop_sync_thread(mddev, false, false); | |
| 4896 | 4915 | mutex_unlock(&mddev->sync_mutex); |
| 4897 | 4916 | } |
| 4898 | 4917 | |
| @@ -6264,14 +6283,7 @@ static void md_clean(struct mddev *mddev) · 1365 unmodified lines | ||
| 6264 | 6283 | |
| 6265 | 6284 | static void __md_stop_writes(struct mddev *mddev) |
| 6266 | 6285 | { |
| 6267 | − set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | |
| 6268 | − if (work_pending(&mddev->del_work)) | |
| 6269 | − flush_workqueue(md_misc_wq); | |
| 6270 | − if (mddev->sync_thread) { | |
| 6271 | − set_bit(MD_RECOVERY_INTR, &mddev->recovery); | |
| 6272 | − md_reap_sync_thread(mddev); | |
| 6273 | − } | |
| 6274 | − | |
| 6286 | + stop_sync_thread(mddev, true, false); | |
| 6275 | 6287 | del_timer_sync(&mddev->safemode_timer); |
| 6276 | 6288 | |
| 6277 | 6289 | if (mddev->pers && mddev->pers->quiesce) { |
| @@ -6355,25 +6367,16 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) · 77 unmodified lines | ||
| 6355 | 6367 | int err = 0; |
| 6356 | 6368 | int did_freeze = 0; |
| 6357 | 6369 | |
| 6370 | + if (mddev->external && test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) | |
| 6371 | + return -EBUSY; | |
| 6372 | + | |
| 6358 | 6373 | if (!test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) { |
| 6359 | 6374 | did_freeze = 1; |
| 6360 | 6375 | set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
| 6361 | 6376 | md_wakeup_thread(mddev->thread); |
| 6362 | 6377 | } |
| 6363 | − if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | |
| 6364 | − set_bit(MD_RECOVERY_INTR, &mddev->recovery); | |
| 6365 | 6378 | |
| 6366 | − /* | |
| 6367 | − * Thread might be blocked waiting for metadata update which will now | |
| 6368 | − * never happen | |
| 6369 | − */ | |
| 6370 | − md_wakeup_thread_directly(mddev->sync_thread); | |
| 6371 | − | |
| 6372 | − if (mddev->external && test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) | |
| 6373 | − return -EBUSY; | |
| 6374 | − mddev_unlock(mddev); | |
| 6375 | − wait_event(resync_wait, !test_bit(MD_RECOVERY_RUNNING, | |
| 6376 | − &mddev->recovery)); | |
| 6379 | + stop_sync_thread(mddev, false, false); | |
| 6377 | 6380 | wait_event(mddev->sb_wait, |
| 6378 | 6381 | !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)); |
| 6379 | 6382 | mddev_lock_nointr(mddev); |
| @@ -6383,29 +6386,30 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev) · 3 unmodified lines | ||
| 6383 | 6386 | mddev->sync_thread || |
| 6384 | 6387 | test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) { |
| 6385 | 6388 | pr_warn("md: %s still in use.\n",mdname(mddev)); |
| 6386 | − if (did_freeze) { | |
| 6387 | − clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); | |
| 6388 | − set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | |
| 6389 | − md_wakeup_thread(mddev->thread); | |
| 6390 | − } | |
| 6391 | 6389 | err = -EBUSY; |
| 6392 | 6390 | goto out; |
| 6393 | 6391 | } |
| 6392 | + | |
| 6394 | 6393 | if (mddev->pers) { |
| 6395 | 6394 | __md_stop_writes(mddev); |
| 6396 | 6395 | |
| 6397 | − err = -ENXIO; | |
| 6398 | − if (mddev->ro == MD_RDONLY) | |
| 6396 | + if (mddev->ro == MD_RDONLY) { | |
| 6397 | + err = -ENXIO; | |
| 6399 | 6398 | goto out; |
| 6399 | + } | |
| 6400 | + | |
| 6400 | 6401 | mddev->ro = MD_RDONLY; |
| 6401 | 6402 | set_disk_ro(mddev->gendisk, 1); |
| 6403 | + } | |
| 6404 | + | |
| 6405 | +out: | |
| 6406 | + if ((mddev->pers && !err) || did_freeze) { | |
| 6402 | 6407 | clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
| 6403 | 6408 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
| 6404 | 6409 | md_wakeup_thread(mddev->thread); |
| 6405 | 6410 | sysfs_notify_dirent_safe(mddev->sysfs_state); |
| 6406 | − err = 0; | |
| 6407 | 6411 | } |
| 6408 | −out: | |
| 6412 | + | |
| 6409 | 6413 | mutex_unlock(&mddev->open_mutex); |
| 6410 | 6414 | return err; |
| 6411 | 6415 | } |
| @@ -6426,20 +6430,8 @@ static int do_md_stop(struct mddev *mddev, int mode, · 14 unmodified lines | ||
| 6426 | 6430 | set_bit(MD_RECOVERY_FROZEN, &mddev->recovery); |
| 6427 | 6431 | md_wakeup_thread(mddev->thread); |
| 6428 | 6432 | } |
| 6429 | − if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | |
| 6430 | − set_bit(MD_RECOVERY_INTR, &mddev->recovery); | |
| 6431 | − | |
| 6432 | − /* | |
| 6433 | − * Thread might be blocked waiting for metadata update which will now | |
| 6434 | − * never happen | |
| 6435 | − */ | |
| 6436 | − md_wakeup_thread_directly(mddev->sync_thread); | |
| 6437 | 6433 | |
| 6438 | − mddev_unlock(mddev); | |
| 6439 | − wait_event(resync_wait, (mddev->sync_thread == NULL && | |
| 6440 | − !test_bit(MD_RECOVERY_RUNNING, | |
| 6441 | − &mddev->recovery))); | |
| 6442 | − mddev_lock_nointr(mddev); | |
| 6434 | + stop_sync_thread(mddev, true, false); | |
| 6443 | 6435 | |
| 6444 | 6436 | mutex_lock(&mddev->open_mutex); |
| 6445 | 6437 | if ((mddev->pers && atomic_read(&mddev->openers) > !!bdev) || |
| @@ -8666,7 +8658,8 @@ static void md_end_clone_io(struct bio *bio) · 2220 unmodified lines | ||
| 8666 | 8658 | struct bio *orig_bio = md_io_clone->orig_bio; |
| 8667 | 8659 | struct mddev *mddev = md_io_clone->mddev; |
| 8668 | 8660 | |
| 8669 | − orig_bio->bi_status = bio->bi_status; | |
| 8661 | + if (bio->bi_status && !orig_bio->bi_status) | |
| 8662 | + orig_bio->bi_status = bio->bi_status; | |
| 8670 | 8663 | |
| 8671 | 8664 | if (md_io_clone->start_time) |
| 8672 | 8665 | bio_end_io_acct(orig_bio, md_io_clone->start_time); |
| @@ -9402,7 +9395,15 @@ static void md_start_sync(struct work_struct *ws) · 729 unmodified lines | ||
| 9402 | 9395 | goto not_running; |
| 9403 | 9396 | } |
| 9404 | 9397 | |
| 9405 | − suspend ? mddev_unlock_and_resume(mddev) : mddev_unlock(mddev); | |
| 9398 | + mddev_unlock(mddev); | |
| 9399 | + /* | |
| 9400 | + * md_start_sync was triggered by MD_RECOVERY_NEEDED, so we should | |
| 9401 | + * not set it again. Otherwise, we may cause issue like this one: | |
| 9402 | + * https://bugzilla.kernel.org/show_bug.cgi?id=218200 | |
| 9403 | + * Therefore, use __mddev_resume(mddev, false). | |
| 9404 | + */ | |
| 9405 | + if (suspend) | |
| 9406 | + __mddev_resume(mddev, false); | |
| 9406 | 9407 | md_wakeup_thread(mddev->sync_thread); |
| 9407 | 9408 | sysfs_notify_dirent_safe(mddev->sysfs_action); |
| 9408 | 9409 | md_new_event(); |
| @@ -9414,7 +9415,15 @@ not_running: · 5 unmodified lines | ||
| 9414 | 9415 | clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); |
| 9415 | 9416 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
| 9416 | 9417 | clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery); |
| 9417 | − suspend ? mddev_unlock_and_resume(mddev) : mddev_unlock(mddev); | |
| 9418 | + mddev_unlock(mddev); | |
| 9419 | + /* | |
| 9420 | + * md_start_sync was triggered by MD_RECOVERY_NEEDED, so we should | |
| 9421 | + * not set it again. Otherwise, we may cause issue like this one: | |
| 9422 | + * https://bugzilla.kernel.org/show_bug.cgi?id=218200 | |
| 9423 | + * Therefore, use __mddev_resume(mddev, false). | |
| 9424 | + */ | |
| 9425 | + if (suspend) | |
| 9426 | + __mddev_resume(mddev, false); | |
| 9418 | 9427 | |
| 9419 | 9428 | wake_up(&resync_wait); |
| 9420 | 9429 | if (test_and_clear_bit(MD_RECOVERY_RECOVER, &mddev->recovery) && |
| @@ -5892,11 +5892,11 @@ static bool stripe_ahead_of_reshape(struct mddev *mddev, struct r5conf *conf, · 5891 unmodified lines | ||
| 5892 | 5892 | int dd_idx; |
| 5893 | 5893 | |
| 5894 | 5894 | for (dd_idx = 0; dd_idx < sh->disks; dd_idx++) { |
| 5895 | − if (dd_idx == sh->pd_idx) | |
| 5895 | + if (dd_idx == sh->pd_idx || dd_idx == sh->qd_idx) | |
| 5896 | 5896 | continue; |
| 5897 | 5897 | |
| 5898 | 5898 | min_sector = min(min_sector, sh->dev[dd_idx].sector); |
| 5899 | − max_sector = min(max_sector, sh->dev[dd_idx].sector); | |
| 5899 | + max_sector = max(max_sector, sh->dev[dd_idx].sector); | |
| 5900 | 5900 | } |
| 5901 | 5901 | |
| 5902 | 5902 | spin_lock_irq(&conf->device_lock); |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | config VIDEO_MGB4 |
| 3 | 3 | tristate "Digiteq Automotive MGB4 support" |
| 4 | 4 | depends on VIDEO_DEV && PCI && I2C && DMADEVICES && SPI && MTD && IIO |
| 5 | + depends on COMMON_CLK | |
| 5 | 6 | select VIDEOBUF2_DMA_SG |
| 6 | 7 | select IIO_BUFFER |
| 7 | 8 | select IIO_TRIGGERED_BUFFER |
| @@ -42,6 +42,10 @@ · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | #define MGB4_USER_IRQS 16 |
| 44 | 44 | |
| 45 | +#define DIGITEQ_VID 0x1ed8 | |
| 46 | +#define T100_DID 0x0101 | |
| 47 | +#define T200_DID 0x0201 | |
| 48 | + | |
| 45 | 49 | ATTRIBUTE_GROUPS(mgb4_pci); |
| 46 | 50 | |
| 47 | 51 | static int flashid; |
| @@ -151,7 +155,7 @@ static struct spi_master *get_spi_adap(struct platform_device *pdev) · 103 unmodified lines | ||
| 151 | 155 | return dev ? container_of(dev, struct spi_master, dev) : NULL; |
| 152 | 156 | } |
| 153 | 157 | |
| 154 | −static int init_spi(struct mgb4_dev *mgbdev) | |
| 158 | +static int init_spi(struct mgb4_dev *mgbdev, u32 devid) | |
| 155 | 159 | { |
| 156 | 160 | struct resource spi_resources[] = { |
| 157 | 161 | { |
| @@ -213,8 +217,13 @@ static int init_spi(struct mgb4_dev *mgbdev) · 55 unmodified lines | ||
| 213 | 217 | snprintf(mgbdev->fw_part_name, sizeof(mgbdev->fw_part_name), |
| 214 | 218 | "mgb4-fw.%d", flashid); |
| 215 | 219 | mgbdev->partitions[0].name = mgbdev->fw_part_name; |
| 216 | − mgbdev->partitions[0].size = 0x400000; | |
| 217 | − mgbdev->partitions[0].offset = 0x400000; | |
| 220 | + if (devid == T200_DID) { | |
| 221 | + mgbdev->partitions[0].size = 0x950000; | |
| 222 | + mgbdev->partitions[0].offset = 0x1000000; | |
| 223 | + } else { | |
| 224 | + mgbdev->partitions[0].size = 0x400000; | |
| 225 | + mgbdev->partitions[0].offset = 0x400000; | |
| 226 | + } | |
| 218 | 227 | mgbdev->partitions[0].mask_flags = 0; |
| 219 | 228 | |
| 220 | 229 | snprintf(mgbdev->data_part_name, sizeof(mgbdev->data_part_name), |
| @@ -551,7 +560,7 @@ static int mgb4_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 330 unmodified lines | ||
| 551 | 560 | goto err_video_regs; |
| 552 | 561 | |
| 553 | 562 | /* SPI FLASH */ |
| 554 | − rv = init_spi(mgbdev); | |
| 563 | + rv = init_spi(mgbdev, id->device); | |
| 555 | 564 | if (rv < 0) |
| 556 | 565 | goto err_cmt_regs; |
| 557 | 566 | |
| @@ -666,7 +675,8 @@ static void mgb4_remove(struct pci_dev *pdev) · 108 unmodified lines | ||
| 666 | 675 | } |
| 667 | 676 | |
| 668 | 677 | static const struct pci_device_id mgb4_pci_ids[] = { |
| 669 | − { PCI_DEVICE(0x1ed8, 0x0101), }, | |
| 678 | + { PCI_DEVICE(DIGITEQ_VID, T100_DID), }, | |
| 679 | + { PCI_DEVICE(DIGITEQ_VID, T200_DID), }, | |
| 670 | 680 | { 0, } |
| 671 | 681 | }; |
| 672 | 682 | MODULE_DEVICE_TABLE(pci, mgb4_pci_ids); |
| @@ -373,7 +373,7 @@ int vsp1_pipeline_stop(struct vsp1_pipeline *pipe) · 372 unmodified lines | ||
| 373 | 373 | (7 << VI6_DPR_SMPPT_TGW_SHIFT) | |
| 374 | 374 | (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT)); |
| 375 | 375 | |
| 376 | − v4l2_subdev_call(&pipe->output->entity.subdev, video, s_stream, 0); | |
| 376 | + vsp1_wpf_stop(pipe->output); | |
| 377 | 377 | |
| 378 | 378 | return ret; |
| 379 | 379 | } |
| @@ -43,14 +43,6 @@ static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf, · 42 unmodified lines | ||
| 43 | 43 | data); |
| 44 | 44 | } |
| 45 | 45 | |
| 46 | −/* ----------------------------------------------------------------------------- | |
| 47 | − * V4L2 Subdevice Operations | |
| 48 | − */ | |
| 49 | − | |
| 50 | −static const struct v4l2_subdev_ops rpf_ops = { | |
| 51 | − .pad = &vsp1_rwpf_pad_ops, | |
| 52 | −}; | |
| 53 | − | |
| 54 | 46 | /* ----------------------------------------------------------------------------- |
| 55 | 47 | * VSP1 Entity Operations |
| 56 | 48 | */ |
| @@ -411,7 +403,7 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index) · 354 unmodified lines | ||
| 411 | 403 | rpf->entity.index = index; |
| 412 | 404 | |
| 413 | 405 | sprintf(name, "rpf.%u", index); |
| 414 | − ret = vsp1_entity_init(vsp1, &rpf->entity, name, 2, &rpf_ops, | |
| 406 | + ret = vsp1_entity_init(vsp1, &rpf->entity, name, 2, &vsp1_rwpf_subdev_ops, | |
| 415 | 407 | MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER); |
| 416 | 408 | if (ret < 0) |
| 417 | 409 | return ERR_PTR(ret); |
| @@ -24,7 +24,7 @@ struct v4l2_rect *vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, · 23 unmodified lines | ||
| 24 | 24 | } |
| 25 | 25 | |
| 26 | 26 | /* ----------------------------------------------------------------------------- |
| 27 | − * V4L2 Subdevice Pad Operations | |
| 27 | + * V4L2 Subdevice Operations | |
| 28 | 28 | */ |
| 29 | 29 | |
| 30 | 30 | static int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, |
| @@ -243,7 +243,7 @@ done: · 212 unmodified lines | ||
| 243 | 243 | return ret; |
| 244 | 244 | } |
| 245 | 245 | |
| 246 | −const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops = { | |
| 246 | +static const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops = { | |
| 247 | 247 | .init_cfg = vsp1_entity_init_cfg, |
| 248 | 248 | .enum_mbus_code = vsp1_rwpf_enum_mbus_code, |
| 249 | 249 | .enum_frame_size = vsp1_rwpf_enum_frame_size, |
| @@ -253,6 +253,10 @@ const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops = { · 3 unmodified lines | ||
| 253 | 253 | .set_selection = vsp1_rwpf_set_selection, |
| 254 | 254 | }; |
| 255 | 255 | |
| 256 | +const struct v4l2_subdev_ops vsp1_rwpf_subdev_ops = { | |
| 257 | + .pad = &vsp1_rwpf_pad_ops, | |
| 258 | +}; | |
| 259 | + | |
| 256 | 260 | /* ----------------------------------------------------------------------------- |
| 257 | 261 | * Controls |
| 258 | 262 | */ |
| @@ -79,9 +79,11 @@ static inline struct vsp1_rwpf *entity_to_rwpf(struct vsp1_entity *entity) · 78 unmodified lines | ||
| 79 | 79 | struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index); |
| 80 | 80 | struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index); |
| 81 | 81 | |
| 82 | +void vsp1_wpf_stop(struct vsp1_rwpf *wpf); | |
| 83 | + | |
| 82 | 84 | int vsp1_rwpf_init_ctrls(struct vsp1_rwpf *rwpf, unsigned int ncontrols); |
| 83 | 85 | |
| 84 | −extern const struct v4l2_subdev_pad_ops vsp1_rwpf_pad_ops; | |
| 86 | +extern const struct v4l2_subdev_ops vsp1_rwpf_subdev_ops; | |
| 85 | 87 | |
| 86 | 88 | struct v4l2_rect *vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, |
| 87 | 89 | struct v4l2_subdev_state *sd_state); |
| @@ -186,17 +186,13 @@ static int wpf_init_controls(struct vsp1_rwpf *wpf) · 185 unmodified lines | ||
| 186 | 186 | } |
| 187 | 187 | |
| 188 | 188 | /* ----------------------------------------------------------------------------- |
| 189 | − * V4L2 Subdevice Core Operations | |
| 189 | + * VSP1 Entity Operations | |
| 190 | 190 | */ |
| 191 | 191 | |
| 192 | −static int wpf_s_stream(struct v4l2_subdev *subdev, int enable) | |
| 192 | +void vsp1_wpf_stop(struct vsp1_rwpf *wpf) | |
| 193 | 193 | { |
| 194 | − struct vsp1_rwpf *wpf = to_rwpf(subdev); | |
| 195 | 194 | struct vsp1_device *vsp1 = wpf->entity.vsp1; |
| 196 | 195 | |
| 197 | − if (enable) | |
| 198 | − return 0; | |
| 199 | − | |
| 200 | 196 | /* |
| 201 | 197 | * Write to registers directly when stopping the stream as there will be |
| 202 | 198 | * no pipeline run to apply the display list. |
| @@ -204,27 +200,8 @@ static int wpf_s_stream(struct v4l2_subdev *subdev, int enable) · 1 unmodified line | ||
| 204 | 200 | vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), 0); |
| 205 | 201 | vsp1_write(vsp1, wpf->entity.index * VI6_WPF_OFFSET + |
| 206 | 202 | VI6_WPF_SRCRPF, 0); |
| 207 | − | |
| 208 | − return 0; | |
| 209 | 203 | } |
| 210 | 204 | |
| 211 | −/* ----------------------------------------------------------------------------- | |
| 212 | − * V4L2 Subdevice Operations | |
| 213 | − */ | |
| 214 | − | |
| 215 | −static const struct v4l2_subdev_video_ops wpf_video_ops = { | |
| 216 | − .s_stream = wpf_s_stream, | |
| 217 | −}; | |
| 218 | − | |
| 219 | −static const struct v4l2_subdev_ops wpf_ops = { | |
| 220 | − .video = &wpf_video_ops, | |
| 221 | − .pad = &vsp1_rwpf_pad_ops, | |
| 222 | −}; | |
| 223 | − | |
| 224 | −/* ----------------------------------------------------------------------------- | |
| 225 | − * VSP1 Entity Operations | |
| 226 | − */ | |
| 227 | − | |
| 228 | 205 | static void vsp1_wpf_destroy(struct vsp1_entity *entity) |
| 229 | 206 | { |
| 230 | 207 | struct vsp1_rwpf *wpf = entity_to_rwpf(entity); |
| @@ -583,7 +560,7 @@ struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) · 352 unmodified lines | ||
| 583 | 560 | wpf->entity.index = index; |
| 584 | 561 | |
| 585 | 562 | sprintf(name, "wpf.%u", index); |
| 586 | − ret = vsp1_entity_init(vsp1, &wpf->entity, name, 2, &wpf_ops, | |
| 563 | + ret = vsp1_entity_init(vsp1, &wpf->entity, name, 2, &vsp1_rwpf_subdev_ops, | |
| 587 | 564 | MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER); |
| 588 | 565 | if (ret < 0) |
| 589 | 566 | return ERR_PTR(ret); |
| @@ -2011,7 +2011,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long time · 2010 unmodified lines | ||
| 2011 | 2011 | |
| 2012 | 2012 | mei_hdr = mei_msg_hdr_init(cb); |
| 2013 | 2013 | if (IS_ERR(mei_hdr)) { |
| 2014 | − rets = -PTR_ERR(mei_hdr); | |
| 2014 | + rets = PTR_ERR(mei_hdr); | |
| 2015 | 2015 | mei_hdr = NULL; |
| 2016 | 2016 | goto err; |
| 2017 | 2017 | } |
| @@ -2032,7 +2032,7 @@ ssize_t mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, unsigned long time · 14 unmodified lines | ||
| 2032 | 2032 | |
| 2033 | 2033 | hbuf_slots = mei_hbuf_empty_slots(dev); |
| 2034 | 2034 | if (hbuf_slots < 0) { |
| 2035 | − rets = -EOVERFLOW; | |
| 2035 | + buf_len = -EOVERFLOW; | |
| 2036 | 2036 | goto out; |
| 2037 | 2037 | } |
| 2038 | 2038 | |
| @@ -84,9 +84,10 @@ mei_pxp_send_message(struct device *dev, const void *message, size_t size, unsig · 83 unmodified lines | ||
| 84 | 84 | byte = ret; |
| 85 | 85 | break; |
| 86 | 86 | } |
| 87 | + return byte; | |
| 87 | 88 | } |
| 88 | 89 | |
| 89 | − return byte; | |
| 90 | + return 0; | |
| 90 | 91 | } |
| 91 | 92 | |
| 92 | 93 | /** |
| @@ -1482,6 +1482,8 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req) · 1481 unmodified lines | ||
| 1482 | 1482 | blk_mq_requeue_request(req, true); |
| 1483 | 1483 | else |
| 1484 | 1484 | __blk_mq_end_request(req, BLK_STS_OK); |
| 1485 | + } else if (mq->in_recovery) { | |
| 1486 | + blk_mq_requeue_request(req, true); | |
| 1485 | 1487 | } else { |
| 1486 | 1488 | blk_mq_end_request(req, BLK_STS_OK); |
| 1487 | 1489 | } |
| @@ -551,7 +551,9 @@ int mmc_cqe_recovery(struct mmc_host *host) · 550 unmodified lines | ||
| 551 | 551 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; |
| 552 | 552 | cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */ |
| 553 | 553 | cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT; |
| 554 | − mmc_wait_for_cmd(host, &cmd, 0); | |
| 554 | + mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | |
| 555 | + | |
| 556 | + mmc_poll_for_busy(host->card, MMC_CQE_RECOVERY_TIMEOUT, true, MMC_BUSY_IO); | |
| 555 | 557 | |
| 556 | 558 | memset(&cmd, 0, sizeof(cmd)); |
| 557 | 559 | cmd.opcode = MMC_CMDQ_TASK_MGMT; |
| @@ -559,10 +561,13 @@ int mmc_cqe_recovery(struct mmc_host *host) · 1 unmodified line | ||
| 559 | 561 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; |
| 560 | 562 | cmd.flags &= ~MMC_RSP_CRC; /* Ignore CRC */ |
| 561 | 563 | cmd.busy_timeout = MMC_CQE_RECOVERY_TIMEOUT; |
| 562 | − err = mmc_wait_for_cmd(host, &cmd, 0); | |
| 564 | + err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | |
| 563 | 565 | |
| 564 | 566 | host->cqe_ops->cqe_recovery_finish(host); |
| 565 | 567 | |
| 568 | + if (err) | |
| 569 | + err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES); | |
| 570 | + | |
| 566 | 571 | mmc_retune_release(host); |
| 567 | 572 | |
| 568 | 573 | return err; |
| @@ -942,8 +942,8 @@ static bool cqhci_clear_all_tasks(struct mmc_host *mmc, unsigned int timeout) · 941 unmodified lines | ||
| 942 | 942 | ret = cqhci_tasks_cleared(cq_host); |
| 943 | 943 | |
| 944 | 944 | if (!ret) |
| 945 | − pr_debug("%s: cqhci: Failed to clear tasks\n", | |
| 946 | − mmc_hostname(mmc)); | |
| 945 | + pr_warn("%s: cqhci: Failed to clear tasks\n", | |
| 946 | + mmc_hostname(mmc)); | |
| 947 | 947 | |
| 948 | 948 | return ret; |
| 949 | 949 | } |
| @@ -976,7 +976,7 @@ static bool cqhci_halt(struct mmc_host *mmc, unsigned int timeout) · 26 unmodified lines | ||
| 976 | 976 | ret = cqhci_halted(cq_host); |
| 977 | 977 | |
| 978 | 978 | if (!ret) |
| 979 | − pr_debug("%s: cqhci: Failed to halt\n", mmc_hostname(mmc)); | |
| 979 | + pr_warn("%s: cqhci: Failed to halt\n", mmc_hostname(mmc)); | |
| 980 | 980 | |
| 981 | 981 | return ret; |
| 982 | 982 | } |
| @@ -984,10 +984,10 @@ static bool cqhci_halt(struct mmc_host *mmc, unsigned int timeout) · 1 unmodified line | ||
| 984 | 984 | /* |
| 985 | 985 | * After halting we expect to be able to use the command line. We interpret the |
| 986 | 986 | * failure to halt to mean the data lines might still be in use (and the upper |
| 987 | − * layers will need to send a STOP command), so we set the timeout based on a | |
| 988 | − * generous command timeout. | |
| 987 | + * layers will need to send a STOP command), however failing to halt complicates | |
| 988 | + * the recovery, so set a timeout that would reasonably allow I/O to complete. | |
| 989 | 989 | */ |
| 990 | −#define CQHCI_START_HALT_TIMEOUT 5 | |
| 990 | +#define CQHCI_START_HALT_TIMEOUT 500 | |
| 991 | 991 | |
| 992 | 992 | static void cqhci_recovery_start(struct mmc_host *mmc) |
| 993 | 993 | { |
| @@ -1075,28 +1075,28 @@ static void cqhci_recovery_finish(struct mmc_host *mmc) · 81 unmodified lines | ||
| 1075 | 1075 | |
| 1076 | 1076 | ok = cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT); |
| 1077 | 1077 | |
| 1078 | − if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT)) | |
| 1079 | − ok = false; | |
| 1080 | − | |
| 1081 | 1078 | /* |
| 1082 | 1079 | * The specification contradicts itself, by saying that tasks cannot be |
| 1083 | 1080 | * cleared if CQHCI does not halt, but if CQHCI does not halt, it should |
| 1084 | 1081 | * be disabled/re-enabled, but not to disable before clearing tasks. |
| 1085 | 1082 | * Have a go anyway. |
| 1086 | 1083 | */ |
| 1087 | − if (!ok) { | |
| 1088 | − pr_debug("%s: cqhci: disable / re-enable\n", mmc_hostname(mmc)); | |
| 1089 | − cqcfg = cqhci_readl(cq_host, CQHCI_CFG); | |
| 1090 | − cqcfg &= ~CQHCI_ENABLE; | |
| 1091 | − cqhci_writel(cq_host, cqcfg, CQHCI_CFG); | |
| 1092 | − cqcfg |= CQHCI_ENABLE; | |
| 1093 | − cqhci_writel(cq_host, cqcfg, CQHCI_CFG); | |
| 1094 | − /* Be sure that there are no tasks */ | |
| 1095 | − ok = cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT); | |
| 1096 | − if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT)) | |
| 1097 | − ok = false; | |
| 1098 | − WARN_ON(!ok); | |
| 1099 | − } | |
| 1084 | + if (!cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT)) | |
| 1085 | + ok = false; | |
| 1086 | + | |
| 1087 | + /* Disable to make sure tasks really are cleared */ | |
| 1088 | + cqcfg = cqhci_readl(cq_host, CQHCI_CFG); | |
| 1089 | + cqcfg &= ~CQHCI_ENABLE; | |
| 1090 | + cqhci_writel(cq_host, cqcfg, CQHCI_CFG); | |
| 1091 | + | |
| 1092 | + cqcfg = cqhci_readl(cq_host, CQHCI_CFG); | |
| 1093 | + cqcfg |= CQHCI_ENABLE; | |
| 1094 | + cqhci_writel(cq_host, cqcfg, CQHCI_CFG); | |
| 1095 | + | |
| 1096 | + cqhci_halt(mmc, CQHCI_FINISH_HALT_TIMEOUT); | |
| 1097 | + | |
| 1098 | + if (!ok) | |
| 1099 | + cqhci_clear_all_tasks(mmc, CQHCI_CLEAR_TIMEOUT); | |
| 1100 | 1100 | |
| 1101 | 1101 | cqhci_recover_mrqs(cq_host); |
| 1102 | 1102 | |
| @@ -1189,6 +1189,32 @@ static void gl9763e_hs400_enhanced_strobe(struct mmc_host *mmc, · 1188 unmodified lines | ||
| 1189 | 1189 | sdhci_writel(host, val, SDHCI_GLI_9763E_HS400_ES_REG); |
| 1190 | 1190 | } |
| 1191 | 1191 | |
| 1192 | +static void gl9763e_set_low_power_negotiation(struct sdhci_pci_slot *slot, | |
| 1193 | + bool enable) | |
| 1194 | +{ | |
| 1195 | + struct pci_dev *pdev = slot->chip->pdev; | |
| 1196 | + u32 value; | |
| 1197 | + | |
| 1198 | + pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); | |
| 1199 | + value &= ~GLI_9763E_VHS_REV; | |
| 1200 | + value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_W); | |
| 1201 | + pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); | |
| 1202 | + | |
| 1203 | + pci_read_config_dword(pdev, PCIE_GLI_9763E_CFG, &value); | |
| 1204 | + | |
| 1205 | + if (enable) | |
| 1206 | + value &= ~GLI_9763E_CFG_LPSN_DIS; | |
| 1207 | + else | |
| 1208 | + value |= GLI_9763E_CFG_LPSN_DIS; | |
| 1209 | + | |
| 1210 | + pci_write_config_dword(pdev, PCIE_GLI_9763E_CFG, value); | |
| 1211 | + | |
| 1212 | + pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); | |
| 1213 | + value &= ~GLI_9763E_VHS_REV; | |
| 1214 | + value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R); | |
| 1215 | + pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); | |
| 1216 | +} | |
| 1217 | + | |
| 1192 | 1218 | static void sdhci_set_gl9763e_signaling(struct sdhci_host *host, |
| 1193 | 1219 | unsigned int timing) |
| 1194 | 1220 | { |
| @@ -1297,6 +1323,9 @@ static int gl9763e_add_host(struct sdhci_pci_slot *slot) · 102 unmodified lines | ||
| 1297 | 1323 | if (ret) |
| 1298 | 1324 | goto cleanup; |
| 1299 | 1325 | |
| 1326 | + /* Disable LPM negotiation to avoid entering L1 state. */ | |
| 1327 | + gl9763e_set_low_power_negotiation(slot, false); | |
| 1328 | + | |
| 1300 | 1329 | return 0; |
| 1301 | 1330 | |
| 1302 | 1331 | cleanup: |
| @@ -1340,31 +1369,6 @@ static void gli_set_gl9763e(struct sdhci_pci_slot *slot) · 37 unmodified lines | ||
| 1340 | 1369 | } |
| 1341 | 1370 | |
| 1342 | 1371 | #ifdef CONFIG_PM |
| 1343 | −static void gl9763e_set_low_power_negotiation(struct sdhci_pci_slot *slot, bool enable) | |
| 1344 | −{ | |
| 1345 | − struct pci_dev *pdev = slot->chip->pdev; | |
| 1346 | − u32 value; | |
| 1347 | − | |
| 1348 | − pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); | |
| 1349 | − value &= ~GLI_9763E_VHS_REV; | |
| 1350 | − value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_W); | |
| 1351 | − pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); | |
| 1352 | − | |
| 1353 | − pci_read_config_dword(pdev, PCIE_GLI_9763E_CFG, &value); | |
| 1354 | − | |
| 1355 | − if (enable) | |
| 1356 | − value &= ~GLI_9763E_CFG_LPSN_DIS; | |
| 1357 | − else | |
| 1358 | − value |= GLI_9763E_CFG_LPSN_DIS; | |
| 1359 | − | |
| 1360 | − pci_write_config_dword(pdev, PCIE_GLI_9763E_CFG, value); | |
| 1361 | − | |
| 1362 | − pci_read_config_dword(pdev, PCIE_GLI_9763E_VHS, &value); | |
| 1363 | − value &= ~GLI_9763E_VHS_REV; | |
| 1364 | − value |= FIELD_PREP(GLI_9763E_VHS_REV, GLI_9763E_VHS_REV_R); | |
| 1365 | − pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); | |
| 1366 | −} | |
| 1367 | − | |
| 1368 | 1372 | static int gl9763e_runtime_suspend(struct sdhci_pci_chip *chip) |
| 1369 | 1373 | { |
| 1370 | 1374 | struct sdhci_pci_slot *slot = chip->slots[0]; |
| @@ -416,12 +416,33 @@ static void sdhci_sprd_request_done(struct sdhci_host *host, · 415 unmodified lines | ||
| 416 | 416 | mmc_request_done(host->mmc, mrq); |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | +static void sdhci_sprd_set_power(struct sdhci_host *host, unsigned char mode, | |
| 420 | + unsigned short vdd) | |
| 421 | +{ | |
| 422 | + struct mmc_host *mmc = host->mmc; | |
| 423 | + | |
| 424 | + switch (mode) { | |
| 425 | + case MMC_POWER_OFF: | |
| 426 | + mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, 0); | |
| 427 | + | |
| 428 | + mmc_regulator_disable_vqmmc(mmc); | |
| 429 | + break; | |
| 430 | + case MMC_POWER_ON: | |
| 431 | + mmc_regulator_enable_vqmmc(mmc); | |
| 432 | + break; | |
| 433 | + case MMC_POWER_UP: | |
| 434 | + mmc_regulator_set_ocr(host->mmc, mmc->supply.vmmc, vdd); | |
| 435 | + break; | |
| 436 | + } | |
| 437 | +} | |
| 438 | + | |
| 419 | 439 | static struct sdhci_ops sdhci_sprd_ops = { |
| 420 | 440 | .read_l = sdhci_sprd_readl, |
| 421 | 441 | .write_l = sdhci_sprd_writel, |
| 422 | 442 | .write_w = sdhci_sprd_writew, |
| 423 | 443 | .write_b = sdhci_sprd_writeb, |
| 424 | 444 | .set_clock = sdhci_sprd_set_clock, |
| 445 | + .set_power = sdhci_sprd_set_power, | |
| 425 | 446 | .get_max_clock = sdhci_sprd_get_max_clock, |
| 426 | 447 | .get_min_clock = sdhci_sprd_get_min_clock, |
| 427 | 448 | .set_bus_width = sdhci_set_bus_width, |
| @@ -823,6 +844,10 @@ static int sdhci_sprd_probe(struct platform_device *pdev) · 395 unmodified lines | ||
| 823 | 844 | host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | |
| 824 | 845 | SDHCI_SUPPORT_DDR50); |
| 825 | 846 | |
| 847 | + ret = mmc_regulator_get_supply(host->mmc); | |
| 848 | + if (ret) | |
| 849 | + goto pm_runtime_disable; | |
| 850 | + | |
| 826 | 851 | ret = sdhci_setup_host(host); |
| 827 | 852 | if (ret) |
| 828 | 853 | goto pm_runtime_disable; |
| @@ -186,6 +186,8 @@ do { \ · 185 unmodified lines | ||
| 186 | 186 | #define ARC_IS_5MBIT 1 /* card default speed is 5MBit */ |
| 187 | 187 | #define ARC_CAN_10MBIT 2 /* card uses COM20022, supporting 10MBit, |
| 188 | 188 | but default is 2.5MBit. */ |
| 189 | +#define ARC_HAS_LED 4 /* card has software controlled LEDs */ | |
| 190 | +#define ARC_HAS_ROTARY 8 /* card has rotary encoder */ | |
| 189 | 191 | |
| 190 | 192 | /* information needed to define an encapsulation driver */ |
| 191 | 193 | struct ArcProto { |
| @@ -213,12 +213,13 @@ static int com20020pci_probe(struct pci_dev *pdev, · 212 unmodified lines | ||
| 213 | 213 | if (!strncmp(ci->name, "EAE PLX-PCI FB2", 15)) |
| 214 | 214 | lp->backplane = 1; |
| 215 | 215 | |
| 216 | − /* Get the dev_id from the PLX rotary coder */ | |
| 217 | − if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) | |
| 218 | − dev_id_mask = 0x3; | |
| 219 | − dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; | |
| 220 | − | |
| 221 | − snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); | |
| 216 | + if (ci->flags & ARC_HAS_ROTARY) { | |
| 217 | + /* Get the dev_id from the PLX rotary coder */ | |
| 218 | + if (!strncmp(ci->name, "EAE PLX-PCI MA1", 15)) | |
| 219 | + dev_id_mask = 0x3; | |
| 220 | + dev->dev_id = (inb(priv->misc + ci->rotary) >> 4) & dev_id_mask; | |
| 221 | + snprintf(dev->name, sizeof(dev->name), "arc%d-%d", dev->dev_id, i); | |
| 222 | + } | |
| 222 | 223 | |
| 223 | 224 | if (arcnet_inb(ioaddr, COM20020_REG_R_STATUS) == 0xFF) { |
| 224 | 225 | pr_err("IO address %Xh is empty!\n", ioaddr); |
| @@ -230,6 +231,10 @@ static int com20020pci_probe(struct pci_dev *pdev, · 5 unmodified lines | ||
| 230 | 231 | goto err_free_arcdev; |
| 231 | 232 | } |
| 232 | 233 | |
| 234 | + ret = com20020_found(dev, IRQF_SHARED); | |
| 235 | + if (ret) | |
| 236 | + goto err_free_arcdev; | |
| 237 | + | |
| 233 | 238 | card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev), |
| 234 | 239 | GFP_KERNEL); |
| 235 | 240 | if (!card) { |
| @@ -239,41 +244,39 @@ static int com20020pci_probe(struct pci_dev *pdev, · 3 unmodified lines | ||
| 239 | 244 | |
| 240 | 245 | card->index = i; |
| 241 | 246 | card->pci_priv = priv; |
| 242 | − card->tx_led.brightness_set = led_tx_set; | |
| 243 | − card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, | |
| 244 | − GFP_KERNEL, "arc%d-%d-tx", | |
| 245 | − dev->dev_id, i); | |
| 246 | − card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, | |
| 247 | − "pci:green:tx:%d-%d", | |
| 248 | − dev->dev_id, i); | |
| 249 | − | |
| 250 | − card->tx_led.dev = &dev->dev; | |
| 251 | − card->recon_led.brightness_set = led_recon_set; | |
| 252 | − card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, | |
| 253 | − GFP_KERNEL, "arc%d-%d-recon", | |
| 254 | − dev->dev_id, i); | |
| 255 | − card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, | |
| 256 | − "pci:red:recon:%d-%d", | |
| 257 | − dev->dev_id, i); | |
| 258 | − card->recon_led.dev = &dev->dev; | |
| 259 | − card->dev = dev; | |
| 260 | − | |
| 261 | − ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); | |
| 262 | − if (ret) | |
| 263 | − goto err_free_arcdev; | |
| 264 | 247 | |
| 265 | − ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); | |
| 266 | − if (ret) | |
| 267 | − goto err_free_arcdev; | |
| 268 | − | |
| 269 | − dev_set_drvdata(&dev->dev, card); | |
| 270 | − | |
| 271 | − ret = com20020_found(dev, IRQF_SHARED); | |
| 272 | − if (ret) | |
| 273 | − goto err_free_arcdev; | |
| 274 | − | |
| 275 | − devm_arcnet_led_init(dev, dev->dev_id, i); | |
| 248 | + if (ci->flags & ARC_HAS_LED) { | |
| 249 | + card->tx_led.brightness_set = led_tx_set; | |
| 250 | + card->tx_led.default_trigger = devm_kasprintf(&pdev->dev, | |
| 251 | + GFP_KERNEL, "arc%d-%d-tx", | |
| 252 | + dev->dev_id, i); | |
| 253 | + card->tx_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, | |
| 254 | + "pci:green:tx:%d-%d", | |
| 255 | + dev->dev_id, i); | |
| 256 | + | |
| 257 | + card->tx_led.dev = &dev->dev; | |
| 258 | + card->recon_led.brightness_set = led_recon_set; | |
| 259 | + card->recon_led.default_trigger = devm_kasprintf(&pdev->dev, | |
| 260 | + GFP_KERNEL, "arc%d-%d-recon", | |
| 261 | + dev->dev_id, i); | |
| 262 | + card->recon_led.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, | |
| 263 | + "pci:red:recon:%d-%d", | |
| 264 | + dev->dev_id, i); | |
| 265 | + card->recon_led.dev = &dev->dev; | |
| 266 | + | |
| 267 | + ret = devm_led_classdev_register(&pdev->dev, &card->tx_led); | |
| 268 | + if (ret) | |
| 269 | + goto err_free_arcdev; | |
| 270 | + | |
| 271 | + ret = devm_led_classdev_register(&pdev->dev, &card->recon_led); | |
| 272 | + if (ret) | |
| 273 | + goto err_free_arcdev; | |
| 274 | + | |
| 275 | + dev_set_drvdata(&dev->dev, card); | |
| 276 | + devm_arcnet_led_init(dev, dev->dev_id, i); | |
| 277 | + } | |
| 276 | 278 | |
| 279 | + card->dev = dev; | |
| 277 | 280 | list_add(&card->list, &priv->list_dev); |
| 278 | 281 | continue; |
| 279 | 282 | |
| @@ -329,7 +332,7 @@ static struct com20020_pci_card_info card_info_5mbit = { · 49 unmodified lines | ||
| 329 | 332 | }; |
| 330 | 333 | |
| 331 | 334 | static struct com20020_pci_card_info card_info_sohard = { |
| 332 | − .name = "PLX-PCI", | |
| 335 | + .name = "SOHARD SH ARC-PCI", | |
| 333 | 336 | .devcount = 1, |
| 334 | 337 | /* SOHARD needs PCI base addr 4 */ |
| 335 | 338 | .chan_map_tbl = { |
| @@ -364,7 +367,7 @@ static struct com20020_pci_card_info card_info_eae_arc1 = { · 28 unmodified lines | ||
| 364 | 367 | }, |
| 365 | 368 | }, |
| 366 | 369 | .rotary = 0x0, |
| 367 | − .flags = ARC_CAN_10MBIT, | |
| 370 | + .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, | |
| 368 | 371 | }; |
| 369 | 372 | |
| 370 | 373 | static struct com20020_pci_card_info card_info_eae_ma1 = { |
| @@ -396,7 +399,7 @@ static struct com20020_pci_card_info card_info_eae_ma1 = { · 25 unmodified lines | ||
| 396 | 399 | }, |
| 397 | 400 | }, |
| 398 | 401 | .rotary = 0x0, |
| 399 | − .flags = ARC_CAN_10MBIT, | |
| 402 | + .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, | |
| 400 | 403 | }; |
| 401 | 404 | |
| 402 | 405 | static struct com20020_pci_card_info card_info_eae_fb2 = { |
| @@ -421,7 +424,7 @@ static struct com20020_pci_card_info card_info_eae_fb2 = { · 18 unmodified lines | ||
| 421 | 424 | }, |
| 422 | 425 | }, |
| 423 | 426 | .rotary = 0x0, |
| 424 | − .flags = ARC_CAN_10MBIT, | |
| 427 | + .flags = ARC_HAS_ROTARY | ARC_HAS_LED | ARC_CAN_10MBIT, | |
| 425 | 428 | }; |
| 426 | 429 | |
| 427 | 430 | static const struct pci_device_id com20020pci_id_table[] = { |
| @@ -1500,6 +1500,10 @@ done: · 1499 unmodified lines | ||
| 1500 | 1500 | static void bond_setup_by_slave(struct net_device *bond_dev, |
| 1501 | 1501 | struct net_device *slave_dev) |
| 1502 | 1502 | { |
| 1503 | + bool was_up = !!(bond_dev->flags & IFF_UP); | |
| 1504 | + | |
| 1505 | + dev_close(bond_dev); | |
| 1506 | + | |
| 1503 | 1507 | bond_dev->header_ops = slave_dev->header_ops; |
| 1504 | 1508 | |
| 1505 | 1509 | bond_dev->type = slave_dev->type; |
| @@ -1514,6 +1518,8 @@ static void bond_setup_by_slave(struct net_device *bond_dev, · 8 unmodified lines | ||
| 1514 | 1518 | bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); |
| 1515 | 1519 | bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); |
| 1516 | 1520 | } |
| 1521 | + if (was_up) | |
| 1522 | + dev_open(bond_dev, NULL); | |
| 1517 | 1523 | } |
| 1518 | 1524 | |
| 1519 | 1525 | /* On bonding slaves other than the currently active slave, suppress |
| @@ -2713,10 +2713,18 @@ static int ksz_connect_tag_protocol(struct dsa_switch *ds, · 2712 unmodified lines | ||
| 2713 | 2713 | { |
| 2714 | 2714 | struct ksz_tagger_data *tagger_data; |
| 2715 | 2715 | |
| 2716 | − tagger_data = ksz_tagger_data(ds); | |
| 2717 | − tagger_data->xmit_work_fn = ksz_port_deferred_xmit; | |
| 2718 | − | |
| 2719 | − return 0; | |
| 2716 | + switch (proto) { | |
| 2717 | + case DSA_TAG_PROTO_KSZ8795: | |
| 2718 | + return 0; | |
| 2719 | + case DSA_TAG_PROTO_KSZ9893: | |
| 2720 | + case DSA_TAG_PROTO_KSZ9477: | |
| 2721 | + case DSA_TAG_PROTO_LAN937X: | |
| 2722 | + tagger_data = ksz_tagger_data(ds); | |
| 2723 | + tagger_data->xmit_work_fn = ksz_port_deferred_xmit; | |
| 2724 | + return 0; | |
| 2725 | + default: | |
| 2726 | + return -EPROTONOSUPPORT; | |
| 2727 | + } | |
| 2720 | 2728 | } |
| 2721 | 2729 | |
| 2722 | 2730 | static int ksz_port_vlan_filtering(struct dsa_switch *ds, int port, |
| @@ -577,6 +577,18 @@ static void mv88e6250_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, · 576 unmodified lines | ||
| 577 | 577 | config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100; |
| 578 | 578 | } |
| 579 | 579 | |
| 580 | +static void mv88e6351_phylink_get_caps(struct mv88e6xxx_chip *chip, int port, | |
| 581 | + struct phylink_config *config) | |
| 582 | +{ | |
| 583 | + unsigned long *supported = config->supported_interfaces; | |
| 584 | + | |
| 585 | + /* Translate the default cmode */ | |
| 586 | + mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported); | |
| 587 | + | |
| 588 | + config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 | | |
| 589 | + MAC_1000FD; | |
| 590 | +} | |
| 591 | + | |
| 580 | 592 | static int mv88e6352_get_port4_serdes_cmode(struct mv88e6xxx_chip *chip) |
| 581 | 593 | { |
| 582 | 594 | u16 reg, val; |
| @@ -3880,7 +3892,8 @@ static int mv88e6xxx_port_setup(struct dsa_switch *ds, int port) · 3297 unmodified lines | ||
| 3880 | 3892 | struct mv88e6xxx_chip *chip = ds->priv; |
| 3881 | 3893 | int err; |
| 3882 | 3894 | |
| 3883 | − if (chip->info->ops->pcs_ops->pcs_init) { | |
| 3895 | + if (chip->info->ops->pcs_ops && | |
| 3896 | + chip->info->ops->pcs_ops->pcs_init) { | |
| 3884 | 3897 | err = chip->info->ops->pcs_ops->pcs_init(chip, port); |
| 3885 | 3898 | if (err) |
| 3886 | 3899 | return err; |
| @@ -3895,7 +3908,8 @@ static void mv88e6xxx_port_teardown(struct dsa_switch *ds, int port) · 8 unmodified lines | ||
| 3895 | 3908 | |
| 3896 | 3909 | mv88e6xxx_teardown_devlink_regions_port(ds, port); |
| 3897 | 3910 | |
| 3898 | − if (chip->info->ops->pcs_ops->pcs_teardown) | |
| 3911 | + if (chip->info->ops->pcs_ops && | |
| 3912 | + chip->info->ops->pcs_ops->pcs_teardown) | |
| 3899 | 3913 | chip->info->ops->pcs_ops->pcs_teardown(chip, port); |
| 3900 | 3914 | } |
| 3901 | 3915 | |
| @@ -4340,7 +4354,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = { · 438 unmodified lines | ||
| 4340 | 4354 | .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, |
| 4341 | 4355 | .stu_getnext = mv88e6352_g1_stu_getnext, |
| 4342 | 4356 | .stu_loadpurge = mv88e6352_g1_stu_loadpurge, |
| 4343 | − .phylink_get_caps = mv88e6185_phylink_get_caps, | |
| 4357 | + .phylink_get_caps = mv88e6351_phylink_get_caps, | |
| 4344 | 4358 | }; |
| 4345 | 4359 | |
| 4346 | 4360 | static const struct mv88e6xxx_ops mv88e6172_ops = { |
| @@ -4440,7 +4454,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = { · 93 unmodified lines | ||
| 4440 | 4454 | .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, |
| 4441 | 4455 | .stu_getnext = mv88e6352_g1_stu_getnext, |
| 4442 | 4456 | .stu_loadpurge = mv88e6352_g1_stu_loadpurge, |
| 4443 | − .phylink_get_caps = mv88e6185_phylink_get_caps, | |
| 4457 | + .phylink_get_caps = mv88e6351_phylink_get_caps, | |
| 4444 | 4458 | }; |
| 4445 | 4459 | |
| 4446 | 4460 | static const struct mv88e6xxx_ops mv88e6176_ops = { |
| @@ -5069,7 +5083,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = { · 622 unmodified lines | ||
| 5069 | 5083 | .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, |
| 5070 | 5084 | .stu_getnext = mv88e6352_g1_stu_getnext, |
| 5071 | 5085 | .stu_loadpurge = mv88e6352_g1_stu_loadpurge, |
| 5072 | − .phylink_get_caps = mv88e6185_phylink_get_caps, | |
| 5086 | + .phylink_get_caps = mv88e6351_phylink_get_caps, | |
| 5073 | 5087 | }; |
| 5074 | 5088 | |
| 5075 | 5089 | static const struct mv88e6xxx_ops mv88e6351_ops = { |
| @@ -5117,7 +5131,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = { · 41 unmodified lines | ||
| 5117 | 5131 | .stu_loadpurge = mv88e6352_g1_stu_loadpurge, |
| 5118 | 5132 | .avb_ops = &mv88e6352_avb_ops, |
| 5119 | 5133 | .ptp_ops = &mv88e6352_ptp_ops, |
| 5120 | − .phylink_get_caps = mv88e6185_phylink_get_caps, | |
| 5134 | + .phylink_get_caps = mv88e6351_phylink_get_caps, | |
| 5121 | 5135 | }; |
| 5122 | 5136 | |
| 5123 | 5137 | static const struct mv88e6xxx_ops mv88e6352_ops = { |
| @@ -465,6 +465,7 @@ mv88e639x_pcs_select(struct mv88e6xxx_chip *chip, int port, · 464 unmodified lines | ||
| 465 | 465 | case PHY_INTERFACE_MODE_10GBASER: |
| 466 | 466 | case PHY_INTERFACE_MODE_XAUI: |
| 467 | 467 | case PHY_INTERFACE_MODE_RXAUI: |
| 468 | + case PHY_INTERFACE_MODE_USXGMII: | |
| 468 | 469 | return &mpcs->xg_pcs; |
| 469 | 470 | |
| 470 | 471 | default: |
| @@ -873,7 +874,8 @@ static int mv88e6393x_xg_pcs_post_config(struct phylink_pcs *pcs, · 402 unmodified lines | ||
| 873 | 874 | struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); |
| 874 | 875 | int err; |
| 875 | 876 | |
| 876 | − if (interface == PHY_INTERFACE_MODE_10GBASER) { | |
| 877 | + if (interface == PHY_INTERFACE_MODE_10GBASER || | |
| 878 | + interface == PHY_INTERFACE_MODE_USXGMII) { | |
| 877 | 879 | err = mv88e6393x_erratum_5_2(mpcs); |
| 878 | 880 | if (err) |
| 879 | 881 | return err; |
| @@ -886,12 +888,37 @@ static int mv88e6393x_xg_pcs_post_config(struct phylink_pcs *pcs, · 6 unmodified lines | ||
| 886 | 888 | return mv88e639x_xg_pcs_enable(mpcs); |
| 887 | 889 | } |
| 888 | 890 | |
| 891 | +static void mv88e6393x_xg_pcs_get_state(struct phylink_pcs *pcs, | |
| 892 | + struct phylink_link_state *state) | |
| 893 | +{ | |
| 894 | + struct mv88e639x_pcs *mpcs = xg_pcs_to_mv88e639x_pcs(pcs); | |
| 895 | + u16 status, lp_status; | |
| 896 | + int err; | |
| 897 | + | |
| 898 | + if (state->interface != PHY_INTERFACE_MODE_USXGMII) | |
| 899 | + return mv88e639x_xg_pcs_get_state(pcs, state); | |
| 900 | + | |
| 901 | + state->link = false; | |
| 902 | + | |
| 903 | + err = mv88e639x_read(mpcs, MV88E6390_USXGMII_PHY_STATUS, &status); | |
| 904 | + err = err ? : mv88e639x_read(mpcs, MV88E6390_USXGMII_LP_STATUS, &lp_status); | |
| 905 | + if (err) { | |
| 906 | + dev_err(mpcs->mdio.dev.parent, | |
| 907 | + "can't read USXGMII status: %pe\n", ERR_PTR(err)); | |
| 908 | + return; | |
| 909 | + } | |
| 910 | + | |
| 911 | + state->link = !!(status & MDIO_USXGMII_LINK); | |
| 912 | + state->an_complete = state->link; | |
| 913 | + phylink_decode_usxgmii_word(state, lp_status); | |
| 914 | +} | |
| 915 | + | |
| 889 | 916 | static const struct phylink_pcs_ops mv88e6393x_xg_pcs_ops = { |
| 890 | 917 | .pcs_enable = mv88e6393x_xg_pcs_enable, |
| 891 | 918 | .pcs_disable = mv88e6393x_xg_pcs_disable, |
| 892 | 919 | .pcs_pre_config = mv88e6393x_xg_pcs_pre_config, |
| 893 | 920 | .pcs_post_config = mv88e6393x_xg_pcs_post_config, |
| 894 | − .pcs_get_state = mv88e639x_xg_pcs_get_state, | |
| 921 | + .pcs_get_state = mv88e6393x_xg_pcs_get_state, | |
| 895 | 922 | .pcs_config = mv88e639x_xg_pcs_config, |
| 896 | 923 | }; |
| 897 | 924 | |
| @@ -146,7 +146,7 @@ irqreturn_t pdsc_adminq_isr(int irq, void *data) · 145 unmodified lines | ||
| 146 | 146 | } |
| 147 | 147 | |
| 148 | 148 | queue_work(pdsc->wq, &qcq->work); |
| 149 | − pds_core_intr_mask(&pdsc->intr_ctrl[irq], PDS_CORE_INTR_MASK_CLEAR); | |
| 149 | + pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR); | |
| 150 | 150 | |
| 151 | 151 | return IRQ_HANDLED; |
| 152 | 152 | } |
| @@ -15,7 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #define PDSC_DRV_DESCRIPTION "AMD/Pensando Core Driver" |
| 16 | 16 | |
| 17 | 17 | #define PDSC_WATCHDOG_SECS 5 |
| 18 | −#define PDSC_QUEUE_NAME_MAX_SZ 32 | |
| 18 | +#define PDSC_QUEUE_NAME_MAX_SZ 16 | |
| 19 | 19 | #define PDSC_ADMINQ_MIN_LENGTH 16 /* must be a power of two */ |
| 20 | 20 | #define PDSC_NOTIFYQ_LENGTH 64 /* must be a power of two */ |
| 21 | 21 | #define PDSC_TEARDOWN_RECOVERY false |
| @@ -261,10 +261,14 @@ static int pdsc_identify(struct pdsc *pdsc) · 260 unmodified lines | ||
| 261 | 261 | struct pds_core_drv_identity drv = {}; |
| 262 | 262 | size_t sz; |
| 263 | 263 | int err; |
| 264 | + int n; | |
| 264 | 265 | |
| 265 | 266 | drv.drv_type = cpu_to_le32(PDS_DRIVER_LINUX); |
| 266 | − snprintf(drv.driver_ver_str, sizeof(drv.driver_ver_str), | |
| 267 | − "%s %s", PDS_CORE_DRV_NAME, utsname()->release); | |
| 267 | + /* Catching the return quiets a Wformat-truncation complaint */ | |
| 268 | + n = snprintf(drv.driver_ver_str, sizeof(drv.driver_ver_str), | |
| 269 | + "%s %s", PDS_CORE_DRV_NAME, utsname()->release); | |
| 270 | + if (n > sizeof(drv.driver_ver_str)) | |
| 271 | + dev_dbg(pdsc->dev, "release name truncated, don't care\n"); | |
| 268 | 272 | |
| 269 | 273 | /* Next let's get some info about the device |
| 270 | 274 | * We use the devcmd_lock at this level in order to |
| @@ -104,7 +104,7 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req, · 103 unmodified lines | ||
| 104 | 104 | struct pds_core_fw_list_info fw_list; |
| 105 | 105 | struct pdsc *pdsc = devlink_priv(dl); |
| 106 | 106 | union pds_core_dev_comp comp; |
| 107 | − char buf[16]; | |
| 107 | + char buf[32]; | |
| 108 | 108 | int listlen; |
| 109 | 109 | int err; |
| 110 | 110 | int i; |
| @@ -682,10 +682,24 @@ static void xgbe_service(struct work_struct *work) · 681 unmodified lines | ||
| 682 | 682 | static void xgbe_service_timer(struct timer_list *t) |
| 683 | 683 | { |
| 684 | 684 | struct xgbe_prv_data *pdata = from_timer(pdata, t, service_timer); |
| 685 | + struct xgbe_channel *channel; | |
| 686 | + unsigned int i; | |
| 685 | 687 | |
| 686 | 688 | queue_work(pdata->dev_workqueue, &pdata->service_work); |
| 687 | 689 | |
| 688 | 690 | mod_timer(&pdata->service_timer, jiffies + HZ); |
| 691 | + | |
| 692 | + if (!pdata->tx_usecs) | |
| 693 | + return; | |
| 694 | + | |
| 695 | + for (i = 0; i < pdata->channel_count; i++) { | |
| 696 | + channel = pdata->channel[i]; | |
| 697 | + if (!channel->tx_ring || channel->tx_timer_active) | |
| 698 | + break; | |
| 699 | + channel->tx_timer_active = 1; | |
| 700 | + mod_timer(&channel->tx_timer, | |
| 701 | + jiffies + usecs_to_jiffies(pdata->tx_usecs)); | |
| 702 | + } | |
| 689 | 703 | } |
| 690 | 704 | |
| 691 | 705 | static void xgbe_init_timers(struct xgbe_prv_data *pdata) |
| @@ -314,10 +314,15 @@ static int xgbe_get_link_ksettings(struct net_device *netdev, · 313 unmodified lines | ||
| 314 | 314 | |
| 315 | 315 | cmd->base.phy_address = pdata->phy.address; |
| 316 | 316 | |
| 317 | − cmd->base.autoneg = pdata->phy.autoneg; | |
| 318 | − cmd->base.speed = pdata->phy.speed; | |
| 319 | − cmd->base.duplex = pdata->phy.duplex; | |
| 317 | + if (netif_carrier_ok(netdev)) { | |
| 318 | + cmd->base.speed = pdata->phy.speed; | |
| 319 | + cmd->base.duplex = pdata->phy.duplex; | |
| 320 | + } else { | |
| 321 | + cmd->base.speed = SPEED_UNKNOWN; | |
| 322 | + cmd->base.duplex = DUPLEX_UNKNOWN; | |
| 323 | + } | |
| 320 | 324 | |
| 325 | + cmd->base.autoneg = pdata->phy.autoneg; | |
| 321 | 326 | cmd->base.port = PORT_NONE; |
| 322 | 327 | |
| 323 | 328 | XGBE_LM_COPY(cmd, supported, lks, supported); |
| @@ -1193,7 +1193,19 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata) · 1192 unmodified lines | ||
| 1193 | 1193 | if (pdata->phy.duplex != DUPLEX_FULL) |
| 1194 | 1194 | return -EINVAL; |
| 1195 | 1195 | |
| 1196 | − xgbe_set_mode(pdata, mode); | |
| 1196 | + /* Force the mode change for SFI in Fixed PHY config. | |
| 1197 | + * Fixed PHY configs needs PLL to be enabled while doing mode set. | |
| 1198 | + * When the SFP module isn't connected during boot, driver assumes | |
| 1199 | + * AN is ON and attempts autonegotiation. However, if the connected | |
| 1200 | + * SFP comes up in Fixed PHY config, the link will not come up as | |
| 1201 | + * PLL isn't enabled while the initial mode set command is issued. | |
| 1202 | + * So, force the mode change for SFI in Fixed PHY configuration to | |
| 1203 | + * fix link issues. | |
| 1204 | + */ | |
| 1205 | + if (mode == XGBE_MODE_SFI) | |
| 1206 | + xgbe_change_mode(pdata, mode); | |
| 1207 | + else | |
| 1208 | + xgbe_set_mode(pdata, mode); | |
| 1197 | 1209 | |
| 1198 | 1210 | return 0; |
| 1199 | 1211 | } |
| @@ -553,17 +553,17 @@ void aq_ptp_tx_hwtstamp(struct aq_nic_s *aq_nic, u64 timestamp) · 552 unmodified lines | ||
| 553 | 553 | |
| 554 | 554 | /* aq_ptp_rx_hwtstamp - utility function which checks for RX time stamp |
| 555 | 555 | * @adapter: pointer to adapter struct |
| 556 | − * @skb: particular skb to send timestamp with | |
| 556 | + * @shhwtstamps: particular skb_shared_hwtstamps to save timestamp | |
| 557 | 557 | * |
| 558 | 558 | * if the timestamp is valid, we convert it into the timecounter ns |
| 559 | 559 | * value, then store that result into the hwtstamps structure which |
| 560 | 560 | * is passed up the network stack |
| 561 | 561 | */ |
| 562 | −static void aq_ptp_rx_hwtstamp(struct aq_ptp_s *aq_ptp, struct sk_buff *skb, | |
| 562 | +static void aq_ptp_rx_hwtstamp(struct aq_ptp_s *aq_ptp, struct skb_shared_hwtstamps *shhwtstamps, | |
| 563 | 563 | u64 timestamp) |
| 564 | 564 | { |
| 565 | 565 | timestamp -= atomic_read(&aq_ptp->offset_ingress); |
| 566 | − aq_ptp_convert_to_hwtstamp(aq_ptp, skb_hwtstamps(skb), timestamp); | |
| 566 | + aq_ptp_convert_to_hwtstamp(aq_ptp, shhwtstamps, timestamp); | |
| 567 | 567 | } |
| 568 | 568 | |
| 569 | 569 | void aq_ptp_hwtstamp_config_get(struct aq_ptp_s *aq_ptp, |
| @@ -639,7 +639,7 @@ bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring) · 69 unmodified lines | ||
| 639 | 639 | &aq_ptp->ptp_rx == ring || &aq_ptp->hwts_rx == ring; |
| 640 | 640 | } |
| 641 | 641 | |
| 642 | −u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p, | |
| 642 | +u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct skb_shared_hwtstamps *shhwtstamps, u8 *p, | |
| 643 | 643 | unsigned int len) |
| 644 | 644 | { |
| 645 | 645 | struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp; |
| @@ -648,7 +648,7 @@ u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p, · 2 unmodified lines | ||
| 648 | 648 | p, len, ×tamp); |
| 649 | 649 | |
| 650 | 650 | if (ret > 0) |
| 651 | − aq_ptp_rx_hwtstamp(aq_ptp, skb, timestamp); | |
| 651 | + aq_ptp_rx_hwtstamp(aq_ptp, shhwtstamps, timestamp); | |
| 652 | 652 | |
| 653 | 653 | return ret; |
| 654 | 654 | } |
| @@ -67,7 +67,7 @@ int aq_ptp_hwtstamp_config_set(struct aq_ptp_s *aq_ptp, · 66 unmodified lines | ||
| 67 | 67 | /* Return either ring is belong to PTP or not*/ |
| 68 | 68 | bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring); |
| 69 | 69 | |
| 70 | −u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct sk_buff *skb, u8 *p, | |
| 70 | +u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, struct skb_shared_hwtstamps *shhwtstamps, u8 *p, | |
| 71 | 71 | unsigned int len); |
| 72 | 72 | |
| 73 | 73 | struct ptp_clock *aq_ptp_get_ptp_clock(struct aq_ptp_s *aq_ptp); |
| @@ -143,7 +143,7 @@ static inline bool aq_ptp_ring(struct aq_nic_s *aq_nic, struct aq_ring_s *ring) · 69 unmodified lines | ||
| 143 | 143 | } |
| 144 | 144 | |
| 145 | 145 | static inline u16 aq_ptp_extract_ts(struct aq_nic_s *aq_nic, |
| 146 | − struct sk_buff *skb, u8 *p, | |
| 146 | + struct skb_shared_hwtstamps *shhwtstamps, u8 *p, | |
| 147 | 147 | unsigned int len) |
| 148 | 148 | { |
| 149 | 149 | return 0; |
| @@ -647,7 +647,7 @@ static int __aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi, · 646 unmodified lines | ||
| 647 | 647 | } |
| 648 | 648 | if (is_ptp_ring) |
| 649 | 649 | buff->len -= |
| 650 | − aq_ptp_extract_ts(self->aq_nic, skb, | |
| 650 | + aq_ptp_extract_ts(self->aq_nic, skb_hwtstamps(skb), | |
| 651 | 651 | aq_buf_vaddr(&buff->rxdata), |
| 652 | 652 | buff->len); |
| 653 | 653 | |
| @@ -742,6 +742,8 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring, · 88 unmodified lines | ||
| 742 | 742 | struct aq_ring_buff_s *buff = &rx_ring->buff_ring[rx_ring->sw_head]; |
| 743 | 743 | bool is_ptp_ring = aq_ptp_ring(rx_ring->aq_nic, rx_ring); |
| 744 | 744 | struct aq_ring_buff_s *buff_ = NULL; |
| 745 | + u16 ptp_hwtstamp_len = 0; | |
| 746 | + struct skb_shared_hwtstamps shhwtstamps; | |
| 745 | 747 | struct sk_buff *skb = NULL; |
| 746 | 748 | unsigned int next_ = 0U; |
| 747 | 749 | struct xdp_buff xdp; |
| @@ -810,11 +812,12 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring, · 62 unmodified lines | ||
| 810 | 812 | hard_start = page_address(buff->rxdata.page) + |
| 811 | 813 | buff->rxdata.pg_off - rx_ring->page_offset; |
| 812 | 814 | |
| 813 | − if (is_ptp_ring) | |
| 814 | − buff->len -= | |
| 815 | − aq_ptp_extract_ts(rx_ring->aq_nic, skb, | |
| 816 | − aq_buf_vaddr(&buff->rxdata), | |
| 817 | − buff->len); | |
| 815 | + if (is_ptp_ring) { | |
| 816 | + ptp_hwtstamp_len = aq_ptp_extract_ts(rx_ring->aq_nic, &shhwtstamps, | |
| 817 | + aq_buf_vaddr(&buff->rxdata), | |
| 818 | + buff->len); | |
| 819 | + buff->len -= ptp_hwtstamp_len; | |
| 820 | + } | |
| 818 | 821 | |
| 819 | 822 | xdp_init_buff(&xdp, frame_sz, &rx_ring->xdp_rxq); |
| 820 | 823 | xdp_prepare_buff(&xdp, hard_start, rx_ring->page_offset, |
| @@ -834,6 +837,9 @@ static int __aq_ring_xdp_clean(struct aq_ring_s *rx_ring, · 13 unmodified lines | ||
| 834 | 837 | if (IS_ERR(skb) || !skb) |
| 835 | 838 | continue; |
| 836 | 839 | |
| 840 | + if (ptp_hwtstamp_len > 0) | |
| 841 | + *skb_hwtstamps(skb) = shhwtstamps; | |
| 842 | + | |
| 837 | 843 | if (buff->is_vlan) |
| 838 | 844 | __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), |
| 839 | 845 | buff->vlan_rx_tag); |
| @@ -2075,6 +2075,7 @@ destroy_flow_table: · 2074 unmodified lines | ||
| 2075 | 2075 | rhashtable_destroy(&tc_info->flow_table); |
| 2076 | 2076 | free_tc_info: |
| 2077 | 2077 | kfree(tc_info); |
| 2078 | + bp->tc_info = NULL; | |
| 2078 | 2079 | return rc; |
| 2079 | 2080 | } |
| 2080 | 2081 | |
| @@ -6474,6 +6474,14 @@ static void tg3_dump_state(struct tg3 *tp) · 6473 unmodified lines | ||
| 6474 | 6474 | int i; |
| 6475 | 6475 | u32 *regs; |
| 6476 | 6476 | |
| 6477 | + /* If it is a PCI error, all registers will be 0xffff, | |
| 6478 | + * we don't dump them out, just report the error and return | |
| 6479 | + */ | |
| 6480 | + if (tp->pdev->error_state != pci_channel_io_normal) { | |
| 6481 | + netdev_err(tp->dev, "PCI channel ERROR!\n"); | |
| 6482 | + return; | |
| 6483 | + } | |
| 6484 | + | |
| 6477 | 6485 | regs = kzalloc(TG3_REG_BLK_SIZE, GFP_ATOMIC); |
| 6478 | 6486 | if (!regs) |
| 6479 | 6487 | return; |
| @@ -6889,7 +6897,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) · 409 unmodified lines | ||
| 6889 | 6897 | desc_idx, *post_ptr); |
| 6890 | 6898 | drop_it_no_recycle: |
| 6891 | 6899 | /* Other statistics kept track of by card. */ |
| 6892 | − tp->rx_dropped++; | |
| 6900 | + tnapi->rx_dropped++; | |
| 6893 | 6901 | goto next_pkt; |
| 6894 | 6902 | } |
| 6895 | 6903 | |
| @@ -7918,8 +7926,10 @@ static int tg3_tso_bug(struct tg3 *tp, struct tg3_napi *tnapi, · 1022 unmodified lines | ||
| 7918 | 7926 | |
| 7919 | 7927 | segs = skb_gso_segment(skb, tp->dev->features & |
| 7920 | 7928 | ~(NETIF_F_TSO | NETIF_F_TSO6)); |
| 7921 | − if (IS_ERR(segs) || !segs) | |
| 7929 | + if (IS_ERR(segs) || !segs) { | |
| 7930 | + tnapi->tx_dropped++; | |
| 7922 | 7931 | goto tg3_tso_bug_end; |
| 7932 | + } | |
| 7923 | 7933 | |
| 7924 | 7934 | skb_list_walk_safe(segs, seg, next) { |
| 7925 | 7935 | skb_mark_not_on_list(seg); |
| @@ -8190,7 +8200,7 @@ dma_error: · 264 unmodified lines | ||
| 8190 | 8200 | drop: |
| 8191 | 8201 | dev_kfree_skb_any(skb); |
| 8192 | 8202 | drop_nofree: |
| 8193 | − tp->tx_dropped++; | |
| 8203 | + tnapi->tx_dropped++; | |
| 8194 | 8204 | return NETDEV_TX_OK; |
| 8195 | 8205 | } |
| 8196 | 8206 | |
| @@ -9405,7 +9415,7 @@ static void __tg3_set_rx_mode(struct net_device *); · 1208 unmodified lines | ||
| 9405 | 9415 | /* tp->lock is held. */ |
| 9406 | 9416 | static int tg3_halt(struct tg3 *tp, int kind, bool silent) |
| 9407 | 9417 | { |
| 9408 | − int err; | |
| 9418 | + int err, i; | |
| 9409 | 9419 | |
| 9410 | 9420 | tg3_stop_fw(tp); |
| 9411 | 9421 | |
| @@ -9426,6 +9436,13 @@ static int tg3_halt(struct tg3 *tp, int kind, bool silent) · 14 unmodified lines | ||
| 9426 | 9436 | |
| 9427 | 9437 | /* And make sure the next sample is new data */ |
| 9428 | 9438 | memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); |
| 9439 | + | |
| 9440 | + for (i = 0; i < TG3_IRQ_MAX_VECS; ++i) { | |
| 9441 | + struct tg3_napi *tnapi = &tp->napi[i]; | |
| 9442 | + | |
| 9443 | + tnapi->rx_dropped = 0; | |
| 9444 | + tnapi->tx_dropped = 0; | |
| 9445 | + } | |
| 9429 | 9446 | } |
| 9430 | 9447 | |
| 9431 | 9448 | return err; |
| @@ -11250,7 +11267,8 @@ static void tg3_reset_task(struct work_struct *work) · 1818 unmodified lines | ||
| 11250 | 11267 | rtnl_lock(); |
| 11251 | 11268 | tg3_full_lock(tp, 0); |
| 11252 | 11269 | |
| 11253 | − if (tp->pcierr_recovery || !netif_running(tp->dev)) { | |
| 11270 | + if (tp->pcierr_recovery || !netif_running(tp->dev) || | |
| 11271 | + tp->pdev->error_state != pci_channel_io_normal) { | |
| 11254 | 11272 | tg3_flag_clear(tp, RESET_TASK_PENDING); |
| 11255 | 11273 | tg3_full_unlock(tp); |
| 11256 | 11274 | rtnl_unlock(); |
| @@ -11975,6 +11993,9 @@ static void tg3_get_nstats(struct tg3 *tp, struct rtnl_link_stats64 *stats) · 718 unmodified lines | ||
| 11975 | 11993 | { |
| 11976 | 11994 | struct rtnl_link_stats64 *old_stats = &tp->net_stats_prev; |
| 11977 | 11995 | struct tg3_hw_stats *hw_stats = tp->hw_stats; |
| 11996 | + unsigned long rx_dropped; | |
| 11997 | + unsigned long tx_dropped; | |
| 11998 | + int i; | |
| 11978 | 11999 | |
| 11979 | 12000 | stats->rx_packets = old_stats->rx_packets + |
| 11980 | 12001 | get_stat64(&hw_stats->rx_ucast_packets) + |
| @@ -12021,8 +12042,26 @@ static void tg3_get_nstats(struct tg3 *tp, struct rtnl_link_stats64 *stats) · 40 unmodified lines | ||
| 12021 | 12042 | stats->rx_missed_errors = old_stats->rx_missed_errors + |
| 12022 | 12043 | get_stat64(&hw_stats->rx_discards); |
| 12023 | 12044 | |
| 12024 | − stats->rx_dropped = tp->rx_dropped; | |
| 12025 | − stats->tx_dropped = tp->tx_dropped; | |
| 12045 | + /* Aggregate per-queue counters. The per-queue counters are updated | |
| 12046 | + * by a single writer, race-free. The result computed by this loop | |
| 12047 | + * might not be 100% accurate (counters can be updated in the middle of | |
| 12048 | + * the loop) but the next tg3_get_nstats() will recompute the current | |
| 12049 | + * value so it is acceptable. | |
| 12050 | + * | |
| 12051 | + * Note that these counters wrap around at 4G on 32bit machines. | |
| 12052 | + */ | |
| 12053 | + rx_dropped = (unsigned long)(old_stats->rx_dropped); | |
| 12054 | + tx_dropped = (unsigned long)(old_stats->tx_dropped); | |
| 12055 | + | |
| 12056 | + for (i = 0; i < tp->irq_cnt; i++) { | |
| 12057 | + struct tg3_napi *tnapi = &tp->napi[i]; | |
| 12058 | + | |
| 12059 | + rx_dropped += tnapi->rx_dropped; | |
| 12060 | + tx_dropped += tnapi->tx_dropped; | |
| 12061 | + } | |
| 12062 | + | |
| 12063 | + stats->rx_dropped = rx_dropped; | |
| 12064 | + stats->tx_dropped = tx_dropped; | |
| 12026 | 12065 | } |
| 12027 | 12066 | |
| 12028 | 12067 | static int tg3_get_regs_len(struct net_device *dev) |
| @@ -3018,6 +3018,7 @@ struct tg3_napi { · 3017 unmodified lines | ||
| 3018 | 3018 | u16 *rx_rcb_prod_idx; |
| 3019 | 3019 | struct tg3_rx_prodring_set prodring; |
| 3020 | 3020 | struct tg3_rx_buffer_desc *rx_rcb; |
| 3021 | + unsigned long rx_dropped; | |
| 3021 | 3022 | |
| 3022 | 3023 | u32 tx_prod ____cacheline_aligned; |
| 3023 | 3024 | u32 tx_cons; |
| @@ -3026,6 +3027,7 @@ struct tg3_napi { · 2 unmodified lines | ||
| 3026 | 3027 | u32 prodmbox; |
| 3027 | 3028 | struct tg3_tx_buffer_desc *tx_ring; |
| 3028 | 3029 | struct tg3_tx_ring_info *tx_buffers; |
| 3030 | + unsigned long tx_dropped; | |
| 3029 | 3031 | |
| 3030 | 3032 | dma_addr_t status_mapping; |
| 3031 | 3033 | dma_addr_t rx_rcb_mapping; |
| @@ -3220,8 +3222,6 @@ struct tg3 { · 188 unmodified lines | ||
| 3220 | 3222 | |
| 3221 | 3223 | |
| 3222 | 3224 | /* begin "everything else" cacheline(s) section */ |
| 3223 | − unsigned long rx_dropped; | |
| 3224 | − unsigned long tx_dropped; | |
| 3225 | 3225 | struct rtnl_link_stats64 net_stats_prev; |
| 3226 | 3226 | struct tg3_ethtool_stats estats_prev; |
| 3227 | 3227 | |
| @@ -432,8 +432,8 @@ static const struct gmac_max_framelen gmac_maxlens[] = { · 431 unmodified lines | ||
| 432 | 432 | .val = CONFIG0_MAXLEN_1536, |
| 433 | 433 | }, |
| 434 | 434 | { |
| 435 | − .max_l3_len = 1542, | |
| 436 | − .val = CONFIG0_MAXLEN_1542, | |
| 435 | + .max_l3_len = 1548, | |
| 436 | + .val = CONFIG0_MAXLEN_1548, | |
| 437 | 437 | }, |
| 438 | 438 | { |
| 439 | 439 | .max_l3_len = 9212, |
| @@ -1145,6 +1145,7 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, · 705 unmodified lines | ||
| 1145 | 1145 | dma_addr_t mapping; |
| 1146 | 1146 | unsigned short mtu; |
| 1147 | 1147 | void *buffer; |
| 1148 | + int ret; | |
| 1148 | 1149 | |
| 1149 | 1150 | mtu = ETH_HLEN; |
| 1150 | 1151 | mtu += netdev->mtu; |
| @@ -1159,9 +1160,30 @@ static int gmac_map_tx_bufs(struct net_device *netdev, struct sk_buff *skb, · 8 unmodified lines | ||
| 1159 | 1160 | word3 |= mtu; |
| 1160 | 1161 | } |
| 1161 | 1162 | |
| 1162 | − if (skb->ip_summed != CHECKSUM_NONE) { | |
| 1163 | + if (skb->len >= ETH_FRAME_LEN) { | |
| 1164 | + /* Hardware offloaded checksumming isn't working on frames | |
| 1165 | + * bigger than 1514 bytes. A hypothesis about this is that the | |
| 1166 | + * checksum buffer is only 1518 bytes, so when the frames get | |
| 1167 | + * bigger they get truncated, or the last few bytes get | |
| 1168 | + * overwritten by the FCS. | |
| 1169 | + * | |
| 1170 | + * Just use software checksumming and bypass on bigger frames. | |
| 1171 | + */ | |
| 1172 | + if (skb->ip_summed == CHECKSUM_PARTIAL) { | |
| 1173 | + ret = skb_checksum_help(skb); | |
| 1174 | + if (ret) | |
| 1175 | + return ret; | |
| 1176 | + } | |
| 1177 | + word1 |= TSS_BYPASS_BIT; | |
| 1178 | + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { | |
| 1163 | 1179 | int tcp = 0; |
| 1164 | 1180 | |
| 1181 | + /* We do not switch off the checksumming on non TCP/UDP | |
| 1182 | + * frames: as is shown from tests, the checksumming engine | |
| 1183 | + * is smart enough to see that a frame is not actually TCP | |
| 1184 | + * or UDP and then just pass it through without any changes | |
| 1185 | + * to the frame. | |
| 1186 | + */ | |
| 1165 | 1187 | if (skb->protocol == htons(ETH_P_IP)) { |
| 1166 | 1188 | word1 |= TSS_IP_CHKSUM_BIT; |
| 1167 | 1189 | tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; |
| @@ -1978,15 +2000,6 @@ static int gmac_change_mtu(struct net_device *netdev, int new_mtu) · 810 unmodified lines | ||
| 1978 | 2000 | return 0; |
| 1979 | 2001 | } |
| 1980 | 2002 | |
| 1981 | −static netdev_features_t gmac_fix_features(struct net_device *netdev, | |
| 1982 | − netdev_features_t features) | |
| 1983 | −{ | |
| 1984 | − if (netdev->mtu + ETH_HLEN + VLAN_HLEN > MTU_SIZE_BIT_MASK) | |
| 1985 | − features &= ~GMAC_OFFLOAD_FEATURES; | |
| 1986 | − | |
| 1987 | − return features; | |
| 1988 | −} | |
| 1989 | − | |
| 1990 | 2003 | static int gmac_set_features(struct net_device *netdev, |
| 1991 | 2004 | netdev_features_t features) |
| 1992 | 2005 | { |
| @@ -2212,7 +2225,6 @@ static const struct net_device_ops gmac_351x_ops = { · 219 unmodified lines | ||
| 2212 | 2225 | .ndo_set_mac_address = gmac_set_mac_address, |
| 2213 | 2226 | .ndo_get_stats64 = gmac_get_stats64, |
| 2214 | 2227 | .ndo_change_mtu = gmac_change_mtu, |
| 2215 | − .ndo_fix_features = gmac_fix_features, | |
| 2216 | 2228 | .ndo_set_features = gmac_set_features, |
| 2217 | 2229 | }; |
| 2218 | 2230 | |
| @@ -2464,11 +2476,12 @@ static int gemini_ethernet_port_probe(struct platform_device *pdev) · 245 unmodified lines | ||
| 2464 | 2476 | |
| 2465 | 2477 | netdev->hw_features = GMAC_OFFLOAD_FEATURES; |
| 2466 | 2478 | netdev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO; |
| 2467 | − /* We can handle jumbo frames up to 10236 bytes so, let's accept | |
| 2468 | − * payloads of 10236 bytes minus VLAN and ethernet header | |
| 2479 | + /* We can receive jumbo frames up to 10236 bytes but only | |
| 2480 | + * transmit 2047 bytes so, let's accept payloads of 2047 | |
| 2481 | + * bytes minus VLAN and ethernet header | |
| 2469 | 2482 | */ |
| 2470 | 2483 | netdev->min_mtu = ETH_MIN_MTU; |
| 2471 | − netdev->max_mtu = 10236 - VLAN_ETH_HLEN; | |
| 2484 | + netdev->max_mtu = MTU_SIZE_BIT_MASK - VLAN_ETH_HLEN; | |
| 2472 | 2485 | |
| 2473 | 2486 | port->freeq_refill = 0; |
| 2474 | 2487 | netif_napi_add(netdev, &port->napi, gmac_napi_poll); |
| @@ -502,7 +502,7 @@ union gmac_txdesc_3 { · 501 unmodified lines | ||
| 502 | 502 | #define SOF_BIT 0x80000000 |
| 503 | 503 | #define EOF_BIT 0x40000000 |
| 504 | 504 | #define EOFIE_BIT BIT(29) |
| 505 | −#define MTU_SIZE_BIT_MASK 0x1fff | |
| 505 | +#define MTU_SIZE_BIT_MASK 0x7ff /* Max MTU 2047 bytes */ | |
| 506 | 506 | |
| 507 | 507 | /* GMAC Tx Descriptor */ |
| 508 | 508 | struct gmac_txdesc { |
| @@ -787,7 +787,7 @@ union gmac_config0 { · 278 unmodified lines | ||
| 787 | 787 | #define CONFIG0_MAXLEN_1536 0 |
| 788 | 788 | #define CONFIG0_MAXLEN_1518 1 |
| 789 | 789 | #define CONFIG0_MAXLEN_1522 2 |
| 790 | −#define CONFIG0_MAXLEN_1542 3 | |
| 790 | +#define CONFIG0_MAXLEN_1548 3 | |
| 791 | 791 | #define CONFIG0_MAXLEN_9k 4 /* 9212 */ |
| 792 | 792 | #define CONFIG0_MAXLEN_10k 5 /* 10236 */ |
| 793 | 793 | #define CONFIG0_MAXLEN_1518__6 6 |
| @@ -516,8 +516,6 @@ struct sk_buff *dpaa2_eth_alloc_skb(struct dpaa2_eth_priv *priv, · 515 unmodified lines | ||
| 516 | 516 | |
| 517 | 517 | memcpy(skb->data, fd_vaddr + fd_offset, fd_length); |
| 518 | 518 | |
| 519 | − dpaa2_eth_recycle_buf(priv, ch, dpaa2_fd_get_addr(fd)); | |
| 520 | − | |
| 521 | 519 | return skb; |
| 522 | 520 | } |
| 523 | 521 | |
| @@ -589,6 +587,7 @@ void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, · 65 unmodified lines | ||
| 589 | 587 | struct rtnl_link_stats64 *percpu_stats; |
| 590 | 588 | struct dpaa2_eth_drv_stats *percpu_extras; |
| 591 | 589 | struct device *dev = priv->net_dev->dev.parent; |
| 590 | + bool recycle_rx_buf = false; | |
| 592 | 591 | void *buf_data; |
| 593 | 592 | u32 xdp_act; |
| 594 | 593 | |
| @@ -618,6 +617,8 @@ void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, · 23 unmodified lines | ||
| 618 | 617 | dma_unmap_page(dev, addr, priv->rx_buf_size, |
| 619 | 618 | DMA_BIDIRECTIONAL); |
| 620 | 619 | skb = dpaa2_eth_build_linear_skb(ch, fd, vaddr); |
| 620 | + } else { | |
| 621 | + recycle_rx_buf = true; | |
| 621 | 622 | } |
| 622 | 623 | } else if (fd_format == dpaa2_fd_sg) { |
| 623 | 624 | WARN_ON(priv->xdp_prog); |
| @@ -637,6 +638,9 @@ void dpaa2_eth_rx(struct dpaa2_eth_priv *priv, · 13 unmodified lines | ||
| 637 | 638 | goto err_build_skb; |
| 638 | 639 | |
| 639 | 640 | dpaa2_eth_receive_skb(priv, ch, fd, vaddr, fq, percpu_stats, skb); |
| 641 | + | |
| 642 | + if (recycle_rx_buf) | |
| 643 | + dpaa2_eth_recycle_buf(priv, ch, dpaa2_fd_get_addr(fd)); | |
| 640 | 644 | return; |
| 641 | 645 | |
| 642 | 646 | err_build_skb: |
| @@ -1073,14 +1077,12 @@ static int dpaa2_eth_build_single_fd(struct dpaa2_eth_priv *priv, · 430 unmodified lines | ||
| 1073 | 1077 | dma_addr_t addr; |
| 1074 | 1078 | |
| 1075 | 1079 | buffer_start = skb->data - dpaa2_eth_needed_headroom(skb); |
| 1076 | − | |
| 1077 | − /* If there's enough room to align the FD address, do it. | |
| 1078 | − * It will help hardware optimize accesses. | |
| 1079 | − */ | |
| 1080 | 1080 | aligned_start = PTR_ALIGN(buffer_start - DPAA2_ETH_TX_BUF_ALIGN, |
| 1081 | 1081 | DPAA2_ETH_TX_BUF_ALIGN); |
| 1082 | 1082 | if (aligned_start >= skb->head) |
| 1083 | 1083 | buffer_start = aligned_start; |
| 1084 | + else | |
| 1085 | + return -ENOMEM; | |
| 1084 | 1086 | |
| 1085 | 1087 | /* Store a backpointer to the skb at the beginning of the buffer |
| 1086 | 1088 | * (in the private data area) such that we can release it |
| @@ -4967,6 +4969,8 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev) · 3880 unmodified lines | ||
| 4967 | 4969 | if (err) |
| 4968 | 4970 | goto err_dl_port_add; |
| 4969 | 4971 | |
| 4972 | + net_dev->needed_headroom = DPAA2_ETH_SWA_SIZE + DPAA2_ETH_TX_BUF_ALIGN; | |
| 4973 | + | |
| 4970 | 4974 | err = register_netdev(net_dev); |
| 4971 | 4975 | if (err < 0) { |
| 4972 | 4976 | dev_err(dev, "register_netdev() failed\n"); |
| @@ -740,7 +740,7 @@ static inline bool dpaa2_eth_rx_pause_enabled(u64 link_options) · 739 unmodified lines | ||
| 740 | 740 | |
| 741 | 741 | static inline unsigned int dpaa2_eth_needed_headroom(struct sk_buff *skb) |
| 742 | 742 | { |
| 743 | − unsigned int headroom = DPAA2_ETH_SWA_SIZE; | |
| 743 | + unsigned int headroom = DPAA2_ETH_SWA_SIZE + DPAA2_ETH_TX_BUF_ALIGN; | |
| 744 | 744 | |
| 745 | 745 | /* If we don't have an skb (e.g. XDP buffer), we only need space for |
| 746 | 746 | * the software annotation area |
| @@ -254,10 +254,13 @@ static int gve_napi_poll(struct napi_struct *napi, int budget) · 253 unmodified lines | ||
| 254 | 254 | if (block->tx) { |
| 255 | 255 | if (block->tx->q_num < priv->tx_cfg.num_queues) |
| 256 | 256 | reschedule |= gve_tx_poll(block, budget); |
| 257 | − else | |
| 257 | + else if (budget) | |
| 258 | 258 | reschedule |= gve_xdp_poll(block, budget); |
| 259 | 259 | } |
| 260 | 260 | |
| 261 | + if (!budget) | |
| 262 | + return 0; | |
| 263 | + | |
| 261 | 264 | if (block->rx) { |
| 262 | 265 | work_done = gve_rx_poll(block, budget); |
| 263 | 266 | reschedule |= work_done == budget; |
| @@ -298,6 +301,9 @@ static int gve_napi_poll_dqo(struct napi_struct *napi, int budget) · 34 unmodified lines | ||
| 298 | 301 | if (block->tx) |
| 299 | 302 | reschedule |= gve_tx_poll_dqo(block, /*do_clean=*/true); |
| 300 | 303 | |
| 304 | + if (!budget) | |
| 305 | + return 0; | |
| 306 | + | |
| 301 | 307 | if (block->rx) { |
| 302 | 308 | work_done = gve_rx_poll_dqo(block, budget); |
| 303 | 309 | reschedule |= work_done == budget; |
| @@ -1007,10 +1007,6 @@ int gve_rx_poll(struct gve_notify_block *block, int budget) · 1006 unmodified lines | ||
| 1007 | 1007 | |
| 1008 | 1008 | feat = block->napi.dev->features; |
| 1009 | 1009 | |
| 1010 | − /* If budget is 0, do all the work */ | |
| 1011 | − if (budget == 0) | |
| 1012 | − budget = INT_MAX; | |
| 1013 | − | |
| 1014 | 1010 | if (budget > 0) |
| 1015 | 1011 | work_done = gve_clean_rx_done(rx, budget, feat); |
| 1016 | 1012 | |
| @@ -925,10 +925,6 @@ bool gve_xdp_poll(struct gve_notify_block *block, int budget) · 924 unmodified lines | ||
| 925 | 925 | bool repoll; |
| 926 | 926 | u32 to_do; |
| 927 | 927 | |
| 928 | − /* If budget is 0, do all the work */ | |
| 929 | − if (budget == 0) | |
| 930 | − budget = INT_MAX; | |
| 931 | − | |
| 932 | 928 | /* Find out how much work there is to be done */ |
| 933 | 929 | nic_done = gve_tx_load_event_counter(priv, tx); |
| 934 | 930 | to_do = min_t(u32, (nic_done - tx->done), budget); |
| @@ -66,6 +66,27 @@ static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb) · 65 unmodified lines | ||
| 66 | 66 | } |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | +static u32 hns_mac_link_anti_shake(struct mac_driver *mac_ctrl_drv) | |
| 70 | +{ | |
| 71 | +#define HNS_MAC_LINK_WAIT_TIME 5 | |
| 72 | +#define HNS_MAC_LINK_WAIT_CNT 40 | |
| 73 | + | |
| 74 | + u32 link_status = 0; | |
| 75 | + int i; | |
| 76 | + | |
| 77 | + if (!mac_ctrl_drv->get_link_status) | |
| 78 | + return link_status; | |
| 79 | + | |
| 80 | + for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) { | |
| 81 | + msleep(HNS_MAC_LINK_WAIT_TIME); | |
| 82 | + mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status); | |
| 83 | + if (!link_status) | |
| 84 | + break; | |
| 85 | + } | |
| 86 | + | |
| 87 | + return link_status; | |
| 88 | +} | |
| 89 | + | |
| 69 | 90 | void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) |
| 70 | 91 | { |
| 71 | 92 | struct mac_driver *mac_ctrl_drv; |
| @@ -83,6 +104,14 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status) · 11 unmodified lines | ||
| 83 | 104 | &sfp_prsnt); |
| 84 | 105 | if (!ret) |
| 85 | 106 | *link_status = *link_status && sfp_prsnt; |
| 107 | + | |
| 108 | + /* for FIBER port, it may have a fake link up. | |
| 109 | + * when the link status changes from down to up, we need to do | |
| 110 | + * anti-shake. the anti-shake time is base on tests. | |
| 111 | + * only FIBER port need to do this. | |
| 112 | + */ | |
| 113 | + if (*link_status && !mac_cb->link) | |
| 114 | + *link_status = hns_mac_link_anti_shake(mac_ctrl_drv); | |
| 86 | 115 | } |
| 87 | 116 | |
| 88 | 117 | mac_cb->link = *link_status; |
| @@ -142,7 +142,8 @@ MODULE_DEVICE_TABLE(acpi, hns_enet_acpi_match); · 141 unmodified lines | ||
| 142 | 142 | |
| 143 | 143 | static void fill_desc(struct hnae_ring *ring, void *priv, |
| 144 | 144 | int size, dma_addr_t dma, int frag_end, |
| 145 | − int buf_num, enum hns_desc_type type, int mtu) | |
| 145 | + int buf_num, enum hns_desc_type type, int mtu, | |
| 146 | + bool is_gso) | |
| 146 | 147 | { |
| 147 | 148 | struct hnae_desc *desc = &ring->desc[ring->next_to_use]; |
| 148 | 149 | struct hnae_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use]; |
| @@ -275,6 +276,15 @@ static int hns_nic_maybe_stop_tso( · 126 unmodified lines | ||
| 275 | 276 | return 0; |
| 276 | 277 | } |
| 277 | 278 | |
| 279 | +static int hns_nic_maybe_stop_tx_v2(struct sk_buff **out_skb, int *bnum, | |
| 280 | + struct hnae_ring *ring) | |
| 281 | +{ | |
| 282 | + if (skb_is_gso(*out_skb)) | |
| 283 | + return hns_nic_maybe_stop_tso(out_skb, bnum, ring); | |
| 284 | + else | |
| 285 | + return hns_nic_maybe_stop_tx(out_skb, bnum, ring); | |
| 286 | +} | |
| 287 | + | |
| 278 | 288 | static void fill_tso_desc(struct hnae_ring *ring, void *priv, |
| 279 | 289 | int size, dma_addr_t dma, int frag_end, |
| 280 | 290 | int buf_num, enum hns_desc_type type, int mtu) |
| @@ -300,6 +310,19 @@ static void fill_tso_desc(struct hnae_ring *ring, void *priv, · 19 unmodified lines | ||
| 300 | 310 | mtu); |
| 301 | 311 | } |
| 302 | 312 | |
| 313 | +static void fill_desc_v2(struct hnae_ring *ring, void *priv, | |
| 314 | + int size, dma_addr_t dma, int frag_end, | |
| 315 | + int buf_num, enum hns_desc_type type, int mtu, | |
| 316 | + bool is_gso) | |
| 317 | +{ | |
| 318 | + if (is_gso) | |
| 319 | + fill_tso_desc(ring, priv, size, dma, frag_end, buf_num, type, | |
| 320 | + mtu); | |
| 321 | + else | |
| 322 | + fill_v2_desc(ring, priv, size, dma, frag_end, buf_num, type, | |
| 323 | + mtu); | |
| 324 | +} | |
| 325 | + | |
| 303 | 326 | netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, |
| 304 | 327 | struct sk_buff *skb, |
| 305 | 328 | struct hns_nic_ring_data *ring_data) |
| @@ -313,6 +336,7 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, · 7 unmodified lines | ||
| 313 | 336 | int seg_num; |
| 314 | 337 | dma_addr_t dma; |
| 315 | 338 | int size, next_to_use; |
| 339 | + bool is_gso; | |
| 316 | 340 | int i; |
| 317 | 341 | |
| 318 | 342 | switch (priv->ops.maybe_stop_tx(&skb, &buf_num, ring)) { |
| @@ -339,8 +363,9 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, · 20 unmodified lines | ||
| 339 | 363 | ring->stats.sw_err_cnt++; |
| 340 | 364 | goto out_err_tx_ok; |
| 341 | 365 | } |
| 366 | + is_gso = skb_is_gso(skb); | |
| 342 | 367 | priv->ops.fill_desc(ring, skb, size, dma, seg_num == 1 ? 1 : 0, |
| 343 | − buf_num, DESC_TYPE_SKB, ndev->mtu); | |
| 368 | + buf_num, DESC_TYPE_SKB, ndev->mtu, is_gso); | |
| 344 | 369 | |
| 345 | 370 | /* fill the fragments */ |
| 346 | 371 | for (i = 1; i < seg_num; i++) { |
| @@ -354,7 +379,7 @@ netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev, · 7 unmodified lines | ||
| 354 | 379 | } |
| 355 | 380 | priv->ops.fill_desc(ring, skb_frag_page(frag), size, dma, |
| 356 | 381 | seg_num - 1 == i ? 1 : 0, buf_num, |
| 357 | − DESC_TYPE_PAGE, ndev->mtu); | |
| 382 | + DESC_TYPE_PAGE, ndev->mtu, is_gso); | |
| 358 | 383 | } |
| 359 | 384 | |
| 360 | 385 | /*complete translate all packets*/ |
| @@ -1776,15 +1801,6 @@ static int hns_nic_set_features(struct net_device *netdev, · 1415 unmodified lines | ||
| 1776 | 1801 | netdev_info(netdev, "enet v1 do not support tso!\n"); |
| 1777 | 1802 | break; |
| 1778 | 1803 | default: |
| 1779 | − if (features & (NETIF_F_TSO | NETIF_F_TSO6)) { | |
| 1780 | − priv->ops.fill_desc = fill_tso_desc; | |
| 1781 | − priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso; | |
| 1782 | − /* The chip only support 7*4096 */ | |
| 1783 | − netif_set_tso_max_size(netdev, 7 * 4096); | |
| 1784 | − } else { | |
| 1785 | − priv->ops.fill_desc = fill_v2_desc; | |
| 1786 | − priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; | |
| 1787 | − } | |
| 1788 | 1804 | break; |
| 1789 | 1805 | } |
| 1790 | 1806 | netdev->features = features; |
| @@ -2159,16 +2175,9 @@ static void hns_nic_set_priv_ops(struct net_device *netdev) · 368 unmodified lines | ||
| 2159 | 2175 | priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; |
| 2160 | 2176 | } else { |
| 2161 | 2177 | priv->ops.get_rxd_bnum = get_v2rx_desc_bnum; |
| 2162 | − if ((netdev->features & NETIF_F_TSO) || | |
| 2163 | − (netdev->features & NETIF_F_TSO6)) { | |
| 2164 | − priv->ops.fill_desc = fill_tso_desc; | |
| 2165 | − priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso; | |
| 2166 | − /* This chip only support 7*4096 */ | |
| 2167 | − netif_set_tso_max_size(netdev, 7 * 4096); | |
| 2168 | − } else { | |
| 2169 | − priv->ops.fill_desc = fill_v2_desc; | |
| 2170 | − priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; | |
| 2171 | − } | |
| 2178 | + priv->ops.fill_desc = fill_desc_v2; | |
| 2179 | + priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx_v2; | |
| 2180 | + netif_set_tso_max_size(netdev, 7 * 4096); | |
| 2172 | 2181 | /* enable tso when init |
| 2173 | 2182 | * control tso on/off through TSE bit in bd |
| 2174 | 2183 | */ |
| @@ -44,7 +44,8 @@ struct hns_nic_ring_data { · 43 unmodified lines | ||
| 44 | 44 | struct hns_nic_ops { |
| 45 | 45 | void (*fill_desc)(struct hnae_ring *ring, void *priv, |
| 46 | 46 | int size, dma_addr_t dma, int frag_end, |
| 47 | − int buf_num, enum hns_desc_type type, int mtu); | |
| 47 | + int buf_num, enum hns_desc_type type, int mtu, | |
| 48 | + bool is_gso); | |
| 48 | 49 | int (*maybe_stop_tx)(struct sk_buff **out_skb, |
| 49 | 50 | int *bnum, struct hnae_ring *ring); |
| 50 | 51 | void (*get_rxd_bnum)(u32 bnum_flag, int *out_bnum); |
| @@ -503,11 +503,14 @@ static void hns3_get_coal_info(struct hns3_enet_tqp_vector *tqp_vector, · 502 unmodified lines | ||
| 503 | 503 | } |
| 504 | 504 | |
| 505 | 505 | sprintf(result[j++], "%d", i); |
| 506 | − sprintf(result[j++], "%s", dim_state_str[dim->state]); | |
| 506 | + sprintf(result[j++], "%s", dim->state < ARRAY_SIZE(dim_state_str) ? | |
| 507 | + dim_state_str[dim->state] : "unknown"); | |
| 507 | 508 | sprintf(result[j++], "%u", dim->profile_ix); |
| 508 | − sprintf(result[j++], "%s", dim_cqe_mode_str[dim->mode]); | |
| 509 | + sprintf(result[j++], "%s", dim->mode < ARRAY_SIZE(dim_cqe_mode_str) ? | |
| 510 | + dim_cqe_mode_str[dim->mode] : "unknown"); | |
| 509 | 511 | sprintf(result[j++], "%s", |
| 510 | − dim_tune_stat_str[dim->tune_state]); | |
| 512 | + dim->tune_state < ARRAY_SIZE(dim_tune_stat_str) ? | |
| 513 | + dim_tune_stat_str[dim->tune_state] : "unknown"); | |
| 511 | 514 | sprintf(result[j++], "%u", dim->steps_left); |
| 512 | 515 | sprintf(result[j++], "%u", dim->steps_right); |
| 513 | 516 | sprintf(result[j++], "%u", dim->tired); |
| @@ -5139,7 +5139,7 @@ static int hns3_init_mac_addr(struct net_device *netdev) · 5138 unmodified lines | ||
| 5139 | 5139 | struct hns3_nic_priv *priv = netdev_priv(netdev); |
| 5140 | 5140 | char format_mac_addr[HNAE3_FORMAT_MAC_ADDR_LEN]; |
| 5141 | 5141 | struct hnae3_handle *h = priv->ae_handle; |
| 5142 | − u8 mac_addr_temp[ETH_ALEN]; | |
| 5142 | + u8 mac_addr_temp[ETH_ALEN] = {0}; | |
| 5143 | 5143 | int ret = 0; |
| 5144 | 5144 | |
| 5145 | 5145 | if (h->ae_algo->ops->get_mac_addr) |
| @@ -61,6 +61,7 @@ static void hclge_sync_fd_table(struct hclge_dev *hdev); · 60 unmodified lines | ||
| 61 | 61 | static void hclge_update_fec_stats(struct hclge_dev *hdev); |
| 62 | 62 | static int hclge_mac_link_status_wait(struct hclge_dev *hdev, int link_ret, |
| 63 | 63 | int wait_cnt); |
| 64 | +static int hclge_update_port_info(struct hclge_dev *hdev); | |
| 64 | 65 | |
| 65 | 66 | static struct hnae3_ae_algo ae_algo; |
| 66 | 67 | |
| @@ -3041,6 +3042,9 @@ static void hclge_update_link_status(struct hclge_dev *hdev) · 2974 unmodified lines | ||
| 3041 | 3042 | |
| 3042 | 3043 | if (state != hdev->hw.mac.link) { |
| 3043 | 3044 | hdev->hw.mac.link = state; |
| 3045 | + if (state == HCLGE_LINK_STATUS_UP) | |
| 3046 | + hclge_update_port_info(hdev); | |
| 3047 | + | |
| 3044 | 3048 | client->ops->link_status_change(handle, state); |
| 3045 | 3049 | hclge_config_mac_tnl_int(hdev, state); |
| 3046 | 3050 | if (rclient && rclient->ops->link_status_change) |
| @@ -10025,8 +10029,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, · 6978 unmodified lines | ||
| 10025 | 10029 | struct hclge_vport_vlan_cfg *vlan, *tmp; |
| 10026 | 10030 | struct hclge_dev *hdev = vport->back; |
| 10027 | 10031 | |
| 10028 | − mutex_lock(&hdev->vport_lock); | |
| 10029 | − | |
| 10030 | 10032 | list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) { |
| 10031 | 10033 | if (vlan->vlan_id == vlan_id) { |
| 10032 | 10034 | if (is_write_tbl && vlan->hd_tbl_status) |
| @@ -10041,8 +10043,6 @@ static void hclge_rm_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, · 8 unmodified lines | ||
| 10041 | 10043 | break; |
| 10042 | 10044 | } |
| 10043 | 10045 | } |
| 10044 | − | |
| 10045 | − mutex_unlock(&hdev->vport_lock); | |
| 10046 | 10046 | } |
| 10047 | 10047 | |
| 10048 | 10048 | void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list) |
| @@ -10451,11 +10451,16 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, · 402 unmodified lines | ||
| 10451 | 10451 | * handle mailbox. Just record the vlan id, and remove it after |
| 10452 | 10452 | * reset finished. |
| 10453 | 10453 | */ |
| 10454 | + mutex_lock(&hdev->vport_lock); | |
| 10454 | 10455 | if ((test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) || |
| 10455 | 10456 | test_bit(HCLGE_STATE_RST_FAIL, &hdev->state)) && is_kill) { |
| 10456 | 10457 | set_bit(vlan_id, vport->vlan_del_fail_bmap); |
| 10458 | + mutex_unlock(&hdev->vport_lock); | |
| 10457 | 10459 | return -EBUSY; |
| 10460 | + } else if (!is_kill && test_bit(vlan_id, vport->vlan_del_fail_bmap)) { | |
| 10461 | + clear_bit(vlan_id, vport->vlan_del_fail_bmap); | |
| 10458 | 10462 | } |
| 10463 | + mutex_unlock(&hdev->vport_lock); | |
| 10459 | 10464 | |
| 10460 | 10465 | /* when port base vlan enabled, we use port base vlan as the vlan |
| 10461 | 10466 | * filter entry. In this case, we don't update vlan filter table |
| @@ -10470,17 +10475,22 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, · 8 unmodified lines | ||
| 10470 | 10475 | } |
| 10471 | 10476 | |
| 10472 | 10477 | if (!ret) { |
| 10473 | − if (!is_kill) | |
| 10478 | + if (!is_kill) { | |
| 10474 | 10479 | hclge_add_vport_vlan_table(vport, vlan_id, |
| 10475 | 10480 | writen_to_tbl); |
| 10476 | − else if (is_kill && vlan_id != 0) | |
| 10481 | + } else if (is_kill && vlan_id != 0) { | |
| 10482 | + mutex_lock(&hdev->vport_lock); | |
| 10477 | 10483 | hclge_rm_vport_vlan_table(vport, vlan_id, false); |
| 10484 | + mutex_unlock(&hdev->vport_lock); | |
| 10485 | + } | |
| 10478 | 10486 | } else if (is_kill) { |
| 10479 | 10487 | /* when remove hw vlan filter failed, record the vlan id, |
| 10480 | 10488 | * and try to remove it from hw later, to be consistence |
| 10481 | 10489 | * with stack |
| 10482 | 10490 | */ |
| 10491 | + mutex_lock(&hdev->vport_lock); | |
| 10483 | 10492 | set_bit(vlan_id, vport->vlan_del_fail_bmap); |
| 10493 | + mutex_unlock(&hdev->vport_lock); | |
| 10484 | 10494 | } |
| 10485 | 10495 | |
| 10486 | 10496 | hclge_set_vport_vlan_fltr_change(vport); |
| @@ -10520,6 +10530,7 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev) · 33 unmodified lines | ||
| 10520 | 10530 | int i, ret, sync_cnt = 0; |
| 10521 | 10531 | u16 vlan_id; |
| 10522 | 10532 | |
| 10533 | + mutex_lock(&hdev->vport_lock); | |
| 10523 | 10534 | /* start from vport 1 for PF is always alive */ |
| 10524 | 10535 | for (i = 0; i < hdev->num_alloc_vport; i++) { |
| 10525 | 10536 | struct hclge_vport *vport = &hdev->vport[i]; |
| @@ -10530,21 +10541,26 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev) · 4 unmodified lines | ||
| 10530 | 10541 | ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q), |
| 10531 | 10542 | vport->vport_id, vlan_id, |
| 10532 | 10543 | true); |
| 10533 | − if (ret && ret != -EINVAL) | |
| 10544 | + if (ret && ret != -EINVAL) { | |
| 10545 | + mutex_unlock(&hdev->vport_lock); | |
| 10534 | 10546 | return; |
| 10547 | + } | |
| 10535 | 10548 | |
| 10536 | 10549 | clear_bit(vlan_id, vport->vlan_del_fail_bmap); |
| 10537 | 10550 | hclge_rm_vport_vlan_table(vport, vlan_id, false); |
| 10538 | 10551 | hclge_set_vport_vlan_fltr_change(vport); |
| 10539 | 10552 | |
| 10540 | 10553 | sync_cnt++; |
| 10541 | − if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) | |
| 10554 | + if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) { | |
| 10555 | + mutex_unlock(&hdev->vport_lock); | |
| 10542 | 10556 | return; |
| 10557 | + } | |
| 10543 | 10558 | |
| 10544 | 10559 | vlan_id = find_first_bit(vport->vlan_del_fail_bmap, |
| 10545 | 10560 | VLAN_N_VID); |
| 10546 | 10561 | } |
| 10547 | 10562 | } |
| 10563 | + mutex_unlock(&hdev->vport_lock); | |
| 10548 | 10564 | |
| 10549 | 10565 | hclge_sync_vlan_fltr_state(hdev); |
| 10550 | 10566 | } |
| @@ -11651,6 +11667,7 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) · 1100 unmodified lines | ||
| 11651 | 11667 | goto err_msi_irq_uninit; |
| 11652 | 11668 | |
| 11653 | 11669 | if (hdev->hw.mac.media_type == HNAE3_MEDIA_TYPE_COPPER) { |
| 11670 | + clear_bit(HNAE3_DEV_SUPPORT_FEC_B, ae_dev->caps); | |
| 11654 | 11671 | if (hnae3_dev_phy_imp_supported(hdev)) |
| 11655 | 11672 | ret = hclge_update_tp_port_info(hdev); |
| 11656 | 11673 | else |
| @@ -1206,6 +1206,8 @@ static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, · 1205 unmodified lines | ||
| 1206 | 1206 | test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) && is_kill) { |
| 1207 | 1207 | set_bit(vlan_id, hdev->vlan_del_fail_bmap); |
| 1208 | 1208 | return -EBUSY; |
| 1209 | + } else if (!is_kill && test_bit(vlan_id, hdev->vlan_del_fail_bmap)) { | |
| 1210 | + clear_bit(vlan_id, hdev->vlan_del_fail_bmap); | |
| 1209 | 1211 | } |
| 1210 | 1212 | |
| 1211 | 1213 | hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN, |
| @@ -1233,20 +1235,25 @@ static void hclgevf_sync_vlan_filter(struct hclgevf_dev *hdev) · 21 unmodified lines | ||
| 1233 | 1235 | int ret, sync_cnt = 0; |
| 1234 | 1236 | u16 vlan_id; |
| 1235 | 1237 | |
| 1238 | + if (bitmap_empty(hdev->vlan_del_fail_bmap, VLAN_N_VID)) | |
| 1239 | + return; | |
| 1240 | + | |
| 1241 | + rtnl_lock(); | |
| 1236 | 1242 | vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); |
| 1237 | 1243 | while (vlan_id != VLAN_N_VID) { |
| 1238 | 1244 | ret = hclgevf_set_vlan_filter(handle, htons(ETH_P_8021Q), |
| 1239 | 1245 | vlan_id, true); |
| 1240 | 1246 | if (ret) |
| 1241 | − return; | |
| 1247 | + break; | |
| 1242 | 1248 | |
| 1243 | 1249 | clear_bit(vlan_id, hdev->vlan_del_fail_bmap); |
| 1244 | 1250 | sync_cnt++; |
| 1245 | 1251 | if (sync_cnt >= HCLGEVF_MAX_SYNC_COUNT) |
| 1246 | − return; | |
| 1252 | + break; | |
| 1247 | 1253 | |
| 1248 | 1254 | vlan_id = find_first_bit(hdev->vlan_del_fail_bmap, VLAN_N_VID); |
| 1249 | 1255 | } |
| 1256 | + rtnl_unlock(); | |
| 1250 | 1257 | } |
| 1251 | 1258 | |
| 1252 | 1259 | static int hclgevf_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) |
| @@ -1974,8 +1981,18 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, · 721 unmodified lines | ||
| 1974 | 1981 | return HCLGEVF_VECTOR0_EVENT_OTHER; |
| 1975 | 1982 | } |
| 1976 | 1983 | |
| 1984 | +static void hclgevf_reset_timer(struct timer_list *t) | |
| 1985 | +{ | |
| 1986 | + struct hclgevf_dev *hdev = from_timer(hdev, t, reset_timer); | |
| 1987 | + | |
| 1988 | + hclgevf_clear_event_cause(hdev, HCLGEVF_VECTOR0_EVENT_RST); | |
| 1989 | + hclgevf_reset_task_schedule(hdev); | |
| 1990 | +} | |
| 1991 | + | |
| 1977 | 1992 | static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) |
| 1978 | 1993 | { |
| 1994 | +#define HCLGEVF_RESET_DELAY 5 | |
| 1995 | + | |
| 1979 | 1996 | enum hclgevf_evt_cause event_cause; |
| 1980 | 1997 | struct hclgevf_dev *hdev = data; |
| 1981 | 1998 | u32 clearval; |
| @@ -1987,7 +2004,8 @@ static irqreturn_t hclgevf_misc_irq_handle(int irq, void *data) · 5 unmodified lines | ||
| 1987 | 2004 | |
| 1988 | 2005 | switch (event_cause) { |
| 1989 | 2006 | case HCLGEVF_VECTOR0_EVENT_RST: |
| 1990 | − hclgevf_reset_task_schedule(hdev); | |
| 2007 | + mod_timer(&hdev->reset_timer, | |
| 2008 | + jiffies + msecs_to_jiffies(HCLGEVF_RESET_DELAY)); | |
| 1991 | 2009 | break; |
| 1992 | 2010 | case HCLGEVF_VECTOR0_EVENT_MBX: |
| 1993 | 2011 | hclgevf_mbx_handler(hdev); |
| @@ -2930,6 +2948,7 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) · 936 unmodified lines | ||
| 2930 | 2948 | HCLGEVF_DRIVER_NAME); |
| 2931 | 2949 | |
| 2932 | 2950 | hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); |
| 2951 | + timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); | |
| 2933 | 2952 | |
| 2934 | 2953 | return 0; |
| 2935 | 2954 | |
| @@ -219,6 +219,7 @@ struct hclgevf_dev { · 218 unmodified lines | ||
| 219 | 219 | enum hnae3_reset_type reset_level; |
| 220 | 220 | unsigned long reset_pending; |
| 221 | 221 | enum hnae3_reset_type reset_type; |
| 222 | + struct timer_list reset_timer; | |
| 222 | 223 | |
| 223 | 224 | #define HCLGEVF_RESET_REQUESTED 0 |
| 224 | 225 | #define HCLGEVF_RESET_PENDING 1 |
| @@ -63,6 +63,9 @@ static int hclgevf_get_mbx_resp(struct hclgevf_dev *hdev, u16 code0, u16 code1, · 62 unmodified lines | ||
| 63 | 63 | i++; |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | + /* ensure additional_info will be seen after received_resp */ | |
| 67 | + smp_rmb(); | |
| 68 | + | |
| 66 | 69 | if (i >= HCLGEVF_MAX_TRY_TIMES) { |
| 67 | 70 | dev_err(&hdev->pdev->dev, |
| 68 | 71 | "VF could not get mbx(%u,%u) resp(=%d) from PF in %d tries\n", |
| @@ -178,6 +181,10 @@ static void hclgevf_handle_mbx_response(struct hclgevf_dev *hdev, · 109 unmodified lines | ||
| 178 | 181 | resp->resp_status = hclgevf_resp_to_errno(resp_status); |
| 179 | 182 | memcpy(resp->additional_info, req->msg.resp_data, |
| 180 | 183 | HCLGE_MBX_MAX_RESP_DATA_SIZE * sizeof(u8)); |
| 184 | + | |
| 185 | + /* ensure additional_info will be seen before setting received_resp */ | |
| 186 | + smp_wmb(); | |
| 187 | + | |
| 181 | 188 | if (match_id) { |
| 182 | 189 | /* If match_id is not zero, it means PF support match_id. |
| 183 | 190 | * if the match_id is right, VF get the right response, or |
| @@ -16224,7 +16224,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 16223 unmodified lines | ||
| 16224 | 16224 | I40E_PRTGL_SAH_MFS_MASK) >> I40E_PRTGL_SAH_MFS_SHIFT; |
| 16225 | 16225 | if (val < MAX_FRAME_SIZE_DEFAULT) |
| 16226 | 16226 | dev_warn(&pdev->dev, "MFS for port %x has been set below the default: %x\n", |
| 16227 | − i, val); | |
| 16227 | + pf->hw.port, val); | |
| 16228 | 16228 | |
| 16229 | 16229 | /* Add a filter to drop all Flow control frames from any VSI from being |
| 16230 | 16230 | * transmitted. By doing so we stop a malicious VF from sending out |
| @@ -3844,7 +3844,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) · 3843 unmodified lines | ||
| 3844 | 3844 | struct i40e_pf *pf = vf->pf; |
| 3845 | 3845 | struct i40e_vsi *vsi = NULL; |
| 3846 | 3846 | int aq_ret = 0; |
| 3847 | − int i, ret; | |
| 3847 | + int i; | |
| 3848 | 3848 | |
| 3849 | 3849 | if (!i40e_sync_vf_state(vf, I40E_VF_STATE_ACTIVE)) { |
| 3850 | 3850 | aq_ret = -EINVAL; |
| @@ -3868,8 +3868,10 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) · 17 unmodified lines | ||
| 3868 | 3868 | } |
| 3869 | 3869 | |
| 3870 | 3870 | cfilter = kzalloc(sizeof(*cfilter), GFP_KERNEL); |
| 3871 | − if (!cfilter) | |
| 3872 | − return -ENOMEM; | |
| 3871 | + if (!cfilter) { | |
| 3872 | + aq_ret = -ENOMEM; | |
| 3873 | + goto err_out; | |
| 3874 | + } | |
| 3873 | 3875 | |
| 3874 | 3876 | /* parse destination mac address */ |
| 3875 | 3877 | for (i = 0; i < ETH_ALEN; i++) |
| @@ -3917,13 +3919,13 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) · 41 unmodified lines | ||
| 3917 | 3919 | |
| 3918 | 3920 | /* Adding cloud filter programmed as TC filter */ |
| 3919 | 3921 | if (tcf.dst_port) |
| 3920 | − ret = i40e_add_del_cloud_filter_big_buf(vsi, cfilter, true); | |
| 3922 | + aq_ret = i40e_add_del_cloud_filter_big_buf(vsi, cfilter, true); | |
| 3921 | 3923 | else |
| 3922 | − ret = i40e_add_del_cloud_filter(vsi, cfilter, true); | |
| 3923 | − if (ret) { | |
| 3924 | + aq_ret = i40e_add_del_cloud_filter(vsi, cfilter, true); | |
| 3925 | + if (aq_ret) { | |
| 3924 | 3926 | dev_err(&pf->pdev->dev, |
| 3925 | 3927 | "VF %d: Failed to add cloud filter, err %pe aq_err %s\n", |
| 3926 | − vf->vf_id, ERR_PTR(ret), | |
| 3928 | + vf->vf_id, ERR_PTR(aq_ret), | |
| 3927 | 3929 | i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); |
| 3928 | 3930 | goto err_free; |
| 3929 | 3931 | } |
| @@ -827,18 +827,10 @@ static int __iavf_set_coalesce(struct net_device *netdev, · 826 unmodified lines | ||
| 827 | 827 | struct iavf_adapter *adapter = netdev_priv(netdev); |
| 828 | 828 | int i; |
| 829 | 829 | |
| 830 | − if (ec->rx_coalesce_usecs == 0) { | |
| 831 | − if (ec->use_adaptive_rx_coalesce) | |
| 832 | − netif_info(adapter, drv, netdev, "rx-usecs=0, need to disable adaptive-rx for a complete disable\n"); | |
| 833 | − } else if ((ec->rx_coalesce_usecs < IAVF_MIN_ITR) || | |
| 834 | − (ec->rx_coalesce_usecs > IAVF_MAX_ITR)) { | |
| 830 | + if (ec->rx_coalesce_usecs > IAVF_MAX_ITR) { | |
| 835 | 831 | netif_info(adapter, drv, netdev, "Invalid value, rx-usecs range is 0-8160\n"); |
| 836 | 832 | return -EINVAL; |
| 837 | − } else if (ec->tx_coalesce_usecs == 0) { | |
| 838 | − if (ec->use_adaptive_tx_coalesce) | |
| 839 | − netif_info(adapter, drv, netdev, "tx-usecs=0, need to disable adaptive-tx for a complete disable\n"); | |
| 840 | − } else if ((ec->tx_coalesce_usecs < IAVF_MIN_ITR) || | |
| 841 | − (ec->tx_coalesce_usecs > IAVF_MAX_ITR)) { | |
| 833 | + } else if (ec->tx_coalesce_usecs > IAVF_MAX_ITR) { | |
| 842 | 834 | netif_info(adapter, drv, netdev, "Invalid value, tx-usecs range is 0-8160\n"); |
| 843 | 835 | return -EINVAL; |
| 844 | 836 | } |
| @@ -15,7 +15,6 @@ · 14 unmodified lines | ||
| 15 | 15 | */ |
| 16 | 16 | #define IAVF_ITR_DYNAMIC 0x8000 /* use top bit as a flag */ |
| 17 | 17 | #define IAVF_ITR_MASK 0x1FFE /* mask for ITR register value */ |
| 18 | −#define IAVF_MIN_ITR 2 /* reg uses 2 usec resolution */ | |
| 19 | 18 | #define IAVF_ITR_100K 10 /* all values below must be even */ |
| 20 | 19 | #define IAVF_ITR_50K 20 |
| 21 | 20 | #define IAVF_ITR_20K 50 |
| @@ -1479,14 +1479,14 @@ ice_post_dwnld_pkg_actions(struct ice_hw *hw) · 1478 unmodified lines | ||
| 1479 | 1479 | } |
| 1480 | 1480 | |
| 1481 | 1481 | /** |
| 1482 | − * ice_download_pkg | |
| 1482 | + * ice_download_pkg_with_sig_seg | |
| 1483 | 1483 | * @hw: pointer to the hardware structure |
| 1484 | 1484 | * @pkg_hdr: pointer to package header |
| 1485 | 1485 | * |
| 1486 | 1486 | * Handles the download of a complete package. |
| 1487 | 1487 | */ |
| 1488 | 1488 | static enum ice_ddp_state |
| 1489 | −ice_download_pkg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr) | |
| 1489 | +ice_download_pkg_with_sig_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr) | |
| 1490 | 1490 | { |
| 1491 | 1491 | enum ice_aq_err aq_err = hw->adminq.sq_last_status; |
| 1492 | 1492 | enum ice_ddp_state state = ICE_DDP_PKG_ERR; |
| @@ -1519,6 +1519,103 @@ ice_download_pkg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr) · 26 unmodified lines | ||
| 1519 | 1519 | state = ice_post_dwnld_pkg_actions(hw); |
| 1520 | 1520 | |
| 1521 | 1521 | ice_release_global_cfg_lock(hw); |
| 1522 | + | |
| 1523 | + return state; | |
| 1524 | +} | |
| 1525 | + | |
| 1526 | +/** | |
| 1527 | + * ice_dwnld_cfg_bufs | |
| 1528 | + * @hw: pointer to the hardware structure | |
| 1529 | + * @bufs: pointer to an array of buffers | |
| 1530 | + * @count: the number of buffers in the array | |
| 1531 | + * | |
| 1532 | + * Obtains global config lock and downloads the package configuration buffers | |
| 1533 | + * to the firmware. | |
| 1534 | + */ | |
| 1535 | +static enum ice_ddp_state | |
| 1536 | +ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count) | |
| 1537 | +{ | |
| 1538 | + enum ice_ddp_state state; | |
| 1539 | + struct ice_buf_hdr *bh; | |
| 1540 | + int status; | |
| 1541 | + | |
| 1542 | + if (!bufs || !count) | |
| 1543 | + return ICE_DDP_PKG_ERR; | |
| 1544 | + | |
| 1545 | + /* If the first buffer's first section has its metadata bit set | |
| 1546 | + * then there are no buffers to be downloaded, and the operation is | |
| 1547 | + * considered a success. | |
| 1548 | + */ | |
| 1549 | + bh = (struct ice_buf_hdr *)bufs; | |
| 1550 | + if (le32_to_cpu(bh->section_entry[0].type) & ICE_METADATA_BUF) | |
| 1551 | + return ICE_DDP_PKG_SUCCESS; | |
| 1552 | + | |
| 1553 | + status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE); | |
| 1554 | + if (status) { | |
| 1555 | + if (status == -EALREADY) | |
| 1556 | + return ICE_DDP_PKG_ALREADY_LOADED; | |
| 1557 | + return ice_map_aq_err_to_ddp_state(hw->adminq.sq_last_status); | |
| 1558 | + } | |
| 1559 | + | |
| 1560 | + state = ice_dwnld_cfg_bufs_no_lock(hw, bufs, 0, count, true); | |
| 1561 | + if (!state) | |
| 1562 | + state = ice_post_dwnld_pkg_actions(hw); | |
| 1563 | + | |
| 1564 | + ice_release_global_cfg_lock(hw); | |
| 1565 | + | |
| 1566 | + return state; | |
| 1567 | +} | |
| 1568 | + | |
| 1569 | +/** | |
| 1570 | + * ice_download_pkg_without_sig_seg | |
| 1571 | + * @hw: pointer to the hardware structure | |
| 1572 | + * @ice_seg: pointer to the segment of the package to be downloaded | |
| 1573 | + * | |
| 1574 | + * Handles the download of a complete package without signature segment. | |
| 1575 | + */ | |
| 1576 | +static enum ice_ddp_state | |
| 1577 | +ice_download_pkg_without_sig_seg(struct ice_hw *hw, struct ice_seg *ice_seg) | |
| 1578 | +{ | |
| 1579 | + struct ice_buf_table *ice_buf_tbl; | |
| 1580 | + | |
| 1581 | + ice_debug(hw, ICE_DBG_PKG, "Segment format version: %d.%d.%d.%d\n", | |
| 1582 | + ice_seg->hdr.seg_format_ver.major, | |
| 1583 | + ice_seg->hdr.seg_format_ver.minor, | |
| 1584 | + ice_seg->hdr.seg_format_ver.update, | |
| 1585 | + ice_seg->hdr.seg_format_ver.draft); | |
| 1586 | + | |
| 1587 | + ice_debug(hw, ICE_DBG_PKG, "Seg: type 0x%X, size %d, name %s\n", | |
| 1588 | + le32_to_cpu(ice_seg->hdr.seg_type), | |
| 1589 | + le32_to_cpu(ice_seg->hdr.seg_size), ice_seg->hdr.seg_id); | |
| 1590 | + | |
| 1591 | + ice_buf_tbl = ice_find_buf_table(ice_seg); | |
| 1592 | + | |
| 1593 | + ice_debug(hw, ICE_DBG_PKG, "Seg buf count: %d\n", | |
| 1594 | + le32_to_cpu(ice_buf_tbl->buf_count)); | |
| 1595 | + | |
| 1596 | + return ice_dwnld_cfg_bufs(hw, ice_buf_tbl->buf_array, | |
| 1597 | + le32_to_cpu(ice_buf_tbl->buf_count)); | |
| 1598 | +} | |
| 1599 | + | |
| 1600 | +/** | |
| 1601 | + * ice_download_pkg | |
| 1602 | + * @hw: pointer to the hardware structure | |
| 1603 | + * @pkg_hdr: pointer to package header | |
| 1604 | + * @ice_seg: pointer to the segment of the package to be downloaded | |
| 1605 | + * | |
| 1606 | + * Handles the download of a complete package. | |
| 1607 | + */ | |
| 1608 | +static enum ice_ddp_state | |
| 1609 | +ice_download_pkg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr, | |
| 1610 | + struct ice_seg *ice_seg) | |
| 1611 | +{ | |
| 1612 | + enum ice_ddp_state state; | |
| 1613 | + | |
| 1614 | + if (hw->pkg_has_signing_seg) | |
| 1615 | + state = ice_download_pkg_with_sig_seg(hw, pkg_hdr); | |
| 1616 | + else | |
| 1617 | + state = ice_download_pkg_without_sig_seg(hw, ice_seg); | |
| 1618 | + | |
| 1522 | 1619 | ice_post_pkg_dwnld_vlan_mode_cfg(hw); |
| 1523 | 1620 | |
| 1524 | 1621 | return state; |
| @@ -2083,7 +2180,7 @@ enum ice_ddp_state ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len) · 558 unmodified lines | ||
| 2083 | 2180 | |
| 2084 | 2181 | /* initialize package hints and then download package */ |
| 2085 | 2182 | ice_init_pkg_hints(hw, seg); |
| 2086 | − state = ice_download_pkg(hw, pkg); | |
| 2183 | + state = ice_download_pkg(hw, pkg, seg); | |
| 2087 | 2184 | if (state == ICE_DDP_PKG_ALREADY_LOADED) { |
| 2088 | 2185 | ice_debug(hw, ICE_DBG_INIT, |
| 2089 | 2186 | "package previously loaded - no work.\n"); |
| @@ -815,12 +815,6 @@ ice_dpll_input_prio_set(const struct dpll_pin *pin, void *pin_priv, · 814 unmodified lines | ||
| 815 | 815 | struct ice_pf *pf = d->pf; |
| 816 | 816 | int ret; |
| 817 | 817 | |
| 818 | − if (prio > ICE_DPLL_PRIO_MAX) { | |
| 819 | − NL_SET_ERR_MSG_FMT(extack, "prio out of supported range 0-%d", | |
| 820 | − ICE_DPLL_PRIO_MAX); | |
| 821 | − return -EINVAL; | |
| 822 | − } | |
| 823 | − | |
| 824 | 818 | mutex_lock(&pf->dplls.lock); |
| 825 | 819 | ret = ice_dpll_hw_input_prio_set(pf, d, p, prio, extack); |
| 826 | 820 | mutex_unlock(&pf->dplls.lock); |
| @@ -1756,6 +1750,7 @@ ice_dpll_init_dpll(struct ice_pf *pf, struct ice_dpll *d, bool cgu, · 929 unmodified lines | ||
| 1756 | 1750 | } |
| 1757 | 1751 | d->pf = pf; |
| 1758 | 1752 | if (cgu) { |
| 1753 | + ice_dpll_update_state(pf, d, true); | |
| 1759 | 1754 | ret = dpll_device_register(d->dpll, type, &ice_dpll_ops, d); |
| 1760 | 1755 | if (ret) { |
| 1761 | 1756 | dpll_device_put(d->dpll); |
| @@ -1796,8 +1791,6 @@ static int ice_dpll_init_worker(struct ice_pf *pf) · 34 unmodified lines | ||
| 1796 | 1791 | struct ice_dplls *d = &pf->dplls; |
| 1797 | 1792 | struct kthread_worker *kworker; |
| 1798 | 1793 | |
| 1799 | − ice_dpll_update_state(pf, &d->eec, true); | |
| 1800 | − ice_dpll_update_state(pf, &d->pps, true); | |
| 1801 | 1794 | kthread_init_delayed_work(&d->work, ice_dpll_periodic_work); |
| 1802 | 1795 | kworker = kthread_create_worker(0, "ice-dplls-%s", |
| 1803 | 1796 | dev_name(ice_pf_to_dev(pf))); |
| @@ -1830,6 +1823,7 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, · 26 unmodified lines | ||
| 1830 | 1823 | int num_pins, i, ret = -EINVAL; |
| 1831 | 1824 | struct ice_hw *hw = &pf->hw; |
| 1832 | 1825 | struct ice_dpll_pin *pins; |
| 1826 | + unsigned long caps; | |
| 1833 | 1827 | u8 freq_supp_num; |
| 1834 | 1828 | bool input; |
| 1835 | 1829 | |
| @@ -1849,6 +1843,7 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, · 13 unmodified lines | ||
| 1849 | 1843 | } |
| 1850 | 1844 | |
| 1851 | 1845 | for (i = 0; i < num_pins; i++) { |
| 1846 | + caps = 0; | |
| 1852 | 1847 | pins[i].idx = i; |
| 1853 | 1848 | pins[i].prop.board_label = ice_cgu_get_pin_name(hw, i, input); |
| 1854 | 1849 | pins[i].prop.type = ice_cgu_get_pin_type(hw, i, input); |
| @@ -1861,8 +1856,8 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, · 6 unmodified lines | ||
| 1861 | 1856 | &dp->input_prio[i]); |
| 1862 | 1857 | if (ret) |
| 1863 | 1858 | return ret; |
| 1864 | − pins[i].prop.capabilities |= | |
| 1865 | − DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE; | |
| 1859 | + caps |= (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE | | |
| 1860 | + DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE); | |
| 1866 | 1861 | pins[i].prop.phase_range.min = |
| 1867 | 1862 | pf->dplls.input_phase_adj_max; |
| 1868 | 1863 | pins[i].prop.phase_range.max = |
| @@ -1872,9 +1867,11 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, · 3 unmodified lines | ||
| 1872 | 1867 | pf->dplls.output_phase_adj_max; |
| 1873 | 1868 | pins[i].prop.phase_range.max = |
| 1874 | 1869 | -pf->dplls.output_phase_adj_max; |
| 1870 | + ret = ice_cgu_get_output_pin_state_caps(hw, i, &caps); | |
| 1871 | + if (ret) | |
| 1872 | + return ret; | |
| 1875 | 1873 | } |
| 1876 | − pins[i].prop.capabilities |= | |
| 1877 | − DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE; | |
| 1874 | + pins[i].prop.capabilities = caps; | |
| 1878 | 1875 | ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL); |
| 1879 | 1876 | if (ret) |
| 1880 | 1877 | return ret; |
| @@ -6,7 +6,6 @@ · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | #include "ice.h" |
| 8 | 8 | |
| 9 | −#define ICE_DPLL_PRIO_MAX 0xF | |
| 10 | 9 | #define ICE_DPLL_RCLK_NUM_MAX 4 |
| 11 | 10 | |
| 12 | 11 | /** ice_dpll_pin - store info about pins |
| @@ -569,6 +569,50 @@ resume_traffic: · 568 unmodified lines | ||
| 569 | 569 | dev_dbg(dev, "Problem restarting traffic for LAG node move\n"); |
| 570 | 570 | } |
| 571 | 571 | |
| 572 | +/** | |
| 573 | + * ice_lag_build_netdev_list - populate the lag struct's netdev list | |
| 574 | + * @lag: local lag struct | |
| 575 | + * @ndlist: pointer to netdev list to populate | |
| 576 | + */ | |
| 577 | +static void ice_lag_build_netdev_list(struct ice_lag *lag, | |
| 578 | + struct ice_lag_netdev_list *ndlist) | |
| 579 | +{ | |
| 580 | + struct ice_lag_netdev_list *nl; | |
| 581 | + struct net_device *tmp_nd; | |
| 582 | + | |
| 583 | + INIT_LIST_HEAD(&ndlist->node); | |
| 584 | + rcu_read_lock(); | |
| 585 | + for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) { | |
| 586 | + nl = kzalloc(sizeof(*nl), GFP_ATOMIC); | |
| 587 | + if (!nl) | |
| 588 | + break; | |
| 589 | + | |
| 590 | + nl->netdev = tmp_nd; | |
| 591 | + list_add(&nl->node, &ndlist->node); | |
| 592 | + } | |
| 593 | + rcu_read_unlock(); | |
| 594 | + lag->netdev_head = &ndlist->node; | |
| 595 | +} | |
| 596 | + | |
| 597 | +/** | |
| 598 | + * ice_lag_destroy_netdev_list - free lag struct's netdev list | |
| 599 | + * @lag: pointer to local lag struct | |
| 600 | + * @ndlist: pointer to lag struct netdev list | |
| 601 | + */ | |
| 602 | +static void ice_lag_destroy_netdev_list(struct ice_lag *lag, | |
| 603 | + struct ice_lag_netdev_list *ndlist) | |
| 604 | +{ | |
| 605 | + struct ice_lag_netdev_list *entry, *n; | |
| 606 | + | |
| 607 | + rcu_read_lock(); | |
| 608 | + list_for_each_entry_safe(entry, n, &ndlist->node, node) { | |
| 609 | + list_del(&entry->node); | |
| 610 | + kfree(entry); | |
| 611 | + } | |
| 612 | + rcu_read_unlock(); | |
| 613 | + lag->netdev_head = NULL; | |
| 614 | +} | |
| 615 | + | |
| 572 | 616 | /** |
| 573 | 617 | * ice_lag_move_single_vf_nodes - Move Tx scheduling nodes for single VF |
| 574 | 618 | * @lag: primary interface LAG struct |
| @@ -597,7 +641,6 @@ ice_lag_move_single_vf_nodes(struct ice_lag *lag, u8 oldport, u8 newport, · 22 unmodified lines | ||
| 597 | 641 | void ice_lag_move_new_vf_nodes(struct ice_vf *vf) |
| 598 | 642 | { |
| 599 | 643 | struct ice_lag_netdev_list ndlist; |
| 600 | − struct list_head *tmp, *n; | |
| 601 | 644 | u8 pri_port, act_port; |
| 602 | 645 | struct ice_lag *lag; |
| 603 | 646 | struct ice_vsi *vsi; |
| @@ -621,38 +664,15 @@ void ice_lag_move_new_vf_nodes(struct ice_vf *vf) · 17 unmodified lines | ||
| 621 | 664 | pri_port = pf->hw.port_info->lport; |
| 622 | 665 | act_port = lag->active_port; |
| 623 | 666 | |
| 624 | − if (lag->upper_netdev) { | |
| 625 | − struct ice_lag_netdev_list *nl; | |
| 626 | − struct net_device *tmp_nd; | |
| 627 | − | |
| 628 | − INIT_LIST_HEAD(&ndlist.node); | |
| 629 | − rcu_read_lock(); | |
| 630 | − for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) { | |
| 631 | − nl = kzalloc(sizeof(*nl), GFP_ATOMIC); | |
| 632 | − if (!nl) | |
| 633 | − break; | |
| 634 | − | |
| 635 | − nl->netdev = tmp_nd; | |
| 636 | − list_add(&nl->node, &ndlist.node); | |
| 637 | − } | |
| 638 | − rcu_read_unlock(); | |
| 639 | − } | |
| 640 | − | |
| 641 | − lag->netdev_head = &ndlist.node; | |
| 667 | + if (lag->upper_netdev) | |
| 668 | + ice_lag_build_netdev_list(lag, &ndlist); | |
| 642 | 669 | |
| 643 | 670 | if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG) && |
| 644 | 671 | lag->bonded && lag->primary && pri_port != act_port && |
| 645 | 672 | !list_empty(lag->netdev_head)) |
| 646 | 673 | ice_lag_move_single_vf_nodes(lag, pri_port, act_port, vsi->idx); |
| 647 | 674 | |
| 648 | − list_for_each_safe(tmp, n, &ndlist.node) { | |
| 649 | − struct ice_lag_netdev_list *entry; | |
| 650 | − | |
| 651 | − entry = list_entry(tmp, struct ice_lag_netdev_list, node); | |
| 652 | − list_del(&entry->node); | |
| 653 | − kfree(entry); | |
| 654 | − } | |
| 655 | − lag->netdev_head = NULL; | |
| 675 | + ice_lag_destroy_netdev_list(lag, &ndlist); | |
| 656 | 676 | |
| 657 | 677 | new_vf_unlock: |
| 658 | 678 | mutex_unlock(&pf->lag_mutex); |
| @@ -679,6 +699,29 @@ static void ice_lag_move_vf_nodes(struct ice_lag *lag, u8 oldport, u8 newport) · 20 unmodified lines | ||
| 679 | 699 | ice_lag_move_single_vf_nodes(lag, oldport, newport, i); |
| 680 | 700 | } |
| 681 | 701 | |
| 702 | +/** | |
| 703 | + * ice_lag_move_vf_nodes_cfg - move vf nodes outside LAG netdev event context | |
| 704 | + * @lag: local lag struct | |
| 705 | + * @src_prt: lport value for source port | |
| 706 | + * @dst_prt: lport value for destination port | |
| 707 | + * | |
| 708 | + * This function is used to move nodes during an out-of-netdev-event situation, | |
| 709 | + * primarily when the driver needs to reconfigure or recreate resources. | |
| 710 | + * | |
| 711 | + * Must be called while holding the lag_mutex to avoid lag events from | |
| 712 | + * processing while out-of-sync moves are happening. Also, paired moves, | |
| 713 | + * such as used in a reset flow, should both be called under the same mutex | |
| 714 | + * lock to avoid changes between start of reset and end of reset. | |
| 715 | + */ | |
| 716 | +void ice_lag_move_vf_nodes_cfg(struct ice_lag *lag, u8 src_prt, u8 dst_prt) | |
| 717 | +{ | |
| 718 | + struct ice_lag_netdev_list ndlist; | |
| 719 | + | |
| 720 | + ice_lag_build_netdev_list(lag, &ndlist); | |
| 721 | + ice_lag_move_vf_nodes(lag, src_prt, dst_prt); | |
| 722 | + ice_lag_destroy_netdev_list(lag, &ndlist); | |
| 723 | +} | |
| 724 | + | |
| 682 | 725 | #define ICE_LAG_SRIOV_CP_RECIPE 10 |
| 683 | 726 | #define ICE_LAG_SRIOV_TRAIN_PKT_LEN 16 |
| 684 | 727 | |
| @@ -2051,7 +2094,6 @@ void ice_lag_rebuild(struct ice_pf *pf) · 1366 unmodified lines | ||
| 2051 | 2094 | { |
| 2052 | 2095 | struct ice_lag_netdev_list ndlist; |
| 2053 | 2096 | struct ice_lag *lag, *prim_lag; |
| 2054 | − struct list_head *tmp, *n; | |
| 2055 | 2097 | u8 act_port, loc_port; |
| 2056 | 2098 | |
| 2057 | 2099 | if (!pf->lag || !pf->lag->bonded) |
| @@ -2063,21 +2105,7 @@ void ice_lag_rebuild(struct ice_pf *pf) · 5 unmodified lines | ||
| 2063 | 2105 | if (lag->primary) { |
| 2064 | 2106 | prim_lag = lag; |
| 2065 | 2107 | } else { |
| 2066 | − struct ice_lag_netdev_list *nl; | |
| 2067 | − struct net_device *tmp_nd; | |
| 2068 | − | |
| 2069 | − INIT_LIST_HEAD(&ndlist.node); | |
| 2070 | − rcu_read_lock(); | |
| 2071 | − for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) { | |
| 2072 | − nl = kzalloc(sizeof(*nl), GFP_ATOMIC); | |
| 2073 | − if (!nl) | |
| 2074 | − break; | |
| 2075 | − | |
| 2076 | − nl->netdev = tmp_nd; | |
| 2077 | − list_add(&nl->node, &ndlist.node); | |
| 2078 | − } | |
| 2079 | − rcu_read_unlock(); | |
| 2080 | − lag->netdev_head = &ndlist.node; | |
| 2108 | + ice_lag_build_netdev_list(lag, &ndlist); | |
| 2081 | 2109 | prim_lag = ice_lag_find_primary(lag); |
| 2082 | 2110 | } |
| 2083 | 2111 | |
| @@ -2107,13 +2135,7 @@ void ice_lag_rebuild(struct ice_pf *pf) · 23 unmodified lines | ||
| 2107 | 2135 | |
| 2108 | 2136 | ice_clear_rdma_cap(pf); |
| 2109 | 2137 | lag_rebuild_out: |
| 2110 | − list_for_each_safe(tmp, n, &ndlist.node) { | |
| 2111 | − struct ice_lag_netdev_list *entry; | |
| 2112 | − | |
| 2113 | − entry = list_entry(tmp, struct ice_lag_netdev_list, node); | |
| 2114 | − list_del(&entry->node); | |
| 2115 | − kfree(entry); | |
| 2116 | − } | |
| 2138 | + ice_lag_destroy_netdev_list(lag, &ndlist); | |
| 2117 | 2139 | mutex_unlock(&pf->lag_mutex); |
| 2118 | 2140 | } |
| 2119 | 2141 | |
| @@ -65,4 +65,5 @@ int ice_init_lag(struct ice_pf *pf); · 64 unmodified lines | ||
| 65 | 65 | void ice_deinit_lag(struct ice_pf *pf); |
| 66 | 66 | void ice_lag_rebuild(struct ice_pf *pf); |
| 67 | 67 | bool ice_lag_is_switchdev_running(struct ice_pf *pf); |
| 68 | +void ice_lag_move_vf_nodes_cfg(struct ice_lag *lag, u8 src_prt, u8 dst_prt); | |
| 68 | 69 | #endif /* _ICE_LAG_H_ */ |
| @@ -7401,15 +7401,6 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) · 7400 unmodified lines | ||
| 7401 | 7401 | goto err_vsi_rebuild; |
| 7402 | 7402 | } |
| 7403 | 7403 | |
| 7404 | − /* configure PTP timestamping after VSI rebuild */ | |
| 7405 | − if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags)) { | |
| 7406 | − if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF) | |
| 7407 | − ice_ptp_cfg_timestamp(pf, false); | |
| 7408 | − else if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL) | |
| 7409 | − /* for E82x PHC owner always need to have interrupts */ | |
| 7410 | − ice_ptp_cfg_timestamp(pf, true); | |
| 7411 | − } | |
| 7412 | − | |
| 7413 | 7404 | err = ice_vsi_rebuild_by_type(pf, ICE_VSI_SWITCHDEV_CTRL); |
| 7414 | 7405 | if (err) { |
| 7415 | 7406 | dev_err(dev, "Switchdev CTRL VSI rebuild failed: %d\n", err); |
| @@ -7461,6 +7452,9 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) · 45 unmodified lines | ||
| 7461 | 7452 | ice_plug_aux_dev(pf); |
| 7462 | 7453 | if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG)) |
| 7463 | 7454 | ice_lag_rebuild(pf); |
| 7455 | + | |
| 7456 | + /* Restore timestamp mode settings after VSI rebuild */ | |
| 7457 | + ice_ptp_restore_timestamp_mode(pf); | |
| 7464 | 7458 | return; |
| 7465 | 7459 | |
| 7466 | 7460 | err_vsi_rebuild: |
| @@ -256,48 +256,42 @@ ice_verify_pin_e810t(struct ptp_clock_info *info, unsigned int pin, · 255 unmodified lines | ||
| 256 | 256 | } |
| 257 | 257 | |
| 258 | 258 | /** |
| 259 | − * ice_ptp_configure_tx_tstamp - Enable or disable Tx timestamp interrupt | |
| 260 | − * @pf: The PF pointer to search in | |
| 261 | − * @on: bool value for whether timestamp interrupt is enabled or disabled | |
| 259 | + * ice_ptp_cfg_tx_interrupt - Configure Tx timestamp interrupt for the device | |
| 260 | + * @pf: Board private structure | |
| 261 | + * | |
| 262 | + * Program the device to respond appropriately to the Tx timestamp interrupt | |
| 263 | + * cause. | |
| 262 | 264 | */ |
| 263 | −static void ice_ptp_configure_tx_tstamp(struct ice_pf *pf, bool on) | |
| 265 | +static void ice_ptp_cfg_tx_interrupt(struct ice_pf *pf) | |
| 264 | 266 | { |
| 267 | + struct ice_hw *hw = &pf->hw; | |
| 268 | + bool enable; | |
| 265 | 269 | u32 val; |
| 266 | 270 | |
| 271 | + switch (pf->ptp.tx_interrupt_mode) { | |
| 272 | + case ICE_PTP_TX_INTERRUPT_ALL: | |
| 273 | + /* React to interrupts across all quads. */ | |
| 274 | + wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f); | |
| 275 | + enable = true; | |
| 276 | + break; | |
| 277 | + case ICE_PTP_TX_INTERRUPT_NONE: | |
| 278 | + /* Do not react to interrupts on any quad. */ | |
| 279 | + wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0); | |
| 280 | + enable = false; | |
| 281 | + break; | |
| 282 | + case ICE_PTP_TX_INTERRUPT_SELF: | |
| 283 | + default: | |
| 284 | + enable = pf->ptp.tstamp_config.tx_type == HWTSTAMP_TX_ON; | |
| 285 | + break; | |
| 286 | + } | |
| 287 | + | |
| 267 | 288 | /* Configure the Tx timestamp interrupt */ |
| 268 | − val = rd32(&pf->hw, PFINT_OICR_ENA); | |
| 269 | − if (on) | |
| 289 | + val = rd32(hw, PFINT_OICR_ENA); | |
| 290 | + if (enable) | |
| 270 | 291 | val |= PFINT_OICR_TSYN_TX_M; |
| 271 | 292 | else |
| 272 | 293 | val &= ~PFINT_OICR_TSYN_TX_M; |
| 273 | − wr32(&pf->hw, PFINT_OICR_ENA, val); | |
| 274 | −} | |
| 275 | − | |
| 276 | −/** | |
| 277 | − * ice_set_tx_tstamp - Enable or disable Tx timestamping | |
| 278 | − * @pf: The PF pointer to search in | |
| 279 | − * @on: bool value for whether timestamps are enabled or disabled | |
| 280 | − */ | |
| 281 | −static void ice_set_tx_tstamp(struct ice_pf *pf, bool on) | |
| 282 | −{ | |
| 283 | − struct ice_vsi *vsi; | |
| 284 | − u16 i; | |
| 285 | − | |
| 286 | − vsi = ice_get_main_vsi(pf); | |
| 287 | − if (!vsi) | |
| 288 | − return; | |
| 289 | − | |
| 290 | − /* Set the timestamp enable flag for all the Tx rings */ | |
| 291 | − ice_for_each_txq(vsi, i) { | |
| 292 | − if (!vsi->tx_rings[i]) | |
| 293 | − continue; | |
| 294 | − vsi->tx_rings[i]->ptp_tx = on; | |
| 295 | − } | |
| 296 | − | |
| 297 | − if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_SELF) | |
| 298 | − ice_ptp_configure_tx_tstamp(pf, on); | |
| 299 | − | |
| 300 | − pf->ptp.tstamp_config.tx_type = on ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; | |
| 294 | + wr32(hw, PFINT_OICR_ENA, val); | |
| 301 | 295 | } |
| 302 | 296 | |
| 303 | 297 | /** |
| @@ -311,7 +305,7 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on) · 7 unmodified lines | ||
| 311 | 305 | u16 i; |
| 312 | 306 | |
| 313 | 307 | vsi = ice_get_main_vsi(pf); |
| 314 | − if (!vsi) | |
| 308 | + if (!vsi || !vsi->rx_rings) | |
| 315 | 309 | return; |
| 316 | 310 | |
| 317 | 311 | /* Set the timestamp flag for all the Rx rings */ |
| @@ -320,23 +314,50 @@ static void ice_set_rx_tstamp(struct ice_pf *pf, bool on) · 2 unmodified lines | ||
| 320 | 314 | continue; |
| 321 | 315 | vsi->rx_rings[i]->ptp_rx = on; |
| 322 | 316 | } |
| 317 | +} | |
| 318 | + | |
| 319 | +/** | |
| 320 | + * ice_ptp_disable_timestamp_mode - Disable current timestamp mode | |
| 321 | + * @pf: Board private structure | |
| 322 | + * | |
| 323 | + * Called during preparation for reset to temporarily disable timestamping on | |
| 324 | + * the device. Called during remove to disable timestamping while cleaning up | |
| 325 | + * driver resources. | |
| 326 | + */ | |
| 327 | +static void ice_ptp_disable_timestamp_mode(struct ice_pf *pf) | |
| 328 | +{ | |
| 329 | + struct ice_hw *hw = &pf->hw; | |
| 330 | + u32 val; | |
| 331 | + | |
| 332 | + val = rd32(hw, PFINT_OICR_ENA); | |
| 333 | + val &= ~PFINT_OICR_TSYN_TX_M; | |
| 334 | + wr32(hw, PFINT_OICR_ENA, val); | |
| 323 | 335 | |
| 324 | − pf->ptp.tstamp_config.rx_filter = on ? HWTSTAMP_FILTER_ALL : | |
| 325 | − HWTSTAMP_FILTER_NONE; | |
| 336 | + ice_set_rx_tstamp(pf, false); | |
| 326 | 337 | } |
| 327 | 338 | |
| 328 | 339 | /** |
| 329 | − * ice_ptp_cfg_timestamp - Configure timestamp for init/deinit | |
| 340 | + * ice_ptp_restore_timestamp_mode - Restore timestamp configuration | |
| 330 | 341 | * @pf: Board private structure |
| 331 | − * @ena: bool value to enable or disable time stamp | |
| 332 | 342 | * |
| 333 | − * This function will configure timestamping during PTP initialization | |
| 334 | − * and deinitialization | |
| 343 | + * Called at the end of rebuild to restore timestamp configuration after | |
| 344 | + * a device reset. | |
| 335 | 345 | */ |
| 336 | −void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) | |
| 346 | +void ice_ptp_restore_timestamp_mode(struct ice_pf *pf) | |
| 337 | 347 | { |
| 338 | − ice_set_tx_tstamp(pf, ena); | |
| 339 | − ice_set_rx_tstamp(pf, ena); | |
| 348 | + struct ice_hw *hw = &pf->hw; | |
| 349 | + bool enable_rx; | |
| 350 | + | |
| 351 | + ice_ptp_cfg_tx_interrupt(pf); | |
| 352 | + | |
| 353 | + enable_rx = pf->ptp.tstamp_config.rx_filter == HWTSTAMP_FILTER_ALL; | |
| 354 | + ice_set_rx_tstamp(pf, enable_rx); | |
| 355 | + | |
| 356 | + /* Trigger an immediate software interrupt to ensure that timestamps | |
| 357 | + * which occurred during reset are handled now. | |
| 358 | + */ | |
| 359 | + wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M); | |
| 360 | + ice_flush(hw); | |
| 340 | 361 | } |
| 341 | 362 | |
| 342 | 363 | /** |
| @@ -2037,10 +2058,10 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config) · 1694 unmodified lines | ||
| 2037 | 2058 | { |
| 2038 | 2059 | switch (config->tx_type) { |
| 2039 | 2060 | case HWTSTAMP_TX_OFF: |
| 2040 | − ice_set_tx_tstamp(pf, false); | |
| 2061 | + pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_OFF; | |
| 2041 | 2062 | break; |
| 2042 | 2063 | case HWTSTAMP_TX_ON: |
| 2043 | − ice_set_tx_tstamp(pf, true); | |
| 2064 | + pf->ptp.tstamp_config.tx_type = HWTSTAMP_TX_ON; | |
| 2044 | 2065 | break; |
| 2045 | 2066 | default: |
| 2046 | 2067 | return -ERANGE; |
| @@ -2048,7 +2069,7 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config) · 1 unmodified line | ||
| 2048 | 2069 | |
| 2049 | 2070 | switch (config->rx_filter) { |
| 2050 | 2071 | case HWTSTAMP_FILTER_NONE: |
| 2051 | − ice_set_rx_tstamp(pf, false); | |
| 2072 | + pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE; | |
| 2052 | 2073 | break; |
| 2053 | 2074 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: |
| 2054 | 2075 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: |
| @@ -2064,12 +2085,15 @@ ice_ptp_set_timestamp_mode(struct ice_pf *pf, struct hwtstamp_config *config) · 9 unmodified lines | ||
| 2064 | 2085 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: |
| 2065 | 2086 | case HWTSTAMP_FILTER_NTP_ALL: |
| 2066 | 2087 | case HWTSTAMP_FILTER_ALL: |
| 2067 | − ice_set_rx_tstamp(pf, true); | |
| 2088 | + pf->ptp.tstamp_config.rx_filter = HWTSTAMP_FILTER_ALL; | |
| 2068 | 2089 | break; |
| 2069 | 2090 | default: |
| 2070 | 2091 | return -ERANGE; |
| 2071 | 2092 | } |
| 2072 | 2093 | |
| 2094 | + /* Immediately update the device timestamping mode */ | |
| 2095 | + ice_ptp_restore_timestamp_mode(pf); | |
| 2096 | + | |
| 2073 | 2097 | return 0; |
| 2074 | 2098 | } |
| 2075 | 2099 | |
| @@ -2737,7 +2761,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf) · 661 unmodified lines | ||
| 2737 | 2761 | clear_bit(ICE_FLAG_PTP, pf->flags); |
| 2738 | 2762 | |
| 2739 | 2763 | /* Disable timestamping for both Tx and Rx */ |
| 2740 | − ice_ptp_cfg_timestamp(pf, false); | |
| 2764 | + ice_ptp_disable_timestamp_mode(pf); | |
| 2741 | 2765 | |
| 2742 | 2766 | kthread_cancel_delayed_work_sync(&ptp->work); |
| 2743 | 2767 | |
| @@ -2803,15 +2827,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf) · 59 unmodified lines | ||
| 2803 | 2827 | /* Release the global hardware lock */ |
| 2804 | 2828 | ice_ptp_unlock(hw); |
| 2805 | 2829 | |
| 2806 | − if (pf->ptp.tx_interrupt_mode == ICE_PTP_TX_INTERRUPT_ALL) { | |
| 2807 | − /* The clock owner for this device type handles the timestamp | |
| 2808 | − * interrupt for all ports. | |
| 2809 | − */ | |
| 2810 | − ice_ptp_configure_tx_tstamp(pf, true); | |
| 2811 | − | |
| 2812 | − /* React on all quads interrupts for E82x */ | |
| 2813 | − wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x1f); | |
| 2814 | − | |
| 2830 | + if (!ice_is_e810(hw)) { | |
| 2815 | 2831 | /* Enable quad interrupts */ |
| 2816 | 2832 | err = ice_ptp_tx_ena_intr(pf, true, itr); |
| 2817 | 2833 | if (err) |
| @@ -2881,13 +2897,6 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port) · 63 unmodified lines | ||
| 2881 | 2897 | case ICE_PHY_E810: |
| 2882 | 2898 | return ice_ptp_init_tx_e810(pf, &ptp_port->tx); |
| 2883 | 2899 | case ICE_PHY_E822: |
| 2884 | − /* Non-owner PFs don't react to any interrupts on E82x, | |
| 2885 | − * neither on own quad nor on others | |
| 2886 | − */ | |
| 2887 | − if (!ice_ptp_pf_handles_tx_interrupt(pf)) { | |
| 2888 | − ice_ptp_configure_tx_tstamp(pf, false); | |
| 2889 | − wr32(hw, PFINT_TSYN_MSK + (0x4 * hw->pf_id), (u32)0x0); | |
| 2890 | − } | |
| 2891 | 2900 | kthread_init_delayed_work(&ptp_port->ov_work, |
| 2892 | 2901 | ice_ptp_wait_for_offsets); |
| 2893 | 2902 | |
| @@ -3032,6 +3041,9 @@ void ice_ptp_init(struct ice_pf *pf) · 138 unmodified lines | ||
| 3032 | 3041 | /* Start the PHY timestamping block */ |
| 3033 | 3042 | ice_ptp_reset_phy_timestamping(pf); |
| 3034 | 3043 | |
| 3044 | + /* Configure initial Tx interrupt settings */ | |
| 3045 | + ice_ptp_cfg_tx_interrupt(pf); | |
| 3046 | + | |
| 3035 | 3047 | set_bit(ICE_FLAG_PTP, pf->flags); |
| 3036 | 3048 | err = ice_ptp_init_work(pf, ptp); |
| 3037 | 3049 | if (err) |
| @@ -3067,7 +3079,7 @@ void ice_ptp_release(struct ice_pf *pf) · 29 unmodified lines | ||
| 3067 | 3079 | return; |
| 3068 | 3080 | |
| 3069 | 3081 | /* Disable timestamping for both Tx and Rx */ |
| 3070 | − ice_ptp_cfg_timestamp(pf, false); | |
| 3082 | + ice_ptp_disable_timestamp_mode(pf); | |
| 3071 | 3083 | |
| 3072 | 3084 | ice_ptp_remove_auxbus_device(pf); |
| 3073 | 3085 | |
| @@ -292,7 +292,7 @@ int ice_ptp_clock_index(struct ice_pf *pf); · 291 unmodified lines | ||
| 292 | 292 | struct ice_pf; |
| 293 | 293 | int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr); |
| 294 | 294 | int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr); |
| 295 | −void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena); | |
| 295 | +void ice_ptp_restore_timestamp_mode(struct ice_pf *pf); | |
| 296 | 296 | |
| 297 | 297 | void ice_ptp_extts_event(struct ice_pf *pf); |
| 298 | 298 | s8 ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb); |
| @@ -317,8 +317,7 @@ static inline int ice_ptp_get_ts_config(struct ice_pf *pf, struct ifreq *ifr) · 18 unmodified lines | ||
| 317 | 317 | return -EOPNOTSUPP; |
| 318 | 318 | } |
| 319 | 319 | |
| 320 | −static inline void ice_ptp_cfg_timestamp(struct ice_pf *pf, bool ena) { } | |
| 321 | − | |
| 320 | +static inline void ice_ptp_restore_timestamp_mode(struct ice_pf *pf) { } | |
| 322 | 321 | static inline void ice_ptp_extts_event(struct ice_pf *pf) { } |
| 323 | 322 | static inline s8 |
| 324 | 323 | ice_ptp_request_ts(struct ice_ptp_tx *tx, struct sk_buff *skb) |
| @@ -3961,3 +3961,57 @@ int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num) · 3960 unmodified lines | ||
| 3961 | 3961 | |
| 3962 | 3962 | return ret; |
| 3963 | 3963 | } |
| 3964 | + | |
| 3965 | +/** | |
| 3966 | + * ice_cgu_get_output_pin_state_caps - get output pin state capabilities | |
| 3967 | + * @hw: pointer to the hw struct | |
| 3968 | + * @pin_id: id of a pin | |
| 3969 | + * @caps: capabilities to modify | |
| 3970 | + * | |
| 3971 | + * Return: | |
| 3972 | + * * 0 - success, state capabilities were modified | |
| 3973 | + * * negative - failure, capabilities were not modified | |
| 3974 | + */ | |
| 3975 | +int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id, | |
| 3976 | + unsigned long *caps) | |
| 3977 | +{ | |
| 3978 | + bool can_change = true; | |
| 3979 | + | |
| 3980 | + switch (hw->device_id) { | |
| 3981 | + case ICE_DEV_ID_E810C_SFP: | |
| 3982 | + if (pin_id == ZL_OUT2 || pin_id == ZL_OUT3) | |
| 3983 | + can_change = false; | |
| 3984 | + break; | |
| 3985 | + case ICE_DEV_ID_E810C_QSFP: | |
| 3986 | + if (pin_id == ZL_OUT2 || pin_id == ZL_OUT3 || pin_id == ZL_OUT4) | |
| 3987 | + can_change = false; | |
| 3988 | + break; | |
| 3989 | + case ICE_DEV_ID_E823L_10G_BASE_T: | |
| 3990 | + case ICE_DEV_ID_E823L_1GBE: | |
| 3991 | + case ICE_DEV_ID_E823L_BACKPLANE: | |
| 3992 | + case ICE_DEV_ID_E823L_QSFP: | |
| 3993 | + case ICE_DEV_ID_E823L_SFP: | |
| 3994 | + case ICE_DEV_ID_E823C_10G_BASE_T: | |
| 3995 | + case ICE_DEV_ID_E823C_BACKPLANE: | |
| 3996 | + case ICE_DEV_ID_E823C_QSFP: | |
| 3997 | + case ICE_DEV_ID_E823C_SFP: | |
| 3998 | + case ICE_DEV_ID_E823C_SGMII: | |
| 3999 | + if (hw->cgu_part_number == | |
| 4000 | + ICE_AQC_GET_LINK_TOPO_NODE_NR_ZL30632_80032 && | |
| 4001 | + pin_id == ZL_OUT2) | |
| 4002 | + can_change = false; | |
| 4003 | + else if (hw->cgu_part_number == | |
| 4004 | + ICE_AQC_GET_LINK_TOPO_NODE_NR_SI5383_5384 && | |
| 4005 | + pin_id == SI_OUT1) | |
| 4006 | + can_change = false; | |
| 4007 | + break; | |
| 4008 | + default: | |
| 4009 | + return -EINVAL; | |
| 4010 | + } | |
| 4011 | + if (can_change) | |
| 4012 | + *caps |= DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE; | |
| 4013 | + else | |
| 4014 | + *caps &= ~DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE; | |
| 4015 | + | |
| 4016 | + return 0; | |
| 4017 | +} | |
| @@ -282,6 +282,8 @@ int ice_get_cgu_state(struct ice_hw *hw, u8 dpll_idx, · 281 unmodified lines | ||
| 282 | 282 | int ice_get_cgu_rclk_pin_info(struct ice_hw *hw, u8 *base_idx, u8 *pin_num); |
| 283 | 283 | |
| 284 | 284 | void ice_ptp_init_phy_model(struct ice_hw *hw); |
| 285 | +int ice_cgu_get_output_pin_state_caps(struct ice_hw *hw, u8 pin_id, | |
| 286 | + unsigned long *caps); | |
| 285 | 287 | |
| 286 | 288 | #define PFTSYN_SEM_BYTES 4 |
| 287 | 289 | |
| @@ -374,16 +374,11 @@ static void ice_ena_vf_mappings(struct ice_vf *vf) · 373 unmodified lines | ||
| 374 | 374 | */ |
| 375 | 375 | int ice_calc_vf_reg_idx(struct ice_vf *vf, struct ice_q_vector *q_vector) |
| 376 | 376 | { |
| 377 | − struct ice_pf *pf; | |
| 378 | − | |
| 379 | 377 | if (!vf || !q_vector) |
| 380 | 378 | return -EINVAL; |
| 381 | 379 | |
| 382 | − pf = vf->pf; | |
| 383 | − | |
| 384 | 380 | /* always add one to account for the OICR being the first MSIX */ |
| 385 | − return pf->sriov_base_vector + pf->vfs.num_msix_per * vf->vf_id + | |
| 386 | − q_vector->v_idx + 1; | |
| 381 | + return vf->first_vector_idx + q_vector->v_idx + 1; | |
| 387 | 382 | } |
| 388 | 383 | |
| 389 | 384 | /** |
| @@ -2306,9 +2306,6 @@ ice_tstamp(struct ice_tx_ring *tx_ring, struct sk_buff *skb, · 2305 unmodified lines | ||
| 2306 | 2306 | if (likely(!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) |
| 2307 | 2307 | return; |
| 2308 | 2308 | |
| 2309 | − if (!tx_ring->ptp_tx) | |
| 2310 | − return; | |
| 2311 | − | |
| 2312 | 2309 | /* Tx timestamps cannot be sampled when doing TSO */ |
| 2313 | 2310 | if (first->tx_flags & ICE_TX_FLAGS_TSO) |
| 2314 | 2311 | return; |
| @@ -380,7 +380,6 @@ struct ice_tx_ring { · 379 unmodified lines | ||
| 380 | 380 | #define ICE_TX_FLAGS_RING_VLAN_L2TAG2 BIT(2) |
| 381 | 381 | u8 flags; |
| 382 | 382 | u8 dcb_tc; /* Traffic class of ring */ |
| 383 | − u8 ptp_tx; | |
| 384 | 383 | } ____cacheline_internodealigned_in_smp; |
| 385 | 384 | |
| 386 | 385 | static inline bool ice_ring_uses_build_skb(struct ice_rx_ring *ring) |
| @@ -829,12 +829,16 @@ static void ice_notify_vf_reset(struct ice_vf *vf) · 828 unmodified lines | ||
| 829 | 829 | int ice_reset_vf(struct ice_vf *vf, u32 flags) |
| 830 | 830 | { |
| 831 | 831 | struct ice_pf *pf = vf->pf; |
| 832 | + struct ice_lag *lag; | |
| 832 | 833 | struct ice_vsi *vsi; |
| 834 | + u8 act_prt, pri_prt; | |
| 833 | 835 | struct device *dev; |
| 834 | 836 | int err = 0; |
| 835 | 837 | bool rsd; |
| 836 | 838 | |
| 837 | 839 | dev = ice_pf_to_dev(pf); |
| 840 | + act_prt = ICE_LAG_INVALID_PORT; | |
| 841 | + pri_prt = pf->hw.port_info->lport; | |
| 838 | 842 | |
| 839 | 843 | if (flags & ICE_VF_RESET_NOTIFY) |
| 840 | 844 | ice_notify_vf_reset(vf); |
| @@ -845,6 +849,17 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags) · 4 unmodified lines | ||
| 845 | 849 | return 0; |
| 846 | 850 | } |
| 847 | 851 | |
| 852 | + lag = pf->lag; | |
| 853 | + mutex_lock(&pf->lag_mutex); | |
| 854 | + if (lag && lag->bonded && lag->primary) { | |
| 855 | + act_prt = lag->active_port; | |
| 856 | + if (act_prt != pri_prt && act_prt != ICE_LAG_INVALID_PORT && | |
| 857 | + lag->upper_netdev) | |
| 858 | + ice_lag_move_vf_nodes_cfg(lag, act_prt, pri_prt); | |
| 859 | + else | |
| 860 | + act_prt = ICE_LAG_INVALID_PORT; | |
| 861 | + } | |
| 862 | + | |
| 848 | 863 | if (flags & ICE_VF_RESET_LOCK) |
| 849 | 864 | mutex_lock(&vf->cfg_lock); |
| 850 | 865 | else |
| @@ -937,6 +952,11 @@ out_unlock: · 86 unmodified lines | ||
| 937 | 952 | if (flags & ICE_VF_RESET_LOCK) |
| 938 | 953 | mutex_unlock(&vf->cfg_lock); |
| 939 | 954 | |
| 955 | + if (lag && lag->bonded && lag->primary && | |
| 956 | + act_prt != ICE_LAG_INVALID_PORT) | |
| 957 | + ice_lag_move_vf_nodes_cfg(lag, pri_prt, act_prt); | |
| 958 | + mutex_unlock(&pf->lag_mutex); | |
| 959 | + | |
| 940 | 960 | return err; |
| 941 | 961 | } |
| 942 | 962 | |
| @@ -32,7 +32,6 @@ static void ice_port_vlan_on(struct ice_vsi *vsi) · 31 unmodified lines | ||
| 32 | 32 | /* setup outer VLAN ops */ |
| 33 | 33 | vlan_ops->set_port_vlan = ice_vsi_set_outer_port_vlan; |
| 34 | 34 | vlan_ops->clear_port_vlan = ice_vsi_clear_outer_port_vlan; |
| 35 | − vlan_ops->clear_port_vlan = ice_vsi_clear_outer_port_vlan; | |
| 36 | 35 | |
| 37 | 36 | /* setup inner VLAN ops */ |
| 38 | 37 | vlan_ops = &vsi->inner_vlan_ops; |
| @@ -47,8 +46,13 @@ static void ice_port_vlan_on(struct ice_vsi *vsi) · 8 unmodified lines | ||
| 47 | 46 | |
| 48 | 47 | vlan_ops->set_port_vlan = ice_vsi_set_inner_port_vlan; |
| 49 | 48 | vlan_ops->clear_port_vlan = ice_vsi_clear_inner_port_vlan; |
| 50 | − vlan_ops->clear_port_vlan = ice_vsi_clear_inner_port_vlan; | |
| 51 | 49 | } |
| 50 | + | |
| 51 | + /* all Rx traffic should be in the domain of the assigned port VLAN, | |
| 52 | + * so prevent disabling Rx VLAN filtering | |
| 53 | + */ | |
| 54 | + vlan_ops->dis_rx_filtering = noop_vlan; | |
| 55 | + | |
| 52 | 56 | vlan_ops->ena_rx_filtering = ice_vsi_ena_rx_vlan_filtering; |
| 53 | 57 | } |
| 54 | 58 | |
| @@ -77,6 +81,8 @@ static void ice_port_vlan_off(struct ice_vsi *vsi) · 22 unmodified lines | ||
| 77 | 81 | vlan_ops->del_vlan = ice_vsi_del_vlan; |
| 78 | 82 | } |
| 79 | 83 | |
| 84 | + vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering; | |
| 85 | + | |
| 80 | 86 | if (!test_bit(ICE_FLAG_VF_VLAN_PRUNING, pf->flags)) |
| 81 | 87 | vlan_ops->ena_rx_filtering = noop_vlan; |
| 82 | 88 | else |
| @@ -141,7 +147,6 @@ void ice_vf_vsi_init_vlan_ops(struct ice_vsi *vsi) · 58 unmodified lines | ||
| 141 | 147 | &vsi->outer_vlan_ops : &vsi->inner_vlan_ops; |
| 142 | 148 | |
| 143 | 149 | vlan_ops->add_vlan = ice_vsi_add_vlan; |
| 144 | − vlan_ops->dis_rx_filtering = ice_vsi_dis_rx_vlan_filtering; | |
| 145 | 150 | vlan_ops->ena_tx_filtering = ice_vsi_ena_tx_vlan_filtering; |
| 146 | 151 | vlan_ops->dis_tx_filtering = ice_vsi_dis_tx_vlan_filtering; |
| 147 | 152 | } |
| @@ -1523,7 +1523,6 @@ static int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg) · 1522 unmodified lines | ||
| 1523 | 1523 | u16 num_q_vectors_mapped, vsi_id, vector_id; |
| 1524 | 1524 | struct virtchnl_irq_map_info *irqmap_info; |
| 1525 | 1525 | struct virtchnl_vector_map *map; |
| 1526 | − struct ice_pf *pf = vf->pf; | |
| 1527 | 1526 | struct ice_vsi *vsi; |
| 1528 | 1527 | int i; |
| 1529 | 1528 | |
| @@ -1535,7 +1534,7 @@ static int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg) · 5 unmodified lines | ||
| 1535 | 1534 | * there is actually at least a single VF queue vector mapped |
| 1536 | 1535 | */ |
| 1537 | 1536 | if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) || |
| 1538 | − pf->vfs.num_msix_per < num_q_vectors_mapped || | |
| 1537 | + vf->num_msix < num_q_vectors_mapped || | |
| 1539 | 1538 | !num_q_vectors_mapped) { |
| 1540 | 1539 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 1541 | 1540 | goto error_param; |
| @@ -1557,7 +1556,7 @@ static int ice_vc_cfg_irq_map_msg(struct ice_vf *vf, u8 *msg) · 15 unmodified lines | ||
| 1557 | 1556 | /* vector_id is always 0-based for each VF, and can never be |
| 1558 | 1557 | * larger than or equal to the max allowed interrupts per VF |
| 1559 | 1558 | */ |
| 1560 | − if (!(vector_id < pf->vfs.num_msix_per) || | |
| 1559 | + if (!(vector_id < vf->num_msix) || | |
| 1561 | 1560 | !ice_vc_isvalid_vsi_id(vf, vsi_id) || |
| 1562 | 1561 | (!vector_id && (map->rxq_map || map->txq_map))) { |
| 1563 | 1562 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| @@ -1603,9 +1602,24 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) · 39 unmodified lines | ||
| 1603 | 1602 | (struct virtchnl_vsi_queue_config_info *)msg; |
| 1604 | 1603 | struct virtchnl_queue_pair_info *qpi; |
| 1605 | 1604 | struct ice_pf *pf = vf->pf; |
| 1605 | + struct ice_lag *lag; | |
| 1606 | 1606 | struct ice_vsi *vsi; |
| 1607 | + u8 act_prt, pri_prt; | |
| 1607 | 1608 | int i = -1, q_idx; |
| 1608 | 1609 | |
| 1610 | + lag = pf->lag; | |
| 1611 | + mutex_lock(&pf->lag_mutex); | |
| 1612 | + act_prt = ICE_LAG_INVALID_PORT; | |
| 1613 | + pri_prt = pf->hw.port_info->lport; | |
| 1614 | + if (lag && lag->bonded && lag->primary) { | |
| 1615 | + act_prt = lag->active_port; | |
| 1616 | + if (act_prt != pri_prt && act_prt != ICE_LAG_INVALID_PORT && | |
| 1617 | + lag->upper_netdev) | |
| 1618 | + ice_lag_move_vf_nodes_cfg(lag, act_prt, pri_prt); | |
| 1619 | + else | |
| 1620 | + act_prt = ICE_LAG_INVALID_PORT; | |
| 1621 | + } | |
| 1622 | + | |
| 1609 | 1623 | if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) |
| 1610 | 1624 | goto error_param; |
| 1611 | 1625 | |
| @@ -1729,6 +1743,11 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) · 117 unmodified lines | ||
| 1729 | 1743 | } |
| 1730 | 1744 | } |
| 1731 | 1745 | |
| 1746 | + if (lag && lag->bonded && lag->primary && | |
| 1747 | + act_prt != ICE_LAG_INVALID_PORT) | |
| 1748 | + ice_lag_move_vf_nodes_cfg(lag, pri_prt, act_prt); | |
| 1749 | + mutex_unlock(&pf->lag_mutex); | |
| 1750 | + | |
| 1732 | 1751 | /* send the response to the VF */ |
| 1733 | 1752 | return ice_vc_send_msg_to_vf(vf, VIRTCHNL_OP_CONFIG_VSI_QUEUES, |
| 1734 | 1753 | VIRTCHNL_STATUS_SUCCESS, NULL, 0); |
| @@ -1743,6 +1762,11 @@ error_param: · 8 unmodified lines | ||
| 1743 | 1762 | vf->vf_id, i); |
| 1744 | 1763 | } |
| 1745 | 1764 | |
| 1765 | + if (lag && lag->bonded && lag->primary && | |
| 1766 | + act_prt != ICE_LAG_INVALID_PORT) | |
| 1767 | + ice_lag_move_vf_nodes_cfg(lag, pri_prt, act_prt); | |
| 1768 | + mutex_unlock(&pf->lag_mutex); | |
| 1769 | + | |
| 1746 | 1770 | ice_lag_move_new_vf_nodes(vf); |
| 1747 | 1771 | |
| 1748 | 1772 | /* send the response to the VF */ |
| @@ -4790,14 +4790,17 @@ static void mvneta_ethtool_get_strings(struct net_device *netdev, u32 sset, · 4789 unmodified lines | ||
| 4790 | 4790 | u8 *data) |
| 4791 | 4791 | { |
| 4792 | 4792 | if (sset == ETH_SS_STATS) { |
| 4793 | + struct mvneta_port *pp = netdev_priv(netdev); | |
| 4793 | 4794 | int i; |
| 4794 | 4795 | |
| 4795 | 4796 | for (i = 0; i < ARRAY_SIZE(mvneta_statistics); i++) |
| 4796 | 4797 | memcpy(data + i * ETH_GSTRING_LEN, |
| 4797 | 4798 | mvneta_statistics[i].name, ETH_GSTRING_LEN); |
| 4798 | 4799 | |
| 4799 | − data += ETH_GSTRING_LEN * ARRAY_SIZE(mvneta_statistics); | |
| 4800 | − page_pool_ethtool_stats_get_strings(data); | |
| 4800 | + if (!pp->bm_priv) { | |
| 4801 | + data += ETH_GSTRING_LEN * ARRAY_SIZE(mvneta_statistics); | |
| 4802 | + page_pool_ethtool_stats_get_strings(data); | |
| 4803 | + } | |
| 4801 | 4804 | } |
| 4802 | 4805 | } |
| 4803 | 4806 | |
| @@ -4915,8 +4918,10 @@ static void mvneta_ethtool_pp_stats(struct mvneta_port *pp, u64 *data) · 111 unmodified lines | ||
| 4915 | 4918 | struct page_pool_stats stats = {}; |
| 4916 | 4919 | int i; |
| 4917 | 4920 | |
| 4918 | − for (i = 0; i < rxq_number; i++) | |
| 4919 | − page_pool_get_stats(pp->rxqs[i].page_pool, &stats); | |
| 4921 | + for (i = 0; i < rxq_number; i++) { | |
| 4922 | + if (pp->rxqs[i].page_pool) | |
| 4923 | + page_pool_get_stats(pp->rxqs[i].page_pool, &stats); | |
| 4924 | + } | |
| 4920 | 4925 | |
| 4921 | 4926 | page_pool_ethtool_stats_get(data, &stats); |
| 4922 | 4927 | } |
| @@ -4932,14 +4937,21 @@ static void mvneta_ethtool_get_stats(struct net_device *dev, · 9 unmodified lines | ||
| 4932 | 4937 | for (i = 0; i < ARRAY_SIZE(mvneta_statistics); i++) |
| 4933 | 4938 | *data++ = pp->ethtool_stats[i]; |
| 4934 | 4939 | |
| 4935 | − mvneta_ethtool_pp_stats(pp, data); | |
| 4940 | + if (!pp->bm_priv) | |
| 4941 | + mvneta_ethtool_pp_stats(pp, data); | |
| 4936 | 4942 | } |
| 4937 | 4943 | |
| 4938 | 4944 | static int mvneta_ethtool_get_sset_count(struct net_device *dev, int sset) |
| 4939 | 4945 | { |
| 4940 | − if (sset == ETH_SS_STATS) | |
| 4941 | − return ARRAY_SIZE(mvneta_statistics) + | |
| 4942 | − page_pool_ethtool_stats_get_count(); | |
| 4946 | + if (sset == ETH_SS_STATS) { | |
| 4947 | + int count = ARRAY_SIZE(mvneta_statistics); | |
| 4948 | + struct mvneta_port *pp = netdev_priv(dev); | |
| 4949 | + | |
| 4950 | + if (!pp->bm_priv) | |
| 4951 | + count += page_pool_ethtool_stats_get_count(); | |
| 4952 | + | |
| 4953 | + return count; | |
| 4954 | + } | |
| 4943 | 4955 | |
| 4944 | 4956 | return -EOPNOTSUPP; |
| 4945 | 4957 | } |
| @@ -1945,7 +1945,7 @@ struct mcs_hw_info { · 1944 unmodified lines | ||
| 1945 | 1945 | u8 tcam_entries; /* RX/TX Tcam entries per mcs block */ |
| 1946 | 1946 | u8 secy_entries; /* RX/TX SECY entries per mcs block */ |
| 1947 | 1947 | u8 sc_entries; /* RX/TX SC CAM entries per mcs block */ |
| 1948 | − u8 sa_entries; /* PN table entries = SA entries */ | |
| 1948 | + u16 sa_entries; /* PN table entries = SA entries */ | |
| 1949 | 1949 | u64 rsvd[16]; |
| 1950 | 1950 | }; |
| 1951 | 1951 | |
| @@ -117,7 +117,7 @@ void mcs_get_rx_secy_stats(struct mcs *mcs, struct mcs_secy_stats *stats, int id · 116 unmodified lines | ||
| 117 | 117 | reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYTAGGEDCTLX(id); |
| 118 | 118 | stats->pkt_tagged_ctl_cnt = mcs_reg_read(mcs, reg); |
| 119 | 119 | |
| 120 | − reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDORNOTAGX(id); | |
| 120 | + reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(id); | |
| 121 | 121 | stats->pkt_untaged_cnt = mcs_reg_read(mcs, reg); |
| 122 | 122 | |
| 123 | 123 | reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(id); |
| @@ -215,7 +215,7 @@ void mcs_get_sc_stats(struct mcs *mcs, struct mcs_sc_stats *stats, · 91 unmodified lines | ||
| 215 | 215 | reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCNOTVALIDX(id); |
| 216 | 216 | stats->pkt_notvalid_cnt = mcs_reg_read(mcs, reg); |
| 217 | 217 | |
| 218 | − reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDOROKX(id); | |
| 218 | + reg = MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDX(id); | |
| 219 | 219 | stats->pkt_unchecked_cnt = mcs_reg_read(mcs, reg); |
| 220 | 220 | |
| 221 | 221 | if (mcs->hw->mcs_blks > 1) { |
| @@ -1219,6 +1219,17 @@ struct mcs *mcs_get_pdata(int mcs_id) · 997 unmodified lines | ||
| 1219 | 1219 | return NULL; |
| 1220 | 1220 | } |
| 1221 | 1221 | |
| 1222 | +bool is_mcs_bypass(int mcs_id) | |
| 1223 | +{ | |
| 1224 | + struct mcs *mcs_dev; | |
| 1225 | + | |
| 1226 | + list_for_each_entry(mcs_dev, &mcs_list, mcs_list) { | |
| 1227 | + if (mcs_dev->mcs_id == mcs_id) | |
| 1228 | + return mcs_dev->bypass; | |
| 1229 | + } | |
| 1230 | + return true; | |
| 1231 | +} | |
| 1232 | + | |
| 1222 | 1233 | void mcs_set_port_cfg(struct mcs *mcs, struct mcs_port_cfg_set_req *req) |
| 1223 | 1234 | { |
| 1224 | 1235 | u64 val = 0; |
| @@ -1436,7 +1447,7 @@ static int mcs_x2p_calibration(struct mcs *mcs) · 211 unmodified lines | ||
| 1436 | 1447 | return err; |
| 1437 | 1448 | } |
| 1438 | 1449 | |
| 1439 | −static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass) | |
| 1450 | +static void mcs_set_external_bypass(struct mcs *mcs, bool bypass) | |
| 1440 | 1451 | { |
| 1441 | 1452 | u64 val; |
| 1442 | 1453 | |
| @@ -1447,6 +1458,7 @@ static void mcs_set_external_bypass(struct mcs *mcs, u8 bypass) · 4 unmodified lines | ||
| 1447 | 1458 | else |
| 1448 | 1459 | val &= ~BIT_ULL(6); |
| 1449 | 1460 | mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val); |
| 1461 | + mcs->bypass = bypass; | |
| 1450 | 1462 | } |
| 1451 | 1463 | |
| 1452 | 1464 | static void mcs_global_cfg(struct mcs *mcs) |
| @@ -149,6 +149,7 @@ struct mcs { · 148 unmodified lines | ||
| 149 | 149 | u16 num_vec; |
| 150 | 150 | void *rvu; |
| 151 | 151 | u16 *tx_sa_active; |
| 152 | + bool bypass; | |
| 152 | 153 | }; |
| 153 | 154 | |
| 154 | 155 | struct mcs_ops { |
| @@ -206,6 +207,7 @@ void mcs_get_custom_tag_cfg(struct mcs *mcs, struct mcs_custom_tag_cfg_get_req * · 51 unmodified lines | ||
| 206 | 207 | int mcs_alloc_ctrlpktrule(struct rsrc_bmap *rsrc, u16 *pf_map, u16 offset, u16 pcifunc); |
| 207 | 208 | int mcs_free_ctrlpktrule(struct mcs *mcs, struct mcs_free_ctrl_pkt_rule_req *req); |
| 208 | 209 | int mcs_ctrlpktrule_write(struct mcs *mcs, struct mcs_ctrl_pkt_rule_write_req *req); |
| 210 | +bool is_mcs_bypass(int mcs_id); | |
| 209 | 211 | |
| 210 | 212 | /* CN10K-B APIs */ |
| 211 | 213 | void cn10kb_mcs_set_hw_capabilities(struct mcs *mcs); |
| @@ -810,14 +810,37 @@ · 809 unmodified lines | ||
| 810 | 810 | offset = 0x9d8ull; \ |
| 811 | 811 | offset; }) |
| 812 | 812 | |
| 813 | +#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDX(a) ({ \ | |
| 814 | + u64 offset; \ | |
| 815 | + \ | |
| 816 | + offset = 0xee80ull; \ | |
| 817 | + if (mcs->hw->mcs_blks > 1) \ | |
| 818 | + offset = 0xe818ull; \ | |
| 819 | + offset += (a) * 0x8ull; \ | |
| 820 | + offset; }) | |
| 821 | + | |
| 822 | +#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(a) ({ \ | |
| 823 | + u64 offset; \ | |
| 824 | + \ | |
| 825 | + offset = 0xa680ull; \ | |
| 826 | + if (mcs->hw->mcs_blks > 1) \ | |
| 827 | + offset = 0xd018ull; \ | |
| 828 | + offset += (a) * 0x8ull; \ | |
| 829 | + offset; }) | |
| 830 | + | |
| 831 | +#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCLATEORDELAYEDX(a) ({ \ | |
| 832 | + u64 offset; \ | |
| 833 | + \ | |
| 834 | + offset = 0xf680ull; \ | |
| 835 | + if (mcs->hw->mcs_blks > 1) \ | |
| 836 | + offset = 0xe018ull; \ | |
| 837 | + offset += (a) * 0x8ull; \ | |
| 838 | + offset; }) | |
| 839 | + | |
| 813 | 840 | #define MCSX_CSE_RX_MEM_SLAVE_INOCTETSSCDECRYPTEDX(a) (0xe680ull + (a) * 0x8ull) |
| 814 | 841 | #define MCSX_CSE_RX_MEM_SLAVE_INOCTETSSCVALIDATEX(a) (0xde80ull + (a) * 0x8ull) |
| 815 | −#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDORNOTAGX(a) (0xa680ull + (a) * 0x8ull) | |
| 816 | 842 | #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYNOTAGX(a) (0xd218 + (a) * 0x8ull) |
| 817 | −#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYUNTAGGEDX(a) (0xd018ull + (a) * 0x8ull) | |
| 818 | −#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCUNCHECKEDOROKX(a) (0xee80ull + (a) * 0x8ull) | |
| 819 | 843 | #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSECYCTLX(a) (0xb680ull + (a) * 0x8ull) |
| 820 | −#define MCSX_CSE_RX_MEM_SLAVE_INPKTSSCLATEORDELAYEDX(a) (0xf680ull + (a) * 0x8ull) | |
| 821 | 844 | #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSAINVALIDX(a) (0x12680ull + (a) * 0x8ull) |
| 822 | 845 | #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSANOTUSINGSAERRORX(a) (0x15680ull + (a) * 0x8ull) |
| 823 | 846 | #define MCSX_CSE_RX_MEM_SLAVE_INPKTSSANOTVALIDX(a) (0x13680ull + (a) * 0x8ull) |
| @@ -2631,6 +2631,9 @@ static void __rvu_flr_handler(struct rvu *rvu, u16 pcifunc) · 2630 unmodified lines | ||
| 2631 | 2631 | rvu_npc_free_mcam_entries(rvu, pcifunc, -1); |
| 2632 | 2632 | rvu_mac_reset(rvu, pcifunc); |
| 2633 | 2633 | |
| 2634 | + if (rvu->mcs_blk_cnt) | |
| 2635 | + rvu_mcs_flr_handler(rvu, pcifunc); | |
| 2636 | + | |
| 2634 | 2637 | mutex_unlock(&rvu->flr_lock); |
| 2635 | 2638 | } |
| 2636 | 2639 | |
| @@ -345,6 +345,7 @@ struct nix_hw { · 344 unmodified lines | ||
| 345 | 345 | struct nix_txvlan txvlan; |
| 346 | 346 | struct nix_ipolicer *ipolicer; |
| 347 | 347 | u64 *tx_credits; |
| 348 | + u8 cc_mcs_cnt; | |
| 348 | 349 | }; |
| 349 | 350 | |
| 350 | 351 | /* RVU block's capabilities or functionality, |
| @@ -1087,7 +1087,7 @@ static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl) · 1086 unmodified lines | ||
| 1087 | 1087 | |
| 1088 | 1088 | rvu_dl->devlink_wq = create_workqueue("rvu_devlink_wq"); |
| 1089 | 1089 | if (!rvu_dl->devlink_wq) |
| 1090 | − goto err; | |
| 1090 | + return -ENOMEM; | |
| 1091 | 1091 | |
| 1092 | 1092 | INIT_WORK(&rvu_reporters->intr_work, rvu_npa_intr_work); |
| 1093 | 1093 | INIT_WORK(&rvu_reporters->err_work, rvu_npa_err_work); |
| @@ -1095,9 +1095,6 @@ static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl) · 1 unmodified line | ||
| 1095 | 1095 | INIT_WORK(&rvu_reporters->ras_work, rvu_npa_ras_work); |
| 1096 | 1096 | |
| 1097 | 1097 | return 0; |
| 1098 | −err: | |
| 1099 | − rvu_npa_health_reporters_destroy(rvu_dl); | |
| 1100 | − return -ENOMEM; | |
| 1101 | 1098 | } |
| 1102 | 1099 | |
| 1103 | 1100 | static int rvu_npa_health_reporters_create(struct rvu_devlink *rvu_dl) |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include "rvu_reg.h" |
| 13 | 13 | #include "rvu.h" |
| 14 | 14 | #include "npc.h" |
| 15 | +#include "mcs.h" | |
| 15 | 16 | #include "cgx.h" |
| 16 | 17 | #include "lmac_common.h" |
| 17 | 18 | #include "rvu_npc_hash.h" |
| @@ -4389,6 +4390,12 @@ static void nix_link_config(struct rvu *rvu, int blkaddr, · 4371 unmodified lines | ||
| 4389 | 4390 | SDP_HW_MAX_FRS << 16 | NIC_HW_MIN_FRS); |
| 4390 | 4391 | } |
| 4391 | 4392 | |
| 4393 | + /* Get MCS external bypass status for CN10K-B */ | |
| 4394 | + if (mcs_get_blkcnt() == 1) { | |
| 4395 | + /* Adjust for 2 credits when external bypass is disabled */ | |
| 4396 | + nix_hw->cc_mcs_cnt = is_mcs_bypass(0) ? 0 : 2; | |
| 4397 | + } | |
| 4398 | + | |
| 4392 | 4399 | /* Set credits for Tx links assuming max packet length allowed. |
| 4393 | 4400 | * This will be reconfigured based on MTU set for PF/VF. |
| 4394 | 4401 | */ |
| @@ -4412,6 +4419,7 @@ static void nix_link_config(struct rvu *rvu, int blkaddr, · 17 unmodified lines | ||
| 4412 | 4419 | tx_credits = (lmac_fifo_len - lmac_max_frs) / 16; |
| 4413 | 4420 | /* Enable credits and set credit pkt count to max allowed */ |
| 4414 | 4421 | cfg = (tx_credits << 12) | (0x1FF << 2) | BIT_ULL(1); |
| 4422 | + cfg |= FIELD_PREP(NIX_AF_LINKX_MCS_CNT_MASK, nix_hw->cc_mcs_cnt); | |
| 4415 | 4423 | |
| 4416 | 4424 | link = iter + slink; |
| 4417 | 4425 | nix_hw->tx_credits[link] = tx_credits; |
| @@ -5505,6 +5513,8 @@ int rvu_mbox_handler_nix_bandprof_free(struct rvu *rvu, · 1087 unmodified lines | ||
| 5505 | 5513 | |
| 5506 | 5514 | ipolicer = &nix_hw->ipolicer[layer]; |
| 5507 | 5515 | for (idx = 0; idx < req->prof_count[layer]; idx++) { |
| 5516 | + if (idx == MAX_BANDPROF_PER_PFFUNC) | |
| 5517 | + break; | |
| 5508 | 5518 | prof_idx = req->prof_idx[layer][idx]; |
| 5509 | 5519 | if (prof_idx >= ipolicer->band_prof.max || |
| 5510 | 5520 | ipolicer->pfvf_map[prof_idx] != pcifunc) |
| @@ -5518,8 +5528,6 @@ int rvu_mbox_handler_nix_bandprof_free(struct rvu *rvu, · 7 unmodified lines | ||
| 5518 | 5528 | ipolicer->pfvf_map[prof_idx] = 0x00; |
| 5519 | 5529 | ipolicer->match_id[prof_idx] = 0; |
| 5520 | 5530 | rvu_free_rsrc(&ipolicer->band_prof, prof_idx); |
| 5521 | − if (idx == MAX_BANDPROF_PER_PFFUNC) | |
| 5522 | − break; | |
| 5523 | 5531 | } |
| 5524 | 5532 | } |
| 5525 | 5533 | mutex_unlock(&rvu->rsrc_lock); |
| @@ -389,7 +389,13 @@ static u64 npc_get_default_entry_action(struct rvu *rvu, struct npc_mcam *mcam, · 388 unmodified lines | ||
| 389 | 389 | int bank, nixlf, index; |
| 390 | 390 | |
| 391 | 391 | /* get ucast entry rule entry index */ |
| 392 | − nix_get_nixlf(rvu, pf_func, &nixlf, NULL); | |
| 392 | + if (nix_get_nixlf(rvu, pf_func, &nixlf, NULL)) { | |
| 393 | + dev_err(rvu->dev, "%s: nixlf not attached to pcifunc:0x%x\n", | |
| 394 | + __func__, pf_func); | |
| 395 | + /* Action 0 is drop */ | |
| 396 | + return 0; | |
| 397 | + } | |
| 398 | + | |
| 393 | 399 | index = npc_get_nixlf_mcam_index(mcam, pf_func, nixlf, |
| 394 | 400 | NIXLF_UCAST_ENTRY); |
| 395 | 401 | bank = npc_get_bank(mcam, index); |
| @@ -31,8 +31,8 @@ static struct hw_reg_map txsch_reg_map[NIX_TXSCH_LVL_CNT] = { · 30 unmodified lines | ||
| 31 | 31 | {NIX_TXSCH_LVL_TL4, 3, 0xFFFF, {{0x0B00, 0x0B08}, {0x0B10, 0x0B18}, |
| 32 | 32 | {0x1200, 0x12E0} } }, |
| 33 | 33 | {NIX_TXSCH_LVL_TL3, 4, 0xFFFF, {{0x1000, 0x10E0}, {0x1600, 0x1608}, |
| 34 | − {0x1610, 0x1618}, {0x1700, 0x17B0} } }, | |
| 35 | − {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17B0} } }, | |
| 34 | + {0x1610, 0x1618}, {0x1700, 0x17C8} } }, | |
| 35 | + {NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x17C8} } }, | |
| 36 | 36 | {NIX_TXSCH_LVL_TL1, 1, 0xFFFF, {{0x0C00, 0x0D98} } }, |
| 37 | 37 | }; |
| 38 | 38 | |
| @@ -437,6 +437,7 @@ · 436 unmodified lines | ||
| 437 | 437 | |
| 438 | 438 | #define NIX_AF_LINKX_BASE_MASK GENMASK_ULL(11, 0) |
| 439 | 439 | #define NIX_AF_LINKX_RANGE_MASK GENMASK_ULL(19, 16) |
| 440 | +#define NIX_AF_LINKX_MCS_CNT_MASK GENMASK_ULL(33, 32) | |
| 440 | 441 | |
| 441 | 442 | /* SSO */ |
| 442 | 443 | #define SSO_AF_CONST (0x1000) |
| @@ -450,6 +450,9 @@ int cn10k_set_ipolicer_rate(struct otx2_nic *pfvf, u16 profile, · 449 unmodified lines | ||
| 450 | 450 | aq->prof.pebs_mantissa = 0; |
| 451 | 451 | aq->prof_mask.pebs_mantissa = 0xFF; |
| 452 | 452 | |
| 453 | + aq->prof.hl_en = 0; | |
| 454 | + aq->prof_mask.hl_en = 1; | |
| 455 | + | |
| 453 | 456 | /* Fill AQ info */ |
| 454 | 457 | aq->qidx = profile; |
| 455 | 458 | aq->ctype = NIX_AQ_CTYPE_BANDPROF; |
| @@ -1070,6 +1070,8 @@ int otx2_init_tc(struct otx2_nic *nic); · 1069 unmodified lines | ||
| 1070 | 1070 | void otx2_shutdown_tc(struct otx2_nic *nic); |
| 1071 | 1071 | int otx2_setup_tc(struct net_device *netdev, enum tc_setup_type type, |
| 1072 | 1072 | void *type_data); |
| 1073 | +void otx2_tc_apply_ingress_police_rules(struct otx2_nic *nic); | |
| 1074 | + | |
| 1073 | 1075 | /* CGX/RPM DMAC filters support */ |
| 1074 | 1076 | int otx2_dmacflt_get_max_cnt(struct otx2_nic *pf); |
| 1075 | 1077 | int otx2_dmacflt_add(struct otx2_nic *pf, const u8 *mac, u32 bit_pos); |
| @@ -334,9 +334,12 @@ static void otx2_get_pauseparam(struct net_device *netdev, · 333 unmodified lines | ||
| 334 | 334 | if (is_otx2_lbkvf(pfvf->pdev)) |
| 335 | 335 | return; |
| 336 | 336 | |
| 337 | + mutex_lock(&pfvf->mbox.lock); | |
| 337 | 338 | req = otx2_mbox_alloc_msg_cgx_cfg_pause_frm(&pfvf->mbox); |
| 338 | − if (!req) | |
| 339 | + if (!req) { | |
| 340 | + mutex_unlock(&pfvf->mbox.lock); | |
| 339 | 341 | return; |
| 342 | + } | |
| 340 | 343 | |
| 341 | 344 | if (!otx2_sync_mbox_msg(&pfvf->mbox)) { |
| 342 | 345 | rsp = (struct cgx_pause_frm_cfg *) |
| @@ -344,6 +347,7 @@ static void otx2_get_pauseparam(struct net_device *netdev, · 1 unmodified line | ||
| 344 | 347 | pause->rx_pause = rsp->rx_pause; |
| 345 | 348 | pause->tx_pause = rsp->tx_pause; |
| 346 | 349 | } |
| 350 | + mutex_unlock(&pfvf->mbox.lock); | |
| 347 | 351 | } |
| 348 | 352 | |
| 349 | 353 | static int otx2_set_pauseparam(struct net_device *netdev, |
| @@ -1088,6 +1088,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc) · 1087 unmodified lines | ||
| 1088 | 1088 | struct ethhdr *eth_hdr; |
| 1089 | 1089 | bool new = false; |
| 1090 | 1090 | int err = 0; |
| 1091 | + u64 vf_num; | |
| 1091 | 1092 | u32 ring; |
| 1092 | 1093 | |
| 1093 | 1094 | if (!flow_cfg->max_flows) { |
| @@ -1100,7 +1101,21 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc) · 6 unmodified lines | ||
| 1100 | 1101 | if (!(pfvf->flags & OTX2_FLAG_NTUPLE_SUPPORT)) |
| 1101 | 1102 | return -ENOMEM; |
| 1102 | 1103 | |
| 1103 | − if (ring >= pfvf->hw.rx_queues && fsp->ring_cookie != RX_CLS_FLOW_DISC) | |
| 1104 | + /* Number of queues on a VF can be greater or less than | |
| 1105 | + * the PF's queue. Hence no need to check for the | |
| 1106 | + * queue count. Hence no need to check queue count if PF | |
| 1107 | + * is installing for its VF. Below is the expected vf_num value | |
| 1108 | + * based on the ethtool commands. | |
| 1109 | + * | |
| 1110 | + * e.g. | |
| 1111 | + * 1. ethtool -U <netdev> ... action -1 ==> vf_num:255 | |
| 1112 | + * 2. ethtool -U <netdev> ... action <queue_num> ==> vf_num:0 | |
| 1113 | + * 3. ethtool -U <netdev> ... vf <vf_idx> queue <queue_num> ==> | |
| 1114 | + * vf_num:vf_idx+1 | |
| 1115 | + */ | |
| 1116 | + vf_num = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie); | |
| 1117 | + if (!is_otx2_vf(pfvf->pcifunc) && !vf_num && | |
| 1118 | + ring >= pfvf->hw.rx_queues && fsp->ring_cookie != RX_CLS_FLOW_DISC) | |
| 1104 | 1119 | return -EINVAL; |
| 1105 | 1120 | |
| 1106 | 1121 | if (fsp->location >= otx2_get_maxflows(flow_cfg)) |
| @@ -1182,6 +1197,9 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc) · 75 unmodified lines | ||
| 1182 | 1197 | flow_cfg->nr_flows++; |
| 1183 | 1198 | } |
| 1184 | 1199 | |
| 1200 | + if (flow->is_vf) | |
| 1201 | + netdev_info(pfvf->netdev, | |
| 1202 | + "Make sure that VF's queue number is within its queue limit\n"); | |
| 1185 | 1203 | return 0; |
| 1186 | 1204 | } |
| 1187 | 1205 | |
| @@ -566,7 +566,9 @@ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq) · 565 unmodified lines | ||
| 566 | 566 | otx2_write64(pf, RVU_PF_VFPF_MBOX_INTX(1), intr); |
| 567 | 567 | otx2_queue_work(mbox, pf->mbox_pfvf_wq, 64, vfs, intr, |
| 568 | 568 | TYPE_PFVF); |
| 569 | − vfs -= 64; | |
| 569 | + if (intr) | |
| 570 | + trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr); | |
| 571 | + vfs = 64; | |
| 570 | 572 | } |
| 571 | 573 | |
| 572 | 574 | intr = otx2_read64(pf, RVU_PF_VFPF_MBOX_INTX(0)); |
| @@ -574,7 +576,8 @@ static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq) · 1 unmodified line | ||
| 574 | 576 | |
| 575 | 577 | otx2_queue_work(mbox, pf->mbox_pfvf_wq, 0, vfs, intr, TYPE_PFVF); |
| 576 | 578 | |
| 577 | − trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr); | |
| 579 | + if (intr) | |
| 580 | + trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr); | |
| 578 | 581 | |
| 579 | 582 | return IRQ_HANDLED; |
| 580 | 583 | } |
| @@ -1685,6 +1688,14 @@ static void otx2_do_set_rx_mode(struct otx2_nic *pf) · 1104 unmodified lines | ||
| 1685 | 1688 | mutex_unlock(&pf->mbox.lock); |
| 1686 | 1689 | } |
| 1687 | 1690 | |
| 1691 | +static void otx2_set_irq_coalesce(struct otx2_nic *pfvf) | |
| 1692 | +{ | |
| 1693 | + int cint; | |
| 1694 | + | |
| 1695 | + for (cint = 0; cint < pfvf->hw.cint_cnt; cint++) | |
| 1696 | + otx2_config_irq_coalescing(pfvf, cint); | |
| 1697 | +} | |
| 1698 | + | |
| 1688 | 1699 | static void otx2_dim_work(struct work_struct *w) |
| 1689 | 1700 | { |
| 1690 | 1701 | struct dim_cq_moder cur_moder; |
| @@ -1700,6 +1711,7 @@ static void otx2_dim_work(struct work_struct *w) · 9 unmodified lines | ||
| 1700 | 1711 | CQ_TIMER_THRESH_MAX : cur_moder.usec; |
| 1701 | 1712 | pfvf->hw.cq_ecount_wait = (cur_moder.pkts > NAPI_POLL_WEIGHT) ? |
| 1702 | 1713 | NAPI_POLL_WEIGHT : cur_moder.pkts; |
| 1714 | + otx2_set_irq_coalesce(pfvf); | |
| 1703 | 1715 | dim->state = DIM_START_MEASURE; |
| 1704 | 1716 | } |
| 1705 | 1717 | |
| @@ -1870,6 +1882,8 @@ int otx2_open(struct net_device *netdev) · 164 unmodified lines | ||
| 1870 | 1882 | if (pf->flags & OTX2_FLAG_DMACFLTR_SUPPORT) |
| 1871 | 1883 | otx2_dmacflt_reinstall_flows(pf); |
| 1872 | 1884 | |
| 1885 | + otx2_tc_apply_ingress_police_rules(pf); | |
| 1886 | + | |
| 1873 | 1887 | err = otx2_rxtx_enable(pf, true); |
| 1874 | 1888 | /* If a mbox communication error happens at this point then interface |
| 1875 | 1889 | * will end up in a state such that it is in down state but hardware |
| @@ -1934,6 +1948,8 @@ int otx2_stop(struct net_device *netdev) · 58 unmodified lines | ||
| 1934 | 1948 | /* Clear RSS enable flag */ |
| 1935 | 1949 | rss = &pf->hw.rss_info; |
| 1936 | 1950 | rss->enable = false; |
| 1951 | + if (!netif_is_rxfh_configured(netdev)) | |
| 1952 | + kfree(rss->rss_ctx[DEFAULT_RSS_CONTEXT_GROUP]); | |
| 1937 | 1953 | |
| 1938 | 1954 | /* Cleanup Queue IRQ */ |
| 1939 | 1955 | vec = pci_irq_vector(pf->pdev, |
| @@ -47,6 +47,9 @@ struct otx2_tc_flow { · 46 unmodified lines | ||
| 47 | 47 | bool is_act_police; |
| 48 | 48 | u32 prio; |
| 49 | 49 | struct npc_install_flow_req req; |
| 50 | + u64 rate; | |
| 51 | + u32 burst; | |
| 52 | + bool is_pps; | |
| 50 | 53 | }; |
| 51 | 54 | |
| 52 | 55 | static void otx2_get_egress_burst_cfg(struct otx2_nic *nic, u32 burst, |
| @@ -284,21 +287,10 @@ static int otx2_tc_egress_matchall_delete(struct otx2_nic *nic, · 231 unmodified lines | ||
| 284 | 287 | return err; |
| 285 | 288 | } |
| 286 | 289 | |
| 287 | −static int otx2_tc_act_set_police(struct otx2_nic *nic, | |
| 288 | − struct otx2_tc_flow *node, | |
| 289 | − struct flow_cls_offload *f, | |
| 290 | − u64 rate, u32 burst, u32 mark, | |
| 291 | − struct npc_install_flow_req *req, bool pps) | |
| 290 | +static int otx2_tc_act_set_hw_police(struct otx2_nic *nic, | |
| 291 | + struct otx2_tc_flow *node) | |
| 292 | 292 | { |
| 293 | − struct netlink_ext_ack *extack = f->common.extack; | |
| 294 | − struct otx2_hw *hw = &nic->hw; | |
| 295 | − int rq_idx, rc; | |
| 296 | − | |
| 297 | − rq_idx = find_first_zero_bit(&nic->rq_bmap, hw->rx_queues); | |
| 298 | − if (rq_idx >= hw->rx_queues) { | |
| 299 | − NL_SET_ERR_MSG_MOD(extack, "Police action rules exceeded"); | |
| 300 | − return -EINVAL; | |
| 301 | − } | |
| 293 | + int rc; | |
| 302 | 294 | |
| 303 | 295 | mutex_lock(&nic->mbox.lock); |
| 304 | 296 | |
| @@ -308,23 +300,17 @@ static int otx2_tc_act_set_police(struct otx2_nic *nic, · 3 unmodified lines | ||
| 308 | 300 | return rc; |
| 309 | 301 | } |
| 310 | 302 | |
| 311 | − rc = cn10k_set_ipolicer_rate(nic, node->leaf_profile, burst, rate, pps); | |
| 303 | + rc = cn10k_set_ipolicer_rate(nic, node->leaf_profile, | |
| 304 | + node->burst, node->rate, node->is_pps); | |
| 312 | 305 | if (rc) |
| 313 | 306 | goto free_leaf; |
| 314 | 307 | |
| 315 | − rc = cn10k_map_unmap_rq_policer(nic, rq_idx, node->leaf_profile, true); | |
| 308 | + rc = cn10k_map_unmap_rq_policer(nic, node->rq, node->leaf_profile, true); | |
| 316 | 309 | if (rc) |
| 317 | 310 | goto free_leaf; |
| 318 | 311 | |
| 319 | 312 | mutex_unlock(&nic->mbox.lock); |
| 320 | 313 | |
| 321 | − req->match_id = mark & 0xFFFFULL; | |
| 322 | − req->index = rq_idx; | |
| 323 | − req->op = NIX_RX_ACTIONOP_UCAST; | |
| 324 | − set_bit(rq_idx, &nic->rq_bmap); | |
| 325 | − node->is_act_police = true; | |
| 326 | − node->rq = rq_idx; | |
| 327 | − | |
| 328 | 314 | return 0; |
| 329 | 315 | |
| 330 | 316 | free_leaf: |
| @@ -336,6 +322,39 @@ free_leaf: · 5 unmodified lines | ||
| 336 | 322 | return rc; |
| 337 | 323 | } |
| 338 | 324 | |
| 325 | +static int otx2_tc_act_set_police(struct otx2_nic *nic, | |
| 326 | + struct otx2_tc_flow *node, | |
| 327 | + struct flow_cls_offload *f, | |
| 328 | + u64 rate, u32 burst, u32 mark, | |
| 329 | + struct npc_install_flow_req *req, bool pps) | |
| 330 | +{ | |
| 331 | + struct netlink_ext_ack *extack = f->common.extack; | |
| 332 | + struct otx2_hw *hw = &nic->hw; | |
| 333 | + int rq_idx, rc; | |
| 334 | + | |
| 335 | + rq_idx = find_first_zero_bit(&nic->rq_bmap, hw->rx_queues); | |
| 336 | + if (rq_idx >= hw->rx_queues) { | |
| 337 | + NL_SET_ERR_MSG_MOD(extack, "Police action rules exceeded"); | |
| 338 | + return -EINVAL; | |
| 339 | + } | |
| 340 | + | |
| 341 | + req->match_id = mark & 0xFFFFULL; | |
| 342 | + req->index = rq_idx; | |
| 343 | + req->op = NIX_RX_ACTIONOP_UCAST; | |
| 344 | + | |
| 345 | + node->is_act_police = true; | |
| 346 | + node->rq = rq_idx; | |
| 347 | + node->burst = burst; | |
| 348 | + node->rate = rate; | |
| 349 | + node->is_pps = pps; | |
| 350 | + | |
| 351 | + rc = otx2_tc_act_set_hw_police(nic, node); | |
| 352 | + if (!rc) | |
| 353 | + set_bit(rq_idx, &nic->rq_bmap); | |
| 354 | + | |
| 355 | + return rc; | |
| 356 | +} | |
| 357 | + | |
| 339 | 358 | static int otx2_tc_parse_actions(struct otx2_nic *nic, |
| 340 | 359 | struct flow_action *flow_action, |
| 341 | 360 | struct npc_install_flow_req *req, |
| @@ -1044,6 +1063,11 @@ static int otx2_tc_del_flow(struct otx2_nic *nic, · 702 unmodified lines | ||
| 1044 | 1063 | } |
| 1045 | 1064 | |
| 1046 | 1065 | if (flow_node->is_act_police) { |
| 1066 | + __clear_bit(flow_node->rq, &nic->rq_bmap); | |
| 1067 | + | |
| 1068 | + if (nic->flags & OTX2_FLAG_INTF_DOWN) | |
| 1069 | + goto free_mcam_flow; | |
| 1070 | + | |
| 1047 | 1071 | mutex_lock(&nic->mbox.lock); |
| 1048 | 1072 | |
| 1049 | 1073 | err = cn10k_map_unmap_rq_policer(nic, flow_node->rq, |
| @@ -1059,11 +1083,10 @@ static int otx2_tc_del_flow(struct otx2_nic *nic, · 9 unmodified lines | ||
| 1059 | 1083 | "Unable to free leaf bandwidth profile(%d)\n", |
| 1060 | 1084 | flow_node->leaf_profile); |
| 1061 | 1085 | |
| 1062 | − __clear_bit(flow_node->rq, &nic->rq_bmap); | |
| 1063 | − | |
| 1064 | 1086 | mutex_unlock(&nic->mbox.lock); |
| 1065 | 1087 | } |
| 1066 | 1088 | |
| 1089 | +free_mcam_flow: | |
| 1067 | 1090 | otx2_del_mcam_flow_entry(nic, flow_node->entry, NULL); |
| 1068 | 1091 | otx2_tc_update_mcam_table(nic, flow_cfg, flow_node, false); |
| 1069 | 1092 | kfree_rcu(flow_node, rcu); |
| @@ -1083,6 +1106,11 @@ static int otx2_tc_add_flow(struct otx2_nic *nic, · 13 unmodified lines | ||
| 1083 | 1106 | if (!(nic->flags & OTX2_FLAG_TC_FLOWER_SUPPORT)) |
| 1084 | 1107 | return -ENOMEM; |
| 1085 | 1108 | |
| 1109 | + if (nic->flags & OTX2_FLAG_INTF_DOWN) { | |
| 1110 | + NL_SET_ERR_MSG_MOD(extack, "Interface not initialized"); | |
| 1111 | + return -EINVAL; | |
| 1112 | + } | |
| 1113 | + | |
| 1086 | 1114 | if (flow_cfg->nr_flows == flow_cfg->max_flows) { |
| 1087 | 1115 | NL_SET_ERR_MSG_MOD(extack, |
| 1088 | 1116 | "Free MCAM entry not available to add the flow"); |
| @@ -1442,3 +1470,45 @@ void otx2_shutdown_tc(struct otx2_nic *nic) · 353 unmodified lines | ||
| 1442 | 1470 | otx2_destroy_tc_flow_list(nic); |
| 1443 | 1471 | } |
| 1444 | 1472 | EXPORT_SYMBOL(otx2_shutdown_tc); |
| 1473 | + | |
| 1474 | +static void otx2_tc_config_ingress_rule(struct otx2_nic *nic, | |
| 1475 | + struct otx2_tc_flow *node) | |
| 1476 | +{ | |
| 1477 | + struct npc_install_flow_req *req; | |
| 1478 | + | |
| 1479 | + if (otx2_tc_act_set_hw_police(nic, node)) | |
| 1480 | + return; | |
| 1481 | + | |
| 1482 | + mutex_lock(&nic->mbox.lock); | |
| 1483 | + | |
| 1484 | + req = otx2_mbox_alloc_msg_npc_install_flow(&nic->mbox); | |
| 1485 | + if (!req) | |
| 1486 | + goto err; | |
| 1487 | + | |
| 1488 | + memcpy(req, &node->req, sizeof(struct npc_install_flow_req)); | |
| 1489 | + | |
| 1490 | + if (otx2_sync_mbox_msg(&nic->mbox)) | |
| 1491 | + netdev_err(nic->netdev, | |
| 1492 | + "Failed to install MCAM flow entry for ingress rule"); | |
| 1493 | +err: | |
| 1494 | + mutex_unlock(&nic->mbox.lock); | |
| 1495 | +} | |
| 1496 | + | |
| 1497 | +void otx2_tc_apply_ingress_police_rules(struct otx2_nic *nic) | |
| 1498 | +{ | |
| 1499 | + struct otx2_flow_config *flow_cfg = nic->flow_cfg; | |
| 1500 | + struct otx2_tc_flow *node; | |
| 1501 | + | |
| 1502 | + /* If any ingress policer rules exist for the interface then | |
| 1503 | + * apply those rules. Ingress policer rules depend on bandwidth | |
| 1504 | + * profiles linked to the receive queues. Since no receive queues | |
| 1505 | + * exist when interface is down, ingress policer rules are stored | |
| 1506 | + * and configured in hardware after all receive queues are allocated | |
| 1507 | + * in otx2_open. | |
| 1508 | + */ | |
| 1509 | + list_for_each_entry(node, &flow_cfg->flow_list_tc, list) { | |
| 1510 | + if (node->is_act_police) | |
| 1511 | + otx2_tc_config_ingress_rule(nic, node); | |
| 1512 | + } | |
| 1513 | +} | |
| 1514 | +EXPORT_SYMBOL(otx2_tc_apply_ingress_police_rules); | |
| @@ -512,11 +512,18 @@ static void otx2_adjust_adaptive_coalese(struct otx2_nic *pfvf, struct otx2_cq_p · 511 unmodified lines | ||
| 512 | 512 | { |
| 513 | 513 | struct dim_sample dim_sample; |
| 514 | 514 | u64 rx_frames, rx_bytes; |
| 515 | + u64 tx_frames, tx_bytes; | |
| 515 | 516 | |
| 516 | 517 | rx_frames = OTX2_GET_RX_STATS(RX_BCAST) + OTX2_GET_RX_STATS(RX_MCAST) + |
| 517 | 518 | OTX2_GET_RX_STATS(RX_UCAST); |
| 518 | 519 | rx_bytes = OTX2_GET_RX_STATS(RX_OCTS); |
| 519 | − dim_update_sample(pfvf->napi_events, rx_frames, rx_bytes, &dim_sample); | |
| 520 | + tx_bytes = OTX2_GET_TX_STATS(TX_OCTS); | |
| 521 | + tx_frames = OTX2_GET_TX_STATS(TX_UCAST); | |
| 522 | + | |
| 523 | + dim_update_sample(pfvf->napi_events, | |
| 524 | + rx_frames + tx_frames, | |
| 525 | + rx_bytes + tx_bytes, | |
| 526 | + &dim_sample); | |
| 520 | 527 | net_dim(&cq_poll->dim, dim_sample); |
| 521 | 528 | } |
| 522 | 529 | |
| @@ -558,16 +565,9 @@ int otx2_napi_handler(struct napi_struct *napi, int budget) · 35 unmodified lines | ||
| 558 | 565 | if (pfvf->flags & OTX2_FLAG_INTF_DOWN) |
| 559 | 566 | return workdone; |
| 560 | 567 | |
| 561 | − /* Check for adaptive interrupt coalesce */ | |
| 562 | − if (workdone != 0 && | |
| 563 | − ((pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED) == | |
| 564 | − OTX2_FLAG_ADPTV_INT_COAL_ENABLED)) { | |
| 565 | − /* Adjust irq coalese using net_dim */ | |
| 568 | + /* Adjust irq coalese using net_dim */ | |
| 569 | + if (pfvf->flags & OTX2_FLAG_ADPTV_INT_COAL_ENABLED) | |
| 566 | 570 | otx2_adjust_adaptive_coalese(pfvf, cq_poll); |
| 567 | − /* Update irq coalescing */ | |
| 568 | − for (i = 0; i < pfvf->hw.cint_cnt; i++) | |
| 569 | − otx2_config_irq_coalescing(pfvf, i); | |
| 570 | − } | |
| 571 | 571 | |
| 572 | 572 | if (unlikely(!filled_cnt)) { |
| 573 | 573 | struct refill_work *work; |
| @@ -177,6 +177,8 @@ static void mlx5e_ptpsq_mark_ts_cqes_undelivered(struct mlx5e_ptpsq *ptpsq, · 176 unmodified lines | ||
| 177 | 177 | |
| 178 | 178 | static void mlx5e_ptp_handle_ts_cqe(struct mlx5e_ptpsq *ptpsq, |
| 179 | 179 | struct mlx5_cqe64 *cqe, |
| 180 | + u8 *md_buff, | |
| 181 | + u8 *md_buff_sz, | |
| 180 | 182 | int budget) |
| 181 | 183 | { |
| 182 | 184 | struct mlx5e_ptp_port_ts_cqe_list *pending_cqe_list = ptpsq->ts_cqe_pending_list; |
| @@ -211,19 +213,24 @@ static void mlx5e_ptp_handle_ts_cqe(struct mlx5e_ptpsq *ptpsq, · 28 unmodified lines | ||
| 211 | 213 | mlx5e_ptpsq_mark_ts_cqes_undelivered(ptpsq, hwtstamp); |
| 212 | 214 | out: |
| 213 | 215 | napi_consume_skb(skb, budget); |
| 214 | − mlx5e_ptp_metadata_fifo_push(&ptpsq->metadata_freelist, metadata_id); | |
| 216 | + md_buff[*md_buff_sz++] = metadata_id; | |
| 215 | 217 | if (unlikely(mlx5e_ptp_metadata_map_unhealthy(&ptpsq->metadata_map)) && |
| 216 | 218 | !test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) |
| 217 | 219 | queue_work(ptpsq->txqsq.priv->wq, &ptpsq->report_unhealthy_work); |
| 218 | 220 | } |
| 219 | 221 | |
| 220 | −static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int budget) | |
| 222 | +static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int napi_budget) | |
| 221 | 223 | { |
| 222 | 224 | struct mlx5e_ptpsq *ptpsq = container_of(cq, struct mlx5e_ptpsq, ts_cq); |
| 223 | − struct mlx5_cqwq *cqwq = &cq->wq; | |
| 225 | + int budget = min(napi_budget, MLX5E_TX_CQ_POLL_BUDGET); | |
| 226 | + u8 metadata_buff[MLX5E_TX_CQ_POLL_BUDGET]; | |
| 227 | + u8 metadata_buff_sz = 0; | |
| 228 | + struct mlx5_cqwq *cqwq; | |
| 224 | 229 | struct mlx5_cqe64 *cqe; |
| 225 | 230 | int work_done = 0; |
| 226 | 231 | |
| 232 | + cqwq = &cq->wq; | |
| 233 | + | |
| 227 | 234 | if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &ptpsq->txqsq.state))) |
| 228 | 235 | return false; |
| 229 | 236 | |
| @@ -234,7 +241,8 @@ static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int budget) · 4 unmodified lines | ||
| 234 | 241 | do { |
| 235 | 242 | mlx5_cqwq_pop(cqwq); |
| 236 | 243 | |
| 237 | − mlx5e_ptp_handle_ts_cqe(ptpsq, cqe, budget); | |
| 244 | + mlx5e_ptp_handle_ts_cqe(ptpsq, cqe, | |
| 245 | + metadata_buff, &metadata_buff_sz, napi_budget); | |
| 238 | 246 | } while ((++work_done < budget) && (cqe = mlx5_cqwq_get_cqe(cqwq))); |
| 239 | 247 | |
| 240 | 248 | mlx5_cqwq_update_db_record(cqwq); |
| @@ -242,6 +250,10 @@ static bool mlx5e_ptp_poll_ts_cq(struct mlx5e_cq *cq, int budget) · 1 unmodified line | ||
| 242 | 250 | /* ensure cq space is freed before enabling more cqes */ |
| 243 | 251 | wmb(); |
| 244 | 252 | |
| 253 | + while (metadata_buff_sz > 0) | |
| 254 | + mlx5e_ptp_metadata_fifo_push(&ptpsq->metadata_freelist, | |
| 255 | + metadata_buff[--metadata_buff_sz]); | |
| 256 | + | |
| 245 | 257 | mlx5e_txqsq_wake(&ptpsq->txqsq); |
| 246 | 258 | |
| 247 | 259 | return work_done == budget; |
| @@ -492,11 +492,11 @@ static int mlx5e_rx_reporter_dump(struct devlink_health_reporter *reporter, · 491 unmodified lines | ||
| 492 | 492 | |
| 493 | 493 | void mlx5e_reporter_rx_timeout(struct mlx5e_rq *rq) |
| 494 | 494 | { |
| 495 | − char icosq_str[MLX5E_REPORTER_PER_Q_MAX_LEN] = {}; | |
| 496 | 495 | char err_str[MLX5E_REPORTER_PER_Q_MAX_LEN]; |
| 497 | 496 | struct mlx5e_icosq *icosq = rq->icosq; |
| 498 | 497 | struct mlx5e_priv *priv = rq->priv; |
| 499 | 498 | struct mlx5e_err_ctx err_ctx = {}; |
| 499 | + char icosq_str[32] = {}; | |
| 500 | 500 | |
| 501 | 501 | err_ctx.ctx = rq; |
| 502 | 502 | err_ctx.recover = mlx5e_rx_reporter_timeout_recover; |
| @@ -505,7 +505,7 @@ void mlx5e_reporter_rx_timeout(struct mlx5e_rq *rq) · 2 unmodified lines | ||
| 505 | 505 | if (icosq) |
| 506 | 506 | snprintf(icosq_str, sizeof(icosq_str), "ICOSQ: 0x%x, ", icosq->sqn); |
| 507 | 507 | snprintf(err_str, sizeof(err_str), |
| 508 | − "RX timeout on channel: %d, %sRQ: 0x%x, CQ: 0x%x", | |
| 508 | + "RX timeout on channel: %d, %s RQ: 0x%x, CQ: 0x%x", | |
| 509 | 509 | rq->ix, icosq_str, rq->rqn, rq->cq.mcq.cqn); |
| 510 | 510 | |
| 511 | 511 | mlx5e_health_report(priv, priv->rx_reporter, err_str, &err_ctx); |
| @@ -300,9 +300,6 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, · 299 unmodified lines | ||
| 300 | 300 | if (err) |
| 301 | 301 | goto destroy_neigh_entry; |
| 302 | 302 | |
| 303 | − e->encap_size = ipv4_encap_size; | |
| 304 | − e->encap_header = encap_header; | |
| 305 | − | |
| 306 | 303 | if (!(nud_state & NUD_VALID)) { |
| 307 | 304 | neigh_event_send(attr.n, NULL); |
| 308 | 305 | /* the encap entry will be made valid on neigh update event |
| @@ -322,6 +319,8 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, · 13 unmodified lines | ||
| 322 | 319 | goto destroy_neigh_entry; |
| 323 | 320 | } |
| 324 | 321 | |
| 322 | + e->encap_size = ipv4_encap_size; | |
| 323 | + e->encap_header = encap_header; | |
| 325 | 324 | e->flags |= MLX5_ENCAP_ENTRY_VALID; |
| 326 | 325 | mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); |
| 327 | 326 | mlx5e_route_lookup_ipv4_put(&attr); |
| @@ -404,16 +403,12 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, · 76 unmodified lines | ||
| 404 | 403 | if (err) |
| 405 | 404 | goto free_encap; |
| 406 | 405 | |
| 407 | − e->encap_size = ipv4_encap_size; | |
| 408 | − kfree(e->encap_header); | |
| 409 | − e->encap_header = encap_header; | |
| 410 | − | |
| 411 | 406 | if (!(nud_state & NUD_VALID)) { |
| 412 | 407 | neigh_event_send(attr.n, NULL); |
| 413 | 408 | /* the encap entry will be made valid on neigh update event |
| 414 | 409 | * and not used before that. |
| 415 | 410 | */ |
| 416 | − goto release_neigh; | |
| 411 | + goto free_encap; | |
| 417 | 412 | } |
| 418 | 413 | |
| 419 | 414 | memset(&reformat_params, 0, sizeof(reformat_params)); |
| @@ -427,6 +422,10 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, · 7 unmodified lines | ||
| 427 | 422 | goto free_encap; |
| 428 | 423 | } |
| 429 | 424 | |
| 425 | + e->encap_size = ipv4_encap_size; | |
| 426 | + kfree(e->encap_header); | |
| 427 | + e->encap_header = encap_header; | |
| 428 | + | |
| 430 | 429 | e->flags |= MLX5_ENCAP_ENTRY_VALID; |
| 431 | 430 | mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); |
| 432 | 431 | mlx5e_route_lookup_ipv4_put(&attr); |
| @@ -568,9 +567,6 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv, · 135 unmodified lines | ||
| 568 | 567 | if (err) |
| 569 | 568 | goto destroy_neigh_entry; |
| 570 | 569 | |
| 571 | − e->encap_size = ipv6_encap_size; | |
| 572 | − e->encap_header = encap_header; | |
| 573 | − | |
| 574 | 570 | if (!(nud_state & NUD_VALID)) { |
| 575 | 571 | neigh_event_send(attr.n, NULL); |
| 576 | 572 | /* the encap entry will be made valid on neigh update event |
| @@ -590,6 +586,8 @@ int mlx5e_tc_tun_create_header_ipv6(struct mlx5e_priv *priv, · 13 unmodified lines | ||
| 590 | 586 | goto destroy_neigh_entry; |
| 591 | 587 | } |
| 592 | 588 | |
| 589 | + e->encap_size = ipv6_encap_size; | |
| 590 | + e->encap_header = encap_header; | |
| 593 | 591 | e->flags |= MLX5_ENCAP_ENTRY_VALID; |
| 594 | 592 | mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); |
| 595 | 593 | mlx5e_route_lookup_ipv6_put(&attr); |
| @@ -671,16 +669,12 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv, · 75 unmodified lines | ||
| 671 | 669 | if (err) |
| 672 | 670 | goto free_encap; |
| 673 | 671 | |
| 674 | − e->encap_size = ipv6_encap_size; | |
| 675 | − kfree(e->encap_header); | |
| 676 | − e->encap_header = encap_header; | |
| 677 | − | |
| 678 | 672 | if (!(nud_state & NUD_VALID)) { |
| 679 | 673 | neigh_event_send(attr.n, NULL); |
| 680 | 674 | /* the encap entry will be made valid on neigh update event |
| 681 | 675 | * and not used before that. |
| 682 | 676 | */ |
| 683 | − goto release_neigh; | |
| 677 | + goto free_encap; | |
| 684 | 678 | } |
| 685 | 679 | |
| 686 | 680 | memset(&reformat_params, 0, sizeof(reformat_params)); |
| @@ -694,6 +688,10 @@ int mlx5e_tc_tun_update_header_ipv6(struct mlx5e_priv *priv, · 7 unmodified lines | ||
| 694 | 688 | goto free_encap; |
| 695 | 689 | } |
| 696 | 690 | |
| 691 | + e->encap_size = ipv6_encap_size; | |
| 692 | + kfree(e->encap_header); | |
| 693 | + e->encap_header = encap_header; | |
| 694 | + | |
| 697 | 695 | e->flags |= MLX5_ENCAP_ENTRY_VALID; |
| 698 | 696 | mlx5e_rep_queue_neigh_stats_work(netdev_priv(attr.out_dev)); |
| 699 | 697 | mlx5e_route_lookup_ipv6_put(&attr); |
| @@ -43,12 +43,17 @@ void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv, · 42 unmodified lines | ||
| 43 | 43 | struct ethtool_drvinfo *drvinfo) |
| 44 | 44 | { |
| 45 | 45 | struct mlx5_core_dev *mdev = priv->mdev; |
| 46 | + int count; | |
| 46 | 47 | |
| 47 | 48 | strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver)); |
| 48 | − snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | |
| 49 | − "%d.%d.%04d (%.16s)", | |
| 50 | − fw_rev_maj(mdev), fw_rev_min(mdev), fw_rev_sub(mdev), | |
| 51 | − mdev->board_id); | |
| 49 | + count = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | |
| 50 | + "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), | |
| 51 | + fw_rev_min(mdev), fw_rev_sub(mdev), mdev->board_id); | |
| 52 | + if (count == sizeof(drvinfo->fw_version)) | |
| 53 | + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | |
| 54 | + "%d.%d.%04d", fw_rev_maj(mdev), | |
| 55 | + fw_rev_min(mdev), fw_rev_sub(mdev)); | |
| 56 | + | |
| 52 | 57 | strscpy(drvinfo->bus_info, dev_name(mdev->device), |
| 53 | 58 | sizeof(drvinfo->bus_info)); |
| 54 | 59 | } |
| @@ -71,13 +71,17 @@ static void mlx5e_rep_get_drvinfo(struct net_device *dev, · 70 unmodified lines | ||
| 71 | 71 | { |
| 72 | 72 | struct mlx5e_priv *priv = netdev_priv(dev); |
| 73 | 73 | struct mlx5_core_dev *mdev = priv->mdev; |
| 74 | + int count; | |
| 74 | 75 | |
| 75 | 76 | strscpy(drvinfo->driver, mlx5e_rep_driver_name, |
| 76 | 77 | sizeof(drvinfo->driver)); |
| 77 | − snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | |
| 78 | − "%d.%d.%04d (%.16s)", | |
| 79 | − fw_rev_maj(mdev), fw_rev_min(mdev), | |
| 80 | − fw_rev_sub(mdev), mdev->board_id); | |
| 78 | + count = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | |
| 79 | + "%d.%d.%04d (%.16s)", fw_rev_maj(mdev), | |
| 80 | + fw_rev_min(mdev), fw_rev_sub(mdev), mdev->board_id); | |
| 81 | + if (count == sizeof(drvinfo->fw_version)) | |
| 82 | + snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | |
| 83 | + "%d.%d.%04d", fw_rev_maj(mdev), | |
| 84 | + fw_rev_min(mdev), fw_rev_sub(mdev)); | |
| 81 | 85 | } |
| 82 | 86 | |
| 83 | 87 | static const struct counter_desc sw_rep_stats_desc[] = { |
| @@ -3147,7 +3147,7 @@ static struct mlx5_fields fields[] = { · 3146 unmodified lines | ||
| 3147 | 3147 | OFFLOAD(DIPV6_31_0, 32, U32_MAX, ip6.daddr.s6_addr32[3], 0, |
| 3148 | 3148 | dst_ipv4_dst_ipv6.ipv6_layout.ipv6[12]), |
| 3149 | 3149 | OFFLOAD(IPV6_HOPLIMIT, 8, U8_MAX, ip6.hop_limit, 0, ttl_hoplimit), |
| 3150 | − OFFLOAD(IP_DSCP, 16, 0xc00f, ip6, 0, ip_dscp), | |
| 3150 | + OFFLOAD(IP_DSCP, 16, 0x0fc0, ip6, 0, ip_dscp), | |
| 3151 | 3151 | |
| 3152 | 3152 | OFFLOAD(TCP_SPORT, 16, U16_MAX, tcp.source, 0, tcp_sport), |
| 3153 | 3153 | OFFLOAD(TCP_DPORT, 16, U16_MAX, tcp.dest, 0, tcp_dport), |
| @@ -3158,21 +3158,31 @@ static struct mlx5_fields fields[] = { · 4 unmodified lines | ||
| 3158 | 3158 | OFFLOAD(UDP_DPORT, 16, U16_MAX, udp.dest, 0, udp_dport), |
| 3159 | 3159 | }; |
| 3160 | 3160 | |
| 3161 | −static unsigned long mask_to_le(unsigned long mask, int size) | |
| 3161 | +static u32 mask_field_get(void *mask, struct mlx5_fields *f) | |
| 3162 | 3162 | { |
| 3163 | − __be32 mask_be32; | |
| 3164 | − __be16 mask_be16; | |
| 3165 | − | |
| 3166 | − if (size == 32) { | |
| 3167 | − mask_be32 = (__force __be32)(mask); | |
| 3168 | − mask = (__force unsigned long)cpu_to_le32(be32_to_cpu(mask_be32)); | |
| 3169 | − } else if (size == 16) { | |
| 3170 | − mask_be32 = (__force __be32)(mask); | |
| 3171 | − mask_be16 = *(__be16 *)&mask_be32; | |
| 3172 | − mask = (__force unsigned long)cpu_to_le16(be16_to_cpu(mask_be16)); | |
| 3163 | + switch (f->field_bsize) { | |
| 3164 | + case 32: | |
| 3165 | + return be32_to_cpu(*(__be32 *)mask) & f->field_mask; | |
| 3166 | + case 16: | |
| 3167 | + return be16_to_cpu(*(__be16 *)mask) & (u16)f->field_mask; | |
| 3168 | + default: | |
| 3169 | + return *(u8 *)mask & (u8)f->field_mask; | |
| 3173 | 3170 | } |
| 3171 | +} | |
| 3174 | 3172 | |
| 3175 | − return mask; | |
| 3173 | +static void mask_field_clear(void *mask, struct mlx5_fields *f) | |
| 3174 | +{ | |
| 3175 | + switch (f->field_bsize) { | |
| 3176 | + case 32: | |
| 3177 | + *(__be32 *)mask &= ~cpu_to_be32(f->field_mask); | |
| 3178 | + break; | |
| 3179 | + case 16: | |
| 3180 | + *(__be16 *)mask &= ~cpu_to_be16((u16)f->field_mask); | |
| 3181 | + break; | |
| 3182 | + default: | |
| 3183 | + *(u8 *)mask &= ~(u8)f->field_mask; | |
| 3184 | + break; | |
| 3185 | + } | |
| 3176 | 3186 | } |
| 3177 | 3187 | |
| 3178 | 3188 | static int offload_pedit_fields(struct mlx5e_priv *priv, |
| @@ -3184,11 +3194,12 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, · 5 unmodified lines | ||
| 3184 | 3194 | struct pedit_headers *set_masks, *add_masks, *set_vals, *add_vals; |
| 3185 | 3195 | struct pedit_headers_action *hdrs = parse_attr->hdrs; |
| 3186 | 3196 | void *headers_c, *headers_v, *action, *vals_p; |
| 3187 | − u32 *s_masks_p, *a_masks_p, s_mask, a_mask; | |
| 3188 | 3197 | struct mlx5e_tc_mod_hdr_acts *mod_acts; |
| 3189 | − unsigned long mask, field_mask; | |
| 3198 | + void *s_masks_p, *a_masks_p; | |
| 3190 | 3199 | int i, first, last, next_z; |
| 3191 | 3200 | struct mlx5_fields *f; |
| 3201 | + unsigned long mask; | |
| 3202 | + u32 s_mask, a_mask; | |
| 3192 | 3203 | u8 cmd; |
| 3193 | 3204 | |
| 3194 | 3205 | mod_acts = &parse_attr->mod_hdr_acts; |
| @@ -3204,15 +3215,11 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, · 9 unmodified lines | ||
| 3204 | 3215 | bool skip; |
| 3205 | 3216 | |
| 3206 | 3217 | f = &fields[i]; |
| 3207 | − /* avoid seeing bits set from previous iterations */ | |
| 3208 | − s_mask = 0; | |
| 3209 | − a_mask = 0; | |
| 3210 | − | |
| 3211 | 3218 | s_masks_p = (void *)set_masks + f->offset; |
| 3212 | 3219 | a_masks_p = (void *)add_masks + f->offset; |
| 3213 | 3220 | |
| 3214 | − s_mask = *s_masks_p & f->field_mask; | |
| 3215 | − a_mask = *a_masks_p & f->field_mask; | |
| 3221 | + s_mask = mask_field_get(s_masks_p, f); | |
| 3222 | + a_mask = mask_field_get(a_masks_p, f); | |
| 3216 | 3223 | |
| 3217 | 3224 | if (!s_mask && !a_mask) /* nothing to offload here */ |
| 3218 | 3225 | continue; |
| @@ -3239,22 +3246,20 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, · 20 unmodified lines | ||
| 3239 | 3246 | match_mask, f->field_bsize)) |
| 3240 | 3247 | skip = true; |
| 3241 | 3248 | /* clear to denote we consumed this field */ |
| 3242 | − *s_masks_p &= ~f->field_mask; | |
| 3249 | + mask_field_clear(s_masks_p, f); | |
| 3243 | 3250 | } else { |
| 3244 | 3251 | cmd = MLX5_ACTION_TYPE_ADD; |
| 3245 | 3252 | mask = a_mask; |
| 3246 | 3253 | vals_p = (void *)add_vals + f->offset; |
| 3247 | 3254 | /* add 0 is no change */ |
| 3248 | − if ((*(u32 *)vals_p & f->field_mask) == 0) | |
| 3255 | + if (!mask_field_get(vals_p, f)) | |
| 3249 | 3256 | skip = true; |
| 3250 | 3257 | /* clear to denote we consumed this field */ |
| 3251 | − *a_masks_p &= ~f->field_mask; | |
| 3258 | + mask_field_clear(a_masks_p, f); | |
| 3252 | 3259 | } |
| 3253 | 3260 | if (skip) |
| 3254 | 3261 | continue; |
| 3255 | 3262 | |
| 3256 | − mask = mask_to_le(mask, f->field_bsize); | |
| 3257 | − | |
| 3258 | 3263 | first = find_first_bit(&mask, f->field_bsize); |
| 3259 | 3264 | next_z = find_next_zero_bit(&mask, f->field_bsize, first); |
| 3260 | 3265 | last = find_last_bit(&mask, f->field_bsize); |
| @@ -3281,10 +3286,9 @@ static int offload_pedit_fields(struct mlx5e_priv *priv, · 20 unmodified lines | ||
| 3281 | 3286 | MLX5_SET(set_action_in, action, field, f->field); |
| 3282 | 3287 | |
| 3283 | 3288 | if (cmd == MLX5_ACTION_TYPE_SET) { |
| 3289 | + unsigned long field_mask = f->field_mask; | |
| 3284 | 3290 | int start; |
| 3285 | 3291 | |
| 3286 | − field_mask = mask_to_le(f->field_mask, f->field_bsize); | |
| 3287 | − | |
| 3288 | 3292 | /* if field is bit sized it can start not from first bit */ |
| 3289 | 3293 | start = find_first_bit(&field_mask, f->field_bsize); |
| 3290 | 3294 | |
| @@ -399,9 +399,9 @@ mlx5e_txwqe_complete(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 398 unmodified lines | ||
| 399 | 399 | u8 metadata_index = be32_to_cpu(eseg->flow_table_metadata); |
| 400 | 400 | |
| 401 | 401 | mlx5e_skb_cb_hwtstamp_init(skb); |
| 402 | − mlx5e_ptpsq_track_metadata(sq->ptpsq, metadata_index); | |
| 403 | 402 | mlx5e_ptp_metadata_map_put(&sq->ptpsq->metadata_map, skb, |
| 404 | 403 | metadata_index); |
| 404 | + mlx5e_ptpsq_track_metadata(sq->ptpsq, metadata_index); | |
| 405 | 405 | if (!netif_tx_queue_stopped(sq->txq) && |
| 406 | 406 | mlx5e_ptpsq_metadata_freelist_empty(sq->ptpsq)) { |
| 407 | 407 | netif_tx_stop_queue(sq->txq); |
| @@ -494,10 +494,10 @@ mlx5e_sq_xmit_wqe(struct mlx5e_txqsq *sq, struct sk_buff *skb, · 86 unmodified lines | ||
| 494 | 494 | |
| 495 | 495 | err_drop: |
| 496 | 496 | stats->dropped++; |
| 497 | − dev_kfree_skb_any(skb); | |
| 498 | 497 | if (unlikely(sq->ptpsq && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) |
| 499 | 498 | mlx5e_ptp_metadata_fifo_push(&sq->ptpsq->metadata_freelist, |
| 500 | 499 | be32_to_cpu(eseg->flow_table_metadata)); |
| 500 | + dev_kfree_skb_any(skb); | |
| 501 | 501 | mlx5e_tx_flush(sq); |
| 502 | 502 | } |
| 503 | 503 | |
| @@ -885,11 +885,14 @@ static void comp_irq_release_sf(struct mlx5_core_dev *dev, u16 vecidx) · 884 unmodified lines | ||
| 885 | 885 | { |
| 886 | 886 | struct mlx5_eq_table *table = dev->priv.eq_table; |
| 887 | 887 | struct mlx5_irq *irq; |
| 888 | + int cpu; | |
| 888 | 889 | |
| 889 | 890 | irq = xa_load(&table->comp_irqs, vecidx); |
| 890 | 891 | if (!irq) |
| 891 | 892 | return; |
| 892 | 893 | |
| 894 | + cpu = cpumask_first(mlx5_irq_get_affinity_mask(irq)); | |
| 895 | + cpumask_clear_cpu(cpu, &table->used_cpus); | |
| 893 | 896 | xa_erase(&table->comp_irqs, vecidx); |
| 894 | 897 | mlx5_irq_affinity_irq_release(dev, irq); |
| 895 | 898 | } |
| @@ -897,16 +900,26 @@ static void comp_irq_release_sf(struct mlx5_core_dev *dev, u16 vecidx) · 1 unmodified line | ||
| 897 | 900 | static int comp_irq_request_sf(struct mlx5_core_dev *dev, u16 vecidx) |
| 898 | 901 | { |
| 899 | 902 | struct mlx5_eq_table *table = dev->priv.eq_table; |
| 903 | + struct mlx5_irq_pool *pool = mlx5_irq_pool_get(dev); | |
| 904 | + struct irq_affinity_desc af_desc = {}; | |
| 900 | 905 | struct mlx5_irq *irq; |
| 901 | 906 | |
| 902 | − irq = mlx5_irq_affinity_irq_request_auto(dev, &table->used_cpus, vecidx); | |
| 903 | − if (IS_ERR(irq)) { | |
| 904 | − /* In case SF irq pool does not exist, fallback to the PF irqs*/ | |
| 905 | − if (PTR_ERR(irq) == -ENOENT) | |
| 906 | − return comp_irq_request_pci(dev, vecidx); | |
| 907 | + /* In case SF irq pool does not exist, fallback to the PF irqs*/ | |
| 908 | + if (!mlx5_irq_pool_is_sf_pool(pool)) | |
| 909 | + return comp_irq_request_pci(dev, vecidx); | |
| 907 | 910 | |
| 911 | + af_desc.is_managed = 1; | |
| 912 | + cpumask_copy(&af_desc.mask, cpu_online_mask); | |
| 913 | + cpumask_andnot(&af_desc.mask, &af_desc.mask, &table->used_cpus); | |
| 914 | + irq = mlx5_irq_affinity_request(pool, &af_desc); | |
| 915 | + if (IS_ERR(irq)) | |
| 908 | 916 | return PTR_ERR(irq); |
| 909 | − } | |
| 917 | + | |
| 918 | + cpumask_or(&table->used_cpus, &table->used_cpus, mlx5_irq_get_affinity_mask(irq)); | |
| 919 | + mlx5_core_dbg(pool->dev, "IRQ %u mapped to cpu %*pbl, %u EQs on this irq\n", | |
| 920 | + pci_irq_vector(dev->pdev, mlx5_irq_get_index(irq)), | |
| 921 | + cpumask_pr_args(mlx5_irq_get_affinity_mask(irq)), | |
| 922 | + mlx5_irq_read_locked(irq) / MLX5_EQ_REFS_PER_IRQ); | |
| 910 | 923 | |
| 911 | 924 | return xa_err(xa_store(&table->comp_irqs, vecidx, irq, GFP_KERNEL)); |
| 912 | 925 | } |
| @@ -616,13 +616,6 @@ static inline bool mlx5_esw_allowed(const struct mlx5_eswitch *esw) · 615 unmodified lines | ||
| 616 | 616 | return esw && MLX5_ESWITCH_MANAGER(esw->dev); |
| 617 | 617 | } |
| 618 | 618 | |
| 619 | −/* The returned number is valid only when the dev is eswitch manager. */ | |
| 620 | −static inline u16 mlx5_eswitch_manager_vport(struct mlx5_core_dev *dev) | |
| 621 | −{ | |
| 622 | − return mlx5_core_is_ecpf_esw_manager(dev) ? | |
| 623 | − MLX5_VPORT_ECPF : MLX5_VPORT_PF; | |
| 624 | −} | |
| 625 | − | |
| 626 | 619 | static inline bool |
| 627 | 620 | mlx5_esw_is_manager_vport(const struct mlx5_eswitch *esw, u16 vport_num) |
| 628 | 621 | { |
| @@ -984,7 +984,8 @@ mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *on_esw, · 983 unmodified lines | ||
| 984 | 984 | dest.vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID; |
| 985 | 985 | flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; |
| 986 | 986 | |
| 987 | − if (rep->vport == MLX5_VPORT_UPLINK && on_esw->offloads.ft_ipsec_tx_pol) { | |
| 987 | + if (rep->vport == MLX5_VPORT_UPLINK && | |
| 988 | + on_esw == from_esw && on_esw->offloads.ft_ipsec_tx_pol) { | |
| 988 | 989 | dest.ft = on_esw->offloads.ft_ipsec_tx_pol; |
| 989 | 990 | flow_act.flags = FLOW_ACT_IGNORE_FLOW_LEVEL; |
| 990 | 991 | dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; |
| @@ -168,45 +168,3 @@ void mlx5_irq_affinity_irq_release(struct mlx5_core_dev *dev, struct mlx5_irq *i · 167 unmodified lines | ||
| 168 | 168 | if (pool->irqs_per_cpu) |
| 169 | 169 | cpu_put(pool, cpu); |
| 170 | 170 | } |
| 171 | − | |
| 172 | −/** | |
| 173 | − * mlx5_irq_affinity_irq_request_auto - request one IRQ for mlx5 device. | |
| 174 | − * @dev: mlx5 device that is requesting the IRQ. | |
| 175 | − * @used_cpus: cpumask of bounded cpus by the device | |
| 176 | − * @vecidx: vector index to request an IRQ for. | |
| 177 | − * | |
| 178 | − * Each IRQ is bounded to at most 1 CPU. | |
| 179 | − * This function is requesting an IRQ according to the default assignment. | |
| 180 | − * The default assignment policy is: | |
| 181 | − * - request the least loaded IRQ which is not bound to any | |
| 182 | − * CPU of the previous IRQs requested. | |
| 183 | − * | |
| 184 | − * On success, this function updates used_cpus mask and returns an irq pointer. | |
| 185 | − * In case of an error, an appropriate error pointer is returned. | |
| 186 | − */ | |
| 187 | −struct mlx5_irq *mlx5_irq_affinity_irq_request_auto(struct mlx5_core_dev *dev, | |
| 188 | − struct cpumask *used_cpus, u16 vecidx) | |
| 189 | −{ | |
| 190 | − struct mlx5_irq_pool *pool = mlx5_irq_pool_get(dev); | |
| 191 | − struct irq_affinity_desc af_desc = {}; | |
| 192 | − struct mlx5_irq *irq; | |
| 193 | − | |
| 194 | − if (!mlx5_irq_pool_is_sf_pool(pool)) | |
| 195 | − return ERR_PTR(-ENOENT); | |
| 196 | − | |
| 197 | − af_desc.is_managed = 1; | |
| 198 | − cpumask_copy(&af_desc.mask, cpu_online_mask); | |
| 199 | − cpumask_andnot(&af_desc.mask, &af_desc.mask, used_cpus); | |
| 200 | − irq = mlx5_irq_affinity_request(pool, &af_desc); | |
| 201 | − | |
| 202 | − if (IS_ERR(irq)) | |
| 203 | − return irq; | |
| 204 | − | |
| 205 | − cpumask_or(used_cpus, used_cpus, mlx5_irq_get_affinity_mask(irq)); | |
| 206 | − mlx5_core_dbg(pool->dev, "IRQ %u mapped to cpu %*pbl, %u EQs on this irq\n", | |
| 207 | − pci_irq_vector(dev->pdev, mlx5_irq_get_index(irq)), | |
| 208 | − cpumask_pr_args(mlx5_irq_get_affinity_mask(irq)), | |
| 209 | − mlx5_irq_read_locked(irq) / MLX5_EQ_REFS_PER_IRQ); | |
| 210 | − | |
| 211 | − return irq; | |
| 212 | −} | |
| @@ -384,7 +384,12 @@ static int mlx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) · 383 unmodified lines | ||
| 384 | 384 | |
| 385 | 385 | static int mlx5_ptp_adjphase(struct ptp_clock_info *ptp, s32 delta) |
| 386 | 386 | { |
| 387 | − return mlx5_ptp_adjtime(ptp, delta); | |
| 387 | + struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); | |
| 388 | + struct mlx5_core_dev *mdev; | |
| 389 | + | |
| 390 | + mdev = container_of(clock, struct mlx5_core_dev, clock); | |
| 391 | + | |
| 392 | + return mlx5_ptp_adjtime_real_time(mdev, delta); | |
| 388 | 393 | } |
| 389 | 394 | |
| 390 | 395 | static int mlx5_ptp_freq_adj_real_time(struct mlx5_core_dev *mdev, long scaled_ppm) |
| @@ -13,11 +13,13 @@ struct mlx5_dm { · 12 unmodified lines | ||
| 13 | 13 | unsigned long *steering_sw_icm_alloc_blocks; |
| 14 | 14 | unsigned long *header_modify_sw_icm_alloc_blocks; |
| 15 | 15 | unsigned long *header_modify_pattern_sw_icm_alloc_blocks; |
| 16 | + unsigned long *header_encap_sw_icm_alloc_blocks; | |
| 16 | 17 | }; |
| 17 | 18 | |
| 18 | 19 | struct mlx5_dm *mlx5_dm_create(struct mlx5_core_dev *dev) |
| 19 | 20 | { |
| 20 | 21 | u64 header_modify_pattern_icm_blocks = 0; |
| 22 | + u64 header_sw_encap_icm_blocks = 0; | |
| 21 | 23 | u64 header_modify_icm_blocks = 0; |
| 22 | 24 | u64 steering_icm_blocks = 0; |
| 23 | 25 | struct mlx5_dm *dm; |
| @@ -54,6 +56,17 @@ struct mlx5_dm *mlx5_dm_create(struct mlx5_core_dev *dev) · 30 unmodified lines | ||
| 54 | 56 | goto err_modify_hdr; |
| 55 | 57 | } |
| 56 | 58 | |
| 59 | + if (MLX5_CAP_DEV_MEM(dev, log_indirect_encap_sw_icm_size)) { | |
| 60 | + header_sw_encap_icm_blocks = | |
| 61 | + BIT(MLX5_CAP_DEV_MEM(dev, log_indirect_encap_sw_icm_size) - | |
| 62 | + MLX5_LOG_SW_ICM_BLOCK_SIZE(dev)); | |
| 63 | + | |
| 64 | + dm->header_encap_sw_icm_alloc_blocks = | |
| 65 | + bitmap_zalloc(header_sw_encap_icm_blocks, GFP_KERNEL); | |
| 66 | + if (!dm->header_encap_sw_icm_alloc_blocks) | |
| 67 | + goto err_pattern; | |
| 68 | + } | |
| 69 | + | |
| 57 | 70 | support_v2 = MLX5_CAP_FLOWTABLE_NIC_RX(dev, sw_owner_v2) && |
| 58 | 71 | MLX5_CAP_FLOWTABLE_NIC_TX(dev, sw_owner_v2) && |
| 59 | 72 | MLX5_CAP64_DEV_MEM(dev, header_modify_pattern_sw_icm_start_address); |
| @@ -66,11 +79,14 @@ struct mlx5_dm *mlx5_dm_create(struct mlx5_core_dev *dev) · 6 unmodified lines | ||
| 66 | 79 | dm->header_modify_pattern_sw_icm_alloc_blocks = |
| 67 | 80 | bitmap_zalloc(header_modify_pattern_icm_blocks, GFP_KERNEL); |
| 68 | 81 | if (!dm->header_modify_pattern_sw_icm_alloc_blocks) |
| 69 | − goto err_pattern; | |
| 82 | + goto err_sw_encap; | |
| 70 | 83 | } |
| 71 | 84 | |
| 72 | 85 | return dm; |
| 73 | 86 | |
| 87 | +err_sw_encap: | |
| 88 | + bitmap_free(dm->header_encap_sw_icm_alloc_blocks); | |
| 89 | + | |
| 74 | 90 | err_pattern: |
| 75 | 91 | bitmap_free(dm->header_modify_sw_icm_alloc_blocks); |
| 76 | 92 | |
| @@ -105,6 +121,14 @@ void mlx5_dm_cleanup(struct mlx5_core_dev *dev) · 28 unmodified lines | ||
| 105 | 121 | bitmap_free(dm->header_modify_sw_icm_alloc_blocks); |
| 106 | 122 | } |
| 107 | 123 | |
| 124 | + if (dm->header_encap_sw_icm_alloc_blocks) { | |
| 125 | + WARN_ON(!bitmap_empty(dm->header_encap_sw_icm_alloc_blocks, | |
| 126 | + BIT(MLX5_CAP_DEV_MEM(dev, | |
| 127 | + log_indirect_encap_sw_icm_size) - | |
| 128 | + MLX5_LOG_SW_ICM_BLOCK_SIZE(dev)))); | |
| 129 | + bitmap_free(dm->header_encap_sw_icm_alloc_blocks); | |
| 130 | + } | |
| 131 | + | |
| 108 | 132 | if (dm->header_modify_pattern_sw_icm_alloc_blocks) { |
| 109 | 133 | WARN_ON(!bitmap_empty(dm->header_modify_pattern_sw_icm_alloc_blocks, |
| 110 | 134 | BIT(MLX5_CAP_DEV_MEM(dev, |
| @@ -164,6 +188,13 @@ int mlx5_dm_sw_icm_alloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type, · 53 unmodified lines | ||
| 164 | 188 | log_header_modify_pattern_sw_icm_size); |
| 165 | 189 | block_map = dm->header_modify_pattern_sw_icm_alloc_blocks; |
| 166 | 190 | break; |
| 191 | + case MLX5_SW_ICM_TYPE_SW_ENCAP: | |
| 192 | + icm_start_addr = MLX5_CAP64_DEV_MEM(dev, | |
| 193 | + indirect_encap_sw_icm_start_address); | |
| 194 | + log_icm_size = MLX5_CAP_DEV_MEM(dev, | |
| 195 | + log_indirect_encap_sw_icm_size); | |
| 196 | + block_map = dm->header_encap_sw_icm_alloc_blocks; | |
| 197 | + break; | |
| 167 | 198 | default: |
| 168 | 199 | return -EINVAL; |
| 169 | 200 | } |
| @@ -242,6 +273,11 @@ int mlx5_dm_sw_icm_dealloc(struct mlx5_core_dev *dev, enum mlx5_sw_icm_type type · 72 unmodified lines | ||
| 242 | 273 | header_modify_pattern_sw_icm_start_address); |
| 243 | 274 | block_map = dm->header_modify_pattern_sw_icm_alloc_blocks; |
| 244 | 275 | break; |
| 276 | + case MLX5_SW_ICM_TYPE_SW_ENCAP: | |
| 277 | + icm_start_addr = MLX5_CAP64_DEV_MEM(dev, | |
| 278 | + indirect_encap_sw_icm_start_address); | |
| 279 | + block_map = dm->header_encap_sw_icm_alloc_blocks; | |
| 280 | + break; | |
| 245 | 281 | default: |
| 246 | 282 | return -EINVAL; |
| 247 | 283 | } |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | struct mlx5_irq { |
| 29 | 29 | struct atomic_notifier_head nh; |
| 30 | 30 | cpumask_var_t mask; |
| 31 | − char name[MLX5_MAX_IRQ_NAME]; | |
| 31 | + char name[MLX5_MAX_IRQ_FORMATTED_NAME]; | |
| 32 | 32 | struct mlx5_irq_pool *pool; |
| 33 | 33 | int refcount; |
| 34 | 34 | struct msi_map map; |
| @@ -292,8 +292,8 @@ struct mlx5_irq *mlx5_irq_alloc(struct mlx5_irq_pool *pool, int i, · 257 unmodified lines | ||
| 292 | 292 | else |
| 293 | 293 | irq_sf_set_name(pool, name, i); |
| 294 | 294 | ATOMIC_INIT_NOTIFIER_HEAD(&irq->nh); |
| 295 | − snprintf(irq->name, MLX5_MAX_IRQ_NAME, | |
| 296 | − "%s@pci:%s", name, pci_name(dev->pdev)); | |
| 295 | + snprintf(irq->name, MLX5_MAX_IRQ_FORMATTED_NAME, | |
| 296 | + MLX5_IRQ_NAME_FORMAT_STR, name, pci_name(dev->pdev)); | |
| 297 | 297 | err = request_irq(irq->map.virq, irq_int_handler, 0, irq->name, |
| 298 | 298 | &irq->nh); |
| 299 | 299 | if (err) { |
| @@ -7,6 +7,9 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/mlx5/driver.h> |
| 8 | 8 | |
| 9 | 9 | #define MLX5_MAX_IRQ_NAME (32) |
| 10 | +#define MLX5_IRQ_NAME_FORMAT_STR ("%s@pci:%s") | |
| 11 | +#define MLX5_MAX_IRQ_FORMATTED_NAME \ | |
| 12 | + (MLX5_MAX_IRQ_NAME + sizeof(MLX5_IRQ_NAME_FORMAT_STR)) | |
| 10 | 13 | /* max irq_index is 2047, so four chars */ |
| 11 | 14 | #define MLX5_MAX_IRQ_IDX_CHARS (4) |
| 12 | 15 | #define MLX5_EQ_REFS_PER_IRQ (2) |
| @@ -57,7 +57,8 @@ static const char *dr_action_id_to_str(enum mlx5dr_action_type action_id) · 56 unmodified lines | ||
| 57 | 57 | |
| 58 | 58 | static bool mlx5dr_action_supp_fwd_fdb_multi_ft(struct mlx5_core_dev *dev) |
| 59 | 59 | { |
| 60 | − return (MLX5_CAP_ESW_FLOWTABLE(dev, fdb_multi_path_any_table_limit_regc) || | |
| 60 | + return (MLX5_CAP_GEN(dev, steering_format_version) < MLX5_STEERING_FORMAT_CONNECTX_6DX || | |
| 61 | + MLX5_CAP_ESW_FLOWTABLE(dev, fdb_multi_path_any_table_limit_regc) || | |
| 61 | 62 | MLX5_CAP_ESW_FLOWTABLE(dev, fdb_multi_path_any_table)); |
| 62 | 63 | } |
| 63 | 64 | |
| @@ -52,7 +52,6 @@ struct dr_qp_init_attr { · 51 unmodified lines | ||
| 52 | 52 | u32 cqn; |
| 53 | 53 | u32 pdn; |
| 54 | 54 | u32 max_send_wr; |
| 55 | − u32 max_send_sge; | |
| 56 | 55 | struct mlx5_uars_page *uar; |
| 57 | 56 | u8 isolate_vl_tc:1; |
| 58 | 57 | }; |
| @@ -247,37 +246,6 @@ static int dr_poll_cq(struct mlx5dr_cq *dr_cq, int ne) · 188 unmodified lines | ||
| 247 | 246 | return err == CQ_POLL_ERR ? err : npolled; |
| 248 | 247 | } |
| 249 | 248 | |
| 250 | −static int dr_qp_get_args_update_send_wqe_size(struct dr_qp_init_attr *attr) | |
| 251 | −{ | |
| 252 | − return roundup_pow_of_two(sizeof(struct mlx5_wqe_ctrl_seg) + | |
| 253 | − sizeof(struct mlx5_wqe_flow_update_ctrl_seg) + | |
| 254 | − sizeof(struct mlx5_wqe_header_modify_argument_update_seg)); | |
| 255 | −} | |
| 256 | − | |
| 257 | −/* We calculate for specific RC QP with the required functionality */ | |
| 258 | −static int dr_qp_calc_rc_send_wqe(struct dr_qp_init_attr *attr) | |
| 259 | −{ | |
| 260 | − int update_arg_size; | |
| 261 | − int inl_size = 0; | |
| 262 | − int tot_size; | |
| 263 | − int size; | |
| 264 | − | |
| 265 | − update_arg_size = dr_qp_get_args_update_send_wqe_size(attr); | |
| 266 | − | |
| 267 | − size = sizeof(struct mlx5_wqe_ctrl_seg) + | |
| 268 | − sizeof(struct mlx5_wqe_raddr_seg); | |
| 269 | − inl_size = size + ALIGN(sizeof(struct mlx5_wqe_inline_seg) + | |
| 270 | − DR_STE_SIZE, 16); | |
| 271 | − | |
| 272 | − size += attr->max_send_sge * sizeof(struct mlx5_wqe_data_seg); | |
| 273 | − | |
| 274 | − size = max(size, update_arg_size); | |
| 275 | − | |
| 276 | − tot_size = max(size, inl_size); | |
| 277 | − | |
| 278 | − return ALIGN(tot_size, MLX5_SEND_WQE_BB); | |
| 279 | −} | |
| 280 | − | |
| 281 | 249 | static struct mlx5dr_qp *dr_create_rc_qp(struct mlx5_core_dev *mdev, |
| 282 | 250 | struct dr_qp_init_attr *attr) |
| 283 | 251 | { |
| @@ -285,7 +253,6 @@ static struct mlx5dr_qp *dr_create_rc_qp(struct mlx5_core_dev *mdev, · 1 unmodified line | ||
| 285 | 253 | u32 temp_qpc[MLX5_ST_SZ_DW(qpc)] = {}; |
| 286 | 254 | struct mlx5_wq_param wqp; |
| 287 | 255 | struct mlx5dr_qp *dr_qp; |
| 288 | − int wqe_size; | |
| 289 | 256 | int inlen; |
| 290 | 257 | void *qpc; |
| 291 | 258 | void *in; |
| @@ -365,15 +332,6 @@ static struct mlx5dr_qp *dr_create_rc_qp(struct mlx5_core_dev *mdev, · 73 unmodified lines | ||
| 365 | 332 | if (err) |
| 366 | 333 | goto err_in; |
| 367 | 334 | dr_qp->uar = attr->uar; |
| 368 | − wqe_size = dr_qp_calc_rc_send_wqe(attr); | |
| 369 | − dr_qp->max_inline_data = min(wqe_size - | |
| 370 | − (sizeof(struct mlx5_wqe_ctrl_seg) + | |
| 371 | − sizeof(struct mlx5_wqe_raddr_seg) + | |
| 372 | − sizeof(struct mlx5_wqe_inline_seg)), | |
| 373 | − (2 * MLX5_SEND_WQE_BB - | |
| 374 | − (sizeof(struct mlx5_wqe_ctrl_seg) + | |
| 375 | − sizeof(struct mlx5_wqe_raddr_seg) + | |
| 376 | − sizeof(struct mlx5_wqe_inline_seg)))); | |
| 377 | 335 | |
| 378 | 336 | return dr_qp; |
| 379 | 337 | |
| @@ -437,48 +395,8 @@ dr_rdma_handle_flow_access_arg_segments(struct mlx5_wqe_ctrl_seg *wq_ctrl, · 57 unmodified lines | ||
| 437 | 395 | MLX5_SEND_WQE_DS; |
| 438 | 396 | } |
| 439 | 397 | |
| 440 | −static int dr_set_data_inl_seg(struct mlx5dr_qp *dr_qp, | |
| 441 | − struct dr_data_seg *data_seg, void *wqe) | |
| 442 | −{ | |
| 443 | − int inline_header_size = sizeof(struct mlx5_wqe_ctrl_seg) + | |
| 444 | − sizeof(struct mlx5_wqe_raddr_seg) + | |
| 445 | − sizeof(struct mlx5_wqe_inline_seg); | |
| 446 | − struct mlx5_wqe_inline_seg *seg; | |
| 447 | − int left_space; | |
| 448 | − int inl = 0; | |
| 449 | − void *addr; | |
| 450 | − int len; | |
| 451 | − int idx; | |
| 452 | − | |
| 453 | − seg = wqe; | |
| 454 | − wqe += sizeof(*seg); | |
| 455 | − addr = (void *)(unsigned long)(data_seg->addr); | |
| 456 | − len = data_seg->length; | |
| 457 | − inl += len; | |
| 458 | − left_space = MLX5_SEND_WQE_BB - inline_header_size; | |
| 459 | − | |
| 460 | − if (likely(len > left_space)) { | |
| 461 | − memcpy(wqe, addr, left_space); | |
| 462 | − len -= left_space; | |
| 463 | − addr += left_space; | |
| 464 | − idx = (dr_qp->sq.pc + 1) & (dr_qp->sq.wqe_cnt - 1); | |
| 465 | − wqe = mlx5_wq_cyc_get_wqe(&dr_qp->wq.sq, idx); | |
| 466 | − } | |
| 467 | − | |
| 468 | − memcpy(wqe, addr, len); | |
| 469 | − | |
| 470 | − if (likely(inl)) { | |
| 471 | − seg->byte_count = cpu_to_be32(inl | MLX5_INLINE_SEG); | |
| 472 | − return DIV_ROUND_UP(inl + sizeof(seg->byte_count), | |
| 473 | − MLX5_SEND_WQE_DS); | |
| 474 | − } else { | |
| 475 | − return 0; | |
| 476 | − } | |
| 477 | −} | |
| 478 | − | |
| 479 | 398 | static void |
| 480 | −dr_rdma_handle_icm_write_segments(struct mlx5dr_qp *dr_qp, | |
| 481 | − struct mlx5_wqe_ctrl_seg *wq_ctrl, | |
| 399 | +dr_rdma_handle_icm_write_segments(struct mlx5_wqe_ctrl_seg *wq_ctrl, | |
| 482 | 400 | u64 remote_addr, |
| 483 | 401 | u32 rkey, |
| 484 | 402 | struct dr_data_seg *data_seg, |
| @@ -494,17 +412,15 @@ dr_rdma_handle_icm_write_segments(struct mlx5dr_qp *dr_qp, · 9 unmodified lines | ||
| 494 | 412 | wq_raddr->reserved = 0; |
| 495 | 413 | |
| 496 | 414 | wq_dseg = (void *)(wq_raddr + 1); |
| 497 | − /* WQE ctrl segment + WQE remote addr segment */ | |
| 498 | − *size = (sizeof(*wq_ctrl) + sizeof(*wq_raddr)) / MLX5_SEND_WQE_DS; | |
| 499 | 415 | |
| 500 | − if (data_seg->send_flags & IB_SEND_INLINE) { | |
| 501 | − *size += dr_set_data_inl_seg(dr_qp, data_seg, wq_dseg); | |
| 502 | − } else { | |
| 503 | − wq_dseg->byte_count = cpu_to_be32(data_seg->length); | |
| 504 | − wq_dseg->lkey = cpu_to_be32(data_seg->lkey); | |
| 505 | − wq_dseg->addr = cpu_to_be64(data_seg->addr); | |
| 506 | − *size += sizeof(*wq_dseg) / MLX5_SEND_WQE_DS; /* WQE data segment */ | |
| 507 | − } | |
| 416 | + wq_dseg->byte_count = cpu_to_be32(data_seg->length); | |
| 417 | + wq_dseg->lkey = cpu_to_be32(data_seg->lkey); | |
| 418 | + wq_dseg->addr = cpu_to_be64(data_seg->addr); | |
| 419 | + | |
| 420 | + *size = (sizeof(*wq_ctrl) + /* WQE ctrl segment */ | |
| 421 | + sizeof(*wq_dseg) + /* WQE data segment */ | |
| 422 | + sizeof(*wq_raddr)) / /* WQE remote addr segment */ | |
| 423 | + MLX5_SEND_WQE_DS; | |
| 508 | 424 | } |
| 509 | 425 | |
| 510 | 426 | static void dr_set_ctrl_seg(struct mlx5_wqe_ctrl_seg *wq_ctrl, |
| @@ -535,7 +451,7 @@ static void dr_rdma_segments(struct mlx5dr_qp *dr_qp, u64 remote_addr, · 24 unmodified lines | ||
| 535 | 451 | switch (opcode) { |
| 536 | 452 | case MLX5_OPCODE_RDMA_READ: |
| 537 | 453 | case MLX5_OPCODE_RDMA_WRITE: |
| 538 | − dr_rdma_handle_icm_write_segments(dr_qp, wq_ctrl, remote_addr, | |
| 454 | + dr_rdma_handle_icm_write_segments(wq_ctrl, remote_addr, | |
| 539 | 455 | rkey, data_seg, &size); |
| 540 | 456 | break; |
| 541 | 457 | case MLX5_OPCODE_FLOW_TBL_ACCESS: |
| @@ -656,7 +572,7 @@ static void dr_fill_write_args_segs(struct mlx5dr_send_ring *send_ring, · 114 unmodified lines | ||
| 656 | 572 | if (send_ring->pending_wqe % send_ring->signal_th == 0) |
| 657 | 573 | send_info->write.send_flags |= IB_SEND_SIGNALED; |
| 658 | 574 | else |
| 659 | − send_info->write.send_flags &= ~IB_SEND_SIGNALED; | |
| 575 | + send_info->write.send_flags = 0; | |
| 660 | 576 | } |
| 661 | 577 | |
| 662 | 578 | static void dr_fill_write_icm_segs(struct mlx5dr_domain *dmn, |
| @@ -680,13 +596,9 @@ static void dr_fill_write_icm_segs(struct mlx5dr_domain *dmn, · 17 unmodified lines | ||
| 680 | 596 | } |
| 681 | 597 | |
| 682 | 598 | send_ring->pending_wqe++; |
| 683 | − if (!send_info->write.lkey) | |
| 684 | − send_info->write.send_flags |= IB_SEND_INLINE; | |
| 685 | 599 | |
| 686 | 600 | if (send_ring->pending_wqe % send_ring->signal_th == 0) |
| 687 | 601 | send_info->write.send_flags |= IB_SEND_SIGNALED; |
| 688 | − else | |
| 689 | − send_info->write.send_flags &= ~IB_SEND_SIGNALED; | |
| 690 | 602 | |
| 691 | 603 | send_ring->pending_wqe++; |
| 692 | 604 | send_info->read.length = send_info->write.length; |
| @@ -696,9 +608,9 @@ static void dr_fill_write_icm_segs(struct mlx5dr_domain *dmn, · 3 unmodified lines | ||
| 696 | 608 | send_info->read.lkey = send_ring->sync_mr->mkey; |
| 697 | 609 | |
| 698 | 610 | if (send_ring->pending_wqe % send_ring->signal_th == 0) |
| 699 | − send_info->read.send_flags |= IB_SEND_SIGNALED; | |
| 611 | + send_info->read.send_flags = IB_SEND_SIGNALED; | |
| 700 | 612 | else |
| 701 | − send_info->read.send_flags &= ~IB_SEND_SIGNALED; | |
| 613 | + send_info->read.send_flags = 0; | |
| 702 | 614 | } |
| 703 | 615 | |
| 704 | 616 | static void dr_fill_data_segs(struct mlx5dr_domain *dmn, |
| @@ -1345,7 +1257,6 @@ int mlx5dr_send_ring_alloc(struct mlx5dr_domain *dmn) · 640 unmodified lines | ||
| 1345 | 1257 | dmn->send_ring->cq->qp = dmn->send_ring->qp; |
| 1346 | 1258 | |
| 1347 | 1259 | dmn->info.max_send_wr = QUEUE_SIZE; |
| 1348 | − init_attr.max_send_sge = 1; | |
| 1349 | 1260 | dmn->info.max_inline_size = min(dmn->send_ring->qp->max_inline_data, |
| 1350 | 1261 | DR_STE_SIZE); |
| 1351 | 1262 | |
| @@ -160,6 +160,18 @@ struct nfp_tun_mac_addr_offload { · 159 unmodified lines | ||
| 160 | 160 | u8 addr[ETH_ALEN]; |
| 161 | 161 | }; |
| 162 | 162 | |
| 163 | +/** | |
| 164 | + * struct nfp_neigh_update_work - update neighbour information to nfp | |
| 165 | + * @work: Work queue for writing neigh to the nfp | |
| 166 | + * @n: neighbour entry | |
| 167 | + * @app: Back pointer to app | |
| 168 | + */ | |
| 169 | +struct nfp_neigh_update_work { | |
| 170 | + struct work_struct work; | |
| 171 | + struct neighbour *n; | |
| 172 | + struct nfp_app *app; | |
| 173 | +}; | |
| 174 | + | |
| 163 | 175 | enum nfp_flower_mac_offload_cmd { |
| 164 | 176 | NFP_TUNNEL_MAC_OFFLOAD_ADD = 0, |
| 165 | 177 | NFP_TUNNEL_MAC_OFFLOAD_DEL = 1, |
| @@ -607,38 +619,30 @@ err: · 441 unmodified lines | ||
| 607 | 619 | nfp_flower_cmsg_warn(app, "Neighbour configuration failed.\n"); |
| 608 | 620 | } |
| 609 | 621 | |
| 610 | −static int | |
| 611 | −nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, | |
| 612 | − void *ptr) | |
| 622 | +static void | |
| 623 | +nfp_tun_release_neigh_update_work(struct nfp_neigh_update_work *update_work) | |
| 613 | 624 | { |
| 614 | − struct nfp_flower_priv *app_priv; | |
| 615 | − struct netevent_redirect *redir; | |
| 616 | − struct neighbour *n; | |
| 625 | + neigh_release(update_work->n); | |
| 626 | + kfree(update_work); | |
| 627 | +} | |
| 628 | + | |
| 629 | +static void nfp_tun_neigh_update(struct work_struct *work) | |
| 630 | +{ | |
| 631 | + struct nfp_neigh_update_work *update_work; | |
| 617 | 632 | struct nfp_app *app; |
| 633 | + struct neighbour *n; | |
| 618 | 634 | bool neigh_invalid; |
| 619 | 635 | int err; |
| 620 | 636 | |
| 621 | − switch (event) { | |
| 622 | − case NETEVENT_REDIRECT: | |
| 623 | − redir = (struct netevent_redirect *)ptr; | |
| 624 | − n = redir->neigh; | |
| 625 | − break; | |
| 626 | − case NETEVENT_NEIGH_UPDATE: | |
| 627 | − n = (struct neighbour *)ptr; | |
| 628 | − break; | |
| 629 | − default: | |
| 630 | − return NOTIFY_DONE; | |
| 631 | − } | |
| 632 | − | |
| 633 | − neigh_invalid = !(n->nud_state & NUD_VALID) || n->dead; | |
| 634 | − | |
| 635 | − app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb); | |
| 636 | − app = app_priv->app; | |
| 637 | + update_work = container_of(work, struct nfp_neigh_update_work, work); | |
| 638 | + app = update_work->app; | |
| 639 | + n = update_work->n; | |
| 637 | 640 | |
| 638 | 641 | if (!nfp_flower_get_port_id_from_netdev(app, n->dev)) |
| 639 | − return NOTIFY_DONE; | |
| 642 | + goto out; | |
| 640 | 643 | |
| 641 | 644 | #if IS_ENABLED(CONFIG_INET) |
| 645 | + neigh_invalid = !(n->nud_state & NUD_VALID) || n->dead; | |
| 642 | 646 | if (n->tbl->family == AF_INET6) { |
| 643 | 647 | #if IS_ENABLED(CONFIG_IPV6) |
| 644 | 648 | struct flowi6 flow6 = {}; |
| @@ -655,13 +659,11 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, · 10 unmodified lines | ||
| 655 | 659 | dst = ip6_dst_lookup_flow(dev_net(n->dev), NULL, |
| 656 | 660 | &flow6, NULL); |
| 657 | 661 | if (IS_ERR(dst)) |
| 658 | − return NOTIFY_DONE; | |
| 662 | + goto out; | |
| 659 | 663 | |
| 660 | 664 | dst_release(dst); |
| 661 | 665 | } |
| 662 | 666 | nfp_tun_write_neigh(n->dev, app, &flow6, n, true, false); |
| 663 | −#else | |
| 664 | − return NOTIFY_DONE; | |
| 665 | 667 | #endif /* CONFIG_IPV6 */ |
| 666 | 668 | } else { |
| 667 | 669 | struct flowi4 flow4 = {}; |
| @@ -678,17 +680,71 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, · 10 unmodified lines | ||
| 678 | 680 | rt = ip_route_output_key(dev_net(n->dev), &flow4); |
| 679 | 681 | err = PTR_ERR_OR_ZERO(rt); |
| 680 | 682 | if (err) |
| 681 | − return NOTIFY_DONE; | |
| 683 | + goto out; | |
| 682 | 684 | |
| 683 | 685 | ip_rt_put(rt); |
| 684 | 686 | } |
| 685 | 687 | nfp_tun_write_neigh(n->dev, app, &flow4, n, false, false); |
| 686 | 688 | } |
| 687 | −#else | |
| 688 | − return NOTIFY_DONE; | |
| 689 | 689 | #endif /* CONFIG_INET */ |
| 690 | +out: | |
| 691 | + nfp_tun_release_neigh_update_work(update_work); | |
| 692 | +} | |
| 690 | 693 | |
| 691 | − return NOTIFY_OK; | |
| 694 | +static struct nfp_neigh_update_work * | |
| 695 | +nfp_tun_alloc_neigh_update_work(struct nfp_app *app, struct neighbour *n) | |
| 696 | +{ | |
| 697 | + struct nfp_neigh_update_work *update_work; | |
| 698 | + | |
| 699 | + update_work = kzalloc(sizeof(*update_work), GFP_ATOMIC); | |
| 700 | + if (!update_work) | |
| 701 | + return NULL; | |
| 702 | + | |
| 703 | + INIT_WORK(&update_work->work, nfp_tun_neigh_update); | |
| 704 | + neigh_hold(n); | |
| 705 | + update_work->n = n; | |
| 706 | + update_work->app = app; | |
| 707 | + | |
| 708 | + return update_work; | |
| 709 | +} | |
| 710 | + | |
| 711 | +static int | |
| 712 | +nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event, | |
| 713 | + void *ptr) | |
| 714 | +{ | |
| 715 | + struct nfp_neigh_update_work *update_work; | |
| 716 | + struct nfp_flower_priv *app_priv; | |
| 717 | + struct netevent_redirect *redir; | |
| 718 | + struct neighbour *n; | |
| 719 | + struct nfp_app *app; | |
| 720 | + | |
| 721 | + switch (event) { | |
| 722 | + case NETEVENT_REDIRECT: | |
| 723 | + redir = (struct netevent_redirect *)ptr; | |
| 724 | + n = redir->neigh; | |
| 725 | + break; | |
| 726 | + case NETEVENT_NEIGH_UPDATE: | |
| 727 | + n = (struct neighbour *)ptr; | |
| 728 | + break; | |
| 729 | + default: | |
| 730 | + return NOTIFY_DONE; | |
| 731 | + } | |
| 732 | +#if IS_ENABLED(CONFIG_IPV6) | |
| 733 | + if (n->tbl != ipv6_stub->nd_tbl && n->tbl != &arp_tbl) | |
| 734 | +#else | |
| 735 | + if (n->tbl != &arp_tbl) | |
| 736 | +#endif | |
| 737 | + return NOTIFY_DONE; | |
| 738 | + | |
| 739 | + app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb); | |
| 740 | + app = app_priv->app; | |
| 741 | + update_work = nfp_tun_alloc_neigh_update_work(app, n); | |
| 742 | + if (!update_work) | |
| 743 | + return NOTIFY_DONE; | |
| 744 | + | |
| 745 | + queue_work(system_highpri_wq, &update_work->work); | |
| 746 | + | |
| 747 | + return NOTIFY_DONE; | |
| 692 | 748 | } |
| 693 | 749 | |
| 694 | 750 | void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb) |
| @@ -706,6 +762,7 @@ void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb) · 11 unmodified lines | ||
| 706 | 762 | netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL); |
| 707 | 763 | if (!netdev) |
| 708 | 764 | goto fail_rcu_unlock; |
| 765 | + dev_hold(netdev); | |
| 709 | 766 | |
| 710 | 767 | flow.daddr = payload->ipv4_addr; |
| 711 | 768 | flow.flowi4_proto = IPPROTO_UDP; |
| @@ -725,13 +782,16 @@ void nfp_tunnel_request_route_v4(struct nfp_app *app, struct sk_buff *skb) · 13 unmodified lines | ||
| 725 | 782 | ip_rt_put(rt); |
| 726 | 783 | if (!n) |
| 727 | 784 | goto fail_rcu_unlock; |
| 785 | + rcu_read_unlock(); | |
| 786 | + | |
| 728 | 787 | nfp_tun_write_neigh(n->dev, app, &flow, n, false, true); |
| 729 | 788 | neigh_release(n); |
| 730 | − rcu_read_unlock(); | |
| 789 | + dev_put(netdev); | |
| 731 | 790 | return; |
| 732 | 791 | |
| 733 | 792 | fail_rcu_unlock: |
| 734 | 793 | rcu_read_unlock(); |
| 794 | + dev_put(netdev); | |
| 735 | 795 | nfp_flower_cmsg_warn(app, "Requested route not found.\n"); |
| 736 | 796 | } |
| 737 | 797 | |
| @@ -749,6 +809,7 @@ void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb) · 11 unmodified lines | ||
| 749 | 809 | netdev = nfp_app_dev_get(app, be32_to_cpu(payload->ingress_port), NULL); |
| 750 | 810 | if (!netdev) |
| 751 | 811 | goto fail_rcu_unlock; |
| 812 | + dev_hold(netdev); | |
| 752 | 813 | |
| 753 | 814 | flow.daddr = payload->ipv6_addr; |
| 754 | 815 | flow.flowi6_proto = IPPROTO_UDP; |
| @@ -766,14 +827,16 @@ void nfp_tunnel_request_route_v6(struct nfp_app *app, struct sk_buff *skb) · 11 unmodified lines | ||
| 766 | 827 | dst_release(dst); |
| 767 | 828 | if (!n) |
| 768 | 829 | goto fail_rcu_unlock; |
| 830 | + rcu_read_unlock(); | |
| 769 | 831 | |
| 770 | 832 | nfp_tun_write_neigh(n->dev, app, &flow, n, true, true); |
| 771 | 833 | neigh_release(n); |
| 772 | − rcu_read_unlock(); | |
| 834 | + dev_put(netdev); | |
| 773 | 835 | return; |
| 774 | 836 | |
| 775 | 837 | fail_rcu_unlock: |
| 776 | 838 | rcu_read_unlock(); |
| 839 | + dev_put(netdev); | |
| 777 | 840 | nfp_flower_cmsg_warn(app, "Requested IPv6 route not found.\n"); |
| 778 | 841 | } |
| 779 | 842 | |
| @@ -223,7 +223,7 @@ struct ionic_desc_info { · 222 unmodified lines | ||
| 223 | 223 | void *cb_arg; |
| 224 | 224 | }; |
| 225 | 225 | |
| 226 | −#define IONIC_QUEUE_NAME_MAX_SZ 32 | |
| 226 | +#define IONIC_QUEUE_NAME_MAX_SZ 16 | |
| 227 | 227 | |
| 228 | 228 | struct ionic_queue { |
| 229 | 229 | struct device *dev; |
| @@ -49,24 +49,24 @@ static void ionic_lif_queue_identify(struct ionic_lif *lif); · 48 unmodified lines | ||
| 49 | 49 | static void ionic_dim_work(struct work_struct *work) |
| 50 | 50 | { |
| 51 | 51 | struct dim *dim = container_of(work, struct dim, work); |
| 52 | + struct ionic_intr_info *intr; | |
| 52 | 53 | struct dim_cq_moder cur_moder; |
| 53 | 54 | struct ionic_qcq *qcq; |
| 55 | + struct ionic_lif *lif; | |
| 54 | 56 | u32 new_coal; |
| 55 | 57 | |
| 56 | 58 | cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix); |
| 57 | 59 | qcq = container_of(dim, struct ionic_qcq, dim); |
| 58 | − new_coal = ionic_coal_usec_to_hw(qcq->q.lif->ionic, cur_moder.usec); | |
| 60 | + lif = qcq->q.lif; | |
| 61 | + new_coal = ionic_coal_usec_to_hw(lif->ionic, cur_moder.usec); | |
| 59 | 62 | new_coal = new_coal ? new_coal : 1; |
| 60 | 63 | |
| 61 | − if (qcq->intr.dim_coal_hw != new_coal) { | |
| 62 | − unsigned int qi = qcq->cq.bound_q->index; | |
| 63 | − struct ionic_lif *lif = qcq->q.lif; | |
| 64 | − | |
| 65 | − qcq->intr.dim_coal_hw = new_coal; | |
| 64 | + intr = &qcq->intr; | |
| 65 | + if (intr->dim_coal_hw != new_coal) { | |
| 66 | + intr->dim_coal_hw = new_coal; | |
| 66 | 67 | |
| 67 | 68 | ionic_intr_coal_init(lif->ionic->idev.intr_ctrl, |
| 68 | − lif->rxqcqs[qi]->intr.index, | |
| 69 | − qcq->intr.dim_coal_hw); | |
| 69 | + intr->index, intr->dim_coal_hw); | |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | dim->state = DIM_START_MEASURE; |
| @@ -196,6 +196,7 @@ enum rtl_registers { · 195 unmodified lines | ||
| 196 | 196 | /* No threshold before first PCI xfer */ |
| 197 | 197 | #define RX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) |
| 198 | 198 | #define RX_EARLY_OFF (1 << 11) |
| 199 | +#define RX_PAUSE_SLOT_ON (1 << 11) /* 8125b and later */ | |
| 199 | 200 | #define RXCFG_DMA_SHIFT 8 |
| 200 | 201 | /* Unlimited maximum PCI burst. */ |
| 201 | 202 | #define RX_DMA_BURST (7 << RXCFG_DMA_SHIFT) |
| @@ -579,6 +580,7 @@ struct rtl8169_tc_offsets { · 377 unmodified lines | ||
| 579 | 580 | enum rtl_flag { |
| 580 | 581 | RTL_FLAG_TASK_ENABLED = 0, |
| 581 | 582 | RTL_FLAG_TASK_RESET_PENDING, |
| 583 | + RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, | |
| 582 | 584 | RTL_FLAG_TASK_TX_TIMEOUT, |
| 583 | 585 | RTL_FLAG_MAX |
| 584 | 586 | }; |
| @@ -624,6 +626,7 @@ struct rtl8169_private { · 39 unmodified lines | ||
| 624 | 626 | |
| 625 | 627 | unsigned supports_gmii:1; |
| 626 | 628 | unsigned aspm_manageable:1; |
| 629 | + unsigned dash_enabled:1; | |
| 627 | 630 | dma_addr_t counters_phys_addr; |
| 628 | 631 | struct rtl8169_counters *counters; |
| 629 | 632 | struct rtl8169_tc_offsets tc_offset; |
| @@ -1253,14 +1256,26 @@ static bool r8168ep_check_dash(struct rtl8169_private *tp) · 623 unmodified lines | ||
| 1253 | 1256 | return r8168ep_ocp_read(tp, 0x128) & BIT(0); |
| 1254 | 1257 | } |
| 1255 | 1258 | |
| 1256 | −static enum rtl_dash_type rtl_check_dash(struct rtl8169_private *tp) | |
| 1259 | +static bool rtl_dash_is_enabled(struct rtl8169_private *tp) | |
| 1260 | +{ | |
| 1261 | + switch (tp->dash_type) { | |
| 1262 | + case RTL_DASH_DP: | |
| 1263 | + return r8168dp_check_dash(tp); | |
| 1264 | + case RTL_DASH_EP: | |
| 1265 | + return r8168ep_check_dash(tp); | |
| 1266 | + default: | |
| 1267 | + return false; | |
| 1268 | + } | |
| 1269 | +} | |
| 1270 | + | |
| 1271 | +static enum rtl_dash_type rtl_get_dash_type(struct rtl8169_private *tp) | |
| 1257 | 1272 | { |
| 1258 | 1273 | switch (tp->mac_version) { |
| 1259 | 1274 | case RTL_GIGA_MAC_VER_28: |
| 1260 | 1275 | case RTL_GIGA_MAC_VER_31: |
| 1261 | − return r8168dp_check_dash(tp) ? RTL_DASH_DP : RTL_DASH_NONE; | |
| 1276 | + return RTL_DASH_DP; | |
| 1262 | 1277 | case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53: |
| 1263 | − return r8168ep_check_dash(tp) ? RTL_DASH_EP : RTL_DASH_NONE; | |
| 1278 | + return RTL_DASH_EP; | |
| 1264 | 1279 | default: |
| 1265 | 1280 | return RTL_DASH_NONE; |
| 1266 | 1281 | } |
| @@ -1453,7 +1468,7 @@ static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) · 186 unmodified lines | ||
| 1453 | 1468 | |
| 1454 | 1469 | device_set_wakeup_enable(tp_to_dev(tp), wolopts); |
| 1455 | 1470 | |
| 1456 | − if (tp->dash_type == RTL_DASH_NONE) { | |
| 1471 | + if (!tp->dash_enabled) { | |
| 1457 | 1472 | rtl_set_d3_pll_down(tp, !wolopts); |
| 1458 | 1473 | tp->dev->wol_enabled = wolopts ? 1 : 0; |
| 1459 | 1474 | } |
| @@ -2292,9 +2307,13 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) · 832 unmodified lines | ||
| 2292 | 2307 | case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_53: |
| 2293 | 2308 | RTL_W32(tp, RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST | RX_EARLY_OFF); |
| 2294 | 2309 | break; |
| 2295 | − case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63: | |
| 2310 | + case RTL_GIGA_MAC_VER_61: | |
| 2296 | 2311 | RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST); |
| 2297 | 2312 | break; |
| 2313 | + case RTL_GIGA_MAC_VER_63: | |
| 2314 | + RTL_W32(tp, RxConfig, RX_FETCH_DFLT_8125 | RX_DMA_BURST | | |
| 2315 | + RX_PAUSE_SLOT_ON); | |
| 2316 | + break; | |
| 2298 | 2317 | default: |
| 2299 | 2318 | RTL_W32(tp, RxConfig, RX128_INT_EN | RX_DMA_BURST); |
| 2300 | 2319 | break; |
| @@ -2512,7 +2531,7 @@ static void rtl_wol_enable_rx(struct rtl8169_private *tp) · 211 unmodified lines | ||
| 2512 | 2531 | |
| 2513 | 2532 | static void rtl_prepare_power_down(struct rtl8169_private *tp) |
| 2514 | 2533 | { |
| 2515 | − if (tp->dash_type != RTL_DASH_NONE) | |
| 2534 | + if (tp->dash_enabled) | |
| 2516 | 2535 | return; |
| 2517 | 2536 | |
| 2518 | 2537 | if (tp->mac_version == RTL_GIGA_MAC_VER_32 || |
| @@ -2586,9 +2605,7 @@ static void rtl_set_rx_mode(struct net_device *dev) · 67 unmodified lines | ||
| 2586 | 2605 | rx_mode &= ~AcceptMulticast; |
| 2587 | 2606 | } else if (netdev_mc_count(dev) > MC_FILTER_LIMIT || |
| 2588 | 2607 | dev->flags & IFF_ALLMULTI || |
| 2589 | − tp->mac_version == RTL_GIGA_MAC_VER_35 || | |
| 2590 | − tp->mac_version == RTL_GIGA_MAC_VER_46 || | |
| 2591 | − tp->mac_version == RTL_GIGA_MAC_VER_48) { | |
| 2608 | + tp->mac_version == RTL_GIGA_MAC_VER_35) { | |
| 2592 | 2609 | /* accept all multicasts */ |
| 2593 | 2610 | } else if (netdev_mc_empty(dev)) { |
| 2594 | 2611 | rx_mode &= ~AcceptMulticast; |
| @@ -4571,6 +4588,8 @@ static void rtl_task(struct work_struct *work) · 1976 unmodified lines | ||
| 4571 | 4588 | reset: |
| 4572 | 4589 | rtl_reset_work(tp); |
| 4573 | 4590 | netif_wake_queue(tp->dev); |
| 4591 | + } else if (test_and_clear_bit(RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE, tp->wk.flags)) { | |
| 4592 | + rtl_reset_work(tp); | |
| 4574 | 4593 | } |
| 4575 | 4594 | out_unlock: |
| 4576 | 4595 | rtnl_unlock(); |
| @@ -4604,7 +4623,7 @@ static void r8169_phylink_handler(struct net_device *ndev) · 27 unmodified lines | ||
| 4604 | 4623 | } else { |
| 4605 | 4624 | /* In few cases rx is broken after link-down otherwise */ |
| 4606 | 4625 | if (rtl_is_8125(tp)) |
| 4607 | − rtl_reset_work(tp); | |
| 4626 | + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_NO_QUEUE_WAKE); | |
| 4608 | 4627 | pm_runtime_idle(d); |
| 4609 | 4628 | } |
| 4610 | 4629 | |
| @@ -4648,10 +4667,16 @@ static void rtl8169_down(struct rtl8169_private *tp) · 37 unmodified lines | ||
| 4648 | 4667 | rtl8169_cleanup(tp); |
| 4649 | 4668 | rtl_disable_exit_l1(tp); |
| 4650 | 4669 | rtl_prepare_power_down(tp); |
| 4670 | + | |
| 4671 | + if (tp->dash_type != RTL_DASH_NONE) | |
| 4672 | + rtl8168_driver_stop(tp); | |
| 4651 | 4673 | } |
| 4652 | 4674 | |
| 4653 | 4675 | static void rtl8169_up(struct rtl8169_private *tp) |
| 4654 | 4676 | { |
| 4677 | + if (tp->dash_type != RTL_DASH_NONE) | |
| 4678 | + rtl8168_driver_start(tp); | |
| 4679 | + | |
| 4655 | 4680 | pci_set_master(tp->pci_dev); |
| 4656 | 4681 | phy_init_hw(tp->phydev); |
| 4657 | 4682 | phy_resume(tp->phydev); |
| @@ -4674,7 +4699,7 @@ static int rtl8169_close(struct net_device *dev) · 16 unmodified lines | ||
| 4674 | 4699 | rtl8169_down(tp); |
| 4675 | 4700 | rtl8169_rx_clear(tp); |
| 4676 | 4701 | |
| 4677 | − cancel_work_sync(&tp->wk.work); | |
| 4702 | + cancel_work(&tp->wk.work); | |
| 4678 | 4703 | |
| 4679 | 4704 | free_irq(tp->irq, tp); |
| 4680 | 4705 | |
| @@ -4869,7 +4894,7 @@ static int rtl8169_runtime_idle(struct device *device) · 188 unmodified lines | ||
| 4869 | 4894 | { |
| 4870 | 4895 | struct rtl8169_private *tp = dev_get_drvdata(device); |
| 4871 | 4896 | |
| 4872 | − if (tp->dash_type != RTL_DASH_NONE) | |
| 4897 | + if (tp->dash_enabled) | |
| 4873 | 4898 | return -EBUSY; |
| 4874 | 4899 | |
| 4875 | 4900 | if (!netif_running(tp->dev) || !netif_carrier_ok(tp->dev)) |
| @@ -4895,8 +4920,7 @@ static void rtl_shutdown(struct pci_dev *pdev) · 19 unmodified lines | ||
| 4895 | 4920 | /* Restore original MAC address */ |
| 4896 | 4921 | rtl_rar_set(tp, tp->dev->perm_addr); |
| 4897 | 4922 | |
| 4898 | − if (system_state == SYSTEM_POWER_OFF && | |
| 4899 | − tp->dash_type == RTL_DASH_NONE) { | |
| 4923 | + if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled) { | |
| 4900 | 4924 | pci_wake_from_d3(pdev, tp->saved_wolopts); |
| 4901 | 4925 | pci_set_power_state(pdev, PCI_D3hot); |
| 4902 | 4926 | } |
| @@ -4909,6 +4933,8 @@ static void rtl_remove_one(struct pci_dev *pdev) · 6 unmodified lines | ||
| 4909 | 4933 | if (pci_dev_run_wake(pdev)) |
| 4910 | 4934 | pm_runtime_get_noresume(&pdev->dev); |
| 4911 | 4935 | |
| 4936 | + cancel_work_sync(&tp->wk.work); | |
| 4937 | + | |
| 4912 | 4938 | unregister_netdev(tp->dev); |
| 4913 | 4939 | |
| 4914 | 4940 | if (tp->dash_type != RTL_DASH_NONE) |
| @@ -5254,7 +5280,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 339 unmodified lines | ||
| 5254 | 5280 | rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1); |
| 5255 | 5281 | tp->aspm_manageable = !rc; |
| 5256 | 5282 | |
| 5257 | − tp->dash_type = rtl_check_dash(tp); | |
| 5283 | + tp->dash_type = rtl_get_dash_type(tp); | |
| 5284 | + tp->dash_enabled = rtl_dash_is_enabled(tp); | |
| 5258 | 5285 | |
| 5259 | 5286 | tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK; |
| 5260 | 5287 | |
| @@ -5325,7 +5352,7 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 64 unmodified lines | ||
| 5325 | 5352 | /* configure chip for default features */ |
| 5326 | 5353 | rtl8169_set_features(dev, dev->features); |
| 5327 | 5354 | |
| 5328 | − if (tp->dash_type == RTL_DASH_NONE) { | |
| 5355 | + if (!tp->dash_enabled) { | |
| 5329 | 5356 | rtl_set_d3_pll_down(tp, true); |
| 5330 | 5357 | } else { |
| 5331 | 5358 | rtl_set_d3_pll_down(tp, false); |
| @@ -5365,7 +5392,8 @@ static int rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 33 unmodified lines | ||
| 5365 | 5392 | "ok" : "ko"); |
| 5366 | 5393 | |
| 5367 | 5394 | if (tp->dash_type != RTL_DASH_NONE) { |
| 5368 | − netdev_info(dev, "DASH enabled\n"); | |
| 5395 | + netdev_info(dev, "DASH %s\n", | |
| 5396 | + tp->dash_enabled ? "enabled" : "disabled"); | |
| 5369 | 5397 | rtl8168_driver_start(tp); |
| 5370 | 5398 | } |
| 5371 | 5399 | |
| @@ -515,6 +515,15 @@ static void ravb_emac_init_gbeth(struct net_device *ndev) · 514 unmodified lines | ||
| 515 | 515 | { |
| 516 | 516 | struct ravb_private *priv = netdev_priv(ndev); |
| 517 | 517 | |
| 518 | + if (priv->phy_interface == PHY_INTERFACE_MODE_MII) { | |
| 519 | + ravb_write(ndev, (1000 << 16) | CXR35_SEL_XMII_MII, CXR35); | |
| 520 | + ravb_modify(ndev, CXR31, CXR31_SEL_LINK0 | CXR31_SEL_LINK1, 0); | |
| 521 | + } else { | |
| 522 | + ravb_write(ndev, (1000 << 16) | CXR35_SEL_XMII_RGMII, CXR35); | |
| 523 | + ravb_modify(ndev, CXR31, CXR31_SEL_LINK0 | CXR31_SEL_LINK1, | |
| 524 | + CXR31_SEL_LINK0); | |
| 525 | + } | |
| 526 | + | |
| 518 | 527 | /* Receive frame limit set register */ |
| 519 | 528 | ravb_write(ndev, GBETH_RX_BUFF_MAX + ETH_FCS_LEN, RFLR); |
| 520 | 529 | |
| @@ -537,14 +546,6 @@ static void ravb_emac_init_gbeth(struct net_device *ndev) · 16 unmodified lines | ||
| 537 | 546 | |
| 538 | 547 | /* E-MAC interrupt enable register */ |
| 539 | 548 | ravb_write(ndev, ECSIPR_ICDIP, ECSIPR); |
| 540 | − | |
| 541 | − if (priv->phy_interface == PHY_INTERFACE_MODE_MII) { | |
| 542 | − ravb_modify(ndev, CXR31, CXR31_SEL_LINK0 | CXR31_SEL_LINK1, 0); | |
| 543 | − ravb_write(ndev, (1000 << 16) | CXR35_SEL_XMII_MII, CXR35); | |
| 544 | − } else { | |
| 545 | − ravb_modify(ndev, CXR31, CXR31_SEL_LINK0 | CXR31_SEL_LINK1, | |
| 546 | − CXR31_SEL_LINK0); | |
| 547 | − } | |
| 548 | 549 | } |
| 549 | 550 | |
| 550 | 551 | static void ravb_emac_init_rcar(struct net_device *ndev) |
| @@ -1811,19 +1812,20 @@ static int ravb_open(struct net_device *ndev) · 1260 unmodified lines | ||
| 1811 | 1812 | if (info->gptp) |
| 1812 | 1813 | ravb_ptp_init(ndev, priv->pdev); |
| 1813 | 1814 | |
| 1814 | − netif_tx_start_all_queues(ndev); | |
| 1815 | − | |
| 1816 | 1815 | /* PHY control start */ |
| 1817 | 1816 | error = ravb_phy_start(ndev); |
| 1818 | 1817 | if (error) |
| 1819 | 1818 | goto out_ptp_stop; |
| 1820 | 1819 | |
| 1820 | + netif_tx_start_all_queues(ndev); | |
| 1821 | + | |
| 1821 | 1822 | return 0; |
| 1822 | 1823 | |
| 1823 | 1824 | out_ptp_stop: |
| 1824 | 1825 | /* Stop PTP Clock driver */ |
| 1825 | 1826 | if (info->gptp) |
| 1826 | 1827 | ravb_ptp_stop(ndev); |
| 1828 | + ravb_stop_dma(ndev); | |
| 1827 | 1829 | out_free_irq_mgmta: |
| 1828 | 1830 | if (!info->multi_irqs) |
| 1829 | 1831 | goto out_free_irq; |
| @@ -1874,6 +1876,12 @@ static void ravb_tx_timeout_work(struct work_struct *work) · 44 unmodified lines | ||
| 1874 | 1876 | struct net_device *ndev = priv->ndev; |
| 1875 | 1877 | int error; |
| 1876 | 1878 | |
| 1879 | + if (!rtnl_trylock()) { | |
| 1880 | + usleep_range(1000, 2000); | |
| 1881 | + schedule_work(&priv->work); | |
| 1882 | + return; | |
| 1883 | + } | |
| 1884 | + | |
| 1877 | 1885 | netif_tx_stop_all_queues(ndev); |
| 1878 | 1886 | |
| 1879 | 1887 | /* Stop PTP Clock driver */ |
| @@ -1907,7 +1915,7 @@ static void ravb_tx_timeout_work(struct work_struct *work) · 27 unmodified lines | ||
| 1907 | 1915 | */ |
| 1908 | 1916 | netdev_err(ndev, "%s: ravb_dmac_init() failed, error %d\n", |
| 1909 | 1917 | __func__, error); |
| 1910 | − return; | |
| 1918 | + goto out_unlock; | |
| 1911 | 1919 | } |
| 1912 | 1920 | ravb_emac_init(ndev); |
| 1913 | 1921 | |
| @@ -1917,6 +1925,9 @@ out: · 3 unmodified lines | ||
| 1917 | 1925 | ravb_ptp_init(ndev, priv->pdev); |
| 1918 | 1926 | |
| 1919 | 1927 | netif_tx_start_all_queues(ndev); |
| 1928 | + | |
| 1929 | +out_unlock: | |
| 1930 | + rtnl_unlock(); | |
| 1920 | 1931 | } |
| 1921 | 1932 | |
| 1922 | 1933 | /* Packet transmit function for Ethernet AVB */ |
| @@ -2645,9 +2656,14 @@ static int ravb_probe(struct platform_device *pdev) · 722 unmodified lines | ||
| 2645 | 2656 | ndev->features = info->net_features; |
| 2646 | 2657 | ndev->hw_features = info->net_hw_features; |
| 2647 | 2658 | |
| 2648 | − reset_control_deassert(rstc); | |
| 2659 | + error = reset_control_deassert(rstc); | |
| 2660 | + if (error) | |
| 2661 | + goto out_free_netdev; | |
| 2662 | + | |
| 2649 | 2663 | pm_runtime_enable(&pdev->dev); |
| 2650 | − pm_runtime_get_sync(&pdev->dev); | |
| 2664 | + error = pm_runtime_resume_and_get(&pdev->dev); | |
| 2665 | + if (error < 0) | |
| 2666 | + goto out_rpm_disable; | |
| 2651 | 2667 | |
| 2652 | 2668 | if (info->multi_irqs) { |
| 2653 | 2669 | if (info->err_mgmt_irqs) |
| @@ -2872,11 +2888,12 @@ out_disable_gptp_clk: · 218 unmodified lines | ||
| 2872 | 2888 | out_disable_refclk: |
| 2873 | 2889 | clk_disable_unprepare(priv->refclk); |
| 2874 | 2890 | out_release: |
| 2875 | − free_netdev(ndev); | |
| 2876 | − | |
| 2877 | 2891 | pm_runtime_put(&pdev->dev); |
| 2892 | +out_rpm_disable: | |
| 2878 | 2893 | pm_runtime_disable(&pdev->dev); |
| 2879 | 2894 | reset_control_assert(rstc); |
| 2895 | +out_free_netdev: | |
| 2896 | + free_netdev(ndev); | |
| 2880 | 2897 | return error; |
| 2881 | 2898 | } |
| 2882 | 2899 | |
| @@ -2886,22 +2903,26 @@ static void ravb_remove(struct platform_device *pdev) · 3 unmodified lines | ||
| 2886 | 2903 | struct ravb_private *priv = netdev_priv(ndev); |
| 2887 | 2904 | const struct ravb_hw_info *info = priv->info; |
| 2888 | 2905 | |
| 2889 | − /* Stop PTP Clock driver */ | |
| 2890 | − if (info->ccc_gac) | |
| 2891 | − ravb_ptp_stop(ndev); | |
| 2892 | − | |
| 2893 | − clk_disable_unprepare(priv->gptp_clk); | |
| 2894 | − clk_disable_unprepare(priv->refclk); | |
| 2895 | − | |
| 2896 | − /* Set reset mode */ | |
| 2897 | − ravb_write(ndev, CCC_OPC_RESET, CCC); | |
| 2898 | 2906 | unregister_netdev(ndev); |
| 2899 | 2907 | if (info->nc_queues) |
| 2900 | 2908 | netif_napi_del(&priv->napi[RAVB_NC]); |
| 2901 | 2909 | netif_napi_del(&priv->napi[RAVB_BE]); |
| 2910 | + | |
| 2902 | 2911 | ravb_mdio_release(priv); |
| 2912 | + | |
| 2913 | + /* Stop PTP Clock driver */ | |
| 2914 | + if (info->ccc_gac) | |
| 2915 | + ravb_ptp_stop(ndev); | |
| 2916 | + | |
| 2903 | 2917 | dma_free_coherent(ndev->dev.parent, priv->desc_bat_size, priv->desc_bat, |
| 2904 | 2918 | priv->desc_bat_dma); |
| 2919 | + | |
| 2920 | + /* Set reset mode */ | |
| 2921 | + ravb_write(ndev, CCC_OPC_RESET, CCC); | |
| 2922 | + | |
| 2923 | + clk_disable_unprepare(priv->gptp_clk); | |
| 2924 | + clk_disable_unprepare(priv->refclk); | |
| 2925 | + | |
| 2905 | 2926 | pm_runtime_put_sync(&pdev->dev); |
| 2906 | 2927 | pm_runtime_disable(&pdev->dev); |
| 2907 | 2928 | reset_control_assert(priv->rstc); |
| @@ -1504,8 +1504,8 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd · 1503 unmodified lines | ||
| 1504 | 1504 | { |
| 1505 | 1505 | struct rswitch_device *rdev = netdev_priv(ndev); |
| 1506 | 1506 | struct rswitch_gwca_queue *gq = rdev->tx_queue; |
| 1507 | + netdev_tx_t ret = NETDEV_TX_OK; | |
| 1507 | 1508 | struct rswitch_ext_desc *desc; |
| 1508 | − int ret = NETDEV_TX_OK; | |
| 1509 | 1509 | dma_addr_t dma_addr; |
| 1510 | 1510 | |
| 1511 | 1511 | if (rswitch_get_num_cur_queues(gq) >= gq->ring_size - 1) { |
| @@ -1517,10 +1517,8 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd · 5 unmodified lines | ||
| 1517 | 1517 | return ret; |
| 1518 | 1518 | |
| 1519 | 1519 | dma_addr = dma_map_single(ndev->dev.parent, skb->data, skb->len, DMA_TO_DEVICE); |
| 1520 | − if (dma_mapping_error(ndev->dev.parent, dma_addr)) { | |
| 1521 | − dev_kfree_skb_any(skb); | |
| 1522 | − return ret; | |
| 1523 | − } | |
| 1520 | + if (dma_mapping_error(ndev->dev.parent, dma_addr)) | |
| 1521 | + goto err_kfree; | |
| 1524 | 1522 | |
| 1525 | 1523 | gq->skbs[gq->cur] = skb; |
| 1526 | 1524 | desc = &gq->tx_ring[gq->cur]; |
| @@ -1533,10 +1531,8 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd · 6 unmodified lines | ||
| 1533 | 1531 | struct rswitch_gwca_ts_info *ts_info; |
| 1534 | 1532 | |
| 1535 | 1533 | ts_info = kzalloc(sizeof(*ts_info), GFP_ATOMIC); |
| 1536 | − if (!ts_info) { | |
| 1537 | − dma_unmap_single(ndev->dev.parent, dma_addr, skb->len, DMA_TO_DEVICE); | |
| 1538 | − return -ENOMEM; | |
| 1539 | − } | |
| 1534 | + if (!ts_info) | |
| 1535 | + goto err_unmap; | |
| 1540 | 1536 | |
| 1541 | 1537 | skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; |
| 1542 | 1538 | rdev->ts_tag++; |
| @@ -1558,6 +1554,14 @@ static netdev_tx_t rswitch_start_xmit(struct sk_buff *skb, struct net_device *nd · 15 unmodified lines | ||
| 1558 | 1554 | gq->cur = rswitch_next_queue_index(gq, true, 1); |
| 1559 | 1555 | rswitch_modify(rdev->addr, GWTRC(gq->index), 0, BIT(gq->index % 32)); |
| 1560 | 1556 | |
| 1557 | + return ret; | |
| 1558 | + | |
| 1559 | +err_unmap: | |
| 1560 | + dma_unmap_single(ndev->dev.parent, dma_addr, skb->len, DMA_TO_DEVICE); | |
| 1561 | + | |
| 1562 | +err_kfree: | |
| 1563 | + dev_kfree_skb_any(skb); | |
| 1564 | + | |
| 1561 | 1565 | return ret; |
| 1562 | 1566 | } |
| 1563 | 1567 | |
| @@ -280,7 +280,7 @@ config DWMAC_INTEL · 279 unmodified lines | ||
| 280 | 280 | config DWMAC_LOONGSON |
| 281 | 281 | tristate "Loongson PCI DWMAC support" |
| 282 | 282 | default MACH_LOONGSON64 |
| 283 | − depends on STMMAC_ETH && PCI | |
| 283 | + depends on (MACH_LOONGSON64 || COMPILE_TEST) && STMMAC_ETH && PCI | |
| 284 | 284 | depends on COMMON_CLK |
| 285 | 285 | help |
| 286 | 286 | This selects the LOONGSON PCI bus support for the stmmac driver, |
| @@ -710,28 +710,22 @@ void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev, · 709 unmodified lines | ||
| 710 | 710 | } |
| 711 | 711 | } |
| 712 | 712 | |
| 713 | −void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq, | |
| 713 | +void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, | |
| 714 | + u32 num_txq, u32 num_rxq, | |
| 714 | 715 | bool enable) |
| 715 | 716 | { |
| 716 | 717 | u32 value; |
| 717 | 718 | |
| 718 | − if (!enable) { | |
| 719 | − value = readl(ioaddr + MAC_FPE_CTRL_STS); | |
| 720 | − | |
| 721 | − value &= ~EFPE; | |
| 722 | − | |
| 723 | − writel(value, ioaddr + MAC_FPE_CTRL_STS); | |
| 724 | − return; | |
| 719 | + if (enable) { | |
| 720 | + cfg->fpe_csr = EFPE; | |
| 721 | + value = readl(ioaddr + GMAC_RXQ_CTRL1); | |
| 722 | + value &= ~GMAC_RXQCTRL_FPRQ; | |
| 723 | + value |= (num_rxq - 1) << GMAC_RXQCTRL_FPRQ_SHIFT; | |
| 724 | + writel(value, ioaddr + GMAC_RXQ_CTRL1); | |
| 725 | + } else { | |
| 726 | + cfg->fpe_csr = 0; | |
| 725 | 727 | } |
| 726 | − | |
| 727 | − value = readl(ioaddr + GMAC_RXQ_CTRL1); | |
| 728 | − value &= ~GMAC_RXQCTRL_FPRQ; | |
| 729 | − value |= (num_rxq - 1) << GMAC_RXQCTRL_FPRQ_SHIFT; | |
| 730 | − writel(value, ioaddr + GMAC_RXQ_CTRL1); | |
| 731 | − | |
| 732 | − value = readl(ioaddr + MAC_FPE_CTRL_STS); | |
| 733 | − value |= EFPE; | |
| 734 | − writel(value, ioaddr + MAC_FPE_CTRL_STS); | |
| 728 | + writel(cfg->fpe_csr, ioaddr + MAC_FPE_CTRL_STS); | |
| 735 | 729 | } |
| 736 | 730 | |
| 737 | 731 | int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev) |
| @@ -741,6 +735,9 @@ int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev) · 3 unmodified lines | ||
| 741 | 735 | |
| 742 | 736 | status = FPE_EVENT_UNKNOWN; |
| 743 | 737 | |
| 738 | + /* Reads from the MAC_FPE_CTRL_STS register should only be performed | |
| 739 | + * here, since the status flags of MAC_FPE_CTRL_STS are "clear on read" | |
| 740 | + */ | |
| 744 | 741 | value = readl(ioaddr + MAC_FPE_CTRL_STS); |
| 745 | 742 | |
| 746 | 743 | if (value & TRSP) { |
| @@ -766,19 +763,15 @@ int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev) · 19 unmodified lines | ||
| 766 | 763 | return status; |
| 767 | 764 | } |
| 768 | 765 | |
| 769 | −void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, enum stmmac_mpacket_type type) | |
| 766 | +void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, | |
| 767 | + enum stmmac_mpacket_type type) | |
| 770 | 768 | { |
| 771 | − u32 value; | |
| 769 | + u32 value = cfg->fpe_csr; | |
| 772 | 770 | |
| 773 | − value = readl(ioaddr + MAC_FPE_CTRL_STS); | |
| 774 | − | |
| 775 | − if (type == MPACKET_VERIFY) { | |
| 776 | − value &= ~SRSP; | |
| 771 | + if (type == MPACKET_VERIFY) | |
| 777 | 772 | value |= SVER; |
| 778 | − } else { | |
| 779 | − value &= ~SVER; | |
| 773 | + else if (type == MPACKET_RESPONSE) | |
| 780 | 774 | value |= SRSP; |
| 781 | − } | |
| 782 | 775 | |
| 783 | 776 | writel(value, ioaddr + MAC_FPE_CTRL_STS); |
| 784 | 777 | } |
| @@ -153,9 +153,11 @@ int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, · 152 unmodified lines | ||
| 153 | 153 | unsigned int ptp_rate); |
| 154 | 154 | void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev, |
| 155 | 155 | struct stmmac_extra_stats *x, u32 txqcnt); |
| 156 | −void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq, | |
| 156 | +void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, | |
| 157 | + u32 num_txq, u32 num_rxq, | |
| 157 | 158 | bool enable); |
| 158 | 159 | void dwmac5_fpe_send_mpacket(void __iomem *ioaddr, |
| 160 | + struct stmmac_fpe_cfg *cfg, | |
| 159 | 161 | enum stmmac_mpacket_type type); |
| 160 | 162 | int dwmac5_fpe_irq_status(void __iomem *ioaddr, struct net_device *dev); |
| 161 | 163 | |
| @@ -1484,7 +1484,8 @@ static int dwxgmac3_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg, · 1483 unmodified lines | ||
| 1484 | 1484 | return 0; |
| 1485 | 1485 | } |
| 1486 | 1486 | |
| 1487 | −static void dwxgmac3_fpe_configure(void __iomem *ioaddr, u32 num_txq, | |
| 1487 | +static void dwxgmac3_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, | |
| 1488 | + u32 num_txq, | |
| 1488 | 1489 | u32 num_rxq, bool enable) |
| 1489 | 1490 | { |
| 1490 | 1491 | u32 value; |
| @@ -412,9 +412,11 @@ struct stmmac_ops { · 411 unmodified lines | ||
| 412 | 412 | unsigned int ptp_rate); |
| 413 | 413 | void (*est_irq_status)(void __iomem *ioaddr, struct net_device *dev, |
| 414 | 414 | struct stmmac_extra_stats *x, u32 txqcnt); |
| 415 | − void (*fpe_configure)(void __iomem *ioaddr, u32 num_txq, u32 num_rxq, | |
| 415 | + void (*fpe_configure)(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg, | |
| 416 | + u32 num_txq, u32 num_rxq, | |
| 416 | 417 | bool enable); |
| 417 | 418 | void (*fpe_send_mpacket)(void __iomem *ioaddr, |
| 419 | + struct stmmac_fpe_cfg *cfg, | |
| 418 | 420 | enum stmmac_mpacket_type type); |
| 419 | 421 | int (*fpe_irq_status)(void __iomem *ioaddr, struct net_device *dev); |
| 420 | 422 | }; |
| @@ -177,8 +177,10 @@ · 176 unmodified lines | ||
| 177 | 177 | #define MMC_XGMAC_RX_DISCARD_OCT_GB 0x1b4 |
| 178 | 178 | #define MMC_XGMAC_RX_ALIGN_ERR_PKT 0x1bc |
| 179 | 179 | |
| 180 | +#define MMC_XGMAC_TX_FPE_INTR_MASK 0x204 | |
| 180 | 181 | #define MMC_XGMAC_TX_FPE_FRAG 0x208 |
| 181 | 182 | #define MMC_XGMAC_TX_HOLD_REQ 0x20c |
| 183 | +#define MMC_XGMAC_RX_FPE_INTR_MASK 0x224 | |
| 182 | 184 | #define MMC_XGMAC_RX_PKT_ASSEMBLY_ERR 0x228 |
| 183 | 185 | #define MMC_XGMAC_RX_PKT_SMD_ERR 0x22c |
| 184 | 186 | #define MMC_XGMAC_RX_PKT_ASSEMBLY_OK 0x230 |
| @@ -352,6 +354,8 @@ static void dwxgmac_mmc_intr_all_mask(void __iomem *mmcaddr) · 167 unmodified lines | ||
| 352 | 354 | { |
| 353 | 355 | writel(0x0, mmcaddr + MMC_RX_INTR_MASK); |
| 354 | 356 | writel(0x0, mmcaddr + MMC_TX_INTR_MASK); |
| 357 | + writel(MMC_DEFAULT_MASK, mmcaddr + MMC_XGMAC_TX_FPE_INTR_MASK); | |
| 358 | + writel(MMC_DEFAULT_MASK, mmcaddr + MMC_XGMAC_RX_FPE_INTR_MASK); | |
| 355 | 359 | writel(MMC_DEFAULT_MASK, mmcaddr + MMC_XGMAC_RX_IPC_INTR_MASK); |
| 356 | 360 | } |
| 357 | 361 | |
| @@ -964,7 +964,8 @@ static void stmmac_fpe_link_state_handle(struct stmmac_priv *priv, bool is_up) · 963 unmodified lines | ||
| 964 | 964 | bool *hs_enable = &fpe_cfg->hs_enable; |
| 965 | 965 | |
| 966 | 966 | if (is_up && *hs_enable) { |
| 967 | − stmmac_fpe_send_mpacket(priv, priv->ioaddr, MPACKET_VERIFY); | |
| 967 | + stmmac_fpe_send_mpacket(priv, priv->ioaddr, fpe_cfg, | |
| 968 | + MPACKET_VERIFY); | |
| 968 | 969 | } else { |
| 969 | 970 | *lo_state = FPE_STATE_OFF; |
| 970 | 971 | *lp_state = FPE_STATE_OFF; |
| @@ -5293,6 +5294,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) · 4322 unmodified lines | ||
| 5293 | 5294 | |
| 5294 | 5295 | dma_dir = page_pool_get_dma_dir(rx_q->page_pool); |
| 5295 | 5296 | buf_sz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE; |
| 5297 | + limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit); | |
| 5296 | 5298 | |
| 5297 | 5299 | if (netif_msg_rx_status(priv)) { |
| 5298 | 5300 | void *rx_head; |
| @@ -5328,10 +5330,10 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue) · 29 unmodified lines | ||
| 5328 | 5330 | len = 0; |
| 5329 | 5331 | } |
| 5330 | 5332 | |
| 5333 | +read_again: | |
| 5331 | 5334 | if (count >= limit) |
| 5332 | 5335 | break; |
| 5333 | 5336 | |
| 5334 | −read_again: | |
| 5335 | 5337 | buf1_len = 0; |
| 5336 | 5338 | buf2_len = 0; |
| 5337 | 5339 | entry = next_entry; |
| @@ -5838,6 +5840,7 @@ static void stmmac_fpe_event_status(struct stmmac_priv *priv, int status) · 500 unmodified lines | ||
| 5838 | 5840 | /* If user has requested FPE enable, quickly response */ |
| 5839 | 5841 | if (*hs_enable) |
| 5840 | 5842 | stmmac_fpe_send_mpacket(priv, priv->ioaddr, |
| 5843 | + fpe_cfg, | |
| 5841 | 5844 | MPACKET_RESPONSE); |
| 5842 | 5845 | } |
| 5843 | 5846 | |
| @@ -7262,6 +7265,7 @@ static void stmmac_fpe_lp_task(struct work_struct *work) · 1418 unmodified lines | ||
| 7262 | 7265 | if (*lo_state == FPE_STATE_ENTERING_ON && |
| 7263 | 7266 | *lp_state == FPE_STATE_ENTERING_ON) { |
| 7264 | 7267 | stmmac_fpe_configure(priv, priv->ioaddr, |
| 7268 | + fpe_cfg, | |
| 7265 | 7269 | priv->plat->tx_queues_to_use, |
| 7266 | 7270 | priv->plat->rx_queues_to_use, |
| 7267 | 7271 | *enable); |
| @@ -7280,6 +7284,7 @@ static void stmmac_fpe_lp_task(struct work_struct *work) · 12 unmodified lines | ||
| 7280 | 7284 | netdev_info(priv->dev, SEND_VERIFY_MPAKCET_FMT, |
| 7281 | 7285 | *lo_state, *lp_state); |
| 7282 | 7286 | stmmac_fpe_send_mpacket(priv, priv->ioaddr, |
| 7287 | + fpe_cfg, | |
| 7283 | 7288 | MPACKET_VERIFY); |
| 7284 | 7289 | } |
| 7285 | 7290 | /* Sleep then retry */ |
| @@ -7294,6 +7299,7 @@ void stmmac_fpe_handshake(struct stmmac_priv *priv, bool enable) · 8 unmodified lines | ||
| 7294 | 7299 | if (priv->plat->fpe_cfg->hs_enable != enable) { |
| 7295 | 7300 | if (enable) { |
| 7296 | 7301 | stmmac_fpe_send_mpacket(priv, priv->ioaddr, |
| 7302 | + priv->plat->fpe_cfg, | |
| 7297 | 7303 | MPACKET_VERIFY); |
| 7298 | 7304 | } else { |
| 7299 | 7305 | priv->plat->fpe_cfg->lo_fpe_state = FPE_STATE_OFF; |
| @@ -7754,6 +7760,7 @@ int stmmac_suspend(struct device *dev) · 454 unmodified lines | ||
| 7754 | 7760 | if (priv->dma_cap.fpesel) { |
| 7755 | 7761 | /* Disable FPE */ |
| 7756 | 7762 | stmmac_fpe_configure(priv, priv->ioaddr, |
| 7763 | + priv->plat->fpe_cfg, | |
| 7757 | 7764 | priv->plat->tx_queues_to_use, |
| 7758 | 7765 | priv->plat->rx_queues_to_use, false); |
| 7759 | 7766 | |
| @@ -1079,6 +1079,7 @@ disable: · 1078 unmodified lines | ||
| 1079 | 1079 | |
| 1080 | 1080 | priv->plat->fpe_cfg->enable = false; |
| 1081 | 1081 | stmmac_fpe_configure(priv, priv->ioaddr, |
| 1082 | + priv->plat->fpe_cfg, | |
| 1082 | 1083 | priv->plat->tx_queues_to_use, |
| 1083 | 1084 | priv->plat->rx_queues_to_use, |
| 1084 | 1085 | false); |
| @@ -2063,7 +2063,7 @@ static int prueth_probe(struct platform_device *pdev) · 2062 unmodified lines | ||
| 2063 | 2063 | &prueth->shram); |
| 2064 | 2064 | if (ret) { |
| 2065 | 2065 | dev_err(dev, "unable to get PRUSS SHRD RAM2: %d\n", ret); |
| 2066 | − pruss_put(prueth->pruss); | |
| 2066 | + goto put_pruss; | |
| 2067 | 2067 | } |
| 2068 | 2068 | |
| 2069 | 2069 | prueth->sram_pool = of_gen_pool_get(np, "sram", 0); |
| @@ -2105,10 +2105,7 @@ static int prueth_probe(struct platform_device *pdev) · 35 unmodified lines | ||
| 2105 | 2105 | prueth->iep1 = icss_iep_get_idx(np, 1); |
| 2106 | 2106 | if (IS_ERR(prueth->iep1)) { |
| 2107 | 2107 | ret = dev_err_probe(dev, PTR_ERR(prueth->iep1), "iep1 get failed\n"); |
| 2108 | − icss_iep_put(prueth->iep0); | |
| 2109 | − prueth->iep0 = NULL; | |
| 2110 | − prueth->iep1 = NULL; | |
| 2111 | − goto free_pool; | |
| 2108 | + goto put_iep0; | |
| 2112 | 2109 | } |
| 2113 | 2110 | |
| 2114 | 2111 | if (prueth->pdata.quirk_10m_link_issue) { |
| @@ -2205,6 +2202,12 @@ netdev_exit: · 90 unmodified lines | ||
| 2205 | 2202 | exit_iep: |
| 2206 | 2203 | if (prueth->pdata.quirk_10m_link_issue) |
| 2207 | 2204 | icss_iep_exit_fw(prueth->iep1); |
| 2205 | + icss_iep_put(prueth->iep1); | |
| 2206 | + | |
| 2207 | +put_iep0: | |
| 2208 | + icss_iep_put(prueth->iep0); | |
| 2209 | + prueth->iep0 = NULL; | |
| 2210 | + prueth->iep1 = NULL; | |
| 2208 | 2211 | |
| 2209 | 2212 | free_pool: |
| 2210 | 2213 | gen_pool_free(prueth->sram_pool, |
| @@ -2212,6 +2215,8 @@ free_pool: · 1 unmodified line | ||
| 2212 | 2215 | |
| 2213 | 2216 | put_mem: |
| 2214 | 2217 | pruss_release_mem_region(prueth->pruss, &prueth->shram); |
| 2218 | + | |
| 2219 | +put_pruss: | |
| 2215 | 2220 | pruss_put(prueth->pruss); |
| 2216 | 2221 | |
| 2217 | 2222 | put_cores: |
| @@ -1769,10 +1769,12 @@ int wx_sw_init(struct wx *wx) · 1768 unmodified lines | ||
| 1769 | 1769 | wx->subsystem_device_id = pdev->subsystem_device; |
| 1770 | 1770 | } else { |
| 1771 | 1771 | err = wx_flash_read_dword(wx, 0xfffdc, &ssid); |
| 1772 | − if (!err) | |
| 1773 | − wx->subsystem_device_id = swab16((u16)ssid); | |
| 1772 | + if (err < 0) { | |
| 1773 | + wx_err(wx, "read of internal subsystem device id failed\n"); | |
| 1774 | + return err; | |
| 1775 | + } | |
| 1774 | 1776 | |
| 1775 | − return err; | |
| 1777 | + wx->subsystem_device_id = swab16((u16)ssid); | |
| 1776 | 1778 | } |
| 1777 | 1779 | |
| 1778 | 1780 | wx->mac_table = kcalloc(wx->mac.num_rar_entries, |
| @@ -1972,11 +1972,11 @@ void wx_reset_interrupt_capability(struct wx *wx) · 1971 unmodified lines | ||
| 1972 | 1972 | if (!pdev->msi_enabled && !pdev->msix_enabled) |
| 1973 | 1973 | return; |
| 1974 | 1974 | |
| 1975 | − pci_free_irq_vectors(wx->pdev); | |
| 1976 | 1975 | if (pdev->msix_enabled) { |
| 1977 | 1976 | kfree(wx->msix_entries); |
| 1978 | 1977 | wx->msix_entries = NULL; |
| 1979 | 1978 | } |
| 1979 | + pci_free_irq_vectors(wx->pdev); | |
| 1980 | 1980 | } |
| 1981 | 1981 | EXPORT_SYMBOL(wx_reset_interrupt_capability); |
| 1982 | 1982 | |
| @@ -121,10 +121,8 @@ static int ngbe_sw_init(struct wx *wx) · 120 unmodified lines | ||
| 121 | 121 | |
| 122 | 122 | /* PCI config space info */ |
| 123 | 123 | err = wx_sw_init(wx); |
| 124 | − if (err < 0) { | |
| 125 | − wx_err(wx, "read of internal subsystem device id failed\n"); | |
| 124 | + if (err < 0) | |
| 126 | 125 | return err; |
| 127 | − } | |
| 128 | 126 | |
| 129 | 127 | /* mac type, phy type , oem type */ |
| 130 | 128 | ngbe_init_type_code(wx); |
| @@ -364,10 +364,8 @@ static int txgbe_sw_init(struct wx *wx) · 363 unmodified lines | ||
| 364 | 364 | |
| 365 | 365 | /* PCI config space info */ |
| 366 | 366 | err = wx_sw_init(wx); |
| 367 | − if (err < 0) { | |
| 368 | − wx_err(wx, "read of internal subsystem device id failed\n"); | |
| 367 | + if (err < 0) | |
| 369 | 368 | return err; |
| 370 | − } | |
| 371 | 369 | |
| 372 | 370 | txgbe_init_type_code(wx); |
| 373 | 371 | |
| @@ -822,7 +822,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 821 unmodified lines | ||
| 822 | 822 | if (lp->features & XAE_FEATURE_FULL_TX_CSUM) { |
| 823 | 823 | /* Tx Full Checksum Offload Enabled */ |
| 824 | 824 | cur_p->app0 |= 2; |
| 825 | − } else if (lp->features & XAE_FEATURE_PARTIAL_RX_CSUM) { | |
| 825 | + } else if (lp->features & XAE_FEATURE_PARTIAL_TX_CSUM) { | |
| 826 | 826 | csum_start_off = skb_transport_offset(skb); |
| 827 | 827 | csum_index_off = csum_start_off + skb->csum_offset; |
| 828 | 828 | /* Tx Partial Checksum Offload Enabled */ |
| @@ -3,5 +3,6 @@ config HYPERV_NET · 2 unmodified lines | ||
| 3 | 3 | tristate "Microsoft Hyper-V virtual network driver" |
| 4 | 4 | depends on HYPERV |
| 5 | 5 | select UCS2_STRING |
| 6 | + select NLS | |
| 6 | 7 | help |
| 7 | 8 | Select this option to enable the Hyper-V virtual network driver. |
| @@ -2206,9 +2206,6 @@ static int netvsc_vf_join(struct net_device *vf_netdev, · 2205 unmodified lines | ||
| 2206 | 2206 | goto upper_link_failed; |
| 2207 | 2207 | } |
| 2208 | 2208 | |
| 2209 | − /* set slave flag before open to prevent IPv6 addrconf */ | |
| 2210 | − vf_netdev->flags |= IFF_SLAVE; | |
| 2211 | − | |
| 2212 | 2209 | schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT); |
| 2213 | 2210 | |
| 2214 | 2211 | call_netdevice_notifiers(NETDEV_JOIN, vf_netdev); |
| @@ -2315,16 +2312,18 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev) · 100 unmodified lines | ||
| 2315 | 2312 | |
123 more lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 75 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 89 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 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 12 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 32 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 347 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 20 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 9 lines aren’t shown here.
This diff is large: its 42 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 33 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 1326 lines aren’t shown here.
This diff is large: its 762 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 11 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 27 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 72 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 12 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 77 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 14 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 297 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 30 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 16 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 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 78 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 42 lines aren’t shown here.
This diff is large: its 46 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 42 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 23 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 90 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 22 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 1256 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 6 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 11 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 11 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 251 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 186 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 37 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 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 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 99 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 47 lines aren’t shown here.
This diff is large: its 203 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 32 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 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 58 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 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 38 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 9 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 29 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 19 lines aren’t shown here.
This diff is large: its 167 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 49 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 133 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 13 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 48 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 11 lines aren’t shown here.
This diff is large: its 238 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 227 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 202 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 402 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 483 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 206 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 91 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 20 lines aren’t shown here.
This diff is large: its 180 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 41 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 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 50 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 9 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 49 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 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 22 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 9 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 16 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 34 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 20 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 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 25 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 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 51 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 12 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 25 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 8 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 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 32 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 245 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 292 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 18 lines aren’t shown here.
This diff is large: its 42 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 92 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 859 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 149 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 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 214 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 273 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 46 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 78 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 37 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 21 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 14 lines aren’t shown here.
This diff is large: its 78 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 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 78 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 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 36 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 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 7 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 226 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 6 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 33 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 37 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 25 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 18 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 15 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 6 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 42 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 10 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 171 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 208 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 35 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 47 lines aren’t shown here.
This diff is large: its 32 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 9 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 203 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 120 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 58 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 39 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 16 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 35 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 25 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 10 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 502 lines aren’t shown here.
This diff is large: its 289 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 38 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 9 lines aren’t shown here.
This diff is large: its 20 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 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 4073 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 118 lines aren’t shown here.
This diff is large: its 103 lines aren’t shown here.
This diff is large: its 498 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 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 220 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 148 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 50 lines aren’t shown here.
This diff is large: its 32 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 5 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 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 9 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.