b0dacee8 parents ee53543 de78657 8b9ad48 b11deb2 cae8d1f 0d647b3 42bb5aa fa7e9ec787 files · +9031 −4685Browse filesUnified · Split
| @@ -45,6 +45,7 @@ Andrey Konovalov <andreyknvl@gmail.com> <andreyknvl@google.com> · 44 unmodified lines | |||
| 45 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com> | 45 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com> |
| 46 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com> | 46 | Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com> |
| 47 | Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com> | 47 | Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com> |
| 48 | André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com> | ||
| 48 | Andy Adamson <andros@citi.umich.edu> | 49 | Andy Adamson <andros@citi.umich.edu> |
| 49 | Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com> | 50 | Antoine Tenart <atenart@kernel.org> <antoine.tenart@bootlin.com> |
| 50 | Antoine Tenart <atenart@kernel.org> <antoine.tenart@free-electrons.com> | 51 | Antoine Tenart <atenart@kernel.org> <antoine.tenart@free-electrons.com> |
| @@ -204,6 +205,7 @@ Juha Yrjola <at solidboot.com> · 153 unmodified lines | |||
| 204 | Juha Yrjola <juha.yrjola@nokia.com> | 205 | Juha Yrjola <juha.yrjola@nokia.com> |
| 205 | Juha Yrjola <juha.yrjola@solidboot.com> | 206 | Juha Yrjola <juha.yrjola@solidboot.com> |
| 206 | Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com> | 207 | Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com> |
| 208 | Kalle Valo <kvalo@kernel.org> <kvalo@codeaurora.org> | ||
| 207 | Kalyan Thota <quic_kalyant@quicinc.com> <kalyan_t@codeaurora.org> | 209 | Kalyan Thota <quic_kalyant@quicinc.com> <kalyan_t@codeaurora.org> |
| 208 | Kay Sievers <kay.sievers@vrfy.org> | 210 | Kay Sievers <kay.sievers@vrfy.org> |
| 209 | Kees Cook <keescook@chromium.org> <kees.cook@canonical.com> | 211 | Kees Cook <keescook@chromium.org> <kees.cook@canonical.com> |
| @@ -249,6 +251,7 @@ Mark Yao <markyao0591@gmail.com> <mark.yao@rock-chips.com> · 39 unmodified lines | |||
| 249 | Martin Kepplinger <martink@posteo.de> <martin.kepplinger@ginzinger.com> | 251 | Martin Kepplinger <martink@posteo.de> <martin.kepplinger@ginzinger.com> |
| 250 | Martin Kepplinger <martink@posteo.de> <martin.kepplinger@puri.sm> | 252 | Martin Kepplinger <martink@posteo.de> <martin.kepplinger@puri.sm> |
| 251 | Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com> | 253 | Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com> |
| 254 | Martyna Szapar-Mudlaw <martyna.szapar-mudlaw@linux.intel.com> <martyna.szapar-mudlaw@intel.com> | ||
| 252 | Mathieu Othacehe <m.othacehe@gmail.com> | 255 | Mathieu Othacehe <m.othacehe@gmail.com> |
| 253 | Matthew Wilcox <willy@infradead.org> <matthew.r.wilcox@intel.com> | 256 | Matthew Wilcox <willy@infradead.org> <matthew.r.wilcox@intel.com> |
| 254 | Matthew Wilcox <willy@infradead.org> <matthew@wil.cx> | 257 | Matthew Wilcox <willy@infradead.org> <matthew@wil.cx> |
| @@ -228,10 +228,10 @@ Core dump support · 227 unmodified lines | |||
| 228 | ----------------- | 228 | ----------------- |
| 229 | 229 | ||
| 230 | The allocation tags for user memory mapped with ``PROT_MTE`` are dumped | 230 | The allocation tags for user memory mapped with ``PROT_MTE`` are dumped |
| 231 | in the core file as additional ``PT_ARM_MEMTAG_MTE`` segments. The | 231 | in the core file as additional ``PT_AARCH64_MEMTAG_MTE`` segments. The |
| 232 | program header for such segment is defined as: | 232 | program header for such segment is defined as: |
| 233 | 233 | ||
| 234 | :``p_type``: ``PT_ARM_MEMTAG_MTE`` | 234 | :``p_type``: ``PT_AARCH64_MEMTAG_MTE`` |
| 235 | :``p_flags``: 0 | 235 | :``p_flags``: 0 |
| 236 | :``p_offset``: segment file offset | 236 | :``p_offset``: segment file offset |
| 237 | :``p_vaddr``: segment virtual address, same as the corresponding | 237 | :``p_vaddr``: segment virtual address, same as the corresponding |
| @@ -189,6 +189,9 @@ stable kernels. · 188 unmodified lines | |||
| 189 | +----------------+-----------------+-----------------+-----------------------------+ | 189 | +----------------+-----------------+-----------------+-----------------------------+ |
| 190 | | Qualcomm Tech. | Kryo4xx Silver | N/A | ARM64_ERRATUM_1024718 | | 190 | | Qualcomm Tech. | Kryo4xx Silver | N/A | ARM64_ERRATUM_1024718 | |
| 191 | +----------------+-----------------+-----------------+-----------------------------+ | 191 | +----------------+-----------------+-----------------+-----------------------------+ |
| 192 | | Qualcomm Tech. | Kryo4xx Gold | N/A | ARM64_ERRATUM_1286807 | | ||
| 193 | +----------------+-----------------+-----------------+-----------------------------+ | ||
| 194 | |||
| 192 | +----------------+-----------------+-----------------+-----------------------------+ | 195 | +----------------+-----------------+-----------------+-----------------------------+ |
| 193 | | Fujitsu | A64FX | E#010001 | FUJITSU_ERRATUM_010001 | | 196 | | Fujitsu | A64FX | E#010001 | FUJITSU_ERRATUM_010001 | |
| 194 | +----------------+-----------------+-----------------+-----------------------------+ | 197 | +----------------+-----------------+-----------------+-----------------------------+ |
| @@ -55,8 +55,6 @@ allOf: · 54 unmodified lines | |||
| 55 | then: | 55 | then: |
| 56 | properties: | 56 | properties: |
| 57 | clocks: | 57 | clocks: |
| 58 | minItems: 7 | ||
| 59 | maxItems: 7 | ||
| 60 | items: | 58 | items: |
| 61 | - description: 32k osc | 59 | - description: 32k osc |
| 62 | - description: 25m osc | 60 | - description: 25m osc |
| @@ -66,8 +64,6 @@ allOf: · 3 unmodified lines | |||
| 66 | - description: ext3 clock input | 64 | - description: ext3 clock input |
| 67 | - description: ext4 clock input | 65 | - description: ext4 clock input |
| 68 | clock-names: | 66 | clock-names: |
| 69 | minItems: 7 | ||
| 70 | maxItems: 7 | ||
| 71 | items: | 67 | items: |
| 72 | - const: ckil | 68 | - const: ckil |
| 73 | - const: osc_25m | 69 | - const: osc_25m |
| @@ -22,7 +22,16 @@ properties: · 21 unmodified lines | |||
| 22 | const: microchip,mpfs-clkcfg | 22 | const: microchip,mpfs-clkcfg |
| 23 | 23 | ||
| 24 | reg: | 24 | reg: |
| 25 | maxItems: 1 | 25 | items: |
| 26 | - description: | | ||
| 27 | clock config registers: | ||
| 28 | These registers contain enable, reset & divider tables for the, cpu, | ||
| 29 | axi, ahb and rtc/mtimer reference clocks as well as enable and reset | ||
| 30 | for the peripheral clocks. | ||
| 31 | - description: | | ||
| 32 | mss pll dri registers: | ||
| 33 | Block of registers responsible for dynamic reconfiguration of the mss | ||
| 34 | pll | ||
| 26 | 35 | ||
| 27 | clocks: | 36 | clocks: |
| 28 | maxItems: 1 | 37 | maxItems: 1 |
| @@ -51,7 +60,7 @@ examples: · 22 unmodified lines | |||
| 51 | #size-cells = <2>; | 60 | #size-cells = <2>; |
| 52 | clkcfg: clock-controller@20002000 { | 61 | clkcfg: clock-controller@20002000 { |
| 53 | compatible = "microchip,mpfs-clkcfg"; | 62 | compatible = "microchip,mpfs-clkcfg"; |
| 54 | reg = <0x0 0x20002000 0x0 0x1000>; | 63 | reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>; |
| 55 | clocks = <&ref>; | 64 | clocks = <&ref>; |
| 56 | #clock-cells = <1>; | 65 | #clock-cells = <1>; |
| 57 | }; | 66 | }; |
| @@ -95,7 +95,6 @@ then: · 94 unmodified lines | |||
| 95 | properties: | 95 | properties: |
| 96 | clocks: | 96 | clocks: |
| 97 | minItems: 1 | 97 | minItems: 1 |
| 98 | maxItems: 4 | ||
| 99 | items: | 98 | items: |
| 100 | - description: Functional clock | 99 | - description: Functional clock |
| 101 | - description: EXTAL input clock | 100 | - description: EXTAL input clock |
| @@ -104,7 +103,6 @@ then: · 2 unmodified lines | |||
| 104 | 103 | ||
| 105 | clock-names: | 104 | clock-names: |
| 106 | minItems: 1 | 105 | minItems: 1 |
| 107 | maxItems: 4 | ||
| 108 | items: | 106 | items: |
| 109 | - const: fck | 107 | - const: fck |
| 110 | # The LVDS encoder can use the EXTAL or DU_DOTCLKINx clocks. | 108 | # The LVDS encoder can use the EXTAL or DU_DOTCLKINx clocks. |
| @@ -128,12 +126,10 @@ then: · 17 unmodified lines | |||
| 128 | else: | 126 | else: |
| 129 | properties: | 127 | properties: |
| 130 | clocks: | 128 | clocks: |
| 131 | maxItems: 1 | ||
| 132 | items: | 129 | items: |
| 133 | - description: Functional clock | 130 | - description: Functional clock |
| 134 | 131 | ||
| 135 | clock-names: | 132 | clock-names: |
| 136 | maxItems: 1 | ||
| 137 | items: | 133 | items: |
| 138 | - const: fck | 134 | - const: fck |
| 139 | 135 | ||
| @@ -109,7 +109,6 @@ allOf: · 108 unmodified lines | |||
| 109 | properties: | 109 | properties: |
| 110 | clocks: | 110 | clocks: |
| 111 | minItems: 1 | 111 | minItems: 1 |
| 112 | maxItems: 3 | ||
| 113 | items: | 112 | items: |
| 114 | - description: Functional clock | 113 | - description: Functional clock |
| 115 | - description: DU_DOTCLKIN0 input clock | 114 | - description: DU_DOTCLKIN0 input clock |
| @@ -117,7 +116,6 @@ allOf: · 1 unmodified line | |||
| 117 | 116 | ||
| 118 | clock-names: | 117 | clock-names: |
| 119 | minItems: 1 | 118 | minItems: 1 |
| 120 | maxItems: 3 | ||
| 121 | items: | 119 | items: |
| 122 | - const: du.0 | 120 | - const: du.0 |
| 123 | - pattern: '^dclkin\.[01]$' | 121 | - pattern: '^dclkin\.[01]$' |
| @@ -159,7 +157,6 @@ allOf: · 35 unmodified lines | |||
| 159 | properties: | 157 | properties: |
| 160 | clocks: | 158 | clocks: |
| 161 | minItems: 2 | 159 | minItems: 2 |
| 162 | maxItems: 4 | ||
| 163 | items: | 160 | items: |
| 164 | - description: Functional clock for DU0 | 161 | - description: Functional clock for DU0 |
| 165 | - description: Functional clock for DU1 | 162 | - description: Functional clock for DU1 |
| @@ -168,7 +165,6 @@ allOf: · 2 unmodified lines | |||
| 168 | 165 | ||
| 169 | clock-names: | 166 | clock-names: |
| 170 | minItems: 2 | 167 | minItems: 2 |
| 171 | maxItems: 4 | ||
| 172 | items: | 168 | items: |
| 173 | - const: du.0 | 169 | - const: du.0 |
| 174 | - const: du.1 | 170 | - const: du.1 |
| @@ -216,7 +212,6 @@ allOf: · 41 unmodified lines | |||
| 216 | properties: | 212 | properties: |
| 217 | clocks: | 213 | clocks: |
| 218 | minItems: 2 | 214 | minItems: 2 |
| 219 | maxItems: 4 | ||
| 220 | items: | 215 | items: |
| 221 | - description: Functional clock for DU0 | 216 | - description: Functional clock for DU0 |
| 222 | - description: Functional clock for DU1 | 217 | - description: Functional clock for DU1 |
| @@ -225,7 +220,6 @@ allOf: · 2 unmodified lines | |||
| 225 | 220 | ||
| 226 | clock-names: | 221 | clock-names: |
| 227 | minItems: 2 | 222 | minItems: 2 |
| 228 | maxItems: 4 | ||
| 229 | items: | 223 | items: |
| 230 | - const: du.0 | 224 | - const: du.0 |
| 231 | - const: du.1 | 225 | - const: du.1 |
| @@ -271,7 +265,6 @@ allOf: · 39 unmodified lines | |||
| 271 | properties: | 265 | properties: |
| 272 | clocks: | 266 | clocks: |
| 273 | minItems: 2 | 267 | minItems: 2 |
| 274 | maxItems: 4 | ||
| 275 | items: | 268 | items: |
| 276 | - description: Functional clock for DU0 | 269 | - description: Functional clock for DU0 |
| 277 | - description: Functional clock for DU1 | 270 | - description: Functional clock for DU1 |
| @@ -280,7 +273,6 @@ allOf: · 2 unmodified lines | |||
| 280 | 273 | ||
| 281 | clock-names: | 274 | clock-names: |
| 282 | minItems: 2 | 275 | minItems: 2 |
| 283 | maxItems: 4 | ||
| 284 | items: | 276 | items: |
| 285 | - const: du.0 | 277 | - const: du.0 |
| 286 | - const: du.1 | 278 | - const: du.1 |
| @@ -327,7 +319,6 @@ allOf: · 40 unmodified lines | |||
| 327 | properties: | 319 | properties: |
| 328 | clocks: | 320 | clocks: |
| 329 | minItems: 2 | 321 | minItems: 2 |
| 330 | maxItems: 4 | ||
| 331 | items: | 322 | items: |
| 332 | - description: Functional clock for DU0 | 323 | - description: Functional clock for DU0 |
| 333 | - description: Functional clock for DU1 | 324 | - description: Functional clock for DU1 |
| @@ -336,7 +327,6 @@ allOf: · 2 unmodified lines | |||
| 336 | 327 | ||
| 337 | clock-names: | 328 | clock-names: |
| 338 | minItems: 2 | 329 | minItems: 2 |
| 339 | maxItems: 4 | ||
| 340 | items: | 330 | items: |
| 341 | - const: du.0 | 331 | - const: du.0 |
| 342 | - const: du.1 | 332 | - const: du.1 |
| @@ -386,7 +376,6 @@ allOf: · 43 unmodified lines | |||
| 386 | properties: | 376 | properties: |
| 387 | clocks: | 377 | clocks: |
| 388 | minItems: 3 | 378 | minItems: 3 |
| 389 | maxItems: 6 | ||
| 390 | items: | 379 | items: |
| 391 | - description: Functional clock for DU0 | 380 | - description: Functional clock for DU0 |
| 392 | - description: Functional clock for DU1 | 381 | - description: Functional clock for DU1 |
| @@ -397,7 +386,6 @@ allOf: · 4 unmodified lines | |||
| 397 | 386 | ||
| 398 | clock-names: | 387 | clock-names: |
| 399 | minItems: 3 | 388 | minItems: 3 |
| 400 | maxItems: 6 | ||
| 401 | items: | 389 | items: |
| 402 | - const: du.0 | 390 | - const: du.0 |
| 403 | - const: du.1 | 391 | - const: du.1 |
| @@ -448,7 +436,6 @@ allOf: · 44 unmodified lines | |||
| 448 | properties: | 436 | properties: |
| 449 | clocks: | 437 | clocks: |
| 450 | minItems: 4 | 438 | minItems: 4 |
| 451 | maxItems: 8 | ||
| 452 | items: | 439 | items: |
| 453 | - description: Functional clock for DU0 | 440 | - description: Functional clock for DU0 |
| 454 | - description: Functional clock for DU1 | 441 | - description: Functional clock for DU1 |
| @@ -461,7 +448,6 @@ allOf: · 6 unmodified lines | |||
| 461 | 448 | ||
| 462 | clock-names: | 449 | clock-names: |
| 463 | minItems: 4 | 450 | minItems: 4 |
| 464 | maxItems: 8 | ||
| 465 | items: | 451 | items: |
| 466 | - const: du.0 | 452 | - const: du.0 |
| 467 | - const: du.1 | 453 | - const: du.1 |
| @@ -525,7 +511,6 @@ allOf: · 57 unmodified lines | |||
| 525 | properties: | 511 | properties: |
| 526 | clocks: | 512 | clocks: |
| 527 | minItems: 3 | 513 | minItems: 3 |
| 528 | maxItems: 6 | ||
| 529 | items: | 514 | items: |
| 530 | - description: Functional clock for DU0 | 515 | - description: Functional clock for DU0 |
| 531 | - description: Functional clock for DU1 | 516 | - description: Functional clock for DU1 |
| @@ -536,7 +521,6 @@ allOf: · 4 unmodified lines | |||
| 536 | 521 | ||
| 537 | clock-names: | 522 | clock-names: |
| 538 | minItems: 3 | 523 | minItems: 3 |
| 539 | maxItems: 6 | ||
| 540 | items: | 524 | items: |
| 541 | - const: du.0 | 525 | - const: du.0 |
| 542 | - const: du.1 | 526 | - const: du.1 |
| @@ -596,7 +580,6 @@ allOf: · 53 unmodified lines | |||
| 596 | properties: | 580 | properties: |
| 597 | clocks: | 581 | clocks: |
| 598 | minItems: 3 | 582 | minItems: 3 |
| 599 | maxItems: 6 | ||
| 600 | items: | 583 | items: |
| 601 | - description: Functional clock for DU0 | 584 | - description: Functional clock for DU0 |
| 602 | - description: Functional clock for DU1 | 585 | - description: Functional clock for DU1 |
| @@ -607,7 +590,6 @@ allOf: · 4 unmodified lines | |||
| 607 | 590 | ||
| 608 | clock-names: | 591 | clock-names: |
| 609 | minItems: 3 | 592 | minItems: 3 |
| 610 | maxItems: 6 | ||
| 611 | items: | 593 | items: |
| 612 | - const: du.0 | 594 | - const: du.0 |
| 613 | - const: du.1 | 595 | - const: du.1 |
| @@ -666,14 +648,12 @@ allOf: · 52 unmodified lines | |||
| 666 | properties: | 648 | properties: |
| 667 | clocks: | 649 | clocks: |
| 668 | minItems: 1 | 650 | minItems: 1 |
| 669 | maxItems: 2 | ||
| 670 | items: | 651 | items: |
| 671 | - description: Functional clock for DU0 | 652 | - description: Functional clock for DU0 |
| 672 | - description: DU_DOTCLKIN0 input clock | 653 | - description: DU_DOTCLKIN0 input clock |
| 673 | 654 | ||
| 674 | clock-names: | 655 | clock-names: |
| 675 | minItems: 1 | 656 | minItems: 1 |
| 676 | maxItems: 2 | ||
| 677 | items: | 657 | items: |
| 678 | - const: du.0 | 658 | - const: du.0 |
| 679 | - const: dclkin.0 | 659 | - const: dclkin.0 |
| @@ -723,7 +703,6 @@ allOf: · 43 unmodified lines | |||
| 723 | properties: | 703 | properties: |
| 724 | clocks: | 704 | clocks: |
| 725 | minItems: 2 | 705 | minItems: 2 |
| 726 | maxItems: 4 | ||
| 727 | items: | 706 | items: |
| 728 | - description: Functional clock for DU0 | 707 | - description: Functional clock for DU0 |
| 729 | - description: Functional clock for DU1 | 708 | - description: Functional clock for DU1 |
| @@ -732,7 +711,6 @@ allOf: · 2 unmodified lines | |||
| 732 | 711 | ||
| 733 | clock-names: | 712 | clock-names: |
| 734 | minItems: 2 | 713 | minItems: 2 |
| 735 | maxItems: 4 | ||
| 736 | items: | 714 | items: |
| 737 | - const: du.0 | 715 | - const: du.0 |
| 738 | - const: du.1 | 716 | - const: du.1 |
| @@ -791,7 +769,6 @@ allOf: · 52 unmodified lines | |||
| 791 | - description: Functional clock | 769 | - description: Functional clock |
| 792 | 770 | ||
| 793 | clock-names: | 771 | clock-names: |
| 794 | maxItems: 1 | ||
| 795 | items: | 772 | items: |
| 796 | - const: du.0 | 773 | - const: du.0 |
| 797 | 774 | ||
| @@ -58,10 +58,9 @@ patternProperties: · 57 unmodified lines | |||
| 58 | description: | | 58 | description: | |
| 59 | The value (two's complement) to be programmed in the channel specific N correction register. | 59 | The value (two's complement) to be programmed in the channel specific N correction register. |
| 60 | For remote channels only. | 60 | For remote channels only. |
| 61 | $ref: /schemas/types.yaml#/definitions/uint32 | 61 | $ref: /schemas/types.yaml#/definitions/int32 |
| 62 | items: | 62 | minimum: -128 |
| 63 | minimum: 0 | 63 | maximum: 127 |
| 64 | maximum: 255 | ||
| 65 | 64 | ||
| 66 | required: | 65 | required: |
| 67 | - reg | 66 | - reg |
| @@ -138,7 +138,6 @@ allOf: · 137 unmodified lines | |||
| 138 | - const: bus | 138 | - const: bus |
| 139 | - const: adc | 139 | - const: adc |
| 140 | minItems: 1 | 140 | minItems: 1 |
| 141 | maxItems: 2 | ||
| 142 | 141 | ||
| 143 | interrupts: | 142 | interrupts: |
| 144 | items: | 143 | items: |
| @@ -170,7 +169,6 @@ allOf: · 25 unmodified lines | |||
| 170 | - const: bus | 169 | - const: bus |
| 171 | - const: adc | 170 | - const: adc |
| 172 | minItems: 1 | 171 | minItems: 1 |
| 173 | maxItems: 2 | ||
| 174 | 172 | ||
| 175 | interrupts: | 173 | interrupts: |
| 176 | items: | 174 | items: |
| @@ -37,8 +37,10 @@ properties: · 36 unmodified lines | |||
| 37 | - qcom,sc7180-smmu-500 | 37 | - qcom,sc7180-smmu-500 |
| 38 | - qcom,sc7280-smmu-500 | 38 | - qcom,sc7280-smmu-500 |
| 39 | - qcom,sc8180x-smmu-500 | 39 | - qcom,sc8180x-smmu-500 |
| 40 | - qcom,sc8280xp-smmu-500 | ||
| 40 | - qcom,sdm845-smmu-500 | 41 | - qcom,sdm845-smmu-500 |
| 41 | - qcom,sdx55-smmu-500 | 42 | - qcom,sdx55-smmu-500 |
| 43 | - qcom,sdx65-smmu-500 | ||
| 42 | - qcom,sm6350-smmu-500 | 44 | - qcom,sm6350-smmu-500 |
| 43 | - qcom,sm8150-smmu-500 | 45 | - qcom,sm8150-smmu-500 |
| 44 | - qcom,sm8250-smmu-500 | 46 | - qcom,sm8250-smmu-500 |
| @@ -62,8 +64,9 @@ properties: · 17 unmodified lines | |||
| 62 | for improved performance. | 64 | for improved performance. |
| 63 | items: | 65 | items: |
| 64 | - enum: | 66 | - enum: |
| 65 | - nvidia,tegra194-smmu | ||
| 66 | - nvidia,tegra186-smmu | 67 | - nvidia,tegra186-smmu |
| 68 | - nvidia,tegra194-smmu | ||
| 69 | - nvidia,tegra234-smmu | ||
| 67 | - const: nvidia,smmu-500 | 70 | - const: nvidia,smmu-500 |
| 68 | - items: | 71 | - items: |
| 69 | - const: arm,mmu-500 | 72 | - const: arm,mmu-500 |
| @@ -157,6 +160,17 @@ properties: · 87 unmodified lines | |||
| 157 | power-domains: | 160 | power-domains: |
| 158 | maxItems: 1 | 161 | maxItems: 1 |
| 159 | 162 | ||
| 163 | nvidia,memory-controller: | ||
| 164 | description: | | ||
| 165 | A phandle to the memory controller on NVIDIA Tegra186 and later SoCs. | ||
| 166 | The memory controller needs to be programmed with a mapping of memory | ||
| 167 | client IDs to ARM SMMU stream IDs. | ||
| 168 | |||
| 169 | If this property is absent, the mapping programmed by early firmware | ||
| 170 | will be used and it is not guaranteed that IOMMU translations will be | ||
| 171 | enabled for any given device. | ||
| 172 | $ref: /schemas/types.yaml#/definitions/phandle | ||
| 173 | |||
| 160 | required: | 174 | required: |
| 161 | - compatible | 175 | - compatible |
| 162 | - reg | 176 | - reg |
| @@ -172,13 +186,20 @@ allOf: · 9 unmodified lines | |||
| 172 | compatible: | 186 | compatible: |
| 173 | contains: | 187 | contains: |
| 174 | enum: | 188 | enum: |
| 175 | - nvidia,tegra194-smmu | ||
| 176 | - nvidia,tegra186-smmu | 189 | - nvidia,tegra186-smmu |
| 190 | - nvidia,tegra194-smmu | ||
| 191 | - nvidia,tegra234-smmu | ||
| 177 | then: | 192 | then: |
| 178 | properties: | 193 | properties: |
| 179 | reg: | 194 | reg: |
| 180 | minItems: 1 | 195 | minItems: 1 |
| 181 | maxItems: 2 | 196 | maxItems: 2 |
| 197 | |||
| 198 | # The reference to the memory controller is required to ensure that the | ||
| 199 | # memory client to stream ID mapping can be done synchronously with the | ||
| 200 | # IOMMU attachment. | ||
| 201 | required: | ||
| 202 | - nvidia,memory-controller | ||
| 182 | else: | 203 | else: |
| 183 | properties: | 204 | properties: |
| 184 | reg: | 205 | reg: |
| @@ -76,7 +76,11 @@ properties: · 75 unmodified lines | |||
| 76 | - mediatek,mt8167-m4u # generation two | 76 | - mediatek,mt8167-m4u # generation two |
| 77 | - mediatek,mt8173-m4u # generation two | 77 | - mediatek,mt8173-m4u # generation two |
| 78 | - mediatek,mt8183-m4u # generation two | 78 | - mediatek,mt8183-m4u # generation two |
| 79 | - mediatek,mt8186-iommu-mm # generation two | ||
| 79 | - mediatek,mt8192-m4u # generation two | 80 | - mediatek,mt8192-m4u # generation two |
| 81 | - mediatek,mt8195-iommu-vdo # generation two | ||
| 82 | - mediatek,mt8195-iommu-vpp # generation two | ||
| 83 | - mediatek,mt8195-iommu-infra # generation two | ||
| 80 | 84 | ||
| 81 | - description: mt7623 generation one | 85 | - description: mt7623 generation one |
| 82 | items: | 86 | items: |
| @@ -119,7 +123,9 @@ properties: · 36 unmodified lines | |||
| 119 | dt-binding/memory/mt8167-larb-port.h for mt8167, | 123 | dt-binding/memory/mt8167-larb-port.h for mt8167, |
| 120 | dt-binding/memory/mt8173-larb-port.h for mt8173, | 124 | dt-binding/memory/mt8173-larb-port.h for mt8173, |
| 121 | dt-binding/memory/mt8183-larb-port.h for mt8183, | 125 | dt-binding/memory/mt8183-larb-port.h for mt8183, |
| 126 | dt-binding/memory/mt8186-memory-port.h for mt8186, | ||
| 122 | dt-binding/memory/mt8192-larb-port.h for mt8192. | 127 | dt-binding/memory/mt8192-larb-port.h for mt8192. |
| 128 | dt-binding/memory/mt8195-memory-port.h for mt8195. | ||
| 123 | 129 | ||
| 124 | power-domains: | 130 | power-domains: |
| 125 | maxItems: 1 | 131 | maxItems: 1 |
| @@ -128,7 +134,6 @@ required: · 2 unmodified lines | |||
| 128 | - compatible | 134 | - compatible |
| 129 | - reg | 135 | - reg |
| 130 | - interrupts | 136 | - interrupts |
| 131 | - mediatek,larbs | ||
| 132 | - '#iommu-cells' | 137 | - '#iommu-cells' |
| 133 | 138 | ||
| 134 | allOf: | 139 | allOf: |
| @@ -140,7 +145,10 @@ allOf: · 5 unmodified lines | |||
| 140 | - mediatek,mt2701-m4u | 145 | - mediatek,mt2701-m4u |
| 141 | - mediatek,mt2712-m4u | 146 | - mediatek,mt2712-m4u |
| 142 | - mediatek,mt8173-m4u | 147 | - mediatek,mt8173-m4u |
| 148 | - mediatek,mt8186-iommu-mm | ||
| 143 | - mediatek,mt8192-m4u | 149 | - mediatek,mt8192-m4u |
| 150 | - mediatek,mt8195-iommu-vdo | ||
| 151 | - mediatek,mt8195-iommu-vpp | ||
| 144 | 152 | ||
| 145 | then: | 153 | then: |
| 146 | required: | 154 | required: |
| @@ -150,12 +158,26 @@ allOf: · 3 unmodified lines | |||
| 150 | properties: | 158 | properties: |
| 151 | compatible: | 159 | compatible: |
| 152 | enum: | 160 | enum: |
| 161 | - mediatek,mt8186-iommu-mm | ||
| 153 | - mediatek,mt8192-m4u | 162 | - mediatek,mt8192-m4u |
| 163 | - mediatek,mt8195-iommu-vdo | ||
| 164 | - mediatek,mt8195-iommu-vpp | ||
| 154 | 165 | ||
| 155 | then: | 166 | then: |
| 156 | required: | 167 | required: |
| 157 | - power-domains | 168 | - power-domains |
| 158 | 169 | ||
| 170 | - if: # The IOMMUs don't have larbs. | ||
| 171 | not: | ||
| 172 | properties: | ||
| 173 | compatible: | ||
| 174 | contains: | ||
| 175 | const: mediatek,mt8195-iommu-infra | ||
| 176 | |||
| 177 | then: | ||
| 178 | required: | ||
| 179 | - mediatek,larbs | ||
| 180 | |||
| 159 | additionalProperties: false | 181 | additionalProperties: false |
| 160 | 182 | ||
| 161 | examples: | 183 | examples: |
| @@ -173,13 +195,3 @@ examples: · 11 unmodified lines | |||
| 173 | <&larb3>, <&larb4>, <&larb5>; | 195 | <&larb3>, <&larb4>, <&larb5>; |
| 174 | #iommu-cells = <1>; | 196 | #iommu-cells = <1>; |
| 175 | }; | 197 | }; |
| 176 | |||
| 177 | - | | ||
| 178 | #include <dt-bindings/memory/mt8173-larb-port.h> | ||
| 179 | |||
| 180 | /* Example for a client device */ | ||
| 181 | display { | ||
| 182 | compatible = "mediatek,mt8173-disp"; | ||
| 183 | iommus = <&iommu M4U_PORT_DISP_OVL0>, | ||
| 184 | <&iommu M4U_PORT_DISP_RDMA0>; | ||
| 185 | }; | ||
| @@ -86,16 +86,6 @@ examples: · 85 unmodified lines | |||
| 86 | - | | 86 | - | |
| 87 | #include <dt-bindings/clock/exynos5250.h> | 87 | #include <dt-bindings/clock/exynos5250.h> |
| 88 | 88 | ||
| 89 | gsc_0: scaler@13e00000 { | ||
| 90 | compatible = "samsung,exynos5-gsc"; | ||
| 91 | reg = <0x13e00000 0x1000>; | ||
| 92 | interrupts = <0 85 0>; | ||
| 93 | power-domains = <&pd_gsc>; | ||
| 94 | clocks = <&clock CLK_GSCL0>; | ||
| 95 | clock-names = "gscl"; | ||
| 96 | iommus = <&sysmmu_gsc0>; | ||
| 97 | }; | ||
| 98 | |||
| 99 | sysmmu_gsc0: iommu@13e80000 { | 89 | sysmmu_gsc0: iommu@13e80000 { |
| 100 | compatible = "samsung,exynos-sysmmu"; | 90 | compatible = "samsung,exynos-sysmmu"; |
| 101 | reg = <0x13E80000 0x1000>; | 91 | reg = <0x13E80000 0x1000>; |
| @@ -43,8 +43,6 @@ patternProperties: · 42 unmodified lines | |||
| 43 | - 4 # LED output FLASH1 | 43 | - 4 # LED output FLASH1 |
| 44 | - 5 # LED output FLASH2 | 44 | - 5 # LED output FLASH2 |
| 45 | 45 | ||
| 46 | unevaluatedProperties: false | ||
| 47 | |||
| 48 | required: | 46 | required: |
| 49 | - compatible | 47 | - compatible |
| 50 | - "#address-cells" | 48 | - "#address-cells" |
| @@ -54,7 +54,7 @@ flexcom@f8034000 { · 53 unmodified lines | |||
| 54 | clock-names = "spi_clk"; | 54 | clock-names = "spi_clk"; |
| 55 | atmel,fifo-size = <32>; | 55 | atmel,fifo-size = <32>; |
| 56 | 56 | ||
| 57 | mtd_dataflash@0 { | 57 | flash@0 { |
| 58 | compatible = "atmel,at25f512b"; | 58 | compatible = "atmel,at25f512b"; |
| 59 | reg = <0>; | 59 | reg = <0>; |
| 60 | spi-max-frequency = <20000000>; | 60 | spi-max-frequency = <20000000>; |
| @@ -202,22 +202,17 @@ allOf: · 201 unmodified lines | |||
| 202 | clocks: | 202 | clocks: |
| 203 | items: | 203 | items: |
| 204 | - description: module clock | 204 | - description: module clock |
| 205 | minItems: 1 | ||
| 206 | maxItems: 1 | ||
| 207 | else: | 205 | else: |
| 208 | properties: | 206 | properties: |
| 209 | clocks: | 207 | clocks: |
| 210 | items: | 208 | items: |
| 211 | - description: module clock | 209 | - description: module clock |
| 212 | - description: timeout clock | 210 | - description: timeout clock |
| 213 | minItems: 2 | 211 | |
| 214 | maxItems: 2 | ||
| 215 | clock-names: | 212 | clock-names: |
| 216 | items: | 213 | items: |
| 217 | - const: sdhci | 214 | - const: sdhci |
| 218 | - const: tmclk | 215 | - const: tmclk |
| 219 | minItems: 2 | ||
| 220 | maxItems: 2 | ||
| 221 | required: | 216 | required: |
| 222 | - clock-names | 217 | - clock-names |
| 223 | 218 | ||
| @@ -147,8 +147,6 @@ allOf: · 146 unmodified lines | |||
| 147 | - description: SoC gpmi io clock | 147 | - description: SoC gpmi io clock |
| 148 | - description: SoC gpmi bch apb clock | 148 | - description: SoC gpmi bch apb clock |
| 149 | clock-names: | 149 | clock-names: |
| 150 | minItems: 2 | ||
| 151 | maxItems: 2 | ||
| 152 | items: | 150 | items: |
| 153 | - const: gpmi_io | 151 | - const: gpmi_io |
| 154 | - const: gpmi_bch_apb | 152 | - const: gpmi_bch_apb |
| @@ -80,8 +80,6 @@ if: · 79 unmodified lines | |||
| 80 | then: | 80 | then: |
| 81 | properties: | 81 | properties: |
| 82 | interrupts: | 82 | interrupts: |
| 83 | minItems: 4 | ||
| 84 | maxItems: 4 | ||
| 85 | items: | 83 | items: |
| 86 | - description: Error and status IRQ | 84 | - description: Error and status IRQ |
| 87 | - description: Message object IRQ | 85 | - description: Message object IRQ |
| @@ -91,7 +89,6 @@ then: · 3 unmodified lines | |||
| 91 | else: | 89 | else: |
| 92 | properties: | 90 | properties: |
| 93 | interrupts: | 91 | interrupts: |
| 94 | maxItems: 1 | ||
| 95 | items: | 92 | items: |
| 96 | - description: Error and status IRQ | 93 | - description: Error and status IRQ |
| 97 | 94 | ||
| @@ -27,32 +27,25 @@ description: · 26 unmodified lines | |||
| 27 | The realtek-mdio driver is an MDIO driver and it must be inserted inside | 27 | The realtek-mdio driver is an MDIO driver and it must be inserted inside |
| 28 | an MDIO node. | 28 | an MDIO node. |
| 29 | 29 | ||
| 30 | The compatible string is only used to identify which (silicon) family the | ||
| 31 | switch belongs to. Roughly speaking, a family is any set of Realtek switches | ||
| 32 | whose chip identification register(s) have a common location and semantics. | ||
| 33 | The different models in a given family can be automatically disambiguated by | ||
| 34 | parsing the chip identification register(s) according to the given family, | ||
| 35 | avoiding the need for a unique compatible string for each model. | ||
| 36 | |||
| 30 | properties: | 37 | properties: |
| 31 | compatible: | 38 | compatible: |
| 32 | enum: | 39 | enum: |
| 33 | - realtek,rtl8365mb | 40 | - realtek,rtl8365mb |
| 34 | - realtek,rtl8366 | ||
| 35 | - realtek,rtl8366rb | 41 | - realtek,rtl8366rb |
| 36 | - realtek,rtl8366s | ||
| 37 | - realtek,rtl8367 | ||
| 38 | - realtek,rtl8367b | ||
| 39 | - realtek,rtl8367rb | ||
| 40 | - realtek,rtl8367s | ||
| 41 | - realtek,rtl8368s | ||
| 42 | - realtek,rtl8369 | ||
| 43 | - realtek,rtl8370 | ||
| 44 | description: | | 42 | description: | |
| 45 | realtek,rtl8365mb: 4+1 ports | 43 | realtek,rtl8365mb: |
| 46 | realtek,rtl8366: 5+1 ports | 44 | Use with models RTL8363NB, RTL8363NB-VB, RTL8363SC, RTL8363SC-VB, |
| 47 | realtek,rtl8366rb: 5+1 ports | 45 | RTL8364NB, RTL8364NB-VB, RTL8365MB, RTL8366SC, RTL8367RB-VB, RTL8367S, |
| 48 | realtek,rtl8366s: 5+1 ports | 46 | RTL8367SB, RTL8370MB, RTL8310SR |
| 49 | realtek,rtl8367: | 47 | realtek,rtl8366rb: |
| 50 | realtek,rtl8367b: | 48 | Use with models RTL8366RB, RTL8366S |
| 51 | realtek,rtl8367rb: 5+2 ports | ||
| 52 | realtek,rtl8367s: 5+2 ports | ||
| 53 | realtek,rtl8368s: 8 ports | ||
| 54 | realtek,rtl8369: 8+1 ports | ||
| 55 | realtek,rtl8370: 8+2 ports | ||
| 56 | 49 | ||
| 57 | mdc-gpios: | 50 | mdc-gpios: |
| 58 | description: GPIO line for the MDC clock line. | 51 | description: GPIO line for the MDC clock line. |
| @@ -335,7 +328,7 @@ examples: · 276 unmodified lines | |||
| 335 | #size-cells = <0>; | 328 | #size-cells = <0>; |
| 336 | 329 | ||
| 337 | switch@29 { | 330 | switch@29 { |
| 338 | compatible = "realtek,rtl8367s"; | 331 | compatible = "realtek,rtl8365mb"; |
| 339 | reg = <29>; | 332 | reg = <29>; |
| 340 | 333 | ||
| 341 | reset-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>; | 334 | reset-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>; |
| @@ -142,7 +142,6 @@ examples: · 141 unmodified lines | |||
| 142 | device_type = "pci"; | 142 | device_type = "pci"; |
| 143 | reg = <0x0 0x0 0x0 0x0 0x0>; | 143 | reg = <0x0 0x0 0x0 0x0 0x0>; |
| 144 | reset-gpios = <&pinctrl_ap 152 0>; | 144 | reset-gpios = <&pinctrl_ap 152 0>; |
| 145 | max-link-speed = <2>; | ||
| 146 | 145 | ||
| 147 | #address-cells = <3>; | 146 | #address-cells = <3>; |
| 148 | #size-cells = <2>; | 147 | #size-cells = <2>; |
| @@ -153,7 +152,6 @@ examples: · 4 unmodified lines | |||
| 153 | device_type = "pci"; | 152 | device_type = "pci"; |
| 154 | reg = <0x800 0x0 0x0 0x0 0x0>; | 153 | reg = <0x800 0x0 0x0 0x0 0x0>; |
| 155 | reset-gpios = <&pinctrl_ap 153 0>; | 154 | reset-gpios = <&pinctrl_ap 153 0>; |
| 156 | max-link-speed = <2>; | ||
| 157 | 155 | ||
| 158 | #address-cells = <3>; | 156 | #address-cells = <3>; |
| 159 | #size-cells = <2>; | 157 | #size-cells = <2>; |
| @@ -164,7 +162,6 @@ examples: · 4 unmodified lines | |||
| 164 | device_type = "pci"; | 162 | device_type = "pci"; |
| 165 | reg = <0x1000 0x0 0x0 0x0 0x0>; | 163 | reg = <0x1000 0x0 0x0 0x0 0x0>; |
| 166 | reset-gpios = <&pinctrl_ap 33 0>; | 164 | reset-gpios = <&pinctrl_ap 33 0>; |
| 167 | max-link-speed = <1>; | ||
| 168 | 165 | ||
| 169 | #address-cells = <3>; | 166 | #address-cells = <3>; |
| 170 | #size-cells = <2>; | 167 | #size-cells = <2>; |
| @@ -102,19 +102,17 @@ if: · 101 unmodified lines | |||
| 102 | then: | 102 | then: |
| 103 | properties: | 103 | properties: |
| 104 | reg: | 104 | reg: |
| 105 | maxItems: 2 | 105 | minItems: 2 |
| 106 | |||
| 106 | reg-names: | 107 | reg-names: |
| 107 | items: | 108 | minItems: 2 |
| 108 | - const: "phy" | ||
| 109 | - const: "phy-ctrl" | ||
| 110 | else: | 109 | else: |
| 111 | properties: | 110 | properties: |
| 112 | reg: | 111 | reg: |
| 113 | maxItems: 1 | 112 | maxItems: 1 |
| 113 | |||
| 114 | reg-names: | 114 | reg-names: |
| 115 | maxItems: 1 | 115 | maxItems: 1 |
| 116 | items: | ||
| 117 | - const: "phy" | ||
| 118 | 116 | ||
| 119 | required: | 117 | required: |
| 120 | - compatible | 118 | - compatible |
| @@ -52,11 +52,19 @@ properties: · 51 unmodified lines | |||
| 52 | hardware supporting it the pull strength in Ohm. | 52 | hardware supporting it the pull strength in Ohm. |
| 53 | 53 | ||
| 54 | drive-push-pull: | 54 | drive-push-pull: |
| 55 | type: boolean | 55 | oneOf: |
| 56 | - type: boolean | ||
| 57 | - $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 58 | enum: [ 0, 1 ] | ||
| 59 | deprecated: true | ||
| 56 | description: drive actively high and low | 60 | description: drive actively high and low |
| 57 | 61 | ||
| 58 | drive-open-drain: | 62 | drive-open-drain: |
| 59 | type: boolean | 63 | oneOf: |
| 64 | - type: boolean | ||
| 65 | - $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 66 | const: 1 # No known cases of 0 | ||
| 67 | deprecated: true | ||
| 60 | description: drive with open drain | 68 | description: drive with open drain |
| 61 | 69 | ||
| 62 | drive-open-source: | 70 | drive-open-source: |
| @@ -58,7 +58,7 @@ properties: · 57 unmodified lines | |||
| 58 | type: object | 58 | type: object |
| 59 | $ref: regulator.yaml# | 59 | $ref: regulator.yaml# |
| 60 | description: | | 60 | description: | |
| 61 | regulator description for buck1 and buck4. | 61 | regulator description for buck1 to buck4, and ldo. |
| 62 | 62 | ||
| 63 | properties: | 63 | properties: |
| 64 | regulator-allowed-modes: | 64 | regulator-allowed-modes: |
| @@ -71,7 +71,6 @@ allOf: · 70 unmodified lines | |||
| 71 | then: | 71 | then: |
| 72 | properties: | 72 | properties: |
| 73 | clock-output-names: | 73 | clock-output-names: |
| 74 | minItems: 1 | ||
| 75 | maxItems: 1 | 74 | maxItems: 1 |
| 76 | 75 | ||
| 77 | - if: | 76 | - if: |
| @@ -102,7 +101,6 @@ allOf: · 24 unmodified lines | |||
| 102 | properties: | 101 | properties: |
| 103 | clock-output-names: | 102 | clock-output-names: |
| 104 | minItems: 3 | 103 | minItems: 3 |
| 105 | maxItems: 3 | ||
| 106 | 104 | ||
| 107 | - if: | 105 | - if: |
| 108 | properties: | 106 | properties: |
| @@ -113,16 +111,12 @@ allOf: · 4 unmodified lines | |||
| 113 | then: | 111 | then: |
| 114 | properties: | 112 | properties: |
| 115 | clocks: | 113 | clocks: |
| 116 | minItems: 3 | ||
| 117 | maxItems: 3 | ||
| 118 | items: | 114 | items: |
| 119 | - description: Bus clock for register access | 115 | - description: Bus clock for register access |
| 120 | - description: 24 MHz oscillator | 116 | - description: 24 MHz oscillator |
| 121 | - description: 32 kHz clock from the CCU | 117 | - description: 32 kHz clock from the CCU |
| 122 | 118 | ||
| 123 | clock-names: | 119 | clock-names: |
| 124 | minItems: 3 | ||
| 125 | maxItems: 3 | ||
| 126 | items: | 120 | items: |
| 127 | - const: bus | 121 | - const: bus |
| 128 | - const: hosc | 122 | - const: hosc |
| @@ -142,7 +136,6 @@ allOf: · 13 unmodified lines | |||
| 142 | properties: | 136 | properties: |
| 143 | clocks: | 137 | clocks: |
| 144 | minItems: 3 | 138 | minItems: 3 |
| 145 | maxItems: 4 | ||
| 146 | items: | 139 | items: |
| 147 | - description: Bus clock for register access | 140 | - description: Bus clock for register access |
| 148 | - description: 24 MHz oscillator | 141 | - description: 24 MHz oscillator |
| @@ -151,7 +144,6 @@ allOf: · 2 unmodified lines | |||
| 151 | 144 | ||
| 152 | clock-names: | 145 | clock-names: |
| 153 | minItems: 3 | 146 | minItems: 3 |
| 154 | maxItems: 4 | ||
| 155 | items: | 147 | items: |
| 156 | - const: bus | 148 | - const: bus |
| 157 | - const: hosc | 149 | - const: hosc |
| @@ -174,14 +166,12 @@ allOf: · 16 unmodified lines | |||
| 174 | then: | 166 | then: |
| 175 | properties: | 167 | properties: |
| 176 | interrupts: | 168 | interrupts: |
| 177 | minItems: 1 | ||
| 178 | maxItems: 1 | 169 | maxItems: 1 |
| 179 | 170 | ||
| 180 | else: | 171 | else: |
| 181 | properties: | 172 | properties: |
| 182 | interrupts: | 173 | interrupts: |
| 183 | minItems: 2 | 174 | minItems: 2 |
| 184 | maxItems: 2 | ||
| 185 | 175 | ||
| 186 | required: | 176 | required: |
| 187 | - "#clock-cells" | 177 | - "#clock-cells" |
| @@ -31,11 +31,19 @@ properties: · 30 unmodified lines | |||
| 31 | to that of the RTC's count register. | 31 | to that of the RTC's count register. |
| 32 | 32 | ||
| 33 | clocks: | 33 | clocks: |
| 34 | maxItems: 1 | 34 | items: |
| 35 | - description: | | ||
| 36 | AHB clock | ||
| 37 | - description: | | ||
| 38 | Reference clock: divided by the prescaler to create a time-based | ||
| 39 | strobe (typically 1 Hz) for the calendar counter. By default, the rtc | ||
| 40 | on the PolarFire SoC shares it's reference with MTIMER so this will | ||
| 41 | be a 1 MHz clock. | ||
| 35 | 42 | ||
| 36 | clock-names: | 43 | clock-names: |
| 37 | items: | 44 | items: |
| 38 | - const: rtc | 45 | - const: rtc |
| 46 | - const: rtcref | ||
| 39 | 47 | ||
| 40 | required: | 48 | required: |
| 41 | - compatible | 49 | - compatible |
| @@ -48,11 +56,12 @@ additionalProperties: false · 6 unmodified lines | |||
| 48 | 56 | ||
| 49 | examples: | 57 | examples: |
| 50 | - | | 58 | - | |
| 59 | #include "dt-bindings/clock/microchip,mpfs-clock.h" | ||
| 51 | rtc@20124000 { | 60 | rtc@20124000 { |
| 52 | compatible = "microchip,mpfs-rtc"; | 61 | compatible = "microchip,mpfs-rtc"; |
| 53 | reg = <0x20124000 0x1000>; | 62 | reg = <0x20124000 0x1000>; |
| 54 | clocks = <&clkcfg 21>; | 63 | clocks = <&clkcfg CLK_RTC>, <&clkcfg CLK_RTCREF>; |
| 55 | clock-names = "rtc"; | 64 | clock-names = "rtc", "rtcref"; |
| 56 | interrupts = <80>, <81>; | 65 | interrupts = <80>, <81>; |
| 57 | }; | 66 | }; |
| 58 | ... | 67 | ... |
| @@ -100,7 +100,6 @@ allOf: · 99 unmodified lines | |||
| 100 | maxItems: 3 | 100 | maxItems: 3 |
| 101 | clock-names: | 101 | clock-names: |
| 102 | minItems: 2 | 102 | minItems: 2 |
| 103 | maxItems: 3 | ||
| 104 | items: | 103 | items: |
| 105 | - const: uart | 104 | - const: uart |
| 106 | - pattern: '^clk_uart_baud[0-1]$' | 105 | - pattern: '^clk_uart_baud[0-1]$' |
| @@ -118,11 +117,8 @@ allOf: · 11 unmodified lines | |||
| 118 | then: | 117 | then: |
| 119 | properties: | 118 | properties: |
| 120 | clocks: | 119 | clocks: |
| 121 | minItems: 2 | ||
| 122 | maxItems: 2 | 120 | maxItems: 2 |
| 123 | clock-names: | 121 | clock-names: |
| 124 | minItems: 2 | ||
| 125 | maxItems: 2 | ||
| 126 | items: | 122 | items: |
| 127 | - const: uart | 123 | - const: uart |
| 128 | - const: clk_uart_baud0 | 124 | - const: clk_uart_baud0 |
| @@ -89,7 +89,6 @@ allOf: · 88 unmodified lines | |||
| 89 | properties: | 89 | properties: |
| 90 | dmas: | 90 | dmas: |
| 91 | minItems: 1 | 91 | minItems: 1 |
| 92 | maxItems: 2 | ||
| 93 | items: | 92 | items: |
| 94 | - description: RX DMA Channel | 93 | - description: RX DMA Channel |
| 95 | - description: TX DMA Channel | 94 | - description: TX DMA Channel |
| @@ -80,7 +80,6 @@ allOf: · 79 unmodified lines | |||
| 80 | then: | 80 | then: |
| 81 | properties: | 81 | properties: |
| 82 | clocks: | 82 | clocks: |
| 83 | minItems: 6 | ||
| 84 | items: | 83 | items: |
| 85 | - description: AUXCLK clock for McASP used by CPB audio | 84 | - description: AUXCLK clock for McASP used by CPB audio |
| 86 | - description: Parent for CPB_McASP auxclk (for 48KHz) | 85 | - description: Parent for CPB_McASP auxclk (for 48KHz) |
| @@ -107,7 +106,6 @@ allOf: · 20 unmodified lines | |||
| 107 | then: | 106 | then: |
| 108 | properties: | 107 | properties: |
| 109 | clocks: | 108 | clocks: |
| 110 | maxItems: 4 | ||
| 111 | items: | 109 | items: |
| 112 | - description: AUXCLK clock for McASP used by CPB audio | 110 | - description: AUXCLK clock for McASP used by CPB audio |
| 113 | - description: Parent for CPB_McASP auxclk (for 48KHz) | 111 | - description: Parent for CPB_McASP auxclk (for 48KHz) |
| @@ -67,7 +67,6 @@ then: · 66 unmodified lines | |||
| 67 | properties: | 67 | properties: |
| 68 | reg: | 68 | reg: |
| 69 | minItems: 2 | 69 | minItems: 2 |
| 70 | maxItems: 3 | ||
| 71 | items: | 70 | items: |
| 72 | - description: TSC1 registers | 71 | - description: TSC1 registers |
| 73 | - description: TSC2 registers | 72 | - description: TSC2 registers |
| @@ -43,6 +43,9 @@ properties: · 42 unmodified lines | |||
| 43 | - const: phy_clk | 43 | - const: phy_clk |
| 44 | - const: ref_clk | 44 | - const: ref_clk |
| 45 | 45 | ||
| 46 | power-domains: | ||
| 47 | maxItems: 1 | ||
| 48 | |||
| 46 | reg: | 49 | reg: |
| 47 | maxItems: 1 | 50 | maxItems: 1 |
| 48 | 51 | ||
| @@ -62,6 +62,7 @@ required: · 61 unmodified lines | |||
| 62 | - interrupts | 62 | - interrupts |
| 63 | - phys | 63 | - phys |
| 64 | - phy-names | 64 | - phy-names |
| 65 | - reg | ||
| 65 | 66 | ||
| 66 | allOf: | 67 | allOf: |
| 67 | - if: | 68 | - if: |
| @@ -235,12 +235,6 @@ offgrpjquota Turn off group journalled quota. · 234 unmodified lines | |||
| 235 | offprjjquota Turn off project journalled quota. | 235 | offprjjquota Turn off project journalled quota. |
| 236 | quota Enable plain user disk quota accounting. | 236 | quota Enable plain user disk quota accounting. |
| 237 | noquota Disable all plain disk quota option. | 237 | noquota Disable all plain disk quota option. |
| 238 | whint_mode=%s Control which write hints are passed down to block | ||
| 239 | layer. This supports "off", "user-based", and | ||
| 240 | "fs-based". In "off" mode (default), f2fs does not pass | ||
| 241 | down hints. In "user-based" mode, f2fs tries to pass | ||
| 242 | down hints given by users. And in "fs-based" mode, f2fs | ||
| 243 | passes down hints with its policy. | ||
| 244 | alloc_mode=%s Adjust block allocation policy, which supports "reuse" | 238 | alloc_mode=%s Adjust block allocation policy, which supports "reuse" |
| 245 | and "default". | 239 | and "default". |
| 246 | fsync_mode=%s Control the policy of fsync. Currently supports "posix", | 240 | fsync_mode=%s Control the policy of fsync. Currently supports "posix", |
| @@ -751,70 +745,6 @@ In order to identify whether the data in the victim segment are valid or not, · 504 unmodified lines | |||
| 751 | F2FS manages a bitmap. Each bit represents the validity of a block, and the | 745 | F2FS manages a bitmap. Each bit represents the validity of a block, and the |
| 752 | bitmap is composed of a bit stream covering whole blocks in main area. | 746 | bitmap is composed of a bit stream covering whole blocks in main area. |
| 753 | 747 | ||
| 754 | Write-hint Policy | ||
| 755 | ----------------- | ||
| 756 | |||
| 757 | 1) whint_mode=off. F2FS only passes down WRITE_LIFE_NOT_SET. | ||
| 758 | |||
| 759 | 2) whint_mode=user-based. F2FS tries to pass down hints given by | ||
| 760 | users. | ||
| 761 | |||
| 762 | ===================== ======================== =================== | ||
| 763 | User F2FS Block | ||
| 764 | ===================== ======================== =================== | ||
| 765 | N/A META WRITE_LIFE_NOT_SET | ||
| 766 | N/A HOT_NODE " | ||
| 767 | N/A WARM_NODE " | ||
| 768 | N/A COLD_NODE " | ||
| 769 | ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME | ||
| 770 | extension list " " | ||
| 771 | |||
| 772 | -- buffered io | ||
| 773 | WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME | ||
| 774 | WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT | ||
| 775 | WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET | ||
| 776 | WRITE_LIFE_NONE " " | ||
| 777 | WRITE_LIFE_MEDIUM " " | ||
| 778 | WRITE_LIFE_LONG " " | ||
| 779 | |||
| 780 | -- direct io | ||
| 781 | WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME | ||
| 782 | WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT | ||
| 783 | WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET | ||
| 784 | WRITE_LIFE_NONE " WRITE_LIFE_NONE | ||
| 785 | WRITE_LIFE_MEDIUM " WRITE_LIFE_MEDIUM | ||
| 786 | WRITE_LIFE_LONG " WRITE_LIFE_LONG | ||
| 787 | ===================== ======================== =================== | ||
| 788 | |||
| 789 | 3) whint_mode=fs-based. F2FS passes down hints with its policy. | ||
| 790 | |||
| 791 | ===================== ======================== =================== | ||
| 792 | User F2FS Block | ||
| 793 | ===================== ======================== =================== | ||
| 794 | N/A META WRITE_LIFE_MEDIUM; | ||
| 795 | N/A HOT_NODE WRITE_LIFE_NOT_SET | ||
| 796 | N/A WARM_NODE " | ||
| 797 | N/A COLD_NODE WRITE_LIFE_NONE | ||
| 798 | ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME | ||
| 799 | extension list " " | ||
| 800 | |||
| 801 | -- buffered io | ||
| 802 | WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME | ||
| 803 | WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT | ||
| 804 | WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_LONG | ||
| 805 | WRITE_LIFE_NONE " " | ||
| 806 | WRITE_LIFE_MEDIUM " " | ||
| 807 | WRITE_LIFE_LONG " " | ||
| 808 | |||
| 809 | -- direct io | ||
| 810 | WRITE_LIFE_EXTREME COLD_DATA WRITE_LIFE_EXTREME | ||
| 811 | WRITE_LIFE_SHORT HOT_DATA WRITE_LIFE_SHORT | ||
| 812 | WRITE_LIFE_NOT_SET WARM_DATA WRITE_LIFE_NOT_SET | ||
| 813 | WRITE_LIFE_NONE " WRITE_LIFE_NONE | ||
| 814 | WRITE_LIFE_MEDIUM " WRITE_LIFE_MEDIUM | ||
| 815 | WRITE_LIFE_LONG " WRITE_LIFE_LONG | ||
| 816 | ===================== ======================== =================== | ||
| 817 | |||
| 818 | Fallocate(2) Policy | 748 | Fallocate(2) Policy |
| 819 | ------------------- | 749 | ------------------- |
| 820 | 750 | ||
| @@ -244,10 +244,11 @@ disclosure of a particular issue, unless requested by a response team or by · 243 unmodified lines | |||
| 244 | an involved disclosed party. The current ambassadors list: | 244 | an involved disclosed party. The current ambassadors list: |
| 245 | 245 | ||
| 246 | ============= ======================================================== | 246 | ============= ======================================================== |
| 247 | ARM Grant Likely <grant.likely@arm.com> | ||
| 248 | AMD Tom Lendacky <tom.lendacky@amd.com> | 247 | AMD Tom Lendacky <tom.lendacky@amd.com> |
| 249 | IBM Z Christian Borntraeger <borntraeger@de.ibm.com> | 248 | Ampere Darren Hart <darren@os.amperecomputing.com> |
| 250 | IBM Power Anton Blanchard <anton@linux.ibm.com> | 249 | ARM Catalin Marinas <catalin.marinas@arm.com> |
| 250 | IBM Power Anton Blanchard <anton@linux.ibm.com> | ||
| 251 | IBM Z Christian Borntraeger <borntraeger@de.ibm.com> | ||
| 251 | Intel Tony Luck <tony.luck@intel.com> | 252 | Intel Tony Luck <tony.luck@intel.com> |
| 252 | Qualcomm Trilok Soni <tsoni@codeaurora.org> | 253 | Qualcomm Trilok Soni <tsoni@codeaurora.org> |
| 253 | 254 | ||
| @@ -121,26 +121,36 @@ even scarier, uses an easily brute-forcable 64-bit key (with a 32-bit output) · 120 unmodified lines | |||
| 121 | instead of SipHash's 128-bit key. However, this may appeal to some | 121 | instead of SipHash's 128-bit key. However, this may appeal to some |
| 122 | high-performance `jhash` users. | 122 | high-performance `jhash` users. |
| 123 | 123 | ||
| 124 | Danger! | 124 | HalfSipHash support is provided through the "hsiphash" family of functions. |
| 125 | 125 | ||
| 126 | Do not ever use HalfSipHash except for as a hashtable key function, and only | 126 | .. warning:: |
| 127 | then when you can be absolutely certain that the outputs will never be | 127 | Do not ever use the hsiphash functions except for as a hashtable key |
| 128 | transmitted out of the kernel. This is only remotely useful over `jhash` as a | 128 | function, and only then when you can be absolutely certain that the outputs |
| 129 | means of mitigating hashtable flooding denial of service attacks. | 129 | will never be transmitted out of the kernel. This is only remotely useful |
| 130 | 130 | over `jhash` as a means of mitigating hashtable flooding denial of service | |
| 131 | Generating a HalfSipHash key | 131 | attacks. |
| 132 | ============================ | 132 | |
| 133 | On 64-bit kernels, the hsiphash functions actually implement SipHash-1-3, a | ||
| 134 | reduced-round variant of SipHash, instead of HalfSipHash-1-3. This is because in | ||
| 135 | 64-bit code, SipHash-1-3 is no slower than HalfSipHash-1-3, and can be faster. | ||
| 136 | Note, this does *not* mean that in 64-bit kernels the hsiphash functions are the | ||
| 137 | same as the siphash ones, or that they are secure; the hsiphash functions still | ||
| 138 | use a less secure reduced-round algorithm and truncate their outputs to 32 | ||
| 139 | bits. | ||
| 140 | |||
| 141 | Generating a hsiphash key | ||
| 142 | ========================= | ||
| 133 | 143 | ||
| 134 | Keys should always be generated from a cryptographically secure source of | 144 | Keys should always be generated from a cryptographically secure source of |
| 135 | random numbers, either using get_random_bytes or get_random_once: | 145 | random numbers, either using get_random_bytes or get_random_once:: |
| 136 | 146 | ||
| 137 | hsiphash_key_t key; | 147 | hsiphash_key_t key; |
| 138 | get_random_bytes(&key, sizeof(key)); | 148 | get_random_bytes(&key, sizeof(key)); |
| 139 | 149 | ||
| 140 | If you're not deriving your key from here, you're doing it wrong. | 150 | If you're not deriving your key from here, you're doing it wrong. |
| 141 | 151 | ||
| 142 | Using the HalfSipHash functions | 152 | Using the hsiphash functions |
| 143 | =============================== | 153 | ============================ |
| 144 | 154 | ||
| 145 | There are two variants of the function, one that takes a list of integers, and | 155 | There are two variants of the function, one that takes a list of integers, and |
| 146 | one that takes a buffer:: | 156 | one that takes a buffer:: |
| @@ -183,7 +193,7 @@ You may then iterate like usual over the returned hash bucket. · 36 unmodified lines | |||
| 183 | Performance | 193 | Performance |
| 184 | =========== | 194 | =========== |
| 185 | 195 | ||
| 186 | HalfSipHash is roughly 3 times slower than JenkinsHash. For many replacements, | 196 | hsiphash() is roughly 3 times slower than jhash(). For many replacements, this |
| 187 | this will not be a problem, as the hashtable lookup isn't the bottleneck. And | 197 | will not be a problem, as the hashtable lookup isn't the bottleneck. And in |
| 188 | in general, this is probably a good sacrifice to make for the security and DoS | 198 | general, this is probably a good sacrifice to make for the security and DoS |
| 189 | resistance of HalfSipHash. | 199 | resistance of hsiphash(). |
| @@ -5986,16 +5986,16 @@ should put the acknowledged interrupt vector into the 'epr' field. · 5985 unmodified lines | |||
| 5986 | #define KVM_SYSTEM_EVENT_RESET 2 | 5986 | #define KVM_SYSTEM_EVENT_RESET 2 |
| 5987 | #define KVM_SYSTEM_EVENT_CRASH 3 | 5987 | #define KVM_SYSTEM_EVENT_CRASH 3 |
| 5988 | __u32 type; | 5988 | __u32 type; |
| 5989 | __u64 flags; | 5989 | __u32 ndata; |
| 5990 | __u64 data[16]; | ||
| 5990 | } system_event; | 5991 | } system_event; |
| 5991 | 5992 | ||
| 5992 | If exit_reason is KVM_EXIT_SYSTEM_EVENT then the vcpu has triggered | 5993 | If exit_reason is KVM_EXIT_SYSTEM_EVENT then the vcpu has triggered |
| 5993 | a system-level event using some architecture specific mechanism (hypercall | 5994 | a system-level event using some architecture specific mechanism (hypercall |
| 5994 | or some special instruction). In case of ARM64, this is triggered using | 5995 | or some special instruction). In case of ARM64, this is triggered using |
| 5995 | HVC instruction based PSCI call from the vcpu. The 'type' field describes | 5996 | HVC instruction based PSCI call from the vcpu. |
| 5996 | the system-level event type. The 'flags' field describes architecture | ||
| 5997 | specific flags for the system-level event. | ||
| 5998 | 5997 | ||
| 5998 | The 'type' field describes the system-level event type. | ||
| 5999 | Valid values for 'type' are: | 5999 | Valid values for 'type' are: |
| 6000 | 6000 | ||
| 6001 | - KVM_SYSTEM_EVENT_SHUTDOWN -- the guest has requested a shutdown of the | 6001 | - KVM_SYSTEM_EVENT_SHUTDOWN -- the guest has requested a shutdown of the |
| @@ -6010,10 +6010,20 @@ Valid values for 'type' are: · 8 unmodified lines | |||
| 6010 | to ignore the request, or to gather VM memory core dump and/or | 6010 | to ignore the request, or to gather VM memory core dump and/or |
| 6011 | reset/shutdown of the VM. | 6011 | reset/shutdown of the VM. |
| 6012 | 6012 | ||
| 6013 | Valid flags are: | 6013 | If KVM_CAP_SYSTEM_EVENT_DATA is present, the 'data' field can contain |
| 6014 | architecture specific information for the system-level event. Only | ||
| 6015 | the first `ndata` items (possibly zero) of the data array are valid. | ||
| 6014 | 6016 | ||
| 6015 | - KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (arm64 only) -- the guest issued | 6017 | - for arm64, data[0] is set to KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 if |
| 6016 | a SYSTEM_RESET2 call according to v1.1 of the PSCI specification. | 6018 | the guest issued a SYSTEM_RESET2 call according to v1.1 of the PSCI |
| 6019 | specification. | ||
| 6020 | |||
| 6021 | - for RISC-V, data[0] is set to the value of the second argument of the | ||
| 6022 | ``sbi_system_reset`` call. | ||
| 6023 | |||
| 6024 | Previous versions of Linux defined a `flags` member in this struct. The | ||
| 6025 | field is now aliased to `data[0]`. Userspace can assume that it is only | ||
| 6026 | written if ndata is greater than 0. | ||
| 6017 | 6027 | ||
| 6018 | :: | 6028 | :: |
| 6019 | 6029 | ||
| @@ -110,7 +110,7 @@ Usage · 109 unmodified lines | |||
| 110 | If you want to sort by the page nums of buf, use the ``-m`` parameter. | 110 | If you want to sort by the page nums of buf, use the ``-m`` parameter. |
| 111 | The detailed parameters are: | 111 | The detailed parameters are: |
| 112 | 112 | ||
| 113 | fundamental function: | 113 | fundamental function:: |
| 114 | 114 | ||
| 115 | Sort: | 115 | Sort: |
| 116 | -a Sort by memory allocation time. | 116 | -a Sort by memory allocation time. |
| @@ -122,7 +122,7 @@ Usage · 5 unmodified lines | |||
| 122 | -s Sort by stack trace. | 122 | -s Sort by stack trace. |
| 123 | -t Sort by times (default). | 123 | -t Sort by times (default). |
| 124 | 124 | ||
| 125 | additional function: | 125 | additional function:: |
| 126 | 126 | ||
| 127 | Cull: | 127 | Cull: |
| 128 | --cull <rules> | 128 | --cull <rules> |
| @@ -153,6 +153,7 @@ Usage · 24 unmodified lines | |||
| 153 | 153 | ||
| 154 | STANDARD FORMAT SPECIFIERS | 154 | STANDARD FORMAT SPECIFIERS |
| 155 | ========================== | 155 | ========================== |
| 156 | :: | ||
| 156 | 157 | ||
| 157 | KEY LONG DESCRIPTION | 158 | KEY LONG DESCRIPTION |
| 158 | p pid process ID | 159 | p pid process ID |
| @@ -2638,6 +2638,7 @@ L: linux-samsung-soc@vger.kernel.org · 2637 unmodified lines | |||
| 2638 | S: Maintained | 2638 | S: Maintained |
| 2639 | C: irc://irc.libera.chat/linux-exynos | 2639 | C: irc://irc.libera.chat/linux-exynos |
| 2640 | Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/ | 2640 | Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/ |
| 2641 | B: mailto:linux-samsung-soc@vger.kernel.org | ||
| 2641 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git | 2642 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git |
| 2642 | F: Documentation/arm/samsung/ | 2643 | F: Documentation/arm/samsung/ |
| 2643 | F: Documentation/devicetree/bindings/arm/samsung/ | 2644 | F: Documentation/devicetree/bindings/arm/samsung/ |
| @@ -3564,8 +3565,9 @@ M: Andy Gospodarek <andy@greyhouse.net> · 920 unmodified lines | |||
| 3564 | L: netdev@vger.kernel.org | 3565 | L: netdev@vger.kernel.org |
| 3565 | S: Supported | 3566 | S: Supported |
| 3566 | W: http://sourceforge.net/projects/bonding/ | 3567 | W: http://sourceforge.net/projects/bonding/ |
| 3568 | F: Documentation/networking/bonding.rst | ||
| 3567 | F: drivers/net/bonding/ | 3569 | F: drivers/net/bonding/ |
| 3568 | F: include/net/bonding.h | 3570 | F: include/net/bond* |
| 3569 | F: include/uapi/linux/if_bonding.h | 3571 | F: include/uapi/linux/if_bonding.h |
| 3570 | 3572 | ||
| 3571 | BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER | 3573 | BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER |
| @@ -3907,7 +3909,9 @@ BROADCOM BNXT_EN 50 GIGABIT ETHERNET DRIVER · 335 unmodified lines | |||
| 3907 | M: Michael Chan <michael.chan@broadcom.com> | 3909 | M: Michael Chan <michael.chan@broadcom.com> |
| 3908 | L: netdev@vger.kernel.org | 3910 | L: netdev@vger.kernel.org |
| 3909 | S: Supported | 3911 | S: Supported |
| 3912 | F: drivers/firmware/broadcom/tee_bnxt_fw.c | ||
| 3910 | F: drivers/net/ethernet/broadcom/bnxt/ | 3913 | F: drivers/net/ethernet/broadcom/bnxt/ |
| 3914 | F: include/linux/firmware/broadcom/tee_bnxt_fw.h | ||
| 3911 | 3915 | ||
| 3912 | BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER | 3916 | BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER |
| 3913 | M: Arend van Spriel <aspriel@gmail.com> | 3917 | M: Arend van Spriel <aspriel@gmail.com> |
| @@ -5430,6 +5434,7 @@ F: net/ax25/sysctl_net_ax25.c · 1516 unmodified lines | |||
| 5430 | 5434 | ||
| 5431 | DATA ACCESS MONITOR | 5435 | DATA ACCESS MONITOR |
| 5432 | M: SeongJae Park <sj@kernel.org> | 5436 | M: SeongJae Park <sj@kernel.org> |
| 5437 | L: damon@lists.linux.dev | ||
| 5433 | L: linux-mm@kvack.org | 5438 | L: linux-mm@kvack.org |
| 5434 | S: Maintained | 5439 | S: Maintained |
| 5435 | F: Documentation/ABI/testing/sysfs-kernel-mm-damon | 5440 | F: Documentation/ABI/testing/sysfs-kernel-mm-damon |
| @@ -5908,7 +5913,7 @@ R: Benjamin Gaignard <benjamin.gaignard@collabora.com> · 472 unmodified lines | |||
| 5908 | R: Liam Mark <lmark@codeaurora.org> | 5913 | R: Liam Mark <lmark@codeaurora.org> |
| 5909 | R: Laura Abbott <labbott@redhat.com> | 5914 | R: Laura Abbott <labbott@redhat.com> |
| 5910 | R: Brian Starkey <Brian.Starkey@arm.com> | 5915 | R: Brian Starkey <Brian.Starkey@arm.com> |
| 5911 | R: John Stultz <john.stultz@linaro.org> | 5916 | R: John Stultz <jstultz@google.com> |
| 5912 | L: linux-media@vger.kernel.org | 5917 | L: linux-media@vger.kernel.org |
| 5913 | L: dri-devel@lists.freedesktop.org | 5918 | L: dri-devel@lists.freedesktop.org |
| 5914 | L: linaro-mm-sig@lists.linaro.org (moderated for non-subscribers) | 5919 | L: linaro-mm-sig@lists.linaro.org (moderated for non-subscribers) |
| @@ -6578,7 +6583,7 @@ F: drivers/gpu/drm/gma500/ · 663 unmodified lines | |||
| 6578 | DRM DRIVERS FOR HISILICON | 6583 | DRM DRIVERS FOR HISILICON |
| 6579 | M: Xinliang Liu <xinliang.liu@linaro.org> | 6584 | M: Xinliang Liu <xinliang.liu@linaro.org> |
| 6580 | M: Tian Tao <tiantao6@hisilicon.com> | 6585 | M: Tian Tao <tiantao6@hisilicon.com> |
| 6581 | R: John Stultz <john.stultz@linaro.org> | 6586 | R: John Stultz <jstultz@google.com> |
| 6582 | R: Xinwei Kong <kong.kongxinwei@hisilicon.com> | 6587 | R: Xinwei Kong <kong.kongxinwei@hisilicon.com> |
| 6583 | R: Chen Feng <puck.chen@hisilicon.com> | 6588 | R: Chen Feng <puck.chen@hisilicon.com> |
| 6584 | L: dri-devel@lists.freedesktop.org | 6589 | L: dri-devel@lists.freedesktop.org |
| @@ -7490,7 +7495,7 @@ F: Documentation/hwmon/f71805f.rst · 905 unmodified lines | |||
| 7490 | F: drivers/hwmon/f71805f.c | 7495 | F: drivers/hwmon/f71805f.c |
| 7491 | 7496 | ||
| 7492 | FADDR2LINE | 7497 | FADDR2LINE |
| 7493 | M: Josh Poimboeuf <jpoimboe@redhat.com> | 7498 | M: Josh Poimboeuf <jpoimboe@kernel.org> |
| 7494 | S: Maintained | 7499 | S: Maintained |
| 7495 | F: scripts/faddr2line | 7500 | F: scripts/faddr2line |
| 7496 | 7501 | ||
| @@ -8103,7 +8108,7 @@ M: Ingo Molnar <mingo@redhat.com> · 606 unmodified lines | |||
| 8103 | R: Peter Zijlstra <peterz@infradead.org> | 8108 | R: Peter Zijlstra <peterz@infradead.org> |
| 8104 | R: Darren Hart <dvhart@infradead.org> | 8109 | R: Darren Hart <dvhart@infradead.org> |
| 8105 | R: Davidlohr Bueso <dave@stgolabs.net> | 8110 | R: Davidlohr Bueso <dave@stgolabs.net> |
| 8106 | R: André Almeida <andrealmeid@collabora.com> | 8111 | R: André Almeida <andrealmeid@igalia.com> |
| 8107 | L: linux-kernel@vger.kernel.org | 8112 | L: linux-kernel@vger.kernel.org |
| 8108 | S: Maintained | 8113 | S: Maintained |
| 8109 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/core | 8114 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/core |
| @@ -8376,7 +8381,7 @@ M: Linus Walleij <linus.walleij@linaro.org> · 266 unmodified lines | |||
| 8376 | M: Bartosz Golaszewski <brgl@bgdev.pl> | 8381 | M: Bartosz Golaszewski <brgl@bgdev.pl> |
| 8377 | L: linux-gpio@vger.kernel.org | 8382 | L: linux-gpio@vger.kernel.org |
| 8378 | S: Maintained | 8383 | S: Maintained |
| 8379 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git | 8384 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git |
| 8380 | F: Documentation/ABI/obsolete/sysfs-gpio | 8385 | F: Documentation/ABI/obsolete/sysfs-gpio |
| 8381 | F: Documentation/ABI/testing/gpio-cdev | 8386 | F: Documentation/ABI/testing/gpio-cdev |
| 8382 | F: Documentation/admin-guide/gpio/ | 8387 | F: Documentation/admin-guide/gpio/ |
| @@ -8839,7 +8844,7 @@ F: Documentation/devicetree/bindings/net/hisilicon*.txt · 456 unmodified lines | |||
| 8839 | F: drivers/net/ethernet/hisilicon/ | 8844 | F: drivers/net/ethernet/hisilicon/ |
| 8840 | 8845 | ||
| 8841 | HIKEY960 ONBOARD USB GPIO HUB DRIVER | 8846 | HIKEY960 ONBOARD USB GPIO HUB DRIVER |
| 8842 | M: John Stultz <john.stultz@linaro.org> | 8847 | M: John Stultz <jstultz@google.com> |
| 8843 | L: linux-kernel@vger.kernel.org | 8848 | L: linux-kernel@vger.kernel.org |
| 8844 | S: Maintained | 8849 | S: Maintained |
| 8845 | F: drivers/misc/hisi_hikey_usb.c | 8850 | F: drivers/misc/hisi_hikey_usb.c |
| @@ -10122,7 +10127,7 @@ S: Supported · 1276 unmodified lines | |||
| 10122 | F: drivers/net/wireless/intel/iwlegacy/ | 10127 | F: drivers/net/wireless/intel/iwlegacy/ |
| 10123 | 10128 | ||
| 10124 | INTEL WIRELESS WIFI LINK (iwlwifi) | 10129 | INTEL WIRELESS WIFI LINK (iwlwifi) |
| 10125 | M: Luca Coelho <luciano.coelho@intel.com> | 10130 | M: Gregory Greenman <gregory.greenman@intel.com> |
| 10126 | L: linux-wireless@vger.kernel.org | 10131 | L: linux-wireless@vger.kernel.org |
| 10127 | S: Supported | 10132 | S: Supported |
| 10128 | W: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi | 10133 | W: https://wireless.wiki.kernel.org/en/users/drivers/iwlwifi |
| @@ -10231,8 +10236,6 @@ F: drivers/net/ethernet/sgi/ioc3-eth.c · 102 unmodified lines | |||
| 10231 | IOMAP FILESYSTEM LIBRARY | 10236 | IOMAP FILESYSTEM LIBRARY |
| 10232 | M: Christoph Hellwig <hch@infradead.org> | 10237 | M: Christoph Hellwig <hch@infradead.org> |
| 10233 | M: Darrick J. Wong <djwong@kernel.org> | 10238 | M: Darrick J. Wong <djwong@kernel.org> |
| 10234 | M: linux-xfs@vger.kernel.org | ||
| 10235 | M: linux-fsdevel@vger.kernel.org | ||
| 10236 | L: linux-xfs@vger.kernel.org | 10239 | L: linux-xfs@vger.kernel.org |
| 10237 | L: linux-fsdevel@vger.kernel.org | 10240 | L: linux-fsdevel@vger.kernel.org |
| 10238 | S: Supported | 10241 | S: Supported |
| @@ -11341,7 +11344,7 @@ F: drivers/mmc/host/litex_mmc.c · 1102 unmodified lines | |||
| 11341 | N: litex | 11344 | N: litex |
| 11342 | 11345 | ||
| 11343 | LIVE PATCHING | 11346 | LIVE PATCHING |
| 11344 | M: Josh Poimboeuf <jpoimboe@redhat.com> | 11347 | M: Josh Poimboeuf <jpoimboe@kernel.org> |
| 11345 | M: Jiri Kosina <jikos@kernel.org> | 11348 | M: Jiri Kosina <jikos@kernel.org> |
| 11346 | M: Miroslav Benes <mbenes@suse.cz> | 11349 | M: Miroslav Benes <mbenes@suse.cz> |
| 11347 | M: Petr Mladek <pmladek@suse.com> | 11350 | M: Petr Mladek <pmladek@suse.com> |
| @@ -11967,6 +11970,7 @@ M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> · 619 unmodified lines | |||
| 11967 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> | 11970 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
| 11968 | L: linux-pm@vger.kernel.org | 11971 | L: linux-pm@vger.kernel.org |
| 11969 | S: Supported | 11972 | S: Supported |
| 11973 | B: mailto:linux-samsung-soc@vger.kernel.org | ||
| 11970 | F: Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml | 11974 | F: Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml |
| 11971 | F: Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml | 11975 | F: Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml |
| 11972 | F: drivers/power/supply/max14577_charger.c | 11976 | F: drivers/power/supply/max14577_charger.c |
| @@ -11978,6 +11982,7 @@ M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> · 5 unmodified lines | |||
| 11978 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> | 11982 | M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
| 11979 | L: linux-kernel@vger.kernel.org | 11983 | L: linux-kernel@vger.kernel.org |
| 11980 | S: Supported | 11984 | S: Supported |
| 11985 | B: mailto:linux-samsung-soc@vger.kernel.org | ||
| 11981 | F: Documentation/devicetree/bindings/*/maxim,max14577.yaml | 11986 | F: Documentation/devicetree/bindings/*/maxim,max14577.yaml |
| 11982 | F: Documentation/devicetree/bindings/*/maxim,max77686.yaml | 11987 | F: Documentation/devicetree/bindings/*/maxim,max77686.yaml |
| 11983 | F: Documentation/devicetree/bindings/*/maxim,max77693.yaml | 11988 | F: Documentation/devicetree/bindings/*/maxim,max77693.yaml |
| @@ -12671,6 +12676,7 @@ MEMORY CONTROLLER DRIVERS · 687 unmodified lines | |||
| 12671 | M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> | 12676 | M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> |
| 12672 | L: linux-kernel@vger.kernel.org | 12677 | L: linux-kernel@vger.kernel.org |
| 12673 | S: Maintained | 12678 | S: Maintained |
| 12679 | B: mailto:krzysztof.kozlowski@linaro.org | ||
| 12674 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git | 12680 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl.git |
| 12675 | F: Documentation/devicetree/bindings/memory-controllers/ | 12681 | F: Documentation/devicetree/bindings/memory-controllers/ |
| 12676 | F: drivers/memory/ | 12682 | F: drivers/memory/ |
| @@ -13619,6 +13625,7 @@ F: net/core/drop_monitor.c · 942 unmodified lines | |||
| 13619 | 13625 | ||
| 13620 | NETWORKING DRIVERS | 13626 | NETWORKING DRIVERS |
| 13621 | M: "David S. Miller" <davem@davemloft.net> | 13627 | M: "David S. Miller" <davem@davemloft.net> |
| 13628 | M: Eric Dumazet <edumazet@google.com> | ||
| 13622 | M: Jakub Kicinski <kuba@kernel.org> | 13629 | M: Jakub Kicinski <kuba@kernel.org> |
| 13623 | M: Paolo Abeni <pabeni@redhat.com> | 13630 | M: Paolo Abeni <pabeni@redhat.com> |
| 13624 | L: netdev@vger.kernel.org | 13631 | L: netdev@vger.kernel.org |
| @@ -13666,6 +13673,7 @@ F: tools/testing/selftests/drivers/net/dsa/ · 41 unmodified lines | |||
| 13666 | 13673 | ||
| 13667 | NETWORKING [GENERAL] | 13674 | NETWORKING [GENERAL] |
| 13668 | M: "David S. Miller" <davem@davemloft.net> | 13675 | M: "David S. Miller" <davem@davemloft.net> |
| 13676 | M: Eric Dumazet <edumazet@google.com> | ||
| 13669 | M: Jakub Kicinski <kuba@kernel.org> | 13677 | M: Jakub Kicinski <kuba@kernel.org> |
| 13670 | M: Paolo Abeni <pabeni@redhat.com> | 13678 | M: Paolo Abeni <pabeni@redhat.com> |
| 13671 | L: netdev@vger.kernel.org | 13679 | L: netdev@vger.kernel.org |
| @@ -14212,7 +14220,7 @@ F: lib/objagg.c · 540 unmodified lines | |||
| 14212 | F: lib/test_objagg.c | 14220 | F: lib/test_objagg.c |
| 14213 | 14221 | ||
| 14214 | OBJTOOL | 14222 | OBJTOOL |
| 14215 | M: Josh Poimboeuf <jpoimboe@redhat.com> | 14223 | M: Josh Poimboeuf <jpoimboe@kernel.org> |
| 14216 | M: Peter Zijlstra <peterz@infradead.org> | 14224 | M: Peter Zijlstra <peterz@infradead.org> |
| 14217 | S: Supported | 14225 | S: Supported |
| 14218 | F: tools/objtool/ | 14226 | F: tools/objtool/ |
| @@ -15463,7 +15471,8 @@ F: tools/perf/ · 1244 unmodified lines | |||
| 15463 | PERFORMANCE EVENTS TOOLING ARM64 | 15471 | PERFORMANCE EVENTS TOOLING ARM64 |
| 15464 | R: John Garry <john.garry@huawei.com> | 15472 | R: John Garry <john.garry@huawei.com> |
| 15465 | R: Will Deacon <will@kernel.org> | 15473 | R: Will Deacon <will@kernel.org> |
| 15466 | R: Mathieu Poirier <mathieu.poirier@linaro.org> | 15474 | R: James Clark <james.clark@arm.com> |
| 15475 | R: Mike Leach <mike.leach@linaro.org> | ||
| 15467 | R: Leo Yan <leo.yan@linaro.org> | 15476 | R: Leo Yan <leo.yan@linaro.org> |
| 15468 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 15477 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 15469 | S: Supported | 15478 | S: Supported |
| @@ -15603,6 +15612,7 @@ L: linux-samsung-soc@vger.kernel.org · 133 unmodified lines | |||
| 15603 | S: Maintained | 15612 | S: Maintained |
| 15604 | C: irc://irc.libera.chat/linux-exynos | 15613 | C: irc://irc.libera.chat/linux-exynos |
| 15605 | Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/ | 15614 | Q: https://patchwork.kernel.org/project/linux-samsung-soc/list/ |
| 15615 | B: mailto:linux-samsung-soc@vger.kernel.org | ||
| 15606 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git | 15616 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git |
| 15607 | F: Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml | 15617 | F: Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml |
| 15608 | F: drivers/pinctrl/samsung/ | 15618 | F: drivers/pinctrl/samsung/ |
| @@ -17319,6 +17329,7 @@ M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> · 1710 unmodified lines | |||
| 17319 | M: Sylwester Nawrocki <s.nawrocki@samsung.com> | 17329 | M: Sylwester Nawrocki <s.nawrocki@samsung.com> |
| 17320 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 17330 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 17321 | S: Supported | 17331 | S: Supported |
| 17332 | B: mailto:linux-samsung-soc@vger.kernel.org | ||
| 17322 | F: Documentation/devicetree/bindings/sound/samsung* | 17333 | F: Documentation/devicetree/bindings/sound/samsung* |
| 17323 | F: sound/soc/samsung/ | 17334 | F: sound/soc/samsung/ |
| 17324 | 17335 | ||
| @@ -17363,6 +17374,7 @@ M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> · 38 unmodified lines | |||
| 17363 | L: linux-kernel@vger.kernel.org | 17374 | L: linux-kernel@vger.kernel.org |
| 17364 | L: linux-samsung-soc@vger.kernel.org | 17375 | L: linux-samsung-soc@vger.kernel.org |
| 17365 | S: Supported | 17376 | S: Supported |
| 17377 | B: mailto:linux-samsung-soc@vger.kernel.org | ||
| 17366 | F: Documentation/devicetree/bindings/clock/samsung,s2mps11.yaml | 17378 | F: Documentation/devicetree/bindings/clock/samsung,s2mps11.yaml |
| 17367 | F: Documentation/devicetree/bindings/mfd/samsung,s2m*.yaml | 17379 | F: Documentation/devicetree/bindings/mfd/samsung,s2m*.yaml |
| 17368 | F: Documentation/devicetree/bindings/mfd/samsung,s5m*.yaml | 17380 | F: Documentation/devicetree/bindings/mfd/samsung,s5m*.yaml |
| @@ -18777,7 +18789,7 @@ F: include/dt-bindings/reset/starfive-jh7100.h · 1408 unmodified lines | |||
| 18777 | 18789 | ||
| 18778 | STATIC BRANCH/CALL | 18790 | STATIC BRANCH/CALL |
| 18779 | M: Peter Zijlstra <peterz@infradead.org> | 18791 | M: Peter Zijlstra <peterz@infradead.org> |
| 18780 | M: Josh Poimboeuf <jpoimboe@redhat.com> | 18792 | M: Josh Poimboeuf <jpoimboe@kernel.org> |
| 18781 | M: Jason Baron <jbaron@akamai.com> | 18793 | M: Jason Baron <jbaron@akamai.com> |
| 18782 | R: Steven Rostedt <rostedt@goodmis.org> | 18794 | R: Steven Rostedt <rostedt@goodmis.org> |
| 18783 | R: Ard Biesheuvel <ardb@kernel.org> | 18795 | R: Ard Biesheuvel <ardb@kernel.org> |
| @@ -19778,7 +19790,7 @@ F: drivers/net/wireless/ti/ · 994 unmodified lines | |||
| 19778 | F: include/linux/wl12xx.h | 19790 | F: include/linux/wl12xx.h |
| 19779 | 19791 | ||
| 19780 | TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER | 19792 | TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER |
| 19781 | M: John Stultz <john.stultz@linaro.org> | 19793 | M: John Stultz <jstultz@google.com> |
| 19782 | M: Thomas Gleixner <tglx@linutronix.de> | 19794 | M: Thomas Gleixner <tglx@linutronix.de> |
| 19783 | R: Stephen Boyd <sboyd@kernel.org> | 19795 | R: Stephen Boyd <sboyd@kernel.org> |
| 19784 | L: linux-kernel@vger.kernel.org | 19796 | L: linux-kernel@vger.kernel.org |
| @@ -21428,6 +21440,15 @@ F: arch/x86/include/asm/uv/ · 1643 unmodified lines | |||
| 21428 | F: arch/x86/kernel/apic/x2apic_uv_x.c | 21440 | F: arch/x86/kernel/apic/x2apic_uv_x.c |
| 21429 | F: arch/x86/platform/uv/ | 21441 | F: arch/x86/platform/uv/ |
| 21430 | 21442 | ||
| 21443 | X86 STACK UNWINDING | ||
| 21444 | M: Josh Poimboeuf <jpoimboe@kernel.org> | ||
| 21445 | M: Peter Zijlstra <peterz@infradead.org> | ||
| 21446 | S: Supported | ||
| 21447 | F: arch/x86/include/asm/unwind*.h | ||
| 21448 | F: arch/x86/kernel/dumpstack.c | ||
| 21449 | F: arch/x86/kernel/stacktrace.c | ||
| 21450 | F: arch/x86/kernel/unwind_*.c | ||
| 21451 | |||
| 21431 | X86 VDSO | 21452 | X86 VDSO |
| 21432 | M: Andy Lutomirski <luto@kernel.org> | 21453 | M: Andy Lutomirski <luto@kernel.org> |
| 21433 | L: linux-kernel@vger.kernel.org | 21454 | L: linux-kernel@vger.kernel.org |
| @@ -21590,7 +21611,6 @@ F: drivers/xen/*swiotlb* · 156 unmodified lines | |||
| 21590 | XFS FILESYSTEM | 21611 | XFS FILESYSTEM |
| 21591 | C: irc://irc.oftc.net/xfs | 21612 | C: irc://irc.oftc.net/xfs |
| 21592 | M: Darrick J. Wong <djwong@kernel.org> | 21613 | M: Darrick J. Wong <djwong@kernel.org> |
| 21593 | M: linux-xfs@vger.kernel.org | ||
| 21594 | L: linux-xfs@vger.kernel.org | 21614 | L: linux-xfs@vger.kernel.org |
| 21595 | S: Supported | 21615 | S: Supported |
| 21596 | W: http://xfs.org/ | 21616 | W: http://xfs.org/ |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 18 | 3 | PATCHLEVEL = 18 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc4 | 5 | EXTRAVERSION = -rc7 |
| 6 | NAME = Superb Owl | 6 | NAME = Superb Owl |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -263,6 +263,8 @@ · 262 unmodified lines | |||
| 263 | compatible = "ti,am3359-tscadc"; | 263 | compatible = "ti,am3359-tscadc"; |
| 264 | reg = <0x0 0x1000>; | 264 | reg = <0x0 0x1000>; |
| 265 | interrupts = <16>; | 265 | interrupts = <16>; |
| 266 | clocks = <&adc_tsc_fck>; | ||
| 267 | clock-names = "fck"; | ||
| 266 | status = "disabled"; | 268 | status = "disabled"; |
| 267 | dmas = <&edma 53 0>, <&edma 57 0>; | 269 | dmas = <&edma 53 0>, <&edma 57 0>; |
| 268 | dma-names = "fifo0", "fifo1"; | 270 | dma-names = "fifo0", "fifo1"; |
| @@ -161,6 +161,8 @@ · 160 unmodified lines | |||
| 161 | 161 | ||
| 162 | /* HS USB Host PHY on PORT 1 */ | 162 | /* HS USB Host PHY on PORT 1 */ |
| 163 | hsusb1_phy: hsusb1_phy { | 163 | hsusb1_phy: hsusb1_phy { |
| 164 | pinctrl-names = "default"; | ||
| 165 | pinctrl-0 = <&hsusb1_rst_pins>; | ||
| 164 | compatible = "usb-nop-xceiv"; | 166 | compatible = "usb-nop-xceiv"; |
| 165 | reset-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>; /* gpio_57 */ | 167 | reset-gpios = <&gpio2 25 GPIO_ACTIVE_LOW>; /* gpio_57 */ |
| 166 | #phy-cells = <0>; | 168 | #phy-cells = <0>; |
| @@ -168,7 +170,9 @@ · 1 unmodified line | |||
| 168 | }; | 170 | }; |
| 169 | 171 | ||
| 170 | &davinci_emac { | 172 | &davinci_emac { |
| 171 | status = "okay"; | 173 | pinctrl-names = "default"; |
| 174 | pinctrl-0 = <ðernet_pins>; | ||
| 175 | status = "okay"; | ||
| 172 | }; | 176 | }; |
| 173 | 177 | ||
| 174 | &davinci_mdio { | 178 | &davinci_mdio { |
| @@ -193,6 +197,8 @@ · 18 unmodified lines | |||
| 193 | }; | 197 | }; |
| 194 | 198 | ||
| 195 | &i2c2 { | 199 | &i2c2 { |
| 200 | pinctrl-names = "default"; | ||
| 201 | pinctrl-0 = <&i2c2_pins>; | ||
| 196 | clock-frequency = <400000>; | 202 | clock-frequency = <400000>; |
| 197 | /* User DIP swithes [1:8] / User LEDS [1:2] */ | 203 | /* User DIP swithes [1:8] / User LEDS [1:2] */ |
| 198 | tca6416: gpio@21 { | 204 | tca6416: gpio@21 { |
| @@ -205,6 +211,8 @@ · 6 unmodified lines | |||
| 205 | }; | 211 | }; |
| 206 | 212 | ||
| 207 | &i2c3 { | 213 | &i2c3 { |
| 214 | pinctrl-names = "default"; | ||
| 215 | pinctrl-0 = <&i2c3_pins>; | ||
| 208 | clock-frequency = <400000>; | 216 | clock-frequency = <400000>; |
| 209 | }; | 217 | }; |
| 210 | 218 | ||
| @@ -223,6 +231,8 @@ · 12 unmodified lines | |||
| 223 | }; | 231 | }; |
| 224 | 232 | ||
| 225 | &usbhshost { | 233 | &usbhshost { |
| 234 | pinctrl-names = "default"; | ||
| 235 | pinctrl-0 = <&hsusb1_pins>; | ||
| 226 | port1-mode = "ehci-phy"; | 236 | port1-mode = "ehci-phy"; |
| 227 | }; | 237 | }; |
| 228 | 238 | ||
| @@ -231,8 +241,35 @@ · 2 unmodified lines | |||
| 231 | }; | 241 | }; |
| 232 | 242 | ||
| 233 | &omap3_pmx_core { | 243 | &omap3_pmx_core { |
| 234 | pinctrl-names = "default"; | 244 | |
| 235 | pinctrl-0 = <&hsusb1_rst_pins>; | 245 | ethernet_pins: pinmux_ethernet_pins { |
| 246 | pinctrl-single,pins = < | ||
| 247 | OMAP3_CORE1_IOPAD(0x21fe, PIN_INPUT | MUX_MODE0) /* rmii_mdio_data */ | ||
| 248 | OMAP3_CORE1_IOPAD(0x2200, MUX_MODE0) /* rmii_mdio_clk */ | ||
| 249 | OMAP3_CORE1_IOPAD(0x2202, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii_rxd0 */ | ||
| 250 | OMAP3_CORE1_IOPAD(0x2204, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii_rxd1 */ | ||
| 251 | OMAP3_CORE1_IOPAD(0x2206, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii_crs_dv */ | ||
| 252 | OMAP3_CORE1_IOPAD(0x2208, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* rmii_rxer */ | ||
| 253 | OMAP3_CORE1_IOPAD(0x220a, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* rmii_txd0 */ | ||
| 254 | OMAP3_CORE1_IOPAD(0x220c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* rmii_txd1 */ | ||
| 255 | OMAP3_CORE1_IOPAD(0x220e, PIN_OUTPUT_PULLDOWN |MUX_MODE0) /* rmii_txen */ | ||
| 256 | OMAP3_CORE1_IOPAD(0x2210, PIN_INPUT_PULLDOWN | MUX_MODE0) /* rmii_50mhz_clk */ | ||
| 257 | >; | ||
| 258 | }; | ||
| 259 | |||
| 260 | i2c2_pins: pinmux_i2c2_pins { | ||
| 261 | pinctrl-single,pins = < | ||
| 262 | OMAP3_CORE1_IOPAD(0x21be, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ | ||
| 263 | OMAP3_CORE1_IOPAD(0x21c0, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ | ||
| 264 | >; | ||
| 265 | }; | ||
| 266 | |||
| 267 | i2c3_pins: pinmux_i2c3_pins { | ||
| 268 | pinctrl-single,pins = < | ||
| 269 | OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ | ||
| 270 | OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ | ||
| 271 | >; | ||
| 272 | }; | ||
| 236 | 273 | ||
| 237 | leds_pins: pinmux_leds_pins { | 274 | leds_pins: pinmux_leds_pins { |
| 238 | pinctrl-single,pins = < | 275 | pinctrl-single,pins = < |
| @@ -300,8 +337,6 @@ · 61 unmodified lines | |||
| 300 | }; | 337 | }; |
| 301 | 338 | ||
| 302 | &omap3_pmx_core2 { | 339 | &omap3_pmx_core2 { |
| 303 | pinctrl-names = "default"; | ||
| 304 | pinctrl-0 = <&hsusb1_pins>; | ||
| 305 | 340 | ||
| 306 | hsusb1_pins: pinmux_hsusb1_pins { | 341 | hsusb1_pins: pinmux_hsusb1_pins { |
| 307 | pinctrl-single,pins = < | 342 | pinctrl-single,pins = < |
| @@ -69,6 +69,8 @@ · 68 unmodified lines | |||
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | &i2c1 { | 71 | &i2c1 { |
| 72 | pinctrl-names = "default"; | ||
| 73 | pinctrl-0 = <&i2c1_pins>; | ||
| 72 | clock-frequency = <400000>; | 74 | clock-frequency = <400000>; |
| 73 | 75 | ||
| 74 | s35390a: s35390a@30 { | 76 | s35390a: s35390a@30 { |
| @@ -179,6 +181,13 @@ · 104 unmodified lines | |||
| 179 | 181 | ||
| 180 | &omap3_pmx_core { | 182 | &omap3_pmx_core { |
| 181 | 183 | ||
| 184 | i2c1_pins: pinmux_i2c1_pins { | ||
| 185 | pinctrl-single,pins = < | ||
| 186 | OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ | ||
| 187 | OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ | ||
| 188 | >; | ||
| 189 | }; | ||
| 190 | |||
| 182 | wl12xx_buffer_pins: pinmux_wl12xx_buffer_pins { | 191 | wl12xx_buffer_pins: pinmux_wl12xx_buffer_pins { |
| 183 | pinctrl-single,pins = < | 192 | pinctrl-single,pins = < |
| 184 | OMAP3_CORE1_IOPAD(0x2156, PIN_OUTPUT | MUX_MODE4) /* mmc1_dat7.gpio_129 */ | 193 | OMAP3_CORE1_IOPAD(0x2156, PIN_OUTPUT | MUX_MODE4) /* mmc1_dat7.gpio_129 */ |
| @@ -44,7 +44,7 @@ · 43 unmodified lines | |||
| 44 | status = "okay"; | 44 | status = "okay"; |
| 45 | 45 | ||
| 46 | /* spi0.0: 4M Flash Macronix MX25R4035FM1IL0 */ | 46 | /* spi0.0: 4M Flash Macronix MX25R4035FM1IL0 */ |
| 47 | spi-flash@0 { | 47 | flash@0 { |
| 48 | compatible = "mxicy,mx25u4035", "jedec,spi-nor"; | 48 | compatible = "mxicy,mx25u4035", "jedec,spi-nor"; |
| 49 | spi-max-frequency = <33000000>; | 49 | spi-max-frequency = <33000000>; |
| 50 | reg = <0>; | 50 | reg = <0>; |
| @@ -225,7 +225,7 @@ · 224 unmodified lines | |||
| 225 | pinctrl_pio_io_reset: gpio_io_reset { | 225 | pinctrl_pio_io_reset: gpio_io_reset { |
| 226 | pinmux = <PIN_PB30__GPIO>; | 226 | pinmux = <PIN_PB30__GPIO>; |
| 227 | bias-disable; | 227 | bias-disable; |
| 228 | drive-open-drain; | 228 | drive-open-drain = <1>; |
| 229 | output-low; | 229 | output-low; |
| 230 | }; | 230 | }; |
| 231 | pinctrl_pio_input: gpio_input { | 231 | pinctrl_pio_input: gpio_input { |
| @@ -211,7 +211,7 @@ · 210 unmodified lines | |||
| 211 | pinmux = <PIN_PD12__FLEXCOM4_IO0>, //DATA | 211 | pinmux = <PIN_PD12__FLEXCOM4_IO0>, //DATA |
| 212 | <PIN_PD13__FLEXCOM4_IO1>; //CLK | 212 | <PIN_PD13__FLEXCOM4_IO1>; //CLK |
| 213 | bias-disable; | 213 | bias-disable; |
| 214 | drive-open-drain; | 214 | drive-open-drain = <1>; |
| 215 | }; | 215 | }; |
| 216 | 216 | ||
| 217 | pinctrl_pwm0 { | 217 | pinctrl_pwm0 { |
| @@ -125,7 +125,7 @@ · 124 unmodified lines | |||
| 125 | cs-gpios = <&pioA 3 GPIO_ACTIVE_HIGH>, <&pioC 11 GPIO_ACTIVE_LOW>, <0>, <0>; | 125 | cs-gpios = <&pioA 3 GPIO_ACTIVE_HIGH>, <&pioC 11 GPIO_ACTIVE_LOW>, <0>, <0>; |
| 126 | status = "okay"; | 126 | status = "okay"; |
| 127 | 127 | ||
| 128 | m25p80@0 { | 128 | flash@0 { |
| 129 | compatible = "jedec,spi-nor"; | 129 | compatible = "jedec,spi-nor"; |
| 130 | spi-max-frequency = <20000000>; | 130 | spi-max-frequency = <20000000>; |
| 131 | reg = <0>; | 131 | reg = <0>; |
| @@ -214,7 +214,7 @@ · 213 unmodified lines | |||
| 214 | pinctrl-0 = <&pinctrl_qspi1_default>; | 214 | pinctrl-0 = <&pinctrl_qspi1_default>; |
| 215 | status = "disabled"; | 215 | status = "disabled"; |
| 216 | 216 | ||
| 217 | qspi1_flash: spi_flash@0 { | 217 | qspi1_flash: flash@0 { |
| 218 | #address-cells = <1>; | 218 | #address-cells = <1>; |
| 219 | #size-cells = <1>; | 219 | #size-cells = <1>; |
| 220 | compatible = "jedec,spi-nor"; | 220 | compatible = "jedec,spi-nor"; |
| @@ -191,7 +191,7 @@ · 190 unmodified lines | |||
| 191 | &qspi1 { | 191 | &qspi1 { |
| 192 | status = "okay"; | 192 | status = "okay"; |
| 193 | 193 | ||
| 194 | qspi1_flash: spi_flash@0 { | 194 | qspi1_flash: flash@0 { |
| 195 | status = "okay"; | 195 | status = "okay"; |
| 196 | }; | 196 | }; |
| 197 | }; | 197 | }; |
| @@ -137,7 +137,7 @@ · 136 unmodified lines | |||
| 137 | pinctrl-0 = <&pinctrl_spi0_default>; | 137 | pinctrl-0 = <&pinctrl_spi0_default>; |
| 138 | status = "okay"; | 138 | status = "okay"; |
| 139 | 139 | ||
| 140 | m25p80@0 { | 140 | flash@0 { |
| 141 | compatible = "atmel,at25df321a"; | 141 | compatible = "atmel,at25df321a"; |
| 142 | reg = <0>; | 142 | reg = <0>; |
| 143 | spi-max-frequency = <50000000>; | 143 | spi-max-frequency = <50000000>; |
| @@ -57,8 +57,8 @@ · 56 unmodified lines | |||
| 57 | }; | 57 | }; |
| 58 | 58 | ||
| 59 | spi0: spi@f0004000 { | 59 | spi0: spi@f0004000 { |
| 60 | pinctrl-names = "default"; | 60 | pinctrl-names = "default", "cs"; |
| 61 | pinctrl-0 = <&pinctrl_spi0_cs>; | 61 | pinctrl-1 = <&pinctrl_spi0_cs>; |
| 62 | cs-gpios = <&pioD 13 0>, <0>, <0>, <&pioD 16 0>; | 62 | cs-gpios = <&pioD 13 0>, <0>, <0>, <&pioD 16 0>; |
| 63 | status = "okay"; | 63 | status = "okay"; |
| 64 | }; | 64 | }; |
| @@ -171,8 +171,8 @@ · 106 unmodified lines | |||
| 171 | }; | 171 | }; |
| 172 | 172 | ||
| 173 | spi1: spi@f8008000 { | 173 | spi1: spi@f8008000 { |
| 174 | pinctrl-names = "default"; | 174 | pinctrl-names = "default", "cs"; |
| 175 | pinctrl-0 = <&pinctrl_spi1_cs>; | 175 | pinctrl-1 = <&pinctrl_spi1_cs>; |
| 176 | cs-gpios = <&pioC 25 0>; | 176 | cs-gpios = <&pioC 25 0>; |
| 177 | status = "okay"; | 177 | status = "okay"; |
| 178 | }; | 178 | }; |
| @@ -49,7 +49,7 @@ · 48 unmodified lines | |||
| 49 | cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; | 49 | cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; |
| 50 | status = "okay"; | 50 | status = "okay"; |
| 51 | 51 | ||
| 52 | m25p80@0 { | 52 | flash@0 { |
| 53 | compatible = "atmel,at25df321a"; | 53 | compatible = "atmel,at25df321a"; |
| 54 | spi-max-frequency = <50000000>; | 54 | spi-max-frequency = <50000000>; |
| 55 | reg = <0>; | 55 | reg = <0>; |
| @@ -81,8 +81,8 @@ · 80 unmodified lines | |||
| 81 | }; | 81 | }; |
| 82 | 82 | ||
| 83 | spi1: spi@fc018000 { | 83 | spi1: spi@fc018000 { |
| 84 | pinctrl-names = "default"; | 84 | pinctrl-names = "default", "cs"; |
| 85 | pinctrl-0 = <&pinctrl_spi0_cs>; | 85 | pinctrl-1 = <&pinctrl_spi1_cs>; |
| 86 | cs-gpios = <&pioB 21 0>; | 86 | cs-gpios = <&pioB 21 0>; |
| 87 | status = "okay"; | 87 | status = "okay"; |
| 88 | }; | 88 | }; |
| @@ -140,7 +140,7 @@ · 51 unmodified lines | |||
| 140 | atmel,pins = | 140 | atmel,pins = |
| 141 | <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; | 141 | <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>; |
| 142 | }; | 142 | }; |
| 143 | pinctrl_spi0_cs: spi0_cs_default { | 143 | pinctrl_spi1_cs: spi1_cs_default { |
| 144 | atmel,pins = | 144 | atmel,pins = |
| 145 | <AT91_PIOB 21 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; | 145 | <AT91_PIOB 21 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>; |
| 146 | }; | 146 | }; |
| @@ -65,7 +65,7 @@ · 64 unmodified lines | |||
| 65 | spi0: spi@f8010000 { | 65 | spi0: spi@f8010000 { |
| 66 | cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; | 66 | cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; |
| 67 | status = "okay"; | 67 | status = "okay"; |
| 68 | m25p80@0 { | 68 | flash@0 { |
| 69 | compatible = "atmel,at25df321a"; | 69 | compatible = "atmel,at25df321a"; |
| 70 | spi-max-frequency = <50000000>; | 70 | spi-max-frequency = <50000000>; |
| 71 | reg = <0>; | 71 | reg = <0>; |
| @@ -495,7 +495,7 @@ · 494 unmodified lines | |||
| 495 | pinctrl_flx3_default: flx3_default { | 495 | pinctrl_flx3_default: flx3_default { |
| 496 | pinmux = <PIN_PD16__FLEXCOM3_IO0>, | 496 | pinmux = <PIN_PD16__FLEXCOM3_IO0>, |
| 497 | <PIN_PD17__FLEXCOM3_IO1>; | 497 | <PIN_PD17__FLEXCOM3_IO1>; |
| 498 | bias-disable; | 498 | bias-pull-up; |
| 499 | }; | 499 | }; |
| 500 | 500 | ||
| 501 | pinctrl_flx4_default: flx4_default { | 501 | pinctrl_flx4_default: flx4_default { |
| @@ -655,7 +655,7 @@ · 153 unmodified lines | |||
| 655 | <PIN_PB21__QSPI0_INT>; | 655 | <PIN_PB21__QSPI0_INT>; |
| 656 | bias-disable; | 656 | bias-disable; |
| 657 | slew-rate = <0>; | 657 | slew-rate = <0>; |
| 658 | atmel,drive-strength = <ATMEL_PIO_DRVSTR_HI>; | 658 | atmel,drive-strength = <ATMEL_PIO_DRVSTR_ME>; |
| 659 | }; | 659 | }; |
| 660 | 660 | ||
| 661 | pinctrl_sdmmc0_default: sdmmc0_default { | 661 | pinctrl_sdmmc0_default: sdmmc0_default { |
| @@ -59,7 +59,7 @@ · 58 unmodified lines | |||
| 59 | spi0: spi@f8010000 { | 59 | spi0: spi@f8010000 { |
| 60 | cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; | 60 | cs-gpios = <&pioC 3 0>, <0>, <0>, <0>; |
| 61 | status = "okay"; | 61 | status = "okay"; |
| 62 | m25p80@0 { | 62 | flash@0 { |
| 63 | compatible = "n25q32b", "jedec,spi-nor"; | 63 | compatible = "n25q32b", "jedec,spi-nor"; |
| 64 | spi-max-frequency = <50000000>; | 64 | spi-max-frequency = <50000000>; |
| 65 | reg = <0>; | 65 | reg = <0>; |
| @@ -73,7 +73,7 @@ · 72 unmodified lines | |||
| 73 | spi0: spi@fffe0000 { | 73 | spi0: spi@fffe0000 { |
| 74 | status = "okay"; | 74 | status = "okay"; |
| 75 | cs-gpios = <&pioA 3 0>, <0>, <0>, <0>; | 75 | cs-gpios = <&pioA 3 0>, <0>, <0>, <0>; |
| 76 | mtd_dataflash@0 { | 76 | flash@0 { |
| 77 | compatible = "atmel,at45", "atmel,dataflash"; | 77 | compatible = "atmel,at45", "atmel,dataflash"; |
| 78 | spi-max-frequency = <15000000>; | 78 | spi-max-frequency = <15000000>; |
| 79 | reg = <0>; | 79 | reg = <0>; |
| @@ -94,7 +94,7 @@ · 14 unmodified lines | |||
| 94 | status = "okay"; | 94 | status = "okay"; |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | nor_flash@10000000 { | 97 | flash@10000000 { |
| 98 | compatible = "cfi-flash"; | 98 | compatible = "cfi-flash"; |
| 99 | reg = <0x10000000 0x800000>; | 99 | reg = <0x10000000 0x800000>; |
| 100 | linux,mtd-name = "physmap-flash.0"; | 100 | linux,mtd-name = "physmap-flash.0"; |
| @@ -92,7 +92,7 @@ · 91 unmodified lines | |||
| 92 | 92 | ||
| 93 | spi0: spi@fffc8000 { | 93 | spi0: spi@fffc8000 { |
| 94 | cs-gpios = <0>, <&pioC 11 0>, <0>, <0>; | 94 | cs-gpios = <0>, <&pioC 11 0>, <0>, <0>; |
| 95 | mtd_dataflash@1 { | 95 | flash@1 { |
| 96 | compatible = "atmel,at45", "atmel,dataflash"; | 96 | compatible = "atmel,at45", "atmel,dataflash"; |
| 97 | spi-max-frequency = <50000000>; | 97 | spi-max-frequency = <50000000>; |
| 98 | reg = <1>; | 98 | reg = <1>; |
| @@ -145,7 +145,7 @@ · 144 unmodified lines | |||
| 145 | cs-gpios = <&pioA 3 0>, <0>, <&pioA 28 0>, <0>; | 145 | cs-gpios = <&pioA 3 0>, <0>, <&pioA 28 0>, <0>; |
| 146 | status = "okay"; | 146 | status = "okay"; |
| 147 | 147 | ||
| 148 | mtd_dataflash@0 { | 148 | flash@0 { |
| 149 | compatible = "atmel,at45", "atmel,dataflash"; | 149 | compatible = "atmel,at45", "atmel,dataflash"; |
| 150 | reg = <0>; | 150 | reg = <0>; |
| 151 | spi-max-frequency = <15000000>; | 151 | spi-max-frequency = <15000000>; |
| @@ -95,7 +95,7 @@ · 94 unmodified lines | |||
| 95 | spi0: spi@fffa4000 { | 95 | spi0: spi@fffa4000 { |
| 96 | status = "okay"; | 96 | status = "okay"; |
| 97 | cs-gpios = <&pioA 5 0>, <0>, <0>, <0>; | 97 | cs-gpios = <&pioA 5 0>, <0>, <0>, <0>; |
| 98 | mtd_dataflash@0 { | 98 | flash@0 { |
| 99 | compatible = "atmel,at45", "atmel,dataflash"; | 99 | compatible = "atmel,at45", "atmel,dataflash"; |
| 100 | spi-max-frequency = <50000000>; | 100 | spi-max-frequency = <50000000>; |
| 101 | reg = <0>; | 101 | reg = <0>; |
| @@ -110,7 +110,7 @@ · 109 unmodified lines | |||
| 110 | 110 | ||
| 111 | spi0: spi@fffc8000 { | 111 | spi0: spi@fffc8000 { |
| 112 | cs-gpios = <0>, <&pioC 11 0>, <0>, <0>; | 112 | cs-gpios = <0>, <&pioC 11 0>, <0>, <0>; |
| 113 | mtd_dataflash@1 { | 113 | flash@1 { |
| 114 | compatible = "atmel,at45", "atmel,dataflash"; | 114 | compatible = "atmel,at45", "atmel,dataflash"; |
| 115 | spi-max-frequency = <50000000>; | 115 | spi-max-frequency = <50000000>; |
| 116 | reg = <1>; | 116 | reg = <1>; |
| @@ -214,11 +214,23 @@ · 97 unmodified lines | |||
| 214 | 24c512@50 { | 214 | 24c512@50 { |
| 215 | compatible = "atmel,24c512"; | 215 | compatible = "atmel,24c512"; |
| 216 | reg = <0x50>; | 216 | reg = <0x50>; |
| 217 | vcc-supply = <®_3v3>; | ||
| 217 | }; | 218 | }; |
| 218 | 219 | ||
| 219 | wm8731: wm8731@1b { | 220 | wm8731: wm8731@1b { |
| 220 | compatible = "wm8731"; | 221 | compatible = "wm8731"; |
| 221 | reg = <0x1b>; | 222 | reg = <0x1b>; |
| 223 | |||
| 224 | /* PCK0 at 12MHz */ | ||
| 225 | clocks = <&pmc PMC_TYPE_SYSTEM 8>; | ||
| 226 | clock-names = "mclk"; | ||
| 227 | assigned-clocks = <&pmc PMC_TYPE_SYSTEM 8>; | ||
| 228 | assigned-clock-rates = <12000000>; | ||
| 229 | |||
| 230 | HPVDD-supply = <&vcc_dac>; | ||
| 231 | AVDD-supply = <&vcc_dac>; | ||
| 232 | DCVDD-supply = <®_3v3>; | ||
| 233 | DBVDD-supply = <®_3v3>; | ||
| 222 | }; | 234 | }; |
| 223 | }; | 235 | }; |
| 224 | 236 | ||
| @@ -254,4 +266,35 @@ · 29 unmodified lines | |||
| 254 | atmel,ssc-controller = <&ssc0>; | 266 | atmel,ssc-controller = <&ssc0>; |
| 255 | atmel,audio-codec = <&wm8731>; | 267 | atmel,audio-codec = <&wm8731>; |
| 256 | }; | 268 | }; |
| 269 | |||
| 270 | reg_5v: fixedregulator0 { | ||
| 271 | compatible = "regulator-fixed"; | ||
| 272 | regulator-name = "5V"; | ||
| 273 | regulator-min-microvolt = <5000000>; | ||
| 274 | regulator-max-microvolt = <5000000>; | ||
| 275 | }; | ||
| 276 | |||
| 277 | reg_3v3: fixedregulator1 { | ||
| 278 | compatible = "regulator-fixed"; | ||
| 279 | regulator-name = "3V3"; | ||
| 280 | vin-supply = <®_5v>; | ||
| 281 | regulator-min-microvolt = <3300000>; | ||
| 282 | regulator-max-microvolt = <3300000>; | ||
| 283 | }; | ||
| 284 | |||
| 285 | reg_1v: fixedregulator2 { | ||
| 286 | compatible = "regulator-fixed"; | ||
| 287 | regulator-name = "1V"; | ||
| 288 | vin-supply = <®_5v>; | ||
| 289 | regulator-min-microvolt = <1000000>; | ||
| 290 | regulator-max-microvolt = <1000000>; | ||
| 291 | }; | ||
| 292 | |||
| 293 | vcc_dac: fixedregulator3 { | ||
| 294 | compatible = "regulator-fixed"; | ||
| 295 | regulator-name = "VCC_DAC"; | ||
| 296 | vin-supply = <®_3v3>; | ||
| 297 | regulator-min-microvolt = <3300000>; | ||
| 298 | regulator-max-microvolt = <3300000>; | ||
| 299 | }; | ||
| 257 | }; | 300 | }; |
| @@ -167,7 +167,7 @@ · 166 unmodified lines | |||
| 167 | spi0: spi@fffa4000{ | 167 | spi0: spi@fffa4000{ |
| 168 | status = "okay"; | 168 | status = "okay"; |
| 169 | cs-gpios = <&pioB 3 0>, <0>, <0>, <0>; | 169 | cs-gpios = <&pioB 3 0>, <0>, <0>, <0>; |
| 170 | mtd_dataflash@0 { | 170 | flash@0 { |
| 171 | compatible = "atmel,at45", "atmel,dataflash"; | 171 | compatible = "atmel,at45", "atmel,dataflash"; |
| 172 | spi-max-frequency = <13000000>; | 172 | spi-max-frequency = <13000000>; |
| 173 | reg = <0>; | 173 | reg = <0>; |
| @@ -119,7 +119,7 @@ · 118 unmodified lines | |||
| 119 | spi0: spi@f0000000 { | 119 | spi0: spi@f0000000 { |
| 120 | status = "okay"; | 120 | status = "okay"; |
| 121 | cs-gpios = <&pioA 14 0>, <0>, <0>, <0>; | 121 | cs-gpios = <&pioA 14 0>, <0>, <0>, <0>; |
| 122 | m25p80@0 { | 122 | flash@0 { |
| 123 | compatible = "atmel,at25df321a"; | 123 | compatible = "atmel,at25df321a"; |
| 124 | spi-max-frequency = <50000000>; | 124 | spi-max-frequency = <50000000>; |
| 125 | reg = <0>; | 125 | reg = <0>; |
| @@ -180,7 +180,7 @@ · 179 unmodified lines | |||
| 180 | spi0: spi@fffcc000 { | 180 | spi0: spi@fffcc000 { |
| 181 | status = "okay"; | 181 | status = "okay"; |
| 182 | cs-gpios = <&pioA 28 0>, <0>, <0>, <0>; | 182 | cs-gpios = <&pioA 28 0>, <0>, <0>, <0>; |
| 183 | mtd_dataflash@0 { | 183 | flash@0 { |
| 184 | compatible = "atmel,at45", "atmel,dataflash"; | 184 | compatible = "atmel,at45", "atmel,dataflash"; |
| 185 | spi-max-frequency = <15000000>; | 185 | spi-max-frequency = <15000000>; |
| 186 | reg = <0>; | 186 | reg = <0>; |
| @@ -125,7 +125,7 @@ · 124 unmodified lines | |||
| 125 | cs-gpios = <&pioA 14 0>, <0>, <0>, <0>; | 125 | cs-gpios = <&pioA 14 0>, <0>, <0>, <0>; |
| 126 | status = "disabled"; /* conflicts with mmc1 */ | 126 | status = "disabled"; /* conflicts with mmc1 */ |
| 127 | 127 | ||
| 128 | m25p80@0 { | 128 | flash@0 { |
| 129 | compatible = "atmel,at25df321a"; | 129 | compatible = "atmel,at25df321a"; |
| 130 | spi-max-frequency = <50000000>; | 130 | spi-max-frequency = <50000000>; |
| 131 | reg = <0>; | 131 | reg = <0>; |
| @@ -4188,11 +4188,11 @@ · 4187 unmodified lines | |||
| 4188 | reg = <0x1d0010 0x4>; | 4188 | reg = <0x1d0010 0x4>; |
| 4189 | reg-names = "sysc"; | 4189 | reg-names = "sysc"; |
| 4190 | ti,sysc-midle = <SYSC_IDLE_FORCE>, | 4190 | ti,sysc-midle = <SYSC_IDLE_FORCE>, |
| 4191 | <SYSC_IDLE_NO>, | 4191 | <SYSC_IDLE_NO>; |
| 4192 | <SYSC_IDLE_SMART>; | ||
| 4193 | ti,sysc-sidle = <SYSC_IDLE_FORCE>, | 4192 | ti,sysc-sidle = <SYSC_IDLE_FORCE>, |
| 4194 | <SYSC_IDLE_NO>, | 4193 | <SYSC_IDLE_NO>, |
| 4195 | <SYSC_IDLE_SMART>; | 4194 | <SYSC_IDLE_SMART>; |
| 4195 | power-domains = <&prm_vpe>; | ||
| 4196 | clocks = <&vpe_clkctrl DRA7_VPE_VPE_CLKCTRL 0>; | 4196 | clocks = <&vpe_clkctrl DRA7_VPE_VPE_CLKCTRL 0>; |
| 4197 | clock-names = "fck"; | 4197 | clock-names = "fck"; |
| 4198 | #address-cells = <1>; | 4198 | #address-cells = <1>; |
| @@ -286,6 +286,8 @@ · 285 unmodified lines | |||
| 286 | codec: sgtl5000@a { | 286 | codec: sgtl5000@a { |
| 287 | compatible = "fsl,sgtl5000"; | 287 | compatible = "fsl,sgtl5000"; |
| 288 | reg = <0x0a>; | 288 | reg = <0x0a>; |
| 289 | pinctrl-names = "default"; | ||
| 290 | pinctrl-0 = <&pinctrl_sgtl5000>; | ||
| 289 | clocks = <&clks IMX6QDL_CLK_CKO>; | 291 | clocks = <&clks IMX6QDL_CLK_CKO>; |
| 290 | VDDA-supply = <®_module_3v3_audio>; | 292 | VDDA-supply = <®_module_3v3_audio>; |
| 291 | VDDIO-supply = <®_module_3v3>; | 293 | VDDIO-supply = <®_module_3v3>; |
| @@ -517,8 +519,6 @@ · 225 unmodified lines | |||
| 517 | MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x130b0 | 519 | MX6QDL_PAD_DISP0_DAT21__AUD4_TXD 0x130b0 |
| 518 | MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x130b0 | 520 | MX6QDL_PAD_DISP0_DAT22__AUD4_TXFS 0x130b0 |
| 519 | MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x130b0 | 521 | MX6QDL_PAD_DISP0_DAT23__AUD4_RXD 0x130b0 |
| 520 | /* SGTL5000 sys_mclk */ | ||
| 521 | MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x130b0 | ||
| 522 | >; | 522 | >; |
| 523 | }; | 523 | }; |
| 524 | 524 | ||
| @@ -811,6 +811,12 @@ · 286 unmodified lines | |||
| 811 | >; | 811 | >; |
| 812 | }; | 812 | }; |
| 813 | 813 | ||
| 814 | pinctrl_sgtl5000: sgtl5000grp { | ||
| 815 | fsl,pins = < | ||
| 816 | MX6QDL_PAD_GPIO_5__CCM_CLKO1 0x130b0 | ||
| 817 | >; | ||
| 818 | }; | ||
| 819 | |||
| 814 | pinctrl_spdif: spdifgrp { | 820 | pinctrl_spdif: spdifgrp { |
| 815 | fsl,pins = < | 821 | fsl,pins = < |
| 816 | MX6QDL_PAD_GPIO_16__SPDIF_IN 0x1b0b0 | 822 | MX6QDL_PAD_GPIO_16__SPDIF_IN 0x1b0b0 |
| @@ -37,7 +37,7 @@ · 36 unmodified lines | |||
| 37 | 37 | ||
| 38 | reg_sd1_vmmc: regulator-sd1-vmmc { | 38 | reg_sd1_vmmc: regulator-sd1-vmmc { |
| 39 | compatible = "regulator-gpio"; | 39 | compatible = "regulator-gpio"; |
| 40 | gpio = <&gpio5 9 GPIO_ACTIVE_HIGH>; | 40 | gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>; |
| 41 | pinctrl-names = "default"; | 41 | pinctrl-names = "default"; |
| 42 | pinctrl-0 = <&pinctrl_snvs_reg_sd>; | 42 | pinctrl-0 = <&pinctrl_snvs_reg_sd>; |
| 43 | regulator-always-on; | 43 | regulator-always-on; |
| @@ -11,3 +11,18 @@ · 10 unmodified lines | |||
| 11 | model = "LogicPD Zoom OMAP35xx SOM-LV Development Kit"; | 11 | model = "LogicPD Zoom OMAP35xx SOM-LV Development Kit"; |
| 12 | compatible = "logicpd,dm3730-som-lv-devkit", "ti,omap3430", "ti,omap3"; | 12 | compatible = "logicpd,dm3730-som-lv-devkit", "ti,omap3430", "ti,omap3"; |
| 13 | }; | 13 | }; |
| 14 | |||
| 15 | &omap3_pmx_core2 { | ||
| 16 | pinctrl-names = "default"; | ||
| 17 | pinctrl-0 = <&hsusb2_2_pins>; | ||
| 18 | hsusb2_2_pins: pinmux_hsusb2_2_pins { | ||
| 19 | pinctrl-single,pins = < | ||
| 20 | OMAP3430_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ | ||
| 21 | OMAP3430_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ | ||
| 22 | OMAP3430_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ | ||
| 23 | OMAP3430_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ | ||
| 24 | OMAP3430_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ | ||
| 25 | OMAP3430_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ | ||
| 26 | >; | ||
| 27 | }; | ||
| 28 | }; | ||
| @@ -11,3 +11,18 @@ · 10 unmodified lines | |||
| 11 | model = "LogicPD Zoom DM3730 SOM-LV Development Kit"; | 11 | model = "LogicPD Zoom DM3730 SOM-LV Development Kit"; |
| 12 | compatible = "logicpd,dm3730-som-lv-devkit", "ti,omap3630", "ti,omap3"; | 12 | compatible = "logicpd,dm3730-som-lv-devkit", "ti,omap3630", "ti,omap3"; |
| 13 | }; | 13 | }; |
| 14 | |||
| 15 | &omap3_pmx_core2 { | ||
| 16 | pinctrl-names = "default"; | ||
| 17 | pinctrl-0 = <&hsusb2_2_pins>; | ||
| 18 | hsusb2_2_pins: pinmux_hsusb2_2_pins { | ||
| 19 | pinctrl-single,pins = < | ||
| 20 | OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ | ||
| 21 | OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ | ||
| 22 | OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ | ||
| 23 | OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ | ||
| 24 | OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ | ||
| 25 | OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ | ||
| 26 | >; | ||
| 27 | }; | ||
| 28 | }; | ||
| @@ -265,21 +265,6 @@ · 264 unmodified lines | |||
| 265 | }; | 265 | }; |
| 266 | }; | 266 | }; |
| 267 | 267 | ||
| 268 | &omap3_pmx_core2 { | ||
| 269 | pinctrl-names = "default"; | ||
| 270 | pinctrl-0 = <&hsusb2_2_pins>; | ||
| 271 | hsusb2_2_pins: pinmux_hsusb2_2_pins { | ||
| 272 | pinctrl-single,pins = < | ||
| 273 | OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ | ||
| 274 | OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ | ||
| 275 | OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ | ||
| 276 | OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ | ||
| 277 | OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ | ||
| 278 | OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ | ||
| 279 | >; | ||
| 280 | }; | ||
| 281 | }; | ||
| 282 | |||
| 283 | &uart2 { | 268 | &uart2 { |
| 284 | interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>; | 269 | interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>; |
| 285 | pinctrl-names = "default"; | 270 | pinctrl-names = "default"; |
| @@ -31,6 +31,8 @@ · 30 unmodified lines | |||
| 31 | aliases { | 31 | aliases { |
| 32 | display0 = &lcd; | 32 | display0 = &lcd; |
| 33 | display1 = &tv0; | 33 | display1 = &tv0; |
| 34 | /delete-property/ mmc2; | ||
| 35 | /delete-property/ mmc3; | ||
| 34 | }; | 36 | }; |
| 35 | 37 | ||
| 36 | ldo_3v3: fixedregulator { | 38 | ldo_3v3: fixedregulator { |
| @@ -26,7 +26,7 @@ · 25 unmodified lines | |||
| 26 | spi0: spi@f0004000 { | 26 | spi0: spi@f0004000 { |
| 27 | dmas = <0>, <0>; /* Do not use DMA for spi0 */ | 27 | dmas = <0>, <0>; /* Do not use DMA for spi0 */ |
| 28 | 28 | ||
| 29 | m25p80@0 { | 29 | flash@0 { |
| 30 | compatible = "atmel,at25df321a"; | 30 | compatible = "atmel,at25df321a"; |
| 31 | spi-max-frequency = <50000000>; | 31 | spi-max-frequency = <50000000>; |
| 32 | reg = <0>; | 32 | reg = <0>; |
| @@ -25,7 +25,7 @@ · 24 unmodified lines | |||
| 25 | spi0: spi@f0004000 { | 25 | spi0: spi@f0004000 { |
| 26 | dmas = <0>, <0>; /* Do not use DMA for spi0 */ | 26 | dmas = <0>, <0>; /* Do not use DMA for spi0 */ |
| 27 | 27 | ||
| 28 | m25p80@0 { | 28 | flash@0 { |
| 29 | compatible = "atmel,at25df321a"; | 29 | compatible = "atmel,at25df321a"; |
| 30 | spi-max-frequency = <50000000>; | 30 | spi-max-frequency = <50000000>; |
| 31 | reg = <0>; | 31 | reg = <0>; |
| @@ -601,9 +601,9 @@ · 600 unmodified lines | |||
| 601 | #size-cells = <0>; | 601 | #size-cells = <0>; |
| 602 | clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; | 602 | clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; |
| 603 | atmel,fifo-size = <32>; | 603 | atmel,fifo-size = <32>; |
| 604 | dmas = <&dma0 AT91_XDMAC_DT_PERID(7)>, | 604 | dmas = <&dma0 AT91_XDMAC_DT_PERID(8)>, |
| 605 | <&dma0 AT91_XDMAC_DT_PERID(8)>; | 605 | <&dma0 AT91_XDMAC_DT_PERID(7)>; |
| 606 | dma-names = "rx", "tx"; | 606 | dma-names = "tx", "rx"; |
| 607 | status = "disabled"; | 607 | status = "disabled"; |
| 608 | }; | 608 | }; |
| 609 | }; | 609 | }; |
| @@ -786,9 +786,9 @@ · 176 unmodified lines | |||
| 786 | #size-cells = <0>; | 786 | #size-cells = <0>; |
| 787 | clocks = <&pmc PMC_TYPE_PERIPHERAL 46>; | 787 | clocks = <&pmc PMC_TYPE_PERIPHERAL 46>; |
| 788 | atmel,fifo-size = <32>; | 788 | atmel,fifo-size = <32>; |
| 789 | dmas = <&dma0 AT91_XDMAC_DT_PERID(21)>, | 789 | dmas = <&dma0 AT91_XDMAC_DT_PERID(22)>, |
| 790 | <&dma0 AT91_XDMAC_DT_PERID(22)>; | 790 | <&dma0 AT91_XDMAC_DT_PERID(21)>; |
| 791 | dma-names = "rx", "tx"; | 791 | dma-names = "tx", "rx"; |
| 792 | status = "disabled"; | 792 | status = "disabled"; |
| 793 | }; | 793 | }; |
| 794 | }; | 794 | }; |
| @@ -810,9 +810,9 @@ · 15 unmodified lines | |||
| 810 | #size-cells = <0>; | 810 | #size-cells = <0>; |
| 811 | clocks = <&pmc PMC_TYPE_PERIPHERAL 47>; | 811 | clocks = <&pmc PMC_TYPE_PERIPHERAL 47>; |
| 812 | atmel,fifo-size = <32>; | 812 | atmel,fifo-size = <32>; |
| 813 | dmas = <&dma0 AT91_XDMAC_DT_PERID(23)>, | 813 | dmas = <&dma0 AT91_XDMAC_DT_PERID(24)>, |
| 814 | <&dma0 AT91_XDMAC_DT_PERID(24)>; | 814 | <&dma0 AT91_XDMAC_DT_PERID(23)>; |
| 815 | dma-names = "rx", "tx"; | 815 | dma-names = "tx", "rx"; |
| 816 | status = "disabled"; | 816 | status = "disabled"; |
| 817 | }; | 817 | }; |
| 818 | }; | 818 | }; |
| @@ -60,7 +60,7 @@ · 59 unmodified lines | |||
| 60 | spi0: spi@fffa4000 { | 60 | spi0: spi@fffa4000 { |
| 61 | cs-gpios = <&pioB 15 GPIO_ACTIVE_HIGH>; | 61 | cs-gpios = <&pioB 15 GPIO_ACTIVE_HIGH>; |
| 62 | status = "okay"; | 62 | status = "okay"; |
| 63 | mtd_dataflash@0 { | 63 | flash@0 { |
| 64 | compatible = "atmel,at45", "atmel,dataflash"; | 64 | compatible = "atmel,at45", "atmel,dataflash"; |
| 65 | reg = <0>; | 65 | reg = <0>; |
| 66 | spi-max-frequency = <15000000>; | 66 | spi-max-frequency = <15000000>; |
| @@ -673,6 +673,7 @@ CONFIG_VIDEO_STI_DELTA=m · 672 unmodified lines | |||
| 673 | CONFIG_VIDEO_RENESAS_FDP1=m | 673 | CONFIG_VIDEO_RENESAS_FDP1=m |
| 674 | CONFIG_VIDEO_RENESAS_JPU=m | 674 | CONFIG_VIDEO_RENESAS_JPU=m |
| 675 | CONFIG_VIDEO_RENESAS_VSP1=m | 675 | CONFIG_VIDEO_RENESAS_VSP1=m |
| 676 | CONFIG_VIDEO_TEGRA_VDE=m | ||
| 676 | CONFIG_V4L_TEST_DRIVERS=y | 677 | CONFIG_V4L_TEST_DRIVERS=y |
| 677 | CONFIG_VIDEO_VIVID=m | 678 | CONFIG_VIDEO_VIVID=m |
| 678 | CONFIG_VIDEO_ADV7180=m | 679 | CONFIG_VIDEO_ADV7180=m |
| @@ -286,7 +286,8 @@ CONFIG_SERIO_NVEC_PS2=y · 285 unmodified lines | |||
| 286 | CONFIG_NVEC_POWER=y | 286 | CONFIG_NVEC_POWER=y |
| 287 | CONFIG_NVEC_PAZ00=y | 287 | CONFIG_NVEC_PAZ00=y |
| 288 | CONFIG_STAGING_MEDIA=y | 288 | CONFIG_STAGING_MEDIA=y |
| 289 | CONFIG_TEGRA_VDE=y | 289 | CONFIG_V4L_MEM2MEM_DRIVERS=y |
| 290 | CONFIG_VIDEO_TEGRA_VDE=y | ||
| 290 | CONFIG_CHROME_PLATFORMS=y | 291 | CONFIG_CHROME_PLATFORMS=y |
| 291 | CONFIG_CROS_EC=y | 292 | CONFIG_CROS_EC=y |
| 292 | CONFIG_CROS_EC_I2C=m | 293 | CONFIG_CROS_EC_I2C=m |
| @@ -440,6 +440,9 @@ extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); · 439 unmodified lines | |||
| 440 | #define ARCH_HAS_VALID_PHYS_ADDR_RANGE | 440 | #define ARCH_HAS_VALID_PHYS_ADDR_RANGE |
| 441 | extern int valid_phys_addr_range(phys_addr_t addr, size_t size); | 441 | extern int valid_phys_addr_range(phys_addr_t addr, size_t size); |
| 442 | extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); | 442 | extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); |
| 443 | extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, | ||
| 444 | unsigned long flags); | ||
| 445 | #define arch_memremap_can_ram_remap arch_memremap_can_ram_remap | ||
| 443 | #endif | 446 | #endif |
| 444 | 447 | ||
| 445 | /* | 448 | /* |
| @@ -17,7 +17,6 @@ menuconfig ARCH_EXYNOS · 16 unmodified lines | |||
| 17 | select EXYNOS_PMU | 17 | select EXYNOS_PMU |
| 18 | select EXYNOS_SROM | 18 | select EXYNOS_SROM |
| 19 | select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS | 19 | select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS |
| 20 | select GPIOLIB | ||
| 21 | select HAVE_ARM_ARCH_TIMER if ARCH_EXYNOS5 | 20 | select HAVE_ARM_ARCH_TIMER if ARCH_EXYNOS5 |
| 22 | select HAVE_ARM_SCU if SMP | 21 | select HAVE_ARM_SCU if SMP |
| 23 | select PINCTRL | 22 | select PINCTRL |
| @@ -314,10 +314,12 @@ void __init omap_gic_of_init(void) · 313 unmodified lines | |||
| 314 | 314 | ||
| 315 | np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic"); | 315 | np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic"); |
| 316 | gic_dist_base_addr = of_iomap(np, 0); | 316 | gic_dist_base_addr = of_iomap(np, 0); |
| 317 | of_node_put(np); | ||
| 317 | WARN_ON(!gic_dist_base_addr); | 318 | WARN_ON(!gic_dist_base_addr); |
| 318 | 319 | ||
| 319 | np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-twd-timer"); | 320 | np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-twd-timer"); |
| 320 | twd_base = of_iomap(np, 0); | 321 | twd_base = of_iomap(np, 0); |
| 322 | of_node_put(np); | ||
| 321 | WARN_ON(!twd_base); | 323 | WARN_ON(!twd_base); |
| 322 | 324 | ||
| 323 | skip_errata_init: | 325 | skip_errata_init: |
| @@ -493,3 +493,11 @@ void __init early_ioremap_init(void) · 492 unmodified lines | |||
| 493 | { | 493 | { |
| 494 | early_ioremap_setup(); | 494 | early_ioremap_setup(); |
| 495 | } | 495 | } |
| 496 | |||
| 497 | bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, | ||
| 498 | unsigned long flags) | ||
| 499 | { | ||
| 500 | unsigned long pfn = PHYS_PFN(offset); | ||
| 501 | |||
| 502 | return memblock_is_map_memory(pfn); | ||
| 503 | } | ||
| @@ -11,26 +11,6 @@ · 10 unmodified lines | |||
| 11 | compatible = "operating-points-v2"; | 11 | compatible = "operating-points-v2"; |
| 12 | opp-shared; | 12 | opp-shared; |
| 13 | 13 | ||
| 14 | opp-100000000 { | ||
| 15 | opp-hz = /bits/ 64 <100000000>; | ||
| 16 | opp-microvolt = <731000>; | ||
| 17 | }; | ||
| 18 | |||
| 19 | opp-250000000 { | ||
| 20 | opp-hz = /bits/ 64 <250000000>; | ||
| 21 | opp-microvolt = <731000>; | ||
| 22 | }; | ||
| 23 | |||
| 24 | opp-500000000 { | ||
| 25 | opp-hz = /bits/ 64 <500000000>; | ||
| 26 | opp-microvolt = <731000>; | ||
| 27 | }; | ||
| 28 | |||
| 29 | opp-667000000 { | ||
| 30 | opp-hz = /bits/ 64 <667000000>; | ||
| 31 | opp-microvolt = <731000>; | ||
| 32 | }; | ||
| 33 | |||
| 34 | opp-1000000000 { | 14 | opp-1000000000 { |
| 35 | opp-hz = /bits/ 64 <1000000000>; | 15 | opp-hz = /bits/ 64 <1000000000>; |
| 36 | opp-microvolt = <761000>; | 16 | opp-microvolt = <761000>; |
| @@ -71,26 +51,6 @@ · 34 unmodified lines | |||
| 71 | compatible = "operating-points-v2"; | 51 | compatible = "operating-points-v2"; |
| 72 | opp-shared; | 52 | opp-shared; |
| 73 | 53 | ||
| 74 | opp-100000000 { | ||
| 75 | opp-hz = /bits/ 64 <100000000>; | ||
| 76 | opp-microvolt = <731000>; | ||
| 77 | }; | ||
| 78 | |||
| 79 | opp-250000000 { | ||
| 80 | opp-hz = /bits/ 64 <250000000>; | ||
| 81 | opp-microvolt = <731000>; | ||
| 82 | }; | ||
| 83 | |||
| 84 | opp-500000000 { | ||
| 85 | opp-hz = /bits/ 64 <500000000>; | ||
| 86 | opp-microvolt = <731000>; | ||
| 87 | }; | ||
| 88 | |||
| 89 | opp-667000000 { | ||
| 90 | opp-hz = /bits/ 64 <667000000>; | ||
| 91 | opp-microvolt = <731000>; | ||
| 92 | }; | ||
| 93 | |||
| 94 | opp-1000000000 { | 54 | opp-1000000000 { |
| 95 | opp-hz = /bits/ 64 <1000000000>; | 55 | opp-hz = /bits/ 64 <1000000000>; |
| 96 | opp-microvolt = <731000>; | 56 | opp-microvolt = <731000>; |
| @@ -11,26 +11,6 @@ · 10 unmodified lines | |||
| 11 | compatible = "operating-points-v2"; | 11 | compatible = "operating-points-v2"; |
| 12 | opp-shared; | 12 | opp-shared; |
| 13 | 13 | ||
| 14 | opp-100000000 { | ||
| 15 | opp-hz = /bits/ 64 <100000000>; | ||
| 16 | opp-microvolt = <731000>; | ||
| 17 | }; | ||
| 18 | |||
| 19 | opp-250000000 { | ||
| 20 | opp-hz = /bits/ 64 <250000000>; | ||
| 21 | opp-microvolt = <731000>; | ||
| 22 | }; | ||
| 23 | |||
| 24 | opp-500000000 { | ||
| 25 | opp-hz = /bits/ 64 <500000000>; | ||
| 26 | opp-microvolt = <731000>; | ||
| 27 | }; | ||
| 28 | |||
| 29 | opp-667000000 { | ||
| 30 | opp-hz = /bits/ 64 <667000000>; | ||
| 31 | opp-microvolt = <731000>; | ||
| 32 | }; | ||
| 33 | |||
| 34 | opp-1000000000 { | 14 | opp-1000000000 { |
| 35 | opp-hz = /bits/ 64 <1000000000>; | 15 | opp-hz = /bits/ 64 <1000000000>; |
| 36 | opp-microvolt = <731000>; | 16 | opp-microvolt = <731000>; |
| @@ -76,26 +56,6 @@ · 39 unmodified lines | |||
| 76 | compatible = "operating-points-v2"; | 56 | compatible = "operating-points-v2"; |
| 77 | opp-shared; | 57 | opp-shared; |
| 78 | 58 | ||
| 79 | opp-100000000 { | ||
| 80 | opp-hz = /bits/ 64 <100000000>; | ||
| 81 | opp-microvolt = <751000>; | ||
| 82 | }; | ||
| 83 | |||
| 84 | opp-250000000 { | ||
| 85 | opp-hz = /bits/ 64 <250000000>; | ||
| 86 | opp-microvolt = <751000>; | ||
| 87 | }; | ||
| 88 | |||
| 89 | opp-500000000 { | ||
| 90 | opp-hz = /bits/ 64 <500000000>; | ||
| 91 | opp-microvolt = <751000>; | ||
| 92 | }; | ||
| 93 | |||
| 94 | opp-667000000 { | ||
| 95 | opp-hz = /bits/ 64 <667000000>; | ||
| 96 | opp-microvolt = <751000>; | ||
| 97 | }; | ||
| 98 | |||
| 99 | opp-1000000000 { | 59 | opp-1000000000 { |
| 100 | opp-hz = /bits/ 64 <1000000000>; | 60 | opp-hz = /bits/ 64 <1000000000>; |
| 101 | opp-microvolt = <771000>; | 61 | opp-microvolt = <771000>; |
| @@ -13,28 +13,28 @@ · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | cpu0: cpu@0 { | 14 | cpu0: cpu@0 { |
| 15 | device_type = "cpu"; | 15 | device_type = "cpu"; |
| 16 | compatible = "arm,cortex-a35","arm,armv8"; | 16 | compatible = "arm,cortex-a35"; |
| 17 | reg = <0x0 0x0>; | 17 | reg = <0x0 0x0>; |
| 18 | enable-method = "psci"; | 18 | enable-method = "psci"; |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | cpu1: cpu@1 { | 21 | cpu1: cpu@1 { |
| 22 | device_type = "cpu"; | 22 | device_type = "cpu"; |
| 23 | compatible = "arm,cortex-a35","arm,armv8"; | 23 | compatible = "arm,cortex-a35"; |
| 24 | reg = <0x0 0x1>; | 24 | reg = <0x0 0x1>; |
| 25 | enable-method = "psci"; | 25 | enable-method = "psci"; |
| 26 | }; | 26 | }; |
| 27 | 27 | ||
| 28 | cpu2: cpu@2 { | 28 | cpu2: cpu@2 { |
| 29 | device_type = "cpu"; | 29 | device_type = "cpu"; |
| 30 | compatible = "arm,cortex-a35","arm,armv8"; | 30 | compatible = "arm,cortex-a35"; |
| 31 | reg = <0x0 0x2>; | 31 | reg = <0x0 0x2>; |
| 32 | enable-method = "psci"; | 32 | enable-method = "psci"; |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | cpu3: cpu@3 { | 35 | cpu3: cpu@3 { |
| 36 | device_type = "cpu"; | 36 | device_type = "cpu"; |
| 37 | compatible = "arm,cortex-a35","arm,armv8"; | 37 | compatible = "arm,cortex-a35"; |
| 38 | reg = <0x0 0x3>; | 38 | reg = <0x0 0x3>; |
| 39 | enable-method = "psci"; | 39 | enable-method = "psci"; |
| 40 | }; | 40 | }; |
| @@ -437,6 +437,7 @@ · 436 unmodified lines | |||
| 437 | "", | 437 | "", |
| 438 | "eMMC_RST#", /* BOOT_12 */ | 438 | "eMMC_RST#", /* BOOT_12 */ |
| 439 | "eMMC_DS", /* BOOT_13 */ | 439 | "eMMC_DS", /* BOOT_13 */ |
| 440 | "", "", | ||
| 440 | /* GPIOC */ | 441 | /* GPIOC */ |
| 441 | "SD_D0_B", /* GPIOC_0 */ | 442 | "SD_D0_B", /* GPIOC_0 */ |
| 442 | "SD_D1_B", /* GPIOC_1 */ | 443 | "SD_D1_B", /* GPIOC_1 */ |
| @@ -95,26 +95,6 @@ · 94 unmodified lines | |||
| 95 | compatible = "operating-points-v2"; | 95 | compatible = "operating-points-v2"; |
| 96 | opp-shared; | 96 | opp-shared; |
| 97 | 97 | ||
| 98 | opp-100000000 { | ||
| 99 | opp-hz = /bits/ 64 <100000000>; | ||
| 100 | opp-microvolt = <730000>; | ||
| 101 | }; | ||
| 102 | |||
| 103 | opp-250000000 { | ||
| 104 | opp-hz = /bits/ 64 <250000000>; | ||
| 105 | opp-microvolt = <730000>; | ||
| 106 | }; | ||
| 107 | |||
| 108 | opp-500000000 { | ||
| 109 | opp-hz = /bits/ 64 <500000000>; | ||
| 110 | opp-microvolt = <730000>; | ||
| 111 | }; | ||
| 112 | |||
| 113 | opp-667000000 { | ||
| 114 | opp-hz = /bits/ 64 <666666666>; | ||
| 115 | opp-microvolt = <750000>; | ||
| 116 | }; | ||
| 117 | |||
| 118 | opp-1000000000 { | 98 | opp-1000000000 { |
| 119 | opp-hz = /bits/ 64 <1000000000>; | 99 | opp-hz = /bits/ 64 <1000000000>; |
| 120 | opp-microvolt = <770000>; | 100 | opp-microvolt = <770000>; |
| @@ -146,12 +146,14 @@ · 145 unmodified lines | |||
| 146 | 146 | ||
| 147 | &usbotg1 { | 147 | &usbotg1 { |
| 148 | dr_mode = "otg"; | 148 | dr_mode = "otg"; |
| 149 | over-current-active-low; | ||
| 149 | vbus-supply = <®_usb_otg1_vbus>; | 150 | vbus-supply = <®_usb_otg1_vbus>; |
| 150 | status = "okay"; | 151 | status = "okay"; |
| 151 | }; | 152 | }; |
| 152 | 153 | ||
| 153 | &usbotg2 { | 154 | &usbotg2 { |
| 154 | dr_mode = "host"; | 155 | dr_mode = "host"; |
| 156 | disable-over-current; | ||
| 155 | status = "okay"; | 157 | status = "okay"; |
| 156 | }; | 158 | }; |
| 157 | 159 | ||
| @@ -215,7 +217,7 @@ · 57 unmodified lines | |||
| 215 | fsl,pins = < | 217 | fsl,pins = < |
| 216 | MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 | 218 | MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 |
| 217 | MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0xd6 | 219 | MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0xd6 |
| 218 | MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 | 220 | MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0xd6 |
| 219 | MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0xd6 | 221 | MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0xd6 |
| 220 | >; | 222 | >; |
| 221 | }; | 223 | }; |
| @@ -211,12 +211,14 @@ · 210 unmodified lines | |||
| 211 | 211 | ||
| 212 | &usbotg1 { | 212 | &usbotg1 { |
| 213 | dr_mode = "otg"; | 213 | dr_mode = "otg"; |
| 214 | over-current-active-low; | ||
| 214 | vbus-supply = <®_usb_otg1_vbus>; | 215 | vbus-supply = <®_usb_otg1_vbus>; |
| 215 | status = "okay"; | 216 | status = "okay"; |
| 216 | }; | 217 | }; |
| 217 | 218 | ||
| 218 | &usbotg2 { | 219 | &usbotg2 { |
| 219 | dr_mode = "host"; | 220 | dr_mode = "host"; |
| 221 | disable-over-current; | ||
| 220 | vbus-supply = <®_usb_otg2_vbus>; | 222 | vbus-supply = <®_usb_otg2_vbus>; |
| 221 | status = "okay"; | 223 | status = "okay"; |
| 222 | }; | 224 | }; |
| @@ -309,7 +311,7 @@ · 86 unmodified lines | |||
| 309 | fsl,pins = < | 311 | fsl,pins = < |
| 310 | MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 | 312 | MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 |
| 311 | MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0xd6 | 313 | MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0xd6 |
| 312 | MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 | 314 | MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0xd6 |
| 313 | MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0xd6 | 315 | MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0xd6 |
| 314 | >; | 316 | >; |
| 315 | }; | 317 | }; |
| @@ -238,12 +238,14 @@ · 237 unmodified lines | |||
| 238 | 238 | ||
| 239 | &usbotg1 { | 239 | &usbotg1 { |
| 240 | dr_mode = "otg"; | 240 | dr_mode = "otg"; |
| 241 | over-current-active-low; | ||
| 241 | vbus-supply = <®_usb_otg1_vbus>; | 242 | vbus-supply = <®_usb_otg1_vbus>; |
| 242 | status = "okay"; | 243 | status = "okay"; |
| 243 | }; | 244 | }; |
| 244 | 245 | ||
| 245 | &usbotg2 { | 246 | &usbotg2 { |
| 246 | dr_mode = "host"; | 247 | dr_mode = "host"; |
| 248 | disable-over-current; | ||
| 247 | vbus-supply = <®_usb_otg2_vbus>; | 249 | vbus-supply = <®_usb_otg2_vbus>; |
| 248 | status = "okay"; | 250 | status = "okay"; |
| 249 | }; | 251 | }; |
| @@ -358,7 +360,7 @@ · 108 unmodified lines | |||
| 358 | fsl,pins = < | 360 | fsl,pins = < |
| 359 | MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 | 361 | MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 |
| 360 | MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0xd6 | 362 | MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0xd6 |
| 361 | MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0xd6 | 363 | MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0xd6 |
| 362 | MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0xd6 | 364 | MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0xd6 |
| 363 | >; | 365 | >; |
| 364 | }; | 366 | }; |
| @@ -59,6 +59,10 @@ · 58 unmodified lines | |||
| 59 | interrupts = <3 IRQ_TYPE_LEVEL_LOW>; | 59 | interrupts = <3 IRQ_TYPE_LEVEL_LOW>; |
| 60 | rohm,reset-snvs-powered; | 60 | rohm,reset-snvs-powered; |
| 61 | 61 | ||
| 62 | #clock-cells = <0>; | ||
| 63 | clocks = <&osc_32k 0>; | ||
| 64 | clock-output-names = "clk-32k-out"; | ||
| 65 | |||
| 62 | regulators { | 66 | regulators { |
| 63 | buck1_reg: BUCK1 { | 67 | buck1_reg: BUCK1 { |
| 64 | regulator-name = "buck1"; | 68 | regulator-name = "buck1"; |
| @@ -293,7 +293,7 @@ · 292 unmodified lines | |||
| 293 | ranges; | 293 | ranges; |
| 294 | 294 | ||
| 295 | sai2: sai@30020000 { | 295 | sai2: sai@30020000 { |
| 296 | compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; | 296 | compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai"; |
| 297 | reg = <0x30020000 0x10000>; | 297 | reg = <0x30020000 0x10000>; |
| 298 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; | 298 | interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; |
| 299 | clocks = <&clk IMX8MN_CLK_SAI2_IPG>, | 299 | clocks = <&clk IMX8MN_CLK_SAI2_IPG>, |
| @@ -307,7 +307,7 @@ · 7 unmodified lines | |||
| 307 | }; | 307 | }; |
| 308 | 308 | ||
| 309 | sai3: sai@30030000 { | 309 | sai3: sai@30030000 { |
| 310 | compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; | 310 | compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai"; |
| 311 | reg = <0x30030000 0x10000>; | 311 | reg = <0x30030000 0x10000>; |
| 312 | interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; | 312 | interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; |
| 313 | clocks = <&clk IMX8MN_CLK_SAI3_IPG>, | 313 | clocks = <&clk IMX8MN_CLK_SAI3_IPG>, |
| @@ -321,7 +321,7 @@ · 7 unmodified lines | |||
| 321 | }; | 321 | }; |
| 322 | 322 | ||
| 323 | sai5: sai@30050000 { | 323 | sai5: sai@30050000 { |
| 324 | compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; | 324 | compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai"; |
| 325 | reg = <0x30050000 0x10000>; | 325 | reg = <0x30050000 0x10000>; |
| 326 | interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; | 326 | interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; |
| 327 | clocks = <&clk IMX8MN_CLK_SAI5_IPG>, | 327 | clocks = <&clk IMX8MN_CLK_SAI5_IPG>, |
| @@ -337,7 +337,7 @@ · 9 unmodified lines | |||
| 337 | }; | 337 | }; |
| 338 | 338 | ||
| 339 | sai6: sai@30060000 { | 339 | sai6: sai@30060000 { |
| 340 | compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; | 340 | compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai"; |
| 341 | reg = <0x30060000 0x10000>; | 341 | reg = <0x30060000 0x10000>; |
| 342 | interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; | 342 | interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; |
| 343 | clocks = <&clk IMX8MN_CLK_SAI6_IPG>, | 343 | clocks = <&clk IMX8MN_CLK_SAI6_IPG>, |
| @@ -394,7 +394,7 @@ · 50 unmodified lines | |||
| 394 | }; | 394 | }; |
| 395 | 395 | ||
| 396 | sai7: sai@300b0000 { | 396 | sai7: sai@300b0000 { |
| 397 | compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; | 397 | compatible = "fsl,imx8mn-sai", "fsl,imx8mq-sai"; |
| 398 | reg = <0x300b0000 0x10000>; | 398 | reg = <0x300b0000 0x10000>; |
| 399 | interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; | 399 | interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; |
| 400 | clocks = <&clk IMX8MN_CLK_SAI7_IPG>, | 400 | clocks = <&clk IMX8MN_CLK_SAI7_IPG>, |
| @@ -253,7 +253,7 @@ · 252 unmodified lines | |||
| 253 | #address-cells = <1>; | 253 | #address-cells = <1>; |
| 254 | #size-cells = <1>; | 254 | #size-cells = <1>; |
| 255 | spi-max-frequency = <84000000>; | 255 | spi-max-frequency = <84000000>; |
| 256 | spi-tx-bus-width = <4>; | 256 | spi-tx-bus-width = <1>; |
| 257 | spi-rx-bus-width = <4>; | 257 | spi-rx-bus-width = <4>; |
| 258 | }; | 258 | }; |
| 259 | }; | 259 | }; |
| @@ -196,7 +196,7 @@ · 195 unmodified lines | |||
| 196 | }; | 196 | }; |
| 197 | 197 | ||
| 198 | clk: clock-controller { | 198 | clk: clock-controller { |
| 199 | compatible = "fsl,imx8qxp-clk", "fsl,scu-clk"; | 199 | compatible = "fsl,imx8qm-clk", "fsl,scu-clk"; |
| 200 | #clock-cells = <2>; | 200 | #clock-cells = <2>; |
| 201 | }; | 201 | }; |
| 202 | 202 | ||
| @@ -262,25 +262,25 @@ · 261 unmodified lines | |||
| 262 | gpio4 { | 262 | gpio4 { |
| 263 | pins = "gpio4"; | 263 | pins = "gpio4"; |
| 264 | function = "32k-out1"; | 264 | function = "32k-out1"; |
| 265 | drive-push-pull; | 265 | drive-push-pull = <1>; |
| 266 | }; | 266 | }; |
| 267 | 267 | ||
| 268 | gpio5 { | 268 | gpio5 { |
| 269 | pins = "gpio5"; | 269 | pins = "gpio5"; |
| 270 | function = "gpio"; | 270 | function = "gpio"; |
| 271 | drive-push-pull; | 271 | drive-push-pull = <0>; |
| 272 | }; | 272 | }; |
| 273 | 273 | ||
| 274 | gpio6 { | 274 | gpio6 { |
| 275 | pins = "gpio6"; | 275 | pins = "gpio6"; |
| 276 | function = "gpio"; | 276 | function = "gpio"; |
| 277 | drive-push-pull; | 277 | drive-push-pull = <1>; |
| 278 | }; | 278 | }; |
| 279 | 279 | ||
| 280 | gpio7 { | 280 | gpio7 { |
| 281 | pins = "gpio7"; | 281 | pins = "gpio7"; |
| 282 | function = "gpio"; | 282 | function = "gpio"; |
| 283 | drive-push-pull; | 283 | drive-push-pull = <0>; |
| 284 | }; | 284 | }; |
| 285 | }; | 285 | }; |
| 286 | 286 | ||
| @@ -462,25 +462,25 @@ · 461 unmodified lines | |||
| 462 | gpio4 { | 462 | gpio4 { |
| 463 | pins = "gpio4"; | 463 | pins = "gpio4"; |
| 464 | function = "32k-out1"; | 464 | function = "32k-out1"; |
| 465 | drive-push-pull; | 465 | drive-push-pull = <1>; |
| 466 | }; | 466 | }; |
| 467 | 467 | ||
| 468 | gpio5 { | 468 | gpio5 { |
| 469 | pins = "gpio5"; | 469 | pins = "gpio5"; |
| 470 | function = "gpio"; | 470 | function = "gpio"; |
| 471 | drive-push-pull; | 471 | drive-push-pull = <0>; |
| 472 | }; | 472 | }; |
| 473 | 473 | ||
| 474 | gpio6 { | 474 | gpio6 { |
| 475 | pins = "gpio6"; | 475 | pins = "gpio6"; |
| 476 | function = "gpio"; | 476 | function = "gpio"; |
| 477 | drive-push-pull; | 477 | drive-push-pull = <1>; |
| 478 | }; | 478 | }; |
| 479 | 479 | ||
| 480 | gpio7 { | 480 | gpio7 { |
| 481 | pins = "gpio7"; | 481 | pins = "gpio7"; |
| 482 | function = "gpio"; | 482 | function = "gpio"; |
| 483 | drive-push-pull; | 483 | drive-push-pull = <1>; |
| 484 | }; | 484 | }; |
| 485 | }; | 485 | }; |
| 486 | 486 | ||
| @@ -174,19 +174,19 @@ · 173 unmodified lines | |||
| 174 | gpio4 { | 174 | gpio4 { |
| 175 | pins = "gpio4"; | 175 | pins = "gpio4"; |
| 176 | function = "32k-out1"; | 176 | function = "32k-out1"; |
| 177 | drive-push-pull; | 177 | drive-push-pull = <1>; |
| 178 | }; | 178 | }; |
| 179 | 179 | ||
| 180 | gpio6 { | 180 | gpio6 { |
| 181 | pins = "gpio6"; | 181 | pins = "gpio6"; |
| 182 | function = "gpio"; | 182 | function = "gpio"; |
| 183 | drive-push-pull; | 183 | drive-push-pull = <1>; |
| 184 | }; | 184 | }; |
| 185 | 185 | ||
| 186 | gpio7 { | 186 | gpio7 { |
| 187 | pins = "gpio7"; | 187 | pins = "gpio7"; |
| 188 | function = "gpio"; | 188 | function = "gpio"; |
| 189 | drive-push-pull; | 189 | drive-push-pull = <0>; |
| 190 | }; | 190 | }; |
| 191 | }; | 191 | }; |
| 192 | 192 | ||
| @@ -148,19 +148,19 @@ · 147 unmodified lines | |||
| 148 | gpio4 { | 148 | gpio4 { |
| 149 | pins = "gpio4"; | 149 | pins = "gpio4"; |
| 150 | function = "32k-out1"; | 150 | function = "32k-out1"; |
| 151 | drive-push-pull; | 151 | drive-push-pull = <1>; |
| 152 | }; | 152 | }; |
| 153 | 153 | ||
| 154 | gpio6 { | 154 | gpio6 { |
| 155 | pins = "gpio6"; | 155 | pins = "gpio6"; |
| 156 | function = "gpio"; | 156 | function = "gpio"; |
| 157 | drive-push-pull; | 157 | drive-push-pull = <1>; |
| 158 | }; | 158 | }; |
| 159 | 159 | ||
| 160 | gpio7 { | 160 | gpio7 { |
| 161 | pins = "gpio7"; | 161 | pins = "gpio7"; |
| 162 | function = "gpio"; | 162 | function = "gpio"; |
| 163 | drive-push-pull; | 163 | drive-push-pull = <0>; |
| 164 | }; | 164 | }; |
| 165 | }; | 165 | }; |
| 166 | 166 | ||
| @@ -59,7 +59,7 @@ · 58 unmodified lines | |||
| 59 | gpio1 { | 59 | gpio1 { |
| 60 | pins = "gpio1"; | 60 | pins = "gpio1"; |
| 61 | function = "fps-out"; | 61 | function = "fps-out"; |
| 62 | drive-push-pull; | 62 | drive-push-pull = <1>; |
| 63 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; | 63 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; |
| 64 | maxim,active-fps-power-up-slot = <7>; | 64 | maxim,active-fps-power-up-slot = <7>; |
| 65 | maxim,active-fps-power-down-slot = <0>; | 65 | maxim,active-fps-power-down-slot = <0>; |
| @@ -68,7 +68,7 @@ · 2 unmodified lines | |||
| 68 | gpio2_3 { | 68 | gpio2_3 { |
| 69 | pins = "gpio2", "gpio3"; | 69 | pins = "gpio2", "gpio3"; |
| 70 | function = "fps-out"; | 70 | function = "fps-out"; |
| 71 | drive-open-drain; | 71 | drive-open-drain = <1>; |
| 72 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; | 72 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; |
| 73 | }; | 73 | }; |
| 74 | 74 | ||
| @@ -80,7 +80,7 @@ · 5 unmodified lines | |||
| 80 | gpio5_6_7 { | 80 | gpio5_6_7 { |
| 81 | pins = "gpio5", "gpio6", "gpio7"; | 81 | pins = "gpio5", "gpio6", "gpio7"; |
| 82 | function = "gpio"; | 82 | function = "gpio"; |
| 83 | drive-push-pull; | 83 | drive-push-pull = <1>; |
| 84 | }; | 84 | }; |
| 85 | }; | 85 | }; |
| 86 | 86 | ||
| @@ -1351,7 +1351,7 @@ · 1350 unmodified lines | |||
| 1351 | gpio1 { | 1351 | gpio1 { |
| 1352 | pins = "gpio1"; | 1352 | pins = "gpio1"; |
| 1353 | function = "fps-out"; | 1353 | function = "fps-out"; |
| 1354 | drive-push-pull; | 1354 | drive-push-pull = <1>; |
| 1355 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; | 1355 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; |
| 1356 | maxim,active-fps-power-up-slot = <7>; | 1356 | maxim,active-fps-power-up-slot = <7>; |
| 1357 | maxim,active-fps-power-down-slot = <0>; | 1357 | maxim,active-fps-power-down-slot = <0>; |
| @@ -1360,14 +1360,14 @@ · 2 unmodified lines | |||
| 1360 | gpio2 { | 1360 | gpio2 { |
| 1361 | pins = "gpio2"; | 1361 | pins = "gpio2"; |
| 1362 | function = "fps-out"; | 1362 | function = "fps-out"; |
| 1363 | drive-open-drain; | 1363 | drive-open-drain = <1>; |
| 1364 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; | 1364 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; |
| 1365 | }; | 1365 | }; |
| 1366 | 1366 | ||
| 1367 | gpio3 { | 1367 | gpio3 { |
| 1368 | pins = "gpio3"; | 1368 | pins = "gpio3"; |
| 1369 | function = "fps-out"; | 1369 | function = "fps-out"; |
| 1370 | drive-open-drain; | 1370 | drive-open-drain = <1>; |
| 1371 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; | 1371 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; |
| 1372 | }; | 1372 | }; |
| 1373 | 1373 | ||
| @@ -1379,7 +1379,7 @@ · 5 unmodified lines | |||
| 1379 | gpio5_6_7 { | 1379 | gpio5_6_7 { |
| 1380 | pins = "gpio5", "gpio6", "gpio7"; | 1380 | pins = "gpio5", "gpio6", "gpio7"; |
| 1381 | function = "gpio"; | 1381 | function = "gpio"; |
| 1382 | drive-push-pull; | 1382 | drive-push-pull = <1>; |
| 1383 | }; | 1383 | }; |
| 1384 | }; | 1384 | }; |
| 1385 | 1385 | ||
| @@ -195,7 +195,7 @@ · 194 unmodified lines | |||
| 195 | gpio1 { | 195 | gpio1 { |
| 196 | pins = "gpio1"; | 196 | pins = "gpio1"; |
| 197 | function = "fps-out"; | 197 | function = "fps-out"; |
| 198 | drive-push-pull; | 198 | drive-push-pull = <1>; |
| 199 | maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>; | 199 | maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>; |
| 200 | maxim,active-fps-power-up-slot = <0>; | 200 | maxim,active-fps-power-up-slot = <0>; |
| 201 | maxim,active-fps-power-down-slot = <7>; | 201 | maxim,active-fps-power-down-slot = <7>; |
| @@ -204,7 +204,7 @@ · 2 unmodified lines | |||
| 204 | gpio2 { | 204 | gpio2 { |
| 205 | pins = "gpio2"; | 205 | pins = "gpio2"; |
| 206 | function = "fps-out"; | 206 | function = "fps-out"; |
| 207 | drive-open-drain; | 207 | drive-open-drain = <1>; |
| 208 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; | 208 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; |
| 209 | maxim,active-fps-power-up-slot = <0>; | 209 | maxim,active-fps-power-up-slot = <0>; |
| 210 | maxim,active-fps-power-down-slot = <7>; | 210 | maxim,active-fps-power-down-slot = <7>; |
| @@ -213,7 +213,7 @@ · 2 unmodified lines | |||
| 213 | gpio3 { | 213 | gpio3 { |
| 214 | pins = "gpio3"; | 214 | pins = "gpio3"; |
| 215 | function = "fps-out"; | 215 | function = "fps-out"; |
| 216 | drive-open-drain; | 216 | drive-open-drain = <1>; |
| 217 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; | 217 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; |
| 218 | maxim,active-fps-power-up-slot = <4>; | 218 | maxim,active-fps-power-up-slot = <4>; |
| 219 | maxim,active-fps-power-down-slot = <3>; | 219 | maxim,active-fps-power-down-slot = <3>; |
| @@ -227,7 +227,7 @@ · 7 unmodified lines | |||
| 227 | gpio5_6_7 { | 227 | gpio5_6_7 { |
| 228 | pins = "gpio5", "gpio6", "gpio7"; | 228 | pins = "gpio5", "gpio6", "gpio7"; |
| 229 | function = "gpio"; | 229 | function = "gpio"; |
| 230 | drive-push-pull; | 230 | drive-push-pull = <1>; |
| 231 | }; | 231 | }; |
| 232 | }; | 232 | }; |
| 233 | 233 | ||
| @@ -1386,7 +1386,7 @@ · 1385 unmodified lines | |||
| 1386 | gpio3 { | 1386 | gpio3 { |
| 1387 | pins = "gpio3"; | 1387 | pins = "gpio3"; |
| 1388 | function = "fps-out"; | 1388 | function = "fps-out"; |
| 1389 | drive-open-drain; | 1389 | drive-open-drain = <1>; |
| 1390 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; | 1390 | maxim,active-fps-source = <MAX77620_FPS_SRC_0>; |
| 1391 | maxim,active-fps-power-up-slot = <4>; | 1391 | maxim,active-fps-power-up-slot = <4>; |
| 1392 | maxim,active-fps-power-down-slot = <2>; | 1392 | maxim,active-fps-power-down-slot = <2>; |
| @@ -1395,7 +1395,7 @@ · 2 unmodified lines | |||
| 1395 | gpio5_6 { | 1395 | gpio5_6 { |
| 1396 | pins = "gpio5", "gpio6"; | 1396 | pins = "gpio5", "gpio6"; |
| 1397 | function = "gpio"; | 1397 | function = "gpio"; |
| 1398 | drive-push-pull; | 1398 | drive-push-pull = <1>; |
| 1399 | }; | 1399 | }; |
| 1400 | 1400 | ||
| 1401 | gpio4 { | 1401 | gpio4 { |
| @@ -192,4 +192,8 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size); · 191 unmodified lines | |||
| 192 | extern int valid_phys_addr_range(phys_addr_t addr, size_t size); | 192 | extern int valid_phys_addr_range(phys_addr_t addr, size_t size); |
| 193 | extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); | 193 | extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); |
| 194 | 194 | ||
| 195 | extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, | ||
| 196 | unsigned long flags); | ||
| 197 | #define arch_memremap_can_ram_remap arch_memremap_can_ram_remap | ||
| 198 | |||
| 195 | #endif /* __ASM_IO_H */ | 199 | #endif /* __ASM_IO_H */ |
| @@ -40,6 +40,7 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu); · 39 unmodified lines | |||
| 40 | void kvm_inject_vabt(struct kvm_vcpu *vcpu); | 40 | void kvm_inject_vabt(struct kvm_vcpu *vcpu); |
| 41 | void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); | 41 | void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); |
| 42 | void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); | 42 | void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); |
| 43 | void kvm_inject_size_fault(struct kvm_vcpu *vcpu); | ||
| 43 | 44 | ||
| 44 | void kvm_vcpu_wfi(struct kvm_vcpu *vcpu); | 45 | void kvm_vcpu_wfi(struct kvm_vcpu *vcpu); |
| 45 | 46 | ||
| @@ -75,6 +75,10 @@ obj-$(CONFIG_ARM64_MTE) += mte.o · 74 unmodified lines | |||
| 75 | obj-y += vdso-wrap.o | 75 | obj-y += vdso-wrap.o |
| 76 | obj-$(CONFIG_COMPAT_VDSO) += vdso32-wrap.o | 76 | obj-$(CONFIG_COMPAT_VDSO) += vdso32-wrap.o |
| 77 | 77 | ||
| 78 | # Force dependency (vdso*-wrap.S includes vdso.so through incbin) | ||
| 79 | $(obj)/vdso-wrap.o: $(obj)/vdso/vdso.so | ||
| 80 | $(obj)/vdso32-wrap.o: $(obj)/vdso32/vdso.so | ||
| 81 | |||
| 78 | obj-y += probes/ | 82 | obj-y += probes/ |
| 79 | head-y := head.o | 83 | head-y := head.o |
| 80 | extra-y += $(head-y) vmlinux.lds | 84 | extra-y += $(head-y) vmlinux.lds |
| @@ -208,6 +208,8 @@ static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = { · 207 unmodified lines | |||
| 208 | #ifdef CONFIG_ARM64_ERRATUM_1286807 | 208 | #ifdef CONFIG_ARM64_ERRATUM_1286807 |
| 209 | { | 209 | { |
| 210 | ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 0), | 210 | ERRATA_MIDR_RANGE(MIDR_CORTEX_A76, 0, 0, 3, 0), |
| 211 | /* Kryo4xx Gold (rcpe to rfpe) => (r0p0 to r3p0) */ | ||
| 212 | ERRATA_MIDR_RANGE(MIDR_QCOM_KRYO_4XX_GOLD, 0xc, 0xe, 0xf, 0xe), | ||
| 211 | }, | 213 | }, |
| 212 | #endif | 214 | #endif |
| 213 | {}, | 215 | {}, |
| @@ -654,7 +654,6 @@ static const struct __ftr_reg_entry { · 653 unmodified lines | |||
| 654 | ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0), | 654 | ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0), |
| 655 | ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1, | 655 | ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1, |
| 656 | &id_aa64isar1_override), | 656 | &id_aa64isar1_override), |
| 657 | ARM64_FTR_REG(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2), | ||
| 658 | ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2, | 657 | ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2, |
| 659 | &id_aa64isar2_override), | 658 | &id_aa64isar2_override), |
| 660 | 659 | ||
| @@ -810,7 +809,7 @@ static void __init sort_ftr_regs(void) · 149 unmodified lines | |||
| 810 | * to sys_id for subsequent binary search in get_arm64_ftr_reg() | 809 | * to sys_id for subsequent binary search in get_arm64_ftr_reg() |
| 811 | * to work correctly. | 810 | * to work correctly. |
| 812 | */ | 811 | */ |
| 813 | BUG_ON(arm64_ftr_regs[i].sys_id < arm64_ftr_regs[i - 1].sys_id); | 812 | BUG_ON(arm64_ftr_regs[i].sys_id <= arm64_ftr_regs[i - 1].sys_id); |
| 814 | } | 813 | } |
| 815 | } | 814 | } |
| 816 | 815 | ||
| @@ -95,7 +95,7 @@ int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset) · 94 unmodified lines | |||
| 95 | for_each_mte_vma(current, vma) { | 95 | for_each_mte_vma(current, vma) { |
| 96 | struct elf_phdr phdr; | 96 | struct elf_phdr phdr; |
| 97 | 97 | ||
| 98 | phdr.p_type = PT_ARM_MEMTAG_MTE; | 98 | phdr.p_type = PT_AARCH64_MEMTAG_MTE; |
| 99 | phdr.p_offset = offset; | 99 | phdr.p_offset = offset; |
| 100 | phdr.p_vaddr = vma->vm_start; | 100 | phdr.p_vaddr = vma->vm_start; |
| 101 | phdr.p_paddr = 0; | 101 | phdr.p_paddr = 0; |
| @@ -52,9 +52,6 @@ GCOV_PROFILE := n · 51 unmodified lines | |||
| 52 | targets += vdso.lds | 52 | targets += vdso.lds |
| 53 | CPPFLAGS_vdso.lds += -P -C -U$(ARCH) | 53 | CPPFLAGS_vdso.lds += -P -C -U$(ARCH) |
| 54 | 54 | ||
| 55 | # Force dependency (incbin is bad) | ||
| 56 | $(obj)/vdso.o : $(obj)/vdso.so | ||
| 57 | |||
| 58 | # Link rule for the .so file, .lds has to be first | 55 | # Link rule for the .so file, .lds has to be first |
| 59 | $(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE | 56 | $(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE |
| 60 | $(call if_changed,vdsold_and_vdso_check) | 57 | $(call if_changed,vdsold_and_vdso_check) |
| @@ -131,9 +131,6 @@ obj-vdso := $(c-obj-vdso) $(c-obj-vdso-gettimeofday) $(asm-obj-vdso) · 130 unmodified lines | |||
| 131 | targets += vdso.lds | 131 | targets += vdso.lds |
| 132 | CPPFLAGS_vdso.lds += -P -C -U$(ARCH) | 132 | CPPFLAGS_vdso.lds += -P -C -U$(ARCH) |
| 133 | 133 | ||
| 134 | # Force dependency (vdso.s includes vdso.so through incbin) | ||
| 135 | $(obj)/vdso.o: $(obj)/vdso.so | ||
| 136 | |||
| 137 | include/generated/vdso32-offsets.h: $(obj)/vdso.so.dbg FORCE | 134 | include/generated/vdso32-offsets.h: $(obj)/vdso.so.dbg FORCE |
| 138 | $(call if_changed,vdsosym) | 135 | $(call if_changed,vdsosym) |
| 139 | 136 | ||
| @@ -198,15 +198,15 @@ SYM_CODE_START(__kvm_hyp_host_vector) · 197 unmodified lines | |||
| 198 | invalid_host_el2_vect // FIQ EL2h | 198 | invalid_host_el2_vect // FIQ EL2h |
| 199 | invalid_host_el2_vect // Error EL2h | 199 | invalid_host_el2_vect // Error EL2h |
| 200 | 200 | ||
| 201 | host_el1_sync_vect // Synchronous 64-bit EL1 | 201 | host_el1_sync_vect // Synchronous 64-bit EL1/EL0 |
| 202 | invalid_host_el1_vect // IRQ 64-bit EL1 | 202 | invalid_host_el1_vect // IRQ 64-bit EL1/EL0 |
| 203 | invalid_host_el1_vect // FIQ 64-bit EL1 | 203 | invalid_host_el1_vect // FIQ 64-bit EL1/EL0 |
| 204 | invalid_host_el1_vect // Error 64-bit EL1 | 204 | invalid_host_el1_vect // Error 64-bit EL1/EL0 |
| 205 | 205 | ||
| 206 | invalid_host_el1_vect // Synchronous 32-bit EL1 | 206 | host_el1_sync_vect // Synchronous 32-bit EL1/EL0 |
| 207 | invalid_host_el1_vect // IRQ 32-bit EL1 | 207 | invalid_host_el1_vect // IRQ 32-bit EL1/EL0 |
| 208 | invalid_host_el1_vect // FIQ 32-bit EL1 | 208 | invalid_host_el1_vect // FIQ 32-bit EL1/EL0 |
| 209 | invalid_host_el1_vect // Error 32-bit EL1 | 209 | invalid_host_el1_vect // Error 32-bit EL1/EL0 |
| 210 | SYM_CODE_END(__kvm_hyp_host_vector) | 210 | SYM_CODE_END(__kvm_hyp_host_vector) |
| 211 | 211 | ||
| 212 | /* | 212 | /* |
| @@ -145,6 +145,34 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr) · 144 unmodified lines | |||
| 145 | inject_abt64(vcpu, true, addr); | 145 | inject_abt64(vcpu, true, addr); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | void kvm_inject_size_fault(struct kvm_vcpu *vcpu) | ||
| 149 | { | ||
| 150 | unsigned long addr, esr; | ||
| 151 | |||
| 152 | addr = kvm_vcpu_get_fault_ipa(vcpu); | ||
| 153 | addr |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0); | ||
| 154 | |||
| 155 | if (kvm_vcpu_trap_is_iabt(vcpu)) | ||
| 156 | kvm_inject_pabt(vcpu, addr); | ||
| 157 | else | ||
| 158 | kvm_inject_dabt(vcpu, addr); | ||
| 159 | |||
| 160 | /* | ||
| 161 | * If AArch64 or LPAE, set FSC to 0 to indicate an Address | ||
| 162 | * Size Fault at level 0, as if exceeding PARange. | ||
| 163 | * | ||
| 164 | * Non-LPAE guests will only get the external abort, as there | ||
| 165 | * is no way to to describe the ASF. | ||
| 166 | */ | ||
| 167 | if (vcpu_el1_is_32bit(vcpu) && | ||
| 168 | !(vcpu_read_sys_reg(vcpu, TCR_EL1) & TTBCR_EAE)) | ||
| 169 | return; | ||
| 170 | |||
| 171 | esr = vcpu_read_sys_reg(vcpu, ESR_EL1); | ||
| 172 | esr &= ~GENMASK_ULL(5, 0); | ||
| 173 | vcpu_write_sys_reg(vcpu, esr, ESR_EL1); | ||
| 174 | } | ||
| 175 | |||
| 148 | /** | 176 | /** |
| 149 | * kvm_inject_undefined - inject an undefined instruction into the guest | 177 | * kvm_inject_undefined - inject an undefined instruction into the guest |
| 150 | * @vcpu: The vCPU in which to inject the exception | 178 | * @vcpu: The vCPU in which to inject the exception |
| @@ -1337,6 +1337,25 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu) · 1336 unmodified lines | |||
| 1337 | fault_ipa = kvm_vcpu_get_fault_ipa(vcpu); | 1337 | fault_ipa = kvm_vcpu_get_fault_ipa(vcpu); |
| 1338 | is_iabt = kvm_vcpu_trap_is_iabt(vcpu); | 1338 | is_iabt = kvm_vcpu_trap_is_iabt(vcpu); |
| 1339 | 1339 | ||
| 1340 | if (fault_status == FSC_FAULT) { | ||
| 1341 | /* Beyond sanitised PARange (which is the IPA limit) */ | ||
| 1342 | if (fault_ipa >= BIT_ULL(get_kvm_ipa_limit())) { | ||
| 1343 | kvm_inject_size_fault(vcpu); | ||
| 1344 | return 1; | ||
| 1345 | } | ||
| 1346 | |||
| 1347 | /* Falls between the IPA range and the PARange? */ | ||
| 1348 | if (fault_ipa >= BIT_ULL(vcpu->arch.hw_mmu->pgt->ia_bits)) { | ||
| 1349 | fault_ipa |= kvm_vcpu_get_hfar(vcpu) & GENMASK(11, 0); | ||
| 1350 | |||
| 1351 | if (is_iabt) | ||
| 1352 | kvm_inject_pabt(vcpu, fault_ipa); | ||
| 1353 | else | ||
| 1354 | kvm_inject_dabt(vcpu, fault_ipa); | ||
| 1355 | return 1; | ||
| 1356 | } | ||
| 1357 | } | ||
| 1358 | |||
| 1340 | /* Synchronous External Abort? */ | 1359 | /* Synchronous External Abort? */ |
| 1341 | if (kvm_vcpu_abt_issea(vcpu)) { | 1360 | if (kvm_vcpu_abt_issea(vcpu)) { |
| 1342 | /* | 1361 | /* |
| @@ -177,6 +177,9 @@ u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx) · 176 unmodified lines | |||
| 177 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 177 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
| 178 | struct kvm_pmc *pmc = &pmu->pmc[select_idx]; | 178 | struct kvm_pmc *pmc = &pmu->pmc[select_idx]; |
| 179 | 179 | ||
| 180 | if (!kvm_vcpu_has_pmu(vcpu)) | ||
| 181 | return 0; | ||
| 182 | |||
| 180 | counter = kvm_pmu_get_pair_counter_value(vcpu, pmc); | 183 | counter = kvm_pmu_get_pair_counter_value(vcpu, pmc); |
| 181 | 184 | ||
| 182 | if (kvm_pmu_pmc_is_chained(pmc) && | 185 | if (kvm_pmu_pmc_is_chained(pmc) && |
| @@ -198,6 +201,9 @@ void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, u64 select_idx, u64 val) · 15 unmodified lines | |||
| 198 | { | 201 | { |
| 199 | u64 reg; | 202 | u64 reg; |
| 200 | 203 | ||
| 204 | if (!kvm_vcpu_has_pmu(vcpu)) | ||
| 205 | return; | ||
| 206 | |||
| 201 | reg = (select_idx == ARMV8_PMU_CYCLE_IDX) | 207 | reg = (select_idx == ARMV8_PMU_CYCLE_IDX) |
| 202 | ? PMCCNTR_EL0 : PMEVCNTR0_EL0 + select_idx; | 208 | ? PMCCNTR_EL0 : PMEVCNTR0_EL0 + select_idx; |
| 203 | __vcpu_sys_reg(vcpu, reg) += (s64)val - kvm_pmu_get_counter_value(vcpu, select_idx); | 209 | __vcpu_sys_reg(vcpu, reg) += (s64)val - kvm_pmu_get_counter_value(vcpu, select_idx); |
| @@ -322,6 +328,9 @@ void kvm_pmu_enable_counter_mask(struct kvm_vcpu *vcpu, u64 val) · 118 unmodified lines | |||
| 322 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 328 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
| 323 | struct kvm_pmc *pmc; | 329 | struct kvm_pmc *pmc; |
| 324 | 330 | ||
| 331 | if (!kvm_vcpu_has_pmu(vcpu)) | ||
| 332 | return; | ||
| 333 | |||
| 325 | if (!(__vcpu_sys_reg(vcpu, PMCR_EL0) & ARMV8_PMU_PMCR_E) || !val) | 334 | if (!(__vcpu_sys_reg(vcpu, PMCR_EL0) & ARMV8_PMU_PMCR_E) || !val) |
| 326 | return; | 335 | return; |
| 327 | 336 | ||
| @@ -357,7 +366,7 @@ void kvm_pmu_disable_counter_mask(struct kvm_vcpu *vcpu, u64 val) · 29 unmodified lines | |||
| 357 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 366 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
| 358 | struct kvm_pmc *pmc; | 367 | struct kvm_pmc *pmc; |
| 359 | 368 | ||
| 360 | if (!val) | 369 | if (!kvm_vcpu_has_pmu(vcpu) || !val) |
| 361 | return; | 370 | return; |
| 362 | 371 | ||
| 363 | for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) { | 372 | for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) { |
| @@ -527,6 +536,9 @@ void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val) · 163 unmodified lines | |||
| 527 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 536 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
| 528 | int i; | 537 | int i; |
| 529 | 538 | ||
| 539 | if (!kvm_vcpu_has_pmu(vcpu)) | ||
| 540 | return; | ||
| 541 | |||
| 530 | if (!(__vcpu_sys_reg(vcpu, PMCR_EL0) & ARMV8_PMU_PMCR_E)) | 542 | if (!(__vcpu_sys_reg(vcpu, PMCR_EL0) & ARMV8_PMU_PMCR_E)) |
| 531 | return; | 543 | return; |
| 532 | 544 | ||
| @@ -576,6 +588,9 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) · 43 unmodified lines | |||
| 576 | { | 588 | { |
| 577 | int i; | 589 | int i; |
| 578 | 590 | ||
| 591 | if (!kvm_vcpu_has_pmu(vcpu)) | ||
| 592 | return; | ||
| 593 | |||
| 579 | if (val & ARMV8_PMU_PMCR_E) { | 594 | if (val & ARMV8_PMU_PMCR_E) { |
| 580 | kvm_pmu_enable_counter_mask(vcpu, | 595 | kvm_pmu_enable_counter_mask(vcpu, |
| 581 | __vcpu_sys_reg(vcpu, PMCNTENSET_EL0)); | 596 | __vcpu_sys_reg(vcpu, PMCNTENSET_EL0)); |
| @@ -739,6 +754,9 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data, · 157 unmodified lines | |||
| 739 | { | 754 | { |
| 740 | u64 reg, mask; | 755 | u64 reg, mask; |
| 741 | 756 | ||
| 757 | if (!kvm_vcpu_has_pmu(vcpu)) | ||
| 758 | return; | ||
| 759 | |||
| 742 | mask = ARMV8_PMU_EVTYPE_MASK; | 760 | mask = ARMV8_PMU_EVTYPE_MASK; |
| 743 | mask &= ~ARMV8_PMU_EVTYPE_EVENT; | 761 | mask &= ~ARMV8_PMU_EVTYPE_EVENT; |
| 744 | mask |= kvm_pmu_event_mask(vcpu->kvm); | 762 | mask |= kvm_pmu_event_mask(vcpu->kvm); |
| @@ -827,6 +845,9 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1) · 82 unmodified lines | |||
| 827 | u64 val, mask = 0; | 845 | u64 val, mask = 0; |
| 828 | int base, i, nr_events; | 846 | int base, i, nr_events; |
| 829 | 847 | ||
| 848 | if (!kvm_vcpu_has_pmu(vcpu)) | ||
| 849 | return 0; | ||
| 850 | |||
| 830 | if (!pmceid1) { | 851 | if (!pmceid1) { |
| 831 | val = read_sysreg(pmceid0_el0); | 852 | val = read_sysreg(pmceid0_el0); |
| 832 | base = 0; | 853 | base = 0; |
| @@ -181,7 +181,8 @@ static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type, u64 flags) · 180 unmodified lines | |||
| 181 | 181 | ||
| 182 | memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event)); | 182 | memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event)); |
| 183 | vcpu->run->system_event.type = type; | 183 | vcpu->run->system_event.type = type; |
| 184 | vcpu->run->system_event.flags = flags; | 184 | vcpu->run->system_event.ndata = 1; |
| 185 | vcpu->run->system_event.data[0] = flags; | ||
| 185 | vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; | 186 | vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; |
| 186 | } | 187 | } |
| 187 | 188 | ||
| @@ -99,3 +99,11 @@ void __init early_ioremap_init(void) · 98 unmodified lines | |||
| 99 | { | 99 | { |
| 100 | early_ioremap_setup(); | 100 | early_ioremap_setup(); |
| 101 | } | 101 | } |
| 102 | |||
| 103 | bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size, | ||
| 104 | unsigned long flags) | ||
| 105 | { | ||
| 106 | unsigned long pfn = PHYS_PFN(offset); | ||
| 107 | |||
| 108 | return pfn_is_map_memory(pfn); | ||
| 109 | } | ||
| @@ -40,9 +40,9 @@ · 39 unmodified lines | |||
| 40 | typedef unsigned int cycles_t; | 40 | typedef unsigned int cycles_t; |
| 41 | 41 | ||
| 42 | /* | 42 | /* |
| 43 | * On R4000/R4400 before version 5.0 an erratum exists such that if the | 43 | * On R4000/R4400 an erratum exists such that if the cycle counter is |
| 44 | * cycle counter is read in the exact moment that it is matching the | 44 | * read in the exact moment that it is matching the compare register, |
| 45 | * compare register, no interrupt will be generated. | 45 | * no interrupt will be generated. |
| 46 | * | 46 | * |
| 47 | * There is a suggested workaround and also the erratum can't strike if | 47 | * There is a suggested workaround and also the erratum can't strike if |
| 48 | * the compare interrupt isn't being used as the clock source device. | 48 | * the compare interrupt isn't being used as the clock source device. |
| @@ -63,7 +63,7 @@ static inline int can_use_mips_counter(unsigned int prid) · 14 unmodified lines | |||
| 63 | if (!__builtin_constant_p(cpu_has_counter)) | 63 | if (!__builtin_constant_p(cpu_has_counter)) |
| 64 | asm volatile("" : "=m" (cpu_data[0].options)); | 64 | asm volatile("" : "=m" (cpu_data[0].options)); |
| 65 | if (likely(cpu_has_counter && | 65 | if (likely(cpu_has_counter && |
| 66 | prid >= (PRID_IMP_R4000 | PRID_REV_ENCODE_44(5, 0)))) | 66 | prid > (PRID_IMP_R4000 | PRID_REV_ENCODE_44(15, 15)))) |
| 67 | return 1; | 67 | return 1; |
| 68 | else | 68 | else |
| 69 | return 0; | 69 | return 0; |
| @@ -141,15 +141,10 @@ static __init int cpu_has_mfc0_count_bug(void) · 140 unmodified lines | |||
| 141 | case CPU_R4400MC: | 141 | case CPU_R4400MC: |
| 142 | /* | 142 | /* |
| 143 | * The published errata for the R4400 up to 3.0 say the CPU | 143 | * The published errata for the R4400 up to 3.0 say the CPU |
| 144 | * has the mfc0 from count bug. | 144 | * has the mfc0 from count bug. This seems the last version |
| 145 | * produced. | ||
| 145 | */ | 146 | */ |
| 146 | if ((current_cpu_data.processor_id & 0xff) <= 0x30) | 147 | return 1; |
| 147 | return 1; | ||
| 148 | |||
| 149 | /* | ||
| 150 | * we assume newer revisions are ok | ||
| 151 | */ | ||
| 152 | return 0; | ||
| 153 | } | 148 | } |
| 154 | 149 | ||
| 155 | return 0; | 150 | return 0; |
| @@ -38,6 +38,7 @@ config PARISC · 37 unmodified lines | |||
| 38 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 38 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
| 39 | select GENERIC_SMP_IDLE_THREAD | 39 | select GENERIC_SMP_IDLE_THREAD |
| 40 | select GENERIC_ARCH_TOPOLOGY if SMP | 40 | select GENERIC_ARCH_TOPOLOGY if SMP |
| 41 | select GENERIC_CPU_DEVICES if !SMP | ||
| 41 | select GENERIC_LIB_DEVMEM_IS_ALLOWED | 42 | select GENERIC_LIB_DEVMEM_IS_ALLOWED |
| 42 | select SYSCTL_ARCH_UNALIGN_ALLOW | 43 | select SYSCTL_ARCH_UNALIGN_ALLOW |
| 43 | select SYSCTL_EXCEPTION_TRACE | 44 | select SYSCTL_EXCEPTION_TRACE |
| @@ -6,6 +6,9 @@ CONFIG_BSD_PROCESS_ACCT=y · 5 unmodified lines | |||
| 6 | CONFIG_IKCONFIG=y | 6 | CONFIG_IKCONFIG=y |
| 7 | CONFIG_IKCONFIG_PROC=y | 7 | CONFIG_IKCONFIG_PROC=y |
| 8 | CONFIG_LOG_BUF_SHIFT=16 | 8 | CONFIG_LOG_BUF_SHIFT=16 |
| 9 | CONFIG_CGROUPS=y | ||
| 10 | CONFIG_NAMESPACES=y | ||
| 11 | CONFIG_USER_NS=y | ||
| 9 | CONFIG_BLK_DEV_INITRD=y | 12 | CONFIG_BLK_DEV_INITRD=y |
| 10 | CONFIG_EXPERT=y | 13 | CONFIG_EXPERT=y |
| 11 | CONFIG_PERF_EVENTS=y | 14 | CONFIG_PERF_EVENTS=y |
| @@ -47,7 +50,6 @@ CONFIG_PARPORT=y · 35 unmodified lines | |||
| 47 | CONFIG_PARPORT_PC=m | 50 | CONFIG_PARPORT_PC=m |
| 48 | CONFIG_PARPORT_1284=y | 51 | CONFIG_PARPORT_1284=y |
| 49 | CONFIG_BLK_DEV_LOOP=y | 52 | CONFIG_BLK_DEV_LOOP=y |
| 50 | CONFIG_BLK_DEV_CRYPTOLOOP=y | ||
| 51 | CONFIG_BLK_DEV_RAM=y | 53 | CONFIG_BLK_DEV_RAM=y |
| 52 | CONFIG_BLK_DEV_RAM_SIZE=6144 | 54 | CONFIG_BLK_DEV_RAM_SIZE=6144 |
| 53 | CONFIG_BLK_DEV_SD=y | 55 | CONFIG_BLK_DEV_SD=y |
| @@ -16,6 +16,7 @@ CONFIG_CGROUPS=y · 15 unmodified lines | |||
| 16 | CONFIG_MEMCG=y | 16 | CONFIG_MEMCG=y |
| 17 | CONFIG_CGROUP_PIDS=y | 17 | CONFIG_CGROUP_PIDS=y |
| 18 | CONFIG_CPUSETS=y | 18 | CONFIG_CPUSETS=y |
| 19 | CONFIG_USER_NS=y | ||
| 19 | CONFIG_RELAY=y | 20 | CONFIG_RELAY=y |
| 20 | CONFIG_BLK_DEV_INITRD=y | 21 | CONFIG_BLK_DEV_INITRD=y |
| 21 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 22 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
| @@ -267,9 +268,9 @@ CONFIG_CRYPTO_DEFLATE=m · 245 unmodified lines | |||
| 267 | CONFIG_CRC_CCITT=m | 268 | CONFIG_CRC_CCITT=m |
| 268 | CONFIG_LIBCRC32C=y | 269 | CONFIG_LIBCRC32C=y |
| 269 | CONFIG_PRINTK_TIME=y | 270 | CONFIG_PRINTK_TIME=y |
| 271 | CONFIG_DEBUG_KERNEL=y | ||
| 270 | CONFIG_STRIP_ASM_SYMS=y | 272 | CONFIG_STRIP_ASM_SYMS=y |
| 271 | CONFIG_MAGIC_SYSRQ=y | 273 | CONFIG_MAGIC_SYSRQ=y |
| 272 | CONFIG_DEBUG_FS=y | 274 | CONFIG_DEBUG_FS=y |
| 273 | CONFIG_DEBUG_KERNEL=y | ||
| 274 | CONFIG_DEBUG_STACKOVERFLOW=y | 275 | CONFIG_DEBUG_STACKOVERFLOW=y |
| 275 | # CONFIG_SCHED_DEBUG is not set | 276 | # CONFIG_SCHED_DEBUG is not set |
| @@ -160,7 +160,7 @@ extern void __update_cache(pte_t pte); · 159 unmodified lines | |||
| 160 | #define SPACEID_SHIFT (MAX_ADDRBITS - 32) | 160 | #define SPACEID_SHIFT (MAX_ADDRBITS - 32) |
| 161 | #else | 161 | #else |
| 162 | #define MAX_ADDRBITS (BITS_PER_LONG) | 162 | #define MAX_ADDRBITS (BITS_PER_LONG) |
| 163 | #define MAX_ADDRESS (1UL << MAX_ADDRBITS) | 163 | #define MAX_ADDRESS (1ULL << MAX_ADDRBITS) |
| 164 | #define SPACEID_SHIFT 0 | 164 | #define SPACEID_SHIFT 0 |
| 165 | #endif | 165 | #endif |
| 166 | 166 | ||
| @@ -403,7 +403,7 @@ void __init parisc_setup_cache_timing(void) · 402 unmodified lines | |||
| 403 | { | 403 | { |
| 404 | unsigned long rangetime, alltime; | 404 | unsigned long rangetime, alltime; |
| 405 | unsigned long size; | 405 | unsigned long size; |
| 406 | unsigned long threshold, threshold2; | 406 | unsigned long threshold; |
| 407 | 407 | ||
| 408 | alltime = mfctl(16); | 408 | alltime = mfctl(16); |
| 409 | flush_data_cache(); | 409 | flush_data_cache(); |
| @@ -418,20 +418,8 @@ void __init parisc_setup_cache_timing(void) · 8 unmodified lines | |||
| 418 | alltime, size, rangetime); | 418 | alltime, size, rangetime); |
| 419 | 419 | ||
| 420 | threshold = L1_CACHE_ALIGN(size * alltime / rangetime); | 420 | threshold = L1_CACHE_ALIGN(size * alltime / rangetime); |
| 421 | 421 | if (threshold > cache_info.dc_size) | |
| 422 | /* | 422 | threshold = cache_info.dc_size; |
| 423 | * The threshold computed above isn't very reliable since the | ||
| 424 | * flush times depend greatly on the percentage of dirty lines | ||
| 425 | * in the flush range. Further, the whole cache time doesn't | ||
| 426 | * include the time to refill lines that aren't in the mm/vma | ||
| 427 | * being flushed. By timing glibc build and checks on mako cpus, | ||
| 428 | * the following formula seems to work reasonably well. The | ||
| 429 | * value from the timing calculation is too small, and increases | ||
| 430 | * build and check times by almost a factor two. | ||
| 431 | */ | ||
| 432 | threshold2 = cache_info.dc_size * num_online_cpus(); | ||
| 433 | if (threshold2 > threshold) | ||
| 434 | threshold = threshold2; | ||
| 435 | if (threshold) | 423 | if (threshold) |
| 436 | parisc_cache_flush_threshold = threshold; | 424 | parisc_cache_flush_threshold = threshold; |
| 437 | printk(KERN_INFO "Cache flush threshold set to %lu KiB\n", | 425 | printk(KERN_INFO "Cache flush threshold set to %lu KiB\n", |
| @@ -152,7 +152,7 @@ int __kprobes parisc_kprobe_ss_handler(struct pt_regs *regs) · 151 unmodified lines | |||
| 152 | /* for absolute branch instructions we can copy iaoq_b. for relative | 152 | /* for absolute branch instructions we can copy iaoq_b. for relative |
| 153 | * branch instructions we need to calculate the new address based on the | 153 | * branch instructions we need to calculate the new address based on the |
| 154 | * difference between iaoq_f and iaoq_b. We cannot use iaoq_b without | 154 | * difference between iaoq_f and iaoq_b. We cannot use iaoq_b without |
| 155 | * modificationt because it's based on our ainsn.insn address. | 155 | * modifications because it's based on our ainsn.insn address. |
| 156 | */ | 156 | */ |
| 157 | 157 | ||
| 158 | if (p->post_handler) | 158 | if (p->post_handler) |
| @@ -40,7 +40,10 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags, · 39 unmodified lines | |||
| 40 | 40 | ||
| 41 | *need_unmap = 1; | 41 | *need_unmap = 1; |
| 42 | set_fixmap(fixmap, page_to_phys(page)); | 42 | set_fixmap(fixmap, page_to_phys(page)); |
| 43 | raw_spin_lock_irqsave(&patch_lock, *flags); | 43 | if (flags) |
| 44 | raw_spin_lock_irqsave(&patch_lock, *flags); | ||
| 45 | else | ||
| 46 | __acquire(&patch_lock); | ||
| 44 | 47 | ||
| 45 | return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK)); | 48 | return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK)); |
| 46 | } | 49 | } |
| @@ -49,7 +52,10 @@ static void __kprobes patch_unmap(int fixmap, unsigned long *flags) · 2 unmodified lines | |||
| 49 | { | 52 | { |
| 50 | clear_fixmap(fixmap); | 53 | clear_fixmap(fixmap); |
| 51 | 54 | ||
| 52 | raw_spin_unlock_irqrestore(&patch_lock, *flags); | 55 | if (flags) |
| 56 | raw_spin_unlock_irqrestore(&patch_lock, *flags); | ||
| 57 | else | ||
| 58 | __release(&patch_lock); | ||
| 53 | } | 59 | } |
| 54 | 60 | ||
| 55 | void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len) | 61 | void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len) |
| @@ -61,9 +67,8 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len) · 5 unmodified lines | |||
| 61 | int mapped; | 67 | int mapped; |
| 62 | 68 | ||
| 63 | /* Make sure we don't have any aliases in cache */ | 69 | /* Make sure we don't have any aliases in cache */ |
| 64 | flush_kernel_dcache_range_asm(start, end); | 70 | flush_kernel_vmap_range(addr, len); |
| 65 | flush_kernel_icache_range_asm(start, end); | 71 | flush_icache_range(start, end); |
| 66 | flush_tlb_kernel_range(start, end); | ||
| 67 | 72 | ||
| 68 | p = fixmap = patch_map(addr, FIX_TEXT_POKE0, &flags, &mapped); | 73 | p = fixmap = patch_map(addr, FIX_TEXT_POKE0, &flags, &mapped); |
| 69 | 74 | ||
| @@ -76,10 +81,8 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len) · 6 unmodified lines | |||
| 76 | * We're crossing a page boundary, so | 81 | * We're crossing a page boundary, so |
| 77 | * need to remap | 82 | * need to remap |
| 78 | */ | 83 | */ |
| 79 | flush_kernel_dcache_range_asm((unsigned long)fixmap, | 84 | flush_kernel_vmap_range((void *)fixmap, |
| 80 | (unsigned long)p); | 85 | (p-fixmap) * sizeof(*p)); |
| 81 | flush_tlb_kernel_range((unsigned long)fixmap, | ||
| 82 | (unsigned long)p); | ||
| 83 | if (mapped) | 86 | if (mapped) |
| 84 | patch_unmap(FIX_TEXT_POKE0, &flags); | 87 | patch_unmap(FIX_TEXT_POKE0, &flags); |
| 85 | p = fixmap = patch_map(addr, FIX_TEXT_POKE0, &flags, | 88 | p = fixmap = patch_map(addr, FIX_TEXT_POKE0, &flags, |
| @@ -87,10 +90,10 @@ void __kprobes __patch_text_multiple(void *addr, u32 *insn, unsigned int len) · 1 unmodified line | |||
| 87 | } | 90 | } |
| 88 | } | 91 | } |
| 89 | 92 | ||
| 90 | flush_kernel_dcache_range_asm((unsigned long)fixmap, (unsigned long)p); | 93 | flush_kernel_vmap_range((void *)fixmap, (p-fixmap) * sizeof(*p)); |
| 91 | flush_tlb_kernel_range((unsigned long)fixmap, (unsigned long)p); | ||
| 92 | if (mapped) | 94 | if (mapped) |
| 93 | patch_unmap(FIX_TEXT_POKE0, &flags); | 95 | patch_unmap(FIX_TEXT_POKE0, &flags); |
| 96 | flush_icache_range(start, end); | ||
| 94 | } | 97 | } |
| 95 | 98 | ||
| 96 | void __kprobes __patch_text(void *addr, u32 insn) | 99 | void __kprobes __patch_text(void *addr, u32 insn) |
| @@ -171,6 +171,7 @@ static int __init processor_probe(struct parisc_device *dev) · 170 unmodified lines | |||
| 171 | p->cpu_num = cpu_info.cpu_num; | 171 | p->cpu_num = cpu_info.cpu_num; |
| 172 | p->cpu_loc = cpu_info.cpu_loc; | 172 | p->cpu_loc = cpu_info.cpu_loc; |
| 173 | 173 | ||
| 174 | set_cpu_possible(cpuid, true); | ||
| 174 | store_cpu_topology(cpuid); | 175 | store_cpu_topology(cpuid); |
| 175 | 176 | ||
| 176 | #ifdef CONFIG_SMP | 177 | #ifdef CONFIG_SMP |
| @@ -419,8 +420,7 @@ show_cpuinfo (struct seq_file *m, void *v) · 242 unmodified lines | |||
| 419 | } | 420 | } |
| 420 | seq_printf(m, " (0x%02lx)\n", boot_cpu_data.pdc.capabilities); | 421 | seq_printf(m, " (0x%02lx)\n", boot_cpu_data.pdc.capabilities); |
| 421 | 422 | ||
| 422 | seq_printf(m, "model\t\t: %s\n" | 423 | seq_printf(m, "model\t\t: %s - %s\n", |
| 423 | "model name\t: %s\n", | ||
| 424 | boot_cpu_data.pdc.sys_model_name, | 424 | boot_cpu_data.pdc.sys_model_name, |
| 425 | cpuinfo->dev ? | 425 | cpuinfo->dev ? |
| 426 | cpuinfo->dev->name : "Unknown"); | 426 | cpuinfo->dev->name : "Unknown"); |
| @@ -461,6 +461,13 @@ static struct parisc_driver cpu_driver __refdata = { · 34 unmodified lines | |||
| 461 | */ | 461 | */ |
| 462 | void __init processor_init(void) | 462 | void __init processor_init(void) |
| 463 | { | 463 | { |
| 464 | unsigned int cpu; | ||
| 465 | |||
| 464 | reset_cpu_topology(); | 466 | reset_cpu_topology(); |
| 467 | |||
| 468 | /* reset possible mask. We will mark those which are possible. */ | ||
| 469 | for_each_possible_cpu(cpu) | ||
| 470 | set_cpu_possible(cpu, false); | ||
| 471 | |||
| 465 | register_parisc_driver(&cpu_driver); | 472 | register_parisc_driver(&cpu_driver); |
| 466 | } | 473 | } |
| @@ -161,6 +161,8 @@ void __init setup_arch(char **cmdline_p) · 160 unmodified lines | |||
| 161 | #ifdef CONFIG_PA11 | 161 | #ifdef CONFIG_PA11 |
| 162 | dma_ops_init(); | 162 | dma_ops_init(); |
| 163 | #endif | 163 | #endif |
| 164 | |||
| 165 | clear_sched_clock_stable(); | ||
| 164 | } | 166 | } |
| 165 | 167 | ||
| 166 | /* | 168 | /* |
| @@ -251,13 +251,9 @@ void __init time_init(void) · 250 unmodified lines | |||
| 251 | static int __init init_cr16_clocksource(void) | 251 | static int __init init_cr16_clocksource(void) |
| 252 | { | 252 | { |
| 253 | /* | 253 | /* |
| 254 | * The cr16 interval timers are not syncronized across CPUs, even if | 254 | * The cr16 interval timers are not synchronized across CPUs. |
| 255 | * they share the same socket. | ||
| 256 | */ | 255 | */ |
| 257 | if (num_online_cpus() > 1 && !running_on_qemu) { | 256 | if (num_online_cpus() > 1 && !running_on_qemu) { |
| 258 | /* mark sched_clock unstable */ | ||
| 259 | clear_sched_clock_stable(); | ||
| 260 | |||
| 261 | clocksource_cr16.name = "cr16_unstable"; | 257 | clocksource_cr16.name = "cr16_unstable"; |
| 262 | clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; | 258 | clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE; |
| 263 | clocksource_cr16.rating = 0; | 259 | clocksource_cr16.rating = 0; |
| @@ -469,7 +469,7 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o · 468 unmodified lines | |||
| 469 | * panic notifiers, and we should call panic | 469 | * panic notifiers, and we should call panic |
| 470 | * directly from the location that we wish. | 470 | * directly from the location that we wish. |
| 471 | * e.g. We should not call panic from | 471 | * e.g. We should not call panic from |
| 472 | * parisc_terminate, but rather the oter way around. | 472 | * parisc_terminate, but rather the other way around. |
| 473 | * This hack works, prints the panic message twice, | 473 | * This hack works, prints the panic message twice, |
| 474 | * and it enables reboot timers! | 474 | * and it enables reboot timers! |
| 475 | */ | 475 | */ |
| @@ -253,7 +253,7 @@ dbl_fadd( · 252 unmodified lines | |||
| 253 | return(NOEXCEPTION); | 253 | return(NOEXCEPTION); |
| 254 | } | 254 | } |
| 255 | right_exponent = 1; /* Set exponent to reflect different bias | 255 | right_exponent = 1; /* Set exponent to reflect different bias |
| 256 | * with denomalized numbers. */ | 256 | * with denormalized numbers. */ |
| 257 | } | 257 | } |
| 258 | else | 258 | else |
| 259 | { | 259 | { |
| @@ -256,7 +256,7 @@ dbl_fsub( · 255 unmodified lines | |||
| 256 | return(NOEXCEPTION); | 256 | return(NOEXCEPTION); |
| 257 | } | 257 | } |
| 258 | right_exponent = 1; /* Set exponent to reflect different bias | 258 | right_exponent = 1; /* Set exponent to reflect different bias |
| 259 | * with denomalized numbers. */ | 259 | * with denormalized numbers. */ |
| 260 | } | 260 | } |
| 261 | else | 261 | else |
| 262 | { | 262 | { |
| @@ -249,7 +249,7 @@ sgl_fadd( · 248 unmodified lines | |||
| 249 | return(NOEXCEPTION); | 249 | return(NOEXCEPTION); |
| 250 | } | 250 | } |
| 251 | right_exponent = 1; /* Set exponent to reflect different bias | 251 | right_exponent = 1; /* Set exponent to reflect different bias |
| 252 | * with denomalized numbers. */ | 252 | * with denormalized numbers. */ |
| 253 | } | 253 | } |
| 254 | else | 254 | else |
| 255 | { | 255 | { |
| @@ -252,7 +252,7 @@ sgl_fsub( · 251 unmodified lines | |||
| 252 | return(NOEXCEPTION); | 252 | return(NOEXCEPTION); |
| 253 | } | 253 | } |
| 254 | right_exponent = 1; /* Set exponent to reflect different bias | 254 | right_exponent = 1; /* Set exponent to reflect different bias |
| 255 | * with denomalized numbers. */ | 255 | * with denormalized numbers. */ |
| 256 | } | 256 | } |
| 257 | else | 257 | else |
| 258 | { | 258 | { |
| @@ -22,12 +22,15 @@ · 21 unmodified lines | |||
| 22 | .macro cvdso_call funct call_time=0 | 22 | .macro cvdso_call funct call_time=0 |
| 23 | .cfi_startproc | 23 | .cfi_startproc |
| 24 | PPC_STLU r1, -PPC_MIN_STKFRM(r1) | 24 | PPC_STLU r1, -PPC_MIN_STKFRM(r1) |
| 25 | .cfi_adjust_cfa_offset PPC_MIN_STKFRM | ||
| 25 | mflr r0 | 26 | mflr r0 |
| 26 | .cfi_register lr, r0 | ||
| 27 | PPC_STLU r1, -PPC_MIN_STKFRM(r1) | 27 | PPC_STLU r1, -PPC_MIN_STKFRM(r1) |
| 28 | .cfi_adjust_cfa_offset PPC_MIN_STKFRM | ||
| 28 | PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) | 29 | PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) |
| 30 | .cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF | ||
| 29 | #ifdef __powerpc64__ | 31 | #ifdef __powerpc64__ |
| 30 | PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1) | 32 | PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1) |
| 33 | .cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT | ||
| 31 | #endif | 34 | #endif |
| 32 | get_datapage r5 | 35 | get_datapage r5 |
| 33 | .ifeq \call_time | 36 | .ifeq \call_time |
| @@ -39,13 +42,15 @@ · 5 unmodified lines | |||
| 39 | PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) | 42 | PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1) |
| 40 | #ifdef __powerpc64__ | 43 | #ifdef __powerpc64__ |
| 41 | PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1) | 44 | PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1) |
| 45 | .cfi_restore r2 | ||
| 42 | #endif | 46 | #endif |
| 43 | .ifeq \call_time | 47 | .ifeq \call_time |
| 44 | cmpwi r3, 0 | 48 | cmpwi r3, 0 |
| 45 | .endif | 49 | .endif |
| 46 | mtlr r0 | 50 | mtlr r0 |
| 47 | .cfi_restore lr | ||
| 48 | addi r1, r1, 2 * PPC_MIN_STKFRM | 51 | addi r1, r1, 2 * PPC_MIN_STKFRM |
| 52 | .cfi_restore lr | ||
| 53 | .cfi_def_cfa_offset 0 | ||
| 49 | crclr so | 54 | crclr so |
| 50 | .ifeq \call_time | 55 | .ifeq \call_time |
| 51 | beqlr+ | 56 | beqlr+ |
| @@ -122,11 +122,27 @@ · 121 unmodified lines | |||
| 122 | 122 | ||
| 123 | /* 0x0 - 0xb */ | 123 | /* 0x0 - 0xb */ |
| 124 | 124 | ||
| 125 | /* 'current->mm' needs to be in r4 */ | 125 | /* switch_mmu_context() needs paging, let's enable it */ |
| 126 | tophys(r4, r2) | 126 | mfmsr r9 |
| 127 | lwz r4, MM(r4) | 127 | ori r11, r9, MSR_DR |
| 128 | tophys(r4, r4) | 128 | mtmsr r11 |
| 129 | /* This only clobbers r0, r3, r4 and r5 */ | 129 | sync |
| 130 | |||
| 131 | /* switch_mmu_context() clobbers r12, rescue it */ | ||
| 132 | SAVE_GPR(12, r1) | ||
| 133 | |||
| 134 | /* Calling switch_mmu_context(<inv>, current->mm, <inv>); */ | ||
| 135 | lwz r4, MM(r2) | ||
| 130 | bl switch_mmu_context | 136 | bl switch_mmu_context |
| 131 | 137 | ||
| 138 | /* restore r12 */ | ||
| 139 | REST_GPR(12, r1) | ||
| 140 | |||
| 141 | /* Disable paging again */ | ||
| 142 | mfmsr r9 | ||
| 143 | li r6, MSR_DR | ||
| 144 | andc r9, r9, r6 | ||
| 145 | mtmsr r9 | ||
| 146 | sync | ||
| 147 | |||
| 132 | .endm | 148 | .endm |
| @@ -462,7 +462,6 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu · 461 unmodified lines | |||
| 462 | { | 462 | { |
| 463 | struct papr_scm_perf_stat *stat; | 463 | struct papr_scm_perf_stat *stat; |
| 464 | struct papr_scm_perf_stats *stats; | 464 | struct papr_scm_perf_stats *stats; |
| 465 | char *statid; | ||
| 466 | int index, rc, count; | 465 | int index, rc, count; |
| 467 | u32 available_events; | 466 | u32 available_events; |
| 468 | 467 | ||
| @@ -493,14 +492,12 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu · 24 unmodified lines | |||
| 493 | 492 | ||
| 494 | for (index = 0, stat = stats->scm_statistic, count = 0; | 493 | for (index = 0, stat = stats->scm_statistic, count = 0; |
| 495 | index < available_events; index++, ++stat) { | 494 | index < available_events; index++, ++stat) { |
| 496 | statid = kzalloc(strlen(stat->stat_id) + 1, GFP_KERNEL); | 495 | p->nvdimm_events_map[count] = kmemdup_nul(stat->stat_id, 8, GFP_KERNEL); |
| 497 | if (!statid) { | 496 | if (!p->nvdimm_events_map[count]) { |
| 498 | rc = -ENOMEM; | 497 | rc = -ENOMEM; |
| 499 | goto out_nvdimm_events_map; | 498 | goto out_nvdimm_events_map; |
| 500 | } | 499 | } |
| 501 | 500 | ||
| 502 | strcpy(statid, stat->stat_id); | ||
| 503 | p->nvdimm_events_map[count] = statid; | ||
| 504 | count++; | 501 | count++; |
| 505 | } | 502 | } |
| 506 | p->nvdimm_events_map[count] = NULL; | 503 | p->nvdimm_events_map[count] = NULL; |
| @@ -27,22 +27,31 @@ struct vas_caps_entry { · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | /* | 28 | /* |
| 29 | * This function is used to get the notification from the drmgr when | 29 | * This function is used to get the notification from the drmgr when |
| 30 | * QoS credits are changed. Though receiving the target total QoS | 30 | * QoS credits are changed. |
| 31 | * credits here, get the official QoS capabilities from the hypervisor. | ||
| 32 | */ | 31 | */ |
| 33 | static ssize_t update_total_credits_trigger(struct vas_cop_feat_caps *caps, | 32 | static ssize_t update_total_credits_store(struct vas_cop_feat_caps *caps, |
| 34 | const char *buf, size_t count) | 33 | const char *buf, size_t count) |
| 35 | { | 34 | { |
| 36 | int err; | 35 | int err; |
| 37 | u16 creds; | 36 | u16 creds; |
| 38 | 37 | ||
| 39 | err = kstrtou16(buf, 0, &creds); | 38 | err = kstrtou16(buf, 0, &creds); |
| 39 | /* | ||
| 40 | * The user space interface from the management console | ||
| 41 | * notifies OS with the new QoS credits and then the | ||
| 42 | * hypervisor. So OS has to use this new credits value | ||
| 43 | * and reconfigure VAS windows (close or reopen depends | ||
| 44 | * on the credits available) instead of depending on VAS | ||
| 45 | * QoS capabilities from the hypervisor. | ||
| 46 | */ | ||
| 40 | if (!err) | 47 | if (!err) |
| 41 | err = vas_reconfig_capabilties(caps->win_type); | 48 | err = vas_reconfig_capabilties(caps->win_type, creds); |
| 42 | 49 | ||
| 43 | if (err) | 50 | if (err) |
| 44 | return -EINVAL; | 51 | return -EINVAL; |
| 45 | 52 | ||
| 53 | pr_info("Set QoS total credits %u\n", creds); | ||
| 54 | |||
| 46 | return count; | 55 | return count; |
| 47 | } | 56 | } |
| 48 | 57 | ||
| @@ -92,7 +101,7 @@ VAS_ATTR_RO(nr_total_credits); · 43 unmodified lines | |||
| 92 | VAS_ATTR_RO(nr_used_credits); | 101 | VAS_ATTR_RO(nr_used_credits); |
| 93 | 102 | ||
| 94 | static struct vas_sysfs_entry update_total_credits_attribute = | 103 | static struct vas_sysfs_entry update_total_credits_attribute = |
| 95 | __ATTR(update_total_credits, 0200, NULL, update_total_credits_trigger); | 104 | __ATTR(update_total_credits, 0200, NULL, update_total_credits_store); |
| 96 | 105 | ||
| 97 | static struct attribute *vas_def_capab_attrs[] = { | 106 | static struct attribute *vas_def_capab_attrs[] = { |
| 98 | &nr_total_credits_attribute.attr, | 107 | &nr_total_credits_attribute.attr, |
| @@ -779,10 +779,10 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds, · 778 unmodified lines | |||
| 779 | * changes. Reconfig window configurations based on the credits | 779 | * changes. Reconfig window configurations based on the credits |
| 780 | * availability from this new capabilities. | 780 | * availability from this new capabilities. |
| 781 | */ | 781 | */ |
| 782 | int vas_reconfig_capabilties(u8 type) | 782 | int vas_reconfig_capabilties(u8 type, int new_nr_creds) |
| 783 | { | 783 | { |
| 784 | struct vas_cop_feat_caps *caps; | 784 | struct vas_cop_feat_caps *caps; |
| 785 | int old_nr_creds, new_nr_creds; | 785 | int old_nr_creds; |
| 786 | struct vas_caps *vcaps; | 786 | struct vas_caps *vcaps; |
| 787 | int rc = 0, nr_active_wins; | 787 | int rc = 0, nr_active_wins; |
| 788 | 788 | ||
| @@ -795,12 +795,6 @@ int vas_reconfig_capabilties(u8 type) · 6 unmodified lines | |||
| 795 | caps = &vcaps->caps; | 795 | caps = &vcaps->caps; |
| 796 | 796 | ||
| 797 | mutex_lock(&vas_pseries_mutex); | 797 | mutex_lock(&vas_pseries_mutex); |
| 798 | rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES, vcaps->feat, | ||
| 799 | (u64)virt_to_phys(&hv_cop_caps)); | ||
| 800 | if (rc) | ||
| 801 | goto out; | ||
| 802 | |||
| 803 | new_nr_creds = be16_to_cpu(hv_cop_caps.target_lpar_creds); | ||
| 804 | 798 | ||
| 805 | old_nr_creds = atomic_read(&caps->nr_total_credits); | 799 | old_nr_creds = atomic_read(&caps->nr_total_credits); |
| 806 | 800 | ||
| @@ -832,7 +826,6 @@ int vas_reconfig_capabilties(u8 type) · 25 unmodified lines | |||
| 832 | false); | 826 | false); |
| 833 | } | 827 | } |
| 834 | 828 | ||
| 835 | out: | ||
| 836 | mutex_unlock(&vas_pseries_mutex); | 829 | mutex_unlock(&vas_pseries_mutex); |
| 837 | return rc; | 830 | return rc; |
| 838 | } | 831 | } |
| @@ -850,7 +843,7 @@ static int pseries_vas_notifier(struct notifier_block *nb, · 11 unmodified lines | |||
| 850 | struct of_reconfig_data *rd = data; | 843 | struct of_reconfig_data *rd = data; |
| 851 | struct device_node *dn = rd->dn; | 844 | struct device_node *dn = rd->dn; |
| 852 | const __be32 *intserv = NULL; | 845 | const __be32 *intserv = NULL; |
| 853 | int len, rc = 0; | 846 | int new_nr_creds, len, rc = 0; |
| 854 | 847 | ||
| 855 | if ((action == OF_RECONFIG_ATTACH_NODE) || | 848 | if ((action == OF_RECONFIG_ATTACH_NODE) || |
| 856 | (action == OF_RECONFIG_DETACH_NODE)) | 849 | (action == OF_RECONFIG_DETACH_NODE)) |
| @@ -862,7 +855,15 @@ static int pseries_vas_notifier(struct notifier_block *nb, · 5 unmodified lines | |||
| 862 | if (!intserv) | 855 | if (!intserv) |
| 863 | return NOTIFY_OK; | 856 | return NOTIFY_OK; |
| 864 | 857 | ||
| 865 | rc = vas_reconfig_capabilties(VAS_GZIP_DEF_FEAT_TYPE); | 858 | rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES, |
| 859 | vascaps[VAS_GZIP_DEF_FEAT_TYPE].feat, | ||
| 860 | (u64)virt_to_phys(&hv_cop_caps)); | ||
| 861 | if (!rc) { | ||
| 862 | new_nr_creds = be16_to_cpu(hv_cop_caps.target_lpar_creds); | ||
| 863 | rc = vas_reconfig_capabilties(VAS_GZIP_DEF_FEAT_TYPE, | ||
| 864 | new_nr_creds); | ||
| 865 | } | ||
| 866 | |||
| 866 | if (rc) | 867 | if (rc) |
| 867 | pr_err("Failed reconfig VAS capabilities with DLPAR\n"); | 868 | pr_err("Failed reconfig VAS capabilities with DLPAR\n"); |
| 868 | 869 | ||
| @@ -135,7 +135,7 @@ struct pseries_vas_window { · 134 unmodified lines | |||
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps); | 137 | int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps); |
| 138 | int vas_reconfig_capabilties(u8 type); | 138 | int vas_reconfig_capabilties(u8 type, int new_nr_creds); |
| 139 | int __init sysfs_pseries_vas_init(struct vas_all_caps *vas_caps); | 139 | int __init sysfs_pseries_vas_init(struct vas_all_caps *vas_caps); |
| 140 | 140 | ||
| 141 | #ifdef CONFIG_PPC_VAS | 141 | #ifdef CONFIG_PPC_VAS |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | |||
| 7 | reg = <0x0 0x41000000 0x0 0xF0>; | 7 | reg = <0x0 0x41000000 0x0 0xF0>; |
| 8 | microchip,sync-update-mask = /bits/ 32 <0>; | 8 | microchip,sync-update-mask = /bits/ 32 <0>; |
| 9 | #pwm-cells = <2>; | 9 | #pwm-cells = <2>; |
| 10 | clocks = <&clkcfg CLK_FIC3>; | 10 | clocks = <&fabric_clk3>; |
| 11 | status = "disabled"; | 11 | status = "disabled"; |
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| @@ -16,10 +16,22 @@ · 2 unmodified lines | |||
| 16 | reg = <0x0 0x44000000 0x0 0x1000>; | 16 | reg = <0x0 0x44000000 0x0 0x1000>; |
| 17 | #address-cells = <1>; | 17 | #address-cells = <1>; |
| 18 | #size-cells = <0>; | 18 | #size-cells = <0>; |
| 19 | clocks = <&clkcfg CLK_FIC3>; | 19 | clocks = <&fabric_clk3>; |
| 20 | interrupt-parent = <&plic>; | 20 | interrupt-parent = <&plic>; |
| 21 | interrupts = <122>; | 21 | interrupts = <122>; |
| 22 | clock-frequency = <100000>; | 22 | clock-frequency = <100000>; |
| 23 | status = "disabled"; | 23 | status = "disabled"; |
| 24 | }; | 24 | }; |
| 25 | |||
| 26 | fabric_clk3: fabric-clk3 { | ||
| 27 | compatible = "fixed-clock"; | ||
| 28 | #clock-cells = <0>; | ||
| 29 | clock-frequency = <62500000>; | ||
| 30 | }; | ||
| 31 | |||
| 32 | fabric_clk1: fabric-clk1 { | ||
| 33 | compatible = "fixed-clock"; | ||
| 34 | #clock-cells = <0>; | ||
| 35 | clock-frequency = <125000000>; | ||
| 36 | }; | ||
| 25 | }; | 37 | }; |
| @@ -45,7 +45,7 @@ · 44 unmodified lines | |||
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | &refclk { | 47 | &refclk { |
| 48 | clock-frequency = <600000000>; | 48 | clock-frequency = <125000000>; |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | &mmuart1 { | 51 | &mmuart1 { |
| @@ -141,7 +141,7 @@ · 140 unmodified lines | |||
| 141 | }; | 141 | }; |
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| 144 | refclk: msspllclk { | 144 | refclk: mssrefclk { |
| 145 | compatible = "fixed-clock"; | 145 | compatible = "fixed-clock"; |
| 146 | #clock-cells = <0>; | 146 | #clock-cells = <0>; |
| 147 | }; | 147 | }; |
| @@ -190,7 +190,7 @@ · 42 unmodified lines | |||
| 190 | 190 | ||
| 191 | clkcfg: clkcfg@20002000 { | 191 | clkcfg: clkcfg@20002000 { |
| 192 | compatible = "microchip,mpfs-clkcfg"; | 192 | compatible = "microchip,mpfs-clkcfg"; |
| 193 | reg = <0x0 0x20002000 0x0 0x1000>; | 193 | reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>; |
| 194 | clocks = <&refclk>; | 194 | clocks = <&refclk>; |
| 195 | #clock-cells = <1>; | 195 | #clock-cells = <1>; |
| 196 | }; | 196 | }; |
| @@ -393,8 +393,8 @@ · 196 unmodified lines | |||
| 393 | reg = <0x0 0x20124000 0x0 0x1000>; | 393 | reg = <0x0 0x20124000 0x0 0x1000>; |
| 394 | interrupt-parent = <&plic>; | 394 | interrupt-parent = <&plic>; |
| 395 | interrupts = <80>, <81>; | 395 | interrupts = <80>, <81>; |
| 396 | clocks = <&clkcfg CLK_RTC>; | 396 | clocks = <&clkcfg CLK_RTC>, <&clkcfg CLK_RTCREF>; |
| 397 | clock-names = "rtc"; | 397 | clock-names = "rtc", "rtcref"; |
| 398 | status = "disabled"; | 398 | status = "disabled"; |
| 399 | }; | 399 | }; |
| 400 | 400 | ||
| @@ -424,7 +424,7 @@ · 23 unmodified lines | |||
| 424 | <0 0 0 3 &pcie_intc 2>, | 424 | <0 0 0 3 &pcie_intc 2>, |
| 425 | <0 0 0 4 &pcie_intc 3>; | 425 | <0 0 0 4 &pcie_intc 3>; |
| 426 | interrupt-map-mask = <0 0 0 7>; | 426 | interrupt-map-mask = <0 0 0 7>; |
| 427 | clocks = <&clkcfg CLK_FIC0>, <&clkcfg CLK_FIC1>, <&clkcfg CLK_FIC3>; | 427 | clocks = <&fabric_clk1>, <&fabric_clk1>, <&fabric_clk3>; |
| 428 | clock-names = "fic0", "fic1", "fic3"; | 428 | clock-names = "fic0", "fic1", "fic3"; |
| 429 | ranges = <0x3000000 0x0 0x8000000 0x20 0x8000000 0x0 0x80000000>; | 429 | ranges = <0x3000000 0x0 0x8000000 0x20 0x8000000 0x0 0x80000000>; |
| 430 | msi-parent = <&pcie>; | 430 | msi-parent = <&pcie>; |
| @@ -101,6 +101,7 @@ CONFIG_VIRTIO_BALLOON=y · 100 unmodified lines | |||
| 101 | CONFIG_VIRTIO_INPUT=y | 101 | CONFIG_VIRTIO_INPUT=y |
| 102 | CONFIG_VIRTIO_MMIO=y | 102 | CONFIG_VIRTIO_MMIO=y |
| 103 | CONFIG_RPMSG_CHAR=y | 103 | CONFIG_RPMSG_CHAR=y |
| 104 | CONFIG_RPMSG_CTRL=y | ||
| 104 | CONFIG_RPMSG_VIRTIO=y | 105 | CONFIG_RPMSG_VIRTIO=y |
| 105 | CONFIG_EXT4_FS=y | 106 | CONFIG_EXT4_FS=y |
| 106 | CONFIG_EXT4_FS_POSIX_ACL=y | 107 | CONFIG_EXT4_FS_POSIX_ACL=y |
| @@ -93,6 +93,7 @@ CONFIG_VIRTIO_BALLOON=y · 92 unmodified lines | |||
| 93 | CONFIG_VIRTIO_INPUT=y | 93 | CONFIG_VIRTIO_INPUT=y |
| 94 | CONFIG_VIRTIO_MMIO=y | 94 | CONFIG_VIRTIO_MMIO=y |
| 95 | CONFIG_RPMSG_CHAR=y | 95 | CONFIG_RPMSG_CHAR=y |
| 96 | CONFIG_RPMSG_CTRL=y | ||
| 96 | CONFIG_RPMSG_VIRTIO=y | 97 | CONFIG_RPMSG_VIRTIO=y |
| 97 | CONFIG_EXT4_FS=y | 98 | CONFIG_EXT4_FS=y |
| 98 | CONFIG_EXT4_FS_POSIX_ACL=y | 99 | CONFIG_EXT4_FS_POSIX_ACL=y |
| @@ -104,7 +104,7 @@ static int patch_text_cb(void *data) · 103 unmodified lines | |||
| 104 | struct patch_insn *patch = data; | 104 | struct patch_insn *patch = data; |
| 105 | int ret = 0; | 105 | int ret = 0; |
| 106 | 106 | ||
| 107 | if (atomic_inc_return(&patch->cpu_count) == 1) { | 107 | if (atomic_inc_return(&patch->cpu_count) == num_online_cpus()) { |
| 108 | ret = | 108 | ret = |
| 109 | patch_text_nosync(patch->addr, &patch->insn, | 109 | patch_text_nosync(patch->addr, &patch->insn, |
| 110 | GET_INSN_LENGTH(patch->insn)); | 110 | GET_INSN_LENGTH(patch->insn)); |
| @@ -83,7 +83,7 @@ void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) · 82 unmodified lines | |||
| 83 | 83 | ||
| 84 | void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, | 84 | void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, |
| 85 | struct kvm_run *run, | 85 | struct kvm_run *run, |
| 86 | u32 type, u64 flags) | 86 | u32 type, u64 reason) |
| 87 | { | 87 | { |
| 88 | unsigned long i; | 88 | unsigned long i; |
| 89 | struct kvm_vcpu *tmp; | 89 | struct kvm_vcpu *tmp; |
| @@ -94,7 +94,8 @@ void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu, · 4 unmodified lines | |||
| 94 | 94 | ||
| 95 | memset(&run->system_event, 0, sizeof(run->system_event)); | 95 | memset(&run->system_event, 0, sizeof(run->system_event)); |
| 96 | run->system_event.type = type; | 96 | run->system_event.type = type; |
| 97 | run->system_event.flags = flags; | 97 | run->system_event.ndata = 1; |
| 98 | run->system_event.data[0] = reason; | ||
| 98 | run->exit_reason = KVM_EXIT_SYSTEM_EVENT; | 99 | run->exit_reason = KVM_EXIT_SYSTEM_EVENT; |
| 99 | } | 100 | } |
| 100 | 101 | ||
| @@ -208,8 +208,25 @@ static void __init setup_bootmem(void) · 207 unmodified lines | |||
| 208 | * early_init_fdt_reserve_self() since __pa() does | 208 | * early_init_fdt_reserve_self() since __pa() does |
| 209 | * not work for DTB pointers that are fixmap addresses | 209 | * not work for DTB pointers that are fixmap addresses |
| 210 | */ | 210 | */ |
| 211 | if (!IS_ENABLED(CONFIG_BUILTIN_DTB)) | 211 | if (!IS_ENABLED(CONFIG_BUILTIN_DTB)) { |
| 212 | memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va)); | 212 | /* |
| 213 | * In case the DTB is not located in a memory region we won't | ||
| 214 | * be able to locate it later on via the linear mapping and | ||
| 215 | * get a segfault when accessing it via __va(dtb_early_pa). | ||
| 216 | * To avoid this situation copy DTB to a memory region. | ||
| 217 | * Note that memblock_phys_alloc will also reserve DTB region. | ||
| 218 | */ | ||
| 219 | if (!memblock_is_memory(dtb_early_pa)) { | ||
| 220 | size_t fdt_size = fdt_totalsize(dtb_early_va); | ||
| 221 | phys_addr_t new_dtb_early_pa = memblock_phys_alloc(fdt_size, PAGE_SIZE); | ||
| 222 | void *new_dtb_early_va = early_memremap(new_dtb_early_pa, fdt_size); | ||
| 223 | |||
| 224 | memcpy(new_dtb_early_va, dtb_early_va, fdt_size); | ||
| 225 | early_memunmap(new_dtb_early_va, fdt_size); | ||
| 226 | _dtb_early_pa = new_dtb_early_pa; | ||
| 227 | } else | ||
| 228 | memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va)); | ||
| 229 | } | ||
| 213 | 230 | ||
| 214 | early_init_fdt_scan_reserved_mem(); | 231 | early_init_fdt_scan_reserved_mem(); |
| 215 | dma_contiguous_reserve(dma32_phys_limit); | 232 | dma_contiguous_reserve(dma32_phys_limit); |
| @@ -30,6 +30,16 @@ KBUILD_CFLAGS_DECOMPRESSOR += -fno-stack-protector · 29 unmodified lines | |||
| 30 | KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-member) | 30 | KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-member) |
| 31 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g) | 31 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g) |
| 32 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,)) | 32 | KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,)) |
| 33 | |||
| 34 | ifdef CONFIG_CC_IS_GCC | ||
| 35 | ifeq ($(call cc-ifversion, -ge, 1200, y), y) | ||
| 36 | ifeq ($(call cc-ifversion, -lt, 1300, y), y) | ||
| 37 | KBUILD_CFLAGS += $(call cc-disable-warning, array-bounds) | ||
| 38 | KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, array-bounds) | ||
| 39 | endif | ||
| 40 | endif | ||
| 41 | endif | ||
| 42 | |||
| 33 | UTS_MACHINE := s390x | 43 | UTS_MACHINE := s390x |
| 34 | STACK_SIZE := $(if $(CONFIG_KASAN),65536,16384) | 44 | STACK_SIZE := $(if $(CONFIG_KASAN),65536,16384) |
| 35 | CHECKFLAGS += -D__s390__ -D__s390x__ | 45 | CHECKFLAGS += -D__s390__ -D__s390x__ |
| @@ -2384,7 +2384,16 @@ static int kvm_s390_vm_mem_op(struct kvm *kvm, struct kvm_s390_mem_op *mop) · 2383 unmodified lines | |||
| 2384 | return -EINVAL; | 2384 | return -EINVAL; |
| 2385 | if (mop->size > MEM_OP_MAX_SIZE) | 2385 | if (mop->size > MEM_OP_MAX_SIZE) |
| 2386 | return -E2BIG; | 2386 | return -E2BIG; |
| 2387 | if (kvm_s390_pv_is_protected(kvm)) | 2387 | /* |
| 2388 | * This is technically a heuristic only, if the kvm->lock is not | ||
| 2389 | * taken, it is not guaranteed that the vm is/remains non-protected. | ||
| 2390 | * This is ok from a kernel perspective, wrongdoing is detected | ||
| 2391 | * on the access, -EFAULT is returned and the vm may crash the | ||
| 2392 | * next time it accesses the memory in question. | ||
| 2393 | * There is no sane usecase to do switching and a memop on two | ||
| 2394 | * different CPUs at the same time. | ||
| 2395 | */ | ||
| 2396 | if (kvm_s390_pv_get_handle(kvm)) | ||
| 2388 | return -EINVAL; | 2397 | return -EINVAL; |
| 2389 | if (mop->flags & KVM_S390_MEMOP_F_SKEY_PROTECTION) { | 2398 | if (mop->flags & KVM_S390_MEMOP_F_SKEY_PROTECTION) { |
| 2390 | if (access_key_invalid(mop->key)) | 2399 | if (access_key_invalid(mop->key)) |
| @@ -1183,6 +1183,7 @@ EXPORT_SYMBOL_GPL(gmap_read_table); · 1182 unmodified lines | |||
| 1183 | static inline void gmap_insert_rmap(struct gmap *sg, unsigned long vmaddr, | 1183 | static inline void gmap_insert_rmap(struct gmap *sg, unsigned long vmaddr, |
| 1184 | struct gmap_rmap *rmap) | 1184 | struct gmap_rmap *rmap) |
| 1185 | { | 1185 | { |
| 1186 | struct gmap_rmap *temp; | ||
| 1186 | void __rcu **slot; | 1187 | void __rcu **slot; |
| 1187 | 1188 | ||
| 1188 | BUG_ON(!gmap_is_shadow(sg)); | 1189 | BUG_ON(!gmap_is_shadow(sg)); |
| @@ -1190,6 +1191,12 @@ static inline void gmap_insert_rmap(struct gmap *sg, unsigned long vmaddr, · 1 unmodified line | |||
| 1190 | if (slot) { | 1191 | if (slot) { |
| 1191 | rmap->next = radix_tree_deref_slot_protected(slot, | 1192 | rmap->next = radix_tree_deref_slot_protected(slot, |
| 1192 | &sg->guest_table_lock); | 1193 | &sg->guest_table_lock); |
| 1194 | for (temp = rmap->next; temp; temp = temp->next) { | ||
| 1195 | if (temp->raddr == rmap->raddr) { | ||
| 1196 | kfree(rmap); | ||
| 1197 | return; | ||
| 1198 | } | ||
| 1199 | } | ||
| 1193 | radix_tree_replace_slot(&sg->host_to_rmap, slot, rmap); | 1200 | radix_tree_replace_slot(&sg->host_to_rmap, slot, rmap); |
| 1194 | } else { | 1201 | } else { |
| 1195 | rmap->next = NULL; | 1202 | rmap->next = NULL; |
| @@ -1866,7 +1866,7 @@ config X86_KERNEL_IBT · 1865 unmodified lines | |||
| 1866 | code with them to make this happen. | 1866 | code with them to make this happen. |
| 1867 | 1867 | ||
| 1868 | In addition to building the kernel with IBT, seal all functions that | 1868 | In addition to building the kernel with IBT, seal all functions that |
| 1869 | are not indirect call targets, avoiding them ever becomming one. | 1869 | are not indirect call targets, avoiding them ever becoming one. |
| 1870 | 1870 | ||
| 1871 | This requires LTO like objtool runs and will slow down the build. It | 1871 | This requires LTO like objtool runs and will slow down the build. It |
| 1872 | does significantly reduce the number of ENDBR instructions in the | 1872 | does significantly reduce the number of ENDBR instructions in the |
| @@ -337,6 +337,9 @@ SYM_CODE_END(ret_from_fork) · 336 unmodified lines | |||
| 337 | 337 | ||
| 338 | call \cfunc | 338 | call \cfunc |
| 339 | 339 | ||
| 340 | /* For some configurations \cfunc ends up being a noreturn. */ | ||
| 341 | REACHABLE | ||
| 342 | |||
| 340 | jmp error_return | 343 | jmp error_return |
| 341 | .endm | 344 | .endm |
| 342 | 345 | ||
| @@ -26,6 +26,7 @@ · 25 unmodified lines | |||
| 26 | * _G - parts with extra graphics on | 26 | * _G - parts with extra graphics on |
| 27 | * _X - regular server parts | 27 | * _X - regular server parts |
| 28 | * _D - micro server parts | 28 | * _D - micro server parts |
| 29 | * _N,_P - other mobile parts | ||
| 29 | * | 30 | * |
| 30 | * Historical OPTDIFFs: | 31 | * Historical OPTDIFFs: |
| 31 | * | 32 | * |
| @@ -107,8 +108,10 @@ · 75 unmodified lines | |||
| 107 | 108 | ||
| 108 | #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ | 109 | #define INTEL_FAM6_ALDERLAKE 0x97 /* Golden Cove / Gracemont */ |
| 109 | #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */ | 110 | #define INTEL_FAM6_ALDERLAKE_L 0x9A /* Golden Cove / Gracemont */ |
| 111 | #define INTEL_FAM6_ALDERLAKE_N 0xBE | ||
| 110 | 112 | ||
| 111 | #define INTEL_FAM6_RAPTORLAKE 0xB7 | 113 | #define INTEL_FAM6_RAPTORLAKE 0xB7 |
| 114 | #define INTEL_FAM6_RAPTORLAKE_P 0xBA | ||
| 112 | 115 | ||
| 113 | /* "Small Core" Processors (Atom) */ | 116 | /* "Small Core" Processors (Atom) */ |
| 114 | 117 | ||
| @@ -131,10 +131,12 @@ extern void __init load_ucode_bsp(void); · 130 unmodified lines | |||
| 131 | extern void load_ucode_ap(void); | 131 | extern void load_ucode_ap(void); |
| 132 | void reload_early_microcode(void); | 132 | void reload_early_microcode(void); |
| 133 | extern bool initrd_gone; | 133 | extern bool initrd_gone; |
| 134 | void microcode_bsp_resume(void); | ||
| 134 | #else | 135 | #else |
| 135 | static inline void __init load_ucode_bsp(void) { } | 136 | static inline void __init load_ucode_bsp(void) { } |
| 136 | static inline void load_ucode_ap(void) { } | 137 | static inline void load_ucode_ap(void) { } |
| 137 | static inline void reload_early_microcode(void) { } | 138 | static inline void reload_early_microcode(void) { } |
| 139 | static inline void microcode_bsp_resume(void) { } | ||
| 138 | #endif | 140 | #endif |
| 139 | 141 | ||
| 140 | #endif /* _ASM_X86_MICROCODE_H */ | 142 | #endif /* _ASM_X86_MICROCODE_H */ |
| @@ -559,10 +559,6 @@ static inline void update_page_count(int level, unsigned long pages) { } · 558 unmodified lines | |||
| 559 | extern pte_t *lookup_address(unsigned long address, unsigned int *level); | 559 | extern pte_t *lookup_address(unsigned long address, unsigned int *level); |
| 560 | extern pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address, | 560 | extern pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address, |
| 561 | unsigned int *level); | 561 | unsigned int *level); |
| 562 | |||
| 563 | struct mm_struct; | ||
| 564 | extern pte_t *lookup_address_in_mm(struct mm_struct *mm, unsigned long address, | ||
| 565 | unsigned int *level); | ||
| 566 | extern pmd_t *lookup_pmd_address(unsigned long address); | 562 | extern pmd_t *lookup_pmd_address(unsigned long address); |
| 567 | extern phys_addr_t slow_virt_to_phys(void *__address); | 563 | extern phys_addr_t slow_virt_to_phys(void *__address); |
| 568 | extern int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, | 564 | extern int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | |||
| 26 | ".align 4 \n" \ | 26 | ".align 4 \n" \ |
| 27 | ".globl " STATIC_CALL_TRAMP_STR(name) " \n" \ | 27 | ".globl " STATIC_CALL_TRAMP_STR(name) " \n" \ |
| 28 | STATIC_CALL_TRAMP_STR(name) ": \n" \ | 28 | STATIC_CALL_TRAMP_STR(name) ": \n" \ |
| 29 | ANNOTATE_NOENDBR \ | ||
| 29 | insns " \n" \ | 30 | insns " \n" \ |
| 30 | ".byte 0x53, 0x43, 0x54 \n" \ | 31 | ".byte 0x53, 0x43, 0x54 \n" \ |
| 31 | ".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \ | 32 | ".type " STATIC_CALL_TRAMP_STR(name) ", @function \n" \ |
| @@ -758,9 +758,9 @@ static struct subsys_interface mc_cpu_interface = { · 757 unmodified lines | |||
| 758 | }; | 758 | }; |
| 759 | 759 | ||
| 760 | /** | 760 | /** |
| 761 | * mc_bp_resume - Update boot CPU microcode during resume. | 761 | * microcode_bsp_resume - Update boot CPU microcode during resume. |
| 762 | */ | 762 | */ |
| 763 | static void mc_bp_resume(void) | 763 | void microcode_bsp_resume(void) |
| 764 | { | 764 | { |
| 765 | int cpu = smp_processor_id(); | 765 | int cpu = smp_processor_id(); |
| 766 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; | 766 | struct ucode_cpu_info *uci = ucode_cpu_info + cpu; |
| @@ -772,7 +772,7 @@ static void mc_bp_resume(void) · 5 unmodified lines | |||
| 772 | } | 772 | } |
| 773 | 773 | ||
| 774 | static struct syscore_ops mc_syscore_ops = { | 774 | static struct syscore_ops mc_syscore_ops = { |
| 775 | .resume = mc_bp_resume, | 775 | .resume = microcode_bsp_resume, |
| 776 | }; | 776 | }; |
| 777 | 777 | ||
| 778 | static int mc_cpu_starting(unsigned int cpu) | 778 | static int mc_cpu_starting(unsigned int cpu) |
| @@ -41,17 +41,7 @@ struct fpu_state_config fpu_user_cfg __ro_after_init; · 40 unmodified lines | |||
| 41 | */ | 41 | */ |
| 42 | struct fpstate init_fpstate __ro_after_init; | 42 | struct fpstate init_fpstate __ro_after_init; |
| 43 | 43 | ||
| 44 | /* | 44 | /* Track in-kernel FPU usage */ |
| 45 | * Track whether the kernel is using the FPU state | ||
| 46 | * currently. | ||
| 47 | * | ||
| 48 | * This flag is used: | ||
| 49 | * | ||
| 50 | * - by IRQ context code to potentially use the FPU | ||
| 51 | * if it's unused. | ||
| 52 | * | ||
| 53 | * - to debug kernel_fpu_begin()/end() correctness | ||
| 54 | */ | ||
| 55 | static DEFINE_PER_CPU(bool, in_kernel_fpu); | 45 | static DEFINE_PER_CPU(bool, in_kernel_fpu); |
| 56 | 46 | ||
| 57 | /* | 47 | /* |
| @@ -59,42 +49,37 @@ static DEFINE_PER_CPU(bool, in_kernel_fpu); · 1 unmodified line | |||
| 59 | */ | 49 | */ |
| 60 | DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx); | 50 | DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx); |
| 61 | 51 | ||
| 62 | static bool kernel_fpu_disabled(void) | ||
| 63 | { | ||
| 64 | return this_cpu_read(in_kernel_fpu); | ||
| 65 | } | ||
| 66 | |||
| 67 | static bool interrupted_kernel_fpu_idle(void) | ||
| 68 | { | ||
| 69 | return !kernel_fpu_disabled(); | ||
| 70 | } | ||
| 71 | |||
| 72 | /* | ||
| 73 | * Were we in user mode (or vm86 mode) when we were | ||
| 74 | * interrupted? | ||
| 75 | * | ||
| 76 | * Doing kernel_fpu_begin/end() is ok if we are running | ||
| 77 | * in an interrupt context from user mode - we'll just | ||
| 78 | * save the FPU state as required. | ||
| 79 | */ | ||
| 80 | static bool interrupted_user_mode(void) | ||
| 81 | { | ||
| 82 | struct pt_regs *regs = get_irq_regs(); | ||
| 83 | return regs && user_mode(regs); | ||
| 84 | } | ||
| 85 | |||
| 86 | /* | 52 | /* |
| 87 | * Can we use the FPU in kernel mode with the | 53 | * Can we use the FPU in kernel mode with the |
| 88 | * whole "kernel_fpu_begin/end()" sequence? | 54 | * whole "kernel_fpu_begin/end()" sequence? |
| 89 | * | ||
| 90 | * It's always ok in process context (ie "not interrupt") | ||
| 91 | * but it is sometimes ok even from an irq. | ||
| 92 | */ | 55 | */ |
| 93 | bool irq_fpu_usable(void) | 56 | bool irq_fpu_usable(void) |
| 94 | { | 57 | { |
| 95 | return !in_interrupt() || | 58 | if (WARN_ON_ONCE(in_nmi())) |
| 96 | interrupted_user_mode() || | 59 | return false; |
| 97 | interrupted_kernel_fpu_idle(); | 60 | |
| 61 | /* In kernel FPU usage already active? */ | ||
| 62 | if (this_cpu_read(in_kernel_fpu)) | ||
| 63 | return false; | ||
| 64 | |||
| 65 | /* | ||
| 66 | * When not in NMI or hard interrupt context, FPU can be used in: | ||
| 67 | * | ||
| 68 | * - Task context except from within fpregs_lock()'ed critical | ||
| 69 | * regions. | ||
| 70 | * | ||
| 71 | * - Soft interrupt processing context which cannot happen | ||
| 72 | * while in a fpregs_lock()'ed critical region. | ||
| 73 | */ | ||
| 74 | if (!in_hardirq()) | ||
| 75 | return true; | ||
| 76 | |||
| 77 | /* | ||
| 78 | * In hard interrupt context it's safe when soft interrupts | ||
| 79 | * are enabled, which means the interrupt did not hit in | ||
| 80 | * a fpregs_lock()'ed critical region. | ||
| 81 | */ | ||
| 82 | return !softirq_count(); | ||
| 98 | } | 83 | } |
| 99 | EXPORT_SYMBOL(irq_fpu_usable); | 84 | EXPORT_SYMBOL(irq_fpu_usable); |
| 100 | 85 | ||
| @@ -339,11 +339,11 @@ static bool stack_access_ok(struct unwind_state *state, unsigned long _addr, · 338 unmodified lines | |||
| 339 | struct stack_info *info = &state->stack_info; | 339 | struct stack_info *info = &state->stack_info; |
| 340 | void *addr = (void *)_addr; | 340 | void *addr = (void *)_addr; |
| 341 | 341 | ||
| 342 | if (!on_stack(info, addr, len) && | 342 | if (on_stack(info, addr, len)) |
| 343 | (get_stack_info(addr, state->task, info, &state->stack_mask))) | 343 | return true; |
| 344 | return false; | ||
| 345 | 344 | ||
| 346 | return true; | 345 | return !get_stack_info(addr, state->task, info, &state->stack_mask) && |
| 346 | on_stack(info, addr, len); | ||
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | static bool deref_stack_reg(struct unwind_state *state, unsigned long addr, | 349 | static bool deref_stack_reg(struct unwind_state *state, unsigned long addr, |
| @@ -887,6 +887,11 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 886 unmodified lines | |||
| 887 | union cpuid10_eax eax; | 887 | union cpuid10_eax eax; |
| 888 | union cpuid10_edx edx; | 888 | union cpuid10_edx edx; |
| 889 | 889 | ||
| 890 | if (!static_cpu_has(X86_FEATURE_ARCH_PERFMON)) { | ||
| 891 | entry->eax = entry->ebx = entry->ecx = entry->edx = 0; | ||
| 892 | break; | ||
| 893 | } | ||
| 894 | |||
| 890 | perf_get_x86_pmu_capability(&cap); | 895 | perf_get_x86_pmu_capability(&cap); |
| 891 | 896 | ||
| 892 | /* | 897 | /* |
| @@ -1085,12 +1090,21 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) · 192 unmodified lines | |||
| 1085 | case 0x80000000: | 1090 | case 0x80000000: |
| 1086 | entry->eax = min(entry->eax, 0x80000021); | 1091 | entry->eax = min(entry->eax, 0x80000021); |
| 1087 | /* | 1092 | /* |
| 1088 | * Serializing LFENCE is reported in a multitude of ways, | 1093 | * Serializing LFENCE is reported in a multitude of ways, and |
| 1089 | * and NullSegClearsBase is not reported in CPUID on Zen2; | 1094 | * NullSegClearsBase is not reported in CPUID on Zen2; help |
| 1090 | * help userspace by providing the CPUID leaf ourselves. | 1095 | * userspace by providing the CPUID leaf ourselves. |
| 1096 | * | ||
| 1097 | * However, only do it if the host has CPUID leaf 0x8000001d. | ||
| 1098 | * QEMU thinks that it can query the host blindly for that | ||
| 1099 | * CPUID leaf if KVM reports that it supports 0x8000001d or | ||
| 1100 | * above. The processor merrily returns values from the | ||
| 1101 | * highest Intel leaf which QEMU tries to use as the guest's | ||
| 1102 | * 0x8000001d. Even worse, this can result in an infinite | ||
| 1103 | * loop if said highest leaf has no subleaves indexed by ECX. | ||
| 1091 | */ | 1104 | */ |
| 1092 | if (static_cpu_has(X86_FEATURE_LFENCE_RDTSC) | 1105 | if (entry->eax >= 0x8000001d && |
| 1093 | || !static_cpu_has_bug(X86_BUG_NULL_SEG)) | 1106 | (static_cpu_has(X86_FEATURE_LFENCE_RDTSC) |
| 1107 | || !static_cpu_has_bug(X86_BUG_NULL_SEG))) | ||
| 1094 | entry->eax = max(entry->eax, 0x80000021); | 1108 | entry->eax = max(entry->eax, 0x80000021); |
| 1095 | break; | 1109 | break; |
| 1096 | case 0x80000001: | 1110 | case 0x80000001: |
| @@ -65,6 +65,30 @@ static __always_inline u64 rsvd_bits(int s, int e) · 64 unmodified lines | |||
| 65 | return ((2ULL << (e - s)) - 1) << s; | 65 | return ((2ULL << (e - s)) - 1) << s; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | /* | ||
| 69 | * The number of non-reserved physical address bits irrespective of features | ||
| 70 | * that repurpose legal bits, e.g. MKTME. | ||
| 71 | */ | ||
| 72 | extern u8 __read_mostly shadow_phys_bits; | ||
| 73 | |||
| 74 | static inline gfn_t kvm_mmu_max_gfn(void) | ||
| 75 | { | ||
| 76 | /* | ||
| 77 | * Note that this uses the host MAXPHYADDR, not the guest's. | ||
| 78 | * EPT/NPT cannot support GPAs that would exceed host.MAXPHYADDR; | ||
| 79 | * assuming KVM is running on bare metal, guest accesses beyond | ||
| 80 | * host.MAXPHYADDR will hit a #PF(RSVD) and never cause a vmexit | ||
| 81 | * (either EPT Violation/Misconfig or #NPF), and so KVM will never | ||
| 82 | * install a SPTE for such addresses. If KVM is running as a VM | ||
| 83 | * itself, on the other hand, it might see a MAXPHYADDR that is less | ||
| 84 | * than hardware's real MAXPHYADDR. Using the host MAXPHYADDR | ||
| 85 | * disallows such SPTEs entirely and simplifies the TDP MMU. | ||
| 86 | */ | ||
| 87 | int max_gpa_bits = likely(tdp_enabled) ? shadow_phys_bits : 52; | ||
| 88 | |||
| 89 | return (1ULL << (max_gpa_bits - PAGE_SHIFT)) - 1; | ||
| 90 | } | ||
| 91 | |||
| 68 | void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_mask); | 92 | void kvm_mmu_set_mmio_spte_mask(u64 mmio_value, u64 mmio_mask, u64 access_mask); |
| 69 | void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_exec_only); | 93 | void kvm_mmu_set_ept_masks(bool has_ad_bits, bool has_exec_only); |
| 70 | 94 | ||
| @@ -473,30 +473,6 @@ retry: · 472 unmodified lines | |||
| 473 | } | 473 | } |
| 474 | #endif | 474 | #endif |
| 475 | 475 | ||
| 476 | static bool spte_has_volatile_bits(u64 spte) | ||
| 477 | { | ||
| 478 | if (!is_shadow_present_pte(spte)) | ||
| 479 | return false; | ||
| 480 | |||
| 481 | /* | ||
| 482 | * Always atomically update spte if it can be updated | ||
| 483 | * out of mmu-lock, it can ensure dirty bit is not lost, | ||
| 484 | * also, it can help us to get a stable is_writable_pte() | ||
| 485 | * to ensure tlb flush is not missed. | ||
| 486 | */ | ||
| 487 | if (spte_can_locklessly_be_made_writable(spte) || | ||
| 488 | is_access_track_spte(spte)) | ||
| 489 | return true; | ||
| 490 | |||
| 491 | if (spte_ad_enabled(spte)) { | ||
| 492 | if ((spte & shadow_accessed_mask) == 0 || | ||
| 493 | (is_writable_pte(spte) && (spte & shadow_dirty_mask) == 0)) | ||
| 494 | return true; | ||
| 495 | } | ||
| 496 | |||
| 497 | return false; | ||
| 498 | } | ||
| 499 | |||
| 500 | /* Rules for using mmu_spte_set: | 476 | /* Rules for using mmu_spte_set: |
| 501 | * Set the sptep from nonpresent to present. | 477 | * Set the sptep from nonpresent to present. |
| 502 | * Note: the sptep being assigned *must* be either not present | 478 | * Note: the sptep being assigned *must* be either not present |
| @@ -557,7 +533,7 @@ static bool mmu_spte_update(u64 *sptep, u64 new_spte) · 54 unmodified lines | |||
| 557 | * we always atomically update it, see the comments in | 533 | * we always atomically update it, see the comments in |
| 558 | * spte_has_volatile_bits(). | 534 | * spte_has_volatile_bits(). |
| 559 | */ | 535 | */ |
| 560 | if (spte_can_locklessly_be_made_writable(old_spte) && | 536 | if (is_mmu_writable_spte(old_spte) && |
| 561 | !is_writable_pte(new_spte)) | 537 | !is_writable_pte(new_spte)) |
| 562 | flush = true; | 538 | flush = true; |
| 563 | 539 | ||
| @@ -591,7 +567,8 @@ static int mmu_spte_clear_track_bits(struct kvm *kvm, u64 *sptep) · 27 unmodified lines | |||
| 591 | u64 old_spte = *sptep; | 567 | u64 old_spte = *sptep; |
| 592 | int level = sptep_to_sp(sptep)->role.level; | 568 | int level = sptep_to_sp(sptep)->role.level; |
| 593 | 569 | ||
| 594 | if (!spte_has_volatile_bits(old_spte)) | 570 | if (!is_shadow_present_pte(old_spte) || |
| 571 | !spte_has_volatile_bits(old_spte)) | ||
| 595 | __update_clear_spte_fast(sptep, 0ull); | 572 | __update_clear_spte_fast(sptep, 0ull); |
| 596 | else | 573 | else |
| 597 | old_spte = __update_clear_spte_slow(sptep, 0ull); | 574 | old_spte = __update_clear_spte_slow(sptep, 0ull); |
| @@ -1187,7 +1164,7 @@ static bool spte_write_protect(u64 *sptep, bool pt_protect) · 589 unmodified lines | |||
| 1187 | u64 spte = *sptep; | 1164 | u64 spte = *sptep; |
| 1188 | 1165 | ||
| 1189 | if (!is_writable_pte(spte) && | 1166 | if (!is_writable_pte(spte) && |
| 1190 | !(pt_protect && spte_can_locklessly_be_made_writable(spte))) | 1167 | !(pt_protect && is_mmu_writable_spte(spte))) |
| 1191 | return false; | 1168 | return false; |
| 1192 | 1169 | ||
| 1193 | rmap_printk("spte %p %llx\n", sptep, *sptep); | 1170 | rmap_printk("spte %p %llx\n", sptep, *sptep); |
| @@ -2804,8 +2781,12 @@ static int host_pfn_mapping_level(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, · 1610 unmodified lines | |||
| 2804 | const struct kvm_memory_slot *slot) | 2781 | const struct kvm_memory_slot *slot) |
| 2805 | { | 2782 | { |
| 2806 | unsigned long hva; | 2783 | unsigned long hva; |
| 2807 | pte_t *pte; | 2784 | unsigned long flags; |
| 2808 | int level; | 2785 | int level = PG_LEVEL_4K; |
| 2786 | pgd_t pgd; | ||
| 2787 | p4d_t p4d; | ||
| 2788 | pud_t pud; | ||
| 2789 | pmd_t pmd; | ||
| 2809 | 2790 | ||
| 2810 | if (!PageCompound(pfn_to_page(pfn)) && !kvm_is_zone_device_pfn(pfn)) | 2791 | if (!PageCompound(pfn_to_page(pfn)) && !kvm_is_zone_device_pfn(pfn)) |
| 2811 | return PG_LEVEL_4K; | 2792 | return PG_LEVEL_4K; |
| @@ -2820,10 +2801,43 @@ static int host_pfn_mapping_level(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, · 8 unmodified lines | |||
| 2820 | */ | 2801 | */ |
| 2821 | hva = __gfn_to_hva_memslot(slot, gfn); | 2802 | hva = __gfn_to_hva_memslot(slot, gfn); |
| 2822 | 2803 | ||
| 2823 | pte = lookup_address_in_mm(kvm->mm, hva, &level); | 2804 | /* |
| 2824 | if (unlikely(!pte)) | 2805 | * Lookup the mapping level in the current mm. The information |
| 2825 | return PG_LEVEL_4K; | 2806 | * may become stale soon, but it is safe to use as long as |
| 2807 | * 1) mmu_notifier_retry was checked after taking mmu_lock, and | ||
| 2808 | * 2) mmu_lock is taken now. | ||
| 2809 | * | ||
| 2810 | * We still need to disable IRQs to prevent concurrent tear down | ||
| 2811 | * of page tables. | ||
| 2812 | */ | ||
| 2813 | local_irq_save(flags); | ||
| 2814 | |||
| 2815 | pgd = READ_ONCE(*pgd_offset(kvm->mm, hva)); | ||
| 2816 | if (pgd_none(pgd)) | ||
| 2817 | goto out; | ||
| 2818 | |||
| 2819 | p4d = READ_ONCE(*p4d_offset(&pgd, hva)); | ||
| 2820 | if (p4d_none(p4d) || !p4d_present(p4d)) | ||
| 2821 | goto out; | ||
| 2822 | |||
| 2823 | pud = READ_ONCE(*pud_offset(&p4d, hva)); | ||
| 2824 | if (pud_none(pud) || !pud_present(pud)) | ||
| 2825 | goto out; | ||
| 2826 | |||
| 2827 | if (pud_large(pud)) { | ||
| 2828 | level = PG_LEVEL_1G; | ||
| 2829 | goto out; | ||
| 2830 | } | ||
| 2826 | 2831 | ||
| 2832 | pmd = READ_ONCE(*pmd_offset(&pud, hva)); | ||
| 2833 | if (pmd_none(pmd) || !pmd_present(pmd)) | ||
| 2834 | goto out; | ||
| 2835 | |||
| 2836 | if (pmd_large(pmd)) | ||
| 2837 | level = PG_LEVEL_2M; | ||
| 2838 | |||
| 2839 | out: | ||
| 2840 | local_irq_restore(flags); | ||
| 2827 | return level; | 2841 | return level; |
| 2828 | } | 2842 | } |
| 2829 | 2843 | ||
| @@ -2992,9 +3006,15 @@ static bool handle_abnormal_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fa · 162 unmodified lines | |||
| 2992 | /* | 3006 | /* |
| 2993 | * If MMIO caching is disabled, emulate immediately without | 3007 | * If MMIO caching is disabled, emulate immediately without |
| 2994 | * touching the shadow page tables as attempting to install an | 3008 | * touching the shadow page tables as attempting to install an |
| 2995 | * MMIO SPTE will just be an expensive nop. | 3009 | * MMIO SPTE will just be an expensive nop. Do not cache MMIO |
| 3010 | * whose gfn is greater than host.MAXPHYADDR, any guest that | ||
| 3011 | * generates such gfns is running nested and is being tricked | ||
| 3012 | * by L0 userspace (you can observe gfn > L1.MAXPHYADDR if | ||
| 3013 | * and only if L1's MAXPHYADDR is inaccurate with respect to | ||
| 3014 | * the hardware's). | ||
| 2996 | */ | 3015 | */ |
| 2997 | if (unlikely(!shadow_mmio_value)) { | 3016 | if (unlikely(!shadow_mmio_value) || |
| 3017 | unlikely(fault->gfn > kvm_mmu_max_gfn())) { | ||
| 2998 | *ret_val = RET_PF_EMULATE; | 3018 | *ret_val = RET_PF_EMULATE; |
| 2999 | return true; | 3019 | return true; |
| 3000 | } | 3020 | } |
| @@ -3153,8 +3173,7 @@ static int fast_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) · 152 unmodified lines | |||
| 3153 | * be removed in the fast path only if the SPTE was | 3173 | * be removed in the fast path only if the SPTE was |
| 3154 | * write-protected for dirty-logging or access tracking. | 3174 | * write-protected for dirty-logging or access tracking. |
| 3155 | */ | 3175 | */ |
| 3156 | if (fault->write && | 3176 | if (fault->write && is_mmu_writable_spte(spte)) { |
| 3157 | spte_can_locklessly_be_made_writable(spte)) { | ||
| 3158 | new_spte |= PT_WRITABLE_MASK; | 3177 | new_spte |= PT_WRITABLE_MASK; |
| 3159 | 3178 | ||
| 3160 | /* | 3179 | /* |
| @@ -90,6 +90,34 @@ static bool kvm_is_mmio_pfn(kvm_pfn_t pfn) · 89 unmodified lines | |||
| 90 | E820_TYPE_RAM); | 90 | E820_TYPE_RAM); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | /* | ||
| 94 | * Returns true if the SPTE has bits that may be set without holding mmu_lock. | ||
| 95 | * The caller is responsible for checking if the SPTE is shadow-present, and | ||
| 96 | * for determining whether or not the caller cares about non-leaf SPTEs. | ||
| 97 | */ | ||
| 98 | bool spte_has_volatile_bits(u64 spte) | ||
| 99 | { | ||
| 100 | /* | ||
| 101 | * Always atomically update spte if it can be updated | ||
| 102 | * out of mmu-lock, it can ensure dirty bit is not lost, | ||
| 103 | * also, it can help us to get a stable is_writable_pte() | ||
| 104 | * to ensure tlb flush is not missed. | ||
| 105 | */ | ||
| 106 | if (!is_writable_pte(spte) && is_mmu_writable_spte(spte)) | ||
| 107 | return true; | ||
| 108 | |||
| 109 | if (is_access_track_spte(spte)) | ||
| 110 | return true; | ||
| 111 | |||
| 112 | if (spte_ad_enabled(spte)) { | ||
| 113 | if (!(spte & shadow_accessed_mask) || | ||
| 114 | (is_writable_pte(spte) && !(spte & shadow_dirty_mask))) | ||
| 115 | return true; | ||
| 116 | } | ||
| 117 | |||
| 118 | return false; | ||
| 119 | } | ||
| 120 | |||
| 93 | bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | 121 | bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, |
| 94 | const struct kvm_memory_slot *slot, | 122 | const struct kvm_memory_slot *slot, |
| 95 | unsigned int pte_access, gfn_t gfn, kvm_pfn_t pfn, | 123 | unsigned int pte_access, gfn_t gfn, kvm_pfn_t pfn, |
| @@ -201,12 +201,6 @@ static inline bool is_removed_spte(u64 spte) · 200 unmodified lines | |||
| 201 | */ | 201 | */ |
| 202 | extern u64 __read_mostly shadow_nonpresent_or_rsvd_lower_gfn_mask; | 202 | extern u64 __read_mostly shadow_nonpresent_or_rsvd_lower_gfn_mask; |
| 203 | 203 | ||
| 204 | /* | ||
| 205 | * The number of non-reserved physical address bits irrespective of features | ||
| 206 | * that repurpose legal bits, e.g. MKTME. | ||
| 207 | */ | ||
| 208 | extern u8 __read_mostly shadow_phys_bits; | ||
| 209 | |||
| 210 | static inline bool is_mmio_spte(u64 spte) | 204 | static inline bool is_mmio_spte(u64 spte) |
| 211 | { | 205 | { |
| 212 | return (spte & shadow_mmio_mask) == shadow_mmio_value && | 206 | return (spte & shadow_mmio_mask) == shadow_mmio_value && |
| @@ -396,7 +390,7 @@ static inline void check_spte_writable_invariants(u64 spte) · 183 unmodified lines | |||
| 396 | "kvm: Writable SPTE is not MMU-writable: %llx", spte); | 390 | "kvm: Writable SPTE is not MMU-writable: %llx", spte); |
| 397 | } | 391 | } |
| 398 | 392 | ||
| 399 | static inline bool spte_can_locklessly_be_made_writable(u64 spte) | 393 | static inline bool is_mmu_writable_spte(u64 spte) |
| 400 | { | 394 | { |
| 401 | return spte & shadow_mmu_writable_mask; | 395 | return spte & shadow_mmu_writable_mask; |
| 402 | } | 396 | } |
| @@ -410,6 +404,8 @@ static inline u64 get_mmio_spte_generation(u64 spte) · 7 unmodified lines | |||
| 410 | return gen; | 404 | return gen; |
| 411 | } | 405 | } |
| 412 | 406 | ||
| 407 | bool spte_has_volatile_bits(u64 spte); | ||
| 408 | |||
| 413 | bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, | 409 | bool make_spte(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp, |
| 414 | const struct kvm_memory_slot *slot, | 410 | const struct kvm_memory_slot *slot, |
| 415 | unsigned int pte_access, gfn_t gfn, kvm_pfn_t pfn, | 411 | unsigned int pte_access, gfn_t gfn, kvm_pfn_t pfn, |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/kvm_host.h> | 6 | #include <linux/kvm_host.h> |
| 7 | 7 | ||
| 8 | #include "mmu.h" | 8 | #include "mmu.h" |
| 9 | #include "spte.h" | ||
| 9 | 10 | ||
| 10 | /* | 11 | /* |
| 11 | * TDP MMU SPTEs are RCU protected to allow paging structures (non-leaf SPTEs) | 12 | * TDP MMU SPTEs are RCU protected to allow paging structures (non-leaf SPTEs) |
| @@ -17,9 +18,38 @@ static inline u64 kvm_tdp_mmu_read_spte(tdp_ptep_t sptep) · 5 unmodified lines | |||
| 17 | { | 18 | { |
| 18 | return READ_ONCE(*rcu_dereference(sptep)); | 19 | return READ_ONCE(*rcu_dereference(sptep)); |
| 19 | } | 20 | } |
| 20 | static inline void kvm_tdp_mmu_write_spte(tdp_ptep_t sptep, u64 val) | 21 | |
| 22 | static inline u64 kvm_tdp_mmu_write_spte_atomic(tdp_ptep_t sptep, u64 new_spte) | ||
| 23 | { | ||
| 24 | return xchg(rcu_dereference(sptep), new_spte); | ||
| 25 | } | ||
| 26 | |||
| 27 | static inline void __kvm_tdp_mmu_write_spte(tdp_ptep_t sptep, u64 new_spte) | ||
| 28 | { | ||
| 29 | WRITE_ONCE(*rcu_dereference(sptep), new_spte); | ||
| 30 | } | ||
| 31 | |||
| 32 | static inline u64 kvm_tdp_mmu_write_spte(tdp_ptep_t sptep, u64 old_spte, | ||
| 33 | u64 new_spte, int level) | ||
| 21 | { | 34 | { |
| 22 | WRITE_ONCE(*rcu_dereference(sptep), val); | 35 | /* |
| 36 | * Atomically write the SPTE if it is a shadow-present, leaf SPTE with | ||
| 37 | * volatile bits, i.e. has bits that can be set outside of mmu_lock. | ||
| 38 | * The Writable bit can be set by KVM's fast page fault handler, and | ||
| 39 | * Accessed and Dirty bits can be set by the CPU. | ||
| 40 | * | ||
| 41 | * Note, non-leaf SPTEs do have Accessed bits and those bits are | ||
| 42 | * technically volatile, but KVM doesn't consume the Accessed bit of | ||
| 43 | * non-leaf SPTEs, i.e. KVM doesn't care if it clobbers the bit. This | ||
| 44 | * logic needs to be reassessed if KVM were to use non-leaf Accessed | ||
| 45 | * bits, e.g. to skip stepping down into child SPTEs when aging SPTEs. | ||
| 46 | */ | ||
| 47 | if (is_shadow_present_pte(old_spte) && is_last_spte(old_spte, level) && | ||
| 48 | spte_has_volatile_bits(old_spte)) | ||
| 49 | return kvm_tdp_mmu_write_spte_atomic(sptep, new_spte); | ||
| 50 | |||
| 51 | __kvm_tdp_mmu_write_spte(sptep, new_spte); | ||
| 52 | return old_spte; | ||
| 23 | } | 53 | } |
| 24 | 54 | ||
| 25 | /* | 55 | /* |
| @@ -426,9 +426,9 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared) · 425 unmodified lines | |||
| 426 | tdp_mmu_unlink_sp(kvm, sp, shared); | 426 | tdp_mmu_unlink_sp(kvm, sp, shared); |
| 427 | 427 | ||
| 428 | for (i = 0; i < PT64_ENT_PER_PAGE; i++) { | 428 | for (i = 0; i < PT64_ENT_PER_PAGE; i++) { |
| 429 | u64 *sptep = rcu_dereference(pt) + i; | 429 | tdp_ptep_t sptep = pt + i; |
| 430 | gfn_t gfn = base_gfn + i * KVM_PAGES_PER_HPAGE(level); | 430 | gfn_t gfn = base_gfn + i * KVM_PAGES_PER_HPAGE(level); |
| 431 | u64 old_child_spte; | 431 | u64 old_spte; |
| 432 | 432 | ||
| 433 | if (shared) { | 433 | if (shared) { |
| 434 | /* | 434 | /* |
| @@ -440,8 +440,8 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared) · 5 unmodified lines | |||
| 440 | * value to the removed SPTE value. | 440 | * value to the removed SPTE value. |
| 441 | */ | 441 | */ |
| 442 | for (;;) { | 442 | for (;;) { |
| 443 | old_child_spte = xchg(sptep, REMOVED_SPTE); | 443 | old_spte = kvm_tdp_mmu_write_spte_atomic(sptep, REMOVED_SPTE); |
| 444 | if (!is_removed_spte(old_child_spte)) | 444 | if (!is_removed_spte(old_spte)) |
| 445 | break; | 445 | break; |
| 446 | cpu_relax(); | 446 | cpu_relax(); |
| 447 | } | 447 | } |
| @@ -455,23 +455,43 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared) · 7 unmodified lines | |||
| 455 | * are guarded by the memslots generation, not by being | 455 | * are guarded by the memslots generation, not by being |
| 456 | * unreachable. | 456 | * unreachable. |
| 457 | */ | 457 | */ |
| 458 | old_child_spte = READ_ONCE(*sptep); | 458 | old_spte = kvm_tdp_mmu_read_spte(sptep); |
| 459 | if (!is_shadow_present_pte(old_child_spte)) | 459 | if (!is_shadow_present_pte(old_spte)) |
| 460 | continue; | 460 | continue; |
| 461 | 461 | ||
| 462 | /* | 462 | /* |
| 463 | * Marking the SPTE as a removed SPTE is not | 463 | * Use the common helper instead of a raw WRITE_ONCE as |
| 464 | * strictly necessary here as the MMU lock will | 464 | * the SPTE needs to be updated atomically if it can be |
| 465 | * stop other threads from concurrently modifying | 465 | * modified by a different vCPU outside of mmu_lock. |
| 466 | * this SPTE. Using the removed SPTE value keeps | 466 | * Even though the parent SPTE is !PRESENT, the TLB |
| 467 | * the two branches consistent and simplifies | 467 | * hasn't yet been flushed, and both Intel and AMD |
| 468 | * the function. | 468 | * document that A/D assists can use upper-level PxE |
| 469 | * entries that are cached in the TLB, i.e. the CPU can | ||
| 470 | * still access the page and mark it dirty. | ||
| 471 | * | ||
| 472 | * No retry is needed in the atomic update path as the | ||
| 473 | * sole concern is dropping a Dirty bit, i.e. no other | ||
| 474 | * task can zap/remove the SPTE as mmu_lock is held for | ||
| 475 | * write. Marking the SPTE as a removed SPTE is not | ||
| 476 | * strictly necessary for the same reason, but using | ||
| 477 | * the remove SPTE value keeps the shared/exclusive | ||
| 478 | * paths consistent and allows the handle_changed_spte() | ||
| 479 | * call below to hardcode the new value to REMOVED_SPTE. | ||
| 480 | * | ||
| 481 | * Note, even though dropping a Dirty bit is the only | ||
| 482 | * scenario where a non-atomic update could result in a | ||
| 483 | * functional bug, simply checking the Dirty bit isn't | ||
| 484 | * sufficient as a fast page fault could read the upper | ||
| 485 | * level SPTE before it is zapped, and then make this | ||
| 486 | * target SPTE writable, resume the guest, and set the | ||
| 487 | * Dirty bit between reading the SPTE above and writing | ||
| 488 | * it here. | ||
| 469 | */ | 489 | */ |
| 470 | WRITE_ONCE(*sptep, REMOVED_SPTE); | 490 | old_spte = kvm_tdp_mmu_write_spte(sptep, old_spte, |
| 491 | REMOVED_SPTE, level); | ||
| 471 | } | 492 | } |
| 472 | handle_changed_spte(kvm, kvm_mmu_page_as_id(sp), gfn, | 493 | handle_changed_spte(kvm, kvm_mmu_page_as_id(sp), gfn, |
| 473 | old_child_spte, REMOVED_SPTE, level, | 494 | old_spte, REMOVED_SPTE, level, shared); |
| 474 | shared); | ||
| 475 | } | 495 | } |
| 476 | 496 | ||
| 477 | call_rcu(&sp->rcu_head, tdp_mmu_free_sp_rcu_callback); | 497 | call_rcu(&sp->rcu_head, tdp_mmu_free_sp_rcu_callback); |
| @@ -667,14 +687,13 @@ static inline int tdp_mmu_zap_spte_atomic(struct kvm *kvm, · 189 unmodified lines | |||
| 667 | KVM_PAGES_PER_HPAGE(iter->level)); | 687 | KVM_PAGES_PER_HPAGE(iter->level)); |
| 668 | 688 | ||
| 669 | /* | 689 | /* |
| 670 | * No other thread can overwrite the removed SPTE as they | 690 | * No other thread can overwrite the removed SPTE as they must either |
| 671 | * must either wait on the MMU lock or use | 691 | * wait on the MMU lock or use tdp_mmu_set_spte_atomic() which will not |
| 672 | * tdp_mmu_set_spte_atomic which will not overwrite the | 692 | * overwrite the special removed SPTE value. No bookkeeping is needed |
| 673 | * special removed SPTE value. No bookkeeping is needed | 693 | * here since the SPTE is going from non-present to non-present. Use |
| 674 | * here since the SPTE is going from non-present | 694 | * the raw write helper to avoid an unnecessary check on volatile bits. |
| 675 | * to non-present. | ||
| 676 | */ | 695 | */ |
| 677 | kvm_tdp_mmu_write_spte(iter->sptep, 0); | 696 | __kvm_tdp_mmu_write_spte(iter->sptep, 0); |
| 678 | 697 | ||
| 679 | return 0; | 698 | return 0; |
| 680 | } | 699 | } |
| @@ -699,10 +718,13 @@ static inline int tdp_mmu_zap_spte_atomic(struct kvm *kvm, · 18 unmodified lines | |||
| 699 | * unless performing certain dirty logging operations. | 718 | * unless performing certain dirty logging operations. |
| 700 | * Leaving record_dirty_log unset in that case prevents page | 719 | * Leaving record_dirty_log unset in that case prevents page |
| 701 | * writes from being double counted. | 720 | * writes from being double counted. |
| 721 | * | ||
| 722 | * Returns the old SPTE value, which _may_ be different than @old_spte if the | ||
| 723 | * SPTE had voldatile bits. | ||
| 702 | */ | 724 | */ |
| 703 | static void __tdp_mmu_set_spte(struct kvm *kvm, int as_id, tdp_ptep_t sptep, | 725 | static u64 __tdp_mmu_set_spte(struct kvm *kvm, int as_id, tdp_ptep_t sptep, |
| 704 | u64 old_spte, u64 new_spte, gfn_t gfn, int level, | 726 | u64 old_spte, u64 new_spte, gfn_t gfn, int level, |
| 705 | bool record_acc_track, bool record_dirty_log) | 727 | bool record_acc_track, bool record_dirty_log) |
| 706 | { | 728 | { |
| 707 | lockdep_assert_held_write(&kvm->mmu_lock); | 729 | lockdep_assert_held_write(&kvm->mmu_lock); |
| 708 | 730 | ||
| @@ -715,7 +737,7 @@ static void __tdp_mmu_set_spte(struct kvm *kvm, int as_id, tdp_ptep_t sptep, · 6 unmodified lines | |||
| 715 | */ | 737 | */ |
| 716 | WARN_ON(is_removed_spte(old_spte) || is_removed_spte(new_spte)); | 738 | WARN_ON(is_removed_spte(old_spte) || is_removed_spte(new_spte)); |
| 717 | 739 | ||
| 718 | kvm_tdp_mmu_write_spte(sptep, new_spte); | 740 | old_spte = kvm_tdp_mmu_write_spte(sptep, old_spte, new_spte, level); |
| 719 | 741 | ||
| 720 | __handle_changed_spte(kvm, as_id, gfn, old_spte, new_spte, level, false); | 742 | __handle_changed_spte(kvm, as_id, gfn, old_spte, new_spte, level, false); |
| 721 | 743 | ||
| @@ -724,6 +746,7 @@ static void __tdp_mmu_set_spte(struct kvm *kvm, int as_id, tdp_ptep_t sptep, · 2 unmodified lines | |||
| 724 | if (record_dirty_log) | 746 | if (record_dirty_log) |
| 725 | handle_changed_spte_dirty_log(kvm, as_id, gfn, old_spte, | 747 | handle_changed_spte_dirty_log(kvm, as_id, gfn, old_spte, |
| 726 | new_spte, level); | 748 | new_spte, level); |
| 749 | return old_spte; | ||
| 727 | } | 750 | } |
| 728 | 751 | ||
| 729 | static inline void _tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, | 752 | static inline void _tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, |
| @@ -732,9 +755,10 @@ static inline void _tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, · 2 unmodified lines | |||
| 732 | { | 755 | { |
| 733 | WARN_ON_ONCE(iter->yielded); | 756 | WARN_ON_ONCE(iter->yielded); |
| 734 | 757 | ||
| 735 | __tdp_mmu_set_spte(kvm, iter->as_id, iter->sptep, iter->old_spte, | 758 | iter->old_spte = __tdp_mmu_set_spte(kvm, iter->as_id, iter->sptep, |
| 736 | new_spte, iter->gfn, iter->level, | 759 | iter->old_spte, new_spte, |
| 737 | record_acc_track, record_dirty_log); | 760 | iter->gfn, iter->level, |
| 761 | record_acc_track, record_dirty_log); | ||
| 738 | } | 762 | } |
| 739 | 763 | ||
| 740 | static inline void tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, | 764 | static inline void tdp_mmu_set_spte(struct kvm *kvm, struct tdp_iter *iter, |
| @@ -815,14 +839,15 @@ static inline bool __must_check tdp_mmu_iter_cond_resched(struct kvm *kvm, · 74 unmodified lines | |||
| 815 | return iter->yielded; | 839 | return iter->yielded; |
| 816 | } | 840 | } |
| 817 | 841 | ||
| 818 | static inline gfn_t tdp_mmu_max_gfn_host(void) | 842 | static inline gfn_t tdp_mmu_max_gfn_exclusive(void) |
| 819 | { | 843 | { |
| 820 | /* | 844 | /* |
| 821 | * Bound TDP MMU walks at host.MAXPHYADDR, guest accesses beyond that | 845 | * Bound TDP MMU walks at host.MAXPHYADDR. KVM disallows memslots with |
| 822 | * will hit a #PF(RSVD) and never hit an EPT Violation/Misconfig / #NPF, | 846 | * a gpa range that would exceed the max gfn, and KVM does not create |
| 823 | * and so KVM will never install a SPTE for such addresses. | 847 | * MMIO SPTEs for "impossible" gfns, instead sending such accesses down |
| 848 | * the slow emulation path every time. | ||
| 824 | */ | 849 | */ |
| 825 | return 1ULL << (shadow_phys_bits - PAGE_SHIFT); | 850 | return kvm_mmu_max_gfn() + 1; |
| 826 | } | 851 | } |
| 827 | 852 | ||
| 828 | static void __tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root, | 853 | static void __tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root, |
| @@ -830,7 +855,7 @@ static void __tdp_mmu_zap_root(struct kvm *kvm, struct kvm_mmu_page *root, · 1 unmodified line | |||
| 830 | { | 855 | { |
| 831 | struct tdp_iter iter; | 856 | struct tdp_iter iter; |
| 832 | 857 | ||
| 833 | gfn_t end = tdp_mmu_max_gfn_host(); | 858 | gfn_t end = tdp_mmu_max_gfn_exclusive(); |
| 834 | gfn_t start = 0; | 859 | gfn_t start = 0; |
| 835 | 860 | ||
| 836 | for_each_tdp_pte_min_level(iter, root, zap_level, start, end) { | 861 | for_each_tdp_pte_min_level(iter, root, zap_level, start, end) { |
| @@ -923,7 +948,7 @@ static bool tdp_mmu_zap_leafs(struct kvm *kvm, struct kvm_mmu_page *root, · 86 unmodified lines | |||
| 923 | { | 948 | { |
| 924 | struct tdp_iter iter; | 949 | struct tdp_iter iter; |
| 925 | 950 | ||
| 926 | end = min(end, tdp_mmu_max_gfn_host()); | 951 | end = min(end, tdp_mmu_max_gfn_exclusive()); |
| 927 | 952 | ||
| 928 | lockdep_assert_held_write(&kvm->mmu_lock); | 953 | lockdep_assert_held_write(&kvm->mmu_lock); |
| 929 | 954 | ||
| @@ -45,6 +45,22 @@ static struct kvm_event_hw_type_mapping amd_event_mapping[] = { · 44 unmodified lines | |||
| 45 | [7] = { 0xd1, 0x00, PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, | 45 | [7] = { 0xd1, 0x00, PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | /* duplicated from amd_f17h_perfmon_event_map. */ | ||
| 49 | static struct kvm_event_hw_type_mapping amd_f17h_event_mapping[] = { | ||
| 50 | [0] = { 0x76, 0x00, PERF_COUNT_HW_CPU_CYCLES }, | ||
| 51 | [1] = { 0xc0, 0x00, PERF_COUNT_HW_INSTRUCTIONS }, | ||
| 52 | [2] = { 0x60, 0xff, PERF_COUNT_HW_CACHE_REFERENCES }, | ||
| 53 | [3] = { 0x64, 0x09, PERF_COUNT_HW_CACHE_MISSES }, | ||
| 54 | [4] = { 0xc2, 0x00, PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, | ||
| 55 | [5] = { 0xc3, 0x00, PERF_COUNT_HW_BRANCH_MISSES }, | ||
| 56 | [6] = { 0x87, 0x02, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, | ||
| 57 | [7] = { 0x87, 0x01, PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, | ||
| 58 | }; | ||
| 59 | |||
| 60 | /* amd_pmc_perf_hw_id depends on these being the same size */ | ||
| 61 | static_assert(ARRAY_SIZE(amd_event_mapping) == | ||
| 62 | ARRAY_SIZE(amd_f17h_event_mapping)); | ||
| 63 | |||
| 48 | static unsigned int get_msr_base(struct kvm_pmu *pmu, enum pmu_type type) | 64 | static unsigned int get_msr_base(struct kvm_pmu *pmu, enum pmu_type type) |
| 49 | { | 65 | { |
| 50 | struct kvm_vcpu *vcpu = pmu_to_vcpu(pmu); | 66 | struct kvm_vcpu *vcpu = pmu_to_vcpu(pmu); |
| @@ -140,6 +156,7 @@ static inline struct kvm_pmc *get_gp_pmc_amd(struct kvm_pmu *pmu, u32 msr, · 89 unmodified lines | |||
| 140 | 156 | ||
| 141 | static unsigned int amd_pmc_perf_hw_id(struct kvm_pmc *pmc) | 157 | static unsigned int amd_pmc_perf_hw_id(struct kvm_pmc *pmc) |
| 142 | { | 158 | { |
| 159 | struct kvm_event_hw_type_mapping *event_mapping; | ||
| 143 | u8 event_select = pmc->eventsel & ARCH_PERFMON_EVENTSEL_EVENT; | 160 | u8 event_select = pmc->eventsel & ARCH_PERFMON_EVENTSEL_EVENT; |
| 144 | u8 unit_mask = (pmc->eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; | 161 | u8 unit_mask = (pmc->eventsel & ARCH_PERFMON_EVENTSEL_UMASK) >> 8; |
| 145 | int i; | 162 | int i; |
| @@ -148,15 +165,20 @@ static unsigned int amd_pmc_perf_hw_id(struct kvm_pmc *pmc) · 2 unmodified lines | |||
| 148 | if (WARN_ON(pmc_is_fixed(pmc))) | 165 | if (WARN_ON(pmc_is_fixed(pmc))) |
| 149 | return PERF_COUNT_HW_MAX; | 166 | return PERF_COUNT_HW_MAX; |
| 150 | 167 | ||
| 168 | if (guest_cpuid_family(pmc->vcpu) >= 0x17) | ||
| 169 | event_mapping = amd_f17h_event_mapping; | ||
| 170 | else | ||
| 171 | event_mapping = amd_event_mapping; | ||
| 172 | |||
| 151 | for (i = 0; i < ARRAY_SIZE(amd_event_mapping); i++) | 173 | for (i = 0; i < ARRAY_SIZE(amd_event_mapping); i++) |
| 152 | if (amd_event_mapping[i].eventsel == event_select | 174 | if (event_mapping[i].eventsel == event_select |
| 153 | && amd_event_mapping[i].unit_mask == unit_mask) | 175 | && event_mapping[i].unit_mask == unit_mask) |
| 154 | break; | 176 | break; |
| 155 | 177 | ||
| 156 | if (i == ARRAY_SIZE(amd_event_mapping)) | 178 | if (i == ARRAY_SIZE(amd_event_mapping)) |
| 157 | return PERF_COUNT_HW_MAX; | 179 | return PERF_COUNT_HW_MAX; |
| 158 | 180 | ||
| 159 | return amd_event_mapping[i].event_type; | 181 | return event_mapping[i].event_type; |
| 160 | } | 182 | } |
| 161 | 183 | ||
| 162 | /* check if a PMC is enabled by comparing it against global_ctrl bits. Because | 184 | /* check if a PMC is enabled by comparing it against global_ctrl bits. Because |
| @@ -1594,24 +1594,51 @@ static void sev_unlock_two_vms(struct kvm *dst_kvm, struct kvm *src_kvm) · 1593 unmodified lines | |||
| 1594 | atomic_set_release(&src_sev->migration_in_progress, 0); | 1594 | atomic_set_release(&src_sev->migration_in_progress, 0); |
| 1595 | } | 1595 | } |
| 1596 | 1596 | ||
| 1597 | /* vCPU mutex subclasses. */ | ||
| 1598 | enum sev_migration_role { | ||
| 1599 | SEV_MIGRATION_SOURCE = 0, | ||
| 1600 | SEV_MIGRATION_TARGET, | ||
| 1601 | SEV_NR_MIGRATION_ROLES, | ||
| 1602 | }; | ||
| 1597 | 1603 | ||
| 1598 | static int sev_lock_vcpus_for_migration(struct kvm *kvm) | 1604 | static int sev_lock_vcpus_for_migration(struct kvm *kvm, |
| 1605 | enum sev_migration_role role) | ||
| 1599 | { | 1606 | { |
| 1600 | struct kvm_vcpu *vcpu; | 1607 | struct kvm_vcpu *vcpu; |
| 1601 | unsigned long i, j; | 1608 | unsigned long i, j; |
| 1609 | bool first = true; | ||
| 1602 | 1610 | ||
| 1603 | kvm_for_each_vcpu(i, vcpu, kvm) { | 1611 | kvm_for_each_vcpu(i, vcpu, kvm) { |
| 1604 | if (mutex_lock_killable(&vcpu->mutex)) | 1612 | if (mutex_lock_killable_nested(&vcpu->mutex, role)) |
| 1605 | goto out_unlock; | 1613 | goto out_unlock; |
| 1614 | |||
| 1615 | if (first) { | ||
| 1616 | /* | ||
| 1617 | * Reset the role to one that avoids colliding with | ||
| 1618 | * the role used for the first vcpu mutex. | ||
| 1619 | */ | ||
| 1620 | role = SEV_NR_MIGRATION_ROLES; | ||
| 1621 | first = false; | ||
| 1622 | } else { | ||
| 1623 | mutex_release(&vcpu->mutex.dep_map, _THIS_IP_); | ||
| 1624 | } | ||
| 1606 | } | 1625 | } |
| 1607 | 1626 | ||
| 1608 | return 0; | 1627 | return 0; |
| 1609 | 1628 | ||
| 1610 | out_unlock: | 1629 | out_unlock: |
| 1630 | |||
| 1631 | first = true; | ||
| 1611 | kvm_for_each_vcpu(j, vcpu, kvm) { | 1632 | kvm_for_each_vcpu(j, vcpu, kvm) { |
| 1612 | if (i == j) | 1633 | if (i == j) |
| 1613 | break; | 1634 | break; |
| 1614 | 1635 | ||
| 1636 | if (first) | ||
| 1637 | first = false; | ||
| 1638 | else | ||
| 1639 | mutex_acquire(&vcpu->mutex.dep_map, role, 0, _THIS_IP_); | ||
| 1640 | |||
| 1641 | |||
| 1615 | mutex_unlock(&vcpu->mutex); | 1642 | mutex_unlock(&vcpu->mutex); |
| 1616 | } | 1643 | } |
| 1617 | return -EINTR; | 1644 | return -EINTR; |
| @@ -1621,8 +1648,15 @@ static void sev_unlock_vcpus_for_migration(struct kvm *kvm) · 3 unmodified lines | |||
| 1621 | { | 1648 | { |
| 1622 | struct kvm_vcpu *vcpu; | 1649 | struct kvm_vcpu *vcpu; |
| 1623 | unsigned long i; | 1650 | unsigned long i; |
| 1651 | bool first = true; | ||
| 1624 | 1652 | ||
| 1625 | kvm_for_each_vcpu(i, vcpu, kvm) { | 1653 | kvm_for_each_vcpu(i, vcpu, kvm) { |
| 1654 | if (first) | ||
| 1655 | first = false; | ||
| 1656 | else | ||
| 1657 | mutex_acquire(&vcpu->mutex.dep_map, | ||
| 1658 | SEV_NR_MIGRATION_ROLES, 0, _THIS_IP_); | ||
| 1659 | |||
| 1626 | mutex_unlock(&vcpu->mutex); | 1660 | mutex_unlock(&vcpu->mutex); |
| 1627 | } | 1661 | } |
| 1628 | } | 1662 | } |
| @@ -1748,10 +1782,10 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd) · 119 unmodified lines | |||
| 1748 | charged = true; | 1782 | charged = true; |
| 1749 | } | 1783 | } |
| 1750 | 1784 | ||
| 1751 | ret = sev_lock_vcpus_for_migration(kvm); | 1785 | ret = sev_lock_vcpus_for_migration(kvm, SEV_MIGRATION_SOURCE); |
| 1752 | if (ret) | 1786 | if (ret) |
| 1753 | goto out_dst_cgroup; | 1787 | goto out_dst_cgroup; |
| 1754 | ret = sev_lock_vcpus_for_migration(source_kvm); | 1788 | ret = sev_lock_vcpus_for_migration(source_kvm, SEV_MIGRATION_TARGET); |
| 1755 | if (ret) | 1789 | if (ret) |
| 1756 | goto out_dst_vcpu; | 1790 | goto out_dst_vcpu; |
| 1757 | 1791 | ||
| @@ -5472,7 +5472,7 @@ static bool vmx_emulation_required_with_pending_exception(struct kvm_vcpu *vcpu) · 5471 unmodified lines | |||
| 5472 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 5472 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 5473 | 5473 | ||
| 5474 | return vmx->emulation_required && !vmx->rmode.vm86_active && | 5474 | return vmx->emulation_required && !vmx->rmode.vm86_active && |
| 5475 | vcpu->arch.exception.pending; | 5475 | (vcpu->arch.exception.pending || vcpu->arch.exception.injected); |
| 5476 | } | 5476 | } |
| 5477 | 5477 | ||
| 5478 | static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) | 5478 | static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) |
| @@ -10020,12 +10020,14 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 10019 unmodified lines | |||
| 10020 | if (kvm_check_request(KVM_REQ_HV_CRASH, vcpu)) { | 10020 | if (kvm_check_request(KVM_REQ_HV_CRASH, vcpu)) { |
| 10021 | vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; | 10021 | vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; |
| 10022 | vcpu->run->system_event.type = KVM_SYSTEM_EVENT_CRASH; | 10022 | vcpu->run->system_event.type = KVM_SYSTEM_EVENT_CRASH; |
| 10023 | vcpu->run->system_event.ndata = 0; | ||
| 10023 | r = 0; | 10024 | r = 0; |
| 10024 | goto out; | 10025 | goto out; |
| 10025 | } | 10026 | } |
| 10026 | if (kvm_check_request(KVM_REQ_HV_RESET, vcpu)) { | 10027 | if (kvm_check_request(KVM_REQ_HV_RESET, vcpu)) { |
| 10027 | vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; | 10028 | vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT; |
| 10028 | vcpu->run->system_event.type = KVM_SYSTEM_EVENT_RESET; | 10029 | vcpu->run->system_event.type = KVM_SYSTEM_EVENT_RESET; |
| 10030 | vcpu->run->system_event.ndata = 0; | ||
| 10029 | r = 0; | 10031 | r = 0; |
| 10030 | goto out; | 10032 | goto out; |
| 10031 | } | 10033 | } |
| @@ -12009,8 +12011,12 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, · 1977 unmodified lines | |||
| 12009 | struct kvm_memory_slot *new, | 12011 | struct kvm_memory_slot *new, |
| 12010 | enum kvm_mr_change change) | 12012 | enum kvm_mr_change change) |
| 12011 | { | 12013 | { |
| 12012 | if (change == KVM_MR_CREATE || change == KVM_MR_MOVE) | 12014 | if (change == KVM_MR_CREATE || change == KVM_MR_MOVE) { |
| 12015 | if ((new->base_gfn + new->npages - 1) > kvm_mmu_max_gfn()) | ||
| 12016 | return -EINVAL; | ||
| 12017 | |||
| 12013 | return kvm_alloc_memslot_metadata(kvm, new); | 12018 | return kvm_alloc_memslot_metadata(kvm, new); |
| 12019 | } | ||
| 12014 | 12020 | ||
| 12015 | if (change == KVM_MR_FLAGS_ONLY) | 12021 | if (change == KVM_MR_FLAGS_ONLY) |
| 12016 | memcpy(&new->arch, &old->arch, sizeof(old->arch)); | 12022 | memcpy(&new->arch, &old->arch, sizeof(old->arch)); |
| @@ -53,12 +53,12 @@ · 52 unmodified lines | |||
| 53 | SYM_FUNC_START(copy_user_generic_unrolled) | 53 | SYM_FUNC_START(copy_user_generic_unrolled) |
| 54 | ASM_STAC | 54 | ASM_STAC |
| 55 | cmpl $8,%edx | 55 | cmpl $8,%edx |
| 56 | jb 20f /* less then 8 bytes, go to byte copy loop */ | 56 | jb .Lcopy_user_short_string_bytes |
| 57 | ALIGN_DESTINATION | 57 | ALIGN_DESTINATION |
| 58 | movl %edx,%ecx | 58 | movl %edx,%ecx |
| 59 | andl $63,%edx | 59 | andl $63,%edx |
| 60 | shrl $6,%ecx | 60 | shrl $6,%ecx |
| 61 | jz .L_copy_short_string | 61 | jz copy_user_short_string |
| 62 | 1: movq (%rsi),%r8 | 62 | 1: movq (%rsi),%r8 |
| 63 | 2: movq 1*8(%rsi),%r9 | 63 | 2: movq 1*8(%rsi),%r9 |
| 64 | 3: movq 2*8(%rsi),%r10 | 64 | 3: movq 2*8(%rsi),%r10 |
| @@ -79,37 +79,11 @@ SYM_FUNC_START(copy_user_generic_unrolled) · 14 unmodified lines | |||
| 79 | leaq 64(%rdi),%rdi | 79 | leaq 64(%rdi),%rdi |
| 80 | decl %ecx | 80 | decl %ecx |
| 81 | jnz 1b | 81 | jnz 1b |
| 82 | .L_copy_short_string: | 82 | jmp copy_user_short_string |
| 83 | movl %edx,%ecx | ||
| 84 | andl $7,%edx | ||
| 85 | shrl $3,%ecx | ||
| 86 | jz 20f | ||
| 87 | 18: movq (%rsi),%r8 | ||
| 88 | 19: movq %r8,(%rdi) | ||
| 89 | leaq 8(%rsi),%rsi | ||
| 90 | leaq 8(%rdi),%rdi | ||
| 91 | decl %ecx | ||
| 92 | jnz 18b | ||
| 93 | 20: andl %edx,%edx | ||
| 94 | jz 23f | ||
| 95 | movl %edx,%ecx | ||
| 96 | 21: movb (%rsi),%al | ||
| 97 | 22: movb %al,(%rdi) | ||
| 98 | incq %rsi | ||
| 99 | incq %rdi | ||
| 100 | decl %ecx | ||
| 101 | jnz 21b | ||
| 102 | 23: xor %eax,%eax | ||
| 103 | ASM_CLAC | ||
| 104 | RET | ||
| 105 | 83 | ||
| 106 | 30: shll $6,%ecx | 84 | 30: shll $6,%ecx |
| 107 | addl %ecx,%edx | 85 | addl %ecx,%edx |
| 108 | jmp 60f | 86 | jmp .Lcopy_user_handle_tail |
| 109 | 40: leal (%rdx,%rcx,8),%edx | ||
| 110 | jmp 60f | ||
| 111 | 50: movl %ecx,%edx | ||
| 112 | 60: jmp .Lcopy_user_handle_tail /* ecx is zerorest also */ | ||
| 113 | 87 | ||
| 114 | _ASM_EXTABLE_CPY(1b, 30b) | 88 | _ASM_EXTABLE_CPY(1b, 30b) |
| 115 | _ASM_EXTABLE_CPY(2b, 30b) | 89 | _ASM_EXTABLE_CPY(2b, 30b) |
| @@ -127,10 +101,6 @@ SYM_FUNC_START(copy_user_generic_unrolled) · 11 unmodified lines | |||
| 127 | _ASM_EXTABLE_CPY(14b, 30b) | 101 | _ASM_EXTABLE_CPY(14b, 30b) |
| 128 | _ASM_EXTABLE_CPY(15b, 30b) | 102 | _ASM_EXTABLE_CPY(15b, 30b) |
| 129 | _ASM_EXTABLE_CPY(16b, 30b) | 103 | _ASM_EXTABLE_CPY(16b, 30b) |
| 130 | _ASM_EXTABLE_CPY(18b, 40b) | ||
| 131 | _ASM_EXTABLE_CPY(19b, 40b) | ||
| 132 | _ASM_EXTABLE_CPY(21b, 50b) | ||
| 133 | _ASM_EXTABLE_CPY(22b, 50b) | ||
| 134 | SYM_FUNC_END(copy_user_generic_unrolled) | 104 | SYM_FUNC_END(copy_user_generic_unrolled) |
| 135 | EXPORT_SYMBOL(copy_user_generic_unrolled) | 105 | EXPORT_SYMBOL(copy_user_generic_unrolled) |
| 136 | 106 | ||
| @@ -191,7 +161,7 @@ EXPORT_SYMBOL(copy_user_generic_string) · 54 unmodified lines | |||
| 191 | SYM_FUNC_START(copy_user_enhanced_fast_string) | 161 | SYM_FUNC_START(copy_user_enhanced_fast_string) |
| 192 | ASM_STAC | 162 | ASM_STAC |
| 193 | /* CPUs without FSRM should avoid rep movsb for short copies */ | 163 | /* CPUs without FSRM should avoid rep movsb for short copies */ |
| 194 | ALTERNATIVE "cmpl $64, %edx; jb .L_copy_short_string", "", X86_FEATURE_FSRM | 164 | ALTERNATIVE "cmpl $64, %edx; jb copy_user_short_string", "", X86_FEATURE_FSRM |
| 195 | movl %edx,%ecx | 165 | movl %edx,%ecx |
| 196 | 1: rep movsb | 166 | 1: rep movsb |
| 197 | xorl %eax,%eax | 167 | xorl %eax,%eax |
| @@ -243,6 +213,53 @@ SYM_CODE_START_LOCAL(.Lcopy_user_handle_tail) · 45 unmodified lines | |||
| 243 | 213 | ||
| 244 | SYM_CODE_END(.Lcopy_user_handle_tail) | 214 | SYM_CODE_END(.Lcopy_user_handle_tail) |
| 245 | 215 | ||
| 216 | /* | ||
| 217 | * Finish memcpy of less than 64 bytes. #AC should already be set. | ||
| 218 | * | ||
| 219 | * Input: | ||
| 220 | * rdi destination | ||
| 221 | * rsi source | ||
| 222 | * rdx count (< 64) | ||
| 223 | * | ||
| 224 | * Output: | ||
| 225 | * eax uncopied bytes or 0 if successful. | ||
| 226 | */ | ||
| 227 | SYM_CODE_START_LOCAL(copy_user_short_string) | ||
| 228 | movl %edx,%ecx | ||
| 229 | andl $7,%edx | ||
| 230 | shrl $3,%ecx | ||
| 231 | jz .Lcopy_user_short_string_bytes | ||
| 232 | 18: movq (%rsi),%r8 | ||
| 233 | 19: movq %r8,(%rdi) | ||
| 234 | leaq 8(%rsi),%rsi | ||
| 235 | leaq 8(%rdi),%rdi | ||
| 236 | decl %ecx | ||
| 237 | jnz 18b | ||
| 238 | .Lcopy_user_short_string_bytes: | ||
| 239 | andl %edx,%edx | ||
| 240 | jz 23f | ||
| 241 | movl %edx,%ecx | ||
| 242 | 21: movb (%rsi),%al | ||
| 243 | 22: movb %al,(%rdi) | ||
| 244 | incq %rsi | ||
| 245 | incq %rdi | ||
| 246 | decl %ecx | ||
| 247 | jnz 21b | ||
| 248 | 23: xor %eax,%eax | ||
| 249 | ASM_CLAC | ||
| 250 | RET | ||
| 251 | |||
| 252 | 40: leal (%rdx,%rcx,8),%edx | ||
| 253 | jmp 60f | ||
| 254 | 50: movl %ecx,%edx /* ecx is zerorest also */ | ||
| 255 | 60: jmp .Lcopy_user_handle_tail | ||
| 256 | |||
| 257 | _ASM_EXTABLE_CPY(18b, 40b) | ||
| 258 | _ASM_EXTABLE_CPY(19b, 40b) | ||
| 259 | _ASM_EXTABLE_CPY(21b, 50b) | ||
| 260 | _ASM_EXTABLE_CPY(22b, 50b) | ||
| 261 | SYM_CODE_END(copy_user_short_string) | ||
| 262 | |||
| 246 | /* | 263 | /* |
| 247 | * copy_user_nocache - Uncached memory copy with exception handling | 264 | * copy_user_nocache - Uncached memory copy with exception handling |
| 248 | * This will force destination out of cache for more performance. | 265 | * This will force destination out of cache for more performance. |
| @@ -48,6 +48,7 @@ SYM_FUNC_START(__put_user_1) · 47 unmodified lines | |||
| 48 | cmp %_ASM_BX,%_ASM_CX | 48 | cmp %_ASM_BX,%_ASM_CX |
| 49 | jae .Lbad_put_user | 49 | jae .Lbad_put_user |
| 50 | SYM_INNER_LABEL(__put_user_nocheck_1, SYM_L_GLOBAL) | 50 | SYM_INNER_LABEL(__put_user_nocheck_1, SYM_L_GLOBAL) |
| 51 | ENDBR | ||
| 51 | ASM_STAC | 52 | ASM_STAC |
| 52 | 1: movb %al,(%_ASM_CX) | 53 | 1: movb %al,(%_ASM_CX) |
| 53 | xor %ecx,%ecx | 54 | xor %ecx,%ecx |
| @@ -62,6 +63,7 @@ SYM_FUNC_START(__put_user_2) · 8 unmodified lines | |||
| 62 | cmp %_ASM_BX,%_ASM_CX | 63 | cmp %_ASM_BX,%_ASM_CX |
| 63 | jae .Lbad_put_user | 64 | jae .Lbad_put_user |
| 64 | SYM_INNER_LABEL(__put_user_nocheck_2, SYM_L_GLOBAL) | 65 | SYM_INNER_LABEL(__put_user_nocheck_2, SYM_L_GLOBAL) |
| 66 | ENDBR | ||
| 65 | ASM_STAC | 67 | ASM_STAC |
| 66 | 2: movw %ax,(%_ASM_CX) | 68 | 2: movw %ax,(%_ASM_CX) |
| 67 | xor %ecx,%ecx | 69 | xor %ecx,%ecx |
| @@ -76,6 +78,7 @@ SYM_FUNC_START(__put_user_4) · 8 unmodified lines | |||
| 76 | cmp %_ASM_BX,%_ASM_CX | 78 | cmp %_ASM_BX,%_ASM_CX |
| 77 | jae .Lbad_put_user | 79 | jae .Lbad_put_user |
| 78 | SYM_INNER_LABEL(__put_user_nocheck_4, SYM_L_GLOBAL) | 80 | SYM_INNER_LABEL(__put_user_nocheck_4, SYM_L_GLOBAL) |
| 81 | ENDBR | ||
| 79 | ASM_STAC | 82 | ASM_STAC |
| 80 | 3: movl %eax,(%_ASM_CX) | 83 | 3: movl %eax,(%_ASM_CX) |
| 81 | xor %ecx,%ecx | 84 | xor %ecx,%ecx |
| @@ -90,6 +93,7 @@ SYM_FUNC_START(__put_user_8) · 8 unmodified lines | |||
| 90 | cmp %_ASM_BX,%_ASM_CX | 93 | cmp %_ASM_BX,%_ASM_CX |
| 91 | jae .Lbad_put_user | 94 | jae .Lbad_put_user |
| 92 | SYM_INNER_LABEL(__put_user_nocheck_8, SYM_L_GLOBAL) | 95 | SYM_INNER_LABEL(__put_user_nocheck_8, SYM_L_GLOBAL) |
| 96 | ENDBR | ||
| 93 | ASM_STAC | 97 | ASM_STAC |
| 94 | 4: mov %_ASM_AX,(%_ASM_CX) | 98 | 4: mov %_ASM_AX,(%_ASM_CX) |
| 95 | #ifdef CONFIG_X86_32 | 99 | #ifdef CONFIG_X86_32 |
| @@ -31,6 +31,7 @@ · 30 unmodified lines | |||
| 31 | .align RETPOLINE_THUNK_SIZE | 31 | .align RETPOLINE_THUNK_SIZE |
| 32 | SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL) | 32 | SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL) |
| 33 | UNWIND_HINT_EMPTY | 33 | UNWIND_HINT_EMPTY |
| 34 | ANNOTATE_NOENDBR | ||
| 34 | 35 | ||
| 35 | ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \ | 36 | ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \ |
| 36 | __stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \ | 37 | __stringify(RETPOLINE \reg), X86_FEATURE_RETPOLINE, \ |
| @@ -55,7 +56,6 @@ SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL) · 18 unmodified lines | |||
| 55 | 56 | ||
| 56 | .align RETPOLINE_THUNK_SIZE | 57 | .align RETPOLINE_THUNK_SIZE |
| 57 | SYM_CODE_START(__x86_indirect_thunk_array) | 58 | SYM_CODE_START(__x86_indirect_thunk_array) |
| 58 | ANNOTATE_NOENDBR // apply_retpolines | ||
| 59 | 59 | ||
| 60 | #define GEN(reg) THUNK reg | 60 | #define GEN(reg) THUNK reg |
| 61 | #include <asm/GEN-for-each-reg.h> | 61 | #include <asm/GEN-for-each-reg.h> |
| @@ -902,6 +902,8 @@ static void __meminit vmemmap_use_sub_pmd(unsigned long start, unsigned long end · 901 unmodified lines | |||
| 902 | 902 | ||
| 903 | static void __meminit vmemmap_use_new_sub_pmd(unsigned long start, unsigned long end) | 903 | static void __meminit vmemmap_use_new_sub_pmd(unsigned long start, unsigned long end) |
| 904 | { | 904 | { |
| 905 | const unsigned long page = ALIGN_DOWN(start, PMD_SIZE); | ||
| 906 | |||
| 905 | vmemmap_flush_unused_pmd(); | 907 | vmemmap_flush_unused_pmd(); |
| 906 | 908 | ||
| 907 | /* | 909 | /* |
| @@ -914,8 +916,7 @@ static void __meminit vmemmap_use_new_sub_pmd(unsigned long start, unsigned long · 6 unmodified lines | |||
| 914 | * Mark with PAGE_UNUSED the unused parts of the new memmap range | 916 | * Mark with PAGE_UNUSED the unused parts of the new memmap range |
| 915 | */ | 917 | */ |
| 916 | if (!IS_ALIGNED(start, PMD_SIZE)) | 918 | if (!IS_ALIGNED(start, PMD_SIZE)) |
| 917 | memset((void *)start, PAGE_UNUSED, | 919 | memset((void *)page, PAGE_UNUSED, start - page); |
| 918 | start - ALIGN_DOWN(start, PMD_SIZE)); | ||
| 919 | 920 | ||
| 920 | /* | 921 | /* |
| 921 | * We want to avoid memset(PAGE_UNUSED) when populating the vmemmap of | 922 | * We want to avoid memset(PAGE_UNUSED) when populating the vmemmap of |
| @@ -638,17 +638,6 @@ pte_t *lookup_address(unsigned long address, unsigned int *level) · 637 unmodified lines | |||
| 638 | } | 638 | } |
| 639 | EXPORT_SYMBOL_GPL(lookup_address); | 639 | EXPORT_SYMBOL_GPL(lookup_address); |
| 640 | 640 | ||
| 641 | /* | ||
| 642 | * Lookup the page table entry for a virtual address in a given mm. Return a | ||
| 643 | * pointer to the entry and the level of the mapping. | ||
| 644 | */ | ||
| 645 | pte_t *lookup_address_in_mm(struct mm_struct *mm, unsigned long address, | ||
| 646 | unsigned int *level) | ||
| 647 | { | ||
| 648 | return lookup_address_in_pgd(pgd_offset(mm, address), address, level); | ||
| 649 | } | ||
| 650 | EXPORT_SYMBOL_GPL(lookup_address_in_mm); | ||
| 651 | |||
| 652 | static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address, | 641 | static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address, |
| 653 | unsigned int *level) | 642 | unsigned int *level) |
| 654 | { | 643 | { |
| @@ -467,7 +467,6 @@ static __init void xen_setup_pci_msi(void) · 466 unmodified lines | |||
| 467 | else | 467 | else |
| 468 | xen_msi_ops.setup_msi_irqs = xen_setup_msi_irqs; | 468 | xen_msi_ops.setup_msi_irqs = xen_setup_msi_irqs; |
| 469 | xen_msi_ops.teardown_msi_irqs = xen_pv_teardown_msi_irqs; | 469 | xen_msi_ops.teardown_msi_irqs = xen_pv_teardown_msi_irqs; |
| 470 | pci_msi_ignore_mask = 1; | ||
| 471 | } else if (xen_hvm_domain()) { | 470 | } else if (xen_hvm_domain()) { |
| 472 | xen_msi_ops.setup_msi_irqs = xen_hvm_setup_msi_irqs; | 471 | xen_msi_ops.setup_msi_irqs = xen_hvm_setup_msi_irqs; |
| 473 | xen_msi_ops.teardown_msi_irqs = xen_teardown_msi_irqs; | 472 | xen_msi_ops.teardown_msi_irqs = xen_teardown_msi_irqs; |
| @@ -481,6 +480,11 @@ static __init void xen_setup_pci_msi(void) · 7 unmodified lines | |||
| 481 | * in allocating the native domain and never use it. | 480 | * in allocating the native domain and never use it. |
| 482 | */ | 481 | */ |
| 483 | x86_init.irqs.create_pci_msi_domain = xen_create_pci_msi_domain; | 482 | x86_init.irqs.create_pci_msi_domain = xen_create_pci_msi_domain; |
| 483 | /* | ||
| 484 | * With XEN PIRQ/Eventchannels in use PCI/MSI[-X] masking is solely | ||
| 485 | * controlled by the hypervisor. | ||
| 486 | */ | ||
| 487 | pci_msi_ignore_mask = 1; | ||
| 484 | } | 488 | } |
| 485 | 489 | ||
| 486 | #else /* CONFIG_PCI_MSI */ | 490 | #else /* CONFIG_PCI_MSI */ |
| @@ -50,6 +50,7 @@ · 49 unmodified lines | |||
| 50 | #define PVH_DS_SEL (PVH_GDT_ENTRY_DS * 8) | 50 | #define PVH_DS_SEL (PVH_GDT_ENTRY_DS * 8) |
| 51 | 51 | ||
| 52 | SYM_CODE_START_LOCAL(pvh_start_xen) | 52 | SYM_CODE_START_LOCAL(pvh_start_xen) |
| 53 | UNWIND_HINT_EMPTY | ||
| 53 | cld | 54 | cld |
| 54 | 55 | ||
| 55 | lgdt (_pa(gdt)) | 56 | lgdt (_pa(gdt)) |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | |||
| 25 | #include <asm/cpu.h> | 25 | #include <asm/cpu.h> |
| 26 | #include <asm/mmu_context.h> | 26 | #include <asm/mmu_context.h> |
| 27 | #include <asm/cpu_device_id.h> | 27 | #include <asm/cpu_device_id.h> |
| 28 | #include <asm/microcode.h> | ||
| 28 | 29 | ||
| 29 | #ifdef CONFIG_X86_32 | 30 | #ifdef CONFIG_X86_32 |
| 30 | __visible unsigned long saved_context_ebx; | 31 | __visible unsigned long saved_context_ebx; |
| @@ -262,11 +263,18 @@ static void notrace __restore_processor_state(struct saved_context *ctxt) · 231 unmodified lines | |||
| 262 | x86_platform.restore_sched_clock_state(); | 263 | x86_platform.restore_sched_clock_state(); |
| 263 | mtrr_bp_restore(); | 264 | mtrr_bp_restore(); |
| 264 | perf_restore_debug_store(); | 265 | perf_restore_debug_store(); |
| 265 | msr_restore_context(ctxt); | ||
| 266 | 266 | ||
| 267 | c = &cpu_data(smp_processor_id()); | 267 | c = &cpu_data(smp_processor_id()); |
| 268 | if (cpu_has(c, X86_FEATURE_MSR_IA32_FEAT_CTL)) | 268 | if (cpu_has(c, X86_FEATURE_MSR_IA32_FEAT_CTL)) |
| 269 | init_ia32_feat_ctl(c); | 269 | init_ia32_feat_ctl(c); |
| 270 | |||
| 271 | microcode_bsp_resume(); | ||
| 272 | |||
| 273 | /* | ||
| 274 | * This needs to happen after the microcode has been updated upon resume | ||
| 275 | * because some of the MSRs are "emulated" in microcode. | ||
| 276 | */ | ||
| 277 | msr_restore_context(ctxt); | ||
| 270 | } | 278 | } |
| 271 | 279 | ||
| 272 | /* Needed by apm.c */ | 280 | /* Needed by apm.c */ |
| @@ -45,6 +45,7 @@ SYM_CODE_END(hypercall_page) · 44 unmodified lines | |||
| 45 | __INIT | 45 | __INIT |
| 46 | SYM_CODE_START(startup_xen) | 46 | SYM_CODE_START(startup_xen) |
| 47 | UNWIND_HINT_EMPTY | 47 | UNWIND_HINT_EMPTY |
| 48 | ANNOTATE_NOENDBR | ||
| 48 | cld | 49 | cld |
| 49 | 50 | ||
| 50 | /* Clear .bss */ | 51 | /* Clear .bss */ |
| @@ -569,7 +569,7 @@ static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit) · 568 unmodified lines | |||
| 569 | struct bfq_entity *entity = &bfqq->entity; | 569 | struct bfq_entity *entity = &bfqq->entity; |
| 570 | struct bfq_entity *inline_entities[BFQ_LIMIT_INLINE_DEPTH]; | 570 | struct bfq_entity *inline_entities[BFQ_LIMIT_INLINE_DEPTH]; |
| 571 | struct bfq_entity **entities = inline_entities; | 571 | struct bfq_entity **entities = inline_entities; |
| 572 | int depth, level; | 572 | int depth, level, alloc_depth = BFQ_LIMIT_INLINE_DEPTH; |
| 573 | int class_idx = bfqq->ioprio_class - 1; | 573 | int class_idx = bfqq->ioprio_class - 1; |
| 574 | struct bfq_sched_data *sched_data; | 574 | struct bfq_sched_data *sched_data; |
| 575 | unsigned long wsum; | 575 | unsigned long wsum; |
| @@ -578,15 +578,21 @@ static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit) · 2 unmodified lines | |||
| 578 | if (!entity->on_st_or_in_serv) | 578 | if (!entity->on_st_or_in_serv) |
| 579 | return false; | 579 | return false; |
| 580 | 580 | ||
| 581 | retry: | ||
| 582 | spin_lock_irq(&bfqd->lock); | ||
| 581 | /* +1 for bfqq entity, root cgroup not included */ | 583 | /* +1 for bfqq entity, root cgroup not included */ |
| 582 | depth = bfqg_to_blkg(bfqq_group(bfqq))->blkcg->css.cgroup->level + 1; | 584 | depth = bfqg_to_blkg(bfqq_group(bfqq))->blkcg->css.cgroup->level + 1; |
| 583 | if (depth > BFQ_LIMIT_INLINE_DEPTH) { | 585 | if (depth > alloc_depth) { |
| 586 | spin_unlock_irq(&bfqd->lock); | ||
| 587 | if (entities != inline_entities) | ||
| 588 | kfree(entities); | ||
| 584 | entities = kmalloc_array(depth, sizeof(*entities), GFP_NOIO); | 589 | entities = kmalloc_array(depth, sizeof(*entities), GFP_NOIO); |
| 585 | if (!entities) | 590 | if (!entities) |
| 586 | return false; | 591 | return false; |
| 592 | alloc_depth = depth; | ||
| 593 | goto retry; | ||
| 587 | } | 594 | } |
| 588 | 595 | ||
| 589 | spin_lock_irq(&bfqd->lock); | ||
| 590 | sched_data = entity->sched_data; | 596 | sched_data = entity->sched_data; |
| 591 | /* Gather our ancestors as we need to traverse them in reverse order */ | 597 | /* Gather our ancestors as we need to traverse them in reverse order */ |
| 592 | level = 0; | 598 | level = 0; |
| @@ -50,7 +50,6 @@ · 49 unmodified lines | |||
| 50 | #include "blk-pm.h" | 50 | #include "blk-pm.h" |
| 51 | #include "blk-cgroup.h" | 51 | #include "blk-cgroup.h" |
| 52 | #include "blk-throttle.h" | 52 | #include "blk-throttle.h" |
| 53 | #include "blk-rq-qos.h" | ||
| 54 | 53 | ||
| 55 | struct dentry *blk_debugfs_root; | 54 | struct dentry *blk_debugfs_root; |
| 56 | 55 | ||
| @@ -315,9 +314,6 @@ void blk_cleanup_queue(struct request_queue *q) · 258 unmodified lines | |||
| 315 | */ | 314 | */ |
| 316 | blk_freeze_queue(q); | 315 | blk_freeze_queue(q); |
| 317 | 316 | ||
| 318 | /* cleanup rq qos structures for queue without disk */ | ||
| 319 | rq_qos_exit(q); | ||
| 320 | |||
| 321 | blk_queue_flag_set(QUEUE_FLAG_DEAD, q); | 317 | blk_queue_flag_set(QUEUE_FLAG_DEAD, q); |
| 322 | 318 | ||
| 323 | blk_sync_queue(q); | 319 | blk_sync_queue(q); |
| @@ -2322,7 +2322,17 @@ static void ioc_timer_fn(struct timer_list *timer) · 2321 unmodified lines | |||
| 2322 | iocg->hweight_donating = hwa; | 2322 | iocg->hweight_donating = hwa; |
| 2323 | iocg->hweight_after_donation = new_hwi; | 2323 | iocg->hweight_after_donation = new_hwi; |
| 2324 | list_add(&iocg->surplus_list, &surpluses); | 2324 | list_add(&iocg->surplus_list, &surpluses); |
| 2325 | } else { | 2325 | } else if (!iocg->abs_vdebt) { |
| 2326 | /* | ||
| 2327 | * @iocg doesn't have enough to donate. Reset | ||
| 2328 | * its inuse to active. | ||
| 2329 | * | ||
| 2330 | * Don't reset debtors as their inuse's are | ||
| 2331 | * owned by debt handling. This shouldn't affect | ||
| 2332 | * donation calculuation in any meaningful way | ||
| 2333 | * as @iocg doesn't have a meaningful amount of | ||
| 2334 | * share anyway. | ||
| 2335 | */ | ||
| 2326 | TRACE_IOCG_PATH(inuse_shortage, iocg, &now, | 2336 | TRACE_IOCG_PATH(inuse_shortage, iocg, &now, |
| 2327 | iocg->inuse, iocg->active, | 2337 | iocg->inuse, iocg->active, |
| 2328 | iocg->hweight_inuse, new_hwi); | 2338 | iocg->hweight_inuse, new_hwi); |
| @@ -1131,14 +1131,7 @@ void blk_mq_start_request(struct request *rq) · 1130 unmodified lines | |||
| 1131 | trace_block_rq_issue(rq); | 1131 | trace_block_rq_issue(rq); |
| 1132 | 1132 | ||
| 1133 | if (test_bit(QUEUE_FLAG_STATS, &q->queue_flags)) { | 1133 | if (test_bit(QUEUE_FLAG_STATS, &q->queue_flags)) { |
| 1134 | u64 start_time; | 1134 | rq->io_start_time_ns = ktime_get_ns(); |
| 1135 | #ifdef CONFIG_BLK_CGROUP | ||
| 1136 | if (rq->bio) | ||
| 1137 | start_time = bio_issue_time(&rq->bio->bi_issue); | ||
| 1138 | else | ||
| 1139 | #endif | ||
| 1140 | start_time = ktime_get_ns(); | ||
| 1141 | rq->io_start_time_ns = start_time; | ||
| 1142 | rq->stats_sectors = blk_rq_sectors(rq); | 1135 | rq->stats_sectors = blk_rq_sectors(rq); |
| 1143 | rq->rq_flags |= RQF_STATS; | 1136 | rq->rq_flags |= RQF_STATS; |
| 1144 | rq_qos_issue(q, rq); | 1137 | rq_qos_issue(q, rq); |
| @@ -96,11 +96,6 @@ static const struct dmi_system_id processor_power_dmi_table[] = { · 95 unmodified lines | |||
| 96 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), | 96 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), |
| 97 | DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")}, | 97 | DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")}, |
| 98 | (void *)1}, | 98 | (void *)1}, |
| 99 | /* T40 can not handle C3 idle state */ | ||
| 100 | { set_max_cstate, "IBM ThinkPad T40", { | ||
| 101 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | ||
| 102 | DMI_MATCH(DMI_PRODUCT_NAME, "23737CU")}, | ||
| 103 | (void *)2}, | ||
| 104 | {}, | 99 | {}, |
| 105 | }; | 100 | }; |
| 106 | 101 | ||
| @@ -795,7 +790,8 @@ static int acpi_processor_setup_cstates(struct acpi_processor *pr) · 688 unmodified lines | |||
| 795 | if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2 || | 790 | if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2 || |
| 796 | cx->type == ACPI_STATE_C3) { | 791 | cx->type == ACPI_STATE_C3) { |
| 797 | state->enter_dead = acpi_idle_play_dead; | 792 | state->enter_dead = acpi_idle_play_dead; |
| 798 | drv->safe_state_index = count; | 793 | if (cx->type != ACPI_STATE_C3) |
| 794 | drv->safe_state_index = count; | ||
| 799 | } | 795 | } |
| 800 | /* | 796 | /* |
| 801 | * Halt-induced C1 is not good for ->enter_s2idle, because it | 797 | * Halt-induced C1 is not good for ->enter_s2idle, because it |
| @@ -20,6 +20,10 @@ · 19 unmodified lines | |||
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/reset.h> | 21 | #include <linux/reset.h> |
| 22 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
| 23 | #include <linux/of_device.h> | ||
| 24 | #include <linux/acpi.h> | ||
| 25 | #include <linux/iommu.h> | ||
| 26 | #include <linux/dma-map-ops.h> | ||
| 23 | 27 | ||
| 24 | #define to_amba_driver(d) container_of(d, struct amba_driver, drv) | 28 | #define to_amba_driver(d) container_of(d, struct amba_driver, drv) |
| 25 | 29 | ||
| @@ -273,6 +277,36 @@ static void amba_shutdown(struct device *dev) · 247 unmodified lines | |||
| 273 | drv->shutdown(to_amba_device(dev)); | 277 | drv->shutdown(to_amba_device(dev)); |
| 274 | } | 278 | } |
| 275 | 279 | ||
| 280 | static int amba_dma_configure(struct device *dev) | ||
| 281 | { | ||
| 282 | struct amba_driver *drv = to_amba_driver(dev->driver); | ||
| 283 | enum dev_dma_attr attr; | ||
| 284 | int ret = 0; | ||
| 285 | |||
| 286 | if (dev->of_node) { | ||
| 287 | ret = of_dma_configure(dev, dev->of_node, true); | ||
| 288 | } else if (has_acpi_companion(dev)) { | ||
| 289 | attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode)); | ||
| 290 | ret = acpi_dma_configure(dev, attr); | ||
| 291 | } | ||
| 292 | |||
| 293 | if (!ret && !drv->driver_managed_dma) { | ||
| 294 | ret = iommu_device_use_default_domain(dev); | ||
| 295 | if (ret) | ||
| 296 | arch_teardown_dma_ops(dev); | ||
| 297 | } | ||
| 298 | |||
| 299 | return ret; | ||
| 300 | } | ||
| 301 | |||
| 302 | static void amba_dma_cleanup(struct device *dev) | ||
| 303 | { | ||
| 304 | struct amba_driver *drv = to_amba_driver(dev->driver); | ||
| 305 | |||
| 306 | if (!drv->driver_managed_dma) | ||
| 307 | iommu_device_unuse_default_domain(dev); | ||
| 308 | } | ||
| 309 | |||
| 276 | #ifdef CONFIG_PM | 310 | #ifdef CONFIG_PM |
| 277 | /* | 311 | /* |
| 278 | * Hooks to provide runtime PM of the pclk (bus clock). It is safe to | 312 | * Hooks to provide runtime PM of the pclk (bus clock). It is safe to |
| @@ -341,7 +375,8 @@ struct bus_type amba_bustype = { · 62 unmodified lines | |||
| 341 | .probe = amba_probe, | 375 | .probe = amba_probe, |
| 342 | .remove = amba_remove, | 376 | .remove = amba_remove, |
| 343 | .shutdown = amba_shutdown, | 377 | .shutdown = amba_shutdown, |
| 344 | .dma_configure = platform_dma_configure, | 378 | .dma_configure = amba_dma_configure, |
| 379 | .dma_cleanup = amba_dma_cleanup, | ||
| 345 | .pm = &amba_pm, | 380 | .pm = &amba_pm, |
| 346 | }; | 381 | }; |
| 347 | EXPORT_SYMBOL_GPL(amba_bustype); | 382 | EXPORT_SYMBOL_GPL(amba_bustype); |
| @@ -2295,6 +2295,7 @@ static int binder_do_deferred_txn_copies(struct binder_alloc *alloc, · 2294 unmodified lines | |||
| 2295 | { | 2295 | { |
| 2296 | int ret = 0; | 2296 | int ret = 0; |
| 2297 | struct binder_sg_copy *sgc, *tmpsgc; | 2297 | struct binder_sg_copy *sgc, *tmpsgc; |
| 2298 | struct binder_ptr_fixup *tmppf; | ||
| 2298 | struct binder_ptr_fixup *pf = | 2299 | struct binder_ptr_fixup *pf = |
| 2299 | list_first_entry_or_null(pf_head, struct binder_ptr_fixup, | 2300 | list_first_entry_or_null(pf_head, struct binder_ptr_fixup, |
| 2300 | node); | 2301 | node); |
| @@ -2349,7 +2350,11 @@ static int binder_do_deferred_txn_copies(struct binder_alloc *alloc, · 48 unmodified lines | |||
| 2349 | list_del(&sgc->node); | 2350 | list_del(&sgc->node); |
| 2350 | kfree(sgc); | 2351 | kfree(sgc); |
| 2351 | } | 2352 | } |
| 2352 | BUG_ON(!list_empty(pf_head)); | 2353 | list_for_each_entry_safe(pf, tmppf, pf_head, node) { |
| 2354 | BUG_ON(pf->skip_size == 0); | ||
| 2355 | list_del(&pf->node); | ||
| 2356 | kfree(pf); | ||
| 2357 | } | ||
| 2353 | BUG_ON(!list_empty(sgc_head)); | 2358 | BUG_ON(!list_empty(sgc_head)); |
| 2354 | 2359 | ||
| 2355 | return ret > 0 ? -EINVAL : ret; | 2360 | return ret > 0 ? -EINVAL : ret; |
| @@ -2486,6 +2491,9 @@ static int binder_translate_fd_array(struct list_head *pf_head, · 130 unmodified lines | |||
| 2486 | struct binder_proc *proc = thread->proc; | 2491 | struct binder_proc *proc = thread->proc; |
| 2487 | int ret; | 2492 | int ret; |
| 2488 | 2493 | ||
| 2494 | if (fda->num_fds == 0) | ||
| 2495 | return 0; | ||
| 2496 | |||
| 2489 | fd_buf_size = sizeof(u32) * fda->num_fds; | 2497 | fd_buf_size = sizeof(u32) * fda->num_fds; |
| 2490 | if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { | 2498 | if (fda->num_fds >= SIZE_MAX / sizeof(u32)) { |
| 2491 | binder_user_error("%d:%d got transaction with invalid number of fds (%lld)\n", | 2499 | binder_user_error("%d:%d got transaction with invalid number of fds (%lld)\n", |
| @@ -667,6 +667,15 @@ const struct cpumask *cpu_coregroup_mask(int cpu) · 666 unmodified lines | |||
| 667 | core_mask = &cpu_topology[cpu].llc_sibling; | 667 | core_mask = &cpu_topology[cpu].llc_sibling; |
| 668 | } | 668 | } |
| 669 | 669 | ||
| 670 | /* | ||
| 671 | * For systems with no shared cpu-side LLC but with clusters defined, | ||
| 672 | * extend core_mask to cluster_siblings. The sched domain builder will | ||
| 673 | * then remove MC as redundant with CLS if SCHED_CLUSTER is enabled. | ||
| 674 | */ | ||
| 675 | if (IS_ENABLED(CONFIG_SCHED_CLUSTER) && | ||
| 676 | cpumask_subset(core_mask, &cpu_topology[cpu].cluster_sibling)) | ||
| 677 | core_mask = &cpu_topology[cpu].cluster_sibling; | ||
| 678 | |||
| 670 | return core_mask; | 679 | return core_mask; |
| 671 | } | 680 | } |
| 672 | 681 | ||
| @@ -684,7 +693,7 @@ void update_siblings_masks(unsigned int cpuid) · 11 unmodified lines | |||
| 684 | for_each_online_cpu(cpu) { | 693 | for_each_online_cpu(cpu) { |
| 685 | cpu_topo = &cpu_topology[cpu]; | 694 | cpu_topo = &cpu_topology[cpu]; |
| 686 | 695 | ||
| 687 | if (cpuid_topo->llc_id == cpu_topo->llc_id) { | 696 | if (cpu_topo->llc_id != -1 && cpuid_topo->llc_id == cpu_topo->llc_id) { |
| 688 | cpumask_set_cpu(cpu, &cpuid_topo->llc_sibling); | 697 | cpumask_set_cpu(cpu, &cpuid_topo->llc_sibling); |
| 689 | cpumask_set_cpu(cpuid, &cpu_topo->llc_sibling); | 698 | cpumask_set_cpu(cpuid, &cpu_topo->llc_sibling); |
| 690 | } | 699 | } |
| @@ -671,6 +671,8 @@ sysfs_failed: · 670 unmodified lines | |||
| 671 | if (dev->bus) | 671 | if (dev->bus) |
| 672 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, | 672 | blocking_notifier_call_chain(&dev->bus->p->bus_notifier, |
| 673 | BUS_NOTIFY_DRIVER_NOT_BOUND, dev); | 673 | BUS_NOTIFY_DRIVER_NOT_BOUND, dev); |
| 674 | if (dev->bus && dev->bus->dma_cleanup) | ||
| 675 | dev->bus->dma_cleanup(dev); | ||
| 674 | pinctrl_bind_failed: | 676 | pinctrl_bind_failed: |
| 675 | device_links_no_driver(dev); | 677 | device_links_no_driver(dev); |
| 676 | device_unbind_cleanup(dev); | 678 | device_unbind_cleanup(dev); |
| @@ -1199,6 +1201,9 @@ static void __device_release_driver(struct device *dev, struct device *parent) · 522 unmodified lines | |||
| 1199 | 1201 | ||
| 1200 | device_remove(dev); | 1202 | device_remove(dev); |
| 1201 | 1203 | ||
| 1204 | if (dev->bus && dev->bus->dma_cleanup) | ||
| 1205 | dev->bus->dma_cleanup(dev); | ||
| 1206 | |||
| 1202 | device_links_driver_cleanup(dev); | 1207 | device_links_driver_cleanup(dev); |
| 1203 | device_unbind_cleanup(dev); | 1208 | device_unbind_cleanup(dev); |
| 1204 | 1209 | ||
| @@ -735,6 +735,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name, · 734 unmodified lines | |||
| 735 | size_t offset, u32 opt_flags) | 735 | size_t offset, u32 opt_flags) |
| 736 | { | 736 | { |
| 737 | struct firmware *fw = NULL; | 737 | struct firmware *fw = NULL; |
| 738 | struct cred *kern_cred = NULL; | ||
| 739 | const struct cred *old_cred; | ||
| 738 | bool nondirect = false; | 740 | bool nondirect = false; |
| 739 | int ret; | 741 | int ret; |
| 740 | 742 | ||
| @@ -751,6 +753,18 @@ _request_firmware(const struct firmware **firmware_p, const char *name, · 10 unmodified lines | |||
| 751 | if (ret <= 0) /* error or already assigned */ | 753 | if (ret <= 0) /* error or already assigned */ |
| 752 | goto out; | 754 | goto out; |
| 753 | 755 | ||
| 756 | /* | ||
| 757 | * We are about to try to access the firmware file. Because we may have been | ||
| 758 | * called by a driver when serving an unrelated request from userland, we use | ||
| 759 | * the kernel credentials to read the file. | ||
| 760 | */ | ||
| 761 | kern_cred = prepare_kernel_cred(NULL); | ||
| 762 | if (!kern_cred) { | ||
| 763 | ret = -ENOMEM; | ||
| 764 | goto out; | ||
| 765 | } | ||
| 766 | old_cred = override_creds(kern_cred); | ||
| 767 | |||
| 754 | ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL); | 768 | ret = fw_get_filesystem_firmware(device, fw->priv, "", NULL); |
| 755 | 769 | ||
| 756 | /* Only full reads can support decompression, platform, and sysfs. */ | 770 | /* Only full reads can support decompression, platform, and sysfs. */ |
| @@ -776,6 +790,9 @@ _request_firmware(const struct firmware **firmware_p, const char *name, · 19 unmodified lines | |||
| 776 | } else | 790 | } else |
| 777 | ret = assign_fw(fw, device); | 791 | ret = assign_fw(fw, device); |
| 778 | 792 | ||
| 793 | revert_creds(old_cred); | ||
| 794 | put_cred(kern_cred); | ||
| 795 | |||
| 779 | out: | 796 | out: |
| 780 | if (ret < 0) { | 797 | if (ret < 0) { |
| 781 | fw_abort_batch_reqs(fw); | 798 | fw_abort_batch_reqs(fw); |
| @@ -30,6 +30,8 @@ · 29 unmodified lines | |||
| 30 | #include <linux/property.h> | 30 | #include <linux/property.h> |
| 31 | #include <linux/kmemleak.h> | 31 | #include <linux/kmemleak.h> |
| 32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
| 33 | #include <linux/iommu.h> | ||
| 34 | #include <linux/dma-map-ops.h> | ||
| 33 | 35 | ||
| 34 | #include "base.h" | 36 | #include "base.h" |
| 35 | #include "power/power.h" | 37 | #include "power/power.h" |
| @@ -1454,9 +1456,9 @@ static void platform_shutdown(struct device *_dev) · 1418 unmodified lines | |||
| 1454 | drv->shutdown(dev); | 1456 | drv->shutdown(dev); |
| 1455 | } | 1457 | } |
| 1456 | 1458 | ||
| 1457 | 1459 | static int platform_dma_configure(struct device *dev) | |
| 1458 | int platform_dma_configure(struct device *dev) | ||
| 1459 | { | 1460 | { |
| 1461 | struct platform_driver *drv = to_platform_driver(dev->driver); | ||
| 1460 | enum dev_dma_attr attr; | 1462 | enum dev_dma_attr attr; |
| 1461 | int ret = 0; | 1463 | int ret = 0; |
| 1462 | 1464 | ||
| @@ -1467,9 +1469,23 @@ int platform_dma_configure(struct device *dev) · 4 unmodified lines | |||
| 1467 | ret = acpi_dma_configure(dev, attr); | 1469 | ret = acpi_dma_configure(dev, attr); |
| 1468 | } | 1470 | } |
| 1469 | 1471 | ||
| 1472 | if (!ret && !drv->driver_managed_dma) { | ||
| 1473 | ret = iommu_device_use_default_domain(dev); | ||
| 1474 | if (ret) | ||
| 1475 | arch_teardown_dma_ops(dev); | ||
| 1476 | } | ||
| 1477 | |||
| 1470 | return ret; | 1478 | return ret; |
| 1471 | } | 1479 | } |
| 1472 | 1480 | ||
| 1481 | static void platform_dma_cleanup(struct device *dev) | ||
| 1482 | { | ||
| 1483 | struct platform_driver *drv = to_platform_driver(dev->driver); | ||
| 1484 | |||
| 1485 | if (!drv->driver_managed_dma) | ||
| 1486 | iommu_device_unuse_default_domain(dev); | ||
| 1487 | } | ||
| 1488 | |||
| 1473 | static const struct dev_pm_ops platform_dev_pm_ops = { | 1489 | static const struct dev_pm_ops platform_dev_pm_ops = { |
| 1474 | SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL) | 1490 | SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend, pm_generic_runtime_resume, NULL) |
| 1475 | USE_PLATFORM_PM_SLEEP_OPS | 1491 | USE_PLATFORM_PM_SLEEP_OPS |
| @@ -1484,6 +1500,7 @@ struct bus_type platform_bus_type = { · 8 unmodified lines | |||
| 1484 | .remove = platform_remove, | 1500 | .remove = platform_remove, |
| 1485 | .shutdown = platform_shutdown, | 1501 | .shutdown = platform_shutdown, |
| 1486 | .dma_configure = platform_dma_configure, | 1502 | .dma_configure = platform_dma_configure, |
| 1503 | .dma_cleanup = platform_dma_cleanup, | ||
| 1487 | .pm = &platform_dev_pm_ops, | 1504 | .pm = &platform_dev_pm_ops, |
| 1488 | }; | 1505 | }; |
| 1489 | EXPORT_SYMBOL_GPL(platform_bus_type); | 1506 | EXPORT_SYMBOL_GPL(platform_bus_type); |
| @@ -152,9 +152,19 @@ static struct attribute *default_attrs[] = { · 151 unmodified lines | |||
| 152 | NULL | 152 | NULL |
| 153 | }; | 153 | }; |
| 154 | 154 | ||
| 155 | static umode_t topology_is_visible(struct kobject *kobj, | ||
| 156 | struct attribute *attr, int unused) | ||
| 157 | { | ||
| 158 | if (attr == &dev_attr_ppin.attr && !topology_ppin(kobj_to_dev(kobj)->id)) | ||
| 159 | return 0; | ||
| 160 | |||
| 161 | return attr->mode; | ||
| 162 | } | ||
| 163 | |||
| 155 | static const struct attribute_group topology_attr_group = { | 164 | static const struct attribute_group topology_attr_group = { |
| 156 | .attrs = default_attrs, | 165 | .attrs = default_attrs, |
| 157 | .bin_attrs = bin_attrs, | 166 | .bin_attrs = bin_attrs, |
| 167 | .is_visible = topology_is_visible, | ||
| 158 | .name = "topology" | 168 | .name = "topology" |
| 159 | }; | 169 | }; |
| 160 | 170 | ||
| @@ -33,6 +33,22 @@ config BLK_DEV_FD · 32 unmodified lines | |||
| 33 | To compile this driver as a module, choose M here: the | 33 | To compile this driver as a module, choose M here: the |
| 34 | module will be called floppy. | 34 | module will be called floppy. |
| 35 | 35 | ||
| 36 | config BLK_DEV_FD_RAWCMD | ||
| 37 | bool "Support for raw floppy disk commands (DEPRECATED)" | ||
| 38 | depends on BLK_DEV_FD | ||
| 39 | help | ||
| 40 | If you want to use actual physical floppies and expect to do | ||
| 41 | special low-level hardware accesses to them (access and use | ||
| 42 | non-standard formats, for example), then enable this. | ||
| 43 | |||
| 44 | Note that the code enabled by this option is rarely used and | ||
| 45 | might be unstable or insecure, and distros should not enable it. | ||
| 46 | |||
| 47 | Note: FDRAWCMD is deprecated and will be removed from the kernel | ||
| 48 | in the near future. | ||
| 49 | |||
| 50 | If unsure, say N. | ||
| 51 | |||
| 36 | config AMIGA_FLOPPY | 52 | config AMIGA_FLOPPY |
| 37 | tristate "Amiga floppy support" | 53 | tristate "Amiga floppy support" |
| 38 | depends on AMIGA | 54 | depends on AMIGA |
| @@ -303,6 +303,7 @@ static struct atari_floppy_struct { · 302 unmodified lines | |||
| 303 | int ref; | 303 | int ref; |
| 304 | int type; | 304 | int type; |
| 305 | struct blk_mq_tag_set tag_set; | 305 | struct blk_mq_tag_set tag_set; |
| 306 | int error_count; | ||
| 306 | } unit[FD_MAX_UNITS]; | 307 | } unit[FD_MAX_UNITS]; |
| 307 | 308 | ||
| 308 | #define UD unit[drive] | 309 | #define UD unit[drive] |
| @@ -705,14 +706,14 @@ static void fd_error( void ) · 396 unmodified lines | |||
| 705 | if (!fd_request) | 706 | if (!fd_request) |
| 706 | return; | 707 | return; |
| 707 | 708 | ||
| 708 | fd_request->error_count++; | 709 | unit[SelectedDrive].error_count++; |
| 709 | if (fd_request->error_count >= MAX_ERRORS) { | 710 | if (unit[SelectedDrive].error_count >= MAX_ERRORS) { |
| 710 | printk(KERN_ERR "fd%d: too many errors.\n", SelectedDrive ); | 711 | printk(KERN_ERR "fd%d: too many errors.\n", SelectedDrive ); |
| 711 | fd_end_request_cur(BLK_STS_IOERR); | 712 | fd_end_request_cur(BLK_STS_IOERR); |
| 712 | finish_fdc(); | 713 | finish_fdc(); |
| 713 | return; | 714 | return; |
| 714 | } | 715 | } |
| 715 | else if (fd_request->error_count == RECALIBRATE_ERRORS) { | 716 | else if (unit[SelectedDrive].error_count == RECALIBRATE_ERRORS) { |
| 716 | printk(KERN_WARNING "fd%d: recalibrating\n", SelectedDrive ); | 717 | printk(KERN_WARNING "fd%d: recalibrating\n", SelectedDrive ); |
| 717 | if (SelectedDrive != -1) | 718 | if (SelectedDrive != -1) |
| 718 | SUD.track = -1; | 719 | SUD.track = -1; |
| @@ -1491,7 +1492,7 @@ static void setup_req_params( int drive ) · 772 unmodified lines | |||
| 1491 | ReqData = ReqBuffer + 512 * ReqCnt; | 1492 | ReqData = ReqBuffer + 512 * ReqCnt; |
| 1492 | 1493 | ||
| 1493 | if (UseTrackbuffer) | 1494 | if (UseTrackbuffer) |
| 1494 | read_track = (ReqCmd == READ && fd_request->error_count == 0); | 1495 | read_track = (ReqCmd == READ && unit[drive].error_count == 0); |
| 1495 | else | 1496 | else |
| 1496 | read_track = 0; | 1497 | read_track = 0; |
| 1497 | 1498 | ||
| @@ -1520,6 +1521,7 @@ static blk_status_t ataflop_queue_rq(struct blk_mq_hw_ctx *hctx, · 22 unmodified lines | |||
| 1520 | return BLK_STS_RESOURCE; | 1521 | return BLK_STS_RESOURCE; |
| 1521 | } | 1522 | } |
| 1522 | fd_request = bd->rq; | 1523 | fd_request = bd->rq; |
| 1524 | unit[drive].error_count = 0; | ||
| 1523 | blk_mq_start_request(fd_request); | 1525 | blk_mq_start_request(fd_request); |
| 1524 | 1526 | ||
| 1525 | atari_disable_irq( IRQ_MFP_FDC ); | 1527 | atari_disable_irq( IRQ_MFP_FDC ); |
| @@ -509,8 +509,8 @@ static unsigned long fdc_busy; · 508 unmodified lines | |||
| 509 | static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); | 509 | static DECLARE_WAIT_QUEUE_HEAD(fdc_wait); |
| 510 | static DECLARE_WAIT_QUEUE_HEAD(command_done); | 510 | static DECLARE_WAIT_QUEUE_HEAD(command_done); |
| 511 | 511 | ||
| 512 | /* Errors during formatting are counted here. */ | 512 | /* errors encountered on the current (or last) request */ |
| 513 | static int format_errors; | 513 | static int floppy_errors; |
| 514 | 514 | ||
| 515 | /* Format request descriptor. */ | 515 | /* Format request descriptor. */ |
| 516 | static struct format_descr format_req; | 516 | static struct format_descr format_req; |
| @@ -530,7 +530,6 @@ static struct format_descr format_req; · 13 unmodified lines | |||
| 530 | static char *floppy_track_buffer; | 530 | static char *floppy_track_buffer; |
| 531 | static int max_buffer_sectors; | 531 | static int max_buffer_sectors; |
| 532 | 532 | ||
| 533 | static int *errors; | ||
| 534 | typedef void (*done_f)(int); | 533 | typedef void (*done_f)(int); |
| 535 | static const struct cont_t { | 534 | static const struct cont_t { |
| 536 | void (*interrupt)(void); | 535 | void (*interrupt)(void); |
| @@ -1455,7 +1454,7 @@ static int interpret_errors(void) · 918 unmodified lines | |||
| 1455 | if (drive_params[current_drive].flags & FTD_MSG) | 1454 | if (drive_params[current_drive].flags & FTD_MSG) |
| 1456 | DPRINT("Over/Underrun - retrying\n"); | 1455 | DPRINT("Over/Underrun - retrying\n"); |
| 1457 | bad = 0; | 1456 | bad = 0; |
| 1458 | } else if (*errors >= drive_params[current_drive].max_errors.reporting) { | 1457 | } else if (floppy_errors >= drive_params[current_drive].max_errors.reporting) { |
| 1459 | print_errors(); | 1458 | print_errors(); |
| 1460 | } | 1459 | } |
| 1461 | if (reply_buffer[ST2] & ST2_WC || reply_buffer[ST2] & ST2_BC) | 1460 | if (reply_buffer[ST2] & ST2_WC || reply_buffer[ST2] & ST2_BC) |
| @@ -2095,7 +2094,7 @@ static void bad_flp_intr(void) · 633 unmodified lines | |||
| 2095 | if (!next_valid_format(current_drive)) | 2094 | if (!next_valid_format(current_drive)) |
| 2096 | return; | 2095 | return; |
| 2097 | } | 2096 | } |
| 2098 | err_count = ++(*errors); | 2097 | err_count = ++floppy_errors; |
| 2099 | INFBOUND(write_errors[current_drive].badness, err_count); | 2098 | INFBOUND(write_errors[current_drive].badness, err_count); |
| 2100 | if (err_count > drive_params[current_drive].max_errors.abort) | 2099 | if (err_count > drive_params[current_drive].max_errors.abort) |
| 2101 | cont->done(0); | 2100 | cont->done(0); |
| @@ -2241,9 +2240,8 @@ static int do_format(int drive, struct format_descr *tmp_format_req) · 139 unmodified lines | |||
| 2241 | return -EINVAL; | 2240 | return -EINVAL; |
| 2242 | } | 2241 | } |
| 2243 | format_req = *tmp_format_req; | 2242 | format_req = *tmp_format_req; |
| 2244 | format_errors = 0; | ||
| 2245 | cont = &format_cont; | 2243 | cont = &format_cont; |
| 2246 | errors = &format_errors; | 2244 | floppy_errors = 0; |
| 2247 | ret = wait_til_done(redo_format, true); | 2245 | ret = wait_til_done(redo_format, true); |
| 2248 | if (ret == -EINTR) | 2246 | if (ret == -EINTR) |
| 2249 | return -EINTR; | 2247 | return -EINTR; |
| @@ -2759,10 +2757,11 @@ static int set_next_request(void) · 509 unmodified lines | |||
| 2759 | current_req = list_first_entry_or_null(&floppy_reqs, struct request, | 2757 | current_req = list_first_entry_or_null(&floppy_reqs, struct request, |
| 2760 | queuelist); | 2758 | queuelist); |
| 2761 | if (current_req) { | 2759 | if (current_req) { |
| 2762 | current_req->error_count = 0; | 2760 | floppy_errors = 0; |
| 2763 | list_del_init(¤t_req->queuelist); | 2761 | list_del_init(¤t_req->queuelist); |
| 2762 | return 1; | ||
| 2764 | } | 2763 | } |
| 2765 | return current_req != NULL; | 2764 | return 0; |
| 2766 | } | 2765 | } |
| 2767 | 2766 | ||
| 2768 | /* Starts or continues processing request. Will automatically unlock the | 2767 | /* Starts or continues processing request. Will automatically unlock the |
| @@ -2821,7 +2820,6 @@ do_request: · 52 unmodified lines | |||
| 2821 | _floppy = floppy_type + drive_params[current_drive].autodetect[drive_state[current_drive].probed_format]; | 2820 | _floppy = floppy_type + drive_params[current_drive].autodetect[drive_state[current_drive].probed_format]; |
| 2822 | } else | 2821 | } else |
| 2823 | probing = 0; | 2822 | probing = 0; |
| 2824 | errors = &(current_req->error_count); | ||
| 2825 | tmp = make_raw_rw_request(); | 2823 | tmp = make_raw_rw_request(); |
| 2826 | if (tmp < 2) { | 2824 | if (tmp < 2) { |
| 2827 | request_done(tmp); | 2825 | request_done(tmp); |
| @@ -2982,6 +2980,8 @@ static const char *drive_name(int type, int drive) · 154 unmodified lines | |||
| 2982 | return "(null)"; | 2980 | return "(null)"; |
| 2983 | } | 2981 | } |
| 2984 | 2982 | ||
| 2983 | #ifdef CONFIG_BLK_DEV_FD_RAWCMD | ||
| 2984 | |||
| 2985 | /* raw commands */ | 2985 | /* raw commands */ |
| 2986 | static void raw_cmd_done(int flag) | 2986 | static void raw_cmd_done(int flag) |
| 2987 | { | 2987 | { |
| @@ -3181,6 +3181,35 @@ static int raw_cmd_ioctl(int cmd, void __user *param) · 193 unmodified lines | |||
| 3181 | return ret; | 3181 | return ret; |
| 3182 | } | 3182 | } |
| 3183 | 3183 | ||
| 3184 | static int floppy_raw_cmd_ioctl(int type, int drive, int cmd, | ||
| 3185 | void __user *param) | ||
| 3186 | { | ||
| 3187 | int ret; | ||
| 3188 | |||
| 3189 | pr_warn_once("Note: FDRAWCMD is deprecated and will be removed from the kernel in the near future.\n"); | ||
| 3190 | |||
| 3191 | if (type) | ||
| 3192 | return -EINVAL; | ||
| 3193 | if (lock_fdc(drive)) | ||
| 3194 | return -EINTR; | ||
| 3195 | set_floppy(drive); | ||
| 3196 | ret = raw_cmd_ioctl(cmd, param); | ||
| 3197 | if (ret == -EINTR) | ||
| 3198 | return -EINTR; | ||
| 3199 | process_fd_request(); | ||
| 3200 | return ret; | ||
| 3201 | } | ||
| 3202 | |||
| 3203 | #else /* CONFIG_BLK_DEV_FD_RAWCMD */ | ||
| 3204 | |||
| 3205 | static int floppy_raw_cmd_ioctl(int type, int drive, int cmd, | ||
| 3206 | void __user *param) | ||
| 3207 | { | ||
| 3208 | return -EOPNOTSUPP; | ||
| 3209 | } | ||
| 3210 | |||
| 3211 | #endif | ||
| 3212 | |||
| 3184 | static int invalidate_drive(struct block_device *bdev) | 3213 | static int invalidate_drive(struct block_device *bdev) |
| 3185 | { | 3214 | { |
| 3186 | /* invalidate the buffer track to force a reread */ | 3215 | /* invalidate the buffer track to force a reread */ |
| @@ -3369,7 +3398,6 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int · 182 unmodified lines | |||
| 3369 | { | 3398 | { |
| 3370 | int drive = (long)bdev->bd_disk->private_data; | 3399 | int drive = (long)bdev->bd_disk->private_data; |
| 3371 | int type = ITYPE(drive_state[drive].fd_device); | 3400 | int type = ITYPE(drive_state[drive].fd_device); |
| 3372 | int i; | ||
| 3373 | int ret; | 3401 | int ret; |
| 3374 | int size; | 3402 | int size; |
| 3375 | union inparam { | 3403 | union inparam { |
| @@ -3520,16 +3548,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int · 144 unmodified lines | |||
| 3520 | outparam = &write_errors[drive]; | 3548 | outparam = &write_errors[drive]; |
| 3521 | break; | 3549 | break; |
| 3522 | case FDRAWCMD: | 3550 | case FDRAWCMD: |
| 3523 | if (type) | 3551 | return floppy_raw_cmd_ioctl(type, drive, cmd, (void __user *)param); |
| 3524 | return -EINVAL; | ||
| 3525 | if (lock_fdc(drive)) | ||
| 3526 | return -EINTR; | ||
| 3527 | set_floppy(drive); | ||
| 3528 | i = raw_cmd_ioctl(cmd, (void __user *)param); | ||
| 3529 | if (i == -EINTR) | ||
| 3530 | return -EINTR; | ||
| 3531 | process_fd_request(); | ||
| 3532 | return i; | ||
| 3533 | case FDTWADDLE: | 3552 | case FDTWADDLE: |
| 3534 | if (lock_fdc(drive)) | 3553 | if (lock_fdc(drive)) |
| 3535 | return -EINTR; | 3554 | return -EINTR; |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | |||
| 21 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
| 22 | #include <linux/acpi.h> | 22 | #include <linux/acpi.h> |
| 23 | #include <linux/iommu.h> | 23 | #include <linux/iommu.h> |
| 24 | #include <linux/dma-map-ops.h> | ||
| 24 | 25 | ||
| 25 | #include "fsl-mc-private.h" | 26 | #include "fsl-mc-private.h" |
| 26 | 27 | ||
| @@ -140,15 +141,33 @@ static int fsl_mc_dma_configure(struct device *dev) · 113 unmodified lines | |||
| 140 | { | 141 | { |
| 141 | struct device *dma_dev = dev; | 142 | struct device *dma_dev = dev; |
| 142 | struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); | 143 | struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); |
| 144 | struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver); | ||
| 143 | u32 input_id = mc_dev->icid; | 145 | u32 input_id = mc_dev->icid; |
| 146 | int ret; | ||
| 144 | 147 | ||
| 145 | while (dev_is_fsl_mc(dma_dev)) | 148 | while (dev_is_fsl_mc(dma_dev)) |
| 146 | dma_dev = dma_dev->parent; | 149 | dma_dev = dma_dev->parent; |
| 147 | 150 | ||
| 148 | if (dev_of_node(dma_dev)) | 151 | if (dev_of_node(dma_dev)) |
| 149 | return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id); | 152 | ret = of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id); |
| 153 | else | ||
| 154 | ret = acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id); | ||
| 155 | |||
| 156 | if (!ret && !mc_drv->driver_managed_dma) { | ||
| 157 | ret = iommu_device_use_default_domain(dev); | ||
| 158 | if (ret) | ||
| 159 | arch_teardown_dma_ops(dev); | ||
| 160 | } | ||
| 161 | |||
| 162 | return ret; | ||
| 163 | } | ||
| 164 | |||
| 165 | static void fsl_mc_dma_cleanup(struct device *dev) | ||
| 166 | { | ||
| 167 | struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(dev->driver); | ||
| 150 | 168 | ||
| 151 | return acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id); | 169 | if (!mc_drv->driver_managed_dma) |
| 170 | iommu_device_unuse_default_domain(dev); | ||
| 152 | } | 171 | } |
| 153 | 172 | ||
| 154 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, | 173 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, |
| @@ -312,6 +331,7 @@ struct bus_type fsl_mc_bus_type = { · 157 unmodified lines | |||
| 312 | .match = fsl_mc_bus_match, | 331 | .match = fsl_mc_bus_match, |
| 313 | .uevent = fsl_mc_bus_uevent, | 332 | .uevent = fsl_mc_bus_uevent, |
| 314 | .dma_configure = fsl_mc_dma_configure, | 333 | .dma_configure = fsl_mc_dma_configure, |
| 334 | .dma_cleanup = fsl_mc_dma_cleanup, | ||
| 315 | .dev_groups = fsl_mc_dev_groups, | 335 | .dev_groups = fsl_mc_dev_groups, |
| 316 | .bus_groups = fsl_mc_bus_groups, | 336 | .bus_groups = fsl_mc_bus_groups, |
| 317 | }; | 337 | }; |
| @@ -224,8 +224,12 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev, unsigned int irq_count) · 223 unmodified lines | |||
| 224 | if (error) | 224 | if (error) |
| 225 | return error; | 225 | return error; |
| 226 | 226 | ||
| 227 | msi_lock_descs(dev); | ||
| 227 | if (msi_first_desc(dev, MSI_DESC_ALL)) | 228 | if (msi_first_desc(dev, MSI_DESC_ALL)) |
| 228 | return -EINVAL; | 229 | error = -EINVAL; |
| 230 | msi_unlock_descs(dev); | ||
| 231 | if (error) | ||
| 232 | return error; | ||
| 229 | 233 | ||
| 230 | /* | 234 | /* |
| 231 | * NOTE: Calling this function will trigger the invocation of the | 235 | * NOTE: Calling this function will trigger the invocation of the |
| @@ -352,8 +352,7 @@ static int of_weim_notify(struct notifier_block *nb, unsigned long action, · 351 unmodified lines | |||
| 352 | 352 | ||
| 353 | pdev = of_find_device_by_node(rd->dn); | 353 | pdev = of_find_device_by_node(rd->dn); |
| 354 | if (!pdev) { | 354 | if (!pdev) { |
| 355 | dev_err(&pdev->dev, | 355 | pr_err("Could not find platform device for '%pOF'\n", |
| 356 | "Could not find platform device for '%pOF'\n", | ||
| 357 | rd->dn); | 356 | rd->dn); |
| 358 | 357 | ||
| 359 | ret = notifier_from_errno(-EINVAL); | 358 | ret = notifier_from_errno(-EINVAL); |
| @@ -370,7 +369,7 @@ static int of_weim_notify(struct notifier_block *nb, unsigned long action, · 10 unmodified lines | |||
| 370 | return ret; | 369 | return ret; |
| 371 | } | 370 | } |
| 372 | 371 | ||
| 373 | struct notifier_block weim_of_notifier = { | 372 | static struct notifier_block weim_of_notifier = { |
| 374 | .notifier_call = of_weim_notify, | 373 | .notifier_call = of_weim_notify, |
| 375 | }; | 374 | }; |
| 376 | #endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ | 375 | #endif /* IS_ENABLED(CONFIG_OF_DYNAMIC) */ |
| @@ -1060,6 +1060,7 @@ static int __maybe_unused mhi_pci_freeze(struct device *dev) · 1059 unmodified lines | |||
| 1060 | * the intermediate restore kernel reinitializes MHI device with new | 1060 | * the intermediate restore kernel reinitializes MHI device with new |
| 1061 | * context. | 1061 | * context. |
| 1062 | */ | 1062 | */ |
| 1063 | flush_work(&mhi_pdev->recovery_work); | ||
| 1063 | if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) { | 1064 | if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) { |
| 1064 | mhi_power_down(mhi_cntrl, true); | 1065 | mhi_power_down(mhi_cntrl, true); |
| 1065 | mhi_unprepare_after_power_down(mhi_cntrl); | 1066 | mhi_unprepare_after_power_down(mhi_cntrl); |
| @@ -1085,6 +1086,7 @@ static const struct dev_pm_ops mhi_pci_pm_ops = { · 19 unmodified lines | |||
| 1085 | .resume = mhi_pci_resume, | 1086 | .resume = mhi_pci_resume, |
| 1086 | .freeze = mhi_pci_freeze, | 1087 | .freeze = mhi_pci_freeze, |
| 1087 | .thaw = mhi_pci_restore, | 1088 | .thaw = mhi_pci_restore, |
| 1089 | .poweroff = mhi_pci_freeze, | ||
| 1088 | .restore = mhi_pci_restore, | 1090 | .restore = mhi_pci_restore, |
| 1089 | #endif | 1091 | #endif |
| 1090 | }; | 1092 | }; |
| @@ -227,6 +227,8 @@ static struct sunxi_rsb_device *sunxi_rsb_device_create(struct sunxi_rsb *rsb, · 226 unmodified lines | |||
| 227 | 227 | ||
| 228 | dev_dbg(&rdev->dev, "device %s registered\n", dev_name(&rdev->dev)); | 228 | dev_dbg(&rdev->dev, "device %s registered\n", dev_name(&rdev->dev)); |
| 229 | 229 | ||
| 230 | return rdev; | ||
| 231 | |||
| 230 | err_device_add: | 232 | err_device_add: |
| 231 | put_device(&rdev->dev); | 233 | put_device(&rdev->dev); |
| 232 | 234 | ||
| @@ -3232,13 +3232,27 @@ static int sysc_check_disabled_devices(struct sysc *ddata) · 3231 unmodified lines | |||
| 3232 | */ | 3232 | */ |
| 3233 | static int sysc_check_active_timer(struct sysc *ddata) | 3233 | static int sysc_check_active_timer(struct sysc *ddata) |
| 3234 | { | 3234 | { |
| 3235 | int error; | ||
| 3236 | |||
| 3235 | if (ddata->cap->type != TI_SYSC_OMAP2_TIMER && | 3237 | if (ddata->cap->type != TI_SYSC_OMAP2_TIMER && |
| 3236 | ddata->cap->type != TI_SYSC_OMAP4_TIMER) | 3238 | ddata->cap->type != TI_SYSC_OMAP4_TIMER) |
| 3237 | return 0; | 3239 | return 0; |
| 3238 | 3240 | ||
| 3241 | /* | ||
| 3242 | * Quirk for omap3 beagleboard revision A to B4 to use gpt12. | ||
| 3243 | * Revision C and later are fixed with commit 23885389dbbb ("ARM: | ||
| 3244 | * dts: Fix timer regression for beagleboard revision c"). This all | ||
| 3245 | * can be dropped if we stop supporting old beagleboard revisions | ||
| 3246 | * A to B4 at some point. | ||
| 3247 | */ | ||
| 3248 | if (sysc_soc->soc == SOC_3430) | ||
| 3249 | error = -ENXIO; | ||
| 3250 | else | ||
| 3251 | error = -EBUSY; | ||
| 3252 | |||
| 3239 | if ((ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) && | 3253 | if ((ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) && |
| 3240 | (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)) | 3254 | (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)) |
| 3241 | return -ENXIO; | 3255 | return error; |
| 3242 | 3256 | ||
| 3243 | return 0; | 3257 | return 0; |
| 3244 | } | 3258 | } |
| @@ -3677,8 +3677,11 @@ static void cleanup_smi_msgs(struct ipmi_smi *intf) · 3676 unmodified lines | |||
| 3677 | void ipmi_unregister_smi(struct ipmi_smi *intf) | 3677 | void ipmi_unregister_smi(struct ipmi_smi *intf) |
| 3678 | { | 3678 | { |
| 3679 | struct ipmi_smi_watcher *w; | 3679 | struct ipmi_smi_watcher *w; |
| 3680 | int intf_num = intf->intf_num, index; | 3680 | int intf_num, index; |
| 3681 | 3681 | ||
| 3682 | if (!intf) | ||
| 3683 | return; | ||
| 3684 | intf_num = intf->intf_num; | ||
| 3682 | mutex_lock(&ipmi_interfaces_mutex); | 3685 | mutex_lock(&ipmi_interfaces_mutex); |
| 3683 | intf->intf_num = -1; | 3686 | intf->intf_num = -1; |
| 3684 | intf->in_shutdown = true; | 3687 | intf->in_shutdown = true; |
| @@ -4518,6 +4521,8 @@ return_unspecified: · 833 unmodified lines | |||
| 4518 | } else | 4521 | } else |
| 4519 | /* The message was sent, start the timer. */ | 4522 | /* The message was sent, start the timer. */ |
| 4520 | intf_start_seq_timer(intf, msg->msgid); | 4523 | intf_start_seq_timer(intf, msg->msgid); |
| 4524 | requeue = 0; | ||
| 4525 | goto out; | ||
| 4521 | } else if (((msg->rsp[0] >> 2) != ((msg->data[0] >> 2) | 1)) | 4526 | } else if (((msg->rsp[0] >> 2) != ((msg->data[0] >> 2) | 1)) |
| 4522 | || (msg->rsp[1] != msg->data[1])) { | 4527 | || (msg->rsp[1] != msg->data[1])) { |
| 4523 | /* | 4528 | /* |
| @@ -2220,10 +2220,7 @@ static void cleanup_one_si(struct smi_info *smi_info) · 2219 unmodified lines | |||
| 2220 | return; | 2220 | return; |
| 2221 | 2221 | ||
| 2222 | list_del(&smi_info->link); | 2222 | list_del(&smi_info->link); |
| 2223 | 2223 | ipmi_unregister_smi(smi_info->intf); | |
| 2224 | if (smi_info->intf) | ||
| 2225 | ipmi_unregister_smi(smi_info->intf); | ||
| 2226 | |||
| 2227 | kfree(smi_info); | 2224 | kfree(smi_info); |
| 2228 | } | 2225 | } |
| 2229 | 2226 | ||
| @@ -318,6 +318,13 @@ static void crng_reseed(bool force) · 317 unmodified lines | |||
| 318 | * the resultant ChaCha state to the user, along with the second | 318 | * the resultant ChaCha state to the user, along with the second |
| 319 | * half of the block containing 32 bytes of random data that may | 319 | * half of the block containing 32 bytes of random data that may |
| 320 | * be used; random_data_len may not be greater than 32. | 320 | * be used; random_data_len may not be greater than 32. |
| 321 | * | ||
| 322 | * The returned ChaCha state contains within it a copy of the old | ||
| 323 | * key value, at index 4, so the state should always be zeroed out | ||
| 324 | * immediately after using in order to maintain forward secrecy. | ||
| 325 | * If the state cannot be erased in a timely manner, then it is | ||
| 326 | * safer to set the random_data parameter to &chacha_state[4] so | ||
| 327 | * that this function overwrites it before returning. | ||
| 321 | */ | 328 | */ |
| 322 | static void crng_fast_key_erasure(u8 key[CHACHA_KEY_SIZE], | 329 | static void crng_fast_key_erasure(u8 key[CHACHA_KEY_SIZE], |
| 323 | u32 chacha_state[CHACHA_STATE_WORDS], | 330 | u32 chacha_state[CHACHA_STATE_WORDS], |
| @@ -333,7 +340,7 @@ static void crng_fast_key_erasure(u8 key[CHACHA_KEY_SIZE], · 9 unmodified lines | |||
| 333 | chacha20_block(chacha_state, first_block); | 340 | chacha20_block(chacha_state, first_block); |
| 334 | 341 | ||
| 335 | memcpy(key, first_block, CHACHA_KEY_SIZE); | 342 | memcpy(key, first_block, CHACHA_KEY_SIZE); |
| 336 | memmove(random_data, first_block + CHACHA_KEY_SIZE, random_data_len); | 343 | memcpy(random_data, first_block + CHACHA_KEY_SIZE, random_data_len); |
| 337 | memzero_explicit(first_block, sizeof(first_block)); | 344 | memzero_explicit(first_block, sizeof(first_block)); |
| 338 | } | 345 | } |
| 339 | 346 | ||
| @@ -11,20 +11,48 @@ · 10 unmodified lines | |||
| 11 | #include <dt-bindings/clock/microchip,mpfs-clock.h> | 11 | #include <dt-bindings/clock/microchip,mpfs-clock.h> |
| 12 | 12 | ||
| 13 | /* address offset of control registers */ | 13 | /* address offset of control registers */ |
| 14 | #define REG_MSSPLL_REF_CR 0x08u | ||
| 15 | #define REG_MSSPLL_POSTDIV_CR 0x10u | ||
| 16 | #define REG_MSSPLL_SSCG_2_CR 0x2Cu | ||
| 14 | #define REG_CLOCK_CONFIG_CR 0x08u | 17 | #define REG_CLOCK_CONFIG_CR 0x08u |
| 18 | #define REG_RTC_CLOCK_CR 0x0Cu | ||
| 15 | #define REG_SUBBLK_CLOCK_CR 0x84u | 19 | #define REG_SUBBLK_CLOCK_CR 0x84u |
| 16 | #define REG_SUBBLK_RESET_CR 0x88u | 20 | #define REG_SUBBLK_RESET_CR 0x88u |
| 17 | 21 | ||
| 22 | #define MSSPLL_FBDIV_SHIFT 0x00u | ||
| 23 | #define MSSPLL_FBDIV_WIDTH 0x0Cu | ||
| 24 | #define MSSPLL_REFDIV_SHIFT 0x08u | ||
| 25 | #define MSSPLL_REFDIV_WIDTH 0x06u | ||
| 26 | #define MSSPLL_POSTDIV_SHIFT 0x08u | ||
| 27 | #define MSSPLL_POSTDIV_WIDTH 0x07u | ||
| 28 | #define MSSPLL_FIXED_DIV 4u | ||
| 29 | |||
| 18 | struct mpfs_clock_data { | 30 | struct mpfs_clock_data { |
| 19 | void __iomem *base; | 31 | void __iomem *base; |
| 32 | void __iomem *msspll_base; | ||
| 20 | struct clk_hw_onecell_data hw_data; | 33 | struct clk_hw_onecell_data hw_data; |
| 21 | }; | 34 | }; |
| 22 | 35 | ||
| 36 | struct mpfs_msspll_hw_clock { | ||
| 37 | void __iomem *base; | ||
| 38 | unsigned int id; | ||
| 39 | u32 reg_offset; | ||
| 40 | u32 shift; | ||
| 41 | u32 width; | ||
| 42 | u32 flags; | ||
| 43 | struct clk_hw hw; | ||
| 44 | struct clk_init_data init; | ||
| 45 | }; | ||
| 46 | |||
| 47 | #define to_mpfs_msspll_clk(_hw) container_of(_hw, struct mpfs_msspll_hw_clock, hw) | ||
| 48 | |||
| 23 | struct mpfs_cfg_clock { | 49 | struct mpfs_cfg_clock { |
| 24 | const struct clk_div_table *table; | 50 | const struct clk_div_table *table; |
| 25 | unsigned int id; | 51 | unsigned int id; |
| 52 | u32 reg_offset; | ||
| 26 | u8 shift; | 53 | u8 shift; |
| 27 | u8 width; | 54 | u8 width; |
| 55 | u8 flags; | ||
| 28 | }; | 56 | }; |
| 29 | 57 | ||
| 30 | struct mpfs_cfg_hw_clock { | 58 | struct mpfs_cfg_hw_clock { |
| @@ -55,7 +83,7 @@ struct mpfs_periph_hw_clock { · 24 unmodified lines | |||
| 55 | */ | 83 | */ |
| 56 | static DEFINE_SPINLOCK(mpfs_clk_lock); | 84 | static DEFINE_SPINLOCK(mpfs_clk_lock); |
| 57 | 85 | ||
| 58 | static const struct clk_parent_data mpfs_cfg_parent[] = { | 86 | static const struct clk_parent_data mpfs_ext_ref[] = { |
| 59 | { .index = 0 }, | 87 | { .index = 0 }, |
| 60 | }; | 88 | }; |
| 61 | 89 | ||
| @@ -69,6 +97,86 @@ static const struct clk_div_table mpfs_div_ahb_table[] = { · 7 unmodified lines | |||
| 69 | { 0, 0 } | 97 | { 0, 0 } |
| 70 | }; | 98 | }; |
| 71 | 99 | ||
| 100 | /* | ||
| 101 | * The only two supported reference clock frequencies for the PolarFire SoC are | ||
| 102 | * 100 and 125 MHz, as the rtc reference is required to be 1 MHz. | ||
| 103 | * It therefore only needs to have divider table entries corresponding to | ||
| 104 | * divide by 100 and 125. | ||
| 105 | */ | ||
| 106 | static const struct clk_div_table mpfs_div_rtcref_table[] = { | ||
| 107 | { 100, 100 }, { 125, 125 }, | ||
| 108 | { 0, 0 } | ||
| 109 | }; | ||
| 110 | |||
| 111 | static unsigned long mpfs_clk_msspll_recalc_rate(struct clk_hw *hw, unsigned long prate) | ||
| 112 | { | ||
| 113 | struct mpfs_msspll_hw_clock *msspll_hw = to_mpfs_msspll_clk(hw); | ||
| 114 | void __iomem *mult_addr = msspll_hw->base + msspll_hw->reg_offset; | ||
| 115 | void __iomem *ref_div_addr = msspll_hw->base + REG_MSSPLL_REF_CR; | ||
| 116 | void __iomem *postdiv_addr = msspll_hw->base + REG_MSSPLL_POSTDIV_CR; | ||
| 117 | u32 mult, ref_div, postdiv; | ||
| 118 | |||
| 119 | mult = readl_relaxed(mult_addr) >> MSSPLL_FBDIV_SHIFT; | ||
| 120 | mult &= clk_div_mask(MSSPLL_FBDIV_WIDTH); | ||
| 121 | ref_div = readl_relaxed(ref_div_addr) >> MSSPLL_REFDIV_SHIFT; | ||
| 122 | ref_div &= clk_div_mask(MSSPLL_REFDIV_WIDTH); | ||
| 123 | postdiv = readl_relaxed(postdiv_addr) >> MSSPLL_POSTDIV_SHIFT; | ||
| 124 | postdiv &= clk_div_mask(MSSPLL_POSTDIV_WIDTH); | ||
| 125 | |||
| 126 | return prate * mult / (ref_div * MSSPLL_FIXED_DIV * postdiv); | ||
| 127 | } | ||
| 128 | |||
| 129 | static const struct clk_ops mpfs_clk_msspll_ops = { | ||
| 130 | .recalc_rate = mpfs_clk_msspll_recalc_rate, | ||
| 131 | }; | ||
| 132 | |||
| 133 | #define CLK_PLL(_id, _name, _parent, _shift, _width, _flags, _offset) { \ | ||
| 134 | .id = _id, \ | ||
| 135 | .shift = _shift, \ | ||
| 136 | .width = _width, \ | ||
| 137 | .reg_offset = _offset, \ | ||
| 138 | .flags = _flags, \ | ||
| 139 | .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, _parent, &mpfs_clk_msspll_ops, 0), \ | ||
| 140 | } | ||
| 141 | |||
| 142 | static struct mpfs_msspll_hw_clock mpfs_msspll_clks[] = { | ||
| 143 | CLK_PLL(CLK_MSSPLL, "clk_msspll", mpfs_ext_ref, MSSPLL_FBDIV_SHIFT, | ||
| 144 | MSSPLL_FBDIV_WIDTH, 0, REG_MSSPLL_SSCG_2_CR), | ||
| 145 | }; | ||
| 146 | |||
| 147 | static int mpfs_clk_register_msspll(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hw, | ||
| 148 | void __iomem *base) | ||
| 149 | { | ||
| 150 | msspll_hw->base = base; | ||
| 151 | |||
| 152 | return devm_clk_hw_register(dev, &msspll_hw->hw); | ||
| 153 | } | ||
| 154 | |||
| 155 | static int mpfs_clk_register_mssplls(struct device *dev, struct mpfs_msspll_hw_clock *msspll_hws, | ||
| 156 | unsigned int num_clks, struct mpfs_clock_data *data) | ||
| 157 | { | ||
| 158 | void __iomem *base = data->msspll_base; | ||
| 159 | unsigned int i; | ||
| 160 | int ret; | ||
| 161 | |||
| 162 | for (i = 0; i < num_clks; i++) { | ||
| 163 | struct mpfs_msspll_hw_clock *msspll_hw = &msspll_hws[i]; | ||
| 164 | |||
| 165 | ret = mpfs_clk_register_msspll(dev, msspll_hw, base); | ||
| 166 | if (ret) | ||
| 167 | return dev_err_probe(dev, ret, "failed to register msspll id: %d\n", | ||
| 168 | CLK_MSSPLL); | ||
| 169 | |||
| 170 | data->hw_data.hws[msspll_hw->id] = &msspll_hw->hw; | ||
| 171 | } | ||
| 172 | |||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 176 | /* | ||
| 177 | * "CFG" clocks | ||
| 178 | */ | ||
| 179 | |||
| 72 | static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate) | 180 | static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate) |
| 73 | { | 181 | { |
| 74 | struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); | 182 | struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); |
| @@ -76,10 +184,10 @@ static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long p · 1 unmodified line | |||
| 76 | void __iomem *base_addr = cfg_hw->sys_base; | 184 | void __iomem *base_addr = cfg_hw->sys_base; |
| 77 | u32 val; | 185 | u32 val; |
| 78 | 186 | ||
| 79 | val = readl_relaxed(base_addr + REG_CLOCK_CONFIG_CR) >> cfg->shift; | 187 | val = readl_relaxed(base_addr + cfg->reg_offset) >> cfg->shift; |
| 80 | val &= clk_div_mask(cfg->width); | 188 | val &= clk_div_mask(cfg->width); |
| 81 | 189 | ||
| 82 | return prate / (1u << val); | 190 | return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width); |
| 83 | } | 191 | } |
| 84 | 192 | ||
| 85 | static long mpfs_cfg_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) | 193 | static long mpfs_cfg_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) |
| @@ -105,11 +213,10 @@ static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned · 19 unmodified lines | |||
| 105 | return divider_setting; | 213 | return divider_setting; |
| 106 | 214 | ||
| 107 | spin_lock_irqsave(&mpfs_clk_lock, flags); | 215 | spin_lock_irqsave(&mpfs_clk_lock, flags); |
| 108 | 216 | val = readl_relaxed(base_addr + cfg->reg_offset); | |
| 109 | val = readl_relaxed(base_addr + REG_CLOCK_CONFIG_CR); | ||
| 110 | val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift); | 217 | val &= ~(clk_div_mask(cfg->width) << cfg_hw->cfg.shift); |
| 111 | val |= divider_setting << cfg->shift; | 218 | val |= divider_setting << cfg->shift; |
| 112 | writel_relaxed(val, base_addr + REG_CLOCK_CONFIG_CR); | 219 | writel_relaxed(val, base_addr + cfg->reg_offset); |
| 113 | 220 | ||
| 114 | spin_unlock_irqrestore(&mpfs_clk_lock, flags); | 221 | spin_unlock_irqrestore(&mpfs_clk_lock, flags); |
| 115 | 222 | ||
| @@ -122,19 +229,33 @@ static const struct clk_ops mpfs_clk_cfg_ops = { · 6 unmodified lines | |||
| 122 | .set_rate = mpfs_cfg_clk_set_rate, | 229 | .set_rate = mpfs_cfg_clk_set_rate, |
| 123 | }; | 230 | }; |
| 124 | 231 | ||
| 125 | #define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags) { \ | 232 | #define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \ |
| 126 | .cfg.id = _id, \ | 233 | .cfg.id = _id, \ |
| 127 | .cfg.shift = _shift, \ | 234 | .cfg.shift = _shift, \ |
| 128 | .cfg.width = _width, \ | 235 | .cfg.width = _width, \ |
| 129 | .cfg.table = _table, \ | 236 | .cfg.table = _table, \ |
| 130 | .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, _parent, &mpfs_clk_cfg_ops, \ | 237 | .cfg.reg_offset = _offset, \ |
| 131 | _flags), \ | 238 | .cfg.flags = _flags, \ |
| 239 | .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \ | ||
| 132 | } | 240 | } |
| 133 | 241 | ||
| 134 | static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = { | 242 | static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = { |
| 135 | CLK_CFG(CLK_CPU, "clk_cpu", mpfs_cfg_parent, 0, 2, mpfs_div_cpu_axi_table, 0), | 243 | CLK_CFG(CLK_CPU, "clk_cpu", "clk_msspll", 0, 2, mpfs_div_cpu_axi_table, 0, |
| 136 | CLK_CFG(CLK_AXI, "clk_axi", mpfs_cfg_parent, 2, 2, mpfs_div_cpu_axi_table, 0), | 244 | REG_CLOCK_CONFIG_CR), |
| 137 | CLK_CFG(CLK_AHB, "clk_ahb", mpfs_cfg_parent, 4, 2, mpfs_div_ahb_table, 0), | 245 | CLK_CFG(CLK_AXI, "clk_axi", "clk_msspll", 2, 2, mpfs_div_cpu_axi_table, 0, |
| 246 | REG_CLOCK_CONFIG_CR), | ||
| 247 | CLK_CFG(CLK_AHB, "clk_ahb", "clk_msspll", 4, 2, mpfs_div_ahb_table, 0, | ||
| 248 | REG_CLOCK_CONFIG_CR), | ||
| 249 | { | ||
| 250 | .cfg.id = CLK_RTCREF, | ||
| 251 | .cfg.shift = 0, | ||
| 252 | .cfg.width = 12, | ||
| 253 | .cfg.table = mpfs_div_rtcref_table, | ||
| 254 | .cfg.reg_offset = REG_RTC_CLOCK_CR, | ||
| 255 | .cfg.flags = CLK_DIVIDER_ONE_BASED, | ||
| 256 | .hw.init = | ||
| 257 | CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0), | ||
| 258 | } | ||
| 138 | }; | 259 | }; |
| 139 | 260 | ||
| 140 | static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hw, | 261 | static int mpfs_clk_register_cfg(struct device *dev, struct mpfs_cfg_hw_clock *cfg_hw, |
| @@ -160,13 +281,17 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock * · 19 unmodified lines | |||
| 160 | return dev_err_probe(dev, ret, "failed to register clock id: %d\n", | 281 | return dev_err_probe(dev, ret, "failed to register clock id: %d\n", |
| 161 | cfg_hw->cfg.id); | 282 | cfg_hw->cfg.id); |
| 162 | 283 | ||
| 163 | id = cfg_hws[i].cfg.id; | 284 | id = cfg_hw->cfg.id; |
| 164 | data->hw_data.hws[id] = &cfg_hw->hw; | 285 | data->hw_data.hws[id] = &cfg_hw->hw; |
| 165 | } | 286 | } |
| 166 | 287 | ||
| 167 | return 0; | 288 | return 0; |
| 168 | } | 289 | } |
| 169 | 290 | ||
| 291 | /* | ||
| 292 | * peripheral clocks - devices connected to axi or ahb buses. | ||
| 293 | */ | ||
| 294 | |||
| 170 | static int mpfs_periph_clk_enable(struct clk_hw *hw) | 295 | static int mpfs_periph_clk_enable(struct clk_hw *hw) |
| 171 | { | 296 | { |
| 172 | struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); | 297 | struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); |
| @@ -200,10 +325,6 @@ static void mpfs_periph_clk_disable(struct clk_hw *hw) · 27 unmodified lines | |||
| 200 | 325 | ||
| 201 | spin_lock_irqsave(&mpfs_clk_lock, flags); | 326 | spin_lock_irqsave(&mpfs_clk_lock, flags); |
| 202 | 327 | ||
| 203 | reg = readl_relaxed(base_addr + REG_SUBBLK_RESET_CR); | ||
| 204 | val = reg | (1u << periph->shift); | ||
| 205 | writel_relaxed(val, base_addr + REG_SUBBLK_RESET_CR); | ||
| 206 | |||
| 207 | reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR); | 328 | reg = readl_relaxed(base_addr + REG_SUBBLK_CLOCK_CR); |
| 208 | val = reg & ~(1u << periph->shift); | 329 | val = reg & ~(1u << periph->shift); |
| 209 | writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR); | 330 | writel_relaxed(val, base_addr + REG_SUBBLK_CLOCK_CR); |
| @@ -249,8 +370,10 @@ static const struct clk_ops mpfs_periph_clk_ops = { · 39 unmodified lines | |||
| 249 | * trap handler | 370 | * trap handler |
| 250 | * - CLK_MMUART0: reserved by the hss | 371 | * - CLK_MMUART0: reserved by the hss |
| 251 | * - CLK_DDRC: provides clock to the ddr subsystem | 372 | * - CLK_DDRC: provides clock to the ddr subsystem |
| 252 | * - CLK_FICx: these provide clocks for sections of the fpga fabric, disabling them would | 373 | * - CLK_FICx: these provide the processor side clocks to the "FIC" (Fabric InterConnect) |
| 253 | * cause the fabric to go into reset | 374 | * clock domain crossers which provide the interface to the FPGA fabric. Disabling them |
| 375 | * causes the FPGA fabric to go into reset. | ||
| 376 | * - CLK_ATHENA: The athena clock is FIC4, which is reserved for the Athena TeraFire. | ||
| 254 | */ | 377 | */ |
| 255 | 378 | ||
| 256 | static struct mpfs_periph_hw_clock mpfs_periph_clks[] = { | 379 | static struct mpfs_periph_hw_clock mpfs_periph_clks[] = { |
| @@ -258,7 +381,7 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = { · 1 unmodified line | |||
| 258 | CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", PARENT_CLK(AHB), 1, 0), | 381 | CLK_PERIPH(CLK_MAC0, "clk_periph_mac0", PARENT_CLK(AHB), 1, 0), |
| 259 | CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", PARENT_CLK(AHB), 2, 0), | 382 | CLK_PERIPH(CLK_MAC1, "clk_periph_mac1", PARENT_CLK(AHB), 2, 0), |
| 260 | CLK_PERIPH(CLK_MMC, "clk_periph_mmc", PARENT_CLK(AHB), 3, 0), | 383 | CLK_PERIPH(CLK_MMC, "clk_periph_mmc", PARENT_CLK(AHB), 3, 0), |
| 261 | CLK_PERIPH(CLK_TIMER, "clk_periph_timer", PARENT_CLK(AHB), 4, 0), | 384 | CLK_PERIPH(CLK_TIMER, "clk_periph_timer", PARENT_CLK(RTCREF), 4, 0), |
| 262 | CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", PARENT_CLK(AHB), 5, CLK_IS_CRITICAL), | 385 | CLK_PERIPH(CLK_MMUART0, "clk_periph_mmuart0", PARENT_CLK(AHB), 5, CLK_IS_CRITICAL), |
| 263 | CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", PARENT_CLK(AHB), 6, 0), | 386 | CLK_PERIPH(CLK_MMUART1, "clk_periph_mmuart1", PARENT_CLK(AHB), 6, 0), |
| 264 | CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", PARENT_CLK(AHB), 7, 0), | 387 | CLK_PERIPH(CLK_MMUART2, "clk_periph_mmuart2", PARENT_CLK(AHB), 7, 0), |
| @@ -277,11 +400,11 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = { · 12 unmodified lines | |||
| 277 | CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", PARENT_CLK(AHB), 21, 0), | 400 | CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", PARENT_CLK(AHB), 21, 0), |
| 278 | CLK_PERIPH(CLK_GPIO2, "clk_periph_gpio2", PARENT_CLK(AHB), 22, 0), | 401 | CLK_PERIPH(CLK_GPIO2, "clk_periph_gpio2", PARENT_CLK(AHB), 22, 0), |
| 279 | CLK_PERIPH(CLK_DDRC, "clk_periph_ddrc", PARENT_CLK(AHB), 23, CLK_IS_CRITICAL), | 402 | CLK_PERIPH(CLK_DDRC, "clk_periph_ddrc", PARENT_CLK(AHB), 23, CLK_IS_CRITICAL), |
| 280 | CLK_PERIPH(CLK_FIC0, "clk_periph_fic0", PARENT_CLK(AHB), 24, CLK_IS_CRITICAL), | 403 | CLK_PERIPH(CLK_FIC0, "clk_periph_fic0", PARENT_CLK(AXI), 24, CLK_IS_CRITICAL), |
| 281 | CLK_PERIPH(CLK_FIC1, "clk_periph_fic1", PARENT_CLK(AHB), 25, CLK_IS_CRITICAL), | 404 | CLK_PERIPH(CLK_FIC1, "clk_periph_fic1", PARENT_CLK(AXI), 25, CLK_IS_CRITICAL), |
| 282 | CLK_PERIPH(CLK_FIC2, "clk_periph_fic2", PARENT_CLK(AHB), 26, CLK_IS_CRITICAL), | 405 | CLK_PERIPH(CLK_FIC2, "clk_periph_fic2", PARENT_CLK(AXI), 26, CLK_IS_CRITICAL), |
| 283 | CLK_PERIPH(CLK_FIC3, "clk_periph_fic3", PARENT_CLK(AHB), 27, CLK_IS_CRITICAL), | 406 | CLK_PERIPH(CLK_FIC3, "clk_periph_fic3", PARENT_CLK(AXI), 27, CLK_IS_CRITICAL), |
| 284 | CLK_PERIPH(CLK_ATHENA, "clk_periph_athena", PARENT_CLK(AHB), 28, 0), | 407 | CLK_PERIPH(CLK_ATHENA, "clk_periph_athena", PARENT_CLK(AXI), 28, CLK_IS_CRITICAL), |
| 285 | CLK_PERIPH(CLK_CFM, "clk_periph_cfm", PARENT_CLK(AHB), 29, 0), | 408 | CLK_PERIPH(CLK_CFM, "clk_periph_cfm", PARENT_CLK(AHB), 29, 0), |
| 286 | }; | 409 | }; |
| 287 | 410 | ||
| @@ -322,8 +445,9 @@ static int mpfs_clk_probe(struct platform_device *pdev) · 34 unmodified lines | |||
| 322 | unsigned int num_clks; | 445 | unsigned int num_clks; |
| 323 | int ret; | 446 | int ret; |
| 324 | 447 | ||
| 325 | /* CLK_RESERVED is not part of cfg_clks nor periph_clks, so add 1 */ | 448 | /* CLK_RESERVED is not part of clock arrays, so add 1 */ |
| 326 | num_clks = ARRAY_SIZE(mpfs_cfg_clks) + ARRAY_SIZE(mpfs_periph_clks) + 1; | 449 | num_clks = ARRAY_SIZE(mpfs_msspll_clks) + ARRAY_SIZE(mpfs_cfg_clks) |
| 450 | + ARRAY_SIZE(mpfs_periph_clks) + 1; | ||
| 327 | 451 | ||
| 328 | clk_data = devm_kzalloc(dev, struct_size(clk_data, hw_data.hws, num_clks), GFP_KERNEL); | 452 | clk_data = devm_kzalloc(dev, struct_size(clk_data, hw_data.hws, num_clks), GFP_KERNEL); |
| 329 | if (!clk_data) | 453 | if (!clk_data) |
| @@ -333,8 +457,17 @@ static int mpfs_clk_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 333 | if (IS_ERR(clk_data->base)) | 457 | if (IS_ERR(clk_data->base)) |
| 334 | return PTR_ERR(clk_data->base); | 458 | return PTR_ERR(clk_data->base); |
| 335 | 459 | ||
| 460 | clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 1); | ||
| 461 | if (IS_ERR(clk_data->msspll_base)) | ||
| 462 | return PTR_ERR(clk_data->msspll_base); | ||
| 463 | |||
| 336 | clk_data->hw_data.num = num_clks; | 464 | clk_data->hw_data.num = num_clks; |
| 337 | 465 | ||
| 466 | ret = mpfs_clk_register_mssplls(dev, mpfs_msspll_clks, ARRAY_SIZE(mpfs_msspll_clks), | ||
| 467 | clk_data); | ||
| 468 | if (ret) | ||
| 469 | return ret; | ||
| 470 | |||
| 338 | ret = mpfs_clk_register_cfgs(dev, mpfs_cfg_clks, ARRAY_SIZE(mpfs_cfg_clks), clk_data); | 471 | ret = mpfs_clk_register_cfgs(dev, mpfs_cfg_clks, ARRAY_SIZE(mpfs_cfg_clks), clk_data); |
| 339 | if (ret) | 472 | if (ret) |
| 340 | return ret; | 473 | return ret; |
| @@ -818,7 +818,7 @@ EXPORT_SYMBOL_GPL(clk_pixel_ops); · 817 unmodified lines | |||
| 818 | static int clk_gfx3d_determine_rate(struct clk_hw *hw, | 818 | static int clk_gfx3d_determine_rate(struct clk_hw *hw, |
| 819 | struct clk_rate_request *req) | 819 | struct clk_rate_request *req) |
| 820 | { | 820 | { |
| 821 | struct clk_rate_request parent_req = { }; | 821 | struct clk_rate_request parent_req = { .min_rate = 0, .max_rate = ULONG_MAX }; |
| 822 | struct clk_rcg2_gfx3d *cgfx = to_clk_rcg2_gfx3d(hw); | 822 | struct clk_rcg2_gfx3d *cgfx = to_clk_rcg2_gfx3d(hw); |
| 823 | struct clk_hw *xo, *p0, *p1, *p2; | 823 | struct clk_hw *xo, *p0, *p1, *p2; |
| 824 | unsigned long p0_rate; | 824 | unsigned long p0_rate; |
| @@ -241,6 +241,7 @@ static struct clk_init_data rtc_32k_init_data = { · 240 unmodified lines | |||
| 241 | .ops = &ccu_mux_ops, | 241 | .ops = &ccu_mux_ops, |
| 242 | .parent_hws = rtc_32k_parents, | 242 | .parent_hws = rtc_32k_parents, |
| 243 | .num_parents = ARRAY_SIZE(rtc_32k_parents), /* updated during probe */ | 243 | .num_parents = ARRAY_SIZE(rtc_32k_parents), /* updated during probe */ |
| 244 | .flags = CLK_IS_CRITICAL, | ||
| 244 | }; | 245 | }; |
| 245 | 246 | ||
| 246 | static struct ccu_mux rtc_32k_clk = { | 247 | static struct ccu_mux rtc_32k_clk = { |
| @@ -346,6 +347,7 @@ static const struct of_device_id sun6i_rtc_ccu_match[] = { · 99 unmodified lines | |||
| 346 | .compatible = "allwinner,sun50i-r329-rtc", | 347 | .compatible = "allwinner,sun50i-r329-rtc", |
| 347 | .data = &sun50i_r329_rtc_ccu_data, | 348 | .data = &sun50i_r329_rtc_ccu_data, |
| 348 | }, | 349 | }, |
| 350 | {}, | ||
| 349 | }; | 351 | }; |
| 350 | 352 | ||
| 351 | int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg) | 353 | int sun6i_rtc_ccu_probe(struct device *dev, void __iomem *reg) |
| @@ -109,6 +109,8 @@ static int sun9i_a80_mmc_config_clk_probe(struct platform_device *pdev) · 108 unmodified lines | |||
| 109 | spin_lock_init(&data->lock); | 109 | spin_lock_init(&data->lock); |
| 110 | 110 | ||
| 111 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 111 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 112 | if (!r) | ||
| 113 | return -EINVAL; | ||
| 112 | /* one clock/reset pair per word */ | 114 | /* one clock/reset pair per word */ |
| 113 | count = DIV_ROUND_UP((resource_size(r)), SUN9I_MMC_WIDTH); | 115 | count = DIV_ROUND_UP((resource_size(r)), SUN9I_MMC_WIDTH); |
| 114 | data->membase = devm_ioremap_resource(&pdev->dev, r); | 116 | data->membase = devm_ioremap_resource(&pdev->dev, r); |
| @@ -24,13 +24,17 @@ · 23 unmodified lines | |||
| 24 | #define CLK_HW_DIV 2 | 24 | #define CLK_HW_DIV 2 |
| 25 | #define LUT_TURBO_IND 1 | 25 | #define LUT_TURBO_IND 1 |
| 26 | 26 | ||
| 27 | #define GT_IRQ_STATUS BIT(2) | ||
| 28 | |||
| 27 | #define HZ_PER_KHZ 1000 | 29 | #define HZ_PER_KHZ 1000 |
| 28 | 30 | ||
| 29 | struct qcom_cpufreq_soc_data { | 31 | struct qcom_cpufreq_soc_data { |
| 30 | u32 reg_enable; | 32 | u32 reg_enable; |
| 33 | u32 reg_domain_state; | ||
| 31 | u32 reg_dcvs_ctrl; | 34 | u32 reg_dcvs_ctrl; |
| 32 | u32 reg_freq_lut; | 35 | u32 reg_freq_lut; |
| 33 | u32 reg_volt_lut; | 36 | u32 reg_volt_lut; |
| 37 | u32 reg_intr_clr; | ||
| 34 | u32 reg_current_vote; | 38 | u32 reg_current_vote; |
| 35 | u32 reg_perf_state; | 39 | u32 reg_perf_state; |
| 36 | u8 lut_row_size; | 40 | u8 lut_row_size; |
| @@ -280,37 +284,46 @@ static void qcom_get_related_cpus(int index, struct cpumask *m) · 243 unmodified lines | |||
| 280 | } | 284 | } |
| 281 | } | 285 | } |
| 282 | 286 | ||
| 283 | static unsigned int qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data) | 287 | static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data) |
| 284 | { | 288 | { |
| 285 | unsigned int val = readl_relaxed(data->base + data->soc_data->reg_current_vote); | 289 | unsigned int lval; |
| 290 | |||
| 291 | if (data->soc_data->reg_current_vote) | ||
| 292 | lval = readl_relaxed(data->base + data->soc_data->reg_current_vote) & 0x3ff; | ||
| 293 | else | ||
| 294 | lval = readl_relaxed(data->base + data->soc_data->reg_domain_state) & 0xff; | ||
| 286 | 295 | ||
| 287 | return (val & 0x3FF) * 19200; | 296 | return lval * xo_rate; |
| 288 | } | 297 | } |
| 289 | 298 | ||
| 290 | static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) | 299 | static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) |
| 291 | { | 300 | { |
| 292 | struct cpufreq_policy *policy = data->policy; | 301 | struct cpufreq_policy *policy = data->policy; |
| 293 | int cpu = cpumask_first(policy->cpus); | 302 | int cpu = cpumask_first(policy->related_cpus); |
| 294 | struct device *dev = get_cpu_device(cpu); | 303 | struct device *dev = get_cpu_device(cpu); |
| 295 | unsigned long freq_hz, throttled_freq; | 304 | unsigned long freq_hz, throttled_freq; |
| 296 | struct dev_pm_opp *opp; | 305 | struct dev_pm_opp *opp; |
| 297 | unsigned int freq; | ||
| 298 | 306 | ||
| 299 | /* | 307 | /* |
| 300 | * Get the h/w throttled frequency, normalize it using the | 308 | * Get the h/w throttled frequency, normalize it using the |
| 301 | * registered opp table and use it to calculate thermal pressure. | 309 | * registered opp table and use it to calculate thermal pressure. |
| 302 | */ | 310 | */ |
| 303 | freq = qcom_lmh_get_throttle_freq(data); | 311 | freq_hz = qcom_lmh_get_throttle_freq(data); |
| 304 | freq_hz = freq * HZ_PER_KHZ; | ||
| 305 | 312 | ||
| 306 | opp = dev_pm_opp_find_freq_floor(dev, &freq_hz); | 313 | opp = dev_pm_opp_find_freq_floor(dev, &freq_hz); |
| 307 | if (IS_ERR(opp) && PTR_ERR(opp) == -ERANGE) | 314 | if (IS_ERR(opp) && PTR_ERR(opp) == -ERANGE) |
| 308 | dev_pm_opp_find_freq_ceil(dev, &freq_hz); | 315 | opp = dev_pm_opp_find_freq_ceil(dev, &freq_hz); |
| 316 | |||
| 317 | if (IS_ERR(opp)) { | ||
| 318 | dev_warn(dev, "Can't find the OPP for throttling: %pe!\n", opp); | ||
| 319 | } else { | ||
| 320 | throttled_freq = freq_hz / HZ_PER_KHZ; | ||
| 309 | 321 | ||
| 310 | throttled_freq = freq_hz / HZ_PER_KHZ; | 322 | /* Update thermal pressure (the boost frequencies are accepted) */ |
| 323 | arch_update_thermal_pressure(policy->related_cpus, throttled_freq); | ||
| 311 | 324 | ||
| 312 | /* Update thermal pressure (the boost frequencies are accepted) */ | 325 | dev_pm_opp_put(opp); |
| 313 | arch_update_thermal_pressure(policy->related_cpus, throttled_freq); | 326 | } |
| 314 | 327 | ||
| 315 | /* | 328 | /* |
| 316 | * In the unlikely case policy is unregistered do not enable | 329 | * In the unlikely case policy is unregistered do not enable |
| @@ -350,6 +363,10 @@ static irqreturn_t qcom_lmh_dcvs_handle_irq(int irq, void *data) · 33 unmodified lines | |||
| 350 | disable_irq_nosync(c_data->throttle_irq); | 363 | disable_irq_nosync(c_data->throttle_irq); |
| 351 | schedule_delayed_work(&c_data->throttle_work, 0); | 364 | schedule_delayed_work(&c_data->throttle_work, 0); |
| 352 | 365 | ||
| 366 | if (c_data->soc_data->reg_intr_clr) | ||
| 367 | writel_relaxed(GT_IRQ_STATUS, | ||
| 368 | c_data->base + c_data->soc_data->reg_intr_clr); | ||
| 369 | |||
| 353 | return IRQ_HANDLED; | 370 | return IRQ_HANDLED; |
| 354 | } | 371 | } |
| 355 | 372 | ||
| @@ -365,9 +382,11 @@ static const struct qcom_cpufreq_soc_data qcom_soc_data = { · 9 unmodified lines | |||
| 365 | 382 | ||
| 366 | static const struct qcom_cpufreq_soc_data epss_soc_data = { | 383 | static const struct qcom_cpufreq_soc_data epss_soc_data = { |
| 367 | .reg_enable = 0x0, | 384 | .reg_enable = 0x0, |
| 385 | .reg_domain_state = 0x20, | ||
| 368 | .reg_dcvs_ctrl = 0xb0, | 386 | .reg_dcvs_ctrl = 0xb0, |
| 369 | .reg_freq_lut = 0x100, | 387 | .reg_freq_lut = 0x100, |
| 370 | .reg_volt_lut = 0x200, | 388 | .reg_volt_lut = 0x200, |
| 389 | .reg_intr_clr = 0x308, | ||
| 371 | .reg_perf_state = 0x320, | 390 | .reg_perf_state = 0x320, |
| 372 | .lut_row_size = 4, | 391 | .lut_row_size = 4, |
| 373 | }; | 392 | }; |
| @@ -417,16 +436,39 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index) · 43 unmodified lines | |||
| 417 | return 0; | 436 | return 0; |
| 418 | } | 437 | } |
| 419 | 438 | ||
| 420 | static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data) | 439 | static int qcom_cpufreq_hw_cpu_online(struct cpufreq_policy *policy) |
| 440 | { | ||
| 441 | struct qcom_cpufreq_data *data = policy->driver_data; | ||
| 442 | struct platform_device *pdev = cpufreq_get_driver_data(); | ||
| 443 | int ret; | ||
| 444 | |||
| 445 | ret = irq_set_affinity_hint(data->throttle_irq, policy->cpus); | ||
| 446 | if (ret) | ||
| 447 | dev_err(&pdev->dev, "Failed to set CPU affinity of %s[%d]\n", | ||
| 448 | data->irq_name, data->throttle_irq); | ||
| 449 | |||
| 450 | return ret; | ||
| 451 | } | ||
| 452 | |||
| 453 | static int qcom_cpufreq_hw_cpu_offline(struct cpufreq_policy *policy) | ||
| 421 | { | 454 | { |
| 455 | struct qcom_cpufreq_data *data = policy->driver_data; | ||
| 456 | |||
| 422 | if (data->throttle_irq <= 0) | 457 | if (data->throttle_irq <= 0) |
| 423 | return; | 458 | return 0; |
| 424 | 459 | ||
| 425 | mutex_lock(&data->throttle_lock); | 460 | mutex_lock(&data->throttle_lock); |
| 426 | data->cancel_throttle = true; | 461 | data->cancel_throttle = true; |
| 427 | mutex_unlock(&data->throttle_lock); | 462 | mutex_unlock(&data->throttle_lock); |
| 428 | 463 | ||
| 429 | cancel_delayed_work_sync(&data->throttle_work); | 464 | cancel_delayed_work_sync(&data->throttle_work); |
| 465 | irq_set_affinity_hint(data->throttle_irq, NULL); | ||
| 466 | |||
| 467 | return 0; | ||
| 468 | } | ||
| 469 | |||
| 470 | static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data) | ||
| 471 | { | ||
| 430 | free_irq(data->throttle_irq, data); | 472 | free_irq(data->throttle_irq, data); |
| 431 | } | 473 | } |
| 432 | 474 | ||
| @@ -583,6 +625,8 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = { · 150 unmodified lines | |||
| 583 | .get = qcom_cpufreq_hw_get, | 625 | .get = qcom_cpufreq_hw_get, |
| 584 | .init = qcom_cpufreq_hw_cpu_init, | 626 | .init = qcom_cpufreq_hw_cpu_init, |
| 585 | .exit = qcom_cpufreq_hw_cpu_exit, | 627 | .exit = qcom_cpufreq_hw_cpu_exit, |
| 628 | .online = qcom_cpufreq_hw_cpu_online, | ||
| 629 | .offline = qcom_cpufreq_hw_cpu_offline, | ||
| 586 | .register_em = cpufreq_register_em_with_opp, | 630 | .register_em = cpufreq_register_em_with_opp, |
| 587 | .fast_switch = qcom_cpufreq_hw_fast_switch, | 631 | .fast_switch = qcom_cpufreq_hw_fast_switch, |
| 588 | .name = "qcom-cpufreq-hw", | 632 | .name = "qcom-cpufreq-hw", |
| @@ -98,8 +98,10 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) · 97 unmodified lines | |||
| 98 | return -ENOMEM; | 98 | return -ENOMEM; |
| 99 | 99 | ||
| 100 | ret = sun50i_cpufreq_get_efuse(&speed); | 100 | ret = sun50i_cpufreq_get_efuse(&speed); |
| 101 | if (ret) | 101 | if (ret) { |
| 102 | kfree(opp_tables); | ||
| 102 | return ret; | 103 | return ret; |
| 104 | } | ||
| 103 | 105 | ||
| 104 | snprintf(name, MAX_NAME_LEN, "speed%d", speed); | 106 | snprintf(name, MAX_NAME_LEN, "speed%d", speed); |
| 105 | 107 | ||
| @@ -543,10 +543,6 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) · 542 unmodified lines | |||
| 543 | file->f_mode |= FMODE_LSEEK; | 543 | file->f_mode |= FMODE_LSEEK; |
| 544 | dmabuf->file = file; | 544 | dmabuf->file = file; |
| 545 | 545 | ||
| 546 | ret = dma_buf_stats_setup(dmabuf); | ||
| 547 | if (ret) | ||
| 548 | goto err_sysfs; | ||
| 549 | |||
| 550 | mutex_init(&dmabuf->lock); | 546 | mutex_init(&dmabuf->lock); |
| 551 | INIT_LIST_HEAD(&dmabuf->attachments); | 547 | INIT_LIST_HEAD(&dmabuf->attachments); |
| 552 | 548 | ||
| @@ -554,6 +550,10 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) · 1 unmodified line | |||
| 554 | list_add(&dmabuf->list_node, &db_list.head); | 550 | list_add(&dmabuf->list_node, &db_list.head); |
| 555 | mutex_unlock(&db_list.lock); | 551 | mutex_unlock(&db_list.lock); |
| 556 | 552 | ||
| 553 | ret = dma_buf_stats_setup(dmabuf); | ||
| 554 | if (ret) | ||
| 555 | goto err_sysfs; | ||
| 556 | |||
| 557 | return dmabuf; | 557 | return dmabuf; |
| 558 | 558 | ||
| 559 | err_sysfs: | 559 | err_sysfs: |
| @@ -668,6 +668,7 @@ EXPORT_SYMBOL_GPL(fw_card_release); · 667 unmodified lines | |||
| 668 | void fw_core_remove_card(struct fw_card *card) | 668 | void fw_core_remove_card(struct fw_card *card) |
| 669 | { | 669 | { |
| 670 | struct fw_card_driver dummy_driver = dummy_driver_template; | 670 | struct fw_card_driver dummy_driver = dummy_driver_template; |
| 671 | unsigned long flags; | ||
| 671 | 672 | ||
| 672 | card->driver->update_phy_reg(card, 4, | 673 | card->driver->update_phy_reg(card, 4, |
| 673 | PHY_LINK_ACTIVE | PHY_CONTENDER, 0); | 674 | PHY_LINK_ACTIVE | PHY_CONTENDER, 0); |
| @@ -682,7 +683,9 @@ void fw_core_remove_card(struct fw_card *card) · 8 unmodified lines | |||
| 682 | dummy_driver.stop_iso = card->driver->stop_iso; | 683 | dummy_driver.stop_iso = card->driver->stop_iso; |
| 683 | card->driver = &dummy_driver; | 684 | card->driver = &dummy_driver; |
| 684 | 685 | ||
| 686 | spin_lock_irqsave(&card->lock, flags); | ||
| 685 | fw_destroy_nodes(card); | 687 | fw_destroy_nodes(card); |
| 688 | spin_unlock_irqrestore(&card->lock, flags); | ||
| 686 | 689 | ||
| 687 | /* Wait for all users, especially device workqueue jobs, to finish. */ | 690 | /* Wait for all users, especially device workqueue jobs, to finish. */ |
| 688 | fw_card_put(card); | 691 | fw_card_put(card); |
| @@ -1500,6 +1500,7 @@ static void outbound_phy_packet_callback(struct fw_packet *packet, · 1499 unmodified lines | |||
| 1500 | { | 1500 | { |
| 1501 | struct outbound_phy_packet_event *e = | 1501 | struct outbound_phy_packet_event *e = |
| 1502 | container_of(packet, struct outbound_phy_packet_event, p); | 1502 | container_of(packet, struct outbound_phy_packet_event, p); |
| 1503 | struct client *e_client; | ||
| 1503 | 1504 | ||
| 1504 | switch (status) { | 1505 | switch (status) { |
| 1505 | /* expected: */ | 1506 | /* expected: */ |
| @@ -1516,9 +1517,10 @@ static void outbound_phy_packet_callback(struct fw_packet *packet, · 10 unmodified lines | |||
| 1516 | } | 1517 | } |
| 1517 | e->phy_packet.data[0] = packet->timestamp; | 1518 | e->phy_packet.data[0] = packet->timestamp; |
| 1518 | 1519 | ||
| 1520 | e_client = e->client; | ||
| 1519 | queue_event(e->client, &e->event, &e->phy_packet, | 1521 | queue_event(e->client, &e->event, &e->phy_packet, |
| 1520 | sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0); | 1522 | sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0); |
| 1521 | client_put(e->client); | 1523 | client_put(e_client); |
| 1522 | } | 1524 | } |
| 1523 | 1525 | ||
| 1524 | static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) | 1526 | static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) |
| @@ -375,16 +375,13 @@ static void report_found_node(struct fw_card *card, · 374 unmodified lines | |||
| 375 | card->bm_retries = 0; | 375 | card->bm_retries = 0; |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | /* Must be called with card->lock held */ | ||
| 378 | void fw_destroy_nodes(struct fw_card *card) | 379 | void fw_destroy_nodes(struct fw_card *card) |
| 379 | { | 380 | { |
| 380 | unsigned long flags; | ||
| 381 | |||
| 382 | spin_lock_irqsave(&card->lock, flags); | ||
| 383 | card->color++; | 381 | card->color++; |
| 384 | if (card->local_node != NULL) | 382 | if (card->local_node != NULL) |
| 385 | for_each_fw_node(card, card->local_node, report_lost_node); | 383 | for_each_fw_node(card, card->local_node, report_lost_node); |
| 386 | card->local_node = NULL; | 384 | card->local_node = NULL; |
| 387 | spin_unlock_irqrestore(&card->lock, flags); | ||
| 388 | } | 385 | } |
| 389 | 386 | ||
| 390 | static void move_tree(struct fw_node *node0, struct fw_node *node1, int port) | 387 | static void move_tree(struct fw_node *node0, struct fw_node *node1, int port) |
| @@ -510,6 +507,8 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, · 119 unmodified lines | |||
| 510 | struct fw_node *local_node; | 507 | struct fw_node *local_node; |
| 511 | unsigned long flags; | 508 | unsigned long flags; |
| 512 | 509 | ||
| 510 | spin_lock_irqsave(&card->lock, flags); | ||
| 511 | |||
| 513 | /* | 512 | /* |
| 514 | * If the selfID buffer is not the immediate successor of the | 513 | * If the selfID buffer is not the immediate successor of the |
| 515 | * previously processed one, we cannot reliably compare the | 514 | * previously processed one, we cannot reliably compare the |
| @@ -521,8 +520,6 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, · 5 unmodified lines | |||
| 521 | card->bm_retries = 0; | 520 | card->bm_retries = 0; |
| 522 | } | 521 | } |
| 523 | 522 | ||
| 524 | spin_lock_irqsave(&card->lock, flags); | ||
| 525 | |||
| 526 | card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated; | 523 | card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated; |
| 527 | card->node_id = node_id; | 524 | card->node_id = node_id; |
| 528 | /* | 525 | /* |
| @@ -73,24 +73,25 @@ static int try_cancel_split_timeout(struct fw_transaction *t) · 72 unmodified lines | |||
| 73 | static int close_transaction(struct fw_transaction *transaction, | 73 | static int close_transaction(struct fw_transaction *transaction, |
| 74 | struct fw_card *card, int rcode) | 74 | struct fw_card *card, int rcode) |
| 75 | { | 75 | { |
| 76 | struct fw_transaction *t; | 76 | struct fw_transaction *t = NULL, *iter; |
| 77 | unsigned long flags; | 77 | unsigned long flags; |
| 78 | 78 | ||
| 79 | spin_lock_irqsave(&card->lock, flags); | 79 | spin_lock_irqsave(&card->lock, flags); |
| 80 | list_for_each_entry(t, &card->transaction_list, link) { | 80 | list_for_each_entry(iter, &card->transaction_list, link) { |
| 81 | if (t == transaction) { | 81 | if (iter == transaction) { |
| 82 | if (!try_cancel_split_timeout(t)) { | 82 | if (!try_cancel_split_timeout(iter)) { |
| 83 | spin_unlock_irqrestore(&card->lock, flags); | 83 | spin_unlock_irqrestore(&card->lock, flags); |
| 84 | goto timed_out; | 84 | goto timed_out; |
| 85 | } | 85 | } |
| 86 | list_del_init(&t->link); | 86 | list_del_init(&iter->link); |
| 87 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 87 | card->tlabel_mask &= ~(1ULL << iter->tlabel); |
| 88 | t = iter; | ||
| 88 | break; | 89 | break; |
| 89 | } | 90 | } |
| 90 | } | 91 | } |
| 91 | spin_unlock_irqrestore(&card->lock, flags); | 92 | spin_unlock_irqrestore(&card->lock, flags); |
| 92 | 93 | ||
| 93 | if (&t->link != &card->transaction_list) { | 94 | if (t) { |
| 94 | t->callback(card, rcode, NULL, 0, t->callback_data); | 95 | t->callback(card, rcode, NULL, 0, t->callback_data); |
| 95 | return 0; | 96 | return 0; |
| 96 | } | 97 | } |
| @@ -935,7 +936,7 @@ EXPORT_SYMBOL(fw_core_handle_request); · 838 unmodified lines | |||
| 935 | 936 | ||
| 936 | void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | 937 | void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) |
| 937 | { | 938 | { |
| 938 | struct fw_transaction *t; | 939 | struct fw_transaction *t = NULL, *iter; |
| 939 | unsigned long flags; | 940 | unsigned long flags; |
| 940 | u32 *data; | 941 | u32 *data; |
| 941 | size_t data_length; | 942 | size_t data_length; |
| @@ -947,20 +948,21 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) · 5 unmodified lines | |||
| 947 | rcode = HEADER_GET_RCODE(p->header[1]); | 948 | rcode = HEADER_GET_RCODE(p->header[1]); |
| 948 | 949 | ||
| 949 | spin_lock_irqsave(&card->lock, flags); | 950 | spin_lock_irqsave(&card->lock, flags); |
| 950 | list_for_each_entry(t, &card->transaction_list, link) { | 951 | list_for_each_entry(iter, &card->transaction_list, link) { |
| 951 | if (t->node_id == source && t->tlabel == tlabel) { | 952 | if (iter->node_id == source && iter->tlabel == tlabel) { |
| 952 | if (!try_cancel_split_timeout(t)) { | 953 | if (!try_cancel_split_timeout(iter)) { |
| 953 | spin_unlock_irqrestore(&card->lock, flags); | 954 | spin_unlock_irqrestore(&card->lock, flags); |
| 954 | goto timed_out; | 955 | goto timed_out; |
| 955 | } | 956 | } |
| 956 | list_del_init(&t->link); | 957 | list_del_init(&iter->link); |
| 957 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 958 | card->tlabel_mask &= ~(1ULL << iter->tlabel); |
| 959 | t = iter; | ||
| 958 | break; | 960 | break; |
| 959 | } | 961 | } |
| 960 | } | 962 | } |
| 961 | spin_unlock_irqrestore(&card->lock, flags); | 963 | spin_unlock_irqrestore(&card->lock, flags); |
| 962 | 964 | ||
| 963 | if (&t->link == &card->transaction_list) { | 965 | if (!t) { |
| 964 | timed_out: | 966 | timed_out: |
| 965 | fw_notice(card, "unsolicited response (source %x, tlabel %x)\n", | 967 | fw_notice(card, "unsolicited response (source %x, tlabel %x)\n", |
| 966 | source, tlabel); | 968 | source, tlabel); |
| @@ -408,7 +408,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, · 407 unmodified lines | |||
| 408 | void *payload, size_t length, void *callback_data) | 408 | void *payload, size_t length, void *callback_data) |
| 409 | { | 409 | { |
| 410 | struct sbp2_logical_unit *lu = callback_data; | 410 | struct sbp2_logical_unit *lu = callback_data; |
| 411 | struct sbp2_orb *orb; | 411 | struct sbp2_orb *orb = NULL, *iter; |
| 412 | struct sbp2_status status; | 412 | struct sbp2_status status; |
| 413 | unsigned long flags; | 413 | unsigned long flags; |
| 414 | 414 | ||
| @@ -433,17 +433,18 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, · 18 unmodified lines | |||
| 433 | 433 | ||
| 434 | /* Lookup the orb corresponding to this status write. */ | 434 | /* Lookup the orb corresponding to this status write. */ |
| 435 | spin_lock_irqsave(&lu->tgt->lock, flags); | 435 | spin_lock_irqsave(&lu->tgt->lock, flags); |
| 436 | list_for_each_entry(orb, &lu->orb_list, link) { | 436 | list_for_each_entry(iter, &lu->orb_list, link) { |
| 437 | if (STATUS_GET_ORB_HIGH(status) == 0 && | 437 | if (STATUS_GET_ORB_HIGH(status) == 0 && |
| 438 | STATUS_GET_ORB_LOW(status) == orb->request_bus) { | 438 | STATUS_GET_ORB_LOW(status) == iter->request_bus) { |
| 439 | orb->rcode = RCODE_COMPLETE; | 439 | iter->rcode = RCODE_COMPLETE; |
| 440 | list_del(&orb->link); | 440 | list_del(&iter->link); |
| 441 | orb = iter; | ||
| 441 | break; | 442 | break; |
| 442 | } | 443 | } |
| 443 | } | 444 | } |
| 444 | spin_unlock_irqrestore(&lu->tgt->lock, flags); | 445 | spin_unlock_irqrestore(&lu->tgt->lock, flags); |
| 445 | 446 | ||
| 446 | if (&orb->link != &lu->orb_list) { | 447 | if (orb) { |
| 447 | orb->callback(orb, &status); | 448 | orb->callback(orb, &status); |
| 448 | kref_put(&orb->kref, free_orb); /* orb callback reference */ | 449 | kref_put(&orb->kref, free_orb); /* orb callback reference */ |
| 449 | } else { | 450 | } else { |
| @@ -871,13 +871,6 @@ static int mvebu_pwm_probe(struct platform_device *pdev, · 870 unmodified lines | |||
| 871 | mvpwm->chip.dev = dev; | 871 | mvpwm->chip.dev = dev; |
| 872 | mvpwm->chip.ops = &mvebu_pwm_ops; | 872 | mvpwm->chip.ops = &mvebu_pwm_ops; |
| 873 | mvpwm->chip.npwm = mvchip->chip.ngpio; | 873 | mvpwm->chip.npwm = mvchip->chip.ngpio; |
| 874 | /* | ||
| 875 | * There may already be some PWM allocated, so we can't force | ||
| 876 | * mvpwm->chip.base to a fixed point like mvchip->chip.base. | ||
| 877 | * So, we let pwmchip_add() do the numbering and take the next free | ||
| 878 | * region. | ||
| 879 | */ | ||
| 880 | mvpwm->chip.base = -1; | ||
| 881 | 874 | ||
| 882 | spin_lock_init(&mvpwm->lock); | 875 | spin_lock_init(&mvpwm->lock); |
| 883 | 876 | ||
| @@ -762,11 +762,11 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, unsigned long *pendin · 761 unmodified lines | |||
| 762 | bitmap_xor(cur_stat, new_stat, old_stat, gc->ngpio); | 762 | bitmap_xor(cur_stat, new_stat, old_stat, gc->ngpio); |
| 763 | bitmap_and(trigger, cur_stat, chip->irq_mask, gc->ngpio); | 763 | bitmap_and(trigger, cur_stat, chip->irq_mask, gc->ngpio); |
| 764 | 764 | ||
| 765 | bitmap_copy(chip->irq_stat, new_stat, gc->ngpio); | ||
| 766 | |||
| 765 | if (bitmap_empty(trigger, gc->ngpio)) | 767 | if (bitmap_empty(trigger, gc->ngpio)) |
| 766 | return false; | 768 | return false; |
| 767 | 769 | ||
| 768 | bitmap_copy(chip->irq_stat, new_stat, gc->ngpio); | ||
| 769 | |||
| 770 | bitmap_and(cur_stat, chip->irq_trig_fall, old_stat, gc->ngpio); | 770 | bitmap_and(cur_stat, chip->irq_trig_fall, old_stat, gc->ngpio); |
| 771 | bitmap_and(old_stat, chip->irq_trig_raise, new_stat, gc->ngpio); | 771 | bitmap_and(old_stat, chip->irq_trig_raise, new_stat, gc->ngpio); |
| 772 | bitmap_or(new_stat, old_stat, cur_stat, gc->ngpio); | 772 | bitmap_or(new_stat, old_stat, cur_stat, gc->ngpio); |
| @@ -130,7 +130,6 @@ static int visconti_gpio_probe(struct platform_device *pdev) · 129 unmodified lines | |||
| 130 | struct gpio_irq_chip *girq; | 130 | struct gpio_irq_chip *girq; |
| 131 | struct irq_domain *parent; | 131 | struct irq_domain *parent; |
| 132 | struct device_node *irq_parent; | 132 | struct device_node *irq_parent; |
| 133 | struct fwnode_handle *fwnode; | ||
| 134 | int ret; | 133 | int ret; |
| 135 | 134 | ||
| 136 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 135 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); |
| @@ -150,14 +149,12 @@ static int visconti_gpio_probe(struct platform_device *pdev) · 13 unmodified lines | |||
| 150 | } | 149 | } |
| 151 | 150 | ||
| 152 | parent = irq_find_host(irq_parent); | 151 | parent = irq_find_host(irq_parent); |
| 152 | of_node_put(irq_parent); | ||
| 153 | if (!parent) { | 153 | if (!parent) { |
| 154 | dev_err(dev, "No IRQ parent domain\n"); | 154 | dev_err(dev, "No IRQ parent domain\n"); |
| 155 | return -ENODEV; | 155 | return -ENODEV; |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | fwnode = of_node_to_fwnode(irq_parent); | ||
| 159 | of_node_put(irq_parent); | ||
| 160 | |||
| 161 | ret = bgpio_init(&priv->gpio_chip, dev, 4, | 158 | ret = bgpio_init(&priv->gpio_chip, dev, 4, |
| 162 | priv->base + GPIO_IDATA, | 159 | priv->base + GPIO_IDATA, |
| 163 | priv->base + GPIO_OSET, | 160 | priv->base + GPIO_OSET, |
| @@ -180,7 +177,7 @@ static int visconti_gpio_probe(struct platform_device *pdev) · 16 unmodified lines | |||
| 180 | 177 | ||
| 181 | girq = &priv->gpio_chip.irq; | 178 | girq = &priv->gpio_chip.irq; |
| 182 | girq->chip = irq_chip; | 179 | girq->chip = irq_chip; |
| 183 | girq->fwnode = fwnode; | 180 | girq->fwnode = of_node_to_fwnode(dev->of_node); |
| 184 | girq->parent_domain = parent; | 181 | girq->parent_domain = parent; |
| 185 | girq->child_to_parent_hwirq = visconti_gpio_child_to_parent_hwirq; | 182 | girq->child_to_parent_hwirq = visconti_gpio_child_to_parent_hwirq; |
| 186 | girq->populate_parent_alloc_arg = visconti_gpio_populate_parent_fwspec; | 183 | girq->populate_parent_alloc_arg = visconti_gpio_populate_parent_fwspec; |
| @@ -910,7 +910,7 @@ static void of_gpiochip_init_valid_mask(struct gpio_chip *chip) · 909 unmodified lines | |||
| 910 | i, &start); | 910 | i, &start); |
| 911 | of_property_read_u32_index(np, "gpio-reserved-ranges", | 911 | of_property_read_u32_index(np, "gpio-reserved-ranges", |
| 912 | i + 1, &count); | 912 | i + 1, &count); |
| 913 | if (start >= chip->ngpio || start + count >= chip->ngpio) | 913 | if (start >= chip->ngpio || start + count > chip->ngpio) |
| 914 | continue; | 914 | continue; |
| 915 | 915 | ||
| 916 | bitmap_clear(chip->valid_mask, start, count); | 916 | bitmap_clear(chip->valid_mask, start, count); |
| @@ -296,6 +296,7 @@ static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx, · 295 unmodified lines | |||
| 296 | { | 296 | { |
| 297 | struct amdgpu_device *adev = ctx->adev; | 297 | struct amdgpu_device *adev = ctx->adev; |
| 298 | enum amd_dpm_forced_level level; | 298 | enum amd_dpm_forced_level level; |
| 299 | u32 current_stable_pstate; | ||
| 299 | int r; | 300 | int r; |
| 300 | 301 | ||
| 301 | mutex_lock(&adev->pm.stable_pstate_ctx_lock); | 302 | mutex_lock(&adev->pm.stable_pstate_ctx_lock); |
| @@ -304,6 +305,10 @@ static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx, · 2 unmodified lines | |||
| 304 | goto done; | 305 | goto done; |
| 305 | } | 306 | } |
| 306 | 307 | ||
| 308 | r = amdgpu_ctx_get_stable_pstate(ctx, ¤t_stable_pstate); | ||
| 309 | if (r || (stable_pstate == current_stable_pstate)) | ||
| 310 | goto done; | ||
| 311 | |||
| 307 | switch (stable_pstate) { | 312 | switch (stable_pstate) { |
| 308 | case AMDGPU_CTX_STABLE_PSTATE_NONE: | 313 | case AMDGPU_CTX_STABLE_PSTATE_NONE: |
| 309 | level = AMD_DPM_FORCED_LEVEL_AUTO; | 314 | level = AMD_DPM_FORCED_LEVEL_AUTO; |
| @@ -2395,6 +2395,71 @@ static int amdgpu_pmops_restore(struct device *dev) · 2394 unmodified lines | |||
| 2395 | return amdgpu_device_resume(drm_dev, true); | 2395 | return amdgpu_device_resume(drm_dev, true); |
| 2396 | } | 2396 | } |
| 2397 | 2397 | ||
| 2398 | static int amdgpu_runtime_idle_check_display(struct device *dev) | ||
| 2399 | { | ||
| 2400 | struct pci_dev *pdev = to_pci_dev(dev); | ||
| 2401 | struct drm_device *drm_dev = pci_get_drvdata(pdev); | ||
| 2402 | struct amdgpu_device *adev = drm_to_adev(drm_dev); | ||
| 2403 | |||
| 2404 | if (adev->mode_info.num_crtc) { | ||
| 2405 | struct drm_connector *list_connector; | ||
| 2406 | struct drm_connector_list_iter iter; | ||
| 2407 | int ret = 0; | ||
| 2408 | |||
| 2409 | /* XXX: Return busy if any displays are connected to avoid | ||
| 2410 | * possible display wakeups after runtime resume due to | ||
| 2411 | * hotplug events in case any displays were connected while | ||
| 2412 | * the GPU was in suspend. Remove this once that is fixed. | ||
| 2413 | */ | ||
| 2414 | mutex_lock(&drm_dev->mode_config.mutex); | ||
| 2415 | drm_connector_list_iter_begin(drm_dev, &iter); | ||
| 2416 | drm_for_each_connector_iter(list_connector, &iter) { | ||
| 2417 | if (list_connector->status == connector_status_connected) { | ||
| 2418 | ret = -EBUSY; | ||
| 2419 | break; | ||
| 2420 | } | ||
| 2421 | } | ||
| 2422 | drm_connector_list_iter_end(&iter); | ||
| 2423 | mutex_unlock(&drm_dev->mode_config.mutex); | ||
| 2424 | |||
| 2425 | if (ret) | ||
| 2426 | return ret; | ||
| 2427 | |||
| 2428 | if (amdgpu_device_has_dc_support(adev)) { | ||
| 2429 | struct drm_crtc *crtc; | ||
| 2430 | |||
| 2431 | drm_for_each_crtc(crtc, drm_dev) { | ||
| 2432 | drm_modeset_lock(&crtc->mutex, NULL); | ||
| 2433 | if (crtc->state->active) | ||
| 2434 | ret = -EBUSY; | ||
| 2435 | drm_modeset_unlock(&crtc->mutex); | ||
| 2436 | if (ret < 0) | ||
| 2437 | break; | ||
| 2438 | } | ||
| 2439 | } else { | ||
| 2440 | mutex_lock(&drm_dev->mode_config.mutex); | ||
| 2441 | drm_modeset_lock(&drm_dev->mode_config.connection_mutex, NULL); | ||
| 2442 | |||
| 2443 | drm_connector_list_iter_begin(drm_dev, &iter); | ||
| 2444 | drm_for_each_connector_iter(list_connector, &iter) { | ||
| 2445 | if (list_connector->dpms == DRM_MODE_DPMS_ON) { | ||
| 2446 | ret = -EBUSY; | ||
| 2447 | break; | ||
| 2448 | } | ||
| 2449 | } | ||
| 2450 | |||
| 2451 | drm_connector_list_iter_end(&iter); | ||
| 2452 | |||
| 2453 | drm_modeset_unlock(&drm_dev->mode_config.connection_mutex); | ||
| 2454 | mutex_unlock(&drm_dev->mode_config.mutex); | ||
| 2455 | } | ||
| 2456 | if (ret) | ||
| 2457 | return ret; | ||
| 2458 | } | ||
| 2459 | |||
| 2460 | return 0; | ||
| 2461 | } | ||
| 2462 | |||
| 2398 | static int amdgpu_pmops_runtime_suspend(struct device *dev) | 2463 | static int amdgpu_pmops_runtime_suspend(struct device *dev) |
| 2399 | { | 2464 | { |
| 2400 | struct pci_dev *pdev = to_pci_dev(dev); | 2465 | struct pci_dev *pdev = to_pci_dev(dev); |
| @@ -2407,6 +2472,10 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev) · 6 unmodified lines | |||
| 2407 | return -EBUSY; | 2472 | return -EBUSY; |
| 2408 | } | 2473 | } |
| 2409 | 2474 | ||
| 2475 | ret = amdgpu_runtime_idle_check_display(dev); | ||
| 2476 | if (ret) | ||
| 2477 | return ret; | ||
| 2478 | |||
| 2410 | /* wait for all rings to drain before suspending */ | 2479 | /* wait for all rings to drain before suspending */ |
| 2411 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { | 2480 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { |
| 2412 | struct amdgpu_ring *ring = adev->rings[i]; | 2481 | struct amdgpu_ring *ring = adev->rings[i]; |
| @@ -2516,41 +2585,7 @@ static int amdgpu_pmops_runtime_idle(struct device *dev) · 103 unmodified lines | |||
| 2516 | return -EBUSY; | 2585 | return -EBUSY; |
| 2517 | } | 2586 | } |
| 2518 | 2587 | ||
| 2519 | if (amdgpu_device_has_dc_support(adev)) { | 2588 | ret = amdgpu_runtime_idle_check_display(dev); |
| 2520 | struct drm_crtc *crtc; | ||
| 2521 | |||
| 2522 | drm_for_each_crtc(crtc, drm_dev) { | ||
| 2523 | drm_modeset_lock(&crtc->mutex, NULL); | ||
| 2524 | if (crtc->state->active) | ||
| 2525 | ret = -EBUSY; | ||
| 2526 | drm_modeset_unlock(&crtc->mutex); | ||
| 2527 | if (ret < 0) | ||
| 2528 | break; | ||
| 2529 | } | ||
| 2530 | |||
| 2531 | } else { | ||
| 2532 | struct drm_connector *list_connector; | ||
| 2533 | struct drm_connector_list_iter iter; | ||
| 2534 | |||
| 2535 | mutex_lock(&drm_dev->mode_config.mutex); | ||
| 2536 | drm_modeset_lock(&drm_dev->mode_config.connection_mutex, NULL); | ||
| 2537 | |||
| 2538 | drm_connector_list_iter_begin(drm_dev, &iter); | ||
| 2539 | drm_for_each_connector_iter(list_connector, &iter) { | ||
| 2540 | if (list_connector->dpms == DRM_MODE_DPMS_ON) { | ||
| 2541 | ret = -EBUSY; | ||
| 2542 | break; | ||
| 2543 | } | ||
| 2544 | } | ||
| 2545 | |||
| 2546 | drm_connector_list_iter_end(&iter); | ||
| 2547 | |||
| 2548 | drm_modeset_unlock(&drm_dev->mode_config.connection_mutex); | ||
| 2549 | mutex_unlock(&drm_dev->mode_config.mutex); | ||
| 2550 | } | ||
| 2551 | |||
| 2552 | if (ret == -EBUSY) | ||
| 2553 | DRM_DEBUG_DRIVER("failing to power off - crtc active\n"); | ||
| 2554 | 2589 | ||
| 2555 | pm_runtime_mark_last_busy(dev); | 2590 | pm_runtime_mark_last_busy(dev); |
| 2556 | pm_runtime_autosuspend(dev); | 2591 | pm_runtime_autosuspend(dev); |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 25 | 25 | ||
| 26 | #include <drm/drm_drv.h> | 26 | #include <drm/drm_drv.h> |
| 27 | #include <xen/xen.h> | ||
| 27 | 28 | ||
| 28 | #include "amdgpu.h" | 29 | #include "amdgpu.h" |
| 29 | #include "amdgpu_ras.h" | 30 | #include "amdgpu_ras.h" |
| @@ -710,7 +711,8 @@ void amdgpu_detect_virtualization(struct amdgpu_device *adev) · 680 unmodified lines | |||
| 710 | adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV; | 711 | adev->virt.caps |= AMDGPU_SRIOV_CAPS_ENABLE_IOV; |
| 711 | 712 | ||
| 712 | if (!reg) { | 713 | if (!reg) { |
| 713 | if (is_virtual_machine()) /* passthrough mode exclus sriov mod */ | 714 | /* passthrough mode exclus sriov mod */ |
| 715 | if (is_virtual_machine() && !xen_initial_domain()) | ||
| 714 | adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE; | 716 | adev->virt.caps |= AMDGPU_PASSTHROUGH_MODE; |
| 715 | } | 717 | } |
| 716 | 718 | ||
| @@ -1151,6 +1151,16 @@ static int gmc_v10_0_set_clockgating_state(void *handle, · 1150 unmodified lines | |||
| 1151 | int r; | 1151 | int r; |
| 1152 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1152 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1153 | 1153 | ||
| 1154 | /* | ||
| 1155 | * The issue mmhub can't disconnect from DF with MMHUB clock gating being disabled | ||
| 1156 | * is a new problem observed at DF 3.0.3, however with the same suspend sequence not | ||
| 1157 | * seen any issue on the DF 3.0.2 series platform. | ||
| 1158 | */ | ||
| 1159 | if (adev->in_s0ix && adev->ip_versions[DF_HWIP][0] > IP_VERSION(3, 0, 2)) { | ||
| 1160 | dev_dbg(adev->dev, "keep mmhub clock gating being enabled for s0ix\n"); | ||
| 1161 | return 0; | ||
| 1162 | } | ||
| 1163 | |||
| 1154 | r = adev->mmhub.funcs->set_clockgating(adev, state); | 1164 | r = adev->mmhub.funcs->set_clockgating(adev, state); |
| 1155 | if (r) | 1165 | if (r) |
| 1156 | return r; | 1166 | return r; |
| @@ -81,6 +81,10 @@ · 80 unmodified lines | |||
| 81 | #include "mxgpu_vi.h" | 81 | #include "mxgpu_vi.h" |
| 82 | #include "amdgpu_dm.h" | 82 | #include "amdgpu_dm.h" |
| 83 | 83 | ||
| 84 | #if IS_ENABLED(CONFIG_X86) | ||
| 85 | #include <asm/intel-family.h> | ||
| 86 | #endif | ||
| 87 | |||
| 84 | #define ixPCIE_LC_L1_PM_SUBSTATE 0x100100C6 | 88 | #define ixPCIE_LC_L1_PM_SUBSTATE 0x100100C6 |
| 85 | #define PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK 0x00000001L | 89 | #define PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK 0x00000001L |
| 86 | #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK 0x00000002L | 90 | #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK 0x00000002L |
| @@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct amdgpu_device *adev) · 1047 unmodified lines | |||
| 1134 | WREG32_PCIE(ixPCIE_LC_CNTL, data); | 1138 | WREG32_PCIE(ixPCIE_LC_CNTL, data); |
| 1135 | } | 1139 | } |
| 1136 | 1140 | ||
| 1141 | static bool aspm_support_quirk_check(void) | ||
| 1142 | { | ||
| 1143 | #if IS_ENABLED(CONFIG_X86) | ||
| 1144 | struct cpuinfo_x86 *c = &cpu_data(0); | ||
| 1145 | |||
| 1146 | return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE); | ||
| 1147 | #else | ||
| 1148 | return true; | ||
| 1149 | #endif | ||
| 1150 | } | ||
| 1151 | |||
| 1137 | static void vi_program_aspm(struct amdgpu_device *adev) | 1152 | static void vi_program_aspm(struct amdgpu_device *adev) |
| 1138 | { | 1153 | { |
| 1139 | u32 data, data1, orig; | 1154 | u32 data, data1, orig; |
| 1140 | bool bL1SS = false; | 1155 | bool bL1SS = false; |
| 1141 | bool bClkReqSupport = true; | 1156 | bool bClkReqSupport = true; |
| 1142 | 1157 | ||
| 1143 | if (!amdgpu_device_should_use_aspm(adev)) | 1158 | if (!amdgpu_device_should_use_aspm(adev) || !aspm_support_quirk_check()) |
| 1144 | return; | 1159 | return; |
| 1145 | 1160 | ||
| 1146 | if (adev->flags & AMD_IS_APU || | 1161 | if (adev->flags & AMD_IS_APU || |
| @@ -130,19 +130,33 @@ void program_sh_mem_settings(struct device_queue_manager *dqm, · 129 unmodified lines | |||
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | static void increment_queue_count(struct device_queue_manager *dqm, | 132 | static void increment_queue_count(struct device_queue_manager *dqm, |
| 133 | enum kfd_queue_type type) | 133 | struct qcm_process_device *qpd, |
| 134 | struct queue *q) | ||
| 134 | { | 135 | { |
| 135 | dqm->active_queue_count++; | 136 | dqm->active_queue_count++; |
| 136 | if (type == KFD_QUEUE_TYPE_COMPUTE || type == KFD_QUEUE_TYPE_DIQ) | 137 | if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE || |
| 138 | q->properties.type == KFD_QUEUE_TYPE_DIQ) | ||
| 137 | dqm->active_cp_queue_count++; | 139 | dqm->active_cp_queue_count++; |
| 140 | |||
| 141 | if (q->properties.is_gws) { | ||
| 142 | dqm->gws_queue_count++; | ||
| 143 | qpd->mapped_gws_queue = true; | ||
| 144 | } | ||
| 138 | } | 145 | } |
| 139 | 146 | ||
| 140 | static void decrement_queue_count(struct device_queue_manager *dqm, | 147 | static void decrement_queue_count(struct device_queue_manager *dqm, |
| 141 | enum kfd_queue_type type) | 148 | struct qcm_process_device *qpd, |
| 149 | struct queue *q) | ||
| 142 | { | 150 | { |
| 143 | dqm->active_queue_count--; | 151 | dqm->active_queue_count--; |
| 144 | if (type == KFD_QUEUE_TYPE_COMPUTE || type == KFD_QUEUE_TYPE_DIQ) | 152 | if (q->properties.type == KFD_QUEUE_TYPE_COMPUTE || |
| 153 | q->properties.type == KFD_QUEUE_TYPE_DIQ) | ||
| 145 | dqm->active_cp_queue_count--; | 154 | dqm->active_cp_queue_count--; |
| 155 | |||
| 156 | if (q->properties.is_gws) { | ||
| 157 | dqm->gws_queue_count--; | ||
| 158 | qpd->mapped_gws_queue = false; | ||
| 159 | } | ||
| 146 | } | 160 | } |
| 147 | 161 | ||
| 148 | /* | 162 | /* |
| @@ -412,7 +426,7 @@ add_queue_to_list: · 263 unmodified lines | |||
| 412 | list_add(&q->list, &qpd->queues_list); | 426 | list_add(&q->list, &qpd->queues_list); |
| 413 | qpd->queue_count++; | 427 | qpd->queue_count++; |
| 414 | if (q->properties.is_active) | 428 | if (q->properties.is_active) |
| 415 | increment_queue_count(dqm, q->properties.type); | 429 | increment_queue_count(dqm, qpd, q); |
| 416 | 430 | ||
| 417 | /* | 431 | /* |
| 418 | * Unconditionally increment this counter, regardless of the queue's | 432 | * Unconditionally increment this counter, regardless of the queue's |
| @@ -601,13 +615,8 @@ static int destroy_queue_nocpsch_locked(struct device_queue_manager *dqm, · 182 unmodified lines | |||
| 601 | deallocate_vmid(dqm, qpd, q); | 615 | deallocate_vmid(dqm, qpd, q); |
| 602 | } | 616 | } |
| 603 | qpd->queue_count--; | 617 | qpd->queue_count--; |
| 604 | if (q->properties.is_active) { | 618 | if (q->properties.is_active) |
| 605 | decrement_queue_count(dqm, q->properties.type); | 619 | decrement_queue_count(dqm, qpd, q); |
| 606 | if (q->properties.is_gws) { | ||
| 607 | dqm->gws_queue_count--; | ||
| 608 | qpd->mapped_gws_queue = false; | ||
| 609 | } | ||
| 610 | } | ||
| 611 | 620 | ||
| 612 | return retval; | 621 | return retval; |
| 613 | } | 622 | } |
| @@ -700,12 +709,11 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q, · 86 unmodified lines | |||
| 700 | * dqm->active_queue_count to determine whether a new runlist must be | 709 | * dqm->active_queue_count to determine whether a new runlist must be |
| 701 | * uploaded. | 710 | * uploaded. |
| 702 | */ | 711 | */ |
| 703 | if (q->properties.is_active && !prev_active) | 712 | if (q->properties.is_active && !prev_active) { |
| 704 | increment_queue_count(dqm, q->properties.type); | 713 | increment_queue_count(dqm, &pdd->qpd, q); |
| 705 | else if (!q->properties.is_active && prev_active) | 714 | } else if (!q->properties.is_active && prev_active) { |
| 706 | decrement_queue_count(dqm, q->properties.type); | 715 | decrement_queue_count(dqm, &pdd->qpd, q); |
| 707 | 716 | } else if (q->gws && !q->properties.is_gws) { | |
| 708 | if (q->gws && !q->properties.is_gws) { | ||
| 709 | if (q->properties.is_active) { | 717 | if (q->properties.is_active) { |
| 710 | dqm->gws_queue_count++; | 718 | dqm->gws_queue_count++; |
| 711 | pdd->qpd.mapped_gws_queue = true; | 719 | pdd->qpd.mapped_gws_queue = true; |
| @@ -767,11 +775,7 @@ static int evict_process_queues_nocpsch(struct device_queue_manager *dqm, · 55 unmodified lines | |||
| 767 | mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type( | 775 | mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type( |
| 768 | q->properties.type)]; | 776 | q->properties.type)]; |
| 769 | q->properties.is_active = false; | 777 | q->properties.is_active = false; |
| 770 | decrement_queue_count(dqm, q->properties.type); | 778 | decrement_queue_count(dqm, qpd, q); |
| 771 | if (q->properties.is_gws) { | ||
| 772 | dqm->gws_queue_count--; | ||
| 773 | qpd->mapped_gws_queue = false; | ||
| 774 | } | ||
| 775 | 779 | ||
| 776 | if (WARN_ONCE(!dqm->sched_running, "Evict when stopped\n")) | 780 | if (WARN_ONCE(!dqm->sched_running, "Evict when stopped\n")) |
| 777 | continue; | 781 | continue; |
| @@ -817,7 +821,7 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm, · 39 unmodified lines | |||
| 817 | continue; | 821 | continue; |
| 818 | 822 | ||
| 819 | q->properties.is_active = false; | 823 | q->properties.is_active = false; |
| 820 | decrement_queue_count(dqm, q->properties.type); | 824 | decrement_queue_count(dqm, qpd, q); |
| 821 | } | 825 | } |
| 822 | pdd->last_evict_timestamp = get_jiffies_64(); | 826 | pdd->last_evict_timestamp = get_jiffies_64(); |
| 823 | retval = execute_queues_cpsch(dqm, | 827 | retval = execute_queues_cpsch(dqm, |
| @@ -888,11 +892,7 @@ static int restore_process_queues_nocpsch(struct device_queue_manager *dqm, · 64 unmodified lines | |||
| 888 | mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type( | 892 | mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type( |
| 889 | q->properties.type)]; | 893 | q->properties.type)]; |
| 890 | q->properties.is_active = true; | 894 | q->properties.is_active = true; |
| 891 | increment_queue_count(dqm, q->properties.type); | 895 | increment_queue_count(dqm, qpd, q); |
| 892 | if (q->properties.is_gws) { | ||
| 893 | dqm->gws_queue_count++; | ||
| 894 | qpd->mapped_gws_queue = true; | ||
| 895 | } | ||
| 896 | 896 | ||
| 897 | if (WARN_ONCE(!dqm->sched_running, "Restore when stopped\n")) | 897 | if (WARN_ONCE(!dqm->sched_running, "Restore when stopped\n")) |
| 898 | continue; | 898 | continue; |
| @@ -950,7 +950,7 @@ static int restore_process_queues_cpsch(struct device_queue_manager *dqm, · 51 unmodified lines | |||
| 950 | continue; | 950 | continue; |
| 951 | 951 | ||
| 952 | q->properties.is_active = true; | 952 | q->properties.is_active = true; |
| 953 | increment_queue_count(dqm, q->properties.type); | 953 | increment_queue_count(dqm, &pdd->qpd, q); |
| 954 | } | 954 | } |
| 955 | retval = execute_queues_cpsch(dqm, | 955 | retval = execute_queues_cpsch(dqm, |
| 956 | KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); | 956 | KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); |
| @@ -1378,7 +1378,7 @@ static int create_kernel_queue_cpsch(struct device_queue_manager *dqm, · 421 unmodified lines | |||
| 1378 | dqm->total_queue_count); | 1378 | dqm->total_queue_count); |
| 1379 | 1379 | ||
| 1380 | list_add(&kq->list, &qpd->priv_queue_list); | 1380 | list_add(&kq->list, &qpd->priv_queue_list); |
| 1381 | increment_queue_count(dqm, kq->queue->properties.type); | 1381 | increment_queue_count(dqm, qpd, kq->queue); |
| 1382 | qpd->is_debug = true; | 1382 | qpd->is_debug = true; |
| 1383 | execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); | 1383 | execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); |
| 1384 | dqm_unlock(dqm); | 1384 | dqm_unlock(dqm); |
| @@ -1392,7 +1392,7 @@ static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm, · 7 unmodified lines | |||
| 1392 | { | 1392 | { |
| 1393 | dqm_lock(dqm); | 1393 | dqm_lock(dqm); |
| 1394 | list_del(&kq->list); | 1394 | list_del(&kq->list); |
| 1395 | decrement_queue_count(dqm, kq->queue->properties.type); | 1395 | decrement_queue_count(dqm, qpd, kq->queue); |
| 1396 | qpd->is_debug = false; | 1396 | qpd->is_debug = false; |
| 1397 | execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0); | 1397 | execute_queues_cpsch(dqm, KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES, 0); |
| 1398 | /* | 1398 | /* |
| @@ -1467,7 +1467,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, · 68 unmodified lines | |||
| 1467 | qpd->queue_count++; | 1467 | qpd->queue_count++; |
| 1468 | 1468 | ||
| 1469 | if (q->properties.is_active) { | 1469 | if (q->properties.is_active) { |
| 1470 | increment_queue_count(dqm, q->properties.type); | 1470 | increment_queue_count(dqm, qpd, q); |
| 1471 | 1471 | ||
| 1472 | execute_queues_cpsch(dqm, | 1472 | execute_queues_cpsch(dqm, |
| 1473 | KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); | 1473 | KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); |
| @@ -1683,15 +1683,11 @@ static int destroy_queue_cpsch(struct device_queue_manager *dqm, · 209 unmodified lines | |||
| 1683 | list_del(&q->list); | 1683 | list_del(&q->list); |
| 1684 | qpd->queue_count--; | 1684 | qpd->queue_count--; |
| 1685 | if (q->properties.is_active) { | 1685 | if (q->properties.is_active) { |
| 1686 | decrement_queue_count(dqm, q->properties.type); | 1686 | decrement_queue_count(dqm, qpd, q); |
| 1687 | retval = execute_queues_cpsch(dqm, | 1687 | retval = execute_queues_cpsch(dqm, |
| 1688 | KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); | 1688 | KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0); |
| 1689 | if (retval == -ETIME) | 1689 | if (retval == -ETIME) |
| 1690 | qpd->reset_wavefronts = true; | 1690 | qpd->reset_wavefronts = true; |
| 1691 | if (q->properties.is_gws) { | ||
| 1692 | dqm->gws_queue_count--; | ||
| 1693 | qpd->mapped_gws_queue = false; | ||
| 1694 | } | ||
| 1695 | } | 1691 | } |
| 1696 | 1692 | ||
| 1697 | /* | 1693 | /* |
| @@ -1932,7 +1928,7 @@ static int process_termination_cpsch(struct device_queue_manager *dqm, · 234 unmodified lines | |||
| 1932 | /* Clean all kernel queues */ | 1928 | /* Clean all kernel queues */ |
| 1933 | list_for_each_entry_safe(kq, kq_next, &qpd->priv_queue_list, list) { | 1929 | list_for_each_entry_safe(kq, kq_next, &qpd->priv_queue_list, list) { |
| 1934 | list_del(&kq->list); | 1930 | list_del(&kq->list); |
| 1935 | decrement_queue_count(dqm, kq->queue->properties.type); | 1931 | decrement_queue_count(dqm, qpd, kq->queue); |
| 1936 | qpd->is_debug = false; | 1932 | qpd->is_debug = false; |
| 1937 | dqm->total_queue_count--; | 1933 | dqm->total_queue_count--; |
| 1938 | filter = KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES; | 1934 | filter = KFD_UNMAP_QUEUES_FILTER_ALL_QUEUES; |
| @@ -1945,13 +1941,8 @@ static int process_termination_cpsch(struct device_queue_manager *dqm, · 6 unmodified lines | |||
| 1945 | else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) | 1941 | else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI) |
| 1946 | deallocate_sdma_queue(dqm, q); | 1942 | deallocate_sdma_queue(dqm, q); |
| 1947 | 1943 | ||
| 1948 | if (q->properties.is_active) { | 1944 | if (q->properties.is_active) |
| 1949 | decrement_queue_count(dqm, q->properties.type); | 1945 | decrement_queue_count(dqm, qpd, q); |
| 1950 | if (q->properties.is_gws) { | ||
| 1951 | dqm->gws_queue_count--; | ||
| 1952 | qpd->mapped_gws_queue = false; | ||
| 1953 | } | ||
| 1954 | } | ||
| 1955 | 1946 | ||
| 1956 | dqm->total_queue_count--; | 1947 | dqm->total_queue_count--; |
| 1957 | } | 1948 | } |
| @@ -1103,7 +1103,7 @@ struct kfd_criu_queue_priv_data { · 1102 unmodified lines | |||
| 1103 | uint32_t priority; | 1103 | uint32_t priority; |
| 1104 | uint32_t q_percent; | 1104 | uint32_t q_percent; |
| 1105 | uint32_t doorbell_id; | 1105 | uint32_t doorbell_id; |
| 1106 | uint32_t is_gws; | 1106 | uint32_t gws; |
| 1107 | uint32_t sdma_id; | 1107 | uint32_t sdma_id; |
| 1108 | uint32_t eop_ring_buffer_size; | 1108 | uint32_t eop_ring_buffer_size; |
| 1109 | uint32_t ctx_save_restore_area_size; | 1109 | uint32_t ctx_save_restore_area_size; |
| @@ -636,6 +636,8 @@ static int criu_checkpoint_queue(struct kfd_process_device *pdd, · 635 unmodified lines | |||
| 636 | q_data->ctx_save_restore_area_size = | 636 | q_data->ctx_save_restore_area_size = |
| 637 | q->properties.ctx_save_restore_area_size; | 637 | q->properties.ctx_save_restore_area_size; |
| 638 | 638 | ||
| 639 | q_data->gws = !!q->gws; | ||
| 640 | |||
| 639 | ret = pqm_checkpoint_mqd(&pdd->process->pqm, q->properties.queue_id, mqd, ctl_stack); | 641 | ret = pqm_checkpoint_mqd(&pdd->process->pqm, q->properties.queue_id, mqd, ctl_stack); |
| 640 | if (ret) { | 642 | if (ret) { |
| 641 | pr_err("Failed checkpoint queue_mqd (%d)\n", ret); | 643 | pr_err("Failed checkpoint queue_mqd (%d)\n", ret); |
| @@ -743,7 +745,6 @@ static void set_queue_properties_from_criu(struct queue_properties *qp, · 101 unmodified lines | |||
| 743 | struct kfd_criu_queue_priv_data *q_data) | 745 | struct kfd_criu_queue_priv_data *q_data) |
| 744 | { | 746 | { |
| 745 | qp->is_interop = false; | 747 | qp->is_interop = false; |
| 746 | qp->is_gws = q_data->is_gws; | ||
| 747 | qp->queue_percent = q_data->q_percent; | 748 | qp->queue_percent = q_data->q_percent; |
| 748 | qp->priority = q_data->priority; | 749 | qp->priority = q_data->priority; |
| 749 | qp->queue_address = q_data->q_address; | 750 | qp->queue_address = q_data->q_address; |
| @@ -826,12 +827,15 @@ int kfd_criu_restore_queue(struct kfd_process *p, · 76 unmodified lines | |||
| 826 | NULL); | 827 | NULL); |
| 827 | if (ret) { | 828 | if (ret) { |
| 828 | pr_err("Failed to create new queue err:%d\n", ret); | 829 | pr_err("Failed to create new queue err:%d\n", ret); |
| 829 | ret = -EINVAL; | 830 | goto exit; |
| 830 | } | 831 | } |
| 831 | 832 | ||
| 833 | if (q_data->gws) | ||
| 834 | ret = pqm_set_gws(&p->pqm, q_data->q_id, pdd->dev->gws); | ||
| 835 | |||
| 832 | exit: | 836 | exit: |
| 833 | if (ret) | 837 | if (ret) |
| 834 | pr_err("Failed to create queue (%d)\n", ret); | 838 | pr_err("Failed to restore queue (%d)\n", ret); |
| 835 | else | 839 | else |
| 836 | pr_debug("Queue id %d was restored successfully\n", queue_id); | 840 | pr_debug("Queue id %d was restored successfully\n", queue_id); |
| 837 | 841 | ||
| @@ -4440,7 +4440,7 @@ static void dp_test_get_audio_test_data(struct dc_link *link, bool disable_video · 4439 unmodified lines | |||
| 4440 | &dpcd_pattern_type.value, | 4440 | &dpcd_pattern_type.value, |
| 4441 | sizeof(dpcd_pattern_type)); | 4441 | sizeof(dpcd_pattern_type)); |
| 4442 | 4442 | ||
| 4443 | channel_count = dpcd_test_mode.bits.channel_count + 1; | 4443 | channel_count = min(dpcd_test_mode.bits.channel_count + 1, AUDIO_CHANNELS_COUNT); |
| 4444 | 4444 | ||
| 4445 | // read pattern periods for requested channels when sawTooth pattern is requested | 4445 | // read pattern periods for requested channels when sawTooth pattern is requested |
| 4446 | if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH || | 4446 | if (dpcd_pattern_type.value == AUDIO_TEST_PATTERN_SAWTOOTH || |
| @@ -997,6 +997,7 @@ static struct clock_source *dcn21_clock_source_create( · 996 unmodified lines | |||
| 997 | return &clk_src->base; | 997 | return &clk_src->base; |
| 998 | } | 998 | } |
| 999 | 999 | ||
| 1000 | kfree(clk_src); | ||
| 1000 | BREAK_TO_DEBUGGER(); | 1001 | BREAK_TO_DEBUGGER(); |
| 1001 | return NULL; | 1002 | return NULL; |
| 1002 | } | 1003 | } |
| @@ -153,9 +153,4 @@ void dcn31_hw_sequencer_construct(struct dc *dc) · 152 unmodified lines | |||
| 153 | dc->hwss.init_hw = dcn20_fpga_init_hw; | 153 | dc->hwss.init_hw = dcn20_fpga_init_hw; |
| 154 | dc->hwseq->funcs.init_pipes = NULL; | 154 | dc->hwseq->funcs.init_pipes = NULL; |
| 155 | } | 155 | } |
| 156 | if (dc->debug.disable_z10) { | ||
| 157 | /*hw not support z10 or sw disable it*/ | ||
| 158 | dc->hwss.z10_restore = NULL; | ||
| 159 | dc->hwss.z10_save_init = NULL; | ||
| 160 | } | ||
| 161 | } | 156 | } |
| @@ -427,6 +427,7 @@ int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors senso · 426 unmodified lines | |||
| 427 | void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev) | 427 | void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev) |
| 428 | { | 428 | { |
| 429 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; | 429 | const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs; |
| 430 | int i; | ||
| 430 | 431 | ||
| 431 | if (!adev->pm.dpm_enabled) | 432 | if (!adev->pm.dpm_enabled) |
| 432 | return; | 433 | return; |
| @@ -434,6 +435,15 @@ void amdgpu_dpm_compute_clocks(struct amdgpu_device *adev) · 1 unmodified line | |||
| 434 | if (!pp_funcs->pm_compute_clocks) | 435 | if (!pp_funcs->pm_compute_clocks) |
| 435 | return; | 436 | return; |
| 436 | 437 | ||
| 438 | if (adev->mode_info.num_crtc) | ||
| 439 | amdgpu_display_bandwidth_update(adev); | ||
| 440 | |||
| 441 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { | ||
| 442 | struct amdgpu_ring *ring = adev->rings[i]; | ||
| 443 | if (ring && ring->sched.ready) | ||
| 444 | amdgpu_fence_wait_empty(ring); | ||
| 445 | } | ||
| 446 | |||
| 437 | mutex_lock(&adev->pm.mutex); | 447 | mutex_lock(&adev->pm.mutex); |
| 438 | pp_funcs->pm_compute_clocks(adev->powerplay.pp_handle); | 448 | pp_funcs->pm_compute_clocks(adev->powerplay.pp_handle); |
| 439 | mutex_unlock(&adev->pm.mutex); | 449 | mutex_unlock(&adev->pm.mutex); |
| @@ -443,6 +453,20 @@ void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable) · 3 unmodified lines | |||
| 443 | { | 453 | { |
| 444 | int ret = 0; | 454 | int ret = 0; |
| 445 | 455 | ||
| 456 | if (adev->family == AMDGPU_FAMILY_SI) { | ||
| 457 | mutex_lock(&adev->pm.mutex); | ||
| 458 | if (enable) { | ||
| 459 | adev->pm.dpm.uvd_active = true; | ||
| 460 | adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD; | ||
| 461 | } else { | ||
| 462 | adev->pm.dpm.uvd_active = false; | ||
| 463 | } | ||
| 464 | mutex_unlock(&adev->pm.mutex); | ||
| 465 | |||
| 466 | amdgpu_dpm_compute_clocks(adev); | ||
| 467 | return; | ||
| 468 | } | ||
| 469 | |||
| 446 | ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable); | 470 | ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable); |
| 447 | if (ret) | 471 | if (ret) |
| 448 | DRM_ERROR("Dpm %s uvd failed, ret = %d. \n", | 472 | DRM_ERROR("Dpm %s uvd failed, ret = %d. \n", |
| @@ -453,6 +477,21 @@ void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable) · 4 unmodified lines | |||
| 453 | { | 477 | { |
| 454 | int ret = 0; | 478 | int ret = 0; |
| 455 | 479 | ||
| 480 | if (adev->family == AMDGPU_FAMILY_SI) { | ||
| 481 | mutex_lock(&adev->pm.mutex); | ||
| 482 | if (enable) { | ||
| 483 | adev->pm.dpm.vce_active = true; | ||
| 484 | /* XXX select vce level based on ring/task */ | ||
| 485 | adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL; | ||
| 486 | } else { | ||
| 487 | adev->pm.dpm.vce_active = false; | ||
| 488 | } | ||
| 489 | mutex_unlock(&adev->pm.mutex); | ||
| 490 | |||
| 491 | amdgpu_dpm_compute_clocks(adev); | ||
| 492 | return; | ||
| 493 | } | ||
| 494 | |||
| 456 | ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable); | 495 | ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable); |
| 457 | if (ret) | 496 | if (ret) |
| 458 | DRM_ERROR("Dpm %s vce failed, ret = %d. \n", | 497 | DRM_ERROR("Dpm %s vce failed, ret = %d. \n", |
| @@ -1028,16 +1028,6 @@ static int amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev) · 1027 unmodified lines | |||
| 1028 | void amdgpu_legacy_dpm_compute_clocks(void *handle) | 1028 | void amdgpu_legacy_dpm_compute_clocks(void *handle) |
| 1029 | { | 1029 | { |
| 1030 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 1030 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1031 | int i = 0; | ||
| 1032 | |||
| 1033 | if (adev->mode_info.num_crtc) | ||
| 1034 | amdgpu_display_bandwidth_update(adev); | ||
| 1035 | |||
| 1036 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { | ||
| 1037 | struct amdgpu_ring *ring = adev->rings[i]; | ||
| 1038 | if (ring && ring->sched.ready) | ||
| 1039 | amdgpu_fence_wait_empty(ring); | ||
| 1040 | } | ||
| 1041 | 1031 | ||
| 1042 | amdgpu_dpm_get_active_displays(adev); | 1032 | amdgpu_dpm_get_active_displays(adev); |
| 1043 | 1033 | ||
| @@ -3892,40 +3892,6 @@ static int si_set_boot_state(struct amdgpu_device *adev) · 3891 unmodified lines | |||
| 3892 | } | 3892 | } |
| 3893 | #endif | 3893 | #endif |
| 3894 | 3894 | ||
| 3895 | static int si_set_powergating_by_smu(void *handle, | ||
| 3896 | uint32_t block_type, | ||
| 3897 | bool gate) | ||
| 3898 | { | ||
| 3899 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | ||
| 3900 | |||
| 3901 | switch (block_type) { | ||
| 3902 | case AMD_IP_BLOCK_TYPE_UVD: | ||
| 3903 | if (!gate) { | ||
| 3904 | adev->pm.dpm.uvd_active = true; | ||
| 3905 | adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD; | ||
| 3906 | } else { | ||
| 3907 | adev->pm.dpm.uvd_active = false; | ||
| 3908 | } | ||
| 3909 | |||
| 3910 | amdgpu_legacy_dpm_compute_clocks(handle); | ||
| 3911 | break; | ||
| 3912 | case AMD_IP_BLOCK_TYPE_VCE: | ||
| 3913 | if (!gate) { | ||
| 3914 | adev->pm.dpm.vce_active = true; | ||
| 3915 | /* XXX select vce level based on ring/task */ | ||
| 3916 | adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL; | ||
| 3917 | } else { | ||
| 3918 | adev->pm.dpm.vce_active = false; | ||
| 3919 | } | ||
| 3920 | |||
| 3921 | amdgpu_legacy_dpm_compute_clocks(handle); | ||
| 3922 | break; | ||
| 3923 | default: | ||
| 3924 | break; | ||
| 3925 | } | ||
| 3926 | return 0; | ||
| 3927 | } | ||
| 3928 | |||
| 3929 | static int si_set_sw_state(struct amdgpu_device *adev) | 3895 | static int si_set_sw_state(struct amdgpu_device *adev) |
| 3930 | { | 3896 | { |
| 3931 | return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_SwitchToSwState) == PPSMC_Result_OK) ? | 3897 | return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_SwitchToSwState) == PPSMC_Result_OK) ? |
| @@ -8125,7 +8091,6 @@ static const struct amd_pm_funcs si_dpm_funcs = { · 4193 unmodified lines | |||
| 8125 | .print_power_state = &si_dpm_print_power_state, | 8091 | .print_power_state = &si_dpm_print_power_state, |
| 8126 | .debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level, | 8092 | .debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level, |
| 8127 | .force_performance_level = &si_dpm_force_performance_level, | 8093 | .force_performance_level = &si_dpm_force_performance_level, |
| 8128 | .set_powergating_by_smu = &si_set_powergating_by_smu, | ||
| 8129 | .vblank_too_short = &si_dpm_vblank_too_short, | 8094 | .vblank_too_short = &si_dpm_vblank_too_short, |
| 8130 | .set_fan_control_mode = &si_dpm_set_fan_control_mode, | 8095 | .set_fan_control_mode = &si_dpm_set_fan_control_mode, |
| 8131 | .get_fan_control_mode = &si_dpm_get_fan_control_mode, | 8096 | .get_fan_control_mode = &si_dpm_get_fan_control_mode, |
| @@ -1487,16 +1487,6 @@ static void pp_pm_compute_clocks(void *handle) · 1486 unmodified lines | |||
| 1487 | { | 1487 | { |
| 1488 | struct pp_hwmgr *hwmgr = handle; | 1488 | struct pp_hwmgr *hwmgr = handle; |
| 1489 | struct amdgpu_device *adev = hwmgr->adev; | 1489 | struct amdgpu_device *adev = hwmgr->adev; |
| 1490 | int i = 0; | ||
| 1491 | |||
| 1492 | if (adev->mode_info.num_crtc) | ||
| 1493 | amdgpu_display_bandwidth_update(adev); | ||
| 1494 | |||
| 1495 | for (i = 0; i < AMDGPU_MAX_RINGS; i++) { | ||
| 1496 | struct amdgpu_ring *ring = adev->rings[i]; | ||
| 1497 | if (ring && ring->sched.ready) | ||
| 1498 | amdgpu_fence_wait_empty(ring); | ||
| 1499 | } | ||
| 1500 | 1490 | ||
| 1501 | if (!amdgpu_device_has_dc_support(adev)) { | 1491 | if (!amdgpu_device_has_dc_support(adev)) { |
| 1502 | amdgpu_dpm_get_active_displays(adev); | 1492 | amdgpu_dpm_get_active_displays(adev); |
| @@ -1351,14 +1351,8 @@ static int smu_disable_dpms(struct smu_context *smu) · 1350 unmodified lines | |||
| 1351 | { | 1351 | { |
| 1352 | struct amdgpu_device *adev = smu->adev; | 1352 | struct amdgpu_device *adev = smu->adev; |
| 1353 | int ret = 0; | 1353 | int ret = 0; |
| 1354 | /* | ||
| 1355 | * TODO: (adev->in_suspend && !adev->in_s0ix) is added to pair | ||
| 1356 | * the workaround which always reset the asic in suspend. | ||
| 1357 | * It's likely that workaround will be dropped in the future. | ||
| 1358 | * Then the change here should be dropped together. | ||
| 1359 | */ | ||
| 1360 | bool use_baco = !smu->is_apu && | 1354 | bool use_baco = !smu->is_apu && |
| 1361 | (((amdgpu_in_reset(adev) || (adev->in_suspend && !adev->in_s0ix)) && | 1355 | ((amdgpu_in_reset(adev) && |
| 1362 | (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) || | 1356 | (amdgpu_asic_reset_method(adev) == AMD_RESET_METHOD_BACO)) || |
| 1363 | ((adev->in_runpm || adev->in_s4) && amdgpu_asic_supports_baco(adev))); | 1357 | ((adev->in_runpm || adev->in_s4) && amdgpu_asic_supports_baco(adev))); |
| 1364 | 1358 | ||
| @@ -78,6 +78,7 @@ config DRM_ITE_IT6505 · 77 unmodified lines | |||
| 78 | tristate "ITE IT6505 DisplayPort bridge" | 78 | tristate "ITE IT6505 DisplayPort bridge" |
| 79 | depends on OF | 79 | depends on OF |
| 80 | select DRM_KMS_HELPER | 80 | select DRM_KMS_HELPER |
| 81 | select DRM_DP_HELPER | ||
| 81 | select EXTCON | 82 | select EXTCON |
| 82 | help | 83 | help |
| 83 | ITE IT6505 DisplayPort bridge chip driver. | 84 | ITE IT6505 DisplayPort bridge chip driver. |
| @@ -97,6 +97,14 @@ · 96 unmodified lines | |||
| 97 | 97 | ||
| 98 | #define INTEL_EDP_BRIGHTNESS_OPTIMIZATION_1 0x359 | 98 | #define INTEL_EDP_BRIGHTNESS_OPTIMIZATION_1 0x359 |
| 99 | 99 | ||
| 100 | enum intel_dp_aux_backlight_modparam { | ||
| 101 | INTEL_DP_AUX_BACKLIGHT_AUTO = -1, | ||
| 102 | INTEL_DP_AUX_BACKLIGHT_OFF = 0, | ||
| 103 | INTEL_DP_AUX_BACKLIGHT_ON = 1, | ||
| 104 | INTEL_DP_AUX_BACKLIGHT_FORCE_VESA = 2, | ||
| 105 | INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL = 3, | ||
| 106 | }; | ||
| 107 | |||
| 100 | /* Intel EDP backlight callbacks */ | 108 | /* Intel EDP backlight callbacks */ |
| 101 | static bool | 109 | static bool |
| 102 | intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector) | 110 | intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector) |
| @@ -126,6 +134,24 @@ intel_dp_aux_supports_hdr_backlight(struct intel_connector *connector) · 23 unmodified lines | |||
| 126 | return false; | 134 | return false; |
| 127 | } | 135 | } |
| 128 | 136 | ||
| 137 | /* | ||
| 138 | * If we don't have HDR static metadata there is no way to | ||
| 139 | * runtime detect used range for nits based control. For now | ||
| 140 | * do not use Intel proprietary eDP backlight control if we | ||
| 141 | * don't have this data in panel EDID. In case we find panel | ||
| 142 | * which supports only nits based control, but doesn't provide | ||
| 143 | * HDR static metadata we need to start maintaining table of | ||
| 144 | * ranges for such panels. | ||
| 145 | */ | ||
| 146 | if (i915->params.enable_dpcd_backlight != INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL && | ||
| 147 | !(connector->base.hdr_sink_metadata.hdmi_type1.metadata_type & | ||
| 148 | BIT(HDMI_STATIC_METADATA_TYPE1))) { | ||
| 149 | drm_info(&i915->drm, | ||
| 150 | "Panel is missing HDR static metadata. Possible support for Intel HDR backlight interface is not used. If your backlight controls don't work try booting with i915.enable_dpcd_backlight=%d. needs this, please file a _new_ bug report on drm/i915, see " FDO_BUG_URL " for details.\n", | ||
| 151 | INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL); | ||
| 152 | return false; | ||
| 153 | } | ||
| 154 | |||
| 129 | panel->backlight.edp.intel.sdr_uses_aux = | 155 | panel->backlight.edp.intel.sdr_uses_aux = |
| 130 | tcon_cap[2] & INTEL_EDP_SDR_TCON_BRIGHTNESS_AUX_CAP; | 156 | tcon_cap[2] & INTEL_EDP_SDR_TCON_BRIGHTNESS_AUX_CAP; |
| 131 | 157 | ||
| @@ -413,14 +439,6 @@ static const struct intel_panel_bl_funcs intel_dp_vesa_bl_funcs = { · 281 unmodified lines | |||
| 413 | .get = intel_dp_aux_vesa_get_backlight, | 439 | .get = intel_dp_aux_vesa_get_backlight, |
| 414 | }; | 440 | }; |
| 415 | 441 | ||
| 416 | enum intel_dp_aux_backlight_modparam { | ||
| 417 | INTEL_DP_AUX_BACKLIGHT_AUTO = -1, | ||
| 418 | INTEL_DP_AUX_BACKLIGHT_OFF = 0, | ||
| 419 | INTEL_DP_AUX_BACKLIGHT_ON = 1, | ||
| 420 | INTEL_DP_AUX_BACKLIGHT_FORCE_VESA = 2, | ||
| 421 | INTEL_DP_AUX_BACKLIGHT_FORCE_INTEL = 3, | ||
| 422 | }; | ||
| 423 | |||
| 424 | int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) | 442 | int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector) |
| 425 | { | 443 | { |
| 426 | struct drm_device *dev = connector->base.dev; | 444 | struct drm_device *dev = connector->base.dev; |
| @@ -1037,7 +1037,7 @@ static int intel_fbc_check_plane(struct intel_atomic_state *state, · 1036 unmodified lines | |||
| 1037 | struct intel_plane_state *plane_state = | 1037 | struct intel_plane_state *plane_state = |
| 1038 | intel_atomic_get_new_plane_state(state, plane); | 1038 | intel_atomic_get_new_plane_state(state, plane); |
| 1039 | const struct drm_framebuffer *fb = plane_state->hw.fb; | 1039 | const struct drm_framebuffer *fb = plane_state->hw.fb; |
| 1040 | struct intel_crtc *crtc = to_intel_crtc(plane_state->uapi.crtc); | 1040 | struct intel_crtc *crtc = to_intel_crtc(plane_state->hw.crtc); |
| 1041 | const struct intel_crtc_state *crtc_state; | 1041 | const struct intel_crtc_state *crtc_state; |
| 1042 | struct intel_fbc *fbc = plane->fbc; | 1042 | struct intel_fbc *fbc = plane->fbc; |
| 1043 | 1043 | ||
| @@ -4345,12 +4345,12 @@ · 4344 unmodified lines | |||
| 4345 | #define _DSPAADDR 0x70184 | 4345 | #define _DSPAADDR 0x70184 |
| 4346 | #define _DSPASTRIDE 0x70188 | 4346 | #define _DSPASTRIDE 0x70188 |
| 4347 | #define _DSPAPOS 0x7018C /* reserved */ | 4347 | #define _DSPAPOS 0x7018C /* reserved */ |
| 4348 | #define DISP_POS_Y_MASK REG_GENMASK(31, 0) | 4348 | #define DISP_POS_Y_MASK REG_GENMASK(31, 16) |
| 4349 | #define DISP_POS_Y(y) REG_FIELD_PREP(DISP_POS_Y_MASK, (y)) | 4349 | #define DISP_POS_Y(y) REG_FIELD_PREP(DISP_POS_Y_MASK, (y)) |
| 4350 | #define DISP_POS_X_MASK REG_GENMASK(15, 0) | 4350 | #define DISP_POS_X_MASK REG_GENMASK(15, 0) |
| 4351 | #define DISP_POS_X(x) REG_FIELD_PREP(DISP_POS_X_MASK, (x)) | 4351 | #define DISP_POS_X(x) REG_FIELD_PREP(DISP_POS_X_MASK, (x)) |
| 4352 | #define _DSPASIZE 0x70190 | 4352 | #define _DSPASIZE 0x70190 |
| 4353 | #define DISP_HEIGHT_MASK REG_GENMASK(31, 0) | 4353 | #define DISP_HEIGHT_MASK REG_GENMASK(31, 16) |
| 4354 | #define DISP_HEIGHT(h) REG_FIELD_PREP(DISP_HEIGHT_MASK, (h)) | 4354 | #define DISP_HEIGHT(h) REG_FIELD_PREP(DISP_HEIGHT_MASK, (h)) |
| 4355 | #define DISP_WIDTH_MASK REG_GENMASK(15, 0) | 4355 | #define DISP_WIDTH_MASK REG_GENMASK(15, 0) |
| 4356 | #define DISP_WIDTH(w) REG_FIELD_PREP(DISP_WIDTH_MASK, (w)) | 4356 | #define DISP_WIDTH(w) REG_FIELD_PREP(DISP_WIDTH_MASK, (w)) |
| @@ -5152,7 +5152,7 @@ · 795 unmodified lines | |||
| 5152 | #define _SEL_FETCH_PLANE_BASE_6_A 0x70940 | 5152 | #define _SEL_FETCH_PLANE_BASE_6_A 0x70940 |
| 5153 | #define _SEL_FETCH_PLANE_BASE_7_A 0x70960 | 5153 | #define _SEL_FETCH_PLANE_BASE_7_A 0x70960 |
| 5154 | #define _SEL_FETCH_PLANE_BASE_CUR_A 0x70880 | 5154 | #define _SEL_FETCH_PLANE_BASE_CUR_A 0x70880 |
| 5155 | #define _SEL_FETCH_PLANE_BASE_1_B 0x70990 | 5155 | #define _SEL_FETCH_PLANE_BASE_1_B 0x71890 |
| 5156 | 5156 | ||
| 5157 | #define _SEL_FETCH_PLANE_BASE_A(plane) _PICK(plane, \ | 5157 | #define _SEL_FETCH_PLANE_BASE_A(plane) _PICK(plane, \ |
| 5158 | _SEL_FETCH_PLANE_BASE_1_A, \ | 5158 | _SEL_FETCH_PLANE_BASE_1_A, \ |
| @@ -1605,17 +1605,17 @@ void i915_vma_close(struct i915_vma *vma) · 1604 unmodified lines | |||
| 1605 | 1605 | ||
| 1606 | static void __i915_vma_remove_closed(struct i915_vma *vma) | 1606 | static void __i915_vma_remove_closed(struct i915_vma *vma) |
| 1607 | { | 1607 | { |
| 1608 | struct intel_gt *gt = vma->vm->gt; | ||
| 1609 | |||
| 1610 | spin_lock_irq(>->closed_lock); | ||
| 1611 | list_del_init(&vma->closed_link); | 1608 | list_del_init(&vma->closed_link); |
| 1612 | spin_unlock_irq(>->closed_lock); | ||
| 1613 | } | 1609 | } |
| 1614 | 1610 | ||
| 1615 | void i915_vma_reopen(struct i915_vma *vma) | 1611 | void i915_vma_reopen(struct i915_vma *vma) |
| 1616 | { | 1612 | { |
| 1613 | struct intel_gt *gt = vma->vm->gt; | ||
| 1614 | |||
| 1615 | spin_lock_irq(>->closed_lock); | ||
| 1617 | if (i915_vma_is_closed(vma)) | 1616 | if (i915_vma_is_closed(vma)) |
| 1618 | __i915_vma_remove_closed(vma); | 1617 | __i915_vma_remove_closed(vma); |
| 1618 | spin_unlock_irq(>->closed_lock); | ||
| 1619 | } | 1619 | } |
| 1620 | 1620 | ||
| 1621 | void i915_vma_release(struct kref *ref) | 1621 | void i915_vma_release(struct kref *ref) |
| @@ -1641,6 +1641,7 @@ static void force_unbind(struct i915_vma *vma) · 19 unmodified lines | |||
| 1641 | static void release_references(struct i915_vma *vma) | 1641 | static void release_references(struct i915_vma *vma) |
| 1642 | { | 1642 | { |
| 1643 | struct drm_i915_gem_object *obj = vma->obj; | 1643 | struct drm_i915_gem_object *obj = vma->obj; |
| 1644 | struct intel_gt *gt = vma->vm->gt; | ||
| 1644 | 1645 | ||
| 1645 | GEM_BUG_ON(i915_vma_is_active(vma)); | 1646 | GEM_BUG_ON(i915_vma_is_active(vma)); |
| 1646 | 1647 | ||
| @@ -1650,7 +1651,9 @@ static void release_references(struct i915_vma *vma) · 3 unmodified lines | |||
| 1650 | rb_erase(&vma->obj_node, &obj->vma.tree); | 1651 | rb_erase(&vma->obj_node, &obj->vma.tree); |
| 1651 | spin_unlock(&obj->vma.lock); | 1652 | spin_unlock(&obj->vma.lock); |
| 1652 | 1653 | ||
| 1654 | spin_lock_irq(>->closed_lock); | ||
| 1653 | __i915_vma_remove_closed(vma); | 1655 | __i915_vma_remove_closed(vma); |
| 1656 | spin_unlock_irq(>->closed_lock); | ||
| 1654 | 1657 | ||
| 1655 | __i915_vma_put(vma); | 1658 | __i915_vma_put(vma); |
| 1656 | } | 1659 | } |
| @@ -580,12 +580,6 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data) · 579 unmodified lines | |||
| 580 | dp->dp_display.connector_type, state); | 580 | dp->dp_display.connector_type, state); |
| 581 | mutex_unlock(&dp->event_mutex); | 581 | mutex_unlock(&dp->event_mutex); |
| 582 | 582 | ||
| 583 | /* | ||
| 584 | * add fail safe mode outside event_mutex scope | ||
| 585 | * to avoid potiential circular lock with drm thread | ||
| 586 | */ | ||
| 587 | dp_panel_add_fail_safe_mode(dp->dp_display.connector); | ||
| 588 | |||
| 589 | /* uevent will complete connection part */ | 583 | /* uevent will complete connection part */ |
| 590 | return 0; | 584 | return 0; |
| 591 | }; | 585 | }; |
| @@ -151,15 +151,6 @@ static int dp_panel_update_modes(struct drm_connector *connector, · 150 unmodified lines | |||
| 151 | return rc; | 151 | return rc; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | void dp_panel_add_fail_safe_mode(struct drm_connector *connector) | ||
| 155 | { | ||
| 156 | /* fail safe edid */ | ||
| 157 | mutex_lock(&connector->dev->mode_config.mutex); | ||
| 158 | if (drm_add_modes_noedid(connector, 640, 480)) | ||
| 159 | drm_set_preferred_mode(connector, 640, 480); | ||
| 160 | mutex_unlock(&connector->dev->mode_config.mutex); | ||
| 161 | } | ||
| 162 | |||
| 163 | int dp_panel_read_sink_caps(struct dp_panel *dp_panel, | 154 | int dp_panel_read_sink_caps(struct dp_panel *dp_panel, |
| 164 | struct drm_connector *connector) | 155 | struct drm_connector *connector) |
| 165 | { | 156 | { |
| @@ -215,8 +206,6 @@ int dp_panel_read_sink_caps(struct dp_panel *dp_panel, · 49 unmodified lines | |||
| 215 | rc = -ETIMEDOUT; | 206 | rc = -ETIMEDOUT; |
| 216 | goto end; | 207 | goto end; |
| 217 | } | 208 | } |
| 218 | |||
| 219 | dp_panel_add_fail_safe_mode(connector); | ||
| 220 | } | 209 | } |
| 221 | 210 | ||
| 222 | if (panel->aux_cfg_update_done) { | 211 | if (panel->aux_cfg_update_done) { |
| @@ -59,7 +59,6 @@ int dp_panel_init_panel_info(struct dp_panel *dp_panel); · 58 unmodified lines | |||
| 59 | int dp_panel_deinit(struct dp_panel *dp_panel); | 59 | int dp_panel_deinit(struct dp_panel *dp_panel); |
| 60 | int dp_panel_timing_cfg(struct dp_panel *dp_panel); | 60 | int dp_panel_timing_cfg(struct dp_panel *dp_panel); |
| 61 | void dp_panel_dump_regs(struct dp_panel *dp_panel); | 61 | void dp_panel_dump_regs(struct dp_panel *dp_panel); |
| 62 | void dp_panel_add_fail_safe_mode(struct drm_connector *connector); | ||
| 63 | int dp_panel_read_sink_caps(struct dp_panel *dp_panel, | 62 | int dp_panel_read_sink_caps(struct dp_panel *dp_panel, |
| 64 | struct drm_connector *connector); | 63 | struct drm_connector *connector); |
| 65 | u32 dp_panel_get_mode_bpp(struct dp_panel *dp_panel, u32 mode_max_bpp, | 64 | u32 dp_panel_get_mode_bpp(struct dp_panel *dp_panel, u32 mode_max_bpp, |
| @@ -46,8 +46,9 @@ static bool · 45 unmodified lines | |||
| 46 | nouveau_get_backlight_name(char backlight_name[BL_NAME_SIZE], | 46 | nouveau_get_backlight_name(char backlight_name[BL_NAME_SIZE], |
| 47 | struct nouveau_backlight *bl) | 47 | struct nouveau_backlight *bl) |
| 48 | { | 48 | { |
| 49 | const int nb = ida_simple_get(&bl_ida, 0, 0, GFP_KERNEL); | 49 | const int nb = ida_alloc_max(&bl_ida, 99, GFP_KERNEL); |
| 50 | if (nb < 0 || nb >= 100) | 50 | |
| 51 | if (nb < 0) | ||
| 51 | return false; | 52 | return false; |
| 52 | if (nb > 0) | 53 | if (nb > 0) |
| 53 | snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight%d", nb); | 54 | snprintf(backlight_name, BL_NAME_SIZE, "nv_backlight%d", nb); |
| @@ -414,7 +415,7 @@ nouveau_backlight_init(struct drm_connector *connector) · 360 unmodified lines | |||
| 414 | nv_encoder, ops, &props); | 415 | nv_encoder, ops, &props); |
| 415 | if (IS_ERR(bl->dev)) { | 416 | if (IS_ERR(bl->dev)) { |
| 416 | if (bl->id >= 0) | 417 | if (bl->id >= 0) |
| 417 | ida_simple_remove(&bl_ida, bl->id); | 418 | ida_free(&bl_ida, bl->id); |
| 418 | ret = PTR_ERR(bl->dev); | 419 | ret = PTR_ERR(bl->dev); |
| 419 | goto fail_alloc; | 420 | goto fail_alloc; |
| 420 | } | 421 | } |
| @@ -442,7 +443,7 @@ nouveau_backlight_fini(struct drm_connector *connector) · 21 unmodified lines | |||
| 442 | return; | 443 | return; |
| 443 | 444 | ||
| 444 | if (bl->id >= 0) | 445 | if (bl->id >= 0) |
| 445 | ida_simple_remove(&bl_ida, bl->id); | 446 | ida_free(&bl_ida, bl->id); |
| 446 | 447 | ||
| 447 | backlight_device_unregister(bl->dev); | 448 | backlight_device_unregister(bl->dev); |
| 448 | nv_conn->backlight = NULL; | 449 | nv_conn->backlight = NULL; |
| @@ -123,7 +123,7 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) · 122 unmodified lines | |||
| 123 | 123 | ||
| 124 | mutex_init(&tdev->iommu.mutex); | 124 | mutex_init(&tdev->iommu.mutex); |
| 125 | 125 | ||
| 126 | if (iommu_present(&platform_bus_type)) { | 126 | if (device_iommu_mapped(dev)) { |
| 127 | tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type); | 127 | tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type); |
| 128 | if (!tdev->iommu.domain) | 128 | if (!tdev->iommu.domain) |
| 129 | goto error; | 129 | goto error; |
| @@ -222,13 +222,11 @@ void sun4i_frontend_update_buffer(struct sun4i_frontend *frontend, · 221 unmodified lines | |||
| 222 | 222 | ||
| 223 | /* Set the physical address of the buffer in memory */ | 223 | /* Set the physical address of the buffer in memory */ |
| 224 | paddr = drm_fb_cma_get_gem_addr(fb, state, 0); | 224 | paddr = drm_fb_cma_get_gem_addr(fb, state, 0); |
| 225 | paddr -= PHYS_OFFSET; | ||
| 226 | DRM_DEBUG_DRIVER("Setting buffer #0 address to %pad\n", &paddr); | 225 | DRM_DEBUG_DRIVER("Setting buffer #0 address to %pad\n", &paddr); |
| 227 | regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR0_REG, paddr); | 226 | regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR0_REG, paddr); |
| 228 | 227 | ||
| 229 | if (fb->format->num_planes > 1) { | 228 | if (fb->format->num_planes > 1) { |
| 230 | paddr = drm_fb_cma_get_gem_addr(fb, state, swap ? 2 : 1); | 229 | paddr = drm_fb_cma_get_gem_addr(fb, state, swap ? 2 : 1); |
| 231 | paddr -= PHYS_OFFSET; | ||
| 232 | DRM_DEBUG_DRIVER("Setting buffer #1 address to %pad\n", &paddr); | 230 | DRM_DEBUG_DRIVER("Setting buffer #1 address to %pad\n", &paddr); |
| 233 | regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR1_REG, | 231 | regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR1_REG, |
| 234 | paddr); | 232 | paddr); |
| @@ -236,7 +234,6 @@ void sun4i_frontend_update_buffer(struct sun4i_frontend *frontend, · 1 unmodified line | |||
| 236 | 234 | ||
| 237 | if (fb->format->num_planes > 2) { | 235 | if (fb->format->num_planes > 2) { |
| 238 | paddr = drm_fb_cma_get_gem_addr(fb, state, swap ? 1 : 2); | 236 | paddr = drm_fb_cma_get_gem_addr(fb, state, swap ? 1 : 2); |
| 239 | paddr -= PHYS_OFFSET; | ||
| 240 | DRM_DEBUG_DRIVER("Setting buffer #2 address to %pad\n", &paddr); | 237 | DRM_DEBUG_DRIVER("Setting buffer #2 address to %pad\n", &paddr); |
| 241 | regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR2_REG, | 238 | regmap_write(frontend->regs, SUN4I_FRONTEND_BUF_ADDR2_REG, |
| 242 | paddr); | 239 | paddr); |
| @@ -38,6 +38,7 @@ · 37 unmodified lines | |||
| 38 | #include <drm/drm_scdc_helper.h> | 38 | #include <drm/drm_scdc_helper.h> |
| 39 | #include <linux/clk.h> | 39 | #include <linux/clk.h> |
| 40 | #include <linux/component.h> | 40 | #include <linux/component.h> |
| 41 | #include <linux/gpio/consumer.h> | ||
| 41 | #include <linux/i2c.h> | 42 | #include <linux/i2c.h> |
| 42 | #include <linux/of_address.h> | 43 | #include <linux/of_address.h> |
| 43 | #include <linux/of_gpio.h> | 44 | #include <linux/of_gpio.h> |
| @@ -528,7 +528,7 @@ int vmw_cmd_send_fence(struct vmw_private *dev_priv, uint32_t *seqno) · 527 unmodified lines | |||
| 528 | *seqno = atomic_add_return(1, &dev_priv->marker_seq); | 528 | *seqno = atomic_add_return(1, &dev_priv->marker_seq); |
| 529 | } while (*seqno == 0); | 529 | } while (*seqno == 0); |
| 530 | 530 | ||
| 531 | if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE)) { | 531 | if (!vmw_has_fences(dev_priv)) { |
| 532 | 532 | ||
| 533 | /* | 533 | /* |
| 534 | * Don't request hardware to send a fence. The | 534 | * Don't request hardware to send a fence. The |
| @@ -675,11 +675,14 @@ int vmw_cmd_emit_dummy_query(struct vmw_private *dev_priv, · 140 unmodified lines | |||
| 675 | */ | 675 | */ |
| 676 | bool vmw_cmd_supported(struct vmw_private *vmw) | 676 | bool vmw_cmd_supported(struct vmw_private *vmw) |
| 677 | { | 677 | { |
| 678 | if ((vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS | | 678 | bool has_cmdbufs = |
| 679 | SVGA_CAP_CMD_BUFFERS_2)) != 0) | 679 | (vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS | |
| 680 | return true; | 680 | SVGA_CAP_CMD_BUFFERS_2)) != 0; |
| 681 | if (vmw_is_svga_v3(vmw)) | ||
| 682 | return (has_cmdbufs && | ||
| 683 | (vmw->capabilities & SVGA_CAP_GBOBJECTS) != 0); | ||
| 681 | /* | 684 | /* |
| 682 | * We have FIFO cmd's | 685 | * We have FIFO cmd's |
| 683 | */ | 686 | */ |
| 684 | return vmw->fifo_mem != NULL; | 687 | return has_cmdbufs || vmw->fifo_mem != NULL; |
| 685 | } | 688 | } |
| @@ -1679,4 +1679,12 @@ static inline void vmw_irq_status_write(struct vmw_private *vmw, · 1678 unmodified lines | |||
| 1679 | outl(status, vmw->io_start + SVGA_IRQSTATUS_PORT); | 1679 | outl(status, vmw->io_start + SVGA_IRQSTATUS_PORT); |
| 1680 | } | 1680 | } |
| 1681 | 1681 | ||
| 1682 | static inline bool vmw_has_fences(struct vmw_private *vmw) | ||
| 1683 | { | ||
| 1684 | if ((vmw->capabilities & (SVGA_CAP_COMMAND_BUFFERS | | ||
| 1685 | SVGA_CAP_CMD_BUFFERS_2)) != 0) | ||
| 1686 | return true; | ||
| 1687 | return (vmw_fifo_caps(vmw) & SVGA_FIFO_CAP_FENCE) != 0; | ||
| 1688 | } | ||
| 1689 | |||
| 1682 | #endif | 1690 | #endif |
| @@ -483,7 +483,7 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par, · 482 unmodified lines | |||
| 483 | 483 | ||
| 484 | static int vmw_fb_kms_framebuffer(struct fb_info *info) | 484 | static int vmw_fb_kms_framebuffer(struct fb_info *info) |
| 485 | { | 485 | { |
| 486 | struct drm_mode_fb_cmd2 mode_cmd; | 486 | struct drm_mode_fb_cmd2 mode_cmd = {0}; |
| 487 | struct vmw_fb_par *par = info->par; | 487 | struct vmw_fb_par *par = info->par; |
| 488 | struct fb_var_screeninfo *var = &info->var; | 488 | struct fb_var_screeninfo *var = &info->var; |
| 489 | struct drm_framebuffer *cur_fb; | 489 | struct drm_framebuffer *cur_fb; |
| @@ -82,6 +82,22 @@ fman_from_fence(struct vmw_fence_obj *fence) · 81 unmodified lines | |||
| 82 | return container_of(fence->base.lock, struct vmw_fence_manager, lock); | 82 | return container_of(fence->base.lock, struct vmw_fence_manager, lock); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static u32 vmw_fence_goal_read(struct vmw_private *vmw) | ||
| 86 | { | ||
| 87 | if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0) | ||
| 88 | return vmw_read(vmw, SVGA_REG_FENCE_GOAL); | ||
| 89 | else | ||
| 90 | return vmw_fifo_mem_read(vmw, SVGA_FIFO_FENCE_GOAL); | ||
| 91 | } | ||
| 92 | |||
| 93 | static void vmw_fence_goal_write(struct vmw_private *vmw, u32 value) | ||
| 94 | { | ||
| 95 | if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0) | ||
| 96 | vmw_write(vmw, SVGA_REG_FENCE_GOAL, value); | ||
| 97 | else | ||
| 98 | vmw_fifo_mem_write(vmw, SVGA_FIFO_FENCE_GOAL, value); | ||
| 99 | } | ||
| 100 | |||
| 85 | /* | 101 | /* |
| 86 | * Note on fencing subsystem usage of irqs: | 102 | * Note on fencing subsystem usage of irqs: |
| 87 | * Typically the vmw_fences_update function is called | 103 | * Typically the vmw_fences_update function is called |
| @@ -392,7 +408,7 @@ static bool vmw_fence_goal_new_locked(struct vmw_fence_manager *fman, · 304 unmodified lines | |||
| 392 | if (likely(!fman->seqno_valid)) | 408 | if (likely(!fman->seqno_valid)) |
| 393 | return false; | 409 | return false; |
| 394 | 410 | ||
| 395 | goal_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE_GOAL); | 411 | goal_seqno = vmw_fence_goal_read(fman->dev_priv); |
| 396 | if (likely(passed_seqno - goal_seqno >= VMW_FENCE_WRAP)) | 412 | if (likely(passed_seqno - goal_seqno >= VMW_FENCE_WRAP)) |
| 397 | return false; | 413 | return false; |
| 398 | 414 | ||
| @@ -400,9 +416,8 @@ static bool vmw_fence_goal_new_locked(struct vmw_fence_manager *fman, · 1 unmodified line | |||
| 400 | list_for_each_entry(fence, &fman->fence_list, head) { | 416 | list_for_each_entry(fence, &fman->fence_list, head) { |
| 401 | if (!list_empty(&fence->seq_passed_actions)) { | 417 | if (!list_empty(&fence->seq_passed_actions)) { |
| 402 | fman->seqno_valid = true; | 418 | fman->seqno_valid = true; |
| 403 | vmw_fifo_mem_write(fman->dev_priv, | 419 | vmw_fence_goal_write(fman->dev_priv, |
| 404 | SVGA_FIFO_FENCE_GOAL, | 420 | fence->base.seqno); |
| 405 | fence->base.seqno); | ||
| 406 | break; | 421 | break; |
| 407 | } | 422 | } |
| 408 | } | 423 | } |
| @@ -434,13 +449,12 @@ static bool vmw_fence_goal_check_locked(struct vmw_fence_obj *fence) · 25 unmodified lines | |||
| 434 | if (dma_fence_is_signaled_locked(&fence->base)) | 449 | if (dma_fence_is_signaled_locked(&fence->base)) |
| 435 | return false; | 450 | return false; |
| 436 | 451 | ||
| 437 | goal_seqno = vmw_fifo_mem_read(fman->dev_priv, SVGA_FIFO_FENCE_GOAL); | 452 | goal_seqno = vmw_fence_goal_read(fman->dev_priv); |
| 438 | if (likely(fman->seqno_valid && | 453 | if (likely(fman->seqno_valid && |
| 439 | goal_seqno - fence->base.seqno < VMW_FENCE_WRAP)) | 454 | goal_seqno - fence->base.seqno < VMW_FENCE_WRAP)) |
| 440 | return false; | 455 | return false; |
| 441 | 456 | ||
| 442 | vmw_fifo_mem_write(fman->dev_priv, SVGA_FIFO_FENCE_GOAL, | 457 | vmw_fence_goal_write(fman->dev_priv, fence->base.seqno); |
| 443 | fence->base.seqno); | ||
| 444 | fman->seqno_valid = true; | 458 | fman->seqno_valid = true; |
| 445 | 459 | ||
| 446 | return true; | 460 | return true; |
| @@ -32,6 +32,14 @@ · 31 unmodified lines | |||
| 32 | 32 | ||
| 33 | #define VMW_FENCE_WRAP (1 << 24) | 33 | #define VMW_FENCE_WRAP (1 << 24) |
| 34 | 34 | ||
| 35 | static u32 vmw_irqflag_fence_goal(struct vmw_private *vmw) | ||
| 36 | { | ||
| 37 | if ((vmw->capabilities2 & SVGA_CAP2_EXTRA_REGS) != 0) | ||
| 38 | return SVGA_IRQFLAG_REG_FENCE_GOAL; | ||
| 39 | else | ||
| 40 | return SVGA_IRQFLAG_FENCE_GOAL; | ||
| 41 | } | ||
| 42 | |||
| 35 | /** | 43 | /** |
| 36 | * vmw_thread_fn - Deferred (process context) irq handler | 44 | * vmw_thread_fn - Deferred (process context) irq handler |
| 37 | * | 45 | * |
| @@ -96,7 +104,7 @@ static irqreturn_t vmw_irq_handler(int irq, void *arg) · 58 unmodified lines | |||
| 96 | wake_up_all(&dev_priv->fifo_queue); | 104 | wake_up_all(&dev_priv->fifo_queue); |
| 97 | 105 | ||
| 98 | if ((masked_status & (SVGA_IRQFLAG_ANY_FENCE | | 106 | if ((masked_status & (SVGA_IRQFLAG_ANY_FENCE | |
| 99 | SVGA_IRQFLAG_FENCE_GOAL)) && | 107 | vmw_irqflag_fence_goal(dev_priv))) && |
| 100 | !test_and_set_bit(VMW_IRQTHREAD_FENCE, dev_priv->irqthread_pending)) | 108 | !test_and_set_bit(VMW_IRQTHREAD_FENCE, dev_priv->irqthread_pending)) |
| 101 | ret = IRQ_WAKE_THREAD; | 109 | ret = IRQ_WAKE_THREAD; |
| 102 | 110 | ||
| @@ -137,8 +145,7 @@ bool vmw_seqno_passed(struct vmw_private *dev_priv, · 34 unmodified lines | |||
| 137 | if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP)) | 145 | if (likely(dev_priv->last_read_seqno - seqno < VMW_FENCE_WRAP)) |
| 138 | return true; | 146 | return true; |
| 139 | 147 | ||
| 140 | if (!(vmw_fifo_caps(dev_priv) & SVGA_FIFO_CAP_FENCE) && | 148 | if (!vmw_has_fences(dev_priv) && vmw_fifo_idle(dev_priv, seqno)) |
| 141 | vmw_fifo_idle(dev_priv, seqno)) | ||
| 142 | return true; | 149 | return true; |
| 143 | 150 | ||
| 144 | /** | 151 | /** |
| @@ -160,6 +167,7 @@ int vmw_fallback_wait(struct vmw_private *dev_priv, · 15 unmodified lines | |||
| 160 | unsigned long timeout) | 167 | unsigned long timeout) |
| 161 | { | 168 | { |
| 162 | struct vmw_fifo_state *fifo_state = dev_priv->fifo; | 169 | struct vmw_fifo_state *fifo_state = dev_priv->fifo; |
| 170 | bool fifo_down = false; | ||
| 163 | 171 | ||
| 164 | uint32_t count = 0; | 172 | uint32_t count = 0; |
| 165 | uint32_t signal_seq; | 173 | uint32_t signal_seq; |
| @@ -176,12 +184,14 @@ int vmw_fallback_wait(struct vmw_private *dev_priv, · 10 unmodified lines | |||
| 176 | */ | 184 | */ |
| 177 | 185 | ||
| 178 | if (fifo_idle) { | 186 | if (fifo_idle) { |
| 179 | down_read(&fifo_state->rwsem); | ||
| 180 | if (dev_priv->cman) { | 187 | if (dev_priv->cman) { |
| 181 | ret = vmw_cmdbuf_idle(dev_priv->cman, interruptible, | 188 | ret = vmw_cmdbuf_idle(dev_priv->cman, interruptible, |
| 182 | 10*HZ); | 189 | 10*HZ); |
| 183 | if (ret) | 190 | if (ret) |
| 184 | goto out_err; | 191 | goto out_err; |
| 192 | } else if (fifo_state) { | ||
| 193 | down_read(&fifo_state->rwsem); | ||
| 194 | fifo_down = true; | ||
| 185 | } | 195 | } |
| 186 | } | 196 | } |
| 187 | 197 | ||
| @@ -218,12 +228,12 @@ int vmw_fallback_wait(struct vmw_private *dev_priv, · 30 unmodified lines | |||
| 218 | } | 228 | } |
| 219 | } | 229 | } |
| 220 | finish_wait(&dev_priv->fence_queue, &__wait); | 230 | finish_wait(&dev_priv->fence_queue, &__wait); |
| 221 | if (ret == 0 && fifo_idle) | 231 | if (ret == 0 && fifo_idle && fifo_state) |
| 222 | vmw_fence_write(dev_priv, signal_seq); | 232 | vmw_fence_write(dev_priv, signal_seq); |
| 223 | 233 | ||
| 224 | wake_up_all(&dev_priv->fence_queue); | 234 | wake_up_all(&dev_priv->fence_queue); |
| 225 | out_err: | 235 | out_err: |
| 226 | if (fifo_idle) | 236 | if (fifo_down) |
| 227 | up_read(&fifo_state->rwsem); | 237 | up_read(&fifo_state->rwsem); |
| 228 | 238 | ||
| 229 | return ret; | 239 | return ret; |
| @@ -266,13 +276,13 @@ void vmw_seqno_waiter_remove(struct vmw_private *dev_priv) · 36 unmodified lines | |||
| 266 | 276 | ||
| 267 | void vmw_goal_waiter_add(struct vmw_private *dev_priv) | 277 | void vmw_goal_waiter_add(struct vmw_private *dev_priv) |
| 268 | { | 278 | { |
| 269 | vmw_generic_waiter_add(dev_priv, SVGA_IRQFLAG_FENCE_GOAL, | 279 | vmw_generic_waiter_add(dev_priv, vmw_irqflag_fence_goal(dev_priv), |
| 270 | &dev_priv->goal_queue_waiters); | 280 | &dev_priv->goal_queue_waiters); |
| 271 | } | 281 | } |
| 272 | 282 | ||
| 273 | void vmw_goal_waiter_remove(struct vmw_private *dev_priv) | 283 | void vmw_goal_waiter_remove(struct vmw_private *dev_priv) |
| 274 | { | 284 | { |
| 275 | vmw_generic_waiter_remove(dev_priv, SVGA_IRQFLAG_FENCE_GOAL, | 285 | vmw_generic_waiter_remove(dev_priv, vmw_irqflag_fence_goal(dev_priv), |
| 276 | &dev_priv->goal_queue_waiters); | 286 | &dev_priv->goal_queue_waiters); |
| 277 | } | 287 | } |
| 278 | 288 | ||
| @@ -1344,7 +1344,6 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv, · 1343 unmodified lines | |||
| 1344 | ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb, | 1344 | ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb, |
| 1345 | mode_cmd, | 1345 | mode_cmd, |
| 1346 | is_bo_proxy); | 1346 | is_bo_proxy); |
| 1347 | |||
| 1348 | /* | 1347 | /* |
| 1349 | * vmw_create_bo_proxy() adds a reference that is no longer | 1348 | * vmw_create_bo_proxy() adds a reference that is no longer |
| 1350 | * needed | 1349 | * needed |
| @@ -1385,13 +1384,16 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, · 34 unmodified lines | |||
| 1385 | ret = vmw_user_lookup_handle(dev_priv, file_priv, | 1384 | ret = vmw_user_lookup_handle(dev_priv, file_priv, |
| 1386 | mode_cmd->handles[0], | 1385 | mode_cmd->handles[0], |
| 1387 | &surface, &bo); | 1386 | &surface, &bo); |
| 1388 | if (ret) | 1387 | if (ret) { |
| 1388 | DRM_ERROR("Invalid buffer object handle %u (0x%x).\n", | ||
| 1389 | mode_cmd->handles[0], mode_cmd->handles[0]); | ||
| 1389 | goto err_out; | 1390 | goto err_out; |
| 1391 | } | ||
| 1390 | 1392 | ||
| 1391 | 1393 | ||
| 1392 | if (!bo && | 1394 | if (!bo && |
| 1393 | !vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)) { | 1395 | !vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)) { |
| 1394 | DRM_ERROR("Surface size cannot exceed %dx%d", | 1396 | DRM_ERROR("Surface size cannot exceed %dx%d\n", |
| 1395 | dev_priv->texture_max_width, | 1397 | dev_priv->texture_max_width, |
| 1396 | dev_priv->texture_max_height); | 1398 | dev_priv->texture_max_height); |
| 1397 | goto err_out; | 1399 | goto err_out; |
| @@ -960,7 +960,7 @@ config SENSORS_LTC4261 · 959 unmodified lines | |||
| 960 | 960 | ||
| 961 | config SENSORS_LTQ_CPUTEMP | 961 | config SENSORS_LTQ_CPUTEMP |
| 962 | bool "Lantiq cpu temperature sensor driver" | 962 | bool "Lantiq cpu temperature sensor driver" |
| 963 | depends on LANTIQ | 963 | depends on SOC_XWAY |
| 964 | help | 964 | help |
| 965 | If you say yes here you get support for the temperature | 965 | If you say yes here you get support for the temperature |
| 966 | sensor inside your CPU. | 966 | sensor inside your CPU. |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/log2.h> | 19 | #include <linux/log2.h> |
| 20 | #include <linux/kthread.h> | 20 | #include <linux/kthread.h> |
| 21 | #include <linux/regmap.h> | 21 | #include <linux/regmap.h> |
| 22 | #include <linux/sched.h> | ||
| 22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 23 | #include <linux/util_macros.h> | 24 | #include <linux/util_macros.h> |
| 24 | 25 | ||
| @@ -294,11 +295,10 @@ static int adt7470_update_thread(void *p) · 269 unmodified lines | |||
| 294 | adt7470_read_temperatures(data); | 295 | adt7470_read_temperatures(data); |
| 295 | mutex_unlock(&data->lock); | 296 | mutex_unlock(&data->lock); |
| 296 | 297 | ||
| 297 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 298 | if (kthread_should_stop()) | 298 | if (kthread_should_stop()) |
| 299 | break; | 299 | break; |
| 300 | 300 | ||
| 301 | schedule_timeout(msecs_to_jiffies(data->auto_update_interval)); | 301 | schedule_timeout_interruptible(msecs_to_jiffies(data->auto_update_interval)); |
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | return 0; | 304 | return 0; |
| @@ -71,7 +71,7 @@ static const struct dmi_system_id asus_wmi_dmi_table[] = { · 70 unmodified lines | |||
| 71 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X399-A"), | 71 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X399-A"), |
| 72 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X470-PRO"), | 72 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X470-PRO"), |
| 73 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VI EXTREME"), | 73 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VI EXTREME"), |
| 74 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VI HERO"), | 74 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("CROSSHAIR VI HERO"), |
| 75 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VI HERO (WI-FI AC)"), | 75 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VI HERO (WI-FI AC)"), |
| 76 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VII HERO"), | 76 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VII HERO"), |
| 77 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VII HERO (WI-FI)"), | 77 | DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VII HERO (WI-FI)"), |
| @@ -1578,8 +1578,9 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, · 1577 unmodified lines | |||
| 1578 | temp *= 125; | 1578 | temp *= 125; |
| 1579 | if (sign) | 1579 | if (sign) |
| 1580 | temp -= 128000; | 1580 | temp -= 128000; |
| 1581 | } else | 1581 | } else { |
| 1582 | temp = data->temp[nr] * 1000; | 1582 | temp = ((s8)data->temp[nr]) * 1000; |
| 1583 | } | ||
| 1583 | 1584 | ||
| 1584 | return sprintf(buf, "%d\n", temp); | 1585 | return sprintf(buf, "%d\n", temp); |
| 1585 | } | 1586 | } |
| @@ -14,6 +14,21 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #define AHE50DC_PMBUS_READ_TEMP4 0xd0 | 15 | #define AHE50DC_PMBUS_READ_TEMP4 0xd0 |
| 16 | 16 | ||
| 17 | static int ahe50dc_fan_write_byte(struct i2c_client *client, int page, u8 value) | ||
| 18 | { | ||
| 19 | /* | ||
| 20 | * The CLEAR_FAULTS operation seems to sometimes (unpredictably, perhaps | ||
| 21 | * 5% of the time or so) trigger a problematic phenomenon in which the | ||
| 22 | * fan speeds surge momentarily and at least some (perhaps all?) of the | ||
| 23 | * system's power outputs experience a glitch. | ||
| 24 | * | ||
| 25 | * However, according to Delta it should be OK to simply not send any | ||
| 26 | * CLEAR_FAULTS commands (the device doesn't seem to be capable of | ||
| 27 | * reporting any faults anyway), so just blackhole them unconditionally. | ||
| 28 | */ | ||
| 29 | return value == PMBUS_CLEAR_FAULTS ? -EOPNOTSUPP : -ENODATA; | ||
| 30 | } | ||
| 31 | |||
| 17 | static int ahe50dc_fan_read_word_data(struct i2c_client *client, int page, int phase, int reg) | 32 | static int ahe50dc_fan_read_word_data(struct i2c_client *client, int page, int phase, int reg) |
| 18 | { | 33 | { |
| 19 | /* temp1 in (virtual) page 1 is remapped to mfr-specific temp4 */ | 34 | /* temp1 in (virtual) page 1 is remapped to mfr-specific temp4 */ |
| @@ -68,6 +83,7 @@ static struct pmbus_driver_info ahe50dc_fan_info = { · 48 unmodified lines | |||
| 68 | PMBUS_HAVE_VIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_FAN34 | | 83 | PMBUS_HAVE_VIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_FAN34 | |
| 69 | PMBUS_HAVE_STATUS_FAN12 | PMBUS_HAVE_STATUS_FAN34 | PMBUS_PAGE_VIRTUAL, | 84 | PMBUS_HAVE_STATUS_FAN12 | PMBUS_HAVE_STATUS_FAN34 | PMBUS_PAGE_VIRTUAL, |
| 70 | .func[1] = PMBUS_HAVE_TEMP | PMBUS_PAGE_VIRTUAL, | 85 | .func[1] = PMBUS_HAVE_TEMP | PMBUS_PAGE_VIRTUAL, |
| 86 | .write_byte = ahe50dc_fan_write_byte, | ||
| 71 | .read_word_data = ahe50dc_fan_read_word_data, | 87 | .read_word_data = ahe50dc_fan_read_word_data, |
| 72 | }; | 88 | }; |
| 73 | 89 | ||
| @@ -2326,6 +2326,9 @@ static int pmbus_init_common(struct i2c_client *client, struct pmbus_data *data, · 2325 unmodified lines | |||
| 2326 | data->has_status_word = true; | 2326 | data->has_status_word = true; |
| 2327 | } | 2327 | } |
| 2328 | 2328 | ||
| 2329 | /* Make sure PEC is disabled, will be enabled later if needed */ | ||
| 2330 | client->flags &= ~I2C_CLIENT_PEC; | ||
| 2331 | |||
| 2329 | /* Enable PEC if the controller and bus supports it */ | 2332 | /* Enable PEC if the controller and bus supports it */ |
| 2330 | if (!(data->flags & PMBUS_NO_CAPABILITY)) { | 2333 | if (!(data->flags & PMBUS_NO_CAPABILITY)) { |
| 2331 | ret = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY); | 2334 | ret = i2c_smbus_read_byte_data(client, PMBUS_CAPABILITY); |
| @@ -124,7 +124,7 @@ static int xdpe122_identify(struct i2c_client *client, · 123 unmodified lines | |||
| 124 | return 0; | 124 | return 0; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | static const struct regulator_desc xdpe122_reg_desc[] = { | 127 | static const struct regulator_desc __maybe_unused xdpe122_reg_desc[] = { |
| 128 | PMBUS_REGULATOR("vout", 0), | 128 | PMBUS_REGULATOR("vout", 0), |
| 129 | PMBUS_REGULATOR("vout", 1), | 129 | PMBUS_REGULATOR("vout", 1), |
| 130 | }; | 130 | }; |
| @@ -708,10 +708,21 @@ static int tmp401_probe(struct i2c_client *client) · 707 unmodified lines | |||
| 708 | return 0; | 708 | return 0; |
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | static const struct of_device_id __maybe_unused tmp4xx_of_match[] = { | ||
| 712 | { .compatible = "ti,tmp401", }, | ||
| 713 | { .compatible = "ti,tmp411", }, | ||
| 714 | { .compatible = "ti,tmp431", }, | ||
| 715 | { .compatible = "ti,tmp432", }, | ||
| 716 | { .compatible = "ti,tmp435", }, | ||
| 717 | { }, | ||
| 718 | }; | ||
| 719 | MODULE_DEVICE_TABLE(of, tmp4xx_of_match); | ||
| 720 | |||
| 711 | static struct i2c_driver tmp401_driver = { | 721 | static struct i2c_driver tmp401_driver = { |
| 712 | .class = I2C_CLASS_HWMON, | 722 | .class = I2C_CLASS_HWMON, |
| 713 | .driver = { | 723 | .driver = { |
| 714 | .name = "tmp401", | 724 | .name = "tmp401", |
| 725 | .of_match_table = of_match_ptr(tmp4xx_of_match), | ||
| 715 | }, | 726 | }, |
| 716 | .probe_new = tmp401_probe, | 727 | .probe_new = tmp401_probe, |
| 717 | .id_table = tmp401_id, | 728 | .id_table = tmp401_id, |
| @@ -69,7 +69,12 @@ static unsigned int preferred_states_mask; · 68 unmodified lines | |||
| 69 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; | 69 | static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; |
| 70 | 70 | ||
| 71 | static unsigned long auto_demotion_disable_flags; | 71 | static unsigned long auto_demotion_disable_flags; |
| 72 | static bool disable_promotion_to_c1e; | 72 | |
| 73 | static enum { | ||
| 74 | C1E_PROMOTION_PRESERVE, | ||
| 75 | C1E_PROMOTION_ENABLE, | ||
| 76 | C1E_PROMOTION_DISABLE | ||
| 77 | } c1e_promotion = C1E_PROMOTION_PRESERVE; | ||
| 73 | 78 | ||
| 74 | struct idle_cpu { | 79 | struct idle_cpu { |
| 75 | struct cpuidle_state *state_table; | 80 | struct cpuidle_state *state_table; |
| @@ -1398,8 +1403,6 @@ static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { } · 1322 unmodified lines | |||
| 1398 | static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; } | 1403 | static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; } |
| 1399 | #endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */ | 1404 | #endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */ |
| 1400 | 1405 | ||
| 1401 | static void c1e_promotion_enable(void); | ||
| 1402 | |||
| 1403 | /** | 1406 | /** |
| 1404 | * ivt_idle_state_table_update - Tune the idle states table for Ivy Town. | 1407 | * ivt_idle_state_table_update - Tune the idle states table for Ivy Town. |
| 1405 | * | 1408 | * |
| @@ -1578,17 +1581,14 @@ static void __init spr_idle_state_table_update(void) · 172 unmodified lines | |||
| 1578 | unsigned long long msr; | 1581 | unsigned long long msr; |
| 1579 | 1582 | ||
| 1580 | /* Check if user prefers C1E over C1. */ | 1583 | /* Check if user prefers C1E over C1. */ |
| 1581 | if (preferred_states_mask & BIT(2)) { | 1584 | if ((preferred_states_mask & BIT(2)) && |
| 1582 | if (preferred_states_mask & BIT(1)) | 1585 | !(preferred_states_mask & BIT(1))) { |
| 1583 | /* Both can't be enabled, stick to the defaults. */ | 1586 | /* Disable C1 and enable C1E. */ |
| 1584 | return; | ||
| 1585 | |||
| 1586 | spr_cstates[0].flags |= CPUIDLE_FLAG_UNUSABLE; | 1587 | spr_cstates[0].flags |= CPUIDLE_FLAG_UNUSABLE; |
| 1587 | spr_cstates[1].flags &= ~CPUIDLE_FLAG_UNUSABLE; | 1588 | spr_cstates[1].flags &= ~CPUIDLE_FLAG_UNUSABLE; |
| 1588 | 1589 | ||
| 1589 | /* Enable C1E using the "C1E promotion" bit. */ | 1590 | /* Enable C1E using the "C1E promotion" bit. */ |
| 1590 | c1e_promotion_enable(); | 1591 | c1e_promotion = C1E_PROMOTION_ENABLE; |
| 1591 | disable_promotion_to_c1e = false; | ||
| 1592 | } | 1592 | } |
| 1593 | 1593 | ||
| 1594 | /* | 1594 | /* |
| @@ -1754,7 +1754,9 @@ static int intel_idle_cpu_init(unsigned int cpu) · 159 unmodified lines | |||
| 1754 | if (auto_demotion_disable_flags) | 1754 | if (auto_demotion_disable_flags) |
| 1755 | auto_demotion_disable(); | 1755 | auto_demotion_disable(); |
| 1756 | 1756 | ||
| 1757 | if (disable_promotion_to_c1e) | 1757 | if (c1e_promotion == C1E_PROMOTION_ENABLE) |
| 1758 | c1e_promotion_enable(); | ||
| 1759 | else if (c1e_promotion == C1E_PROMOTION_DISABLE) | ||
| 1758 | c1e_promotion_disable(); | 1760 | c1e_promotion_disable(); |
| 1759 | 1761 | ||
| 1760 | return 0; | 1762 | return 0; |
| @@ -1833,7 +1835,8 @@ static int __init intel_idle_init(void) · 72 unmodified lines | |||
| 1833 | if (icpu) { | 1835 | if (icpu) { |
| 1834 | cpuidle_state_table = icpu->state_table; | 1836 | cpuidle_state_table = icpu->state_table; |
| 1835 | auto_demotion_disable_flags = icpu->auto_demotion_disable_flags; | 1837 | auto_demotion_disable_flags = icpu->auto_demotion_disable_flags; |
| 1836 | disable_promotion_to_c1e = icpu->disable_promotion_to_c1e; | 1838 | if (icpu->disable_promotion_to_c1e) |
| 1839 | c1e_promotion = C1E_PROMOTION_DISABLE; | ||
| 1837 | if (icpu->use_acpi || force_use_acpi) | 1840 | if (icpu->use_acpi || force_use_acpi) |
| 1838 | intel_idle_acpi_cst_extract(); | 1841 | intel_idle_acpi_cst_extract(); |
| 1839 | } else if (!intel_idle_acpi_cst_extract()) { | 1842 | } else if (!intel_idle_acpi_cst_extract()) { |
| @@ -745,7 +745,7 @@ static int ad7280a_write_thresh(struct iio_dev *indio_dev, · 744 unmodified lines | |||
| 745 | case IIO_EV_DIR_RISING: | 745 | case IIO_EV_DIR_RISING: |
| 746 | addr = AD7280A_CELL_OVERVOLTAGE_REG; | 746 | addr = AD7280A_CELL_OVERVOLTAGE_REG; |
| 747 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr, | 747 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr, |
| 748 | 1, val); | 748 | 1, value); |
| 749 | if (ret) | 749 | if (ret) |
| 750 | break; | 750 | break; |
| 751 | st->cell_threshhigh = value; | 751 | st->cell_threshhigh = value; |
| @@ -753,7 +753,7 @@ static int ad7280a_write_thresh(struct iio_dev *indio_dev, · 1 unmodified line | |||
| 753 | case IIO_EV_DIR_FALLING: | 753 | case IIO_EV_DIR_FALLING: |
| 754 | addr = AD7280A_CELL_UNDERVOLTAGE_REG; | 754 | addr = AD7280A_CELL_UNDERVOLTAGE_REG; |
| 755 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr, | 755 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr, |
| 756 | 1, val); | 756 | 1, value); |
| 757 | if (ret) | 757 | if (ret) |
| 758 | break; | 758 | break; |
| 759 | st->cell_threshlow = value; | 759 | st->cell_threshlow = value; |
| @@ -770,18 +770,18 @@ static int ad7280a_write_thresh(struct iio_dev *indio_dev, · 10 unmodified lines | |||
| 770 | case IIO_EV_DIR_RISING: | 770 | case IIO_EV_DIR_RISING: |
| 771 | addr = AD7280A_AUX_ADC_OVERVOLTAGE_REG; | 771 | addr = AD7280A_AUX_ADC_OVERVOLTAGE_REG; |
| 772 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr, | 772 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr, |
| 773 | 1, val); | 773 | 1, value); |
| 774 | if (ret) | 774 | if (ret) |
| 775 | break; | 775 | break; |
| 776 | st->aux_threshhigh = val; | 776 | st->aux_threshhigh = value; |
| 777 | break; | 777 | break; |
| 778 | case IIO_EV_DIR_FALLING: | 778 | case IIO_EV_DIR_FALLING: |
| 779 | addr = AD7280A_AUX_ADC_UNDERVOLTAGE_REG; | 779 | addr = AD7280A_AUX_ADC_UNDERVOLTAGE_REG; |
| 780 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr, | 780 | ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr, |
| 781 | 1, val); | 781 | 1, value); |
| 782 | if (ret) | 782 | if (ret) |
| 783 | break; | 783 | break; |
| 784 | st->aux_threshlow = val; | 784 | st->aux_threshlow = value; |
| 785 | break; | 785 | break; |
| 786 | default: | 786 | default: |
| 787 | ret = -EINVAL; | 787 | ret = -EINVAL; |
| @@ -471,12 +471,15 @@ static ssize_t calibration_forced_value_store(struct device *dev, · 470 unmodified lines | |||
| 471 | ret = scd4x_write_and_fetch(state, CMD_FRC, arg, &val, sizeof(val)); | 471 | ret = scd4x_write_and_fetch(state, CMD_FRC, arg, &val, sizeof(val)); |
| 472 | mutex_unlock(&state->lock); | 472 | mutex_unlock(&state->lock); |
| 473 | 473 | ||
| 474 | if (ret) | ||
| 475 | return ret; | ||
| 476 | |||
| 474 | if (val == 0xff) { | 477 | if (val == 0xff) { |
| 475 | dev_err(dev, "forced calibration has failed"); | 478 | dev_err(dev, "forced calibration has failed"); |
| 476 | return -EINVAL; | 479 | return -EINVAL; |
| 477 | } | 480 | } |
| 478 | 481 | ||
| 479 | return ret ?: len; | 482 | return len; |
| 480 | } | 483 | } |
| 481 | 484 | ||
| 482 | static IIO_DEVICE_ATTR_RW(calibration_auto_enable, 0); | 485 | static IIO_DEVICE_ATTR_RW(calibration_auto_enable, 0); |
| @@ -656,7 +656,7 @@ static int ad3552r_reset(struct ad3552r_desc *dac) · 655 unmodified lines | |||
| 656 | { | 656 | { |
| 657 | struct reg_addr_pool addr; | 657 | struct reg_addr_pool addr; |
| 658 | int ret; | 658 | int ret; |
| 659 | u16 val; | 659 | int val; |
| 660 | 660 | ||
| 661 | dac->gpio_reset = devm_gpiod_get_optional(&dac->spi->dev, "reset", | 661 | dac->gpio_reset = devm_gpiod_get_optional(&dac->spi->dev, "reset", |
| 662 | GPIOD_OUT_LOW); | 662 | GPIOD_OUT_LOW); |
| @@ -809,10 +809,10 @@ static int ad3552r_configure_custom_gain(struct ad3552r_desc *dac, · 146 unmodified lines | |||
| 809 | 809 | ||
| 810 | gain_child = fwnode_get_named_child_node(child, | 810 | gain_child = fwnode_get_named_child_node(child, |
| 811 | "custom-output-range-config"); | 811 | "custom-output-range-config"); |
| 812 | if (IS_ERR(gain_child)) { | 812 | if (!gain_child) { |
| 813 | dev_err(dev, | 813 | dev_err(dev, |
| 814 | "mandatory custom-output-range-config property missing\n"); | 814 | "mandatory custom-output-range-config property missing\n"); |
| 815 | return PTR_ERR(gain_child); | 815 | return -EINVAL; |
| 816 | } | 816 | } |
| 817 | 817 | ||
| 818 | dac->ch_data[ch].range_override = 1; | 818 | dac->ch_data[ch].range_override = 1; |
| @@ -178,7 +178,7 @@ static int ad5446_read_raw(struct iio_dev *indio_dev, · 177 unmodified lines | |||
| 178 | 178 | ||
| 179 | switch (m) { | 179 | switch (m) { |
| 180 | case IIO_CHAN_INFO_RAW: | 180 | case IIO_CHAN_INFO_RAW: |
| 181 | *val = st->cached_val; | 181 | *val = st->cached_val >> chan->scan_type.shift; |
| 182 | return IIO_VAL_INT; | 182 | return IIO_VAL_INT; |
| 183 | case IIO_CHAN_INFO_SCALE: | 183 | case IIO_CHAN_INFO_SCALE: |
| 184 | *val = st->vref_mv; | 184 | *val = st->vref_mv; |
| @@ -522,7 +522,7 @@ static int ad5592r_alloc_channels(struct iio_dev *iio_dev) · 521 unmodified lines | |||
| 522 | if (!ret) | 522 | if (!ret) |
| 523 | st->channel_modes[reg] = tmp; | 523 | st->channel_modes[reg] = tmp; |
| 524 | 524 | ||
| 525 | fwnode_property_read_u32(child, "adi,off-state", &tmp); | 525 | ret = fwnode_property_read_u32(child, "adi,off-state", &tmp); |
| 526 | if (!ret) | 526 | if (!ret) |
| 527 | st->channel_offstate[reg] = tmp; | 527 | st->channel_offstate[reg] = tmp; |
| 528 | } | 528 | } |
| @@ -298,7 +298,7 @@ static int ltc2688_read_raw(struct iio_dev *indio_dev, · 297 unmodified lines | |||
| 298 | if (ret) | 298 | if (ret) |
| 299 | return ret; | 299 | return ret; |
| 300 | 300 | ||
| 301 | *val = 16; | 301 | *val2 = 16; |
| 302 | return IIO_VAL_FRACTIONAL_LOG2; | 302 | return IIO_VAL_FRACTIONAL_LOG2; |
| 303 | case IIO_CHAN_INFO_CALIBBIAS: | 303 | case IIO_CHAN_INFO_CALIBBIAS: |
| 304 | ret = regmap_read(st->regmap, | 304 | ret = regmap_read(st->regmap, |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
| 20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 21 | #include <linux/mod_devicetable.h> | 21 | #include <linux/mod_devicetable.h> |
| 22 | #include <linux/property.h> | ||
| 22 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
| 23 | 24 | ||
| 24 | enum chip_id { | 25 | enum chip_id { |
| @@ -311,6 +312,7 @@ static int dac5571_probe(struct i2c_client *client, · 286 unmodified lines | |||
| 311 | const struct dac5571_spec *spec; | 312 | const struct dac5571_spec *spec; |
| 312 | struct dac5571_data *data; | 313 | struct dac5571_data *data; |
| 313 | struct iio_dev *indio_dev; | 314 | struct iio_dev *indio_dev; |
| 315 | enum chip_id chip_id; | ||
| 314 | int ret, i; | 316 | int ret, i; |
| 315 | 317 | ||
| 316 | indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); | 318 | indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); |
| @@ -326,7 +328,13 @@ static int dac5571_probe(struct i2c_client *client, · 9 unmodified lines | |||
| 326 | indio_dev->modes = INDIO_DIRECT_MODE; | 328 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 327 | indio_dev->channels = dac5571_channels; | 329 | indio_dev->channels = dac5571_channels; |
| 328 | 330 | ||
| 329 | spec = &dac5571_spec[id->driver_data]; | 331 | if (dev_fwnode(dev)) |
| 332 | chip_id = (uintptr_t)device_get_match_data(dev); | ||
| 333 | else | ||
| 334 | chip_id = id->driver_data; | ||
| 335 | |||
| 336 | spec = &dac5571_spec[chip_id]; | ||
| 337 | |||
| 330 | indio_dev->num_channels = spec->num_channels; | 338 | indio_dev->num_channels = spec->num_channels; |
| 331 | data->spec = spec; | 339 | data->spec = spec; |
| 332 | 340 | ||
| @@ -385,15 +393,15 @@ static int dac5571_remove(struct i2c_client *i2c) · 52 unmodified lines | |||
| 385 | } | 393 | } |
| 386 | 394 | ||
| 387 | static const struct of_device_id dac5571_of_id[] = { | 395 | static const struct of_device_id dac5571_of_id[] = { |
| 388 | {.compatible = "ti,dac5571"}, | 396 | {.compatible = "ti,dac5571", .data = (void *)single_8bit}, |
| 389 | {.compatible = "ti,dac6571"}, | 397 | {.compatible = "ti,dac6571", .data = (void *)single_10bit}, |
| 390 | {.compatible = "ti,dac7571"}, | 398 | {.compatible = "ti,dac7571", .data = (void *)single_12bit}, |
| 391 | {.compatible = "ti,dac5574"}, | 399 | {.compatible = "ti,dac5574", .data = (void *)quad_8bit}, |
| 392 | {.compatible = "ti,dac6574"}, | 400 | {.compatible = "ti,dac6574", .data = (void *)quad_10bit}, |
| 393 | {.compatible = "ti,dac7574"}, | 401 | {.compatible = "ti,dac7574", .data = (void *)quad_12bit}, |
| 394 | {.compatible = "ti,dac5573"}, | 402 | {.compatible = "ti,dac5573", .data = (void *)quad_8bit}, |
| 395 | {.compatible = "ti,dac6573"}, | 403 | {.compatible = "ti,dac6573", .data = (void *)quad_10bit}, |
| 396 | {.compatible = "ti,dac7573"}, | 404 | {.compatible = "ti,dac7573", .data = (void *)quad_12bit}, |
| 397 | {} | 405 | {} |
| 398 | }; | 406 | }; |
| 399 | MODULE_DEVICE_TABLE(of, dac5571_of_id); | 407 | MODULE_DEVICE_TABLE(of, dac5571_of_id); |
| @@ -8,6 +8,7 @@ menu "Filters" · 7 unmodified lines | |||
| 8 | config ADMV8818 | 8 | config ADMV8818 |
| 9 | tristate "Analog Devices ADMV8818 High-Pass and Low-Pass Filter" | 9 | tristate "Analog Devices ADMV8818 High-Pass and Low-Pass Filter" |
| 10 | depends on SPI && COMMON_CLK && 64BIT | 10 | depends on SPI && COMMON_CLK && 64BIT |
| 11 | select REGMAP_SPI | ||
| 11 | help | 12 | help |
| 12 | Say yes here to build support for Analog Devices ADMV8818 | 13 | Say yes here to build support for Analog Devices ADMV8818 |
| 13 | 2 GHz to 18 GHz, Digitally Tunable, High-Pass and Low-Pass Filter. | 14 | 2 GHz to 18 GHz, Digitally Tunable, High-Pass and Low-Pass Filter. |
| @@ -730,7 +730,7 @@ static int bmi160_chip_init(struct bmi160_data *data, bool use_spi) · 729 unmodified lines | |||
| 730 | 730 | ||
| 731 | ret = regmap_write(data->regmap, BMI160_REG_CMD, BMI160_CMD_SOFTRESET); | 731 | ret = regmap_write(data->regmap, BMI160_REG_CMD, BMI160_CMD_SOFTRESET); |
| 732 | if (ret) | 732 | if (ret) |
| 733 | return ret; | 733 | goto disable_regulator; |
| 734 | 734 | ||
| 735 | usleep_range(BMI160_SOFTRESET_USLEEP, BMI160_SOFTRESET_USLEEP + 1); | 735 | usleep_range(BMI160_SOFTRESET_USLEEP, BMI160_SOFTRESET_USLEEP + 1); |
| 736 | 736 | ||
| @@ -741,29 +741,37 @@ static int bmi160_chip_init(struct bmi160_data *data, bool use_spi) · 4 unmodified lines | |||
| 741 | if (use_spi) { | 741 | if (use_spi) { |
| 742 | ret = regmap_read(data->regmap, BMI160_REG_DUMMY, &val); | 742 | ret = regmap_read(data->regmap, BMI160_REG_DUMMY, &val); |
| 743 | if (ret) | 743 | if (ret) |
| 744 | return ret; | 744 | goto disable_regulator; |
| 745 | } | 745 | } |
| 746 | 746 | ||
| 747 | ret = regmap_read(data->regmap, BMI160_REG_CHIP_ID, &val); | 747 | ret = regmap_read(data->regmap, BMI160_REG_CHIP_ID, &val); |
| 748 | if (ret) { | 748 | if (ret) { |
| 749 | dev_err(dev, "Error reading chip id\n"); | 749 | dev_err(dev, "Error reading chip id\n"); |
| 750 | return ret; | 750 | goto disable_regulator; |
| 751 | } | 751 | } |
| 752 | if (val != BMI160_CHIP_ID_VAL) { | 752 | if (val != BMI160_CHIP_ID_VAL) { |
| 753 | dev_err(dev, "Wrong chip id, got %x expected %x\n", | 753 | dev_err(dev, "Wrong chip id, got %x expected %x\n", |
| 754 | val, BMI160_CHIP_ID_VAL); | 754 | val, BMI160_CHIP_ID_VAL); |
| 755 | return -ENODEV; | 755 | ret = -ENODEV; |
| 756 | goto disable_regulator; | ||
| 756 | } | 757 | } |
| 757 | 758 | ||
| 758 | ret = bmi160_set_mode(data, BMI160_ACCEL, true); | 759 | ret = bmi160_set_mode(data, BMI160_ACCEL, true); |
| 759 | if (ret) | 760 | if (ret) |
| 760 | return ret; | 761 | goto disable_regulator; |
| 761 | 762 | ||
| 762 | ret = bmi160_set_mode(data, BMI160_GYRO, true); | 763 | ret = bmi160_set_mode(data, BMI160_GYRO, true); |
| 763 | if (ret) | 764 | if (ret) |
| 764 | return ret; | 765 | goto disable_accel; |
| 765 | 766 | ||
| 766 | return 0; | 767 | return 0; |
| 768 | |||
| 769 | disable_accel: | ||
| 770 | bmi160_set_mode(data, BMI160_ACCEL, false); | ||
| 771 | |||
| 772 | disable_regulator: | ||
| 773 | regulator_bulk_disable(ARRAY_SIZE(data->supplies), data->supplies); | ||
| 774 | return ret; | ||
| 767 | } | 775 | } |
| 768 | 776 | ||
| 769 | static int bmi160_data_rdy_trigger_set_state(struct iio_trigger *trig, | 777 | static int bmi160_data_rdy_trigger_set_state(struct iio_trigger *trig, |
| @@ -18,12 +18,15 @@ static int inv_icm42600_i2c_bus_setup(struct inv_icm42600_state *st) · 17 unmodified lines | |||
| 18 | unsigned int mask, val; | 18 | unsigned int mask, val; |
| 19 | int ret; | 19 | int ret; |
| 20 | 20 | ||
| 21 | /* setup interface registers */ | 21 | /* |
| 22 | ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG6, | 22 | * setup interface registers |
| 23 | INV_ICM42600_INTF_CONFIG6_MASK, | 23 | * This register write to REG_INTF_CONFIG6 enables a spike filter that |
| 24 | INV_ICM42600_INTF_CONFIG6_I3C_EN); | 24 | * is impacting the line and can prevent the I2C ACK to be seen by the |
| 25 | if (ret) | 25 | * controller. So we don't test the return value. |
| 26 | return ret; | 26 | */ |
| 27 | regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG6, | ||
| 28 | INV_ICM42600_INTF_CONFIG6_MASK, | ||
| 29 | INV_ICM42600_INTF_CONFIG6_I3C_EN); | ||
| 27 | 30 | ||
| 28 | ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG4, | 31 | ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG4, |
| 29 | INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY, 0); | 32 | INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY, 0); |
| @@ -416,6 +416,7 @@ static int ak8975_power_on(const struct ak8975_data *data) · 415 unmodified lines | |||
| 416 | if (ret) { | 416 | if (ret) { |
| 417 | dev_warn(&data->client->dev, | 417 | dev_warn(&data->client->dev, |
| 418 | "Failed to enable specified Vid supply\n"); | 418 | "Failed to enable specified Vid supply\n"); |
| 419 | regulator_disable(data->vdd); | ||
| 419 | return ret; | 420 | return ret; |
| 420 | } | 421 | } |
| 421 | 422 | ||
| @@ -70,13 +70,17 @@ · 69 unmodified lines | |||
| 70 | #define SX9324_REG_AFE_PH2 0x2a | 70 | #define SX9324_REG_AFE_PH2 0x2a |
| 71 | #define SX9324_REG_AFE_PH3 0x2b | 71 | #define SX9324_REG_AFE_PH3 0x2b |
| 72 | #define SX9324_REG_AFE_CTRL8 0x2c | 72 | #define SX9324_REG_AFE_CTRL8 0x2c |
| 73 | #define SX9324_REG_AFE_CTRL8_RESFILTN_4KOHM 0x02 | 73 | #define SX9324_REG_AFE_CTRL8_RESERVED 0x10 |
| 74 | #define SX9324_REG_AFE_CTRL8_RESFILTIN_4KOHM 0x02 | ||
| 74 | #define SX9324_REG_AFE_CTRL9 0x2d | 75 | #define SX9324_REG_AFE_CTRL9 0x2d |
| 75 | #define SX9324_REG_AFE_CTRL9_AGAIN_1 0x08 | 76 | #define SX9324_REG_AFE_CTRL9_AGAIN_1 0x08 |
| 76 | 77 | ||
| 77 | #define SX9324_REG_PROX_CTRL0 0x30 | 78 | #define SX9324_REG_PROX_CTRL0 0x30 |
| 78 | #define SX9324_REG_PROX_CTRL0_GAIN_MASK GENMASK(5, 3) | 79 | #define SX9324_REG_PROX_CTRL0_GAIN_MASK GENMASK(5, 3) |
| 79 | #define SX9324_REG_PROX_CTRL0_GAIN_1 0x80 | 80 | #define SX9324_REG_PROX_CTRL0_GAIN_SHIFT 3 |
| 81 | #define SX9324_REG_PROX_CTRL0_GAIN_RSVD 0x0 | ||
| 82 | #define SX9324_REG_PROX_CTRL0_GAIN_1 0x1 | ||
| 83 | #define SX9324_REG_PROX_CTRL0_GAIN_8 0x4 | ||
| 80 | #define SX9324_REG_PROX_CTRL0_RAWFILT_MASK GENMASK(2, 0) | 84 | #define SX9324_REG_PROX_CTRL0_RAWFILT_MASK GENMASK(2, 0) |
| 81 | #define SX9324_REG_PROX_CTRL0_RAWFILT_1P50 0x01 | 85 | #define SX9324_REG_PROX_CTRL0_RAWFILT_1P50 0x01 |
| 82 | #define SX9324_REG_PROX_CTRL1 0x31 | 86 | #define SX9324_REG_PROX_CTRL1 0x31 |
| @@ -379,7 +383,14 @@ static int sx9324_read_gain(struct sx_common_data *data, · 296 unmodified lines | |||
| 379 | if (ret) | 383 | if (ret) |
| 380 | return ret; | 384 | return ret; |
| 381 | 385 | ||
| 382 | *val = 1 << FIELD_GET(SX9324_REG_PROX_CTRL0_GAIN_MASK, regval); | 386 | regval = FIELD_GET(SX9324_REG_PROX_CTRL0_GAIN_MASK, regval); |
| 387 | if (regval) | ||
| 388 | regval--; | ||
| 389 | else if (regval == SX9324_REG_PROX_CTRL0_GAIN_RSVD || | ||
| 390 | regval > SX9324_REG_PROX_CTRL0_GAIN_8) | ||
| 391 | return -EINVAL; | ||
| 392 | |||
| 393 | *val = 1 << regval; | ||
| 383 | 394 | ||
| 384 | return IIO_VAL_INT; | 395 | return IIO_VAL_INT; |
| 385 | } | 396 | } |
| @@ -725,8 +736,12 @@ static int sx9324_write_gain(struct sx_common_data *data, · 339 unmodified lines | |||
| 725 | unsigned int gain, reg; | 736 | unsigned int gain, reg; |
| 726 | int ret; | 737 | int ret; |
| 727 | 738 | ||
| 728 | gain = ilog2(val); | ||
| 729 | reg = SX9324_REG_PROX_CTRL0 + chan->channel / 2; | 739 | reg = SX9324_REG_PROX_CTRL0 + chan->channel / 2; |
| 740 | |||
| 741 | gain = ilog2(val) + 1; | ||
| 742 | if (val <= 0 || gain > SX9324_REG_PROX_CTRL0_GAIN_8) | ||
| 743 | return -EINVAL; | ||
| 744 | |||
| 730 | gain = FIELD_PREP(SX9324_REG_PROX_CTRL0_GAIN_MASK, gain); | 745 | gain = FIELD_PREP(SX9324_REG_PROX_CTRL0_GAIN_MASK, gain); |
| 731 | 746 | ||
| 732 | mutex_lock(&data->mutex); | 747 | mutex_lock(&data->mutex); |
| @@ -781,12 +796,15 @@ static const struct sx_common_reg_default sx9324_default_regs[] = { · 48 unmodified lines | |||
| 781 | { SX9324_REG_AFE_PH2, 0x1a }, | 796 | { SX9324_REG_AFE_PH2, 0x1a }, |
| 782 | { SX9324_REG_AFE_PH3, 0x16 }, | 797 | { SX9324_REG_AFE_PH3, 0x16 }, |
| 783 | 798 | ||
| 784 | { SX9324_REG_AFE_CTRL8, SX9324_REG_AFE_CTRL8_RESFILTN_4KOHM }, | 799 | { SX9324_REG_AFE_CTRL8, SX9324_REG_AFE_CTRL8_RESERVED | |
| 800 | SX9324_REG_AFE_CTRL8_RESFILTIN_4KOHM }, | ||
| 785 | { SX9324_REG_AFE_CTRL9, SX9324_REG_AFE_CTRL9_AGAIN_1 }, | 801 | { SX9324_REG_AFE_CTRL9, SX9324_REG_AFE_CTRL9_AGAIN_1 }, |
| 786 | 802 | ||
| 787 | { SX9324_REG_PROX_CTRL0, SX9324_REG_PROX_CTRL0_GAIN_1 | | 803 | { SX9324_REG_PROX_CTRL0, |
| 804 | SX9324_REG_PROX_CTRL0_GAIN_1 << SX9324_REG_PROX_CTRL0_GAIN_SHIFT | | ||
| 788 | SX9324_REG_PROX_CTRL0_RAWFILT_1P50 }, | 805 | SX9324_REG_PROX_CTRL0_RAWFILT_1P50 }, |
| 789 | { SX9324_REG_PROX_CTRL1, SX9324_REG_PROX_CTRL0_GAIN_1 | | 806 | { SX9324_REG_PROX_CTRL1, |
| 807 | SX9324_REG_PROX_CTRL0_GAIN_1 << SX9324_REG_PROX_CTRL0_GAIN_SHIFT | | ||
| 790 | SX9324_REG_PROX_CTRL0_RAWFILT_1P50 }, | 808 | SX9324_REG_PROX_CTRL0_RAWFILT_1P50 }, |
| 791 | { SX9324_REG_PROX_CTRL2, SX9324_REG_PROX_CTRL2_AVGNEG_THRESH_16K }, | 809 | { SX9324_REG_PROX_CTRL2, SX9324_REG_PROX_CTRL2_AVGNEG_THRESH_16K }, |
| 792 | { SX9324_REG_PROX_CTRL3, SX9324_REG_PROX_CTRL3_AVGDEB_2SAMPLES | | 810 | { SX9324_REG_PROX_CTRL3, SX9324_REG_PROX_CTRL3_AVGDEB_2SAMPLES | |
| @@ -521,6 +521,7 @@ int sx_common_probe(struct i2c_client *client, · 520 unmodified lines | |||
| 521 | return dev_err_probe(dev, ret, "error reading WHOAMI\n"); | 521 | return dev_err_probe(dev, ret, "error reading WHOAMI\n"); |
| 522 | 522 | ||
| 523 | ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(dev)); | 523 | ACPI_COMPANION_SET(&indio_dev->dev, ACPI_COMPANION(dev)); |
| 524 | indio_dev->dev.of_node = client->dev.of_node; | ||
| 524 | indio_dev->modes = INDIO_DIRECT_MODE; | 525 | indio_dev->modes = INDIO_DIRECT_MODE; |
| 525 | 526 | ||
| 526 | indio_dev->channels = data->chip_info->iio_channels; | 527 | indio_dev->channels = data->chip_info->iio_channels; |
| @@ -2308,10 +2308,8 @@ err: · 2307 unmodified lines | |||
| 2308 | return NULL; | 2308 | return NULL; |
| 2309 | } | 2309 | } |
| 2310 | 2310 | ||
| 2311 | static void irdma_cm_node_free_cb(struct rcu_head *rcu_head) | 2311 | static void irdma_destroy_connection(struct irdma_cm_node *cm_node) |
| 2312 | { | 2312 | { |
| 2313 | struct irdma_cm_node *cm_node = | ||
| 2314 | container_of(rcu_head, struct irdma_cm_node, rcu_head); | ||
| 2315 | struct irdma_cm_core *cm_core = cm_node->cm_core; | 2313 | struct irdma_cm_core *cm_core = cm_node->cm_core; |
| 2316 | struct irdma_qp *iwqp; | 2314 | struct irdma_qp *iwqp; |
| 2317 | struct irdma_cm_info nfo; | 2315 | struct irdma_cm_info nfo; |
| @@ -2359,7 +2357,6 @@ static void irdma_cm_node_free_cb(struct rcu_head *rcu_head) · 41 unmodified lines | |||
| 2359 | } | 2357 | } |
| 2360 | 2358 | ||
| 2361 | cm_core->cm_free_ah(cm_node); | 2359 | cm_core->cm_free_ah(cm_node); |
| 2362 | kfree(cm_node); | ||
| 2363 | } | 2360 | } |
| 2364 | 2361 | ||
| 2365 | /** | 2362 | /** |
| @@ -2387,8 +2384,9 @@ void irdma_rem_ref_cm_node(struct irdma_cm_node *cm_node) · 21 unmodified lines | |||
| 2387 | 2384 | ||
| 2388 | spin_unlock_irqrestore(&cm_core->ht_lock, flags); | 2385 | spin_unlock_irqrestore(&cm_core->ht_lock, flags); |
| 2389 | 2386 | ||
| 2390 | /* wait for all list walkers to exit their grace period */ | 2387 | irdma_destroy_connection(cm_node); |
| 2391 | call_rcu(&cm_node->rcu_head, irdma_cm_node_free_cb); | 2388 | |
| 2389 | kfree_rcu(cm_node, rcu_head); | ||
| 2392 | } | 2390 | } |
| 2393 | 2391 | ||
| 2394 | /** | 2392 | /** |
| @@ -3246,15 +3244,10 @@ int irdma_setup_cm_core(struct irdma_device *iwdev, u8 rdma_ver) · 851 unmodified lines | |||
| 3246 | */ | 3244 | */ |
| 3247 | void irdma_cleanup_cm_core(struct irdma_cm_core *cm_core) | 3245 | void irdma_cleanup_cm_core(struct irdma_cm_core *cm_core) |
| 3248 | { | 3246 | { |
| 3249 | unsigned long flags; | ||
| 3250 | |||
| 3251 | if (!cm_core) | 3247 | if (!cm_core) |
| 3252 | return; | 3248 | return; |
| 3253 | 3249 | ||
| 3254 | spin_lock_irqsave(&cm_core->ht_lock, flags); | 3250 | del_timer_sync(&cm_core->tcp_timer); |
| 3255 | if (timer_pending(&cm_core->tcp_timer)) | ||
| 3256 | del_timer_sync(&cm_core->tcp_timer); | ||
| 3257 | spin_unlock_irqrestore(&cm_core->ht_lock, flags); | ||
| 3258 | 3251 | ||
| 3259 | destroy_workqueue(cm_core->event_wq); | 3252 | destroy_workqueue(cm_core->event_wq); |
| 3260 | cm_core->dev->ws_reset(&cm_core->iwdev->vsi); | 3253 | cm_core->dev->ws_reset(&cm_core->iwdev->vsi); |
| @@ -3467,12 +3460,6 @@ static void irdma_cm_disconn_true(struct irdma_qp *iwqp) · 206 unmodified lines | |||
| 3467 | } | 3460 | } |
| 3468 | 3461 | ||
| 3469 | cm_id = iwqp->cm_id; | 3462 | cm_id = iwqp->cm_id; |
| 3470 | /* make sure we havent already closed this connection */ | ||
| 3471 | if (!cm_id) { | ||
| 3472 | spin_unlock_irqrestore(&iwqp->lock, flags); | ||
| 3473 | return; | ||
| 3474 | } | ||
| 3475 | |||
| 3476 | original_hw_tcp_state = iwqp->hw_tcp_state; | 3463 | original_hw_tcp_state = iwqp->hw_tcp_state; |
| 3477 | original_ibqp_state = iwqp->ibqp_state; | 3464 | original_ibqp_state = iwqp->ibqp_state; |
| 3478 | last_ae = iwqp->last_aeq; | 3465 | last_ae = iwqp->last_aeq; |
| @@ -3494,11 +3481,11 @@ static void irdma_cm_disconn_true(struct irdma_qp *iwqp) · 15 unmodified lines | |||
| 3494 | disconn_status = -ECONNRESET; | 3481 | disconn_status = -ECONNRESET; |
| 3495 | } | 3482 | } |
| 3496 | 3483 | ||
| 3497 | if ((original_hw_tcp_state == IRDMA_TCP_STATE_CLOSED || | 3484 | if (original_hw_tcp_state == IRDMA_TCP_STATE_CLOSED || |
| 3498 | original_hw_tcp_state == IRDMA_TCP_STATE_TIME_WAIT || | 3485 | original_hw_tcp_state == IRDMA_TCP_STATE_TIME_WAIT || |
| 3499 | last_ae == IRDMA_AE_RDMAP_ROE_BAD_LLP_CLOSE || | 3486 | last_ae == IRDMA_AE_RDMAP_ROE_BAD_LLP_CLOSE || |
| 3500 | last_ae == IRDMA_AE_BAD_CLOSE || | 3487 | last_ae == IRDMA_AE_BAD_CLOSE || |
| 3501 | last_ae == IRDMA_AE_LLP_CONNECTION_RESET || iwdev->rf->reset)) { | 3488 | last_ae == IRDMA_AE_LLP_CONNECTION_RESET || iwdev->rf->reset || !cm_id) { |
| 3502 | issue_close = 1; | 3489 | issue_close = 1; |
| 3503 | iwqp->cm_id = NULL; | 3490 | iwqp->cm_id = NULL; |
| 3504 | qp->term_flags = 0; | 3491 | qp->term_flags = 0; |
| @@ -258,18 +258,16 @@ int irdma_net_event(struct notifier_block *notifier, unsigned long event, · 257 unmodified lines | |||
| 258 | u32 local_ipaddr[4] = {}; | 258 | u32 local_ipaddr[4] = {}; |
| 259 | bool ipv4 = true; | 259 | bool ipv4 = true; |
| 260 | 260 | ||
| 261 | real_dev = rdma_vlan_dev_real_dev(netdev); | ||
| 262 | if (!real_dev) | ||
| 263 | real_dev = netdev; | ||
| 264 | |||
| 265 | ibdev = ib_device_get_by_netdev(real_dev, RDMA_DRIVER_IRDMA); | ||
| 266 | if (!ibdev) | ||
| 267 | return NOTIFY_DONE; | ||
| 268 | |||
| 269 | iwdev = to_iwdev(ibdev); | ||
| 270 | |||
| 271 | switch (event) { | 261 | switch (event) { |
| 272 | case NETEVENT_NEIGH_UPDATE: | 262 | case NETEVENT_NEIGH_UPDATE: |
| 263 | real_dev = rdma_vlan_dev_real_dev(netdev); | ||
| 264 | if (!real_dev) | ||
| 265 | real_dev = netdev; | ||
| 266 | ibdev = ib_device_get_by_netdev(real_dev, RDMA_DRIVER_IRDMA); | ||
| 267 | if (!ibdev) | ||
| 268 | return NOTIFY_DONE; | ||
| 269 | |||
| 270 | iwdev = to_iwdev(ibdev); | ||
| 273 | p = (__be32 *)neigh->primary_key; | 271 | p = (__be32 *)neigh->primary_key; |
| 274 | if (neigh->tbl->family == AF_INET6) { | 272 | if (neigh->tbl->family == AF_INET6) { |
| 275 | ipv4 = false; | 273 | ipv4 = false; |
| @@ -290,13 +288,12 @@ int irdma_net_event(struct notifier_block *notifier, unsigned long event, · 14 unmodified lines | |||
| 290 | irdma_manage_arp_cache(iwdev->rf, neigh->ha, | 288 | irdma_manage_arp_cache(iwdev->rf, neigh->ha, |
| 291 | local_ipaddr, ipv4, | 289 | local_ipaddr, ipv4, |
| 292 | IRDMA_ARP_DELETE); | 290 | IRDMA_ARP_DELETE); |
| 291 | ib_device_put(ibdev); | ||
| 293 | break; | 292 | break; |
| 294 | default: | 293 | default: |
| 295 | break; | 294 | break; |
| 296 | } | 295 | } |
| 297 | 296 | ||
| 298 | ib_device_put(ibdev); | ||
| 299 | |||
| 300 | return NOTIFY_DONE; | 297 | return NOTIFY_DONE; |
| 301 | } | 298 | } |
| 302 | 299 | ||
| @@ -1618,13 +1618,13 @@ int irdma_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, · 1617 unmodified lines | |||
| 1618 | 1618 | ||
| 1619 | if (issue_modify_qp && iwqp->ibqp_state > IB_QPS_RTS) { | 1619 | if (issue_modify_qp && iwqp->ibqp_state > IB_QPS_RTS) { |
| 1620 | if (dont_wait) { | 1620 | if (dont_wait) { |
| 1621 | if (iwqp->cm_id && iwqp->hw_tcp_state) { | 1621 | if (iwqp->hw_tcp_state) { |
| 1622 | spin_lock_irqsave(&iwqp->lock, flags); | 1622 | spin_lock_irqsave(&iwqp->lock, flags); |
| 1623 | iwqp->hw_tcp_state = IRDMA_TCP_STATE_CLOSED; | 1623 | iwqp->hw_tcp_state = IRDMA_TCP_STATE_CLOSED; |
| 1624 | iwqp->last_aeq = IRDMA_AE_RESET_SENT; | 1624 | iwqp->last_aeq = IRDMA_AE_RESET_SENT; |
| 1625 | spin_unlock_irqrestore(&iwqp->lock, flags); | 1625 | spin_unlock_irqrestore(&iwqp->lock, flags); |
| 1626 | irdma_cm_disconn(iwqp); | ||
| 1627 | } | 1626 | } |
| 1627 | irdma_cm_disconn(iwqp); | ||
| 1628 | } else { | 1628 | } else { |
| 1629 | int close_timer_started; | 1629 | int close_timer_started; |
| 1630 | 1630 | ||
| @@ -38,13 +38,13 @@ static int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid) · 37 unmodified lines | |||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | /** | 40 | /** |
| 41 | * rxe_mcast_delete - delete multicast address from rxe device | 41 | * rxe_mcast_del - delete multicast address from rxe device |
| 42 | * @rxe: rxe device object | 42 | * @rxe: rxe device object |
| 43 | * @mgid: multicast address as a gid | 43 | * @mgid: multicast address as a gid |
| 44 | * | 44 | * |
| 45 | * Returns 0 on success else an error | 45 | * Returns 0 on success else an error |
| 46 | */ | 46 | */ |
| 47 | static int rxe_mcast_delete(struct rxe_dev *rxe, union ib_gid *mgid) | 47 | static int rxe_mcast_del(struct rxe_dev *rxe, union ib_gid *mgid) |
| 48 | { | 48 | { |
| 49 | unsigned char ll_addr[ETH_ALEN]; | 49 | unsigned char ll_addr[ETH_ALEN]; |
| 50 | 50 | ||
| @@ -143,11 +143,10 @@ static struct rxe_mcg *__rxe_lookup_mcg(struct rxe_dev *rxe, · 92 unmodified lines | |||
| 143 | struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid) | 143 | struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid) |
| 144 | { | 144 | { |
| 145 | struct rxe_mcg *mcg; | 145 | struct rxe_mcg *mcg; |
| 146 | unsigned long flags; | ||
| 147 | 146 | ||
| 148 | spin_lock_irqsave(&rxe->mcg_lock, flags); | 147 | spin_lock_bh(&rxe->mcg_lock); |
| 149 | mcg = __rxe_lookup_mcg(rxe, mgid); | 148 | mcg = __rxe_lookup_mcg(rxe, mgid); |
| 150 | spin_unlock_irqrestore(&rxe->mcg_lock, flags); | 149 | spin_unlock_bh(&rxe->mcg_lock); |
| 151 | 150 | ||
| 152 | return mcg; | 151 | return mcg; |
| 153 | } | 152 | } |
| @@ -159,17 +158,10 @@ struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid) · 5 unmodified lines | |||
| 159 | * @mcg: new mcg object | 158 | * @mcg: new mcg object |
| 160 | * | 159 | * |
| 161 | * Context: caller should hold rxe->mcg lock | 160 | * Context: caller should hold rxe->mcg lock |
| 162 | * Returns: 0 on success else an error | ||
| 163 | */ | 161 | */ |
| 164 | static int __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid, | 162 | static void __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid, |
| 165 | struct rxe_mcg *mcg) | 163 | struct rxe_mcg *mcg) |
| 166 | { | 164 | { |
| 167 | int err; | ||
| 168 | |||
| 169 | err = rxe_mcast_add(rxe, mgid); | ||
| 170 | if (unlikely(err)) | ||
| 171 | return err; | ||
| 172 | |||
| 173 | kref_init(&mcg->ref_cnt); | 165 | kref_init(&mcg->ref_cnt); |
| 174 | memcpy(&mcg->mgid, mgid, sizeof(mcg->mgid)); | 166 | memcpy(&mcg->mgid, mgid, sizeof(mcg->mgid)); |
| 175 | INIT_LIST_HEAD(&mcg->qp_list); | 167 | INIT_LIST_HEAD(&mcg->qp_list); |
| @@ -184,8 +176,6 @@ static int __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid, · 8 unmodified lines | |||
| 184 | */ | 176 | */ |
| 185 | kref_get(&mcg->ref_cnt); | 177 | kref_get(&mcg->ref_cnt); |
| 186 | __rxe_insert_mcg(mcg); | 178 | __rxe_insert_mcg(mcg); |
| 187 | |||
| 188 | return 0; | ||
| 189 | } | 179 | } |
| 190 | 180 | ||
| 191 | /** | 181 | /** |
| @@ -198,7 +188,6 @@ static int __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid, · 6 unmodified lines | |||
| 198 | static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) | 188 | static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) |
| 199 | { | 189 | { |
| 200 | struct rxe_mcg *mcg, *tmp; | 190 | struct rxe_mcg *mcg, *tmp; |
| 201 | unsigned long flags; | ||
| 202 | int err; | 191 | int err; |
| 203 | 192 | ||
| 204 | if (rxe->attr.max_mcast_grp == 0) | 193 | if (rxe->attr.max_mcast_grp == 0) |
| @@ -209,36 +198,38 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) · 4 unmodified lines | |||
| 209 | if (mcg) | 198 | if (mcg) |
| 210 | return mcg; | 199 | return mcg; |
| 211 | 200 | ||
| 201 | /* check to see if we have reached limit */ | ||
| 202 | if (atomic_inc_return(&rxe->mcg_num) > rxe->attr.max_mcast_grp) { | ||
| 203 | err = -ENOMEM; | ||
| 204 | goto err_dec; | ||
| 205 | } | ||
| 206 | |||
| 212 | /* speculative alloc of new mcg */ | 207 | /* speculative alloc of new mcg */ |
| 213 | mcg = kzalloc(sizeof(*mcg), GFP_KERNEL); | 208 | mcg = kzalloc(sizeof(*mcg), GFP_KERNEL); |
| 214 | if (!mcg) | 209 | if (!mcg) |
| 215 | return ERR_PTR(-ENOMEM); | 210 | return ERR_PTR(-ENOMEM); |
| 216 | 211 | ||
| 217 | spin_lock_irqsave(&rxe->mcg_lock, flags); | 212 | spin_lock_bh(&rxe->mcg_lock); |
| 218 | /* re-check to see if someone else just added it */ | 213 | /* re-check to see if someone else just added it */ |
| 219 | tmp = __rxe_lookup_mcg(rxe, mgid); | 214 | tmp = __rxe_lookup_mcg(rxe, mgid); |
| 220 | if (tmp) { | 215 | if (tmp) { |
| 216 | spin_unlock_bh(&rxe->mcg_lock); | ||
| 217 | atomic_dec(&rxe->mcg_num); | ||
| 221 | kfree(mcg); | 218 | kfree(mcg); |
| 222 | mcg = tmp; | 219 | return tmp; |
| 223 | goto out; | ||
| 224 | } | 220 | } |
| 225 | 221 | ||
| 226 | if (atomic_inc_return(&rxe->mcg_num) > rxe->attr.max_mcast_grp) { | 222 | __rxe_init_mcg(rxe, mgid, mcg); |
| 227 | err = -ENOMEM; | 223 | spin_unlock_bh(&rxe->mcg_lock); |
| 228 | goto err_dec; | ||
| 229 | } | ||
| 230 | 224 | ||
| 231 | err = __rxe_init_mcg(rxe, mgid, mcg); | 225 | /* add mcast address outside of lock */ |
| 232 | if (err) | 226 | err = rxe_mcast_add(rxe, mgid); |
| 233 | goto err_dec; | 227 | if (!err) |
| 234 | out: | 228 | return mcg; |
| 235 | spin_unlock_irqrestore(&rxe->mcg_lock, flags); | ||
| 236 | return mcg; | ||
| 237 | 229 | ||
| 230 | kfree(mcg); | ||
| 238 | err_dec: | 231 | err_dec: |
| 239 | atomic_dec(&rxe->mcg_num); | 232 | atomic_dec(&rxe->mcg_num); |
| 240 | spin_unlock_irqrestore(&rxe->mcg_lock, flags); | ||
| 241 | kfree(mcg); | ||
| 242 | return ERR_PTR(err); | 233 | return ERR_PTR(err); |
| 243 | } | 234 | } |
| 244 | 235 | ||
| @@ -268,7 +259,6 @@ static void __rxe_destroy_mcg(struct rxe_mcg *mcg) · 23 unmodified lines | |||
| 268 | __rxe_remove_mcg(mcg); | 259 | __rxe_remove_mcg(mcg); |
| 269 | kref_put(&mcg->ref_cnt, rxe_cleanup_mcg); | 260 | kref_put(&mcg->ref_cnt, rxe_cleanup_mcg); |
| 270 | 261 | ||
| 271 | rxe_mcast_delete(mcg->rxe, &mcg->mgid); | ||
| 272 | atomic_dec(&rxe->mcg_num); | 262 | atomic_dec(&rxe->mcg_num); |
| 273 | } | 263 | } |
| 274 | 264 | ||
| @@ -280,11 +270,12 @@ static void __rxe_destroy_mcg(struct rxe_mcg *mcg) · 5 unmodified lines | |||
| 280 | */ | 270 | */ |
| 281 | static void rxe_destroy_mcg(struct rxe_mcg *mcg) | 271 | static void rxe_destroy_mcg(struct rxe_mcg *mcg) |
| 282 | { | 272 | { |
| 283 | unsigned long flags; | 273 | /* delete mcast address outside of lock */ |
| 274 | rxe_mcast_del(mcg->rxe, &mcg->mgid); | ||
| 284 | 275 | ||
| 285 | spin_lock_irqsave(&mcg->rxe->mcg_lock, flags); | 276 | spin_lock_bh(&mcg->rxe->mcg_lock); |
| 286 | __rxe_destroy_mcg(mcg); | 277 | __rxe_destroy_mcg(mcg); |
| 287 | spin_unlock_irqrestore(&mcg->rxe->mcg_lock, flags); | 278 | spin_unlock_bh(&mcg->rxe->mcg_lock); |
| 288 | } | 279 | } |
| 289 | 280 | ||
| 290 | /** | 281 | /** |
| @@ -339,25 +330,24 @@ static int rxe_attach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) · 48 unmodified lines | |||
| 339 | { | 330 | { |
| 340 | struct rxe_dev *rxe = mcg->rxe; | 331 | struct rxe_dev *rxe = mcg->rxe; |
| 341 | struct rxe_mca *mca, *tmp; | 332 | struct rxe_mca *mca, *tmp; |
| 342 | unsigned long flags; | ||
| 343 | int err; | 333 | int err; |
| 344 | 334 | ||
| 345 | /* check to see if the qp is already a member of the group */ | 335 | /* check to see if the qp is already a member of the group */ |
| 346 | spin_lock_irqsave(&rxe->mcg_lock, flags); | 336 | spin_lock_bh(&rxe->mcg_lock); |
| 347 | list_for_each_entry(mca, &mcg->qp_list, qp_list) { | 337 | list_for_each_entry(mca, &mcg->qp_list, qp_list) { |
| 348 | if (mca->qp == qp) { | 338 | if (mca->qp == qp) { |
| 349 | spin_unlock_irqrestore(&rxe->mcg_lock, flags); | 339 | spin_unlock_bh(&rxe->mcg_lock); |
| 350 | return 0; | 340 | return 0; |
| 351 | } | 341 | } |
| 352 | } | 342 | } |
| 353 | spin_unlock_irqrestore(&rxe->mcg_lock, flags); | 343 | spin_unlock_bh(&rxe->mcg_lock); |
| 354 | 344 | ||
| 355 | /* speculative alloc new mca without using GFP_ATOMIC */ | 345 | /* speculative alloc new mca without using GFP_ATOMIC */ |
| 356 | mca = kzalloc(sizeof(*mca), GFP_KERNEL); | 346 | mca = kzalloc(sizeof(*mca), GFP_KERNEL); |
| 357 | if (!mca) | 347 | if (!mca) |
| 358 | return -ENOMEM; | 348 | return -ENOMEM; |
| 359 | 349 | ||
| 360 | spin_lock_irqsave(&rxe->mcg_lock, flags); | 350 | spin_lock_bh(&rxe->mcg_lock); |
| 361 | /* re-check to see if someone else just attached qp */ | 351 | /* re-check to see if someone else just attached qp */ |
| 362 | list_for_each_entry(tmp, &mcg->qp_list, qp_list) { | 352 | list_for_each_entry(tmp, &mcg->qp_list, qp_list) { |
| 363 | if (tmp->qp == qp) { | 353 | if (tmp->qp == qp) { |
| @@ -371,7 +361,7 @@ static int rxe_attach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) · 7 unmodified lines | |||
| 371 | if (err) | 361 | if (err) |
| 372 | kfree(mca); | 362 | kfree(mca); |
| 373 | out: | 363 | out: |
| 374 | spin_unlock_irqrestore(&rxe->mcg_lock, flags); | 364 | spin_unlock_bh(&rxe->mcg_lock); |
| 375 | return err; | 365 | return err; |
| 376 | } | 366 | } |
| 377 | 367 | ||
| @@ -405,9 +395,8 @@ static int rxe_detach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) · 27 unmodified lines | |||
| 405 | { | 395 | { |
| 406 | struct rxe_dev *rxe = mcg->rxe; | 396 | struct rxe_dev *rxe = mcg->rxe; |
| 407 | struct rxe_mca *mca, *tmp; | 397 | struct rxe_mca *mca, *tmp; |
| 408 | unsigned long flags; | ||
| 409 | 398 | ||
| 410 | spin_lock_irqsave(&rxe->mcg_lock, flags); | 399 | spin_lock_bh(&rxe->mcg_lock); |
| 411 | list_for_each_entry_safe(mca, tmp, &mcg->qp_list, qp_list) { | 400 | list_for_each_entry_safe(mca, tmp, &mcg->qp_list, qp_list) { |
| 412 | if (mca->qp == qp) { | 401 | if (mca->qp == qp) { |
| 413 | __rxe_cleanup_mca(mca, mcg); | 402 | __rxe_cleanup_mca(mca, mcg); |
| @@ -421,13 +410,13 @@ static int rxe_detach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) · 7 unmodified lines | |||
| 421 | if (atomic_read(&mcg->qp_num) <= 0) | 410 | if (atomic_read(&mcg->qp_num) <= 0) |
| 422 | __rxe_destroy_mcg(mcg); | 411 | __rxe_destroy_mcg(mcg); |
| 423 | 412 | ||
| 424 | spin_unlock_irqrestore(&rxe->mcg_lock, flags); | 413 | spin_unlock_bh(&rxe->mcg_lock); |
| 425 | return 0; | 414 | return 0; |
| 426 | } | 415 | } |
| 427 | } | 416 | } |
| 428 | 417 | ||
| 429 | /* we didn't find the qp on the list */ | 418 | /* we didn't find the qp on the list */ |
| 430 | spin_unlock_irqrestore(&rxe->mcg_lock, flags); | 419 | spin_unlock_bh(&rxe->mcg_lock); |
| 431 | return -EINVAL; | 420 | return -EINVAL; |
| 432 | } | 421 | } |
| 433 | 422 | ||
| @@ -680,6 +680,11 @@ static struct resp_res *rxe_prepare_read_res(struct rxe_qp *qp, · 679 unmodified lines | |||
| 680 | * It is assumed that the access permissions if originally good | 680 | * It is assumed that the access permissions if originally good |
| 681 | * are OK and the mappings to be unchanged. | 681 | * are OK and the mappings to be unchanged. |
| 682 | * | 682 | * |
| 683 | * TODO: If someone reregisters an MR to change its size or | ||
| 684 | * access permissions during the processing of an RDMA read | ||
| 685 | * we should kill the responder resource and complete the | ||
| 686 | * operation with an error. | ||
| 687 | * | ||
| 683 | * Return: mr on success else NULL | 688 | * Return: mr on success else NULL |
| 684 | */ | 689 | */ |
| 685 | static struct rxe_mr *rxe_recheck_mr(struct rxe_qp *qp, u32 rkey) | 690 | static struct rxe_mr *rxe_recheck_mr(struct rxe_qp *qp, u32 rkey) |
| @@ -690,23 +695,27 @@ static struct rxe_mr *rxe_recheck_mr(struct rxe_qp *qp, u32 rkey) · 4 unmodified lines | |||
| 690 | 695 | ||
| 691 | if (rkey_is_mw(rkey)) { | 696 | if (rkey_is_mw(rkey)) { |
| 692 | mw = rxe_pool_get_index(&rxe->mw_pool, rkey >> 8); | 697 | mw = rxe_pool_get_index(&rxe->mw_pool, rkey >> 8); |
| 693 | if (!mw || mw->rkey != rkey) | 698 | if (!mw) |
| 694 | return NULL; | 699 | return NULL; |
| 695 | 700 | ||
| 696 | if (mw->state != RXE_MW_STATE_VALID) { | 701 | mr = mw->mr; |
| 702 | if (mw->rkey != rkey || mw->state != RXE_MW_STATE_VALID || | ||
| 703 | !mr || mr->state != RXE_MR_STATE_VALID) { | ||
| 697 | rxe_put(mw); | 704 | rxe_put(mw); |
| 698 | return NULL; | 705 | return NULL; |
| 699 | } | 706 | } |
| 700 | 707 | ||
| 701 | mr = mw->mr; | 708 | rxe_get(mr); |
| 702 | rxe_put(mw); | 709 | rxe_put(mw); |
| 703 | } else { | 710 | |
| 704 | mr = rxe_pool_get_index(&rxe->mr_pool, rkey >> 8); | 711 | return mr; |
| 705 | if (!mr || mr->rkey != rkey) | ||
| 706 | return NULL; | ||
| 707 | } | 712 | } |
| 708 | 713 | ||
| 709 | if (mr->state != RXE_MR_STATE_VALID) { | 714 | mr = rxe_pool_get_index(&rxe->mr_pool, rkey >> 8); |
| 715 | if (!mr) | ||
| 716 | return NULL; | ||
| 717 | |||
| 718 | if (mr->rkey != rkey || mr->state != RXE_MR_STATE_VALID) { | ||
| 710 | rxe_put(mr); | 719 | rxe_put(mr); |
| 711 | return NULL; | 720 | return NULL; |
| 712 | } | 721 | } |
| @@ -736,8 +745,14 @@ static enum resp_states read_reply(struct rxe_qp *qp, · 23 unmodified lines | |||
| 736 | } | 745 | } |
| 737 | 746 | ||
| 738 | if (res->state == rdatm_res_state_new) { | 747 | if (res->state == rdatm_res_state_new) { |
| 739 | mr = qp->resp.mr; | 748 | if (!res->replay) { |
| 740 | qp->resp.mr = NULL; | 749 | mr = qp->resp.mr; |
| 750 | qp->resp.mr = NULL; | ||
| 751 | } else { | ||
| 752 | mr = rxe_recheck_mr(qp, res->read.rkey); | ||
| 753 | if (!mr) | ||
| 754 | return RESPST_ERR_RKEY_VIOLATION; | ||
| 755 | } | ||
| 741 | 756 | ||
| 742 | if (res->read.resid <= mtu) | 757 | if (res->read.resid <= mtu) |
| 743 | opcode = IB_OPCODE_RC_RDMA_READ_RESPONSE_ONLY; | 758 | opcode = IB_OPCODE_RC_RDMA_READ_RESPONSE_ONLY; |
| @@ -968,14 +968,15 @@ static void siw_accept_newconn(struct siw_cep *cep) · 967 unmodified lines | |||
| 968 | 968 | ||
| 969 | siw_cep_set_inuse(new_cep); | 969 | siw_cep_set_inuse(new_cep); |
| 970 | rv = siw_proc_mpareq(new_cep); | 970 | rv = siw_proc_mpareq(new_cep); |
| 971 | siw_cep_set_free(new_cep); | ||
| 972 | |||
| 973 | if (rv != -EAGAIN) { | 971 | if (rv != -EAGAIN) { |
| 974 | siw_cep_put(cep); | 972 | siw_cep_put(cep); |
| 975 | new_cep->listen_cep = NULL; | 973 | new_cep->listen_cep = NULL; |
| 976 | if (rv) | 974 | if (rv) { |
| 975 | siw_cep_set_free(new_cep); | ||
| 977 | goto error; | 976 | goto error; |
| 977 | } | ||
| 978 | } | 978 | } |
| 979 | siw_cep_set_free(new_cep); | ||
| 979 | } | 980 | } |
| 980 | return; | 981 | return; |
| 981 | 982 | ||
| @@ -1087,9 +1087,15 @@ static int of_count_icc_providers(struct device_node *np) · 1086 unmodified lines | |||
| 1087 | { | 1087 | { |
| 1088 | struct device_node *child; | 1088 | struct device_node *child; |
| 1089 | int count = 0; | 1089 | int count = 0; |
| 1090 | const struct of_device_id __maybe_unused ignore_list[] = { | ||
| 1091 | { .compatible = "qcom,sc7180-ipa-virt" }, | ||
| 1092 | { .compatible = "qcom,sdx55-ipa-virt" }, | ||
| 1093 | {} | ||
| 1094 | }; | ||
| 1090 | 1095 | ||
| 1091 | for_each_available_child_of_node(np, child) { | 1096 | for_each_available_child_of_node(np, child) { |
| 1092 | if (of_property_read_bool(child, "#interconnect-cells")) | 1097 | if (of_property_read_bool(child, "#interconnect-cells") && |
| 1098 | likely(!of_match_node(ignore_list, child))) | ||
| 1093 | count++; | 1099 | count++; |
| 1094 | count += of_count_icc_providers(child); | 1100 | count += of_count_icc_providers(child); |
| 1095 | } | 1101 | } |
| @@ -47,7 +47,6 @@ DEFINE_QNODE(qnm_mnoc_sf, SC7180_MASTER_MNOC_SF_MEM_NOC, 1, 32, SC7180_SLAVE_GEM · 46 unmodified lines | |||
| 47 | DEFINE_QNODE(qnm_snoc_gc, SC7180_MASTER_SNOC_GC_MEM_NOC, 1, 8, SC7180_SLAVE_LLCC); | 47 | DEFINE_QNODE(qnm_snoc_gc, SC7180_MASTER_SNOC_GC_MEM_NOC, 1, 8, SC7180_SLAVE_LLCC); |
| 48 | DEFINE_QNODE(qnm_snoc_sf, SC7180_MASTER_SNOC_SF_MEM_NOC, 1, 16, SC7180_SLAVE_LLCC); | 48 | DEFINE_QNODE(qnm_snoc_sf, SC7180_MASTER_SNOC_SF_MEM_NOC, 1, 16, SC7180_SLAVE_LLCC); |
| 49 | DEFINE_QNODE(qxm_gpu, SC7180_MASTER_GFX3D, 2, 32, SC7180_SLAVE_GEM_NOC_SNOC, SC7180_SLAVE_LLCC); | 49 | DEFINE_QNODE(qxm_gpu, SC7180_MASTER_GFX3D, 2, 32, SC7180_SLAVE_GEM_NOC_SNOC, SC7180_SLAVE_LLCC); |
| 50 | DEFINE_QNODE(ipa_core_master, SC7180_MASTER_IPA_CORE, 1, 8, SC7180_SLAVE_IPA_CORE); | ||
| 51 | DEFINE_QNODE(llcc_mc, SC7180_MASTER_LLCC, 2, 4, SC7180_SLAVE_EBI1); | 50 | DEFINE_QNODE(llcc_mc, SC7180_MASTER_LLCC, 2, 4, SC7180_SLAVE_EBI1); |
| 52 | DEFINE_QNODE(qhm_mnoc_cfg, SC7180_MASTER_CNOC_MNOC_CFG, 1, 4, SC7180_SLAVE_SERVICE_MNOC); | 51 | DEFINE_QNODE(qhm_mnoc_cfg, SC7180_MASTER_CNOC_MNOC_CFG, 1, 4, SC7180_SLAVE_SERVICE_MNOC); |
| 53 | DEFINE_QNODE(qxm_camnoc_hf0, SC7180_MASTER_CAMNOC_HF0, 2, 32, SC7180_SLAVE_MNOC_HF_MEM_NOC); | 52 | DEFINE_QNODE(qxm_camnoc_hf0, SC7180_MASTER_CAMNOC_HF0, 2, 32, SC7180_SLAVE_MNOC_HF_MEM_NOC); |
| @@ -129,7 +128,6 @@ DEFINE_QNODE(qhs_mdsp_ms_mpu_cfg, SC7180_SLAVE_MSS_PROC_MS_MPU_CFG, 1, 4); · 75 unmodified lines | |||
| 129 | DEFINE_QNODE(qns_gem_noc_snoc, SC7180_SLAVE_GEM_NOC_SNOC, 1, 8, SC7180_MASTER_GEM_NOC_SNOC); | 128 | DEFINE_QNODE(qns_gem_noc_snoc, SC7180_SLAVE_GEM_NOC_SNOC, 1, 8, SC7180_MASTER_GEM_NOC_SNOC); |
| 130 | DEFINE_QNODE(qns_llcc, SC7180_SLAVE_LLCC, 1, 16, SC7180_MASTER_LLCC); | 129 | DEFINE_QNODE(qns_llcc, SC7180_SLAVE_LLCC, 1, 16, SC7180_MASTER_LLCC); |
| 131 | DEFINE_QNODE(srvc_gemnoc, SC7180_SLAVE_SERVICE_GEM_NOC, 1, 4); | 130 | DEFINE_QNODE(srvc_gemnoc, SC7180_SLAVE_SERVICE_GEM_NOC, 1, 4); |
| 132 | DEFINE_QNODE(ipa_core_slave, SC7180_SLAVE_IPA_CORE, 1, 8); | ||
| 133 | DEFINE_QNODE(ebi, SC7180_SLAVE_EBI1, 2, 4); | 131 | DEFINE_QNODE(ebi, SC7180_SLAVE_EBI1, 2, 4); |
| 134 | DEFINE_QNODE(qns_mem_noc_hf, SC7180_SLAVE_MNOC_HF_MEM_NOC, 1, 32, SC7180_MASTER_MNOC_HF_MEM_NOC); | 132 | DEFINE_QNODE(qns_mem_noc_hf, SC7180_SLAVE_MNOC_HF_MEM_NOC, 1, 32, SC7180_MASTER_MNOC_HF_MEM_NOC); |
| 135 | DEFINE_QNODE(qns_mem_noc_sf, SC7180_SLAVE_MNOC_SF_MEM_NOC, 1, 32, SC7180_MASTER_MNOC_SF_MEM_NOC); | 133 | DEFINE_QNODE(qns_mem_noc_sf, SC7180_SLAVE_MNOC_SF_MEM_NOC, 1, 32, SC7180_MASTER_MNOC_SF_MEM_NOC); |
| @@ -160,7 +158,6 @@ DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi); · 24 unmodified lines | |||
| 160 | DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc); | 158 | DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc); |
| 161 | DEFINE_QBCM(bcm_mm0, "MM0", false, &qns_mem_noc_hf); | 159 | DEFINE_QBCM(bcm_mm0, "MM0", false, &qns_mem_noc_hf); |
| 162 | DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto); | 160 | DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto); |
| 163 | DEFINE_QBCM(bcm_ip0, "IP0", false, &ipa_core_slave); | ||
| 164 | DEFINE_QBCM(bcm_cn0, "CN0", true, &qnm_snoc, &xm_qdss_dap, &qhs_a1_noc_cfg, &qhs_a2_noc_cfg, &qhs_ahb2phy0, &qhs_aop, &qhs_aoss, &qhs_boot_rom, &qhs_camera_cfg, &qhs_camera_nrt_throttle_cfg, &qhs_camera_rt_throttle_cfg, &qhs_clk_ctl, &qhs_cpr_cx, &qhs_cpr_mx, &qhs_crypto0_cfg, &qhs_dcc_cfg, &qhs_ddrss_cfg, &qhs_display_cfg, &qhs_display_rt_throttle_cfg, &qhs_display_throttle_cfg, &qhs_glm, &qhs_gpuss_cfg, &qhs_imem_cfg, &qhs_ipa, &qhs_mnoc_cfg, &qhs_mss_cfg, &qhs_npu_cfg, &qhs_npu_dma_throttle_cfg, &qhs_npu_dsp_throttle_cfg, &qhs_pimem_cfg, &qhs_prng, &qhs_qdss_cfg, &qhs_qm_cfg, &qhs_qm_mpu_cfg, &qhs_qup0, &qhs_qup1, &qhs_security, &qhs_snoc_cfg, &qhs_tcsr, &qhs_tlmm_1, &qhs_tlmm_2, &qhs_tlmm_3, &qhs_ufs_mem_cfg, &qhs_usb3, &qhs_venus_cfg, &qhs_venus_throttle_cfg, &qhs_vsense_ctrl_cfg, &srvc_cnoc); | 161 | DEFINE_QBCM(bcm_cn0, "CN0", true, &qnm_snoc, &xm_qdss_dap, &qhs_a1_noc_cfg, &qhs_a2_noc_cfg, &qhs_ahb2phy0, &qhs_aop, &qhs_aoss, &qhs_boot_rom, &qhs_camera_cfg, &qhs_camera_nrt_throttle_cfg, &qhs_camera_rt_throttle_cfg, &qhs_clk_ctl, &qhs_cpr_cx, &qhs_cpr_mx, &qhs_crypto0_cfg, &qhs_dcc_cfg, &qhs_ddrss_cfg, &qhs_display_cfg, &qhs_display_rt_throttle_cfg, &qhs_display_throttle_cfg, &qhs_glm, &qhs_gpuss_cfg, &qhs_imem_cfg, &qhs_ipa, &qhs_mnoc_cfg, &qhs_mss_cfg, &qhs_npu_cfg, &qhs_npu_dma_throttle_cfg, &qhs_npu_dsp_throttle_cfg, &qhs_pimem_cfg, &qhs_prng, &qhs_qdss_cfg, &qhs_qm_cfg, &qhs_qm_mpu_cfg, &qhs_qup0, &qhs_qup1, &qhs_security, &qhs_snoc_cfg, &qhs_tcsr, &qhs_tlmm_1, &qhs_tlmm_2, &qhs_tlmm_3, &qhs_ufs_mem_cfg, &qhs_usb3, &qhs_venus_cfg, &qhs_venus_throttle_cfg, &qhs_vsense_ctrl_cfg, &srvc_cnoc); |
| 165 | DEFINE_QBCM(bcm_mm1, "MM1", false, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qhm_mnoc_cfg, &qxm_mdp0, &qxm_rot, &qxm_venus0, &qxm_venus_arm9); | 162 | DEFINE_QBCM(bcm_mm1, "MM1", false, &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp, &qxm_camnoc_sf_uncomp, &qhm_mnoc_cfg, &qxm_mdp0, &qxm_rot, &qxm_venus0, &qxm_venus_arm9); |
| 166 | DEFINE_QBCM(bcm_sh2, "SH2", false, &acm_sys_tcu); | 163 | DEFINE_QBCM(bcm_sh2, "SH2", false, &acm_sys_tcu); |
| @@ -372,22 +369,6 @@ static struct qcom_icc_desc sc7180_gem_noc = { · 205 unmodified lines | |||
| 372 | .num_bcms = ARRAY_SIZE(gem_noc_bcms), | 369 | .num_bcms = ARRAY_SIZE(gem_noc_bcms), |
| 373 | }; | 370 | }; |
| 374 | 371 | ||
| 375 | static struct qcom_icc_bcm *ipa_virt_bcms[] = { | ||
| 376 | &bcm_ip0, | ||
| 377 | }; | ||
| 378 | |||
| 379 | static struct qcom_icc_node *ipa_virt_nodes[] = { | ||
| 380 | [MASTER_IPA_CORE] = &ipa_core_master, | ||
| 381 | [SLAVE_IPA_CORE] = &ipa_core_slave, | ||
| 382 | }; | ||
| 383 | |||
| 384 | static struct qcom_icc_desc sc7180_ipa_virt = { | ||
| 385 | .nodes = ipa_virt_nodes, | ||
| 386 | .num_nodes = ARRAY_SIZE(ipa_virt_nodes), | ||
| 387 | .bcms = ipa_virt_bcms, | ||
| 388 | .num_bcms = ARRAY_SIZE(ipa_virt_bcms), | ||
| 389 | }; | ||
| 390 | |||
| 391 | static struct qcom_icc_bcm *mc_virt_bcms[] = { | 372 | static struct qcom_icc_bcm *mc_virt_bcms[] = { |
| 392 | &bcm_acv, | 373 | &bcm_acv, |
| 393 | &bcm_mc0, | 374 | &bcm_mc0, |
| @@ -519,8 +500,6 @@ static const struct of_device_id qnoc_of_match[] = { · 125 unmodified lines | |||
| 519 | .data = &sc7180_dc_noc}, | 500 | .data = &sc7180_dc_noc}, |
| 520 | { .compatible = "qcom,sc7180-gem-noc", | 501 | { .compatible = "qcom,sc7180-gem-noc", |
| 521 | .data = &sc7180_gem_noc}, | 502 | .data = &sc7180_gem_noc}, |
| 522 | { .compatible = "qcom,sc7180-ipa-virt", | ||
| 523 | .data = &sc7180_ipa_virt}, | ||
| 524 | { .compatible = "qcom,sc7180-mc-virt", | 503 | { .compatible = "qcom,sc7180-mc-virt", |
| 525 | .data = &sc7180_mc_virt}, | 504 | .data = &sc7180_mc_virt}, |
| 526 | { .compatible = "qcom,sc7180-mmss-noc", | 505 | { .compatible = "qcom,sc7180-mmss-noc", |
| @@ -18,7 +18,6 @@ · 17 unmodified lines | |||
| 18 | #include "icc-rpmh.h" | 18 | #include "icc-rpmh.h" |
| 19 | #include "sdx55.h" | 19 | #include "sdx55.h" |
| 20 | 20 | ||
| 21 | DEFINE_QNODE(ipa_core_master, SDX55_MASTER_IPA_CORE, 1, 8, SDX55_SLAVE_IPA_CORE); | ||
| 22 | DEFINE_QNODE(llcc_mc, SDX55_MASTER_LLCC, 4, 4, SDX55_SLAVE_EBI_CH0); | 21 | DEFINE_QNODE(llcc_mc, SDX55_MASTER_LLCC, 4, 4, SDX55_SLAVE_EBI_CH0); |
| 23 | DEFINE_QNODE(acm_tcu, SDX55_MASTER_TCU_0, 1, 8, SDX55_SLAVE_LLCC, SDX55_SLAVE_MEM_NOC_SNOC, SDX55_SLAVE_MEM_NOC_PCIE_SNOC); | 22 | DEFINE_QNODE(acm_tcu, SDX55_MASTER_TCU_0, 1, 8, SDX55_SLAVE_LLCC, SDX55_SLAVE_MEM_NOC_SNOC, SDX55_SLAVE_MEM_NOC_PCIE_SNOC); |
| 24 | DEFINE_QNODE(qnm_snoc_gc, SDX55_MASTER_SNOC_GC_MEM_NOC, 1, 8, SDX55_SLAVE_LLCC); | 23 | DEFINE_QNODE(qnm_snoc_gc, SDX55_MASTER_SNOC_GC_MEM_NOC, 1, 8, SDX55_SLAVE_LLCC); |
| @@ -40,7 +39,6 @@ DEFINE_QNODE(xm_pcie, SDX55_MASTER_PCIE, 1, 8, SDX55_SLAVE_ANOC_SNOC); · 15 unmodified lines | |||
| 40 | DEFINE_QNODE(xm_qdss_etr, SDX55_MASTER_QDSS_ETR, 1, 8, SDX55_SLAVE_SNOC_CFG, SDX55_SLAVE_EMAC_CFG, SDX55_SLAVE_USB3, SDX55_SLAVE_AOSS, SDX55_SLAVE_SPMI_FETCHER, SDX55_SLAVE_QDSS_CFG, SDX55_SLAVE_PDM, SDX55_SLAVE_SNOC_MEM_NOC_GC, SDX55_SLAVE_TCSR, SDX55_SLAVE_CNOC_DDRSS, SDX55_SLAVE_SPMI_VGI_COEX, SDX55_SLAVE_QPIC, SDX55_SLAVE_OCIMEM, SDX55_SLAVE_IPA_CFG, SDX55_SLAVE_USB3_PHY_CFG, SDX55_SLAVE_AOP, SDX55_SLAVE_BLSP_1, SDX55_SLAVE_SDCC_1, SDX55_SLAVE_CNOC_MSS, SDX55_SLAVE_PCIE_PARF, SDX55_SLAVE_ECC_CFG, SDX55_SLAVE_AUDIO, SDX55_SLAVE_AOSS, SDX55_SLAVE_PRNG, SDX55_SLAVE_CRYPTO_0_CFG, SDX55_SLAVE_TCU, SDX55_SLAVE_CLK_CTL, SDX55_SLAVE_IMEM_CFG); | 39 | DEFINE_QNODE(xm_qdss_etr, SDX55_MASTER_QDSS_ETR, 1, 8, SDX55_SLAVE_SNOC_CFG, SDX55_SLAVE_EMAC_CFG, SDX55_SLAVE_USB3, SDX55_SLAVE_AOSS, SDX55_SLAVE_SPMI_FETCHER, SDX55_SLAVE_QDSS_CFG, SDX55_SLAVE_PDM, SDX55_SLAVE_SNOC_MEM_NOC_GC, SDX55_SLAVE_TCSR, SDX55_SLAVE_CNOC_DDRSS, SDX55_SLAVE_SPMI_VGI_COEX, SDX55_SLAVE_QPIC, SDX55_SLAVE_OCIMEM, SDX55_SLAVE_IPA_CFG, SDX55_SLAVE_USB3_PHY_CFG, SDX55_SLAVE_AOP, SDX55_SLAVE_BLSP_1, SDX55_SLAVE_SDCC_1, SDX55_SLAVE_CNOC_MSS, SDX55_SLAVE_PCIE_PARF, SDX55_SLAVE_ECC_CFG, SDX55_SLAVE_AUDIO, SDX55_SLAVE_AOSS, SDX55_SLAVE_PRNG, SDX55_SLAVE_CRYPTO_0_CFG, SDX55_SLAVE_TCU, SDX55_SLAVE_CLK_CTL, SDX55_SLAVE_IMEM_CFG); |
| 41 | DEFINE_QNODE(xm_sdc1, SDX55_MASTER_SDCC_1, 1, 8, SDX55_SLAVE_AOSS, SDX55_SLAVE_IPA_CFG, SDX55_SLAVE_ANOC_SNOC, SDX55_SLAVE_AOP, SDX55_SLAVE_AUDIO); | 40 | DEFINE_QNODE(xm_sdc1, SDX55_MASTER_SDCC_1, 1, 8, SDX55_SLAVE_AOSS, SDX55_SLAVE_IPA_CFG, SDX55_SLAVE_ANOC_SNOC, SDX55_SLAVE_AOP, SDX55_SLAVE_AUDIO); |
| 42 | DEFINE_QNODE(xm_usb3, SDX55_MASTER_USB3, 1, 8, SDX55_SLAVE_ANOC_SNOC); | 41 | DEFINE_QNODE(xm_usb3, SDX55_MASTER_USB3, 1, 8, SDX55_SLAVE_ANOC_SNOC); |
| 43 | DEFINE_QNODE(ipa_core_slave, SDX55_SLAVE_IPA_CORE, 1, 8); | ||
| 44 | DEFINE_QNODE(ebi, SDX55_SLAVE_EBI_CH0, 1, 4); | 42 | DEFINE_QNODE(ebi, SDX55_SLAVE_EBI_CH0, 1, 4); |
| 45 | DEFINE_QNODE(qns_llcc, SDX55_SLAVE_LLCC, 1, 16, SDX55_SLAVE_EBI_CH0); | 43 | DEFINE_QNODE(qns_llcc, SDX55_SLAVE_LLCC, 1, 16, SDX55_SLAVE_EBI_CH0); |
| 46 | DEFINE_QNODE(qns_memnoc_snoc, SDX55_SLAVE_MEM_NOC_SNOC, 1, 8, SDX55_MASTER_MEM_NOC_SNOC); | 44 | DEFINE_QNODE(qns_memnoc_snoc, SDX55_SLAVE_MEM_NOC_SNOC, 1, 8, SDX55_MASTER_MEM_NOC_SNOC); |
| @@ -82,7 +80,6 @@ DEFINE_QNODE(xs_sys_tcu_cfg, SDX55_SLAVE_TCU, 1, 8); · 35 unmodified lines | |||
| 82 | DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi); | 80 | DEFINE_QBCM(bcm_mc0, "MC0", true, &ebi); |
| 83 | DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc); | 81 | DEFINE_QBCM(bcm_sh0, "SH0", true, &qns_llcc); |
| 84 | DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto); | 82 | DEFINE_QBCM(bcm_ce0, "CE0", false, &qxm_crypto); |
| 85 | DEFINE_QBCM(bcm_ip0, "IP0", false, &ipa_core_slave); | ||
| 86 | DEFINE_QBCM(bcm_pn0, "PN0", false, &qhm_snoc_cfg); | 83 | DEFINE_QBCM(bcm_pn0, "PN0", false, &qhm_snoc_cfg); |
| 87 | DEFINE_QBCM(bcm_sh3, "SH3", false, &xm_apps_rdwr); | 84 | DEFINE_QBCM(bcm_sh3, "SH3", false, &xm_apps_rdwr); |
| 88 | DEFINE_QBCM(bcm_sh4, "SH4", false, &qns_memnoc_snoc, &qns_sys_pcie); | 85 | DEFINE_QBCM(bcm_sh4, "SH4", false, &qns_memnoc_snoc, &qns_sys_pcie); |
| @@ -219,22 +216,6 @@ static const struct qcom_icc_desc sdx55_system_noc = { · 130 unmodified lines | |||
| 219 | .num_bcms = ARRAY_SIZE(system_noc_bcms), | 216 | .num_bcms = ARRAY_SIZE(system_noc_bcms), |
| 220 | }; | 217 | }; |
| 221 | 218 | ||
| 222 | static struct qcom_icc_bcm *ipa_virt_bcms[] = { | ||
| 223 | &bcm_ip0, | ||
| 224 | }; | ||
| 225 | |||
| 226 | static struct qcom_icc_node *ipa_virt_nodes[] = { | ||
| 227 | [MASTER_IPA_CORE] = &ipa_core_master, | ||
| 228 | [SLAVE_IPA_CORE] = &ipa_core_slave, | ||
| 229 | }; | ||
| 230 | |||
| 231 | static const struct qcom_icc_desc sdx55_ipa_virt = { | ||
| 232 | .nodes = ipa_virt_nodes, | ||
| 233 | .num_nodes = ARRAY_SIZE(ipa_virt_nodes), | ||
| 234 | .bcms = ipa_virt_bcms, | ||
| 235 | .num_bcms = ARRAY_SIZE(ipa_virt_bcms), | ||
| 236 | }; | ||
| 237 | |||
| 238 | static const struct of_device_id qnoc_of_match[] = { | 219 | static const struct of_device_id qnoc_of_match[] = { |
| 239 | { .compatible = "qcom,sdx55-mc-virt", | 220 | { .compatible = "qcom,sdx55-mc-virt", |
| 240 | .data = &sdx55_mc_virt}, | 221 | .data = &sdx55_mc_virt}, |
| @@ -242,8 +223,6 @@ static const struct of_device_id qnoc_of_match[] = { · 1 unmodified line | |||
| 242 | .data = &sdx55_mem_noc}, | 223 | .data = &sdx55_mem_noc}, |
| 243 | { .compatible = "qcom,sdx55-system-noc", | 224 | { .compatible = "qcom,sdx55-system-noc", |
| 244 | .data = &sdx55_system_noc}, | 225 | .data = &sdx55_system_noc}, |
| 245 | { .compatible = "qcom,sdx55-ipa-virt", | ||
| 246 | .data = &sdx55_ipa_virt}, | ||
| 247 | { } | 226 | { } |
| 248 | }; | 227 | }; |
| 249 | MODULE_DEVICE_TABLE(of, qnoc_of_match); | 228 | MODULE_DEVICE_TABLE(of, qnoc_of_match); |
| @@ -407,6 +407,7 @@ · 406 unmodified lines | |||
| 407 | /* IOMMU IVINFO */ | 407 | /* IOMMU IVINFO */ |
| 408 | #define IOMMU_IVINFO_OFFSET 36 | 408 | #define IOMMU_IVINFO_OFFSET 36 |
| 409 | #define IOMMU_IVINFO_EFRSUP BIT(0) | 409 | #define IOMMU_IVINFO_EFRSUP BIT(0) |
| 410 | #define IOMMU_IVINFO_DMA_REMAP BIT(1) | ||
| 410 | 411 | ||
| 411 | /* IOMMU Feature Reporting Field (for IVHD type 10h */ | 412 | /* IOMMU Feature Reporting Field (for IVHD type 10h */ |
| 412 | #define IOMMU_FEAT_GASUP_SHIFT 6 | 413 | #define IOMMU_FEAT_GASUP_SHIFT 6 |
| @@ -449,6 +450,9 @@ extern struct irq_remap_table **irq_lookup_table; · 36 unmodified lines | |||
| 449 | /* Interrupt remapping feature used? */ | 450 | /* Interrupt remapping feature used? */ |
| 450 | extern bool amd_iommu_irq_remap; | 451 | extern bool amd_iommu_irq_remap; |
| 451 | 452 | ||
| 453 | /* IVRS indicates that pre-boot remapping was enabled */ | ||
| 454 | extern bool amdr_ivrs_remap_support; | ||
| 455 | |||
| 452 | /* kmem_cache to get tables with 128 byte alignement */ | 456 | /* kmem_cache to get tables with 128 byte alignement */ |
| 453 | extern struct kmem_cache *amd_iommu_irq_cache; | 457 | extern struct kmem_cache *amd_iommu_irq_cache; |
| 454 | 458 | ||
| @@ -84,7 +84,7 @@ · 83 unmodified lines | |||
| 84 | #define ACPI_DEVFLAG_LINT1 0x80 | 84 | #define ACPI_DEVFLAG_LINT1 0x80 |
| 85 | #define ACPI_DEVFLAG_ATSDIS 0x10000000 | 85 | #define ACPI_DEVFLAG_ATSDIS 0x10000000 |
| 86 | 86 | ||
| 87 | #define LOOP_TIMEOUT 100000 | 87 | #define LOOP_TIMEOUT 2000000 |
| 88 | /* | 88 | /* |
| 89 | * ACPI table definitions | 89 | * ACPI table definitions |
| 90 | * | 90 | * |
| @@ -182,6 +182,7 @@ u32 amd_iommu_max_pasid __read_mostly = ~0; · 91 unmodified lines | |||
| 182 | 182 | ||
| 183 | bool amd_iommu_v2_present __read_mostly; | 183 | bool amd_iommu_v2_present __read_mostly; |
| 184 | static bool amd_iommu_pc_present __read_mostly; | 184 | static bool amd_iommu_pc_present __read_mostly; |
| 185 | bool amdr_ivrs_remap_support __read_mostly; | ||
| 185 | 186 | ||
| 186 | bool amd_iommu_force_isolation __read_mostly; | 187 | bool amd_iommu_force_isolation __read_mostly; |
| 187 | 188 | ||
| @@ -326,6 +327,8 @@ static void __init early_iommu_features_init(struct amd_iommu *iommu, · 138 unmodified lines | |||
| 326 | { | 327 | { |
| 327 | if (amd_iommu_ivinfo & IOMMU_IVINFO_EFRSUP) | 328 | if (amd_iommu_ivinfo & IOMMU_IVINFO_EFRSUP) |
| 328 | iommu->features = h->efr_reg; | 329 | iommu->features = h->efr_reg; |
| 330 | if (amd_iommu_ivinfo & IOMMU_IVINFO_DMA_REMAP) | ||
| 331 | amdr_ivrs_remap_support = true; | ||
| 329 | } | 332 | } |
| 330 | 333 | ||
| 331 | /* Access to l1 and l2 indexed register spaces */ | 334 | /* Access to l1 and l2 indexed register spaces */ |
| @@ -1986,8 +1989,7 @@ static int __init amd_iommu_init_pci(void) · 1654 unmodified lines | |||
| 1986 | for_each_iommu(iommu) | 1989 | for_each_iommu(iommu) |
| 1987 | iommu_flush_all_caches(iommu); | 1990 | iommu_flush_all_caches(iommu); |
| 1988 | 1991 | ||
| 1989 | if (!ret) | 1992 | print_iommu_info(); |
| 1990 | print_iommu_info(); | ||
| 1991 | 1993 | ||
| 1992 | out: | 1994 | out: |
| 1993 | return ret; | 1995 | return ret; |
| @@ -1838,17 +1838,10 @@ void amd_iommu_domain_update(struct protection_domain *domain) · 1837 unmodified lines | |||
| 1838 | amd_iommu_domain_flush_complete(domain); | 1838 | amd_iommu_domain_flush_complete(domain); |
| 1839 | } | 1839 | } |
| 1840 | 1840 | ||
| 1841 | static void __init amd_iommu_init_dma_ops(void) | ||
| 1842 | { | ||
| 1843 | swiotlb = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0; | ||
| 1844 | } | ||
| 1845 | |||
| 1846 | int __init amd_iommu_init_api(void) | 1841 | int __init amd_iommu_init_api(void) |
| 1847 | { | 1842 | { |
| 1848 | int err; | 1843 | int err; |
| 1849 | 1844 | ||
| 1850 | amd_iommu_init_dma_ops(); | ||
| 1851 | |||
| 1852 | err = bus_set_iommu(&pci_bus_type, &amd_iommu_ops); | 1845 | err = bus_set_iommu(&pci_bus_type, &amd_iommu_ops); |
| 1853 | if (err) | 1846 | if (err) |
| 1854 | return err; | 1847 | return err; |
| @@ -2162,6 +2155,8 @@ static bool amd_iommu_capable(enum iommu_cap cap) · 307 unmodified lines | |||
| 2162 | return (irq_remapping_enabled == 1); | 2155 | return (irq_remapping_enabled == 1); |
| 2163 | case IOMMU_CAP_NOEXEC: | 2156 | case IOMMU_CAP_NOEXEC: |
| 2164 | return false; | 2157 | return false; |
| 2158 | case IOMMU_CAP_PRE_BOOT_PROTECTION: | ||
| 2159 | return amdr_ivrs_remap_support; | ||
| 2165 | default: | 2160 | default: |
| 2166 | break; | 2161 | break; |
| 2167 | } | 2162 | } |
| @@ -2271,6 +2266,12 @@ static int amd_iommu_def_domain_type(struct device *dev) · 103 unmodified lines | |||
| 2271 | return 0; | 2266 | return 0; |
| 2272 | } | 2267 | } |
| 2273 | 2268 | ||
| 2269 | static bool amd_iommu_enforce_cache_coherency(struct iommu_domain *domain) | ||
| 2270 | { | ||
| 2271 | /* IOMMU_PTE_FC is always set */ | ||
| 2272 | return true; | ||
| 2273 | } | ||
| 2274 | |||
| 2274 | const struct iommu_ops amd_iommu_ops = { | 2275 | const struct iommu_ops amd_iommu_ops = { |
| 2275 | .capable = amd_iommu_capable, | 2276 | .capable = amd_iommu_capable, |
| 2276 | .domain_alloc = amd_iommu_domain_alloc, | 2277 | .domain_alloc = amd_iommu_domain_alloc, |
| @@ -2293,6 +2294,7 @@ const struct iommu_ops amd_iommu_ops = { · 16 unmodified lines | |||
| 2293 | .flush_iotlb_all = amd_iommu_flush_iotlb_all, | 2294 | .flush_iotlb_all = amd_iommu_flush_iotlb_all, |
| 2294 | .iotlb_sync = amd_iommu_iotlb_sync, | 2295 | .iotlb_sync = amd_iommu_iotlb_sync, |
| 2295 | .free = amd_iommu_domain_free, | 2296 | .free = amd_iommu_domain_free, |
| 2297 | .enforce_cache_coherency = amd_iommu_enforce_cache_coherency, | ||
| 2296 | } | 2298 | } |
| 2297 | }; | 2299 | }; |
| 2298 | 2300 | ||
| @@ -956,6 +956,7 @@ static void __exit amd_iommu_v2_exit(void) · 955 unmodified lines | |||
| 956 | { | 956 | { |
| 957 | struct device_state *dev_state, *next; | 957 | struct device_state *dev_state, *next; |
| 958 | unsigned long flags; | 958 | unsigned long flags; |
| 959 | LIST_HEAD(freelist); | ||
| 959 | 960 | ||
| 960 | if (!amd_iommu_v2_supported()) | 961 | if (!amd_iommu_v2_supported()) |
| 961 | return; | 962 | return; |
| @@ -975,11 +976,20 @@ static void __exit amd_iommu_v2_exit(void) · 13 unmodified lines | |||
| 975 | 976 | ||
| 976 | put_device_state(dev_state); | 977 | put_device_state(dev_state); |
| 977 | list_del(&dev_state->list); | 978 | list_del(&dev_state->list); |
| 978 | free_device_state(dev_state); | 979 | list_add_tail(&dev_state->list, &freelist); |
| 979 | } | 980 | } |
| 980 | 981 | ||
| 981 | spin_unlock_irqrestore(&state_lock, flags); | 982 | spin_unlock_irqrestore(&state_lock, flags); |
| 982 | 983 | ||
| 984 | /* | ||
| 985 | * Since free_device_state waits on the count to be zero, | ||
| 986 | * we need to free dev_state outside the spinlock. | ||
| 987 | */ | ||
| 988 | list_for_each_entry_safe(dev_state, next, &freelist, list) { | ||
| 989 | list_del(&dev_state->list); | ||
| 990 | free_device_state(dev_state); | ||
| 991 | } | ||
| 992 | |||
| 983 | destroy_workqueue(iommu_wq); | 993 | destroy_workqueue(iommu_wq); |
| 984 | } | 994 | } |
| 985 | 995 | ||
| @@ -773,6 +773,7 @@ static const struct iommu_ops apple_dart_iommu_ops = { · 772 unmodified lines | |||
| 773 | .get_resv_regions = apple_dart_get_resv_regions, | 773 | .get_resv_regions = apple_dart_get_resv_regions, |
| 774 | .put_resv_regions = generic_iommu_put_resv_regions, | 774 | .put_resv_regions = generic_iommu_put_resv_regions, |
| 775 | .pgsize_bitmap = -1UL, /* Restricted during dart probe */ | 775 | .pgsize_bitmap = -1UL, /* Restricted during dart probe */ |
| 776 | .owner = THIS_MODULE, | ||
| 776 | .default_domain_ops = &(const struct iommu_domain_ops) { | 777 | .default_domain_ops = &(const struct iommu_domain_ops) { |
| 777 | .attach_dev = apple_dart_attach_dev, | 778 | .attach_dev = apple_dart_attach_dev, |
| 778 | .detach_dev = apple_dart_detach_dev, | 779 | .detach_dev = apple_dart_detach_dev, |
| @@ -859,16 +860,15 @@ static int apple_dart_probe(struct platform_device *pdev) · 80 unmodified lines | |||
| 859 | dart->dev = dev; | 860 | dart->dev = dev; |
| 860 | spin_lock_init(&dart->lock); | 861 | spin_lock_init(&dart->lock); |
| 861 | 862 | ||
| 862 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 863 | dart->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); |
| 864 | if (IS_ERR(dart->regs)) | ||
| 865 | return PTR_ERR(dart->regs); | ||
| 866 | |||
| 863 | if (resource_size(res) < 0x4000) { | 867 | if (resource_size(res) < 0x4000) { |
| 864 | dev_err(dev, "MMIO region too small (%pr)\n", res); | 868 | dev_err(dev, "MMIO region too small (%pr)\n", res); |
| 865 | return -EINVAL; | 869 | return -EINVAL; |
| 866 | } | 870 | } |
| 867 | 871 | ||
| 868 | dart->regs = devm_ioremap_resource(dev, res); | ||
| 869 | if (IS_ERR(dart->regs)) | ||
| 870 | return PTR_ERR(dart->regs); | ||
| 871 | |||
| 872 | dart->irq = platform_get_irq(pdev, 0); | 872 | dart->irq = platform_get_irq(pdev, 0); |
| 873 | if (dart->irq < 0) | 873 | if (dart->irq < 0) |
| 874 | return -ENODEV; | 874 | return -ENODEV; |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/mm.h> | 6 | #include <linux/mm.h> |
| 7 | #include <linux/mmu_context.h> | 7 | #include <linux/mmu_context.h> |
| 8 | #include <linux/mmu_notifier.h> | 8 | #include <linux/mmu_notifier.h> |
| 9 | #include <linux/sched/mm.h> | ||
| 9 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
| 10 | 11 | ||
| 11 | #include "arm-smmu-v3.h" | 12 | #include "arm-smmu-v3.h" |
| @@ -96,9 +97,14 @@ static struct arm_smmu_ctx_desc *arm_smmu_alloc_shared_cd(struct mm_struct *mm) · 84 unmodified lines | |||
| 96 | struct arm_smmu_ctx_desc *cd; | 97 | struct arm_smmu_ctx_desc *cd; |
| 97 | struct arm_smmu_ctx_desc *ret = NULL; | 98 | struct arm_smmu_ctx_desc *ret = NULL; |
| 98 | 99 | ||
| 100 | /* Don't free the mm until we release the ASID */ | ||
| 101 | mmgrab(mm); | ||
| 102 | |||
| 99 | asid = arm64_mm_context_get(mm); | 103 | asid = arm64_mm_context_get(mm); |
| 100 | if (!asid) | 104 | if (!asid) { |
| 101 | return ERR_PTR(-ESRCH); | 105 | err = -ESRCH; |
| 106 | goto out_drop_mm; | ||
| 107 | } | ||
| 102 | 108 | ||
| 103 | cd = kzalloc(sizeof(*cd), GFP_KERNEL); | 109 | cd = kzalloc(sizeof(*cd), GFP_KERNEL); |
| 104 | if (!cd) { | 110 | if (!cd) { |
| @@ -165,6 +171,8 @@ out_free_cd: · 60 unmodified lines | |||
| 165 | kfree(cd); | 171 | kfree(cd); |
| 166 | out_put_context: | 172 | out_put_context: |
| 167 | arm64_mm_context_put(mm); | 173 | arm64_mm_context_put(mm); |
| 174 | out_drop_mm: | ||
| 175 | mmdrop(mm); | ||
| 168 | return err < 0 ? ERR_PTR(err) : ret; | 176 | return err < 0 ? ERR_PTR(err) : ret; |
| 169 | } | 177 | } |
| 170 | 178 | ||
| @@ -173,6 +181,7 @@ static void arm_smmu_free_shared_cd(struct arm_smmu_ctx_desc *cd) · 2 unmodified lines | |||
| 173 | if (arm_smmu_free_asid(cd)) { | 181 | if (arm_smmu_free_asid(cd)) { |
| 174 | /* Unpin ASID */ | 182 | /* Unpin ASID */ |
| 175 | arm64_mm_context_put(cd->mm); | 183 | arm64_mm_context_put(cd->mm); |
| 184 | mmdrop(cd->mm); | ||
| 176 | kfree(cd); | 185 | kfree(cd); |
| 177 | } | 186 | } |
| 178 | } | 187 | } |
| @@ -183,7 +192,14 @@ static void arm_smmu_mm_invalidate_range(struct mmu_notifier *mn, · 4 unmodified lines | |||
| 183 | { | 192 | { |
| 184 | struct arm_smmu_mmu_notifier *smmu_mn = mn_to_smmu(mn); | 193 | struct arm_smmu_mmu_notifier *smmu_mn = mn_to_smmu(mn); |
| 185 | struct arm_smmu_domain *smmu_domain = smmu_mn->domain; | 194 | struct arm_smmu_domain *smmu_domain = smmu_mn->domain; |
| 186 | size_t size = end - start + 1; | 195 | size_t size; |
| 196 | |||
| 197 | /* | ||
| 198 | * The mm_types defines vm_end as the first byte after the end address, | ||
| 199 | * different from IOMMU subsystem using the last address of an address | ||
| 200 | * range. So do a simple translation here by calculating size correctly. | ||
| 201 | */ | ||
| 202 | size = end - start; | ||
| 187 | 203 | ||
| 188 | if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) | 204 | if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) |
| 189 | arm_smmu_tlb_inv_range_asid(start, size, smmu_mn->cd->asid, | 205 | arm_smmu_tlb_inv_range_asid(start, size, smmu_mn->cd->asid, |
| @@ -3770,6 +3770,8 @@ static int arm_smmu_device_probe(struct platform_device *pdev) · 3769 unmodified lines | |||
| 3770 | 3770 | ||
| 3771 | /* Base address */ | 3771 | /* Base address */ |
| 3772 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 3772 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 3773 | if (!res) | ||
| 3774 | return -EINVAL; | ||
| 3773 | if (resource_size(res) < arm_smmu_resource_size(smmu)) { | 3775 | if (resource_size(res) < arm_smmu_resource_size(smmu)) { |
| 3774 | dev_err(dev, "MMIO region too small (%pr)\n", res); | 3776 | dev_err(dev, "MMIO region too small (%pr)\n", res); |
| 3775 | return -EINVAL; | 3777 | return -EINVAL; |
| @@ -211,7 +211,8 @@ struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu) · 210 unmodified lines | |||
| 211 | if (of_property_read_bool(np, "calxeda,smmu-secure-config-access")) | 211 | if (of_property_read_bool(np, "calxeda,smmu-secure-config-access")) |
| 212 | smmu->impl = &calxeda_impl; | 212 | smmu->impl = &calxeda_impl; |
| 213 | 213 | ||
| 214 | if (of_device_is_compatible(np, "nvidia,tegra194-smmu") || | 214 | if (of_device_is_compatible(np, "nvidia,tegra234-smmu") || |
| 215 | of_device_is_compatible(np, "nvidia,tegra194-smmu") || | ||
| 215 | of_device_is_compatible(np, "nvidia,tegra186-smmu")) | 216 | of_device_is_compatible(np, "nvidia,tegra186-smmu")) |
| 216 | return nvidia_smmu_impl_init(smmu); | 217 | return nvidia_smmu_impl_init(smmu); |
| 217 | 218 | ||
| @@ -258,6 +258,34 @@ static void nvidia_smmu_probe_finalize(struct arm_smmu_device *smmu, struct devi · 257 unmodified lines | |||
| 258 | dev_name(dev), err); | 258 | dev_name(dev), err); |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | static int nvidia_smmu_init_context(struct arm_smmu_domain *smmu_domain, | ||
| 262 | struct io_pgtable_cfg *pgtbl_cfg, | ||
| 263 | struct device *dev) | ||
| 264 | { | ||
| 265 | struct arm_smmu_device *smmu = smmu_domain->smmu; | ||
| 266 | const struct device_node *np = smmu->dev->of_node; | ||
| 267 | |||
| 268 | /* | ||
| 269 | * Tegra194 and Tegra234 SoCs have the erratum that causes walk cache | ||
| 270 | * entries to not be invalidated correctly. The problem is that the walk | ||
| 271 | * cache index generated for IOVA is not same across translation and | ||
| 272 | * invalidation requests. This is leading to page faults when PMD entry | ||
| 273 | * is released during unmap and populated with new PTE table during | ||
| 274 | * subsequent map request. Disabling large page mappings avoids the | ||
| 275 | * release of PMD entry and avoid translations seeing stale PMD entry in | ||
| 276 | * walk cache. | ||
| 277 | * Fix this by limiting the page mappings to PAGE_SIZE on Tegra194 and | ||
| 278 | * Tegra234. | ||
| 279 | */ | ||
| 280 | if (of_device_is_compatible(np, "nvidia,tegra234-smmu") || | ||
| 281 | of_device_is_compatible(np, "nvidia,tegra194-smmu")) { | ||
| 282 | smmu->pgsize_bitmap = PAGE_SIZE; | ||
| 283 | pgtbl_cfg->pgsize_bitmap = smmu->pgsize_bitmap; | ||
| 284 | } | ||
| 285 | |||
| 286 | return 0; | ||
| 287 | } | ||
| 288 | |||
| 261 | static const struct arm_smmu_impl nvidia_smmu_impl = { | 289 | static const struct arm_smmu_impl nvidia_smmu_impl = { |
| 262 | .read_reg = nvidia_smmu_read_reg, | 290 | .read_reg = nvidia_smmu_read_reg, |
| 263 | .write_reg = nvidia_smmu_write_reg, | 291 | .write_reg = nvidia_smmu_write_reg, |
| @@ -268,10 +296,12 @@ static const struct arm_smmu_impl nvidia_smmu_impl = { · 4 unmodified lines | |||
| 268 | .global_fault = nvidia_smmu_global_fault, | 296 | .global_fault = nvidia_smmu_global_fault, |
| 269 | .context_fault = nvidia_smmu_context_fault, | 297 | .context_fault = nvidia_smmu_context_fault, |
| 270 | .probe_finalize = nvidia_smmu_probe_finalize, | 298 | .probe_finalize = nvidia_smmu_probe_finalize, |
| 299 | .init_context = nvidia_smmu_init_context, | ||
| 271 | }; | 300 | }; |
| 272 | 301 | ||
| 273 | static const struct arm_smmu_impl nvidia_smmu_single_impl = { | 302 | static const struct arm_smmu_impl nvidia_smmu_single_impl = { |
| 274 | .probe_finalize = nvidia_smmu_probe_finalize, | 303 | .probe_finalize = nvidia_smmu_probe_finalize, |
| 304 | .init_context = nvidia_smmu_init_context, | ||
| 275 | }; | 305 | }; |
| 276 | 306 | ||
| 277 | struct arm_smmu_device *nvidia_smmu_impl_init(struct arm_smmu_device *smmu) | 307 | struct arm_smmu_device *nvidia_smmu_impl_init(struct arm_smmu_device *smmu) |
| @@ -408,6 +408,7 @@ static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = { · 407 unmodified lines | |||
| 408 | { .compatible = "qcom,sc7180-smmu-500" }, | 408 | { .compatible = "qcom,sc7180-smmu-500" }, |
| 409 | { .compatible = "qcom,sc7280-smmu-500" }, | 409 | { .compatible = "qcom,sc7280-smmu-500" }, |
| 410 | { .compatible = "qcom,sc8180x-smmu-500" }, | 410 | { .compatible = "qcom,sc8180x-smmu-500" }, |
| 411 | { .compatible = "qcom,sc8280xp-smmu-500" }, | ||
| 411 | { .compatible = "qcom,sdm630-smmu-v2" }, | 412 | { .compatible = "qcom,sdm630-smmu-v2" }, |
| 412 | { .compatible = "qcom,sdm845-smmu-500" }, | 413 | { .compatible = "qcom,sdm845-smmu-500" }, |
| 413 | { .compatible = "qcom,sm6125-smmu-500" }, | 414 | { .compatible = "qcom,sm6125-smmu-500" }, |
| @@ -1574,6 +1574,9 @@ static int arm_smmu_def_domain_type(struct device *dev) · 1573 unmodified lines | |||
| 1574 | struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev); | 1574 | struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev); |
| 1575 | const struct arm_smmu_impl *impl = cfg->smmu->impl; | 1575 | const struct arm_smmu_impl *impl = cfg->smmu->impl; |
| 1576 | 1576 | ||
| 1577 | if (using_legacy_binding) | ||
| 1578 | return IOMMU_DOMAIN_IDENTITY; | ||
| 1579 | |||
| 1577 | if (impl && impl->def_domain_type) | 1580 | if (impl && impl->def_domain_type) |
| 1578 | return impl->def_domain_type(dev); | 1581 | return impl->def_domain_type(dev); |
| 1579 | 1582 | ||
| @@ -2092,11 +2095,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev) · 512 unmodified lines | |||
| 2092 | if (err) | 2095 | if (err) |
| 2093 | return err; | 2096 | return err; |
| 2094 | 2097 | ||
| 2095 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2098 | smmu->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); |
| 2096 | ioaddr = res->start; | ||
| 2097 | smmu->base = devm_ioremap_resource(dev, res); | ||
| 2098 | if (IS_ERR(smmu->base)) | 2099 | if (IS_ERR(smmu->base)) |
| 2099 | return PTR_ERR(smmu->base); | 2100 | return PTR_ERR(smmu->base); |
| 2101 | ioaddr = res->start; | ||
| 2100 | /* | 2102 | /* |
| 2101 | * The resource size should effectively match the value of SMMU_TOP; | 2103 | * The resource size should effectively match the value of SMMU_TOP; |
| 2102 | * stash that temporarily until we know PAGESIZE to validate it with. | 2104 | * stash that temporarily until we know PAGESIZE to validate it with. |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | #include <linux/iommu.h> | 20 | #include <linux/iommu.h> |
| 21 | #include <linux/iova.h> | 21 | #include <linux/iova.h> |
| 22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
| 23 | #include <linux/list_sort.h> | ||
| 23 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
| 24 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
| 25 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
| @@ -414,6 +415,15 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie, · 388 unmodified lines | |||
| 414 | return 0; | 415 | return 0; |
| 415 | } | 416 | } |
| 416 | 417 | ||
| 418 | static int iommu_dma_ranges_sort(void *priv, const struct list_head *a, | ||
| 419 | const struct list_head *b) | ||
| 420 | { | ||
| 421 | struct resource_entry *res_a = list_entry(a, typeof(*res_a), node); | ||
| 422 | struct resource_entry *res_b = list_entry(b, typeof(*res_b), node); | ||
| 423 | |||
| 424 | return res_a->res->start > res_b->res->start; | ||
| 425 | } | ||
| 426 | |||
| 417 | static int iova_reserve_pci_windows(struct pci_dev *dev, | 427 | static int iova_reserve_pci_windows(struct pci_dev *dev, |
| 418 | struct iova_domain *iovad) | 428 | struct iova_domain *iovad) |
| 419 | { | 429 | { |
| @@ -432,6 +442,7 @@ static int iova_reserve_pci_windows(struct pci_dev *dev, · 12 unmodified lines | |||
| 432 | } | 442 | } |
| 433 | 443 | ||
| 434 | /* Get reserved DMA windows from host bridge */ | 444 | /* Get reserved DMA windows from host bridge */ |
| 445 | list_sort(NULL, &bridge->dma_ranges, iommu_dma_ranges_sort); | ||
| 435 | resource_list_for_each_entry(window, &bridge->dma_ranges) { | 446 | resource_list_for_each_entry(window, &bridge->dma_ranges) { |
| 436 | end = window->res->start - window->offset; | 447 | end = window->res->start - window->offset; |
| 437 | resv_iova: | 448 | resv_iova: |
| @@ -440,7 +451,7 @@ resv_iova: · 2 unmodified lines | |||
| 440 | hi = iova_pfn(iovad, end); | 451 | hi = iova_pfn(iovad, end); |
| 441 | reserve_iova(iovad, lo, hi); | 452 | reserve_iova(iovad, lo, hi); |
| 442 | } else if (end < start) { | 453 | } else if (end < start) { |
| 443 | /* dma_ranges list should be sorted */ | 454 | /* DMA ranges should be non-overlapping */ |
| 444 | dev_err(&dev->dev, | 455 | dev_err(&dev->dev, |
| 445 | "Failed to reserve IOVA [%pa-%pa]\n", | 456 | "Failed to reserve IOVA [%pa-%pa]\n", |
| 446 | &start, &end); | 457 | &start, &end); |
| @@ -776,6 +787,7 @@ static struct page **__iommu_dma_alloc_noncontiguous(struct device *dev, · 329 unmodified lines | |||
| 776 | unsigned int count, min_size, alloc_sizes = domain->pgsize_bitmap; | 787 | unsigned int count, min_size, alloc_sizes = domain->pgsize_bitmap; |
| 777 | struct page **pages; | 788 | struct page **pages; |
| 778 | dma_addr_t iova; | 789 | dma_addr_t iova; |
| 790 | ssize_t ret; | ||
| 779 | 791 | ||
| 780 | if (static_branch_unlikely(&iommu_deferred_attach_enabled) && | 792 | if (static_branch_unlikely(&iommu_deferred_attach_enabled) && |
| 781 | iommu_deferred_attach(dev, domain)) | 793 | iommu_deferred_attach(dev, domain)) |
| @@ -813,8 +825,8 @@ static struct page **__iommu_dma_alloc_noncontiguous(struct device *dev, · 31 unmodified lines | |||
| 813 | arch_dma_prep_coherent(sg_page(sg), sg->length); | 825 | arch_dma_prep_coherent(sg_page(sg), sg->length); |
| 814 | } | 826 | } |
| 815 | 827 | ||
| 816 | if (iommu_map_sg_atomic(domain, iova, sgt->sgl, sgt->orig_nents, ioprot) | 828 | ret = iommu_map_sg_atomic(domain, iova, sgt->sgl, sgt->orig_nents, ioprot); |
| 817 | < size) | 829 | if (ret < 0 || ret < size) |
| 818 | goto out_free_sg; | 830 | goto out_free_sg; |
| 819 | 831 | ||
| 820 | sgt->sgl->dma_address = iova; | 832 | sgt->sgl->dma_address = iova; |
| @@ -971,6 +983,11 @@ static dma_addr_t iommu_dma_map_page(struct device *dev, struct page *page, · 150 unmodified lines | |||
| 971 | void *padding_start; | 983 | void *padding_start; |
| 972 | size_t padding_size, aligned_size; | 984 | size_t padding_size, aligned_size; |
| 973 | 985 | ||
| 986 | if (!is_swiotlb_active(dev)) { | ||
| 987 | dev_warn_once(dev, "DMA bounce buffers are inactive, unable to map unaligned transaction.\n"); | ||
| 988 | return DMA_MAPPING_ERROR; | ||
| 989 | } | ||
| 990 | |||
| 974 | aligned_size = iova_align(iovad, size); | 991 | aligned_size = iova_align(iovad, size); |
| 975 | phys = swiotlb_tbl_map_single(dev, phys, size, aligned_size, | 992 | phys = swiotlb_tbl_map_single(dev, phys, size, aligned_size, |
| 976 | iova_mask(iovad), dir, attrs); | 993 | iova_mask(iovad), dir, attrs); |
| @@ -1209,7 +1226,7 @@ static int iommu_dma_map_sg(struct device *dev, struct scatterlist *sg, · 232 unmodified lines | |||
| 1209 | * implementation - it knows better than we do. | 1226 | * implementation - it knows better than we do. |
| 1210 | */ | 1227 | */ |
| 1211 | ret = iommu_map_sg_atomic(domain, iova, sg, nents, prot); | 1228 | ret = iommu_map_sg_atomic(domain, iova, sg, nents, prot); |
| 1212 | if (ret < iova_len) | 1229 | if (ret < 0 || ret < iova_len) |
| 1213 | goto out_free_iova; | 1230 | goto out_free_iova; |
| 1214 | 1231 | ||
| 1215 | return __finalise_sg(dev, sg, nents, iova); | 1232 | return __finalise_sg(dev, sg, nents, iova); |
| @@ -11,6 +11,9 @@ · 10 unmodified lines | |||
| 11 | #include <linux/fsl/guts.h> | 11 | #include <linux/fsl/guts.h> |
| 12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
| 13 | #include <linux/genalloc.h> | 13 | #include <linux/genalloc.h> |
| 14 | #include <linux/of_address.h> | ||
| 15 | #include <linux/of_irq.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 14 | 17 | ||
| 15 | #include <asm/mpc85xx.h> | 18 | #include <asm/mpc85xx.h> |
| 16 | 19 | ||
| @@ -9,6 +9,7 @@ · 8 unmodified lines | |||
| 9 | 9 | ||
| 10 | #include "fsl_pamu_domain.h" | 10 | #include "fsl_pamu_domain.h" |
| 11 | 11 | ||
| 12 | #include <linux/platform_device.h> | ||
| 12 | #include <sysdev/fsl_pci.h> | 13 | #include <sysdev/fsl_pci.h> |
| 13 | 14 | ||
| 14 | /* | 15 | /* |
| @@ -533,33 +533,6 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain) · 532 unmodified lines | |||
| 533 | rcu_read_unlock(); | 533 | rcu_read_unlock(); |
| 534 | } | 534 | } |
| 535 | 535 | ||
| 536 | static bool domain_update_iommu_snooping(struct intel_iommu *skip) | ||
| 537 | { | ||
| 538 | struct dmar_drhd_unit *drhd; | ||
| 539 | struct intel_iommu *iommu; | ||
| 540 | bool ret = true; | ||
| 541 | |||
| 542 | rcu_read_lock(); | ||
| 543 | for_each_active_iommu(iommu, drhd) { | ||
| 544 | if (iommu != skip) { | ||
| 545 | /* | ||
| 546 | * If the hardware is operating in the scalable mode, | ||
| 547 | * the snooping control is always supported since we | ||
| 548 | * always set PASID-table-entry.PGSNP bit if the domain | ||
| 549 | * is managed outside (UNMANAGED). | ||
| 550 | */ | ||
| 551 | if (!sm_supported(iommu) && | ||
| 552 | !ecap_sc_support(iommu->ecap)) { | ||
| 553 | ret = false; | ||
| 554 | break; | ||
| 555 | } | ||
| 556 | } | ||
| 557 | } | ||
| 558 | rcu_read_unlock(); | ||
| 559 | |||
| 560 | return ret; | ||
| 561 | } | ||
| 562 | |||
| 563 | static int domain_update_iommu_superpage(struct dmar_domain *domain, | 536 | static int domain_update_iommu_superpage(struct dmar_domain *domain, |
| 564 | struct intel_iommu *skip) | 537 | struct intel_iommu *skip) |
| 565 | { | 538 | { |
| @@ -641,7 +614,6 @@ static unsigned long domain_super_pgsize_bitmap(struct dmar_domain *domain) · 75 unmodified lines | |||
| 641 | static void domain_update_iommu_cap(struct dmar_domain *domain) | 614 | static void domain_update_iommu_cap(struct dmar_domain *domain) |
| 642 | { | 615 | { |
| 643 | domain_update_iommu_coherency(domain); | 616 | domain_update_iommu_coherency(domain); |
| 644 | domain->iommu_snooping = domain_update_iommu_snooping(NULL); | ||
| 645 | domain->iommu_superpage = domain_update_iommu_superpage(domain, NULL); | 617 | domain->iommu_superpage = domain_update_iommu_superpage(domain, NULL); |
| 646 | 618 | ||
| 647 | /* | 619 | /* |
| @@ -1588,7 +1560,8 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, · 940 unmodified lines | |||
| 1588 | unsigned long pfn, unsigned int pages, | 1560 | unsigned long pfn, unsigned int pages, |
| 1589 | int ih, int map) | 1561 | int ih, int map) |
| 1590 | { | 1562 | { |
| 1591 | unsigned int mask = ilog2(__roundup_pow_of_two(pages)); | 1563 | unsigned int aligned_pages = __roundup_pow_of_two(pages); |
| 1564 | unsigned int mask = ilog2(aligned_pages); | ||
| 1592 | uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT; | 1565 | uint64_t addr = (uint64_t)pfn << VTD_PAGE_SHIFT; |
| 1593 | u16 did = domain->iommu_did[iommu->seq_id]; | 1566 | u16 did = domain->iommu_did[iommu->seq_id]; |
| 1594 | 1567 | ||
| @@ -1600,10 +1573,30 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu, · 5 unmodified lines | |||
| 1600 | if (domain_use_first_level(domain)) { | 1573 | if (domain_use_first_level(domain)) { |
| 1601 | qi_flush_piotlb(iommu, did, PASID_RID2PASID, addr, pages, ih); | 1574 | qi_flush_piotlb(iommu, did, PASID_RID2PASID, addr, pages, ih); |
| 1602 | } else { | 1575 | } else { |
| 1576 | unsigned long bitmask = aligned_pages - 1; | ||
| 1577 | |||
| 1578 | /* | ||
| 1579 | * PSI masks the low order bits of the base address. If the | ||
| 1580 | * address isn't aligned to the mask, then compute a mask value | ||
| 1581 | * needed to ensure the target range is flushed. | ||
| 1582 | */ | ||
| 1583 | if (unlikely(bitmask & pfn)) { | ||
| 1584 | unsigned long end_pfn = pfn + pages - 1, shared_bits; | ||
| 1585 | |||
| 1586 | /* | ||
| 1587 | * Since end_pfn <= pfn + bitmask, the only way bits | ||
| 1588 | * higher than bitmask can differ in pfn and end_pfn is | ||
| 1589 | * by carrying. This means after masking out bitmask, | ||
| 1590 | * high bits starting with the first set bit in | ||
| 1591 | * shared_bits are all equal in both pfn and end_pfn. | ||
| 1592 | */ | ||
| 1593 | shared_bits = ~(pfn ^ end_pfn) & ~bitmask; | ||
| 1594 | mask = shared_bits ? __ffs(shared_bits) : BITS_PER_LONG; | ||
| 1595 | } | ||
| 1596 | |||
| 1603 | /* | 1597 | /* |
| 1604 | * Fallback to domain selective flush if no PSI support or | 1598 | * Fallback to domain selective flush if no PSI support or |
| 1605 | * the size is too big. PSI requires page size to be 2 ^ x, | 1599 | * the size is too big. |
| 1606 | * and the base address is naturally aligned to the size. | ||
| 1607 | */ | 1600 | */ |
| 1608 | if (!cap_pgsel_inv(iommu->cap) || | 1601 | if (!cap_pgsel_inv(iommu->cap) || |
| 1609 | mask > cap_max_amask_val(iommu->cap)) | 1602 | mask > cap_max_amask_val(iommu->cap)) |
| @@ -2439,7 +2432,7 @@ static int domain_setup_first_level(struct intel_iommu *iommu, · 829 unmodified lines | |||
| 2439 | if (level == 5) | 2432 | if (level == 5) |
| 2440 | flags |= PASID_FLAG_FL5LP; | 2433 | flags |= PASID_FLAG_FL5LP; |
| 2441 | 2434 | ||
| 2442 | if (domain->domain.type == IOMMU_DOMAIN_UNMANAGED) | 2435 | if (domain->force_snooping) |
| 2443 | flags |= PASID_FLAG_PAGE_SNOOP; | 2436 | flags |= PASID_FLAG_PAGE_SNOOP; |
| 2444 | 2437 | ||
| 2445 | return intel_pasid_setup_first_level(iommu, dev, (pgd_t *)pgd, pasid, | 2438 | return intel_pasid_setup_first_level(iommu, dev, (pgd_t *)pgd, pasid, |
| @@ -2453,64 +2446,6 @@ static bool dev_is_real_dma_subdevice(struct device *dev) · 7 unmodified lines | |||
| 2453 | pci_real_dma_dev(to_pci_dev(dev)) != to_pci_dev(dev); | 2446 | pci_real_dma_dev(to_pci_dev(dev)) != to_pci_dev(dev); |
| 2454 | } | 2447 | } |
| 2455 | 2448 | ||
| 2456 | static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu, | ||
| 2457 | int bus, int devfn, | ||
| 2458 | struct device *dev, | ||
| 2459 | struct dmar_domain *domain) | ||
| 2460 | { | ||
| 2461 | struct device_domain_info *info = dev_iommu_priv_get(dev); | ||
| 2462 | unsigned long flags; | ||
| 2463 | int ret; | ||
| 2464 | |||
| 2465 | spin_lock_irqsave(&device_domain_lock, flags); | ||
| 2466 | info->domain = domain; | ||
| 2467 | spin_lock(&iommu->lock); | ||
| 2468 | ret = domain_attach_iommu(domain, iommu); | ||
| 2469 | spin_unlock(&iommu->lock); | ||
| 2470 | if (ret) { | ||
| 2471 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 2472 | return NULL; | ||
| 2473 | } | ||
| 2474 | list_add(&info->link, &domain->devices); | ||
| 2475 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 2476 | |||
| 2477 | /* PASID table is mandatory for a PCI device in scalable mode. */ | ||
| 2478 | if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) { | ||
| 2479 | ret = intel_pasid_alloc_table(dev); | ||
| 2480 | if (ret) { | ||
| 2481 | dev_err(dev, "PASID table allocation failed\n"); | ||
| 2482 | dmar_remove_one_dev_info(dev); | ||
| 2483 | return NULL; | ||
| 2484 | } | ||
| 2485 | |||
| 2486 | /* Setup the PASID entry for requests without PASID: */ | ||
| 2487 | spin_lock_irqsave(&iommu->lock, flags); | ||
| 2488 | if (hw_pass_through && domain_type_is_si(domain)) | ||
| 2489 | ret = intel_pasid_setup_pass_through(iommu, domain, | ||
| 2490 | dev, PASID_RID2PASID); | ||
| 2491 | else if (domain_use_first_level(domain)) | ||
| 2492 | ret = domain_setup_first_level(iommu, domain, dev, | ||
| 2493 | PASID_RID2PASID); | ||
| 2494 | else | ||
| 2495 | ret = intel_pasid_setup_second_level(iommu, domain, | ||
| 2496 | dev, PASID_RID2PASID); | ||
| 2497 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
| 2498 | if (ret) { | ||
| 2499 | dev_err(dev, "Setup RID2PASID failed\n"); | ||
| 2500 | dmar_remove_one_dev_info(dev); | ||
| 2501 | return NULL; | ||
| 2502 | } | ||
| 2503 | } | ||
| 2504 | |||
| 2505 | if (dev && domain_context_mapping(domain, dev)) { | ||
| 2506 | dev_err(dev, "Domain context map failed\n"); | ||
| 2507 | dmar_remove_one_dev_info(dev); | ||
| 2508 | return NULL; | ||
| 2509 | } | ||
| 2510 | |||
| 2511 | return domain; | ||
| 2512 | } | ||
| 2513 | |||
| 2514 | static int iommu_domain_identity_map(struct dmar_domain *domain, | 2449 | static int iommu_domain_identity_map(struct dmar_domain *domain, |
| 2515 | unsigned long first_vpfn, | 2450 | unsigned long first_vpfn, |
| 2516 | unsigned long last_vpfn) | 2451 | unsigned long last_vpfn) |
| @@ -2586,17 +2521,62 @@ static int __init si_domain_init(int hw) · 69 unmodified lines | |||
| 2586 | 2521 | ||
| 2587 | static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev) | 2522 | static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev) |
| 2588 | { | 2523 | { |
| 2589 | struct dmar_domain *ndomain; | 2524 | struct device_domain_info *info = dev_iommu_priv_get(dev); |
| 2590 | struct intel_iommu *iommu; | 2525 | struct intel_iommu *iommu; |
| 2526 | unsigned long flags; | ||
| 2591 | u8 bus, devfn; | 2527 | u8 bus, devfn; |
| 2528 | int ret; | ||
| 2592 | 2529 | ||
| 2593 | iommu = device_to_iommu(dev, &bus, &devfn); | 2530 | iommu = device_to_iommu(dev, &bus, &devfn); |
| 2594 | if (!iommu) | 2531 | if (!iommu) |
| 2595 | return -ENODEV; | 2532 | return -ENODEV; |
| 2596 | 2533 | ||
| 2597 | ndomain = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain); | 2534 | spin_lock_irqsave(&device_domain_lock, flags); |
| 2598 | if (ndomain != domain) | 2535 | info->domain = domain; |
| 2599 | return -EBUSY; | 2536 | spin_lock(&iommu->lock); |
| 2537 | ret = domain_attach_iommu(domain, iommu); | ||
| 2538 | spin_unlock(&iommu->lock); | ||
| 2539 | if (ret) { | ||
| 2540 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 2541 | return ret; | ||
| 2542 | } | ||
| 2543 | list_add(&info->link, &domain->devices); | ||
| 2544 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 2545 | |||
| 2546 | /* PASID table is mandatory for a PCI device in scalable mode. */ | ||
| 2547 | if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) { | ||
| 2548 | ret = intel_pasid_alloc_table(dev); | ||
| 2549 | if (ret) { | ||
| 2550 | dev_err(dev, "PASID table allocation failed\n"); | ||
| 2551 | dmar_remove_one_dev_info(dev); | ||
| 2552 | return ret; | ||
| 2553 | } | ||
| 2554 | |||
| 2555 | /* Setup the PASID entry for requests without PASID: */ | ||
| 2556 | spin_lock_irqsave(&iommu->lock, flags); | ||
| 2557 | if (hw_pass_through && domain_type_is_si(domain)) | ||
| 2558 | ret = intel_pasid_setup_pass_through(iommu, domain, | ||
| 2559 | dev, PASID_RID2PASID); | ||
| 2560 | else if (domain_use_first_level(domain)) | ||
| 2561 | ret = domain_setup_first_level(iommu, domain, dev, | ||
| 2562 | PASID_RID2PASID); | ||
| 2563 | else | ||
| 2564 | ret = intel_pasid_setup_second_level(iommu, domain, | ||
| 2565 | dev, PASID_RID2PASID); | ||
| 2566 | spin_unlock_irqrestore(&iommu->lock, flags); | ||
| 2567 | if (ret) { | ||
| 2568 | dev_err(dev, "Setup RID2PASID failed\n"); | ||
| 2569 | dmar_remove_one_dev_info(dev); | ||
| 2570 | return ret; | ||
| 2571 | } | ||
| 2572 | } | ||
| 2573 | |||
| 2574 | ret = domain_context_mapping(domain, dev); | ||
| 2575 | if (ret) { | ||
| 2576 | dev_err(dev, "Domain context map failed\n"); | ||
| 2577 | dmar_remove_one_dev_info(dev); | ||
| 2578 | return ret; | ||
| 2579 | } | ||
| 2600 | 2580 | ||
| 2601 | return 0; | 2581 | return 0; |
| 2602 | } | 2582 | } |
| @@ -3586,12 +3566,7 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru) · 983 unmodified lines | |||
| 3586 | iommu->name); | 3566 | iommu->name); |
| 3587 | return -ENXIO; | 3567 | return -ENXIO; |
| 3588 | } | 3568 | } |
| 3589 | if (!ecap_sc_support(iommu->ecap) && | 3569 | |
| 3590 | domain_update_iommu_snooping(iommu)) { | ||
| 3591 | pr_warn("%s: Doesn't support snooping.\n", | ||
| 3592 | iommu->name); | ||
| 3593 | return -ENXIO; | ||
| 3594 | } | ||
| 3595 | sp = domain_update_iommu_superpage(NULL, iommu) - 1; | 3570 | sp = domain_update_iommu_superpage(NULL, iommu) - 1; |
| 3596 | if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) { | 3571 | if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) { |
| 3597 | pr_warn("%s: Doesn't support large page.\n", | 3572 | pr_warn("%s: Doesn't support large page.\n", |
| @@ -4283,7 +4258,6 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width) · 685 unmodified lines | |||
| 4283 | domain->agaw = width_to_agaw(adjust_width); | 4258 | domain->agaw = width_to_agaw(adjust_width); |
| 4284 | 4259 | ||
| 4285 | domain->iommu_coherency = false; | 4260 | domain->iommu_coherency = false; |
| 4286 | domain->iommu_snooping = false; | ||
| 4287 | domain->iommu_superpage = 0; | 4261 | domain->iommu_superpage = 0; |
| 4288 | domain->max_addr = 0; | 4262 | domain->max_addr = 0; |
| 4289 | 4263 | ||
| @@ -4348,6 +4322,9 @@ static int prepare_domain_attach_device(struct iommu_domain *domain, · 58 unmodified lines | |||
| 4348 | if (!iommu) | 4322 | if (!iommu) |
| 4349 | return -ENODEV; | 4323 | return -ENODEV; |
| 4350 | 4324 | ||
| 4325 | if (dmar_domain->force_snooping && !ecap_sc_support(iommu->ecap)) | ||
| 4326 | return -EOPNOTSUPP; | ||
| 4327 | |||
| 4351 | /* check if this iommu agaw is sufficient for max mapped address */ | 4328 | /* check if this iommu agaw is sufficient for max mapped address */ |
| 4352 | addr_width = agaw_to_width(iommu->agaw); | 4329 | addr_width = agaw_to_width(iommu->agaw); |
| 4353 | if (addr_width > cap_mgaw(iommu->cap)) | 4330 | if (addr_width > cap_mgaw(iommu->cap)) |
| @@ -4422,7 +4399,7 @@ static int intel_iommu_map(struct iommu_domain *domain, · 68 unmodified lines | |||
| 4422 | prot |= DMA_PTE_READ; | 4399 | prot |= DMA_PTE_READ; |
| 4423 | if (iommu_prot & IOMMU_WRITE) | 4400 | if (iommu_prot & IOMMU_WRITE) |
| 4424 | prot |= DMA_PTE_WRITE; | 4401 | prot |= DMA_PTE_WRITE; |
| 4425 | if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping) | 4402 | if (dmar_domain->set_pte_snp) |
| 4426 | prot |= DMA_PTE_SNP; | 4403 | prot |= DMA_PTE_SNP; |
| 4427 | 4404 | ||
| 4428 | max_addr = iova + size; | 4405 | max_addr = iova + size; |
| @@ -4545,12 +4522,71 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, · 116 unmodified lines | |||
| 4545 | return phys; | 4522 | return phys; |
| 4546 | } | 4523 | } |
| 4547 | 4524 | ||
| 4525 | static bool domain_support_force_snooping(struct dmar_domain *domain) | ||
| 4526 | { | ||
| 4527 | struct device_domain_info *info; | ||
| 4528 | bool support = true; | ||
| 4529 | |||
| 4530 | assert_spin_locked(&device_domain_lock); | ||
| 4531 | list_for_each_entry(info, &domain->devices, link) { | ||
| 4532 | if (!ecap_sc_support(info->iommu->ecap)) { | ||
| 4533 | support = false; | ||
| 4534 | break; | ||
| 4535 | } | ||
| 4536 | } | ||
| 4537 | |||
| 4538 | return support; | ||
| 4539 | } | ||
| 4540 | |||
| 4541 | static void domain_set_force_snooping(struct dmar_domain *domain) | ||
| 4542 | { | ||
| 4543 | struct device_domain_info *info; | ||
| 4544 | |||
| 4545 | assert_spin_locked(&device_domain_lock); | ||
| 4546 | |||
| 4547 | /* | ||
| 4548 | * Second level page table supports per-PTE snoop control. The | ||
| 4549 | * iommu_map() interface will handle this by setting SNP bit. | ||
| 4550 | */ | ||
| 4551 | if (!domain_use_first_level(domain)) { | ||
| 4552 | domain->set_pte_snp = true; | ||
| 4553 | return; | ||
| 4554 | } | ||
| 4555 | |||
| 4556 | list_for_each_entry(info, &domain->devices, link) | ||
| 4557 | intel_pasid_setup_page_snoop_control(info->iommu, info->dev, | ||
| 4558 | PASID_RID2PASID); | ||
| 4559 | } | ||
| 4560 | |||
| 4561 | static bool intel_iommu_enforce_cache_coherency(struct iommu_domain *domain) | ||
| 4562 | { | ||
| 4563 | struct dmar_domain *dmar_domain = to_dmar_domain(domain); | ||
| 4564 | unsigned long flags; | ||
| 4565 | |||
| 4566 | if (dmar_domain->force_snooping) | ||
| 4567 | return true; | ||
| 4568 | |||
| 4569 | spin_lock_irqsave(&device_domain_lock, flags); | ||
| 4570 | if (!domain_support_force_snooping(dmar_domain)) { | ||
| 4571 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 4572 | return false; | ||
| 4573 | } | ||
| 4574 | |||
| 4575 | domain_set_force_snooping(dmar_domain); | ||
| 4576 | dmar_domain->force_snooping = true; | ||
| 4577 | spin_unlock_irqrestore(&device_domain_lock, flags); | ||
| 4578 | |||
| 4579 | return true; | ||
| 4580 | } | ||
| 4581 | |||
| 4548 | static bool intel_iommu_capable(enum iommu_cap cap) | 4582 | static bool intel_iommu_capable(enum iommu_cap cap) |
| 4549 | { | 4583 | { |
| 4550 | if (cap == IOMMU_CAP_CACHE_COHERENCY) | 4584 | if (cap == IOMMU_CAP_CACHE_COHERENCY) |
| 4551 | return domain_update_iommu_snooping(NULL); | 4585 | return true; |
| 4552 | if (cap == IOMMU_CAP_INTR_REMAP) | 4586 | if (cap == IOMMU_CAP_INTR_REMAP) |
| 4553 | return irq_remapping_enabled == 1; | 4587 | return irq_remapping_enabled == 1; |
| 4588 | if (cap == IOMMU_CAP_PRE_BOOT_PROTECTION) | ||
| 4589 | return dmar_platform_optin(); | ||
| 4554 | 4590 | ||
| 4555 | return false; | 4591 | return false; |
| 4556 | } | 4592 | } |
| @@ -4898,6 +4934,7 @@ const struct iommu_ops intel_iommu_ops = { · 341 unmodified lines | |||
| 4898 | .iotlb_sync = intel_iommu_tlb_sync, | 4934 | .iotlb_sync = intel_iommu_tlb_sync, |
| 4899 | .iova_to_phys = intel_iommu_iova_to_phys, | 4935 | .iova_to_phys = intel_iommu_iova_to_phys, |
| 4900 | .free = intel_iommu_domain_free, | 4936 | .free = intel_iommu_domain_free, |
| 4937 | .enforce_cache_coherency = intel_iommu_enforce_cache_coherency, | ||
| 4901 | } | 4938 | } |
| 4902 | }; | 4939 | }; |
| 4903 | 4940 | ||
| @@ -710,9 +710,6 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu, · 709 unmodified lines | |||
| 710 | pasid_set_fault_enable(pte); | 710 | pasid_set_fault_enable(pte); |
| 711 | pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap)); | 711 | pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap)); |
| 712 | 712 | ||
| 713 | if (domain->domain.type == IOMMU_DOMAIN_UNMANAGED) | ||
| 714 | pasid_set_pgsnp(pte); | ||
| 715 | |||
| 716 | /* | 713 | /* |
| 717 | * Since it is a second level only translation setup, we should | 714 | * Since it is a second level only translation setup, we should |
| 718 | * set SRE bit as well (addresses are expected to be GPAs). | 715 | * set SRE bit as well (addresses are expected to be GPAs). |
| @@ -762,3 +759,45 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu, · 43 unmodified lines | |||
| 762 | 759 | ||
| 763 | return 0; | 760 | return 0; |
| 764 | } | 761 | } |
| 762 | |||
| 763 | /* | ||
| 764 | * Set the page snoop control for a pasid entry which has been set up. | ||
| 765 | */ | ||
| 766 | void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu, | ||
| 767 | struct device *dev, u32 pasid) | ||
| 768 | { | ||
| 769 | struct pasid_entry *pte; | ||
| 770 | u16 did; | ||
| 771 | |||
| 772 | spin_lock(&iommu->lock); | ||
| 773 | pte = intel_pasid_get_entry(dev, pasid); | ||
| 774 | if (WARN_ON(!pte || !pasid_pte_is_present(pte))) { | ||
| 775 | spin_unlock(&iommu->lock); | ||
| 776 | return; | ||
| 777 | } | ||
| 778 | |||
| 779 | pasid_set_pgsnp(pte); | ||
| 780 | did = pasid_get_domain_id(pte); | ||
| 781 | spin_unlock(&iommu->lock); | ||
| 782 | |||
| 783 | if (!ecap_coherent(iommu->ecap)) | ||
| 784 | clflush_cache_range(pte, sizeof(*pte)); | ||
| 785 | |||
| 786 | /* | ||
| 787 | * VT-d spec 3.4 table23 states guides for cache invalidation: | ||
| 788 | * | ||
| 789 | * - PASID-selective-within-Domain PASID-cache invalidation | ||
| 790 | * - PASID-selective PASID-based IOTLB invalidation | ||
| 791 | * - If (pasid is RID_PASID) | ||
| 792 | * - Global Device-TLB invalidation to affected functions | ||
| 793 | * Else | ||
| 794 | * - PASID-based Device-TLB invalidation (with S=1 and | ||
| 795 | * Addr[63:12]=0x7FFFFFFF_FFFFF) to affected functions | ||
| 796 | */ | ||
| 797 | pasid_cache_invalidation_with_pasid(iommu, did, pasid); | ||
| 798 | qi_flush_piotlb(iommu, did, pasid, 0, -1, 0); | ||
| 799 | |||
| 800 | /* Device IOTLB doesn't need to be flushed in caching mode. */ | ||
| 801 | if (!cap_caching_mode(iommu->cap)) | ||
| 802 | devtlb_invalidation_with_pasid(iommu, dev, pasid); | ||
| 803 | } | ||
| @@ -123,4 +123,6 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, · 122 unmodified lines | |||
| 123 | bool fault_ignore); | 123 | bool fault_ignore); |
| 124 | int vcmd_alloc_pasid(struct intel_iommu *iommu, u32 *pasid); | 124 | int vcmd_alloc_pasid(struct intel_iommu *iommu, u32 *pasid); |
| 125 | void vcmd_free_pasid(struct intel_iommu *iommu, u32 pasid); | 125 | void vcmd_free_pasid(struct intel_iommu *iommu, u32 pasid); |
| 126 | void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu, | ||
| 127 | struct device *dev, u32 pasid); | ||
| 126 | #endif /* __INTEL_PASID_H */ | 128 | #endif /* __INTEL_PASID_H */ |
| @@ -757,6 +757,10 @@ bad_req: · 756 unmodified lines | |||
| 757 | goto bad_req; | 757 | goto bad_req; |
| 758 | } | 758 | } |
| 759 | 759 | ||
| 760 | /* Drop Stop Marker message. No need for a response. */ | ||
| 761 | if (unlikely(req->lpig && !req->rd_req && !req->wr_req)) | ||
| 762 | goto prq_advance; | ||
| 763 | |||
| 760 | if (!svm || svm->pasid != req->pasid) { | 764 | if (!svm || svm->pasid != req->pasid) { |
| 761 | /* | 765 | /* |
| 762 | * It can't go away, because the driver is not permitted | 766 | * It can't go away, because the driver is not permitted |
| @@ -18,7 +18,6 @@ · 17 unmodified lines | |||
| 18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
| 19 | #include <linux/iommu.h> | 19 | #include <linux/iommu.h> |
| 20 | #include <linux/idr.h> | 20 | #include <linux/idr.h> |
| 21 | #include <linux/notifier.h> | ||
| 22 | #include <linux/err.h> | 21 | #include <linux/err.h> |
| 23 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
| 24 | #include <linux/bitops.h> | 23 | #include <linux/bitops.h> |
| @@ -40,14 +39,16 @@ struct iommu_group { · 15 unmodified lines | |||
| 40 | struct kobject *devices_kobj; | 39 | struct kobject *devices_kobj; |
| 41 | struct list_head devices; | 40 | struct list_head devices; |
| 42 | struct mutex mutex; | 41 | struct mutex mutex; |
| 43 | struct blocking_notifier_head notifier; | ||
| 44 | void *iommu_data; | 42 | void *iommu_data; |
| 45 | void (*iommu_data_release)(void *iommu_data); | 43 | void (*iommu_data_release)(void *iommu_data); |
| 46 | char *name; | 44 | char *name; |
| 47 | int id; | 45 | int id; |
| 48 | struct iommu_domain *default_domain; | 46 | struct iommu_domain *default_domain; |
| 47 | struct iommu_domain *blocking_domain; | ||
| 49 | struct iommu_domain *domain; | 48 | struct iommu_domain *domain; |
| 50 | struct list_head entry; | 49 | struct list_head entry; |
| 50 | unsigned int owner_cnt; | ||
| 51 | void *owner; | ||
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 53 | struct group_device { | 54 | struct group_device { |
| @@ -82,8 +83,8 @@ static int __iommu_attach_device(struct iommu_domain *domain, · 28 unmodified lines | |||
| 82 | struct device *dev); | 83 | struct device *dev); |
| 83 | static int __iommu_attach_group(struct iommu_domain *domain, | 84 | static int __iommu_attach_group(struct iommu_domain *domain, |
| 84 | struct iommu_group *group); | 85 | struct iommu_group *group); |
| 85 | static void __iommu_detach_group(struct iommu_domain *domain, | 86 | static int __iommu_group_set_domain(struct iommu_group *group, |
| 86 | struct iommu_group *group); | 87 | struct iommu_domain *new_domain); |
| 87 | static int iommu_create_device_direct_mappings(struct iommu_group *group, | 88 | static int iommu_create_device_direct_mappings(struct iommu_group *group, |
| 88 | struct device *dev); | 89 | struct device *dev); |
| 89 | static struct iommu_group *iommu_group_get_for_dev(struct device *dev); | 90 | static struct iommu_group *iommu_group_get_for_dev(struct device *dev); |
| @@ -294,7 +295,11 @@ int iommu_probe_device(struct device *dev) · 204 unmodified lines | |||
| 294 | mutex_lock(&group->mutex); | 295 | mutex_lock(&group->mutex); |
| 295 | iommu_alloc_default_domain(group, dev); | 296 | iommu_alloc_default_domain(group, dev); |
| 296 | 297 | ||
| 297 | if (group->default_domain) { | 298 | /* |
| 299 | * If device joined an existing group which has been claimed, don't | ||
| 300 | * attach the default domain. | ||
| 301 | */ | ||
| 302 | if (group->default_domain && !group->owner) { | ||
| 298 | ret = __iommu_attach_device(group->default_domain, dev); | 303 | ret = __iommu_attach_device(group->default_domain, dev); |
| 299 | if (ret) { | 304 | if (ret) { |
| 300 | mutex_unlock(&group->mutex); | 305 | mutex_unlock(&group->mutex); |
| @@ -506,6 +511,13 @@ int iommu_get_group_resv_regions(struct iommu_group *group, · 205 unmodified lines | |||
| 506 | list_for_each_entry(device, &group->devices, list) { | 511 | list_for_each_entry(device, &group->devices, list) { |
| 507 | struct list_head dev_resv_regions; | 512 | struct list_head dev_resv_regions; |
| 508 | 513 | ||
| 514 | /* | ||
| 515 | * Non-API groups still expose reserved_regions in sysfs, | ||
| 516 | * so filter out calls that get here that way. | ||
| 517 | */ | ||
| 518 | if (!device->dev->iommu) | ||
| 519 | break; | ||
| 520 | |||
| 509 | INIT_LIST_HEAD(&dev_resv_regions); | 521 | INIT_LIST_HEAD(&dev_resv_regions); |
| 510 | iommu_get_resv_regions(device->dev, &dev_resv_regions); | 522 | iommu_get_resv_regions(device->dev, &dev_resv_regions); |
| 511 | ret = iommu_insert_device_resv_regions(&dev_resv_regions, head); | 523 | ret = iommu_insert_device_resv_regions(&dev_resv_regions, head); |
| @@ -592,6 +604,8 @@ static void iommu_group_release(struct kobject *kobj) · 80 unmodified lines | |||
| 592 | 604 | ||
| 593 | if (group->default_domain) | 605 | if (group->default_domain) |
| 594 | iommu_domain_free(group->default_domain); | 606 | iommu_domain_free(group->default_domain); |
| 607 | if (group->blocking_domain) | ||
| 608 | iommu_domain_free(group->blocking_domain); | ||
| 595 | 609 | ||
| 596 | kfree(group->name); | 610 | kfree(group->name); |
| 597 | kfree(group); | 611 | kfree(group); |
| @@ -626,7 +640,6 @@ struct iommu_group *iommu_group_alloc(void) · 28 unmodified lines | |||
| 626 | mutex_init(&group->mutex); | 640 | mutex_init(&group->mutex); |
| 627 | INIT_LIST_HEAD(&group->devices); | 641 | INIT_LIST_HEAD(&group->devices); |
| 628 | INIT_LIST_HEAD(&group->entry); | 642 | INIT_LIST_HEAD(&group->entry); |
| 629 | BLOCKING_INIT_NOTIFIER_HEAD(&group->notifier); | ||
| 630 | 643 | ||
| 631 | ret = ida_simple_get(&iommu_group_ida, 0, 0, GFP_KERNEL); | 644 | ret = ida_simple_get(&iommu_group_ida, 0, 0, GFP_KERNEL); |
| 632 | if (ret < 0) { | 645 | if (ret < 0) { |
| @@ -899,10 +912,6 @@ rename: · 266 unmodified lines | |||
| 899 | if (ret) | 912 | if (ret) |
| 900 | goto err_put_group; | 913 | goto err_put_group; |
| 901 | 914 | ||
| 902 | /* Notify any listeners about change to group. */ | ||
| 903 | blocking_notifier_call_chain(&group->notifier, | ||
| 904 | IOMMU_GROUP_NOTIFY_ADD_DEVICE, dev); | ||
| 905 | |||
| 906 | trace_add_device_to_group(group->id, dev); | 915 | trace_add_device_to_group(group->id, dev); |
| 907 | 916 | ||
| 908 | dev_info(dev, "Adding to iommu group %d\n", group->id); | 917 | dev_info(dev, "Adding to iommu group %d\n", group->id); |
| @@ -944,10 +953,6 @@ void iommu_group_remove_device(struct device *dev) · 35 unmodified lines | |||
| 944 | 953 | ||
| 945 | dev_info(dev, "Removing from iommu group %d\n", group->id); | 954 | dev_info(dev, "Removing from iommu group %d\n", group->id); |
| 946 | 955 | ||
| 947 | /* Pre-notify listeners that a device is being removed. */ | ||
| 948 | blocking_notifier_call_chain(&group->notifier, | ||
| 949 | IOMMU_GROUP_NOTIFY_DEL_DEVICE, dev); | ||
| 950 | |||
| 951 | mutex_lock(&group->mutex); | 956 | mutex_lock(&group->mutex); |
| 952 | list_for_each_entry(tmp_device, &group->devices, list) { | 957 | list_for_each_entry(tmp_device, &group->devices, list) { |
| 953 | if (tmp_device->dev == dev) { | 958 | if (tmp_device->dev == dev) { |
| @@ -1069,36 +1074,6 @@ void iommu_group_put(struct iommu_group *group) · 115 unmodified lines | |||
| 1069 | } | 1074 | } |
| 1070 | EXPORT_SYMBOL_GPL(iommu_group_put); | 1075 | EXPORT_SYMBOL_GPL(iommu_group_put); |
| 1071 | 1076 | ||
| 1072 | /** | ||
| 1073 | * iommu_group_register_notifier - Register a notifier for group changes | ||
| 1074 | * @group: the group to watch | ||
| 1075 | * @nb: notifier block to signal | ||
| 1076 | * | ||
| 1077 | * This function allows iommu group users to track changes in a group. | ||
| 1078 | * See include/linux/iommu.h for actions sent via this notifier. Caller | ||
| 1079 | * should hold a reference to the group throughout notifier registration. | ||
| 1080 | */ | ||
| 1081 | int iommu_group_register_notifier(struct iommu_group *group, | ||
| 1082 | struct notifier_block *nb) | ||
| 1083 | { | ||
| 1084 | return blocking_notifier_chain_register(&group->notifier, nb); | ||
| 1085 | } | ||
| 1086 | EXPORT_SYMBOL_GPL(iommu_group_register_notifier); | ||
| 1087 | |||
| 1088 | /** | ||
| 1089 | * iommu_group_unregister_notifier - Unregister a notifier | ||
| 1090 | * @group: the group to watch | ||
| 1091 | * @nb: notifier block to signal | ||
| 1092 | * | ||
| 1093 | * Unregister a previously registered group notifier block. | ||
| 1094 | */ | ||
| 1095 | int iommu_group_unregister_notifier(struct iommu_group *group, | ||
| 1096 | struct notifier_block *nb) | ||
| 1097 | { | ||
| 1098 | return blocking_notifier_chain_unregister(&group->notifier, nb); | ||
| 1099 | } | ||
| 1100 | EXPORT_SYMBOL_GPL(iommu_group_unregister_notifier); | ||
| 1101 | |||
| 1102 | /** | 1077 | /** |
| 1103 | * iommu_register_device_fault_handler() - Register a device fault handler | 1078 | * iommu_register_device_fault_handler() - Register a device fault handler |
| 1104 | * @dev: the device | 1079 | * @dev: the device |
| @@ -1644,14 +1619,8 @@ static int remove_iommu_group(struct device *dev, void *data) · 539 unmodified lines | |||
| 1644 | static int iommu_bus_notifier(struct notifier_block *nb, | 1619 | static int iommu_bus_notifier(struct notifier_block *nb, |
| 1645 | unsigned long action, void *data) | 1620 | unsigned long action, void *data) |
| 1646 | { | 1621 | { |
| 1647 | unsigned long group_action = 0; | ||
| 1648 | struct device *dev = data; | 1622 | struct device *dev = data; |
| 1649 | struct iommu_group *group; | ||
| 1650 | 1623 | ||
| 1651 | /* | ||
| 1652 | * ADD/DEL call into iommu driver ops if provided, which may | ||
| 1653 | * result in ADD/DEL notifiers to group->notifier | ||
| 1654 | */ | ||
| 1655 | if (action == BUS_NOTIFY_ADD_DEVICE) { | 1624 | if (action == BUS_NOTIFY_ADD_DEVICE) { |
| 1656 | int ret; | 1625 | int ret; |
| 1657 | 1626 | ||
| @@ -1662,34 +1631,6 @@ static int iommu_bus_notifier(struct notifier_block *nb, · 4 unmodified lines | |||
| 1662 | return NOTIFY_OK; | 1631 | return NOTIFY_OK; |
| 1663 | } | 1632 | } |
| 1664 | 1633 | ||
| 1665 | /* | ||
| 1666 | * Remaining BUS_NOTIFYs get filtered and republished to the | ||
| 1667 | * group, if anyone is listening | ||
| 1668 | */ | ||
| 1669 | group = iommu_group_get(dev); | ||
| 1670 | if (!group) | ||
| 1671 | return 0; | ||
| 1672 | |||
| 1673 | switch (action) { | ||
| 1674 | case BUS_NOTIFY_BIND_DRIVER: | ||
| 1675 | group_action = IOMMU_GROUP_NOTIFY_BIND_DRIVER; | ||
| 1676 | break; | ||
| 1677 | case BUS_NOTIFY_BOUND_DRIVER: | ||
| 1678 | group_action = IOMMU_GROUP_NOTIFY_BOUND_DRIVER; | ||
| 1679 | break; | ||
| 1680 | case BUS_NOTIFY_UNBIND_DRIVER: | ||
| 1681 | group_action = IOMMU_GROUP_NOTIFY_UNBIND_DRIVER; | ||
| 1682 | break; | ||
| 1683 | case BUS_NOTIFY_UNBOUND_DRIVER: | ||
| 1684 | group_action = IOMMU_GROUP_NOTIFY_UNBOUND_DRIVER; | ||
| 1685 | break; | ||
| 1686 | } | ||
| 1687 | |||
| 1688 | if (group_action) | ||
| 1689 | blocking_notifier_call_chain(&group->notifier, | ||
| 1690 | group_action, dev); | ||
| 1691 | |||
| 1692 | iommu_group_put(group); | ||
| 1693 | return 0; | 1634 | return 0; |
| 1694 | } | 1635 | } |
| 1695 | 1636 | ||
| @@ -1906,6 +1847,29 @@ bool iommu_present(struct bus_type *bus) · 210 unmodified lines | |||
| 1906 | } | 1847 | } |
| 1907 | EXPORT_SYMBOL_GPL(iommu_present); | 1848 | EXPORT_SYMBOL_GPL(iommu_present); |
| 1908 | 1849 | ||
| 1850 | /** | ||
| 1851 | * device_iommu_capable() - check for a general IOMMU capability | ||
| 1852 | * @dev: device to which the capability would be relevant, if available | ||
| 1853 | * @cap: IOMMU capability | ||
| 1854 | * | ||
| 1855 | * Return: true if an IOMMU is present and supports the given capability | ||
| 1856 | * for the given device, otherwise false. | ||
| 1857 | */ | ||
| 1858 | bool device_iommu_capable(struct device *dev, enum iommu_cap cap) | ||
| 1859 | { | ||
| 1860 | const struct iommu_ops *ops; | ||
| 1861 | |||
| 1862 | if (!dev->iommu || !dev->iommu->iommu_dev) | ||
| 1863 | return false; | ||
| 1864 | |||
| 1865 | ops = dev_iommu_ops(dev); | ||
| 1866 | if (!ops->capable) | ||
| 1867 | return false; | ||
| 1868 | |||
| 1869 | return ops->capable(cap); | ||
| 1870 | } | ||
| 1871 | EXPORT_SYMBOL_GPL(device_iommu_capable); | ||
| 1872 | |||
| 1909 | bool iommu_capable(struct bus_type *bus, enum iommu_cap cap) | 1873 | bool iommu_capable(struct bus_type *bus, enum iommu_cap cap) |
| 1910 | { | 1874 | { |
| 1911 | if (!bus->iommu_ops || !bus->iommu_ops->capable) | 1875 | if (!bus->iommu_ops || !bus->iommu_ops->capable) |
| @@ -1976,6 +1940,24 @@ void iommu_domain_free(struct iommu_domain *domain) · 64 unmodified lines | |||
| 1976 | } | 1940 | } |
| 1977 | EXPORT_SYMBOL_GPL(iommu_domain_free); | 1941 | EXPORT_SYMBOL_GPL(iommu_domain_free); |
| 1978 | 1942 | ||
| 1943 | /* | ||
| 1944 | * Put the group's domain back to the appropriate core-owned domain - either the | ||
| 1945 | * standard kernel-mode DMA configuration or an all-DMA-blocked domain. | ||
| 1946 | */ | ||
| 1947 | static void __iommu_group_set_core_domain(struct iommu_group *group) | ||
| 1948 | { | ||
| 1949 | struct iommu_domain *new_domain; | ||
| 1950 | int ret; | ||
| 1951 | |||
| 1952 | if (group->owner) | ||
| 1953 | new_domain = group->blocking_domain; | ||
| 1954 | else | ||
| 1955 | new_domain = group->default_domain; | ||
| 1956 | |||
| 1957 | ret = __iommu_group_set_domain(group, new_domain); | ||
| 1958 | WARN(ret, "iommu driver failed to attach the default/blocking domain"); | ||
| 1959 | } | ||
| 1960 | |||
| 1979 | static int __iommu_attach_device(struct iommu_domain *domain, | 1961 | static int __iommu_attach_device(struct iommu_domain *domain, |
| 1980 | struct device *dev) | 1962 | struct device *dev) |
| 1981 | { | 1963 | { |
| @@ -2032,9 +2014,6 @@ static void __iommu_detach_device(struct iommu_domain *domain, · 50 unmodified lines | |||
| 2032 | if (iommu_is_attach_deferred(dev)) | 2014 | if (iommu_is_attach_deferred(dev)) |
| 2033 | return; | 2015 | return; |
| 2034 | 2016 | ||
| 2035 | if (unlikely(domain->ops->detach_dev == NULL)) | ||
| 2036 | return; | ||
| 2037 | |||
| 2038 | domain->ops->detach_dev(domain, dev); | 2017 | domain->ops->detach_dev(domain, dev); |
| 2039 | trace_detach_device_from_domain(dev); | 2018 | trace_detach_device_from_domain(dev); |
| 2040 | } | 2019 | } |
| @@ -2048,12 +2027,10 @@ void iommu_detach_device(struct iommu_domain *domain, struct device *dev) · 7 unmodified lines | |||
| 2048 | return; | 2027 | return; |
| 2049 | 2028 | ||
| 2050 | mutex_lock(&group->mutex); | 2029 | mutex_lock(&group->mutex); |
| 2051 | if (iommu_group_device_count(group) != 1) { | 2030 | if (WARN_ON(domain != group->domain) || |
| 2052 | WARN_ON(1); | 2031 | WARN_ON(iommu_group_device_count(group) != 1)) |
| 2053 | goto out_unlock; | 2032 | goto out_unlock; |
| 2054 | } | 2033 | __iommu_group_set_core_domain(group); |
| 2055 | |||
| 2056 | __iommu_detach_group(domain, group); | ||
| 2057 | 2034 | ||
| 2058 | out_unlock: | 2035 | out_unlock: |
| 2059 | mutex_unlock(&group->mutex); | 2036 | mutex_unlock(&group->mutex); |
| @@ -2109,7 +2086,8 @@ static int __iommu_attach_group(struct iommu_domain *domain, · 49 unmodified lines | |||
| 2109 | { | 2086 | { |
| 2110 | int ret; | 2087 | int ret; |
| 2111 | 2088 | ||
| 2112 | if (group->default_domain && group->domain != group->default_domain) | 2089 | if (group->domain && group->domain != group->default_domain && |
| 2090 | group->domain != group->blocking_domain) | ||
| 2113 | return -EBUSY; | 2091 | return -EBUSY; |
| 2114 | 2092 | ||
| 2115 | ret = __iommu_group_for_each_dev(group, domain, | 2093 | ret = __iommu_group_for_each_dev(group, domain, |
| @@ -2141,34 +2119,49 @@ static int iommu_group_do_detach_device(struct device *dev, void *data) · 25 unmodified lines | |||
| 2141 | return 0; | 2119 | return 0; |
| 2142 | } | 2120 | } |
| 2143 | 2121 | ||
| 2144 | static void __iommu_detach_group(struct iommu_domain *domain, | 2122 | static int __iommu_group_set_domain(struct iommu_group *group, |
| 2145 | struct iommu_group *group) | 2123 | struct iommu_domain *new_domain) |
| 2146 | { | 2124 | { |
| 2147 | int ret; | 2125 | int ret; |
| 2148 | 2126 | ||
| 2149 | if (!group->default_domain) { | 2127 | if (group->domain == new_domain) |
| 2150 | __iommu_group_for_each_dev(group, domain, | 2128 | return 0; |
| 2129 | |||
| 2130 | /* | ||
| 2131 | * New drivers should support default domains and so the detach_dev() op | ||
| 2132 | * will never be called. Otherwise the NULL domain represents some | ||
| 2133 | * platform specific behavior. | ||
| 2134 | */ | ||
| 2135 | if (!new_domain) { | ||
| 2136 | if (WARN_ON(!group->domain->ops->detach_dev)) | ||
| 2137 | return -EINVAL; | ||
| 2138 | __iommu_group_for_each_dev(group, group->domain, | ||
| 2151 | iommu_group_do_detach_device); | 2139 | iommu_group_do_detach_device); |
| 2152 | group->domain = NULL; | 2140 | group->domain = NULL; |
| 2153 | return; | 2141 | return 0; |
| 2154 | } | 2142 | } |
| 2155 | 2143 | ||
| 2156 | if (group->domain == group->default_domain) | 2144 | /* |
| 2157 | return; | 2145 | * Changing the domain is done by calling attach_dev() on the new |
| 2158 | 2146 | * domain. This switch does not have to be atomic and DMA can be | |
| 2159 | /* Detach by re-attaching to the default domain */ | 2147 | * discarded during the transition. DMA must only be able to access |
| 2160 | ret = __iommu_group_for_each_dev(group, group->default_domain, | 2148 | * either new_domain or group->domain, never something else. |
| 2149 | * | ||
| 2150 | * Note that this is called in error unwind paths, attaching to a | ||
| 2151 | * domain that has already been attached cannot fail. | ||
| 2152 | */ | ||
| 2153 | ret = __iommu_group_for_each_dev(group, new_domain, | ||
| 2161 | iommu_group_do_attach_device); | 2154 | iommu_group_do_attach_device); |
| 2162 | if (ret != 0) | 2155 | if (ret) |
| 2163 | WARN_ON(1); | 2156 | return ret; |
| 2164 | else | 2157 | group->domain = new_domain; |
| 2165 | group->domain = group->default_domain; | 2158 | return 0; |
| 2166 | } | 2159 | } |
| 2167 | 2160 | ||
| 2168 | void iommu_detach_group(struct iommu_domain *domain, struct iommu_group *group) | 2161 | void iommu_detach_group(struct iommu_domain *domain, struct iommu_group *group) |
| 2169 | { | 2162 | { |
| 2170 | mutex_lock(&group->mutex); | 2163 | mutex_lock(&group->mutex); |
| 2171 | __iommu_detach_group(domain, group); | 2164 | __iommu_group_set_core_domain(group); |
| 2172 | mutex_unlock(&group->mutex); | 2165 | mutex_unlock(&group->mutex); |
| 2173 | } | 2166 | } |
| 2174 | EXPORT_SYMBOL_GPL(iommu_detach_group); | 2167 | EXPORT_SYMBOL_GPL(iommu_detach_group); |
| @@ -3019,7 +3012,7 @@ static ssize_t iommu_group_store_type(struct iommu_group *group, · 844 unmodified lines | |||
| 3019 | if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) | 3012 | if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) |
| 3020 | return -EACCES; | 3013 | return -EACCES; |
| 3021 | 3014 | ||
| 3022 | if (WARN_ON(!group)) | 3015 | if (WARN_ON(!group) || !group->default_domain) |
| 3023 | return -EINVAL; | 3016 | return -EINVAL; |
| 3024 | 3017 | ||
| 3025 | if (sysfs_streq(buf, "identity")) | 3018 | if (sysfs_streq(buf, "identity")) |
| @@ -3095,3 +3088,167 @@ out: · 69 unmodified lines | |||
| 3095 | 3088 | ||
| 3096 | return ret; | 3089 | return ret; |
| 3097 | } | 3090 | } |
| 3091 | |||
| 3092 | /** | ||
| 3093 | * iommu_device_use_default_domain() - Device driver wants to handle device | ||
| 3094 | * DMA through the kernel DMA API. | ||
| 3095 | * @dev: The device. | ||
| 3096 | * | ||
| 3097 | * The device driver about to bind @dev wants to do DMA through the kernel | ||
| 3098 | * DMA API. Return 0 if it is allowed, otherwise an error. | ||
| 3099 | */ | ||
| 3100 | int iommu_device_use_default_domain(struct device *dev) | ||
| 3101 | { | ||
| 3102 | struct iommu_group *group = iommu_group_get(dev); | ||
| 3103 | int ret = 0; | ||
| 3104 | |||
| 3105 | if (!group) | ||
| 3106 | return 0; | ||
| 3107 | |||
| 3108 | mutex_lock(&group->mutex); | ||
| 3109 | if (group->owner_cnt) { | ||
| 3110 | if (group->domain != group->default_domain || | ||
| 3111 | group->owner) { | ||
| 3112 | ret = -EBUSY; | ||
| 3113 | goto unlock_out; | ||
| 3114 | } | ||
| 3115 | } | ||
| 3116 | |||
| 3117 | group->owner_cnt++; | ||
| 3118 | |||
| 3119 | unlock_out: | ||
| 3120 | mutex_unlock(&group->mutex); | ||
| 3121 | iommu_group_put(group); | ||
| 3122 | |||
| 3123 | return ret; | ||
| 3124 | } | ||
| 3125 | |||
| 3126 | /** | ||
| 3127 | * iommu_device_unuse_default_domain() - Device driver stops handling device | ||
| 3128 | * DMA through the kernel DMA API. | ||
| 3129 | * @dev: The device. | ||
| 3130 | * | ||
| 3131 | * The device driver doesn't want to do DMA through kernel DMA API anymore. | ||
| 3132 | * It must be called after iommu_device_use_default_domain(). | ||
| 3133 | */ | ||
| 3134 | void iommu_device_unuse_default_domain(struct device *dev) | ||
| 3135 | { | ||
| 3136 | struct iommu_group *group = iommu_group_get(dev); | ||
| 3137 | |||
| 3138 | if (!group) | ||
| 3139 | return; | ||
| 3140 | |||
| 3141 | mutex_lock(&group->mutex); | ||
| 3142 | if (!WARN_ON(!group->owner_cnt)) | ||
| 3143 | group->owner_cnt--; | ||
| 3144 | |||
| 3145 | mutex_unlock(&group->mutex); | ||
| 3146 | iommu_group_put(group); | ||
| 3147 | } | ||
| 3148 | |||
| 3149 | static int __iommu_group_alloc_blocking_domain(struct iommu_group *group) | ||
| 3150 | { | ||
| 3151 | struct group_device *dev = | ||
| 3152 | list_first_entry(&group->devices, struct group_device, list); | ||
| 3153 | |||
| 3154 | if (group->blocking_domain) | ||
| 3155 | return 0; | ||
| 3156 | |||
| 3157 | group->blocking_domain = | ||
| 3158 | __iommu_domain_alloc(dev->dev->bus, IOMMU_DOMAIN_BLOCKED); | ||
| 3159 | if (!group->blocking_domain) { | ||
| 3160 | /* | ||
| 3161 | * For drivers that do not yet understand IOMMU_DOMAIN_BLOCKED | ||
| 3162 | * create an empty domain instead. | ||
| 3163 | */ | ||
| 3164 | group->blocking_domain = __iommu_domain_alloc( | ||
| 3165 | dev->dev->bus, IOMMU_DOMAIN_UNMANAGED); | ||
| 3166 | if (!group->blocking_domain) | ||
| 3167 | return -EINVAL; | ||
| 3168 | } | ||
| 3169 | return 0; | ||
| 3170 | } | ||
| 3171 | |||
| 3172 | /** | ||
| 3173 | * iommu_group_claim_dma_owner() - Set DMA ownership of a group | ||
| 3174 | * @group: The group. | ||
| 3175 | * @owner: Caller specified pointer. Used for exclusive ownership. | ||
| 3176 | * | ||
| 3177 | * This is to support backward compatibility for vfio which manages | ||
| 3178 | * the dma ownership in iommu_group level. New invocations on this | ||
| 3179 | * interface should be prohibited. | ||
| 3180 | */ | ||
| 3181 | int iommu_group_claim_dma_owner(struct iommu_group *group, void *owner) | ||
| 3182 | { | ||
| 3183 | int ret = 0; | ||
| 3184 | |||
| 3185 | mutex_lock(&group->mutex); | ||
| 3186 | if (group->owner_cnt) { | ||
| 3187 | ret = -EPERM; | ||
| 3188 | goto unlock_out; | ||
| 3189 | } else { | ||
| 3190 | if (group->domain && group->domain != group->default_domain) { | ||
| 3191 | ret = -EBUSY; | ||
| 3192 | goto unlock_out; | ||
| 3193 | } | ||
| 3194 | |||
| 3195 | ret = __iommu_group_alloc_blocking_domain(group); | ||
| 3196 | if (ret) | ||
| 3197 | goto unlock_out; | ||
| 3198 | |||
| 3199 | ret = __iommu_group_set_domain(group, group->blocking_domain); | ||
| 3200 | if (ret) | ||
| 3201 | goto unlock_out; | ||
| 3202 | group->owner = owner; | ||
| 3203 | } | ||
| 3204 | |||
| 3205 | group->owner_cnt++; | ||
| 3206 | unlock_out: | ||
| 3207 | mutex_unlock(&group->mutex); | ||
| 3208 | |||
| 3209 | return ret; | ||
| 3210 | } | ||
| 3211 | EXPORT_SYMBOL_GPL(iommu_group_claim_dma_owner); | ||
| 3212 | |||
| 3213 | /** | ||
| 3214 | * iommu_group_release_dma_owner() - Release DMA ownership of a group | ||
| 3215 | * @group: The group. | ||
| 3216 | * | ||
| 3217 | * Release the DMA ownership claimed by iommu_group_claim_dma_owner(). | ||
| 3218 | */ | ||
| 3219 | void iommu_group_release_dma_owner(struct iommu_group *group) | ||
| 3220 | { | ||
| 3221 | int ret; | ||
| 3222 | |||
| 3223 | mutex_lock(&group->mutex); | ||
| 3224 | if (WARN_ON(!group->owner_cnt || !group->owner)) | ||
| 3225 | goto unlock_out; | ||
| 3226 | |||
| 3227 | group->owner_cnt = 0; | ||
| 3228 | group->owner = NULL; | ||
| 3229 | ret = __iommu_group_set_domain(group, group->default_domain); | ||
| 3230 | WARN(ret, "iommu driver failed to attach the default domain"); | ||
| 3231 | |||
| 3232 | unlock_out: | ||
| 3233 | mutex_unlock(&group->mutex); | ||
| 3234 | } | ||
| 3235 | EXPORT_SYMBOL_GPL(iommu_group_release_dma_owner); | ||
| 3236 | |||
| 3237 | /** | ||
| 3238 | * iommu_group_dma_owner_claimed() - Query group dma ownership status | ||
| 3239 | * @group: The group. | ||
| 3240 | * | ||
| 3241 | * This provides status query on a given group. It is racy and only for | ||
| 3242 | * non-binding status reporting. | ||
| 3243 | */ | ||
| 3244 | bool iommu_group_dma_owner_claimed(struct iommu_group *group) | ||
| 3245 | { | ||
| 3246 | unsigned int user; | ||
| 3247 | |||
| 3248 | mutex_lock(&group->mutex); | ||
| 3249 | user = group->owner_cnt; | ||
| 3250 | mutex_unlock(&group->mutex); | ||
| 3251 | |||
| 3252 | return user; | ||
| 3253 | } | ||
| 3254 | EXPORT_SYMBOL_GPL(iommu_group_dma_owner_claimed); | ||
| @@ -583,7 +583,7 @@ static void print_ctx_regs(void __iomem *base, int ctx) · 582 unmodified lines | |||
| 583 | GET_SCTLR(base, ctx), GET_ACTLR(base, ctx)); | 583 | GET_SCTLR(base, ctx), GET_ACTLR(base, ctx)); |
| 584 | } | 584 | } |
| 585 | 585 | ||
| 586 | static void insert_iommu_master(struct device *dev, | 586 | static int insert_iommu_master(struct device *dev, |
| 587 | struct msm_iommu_dev **iommu, | 587 | struct msm_iommu_dev **iommu, |
| 588 | struct of_phandle_args *spec) | 588 | struct of_phandle_args *spec) |
| 589 | { | 589 | { |
| @@ -592,6 +592,10 @@ static void insert_iommu_master(struct device *dev, · 2 unmodified lines | |||
| 592 | 592 | ||
| 593 | if (list_empty(&(*iommu)->ctx_list)) { | 593 | if (list_empty(&(*iommu)->ctx_list)) { |
| 594 | master = kzalloc(sizeof(*master), GFP_ATOMIC); | 594 | master = kzalloc(sizeof(*master), GFP_ATOMIC); |
| 595 | if (!master) { | ||
| 596 | dev_err(dev, "Failed to allocate iommu_master\n"); | ||
| 597 | return -ENOMEM; | ||
| 598 | } | ||
| 595 | master->of_node = dev->of_node; | 599 | master->of_node = dev->of_node; |
| 596 | list_add(&master->list, &(*iommu)->ctx_list); | 600 | list_add(&master->list, &(*iommu)->ctx_list); |
| 597 | dev_iommu_priv_set(dev, master); | 601 | dev_iommu_priv_set(dev, master); |
| @@ -601,30 +605,34 @@ static void insert_iommu_master(struct device *dev, · 3 unmodified lines | |||
| 601 | if (master->mids[sid] == spec->args[0]) { | 605 | if (master->mids[sid] == spec->args[0]) { |
| 602 | dev_warn(dev, "Stream ID 0x%hx repeated; ignoring\n", | 606 | dev_warn(dev, "Stream ID 0x%hx repeated; ignoring\n", |
| 603 | sid); | 607 | sid); |
| 604 | return; | 608 | return 0; |
| 605 | } | 609 | } |
| 606 | 610 | ||
| 607 | master->mids[master->num_mids++] = spec->args[0]; | 611 | master->mids[master->num_mids++] = spec->args[0]; |
| 612 | return 0; | ||
| 608 | } | 613 | } |
| 609 | 614 | ||
| 610 | static int qcom_iommu_of_xlate(struct device *dev, | 615 | static int qcom_iommu_of_xlate(struct device *dev, |
| 611 | struct of_phandle_args *spec) | 616 | struct of_phandle_args *spec) |
| 612 | { | 617 | { |
| 613 | struct msm_iommu_dev *iommu; | 618 | struct msm_iommu_dev *iommu = NULL, *iter; |
| 614 | unsigned long flags; | 619 | unsigned long flags; |
| 615 | int ret = 0; | 620 | int ret = 0; |
| 616 | 621 | ||
| 617 | spin_lock_irqsave(&msm_iommu_lock, flags); | 622 | spin_lock_irqsave(&msm_iommu_lock, flags); |
| 618 | list_for_each_entry(iommu, &qcom_iommu_devices, dev_node) | 623 | list_for_each_entry(iter, &qcom_iommu_devices, dev_node) { |
| 619 | if (iommu->dev->of_node == spec->np) | 624 | if (iter->dev->of_node == spec->np) { |
| 625 | iommu = iter; | ||
| 620 | break; | 626 | break; |
| 627 | } | ||
| 628 | } | ||
| 621 | 629 | ||
| 622 | if (!iommu || iommu->dev->of_node != spec->np) { | 630 | if (!iommu) { |
| 623 | ret = -ENODEV; | 631 | ret = -ENODEV; |
| 624 | goto fail; | 632 | goto fail; |
| 625 | } | 633 | } |
| 626 | 634 | ||
| 627 | insert_iommu_master(dev, &iommu, spec); | 635 | ret = insert_iommu_master(dev, &iommu, spec); |
| 628 | fail: | 636 | fail: |
| 629 | spin_unlock_irqrestore(&msm_iommu_lock, flags); | 637 | spin_unlock_irqrestore(&msm_iommu_lock, flags); |
| 630 | 638 | ||
| @@ -14,12 +14,14 @@ · 13 unmodified lines | |||
| 14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
| 15 | #include <linux/iommu.h> | 15 | #include <linux/iommu.h> |
| 16 | #include <linux/iopoll.h> | 16 | #include <linux/iopoll.h> |
| 17 | #include <linux/io-pgtable.h> | ||
| 17 | #include <linux/list.h> | 18 | #include <linux/list.h> |
| 18 | #include <linux/mfd/syscon.h> | 19 | #include <linux/mfd/syscon.h> |
| 19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 20 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
| 21 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
| 22 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
| 24 | #include <linux/pci.h> | ||
| 23 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
| 24 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
| 25 | #include <linux/regmap.h> | 27 | #include <linux/regmap.h> |
| @@ -29,7 +31,7 @@ · 3 unmodified lines | |||
| 29 | #include <asm/barrier.h> | 31 | #include <asm/barrier.h> |
| 30 | #include <soc/mediatek/smi.h> | 32 | #include <soc/mediatek/smi.h> |
| 31 | 33 | ||
| 32 | #include "mtk_iommu.h" | 34 | #include <dt-bindings/memory/mtk-memory-port.h> |
| 33 | 35 | ||
| 34 | #define REG_MMU_PT_BASE_ADDR 0x000 | 36 | #define REG_MMU_PT_BASE_ADDR 0x000 |
| 35 | #define MMU_PT_ADDR_MASK GENMASK(31, 7) | 37 | #define MMU_PT_ADDR_MASK GENMASK(31, 7) |
| @@ -51,6 +53,8 @@ · 15 unmodified lines | |||
| 51 | #define F_MMU_STANDARD_AXI_MODE_MASK (BIT(3) | BIT(19)) | 53 | #define F_MMU_STANDARD_AXI_MODE_MASK (BIT(3) | BIT(19)) |
| 52 | 54 | ||
| 53 | #define REG_MMU_DCM_DIS 0x050 | 55 | #define REG_MMU_DCM_DIS 0x050 |
| 56 | #define F_MMU_DCM BIT(8) | ||
| 57 | |||
| 54 | #define REG_MMU_WR_LEN_CTRL 0x054 | 58 | #define REG_MMU_WR_LEN_CTRL 0x054 |
| 55 | #define F_MMU_WR_THROT_DIS_MASK (BIT(5) | BIT(21)) | 59 | #define F_MMU_WR_THROT_DIS_MASK (BIT(5) | BIT(21)) |
| 56 | 60 | ||
| @@ -103,10 +107,15 @@ · 46 unmodified lines | |||
| 103 | #define REG_MMU1_INT_ID 0x154 | 107 | #define REG_MMU1_INT_ID 0x154 |
| 104 | #define F_MMU_INT_ID_COMM_ID(a) (((a) >> 9) & 0x7) | 108 | #define F_MMU_INT_ID_COMM_ID(a) (((a) >> 9) & 0x7) |
| 105 | #define F_MMU_INT_ID_SUB_COMM_ID(a) (((a) >> 7) & 0x3) | 109 | #define F_MMU_INT_ID_SUB_COMM_ID(a) (((a) >> 7) & 0x3) |
| 110 | #define F_MMU_INT_ID_COMM_ID_EXT(a) (((a) >> 10) & 0x7) | ||
| 111 | #define F_MMU_INT_ID_SUB_COMM_ID_EXT(a) (((a) >> 7) & 0x7) | ||
| 106 | #define F_MMU_INT_ID_LARB_ID(a) (((a) >> 7) & 0x7) | 112 | #define F_MMU_INT_ID_LARB_ID(a) (((a) >> 7) & 0x7) |
| 107 | #define F_MMU_INT_ID_PORT_ID(a) (((a) >> 2) & 0x1f) | 113 | #define F_MMU_INT_ID_PORT_ID(a) (((a) >> 2) & 0x1f) |
| 108 | 114 | ||
| 109 | #define MTK_PROTECT_PA_ALIGN 256 | 115 | #define MTK_PROTECT_PA_ALIGN 256 |
| 116 | #define MTK_IOMMU_BANK_SZ 0x1000 | ||
| 117 | |||
| 118 | #define PERICFG_IOMMU_1 0x714 | ||
| 110 | 119 | ||
| 111 | #define HAS_4GB_MODE BIT(0) | 120 | #define HAS_4GB_MODE BIT(0) |
| 112 | /* HW will use the EMI clock if there isn't the "bclk". */ | 121 | /* HW will use the EMI clock if there isn't the "bclk". */ |
| @@ -114,25 +123,147 @@ · 1 unmodified line | |||
| 114 | #define HAS_VLD_PA_RNG BIT(2) | 123 | #define HAS_VLD_PA_RNG BIT(2) |
| 115 | #define RESET_AXI BIT(3) | 124 | #define RESET_AXI BIT(3) |
| 116 | #define OUT_ORDER_WR_EN BIT(4) | 125 | #define OUT_ORDER_WR_EN BIT(4) |
| 117 | #define HAS_SUB_COMM BIT(5) | 126 | #define HAS_SUB_COMM_2BITS BIT(5) |
| 118 | #define WR_THROT_EN BIT(6) | 127 | #define HAS_SUB_COMM_3BITS BIT(6) |
| 119 | #define HAS_LEGACY_IVRP_PADDR BIT(7) | 128 | #define WR_THROT_EN BIT(7) |
| 120 | #define IOVA_34_EN BIT(8) | 129 | #define HAS_LEGACY_IVRP_PADDR BIT(8) |
| 130 | #define IOVA_34_EN BIT(9) | ||
| 131 | #define SHARE_PGTABLE BIT(10) /* 2 HW share pgtable */ | ||
| 132 | #define DCM_DISABLE BIT(11) | ||
| 133 | #define STD_AXI_MODE BIT(12) /* For non MM iommu */ | ||
| 134 | /* 2 bits: iommu type */ | ||
| 135 | #define MTK_IOMMU_TYPE_MM (0x0 << 13) | ||
| 136 | #define MTK_IOMMU_TYPE_INFRA (0x1 << 13) | ||
| 137 | #define MTK_IOMMU_TYPE_MASK (0x3 << 13) | ||
| 138 | /* PM and clock always on. e.g. infra iommu */ | ||
| 139 | #define PM_CLK_AO BIT(15) | ||
| 140 | #define IFA_IOMMU_PCIE_SUPPORT BIT(16) | ||
| 141 | |||
| 142 | #define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask) \ | ||
| 143 | ((((pdata)->flags) & (mask)) == (_x)) | ||
| 144 | |||
| 145 | #define MTK_IOMMU_HAS_FLAG(pdata, _x) MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, _x) | ||
| 146 | #define MTK_IOMMU_IS_TYPE(pdata, _x) MTK_IOMMU_HAS_FLAG_MASK(pdata, _x,\ | ||
| 147 | MTK_IOMMU_TYPE_MASK) | ||
| 148 | |||
| 149 | #define MTK_INVALID_LARBID MTK_LARB_NR_MAX | ||
| 150 | |||
| 151 | #define MTK_LARB_COM_MAX 8 | ||
| 152 | #define MTK_LARB_SUBCOM_MAX 8 | ||
| 153 | |||
| 154 | #define MTK_IOMMU_GROUP_MAX 8 | ||
| 155 | #define MTK_IOMMU_BANK_MAX 5 | ||
| 156 | |||
| 157 | enum mtk_iommu_plat { | ||
| 158 | M4U_MT2712, | ||
| 159 | M4U_MT6779, | ||
| 160 | M4U_MT8167, | ||
| 161 | M4U_MT8173, | ||
| 162 | M4U_MT8183, | ||
| 163 | M4U_MT8186, | ||
| 164 | M4U_MT8192, | ||
| 165 | M4U_MT8195, | ||
| 166 | }; | ||
| 167 | |||
| 168 | struct mtk_iommu_iova_region { | ||
| 169 | dma_addr_t iova_base; | ||
| 170 | unsigned long long size; | ||
| 171 | }; | ||
| 172 | |||
| 173 | struct mtk_iommu_suspend_reg { | ||
| 174 | u32 misc_ctrl; | ||
| 175 | u32 dcm_dis; | ||
| 176 | u32 ctrl_reg; | ||
| 177 | u32 vld_pa_rng; | ||
| 178 | u32 wr_len_ctrl; | ||
| 179 | |||
| 180 | u32 int_control[MTK_IOMMU_BANK_MAX]; | ||
| 181 | u32 int_main_control[MTK_IOMMU_BANK_MAX]; | ||
| 182 | u32 ivrp_paddr[MTK_IOMMU_BANK_MAX]; | ||
| 183 | }; | ||
| 184 | |||
| 185 | struct mtk_iommu_plat_data { | ||
| 186 | enum mtk_iommu_plat m4u_plat; | ||
| 187 | u32 flags; | ||
| 188 | u32 inv_sel_reg; | ||
| 189 | |||
| 190 | char *pericfg_comp_str; | ||
| 191 | struct list_head *hw_list; | ||
| 192 | unsigned int iova_region_nr; | ||
| 193 | const struct mtk_iommu_iova_region *iova_region; | ||
| 194 | |||
| 195 | u8 banks_num; | ||
| 196 | bool banks_enable[MTK_IOMMU_BANK_MAX]; | ||
| 197 | unsigned int banks_portmsk[MTK_IOMMU_BANK_MAX]; | ||
| 198 | unsigned char larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX]; | ||
| 199 | }; | ||
| 200 | |||
| 201 | struct mtk_iommu_bank_data { | ||
| 202 | void __iomem *base; | ||
| 203 | int irq; | ||
| 204 | u8 id; | ||
| 205 | struct device *parent_dev; | ||
| 206 | struct mtk_iommu_data *parent_data; | ||
| 207 | spinlock_t tlb_lock; /* lock for tlb range flush */ | ||
| 208 | struct mtk_iommu_domain *m4u_dom; /* Each bank has a domain */ | ||
| 209 | }; | ||
| 210 | |||
| 211 | struct mtk_iommu_data { | ||
| 212 | struct device *dev; | ||
| 213 | struct clk *bclk; | ||
| 214 | phys_addr_t protect_base; /* protect memory base */ | ||
| 215 | struct mtk_iommu_suspend_reg reg; | ||
| 216 | struct iommu_group *m4u_group[MTK_IOMMU_GROUP_MAX]; | ||
| 217 | bool enable_4GB; | ||
| 121 | 218 | ||
| 122 | #define MTK_IOMMU_HAS_FLAG(pdata, _x) \ | 219 | struct iommu_device iommu; |
| 123 | ((((pdata)->flags) & (_x)) == (_x)) | 220 | const struct mtk_iommu_plat_data *plat_data; |
| 221 | struct device *smicomm_dev; | ||
| 222 | |||
| 223 | struct mtk_iommu_bank_data *bank; | ||
| 224 | |||
| 225 | struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */ | ||
| 226 | struct regmap *pericfg; | ||
| 227 | |||
| 228 | struct mutex mutex; /* Protect m4u_group/m4u_dom above */ | ||
| 229 | |||
| 230 | /* | ||
| 231 | * In the sharing pgtable case, list data->list to the global list like m4ulist. | ||
| 232 | * In the non-sharing pgtable case, list data->list to the itself hw_list_head. | ||
| 233 | */ | ||
| 234 | struct list_head *hw_list; | ||
| 235 | struct list_head hw_list_head; | ||
| 236 | struct list_head list; | ||
| 237 | struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX]; | ||
| 238 | }; | ||
| 124 | 239 | ||
| 125 | struct mtk_iommu_domain { | 240 | struct mtk_iommu_domain { |
| 126 | struct io_pgtable_cfg cfg; | 241 | struct io_pgtable_cfg cfg; |
| 127 | struct io_pgtable_ops *iop; | 242 | struct io_pgtable_ops *iop; |
| 128 | 243 | ||
| 129 | struct mtk_iommu_data *data; | 244 | struct mtk_iommu_bank_data *bank; |
| 130 | struct iommu_domain domain; | 245 | struct iommu_domain domain; |
| 246 | |||
| 247 | struct mutex mutex; /* Protect "data" in this structure */ | ||
| 131 | }; | 248 | }; |
| 132 | 249 | ||
| 250 | static int mtk_iommu_bind(struct device *dev) | ||
| 251 | { | ||
| 252 | struct mtk_iommu_data *data = dev_get_drvdata(dev); | ||
| 253 | |||
| 254 | return component_bind_all(dev, &data->larb_imu); | ||
| 255 | } | ||
| 256 | |||
| 257 | static void mtk_iommu_unbind(struct device *dev) | ||
| 258 | { | ||
| 259 | struct mtk_iommu_data *data = dev_get_drvdata(dev); | ||
| 260 | |||
| 261 | component_unbind_all(dev, &data->larb_imu); | ||
| 262 | } | ||
| 263 | |||
| 133 | static const struct iommu_ops mtk_iommu_ops; | 264 | static const struct iommu_ops mtk_iommu_ops; |
| 134 | 265 | ||
| 135 | static int mtk_iommu_hw_init(const struct mtk_iommu_data *data); | 266 | static int mtk_iommu_hw_init(const struct mtk_iommu_data *data, unsigned int bankid); |
| 136 | 267 | ||
| 137 | #define MTK_IOMMU_TLB_ADDR(iova) ({ \ | 268 | #define MTK_IOMMU_TLB_ADDR(iova) ({ \ |
| 138 | dma_addr_t _addr = iova; \ | 269 | dma_addr_t _addr = iova; \ |
| @@ -165,42 +296,28 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data); · 26 unmodified lines | |||
| 165 | 296 | ||
| 166 | static LIST_HEAD(m4ulist); /* List all the M4U HWs */ | 297 | static LIST_HEAD(m4ulist); /* List all the M4U HWs */ |
| 167 | 298 | ||
| 168 | #define for_each_m4u(data) list_for_each_entry(data, &m4ulist, list) | 299 | #define for_each_m4u(data, head) list_for_each_entry(data, head, list) |
| 169 | |||
| 170 | struct mtk_iommu_iova_region { | ||
| 171 | dma_addr_t iova_base; | ||
| 172 | unsigned long long size; | ||
| 173 | }; | ||
| 174 | 300 | ||
| 175 | static const struct mtk_iommu_iova_region single_domain[] = { | 301 | static const struct mtk_iommu_iova_region single_domain[] = { |
| 176 | {.iova_base = 0, .size = SZ_4G}, | 302 | {.iova_base = 0, .size = SZ_4G}, |
| 177 | }; | 303 | }; |
| 178 | 304 | ||
| 179 | static const struct mtk_iommu_iova_region mt8192_multi_dom[] = { | 305 | static const struct mtk_iommu_iova_region mt8192_multi_dom[] = { |
| 180 | { .iova_base = 0x0, .size = SZ_4G}, /* disp: 0 ~ 4G */ | 306 | { .iova_base = 0x0, .size = SZ_4G}, /* 0 ~ 4G */ |
| 181 | #if IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) | 307 | #if IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) |
| 182 | { .iova_base = SZ_4G, .size = SZ_4G}, /* vdec: 4G ~ 8G */ | 308 | { .iova_base = SZ_4G, .size = SZ_4G}, /* 4G ~ 8G */ |
| 183 | { .iova_base = SZ_4G * 2, .size = SZ_4G}, /* CAM/MDP: 8G ~ 12G */ | 309 | { .iova_base = SZ_4G * 2, .size = SZ_4G}, /* 8G ~ 12G */ |
| 310 | { .iova_base = SZ_4G * 3, .size = SZ_4G}, /* 12G ~ 16G */ | ||
| 311 | |||
| 184 | { .iova_base = 0x240000000ULL, .size = 0x4000000}, /* CCU0 */ | 312 | { .iova_base = 0x240000000ULL, .size = 0x4000000}, /* CCU0 */ |
| 185 | { .iova_base = 0x244000000ULL, .size = 0x4000000}, /* CCU1 */ | 313 | { .iova_base = 0x244000000ULL, .size = 0x4000000}, /* CCU1 */ |
| 186 | #endif | 314 | #endif |
| 187 | }; | 315 | }; |
| 188 | 316 | ||
| 189 | /* | 317 | /* If 2 M4U share a domain(use the same hwlist), Put the corresponding info in first data.*/ |
| 190 | * There may be 1 or 2 M4U HWs, But we always expect they are in the same domain | 318 | static struct mtk_iommu_data *mtk_iommu_get_frst_data(struct list_head *hwlist) |
| 191 | * for the performance. | ||
| 192 | * | ||
| 193 | * Here always return the mtk_iommu_data of the first probed M4U where the | ||
| 194 | * iommu domain information is recorded. | ||
| 195 | */ | ||
| 196 | static struct mtk_iommu_data *mtk_iommu_get_m4u_data(void) | ||
| 197 | { | 319 | { |
| 198 | struct mtk_iommu_data *data; | 320 | return list_first_entry(hwlist, struct mtk_iommu_data, list); |
| 199 | |||
| 200 | for_each_m4u(data) | ||
| 201 | return data; | ||
| 202 | |||
| 203 | return NULL; | ||
| 204 | } | 321 | } |
| 205 | 322 | ||
| 206 | static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom) | 323 | static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom) |
| @@ -210,46 +327,72 @@ static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom) · 3 unmodified lines | |||
| 210 | 327 | ||
| 211 | static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data) | 328 | static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data) |
| 212 | { | 329 | { |
| 330 | /* Tlb flush all always is in bank0. */ | ||
| 331 | struct mtk_iommu_bank_data *bank = &data->bank[0]; | ||
| 332 | void __iomem *base = bank->base; | ||
| 213 | unsigned long flags; | 333 | unsigned long flags; |
| 214 | 334 | ||
| 215 | spin_lock_irqsave(&data->tlb_lock, flags); | 335 | spin_lock_irqsave(&bank->tlb_lock, flags); |
| 216 | writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, | 336 | writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, base + data->plat_data->inv_sel_reg); |
| 217 | data->base + data->plat_data->inv_sel_reg); | 337 | writel_relaxed(F_ALL_INVLD, base + REG_MMU_INVALIDATE); |
| 218 | writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE); | ||
| 219 | wmb(); /* Make sure the tlb flush all done */ | 338 | wmb(); /* Make sure the tlb flush all done */ |
| 220 | spin_unlock_irqrestore(&data->tlb_lock, flags); | 339 | spin_unlock_irqrestore(&bank->tlb_lock, flags); |
| 221 | } | 340 | } |
| 222 | 341 | ||
| 223 | static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size, | 342 | static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size, |
| 224 | size_t granule, | 343 | struct mtk_iommu_bank_data *bank) |
| 225 | struct mtk_iommu_data *data) | ||
| 226 | { | 344 | { |
| 345 | struct list_head *head = bank->parent_data->hw_list; | ||
| 346 | struct mtk_iommu_bank_data *curbank; | ||
| 347 | struct mtk_iommu_data *data; | ||
| 348 | bool check_pm_status; | ||
| 227 | unsigned long flags; | 349 | unsigned long flags; |
| 350 | void __iomem *base; | ||
| 228 | int ret; | 351 | int ret; |
| 229 | u32 tmp; | 352 | u32 tmp; |
| 230 | 353 | ||
| 231 | for_each_m4u(data) { | 354 | for_each_m4u(data, head) { |
| 232 | if (pm_runtime_get_if_in_use(data->dev) <= 0) | 355 | /* |
| 233 | continue; | 356 | * To avoid resume the iommu device frequently when the iommu device |
| 357 | * is not active, it doesn't always call pm_runtime_get here, then tlb | ||
| 358 | * flush depends on the tlb flush all in the runtime resume. | ||
| 359 | * | ||
| 360 | * There are 2 special cases: | ||
| 361 | * | ||
| 362 | * Case1: The iommu dev doesn't have power domain but has bclk. This case | ||
| 363 | * should also avoid the tlb flush while the dev is not active to mute | ||
| 364 | * the tlb timeout log. like mt8173. | ||
| 365 | * | ||
| 366 | * Case2: The power/clock of infra iommu is always on, and it doesn't | ||
| 367 | * have the device link with the master devices. This case should avoid | ||
| 368 | * the PM status check. | ||
| 369 | */ | ||
| 370 | check_pm_status = !MTK_IOMMU_HAS_FLAG(data->plat_data, PM_CLK_AO); | ||
| 234 | 371 | ||
| 235 | spin_lock_irqsave(&data->tlb_lock, flags); | 372 | if (check_pm_status) { |
| 373 | if (pm_runtime_get_if_in_use(data->dev) <= 0) | ||
| 374 | continue; | ||
| 375 | } | ||
| 376 | |||
| 377 | curbank = &data->bank[bank->id]; | ||
| 378 | base = curbank->base; | ||
| 379 | |||
| 380 | spin_lock_irqsave(&curbank->tlb_lock, flags); | ||
| 236 | writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, | 381 | writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, |
| 237 | data->base + data->plat_data->inv_sel_reg); | 382 | base + data->plat_data->inv_sel_reg); |
| 238 | 383 | ||
| 239 | writel_relaxed(MTK_IOMMU_TLB_ADDR(iova), | 384 | writel_relaxed(MTK_IOMMU_TLB_ADDR(iova), base + REG_MMU_INVLD_START_A); |
| 240 | data->base + REG_MMU_INVLD_START_A); | ||
| 241 | writel_relaxed(MTK_IOMMU_TLB_ADDR(iova + size - 1), | 385 | writel_relaxed(MTK_IOMMU_TLB_ADDR(iova + size - 1), |
| 242 | data->base + REG_MMU_INVLD_END_A); | 386 | base + REG_MMU_INVLD_END_A); |
| 243 | writel_relaxed(F_MMU_INV_RANGE, | 387 | writel_relaxed(F_MMU_INV_RANGE, base + REG_MMU_INVALIDATE); |
| 244 | data->base + REG_MMU_INVALIDATE); | ||
| 245 | 388 | ||
| 246 | /* tlb sync */ | 389 | /* tlb sync */ |
| 247 | ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, | 390 | ret = readl_poll_timeout_atomic(base + REG_MMU_CPE_DONE, |
| 248 | tmp, tmp != 0, 10, 1000); | 391 | tmp, tmp != 0, 10, 1000); |
| 249 | 392 | ||
| 250 | /* Clear the CPE status */ | 393 | /* Clear the CPE status */ |
| 251 | writel_relaxed(0, data->base + REG_MMU_CPE_DONE); | 394 | writel_relaxed(0, base + REG_MMU_CPE_DONE); |
| 252 | spin_unlock_irqrestore(&data->tlb_lock, flags); | 395 | spin_unlock_irqrestore(&curbank->tlb_lock, flags); |
| 253 | 396 | ||
| 254 | if (ret) { | 397 | if (ret) { |
| 255 | dev_warn(data->dev, | 398 | dev_warn(data->dev, |
| @@ -257,70 +400,103 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size, · 1 unmodified line | |||
| 257 | mtk_iommu_tlb_flush_all(data); | 400 | mtk_iommu_tlb_flush_all(data); |
| 258 | } | 401 | } |
| 259 | 402 | ||
| 260 | pm_runtime_put(data->dev); | 403 | if (check_pm_status) |
| 404 | pm_runtime_put(data->dev); | ||
| 261 | } | 405 | } |
| 262 | } | 406 | } |
| 263 | 407 | ||
| 264 | static irqreturn_t mtk_iommu_isr(int irq, void *dev_id) | 408 | static irqreturn_t mtk_iommu_isr(int irq, void *dev_id) |
| 265 | { | 409 | { |
| 266 | struct mtk_iommu_data *data = dev_id; | 410 | struct mtk_iommu_bank_data *bank = dev_id; |
| 267 | struct mtk_iommu_domain *dom = data->m4u_dom; | 411 | struct mtk_iommu_data *data = bank->parent_data; |
| 268 | unsigned int fault_larb, fault_port, sub_comm = 0; | 412 | struct mtk_iommu_domain *dom = bank->m4u_dom; |
| 413 | unsigned int fault_larb = MTK_INVALID_LARBID, fault_port = 0, sub_comm = 0; | ||
| 269 | u32 int_state, regval, va34_32, pa34_32; | 414 | u32 int_state, regval, va34_32, pa34_32; |
| 415 | const struct mtk_iommu_plat_data *plat_data = data->plat_data; | ||
| 416 | void __iomem *base = bank->base; | ||
| 270 | u64 fault_iova, fault_pa; | 417 | u64 fault_iova, fault_pa; |
| 271 | bool layer, write; | 418 | bool layer, write; |
| 272 | 419 | ||
| 273 | /* Read error info from registers */ | 420 | /* Read error info from registers */ |
| 274 | int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST1); | 421 | int_state = readl_relaxed(base + REG_MMU_FAULT_ST1); |
| 275 | if (int_state & F_REG_MMU0_FAULT_MASK) { | 422 | if (int_state & F_REG_MMU0_FAULT_MASK) { |
| 276 | regval = readl_relaxed(data->base + REG_MMU0_INT_ID); | 423 | regval = readl_relaxed(base + REG_MMU0_INT_ID); |
| 277 | fault_iova = readl_relaxed(data->base + REG_MMU0_FAULT_VA); | 424 | fault_iova = readl_relaxed(base + REG_MMU0_FAULT_VA); |
| 278 | fault_pa = readl_relaxed(data->base + REG_MMU0_INVLD_PA); | 425 | fault_pa = readl_relaxed(base + REG_MMU0_INVLD_PA); |
| 279 | } else { | 426 | } else { |
| 280 | regval = readl_relaxed(data->base + REG_MMU1_INT_ID); | 427 | regval = readl_relaxed(base + REG_MMU1_INT_ID); |
| 281 | fault_iova = readl_relaxed(data->base + REG_MMU1_FAULT_VA); | 428 | fault_iova = readl_relaxed(base + REG_MMU1_FAULT_VA); |
| 282 | fault_pa = readl_relaxed(data->base + REG_MMU1_INVLD_PA); | 429 | fault_pa = readl_relaxed(base + REG_MMU1_INVLD_PA); |
| 283 | } | 430 | } |
| 284 | layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT; | 431 | layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT; |
| 285 | write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT; | 432 | write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT; |
| 286 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) { | 433 | if (MTK_IOMMU_HAS_FLAG(plat_data, IOVA_34_EN)) { |
| 287 | va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova); | 434 | va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova); |
| 288 | pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova); | ||
| 289 | fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK; | 435 | fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK; |
| 290 | fault_iova |= (u64)va34_32 << 32; | 436 | fault_iova |= (u64)va34_32 << 32; |
| 291 | fault_pa |= (u64)pa34_32 << 32; | ||
| 292 | } | 437 | } |
| 293 | 438 | pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova); | |
| 294 | fault_port = F_MMU_INT_ID_PORT_ID(regval); | 439 | fault_pa |= (u64)pa34_32 << 32; |
| 295 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) { | 440 | |
| 296 | fault_larb = F_MMU_INT_ID_COMM_ID(regval); | 441 | if (MTK_IOMMU_IS_TYPE(plat_data, MTK_IOMMU_TYPE_MM)) { |
| 297 | sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval); | 442 | fault_port = F_MMU_INT_ID_PORT_ID(regval); |
| 298 | } else { | 443 | if (MTK_IOMMU_HAS_FLAG(plat_data, HAS_SUB_COMM_2BITS)) { |
| 299 | fault_larb = F_MMU_INT_ID_LARB_ID(regval); | 444 | fault_larb = F_MMU_INT_ID_COMM_ID(regval); |
| 445 | sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval); | ||
| 446 | } else if (MTK_IOMMU_HAS_FLAG(plat_data, HAS_SUB_COMM_3BITS)) { | ||
| 447 | fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval); | ||
| 448 | sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval); | ||
| 449 | } else { | ||
| 450 | fault_larb = F_MMU_INT_ID_LARB_ID(regval); | ||
| 451 | } | ||
| 452 | fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm]; | ||
| 300 | } | 453 | } |
| 301 | fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm]; | ||
| 302 | 454 | ||
| 303 | if (report_iommu_fault(&dom->domain, data->dev, fault_iova, | 455 | if (report_iommu_fault(&dom->domain, bank->parent_dev, fault_iova, |
| 304 | write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) { | 456 | write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) { |
| 305 | dev_err_ratelimited( | 457 | dev_err_ratelimited( |
| 306 | data->dev, | 458 | bank->parent_dev, |
| 307 | "fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d layer=%d %s\n", | 459 | "fault type=0x%x iova=0x%llx pa=0x%llx master=0x%x(larb=%d port=%d) layer=%d %s\n", |
| 308 | int_state, fault_iova, fault_pa, fault_larb, fault_port, | 460 | int_state, fault_iova, fault_pa, regval, fault_larb, fault_port, |
| 309 | layer, write ? "write" : "read"); | 461 | layer, write ? "write" : "read"); |
| 310 | } | 462 | } |
| 311 | 463 | ||
| 312 | /* Interrupt clear */ | 464 | /* Interrupt clear */ |
| 313 | regval = readl_relaxed(data->base + REG_MMU_INT_CONTROL0); | 465 | regval = readl_relaxed(base + REG_MMU_INT_CONTROL0); |
| 314 | regval |= F_INT_CLR_BIT; | 466 | regval |= F_INT_CLR_BIT; |
| 315 | writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0); | 467 | writel_relaxed(regval, base + REG_MMU_INT_CONTROL0); |
| 316 | 468 | ||
| 317 | mtk_iommu_tlb_flush_all(data); | 469 | mtk_iommu_tlb_flush_all(data); |
| 318 | 470 | ||
| 319 | return IRQ_HANDLED; | 471 | return IRQ_HANDLED; |
| 320 | } | 472 | } |
| 321 | 473 | ||
| 322 | static int mtk_iommu_get_domain_id(struct device *dev, | 474 | static unsigned int mtk_iommu_get_bank_id(struct device *dev, |
| 323 | const struct mtk_iommu_plat_data *plat_data) | 475 | const struct mtk_iommu_plat_data *plat_data) |
| 476 | { | ||
| 477 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); | ||
| 478 | unsigned int i, portmsk = 0, bankid = 0; | ||
| 479 | |||
| 480 | if (plat_data->banks_num == 1) | ||
| 481 | return bankid; | ||
| 482 | |||
| 483 | for (i = 0; i < fwspec->num_ids; i++) | ||
| 484 | portmsk |= BIT(MTK_M4U_TO_PORT(fwspec->ids[i])); | ||
| 485 | |||
| 486 | for (i = 0; i < plat_data->banks_num && i < MTK_IOMMU_BANK_MAX; i++) { | ||
| 487 | if (!plat_data->banks_enable[i]) | ||
| 488 | continue; | ||
| 489 | |||
| 490 | if (portmsk & plat_data->banks_portmsk[i]) { | ||
| 491 | bankid = i; | ||
| 492 | break; | ||
| 493 | } | ||
| 494 | } | ||
| 495 | return bankid; /* default is 0 */ | ||
| 496 | } | ||
| 497 | |||
| 498 | static int mtk_iommu_get_iova_region_id(struct device *dev, | ||
| 499 | const struct mtk_iommu_plat_data *plat_data) | ||
| 324 | { | 500 | { |
| 325 | const struct mtk_iommu_iova_region *rgn = plat_data->iova_region; | 501 | const struct mtk_iommu_iova_region *rgn = plat_data->iova_region; |
| 326 | const struct bus_dma_region *dma_rgn = dev->dma_range_map; | 502 | const struct bus_dma_region *dma_rgn = dev->dma_range_map; |
| @@ -349,46 +525,65 @@ static int mtk_iommu_get_domain_id(struct device *dev, · 22 unmodified lines | |||
| 349 | return -EINVAL; | 525 | return -EINVAL; |
| 350 | } | 526 | } |
| 351 | 527 | ||
| 352 | static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev, | 528 | static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev, |
| 353 | bool enable, unsigned int domid) | 529 | bool enable, unsigned int regionid) |
| 354 | { | 530 | { |
| 355 | struct mtk_smi_larb_iommu *larb_mmu; | 531 | struct mtk_smi_larb_iommu *larb_mmu; |
| 356 | unsigned int larbid, portid; | 532 | unsigned int larbid, portid; |
| 357 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); | 533 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); |
| 358 | const struct mtk_iommu_iova_region *region; | 534 | const struct mtk_iommu_iova_region *region; |
| 359 | int i; | 535 | u32 peri_mmuen, peri_mmuen_msk; |
| 536 | int i, ret = 0; | ||
| 360 | 537 | ||
| 361 | for (i = 0; i < fwspec->num_ids; ++i) { | 538 | for (i = 0; i < fwspec->num_ids; ++i) { |
| 362 | larbid = MTK_M4U_TO_LARB(fwspec->ids[i]); | 539 | larbid = MTK_M4U_TO_LARB(fwspec->ids[i]); |
| 363 | portid = MTK_M4U_TO_PORT(fwspec->ids[i]); | 540 | portid = MTK_M4U_TO_PORT(fwspec->ids[i]); |
| 364 | 541 | ||
| 365 | larb_mmu = &data->larb_imu[larbid]; | 542 | if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) { |
| 366 | 543 | larb_mmu = &data->larb_imu[larbid]; | |
| 367 | region = data->plat_data->iova_region + domid; | 544 | |
| 368 | larb_mmu->bank[portid] = upper_32_bits(region->iova_base); | 545 | region = data->plat_data->iova_region + regionid; |
| 369 | 546 | larb_mmu->bank[portid] = upper_32_bits(region->iova_base); | |
| 370 | dev_dbg(dev, "%s iommu for larb(%s) port %d dom %d bank %d.\n", | 547 | |
| 371 | enable ? "enable" : "disable", dev_name(larb_mmu->dev), | 548 | dev_dbg(dev, "%s iommu for larb(%s) port %d region %d rgn-bank %d.\n", |
| 372 | portid, domid, larb_mmu->bank[portid]); | 549 | enable ? "enable" : "disable", dev_name(larb_mmu->dev), |
| 373 | 550 | portid, regionid, larb_mmu->bank[portid]); | |
| 374 | if (enable) | 551 | |
| 375 | larb_mmu->mmu |= MTK_SMI_MMU_EN(portid); | 552 | if (enable) |
| 376 | else | 553 | larb_mmu->mmu |= MTK_SMI_MMU_EN(portid); |
| 377 | larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid); | 554 | else |
| 555 | larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid); | ||
| 556 | } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) { | ||
| 557 | peri_mmuen_msk = BIT(portid); | ||
| 558 | /* PCI dev has only one output id, enable the next writing bit for PCIe */ | ||
| 559 | if (dev_is_pci(dev)) | ||
| 560 | peri_mmuen_msk |= BIT(portid + 1); | ||
| 561 | |||
| 562 | peri_mmuen = enable ? peri_mmuen_msk : 0; | ||
| 563 | ret = regmap_update_bits(data->pericfg, PERICFG_IOMMU_1, | ||
| 564 | peri_mmuen_msk, peri_mmuen); | ||
| 565 | if (ret) | ||
| 566 | dev_err(dev, "%s iommu(%s) inframaster 0x%x fail(%d).\n", | ||
| 567 | enable ? "enable" : "disable", | ||
| 568 | dev_name(data->dev), peri_mmuen_msk, ret); | ||
| 569 | } | ||
| 378 | } | 570 | } |
| 571 | return ret; | ||
| 379 | } | 572 | } |
| 380 | 573 | ||
| 381 | static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, | 574 | static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, |
| 382 | struct mtk_iommu_data *data, | 575 | struct mtk_iommu_data *data, |
| 383 | unsigned int domid) | 576 | unsigned int region_id) |
| 384 | { | 577 | { |
| 385 | const struct mtk_iommu_iova_region *region; | 578 | const struct mtk_iommu_iova_region *region; |
| 386 | 579 | struct mtk_iommu_domain *m4u_dom; | |
| 387 | /* Use the exist domain as there is only one pgtable here. */ | 580 | |
| 388 | if (data->m4u_dom) { | 581 | /* Always use bank0 in sharing pgtable case */ |
| 389 | dom->iop = data->m4u_dom->iop; | 582 | m4u_dom = data->bank[0].m4u_dom; |
| 390 | dom->cfg = data->m4u_dom->cfg; | 583 | if (m4u_dom) { |
| 391 | dom->domain.pgsize_bitmap = data->m4u_dom->cfg.pgsize_bitmap; | 584 | dom->iop = m4u_dom->iop; |
| 585 | dom->cfg = m4u_dom->cfg; | ||
| 586 | dom->domain.pgsize_bitmap = m4u_dom->cfg.pgsize_bitmap; | ||
| 392 | goto update_iova_region; | 587 | goto update_iova_region; |
| 393 | } | 588 | } |
| 394 | 589 | ||
| @@ -417,7 +612,7 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom, · 22 unmodified lines | |||
| 417 | 612 | ||
| 418 | update_iova_region: | 613 | update_iova_region: |
| 419 | /* Update the iova region for this domain */ | 614 | /* Update the iova region for this domain */ |
| 420 | region = data->plat_data->iova_region + domid; | 615 | region = data->plat_data->iova_region + region_id; |
| 421 | dom->domain.geometry.aperture_start = region->iova_base; | 616 | dom->domain.geometry.aperture_start = region->iova_base; |
| 422 | dom->domain.geometry.aperture_end = region->iova_base + region->size - 1; | 617 | dom->domain.geometry.aperture_end = region->iova_base + region->size - 1; |
| 423 | dom->domain.geometry.force_aperture = true; | 618 | dom->domain.geometry.force_aperture = true; |
| @@ -428,12 +623,13 @@ static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type) · 4 unmodified lines | |||
| 428 | { | 623 | { |
| 429 | struct mtk_iommu_domain *dom; | 624 | struct mtk_iommu_domain *dom; |
| 430 | 625 | ||
| 431 | if (type != IOMMU_DOMAIN_DMA) | 626 | if (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_UNMANAGED) |
| 432 | return NULL; | 627 | return NULL; |
| 433 | 628 | ||
| 434 | dom = kzalloc(sizeof(*dom), GFP_KERNEL); | 629 | dom = kzalloc(sizeof(*dom), GFP_KERNEL); |
| 435 | if (!dom) | 630 | if (!dom) |
| 436 | return NULL; | 631 | return NULL; |
| 632 | mutex_init(&dom->mutex); | ||
| 437 | 633 | ||
| 438 | return &dom->domain; | 634 | return &dom->domain; |
| 439 | } | 635 | } |
| @@ -446,40 +642,60 @@ static void mtk_iommu_domain_free(struct iommu_domain *domain) · 6 unmodified lines | |||
| 446 | static int mtk_iommu_attach_device(struct iommu_domain *domain, | 642 | static int mtk_iommu_attach_device(struct iommu_domain *domain, |
| 447 | struct device *dev) | 643 | struct device *dev) |
| 448 | { | 644 | { |
| 449 | struct mtk_iommu_data *data = dev_iommu_priv_get(dev); | 645 | struct mtk_iommu_data *data = dev_iommu_priv_get(dev), *frstdata; |
| 450 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 646 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); |
| 647 | struct list_head *hw_list = data->hw_list; | ||
| 451 | struct device *m4udev = data->dev; | 648 | struct device *m4udev = data->dev; |
| 452 | int ret, domid; | 649 | struct mtk_iommu_bank_data *bank; |
| 650 | unsigned int bankid; | ||
| 651 | int ret, region_id; | ||
| 453 | 652 | ||
| 454 | domid = mtk_iommu_get_domain_id(dev, data->plat_data); | 653 | region_id = mtk_iommu_get_iova_region_id(dev, data->plat_data); |
| 455 | if (domid < 0) | 654 | if (region_id < 0) |
| 456 | return domid; | 655 | return region_id; |
| 457 | 656 | ||
| 458 | if (!dom->data) { | 657 | bankid = mtk_iommu_get_bank_id(dev, data->plat_data); |
| 459 | if (mtk_iommu_domain_finalise(dom, data, domid)) | 658 | mutex_lock(&dom->mutex); |
| 659 | if (!dom->bank) { | ||
| 660 | /* Data is in the frstdata in sharing pgtable case. */ | ||
| 661 | frstdata = mtk_iommu_get_frst_data(hw_list); | ||
| 662 | |||
| 663 | ret = mtk_iommu_domain_finalise(dom, frstdata, region_id); | ||
| 664 | if (ret) { | ||
| 665 | mutex_unlock(&dom->mutex); | ||
| 460 | return -ENODEV; | 666 | return -ENODEV; |
| 461 | dom->data = data; | 667 | } |
| 668 | dom->bank = &data->bank[bankid]; | ||
| 462 | } | 669 | } |
| 670 | mutex_unlock(&dom->mutex); | ||
| 463 | 671 | ||
| 464 | if (!data->m4u_dom) { /* Initialize the M4U HW */ | 672 | mutex_lock(&data->mutex); |
| 673 | bank = &data->bank[bankid]; | ||
| 674 | if (!bank->m4u_dom) { /* Initialize the M4U HW for each a BANK */ | ||
| 465 | ret = pm_runtime_resume_and_get(m4udev); | 675 | ret = pm_runtime_resume_and_get(m4udev); |
| 466 | if (ret < 0) | 676 | if (ret < 0) { |
| 467 | return ret; | 677 | dev_err(m4udev, "pm get fail(%d) in attach.\n", ret); |
| 678 | goto err_unlock; | ||
| 679 | } | ||
| 468 | 680 | ||
| 469 | ret = mtk_iommu_hw_init(data); | 681 | ret = mtk_iommu_hw_init(data, bankid); |
| 470 | if (ret) { | 682 | if (ret) { |
| 471 | pm_runtime_put(m4udev); | 683 | pm_runtime_put(m4udev); |
| 472 | return ret; | 684 | goto err_unlock; |
| 473 | } | 685 | } |
| 474 | data->m4u_dom = dom; | 686 | bank->m4u_dom = dom; |
| 475 | writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, | 687 | writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, |
| 476 | data->base + REG_MMU_PT_BASE_ADDR); | 688 | bank->base + REG_MMU_PT_BASE_ADDR); |
| 477 | 689 | ||
| 478 | pm_runtime_put(m4udev); | 690 | pm_runtime_put(m4udev); |
| 479 | } | 691 | } |
| 692 | mutex_unlock(&data->mutex); | ||
| 480 | 693 | ||
| 481 | mtk_iommu_config(data, dev, true, domid); | 694 | return mtk_iommu_config(data, dev, true, region_id); |
| 482 | return 0; | 695 | |
| 696 | err_unlock: | ||
| 697 | mutex_unlock(&data->mutex); | ||
| 698 | return ret; | ||
| 483 | } | 699 | } |
| 484 | 700 | ||
| 485 | static void mtk_iommu_detach_device(struct iommu_domain *domain, | 701 | static void mtk_iommu_detach_device(struct iommu_domain *domain, |
| @@ -496,7 +712,7 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova, · 10 unmodified lines | |||
| 496 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 712 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); |
| 497 | 713 | ||
| 498 | /* The "4GB mode" M4U physically can not use the lower remap of Dram. */ | 714 | /* The "4GB mode" M4U physically can not use the lower remap of Dram. */ |
| 499 | if (dom->data->enable_4GB) | 715 | if (dom->bank->parent_data->enable_4GB) |
| 500 | paddr |= BIT_ULL(32); | 716 | paddr |= BIT_ULL(32); |
| 501 | 717 | ||
| 502 | /* Synchronize with the tlb_lock */ | 718 | /* Synchronize with the tlb_lock */ |
| @@ -517,7 +733,7 @@ static void mtk_iommu_flush_iotlb_all(struct iommu_domain *domain) · 14 unmodified lines | |||
| 517 | { | 733 | { |
| 518 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 734 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); |
| 519 | 735 | ||
| 520 | mtk_iommu_tlb_flush_all(dom->data); | 736 | mtk_iommu_tlb_flush_all(dom->bank->parent_data); |
| 521 | } | 737 | } |
| 522 | 738 | ||
| 523 | static void mtk_iommu_iotlb_sync(struct iommu_domain *domain, | 739 | static void mtk_iommu_iotlb_sync(struct iommu_domain *domain, |
| @@ -526,8 +742,7 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain *domain, · 2 unmodified lines | |||
| 526 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 742 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); |
| 527 | size_t length = gather->end - gather->start + 1; | 743 | size_t length = gather->end - gather->start + 1; |
| 528 | 744 | ||
| 529 | mtk_iommu_tlb_flush_range_sync(gather->start, length, gather->pgsize, | 745 | mtk_iommu_tlb_flush_range_sync(gather->start, length, dom->bank); |
| 530 | dom->data); | ||
| 531 | } | 746 | } |
| 532 | 747 | ||
| 533 | static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova, | 748 | static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova, |
| @@ -535,7 +750,7 @@ static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova, · 1 unmodified line | |||
| 535 | { | 750 | { |
| 536 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 751 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); |
| 537 | 752 | ||
| 538 | mtk_iommu_tlb_flush_range_sync(iova, size, size, dom->data); | 753 | mtk_iommu_tlb_flush_range_sync(iova, size, dom->bank); |
| 539 | } | 754 | } |
| 540 | 755 | ||
| 541 | static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, | 756 | static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, |
| @@ -546,7 +761,7 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, · 4 unmodified lines | |||
| 546 | 761 | ||
| 547 | pa = dom->iop->iova_to_phys(dom->iop, iova); | 762 | pa = dom->iop->iova_to_phys(dom->iop, iova); |
| 548 | if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT) && | 763 | if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT) && |
| 549 | dom->data->enable_4GB && | 764 | dom->bank->parent_data->enable_4GB && |
| 550 | pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE) | 765 | pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE) |
| 551 | pa &= ~BIT_ULL(32); | 766 | pa &= ~BIT_ULL(32); |
| 552 | 767 | ||
| @@ -566,12 +781,18 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) · 13 unmodified lines | |||
| 566 | 781 | ||
| 567 | data = dev_iommu_priv_get(dev); | 782 | data = dev_iommu_priv_get(dev); |
| 568 | 783 | ||
| 784 | if (!MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) | ||
| 785 | return &data->iommu; | ||
| 786 | |||
| 569 | /* | 787 | /* |
| 570 | * Link the consumer device with the smi-larb device(supplier). | 788 | * Link the consumer device with the smi-larb device(supplier). |
| 571 | * The device that connects with each a larb is a independent HW. | 789 | * The device that connects with each a larb is a independent HW. |
| 572 | * All the ports in each a device should be in the same larbs. | 790 | * All the ports in each a device should be in the same larbs. |
| 573 | */ | 791 | */ |
| 574 | larbid = MTK_M4U_TO_LARB(fwspec->ids[0]); | 792 | larbid = MTK_M4U_TO_LARB(fwspec->ids[0]); |
| 793 | if (larbid >= MTK_LARB_NR_MAX) | ||
| 794 | return ERR_PTR(-EINVAL); | ||
| 795 | |||
| 575 | for (i = 1; i < fwspec->num_ids; i++) { | 796 | for (i = 1; i < fwspec->num_ids; i++) { |
| 576 | larbidx = MTK_M4U_TO_LARB(fwspec->ids[i]); | 797 | larbidx = MTK_M4U_TO_LARB(fwspec->ids[i]); |
| 577 | if (larbid != larbidx) { | 798 | if (larbid != larbidx) { |
| @@ -581,6 +802,9 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) · 3 unmodified lines | |||
| 581 | } | 802 | } |
| 582 | } | 803 | } |
| 583 | larbdev = data->larb_imu[larbid].dev; | 804 | larbdev = data->larb_imu[larbid].dev; |
| 805 | if (!larbdev) | ||
| 806 | return ERR_PTR(-EINVAL); | ||
| 807 | |||
| 584 | link = device_link_add(dev, larbdev, | 808 | link = device_link_add(dev, larbdev, |
| 585 | DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); | 809 | DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); |
| 586 | if (!link) | 810 | if (!link) |
| @@ -599,34 +823,55 @@ static void mtk_iommu_release_device(struct device *dev) · 12 unmodified lines | |||
| 599 | return; | 823 | return; |
| 600 | 824 | ||
| 601 | data = dev_iommu_priv_get(dev); | 825 | data = dev_iommu_priv_get(dev); |
| 602 | larbid = MTK_M4U_TO_LARB(fwspec->ids[0]); | 826 | if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) { |
| 603 | larbdev = data->larb_imu[larbid].dev; | 827 | larbid = MTK_M4U_TO_LARB(fwspec->ids[0]); |
| 604 | device_link_remove(dev, larbdev); | 828 | larbdev = data->larb_imu[larbid].dev; |
| 829 | device_link_remove(dev, larbdev); | ||
| 830 | } | ||
| 605 | 831 | ||
| 606 | iommu_fwspec_free(dev); | 832 | iommu_fwspec_free(dev); |
| 607 | } | 833 | } |
| 608 | 834 | ||
| 835 | static int mtk_iommu_get_group_id(struct device *dev, const struct mtk_iommu_plat_data *plat_data) | ||
| 836 | { | ||
| 837 | unsigned int bankid; | ||
| 838 | |||
| 839 | /* | ||
| 840 | * If the bank function is enabled, each bank is a iommu group/domain. | ||
| 841 | * Otherwise, each iova region is a iommu group/domain. | ||
| 842 | */ | ||
| 843 | bankid = mtk_iommu_get_bank_id(dev, plat_data); | ||
| 844 | if (bankid) | ||
| 845 | return bankid; | ||
| 846 | |||
| 847 | return mtk_iommu_get_iova_region_id(dev, plat_data); | ||
| 848 | } | ||
| 849 | |||
| 609 | static struct iommu_group *mtk_iommu_device_group(struct device *dev) | 850 | static struct iommu_group *mtk_iommu_device_group(struct device *dev) |
| 610 | { | 851 | { |
| 611 | struct mtk_iommu_data *data = mtk_iommu_get_m4u_data(); | 852 | struct mtk_iommu_data *c_data = dev_iommu_priv_get(dev), *data; |
| 853 | struct list_head *hw_list = c_data->hw_list; | ||
| 612 | struct iommu_group *group; | 854 | struct iommu_group *group; |
| 613 | int domid; | 855 | int groupid; |
| 614 | 856 | ||
| 857 | data = mtk_iommu_get_frst_data(hw_list); | ||
| 615 | if (!data) | 858 | if (!data) |
| 616 | return ERR_PTR(-ENODEV); | 859 | return ERR_PTR(-ENODEV); |
| 617 | 860 | ||
| 618 | domid = mtk_iommu_get_domain_id(dev, data->plat_data); | 861 | groupid = mtk_iommu_get_group_id(dev, data->plat_data); |
| 619 | if (domid < 0) | 862 | if (groupid < 0) |
| 620 | return ERR_PTR(domid); | 863 | return ERR_PTR(groupid); |
| 621 | 864 | ||
| 622 | group = data->m4u_group[domid]; | 865 | mutex_lock(&data->mutex); |
| 866 | group = data->m4u_group[groupid]; | ||
| 623 | if (!group) { | 867 | if (!group) { |
| 624 | group = iommu_group_alloc(); | 868 | group = iommu_group_alloc(); |
| 625 | if (!IS_ERR(group)) | 869 | if (!IS_ERR(group)) |
| 626 | data->m4u_group[domid] = group; | 870 | data->m4u_group[groupid] = group; |
| 627 | } else { | 871 | } else { |
| 628 | iommu_group_ref_get(group); | 872 | iommu_group_ref_get(group); |
| 629 | } | 873 | } |
| 874 | mutex_unlock(&data->mutex); | ||
| 630 | return group; | 875 | return group; |
| 631 | } | 876 | } |
| 632 | 877 | ||
| @@ -656,14 +901,14 @@ static void mtk_iommu_get_resv_regions(struct device *dev, · 23 unmodified lines | |||
| 656 | struct list_head *head) | 901 | struct list_head *head) |
| 657 | { | 902 | { |
| 658 | struct mtk_iommu_data *data = dev_iommu_priv_get(dev); | 903 | struct mtk_iommu_data *data = dev_iommu_priv_get(dev); |
| 659 | unsigned int domid = mtk_iommu_get_domain_id(dev, data->plat_data), i; | 904 | unsigned int regionid = mtk_iommu_get_iova_region_id(dev, data->plat_data), i; |
| 660 | const struct mtk_iommu_iova_region *resv, *curdom; | 905 | const struct mtk_iommu_iova_region *resv, *curdom; |
| 661 | struct iommu_resv_region *region; | 906 | struct iommu_resv_region *region; |
| 662 | int prot = IOMMU_WRITE | IOMMU_READ; | 907 | int prot = IOMMU_WRITE | IOMMU_READ; |
| 663 | 908 | ||
| 664 | if ((int)domid < 0) | 909 | if ((int)regionid < 0) |
| 665 | return; | 910 | return; |
| 666 | curdom = data->plat_data->iova_region + domid; | 911 | curdom = data->plat_data->iova_region + regionid; |
| 667 | for (i = 0; i < data->plat_data->iova_region_nr; i++) { | 912 | for (i = 0; i < data->plat_data->iova_region_nr; i++) { |
| 668 | resv = data->plat_data->iova_region + i; | 913 | resv = data->plat_data->iova_region + i; |
| 669 | 914 | ||
| @@ -704,42 +949,24 @@ static const struct iommu_ops mtk_iommu_ops = { · 34 unmodified lines | |||
| 704 | } | 949 | } |
| 705 | }; | 950 | }; |
| 706 | 951 | ||
| 707 | static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) | 952 | static int mtk_iommu_hw_init(const struct mtk_iommu_data *data, unsigned int bankid) |
| 708 | { | 953 | { |
| 954 | const struct mtk_iommu_bank_data *bankx = &data->bank[bankid]; | ||
| 955 | const struct mtk_iommu_bank_data *bank0 = &data->bank[0]; | ||
| 709 | u32 regval; | 956 | u32 regval; |
| 710 | 957 | ||
| 958 | /* | ||
| 959 | * Global control settings are in bank0. May re-init these global registers | ||
| 960 | * since no sure if there is bank0 consumers. | ||
| 961 | */ | ||
| 711 | if (data->plat_data->m4u_plat == M4U_MT8173) { | 962 | if (data->plat_data->m4u_plat == M4U_MT8173) { |
| 712 | regval = F_MMU_PREFETCH_RT_REPLACE_MOD | | 963 | regval = F_MMU_PREFETCH_RT_REPLACE_MOD | |
| 713 | F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173; | 964 | F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173; |
| 714 | } else { | 965 | } else { |
| 715 | regval = readl_relaxed(data->base + REG_MMU_CTRL_REG); | 966 | regval = readl_relaxed(bank0->base + REG_MMU_CTRL_REG); |
| 716 | regval |= F_MMU_TF_PROT_TO_PROGRAM_ADDR; | 967 | regval |= F_MMU_TF_PROT_TO_PROGRAM_ADDR; |
| 717 | } | 968 | } |
| 718 | writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); | 969 | writel_relaxed(regval, bank0->base + REG_MMU_CTRL_REG); |
| 719 | |||
| 720 | regval = F_L2_MULIT_HIT_EN | | ||
| 721 | F_TABLE_WALK_FAULT_INT_EN | | ||
| 722 | F_PREETCH_FIFO_OVERFLOW_INT_EN | | ||
| 723 | F_MISS_FIFO_OVERFLOW_INT_EN | | ||
| 724 | F_PREFETCH_FIFO_ERR_INT_EN | | ||
| 725 | F_MISS_FIFO_ERR_INT_EN; | ||
| 726 | writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0); | ||
| 727 | |||
| 728 | regval = F_INT_TRANSLATION_FAULT | | ||
| 729 | F_INT_MAIN_MULTI_HIT_FAULT | | ||
| 730 | F_INT_INVALID_PA_FAULT | | ||
| 731 | F_INT_ENTRY_REPLACEMENT_FAULT | | ||
| 732 | F_INT_TLB_MISS_FAULT | | ||
| 733 | F_INT_MISS_TRANSACTION_FIFO_FAULT | | ||
| 734 | F_INT_PRETETCH_TRANSATION_FIFO_FAULT; | ||
| 735 | writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL); | ||
| 736 | |||
| 737 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR)) | ||
| 738 | regval = (data->protect_base >> 1) | (data->enable_4GB << 31); | ||
| 739 | else | ||
| 740 | regval = lower_32_bits(data->protect_base) | | ||
| 741 | upper_32_bits(data->protect_base); | ||
| 742 | writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR); | ||
| 743 | 970 | ||
| 744 | if (data->enable_4GB && | 971 | if (data->enable_4GB && |
| 745 | MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_VLD_PA_RNG)) { | 972 | MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_VLD_PA_RNG)) { |
| @@ -748,31 +975,61 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) · 2 unmodified lines | |||
| 748 | * 0x1_0000_0000 to 0x1_ffff_ffff. here record bit[32:30]. | 975 | * 0x1_0000_0000 to 0x1_ffff_ffff. here record bit[32:30]. |
| 749 | */ | 976 | */ |
| 750 | regval = F_MMU_VLD_PA_RNG(7, 4); | 977 | regval = F_MMU_VLD_PA_RNG(7, 4); |
| 751 | writel_relaxed(regval, data->base + REG_MMU_VLD_PA_RNG); | 978 | writel_relaxed(regval, bank0->base + REG_MMU_VLD_PA_RNG); |
| 752 | } | 979 | } |
| 753 | writel_relaxed(0, data->base + REG_MMU_DCM_DIS); | 980 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, DCM_DISABLE)) |
| 981 | writel_relaxed(F_MMU_DCM, bank0->base + REG_MMU_DCM_DIS); | ||
| 982 | else | ||
| 983 | writel_relaxed(0, bank0->base + REG_MMU_DCM_DIS); | ||
| 984 | |||
| 754 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, WR_THROT_EN)) { | 985 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, WR_THROT_EN)) { |
| 755 | /* write command throttling mode */ | 986 | /* write command throttling mode */ |
| 756 | regval = readl_relaxed(data->base + REG_MMU_WR_LEN_CTRL); | 987 | regval = readl_relaxed(bank0->base + REG_MMU_WR_LEN_CTRL); |
| 757 | regval &= ~F_MMU_WR_THROT_DIS_MASK; | 988 | regval &= ~F_MMU_WR_THROT_DIS_MASK; |
| 758 | writel_relaxed(regval, data->base + REG_MMU_WR_LEN_CTRL); | 989 | writel_relaxed(regval, bank0->base + REG_MMU_WR_LEN_CTRL); |
| 759 | } | 990 | } |
| 760 | 991 | ||
| 761 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, RESET_AXI)) { | 992 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, RESET_AXI)) { |
| 762 | /* The register is called STANDARD_AXI_MODE in this case */ | 993 | /* The register is called STANDARD_AXI_MODE in this case */ |
| 763 | regval = 0; | 994 | regval = 0; |
| 764 | } else { | 995 | } else { |
| 765 | regval = readl_relaxed(data->base + REG_MMU_MISC_CTRL); | 996 | regval = readl_relaxed(bank0->base + REG_MMU_MISC_CTRL); |
| 766 | regval &= ~F_MMU_STANDARD_AXI_MODE_MASK; | 997 | if (!MTK_IOMMU_HAS_FLAG(data->plat_data, STD_AXI_MODE)) |
| 998 | regval &= ~F_MMU_STANDARD_AXI_MODE_MASK; | ||
| 767 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, OUT_ORDER_WR_EN)) | 999 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, OUT_ORDER_WR_EN)) |
| 768 | regval &= ~F_MMU_IN_ORDER_WR_EN_MASK; | 1000 | regval &= ~F_MMU_IN_ORDER_WR_EN_MASK; |
| 769 | } | 1001 | } |
| 770 | writel_relaxed(regval, data->base + REG_MMU_MISC_CTRL); | 1002 | writel_relaxed(regval, bank0->base + REG_MMU_MISC_CTRL); |
| 771 | 1003 | ||
| 772 | if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0, | 1004 | /* Independent settings for each bank */ |
| 773 | dev_name(data->dev), (void *)data)) { | 1005 | regval = F_L2_MULIT_HIT_EN | |
| 774 | writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); | 1006 | F_TABLE_WALK_FAULT_INT_EN | |
| 775 | dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq); | 1007 | F_PREETCH_FIFO_OVERFLOW_INT_EN | |
| 1008 | F_MISS_FIFO_OVERFLOW_INT_EN | | ||
| 1009 | F_PREFETCH_FIFO_ERR_INT_EN | | ||
| 1010 | F_MISS_FIFO_ERR_INT_EN; | ||
| 1011 | writel_relaxed(regval, bankx->base + REG_MMU_INT_CONTROL0); | ||
| 1012 | |||
| 1013 | regval = F_INT_TRANSLATION_FAULT | | ||
| 1014 | F_INT_MAIN_MULTI_HIT_FAULT | | ||
| 1015 | F_INT_INVALID_PA_FAULT | | ||
| 1016 | F_INT_ENTRY_REPLACEMENT_FAULT | | ||
| 1017 | F_INT_TLB_MISS_FAULT | | ||
| 1018 | F_INT_MISS_TRANSACTION_FIFO_FAULT | | ||
| 1019 | F_INT_PRETETCH_TRANSATION_FIFO_FAULT; | ||
| 1020 | writel_relaxed(regval, bankx->base + REG_MMU_INT_MAIN_CONTROL); | ||
| 1021 | |||
| 1022 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR)) | ||
| 1023 | regval = (data->protect_base >> 1) | (data->enable_4GB << 31); | ||
| 1024 | else | ||
| 1025 | regval = lower_32_bits(data->protect_base) | | ||
| 1026 | upper_32_bits(data->protect_base); | ||
| 1027 | writel_relaxed(regval, bankx->base + REG_MMU_IVRP_PADDR); | ||
| 1028 | |||
| 1029 | if (devm_request_irq(bankx->parent_dev, bankx->irq, mtk_iommu_isr, 0, | ||
| 1030 | dev_name(bankx->parent_dev), (void *)bankx)) { | ||
| 1031 | writel_relaxed(0, bankx->base + REG_MMU_PT_BASE_ADDR); | ||
| 1032 | dev_err(bankx->parent_dev, "Failed @ IRQ-%d Request\n", bankx->irq); | ||
| 776 | return -ENODEV; | 1033 | return -ENODEV; |
| 777 | } | 1034 | } |
| 778 | 1035 | ||
| @@ -784,21 +1041,91 @@ static const struct component_master_ops mtk_iommu_com_ops = { · 5 unmodified lines | |||
| 784 | .unbind = mtk_iommu_unbind, | 1041 | .unbind = mtk_iommu_unbind, |
| 785 | }; | 1042 | }; |
| 786 | 1043 | ||
| 1044 | static int mtk_iommu_mm_dts_parse(struct device *dev, struct component_match **match, | ||
| 1045 | struct mtk_iommu_data *data) | ||
| 1046 | { | ||
| 1047 | struct device_node *larbnode, *smicomm_node, *smi_subcomm_node; | ||
| 1048 | struct platform_device *plarbdev; | ||
| 1049 | struct device_link *link; | ||
| 1050 | int i, larb_nr, ret; | ||
| 1051 | |||
| 1052 | larb_nr = of_count_phandle_with_args(dev->of_node, "mediatek,larbs", NULL); | ||
| 1053 | if (larb_nr < 0) | ||
| 1054 | return larb_nr; | ||
| 1055 | |||
| 1056 | for (i = 0; i < larb_nr; i++) { | ||
| 1057 | u32 id; | ||
| 1058 | |||
| 1059 | larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i); | ||
| 1060 | if (!larbnode) | ||
| 1061 | return -EINVAL; | ||
| 1062 | |||
| 1063 | if (!of_device_is_available(larbnode)) { | ||
| 1064 | of_node_put(larbnode); | ||
| 1065 | continue; | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id); | ||
| 1069 | if (ret)/* The id is consecutive if there is no this property */ | ||
| 1070 | id = i; | ||
| 1071 | |||
| 1072 | plarbdev = of_find_device_by_node(larbnode); | ||
| 1073 | if (!plarbdev) { | ||
| 1074 | of_node_put(larbnode); | ||
| 1075 | return -ENODEV; | ||
| 1076 | } | ||
| 1077 | if (!plarbdev->dev.driver) { | ||
| 1078 | of_node_put(larbnode); | ||
| 1079 | return -EPROBE_DEFER; | ||
| 1080 | } | ||
| 1081 | data->larb_imu[id].dev = &plarbdev->dev; | ||
| 1082 | |||
| 1083 | component_match_add_release(dev, match, component_release_of, | ||
| 1084 | component_compare_of, larbnode); | ||
| 1085 | } | ||
| 1086 | |||
| 1087 | /* Get smi-(sub)-common dev from the last larb. */ | ||
| 1088 | smi_subcomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0); | ||
| 1089 | if (!smi_subcomm_node) | ||
| 1090 | return -EINVAL; | ||
| 1091 | |||
| 1092 | /* | ||
| 1093 | * It may have two level smi-common. the node is smi-sub-common if it | ||
| 1094 | * has a new mediatek,smi property. otherwise it is smi-commmon. | ||
| 1095 | */ | ||
| 1096 | smicomm_node = of_parse_phandle(smi_subcomm_node, "mediatek,smi", 0); | ||
| 1097 | if (smicomm_node) | ||
| 1098 | of_node_put(smi_subcomm_node); | ||
| 1099 | else | ||
| 1100 | smicomm_node = smi_subcomm_node; | ||
| 1101 | |||
| 1102 | plarbdev = of_find_device_by_node(smicomm_node); | ||
| 1103 | of_node_put(smicomm_node); | ||
| 1104 | data->smicomm_dev = &plarbdev->dev; | ||
| 1105 | |||
| 1106 | link = device_link_add(data->smicomm_dev, dev, | ||
| 1107 | DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME); | ||
| 1108 | if (!link) { | ||
| 1109 | dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev)); | ||
| 1110 | return -EINVAL; | ||
| 1111 | } | ||
| 1112 | return 0; | ||
| 1113 | } | ||
| 1114 | |||
| 787 | static int mtk_iommu_probe(struct platform_device *pdev) | 1115 | static int mtk_iommu_probe(struct platform_device *pdev) |
| 788 | { | 1116 | { |
| 789 | struct mtk_iommu_data *data; | 1117 | struct mtk_iommu_data *data; |
| 790 | struct device *dev = &pdev->dev; | 1118 | struct device *dev = &pdev->dev; |
| 791 | struct device_node *larbnode, *smicomm_node; | ||
| 792 | struct platform_device *plarbdev; | ||
| 793 | struct device_link *link; | ||
| 794 | struct resource *res; | 1119 | struct resource *res; |
| 795 | resource_size_t ioaddr; | 1120 | resource_size_t ioaddr; |
| 796 | struct component_match *match = NULL; | 1121 | struct component_match *match = NULL; |
| 797 | struct regmap *infracfg; | 1122 | struct regmap *infracfg; |
| 798 | void *protect; | 1123 | void *protect; |
| 799 | int i, larb_nr, ret; | 1124 | int ret, banks_num, i = 0; |
| 800 | u32 val; | 1125 | u32 val; |
| 801 | char *p; | 1126 | char *p; |
| 1127 | struct mtk_iommu_bank_data *bank; | ||
| 1128 | void __iomem *base; | ||
| 802 | 1129 | ||
| 803 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); | 1130 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); |
| 804 | if (!data) | 1131 | if (!data) |
| @@ -835,15 +1162,36 @@ static int mtk_iommu_probe(struct platform_device *pdev) · 30 unmodified lines | |||
| 835 | data->enable_4GB = !!(val & F_DDR_4GB_SUPPORT_EN); | 1162 | data->enable_4GB = !!(val & F_DDR_4GB_SUPPORT_EN); |
| 836 | } | 1163 | } |
| 837 | 1164 | ||
| 1165 | banks_num = data->plat_data->banks_num; | ||
| 838 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1166 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 839 | data->base = devm_ioremap_resource(dev, res); | 1167 | if (resource_size(res) < banks_num * MTK_IOMMU_BANK_SZ) { |
| 840 | if (IS_ERR(data->base)) | 1168 | dev_err(dev, "banknr %d. res %pR is not enough.\n", banks_num, res); |
| 841 | return PTR_ERR(data->base); | 1169 | return -EINVAL; |
| 1170 | } | ||
| 1171 | base = devm_ioremap_resource(dev, res); | ||
| 1172 | if (IS_ERR(base)) | ||
| 1173 | return PTR_ERR(base); | ||
| 842 | ioaddr = res->start; | 1174 | ioaddr = res->start; |
| 843 | 1175 | ||
| 844 | data->irq = platform_get_irq(pdev, 0); | 1176 | data->bank = devm_kmalloc(dev, banks_num * sizeof(*data->bank), GFP_KERNEL); |
| 845 | if (data->irq < 0) | 1177 | if (!data->bank) |
| 846 | return data->irq; | 1178 | return -ENOMEM; |
| 1179 | |||
| 1180 | do { | ||
| 1181 | if (!data->plat_data->banks_enable[i]) | ||
| 1182 | continue; | ||
| 1183 | bank = &data->bank[i]; | ||
| 1184 | bank->id = i; | ||
| 1185 | bank->base = base + i * MTK_IOMMU_BANK_SZ; | ||
| 1186 | bank->m4u_dom = NULL; | ||
| 1187 | |||
| 1188 | bank->irq = platform_get_irq(pdev, i); | ||
| 1189 | if (bank->irq < 0) | ||
| 1190 | return bank->irq; | ||
| 1191 | bank->parent_dev = dev; | ||
| 1192 | bank->parent_data = data; | ||
| 1193 | spin_lock_init(&bank->tlb_lock); | ||
| 1194 | } while (++i < banks_num); | ||
| 847 | 1195 | ||
| 848 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_BCLK)) { | 1196 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_BCLK)) { |
| 849 | data->bclk = devm_clk_get(dev, "bclk"); | 1197 | data->bclk = devm_clk_get(dev, "bclk"); |
| @@ -851,62 +1199,27 @@ static int mtk_iommu_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 851 | return PTR_ERR(data->bclk); | 1199 | return PTR_ERR(data->bclk); |
| 852 | } | 1200 | } |
| 853 | 1201 | ||
| 854 | larb_nr = of_count_phandle_with_args(dev->of_node, | 1202 | pm_runtime_enable(dev); |
| 855 | "mediatek,larbs", NULL); | ||
| 856 | if (larb_nr < 0) | ||
| 857 | return larb_nr; | ||
| 858 | |||
| 859 | for (i = 0; i < larb_nr; i++) { | ||
| 860 | u32 id; | ||
| 861 | |||
| 862 | larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i); | ||
| 863 | if (!larbnode) | ||
| 864 | return -EINVAL; | ||
| 865 | |||
| 866 | if (!of_device_is_available(larbnode)) { | ||
| 867 | of_node_put(larbnode); | ||
| 868 | continue; | ||
| 869 | } | ||
| 870 | |||
| 871 | ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id); | ||
| 872 | if (ret)/* The id is consecutive if there is no this property */ | ||
| 873 | id = i; | ||
| 874 | 1203 | ||
| 875 | plarbdev = of_find_device_by_node(larbnode); | 1204 | if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) { |
| 876 | if (!plarbdev) { | 1205 | ret = mtk_iommu_mm_dts_parse(dev, &match, data); |
| 877 | of_node_put(larbnode); | 1206 | if (ret) { |
| 878 | return -ENODEV; | 1207 | dev_err(dev, "mm dts parse fail(%d).", ret); |
| 1208 | goto out_runtime_disable; | ||
| 879 | } | 1209 | } |
| 880 | if (!plarbdev->dev.driver) { | 1210 | } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) && |
| 881 | of_node_put(larbnode); | 1211 | data->plat_data->pericfg_comp_str) { |
| 882 | return -EPROBE_DEFER; | 1212 | infracfg = syscon_regmap_lookup_by_compatible(data->plat_data->pericfg_comp_str); |
| 1213 | if (IS_ERR(infracfg)) { | ||
| 1214 | ret = PTR_ERR(infracfg); | ||
| 1215 | goto out_runtime_disable; | ||
| 883 | } | 1216 | } |
| 884 | data->larb_imu[id].dev = &plarbdev->dev; | ||
| 885 | |||
| 886 | component_match_add_release(dev, &match, component_release_of, | ||
| 887 | component_compare_of, larbnode); | ||
| 888 | } | ||
| 889 | |||
| 890 | /* Get smi-common dev from the last larb. */ | ||
| 891 | smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0); | ||
| 892 | if (!smicomm_node) | ||
| 893 | return -EINVAL; | ||
| 894 | |||
| 895 | plarbdev = of_find_device_by_node(smicomm_node); | ||
| 896 | of_node_put(smicomm_node); | ||
| 897 | data->smicomm_dev = &plarbdev->dev; | ||
| 898 | |||
| 899 | pm_runtime_enable(dev); | ||
| 900 | 1217 | ||
| 901 | link = device_link_add(data->smicomm_dev, dev, | 1218 | data->pericfg = infracfg; |
| 902 | DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME); | ||
| 903 | if (!link) { | ||
| 904 | dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev)); | ||
| 905 | ret = -EINVAL; | ||
| 906 | goto out_runtime_disable; | ||
| 907 | } | 1219 | } |
| 908 | 1220 | ||
| 909 | platform_set_drvdata(pdev, data); | 1221 | platform_set_drvdata(pdev, data); |
| 1222 | mutex_init(&data->mutex); | ||
| 910 | 1223 | ||
| 911 | ret = iommu_device_sysfs_add(&data->iommu, dev, NULL, | 1224 | ret = iommu_device_sysfs_add(&data->iommu, dev, NULL, |
| 912 | "mtk-iommu.%pa", &ioaddr); | 1225 | "mtk-iommu.%pa", &ioaddr); |
| @@ -917,8 +1230,14 @@ static int mtk_iommu_probe(struct platform_device *pdev) · 4 unmodified lines | |||
| 917 | if (ret) | 1230 | if (ret) |
| 918 | goto out_sysfs_remove; | 1231 | goto out_sysfs_remove; |
| 919 | 1232 | ||
| 920 | spin_lock_init(&data->tlb_lock); | 1233 | if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE)) { |
| 921 | list_add_tail(&data->list, &m4ulist); | 1234 | list_add_tail(&data->list, data->plat_data->hw_list); |
| 1235 | data->hw_list = data->plat_data->hw_list; | ||
| 1236 | } else { | ||
| 1237 | INIT_LIST_HEAD(&data->hw_list_head); | ||
| 1238 | list_add_tail(&data->list, &data->hw_list_head); | ||
| 1239 | data->hw_list = &data->hw_list_head; | ||
| 1240 | } | ||
| 922 | 1241 | ||
| 923 | if (!iommu_present(&platform_bus_type)) { | 1242 | if (!iommu_present(&platform_bus_type)) { |
| 924 | ret = bus_set_iommu(&platform_bus_type, &mtk_iommu_ops); | 1243 | ret = bus_set_iommu(&platform_bus_type, &mtk_iommu_ops); |
| @@ -926,9 +1245,20 @@ static int mtk_iommu_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 926 | goto out_list_del; | 1245 | goto out_list_del; |
| 927 | } | 1246 | } |
| 928 | 1247 | ||
| 929 | ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match); | 1248 | if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) { |
| 930 | if (ret) | 1249 | ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match); |
| 931 | goto out_bus_set_null; | 1250 | if (ret) |
| 1251 | goto out_bus_set_null; | ||
| 1252 | } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) && | ||
| 1253 | MTK_IOMMU_HAS_FLAG(data->plat_data, IFA_IOMMU_PCIE_SUPPORT)) { | ||
| 1254 | #ifdef CONFIG_PCI | ||
| 1255 | if (!iommu_present(&pci_bus_type)) { | ||
| 1256 | ret = bus_set_iommu(&pci_bus_type, &mtk_iommu_ops); | ||
| 1257 | if (ret) /* PCIe fail don't affect platform_bus. */ | ||
| 1258 | goto out_list_del; | ||
| 1259 | } | ||
| 1260 | #endif | ||
| 1261 | } | ||
| 932 | return ret; | 1262 | return ret; |
| 933 | 1263 | ||
| 934 | out_bus_set_null: | 1264 | out_bus_set_null: |
| @@ -939,7 +1269,8 @@ out_list_del: · 4 unmodified lines | |||
| 939 | out_sysfs_remove: | 1269 | out_sysfs_remove: |
| 940 | iommu_device_sysfs_remove(&data->iommu); | 1270 | iommu_device_sysfs_remove(&data->iommu); |
| 941 | out_link_remove: | 1271 | out_link_remove: |
| 942 | device_link_remove(data->smicomm_dev, dev); | 1272 | if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) |
| 1273 | device_link_remove(data->smicomm_dev, dev); | ||
| 943 | out_runtime_disable: | 1274 | out_runtime_disable: |
| 944 | pm_runtime_disable(dev); | 1275 | pm_runtime_disable(dev); |
| 945 | return ret; | 1276 | return ret; |
| @@ -948,18 +1279,30 @@ out_runtime_disable: · 2 unmodified lines | |||
| 948 | static int mtk_iommu_remove(struct platform_device *pdev) | 1279 | static int mtk_iommu_remove(struct platform_device *pdev) |
| 949 | { | 1280 | { |
| 950 | struct mtk_iommu_data *data = platform_get_drvdata(pdev); | 1281 | struct mtk_iommu_data *data = platform_get_drvdata(pdev); |
| 1282 | struct mtk_iommu_bank_data *bank; | ||
| 1283 | int i; | ||
| 951 | 1284 | ||
| 952 | iommu_device_sysfs_remove(&data->iommu); | 1285 | iommu_device_sysfs_remove(&data->iommu); |
| 953 | iommu_device_unregister(&data->iommu); | 1286 | iommu_device_unregister(&data->iommu); |
| 954 | 1287 | ||
| 955 | if (iommu_present(&platform_bus_type)) | 1288 | list_del(&data->list); |
| 956 | bus_set_iommu(&platform_bus_type, NULL); | ||
| 957 | 1289 | ||
| 958 | clk_disable_unprepare(data->bclk); | 1290 | if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) { |
| 959 | device_link_remove(data->smicomm_dev, &pdev->dev); | 1291 | device_link_remove(data->smicomm_dev, &pdev->dev); |
| 1292 | component_master_del(&pdev->dev, &mtk_iommu_com_ops); | ||
| 1293 | } else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) && | ||
| 1294 | MTK_IOMMU_HAS_FLAG(data->plat_data, IFA_IOMMU_PCIE_SUPPORT)) { | ||
| 1295 | #ifdef CONFIG_PCI | ||
| 1296 | bus_set_iommu(&pci_bus_type, NULL); | ||
| 1297 | #endif | ||
| 1298 | } | ||
| 960 | pm_runtime_disable(&pdev->dev); | 1299 | pm_runtime_disable(&pdev->dev); |
| 961 | devm_free_irq(&pdev->dev, data->irq, data); | 1300 | for (i = 0; i < data->plat_data->banks_num; i++) { |
| 962 | component_master_del(&pdev->dev, &mtk_iommu_com_ops); | 1301 | bank = &data->bank[i]; |
| 1302 | if (!bank->m4u_dom) | ||
| 1303 | continue; | ||
| 1304 | devm_free_irq(&pdev->dev, bank->irq, bank); | ||
| 1305 | } | ||
| 963 | return 0; | 1306 | return 0; |
| 964 | } | 1307 | } |
| 965 | 1308 | ||
| @@ -967,16 +1310,23 @@ static int __maybe_unused mtk_iommu_runtime_suspend(struct device *dev) · 1 unmodified line | |||
| 967 | { | 1310 | { |
| 968 | struct mtk_iommu_data *data = dev_get_drvdata(dev); | 1311 | struct mtk_iommu_data *data = dev_get_drvdata(dev); |
| 969 | struct mtk_iommu_suspend_reg *reg = &data->reg; | 1312 | struct mtk_iommu_suspend_reg *reg = &data->reg; |
| 970 | void __iomem *base = data->base; | 1313 | void __iomem *base; |
| 1314 | int i = 0; | ||
| 971 | 1315 | ||
| 1316 | base = data->bank[i].base; | ||
| 972 | reg->wr_len_ctrl = readl_relaxed(base + REG_MMU_WR_LEN_CTRL); | 1317 | reg->wr_len_ctrl = readl_relaxed(base + REG_MMU_WR_LEN_CTRL); |
| 973 | reg->misc_ctrl = readl_relaxed(base + REG_MMU_MISC_CTRL); | 1318 | reg->misc_ctrl = readl_relaxed(base + REG_MMU_MISC_CTRL); |
| 974 | reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM_DIS); | 1319 | reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM_DIS); |
| 975 | reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG); | 1320 | reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG); |
| 976 | reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL0); | ||
| 977 | reg->int_main_control = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL); | ||
| 978 | reg->ivrp_paddr = readl_relaxed(base + REG_MMU_IVRP_PADDR); | ||
| 979 | reg->vld_pa_rng = readl_relaxed(base + REG_MMU_VLD_PA_RNG); | 1321 | reg->vld_pa_rng = readl_relaxed(base + REG_MMU_VLD_PA_RNG); |
| 1322 | do { | ||
| 1323 | if (!data->plat_data->banks_enable[i]) | ||
| 1324 | continue; | ||
| 1325 | base = data->bank[i].base; | ||
| 1326 | reg->int_control[i] = readl_relaxed(base + REG_MMU_INT_CONTROL0); | ||
| 1327 | reg->int_main_control[i] = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL); | ||
| 1328 | reg->ivrp_paddr[i] = readl_relaxed(base + REG_MMU_IVRP_PADDR); | ||
| 1329 | } while (++i < data->plat_data->banks_num); | ||
| 980 | clk_disable_unprepare(data->bclk); | 1330 | clk_disable_unprepare(data->bclk); |
| 981 | return 0; | 1331 | return 0; |
| 982 | } | 1332 | } |
| @@ -985,9 +1335,9 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev) · 2 unmodified lines | |||
| 985 | { | 1335 | { |
| 986 | struct mtk_iommu_data *data = dev_get_drvdata(dev); | 1336 | struct mtk_iommu_data *data = dev_get_drvdata(dev); |
| 987 | struct mtk_iommu_suspend_reg *reg = &data->reg; | 1337 | struct mtk_iommu_suspend_reg *reg = &data->reg; |
| 988 | struct mtk_iommu_domain *m4u_dom = data->m4u_dom; | 1338 | struct mtk_iommu_domain *m4u_dom; |
| 989 | void __iomem *base = data->base; | 1339 | void __iomem *base; |
| 990 | int ret; | 1340 | int ret, i = 0; |
| 991 | 1341 | ||
| 992 | ret = clk_prepare_enable(data->bclk); | 1342 | ret = clk_prepare_enable(data->bclk); |
| 993 | if (ret) { | 1343 | if (ret) { |
| @@ -999,18 +1349,26 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev) · 5 unmodified lines | |||
| 999 | * Uppon first resume, only enable the clk and return, since the values of the | 1349 | * Uppon first resume, only enable the clk and return, since the values of the |
| 1000 | * registers are not yet set. | 1350 | * registers are not yet set. |
| 1001 | */ | 1351 | */ |
| 1002 | if (!m4u_dom) | 1352 | if (!reg->wr_len_ctrl) |
| 1003 | return 0; | 1353 | return 0; |
| 1004 | 1354 | ||
| 1355 | base = data->bank[i].base; | ||
| 1005 | writel_relaxed(reg->wr_len_ctrl, base + REG_MMU_WR_LEN_CTRL); | 1356 | writel_relaxed(reg->wr_len_ctrl, base + REG_MMU_WR_LEN_CTRL); |
| 1006 | writel_relaxed(reg->misc_ctrl, base + REG_MMU_MISC_CTRL); | 1357 | writel_relaxed(reg->misc_ctrl, base + REG_MMU_MISC_CTRL); |
| 1007 | writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM_DIS); | 1358 | writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM_DIS); |
| 1008 | writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG); | 1359 | writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG); |
| 1009 | writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0); | ||
| 1010 | writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL); | ||
| 1011 | writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR); | ||
| 1012 | writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG); | 1360 | writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG); |
| 1013 | writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, base + REG_MMU_PT_BASE_ADDR); | 1361 | do { |
| 1362 | m4u_dom = data->bank[i].m4u_dom; | ||
| 1363 | if (!data->plat_data->banks_enable[i] || !m4u_dom) | ||
| 1364 | continue; | ||
| 1365 | base = data->bank[i].base; | ||
| 1366 | writel_relaxed(reg->int_control[i], base + REG_MMU_INT_CONTROL0); | ||
| 1367 | writel_relaxed(reg->int_main_control[i], base + REG_MMU_INT_MAIN_CONTROL); | ||
| 1368 | writel_relaxed(reg->ivrp_paddr[i], base + REG_MMU_IVRP_PADDR); | ||
| 1369 | writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, | ||
| 1370 | base + REG_MMU_PT_BASE_ADDR); | ||
| 1371 | } while (++i < data->plat_data->banks_num); | ||
| 1014 | 1372 | ||
| 1015 | /* | 1373 | /* |
| 1016 | * Users may allocate dma buffer before they call pm_runtime_get, | 1374 | * Users may allocate dma buffer before they call pm_runtime_get, |
| @@ -1029,17 +1387,24 @@ static const struct dev_pm_ops mtk_iommu_pm_ops = { · 12 unmodified lines | |||
| 1029 | 1387 | ||
| 1030 | static const struct mtk_iommu_plat_data mt2712_data = { | 1388 | static const struct mtk_iommu_plat_data mt2712_data = { |
| 1031 | .m4u_plat = M4U_MT2712, | 1389 | .m4u_plat = M4U_MT2712, |
| 1032 | .flags = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG, | 1390 | .flags = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG | SHARE_PGTABLE | |
| 1391 | MTK_IOMMU_TYPE_MM, | ||
| 1392 | .hw_list = &m4ulist, | ||
| 1033 | .inv_sel_reg = REG_MMU_INV_SEL_GEN1, | 1393 | .inv_sel_reg = REG_MMU_INV_SEL_GEN1, |
| 1034 | .iova_region = single_domain, | 1394 | .iova_region = single_domain, |
| 1395 | .banks_num = 1, | ||
| 1396 | .banks_enable = {true}, | ||
| 1035 | .iova_region_nr = ARRAY_SIZE(single_domain), | 1397 | .iova_region_nr = ARRAY_SIZE(single_domain), |
| 1036 | .larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}, | 1398 | .larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}}, |
| 1037 | }; | 1399 | }; |
| 1038 | 1400 | ||
| 1039 | static const struct mtk_iommu_plat_data mt6779_data = { | 1401 | static const struct mtk_iommu_plat_data mt6779_data = { |
| 1040 | .m4u_plat = M4U_MT6779, | 1402 | .m4u_plat = M4U_MT6779, |
| 1041 | .flags = HAS_SUB_COMM | OUT_ORDER_WR_EN | WR_THROT_EN, | 1403 | .flags = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN | |
| 1404 | MTK_IOMMU_TYPE_MM, | ||
| 1042 | .inv_sel_reg = REG_MMU_INV_SEL_GEN2, | 1405 | .inv_sel_reg = REG_MMU_INV_SEL_GEN2, |
| 1406 | .banks_num = 1, | ||
| 1407 | .banks_enable = {true}, | ||
| 1043 | .iova_region = single_domain, | 1408 | .iova_region = single_domain, |
| 1044 | .iova_region_nr = ARRAY_SIZE(single_domain), | 1409 | .iova_region_nr = ARRAY_SIZE(single_domain), |
| 1045 | .larbid_remap = {{0}, {1}, {2}, {3}, {5}, {7, 8}, {10}, {9}}, | 1410 | .larbid_remap = {{0}, {1}, {2}, {3}, {5}, {7, 8}, {10}, {9}}, |
| @@ -1047,8 +1412,10 @@ static const struct mtk_iommu_plat_data mt6779_data = { · 1 unmodified line | |||
| 1047 | 1412 | ||
| 1048 | static const struct mtk_iommu_plat_data mt8167_data = { | 1413 | static const struct mtk_iommu_plat_data mt8167_data = { |
| 1049 | .m4u_plat = M4U_MT8167, | 1414 | .m4u_plat = M4U_MT8167, |
| 1050 | .flags = RESET_AXI | HAS_LEGACY_IVRP_PADDR, | 1415 | .flags = RESET_AXI | HAS_LEGACY_IVRP_PADDR | MTK_IOMMU_TYPE_MM, |
| 1051 | .inv_sel_reg = REG_MMU_INV_SEL_GEN1, | 1416 | .inv_sel_reg = REG_MMU_INV_SEL_GEN1, |
| 1417 | .banks_num = 1, | ||
| 1418 | .banks_enable = {true}, | ||
| 1052 | .iova_region = single_domain, | 1419 | .iova_region = single_domain, |
| 1053 | .iova_region_nr = ARRAY_SIZE(single_domain), | 1420 | .iova_region_nr = ARRAY_SIZE(single_domain), |
| 1054 | .larbid_remap = {{0}, {1}, {2}}, /* Linear mapping. */ | 1421 | .larbid_remap = {{0}, {1}, {2}}, /* Linear mapping. */ |
| @@ -1057,8 +1424,10 @@ static const struct mtk_iommu_plat_data mt8167_data = { · 2 unmodified lines | |||
| 1057 | static const struct mtk_iommu_plat_data mt8173_data = { | 1424 | static const struct mtk_iommu_plat_data mt8173_data = { |
| 1058 | .m4u_plat = M4U_MT8173, | 1425 | .m4u_plat = M4U_MT8173, |
| 1059 | .flags = HAS_4GB_MODE | HAS_BCLK | RESET_AXI | | 1426 | .flags = HAS_4GB_MODE | HAS_BCLK | RESET_AXI | |
| 1060 | HAS_LEGACY_IVRP_PADDR, | 1427 | HAS_LEGACY_IVRP_PADDR | MTK_IOMMU_TYPE_MM, |
| 1061 | .inv_sel_reg = REG_MMU_INV_SEL_GEN1, | 1428 | .inv_sel_reg = REG_MMU_INV_SEL_GEN1, |
| 1429 | .banks_num = 1, | ||
| 1430 | .banks_enable = {true}, | ||
| 1062 | .iova_region = single_domain, | 1431 | .iova_region = single_domain, |
| 1063 | .iova_region_nr = ARRAY_SIZE(single_domain), | 1432 | .iova_region_nr = ARRAY_SIZE(single_domain), |
| 1064 | .larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}}, /* Linear mapping. */ | 1433 | .larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}}, /* Linear mapping. */ |
| @@ -1066,31 +1435,100 @@ static const struct mtk_iommu_plat_data mt8173_data = { · 1 unmodified line | |||
| 1066 | 1435 | ||
| 1067 | static const struct mtk_iommu_plat_data mt8183_data = { | 1436 | static const struct mtk_iommu_plat_data mt8183_data = { |
| 1068 | .m4u_plat = M4U_MT8183, | 1437 | .m4u_plat = M4U_MT8183, |
| 1069 | .flags = RESET_AXI, | 1438 | .flags = RESET_AXI | MTK_IOMMU_TYPE_MM, |
| 1070 | .inv_sel_reg = REG_MMU_INV_SEL_GEN1, | 1439 | .inv_sel_reg = REG_MMU_INV_SEL_GEN1, |
| 1440 | .banks_num = 1, | ||
| 1441 | .banks_enable = {true}, | ||
| 1071 | .iova_region = single_domain, | 1442 | .iova_region = single_domain, |
| 1072 | .iova_region_nr = ARRAY_SIZE(single_domain), | 1443 | .iova_region_nr = ARRAY_SIZE(single_domain), |
| 1073 | .larbid_remap = {{0}, {4}, {5}, {6}, {7}, {2}, {3}, {1}}, | 1444 | .larbid_remap = {{0}, {4}, {5}, {6}, {7}, {2}, {3}, {1}}, |
| 1074 | }; | 1445 | }; |
| 1075 | 1446 | ||
| 1447 | static const struct mtk_iommu_plat_data mt8186_data_mm = { | ||
| 1448 | .m4u_plat = M4U_MT8186, | ||
| 1449 | .flags = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | | ||
| 1450 | WR_THROT_EN | IOVA_34_EN | MTK_IOMMU_TYPE_MM, | ||
| 1451 | .larbid_remap = {{0}, {1, MTK_INVALID_LARBID, 8}, {4}, {7}, {2}, {9, 11, 19, 20}, | ||
| 1452 | {MTK_INVALID_LARBID, 14, 16}, | ||
| 1453 | {MTK_INVALID_LARBID, 13, MTK_INVALID_LARBID, 17}}, | ||
| 1454 | .inv_sel_reg = REG_MMU_INV_SEL_GEN2, | ||
| 1455 | .banks_num = 1, | ||
| 1456 | .banks_enable = {true}, | ||
| 1457 | .iova_region = mt8192_multi_dom, | ||
| 1458 | .iova_region_nr = ARRAY_SIZE(mt8192_multi_dom), | ||
| 1459 | }; | ||
| 1460 | |||
| 1076 | static const struct mtk_iommu_plat_data mt8192_data = { | 1461 | static const struct mtk_iommu_plat_data mt8192_data = { |
| 1077 | .m4u_plat = M4U_MT8192, | 1462 | .m4u_plat = M4U_MT8192, |
| 1078 | .flags = HAS_BCLK | HAS_SUB_COMM | OUT_ORDER_WR_EN | | 1463 | .flags = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | |
| 1079 | WR_THROT_EN | IOVA_34_EN, | 1464 | WR_THROT_EN | IOVA_34_EN | MTK_IOMMU_TYPE_MM, |
| 1080 | .inv_sel_reg = REG_MMU_INV_SEL_GEN2, | 1465 | .inv_sel_reg = REG_MMU_INV_SEL_GEN2, |
| 1466 | .banks_num = 1, | ||
| 1467 | .banks_enable = {true}, | ||
| 1081 | .iova_region = mt8192_multi_dom, | 1468 | .iova_region = mt8192_multi_dom, |
| 1082 | .iova_region_nr = ARRAY_SIZE(mt8192_multi_dom), | 1469 | .iova_region_nr = ARRAY_SIZE(mt8192_multi_dom), |
| 1083 | .larbid_remap = {{0}, {1}, {4, 5}, {7}, {2}, {9, 11, 19, 20}, | 1470 | .larbid_remap = {{0}, {1}, {4, 5}, {7}, {2}, {9, 11, 19, 20}, |
| 1084 | {0, 14, 16}, {0, 13, 18, 17}}, | 1471 | {0, 14, 16}, {0, 13, 18, 17}}, |
| 1085 | }; | 1472 | }; |
| 1086 | 1473 | ||
| 1474 | static const struct mtk_iommu_plat_data mt8195_data_infra = { | ||
| 1475 | .m4u_plat = M4U_MT8195, | ||
| 1476 | .flags = WR_THROT_EN | DCM_DISABLE | STD_AXI_MODE | PM_CLK_AO | | ||
| 1477 | MTK_IOMMU_TYPE_INFRA | IFA_IOMMU_PCIE_SUPPORT, | ||
| 1478 | .pericfg_comp_str = "mediatek,mt8195-pericfg_ao", | ||
| 1479 | .inv_sel_reg = REG_MMU_INV_SEL_GEN2, | ||
| 1480 | .banks_num = 5, | ||
| 1481 | .banks_enable = {true, false, false, false, true}, | ||
| 1482 | .banks_portmsk = {[0] = GENMASK(19, 16), /* PCIe */ | ||
| 1483 | [4] = GENMASK(31, 20), /* USB */ | ||
| 1484 | }, | ||
| 1485 | .iova_region = single_domain, | ||
| 1486 | .iova_region_nr = ARRAY_SIZE(single_domain), | ||
| 1487 | }; | ||
| 1488 | |||
| 1489 | static const struct mtk_iommu_plat_data mt8195_data_vdo = { | ||
| 1490 | .m4u_plat = M4U_MT8195, | ||
| 1491 | .flags = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | | ||
| 1492 | WR_THROT_EN | IOVA_34_EN | SHARE_PGTABLE | MTK_IOMMU_TYPE_MM, | ||
| 1493 | .hw_list = &m4ulist, | ||
| 1494 | .inv_sel_reg = REG_MMU_INV_SEL_GEN2, | ||
| 1495 | .banks_num = 1, | ||
| 1496 | .banks_enable = {true}, | ||
| 1497 | .iova_region = mt8192_multi_dom, | ||
| 1498 | .iova_region_nr = ARRAY_SIZE(mt8192_multi_dom), | ||
| 1499 | .larbid_remap = {{2, 0}, {21}, {24}, {7}, {19}, {9, 10, 11}, | ||
| 1500 | {13, 17, 15/* 17b */, 25}, {5}}, | ||
| 1501 | }; | ||
| 1502 | |||
| 1503 | static const struct mtk_iommu_plat_data mt8195_data_vpp = { | ||
| 1504 | .m4u_plat = M4U_MT8195, | ||
| 1505 | .flags = HAS_BCLK | HAS_SUB_COMM_3BITS | OUT_ORDER_WR_EN | | ||
| 1506 | WR_THROT_EN | IOVA_34_EN | SHARE_PGTABLE | MTK_IOMMU_TYPE_MM, | ||
| 1507 | .hw_list = &m4ulist, | ||
| 1508 | .inv_sel_reg = REG_MMU_INV_SEL_GEN2, | ||
| 1509 | .banks_num = 1, | ||
| 1510 | .banks_enable = {true}, | ||
| 1511 | .iova_region = mt8192_multi_dom, | ||
| 1512 | .iova_region_nr = ARRAY_SIZE(mt8192_multi_dom), | ||
| 1513 | .larbid_remap = {{1}, {3}, | ||
| 1514 | {22, MTK_INVALID_LARBID, MTK_INVALID_LARBID, MTK_INVALID_LARBID, 23}, | ||
| 1515 | {8}, {20}, {12}, | ||
| 1516 | /* 16: 16a; 29: 16b; 30: CCUtop0; 31: CCUtop1 */ | ||
| 1517 | {14, 16, 29, 26, 30, 31, 18}, | ||
| 1518 | {4, MTK_INVALID_LARBID, MTK_INVALID_LARBID, MTK_INVALID_LARBID, 6}}, | ||
| 1519 | }; | ||
| 1520 | |||
| 1087 | static const struct of_device_id mtk_iommu_of_ids[] = { | 1521 | static const struct of_device_id mtk_iommu_of_ids[] = { |
| 1088 | { .compatible = "mediatek,mt2712-m4u", .data = &mt2712_data}, | 1522 | { .compatible = "mediatek,mt2712-m4u", .data = &mt2712_data}, |
| 1089 | { .compatible = "mediatek,mt6779-m4u", .data = &mt6779_data}, | 1523 | { .compatible = "mediatek,mt6779-m4u", .data = &mt6779_data}, |
| 1090 | { .compatible = "mediatek,mt8167-m4u", .data = &mt8167_data}, | 1524 | { .compatible = "mediatek,mt8167-m4u", .data = &mt8167_data}, |
| 1091 | { .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data}, | 1525 | { .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data}, |
| 1092 | { .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data}, | 1526 | { .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data}, |
| 1527 | { .compatible = "mediatek,mt8186-iommu-mm", .data = &mt8186_data_mm}, /* mm: m4u */ | ||
| 1093 | { .compatible = "mediatek,mt8192-m4u", .data = &mt8192_data}, | 1528 | { .compatible = "mediatek,mt8192-m4u", .data = &mt8192_data}, |
| 1529 | { .compatible = "mediatek,mt8195-iommu-infra", .data = &mt8195_data_infra}, | ||
| 1530 | { .compatible = "mediatek,mt8195-iommu-vdo", .data = &mt8195_data_vdo}, | ||
| 1531 | { .compatible = "mediatek,mt8195-iommu-vpp", .data = &mt8195_data_vpp}, | ||
| 1094 | {} | 1532 | {} |
| 1095 | }; | 1533 | }; |
| 1096 | 1534 | ||
| @@ -1,101 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2015-2016 MediaTek Inc. | ||
| 4 | * Author: Honghui Zhang <honghui.zhang@mediatek.com> | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef _MTK_IOMMU_H_ | ||
| 8 | #define _MTK_IOMMU_H_ | ||
| 9 | |||
| 10 | #include <linux/clk.h> | ||
| 11 | #include <linux/component.h> | ||
| 12 | #include <linux/device.h> | ||
| 13 | #include <linux/io.h> | ||
| 14 | #include <linux/io-pgtable.h> | ||
| 15 | #include <linux/iommu.h> | ||
| 16 | #include <linux/list.h> | ||
| 17 | #include <linux/spinlock.h> | ||
| 18 | #include <linux/dma-mapping.h> | ||
| 19 | #include <soc/mediatek/smi.h> | ||
| 20 | #include <dt-bindings/memory/mtk-memory-port.h> | ||
| 21 | |||
| 22 | #define MTK_LARB_COM_MAX 8 | ||
| 23 | #define MTK_LARB_SUBCOM_MAX 4 | ||
| 24 | |||
| 25 | #define MTK_IOMMU_GROUP_MAX 8 | ||
| 26 | |||
| 27 | struct mtk_iommu_suspend_reg { | ||
| 28 | union { | ||
| 29 | u32 standard_axi_mode;/* v1 */ | ||
| 30 | u32 misc_ctrl;/* v2 */ | ||
| 31 | }; | ||
| 32 | u32 dcm_dis; | ||
| 33 | u32 ctrl_reg; | ||
| 34 | u32 int_control0; | ||
| 35 | u32 int_main_control; | ||
| 36 | u32 ivrp_paddr; | ||
| 37 | u32 vld_pa_rng; | ||
| 38 | u32 wr_len_ctrl; | ||
| 39 | }; | ||
| 40 | |||
| 41 | enum mtk_iommu_plat { | ||
| 42 | M4U_MT2701, | ||
| 43 | M4U_MT2712, | ||
| 44 | M4U_MT6779, | ||
| 45 | M4U_MT8167, | ||
| 46 | M4U_MT8173, | ||
| 47 | M4U_MT8183, | ||
| 48 | M4U_MT8192, | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct mtk_iommu_iova_region; | ||
| 52 | |||
| 53 | struct mtk_iommu_plat_data { | ||
| 54 | enum mtk_iommu_plat m4u_plat; | ||
| 55 | u32 flags; | ||
| 56 | u32 inv_sel_reg; | ||
| 57 | |||
| 58 | unsigned int iova_region_nr; | ||
| 59 | const struct mtk_iommu_iova_region *iova_region; | ||
| 60 | unsigned char larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX]; | ||
| 61 | }; | ||
| 62 | |||
| 63 | struct mtk_iommu_domain; | ||
| 64 | |||
| 65 | struct mtk_iommu_data { | ||
| 66 | void __iomem *base; | ||
| 67 | int irq; | ||
| 68 | struct device *dev; | ||
| 69 | struct clk *bclk; | ||
| 70 | phys_addr_t protect_base; /* protect memory base */ | ||
| 71 | struct mtk_iommu_suspend_reg reg; | ||
| 72 | struct mtk_iommu_domain *m4u_dom; | ||
| 73 | struct iommu_group *m4u_group[MTK_IOMMU_GROUP_MAX]; | ||
| 74 | bool enable_4GB; | ||
| 75 | spinlock_t tlb_lock; /* lock for tlb range flush */ | ||
| 76 | |||
| 77 | struct iommu_device iommu; | ||
| 78 | const struct mtk_iommu_plat_data *plat_data; | ||
| 79 | struct device *smicomm_dev; | ||
| 80 | |||
| 81 | struct dma_iommu_mapping *mapping; /* For mtk_iommu_v1.c */ | ||
| 82 | |||
| 83 | struct list_head list; | ||
| 84 | struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX]; | ||
| 85 | }; | ||
| 86 | |||
| 87 | static inline int mtk_iommu_bind(struct device *dev) | ||
| 88 | { | ||
| 89 | struct mtk_iommu_data *data = dev_get_drvdata(dev); | ||
| 90 | |||
| 91 | return component_bind_all(dev, &data->larb_imu); | ||
| 92 | } | ||
| 93 | |||
| 94 | static inline void mtk_iommu_unbind(struct device *dev) | ||
| 95 | { | ||
| 96 | struct mtk_iommu_data *data = dev_get_drvdata(dev); | ||
| 97 | |||
| 98 | component_unbind_all(dev, &data->larb_imu); | ||
| 99 | } | ||
| 100 | |||
| 101 | #endif | ||
| @@ -7,7 +7,6 @@ · 6 unmodified lines | |||
| 7 | * | 7 | * |
| 8 | * Based on driver/iommu/mtk_iommu.c | 8 | * Based on driver/iommu/mtk_iommu.c |
| 9 | */ | 9 | */ |
| 10 | #include <linux/memblock.h> | ||
| 11 | #include <linux/bug.h> | 10 | #include <linux/bug.h> |
| 12 | #include <linux/clk.h> | 11 | #include <linux/clk.h> |
| 13 | #include <linux/component.h> | 12 | #include <linux/component.h> |
| @@ -28,10 +27,9 @@ · 14 unmodified lines | |||
| 28 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
| 29 | #include <asm/barrier.h> | 28 | #include <asm/barrier.h> |
| 30 | #include <asm/dma-iommu.h> | 29 | #include <asm/dma-iommu.h> |
| 31 | #include <linux/init.h> | 30 | #include <dt-bindings/memory/mtk-memory-port.h> |
| 32 | #include <dt-bindings/memory/mt2701-larb-port.h> | 31 | #include <dt-bindings/memory/mt2701-larb-port.h> |
| 33 | #include <soc/mediatek/smi.h> | 32 | #include <soc/mediatek/smi.h> |
| 34 | #include "mtk_iommu.h" | ||
| 35 | 33 | ||
| 36 | #define REG_MMU_PT_BASE_ADDR 0x000 | 34 | #define REG_MMU_PT_BASE_ADDR 0x000 |
| 37 | 35 | ||
| @@ -80,6 +78,7 @@ · 42 unmodified lines | |||
| 80 | /* MTK generation one iommu HW only support 4K size mapping */ | 78 | /* MTK generation one iommu HW only support 4K size mapping */ |
| 81 | #define MT2701_IOMMU_PAGE_SHIFT 12 | 79 | #define MT2701_IOMMU_PAGE_SHIFT 12 |
| 82 | #define MT2701_IOMMU_PAGE_SIZE (1UL << MT2701_IOMMU_PAGE_SHIFT) | 80 | #define MT2701_IOMMU_PAGE_SIZE (1UL << MT2701_IOMMU_PAGE_SHIFT) |
| 81 | #define MT2701_LARB_NR_MAX 3 | ||
| 83 | 82 | ||
| 84 | /* | 83 | /* |
| 85 | * MTK m4u support 4GB iova address space, and only support 4K page | 84 | * MTK m4u support 4GB iova address space, and only support 4K page |
| @@ -87,17 +86,53 @@ · 1 unmodified line | |||
| 87 | */ | 86 | */ |
| 88 | #define M2701_IOMMU_PGT_SIZE SZ_4M | 87 | #define M2701_IOMMU_PGT_SIZE SZ_4M |
| 89 | 88 | ||
| 90 | struct mtk_iommu_domain { | 89 | struct mtk_iommu_v1_suspend_reg { |
| 90 | u32 standard_axi_mode; | ||
| 91 | u32 dcm_dis; | ||
| 92 | u32 ctrl_reg; | ||
| 93 | u32 int_control0; | ||
| 94 | }; | ||
| 95 | |||
| 96 | struct mtk_iommu_v1_data { | ||
| 97 | void __iomem *base; | ||
| 98 | int irq; | ||
| 99 | struct device *dev; | ||
| 100 | struct clk *bclk; | ||
| 101 | phys_addr_t protect_base; /* protect memory base */ | ||
| 102 | struct mtk_iommu_v1_domain *m4u_dom; | ||
| 103 | |||
| 104 | struct iommu_device iommu; | ||
| 105 | struct dma_iommu_mapping *mapping; | ||
| 106 | struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX]; | ||
| 107 | |||
| 108 | struct mtk_iommu_v1_suspend_reg reg; | ||
| 109 | }; | ||
| 110 | |||
| 111 | struct mtk_iommu_v1_domain { | ||
| 91 | spinlock_t pgtlock; /* lock for page table */ | 112 | spinlock_t pgtlock; /* lock for page table */ |
| 92 | struct iommu_domain domain; | 113 | struct iommu_domain domain; |
| 93 | u32 *pgt_va; | 114 | u32 *pgt_va; |
| 94 | dma_addr_t pgt_pa; | 115 | dma_addr_t pgt_pa; |
| 95 | struct mtk_iommu_data *data; | 116 | struct mtk_iommu_v1_data *data; |
| 96 | }; | 117 | }; |
| 97 | 118 | ||
| 98 | static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom) | 119 | static int mtk_iommu_v1_bind(struct device *dev) |
| 120 | { | ||
| 121 | struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); | ||
| 122 | |||
| 123 | return component_bind_all(dev, &data->larb_imu); | ||
| 124 | } | ||
| 125 | |||
| 126 | static void mtk_iommu_v1_unbind(struct device *dev) | ||
| 127 | { | ||
| 128 | struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); | ||
| 129 | |||
| 130 | component_unbind_all(dev, &data->larb_imu); | ||
| 131 | } | ||
| 132 | |||
| 133 | static struct mtk_iommu_v1_domain *to_mtk_domain(struct iommu_domain *dom) | ||
| 99 | { | 134 | { |
| 100 | return container_of(dom, struct mtk_iommu_domain, domain); | 135 | return container_of(dom, struct mtk_iommu_v1_domain, domain); |
| 101 | } | 136 | } |
| 102 | 137 | ||
| 103 | static const int mt2701_m4u_in_larb[] = { | 138 | static const int mt2701_m4u_in_larb[] = { |
| @@ -123,7 +158,7 @@ static inline int mt2701_m4u_to_port(int id) · 19 unmodified lines | |||
| 123 | return id - mt2701_m4u_in_larb[larb]; | 158 | return id - mt2701_m4u_in_larb[larb]; |
| 124 | } | 159 | } |
| 125 | 160 | ||
| 126 | static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data) | 161 | static void mtk_iommu_v1_tlb_flush_all(struct mtk_iommu_v1_data *data) |
| 127 | { | 162 | { |
| 128 | writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, | 163 | writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, |
| 129 | data->base + REG_MMU_INV_SEL); | 164 | data->base + REG_MMU_INV_SEL); |
| @@ -131,8 +166,8 @@ static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data) · 1 unmodified line | |||
| 131 | wmb(); /* Make sure the tlb flush all done */ | 166 | wmb(); /* Make sure the tlb flush all done */ |
| 132 | } | 167 | } |
| 133 | 168 | ||
| 134 | static void mtk_iommu_tlb_flush_range(struct mtk_iommu_data *data, | 169 | static void mtk_iommu_v1_tlb_flush_range(struct mtk_iommu_v1_data *data, |
| 135 | unsigned long iova, size_t size) | 170 | unsigned long iova, size_t size) |
| 136 | { | 171 | { |
| 137 | int ret; | 172 | int ret; |
| 138 | u32 tmp; | 173 | u32 tmp; |
| @@ -150,16 +185,16 @@ static void mtk_iommu_tlb_flush_range(struct mtk_iommu_data *data, · 11 unmodified lines | |||
| 150 | if (ret) { | 185 | if (ret) { |
| 151 | dev_warn(data->dev, | 186 | dev_warn(data->dev, |
| 152 | "Partial TLB flush timed out, falling back to full flush\n"); | 187 | "Partial TLB flush timed out, falling back to full flush\n"); |
| 153 | mtk_iommu_tlb_flush_all(data); | 188 | mtk_iommu_v1_tlb_flush_all(data); |
| 154 | } | 189 | } |
| 155 | /* Clear the CPE status */ | 190 | /* Clear the CPE status */ |
| 156 | writel_relaxed(0, data->base + REG_MMU_CPE_DONE); | 191 | writel_relaxed(0, data->base + REG_MMU_CPE_DONE); |
| 157 | } | 192 | } |
| 158 | 193 | ||
| 159 | static irqreturn_t mtk_iommu_isr(int irq, void *dev_id) | 194 | static irqreturn_t mtk_iommu_v1_isr(int irq, void *dev_id) |
| 160 | { | 195 | { |
| 161 | struct mtk_iommu_data *data = dev_id; | 196 | struct mtk_iommu_v1_data *data = dev_id; |
| 162 | struct mtk_iommu_domain *dom = data->m4u_dom; | 197 | struct mtk_iommu_v1_domain *dom = data->m4u_dom; |
| 163 | u32 int_state, regval, fault_iova, fault_pa; | 198 | u32 int_state, regval, fault_iova, fault_pa; |
| 164 | unsigned int fault_larb, fault_port; | 199 | unsigned int fault_larb, fault_port; |
| 165 | 200 | ||
| @@ -189,13 +224,13 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id) · 23 unmodified lines | |||
| 189 | regval |= F_INT_CLR_BIT; | 224 | regval |= F_INT_CLR_BIT; |
| 190 | writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL); | 225 | writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL); |
| 191 | 226 | ||
| 192 | mtk_iommu_tlb_flush_all(data); | 227 | mtk_iommu_v1_tlb_flush_all(data); |
| 193 | 228 | ||
| 194 | return IRQ_HANDLED; | 229 | return IRQ_HANDLED; |
| 195 | } | 230 | } |
| 196 | 231 | ||
| 197 | static void mtk_iommu_config(struct mtk_iommu_data *data, | 232 | static void mtk_iommu_v1_config(struct mtk_iommu_v1_data *data, |
| 198 | struct device *dev, bool enable) | 233 | struct device *dev, bool enable) |
| 199 | { | 234 | { |
| 200 | struct mtk_smi_larb_iommu *larb_mmu; | 235 | struct mtk_smi_larb_iommu *larb_mmu; |
| 201 | unsigned int larbid, portid; | 236 | unsigned int larbid, portid; |
| @@ -217,9 +252,9 @@ static void mtk_iommu_config(struct mtk_iommu_data *data, · 15 unmodified lines | |||
| 217 | } | 252 | } |
| 218 | } | 253 | } |
| 219 | 254 | ||
| 220 | static int mtk_iommu_domain_finalise(struct mtk_iommu_data *data) | 255 | static int mtk_iommu_v1_domain_finalise(struct mtk_iommu_v1_data *data) |
| 221 | { | 256 | { |
| 222 | struct mtk_iommu_domain *dom = data->m4u_dom; | 257 | struct mtk_iommu_v1_domain *dom = data->m4u_dom; |
| 223 | 258 | ||
| 224 | spin_lock_init(&dom->pgtlock); | 259 | spin_lock_init(&dom->pgtlock); |
| 225 | 260 | ||
| @@ -235,9 +270,9 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_data *data) · 9 unmodified lines | |||
| 235 | return 0; | 270 | return 0; |
| 236 | } | 271 | } |
| 237 | 272 | ||
| 238 | static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type) | 273 | static struct iommu_domain *mtk_iommu_v1_domain_alloc(unsigned type) |
| 239 | { | 274 | { |
| 240 | struct mtk_iommu_domain *dom; | 275 | struct mtk_iommu_v1_domain *dom; |
| 241 | 276 | ||
| 242 | if (type != IOMMU_DOMAIN_UNMANAGED) | 277 | if (type != IOMMU_DOMAIN_UNMANAGED) |
| 243 | return NULL; | 278 | return NULL; |
| @@ -249,21 +284,20 @@ static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type) · 5 unmodified lines | |||
| 249 | return &dom->domain; | 284 | return &dom->domain; |
| 250 | } | 285 | } |
| 251 | 286 | ||
| 252 | static void mtk_iommu_domain_free(struct iommu_domain *domain) | 287 | static void mtk_iommu_v1_domain_free(struct iommu_domain *domain) |
| 253 | { | 288 | { |
| 254 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 289 | struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); |
| 255 | struct mtk_iommu_data *data = dom->data; | 290 | struct mtk_iommu_v1_data *data = dom->data; |
| 256 | 291 | ||
| 257 | dma_free_coherent(data->dev, M2701_IOMMU_PGT_SIZE, | 292 | dma_free_coherent(data->dev, M2701_IOMMU_PGT_SIZE, |
| 258 | dom->pgt_va, dom->pgt_pa); | 293 | dom->pgt_va, dom->pgt_pa); |
| 259 | kfree(to_mtk_domain(domain)); | 294 | kfree(to_mtk_domain(domain)); |
| 260 | } | 295 | } |
| 261 | 296 | ||
| 262 | static int mtk_iommu_attach_device(struct iommu_domain *domain, | 297 | static int mtk_iommu_v1_attach_device(struct iommu_domain *domain, struct device *dev) |
| 263 | struct device *dev) | ||
| 264 | { | 298 | { |
| 265 | struct mtk_iommu_data *data = dev_iommu_priv_get(dev); | 299 | struct mtk_iommu_v1_data *data = dev_iommu_priv_get(dev); |
| 266 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 300 | struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); |
| 267 | struct dma_iommu_mapping *mtk_mapping; | 301 | struct dma_iommu_mapping *mtk_mapping; |
| 268 | int ret; | 302 | int ret; |
| 269 | 303 | ||
| @@ -274,29 +308,28 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, · 4 unmodified lines | |||
| 274 | 308 | ||
| 275 | if (!data->m4u_dom) { | 309 | if (!data->m4u_dom) { |
| 276 | data->m4u_dom = dom; | 310 | data->m4u_dom = dom; |
| 277 | ret = mtk_iommu_domain_finalise(data); | 311 | ret = mtk_iommu_v1_domain_finalise(data); |
| 278 | if (ret) { | 312 | if (ret) { |
| 279 | data->m4u_dom = NULL; | 313 | data->m4u_dom = NULL; |
| 280 | return ret; | 314 | return ret; |
| 281 | } | 315 | } |
| 282 | } | 316 | } |
| 283 | 317 | ||
| 284 | mtk_iommu_config(data, dev, true); | 318 | mtk_iommu_v1_config(data, dev, true); |
| 285 | return 0; | 319 | return 0; |
| 286 | } | 320 | } |
| 287 | 321 | ||
| 288 | static void mtk_iommu_detach_device(struct iommu_domain *domain, | 322 | static void mtk_iommu_v1_detach_device(struct iommu_domain *domain, struct device *dev) |
| 289 | struct device *dev) | ||
| 290 | { | 323 | { |
| 291 | struct mtk_iommu_data *data = dev_iommu_priv_get(dev); | 324 | struct mtk_iommu_v1_data *data = dev_iommu_priv_get(dev); |
| 292 | 325 | ||
| 293 | mtk_iommu_config(data, dev, false); | 326 | mtk_iommu_v1_config(data, dev, false); |
| 294 | } | 327 | } |
| 295 | 328 | ||
| 296 | static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova, | 329 | static int mtk_iommu_v1_map(struct iommu_domain *domain, unsigned long iova, |
| 297 | phys_addr_t paddr, size_t size, int prot, gfp_t gfp) | 330 | phys_addr_t paddr, size_t size, int prot, gfp_t gfp) |
| 298 | { | 331 | { |
| 299 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 332 | struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); |
| 300 | unsigned int page_num = size >> MT2701_IOMMU_PAGE_SHIFT; | 333 | unsigned int page_num = size >> MT2701_IOMMU_PAGE_SHIFT; |
| 301 | unsigned long flags; | 334 | unsigned long flags; |
| 302 | unsigned int i; | 335 | unsigned int i; |
| @@ -317,16 +350,15 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova, · 14 unmodified lines | |||
| 317 | 350 | ||
| 318 | spin_unlock_irqrestore(&dom->pgtlock, flags); | 351 | spin_unlock_irqrestore(&dom->pgtlock, flags); |
| 319 | 352 | ||
| 320 | mtk_iommu_tlb_flush_range(dom->data, iova, size); | 353 | mtk_iommu_v1_tlb_flush_range(dom->data, iova, size); |
| 321 | 354 | ||
| 322 | return map_size == size ? 0 : -EEXIST; | 355 | return map_size == size ? 0 : -EEXIST; |
| 323 | } | 356 | } |
| 324 | 357 | ||
| 325 | static size_t mtk_iommu_unmap(struct iommu_domain *domain, | 358 | static size_t mtk_iommu_v1_unmap(struct iommu_domain *domain, unsigned long iova, |
| 326 | unsigned long iova, size_t size, | 359 | size_t size, struct iommu_iotlb_gather *gather) |
| 327 | struct iommu_iotlb_gather *gather) | ||
| 328 | { | 360 | { |
| 329 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 361 | struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); |
| 330 | unsigned long flags; | 362 | unsigned long flags; |
| 331 | u32 *pgt_base_iova = dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT); | 363 | u32 *pgt_base_iova = dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT); |
| 332 | unsigned int page_num = size >> MT2701_IOMMU_PAGE_SHIFT; | 364 | unsigned int page_num = size >> MT2701_IOMMU_PAGE_SHIFT; |
| @@ -335,15 +367,14 @@ static size_t mtk_iommu_unmap(struct iommu_domain *domain, · 2 unmodified lines | |||
| 335 | memset(pgt_base_iova, 0, page_num * sizeof(u32)); | 367 | memset(pgt_base_iova, 0, page_num * sizeof(u32)); |
| 336 | spin_unlock_irqrestore(&dom->pgtlock, flags); | 368 | spin_unlock_irqrestore(&dom->pgtlock, flags); |
| 337 | 369 | ||
| 338 | mtk_iommu_tlb_flush_range(dom->data, iova, size); | 370 | mtk_iommu_v1_tlb_flush_range(dom->data, iova, size); |
| 339 | 371 | ||
| 340 | return size; | 372 | return size; |
| 341 | } | 373 | } |
| 342 | 374 | ||
| 343 | static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, | 375 | static phys_addr_t mtk_iommu_v1_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova) |
| 344 | dma_addr_t iova) | ||
| 345 | { | 376 | { |
| 346 | struct mtk_iommu_domain *dom = to_mtk_domain(domain); | 377 | struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain); |
| 347 | unsigned long flags; | 378 | unsigned long flags; |
| 348 | phys_addr_t pa; | 379 | phys_addr_t pa; |
| 349 | 380 | ||
| @@ -355,17 +386,16 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, · 5 unmodified lines | |||
| 355 | return pa; | 386 | return pa; |
| 356 | } | 387 | } |
| 357 | 388 | ||
| 358 | static const struct iommu_ops mtk_iommu_ops; | 389 | static const struct iommu_ops mtk_iommu_v1_ops; |
| 359 | 390 | ||
| 360 | /* | 391 | /* |
| 361 | * MTK generation one iommu HW only support one iommu domain, and all the client | 392 | * MTK generation one iommu HW only support one iommu domain, and all the client |
| 362 | * sharing the same iova address space. | 393 | * sharing the same iova address space. |
| 363 | */ | 394 | */ |
| 364 | static int mtk_iommu_create_mapping(struct device *dev, | 395 | static int mtk_iommu_v1_create_mapping(struct device *dev, struct of_phandle_args *args) |
| 365 | struct of_phandle_args *args) | ||
| 366 | { | 396 | { |
| 367 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); | 397 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); |
| 368 | struct mtk_iommu_data *data; | 398 | struct mtk_iommu_v1_data *data; |
| 369 | struct platform_device *m4updev; | 399 | struct platform_device *m4updev; |
| 370 | struct dma_iommu_mapping *mtk_mapping; | 400 | struct dma_iommu_mapping *mtk_mapping; |
| 371 | int ret; | 401 | int ret; |
| @@ -377,11 +407,11 @@ static int mtk_iommu_create_mapping(struct device *dev, · 5 unmodified lines | |||
| 377 | } | 407 | } |
| 378 | 408 | ||
| 379 | if (!fwspec) { | 409 | if (!fwspec) { |
| 380 | ret = iommu_fwspec_init(dev, &args->np->fwnode, &mtk_iommu_ops); | 410 | ret = iommu_fwspec_init(dev, &args->np->fwnode, &mtk_iommu_v1_ops); |
| 381 | if (ret) | 411 | if (ret) |
| 382 | return ret; | 412 | return ret; |
| 383 | fwspec = dev_iommu_fwspec_get(dev); | 413 | fwspec = dev_iommu_fwspec_get(dev); |
| 384 | } else if (dev_iommu_fwspec_get(dev)->ops != &mtk_iommu_ops) { | 414 | } else if (dev_iommu_fwspec_get(dev)->ops != &mtk_iommu_v1_ops) { |
| 385 | return -EINVAL; | 415 | return -EINVAL; |
| 386 | } | 416 | } |
| 387 | 417 | ||
| @@ -413,16 +443,16 @@ static int mtk_iommu_create_mapping(struct device *dev, · 25 unmodified lines | |||
| 413 | return 0; | 443 | return 0; |
| 414 | } | 444 | } |
| 415 | 445 | ||
| 416 | static int mtk_iommu_def_domain_type(struct device *dev) | 446 | static int mtk_iommu_v1_def_domain_type(struct device *dev) |
| 417 | { | 447 | { |
| 418 | return IOMMU_DOMAIN_UNMANAGED; | 448 | return IOMMU_DOMAIN_UNMANAGED; |
| 419 | } | 449 | } |
| 420 | 450 | ||
| 421 | static struct iommu_device *mtk_iommu_probe_device(struct device *dev) | 451 | static struct iommu_device *mtk_iommu_v1_probe_device(struct device *dev) |
| 422 | { | 452 | { |
| 423 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); | 453 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); |
| 424 | struct of_phandle_args iommu_spec; | 454 | struct of_phandle_args iommu_spec; |
| 425 | struct mtk_iommu_data *data; | 455 | struct mtk_iommu_v1_data *data; |
| 426 | int err, idx = 0, larbid, larbidx; | 456 | int err, idx = 0, larbid, larbidx; |
| 427 | struct device_link *link; | 457 | struct device_link *link; |
| 428 | struct device *larbdev; | 458 | struct device *larbdev; |
| @@ -440,7 +470,7 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) · 11 unmodified lines | |||
| 440 | "#iommu-cells", | 470 | "#iommu-cells", |
| 441 | idx, &iommu_spec)) { | 471 | idx, &iommu_spec)) { |
| 442 | 472 | ||
| 443 | err = mtk_iommu_create_mapping(dev, &iommu_spec); | 473 | err = mtk_iommu_v1_create_mapping(dev, &iommu_spec); |
| 444 | of_node_put(iommu_spec.np); | 474 | of_node_put(iommu_spec.np); |
| 445 | if (err) | 475 | if (err) |
| 446 | return ERR_PTR(err); | 476 | return ERR_PTR(err); |
| @@ -450,13 +480,16 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) · 3 unmodified lines | |||
| 450 | idx++; | 480 | idx++; |
| 451 | } | 481 | } |
| 452 | 482 | ||
| 453 | if (!fwspec || fwspec->ops != &mtk_iommu_ops) | 483 | if (!fwspec || fwspec->ops != &mtk_iommu_v1_ops) |
| 454 | return ERR_PTR(-ENODEV); /* Not a iommu client device */ | 484 | return ERR_PTR(-ENODEV); /* Not a iommu client device */ |
| 455 | 485 | ||
| 456 | data = dev_iommu_priv_get(dev); | 486 | data = dev_iommu_priv_get(dev); |
| 457 | 487 | ||
| 458 | /* Link the consumer device with the smi-larb device(supplier) */ | 488 | /* Link the consumer device with the smi-larb device(supplier) */ |
| 459 | larbid = mt2701_m4u_to_larb(fwspec->ids[0]); | 489 | larbid = mt2701_m4u_to_larb(fwspec->ids[0]); |
| 490 | if (larbid >= MT2701_LARB_NR_MAX) | ||
| 491 | return ERR_PTR(-EINVAL); | ||
| 492 | |||
| 460 | for (idx = 1; idx < fwspec->num_ids; idx++) { | 493 | for (idx = 1; idx < fwspec->num_ids; idx++) { |
| 461 | larbidx = mt2701_m4u_to_larb(fwspec->ids[idx]); | 494 | larbidx = mt2701_m4u_to_larb(fwspec->ids[idx]); |
| 462 | if (larbid != larbidx) { | 495 | if (larbid != larbidx) { |
| @@ -467,6 +500,9 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) · 4 unmodified lines | |||
| 467 | } | 500 | } |
| 468 | 501 | ||
| 469 | larbdev = data->larb_imu[larbid].dev; | 502 | larbdev = data->larb_imu[larbid].dev; |
| 503 | if (!larbdev) | ||
| 504 | return ERR_PTR(-EINVAL); | ||
| 505 | |||
| 470 | link = device_link_add(dev, larbdev, | 506 | link = device_link_add(dev, larbdev, |
| 471 | DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); | 507 | DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS); |
| 472 | if (!link) | 508 | if (!link) |
| @@ -475,10 +511,10 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev) · 2 unmodified lines | |||
| 475 | return &data->iommu; | 511 | return &data->iommu; |
| 476 | } | 512 | } |
| 477 | 513 | ||
| 478 | static void mtk_iommu_probe_finalize(struct device *dev) | 514 | static void mtk_iommu_v1_probe_finalize(struct device *dev) |
| 479 | { | 515 | { |
| 480 | struct dma_iommu_mapping *mtk_mapping; | 516 | struct dma_iommu_mapping *mtk_mapping; |
| 481 | struct mtk_iommu_data *data; | 517 | struct mtk_iommu_v1_data *data; |
| 482 | int err; | 518 | int err; |
| 483 | 519 | ||
| 484 | data = dev_iommu_priv_get(dev); | 520 | data = dev_iommu_priv_get(dev); |
| @@ -489,14 +525,14 @@ static void mtk_iommu_probe_finalize(struct device *dev) · 4 unmodified lines | |||
| 489 | dev_err(dev, "Can't create IOMMU mapping - DMA-OPS will not work\n"); | 525 | dev_err(dev, "Can't create IOMMU mapping - DMA-OPS will not work\n"); |
| 490 | } | 526 | } |
| 491 | 527 | ||
| 492 | static void mtk_iommu_release_device(struct device *dev) | 528 | static void mtk_iommu_v1_release_device(struct device *dev) |
| 493 | { | 529 | { |
| 494 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); | 530 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); |
| 495 | struct mtk_iommu_data *data; | 531 | struct mtk_iommu_v1_data *data; |
| 496 | struct device *larbdev; | 532 | struct device *larbdev; |
| 497 | unsigned int larbid; | 533 | unsigned int larbid; |
| 498 | 534 | ||
| 499 | if (!fwspec || fwspec->ops != &mtk_iommu_ops) | 535 | if (!fwspec || fwspec->ops != &mtk_iommu_v1_ops) |
| 500 | return; | 536 | return; |
| 501 | 537 | ||
| 502 | data = dev_iommu_priv_get(dev); | 538 | data = dev_iommu_priv_get(dev); |
| @@ -507,7 +543,7 @@ static void mtk_iommu_release_device(struct device *dev) · 4 unmodified lines | |||
| 507 | iommu_fwspec_free(dev); | 543 | iommu_fwspec_free(dev); |
| 508 | } | 544 | } |
| 509 | 545 | ||
| 510 | static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) | 546 | static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data) |
| 511 | { | 547 | { |
| 512 | u32 regval; | 548 | u32 regval; |
| 513 | int ret; | 549 | int ret; |
| @@ -537,7 +573,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) · 23 unmodified lines | |||
| 537 | 573 | ||
| 538 | writel_relaxed(F_MMU_DCM_ON, data->base + REG_MMU_DCM); | 574 | writel_relaxed(F_MMU_DCM_ON, data->base + REG_MMU_DCM); |
| 539 | 575 | ||
| 540 | if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0, | 576 | if (devm_request_irq(data->dev, data->irq, mtk_iommu_v1_isr, 0, |
| 541 | dev_name(data->dev), (void *)data)) { | 577 | dev_name(data->dev), (void *)data)) { |
| 542 | writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); | 578 | writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); |
| 543 | clk_disable_unprepare(data->bclk); | 579 | clk_disable_unprepare(data->bclk); |
| @@ -548,39 +584,39 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data) · 4 unmodified lines | |||
| 548 | return 0; | 584 | return 0; |
| 549 | } | 585 | } |
| 550 | 586 | ||
| 551 | static const struct iommu_ops mtk_iommu_ops = { | 587 | static const struct iommu_ops mtk_iommu_v1_ops = { |
| 552 | .domain_alloc = mtk_iommu_domain_alloc, | 588 | .domain_alloc = mtk_iommu_v1_domain_alloc, |
| 553 | .probe_device = mtk_iommu_probe_device, | 589 | .probe_device = mtk_iommu_v1_probe_device, |
| 554 | .probe_finalize = mtk_iommu_probe_finalize, | 590 | .probe_finalize = mtk_iommu_v1_probe_finalize, |
| 555 | .release_device = mtk_iommu_release_device, | 591 | .release_device = mtk_iommu_v1_release_device, |
| 556 | .def_domain_type = mtk_iommu_def_domain_type, | 592 | .def_domain_type = mtk_iommu_v1_def_domain_type, |
| 557 | .device_group = generic_device_group, | 593 | .device_group = generic_device_group, |
| 558 | .pgsize_bitmap = ~0UL << MT2701_IOMMU_PAGE_SHIFT, | 594 | .pgsize_bitmap = ~0UL << MT2701_IOMMU_PAGE_SHIFT, |
| 559 | .owner = THIS_MODULE, | 595 | .owner = THIS_MODULE, |
| 560 | .default_domain_ops = &(const struct iommu_domain_ops) { | 596 | .default_domain_ops = &(const struct iommu_domain_ops) { |
| 561 | .attach_dev = mtk_iommu_attach_device, | 597 | .attach_dev = mtk_iommu_v1_attach_device, |
| 562 | .detach_dev = mtk_iommu_detach_device, | 598 | .detach_dev = mtk_iommu_v1_detach_device, |
| 563 | .map = mtk_iommu_map, | 599 | .map = mtk_iommu_v1_map, |
| 564 | .unmap = mtk_iommu_unmap, | 600 | .unmap = mtk_iommu_v1_unmap, |
| 565 | .iova_to_phys = mtk_iommu_iova_to_phys, | 601 | .iova_to_phys = mtk_iommu_v1_iova_to_phys, |
| 566 | .free = mtk_iommu_domain_free, | 602 | .free = mtk_iommu_v1_domain_free, |
| 567 | } | 603 | } |
| 568 | }; | 604 | }; |
| 569 | 605 | ||
| 570 | static const struct of_device_id mtk_iommu_of_ids[] = { | 606 | static const struct of_device_id mtk_iommu_v1_of_ids[] = { |
| 571 | { .compatible = "mediatek,mt2701-m4u", }, | 607 | { .compatible = "mediatek,mt2701-m4u", }, |
| 572 | {} | 608 | {} |
| 573 | }; | 609 | }; |
| 574 | 610 | ||
| 575 | static const struct component_master_ops mtk_iommu_com_ops = { | 611 | static const struct component_master_ops mtk_iommu_v1_com_ops = { |
| 576 | .bind = mtk_iommu_bind, | 612 | .bind = mtk_iommu_v1_bind, |
| 577 | .unbind = mtk_iommu_unbind, | 613 | .unbind = mtk_iommu_v1_unbind, |
| 578 | }; | 614 | }; |
| 579 | 615 | ||
| 580 | static int mtk_iommu_probe(struct platform_device *pdev) | 616 | static int mtk_iommu_v1_probe(struct platform_device *pdev) |
| 581 | { | 617 | { |
| 582 | struct mtk_iommu_data *data; | ||
| 583 | struct device *dev = &pdev->dev; | 618 | struct device *dev = &pdev->dev; |
| 619 | struct mtk_iommu_v1_data *data; | ||
| 584 | struct resource *res; | 620 | struct resource *res; |
| 585 | struct component_match *match = NULL; | 621 | struct component_match *match = NULL; |
| 586 | void *protect; | 622 | void *protect; |
| @@ -647,7 +683,7 @@ static int mtk_iommu_probe(struct platform_device *pdev) · 60 unmodified lines | |||
| 647 | 683 | ||
| 648 | platform_set_drvdata(pdev, data); | 684 | platform_set_drvdata(pdev, data); |
| 649 | 685 | ||
| 650 | ret = mtk_iommu_hw_init(data); | 686 | ret = mtk_iommu_v1_hw_init(data); |
| 651 | if (ret) | 687 | if (ret) |
| 652 | return ret; | 688 | return ret; |
| 653 | 689 | ||
| @@ -656,17 +692,17 @@ static int mtk_iommu_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 656 | if (ret) | 692 | if (ret) |
| 657 | return ret; | 693 | return ret; |
| 658 | 694 | ||
| 659 | ret = iommu_device_register(&data->iommu, &mtk_iommu_ops, dev); | 695 | ret = iommu_device_register(&data->iommu, &mtk_iommu_v1_ops, dev); |
| 660 | if (ret) | 696 | if (ret) |
| 661 | goto out_sysfs_remove; | 697 | goto out_sysfs_remove; |
| 662 | 698 | ||
| 663 | if (!iommu_present(&platform_bus_type)) { | 699 | if (!iommu_present(&platform_bus_type)) { |
| 664 | ret = bus_set_iommu(&platform_bus_type, &mtk_iommu_ops); | 700 | ret = bus_set_iommu(&platform_bus_type, &mtk_iommu_v1_ops); |
| 665 | if (ret) | 701 | if (ret) |
| 666 | goto out_dev_unreg; | 702 | goto out_dev_unreg; |
| 667 | } | 703 | } |
| 668 | 704 | ||
| 669 | ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match); | 705 | ret = component_master_add_with_match(dev, &mtk_iommu_v1_com_ops, match); |
| 670 | if (ret) | 706 | if (ret) |
| 671 | goto out_bus_set_null; | 707 | goto out_bus_set_null; |
| 672 | return ret; | 708 | return ret; |
| @@ -680,9 +716,9 @@ out_sysfs_remove: · 7 unmodified lines | |||
| 680 | return ret; | 716 | return ret; |
| 681 | } | 717 | } |
| 682 | 718 | ||
| 683 | static int mtk_iommu_remove(struct platform_device *pdev) | 719 | static int mtk_iommu_v1_remove(struct platform_device *pdev) |
| 684 | { | 720 | { |
| 685 | struct mtk_iommu_data *data = platform_get_drvdata(pdev); | 721 | struct mtk_iommu_v1_data *data = platform_get_drvdata(pdev); |
| 686 | 722 | ||
| 687 | iommu_device_sysfs_remove(&data->iommu); | 723 | iommu_device_sysfs_remove(&data->iommu); |
| 688 | iommu_device_unregister(&data->iommu); | 724 | iommu_device_unregister(&data->iommu); |
| @@ -692,14 +728,14 @@ static int mtk_iommu_remove(struct platform_device *pdev) · 3 unmodified lines | |||
| 692 | 728 | ||
| 693 | clk_disable_unprepare(data->bclk); | 729 | clk_disable_unprepare(data->bclk); |
| 694 | devm_free_irq(&pdev->dev, data->irq, data); | 730 | devm_free_irq(&pdev->dev, data->irq, data); |
| 695 | component_master_del(&pdev->dev, &mtk_iommu_com_ops); | 731 | component_master_del(&pdev->dev, &mtk_iommu_v1_com_ops); |
| 696 | return 0; | 732 | return 0; |
| 697 | } | 733 | } |
| 698 | 734 | ||
| 699 | static int __maybe_unused mtk_iommu_suspend(struct device *dev) | 735 | static int __maybe_unused mtk_iommu_v1_suspend(struct device *dev) |
| 700 | { | 736 | { |
| 701 | struct mtk_iommu_data *data = dev_get_drvdata(dev); | 737 | struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); |
| 702 | struct mtk_iommu_suspend_reg *reg = &data->reg; | 738 | struct mtk_iommu_v1_suspend_reg *reg = &data->reg; |
| 703 | void __iomem *base = data->base; | 739 | void __iomem *base = data->base; |
| 704 | 740 | ||
| 705 | reg->standard_axi_mode = readl_relaxed(base + | 741 | reg->standard_axi_mode = readl_relaxed(base + |
| @@ -710,10 +746,10 @@ static int __maybe_unused mtk_iommu_suspend(struct device *dev) · 4 unmodified lines | |||
| 710 | return 0; | 746 | return 0; |
| 711 | } | 747 | } |
| 712 | 748 | ||
| 713 | static int __maybe_unused mtk_iommu_resume(struct device *dev) | 749 | static int __maybe_unused mtk_iommu_v1_resume(struct device *dev) |
| 714 | { | 750 | { |
| 715 | struct mtk_iommu_data *data = dev_get_drvdata(dev); | 751 | struct mtk_iommu_v1_data *data = dev_get_drvdata(dev); |
| 716 | struct mtk_iommu_suspend_reg *reg = &data->reg; | 752 | struct mtk_iommu_v1_suspend_reg *reg = &data->reg; |
| 717 | void __iomem *base = data->base; | 753 | void __iomem *base = data->base; |
| 718 | 754 | ||
| 719 | writel_relaxed(data->m4u_dom->pgt_pa, base + REG_MMU_PT_BASE_ADDR); | 755 | writel_relaxed(data->m4u_dom->pgt_pa, base + REG_MMU_PT_BASE_ADDR); |
| @@ -726,20 +762,20 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev) · 6 unmodified lines | |||
| 726 | return 0; | 762 | return 0; |
| 727 | } | 763 | } |
| 728 | 764 | ||
| 729 | static const struct dev_pm_ops mtk_iommu_pm_ops = { | 765 | static const struct dev_pm_ops mtk_iommu_v1_pm_ops = { |
| 730 | SET_SYSTEM_SLEEP_PM_OPS(mtk_iommu_suspend, mtk_iommu_resume) | 766 | SET_SYSTEM_SLEEP_PM_OPS(mtk_iommu_v1_suspend, mtk_iommu_v1_resume) |
| 731 | }; | 767 | }; |
| 732 | 768 | ||
| 733 | static struct platform_driver mtk_iommu_driver = { | 769 | static struct platform_driver mtk_iommu_v1_driver = { |
| 734 | .probe = mtk_iommu_probe, | 770 | .probe = mtk_iommu_v1_probe, |
| 735 | .remove = mtk_iommu_remove, | 771 | .remove = mtk_iommu_v1_remove, |
| 736 | .driver = { | 772 | .driver = { |
| 737 | .name = "mtk-iommu-v1", | 773 | .name = "mtk-iommu-v1", |
| 738 | .of_match_table = mtk_iommu_of_ids, | 774 | .of_match_table = mtk_iommu_v1_of_ids, |
| 739 | .pm = &mtk_iommu_pm_ops, | 775 | .pm = &mtk_iommu_v1_pm_ops, |
| 740 | } | 776 | } |
| 741 | }; | 777 | }; |
| 742 | module_platform_driver(mtk_iommu_driver); | 778 | module_platform_driver(mtk_iommu_v1_driver); |
| 743 | 779 | ||
| 744 | MODULE_DESCRIPTION("IOMMU API for MediaTek M4U v1 implementations"); | 780 | MODULE_DESCRIPTION("IOMMU API for MediaTek M4U v1 implementations"); |
| 745 | MODULE_LICENSE("GPL v2"); | 781 | MODULE_LICENSE("GPL v2"); |
| @@ -99,7 +99,7 @@ static int s390_iommu_attach_device(struct iommu_domain *domain, · 98 unmodified lines | |||
| 99 | if (!domain_device) | 99 | if (!domain_device) |
| 100 | return -ENOMEM; | 100 | return -ENOMEM; |
| 101 | 101 | ||
| 102 | if (zdev->dma_table) { | 102 | if (zdev->dma_table && !zdev->s390_domain) { |
| 103 | cc = zpci_dma_exit_device(zdev); | 103 | cc = zpci_dma_exit_device(zdev); |
| 104 | if (cc) { | 104 | if (cc) { |
| 105 | rc = -EIO; | 105 | rc = -EIO; |
| @@ -107,6 +107,9 @@ static int s390_iommu_attach_device(struct iommu_domain *domain, · 1 unmodified line | |||
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | if (zdev->s390_domain) | ||
| 111 | zpci_unregister_ioat(zdev, 0); | ||
| 112 | |||
| 110 | zdev->dma_table = s390_domain->dma_table; | 113 | zdev->dma_table = s390_domain->dma_table; |
| 111 | cc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, | 114 | cc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, |
| 112 | virt_to_phys(zdev->dma_table)); | 115 | virt_to_phys(zdev->dma_table)); |
| @@ -136,7 +139,13 @@ static int s390_iommu_attach_device(struct iommu_domain *domain, · 23 unmodified lines | |||
| 136 | return 0; | 139 | return 0; |
| 137 | 140 | ||
| 138 | out_restore: | 141 | out_restore: |
| 139 | zpci_dma_init_device(zdev); | 142 | if (!zdev->s390_domain) { |
| 143 | zpci_dma_init_device(zdev); | ||
| 144 | } else { | ||
| 145 | zdev->dma_table = zdev->s390_domain->dma_table; | ||
| 146 | zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, | ||
| 147 | virt_to_phys(zdev->dma_table)); | ||
| 148 | } | ||
| 140 | out_free: | 149 | out_free: |
| 141 | kfree(domain_device); | 150 | kfree(domain_device); |
| 142 | 151 | ||
| @@ -167,7 +176,7 @@ static void s390_iommu_detach_device(struct iommu_domain *domain, · 24 unmodified lines | |||
| 167 | } | 176 | } |
| 168 | spin_unlock_irqrestore(&s390_domain->list_lock, flags); | 177 | spin_unlock_irqrestore(&s390_domain->list_lock, flags); |
| 169 | 178 | ||
| 170 | if (found) { | 179 | if (found && (zdev->s390_domain == s390_domain)) { |
| 171 | zdev->s390_domain = NULL; | 180 | zdev->s390_domain = NULL; |
| 172 | zpci_unregister_ioat(zdev, 0); | 181 | zpci_unregister_ioat(zdev, 0); |
| 173 | zpci_dma_init_device(zdev); | 182 | zpci_dma_init_device(zdev); |
| @@ -164,25 +164,39 @@ static const struct regmap_access_table rpcif_volatile_table = { · 163 unmodified lines | |||
| 164 | 164 | ||
| 165 | 165 | ||
| 166 | /* | 166 | /* |
| 167 | * Custom accessor functions to ensure SMRDR0 and SMWDR0 are always accessed | 167 | * Custom accessor functions to ensure SM[RW]DR[01] are always accessed with |
| 168 | * with proper width. Requires SMENR_SPIDE to be correctly set before! | 168 | * proper width. Requires rpcif.xfer_size to be correctly set before! |
| 169 | */ | 169 | */ |
| 170 | static int rpcif_reg_read(void *context, unsigned int reg, unsigned int *val) | 170 | static int rpcif_reg_read(void *context, unsigned int reg, unsigned int *val) |
| 171 | { | 171 | { |
| 172 | struct rpcif *rpc = context; | 172 | struct rpcif *rpc = context; |
| 173 | 173 | ||
| 174 | if (reg == RPCIF_SMRDR0 || reg == RPCIF_SMWDR0) { | 174 | switch (reg) { |
| 175 | u32 spide = readl(rpc->base + RPCIF_SMENR) & RPCIF_SMENR_SPIDE(0xF); | 175 | case RPCIF_SMRDR0: |
| 176 | 176 | case RPCIF_SMWDR0: | |
| 177 | if (spide == 0x8) { | 177 | switch (rpc->xfer_size) { |
| 178 | case 1: | ||
| 178 | *val = readb(rpc->base + reg); | 179 | *val = readb(rpc->base + reg); |
| 179 | return 0; | 180 | return 0; |
| 180 | } else if (spide == 0xC) { | 181 | |
| 182 | case 2: | ||
| 181 | *val = readw(rpc->base + reg); | 183 | *val = readw(rpc->base + reg); |
| 182 | return 0; | 184 | return 0; |
| 183 | } else if (spide != 0xF) { | 185 | |
| 186 | case 4: | ||
| 187 | case 8: | ||
| 188 | *val = readl(rpc->base + reg); | ||
| 189 | return 0; | ||
| 190 | |||
| 191 | default: | ||
| 184 | return -EILSEQ; | 192 | return -EILSEQ; |
| 185 | } | 193 | } |
| 194 | |||
| 195 | case RPCIF_SMRDR1: | ||
| 196 | case RPCIF_SMWDR1: | ||
| 197 | if (rpc->xfer_size != 8) | ||
| 198 | return -EILSEQ; | ||
| 199 | break; | ||
| 186 | } | 200 | } |
| 187 | 201 | ||
| 188 | *val = readl(rpc->base + reg); | 202 | *val = readl(rpc->base + reg); |
| @@ -193,18 +207,34 @@ static int rpcif_reg_write(void *context, unsigned int reg, unsigned int val) · 4 unmodified lines | |||
| 193 | { | 207 | { |
| 194 | struct rpcif *rpc = context; | 208 | struct rpcif *rpc = context; |
| 195 | 209 | ||
| 196 | if (reg == RPCIF_SMRDR0 || reg == RPCIF_SMWDR0) { | 210 | switch (reg) { |
| 197 | u32 spide = readl(rpc->base + RPCIF_SMENR) & RPCIF_SMENR_SPIDE(0xF); | 211 | case RPCIF_SMWDR0: |
| 198 | 212 | switch (rpc->xfer_size) { | |
| 199 | if (spide == 0x8) { | 213 | case 1: |
| 200 | writeb(val, rpc->base + reg); | 214 | writeb(val, rpc->base + reg); |
| 201 | return 0; | 215 | return 0; |
| 202 | } else if (spide == 0xC) { | 216 | |
| 217 | case 2: | ||
| 203 | writew(val, rpc->base + reg); | 218 | writew(val, rpc->base + reg); |
| 204 | return 0; | 219 | return 0; |
| 205 | } else if (spide != 0xF) { | 220 | |
| 221 | case 4: | ||
| 222 | case 8: | ||
| 223 | writel(val, rpc->base + reg); | ||
| 224 | return 0; | ||
| 225 | |||
| 226 | default: | ||
| 206 | return -EILSEQ; | 227 | return -EILSEQ; |
| 207 | } | 228 | } |
| 229 | |||
| 230 | case RPCIF_SMWDR1: | ||
| 231 | if (rpc->xfer_size != 8) | ||
| 232 | return -EILSEQ; | ||
| 233 | break; | ||
| 234 | |||
| 235 | case RPCIF_SMRDR0: | ||
| 236 | case RPCIF_SMRDR1: | ||
| 237 | return -EPERM; | ||
| 208 | } | 238 | } |
| 209 | 239 | ||
| 210 | writel(val, rpc->base + reg); | 240 | writel(val, rpc->base + reg); |
| @@ -469,6 +499,7 @@ int rpcif_manual_xfer(struct rpcif *rpc) · 258 unmodified lines | |||
| 469 | 499 | ||
| 470 | smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)); | 500 | smenr |= RPCIF_SMENR_SPIDE(rpcif_bits_set(rpc, nbytes)); |
| 471 | regmap_write(rpc->regmap, RPCIF_SMENR, smenr); | 501 | regmap_write(rpc->regmap, RPCIF_SMENR, smenr); |
| 502 | rpc->xfer_size = nbytes; | ||
| 472 | 503 | ||
| 473 | memcpy(data, rpc->buffer + pos, nbytes); | 504 | memcpy(data, rpc->buffer + pos, nbytes); |
| 474 | if (nbytes == 8) { | 505 | if (nbytes == 8) { |
| @@ -533,6 +564,7 @@ int rpcif_manual_xfer(struct rpcif *rpc) · 58 unmodified lines | |||
| 533 | regmap_write(rpc->regmap, RPCIF_SMENR, smenr); | 564 | regmap_write(rpc->regmap, RPCIF_SMENR, smenr); |
| 534 | regmap_write(rpc->regmap, RPCIF_SMCR, | 565 | regmap_write(rpc->regmap, RPCIF_SMCR, |
| 535 | rpc->smcr | RPCIF_SMCR_SPIE); | 566 | rpc->smcr | RPCIF_SMCR_SPIE); |
| 567 | rpc->xfer_size = nbytes; | ||
| 536 | ret = wait_msg_xfer_end(rpc); | 568 | ret = wait_msg_xfer_end(rpc); |
| 537 | if (ret) | 569 | if (ret) |
| 538 | goto err_out; | 570 | goto err_out; |
| @@ -31,6 +31,8 @@ · 30 unmodified lines | |||
| 31 | */ | 31 | */ |
| 32 | 32 | ||
| 33 | #define FM25_SN_LEN 8 /* serial number length */ | 33 | #define FM25_SN_LEN 8 /* serial number length */ |
| 34 | #define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */ | ||
| 35 | |||
| 34 | struct at25_data { | 36 | struct at25_data { |
| 35 | struct spi_eeprom chip; | 37 | struct spi_eeprom chip; |
| 36 | struct spi_device *spi; | 38 | struct spi_device *spi; |
| @@ -39,6 +41,7 @@ struct at25_data { · 2 unmodified lines | |||
| 39 | struct nvmem_config nvmem_config; | 41 | struct nvmem_config nvmem_config; |
| 40 | struct nvmem_device *nvmem; | 42 | struct nvmem_device *nvmem; |
| 41 | u8 sernum[FM25_SN_LEN]; | 43 | u8 sernum[FM25_SN_LEN]; |
| 44 | u8 command[EE_MAXADDRLEN + 1]; | ||
| 42 | }; | 45 | }; |
| 43 | 46 | ||
| 44 | #define AT25_WREN 0x06 /* latch the write enable */ | 47 | #define AT25_WREN 0x06 /* latch the write enable */ |
| @@ -61,8 +64,6 @@ struct at25_data { · 16 unmodified lines | |||
| 61 | 64 | ||
| 62 | #define FM25_ID_LEN 9 /* ID length */ | 65 | #define FM25_ID_LEN 9 /* ID length */ |
| 63 | 66 | ||
| 64 | #define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */ | ||
| 65 | |||
| 66 | /* | 67 | /* |
| 67 | * Specs often allow 5ms for a page write, sometimes 20ms; | 68 | * Specs often allow 5ms for a page write, sometimes 20ms; |
| 68 | * it's important to recover from write timeouts. | 69 | * it's important to recover from write timeouts. |
| @@ -78,7 +79,6 @@ static int at25_ee_read(void *priv, unsigned int offset, · 9 unmodified lines | |||
| 78 | { | 79 | { |
| 79 | struct at25_data *at25 = priv; | 80 | struct at25_data *at25 = priv; |
| 80 | char *buf = val; | 81 | char *buf = val; |
| 81 | u8 command[EE_MAXADDRLEN + 1]; | ||
| 82 | u8 *cp; | 82 | u8 *cp; |
| 83 | ssize_t status; | 83 | ssize_t status; |
| 84 | struct spi_transfer t[2]; | 84 | struct spi_transfer t[2]; |
| @@ -92,12 +92,15 @@ static int at25_ee_read(void *priv, unsigned int offset, · 7 unmodified lines | |||
| 92 | if (unlikely(!count)) | 92 | if (unlikely(!count)) |
| 93 | return -EINVAL; | 93 | return -EINVAL; |
| 94 | 94 | ||
| 95 | cp = command; | 95 | cp = at25->command; |
| 96 | 96 | ||
| 97 | instr = AT25_READ; | 97 | instr = AT25_READ; |
| 98 | if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR) | 98 | if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR) |
| 99 | if (offset >= BIT(at25->addrlen * 8)) | 99 | if (offset >= BIT(at25->addrlen * 8)) |
| 100 | instr |= AT25_INSTR_BIT3; | 100 | instr |= AT25_INSTR_BIT3; |
| 101 | |||
| 102 | mutex_lock(&at25->lock); | ||
| 103 | |||
| 101 | *cp++ = instr; | 104 | *cp++ = instr; |
| 102 | 105 | ||
| 103 | /* 8/16/24-bit address is written MSB first */ | 106 | /* 8/16/24-bit address is written MSB first */ |
| @@ -116,7 +119,7 @@ static int at25_ee_read(void *priv, unsigned int offset, · 12 unmodified lines | |||
| 116 | spi_message_init(&m); | 119 | spi_message_init(&m); |
| 117 | memset(t, 0, sizeof(t)); | 120 | memset(t, 0, sizeof(t)); |
| 118 | 121 | ||
| 119 | t[0].tx_buf = command; | 122 | t[0].tx_buf = at25->command; |
| 120 | t[0].len = at25->addrlen + 1; | 123 | t[0].len = at25->addrlen + 1; |
| 121 | spi_message_add_tail(&t[0], &m); | 124 | spi_message_add_tail(&t[0], &m); |
| 122 | 125 | ||
| @@ -124,8 +127,6 @@ static int at25_ee_read(void *priv, unsigned int offset, · 1 unmodified line | |||
| 124 | t[1].len = count; | 127 | t[1].len = count; |
| 125 | spi_message_add_tail(&t[1], &m); | 128 | spi_message_add_tail(&t[1], &m); |
| 126 | 129 | ||
| 127 | mutex_lock(&at25->lock); | ||
| 128 | |||
| 129 | /* | 130 | /* |
| 130 | * Read it all at once. | 131 | * Read it all at once. |
| 131 | * | 132 | * |
| @@ -152,7 +153,7 @@ static int fm25_aux_read(struct at25_data *at25, u8 *buf, uint8_t command, · 20 unmodified lines | |||
| 152 | spi_message_init(&m); | 153 | spi_message_init(&m); |
| 153 | memset(t, 0, sizeof(t)); | 154 | memset(t, 0, sizeof(t)); |
| 154 | 155 | ||
| 155 | t[0].tx_buf = &command; | 156 | t[0].tx_buf = at25->command; |
| 156 | t[0].len = 1; | 157 | t[0].len = 1; |
| 157 | spi_message_add_tail(&t[0], &m); | 158 | spi_message_add_tail(&t[0], &m); |
| 158 | 159 | ||
| @@ -162,6 +163,8 @@ static int fm25_aux_read(struct at25_data *at25, u8 *buf, uint8_t command, · 3 unmodified lines | |||
| 162 | 163 | ||
| 163 | mutex_lock(&at25->lock); | 164 | mutex_lock(&at25->lock); |
| 164 | 165 | ||
| 166 | at25->command[0] = command; | ||
| 167 | |||
| 165 | status = spi_sync(at25->spi, &m); | 168 | status = spi_sync(at25->spi, &m); |
| 166 | dev_dbg(&at25->spi->dev, "read %d aux bytes --> %d\n", len, status); | 169 | dev_dbg(&at25->spi->dev, "read %d aux bytes --> %d\n", len, status); |
| 167 | 170 | ||
| @@ -1384,13 +1384,17 @@ static int mmc_select_hs400es(struct mmc_card *card) · 1383 unmodified lines | |||
| 1384 | goto out_err; | 1384 | goto out_err; |
| 1385 | } | 1385 | } |
| 1386 | 1386 | ||
| 1387 | /* | ||
| 1388 | * Bump to HS timing and frequency. Some cards don't handle | ||
| 1389 | * SEND_STATUS reliably at the initial frequency. | ||
| 1390 | */ | ||
| 1387 | mmc_set_timing(host, MMC_TIMING_MMC_HS); | 1391 | mmc_set_timing(host, MMC_TIMING_MMC_HS); |
| 1392 | mmc_set_bus_speed(card); | ||
| 1393 | |||
| 1388 | err = mmc_switch_status(card, true); | 1394 | err = mmc_switch_status(card, true); |
| 1389 | if (err) | 1395 | if (err) |
| 1390 | goto out_err; | 1396 | goto out_err; |
| 1391 | 1397 | ||
| 1392 | mmc_set_clock(host, card->ext_csd.hs_max_dtr); | ||
| 1393 | |||
| 1394 | /* Switch card to DDR with strobe bit */ | 1398 | /* Switch card to DDR with strobe bit */ |
| 1395 | val = EXT_CSD_DDR_BUS_WIDTH_8 | EXT_CSD_BUS_WIDTH_STROBE; | 1399 | val = EXT_CSD_DDR_BUS_WIDTH_8 | EXT_CSD_BUS_WIDTH_STROBE; |
| 1396 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1400 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
| @@ -1448,7 +1452,7 @@ out_err: · 51 unmodified lines | |||
| 1448 | static int mmc_select_hs200(struct mmc_card *card) | 1452 | static int mmc_select_hs200(struct mmc_card *card) |
| 1449 | { | 1453 | { |
| 1450 | struct mmc_host *host = card->host; | 1454 | struct mmc_host *host = card->host; |
| 1451 | unsigned int old_timing, old_signal_voltage; | 1455 | unsigned int old_timing, old_signal_voltage, old_clock; |
| 1452 | int err = -EINVAL; | 1456 | int err = -EINVAL; |
| 1453 | u8 val; | 1457 | u8 val; |
| 1454 | 1458 | ||
| @@ -1479,8 +1483,17 @@ static int mmc_select_hs200(struct mmc_card *card) · 24 unmodified lines | |||
| 1479 | false, true, MMC_CMD_RETRIES); | 1483 | false, true, MMC_CMD_RETRIES); |
| 1480 | if (err) | 1484 | if (err) |
| 1481 | goto err; | 1485 | goto err; |
| 1486 | |||
| 1487 | /* | ||
| 1488 | * Bump to HS timing and frequency. Some cards don't handle | ||
| 1489 | * SEND_STATUS reliably at the initial frequency. | ||
| 1490 | * NB: We can't move to full (HS200) speeds until after we've | ||
| 1491 | * successfully switched over. | ||
| 1492 | */ | ||
| 1482 | old_timing = host->ios.timing; | 1493 | old_timing = host->ios.timing; |
| 1494 | old_clock = host->ios.clock; | ||
| 1483 | mmc_set_timing(host, MMC_TIMING_MMC_HS200); | 1495 | mmc_set_timing(host, MMC_TIMING_MMC_HS200); |
| 1496 | mmc_set_clock(card->host, card->ext_csd.hs_max_dtr); | ||
| 1484 | 1497 | ||
| 1485 | /* | 1498 | /* |
| 1486 | * For HS200, CRC errors are not a reliable way to know the | 1499 | * For HS200, CRC errors are not a reliable way to know the |
| @@ -1493,8 +1506,10 @@ static int mmc_select_hs200(struct mmc_card *card) · 6 unmodified lines | |||
| 1493 | * mmc_select_timing() assumes timing has not changed if | 1506 | * mmc_select_timing() assumes timing has not changed if |
| 1494 | * it is a switch error. | 1507 | * it is a switch error. |
| 1495 | */ | 1508 | */ |
| 1496 | if (err == -EBADMSG) | 1509 | if (err == -EBADMSG) { |
| 1510 | mmc_set_clock(host, old_clock); | ||
| 1497 | mmc_set_timing(host, old_timing); | 1511 | mmc_set_timing(host, old_timing); |
| 1512 | } | ||
| 1498 | } | 1513 | } |
| 1499 | err: | 1514 | err: |
| 1500 | if (err) { | 1515 | if (err) { |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | #include <linux/regulator/consumer.h> | 17 | #include <linux/regulator/consumer.h> |
| 18 | #include <linux/interconnect.h> | 18 | #include <linux/interconnect.h> |
| 19 | #include <linux/pinctrl/consumer.h> | 19 | #include <linux/pinctrl/consumer.h> |
| 20 | #include <linux/reset.h> | ||
| 20 | 21 | ||
| 21 | #include "sdhci-pltfm.h" | 22 | #include "sdhci-pltfm.h" |
| 22 | #include "cqhci.h" | 23 | #include "cqhci.h" |
| @@ -2482,6 +2483,43 @@ static inline void sdhci_msm_get_of_property(struct platform_device *pdev, · 2459 unmodified lines | |||
| 2482 | of_property_read_u32(node, "qcom,dll-config", &msm_host->dll_config); | 2483 | of_property_read_u32(node, "qcom,dll-config", &msm_host->dll_config); |
| 2483 | } | 2484 | } |
| 2484 | 2485 | ||
| 2486 | static int sdhci_msm_gcc_reset(struct device *dev, struct sdhci_host *host) | ||
| 2487 | { | ||
| 2488 | struct reset_control *reset; | ||
| 2489 | int ret = 0; | ||
| 2490 | |||
| 2491 | reset = reset_control_get_optional_exclusive(dev, NULL); | ||
| 2492 | if (IS_ERR(reset)) | ||
| 2493 | return dev_err_probe(dev, PTR_ERR(reset), | ||
| 2494 | "unable to acquire core_reset\n"); | ||
| 2495 | |||
| 2496 | if (!reset) | ||
| 2497 | return ret; | ||
| 2498 | |||
| 2499 | ret = reset_control_assert(reset); | ||
| 2500 | if (ret) { | ||
| 2501 | reset_control_put(reset); | ||
| 2502 | return dev_err_probe(dev, ret, "core_reset assert failed\n"); | ||
| 2503 | } | ||
| 2504 | |||
| 2505 | /* | ||
| 2506 | * The hardware requirement for delay between assert/deassert | ||
| 2507 | * is at least 3-4 sleep clock (32.7KHz) cycles, which comes to | ||
| 2508 | * ~125us (4/32768). To be on the safe side add 200us delay. | ||
| 2509 | */ | ||
| 2510 | usleep_range(200, 210); | ||
| 2511 | |||
| 2512 | ret = reset_control_deassert(reset); | ||
| 2513 | if (ret) { | ||
| 2514 | reset_control_put(reset); | ||
| 2515 | return dev_err_probe(dev, ret, "core_reset deassert failed\n"); | ||
| 2516 | } | ||
| 2517 | |||
| 2518 | usleep_range(200, 210); | ||
| 2519 | reset_control_put(reset); | ||
| 2520 | |||
| 2521 | return ret; | ||
| 2522 | } | ||
| 2485 | 2523 | ||
| 2486 | static int sdhci_msm_probe(struct platform_device *pdev) | 2524 | static int sdhci_msm_probe(struct platform_device *pdev) |
| 2487 | { | 2525 | { |
| @@ -2529,6 +2567,10 @@ static int sdhci_msm_probe(struct platform_device *pdev) · 41 unmodified lines | |||
| 2529 | 2567 | ||
| 2530 | msm_host->saved_tuning_phase = INVALID_TUNING_PHASE; | 2568 | msm_host->saved_tuning_phase = INVALID_TUNING_PHASE; |
| 2531 | 2569 | ||
| 2570 | ret = sdhci_msm_gcc_reset(&pdev->dev, host); | ||
| 2571 | if (ret) | ||
| 2572 | goto pltfm_free; | ||
| 2573 | |||
| 2532 | /* Setup SDCC bus voter clock. */ | 2574 | /* Setup SDCC bus voter clock. */ |
| 2533 | msm_host->bus_clk = devm_clk_get(&pdev->dev, "bus"); | 2575 | msm_host->bus_clk = devm_clk_get(&pdev->dev, "bus"); |
| 2534 | if (!IS_ERR(msm_host->bus_clk)) { | 2576 | if (!IS_ERR(msm_host->bus_clk)) { |
| @@ -377,8 +377,9 @@ static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host, · 376 unmodified lines | |||
| 377 | pdes[i].buf_addr_ptr1 = | 377 | pdes[i].buf_addr_ptr1 = |
| 378 | cpu_to_le32(sg_dma_address(&data->sg[i]) >> | 378 | cpu_to_le32(sg_dma_address(&data->sg[i]) >> |
| 379 | host->cfg->idma_des_shift); | 379 | host->cfg->idma_des_shift); |
| 380 | pdes[i].buf_addr_ptr2 = cpu_to_le32((u32)next_desc >> | 380 | pdes[i].buf_addr_ptr2 = |
| 381 | host->cfg->idma_des_shift); | 381 | cpu_to_le32(next_desc >> |
| 382 | host->cfg->idma_des_shift); | ||
| 382 | } | 383 | } |
| 383 | 384 | ||
| 384 | pdes[0].config |= cpu_to_le32(SDXC_IDMAC_DES0_FD); | 385 | pdes[0].config |= cpu_to_le32(SDXC_IDMAC_DES0_FD); |
| @@ -43,6 +43,7 @@ · 42 unmodified lines | |||
| 43 | 43 | ||
| 44 | struct mtk_ecc_caps { | 44 | struct mtk_ecc_caps { |
| 45 | u32 err_mask; | 45 | u32 err_mask; |
| 46 | u32 err_shift; | ||
| 46 | const u8 *ecc_strength; | 47 | const u8 *ecc_strength; |
| 47 | const u32 *ecc_regs; | 48 | const u32 *ecc_regs; |
| 48 | u8 num_ecc_strength; | 49 | u8 num_ecc_strength; |
| @@ -76,7 +77,7 @@ static const u8 ecc_strength_mt2712[] = { · 27 unmodified lines | |||
| 76 | }; | 77 | }; |
| 77 | 78 | ||
| 78 | static const u8 ecc_strength_mt7622[] = { | 79 | static const u8 ecc_strength_mt7622[] = { |
| 79 | 4, 6, 8, 10, 12, 14, 16 | 80 | 4, 6, 8, 10, 12 |
| 80 | }; | 81 | }; |
| 81 | 82 | ||
| 82 | enum mtk_ecc_regs { | 83 | enum mtk_ecc_regs { |
| @@ -221,7 +222,7 @@ void mtk_ecc_get_stats(struct mtk_ecc *ecc, struct mtk_ecc_stats *stats, · 138 unmodified lines | |||
| 221 | for (i = 0; i < sectors; i++) { | 222 | for (i = 0; i < sectors; i++) { |
| 222 | offset = (i >> 2) << 2; | 223 | offset = (i >> 2) << 2; |
| 223 | err = readl(ecc->regs + ECC_DECENUM0 + offset); | 224 | err = readl(ecc->regs + ECC_DECENUM0 + offset); |
| 224 | err = err >> ((i % 4) * 8); | 225 | err = err >> ((i % 4) * ecc->caps->err_shift); |
| 225 | err &= ecc->caps->err_mask; | 226 | err &= ecc->caps->err_mask; |
| 226 | if (err == ecc->caps->err_mask) { | 227 | if (err == ecc->caps->err_mask) { |
| 227 | /* uncorrectable errors */ | 228 | /* uncorrectable errors */ |
| @@ -449,6 +450,7 @@ EXPORT_SYMBOL(mtk_ecc_get_parity_bits); · 221 unmodified lines | |||
| 449 | 450 | ||
| 450 | static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = { | 451 | static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = { |
| 451 | .err_mask = 0x3f, | 452 | .err_mask = 0x3f, |
| 453 | .err_shift = 8, | ||
| 452 | .ecc_strength = ecc_strength_mt2701, | 454 | .ecc_strength = ecc_strength_mt2701, |
| 453 | .ecc_regs = mt2701_ecc_regs, | 455 | .ecc_regs = mt2701_ecc_regs, |
| 454 | .num_ecc_strength = 20, | 456 | .num_ecc_strength = 20, |
| @@ -459,6 +461,7 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2701 = { · 4 unmodified lines | |||
| 459 | 461 | ||
| 460 | static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = { | 462 | static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = { |
| 461 | .err_mask = 0x7f, | 463 | .err_mask = 0x7f, |
| 464 | .err_shift = 8, | ||
| 462 | .ecc_strength = ecc_strength_mt2712, | 465 | .ecc_strength = ecc_strength_mt2712, |
| 463 | .ecc_regs = mt2712_ecc_regs, | 466 | .ecc_regs = mt2712_ecc_regs, |
| 464 | .num_ecc_strength = 23, | 467 | .num_ecc_strength = 23, |
| @@ -468,10 +471,11 @@ static const struct mtk_ecc_caps mtk_ecc_caps_mt2712 = { · 3 unmodified lines | |||
| 468 | }; | 471 | }; |
| 469 | 472 | ||
| 470 | static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = { | 473 | static const struct mtk_ecc_caps mtk_ecc_caps_mt7622 = { |
| 471 | .err_mask = 0x3f, | 474 | .err_mask = 0x1f, |
| 475 | .err_shift = 5, | ||
| 472 | .ecc_strength = ecc_strength_mt7622, | 476 | .ecc_strength = ecc_strength_mt7622, |
| 473 | .ecc_regs = mt7622_ecc_regs, | 477 | .ecc_regs = mt7622_ecc_regs, |
| 474 | .num_ecc_strength = 7, | 478 | .num_ecc_strength = 5, |
| 475 | .ecc_mode_shift = 4, | 479 | .ecc_mode_shift = 4, |
| 476 | .parity_bits = 13, | 480 | .parity_bits = 13, |
| 477 | .pg_irq_sel = 0, | 481 | .pg_irq_sel = 0, |
| @@ -2651,10 +2651,23 @@ static int qcom_nand_attach_chip(struct nand_chip *chip) · 2650 unmodified lines | |||
| 2651 | ecc->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; | 2651 | ecc->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; |
| 2652 | 2652 | ||
| 2653 | mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops); | 2653 | mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops); |
| 2654 | /* Free the initially allocated BAM transaction for reading the ONFI params */ | ||
| 2655 | if (nandc->props->is_bam) | ||
| 2656 | free_bam_transaction(nandc); | ||
| 2654 | 2657 | ||
| 2655 | nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage, | 2658 | nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage, |
| 2656 | cwperpage); | 2659 | cwperpage); |
| 2657 | 2660 | ||
| 2661 | /* Now allocate the BAM transaction based on updated max_cwperpage */ | ||
| 2662 | if (nandc->props->is_bam) { | ||
| 2663 | nandc->bam_txn = alloc_bam_transaction(nandc); | ||
| 2664 | if (!nandc->bam_txn) { | ||
| 2665 | dev_err(nandc->dev, | ||
| 2666 | "failed to allocate bam transaction\n"); | ||
| 2667 | return -ENOMEM; | ||
| 2668 | } | ||
| 2669 | } | ||
| 2670 | |||
| 2658 | /* | 2671 | /* |
| 2659 | * DATA_UD_BYTES varies based on whether the read/write command protects | 2672 | * DATA_UD_BYTES varies based on whether the read/write command protects |
| 2660 | * spare data with ECC too. We protect spare data by default, so we set | 2673 | * spare data with ECC too. We protect spare data by default, so we set |
| @@ -2955,17 +2968,6 @@ static int qcom_nand_host_init_and_register(struct qcom_nand_controller *nandc, · 294 unmodified lines | |||
| 2955 | if (ret) | 2968 | if (ret) |
| 2956 | return ret; | 2969 | return ret; |
| 2957 | 2970 | ||
| 2958 | if (nandc->props->is_bam) { | ||
| 2959 | free_bam_transaction(nandc); | ||
| 2960 | nandc->bam_txn = alloc_bam_transaction(nandc); | ||
| 2961 | if (!nandc->bam_txn) { | ||
| 2962 | dev_err(nandc->dev, | ||
| 2963 | "failed to allocate bam transaction\n"); | ||
| 2964 | nand_cleanup(chip); | ||
| 2965 | return -ENOMEM; | ||
| 2966 | } | ||
| 2967 | } | ||
| 2968 | |||
| 2969 | ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0); | 2971 | ret = mtd_device_parse_register(mtd, probes, NULL, NULL, 0); |
| 2970 | if (ret) | 2972 | if (ret) |
| 2971 | nand_cleanup(chip); | 2973 | nand_cleanup(chip); |
| @@ -384,7 +384,8 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf, · 383 unmodified lines | |||
| 384 | dma_addr_t dma_addr; | 384 | dma_addr_t dma_addr; |
| 385 | dma_cookie_t cookie; | 385 | dma_cookie_t cookie; |
| 386 | uint32_t reg; | 386 | uint32_t reg; |
| 387 | int ret; | 387 | int ret = 0; |
| 388 | unsigned long time_left; | ||
| 388 | 389 | ||
| 389 | if (dir == DMA_FROM_DEVICE) { | 390 | if (dir == DMA_FROM_DEVICE) { |
| 390 | chan = flctl->chan_fifo0_rx; | 391 | chan = flctl->chan_fifo0_rx; |
| @@ -425,13 +426,14 @@ static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf, · 34 unmodified lines | |||
| 425 | goto out; | 426 | goto out; |
| 426 | } | 427 | } |
| 427 | 428 | ||
| 428 | ret = | 429 | time_left = |
| 429 | wait_for_completion_timeout(&flctl->dma_complete, | 430 | wait_for_completion_timeout(&flctl->dma_complete, |
| 430 | msecs_to_jiffies(3000)); | 431 | msecs_to_jiffies(3000)); |
| 431 | 432 | ||
| 432 | if (ret <= 0) { | 433 | if (time_left == 0) { |
| 433 | dmaengine_terminate_all(chan); | 434 | dmaengine_terminate_all(chan); |
| 434 | dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n"); | 435 | dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n"); |
| 436 | ret = -ETIMEDOUT; | ||
| 435 | } | 437 | } |
| 436 | 438 | ||
| 437 | out: | 439 | out: |
| @@ -441,7 +443,7 @@ out: · 3 unmodified lines | |||
| 441 | 443 | ||
| 442 | dma_unmap_single(chan->device->dev, dma_addr, len, dir); | 444 | dma_unmap_single(chan->device->dev, dma_addr, len, dir); |
| 443 | 445 | ||
| 444 | /* ret > 0 is success */ | 446 | /* ret == 0 is success */ |
| 445 | return ret; | 447 | return ret; |
| 446 | } | 448 | } |
| 447 | 449 | ||
| @@ -465,7 +467,7 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset) · 17 unmodified lines | |||
| 465 | 467 | ||
| 466 | /* initiate DMA transfer */ | 468 | /* initiate DMA transfer */ |
| 467 | if (flctl->chan_fifo0_rx && rlen >= 32 && | 469 | if (flctl->chan_fifo0_rx && rlen >= 32 && |
| 468 | flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE) > 0) | 470 | !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE)) |
| 469 | goto convert; /* DMA success */ | 471 | goto convert; /* DMA success */ |
| 470 | 472 | ||
| 471 | /* do polling transfer */ | 473 | /* do polling transfer */ |
| @@ -524,7 +526,7 @@ static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, · 52 unmodified lines | |||
| 524 | 526 | ||
| 525 | /* initiate DMA transfer */ | 527 | /* initiate DMA transfer */ |
| 526 | if (flctl->chan_fifo0_tx && rlen >= 32 && | 528 | if (flctl->chan_fifo0_tx && rlen >= 32 && |
| 527 | flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE) > 0) | 529 | !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE)) |
| 528 | return; /* DMA success */ | 530 | return; /* DMA success */ |
| 529 | 531 | ||
| 530 | /* do polling transfer */ | 532 | /* do polling transfer */ |
| @@ -241,13 +241,14 @@ struct grcan_device_config { · 240 unmodified lines | |||
| 241 | .rxsize = GRCAN_DEFAULT_BUFFER_SIZE, \ | 241 | .rxsize = GRCAN_DEFAULT_BUFFER_SIZE, \ |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | #define GRCAN_TXBUG_SAFE_GRLIB_VERSION 0x4100 | 244 | #define GRCAN_TXBUG_SAFE_GRLIB_VERSION 4100 |
| 245 | #define GRLIB_VERSION_MASK 0xffff | 245 | #define GRLIB_VERSION_MASK 0xffff |
| 246 | 246 | ||
| 247 | /* GRCAN private data structure */ | 247 | /* GRCAN private data structure */ |
| 248 | struct grcan_priv { | 248 | struct grcan_priv { |
| 249 | struct can_priv can; /* must be the first member */ | 249 | struct can_priv can; /* must be the first member */ |
| 250 | struct net_device *dev; | 250 | struct net_device *dev; |
| 251 | struct device *ofdev_dev; | ||
| 251 | struct napi_struct napi; | 252 | struct napi_struct napi; |
| 252 | 253 | ||
| 253 | struct grcan_registers __iomem *regs; /* ioremap'ed registers */ | 254 | struct grcan_registers __iomem *regs; /* ioremap'ed registers */ |
| @@ -921,7 +922,7 @@ static void grcan_free_dma_buffers(struct net_device *dev) · 667 unmodified lines | |||
| 921 | struct grcan_priv *priv = netdev_priv(dev); | 922 | struct grcan_priv *priv = netdev_priv(dev); |
| 922 | struct grcan_dma *dma = &priv->dma; | 923 | struct grcan_dma *dma = &priv->dma; |
| 923 | 924 | ||
| 924 | dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf, | 925 | dma_free_coherent(priv->ofdev_dev, dma->base_size, dma->base_buf, |
| 925 | dma->base_handle); | 926 | dma->base_handle); |
| 926 | memset(dma, 0, sizeof(*dma)); | 927 | memset(dma, 0, sizeof(*dma)); |
| 927 | } | 928 | } |
| @@ -946,7 +947,7 @@ static int grcan_allocate_dma_buffers(struct net_device *dev, · 18 unmodified lines | |||
| 946 | 947 | ||
| 947 | /* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */ | 948 | /* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */ |
| 948 | dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT; | 949 | dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT; |
| 949 | dma->base_buf = dma_alloc_coherent(&dev->dev, | 950 | dma->base_buf = dma_alloc_coherent(priv->ofdev_dev, |
| 950 | dma->base_size, | 951 | dma->base_size, |
| 951 | &dma->base_handle, | 952 | &dma->base_handle, |
| 952 | GFP_KERNEL); | 953 | GFP_KERNEL); |
| @@ -1102,8 +1103,10 @@ static int grcan_close(struct net_device *dev) · 149 unmodified lines | |||
| 1102 | 1103 | ||
| 1103 | priv->closing = true; | 1104 | priv->closing = true; |
| 1104 | if (priv->need_txbug_workaround) { | 1105 | if (priv->need_txbug_workaround) { |
| 1106 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 1105 | del_timer_sync(&priv->hang_timer); | 1107 | del_timer_sync(&priv->hang_timer); |
| 1106 | del_timer_sync(&priv->rr_timer); | 1108 | del_timer_sync(&priv->rr_timer); |
| 1109 | spin_lock_irqsave(&priv->lock, flags); | ||
| 1107 | } | 1110 | } |
| 1108 | netif_stop_queue(dev); | 1111 | netif_stop_queue(dev); |
| 1109 | grcan_stop_hardware(dev); | 1112 | grcan_stop_hardware(dev); |
| @@ -1122,7 +1125,7 @@ static int grcan_close(struct net_device *dev) · 12 unmodified lines | |||
| 1122 | return 0; | 1125 | return 0; |
| 1123 | } | 1126 | } |
| 1124 | 1127 | ||
| 1125 | static int grcan_transmit_catch_up(struct net_device *dev, int budget) | 1128 | static void grcan_transmit_catch_up(struct net_device *dev) |
| 1126 | { | 1129 | { |
| 1127 | struct grcan_priv *priv = netdev_priv(dev); | 1130 | struct grcan_priv *priv = netdev_priv(dev); |
| 1128 | unsigned long flags; | 1131 | unsigned long flags; |
| @@ -1130,7 +1133,7 @@ static int grcan_transmit_catch_up(struct net_device *dev, int budget) · 1 unmodified line | |||
| 1130 | 1133 | ||
| 1131 | spin_lock_irqsave(&priv->lock, flags); | 1134 | spin_lock_irqsave(&priv->lock, flags); |
| 1132 | 1135 | ||
| 1133 | work_done = catch_up_echo_skb(dev, budget, true); | 1136 | work_done = catch_up_echo_skb(dev, -1, true); |
| 1134 | if (work_done) { | 1137 | if (work_done) { |
| 1135 | if (!priv->resetting && !priv->closing && | 1138 | if (!priv->resetting && !priv->closing && |
| 1136 | !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) | 1139 | !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)) |
| @@ -1144,8 +1147,6 @@ static int grcan_transmit_catch_up(struct net_device *dev, int budget) · 7 unmodified lines | |||
| 1144 | } | 1147 | } |
| 1145 | 1148 | ||
| 1146 | spin_unlock_irqrestore(&priv->lock, flags); | 1149 | spin_unlock_irqrestore(&priv->lock, flags); |
| 1147 | |||
| 1148 | return work_done; | ||
| 1149 | } | 1150 | } |
| 1150 | 1151 | ||
| 1151 | static int grcan_receive(struct net_device *dev, int budget) | 1152 | static int grcan_receive(struct net_device *dev, int budget) |
| @@ -1227,19 +1228,13 @@ static int grcan_poll(struct napi_struct *napi, int budget) · 75 unmodified lines | |||
| 1227 | struct net_device *dev = priv->dev; | 1228 | struct net_device *dev = priv->dev; |
| 1228 | struct grcan_registers __iomem *regs = priv->regs; | 1229 | struct grcan_registers __iomem *regs = priv->regs; |
| 1229 | unsigned long flags; | 1230 | unsigned long flags; |
| 1230 | int tx_work_done, rx_work_done; | 1231 | int work_done; |
| 1231 | int rx_budget = budget / 2; | ||
| 1232 | int tx_budget = budget - rx_budget; | ||
| 1233 | 1232 | ||
| 1234 | /* Half of the budget for receiving messages */ | 1233 | work_done = grcan_receive(dev, budget); |
| 1235 | rx_work_done = grcan_receive(dev, rx_budget); | ||
| 1236 | 1234 | ||
| 1237 | /* Half of the budget for transmitting messages as that can trigger echo | 1235 | grcan_transmit_catch_up(dev); |
| 1238 | * frames being received | ||
| 1239 | */ | ||
| 1240 | tx_work_done = grcan_transmit_catch_up(dev, tx_budget); | ||
| 1241 | 1236 | ||
| 1242 | if (rx_work_done < rx_budget && tx_work_done < tx_budget) { | 1237 | if (work_done < budget) { |
| 1243 | napi_complete(napi); | 1238 | napi_complete(napi); |
| 1244 | 1239 | ||
| 1245 | /* Guarantee no interference with a running reset that otherwise | 1240 | /* Guarantee no interference with a running reset that otherwise |
| @@ -1256,7 +1251,7 @@ static int grcan_poll(struct napi_struct *napi, int budget) · 10 unmodified lines | |||
| 1256 | spin_unlock_irqrestore(&priv->lock, flags); | 1251 | spin_unlock_irqrestore(&priv->lock, flags); |
| 1257 | } | 1252 | } |
| 1258 | 1253 | ||
| 1259 | return rx_work_done + tx_work_done; | 1254 | return work_done; |
| 1260 | } | 1255 | } |
| 1261 | 1256 | ||
| 1262 | /* Work tx bug by waiting while for the risky situation to clear. If that fails, | 1257 | /* Work tx bug by waiting while for the risky situation to clear. If that fails, |
| @@ -1587,6 +1582,7 @@ static int grcan_setup_netdev(struct platform_device *ofdev, · 324 unmodified lines | |||
| 1587 | memcpy(&priv->config, &grcan_module_config, | 1582 | memcpy(&priv->config, &grcan_module_config, |
| 1588 | sizeof(struct grcan_device_config)); | 1583 | sizeof(struct grcan_device_config)); |
| 1589 | priv->dev = dev; | 1584 | priv->dev = dev; |
| 1585 | priv->ofdev_dev = &ofdev->dev; | ||
| 1590 | priv->regs = base; | 1586 | priv->regs = base; |
| 1591 | priv->can.bittiming_const = &grcan_bittiming_const; | 1587 | priv->can.bittiming_const = &grcan_bittiming_const; |
| 1592 | priv->can.do_set_bittiming = grcan_set_bittiming; | 1588 | priv->can.do_set_bittiming = grcan_set_bittiming; |
| @@ -1639,6 +1635,7 @@ exit_free_candev: · 46 unmodified lines | |||
| 1639 | static int grcan_probe(struct platform_device *ofdev) | 1635 | static int grcan_probe(struct platform_device *ofdev) |
| 1640 | { | 1636 | { |
| 1641 | struct device_node *np = ofdev->dev.of_node; | 1637 | struct device_node *np = ofdev->dev.of_node; |
| 1638 | struct device_node *sysid_parent; | ||
| 1642 | u32 sysid, ambafreq; | 1639 | u32 sysid, ambafreq; |
| 1643 | int irq, err; | 1640 | int irq, err; |
| 1644 | void __iomem *base; | 1641 | void __iomem *base; |
| @@ -1647,10 +1644,15 @@ static int grcan_probe(struct platform_device *ofdev) · 2 unmodified lines | |||
| 1647 | /* Compare GRLIB version number with the first that does not | 1644 | /* Compare GRLIB version number with the first that does not |
| 1648 | * have the tx bug (see start_xmit) | 1645 | * have the tx bug (see start_xmit) |
| 1649 | */ | 1646 | */ |
| 1650 | err = of_property_read_u32(np, "systemid", &sysid); | 1647 | sysid_parent = of_find_node_by_path("/ambapp0"); |
| 1651 | if (!err && ((sysid & GRLIB_VERSION_MASK) | 1648 | if (sysid_parent) { |
| 1652 | >= GRCAN_TXBUG_SAFE_GRLIB_VERSION)) | 1649 | of_node_get(sysid_parent); |
| 1653 | txbug = false; | 1650 | err = of_property_read_u32(sysid_parent, "systemid", &sysid); |
| 1651 | if (!err && ((sysid & GRLIB_VERSION_MASK) >= | ||
| 1652 | GRCAN_TXBUG_SAFE_GRLIB_VERSION)) | ||
| 1653 | txbug = false; | ||
| 1654 | of_node_put(sysid_parent); | ||
| 1655 | } | ||
| 1654 | 1656 | ||
| 1655 | err = of_property_read_u32(np, "freq", &ambafreq); | 1657 | err = of_property_read_u32(np, "freq", &ambafreq); |
| 1656 | if (err) { | 1658 | if (err) { |
| @@ -1354,46 +1354,25 @@ static void b53_phylink_get_caps(struct dsa_switch *ds, int port, · 1353 unmodified lines | |||
| 1354 | config->legacy_pre_march2020 = false; | 1354 | config->legacy_pre_march2020 = false; |
| 1355 | } | 1355 | } |
| 1356 | 1356 | ||
| 1357 | int b53_phylink_mac_link_state(struct dsa_switch *ds, int port, | 1357 | static struct phylink_pcs *b53_phylink_mac_select_pcs(struct dsa_switch *ds, |
| 1358 | struct phylink_link_state *state) | 1358 | int port, |
| 1359 | phy_interface_t interface) | ||
| 1359 | { | 1360 | { |
| 1360 | struct b53_device *dev = ds->priv; | 1361 | struct b53_device *dev = ds->priv; |
| 1361 | int ret = -EOPNOTSUPP; | ||
| 1362 | 1362 | ||
| 1363 | if ((phy_interface_mode_is_8023z(state->interface) || | 1363 | if (!dev->ops->phylink_mac_select_pcs) |
| 1364 | state->interface == PHY_INTERFACE_MODE_SGMII) && | 1364 | return NULL; |
| 1365 | dev->ops->serdes_link_state) | ||
| 1366 | ret = dev->ops->serdes_link_state(dev, port, state); | ||
| 1367 | 1365 | ||
| 1368 | return ret; | 1366 | return dev->ops->phylink_mac_select_pcs(dev, port, interface); |
| 1369 | } | 1367 | } |
| 1370 | EXPORT_SYMBOL(b53_phylink_mac_link_state); | ||
| 1371 | 1368 | ||
| 1372 | void b53_phylink_mac_config(struct dsa_switch *ds, int port, | 1369 | void b53_phylink_mac_config(struct dsa_switch *ds, int port, |
| 1373 | unsigned int mode, | 1370 | unsigned int mode, |
| 1374 | const struct phylink_link_state *state) | 1371 | const struct phylink_link_state *state) |
| 1375 | { | 1372 | { |
| 1376 | struct b53_device *dev = ds->priv; | ||
| 1377 | |||
| 1378 | if (mode == MLO_AN_PHY || mode == MLO_AN_FIXED) | ||
| 1379 | return; | ||
| 1380 | |||
| 1381 | if ((phy_interface_mode_is_8023z(state->interface) || | ||
| 1382 | state->interface == PHY_INTERFACE_MODE_SGMII) && | ||
| 1383 | dev->ops->serdes_config) | ||
| 1384 | dev->ops->serdes_config(dev, port, mode, state); | ||
| 1385 | } | 1373 | } |
| 1386 | EXPORT_SYMBOL(b53_phylink_mac_config); | 1374 | EXPORT_SYMBOL(b53_phylink_mac_config); |
| 1387 | 1375 | ||
| 1388 | void b53_phylink_mac_an_restart(struct dsa_switch *ds, int port) | ||
| 1389 | { | ||
| 1390 | struct b53_device *dev = ds->priv; | ||
| 1391 | |||
| 1392 | if (dev->ops->serdes_an_restart) | ||
| 1393 | dev->ops->serdes_an_restart(dev, port); | ||
| 1394 | } | ||
| 1395 | EXPORT_SYMBOL(b53_phylink_mac_an_restart); | ||
| 1396 | |||
| 1397 | void b53_phylink_mac_link_down(struct dsa_switch *ds, int port, | 1376 | void b53_phylink_mac_link_down(struct dsa_switch *ds, int port, |
| 1398 | unsigned int mode, | 1377 | unsigned int mode, |
| 1399 | phy_interface_t interface) | 1378 | phy_interface_t interface) |
| @@ -2269,9 +2248,8 @@ static const struct dsa_switch_ops b53_switch_ops = { · 869 unmodified lines | |||
| 2269 | .phy_write = b53_phy_write16, | 2248 | .phy_write = b53_phy_write16, |
| 2270 | .adjust_link = b53_adjust_link, | 2249 | .adjust_link = b53_adjust_link, |
| 2271 | .phylink_get_caps = b53_phylink_get_caps, | 2250 | .phylink_get_caps = b53_phylink_get_caps, |
| 2272 | .phylink_mac_link_state = b53_phylink_mac_link_state, | 2251 | .phylink_mac_select_pcs = b53_phylink_mac_select_pcs, |
| 2273 | .phylink_mac_config = b53_phylink_mac_config, | 2252 | .phylink_mac_config = b53_phylink_mac_config, |
| 2274 | .phylink_mac_an_restart = b53_phylink_mac_an_restart, | ||
| 2275 | .phylink_mac_link_down = b53_phylink_mac_link_down, | 2253 | .phylink_mac_link_down = b53_phylink_mac_link_down, |
| 2276 | .phylink_mac_link_up = b53_phylink_mac_link_up, | 2254 | .phylink_mac_link_up = b53_phylink_mac_link_up, |
| 2277 | .port_enable = b53_enable_port, | 2255 | .port_enable = b53_enable_port, |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
| 23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
| 24 | #include <linux/phy.h> | 24 | #include <linux/phylink.h> |
| 25 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
| 26 | #include <net/dsa.h> | 26 | #include <net/dsa.h> |
| 27 | 27 | ||
| @@ -29,7 +29,6 @@ · 1 unmodified line | |||
| 29 | 29 | ||
| 30 | struct b53_device; | 30 | struct b53_device; |
| 31 | struct net_device; | 31 | struct net_device; |
| 32 | struct phylink_link_state; | ||
| 33 | 32 | ||
| 34 | struct b53_io_ops { | 33 | struct b53_io_ops { |
| 35 | int (*read8)(struct b53_device *dev, u8 page, u8 reg, u8 *value); | 34 | int (*read8)(struct b53_device *dev, u8 page, u8 reg, u8 *value); |
| @@ -48,13 +47,10 @@ struct b53_io_ops { · 12 unmodified lines | |||
| 48 | void (*irq_disable)(struct b53_device *dev, int port); | 47 | void (*irq_disable)(struct b53_device *dev, int port); |
| 49 | void (*phylink_get_caps)(struct b53_device *dev, int port, | 48 | void (*phylink_get_caps)(struct b53_device *dev, int port, |
| 50 | struct phylink_config *config); | 49 | struct phylink_config *config); |
| 50 | struct phylink_pcs *(*phylink_mac_select_pcs)(struct b53_device *dev, | ||
| 51 | int port, | ||
| 52 | phy_interface_t interface); | ||
| 51 | u8 (*serdes_map_lane)(struct b53_device *dev, int port); | 53 | u8 (*serdes_map_lane)(struct b53_device *dev, int port); |
| 52 | int (*serdes_link_state)(struct b53_device *dev, int port, | ||
| 53 | struct phylink_link_state *state); | ||
| 54 | void (*serdes_config)(struct b53_device *dev, int port, | ||
| 55 | unsigned int mode, | ||
| 56 | const struct phylink_link_state *state); | ||
| 57 | void (*serdes_an_restart)(struct b53_device *dev, int port); | ||
| 58 | void (*serdes_link_set)(struct b53_device *dev, int port, | 54 | void (*serdes_link_set)(struct b53_device *dev, int port, |
| 59 | unsigned int mode, phy_interface_t interface, | 55 | unsigned int mode, phy_interface_t interface, |
| 60 | bool link_up); | 56 | bool link_up); |
| @@ -85,8 +81,15 @@ enum { · 24 unmodified lines | |||
| 85 | BCM7278_DEVICE_ID = 0x7278, | 81 | BCM7278_DEVICE_ID = 0x7278, |
| 86 | }; | 82 | }; |
| 87 | 83 | ||
| 84 | struct b53_pcs { | ||
| 85 | struct phylink_pcs pcs; | ||
| 86 | struct b53_device *dev; | ||
| 87 | u8 lane; | ||
| 88 | }; | ||
| 89 | |||
| 88 | #define B53_N_PORTS 9 | 90 | #define B53_N_PORTS 9 |
| 89 | #define B53_N_PORTS_25 6 | 91 | #define B53_N_PORTS_25 6 |
| 92 | #define B53_N_PCS 2 | ||
| 90 | 93 | ||
| 91 | struct b53_port { | 94 | struct b53_port { |
| 92 | u16 vlan_ctl_mask; | 95 | u16 vlan_ctl_mask; |
| @@ -143,6 +146,8 @@ struct b53_device { · 50 unmodified lines | |||
| 143 | bool vlan_enabled; | 146 | bool vlan_enabled; |
| 144 | unsigned int num_ports; | 147 | unsigned int num_ports; |
| 145 | struct b53_port *ports; | 148 | struct b53_port *ports; |
| 149 | |||
| 150 | struct b53_pcs pcs[B53_N_PCS]; | ||
| 146 | }; | 151 | }; |
| 147 | 152 | ||
| 148 | #define b53_for_each_port(dev, i) \ | 153 | #define b53_for_each_port(dev, i) \ |
| @@ -336,12 +341,9 @@ int b53_br_flags(struct dsa_switch *ds, int port, · 187 unmodified lines | |||
| 336 | struct netlink_ext_ack *extack); | 341 | struct netlink_ext_ack *extack); |
| 337 | int b53_setup_devlink_resources(struct dsa_switch *ds); | 342 | int b53_setup_devlink_resources(struct dsa_switch *ds); |
| 338 | void b53_port_event(struct dsa_switch *ds, int port); | 343 | void b53_port_event(struct dsa_switch *ds, int port); |
| 339 | int b53_phylink_mac_link_state(struct dsa_switch *ds, int port, | ||
| 340 | struct phylink_link_state *state); | ||
| 341 | void b53_phylink_mac_config(struct dsa_switch *ds, int port, | 344 | void b53_phylink_mac_config(struct dsa_switch *ds, int port, |
| 342 | unsigned int mode, | 345 | unsigned int mode, |
| 343 | const struct phylink_link_state *state); | 346 | const struct phylink_link_state *state); |
| 344 | void b53_phylink_mac_an_restart(struct dsa_switch *ds, int port); | ||
| 345 | void b53_phylink_mac_link_down(struct dsa_switch *ds, int port, | 347 | void b53_phylink_mac_link_down(struct dsa_switch *ds, int port, |
| 346 | unsigned int mode, | 348 | unsigned int mode, |
| 347 | phy_interface_t interface); | 349 | phy_interface_t interface); |
| @@ -17,6 +17,11 @@ · 16 unmodified lines | |||
| 17 | #include "b53_serdes.h" | 17 | #include "b53_serdes.h" |
| 18 | #include "b53_regs.h" | 18 | #include "b53_regs.h" |
| 19 | 19 | ||
| 20 | static inline struct b53_pcs *pcs_to_b53_pcs(struct phylink_pcs *pcs) | ||
| 21 | { | ||
| 22 | return container_of(pcs, struct b53_pcs, pcs); | ||
| 23 | } | ||
| 24 | |||
| 20 | static void b53_serdes_write_blk(struct b53_device *dev, u8 offset, u16 block, | 25 | static void b53_serdes_write_blk(struct b53_device *dev, u8 offset, u16 block, |
| 21 | u16 value) | 26 | u16 value) |
| 22 | { | 27 | { |
| @@ -60,51 +65,47 @@ static u16 b53_serdes_read(struct b53_device *dev, u8 lane, · 37 unmodified lines | |||
| 60 | return b53_serdes_read_blk(dev, offset, block); | 65 | return b53_serdes_read_blk(dev, offset, block); |
| 61 | } | 66 | } |
| 62 | 67 | ||
| 63 | void b53_serdes_config(struct b53_device *dev, int port, unsigned int mode, | 68 | static int b53_serdes_config(struct phylink_pcs *pcs, unsigned int mode, |
| 64 | const struct phylink_link_state *state) | 69 | phy_interface_t interface, |
| 70 | const unsigned long *advertising, | ||
| 71 | bool permit_pause_to_mac) | ||
| 65 | { | 72 | { |
| 66 | u8 lane = b53_serdes_map_lane(dev, port); | 73 | struct b53_device *dev = pcs_to_b53_pcs(pcs)->dev; |
| 74 | u8 lane = pcs_to_b53_pcs(pcs)->lane; | ||
| 67 | u16 reg; | 75 | u16 reg; |
| 68 | 76 | ||
| 69 | if (lane == B53_INVALID_LANE) | ||
| 70 | return; | ||
| 71 | |||
| 72 | reg = b53_serdes_read(dev, lane, B53_SERDES_DIGITAL_CONTROL(1), | 77 | reg = b53_serdes_read(dev, lane, B53_SERDES_DIGITAL_CONTROL(1), |
| 73 | SERDES_DIGITAL_BLK); | 78 | SERDES_DIGITAL_BLK); |
| 74 | if (state->interface == PHY_INTERFACE_MODE_1000BASEX) | 79 | if (interface == PHY_INTERFACE_MODE_1000BASEX) |
| 75 | reg |= FIBER_MODE_1000X; | 80 | reg |= FIBER_MODE_1000X; |
| 76 | else | 81 | else |
| 77 | reg &= ~FIBER_MODE_1000X; | 82 | reg &= ~FIBER_MODE_1000X; |
| 78 | b53_serdes_write(dev, lane, B53_SERDES_DIGITAL_CONTROL(1), | 83 | b53_serdes_write(dev, lane, B53_SERDES_DIGITAL_CONTROL(1), |
| 79 | SERDES_DIGITAL_BLK, reg); | 84 | SERDES_DIGITAL_BLK, reg); |
| 85 | |||
| 86 | return 0; | ||
| 80 | } | 87 | } |
| 81 | EXPORT_SYMBOL(b53_serdes_config); | ||
| 82 | 88 | ||
| 83 | void b53_serdes_an_restart(struct b53_device *dev, int port) | 89 | static void b53_serdes_an_restart(struct phylink_pcs *pcs) |
| 84 | { | 90 | { |
| 85 | u8 lane = b53_serdes_map_lane(dev, port); | 91 | struct b53_device *dev = pcs_to_b53_pcs(pcs)->dev; |
| 92 | u8 lane = pcs_to_b53_pcs(pcs)->lane; | ||
| 86 | u16 reg; | 93 | u16 reg; |
| 87 | 94 | ||
| 88 | if (lane == B53_INVALID_LANE) | ||
| 89 | return; | ||
| 90 | |||
| 91 | reg = b53_serdes_read(dev, lane, B53_SERDES_MII_REG(MII_BMCR), | 95 | reg = b53_serdes_read(dev, lane, B53_SERDES_MII_REG(MII_BMCR), |
| 92 | SERDES_MII_BLK); | 96 | SERDES_MII_BLK); |
| 93 | reg |= BMCR_ANRESTART; | 97 | reg |= BMCR_ANRESTART; |
| 94 | b53_serdes_write(dev, lane, B53_SERDES_MII_REG(MII_BMCR), | 98 | b53_serdes_write(dev, lane, B53_SERDES_MII_REG(MII_BMCR), |
| 95 | SERDES_MII_BLK, reg); | 99 | SERDES_MII_BLK, reg); |
| 96 | } | 100 | } |
| 97 | EXPORT_SYMBOL(b53_serdes_an_restart); | ||
| 98 | 101 | ||
| 99 | int b53_serdes_link_state(struct b53_device *dev, int port, | 102 | static void b53_serdes_get_state(struct phylink_pcs *pcs, |
| 100 | struct phylink_link_state *state) | 103 | struct phylink_link_state *state) |
| 101 | { | 104 | { |
| 102 | u8 lane = b53_serdes_map_lane(dev, port); | 105 | struct b53_device *dev = pcs_to_b53_pcs(pcs)->dev; |
| 106 | u8 lane = pcs_to_b53_pcs(pcs)->lane; | ||
| 103 | u16 dig, bmsr; | 107 | u16 dig, bmsr; |
| 104 | 108 | ||
| 105 | if (lane == B53_INVALID_LANE) | ||
| 106 | return 1; | ||
| 107 | |||
| 108 | dig = b53_serdes_read(dev, lane, B53_SERDES_DIGITAL_STATUS, | 109 | dig = b53_serdes_read(dev, lane, B53_SERDES_DIGITAL_STATUS, |
| 109 | SERDES_DIGITAL_BLK); | 110 | SERDES_DIGITAL_BLK); |
| 110 | bmsr = b53_serdes_read(dev, lane, B53_SERDES_MII_REG(MII_BMSR), | 111 | bmsr = b53_serdes_read(dev, lane, B53_SERDES_MII_REG(MII_BMSR), |
| @@ -133,10 +134,7 @@ int b53_serdes_link_state(struct b53_device *dev, int port, · 22 unmodified lines | |||
| 133 | state->pause |= MLO_PAUSE_RX; | 134 | state->pause |= MLO_PAUSE_RX; |
| 134 | if (dig & PAUSE_RESOLUTION_TX_SIDE) | 135 | if (dig & PAUSE_RESOLUTION_TX_SIDE) |
| 135 | state->pause |= MLO_PAUSE_TX; | 136 | state->pause |= MLO_PAUSE_TX; |
| 136 | |||
| 137 | return 0; | ||
| 138 | } | 137 | } |
| 139 | EXPORT_SYMBOL(b53_serdes_link_state); | ||
| 140 | 138 | ||
| 141 | void b53_serdes_link_set(struct b53_device *dev, int port, unsigned int mode, | 139 | void b53_serdes_link_set(struct b53_device *dev, int port, unsigned int mode, |
| 142 | phy_interface_t interface, bool link_up) | 140 | phy_interface_t interface, bool link_up) |
| @@ -158,6 +156,12 @@ void b53_serdes_link_set(struct b53_device *dev, int port, unsigned int mode, · 15 unmodified lines | |||
| 158 | } | 156 | } |
| 159 | EXPORT_SYMBOL(b53_serdes_link_set); | 157 | EXPORT_SYMBOL(b53_serdes_link_set); |
| 160 | 158 | ||
| 159 | static const struct phylink_pcs_ops b53_pcs_ops = { | ||
| 160 | .pcs_get_state = b53_serdes_get_state, | ||
| 161 | .pcs_config = b53_serdes_config, | ||
| 162 | .pcs_an_restart = b53_serdes_an_restart, | ||
| 163 | }; | ||
| 164 | |||
| 161 | void b53_serdes_phylink_get_caps(struct b53_device *dev, int port, | 165 | void b53_serdes_phylink_get_caps(struct b53_device *dev, int port, |
| 162 | struct phylink_config *config) | 166 | struct phylink_config *config) |
| 163 | { | 167 | { |
| @@ -187,9 +191,28 @@ void b53_serdes_phylink_get_caps(struct b53_device *dev, int port, · 23 unmodified lines | |||
| 187 | } | 191 | } |
| 188 | EXPORT_SYMBOL(b53_serdes_phylink_get_caps); | 192 | EXPORT_SYMBOL(b53_serdes_phylink_get_caps); |
| 189 | 193 | ||
| 194 | struct phylink_pcs *b53_serdes_phylink_mac_select_pcs(struct b53_device *dev, | ||
| 195 | int port, | ||
| 196 | phy_interface_t interface) | ||
| 197 | { | ||
| 198 | u8 lane = b53_serdes_map_lane(dev, port); | ||
| 199 | |||
| 200 | if (lane == B53_INVALID_LANE || lane >= B53_N_PCS || | ||
| 201 | !dev->pcs[lane].dev) | ||
| 202 | return NULL; | ||
| 203 | |||
| 204 | if (!phy_interface_mode_is_8023z(interface) && | ||
| 205 | interface != PHY_INTERFACE_MODE_SGMII) | ||
| 206 | return NULL; | ||
| 207 | |||
| 208 | return &dev->pcs[lane].pcs; | ||
| 209 | } | ||
| 210 | EXPORT_SYMBOL(b53_serdes_phylink_mac_select_pcs); | ||
| 211 | |||
| 190 | int b53_serdes_init(struct b53_device *dev, int port) | 212 | int b53_serdes_init(struct b53_device *dev, int port) |
| 191 | { | 213 | { |
| 192 | u8 lane = b53_serdes_map_lane(dev, port); | 214 | u8 lane = b53_serdes_map_lane(dev, port); |
| 215 | struct b53_pcs *pcs; | ||
| 193 | u16 id0, msb, lsb; | 216 | u16 id0, msb, lsb; |
| 194 | 217 | ||
| 195 | if (lane == B53_INVALID_LANE) | 218 | if (lane == B53_INVALID_LANE) |
| @@ -212,6 +235,11 @@ int b53_serdes_init(struct b53_device *dev, int port) · 16 unmodified lines | |||
| 212 | (id0 >> SERDES_ID0_REV_NUM_SHIFT) & SERDES_ID0_REV_NUM_MASK, | 235 | (id0 >> SERDES_ID0_REV_NUM_SHIFT) & SERDES_ID0_REV_NUM_MASK, |
| 213 | (u32)msb << 16 | lsb); | 236 | (u32)msb << 16 | lsb); |
| 214 | 237 | ||
| 238 | pcs = &dev->pcs[lane]; | ||
| 239 | pcs->dev = dev; | ||
| 240 | pcs->lane = lane; | ||
| 241 | pcs->pcs.ops = &b53_pcs_ops; | ||
| 242 | |||
| 215 | return 0; | 243 | return 0; |
| 216 | } | 244 | } |
| 217 | EXPORT_SYMBOL(b53_serdes_init); | 245 | EXPORT_SYMBOL(b53_serdes_init); |
| @@ -107,14 +107,11 @@ static inline u8 b53_serdes_map_lane(struct b53_device *dev, int port) · 106 unmodified lines | |||
| 107 | return dev->ops->serdes_map_lane(dev, port); | 107 | return dev->ops->serdes_map_lane(dev, port); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | int b53_serdes_get_link(struct b53_device *dev, int port); | ||
| 111 | int b53_serdes_link_state(struct b53_device *dev, int port, | ||
| 112 | struct phylink_link_state *state); | ||
| 113 | void b53_serdes_config(struct b53_device *dev, int port, unsigned int mode, | ||
| 114 | const struct phylink_link_state *state); | ||
| 115 | void b53_serdes_an_restart(struct b53_device *dev, int port); | ||
| 116 | void b53_serdes_link_set(struct b53_device *dev, int port, unsigned int mode, | 110 | void b53_serdes_link_set(struct b53_device *dev, int port, unsigned int mode, |
| 117 | phy_interface_t interface, bool link_up); | 111 | phy_interface_t interface, bool link_up); |
| 112 | struct phylink_pcs *b53_serdes_phylink_mac_select_pcs(struct b53_device *dev, | ||
| 113 | int port, | ||
| 114 | phy_interface_t interface); | ||
| 118 | void b53_serdes_phylink_get_caps(struct b53_device *dev, int port, | 115 | void b53_serdes_phylink_get_caps(struct b53_device *dev, int port, |
| 119 | struct phylink_config *config); | 116 | struct phylink_config *config); |
| 120 | #if IS_ENABLED(CONFIG_B53_SERDES) | 117 | #if IS_ENABLED(CONFIG_B53_SERDES) |
| @@ -491,10 +491,8 @@ static const struct b53_io_ops b53_srab_ops = { · 490 unmodified lines | |||
| 491 | .irq_disable = b53_srab_irq_disable, | 491 | .irq_disable = b53_srab_irq_disable, |
| 492 | .phylink_get_caps = b53_srab_phylink_get_caps, | 492 | .phylink_get_caps = b53_srab_phylink_get_caps, |
| 493 | #if IS_ENABLED(CONFIG_B53_SERDES) | 493 | #if IS_ENABLED(CONFIG_B53_SERDES) |
| 494 | .phylink_mac_select_pcs = b53_serdes_phylink_mac_select_pcs, | ||
| 494 | .serdes_map_lane = b53_srab_serdes_map_lane, | 495 | .serdes_map_lane = b53_srab_serdes_map_lane, |
| 495 | .serdes_link_state = b53_serdes_link_state, | ||
| 496 | .serdes_config = b53_serdes_config, | ||
| 497 | .serdes_an_restart = b53_serdes_an_restart, | ||
| 498 | .serdes_link_set = b53_serdes_link_set, | 496 | .serdes_link_set = b53_serdes_link_set, |
| 499 | #endif | 497 | #endif |
| 500 | }; | 498 | }; |
| @@ -809,6 +809,9 @@ static void bcm_sf2_sw_mac_link_down(struct dsa_switch *ds, int port, · 808 unmodified lines | |||
| 809 | struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); | 809 | struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds); |
| 810 | u32 reg, offset; | 810 | u32 reg, offset; |
| 811 | 811 | ||
| 812 | if (priv->wol_ports_mask & BIT(port)) | ||
| 813 | return; | ||
| 814 | |||
| 812 | if (port != core_readl(priv, CORE_IMP0_PRT_ID)) { | 815 | if (port != core_readl(priv, CORE_IMP0_PRT_ID)) { |
| 813 | if (priv->type == BCM4908_DEVICE_ID || | 816 | if (priv->type == BCM4908_DEVICE_ID || |
| 814 | priv->type == BCM7445_DEVICE_ID) | 817 | priv->type == BCM7445_DEVICE_ID) |
| @@ -1681,9 +1681,6 @@ static void gswip_phylink_mac_config(struct dsa_switch *ds, int port, · 1680 unmodified lines | |||
| 1681 | break; | 1681 | break; |
| 1682 | case PHY_INTERFACE_MODE_RMII: | 1682 | case PHY_INTERFACE_MODE_RMII: |
| 1683 | miicfg |= GSWIP_MII_CFG_MODE_RMIIM; | 1683 | miicfg |= GSWIP_MII_CFG_MODE_RMIIM; |
| 1684 | |||
| 1685 | /* Configure the RMII clock as output: */ | ||
| 1686 | miicfg |= GSWIP_MII_CFG_RMII_CLK; | ||
| 1687 | break; | 1684 | break; |
| 1688 | case PHY_INTERFACE_MODE_RGMII: | 1685 | case PHY_INTERFACE_MODE_RGMII: |
| 1689 | case PHY_INTERFACE_MODE_RGMII_ID: | 1686 | case PHY_INTERFACE_MODE_RGMII_ID: |
| @@ -1021,14 +1021,32 @@ static int ksz9477_port_mirror_add(struct dsa_switch *ds, int port, · 1020 unmodified lines | |||
| 1021 | bool ingress, struct netlink_ext_ack *extack) | 1021 | bool ingress, struct netlink_ext_ack *extack) |
| 1022 | { | 1022 | { |
| 1023 | struct ksz_device *dev = ds->priv; | 1023 | struct ksz_device *dev = ds->priv; |
| 1024 | u8 data; | ||
| 1025 | int p; | ||
| 1026 | |||
| 1027 | /* Limit to one sniffer port | ||
| 1028 | * Check if any of the port is already set for sniffing | ||
| 1029 | * If yes, instruct the user to remove the previous entry & exit | ||
| 1030 | */ | ||
| 1031 | for (p = 0; p < dev->port_cnt; p++) { | ||
| 1032 | /* Skip the current sniffing port */ | ||
| 1033 | if (p == mirror->to_local_port) | ||
| 1034 | continue; | ||
| 1035 | |||
| 1036 | ksz_pread8(dev, p, P_MIRROR_CTRL, &data); | ||
| 1037 | |||
| 1038 | if (data & PORT_MIRROR_SNIFFER) { | ||
| 1039 | NL_SET_ERR_MSG_MOD(extack, | ||
| 1040 | "Sniffer port is already configured, delete existing rules & retry"); | ||
| 1041 | return -EBUSY; | ||
| 1042 | } | ||
| 1043 | } | ||
| 1024 | 1044 | ||
| 1025 | if (ingress) | 1045 | if (ingress) |
| 1026 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, true); | 1046 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, true); |
| 1027 | else | 1047 | else |
| 1028 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, true); | 1048 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, true); |
| 1029 | 1049 | ||
| 1030 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_SNIFFER, false); | ||
| 1031 | |||
| 1032 | /* configure mirror port */ | 1050 | /* configure mirror port */ |
| 1033 | ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, | 1051 | ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, |
| 1034 | PORT_MIRROR_SNIFFER, true); | 1052 | PORT_MIRROR_SNIFFER, true); |
| @@ -1042,16 +1060,28 @@ static void ksz9477_port_mirror_del(struct dsa_switch *ds, int port, · 7 unmodified lines | |||
| 1042 | struct dsa_mall_mirror_tc_entry *mirror) | 1060 | struct dsa_mall_mirror_tc_entry *mirror) |
| 1043 | { | 1061 | { |
| 1044 | struct ksz_device *dev = ds->priv; | 1062 | struct ksz_device *dev = ds->priv; |
| 1063 | bool in_use = false; | ||
| 1045 | u8 data; | 1064 | u8 data; |
| 1065 | int p; | ||
| 1046 | 1066 | ||
| 1047 | if (mirror->ingress) | 1067 | if (mirror->ingress) |
| 1048 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, false); | 1068 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_RX, false); |
| 1049 | else | 1069 | else |
| 1050 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, false); | 1070 | ksz_port_cfg(dev, port, P_MIRROR_CTRL, PORT_MIRROR_TX, false); |
| 1051 | 1071 | ||
| 1052 | ksz_pread8(dev, port, P_MIRROR_CTRL, &data); | ||
| 1053 | 1072 | ||
| 1054 | if (!(data & (PORT_MIRROR_RX | PORT_MIRROR_TX))) | 1073 | /* Check if any of the port is still referring to sniffer port */ |
| 1074 | for (p = 0; p < dev->port_cnt; p++) { | ||
| 1075 | ksz_pread8(dev, p, P_MIRROR_CTRL, &data); | ||
| 1076 | |||
| 1077 | if ((data & (PORT_MIRROR_RX | PORT_MIRROR_TX))) { | ||
| 1078 | in_use = true; | ||
| 1079 | break; | ||
| 1080 | } | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | /* delete sniffing if there are no other mirroring rules */ | ||
| 1084 | if (!in_use) | ||
| 1055 | ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, | 1085 | ksz_port_cfg(dev, mirror->to_local_port, P_MIRROR_CTRL, |
| 1056 | PORT_MIRROR_SNIFFER, false); | 1086 | PORT_MIRROR_SNIFFER, false); |
| 1057 | } | 1087 | } |
| @@ -2229,6 +2229,7 @@ mt7530_setup(struct dsa_switch *ds) · 2228 unmodified lines | |||
| 2229 | ret = of_get_phy_mode(mac_np, &interface); | 2229 | ret = of_get_phy_mode(mac_np, &interface); |
| 2230 | if (ret && ret != -ENODEV) { | 2230 | if (ret && ret != -ENODEV) { |
| 2231 | of_node_put(mac_np); | 2231 | of_node_put(mac_np); |
| 2232 | of_node_put(phy_node); | ||
| 2232 | return ret; | 2233 | return ret; |
| 2233 | } | 2234 | } |
| 2234 | id = of_mdio_parse_addr(ds->dev, phy_node); | 2235 | id = of_mdio_parse_addr(ds->dev, phy_node); |
| @@ -40,8 +40,9 @@ int mv88e6xxx_port_hidden_wait(struct mv88e6xxx_chip *chip) · 39 unmodified lines | |||
| 40 | { | 40 | { |
| 41 | int bit = __bf_shf(MV88E6XXX_PORT_RESERVED_1A_BUSY); | 41 | int bit = __bf_shf(MV88E6XXX_PORT_RESERVED_1A_BUSY); |
| 42 | 42 | ||
| 43 | return mv88e6xxx_wait_bit(chip, MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT, | 43 | return mv88e6xxx_port_wait_bit(chip, |
| 44 | MV88E6XXX_PORT_RESERVED_1A, bit, 0); | 44 | MV88E6XXX_PORT_RESERVED_1A_CTRL_PORT, |
| 45 | MV88E6XXX_PORT_RESERVED_1A, bit, 0); | ||
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port, | 48 | int mv88e6xxx_port_hidden_read(struct mv88e6xxx_chip *chip, int block, int port, |
| @@ -403,6 +403,7 @@ static int felix_update_trapping_destinations(struct dsa_switch *ds, · 402 unmodified lines | |||
| 403 | { | 403 | { |
| 404 | struct ocelot *ocelot = ds->priv; | 404 | struct ocelot *ocelot = ds->priv; |
| 405 | struct felix *felix = ocelot_to_felix(ocelot); | 405 | struct felix *felix = ocelot_to_felix(ocelot); |
| 406 | struct ocelot_vcap_block *block_vcap_is2; | ||
| 406 | struct ocelot_vcap_filter *trap; | 407 | struct ocelot_vcap_filter *trap; |
| 407 | enum ocelot_mask_mode mask_mode; | 408 | enum ocelot_mask_mode mask_mode; |
| 408 | unsigned long port_mask; | 409 | unsigned long port_mask; |
| @@ -422,9 +423,13 @@ static int felix_update_trapping_destinations(struct dsa_switch *ds, · 13 unmodified lines | |||
| 422 | /* We are sure that "cpu" was found, otherwise | 423 | /* We are sure that "cpu" was found, otherwise |
| 423 | * dsa_tree_setup_default_cpu() would have failed earlier. | 424 | * dsa_tree_setup_default_cpu() would have failed earlier. |
| 424 | */ | 425 | */ |
| 426 | block_vcap_is2 = &ocelot->block[VCAP_IS2]; | ||
| 425 | 427 | ||
| 426 | /* Make sure all traps are set up for that destination */ | 428 | /* Make sure all traps are set up for that destination */ |
| 427 | list_for_each_entry(trap, &ocelot->traps, trap_list) { | 429 | list_for_each_entry(trap, &block_vcap_is2->rules, list) { |
| 430 | if (!trap->is_trap) | ||
| 431 | continue; | ||
| 432 | |||
| 428 | /* Figure out the current trapping destination */ | 433 | /* Figure out the current trapping destination */ |
| 429 | if (using_tag_8021q) { | 434 | if (using_tag_8021q) { |
| 430 | /* Redirect to the tag_8021q CPU port. If timestamps | 435 | /* Redirect to the tag_8021q CPU port. If timestamps |
| @@ -267,7 +267,6 @@ static const struct of_device_id realtek_mdio_of_match[] = { · 266 unmodified lines | |||
| 267 | #endif | 267 | #endif |
| 268 | #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB) | 268 | #if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB) |
| 269 | { .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, }, | 269 | { .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, }, |
| 270 | { .compatible = "realtek,rtl8367s", .data = &rtl8365mb_variant, }, | ||
| 271 | #endif | 270 | #endif |
| 272 | { /* sentinel */ }, | 271 | { /* sentinel */ }, |
| 273 | }; | 272 | }; |
| @@ -551,10 +551,6 @@ static const struct of_device_id realtek_smi_of_match[] = { · 550 unmodified lines | |||
| 551 | .compatible = "realtek,rtl8365mb", | 551 | .compatible = "realtek,rtl8365mb", |
| 552 | .data = &rtl8365mb_variant, | 552 | .data = &rtl8365mb_variant, |
| 553 | }, | 553 | }, |
| 554 | { | ||
| 555 | .compatible = "realtek,rtl8367s", | ||
| 556 | .data = &rtl8365mb_variant, | ||
| 557 | }, | ||
| 558 | #endif | 554 | #endif |
| 559 | { /* sentinel */ }, | 555 | { /* sentinel */ }, |
| 560 | }; | 556 | }; |
| @@ -449,7 +449,7 @@ static int aq_pm_freeze(struct device *dev) · 448 unmodified lines | |||
| 449 | 449 | ||
| 450 | static int aq_pm_suspend_poweroff(struct device *dev) | 450 | static int aq_pm_suspend_poweroff(struct device *dev) |
| 451 | { | 451 | { |
| 452 | return aq_suspend_common(dev, false); | 452 | return aq_suspend_common(dev, true); |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | static int aq_pm_thaw(struct device *dev) | 455 | static int aq_pm_thaw(struct device *dev) |
| @@ -459,7 +459,7 @@ static int aq_pm_thaw(struct device *dev) · 3 unmodified lines | |||
| 459 | 459 | ||
| 460 | static int aq_pm_resume_restore(struct device *dev) | 460 | static int aq_pm_resume_restore(struct device *dev) |
| 461 | { | 461 | { |
| 462 | return atl_resume_common(dev, false); | 462 | return atl_resume_common(dev, true); |
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | static const struct dev_pm_ops aq_pm_ops = { | 465 | static const struct dev_pm_ops aq_pm_ops = { |
| @@ -346,7 +346,6 @@ int aq_ring_rx_clean(struct aq_ring_s *self, · 345 unmodified lines | |||
| 346 | int budget) | 346 | int budget) |
| 347 | { | 347 | { |
| 348 | struct net_device *ndev = aq_nic_get_ndev(self->aq_nic); | 348 | struct net_device *ndev = aq_nic_get_ndev(self->aq_nic); |
| 349 | bool is_rsc_completed = true; | ||
| 350 | int err = 0; | 349 | int err = 0; |
| 351 | 350 | ||
| 352 | for (; (self->sw_head != self->hw_head) && budget; | 351 | for (; (self->sw_head != self->hw_head) && budget; |
| @@ -364,12 +363,17 @@ int aq_ring_rx_clean(struct aq_ring_s *self, · 11 unmodified lines | |||
| 364 | continue; | 363 | continue; |
| 365 | 364 | ||
| 366 | if (!buff->is_eop) { | 365 | if (!buff->is_eop) { |
| 366 | unsigned int frag_cnt = 0U; | ||
| 367 | buff_ = buff; | 367 | buff_ = buff; |
| 368 | do { | 368 | do { |
| 369 | bool is_rsc_completed = true; | ||
| 370 | |||
| 369 | if (buff_->next >= self->size) { | 371 | if (buff_->next >= self->size) { |
| 370 | err = -EIO; | 372 | err = -EIO; |
| 371 | goto err_exit; | 373 | goto err_exit; |
| 372 | } | 374 | } |
| 375 | |||
| 376 | frag_cnt++; | ||
| 373 | next_ = buff_->next, | 377 | next_ = buff_->next, |
| 374 | buff_ = &self->buff_ring[next_]; | 378 | buff_ = &self->buff_ring[next_]; |
| 375 | is_rsc_completed = | 379 | is_rsc_completed = |
| @@ -377,18 +381,17 @@ int aq_ring_rx_clean(struct aq_ring_s *self, · 1 unmodified line | |||
| 377 | next_, | 381 | next_, |
| 378 | self->hw_head); | 382 | self->hw_head); |
| 379 | 383 | ||
| 380 | if (unlikely(!is_rsc_completed)) | 384 | if (unlikely(!is_rsc_completed) || |
| 381 | break; | 385 | frag_cnt > MAX_SKB_FRAGS) { |
| 386 | err = 0; | ||
| 387 | goto err_exit; | ||
| 388 | } | ||
| 382 | 389 | ||
| 383 | buff->is_error |= buff_->is_error; | 390 | buff->is_error |= buff_->is_error; |
| 384 | buff->is_cso_err |= buff_->is_cso_err; | 391 | buff->is_cso_err |= buff_->is_cso_err; |
| 385 | 392 | ||
| 386 | } while (!buff_->is_eop); | 393 | } while (!buff_->is_eop); |
| 387 | 394 | ||
| 388 | if (!is_rsc_completed) { | ||
| 389 | err = 0; | ||
| 390 | goto err_exit; | ||
| 391 | } | ||
| 392 | if (buff->is_error || | 395 | if (buff->is_error || |
| 393 | (buff->is_lro && buff->is_cso_err)) { | 396 | (buff->is_lro && buff->is_cso_err)) { |
| 394 | buff_ = buff; | 397 | buff_ = buff; |
| @@ -446,7 +449,7 @@ int aq_ring_rx_clean(struct aq_ring_s *self, · 51 unmodified lines | |||
| 446 | ALIGN(hdr_len, sizeof(long))); | 449 | ALIGN(hdr_len, sizeof(long))); |
| 447 | 450 | ||
| 448 | if (buff->len - hdr_len > 0) { | 451 | if (buff->len - hdr_len > 0) { |
| 449 | skb_add_rx_frag(skb, 0, buff->rxdata.page, | 452 | skb_add_rx_frag(skb, i++, buff->rxdata.page, |
| 450 | buff->rxdata.pg_off + hdr_len, | 453 | buff->rxdata.pg_off + hdr_len, |
| 451 | buff->len - hdr_len, | 454 | buff->len - hdr_len, |
| 452 | AQ_CFG_RX_FRAME_MAX); | 455 | AQ_CFG_RX_FRAME_MAX); |
| @@ -455,7 +458,6 @@ int aq_ring_rx_clean(struct aq_ring_s *self, · 2 unmodified lines | |||
| 455 | 458 | ||
| 456 | if (!buff->is_eop) { | 459 | if (!buff->is_eop) { |
| 457 | buff_ = buff; | 460 | buff_ = buff; |
| 458 | i = 1U; | ||
| 459 | do { | 461 | do { |
| 460 | next_ = buff_->next; | 462 | next_ = buff_->next; |
| 461 | buff_ = &self->buff_ring[next_]; | 463 | buff_ = &self->buff_ring[next_]; |
| @@ -889,6 +889,13 @@ int hw_atl_b0_hw_ring_tx_head_update(struct aq_hw_s *self, · 888 unmodified lines | |||
| 889 | err = -ENXIO; | 889 | err = -ENXIO; |
| 890 | goto err_exit; | 890 | goto err_exit; |
| 891 | } | 891 | } |
| 892 | |||
| 893 | /* Validate that the new hw_head_ is reasonable. */ | ||
| 894 | if (hw_head_ >= ring->size) { | ||
| 895 | err = -ENXIO; | ||
| 896 | goto err_exit; | ||
| 897 | } | ||
| 898 | |||
| 892 | ring->hw_head = hw_head_; | 899 | ring->hw_head = hw_head_; |
| 893 | err = aq_hw_err_from_flags(self); | 900 | err = aq_hw_err_from_flags(self); |
| 894 | 901 | ||
| @@ -14153,10 +14153,6 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) · 14152 unmodified lines | |||
| 14153 | 14153 | ||
| 14154 | /* Stop Tx */ | 14154 | /* Stop Tx */ |
| 14155 | bnx2x_tx_disable(bp); | 14155 | bnx2x_tx_disable(bp); |
| 14156 | /* Delete all NAPI objects */ | ||
| 14157 | bnx2x_del_all_napi(bp); | ||
| 14158 | if (CNIC_LOADED(bp)) | ||
| 14159 | bnx2x_del_all_napi_cnic(bp); | ||
| 14160 | netdev_reset_tc(bp->dev); | 14156 | netdev_reset_tc(bp->dev); |
| 14161 | 14157 | ||
| 14162 | del_timer_sync(&bp->timer); | 14158 | del_timer_sync(&bp->timer); |
| @@ -14261,6 +14257,11 @@ static pci_ers_result_t bnx2x_io_slot_reset(struct pci_dev *pdev) · 98 unmodified lines | |||
| 14261 | bnx2x_drain_tx_queues(bp); | 14257 | bnx2x_drain_tx_queues(bp); |
| 14262 | bnx2x_send_unload_req(bp, UNLOAD_RECOVERY); | 14258 | bnx2x_send_unload_req(bp, UNLOAD_RECOVERY); |
| 14263 | bnx2x_netif_stop(bp, 1); | 14259 | bnx2x_netif_stop(bp, 1); |
| 14260 | bnx2x_del_all_napi(bp); | ||
| 14261 | |||
| 14262 | if (CNIC_LOADED(bp)) | ||
| 14263 | bnx2x_del_all_napi_cnic(bp); | ||
| 14264 | |||
| 14264 | bnx2x_free_irq(bp); | 14265 | bnx2x_free_irq(bp); |
| 14265 | 14266 | ||
| 14266 | /* Report UNLOAD_DONE to MCP */ | 14267 | /* Report UNLOAD_DONE to MCP */ |
| @@ -2707,6 +2707,10 @@ static int bnxt_poll_p5(struct napi_struct *napi, int budget) · 2706 unmodified lines | |||
| 2707 | u32 idx = le32_to_cpu(nqcmp->cq_handle_low); | 2707 | u32 idx = le32_to_cpu(nqcmp->cq_handle_low); |
| 2708 | struct bnxt_cp_ring_info *cpr2; | 2708 | struct bnxt_cp_ring_info *cpr2; |
| 2709 | 2709 | ||
| 2710 | /* No more budget for RX work */ | ||
| 2711 | if (budget && work_done >= budget && idx == BNXT_RX_HDL) | ||
| 2712 | break; | ||
| 2713 | |||
| 2710 | cpr2 = cpr->cp_ring_arr[idx]; | 2714 | cpr2 = cpr->cp_ring_arr[idx]; |
| 2711 | work_done += __bnxt_poll_work(bp, cpr2, | 2715 | work_done += __bnxt_poll_work(bp, cpr2, |
| 2712 | budget - work_done); | 2716 | budget - work_done); |
| @@ -10983,7 +10987,7 @@ static bool bnxt_rfs_capable(struct bnxt *bp) · 8270 unmodified lines | |||
| 10983 | 10987 | ||
| 10984 | if (bp->flags & BNXT_FLAG_CHIP_P5) | 10988 | if (bp->flags & BNXT_FLAG_CHIP_P5) |
| 10985 | return bnxt_rfs_supported(bp); | 10989 | return bnxt_rfs_supported(bp); |
| 10986 | if (!(bp->flags & BNXT_FLAG_MSIX_CAP) || !bnxt_can_reserve_rings(bp)) | 10990 | if (!(bp->flags & BNXT_FLAG_MSIX_CAP) || !bnxt_can_reserve_rings(bp) || !bp->rx_nr_rings) |
| 10987 | return false; | 10991 | return false; |
| 10988 | 10992 | ||
| 10989 | vnics = 1 + bp->rx_nr_rings; | 10993 | vnics = 1 + bp->rx_nr_rings; |
| @@ -13234,10 +13238,9 @@ static int bnxt_init_dflt_ring_mode(struct bnxt *bp) · 2244 unmodified lines | |||
| 13234 | goto init_dflt_ring_err; | 13238 | goto init_dflt_ring_err; |
| 13235 | 13239 | ||
| 13236 | bp->tx_nr_rings_per_tc = bp->tx_nr_rings; | 13240 | bp->tx_nr_rings_per_tc = bp->tx_nr_rings; |
| 13237 | if (bnxt_rfs_supported(bp) && bnxt_rfs_capable(bp)) { | 13241 | |
| 13238 | bp->flags |= BNXT_FLAG_RFS; | 13242 | bnxt_set_dflt_rfs(bp); |
| 13239 | bp->dev->features |= NETIF_F_NTUPLE; | 13243 | |
| 13240 | } | ||
| 13241 | init_dflt_ring_err: | 13244 | init_dflt_ring_err: |
| 13242 | bnxt_ulp_irq_restart(bp, rc); | 13245 | bnxt_ulp_irq_restart(bp, rc); |
| 13243 | return rc; | 13246 | return rc; |
| @@ -846,13 +846,6 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg) · 845 unmodified lines | |||
| 846 | if (rc) | 846 | if (rc) |
| 847 | return rc; | 847 | return rc; |
| 848 | 848 | ||
| 849 | if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC) { | ||
| 850 | bnxt_ptp_timecounter_init(bp, false); | ||
| 851 | rc = bnxt_ptp_init_rtc(bp, phc_cfg); | ||
| 852 | if (rc) | ||
| 853 | goto out; | ||
| 854 | } | ||
| 855 | |||
| 856 | if (ptp->ptp_clock && bnxt_pps_config_ok(bp)) | 849 | if (ptp->ptp_clock && bnxt_pps_config_ok(bp)) |
| 857 | return 0; | 850 | return 0; |
| 858 | 851 | ||
| @@ -861,8 +854,14 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg) · 2 unmodified lines | |||
| 861 | atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS); | 854 | atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS); |
| 862 | spin_lock_init(&ptp->ptp_lock); | 855 | spin_lock_init(&ptp->ptp_lock); |
| 863 | 856 | ||
| 864 | if (!(bp->fw_cap & BNXT_FW_CAP_PTP_RTC)) | 857 | if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC) { |
| 858 | bnxt_ptp_timecounter_init(bp, false); | ||
| 859 | rc = bnxt_ptp_init_rtc(bp, phc_cfg); | ||
| 860 | if (rc) | ||
| 861 | goto out; | ||
| 862 | } else { | ||
| 865 | bnxt_ptp_timecounter_init(bp, true); | 863 | bnxt_ptp_timecounter_init(bp, true); |
| 864 | } | ||
| 866 | 865 | ||
| 867 | ptp->ptp_info = bnxt_ptp_caps; | 866 | ptp->ptp_info = bnxt_ptp_caps; |
| 868 | if ((bp->fw_cap & BNXT_FW_CAP_PTP_PPS)) { | 867 | if ((bp->fw_cap & BNXT_FW_CAP_PTP_PPS)) { |
| @@ -2035,6 +2035,11 @@ static struct sk_buff *bcmgenet_add_tsb(struct net_device *dev, · 2034 unmodified lines | |||
| 2035 | return skb; | 2035 | return skb; |
| 2036 | } | 2036 | } |
| 2037 | 2037 | ||
| 2038 | static void bcmgenet_hide_tsb(struct sk_buff *skb) | ||
| 2039 | { | ||
| 2040 | __skb_pull(skb, sizeof(struct status_64)); | ||
| 2041 | } | ||
| 2042 | |||
| 2038 | static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) | 2043 | static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) |
| 2039 | { | 2044 | { |
| 2040 | struct bcmgenet_priv *priv = netdev_priv(dev); | 2045 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| @@ -2141,6 +2146,8 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev) · 100 unmodified lines | |||
| 2141 | } | 2146 | } |
| 2142 | 2147 | ||
| 2143 | GENET_CB(skb)->last_cb = tx_cb_ptr; | 2148 | GENET_CB(skb)->last_cb = tx_cb_ptr; |
| 2149 | |||
| 2150 | bcmgenet_hide_tsb(skb); | ||
| 2144 | skb_tx_timestamp(skb); | 2151 | skb_tx_timestamp(skb); |
| 2145 | 2152 | ||
| 2146 | /* Decrement total BD count and advance our write pointer */ | 2153 | /* Decrement total BD count and advance our write pointer */ |
| @@ -3992,6 +3999,10 @@ static int bcmgenet_probe(struct platform_device *pdev) · 1845 unmodified lines | |||
| 3992 | goto err; | 3999 | goto err; |
| 3993 | } | 4000 | } |
| 3994 | priv->wol_irq = platform_get_irq_optional(pdev, 2); | 4001 | priv->wol_irq = platform_get_irq_optional(pdev, 2); |
| 4002 | if (priv->wol_irq == -EPROBE_DEFER) { | ||
| 4003 | err = priv->wol_irq; | ||
| 4004 | goto err; | ||
| 4005 | } | ||
| 3995 | 4006 | ||
| 3996 | priv->base = devm_platform_ioremap_resource(pdev, 0); | 4007 | priv->base = devm_platform_ioremap_resource(pdev, 0); |
| 3997 | if (IS_ERR(priv->base)) { | 4008 | if (IS_ERR(priv->base)) { |
| @@ -59,7 +59,7 @@ struct nicpf { · 58 unmodified lines | |||
| 59 | 59 | ||
| 60 | /* MSI-X */ | 60 | /* MSI-X */ |
| 61 | u8 num_vec; | 61 | u8 num_vec; |
| 62 | bool irq_allocated[NIC_PF_MSIX_VECTORS]; | 62 | unsigned int irq_allocated[NIC_PF_MSIX_VECTORS]; |
| 63 | char irq_name[NIC_PF_MSIX_VECTORS][20]; | 63 | char irq_name[NIC_PF_MSIX_VECTORS][20]; |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| @@ -1150,7 +1150,7 @@ static irqreturn_t nic_mbx_intr_handler(int irq, void *nic_irq) · 1084 unmodified lines | |||
| 1150 | u64 intr; | 1150 | u64 intr; |
| 1151 | u8 vf; | 1151 | u8 vf; |
| 1152 | 1152 | ||
| 1153 | if (irq == pci_irq_vector(nic->pdev, NIC_PF_INTR_ID_MBOX0)) | 1153 | if (irq == nic->irq_allocated[NIC_PF_INTR_ID_MBOX0]) |
| 1154 | mbx = 0; | 1154 | mbx = 0; |
| 1155 | else | 1155 | else |
| 1156 | mbx = 1; | 1156 | mbx = 1; |
| @@ -1176,14 +1176,14 @@ static void nic_free_all_interrupts(struct nicpf *nic) · 19 unmodified lines | |||
| 1176 | 1176 | ||
| 1177 | for (irq = 0; irq < nic->num_vec; irq++) { | 1177 | for (irq = 0; irq < nic->num_vec; irq++) { |
| 1178 | if (nic->irq_allocated[irq]) | 1178 | if (nic->irq_allocated[irq]) |
| 1179 | free_irq(pci_irq_vector(nic->pdev, irq), nic); | 1179 | free_irq(nic->irq_allocated[irq], nic); |
| 1180 | nic->irq_allocated[irq] = false; | 1180 | nic->irq_allocated[irq] = 0; |
| 1181 | } | 1181 | } |
| 1182 | } | 1182 | } |
| 1183 | 1183 | ||
| 1184 | static int nic_register_interrupts(struct nicpf *nic) | 1184 | static int nic_register_interrupts(struct nicpf *nic) |
| 1185 | { | 1185 | { |
| 1186 | int i, ret; | 1186 | int i, ret, irq; |
| 1187 | nic->num_vec = pci_msix_vec_count(nic->pdev); | 1187 | nic->num_vec = pci_msix_vec_count(nic->pdev); |
| 1188 | 1188 | ||
| 1189 | /* Enable MSI-X */ | 1189 | /* Enable MSI-X */ |
| @@ -1201,13 +1201,13 @@ static int nic_register_interrupts(struct nicpf *nic) · 11 unmodified lines | |||
| 1201 | sprintf(nic->irq_name[i], | 1201 | sprintf(nic->irq_name[i], |
| 1202 | "NICPF Mbox%d", (i - NIC_PF_INTR_ID_MBOX0)); | 1202 | "NICPF Mbox%d", (i - NIC_PF_INTR_ID_MBOX0)); |
| 1203 | 1203 | ||
| 1204 | ret = request_irq(pci_irq_vector(nic->pdev, i), | 1204 | irq = pci_irq_vector(nic->pdev, i); |
| 1205 | nic_mbx_intr_handler, 0, | 1205 | ret = request_irq(irq, nic_mbx_intr_handler, 0, |
| 1206 | nic->irq_name[i], nic); | 1206 | nic->irq_name[i], nic); |
| 1207 | if (ret) | 1207 | if (ret) |
| 1208 | goto fail; | 1208 | goto fail; |
| 1209 | 1209 | ||
| 1210 | nic->irq_allocated[i] = true; | 1210 | nic->irq_allocated[i] = irq; |
| 1211 | } | 1211 | } |
| 1212 | 1212 | ||
| 1213 | /* Enable mailbox interrupt */ | 1213 | /* Enable mailbox interrupt */ |
| @@ -2793,14 +2793,14 @@ int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p) · 2792 unmodified lines | |||
| 2793 | goto out; | 2793 | goto out; |
| 2794 | na = ret; | 2794 | na = ret; |
| 2795 | 2795 | ||
| 2796 | memcpy(p->id, vpd + id, min_t(int, id_len, ID_LEN)); | 2796 | memcpy(p->id, vpd + id, min_t(unsigned int, id_len, ID_LEN)); |
| 2797 | strim(p->id); | 2797 | strim(p->id); |
| 2798 | memcpy(p->sn, vpd + sn, min_t(int, sn_len, SERNUM_LEN)); | 2798 | memcpy(p->sn, vpd + sn, min_t(unsigned int, sn_len, SERNUM_LEN)); |
| 2799 | strim(p->sn); | 2799 | strim(p->sn); |
| 2800 | memcpy(p->pn, vpd + pn, min_t(int, pn_len, PN_LEN)); | 2800 | memcpy(p->pn, vpd + pn, min_t(unsigned int, pn_len, PN_LEN)); |
| 2801 | strim(p->pn); | 2801 | strim(p->pn); |
| 2802 | memcpy(p->na, vpd + na, min_t(int, na_len, MACADDR_LEN)); | 2802 | memcpy(p->na, vpd + na, min_t(unsigned int, na_len, MACADDR_LEN)); |
| 2803 | strim((char *)p->na); | 2803 | strim(p->na); |
| 2804 | 2804 | ||
| 2805 | out: | 2805 | out: |
| 2806 | vfree(vpd); | 2806 | vfree(vpd); |
| @@ -1399,8 +1399,10 @@ static int tulip_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 1398 unmodified lines | |||
| 1399 | 1399 | ||
| 1400 | /* alloc_etherdev ensures aligned and zeroed private structures */ | 1400 | /* alloc_etherdev ensures aligned and zeroed private structures */ |
| 1401 | dev = alloc_etherdev (sizeof (*tp)); | 1401 | dev = alloc_etherdev (sizeof (*tp)); |
| 1402 | if (!dev) | 1402 | if (!dev) { |
| 1403 | pci_disable_device(pdev); | ||
| 1403 | return -ENOMEM; | 1404 | return -ENOMEM; |
| 1405 | } | ||
| 1404 | 1406 | ||
| 1405 | SET_NETDEV_DEV(dev, &pdev->dev); | 1407 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 1406 | if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { | 1408 | if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { |
| @@ -1785,6 +1787,7 @@ err_out_free_res: · 378 unmodified lines | |||
| 1785 | 1787 | ||
| 1786 | err_out_free_netdev: | 1788 | err_out_free_netdev: |
| 1787 | free_netdev (dev); | 1789 | free_netdev (dev); |
| 1790 | pci_disable_device(pdev); | ||
| 1788 | return -ENODEV; | 1791 | return -ENODEV; |
| 1789 | } | 1792 | } |
| 1790 | 1793 | ||
| @@ -297,10 +297,6 @@ int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data) · 296 unmodified lines | |||
| 297 | if (tc < 0 || tc >= priv->num_tx_rings) | 297 | if (tc < 0 || tc >= priv->num_tx_rings) |
| 298 | return -EINVAL; | 298 | return -EINVAL; |
| 299 | 299 | ||
| 300 | /* Do not support TXSTART and TX CSUM offload simutaniously */ | ||
| 301 | if (ndev->features & NETIF_F_CSUM_MASK) | ||
| 302 | return -EBUSY; | ||
| 303 | |||
| 304 | /* TSD and Qbv are mutually exclusive in hardware */ | 300 | /* TSD and Qbv are mutually exclusive in hardware */ |
| 305 | if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE) | 301 | if (enetc_rd(&priv->si->hw, ENETC_QBV_PTGCR_OFFSET) & ENETC_QBV_TGE) |
| 306 | return -EBUSY; | 302 | return -EBUSY; |
| @@ -3731,7 +3731,7 @@ static int fec_enet_init_stop_mode(struct fec_enet_private *fep, · 3730 unmodified lines | |||
| 3731 | ARRAY_SIZE(out_val)); | 3731 | ARRAY_SIZE(out_val)); |
| 3732 | if (ret) { | 3732 | if (ret) { |
| 3733 | dev_dbg(&fep->pdev->dev, "no stop mode property\n"); | 3733 | dev_dbg(&fep->pdev->dev, "no stop mode property\n"); |
| 3734 | return ret; | 3734 | goto out; |
| 3735 | } | 3735 | } |
| 3736 | 3736 | ||
| 3737 | fep->stop_gpr.gpr = syscon_node_to_regmap(gpr_np); | 3737 | fep->stop_gpr.gpr = syscon_node_to_regmap(gpr_np); |
| @@ -1065,19 +1065,23 @@ int hns_mac_init(struct dsaf_device *dsaf_dev) · 1064 unmodified lines | |||
| 1065 | device_for_each_child_node(dsaf_dev->dev, child) { | 1065 | device_for_each_child_node(dsaf_dev->dev, child) { |
| 1066 | ret = fwnode_property_read_u32(child, "reg", &port_id); | 1066 | ret = fwnode_property_read_u32(child, "reg", &port_id); |
| 1067 | if (ret) { | 1067 | if (ret) { |
| 1068 | fwnode_handle_put(child); | ||
| 1068 | dev_err(dsaf_dev->dev, | 1069 | dev_err(dsaf_dev->dev, |
| 1069 | "get reg fail, ret=%d!\n", ret); | 1070 | "get reg fail, ret=%d!\n", ret); |
| 1070 | return ret; | 1071 | return ret; |
| 1071 | } | 1072 | } |
| 1072 | if (port_id >= max_port_num) { | 1073 | if (port_id >= max_port_num) { |
| 1074 | fwnode_handle_put(child); | ||
| 1073 | dev_err(dsaf_dev->dev, | 1075 | dev_err(dsaf_dev->dev, |
| 1074 | "reg(%u) out of range!\n", port_id); | 1076 | "reg(%u) out of range!\n", port_id); |
| 1075 | return -EINVAL; | 1077 | return -EINVAL; |
| 1076 | } | 1078 | } |
| 1077 | mac_cb = devm_kzalloc(dsaf_dev->dev, sizeof(*mac_cb), | 1079 | mac_cb = devm_kzalloc(dsaf_dev->dev, sizeof(*mac_cb), |
| 1078 | GFP_KERNEL); | 1080 | GFP_KERNEL); |
| 1079 | if (!mac_cb) | 1081 | if (!mac_cb) { |
| 1082 | fwnode_handle_put(child); | ||
| 1080 | return -ENOMEM; | 1083 | return -ENOMEM; |
| 1084 | } | ||
| 1081 | mac_cb->fw_port = child; | 1085 | mac_cb->fw_port = child; |
| 1082 | mac_cb->mac_id = (u8)port_id; | 1086 | mac_cb->mac_id = (u8)port_id; |
| 1083 | dsaf_dev->mac_cb[port_id] = mac_cb; | 1087 | dsaf_dev->mac_cb[port_id] = mac_cb; |
| @@ -75,7 +75,7 @@ int hclge_comm_tqps_update_stats(struct hnae3_handle *handle, · 74 unmodified lines | |||
| 75 | ret = hclge_comm_cmd_send(hw, &desc, 1); | 75 | ret = hclge_comm_cmd_send(hw, &desc, 1); |
| 76 | if (ret) { | 76 | if (ret) { |
| 77 | dev_err(&hw->cmq.csq.pdev->dev, | 77 | dev_err(&hw->cmq.csq.pdev->dev, |
| 78 | "failed to get tqp stat, ret = %d, tx = %u.\n", | 78 | "failed to get tqp stat, ret = %d, rx = %u.\n", |
| 79 | ret, i); | 79 | ret, i); |
| 80 | return ret; | 80 | return ret; |
| 81 | } | 81 | } |
| @@ -89,7 +89,7 @@ int hclge_comm_tqps_update_stats(struct hnae3_handle *handle, · 7 unmodified lines | |||
| 89 | ret = hclge_comm_cmd_send(hw, &desc, 1); | 89 | ret = hclge_comm_cmd_send(hw, &desc, 1); |
| 90 | if (ret) { | 90 | if (ret) { |
| 91 | dev_err(&hw->cmq.csq.pdev->dev, | 91 | dev_err(&hw->cmq.csq.pdev->dev, |
| 92 | "failed to get tqp stat, ret = %d, rx = %u.\n", | 92 | "failed to get tqp stat, ret = %d, tx = %u.\n", |
| 93 | ret, i); | 93 | ret, i); |
| 94 | return ret; | 94 | return ret; |
| 95 | } | 95 | } |
| @@ -562,12 +562,12 @@ static void hns3_dbg_tx_spare_info(struct hns3_enet_ring *ring, char *buf, · 561 unmodified lines | |||
| 562 | 562 | ||
| 563 | for (i = 0; i < ring_num; i++) { | 563 | for (i = 0; i < ring_num; i++) { |
| 564 | j = 0; | 564 | j = 0; |
| 565 | sprintf(result[j++], "%8u", i); | 565 | sprintf(result[j++], "%u", i); |
| 566 | sprintf(result[j++], "%9u", ring->tx_copybreak); | 566 | sprintf(result[j++], "%u", ring->tx_copybreak); |
| 567 | sprintf(result[j++], "%3u", tx_spare->len); | 567 | sprintf(result[j++], "%u", tx_spare->len); |
| 568 | sprintf(result[j++], "%3u", tx_spare->next_to_use); | 568 | sprintf(result[j++], "%u", tx_spare->next_to_use); |
| 569 | sprintf(result[j++], "%3u", tx_spare->next_to_clean); | 569 | sprintf(result[j++], "%u", tx_spare->next_to_clean); |
| 570 | sprintf(result[j++], "%3u", tx_spare->last_to_clean); | 570 | sprintf(result[j++], "%u", tx_spare->last_to_clean); |
| 571 | sprintf(result[j++], "%pad", &tx_spare->dma); | 571 | sprintf(result[j++], "%pad", &tx_spare->dma); |
| 572 | hns3_dbg_fill_content(content, sizeof(content), | 572 | hns3_dbg_fill_content(content, sizeof(content), |
| 573 | tx_spare_info_items, | 573 | tx_spare_info_items, |
| @@ -598,35 +598,35 @@ static void hns3_dump_rx_queue_info(struct hns3_enet_ring *ring, · 24 unmodified lines | |||
| 598 | u32 base_add_l, base_add_h; | 598 | u32 base_add_l, base_add_h; |
| 599 | u32 j = 0; | 599 | u32 j = 0; |
| 600 | 600 | ||
| 601 | sprintf(result[j++], "%8u", index); | 601 | sprintf(result[j++], "%u", index); |
| 602 | 602 | ||
| 603 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | 603 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 604 | HNS3_RING_RX_RING_BD_NUM_REG)); | 604 | HNS3_RING_RX_RING_BD_NUM_REG)); |
| 605 | 605 | ||
| 606 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | 606 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 607 | HNS3_RING_RX_RING_BD_LEN_REG)); | 607 | HNS3_RING_RX_RING_BD_LEN_REG)); |
| 608 | 608 | ||
| 609 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + | 609 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 610 | HNS3_RING_RX_RING_TAIL_REG)); | 610 | HNS3_RING_RX_RING_TAIL_REG)); |
| 611 | 611 | ||
| 612 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + | 612 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 613 | HNS3_RING_RX_RING_HEAD_REG)); | 613 | HNS3_RING_RX_RING_HEAD_REG)); |
| 614 | 614 | ||
| 615 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | 615 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 616 | HNS3_RING_RX_RING_FBDNUM_REG)); | 616 | HNS3_RING_RX_RING_FBDNUM_REG)); |
| 617 | 617 | ||
| 618 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | 618 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 619 | HNS3_RING_RX_RING_PKTNUM_RECORD_REG)); | 619 | HNS3_RING_RX_RING_PKTNUM_RECORD_REG)); |
| 620 | sprintf(result[j++], "%9u", ring->rx_copybreak); | 620 | sprintf(result[j++], "%u", ring->rx_copybreak); |
| 621 | 621 | ||
| 622 | sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base + | 622 | sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base + |
| 623 | HNS3_RING_EN_REG) ? "on" : "off"); | 623 | HNS3_RING_EN_REG) ? "on" : "off"); |
| 624 | 624 | ||
| 625 | if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) | 625 | if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) |
| 626 | sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base + | 626 | sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base + |
| 627 | HNS3_RING_RX_EN_REG) ? "on" : "off"); | 627 | HNS3_RING_RX_EN_REG) ? "on" : "off"); |
| 628 | else | 628 | else |
| 629 | sprintf(result[j++], "%10s", "NA"); | 629 | sprintf(result[j++], "%s", "NA"); |
| 630 | 630 | ||
| 631 | base_add_h = readl_relaxed(ring->tqp->io_base + | 631 | base_add_h = readl_relaxed(ring->tqp->io_base + |
| 632 | HNS3_RING_RX_RING_BASEADDR_H_REG); | 632 | HNS3_RING_RX_RING_BASEADDR_H_REG); |
| @@ -700,36 +700,36 @@ static void hns3_dump_tx_queue_info(struct hns3_enet_ring *ring, · 67 unmodified lines | |||
| 700 | u32 base_add_l, base_add_h; | 700 | u32 base_add_l, base_add_h; |
| 701 | u32 j = 0; | 701 | u32 j = 0; |
| 702 | 702 | ||
| 703 | sprintf(result[j++], "%8u", index); | 703 | sprintf(result[j++], "%u", index); |
| 704 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | 704 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 705 | HNS3_RING_TX_RING_BD_NUM_REG)); | 705 | HNS3_RING_TX_RING_BD_NUM_REG)); |
| 706 | 706 | ||
| 707 | sprintf(result[j++], "%2u", readl_relaxed(ring->tqp->io_base + | 707 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 708 | HNS3_RING_TX_RING_TC_REG)); | 708 | HNS3_RING_TX_RING_TC_REG)); |
| 709 | 709 | ||
| 710 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + | 710 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 711 | HNS3_RING_TX_RING_TAIL_REG)); | 711 | HNS3_RING_TX_RING_TAIL_REG)); |
| 712 | 712 | ||
| 713 | sprintf(result[j++], "%4u", readl_relaxed(ring->tqp->io_base + | 713 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 714 | HNS3_RING_TX_RING_HEAD_REG)); | 714 | HNS3_RING_TX_RING_HEAD_REG)); |
| 715 | 715 | ||
| 716 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | 716 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 717 | HNS3_RING_TX_RING_FBDNUM_REG)); | 717 | HNS3_RING_TX_RING_FBDNUM_REG)); |
| 718 | 718 | ||
| 719 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | 719 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 720 | HNS3_RING_TX_RING_OFFSET_REG)); | 720 | HNS3_RING_TX_RING_OFFSET_REG)); |
| 721 | 721 | ||
| 722 | sprintf(result[j++], "%6u", readl_relaxed(ring->tqp->io_base + | 722 | sprintf(result[j++], "%u", readl_relaxed(ring->tqp->io_base + |
| 723 | HNS3_RING_TX_RING_PKTNUM_RECORD_REG)); | 723 | HNS3_RING_TX_RING_PKTNUM_RECORD_REG)); |
| 724 | 724 | ||
| 725 | sprintf(result[j++], "%7s", readl_relaxed(ring->tqp->io_base + | 725 | sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base + |
| 726 | HNS3_RING_EN_REG) ? "on" : "off"); | 726 | HNS3_RING_EN_REG) ? "on" : "off"); |
| 727 | 727 | ||
| 728 | if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) | 728 | if (hnae3_ae_dev_tqp_txrx_indep_supported(ae_dev)) |
| 729 | sprintf(result[j++], "%10s", readl_relaxed(ring->tqp->io_base + | 729 | sprintf(result[j++], "%s", readl_relaxed(ring->tqp->io_base + |
| 730 | HNS3_RING_TX_EN_REG) ? "on" : "off"); | 730 | HNS3_RING_TX_EN_REG) ? "on" : "off"); |
| 731 | else | 731 | else |
| 732 | sprintf(result[j++], "%10s", "NA"); | 732 | sprintf(result[j++], "%s", "NA"); |
| 733 | 733 | ||
| 734 | base_add_h = readl_relaxed(ring->tqp->io_base + | 734 | base_add_h = readl_relaxed(ring->tqp->io_base + |
| 735 | HNS3_RING_TX_RING_BASEADDR_H_REG); | 735 | HNS3_RING_TX_RING_BASEADDR_H_REG); |
| @@ -848,15 +848,15 @@ static void hns3_dump_rx_bd_info(struct hns3_nic_priv *priv, · 112 unmodified lines | |||
| 848 | { | 848 | { |
| 849 | unsigned int j = 0; | 849 | unsigned int j = 0; |
| 850 | 850 | ||
| 851 | sprintf(result[j++], "%5d", idx); | 851 | sprintf(result[j++], "%d", idx); |
| 852 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info)); | 852 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.l234_info)); |
| 853 | sprintf(result[j++], "%7u", le16_to_cpu(desc->rx.pkt_len)); | 853 | sprintf(result[j++], "%u", le16_to_cpu(desc->rx.pkt_len)); |
| 854 | sprintf(result[j++], "%4u", le16_to_cpu(desc->rx.size)); | 854 | sprintf(result[j++], "%u", le16_to_cpu(desc->rx.size)); |
| 855 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash)); | 855 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.rss_hash)); |
| 856 | sprintf(result[j++], "%5u", le16_to_cpu(desc->rx.fd_id)); | 856 | sprintf(result[j++], "%u", le16_to_cpu(desc->rx.fd_id)); |
| 857 | sprintf(result[j++], "%8u", le16_to_cpu(desc->rx.vlan_tag)); | 857 | sprintf(result[j++], "%u", le16_to_cpu(desc->rx.vlan_tag)); |
| 858 | sprintf(result[j++], "%15u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb)); | 858 | sprintf(result[j++], "%u", le16_to_cpu(desc->rx.o_dm_vlan_id_fb)); |
| 859 | sprintf(result[j++], "%11u", le16_to_cpu(desc->rx.ot_vlan_tag)); | 859 | sprintf(result[j++], "%u", le16_to_cpu(desc->rx.ot_vlan_tag)); |
| 860 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info)); | 860 | sprintf(result[j++], "%#x", le32_to_cpu(desc->rx.bd_base_info)); |
| 861 | if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) { | 861 | if (test_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state)) { |
| 862 | u32 ol_info = le32_to_cpu(desc->rx.ol_info); | 862 | u32 ol_info = le32_to_cpu(desc->rx.ol_info); |
| @@ -930,19 +930,19 @@ static void hns3_dump_tx_bd_info(struct hns3_nic_priv *priv, · 67 unmodified lines | |||
| 930 | { | 930 | { |
| 931 | unsigned int j = 0; | 931 | unsigned int j = 0; |
| 932 | 932 | ||
| 933 | sprintf(result[j++], "%6d", idx); | 933 | sprintf(result[j++], "%d", idx); |
| 934 | sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr)); | 934 | sprintf(result[j++], "%#llx", le64_to_cpu(desc->addr)); |
| 935 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.vlan_tag)); | 935 | sprintf(result[j++], "%u", le16_to_cpu(desc->tx.vlan_tag)); |
| 936 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.send_size)); | 936 | sprintf(result[j++], "%u", le16_to_cpu(desc->tx.send_size)); |
| 937 | sprintf(result[j++], "%#x", | 937 | sprintf(result[j++], "%#x", |
| 938 | le32_to_cpu(desc->tx.type_cs_vlan_tso_len)); | 938 | le32_to_cpu(desc->tx.type_cs_vlan_tso_len)); |
| 939 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.outer_vlan_tag)); | 939 | sprintf(result[j++], "%u", le16_to_cpu(desc->tx.outer_vlan_tag)); |
| 940 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.tv)); | 940 | sprintf(result[j++], "%u", le16_to_cpu(desc->tx.tv)); |
| 941 | sprintf(result[j++], "%10u", | 941 | sprintf(result[j++], "%u", |
| 942 | le32_to_cpu(desc->tx.ol_type_vlan_len_msec)); | 942 | le32_to_cpu(desc->tx.ol_type_vlan_len_msec)); |
| 943 | sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs)); | 943 | sprintf(result[j++], "%#x", le32_to_cpu(desc->tx.paylen_ol4cs)); |
| 944 | sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri)); | 944 | sprintf(result[j++], "%#x", le16_to_cpu(desc->tx.bdtp_fe_sc_vld_ra_ri)); |
| 945 | sprintf(result[j++], "%5u", le16_to_cpu(desc->tx.mss_hw_csum)); | 945 | sprintf(result[j++], "%u", le16_to_cpu(desc->tx.mss_hw_csum)); |
| 946 | } | 946 | } |
| 947 | 947 | ||
| 948 | static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len) | 948 | static int hns3_dbg_tx_bd_info(struct hns3_dbg_data *d, char *buf, int len) |
| @@ -5203,6 +5203,13 @@ static void hns3_state_init(struct hnae3_handle *handle) · 5202 unmodified lines | |||
| 5203 | set_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state); | 5203 | set_bit(HNS3_NIC_STATE_RXD_ADV_LAYOUT_ENABLE, &priv->state); |
| 5204 | } | 5204 | } |
| 5205 | 5205 | ||
| 5206 | static void hns3_state_uninit(struct hnae3_handle *handle) | ||
| 5207 | { | ||
| 5208 | struct hns3_nic_priv *priv = handle->priv; | ||
| 5209 | |||
| 5210 | clear_bit(HNS3_NIC_STATE_INITED, &priv->state); | ||
| 5211 | } | ||
| 5212 | |||
| 5206 | static int hns3_client_init(struct hnae3_handle *handle) | 5213 | static int hns3_client_init(struct hnae3_handle *handle) |
| 5207 | { | 5214 | { |
| 5208 | struct pci_dev *pdev = handle->pdev; | 5215 | struct pci_dev *pdev = handle->pdev; |
| @@ -5320,7 +5327,9 @@ static int hns3_client_init(struct hnae3_handle *handle) · 111 unmodified lines | |||
| 5320 | return ret; | 5327 | return ret; |
| 5321 | 5328 | ||
| 5322 | out_reg_netdev_fail: | 5329 | out_reg_netdev_fail: |
| 5330 | hns3_state_uninit(handle); | ||
| 5323 | hns3_dbg_uninit(handle); | 5331 | hns3_dbg_uninit(handle); |
| 5332 | hns3_client_stop(handle); | ||
| 5324 | out_client_start: | 5333 | out_client_start: |
| 5325 | hns3_free_rx_cpu_rmap(netdev); | 5334 | hns3_free_rx_cpu_rmap(netdev); |
| 5326 | hns3_nic_uninit_irq(priv); | 5335 | hns3_nic_uninit_irq(priv); |
| @@ -94,6 +94,13 @@ static int hclge_send_mbx_msg(struct hclge_vport *vport, u8 *msg, u16 msg_len, · 93 unmodified lines | |||
| 94 | enum hclge_comm_cmd_status status; | 94 | enum hclge_comm_cmd_status status; |
| 95 | struct hclge_desc desc; | 95 | struct hclge_desc desc; |
| 96 | 96 | ||
| 97 | if (msg_len > HCLGE_MBX_MAX_MSG_SIZE) { | ||
| 98 | dev_err(&hdev->pdev->dev, | ||
| 99 | "msg data length(=%u) exceeds maximum(=%u)\n", | ||
| 100 | msg_len, HCLGE_MBX_MAX_MSG_SIZE); | ||
| 101 | return -EMSGSIZE; | ||
| 102 | } | ||
| 103 | |||
| 97 | resp_pf_to_vf = (struct hclge_mbx_pf_to_vf_cmd *)desc.data; | 104 | resp_pf_to_vf = (struct hclge_mbx_pf_to_vf_cmd *)desc.data; |
| 98 | 105 | ||
| 99 | hclge_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_PF_TO_VF, false); | 106 | hclge_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_PF_TO_VF, false); |
| @@ -176,7 +183,7 @@ static int hclge_get_ring_chain_from_mbx( · 76 unmodified lines | |||
| 176 | ring_num = req->msg.ring_num; | 183 | ring_num = req->msg.ring_num; |
| 177 | 184 | ||
| 178 | if (ring_num > HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM) | 185 | if (ring_num > HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM) |
| 179 | return -ENOMEM; | 186 | return -EINVAL; |
| 180 | 187 | ||
| 181 | for (i = 0; i < ring_num; i++) { | 188 | for (i = 0; i < ring_num; i++) { |
| 182 | if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) { | 189 | if (req->msg.param[i].tqp_index >= vport->nic.kinfo.rss_size) { |
| @@ -587,9 +594,9 @@ static int hclge_set_vf_mtu(struct hclge_vport *vport, · 404 unmodified lines | |||
| 587 | return hclge_set_vport_mtu(vport, mtu); | 594 | return hclge_set_vport_mtu(vport, mtu); |
| 588 | } | 595 | } |
| 589 | 596 | ||
| 590 | static void hclge_get_queue_id_in_pf(struct hclge_vport *vport, | 597 | static int hclge_get_queue_id_in_pf(struct hclge_vport *vport, |
| 591 | struct hclge_mbx_vf_to_pf_cmd *mbx_req, | 598 | struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
| 592 | struct hclge_respond_to_vf_msg *resp_msg) | 599 | struct hclge_respond_to_vf_msg *resp_msg) |
| 593 | { | 600 | { |
| 594 | struct hnae3_handle *handle = &vport->nic; | 601 | struct hnae3_handle *handle = &vport->nic; |
| 595 | struct hclge_dev *hdev = vport->back; | 602 | struct hclge_dev *hdev = vport->back; |
| @@ -599,17 +606,18 @@ static void hclge_get_queue_id_in_pf(struct hclge_vport *vport, · 3 unmodified lines | |||
| 599 | if (queue_id >= handle->kinfo.num_tqps) { | 606 | if (queue_id >= handle->kinfo.num_tqps) { |
| 600 | dev_err(&hdev->pdev->dev, "Invalid queue id(%u) from VF %u\n", | 607 | dev_err(&hdev->pdev->dev, "Invalid queue id(%u) from VF %u\n", |
| 601 | queue_id, mbx_req->mbx_src_vfid); | 608 | queue_id, mbx_req->mbx_src_vfid); |
| 602 | return; | 609 | return -EINVAL; |
| 603 | } | 610 | } |
| 604 | 611 | ||
| 605 | qid_in_pf = hclge_covert_handle_qid_global(&vport->nic, queue_id); | 612 | qid_in_pf = hclge_covert_handle_qid_global(&vport->nic, queue_id); |
| 606 | memcpy(resp_msg->data, &qid_in_pf, sizeof(qid_in_pf)); | 613 | memcpy(resp_msg->data, &qid_in_pf, sizeof(qid_in_pf)); |
| 607 | resp_msg->len = sizeof(qid_in_pf); | 614 | resp_msg->len = sizeof(qid_in_pf); |
| 615 | return 0; | ||
| 608 | } | 616 | } |
| 609 | 617 | ||
| 610 | static void hclge_get_rss_key(struct hclge_vport *vport, | 618 | static int hclge_get_rss_key(struct hclge_vport *vport, |
| 611 | struct hclge_mbx_vf_to_pf_cmd *mbx_req, | 619 | struct hclge_mbx_vf_to_pf_cmd *mbx_req, |
| 612 | struct hclge_respond_to_vf_msg *resp_msg) | 620 | struct hclge_respond_to_vf_msg *resp_msg) |
| 613 | { | 621 | { |
| 614 | #define HCLGE_RSS_MBX_RESP_LEN 8 | 622 | #define HCLGE_RSS_MBX_RESP_LEN 8 |
| 615 | struct hclge_dev *hdev = vport->back; | 623 | struct hclge_dev *hdev = vport->back; |
| @@ -627,13 +635,14 @@ static void hclge_get_rss_key(struct hclge_vport *vport, · 11 unmodified lines | |||
| 627 | dev_warn(&hdev->pdev->dev, | 635 | dev_warn(&hdev->pdev->dev, |
| 628 | "failed to get the rss hash key, the index(%u) invalid !\n", | 636 | "failed to get the rss hash key, the index(%u) invalid !\n", |
| 629 | index); | 637 | index); |
| 630 | return; | 638 | return -EINVAL; |
| 631 | } | 639 | } |
| 632 | 640 | ||
| 633 | memcpy(resp_msg->data, | 641 | memcpy(resp_msg->data, |
| 634 | &rss_cfg->rss_hash_key[index * HCLGE_RSS_MBX_RESP_LEN], | 642 | &rss_cfg->rss_hash_key[index * HCLGE_RSS_MBX_RESP_LEN], |
| 635 | HCLGE_RSS_MBX_RESP_LEN); | 643 | HCLGE_RSS_MBX_RESP_LEN); |
| 636 | resp_msg->len = HCLGE_RSS_MBX_RESP_LEN; | 644 | resp_msg->len = HCLGE_RSS_MBX_RESP_LEN; |
| 645 | return 0; | ||
| 637 | } | 646 | } |
| 638 | 647 | ||
| 639 | static void hclge_link_fail_parse(struct hclge_dev *hdev, u8 link_fail_code) | 648 | static void hclge_link_fail_parse(struct hclge_dev *hdev, u8 link_fail_code) |
| @@ -809,10 +818,10 @@ void hclge_mbx_handler(struct hclge_dev *hdev) · 169 unmodified lines | |||
| 809 | "VF fail(%d) to set mtu\n", ret); | 818 | "VF fail(%d) to set mtu\n", ret); |
| 810 | break; | 819 | break; |
| 811 | case HCLGE_MBX_GET_QID_IN_PF: | 820 | case HCLGE_MBX_GET_QID_IN_PF: |
| 812 | hclge_get_queue_id_in_pf(vport, req, &resp_msg); | 821 | ret = hclge_get_queue_id_in_pf(vport, req, &resp_msg); |
| 813 | break; | 822 | break; |
| 814 | case HCLGE_MBX_GET_RSS_KEY: | 823 | case HCLGE_MBX_GET_RSS_KEY: |
| 815 | hclge_get_rss_key(vport, req, &resp_msg); | 824 | ret = hclge_get_rss_key(vport, req, &resp_msg); |
| 816 | break; | 825 | break; |
| 817 | case HCLGE_MBX_GET_LINK_MODE: | 826 | case HCLGE_MBX_GET_LINK_MODE: |
| 818 | hclge_get_link_mode(vport, req); | 827 | hclge_get_link_mode(vport, req); |
| @@ -771,7 +771,7 @@ struct hinic_hw_wqe *hinic_get_wqe(struct hinic_wq *wq, unsigned int wqe_size, · 770 unmodified lines | |||
| 771 | /* If we only have one page, still need to get shadown wqe when | 771 | /* If we only have one page, still need to get shadown wqe when |
| 772 | * wqe rolling-over page | 772 | * wqe rolling-over page |
| 773 | */ | 773 | */ |
| 774 | if (curr_pg != end_pg || MASKED_WQE_IDX(wq, end_prod_idx) < *prod_idx) { | 774 | if (curr_pg != end_pg || end_prod_idx < *prod_idx) { |
| 775 | void *shadow_addr = &wq->shadow_wqe[curr_pg * wq->max_wqe_size]; | 775 | void *shadow_addr = &wq->shadow_wqe[curr_pg * wq->max_wqe_size]; |
| 776 | 776 | ||
| 777 | copy_wqe_to_shadow(wq, shadow_addr, num_wqebbs, *prod_idx); | 777 | copy_wqe_to_shadow(wq, shadow_addr, num_wqebbs, *prod_idx); |
| @@ -841,7 +841,10 @@ struct hinic_hw_wqe *hinic_read_wqe(struct hinic_wq *wq, unsigned int wqe_size, · 63 unmodified lines | |||
| 841 | 841 | ||
| 842 | *cons_idx = curr_cons_idx; | 842 | *cons_idx = curr_cons_idx; |
| 843 | 843 | ||
| 844 | if (curr_pg != end_pg) { | 844 | /* If we only have one page, still need to get shadown wqe when |
| 845 | * wqe rolling-over page | ||
| 846 | */ | ||
| 847 | if (curr_pg != end_pg || end_cons_idx < curr_cons_idx) { | ||
| 845 | void *shadow_addr = &wq->shadow_wqe[curr_pg * wq->max_wqe_size]; | 848 | void *shadow_addr = &wq->shadow_wqe[curr_pg * wq->max_wqe_size]; |
| 846 | 849 | ||
| 847 | copy_wqe_to_shadow(wq, shadow_addr, num_wqebbs, *cons_idx); | 850 | copy_wqe_to_shadow(wq, shadow_addr, num_wqebbs, *cons_idx); |
| @@ -3210,13 +3210,8 @@ static void ibmvnic_get_ringparam(struct net_device *netdev, · 3209 unmodified lines | |||
| 3210 | { | 3210 | { |
| 3211 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | 3211 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
| 3212 | 3212 | ||
| 3213 | if (adapter->priv_flags & IBMVNIC_USE_SERVER_MAXES) { | 3213 | ring->rx_max_pending = adapter->max_rx_add_entries_per_subcrq; |
| 3214 | ring->rx_max_pending = adapter->max_rx_add_entries_per_subcrq; | 3214 | ring->tx_max_pending = adapter->max_tx_entries_per_subcrq; |
| 3215 | ring->tx_max_pending = adapter->max_tx_entries_per_subcrq; | ||
| 3216 | } else { | ||
| 3217 | ring->rx_max_pending = IBMVNIC_MAX_QUEUE_SZ; | ||
| 3218 | ring->tx_max_pending = IBMVNIC_MAX_QUEUE_SZ; | ||
| 3219 | } | ||
| 3220 | ring->rx_mini_max_pending = 0; | 3215 | ring->rx_mini_max_pending = 0; |
| 3221 | ring->rx_jumbo_max_pending = 0; | 3216 | ring->rx_jumbo_max_pending = 0; |
| 3222 | ring->rx_pending = adapter->req_rx_add_entries_per_subcrq; | 3217 | ring->rx_pending = adapter->req_rx_add_entries_per_subcrq; |
| @@ -3231,23 +3226,21 @@ static int ibmvnic_set_ringparam(struct net_device *netdev, · 8 unmodified lines | |||
| 3231 | struct netlink_ext_ack *extack) | 3226 | struct netlink_ext_ack *extack) |
| 3232 | { | 3227 | { |
| 3233 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | 3228 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
| 3234 | int ret; | ||
| 3235 | 3229 | ||
| 3236 | ret = 0; | 3230 | if (ring->rx_pending > adapter->max_rx_add_entries_per_subcrq || |
| 3231 | ring->tx_pending > adapter->max_tx_entries_per_subcrq) { | ||
| 3232 | netdev_err(netdev, "Invalid request.\n"); | ||
| 3233 | netdev_err(netdev, "Max tx buffers = %llu\n", | ||
| 3234 | adapter->max_rx_add_entries_per_subcrq); | ||
| 3235 | netdev_err(netdev, "Max rx buffers = %llu\n", | ||
| 3236 | adapter->max_tx_entries_per_subcrq); | ||
| 3237 | return -EINVAL; | ||
| 3238 | } | ||
| 3239 | |||
| 3237 | adapter->desired.rx_entries = ring->rx_pending; | 3240 | adapter->desired.rx_entries = ring->rx_pending; |
| 3238 | adapter->desired.tx_entries = ring->tx_pending; | 3241 | adapter->desired.tx_entries = ring->tx_pending; |
| 3239 | 3242 | ||
| 3240 | ret = wait_for_reset(adapter); | 3243 | return wait_for_reset(adapter); |
| 3241 | |||
| 3242 | if (!ret && | ||
| 3243 | (adapter->req_rx_add_entries_per_subcrq != ring->rx_pending || | ||
| 3244 | adapter->req_tx_entries_per_subcrq != ring->tx_pending)) | ||
| 3245 | netdev_info(netdev, | ||
| 3246 | "Could not match full ringsize request. Requested: RX %d, TX %d; Allowed: RX %llu, TX %llu\n", | ||
| 3247 | ring->rx_pending, ring->tx_pending, | ||
| 3248 | adapter->req_rx_add_entries_per_subcrq, | ||
| 3249 | adapter->req_tx_entries_per_subcrq); | ||
| 3250 | return ret; | ||
| 3251 | } | 3244 | } |
| 3252 | 3245 | ||
| 3253 | static void ibmvnic_get_channels(struct net_device *netdev, | 3246 | static void ibmvnic_get_channels(struct net_device *netdev, |
| @@ -3255,14 +3248,8 @@ static void ibmvnic_get_channels(struct net_device *netdev, · 1 unmodified line | |||
| 3255 | { | 3248 | { |
| 3256 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | 3249 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
| 3257 | 3250 | ||
| 3258 | if (adapter->priv_flags & IBMVNIC_USE_SERVER_MAXES) { | 3251 | channels->max_rx = adapter->max_rx_queues; |
| 3259 | channels->max_rx = adapter->max_rx_queues; | 3252 | channels->max_tx = adapter->max_tx_queues; |
| 3260 | channels->max_tx = adapter->max_tx_queues; | ||
| 3261 | } else { | ||
| 3262 | channels->max_rx = IBMVNIC_MAX_QUEUES; | ||
| 3263 | channels->max_tx = IBMVNIC_MAX_QUEUES; | ||
| 3264 | } | ||
| 3265 | |||
| 3266 | channels->max_other = 0; | 3253 | channels->max_other = 0; |
| 3267 | channels->max_combined = 0; | 3254 | channels->max_combined = 0; |
| 3268 | channels->rx_count = adapter->req_rx_queues; | 3255 | channels->rx_count = adapter->req_rx_queues; |
| @@ -3275,22 +3262,11 @@ static int ibmvnic_set_channels(struct net_device *netdev, · 6 unmodified lines | |||
| 3275 | struct ethtool_channels *channels) | 3262 | struct ethtool_channels *channels) |
| 3276 | { | 3263 | { |
| 3277 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | 3264 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
| 3278 | int ret; | ||
| 3279 | 3265 | ||
| 3280 | ret = 0; | ||
| 3281 | adapter->desired.rx_queues = channels->rx_count; | 3266 | adapter->desired.rx_queues = channels->rx_count; |
| 3282 | adapter->desired.tx_queues = channels->tx_count; | 3267 | adapter->desired.tx_queues = channels->tx_count; |
| 3283 | 3268 | ||
| 3284 | ret = wait_for_reset(adapter); | 3269 | return wait_for_reset(adapter); |
| 3285 | |||
| 3286 | if (!ret && | ||
| 3287 | (adapter->req_rx_queues != channels->rx_count || | ||
| 3288 | adapter->req_tx_queues != channels->tx_count)) | ||
| 3289 | netdev_info(netdev, | ||
| 3290 | "Could not match full channels request. Requested: RX %d, TX %d; Allowed: RX %llu, TX %llu\n", | ||
| 3291 | channels->rx_count, channels->tx_count, | ||
| 3292 | adapter->req_rx_queues, adapter->req_tx_queues); | ||
| 3293 | return ret; | ||
| 3294 | } | 3270 | } |
| 3295 | 3271 | ||
| 3296 | static void ibmvnic_get_strings(struct net_device *dev, u32 stringset, u8 *data) | 3272 | static void ibmvnic_get_strings(struct net_device *dev, u32 stringset, u8 *data) |
| @@ -3298,43 +3274,32 @@ static void ibmvnic_get_strings(struct net_device *dev, u32 stringset, u8 *data) · 1 unmodified line | |||
| 3298 | struct ibmvnic_adapter *adapter = netdev_priv(dev); | 3274 | struct ibmvnic_adapter *adapter = netdev_priv(dev); |
| 3299 | int i; | 3275 | int i; |
| 3300 | 3276 | ||
| 3301 | switch (stringset) { | 3277 | if (stringset != ETH_SS_STATS) |
| 3302 | case ETH_SS_STATS: | 3278 | return; |
| 3303 | for (i = 0; i < ARRAY_SIZE(ibmvnic_stats); | ||
| 3304 | i++, data += ETH_GSTRING_LEN) | ||
| 3305 | memcpy(data, ibmvnic_stats[i].name, ETH_GSTRING_LEN); | ||
| 3306 | 3279 | ||
| 3307 | for (i = 0; i < adapter->req_tx_queues; i++) { | 3280 | for (i = 0; i < ARRAY_SIZE(ibmvnic_stats); i++, data += ETH_GSTRING_LEN) |
| 3308 | snprintf(data, ETH_GSTRING_LEN, "tx%d_packets", i); | 3281 | memcpy(data, ibmvnic_stats[i].name, ETH_GSTRING_LEN); |
| 3309 | data += ETH_GSTRING_LEN; | ||
| 3310 | 3282 | ||
| 3311 | snprintf(data, ETH_GSTRING_LEN, "tx%d_bytes", i); | 3283 | for (i = 0; i < adapter->req_tx_queues; i++) { |
| 3312 | data += ETH_GSTRING_LEN; | 3284 | snprintf(data, ETH_GSTRING_LEN, "tx%d_packets", i); |
| 3285 | data += ETH_GSTRING_LEN; | ||
| 3313 | 3286 | ||
| 3314 | snprintf(data, ETH_GSTRING_LEN, | 3287 | snprintf(data, ETH_GSTRING_LEN, "tx%d_bytes", i); |
| 3315 | "tx%d_dropped_packets", i); | 3288 | data += ETH_GSTRING_LEN; |
| 3316 | data += ETH_GSTRING_LEN; | ||
| 3317 | } | ||
| 3318 | 3289 | ||
| 3319 | for (i = 0; i < adapter->req_rx_queues; i++) { | 3290 | snprintf(data, ETH_GSTRING_LEN, "tx%d_dropped_packets", i); |
| 3320 | snprintf(data, ETH_GSTRING_LEN, "rx%d_packets", i); | 3291 | data += ETH_GSTRING_LEN; |
| 3321 | data += ETH_GSTRING_LEN; | 3292 | } |
| 3322 | 3293 | ||
| 3323 | snprintf(data, ETH_GSTRING_LEN, "rx%d_bytes", i); | 3294 | for (i = 0; i < adapter->req_rx_queues; i++) { |
| 3324 | data += ETH_GSTRING_LEN; | 3295 | snprintf(data, ETH_GSTRING_LEN, "rx%d_packets", i); |
| 3296 | data += ETH_GSTRING_LEN; | ||
| 3325 | 3297 | ||
| 3326 | snprintf(data, ETH_GSTRING_LEN, "rx%d_interrupts", i); | 3298 | snprintf(data, ETH_GSTRING_LEN, "rx%d_bytes", i); |
| 3327 | data += ETH_GSTRING_LEN; | 3299 | data += ETH_GSTRING_LEN; |
| 3328 | } | ||
| 3329 | break; | ||
| 3330 | 3300 | ||
| 3331 | case ETH_SS_PRIV_FLAGS: | 3301 | snprintf(data, ETH_GSTRING_LEN, "rx%d_interrupts", i); |
| 3332 | for (i = 0; i < ARRAY_SIZE(ibmvnic_priv_flags); i++) | 3302 | data += ETH_GSTRING_LEN; |
| 3333 | strcpy(data + i * ETH_GSTRING_LEN, | ||
| 3334 | ibmvnic_priv_flags[i]); | ||
| 3335 | break; | ||
| 3336 | default: | ||
| 3337 | return; | ||
| 3338 | } | 3303 | } |
| 3339 | } | 3304 | } |
| 3340 | 3305 | ||
| @@ -3347,8 +3312,6 @@ static int ibmvnic_get_sset_count(struct net_device *dev, int sset) · 6 unmodified lines | |||
| 3347 | return ARRAY_SIZE(ibmvnic_stats) + | 3312 | return ARRAY_SIZE(ibmvnic_stats) + |
| 3348 | adapter->req_tx_queues * NUM_TX_STATS + | 3313 | adapter->req_tx_queues * NUM_TX_STATS + |
| 3349 | adapter->req_rx_queues * NUM_RX_STATS; | 3314 | adapter->req_rx_queues * NUM_RX_STATS; |
| 3350 | case ETH_SS_PRIV_FLAGS: | ||
| 3351 | return ARRAY_SIZE(ibmvnic_priv_flags); | ||
| 3352 | default: | 3315 | default: |
| 3353 | return -EOPNOTSUPP; | 3316 | return -EOPNOTSUPP; |
| 3354 | } | 3317 | } |
| @@ -3401,26 +3364,6 @@ static void ibmvnic_get_ethtool_stats(struct net_device *dev, · 46 unmodified lines | |||
| 3401 | } | 3364 | } |
| 3402 | } | 3365 | } |
| 3403 | 3366 | ||
| 3404 | static u32 ibmvnic_get_priv_flags(struct net_device *netdev) | ||
| 3405 | { | ||
| 3406 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | ||
| 3407 | |||
| 3408 | return adapter->priv_flags; | ||
| 3409 | } | ||
| 3410 | |||
| 3411 | static int ibmvnic_set_priv_flags(struct net_device *netdev, u32 flags) | ||
| 3412 | { | ||
| 3413 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); | ||
| 3414 | bool which_maxes = !!(flags & IBMVNIC_USE_SERVER_MAXES); | ||
| 3415 | |||
| 3416 | if (which_maxes) | ||
| 3417 | adapter->priv_flags |= IBMVNIC_USE_SERVER_MAXES; | ||
| 3418 | else | ||
| 3419 | adapter->priv_flags &= ~IBMVNIC_USE_SERVER_MAXES; | ||
| 3420 | |||
| 3421 | return 0; | ||
| 3422 | } | ||
| 3423 | |||
| 3424 | static const struct ethtool_ops ibmvnic_ethtool_ops = { | 3367 | static const struct ethtool_ops ibmvnic_ethtool_ops = { |
| 3425 | .get_drvinfo = ibmvnic_get_drvinfo, | 3368 | .get_drvinfo = ibmvnic_get_drvinfo, |
| 3426 | .get_msglevel = ibmvnic_get_msglevel, | 3369 | .get_msglevel = ibmvnic_get_msglevel, |
| @@ -3434,8 +3377,6 @@ static const struct ethtool_ops ibmvnic_ethtool_ops = { · 7 unmodified lines | |||
| 3434 | .get_sset_count = ibmvnic_get_sset_count, | 3377 | .get_sset_count = ibmvnic_get_sset_count, |
| 3435 | .get_ethtool_stats = ibmvnic_get_ethtool_stats, | 3378 | .get_ethtool_stats = ibmvnic_get_ethtool_stats, |
| 3436 | .get_link_ksettings = ibmvnic_get_link_ksettings, | 3379 | .get_link_ksettings = ibmvnic_get_link_ksettings, |
| 3437 | .get_priv_flags = ibmvnic_get_priv_flags, | ||
| 3438 | .set_priv_flags = ibmvnic_set_priv_flags, | ||
| 3439 | }; | 3380 | }; |
| 3440 | 3381 | ||
| 3441 | /* Routines for managing CRQs/sCRQs */ | 3382 | /* Routines for managing CRQs/sCRQs */ |
| @@ -41,11 +41,6 @@ · 40 unmodified lines | |||
| 41 | 41 | ||
| 42 | #define IBMVNIC_RESET_DELAY 100 | 42 | #define IBMVNIC_RESET_DELAY 100 |
| 43 | 43 | ||
| 44 | static const char ibmvnic_priv_flags[][ETH_GSTRING_LEN] = { | ||
| 45 | #define IBMVNIC_USE_SERVER_MAXES 0x1 | ||
| 46 | "use-server-maxes" | ||
| 47 | }; | ||
| 48 | |||
| 49 | struct ibmvnic_login_buffer { | 44 | struct ibmvnic_login_buffer { |
| 50 | __be32 len; | 45 | __be32 len; |
| 51 | __be32 version; | 46 | __be32 version; |
| @@ -883,7 +878,6 @@ struct ibmvnic_adapter { · 831 unmodified lines | |||
| 883 | struct ibmvnic_control_ip_offload_buffer ip_offload_ctrl; | 878 | struct ibmvnic_control_ip_offload_buffer ip_offload_ctrl; |
| 884 | dma_addr_t ip_offload_ctrl_tok; | 879 | dma_addr_t ip_offload_ctrl_tok; |
| 885 | u32 msg_enable; | 880 | u32 msg_enable; |
| 886 | u32 priv_flags; | ||
| 887 | 881 | ||
| 888 | /* Vital Product Data (VPD) */ | 882 | /* Vital Product Data (VPD) */ |
| 889 | struct ibmvnic_vpd *vpd; | 883 | struct ibmvnic_vpd *vpd; |
| @@ -7549,42 +7549,43 @@ static void i40e_free_macvlan_channels(struct i40e_vsi *vsi) · 7548 unmodified lines | |||
| 7549 | static int i40e_fwd_ring_up(struct i40e_vsi *vsi, struct net_device *vdev, | 7549 | static int i40e_fwd_ring_up(struct i40e_vsi *vsi, struct net_device *vdev, |
| 7550 | struct i40e_fwd_adapter *fwd) | 7550 | struct i40e_fwd_adapter *fwd) |
| 7551 | { | 7551 | { |
| 7552 | struct i40e_channel *ch = NULL, *ch_tmp, *iter; | ||
| 7552 | int ret = 0, num_tc = 1, i, aq_err; | 7553 | int ret = 0, num_tc = 1, i, aq_err; |
| 7553 | struct i40e_channel *ch, *ch_tmp; | ||
| 7554 | struct i40e_pf *pf = vsi->back; | 7554 | struct i40e_pf *pf = vsi->back; |
| 7555 | struct i40e_hw *hw = &pf->hw; | 7555 | struct i40e_hw *hw = &pf->hw; |
| 7556 | 7556 | ||
| 7557 | if (list_empty(&vsi->macvlan_list)) | ||
| 7558 | return -EINVAL; | ||
| 7559 | |||
| 7560 | /* Go through the list and find an available channel */ | 7557 | /* Go through the list and find an available channel */ |
| 7561 | list_for_each_entry_safe(ch, ch_tmp, &vsi->macvlan_list, list) { | 7558 | list_for_each_entry_safe(iter, ch_tmp, &vsi->macvlan_list, list) { |
| 7562 | if (!i40e_is_channel_macvlan(ch)) { | 7559 | if (!i40e_is_channel_macvlan(iter)) { |
| 7563 | ch->fwd = fwd; | 7560 | iter->fwd = fwd; |
| 7564 | /* record configuration for macvlan interface in vdev */ | 7561 | /* record configuration for macvlan interface in vdev */ |
| 7565 | for (i = 0; i < num_tc; i++) | 7562 | for (i = 0; i < num_tc; i++) |
| 7566 | netdev_bind_sb_channel_queue(vsi->netdev, vdev, | 7563 | netdev_bind_sb_channel_queue(vsi->netdev, vdev, |
| 7567 | i, | 7564 | i, |
| 7568 | ch->num_queue_pairs, | 7565 | iter->num_queue_pairs, |
| 7569 | ch->base_queue); | 7566 | iter->base_queue); |
| 7570 | for (i = 0; i < ch->num_queue_pairs; i++) { | 7567 | for (i = 0; i < iter->num_queue_pairs; i++) { |
| 7571 | struct i40e_ring *tx_ring, *rx_ring; | 7568 | struct i40e_ring *tx_ring, *rx_ring; |
| 7572 | u16 pf_q; | 7569 | u16 pf_q; |
| 7573 | 7570 | ||
| 7574 | pf_q = ch->base_queue + i; | 7571 | pf_q = iter->base_queue + i; |
| 7575 | 7572 | ||
| 7576 | /* Get to TX ring ptr */ | 7573 | /* Get to TX ring ptr */ |
| 7577 | tx_ring = vsi->tx_rings[pf_q]; | 7574 | tx_ring = vsi->tx_rings[pf_q]; |
| 7578 | tx_ring->ch = ch; | 7575 | tx_ring->ch = iter; |
| 7579 | 7576 | ||
| 7580 | /* Get the RX ring ptr */ | 7577 | /* Get the RX ring ptr */ |
| 7581 | rx_ring = vsi->rx_rings[pf_q]; | 7578 | rx_ring = vsi->rx_rings[pf_q]; |
| 7582 | rx_ring->ch = ch; | 7579 | rx_ring->ch = iter; |
| 7583 | } | 7580 | } |
| 7581 | ch = iter; | ||
| 7584 | break; | 7582 | break; |
| 7585 | } | 7583 | } |
| 7586 | } | 7584 | } |
| 7587 | 7585 | ||
| 7586 | if (!ch) | ||
| 7587 | return -EINVAL; | ||
| 7588 | |||
| 7588 | /* Guarantee all rings are updated before we update the | 7589 | /* Guarantee all rings are updated before we update the |
| 7589 | * MAC address filter. | 7590 | * MAC address filter. |
| 7590 | */ | 7591 | */ |
| @@ -540,6 +540,7 @@ struct ice_pf { · 539 unmodified lines | |||
| 540 | struct mutex avail_q_mutex; /* protects access to avail_[rx|tx]qs */ | 540 | struct mutex avail_q_mutex; /* protects access to avail_[rx|tx]qs */ |
| 541 | struct mutex sw_mutex; /* lock for protecting VSI alloc flow */ | 541 | struct mutex sw_mutex; /* lock for protecting VSI alloc flow */ |
| 542 | struct mutex tc_mutex; /* lock to protect TC changes */ | 542 | struct mutex tc_mutex; /* lock to protect TC changes */ |
| 543 | struct mutex adev_mutex; /* lock to protect aux device access */ | ||
| 543 | u32 msg_enable; | 544 | u32 msg_enable; |
| 544 | struct ice_ptp ptp; | 545 | struct ice_ptp ptp; |
| 545 | struct tty_driver *ice_gnss_tty_driver; | 546 | struct tty_driver *ice_gnss_tty_driver; |
| @@ -37,14 +37,17 @@ void ice_send_event_to_aux(struct ice_pf *pf, struct iidc_event *event) · 36 unmodified lines | |||
| 37 | if (WARN_ON_ONCE(!in_task())) | 37 | if (WARN_ON_ONCE(!in_task())) |
| 38 | return; | 38 | return; |
| 39 | 39 | ||
| 40 | mutex_lock(&pf->adev_mutex); | ||
| 40 | if (!pf->adev) | 41 | if (!pf->adev) |
| 41 | return; | 42 | goto finish; |
| 42 | 43 | ||
| 43 | device_lock(&pf->adev->dev); | 44 | device_lock(&pf->adev->dev); |
| 44 | iadrv = ice_get_auxiliary_drv(pf); | 45 | iadrv = ice_get_auxiliary_drv(pf); |
| 45 | if (iadrv && iadrv->event_handler) | 46 | if (iadrv && iadrv->event_handler) |
| 46 | iadrv->event_handler(pf, event); | 47 | iadrv->event_handler(pf, event); |
| 47 | device_unlock(&pf->adev->dev); | 48 | device_unlock(&pf->adev->dev); |
| 49 | finish: | ||
| 50 | mutex_unlock(&pf->adev_mutex); | ||
| 48 | } | 51 | } |
| 49 | 52 | ||
| 50 | /** | 53 | /** |
| @@ -290,7 +293,6 @@ int ice_plug_aux_dev(struct ice_pf *pf) · 239 unmodified lines | |||
| 290 | return -ENOMEM; | 293 | return -ENOMEM; |
| 291 | 294 | ||
| 292 | adev = &iadev->adev; | 295 | adev = &iadev->adev; |
| 293 | pf->adev = adev; | ||
| 294 | iadev->pf = pf; | 296 | iadev->pf = pf; |
| 295 | 297 | ||
| 296 | adev->id = pf->aux_idx; | 298 | adev->id = pf->aux_idx; |
| @@ -300,18 +302,20 @@ int ice_plug_aux_dev(struct ice_pf *pf) · 3 unmodified lines | |||
| 300 | 302 | ||
| 301 | ret = auxiliary_device_init(adev); | 303 | ret = auxiliary_device_init(adev); |
| 302 | if (ret) { | 304 | if (ret) { |
| 303 | pf->adev = NULL; | ||
| 304 | kfree(iadev); | 305 | kfree(iadev); |
| 305 | return ret; | 306 | return ret; |
| 306 | } | 307 | } |
| 307 | 308 | ||
| 308 | ret = auxiliary_device_add(adev); | 309 | ret = auxiliary_device_add(adev); |
| 309 | if (ret) { | 310 | if (ret) { |
| 310 | pf->adev = NULL; | ||
| 311 | auxiliary_device_uninit(adev); | 311 | auxiliary_device_uninit(adev); |
| 312 | return ret; | 312 | return ret; |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | mutex_lock(&pf->adev_mutex); | ||
| 316 | pf->adev = adev; | ||
| 317 | mutex_unlock(&pf->adev_mutex); | ||
| 318 | |||
| 315 | return 0; | 319 | return 0; |
| 316 | } | 320 | } |
| 317 | 321 | ||
| @@ -320,12 +324,17 @@ int ice_plug_aux_dev(struct ice_pf *pf) · 2 unmodified lines | |||
| 320 | */ | 324 | */ |
| 321 | void ice_unplug_aux_dev(struct ice_pf *pf) | 325 | void ice_unplug_aux_dev(struct ice_pf *pf) |
| 322 | { | 326 | { |
| 323 | if (!pf->adev) | 327 | struct auxiliary_device *adev; |
| 324 | return; | ||
| 325 | 328 | ||
| 326 | auxiliary_device_delete(pf->adev); | 329 | mutex_lock(&pf->adev_mutex); |
| 327 | auxiliary_device_uninit(pf->adev); | 330 | adev = pf->adev; |
| 328 | pf->adev = NULL; | 331 | pf->adev = NULL; |
| 332 | mutex_unlock(&pf->adev_mutex); | ||
| 333 | |||
| 334 | if (adev) { | ||
| 335 | auxiliary_device_delete(adev); | ||
| 336 | auxiliary_device_uninit(adev); | ||
| 337 | } | ||
| 329 | } | 338 | } |
| 330 | 339 | ||
| 331 | /** | 340 | /** |
| @@ -3769,6 +3769,7 @@ u16 ice_get_avail_rxq_count(struct ice_pf *pf) · 3768 unmodified lines | |||
| 3769 | static void ice_deinit_pf(struct ice_pf *pf) | 3769 | static void ice_deinit_pf(struct ice_pf *pf) |
| 3770 | { | 3770 | { |
| 3771 | ice_service_task_stop(pf); | 3771 | ice_service_task_stop(pf); |
| 3772 | mutex_destroy(&pf->adev_mutex); | ||
| 3772 | mutex_destroy(&pf->sw_mutex); | 3773 | mutex_destroy(&pf->sw_mutex); |
| 3773 | mutex_destroy(&pf->tc_mutex); | 3774 | mutex_destroy(&pf->tc_mutex); |
| 3774 | mutex_destroy(&pf->avail_q_mutex); | 3775 | mutex_destroy(&pf->avail_q_mutex); |
| @@ -3847,6 +3848,7 @@ static int ice_init_pf(struct ice_pf *pf) · 72 unmodified lines | |||
| 3847 | 3848 | ||
| 3848 | mutex_init(&pf->sw_mutex); | 3849 | mutex_init(&pf->sw_mutex); |
| 3849 | mutex_init(&pf->tc_mutex); | 3850 | mutex_init(&pf->tc_mutex); |
| 3851 | mutex_init(&pf->adev_mutex); | ||
| 3850 | 3852 | ||
| 3851 | INIT_HLIST_HEAD(&pf->aq_wait_list); | 3853 | INIT_HLIST_HEAD(&pf->aq_wait_list); |
| 3852 | spin_lock_init(&pf->aq_wait_lock); | 3854 | spin_lock_init(&pf->aq_wait_lock); |
| @@ -6929,12 +6931,15 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) · 3076 unmodified lines | |||
| 6929 | 6931 | ||
| 6930 | dev_dbg(dev, "rebuilding PF after reset_type=%d\n", reset_type); | 6932 | dev_dbg(dev, "rebuilding PF after reset_type=%d\n", reset_type); |
| 6931 | 6933 | ||
| 6934 | #define ICE_EMP_RESET_SLEEP_MS 5000 | ||
| 6932 | if (reset_type == ICE_RESET_EMPR) { | 6935 | if (reset_type == ICE_RESET_EMPR) { |
| 6933 | /* If an EMP reset has occurred, any previously pending flash | 6936 | /* If an EMP reset has occurred, any previously pending flash |
| 6934 | * update will have completed. We no longer know whether or | 6937 | * update will have completed. We no longer know whether or |
| 6935 | * not the NVM update EMP reset is restricted. | 6938 | * not the NVM update EMP reset is restricted. |
| 6936 | */ | 6939 | */ |
| 6937 | pf->fw_emp_reset_disabled = false; | 6940 | pf->fw_emp_reset_disabled = false; |
| 6941 | |||
| 6942 | msleep(ICE_EMP_RESET_SLEEP_MS); | ||
| 6938 | } | 6943 | } |
| 6939 | 6944 | ||
| 6940 | err = ice_init_all_ctrlq(hw); | 6945 | err = ice_init_all_ctrlq(hw); |
| @@ -2287,6 +2287,7 @@ ice_ptp_init_tx_e810(struct ice_pf *pf, struct ice_ptp_tx *tx) · 2286 unmodified lines | |||
| 2287 | 2287 | ||
| 2288 | /** | 2288 | /** |
| 2289 | * ice_ptp_tx_tstamp_cleanup - Cleanup old timestamp requests that got dropped | 2289 | * ice_ptp_tx_tstamp_cleanup - Cleanup old timestamp requests that got dropped |
| 2290 | * @hw: pointer to the hw struct | ||
| 2290 | * @tx: PTP Tx tracker to clean up | 2291 | * @tx: PTP Tx tracker to clean up |
| 2291 | * | 2292 | * |
| 2292 | * Loop through the Tx timestamp requests and see if any of them have been | 2293 | * Loop through the Tx timestamp requests and see if any of them have been |
| @@ -2295,7 +2296,7 @@ ice_ptp_init_tx_e810(struct ice_pf *pf, struct ice_ptp_tx *tx) · 2 unmodified lines | |||
| 2295 | * timestamp will never be captured. This might happen if the packet gets | 2296 | * timestamp will never be captured. This might happen if the packet gets |
| 2296 | * discarded before it reaches the PHY timestamping block. | 2297 | * discarded before it reaches the PHY timestamping block. |
| 2297 | */ | 2298 | */ |
| 2298 | static void ice_ptp_tx_tstamp_cleanup(struct ice_ptp_tx *tx) | 2299 | static void ice_ptp_tx_tstamp_cleanup(struct ice_hw *hw, struct ice_ptp_tx *tx) |
| 2299 | { | 2300 | { |
| 2300 | u8 idx; | 2301 | u8 idx; |
| 2301 | 2302 | ||
| @@ -2304,11 +2305,16 @@ static void ice_ptp_tx_tstamp_cleanup(struct ice_ptp_tx *tx) · 2 unmodified lines | |||
| 2304 | 2305 | ||
| 2305 | for_each_set_bit(idx, tx->in_use, tx->len) { | 2306 | for_each_set_bit(idx, tx->in_use, tx->len) { |
| 2306 | struct sk_buff *skb; | 2307 | struct sk_buff *skb; |
| 2308 | u64 raw_tstamp; | ||
| 2307 | 2309 | ||
| 2308 | /* Check if this SKB has been waiting for too long */ | 2310 | /* Check if this SKB has been waiting for too long */ |
| 2309 | if (time_is_after_jiffies(tx->tstamps[idx].start + 2 * HZ)) | 2311 | if (time_is_after_jiffies(tx->tstamps[idx].start + 2 * HZ)) |
| 2310 | continue; | 2312 | continue; |
| 2311 | 2313 | ||
| 2314 | /* Read tstamp to be able to use this register again */ | ||
| 2315 | ice_read_phy_tstamp(hw, tx->quad, idx + tx->quad_offset, | ||
| 2316 | &raw_tstamp); | ||
| 2317 | |||
| 2312 | spin_lock(&tx->lock); | 2318 | spin_lock(&tx->lock); |
| 2313 | skb = tx->tstamps[idx].skb; | 2319 | skb = tx->tstamps[idx].skb; |
| 2314 | tx->tstamps[idx].skb = NULL; | 2320 | tx->tstamps[idx].skb = NULL; |
| @@ -2330,7 +2336,7 @@ static void ice_ptp_periodic_work(struct kthread_work *work) · 15 unmodified lines | |||
| 2330 | 2336 | ||
| 2331 | ice_ptp_update_cached_phctime(pf); | 2337 | ice_ptp_update_cached_phctime(pf); |
| 2332 | 2338 | ||
| 2333 | ice_ptp_tx_tstamp_cleanup(&pf->ptp.port.tx); | 2339 | ice_ptp_tx_tstamp_cleanup(&pf->hw, &pf->ptp.port.tx); |
| 2334 | 2340 | ||
| 2335 | /* Run twice a second */ | 2341 | /* Run twice a second */ |
| 2336 | kthread_queue_delayed_work(ptp->kworker, &ptp->work, | 2342 | kthread_queue_delayed_work(ptp->kworker, &ptp->work, |
| @@ -1046,8 +1046,8 @@ int ice_sriov_configure(struct pci_dev *pdev, int num_vfs) · 1045 unmodified lines | |||
| 1046 | 1046 | ||
| 1047 | if (!num_vfs) { | 1047 | if (!num_vfs) { |
| 1048 | if (!pci_vfs_assigned(pdev)) { | 1048 | if (!pci_vfs_assigned(pdev)) { |
| 1049 | ice_mbx_deinit_snapshot(&pf->hw); | ||
| 1050 | ice_free_vfs(pf); | 1049 | ice_free_vfs(pf); |
| 1050 | ice_mbx_deinit_snapshot(&pf->hw); | ||
| 1051 | if (pf->lag) | 1051 | if (pf->lag) |
| 1052 | ice_enable_lag(pf->lag); | 1052 | ice_enable_lag(pf->lag); |
| 1053 | return 0; | 1053 | return 0; |
| @@ -1307,13 +1307,52 @@ error_param: · 1306 unmodified lines | |||
| 1307 | NULL, 0); | 1307 | NULL, 0); |
| 1308 | } | 1308 | } |
| 1309 | 1309 | ||
| 1310 | /** | ||
| 1311 | * ice_vf_vsi_dis_single_txq - disable a single Tx queue | ||
| 1312 | * @vf: VF to disable queue for | ||
| 1313 | * @vsi: VSI for the VF | ||
| 1314 | * @q_id: VF relative (0-based) queue ID | ||
| 1315 | * | ||
| 1316 | * Attempt to disable the Tx queue passed in. If the Tx queue was successfully | ||
| 1317 | * disabled then clear q_id bit in the enabled queues bitmap and return | ||
| 1318 | * success. Otherwise return error. | ||
| 1319 | */ | ||
| 1320 | static int | ||
| 1321 | ice_vf_vsi_dis_single_txq(struct ice_vf *vf, struct ice_vsi *vsi, u16 q_id) | ||
| 1322 | { | ||
| 1323 | struct ice_txq_meta txq_meta = { 0 }; | ||
| 1324 | struct ice_tx_ring *ring; | ||
| 1325 | int err; | ||
| 1326 | |||
| 1327 | if (!test_bit(q_id, vf->txq_ena)) | ||
| 1328 | dev_dbg(ice_pf_to_dev(vsi->back), "Queue %u on VSI %u is not enabled, but stopping it anyway\n", | ||
| 1329 | q_id, vsi->vsi_num); | ||
| 1330 | |||
| 1331 | ring = vsi->tx_rings[q_id]; | ||
| 1332 | if (!ring) | ||
| 1333 | return -EINVAL; | ||
| 1334 | |||
| 1335 | ice_fill_txq_meta(vsi, ring, &txq_meta); | ||
| 1336 | |||
| 1337 | err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, vf->vf_id, ring, &txq_meta); | ||
| 1338 | if (err) { | ||
| 1339 | dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Tx ring %d on VSI %d\n", | ||
| 1340 | q_id, vsi->vsi_num); | ||
| 1341 | return err; | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | /* Clear enabled queues flag */ | ||
| 1345 | clear_bit(q_id, vf->txq_ena); | ||
| 1346 | |||
| 1347 | return 0; | ||
| 1348 | } | ||
| 1349 | |||
| 1310 | /** | 1350 | /** |
| 1311 | * ice_vc_dis_qs_msg | 1351 | * ice_vc_dis_qs_msg |
| 1312 | * @vf: pointer to the VF info | 1352 | * @vf: pointer to the VF info |
| 1313 | * @msg: pointer to the msg buffer | 1353 | * @msg: pointer to the msg buffer |
| 1314 | * | 1354 | * |
| 1315 | * called from the VF to disable all or specific | 1355 | * called from the VF to disable all or specific queue(s) |
| 1316 | * queue(s) | ||
| 1317 | */ | 1356 | */ |
| 1318 | static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) | 1357 | static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) |
| 1319 | { | 1358 | { |
| @@ -1350,30 +1389,15 @@ static int ice_vc_dis_qs_msg(struct ice_vf *vf, u8 *msg) · 30 unmodified lines | |||
| 1350 | q_map = vqs->tx_queues; | 1389 | q_map = vqs->tx_queues; |
| 1351 | 1390 | ||
| 1352 | for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { | 1391 | for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) { |
| 1353 | struct ice_tx_ring *ring = vsi->tx_rings[vf_q_id]; | ||
| 1354 | struct ice_txq_meta txq_meta = { 0 }; | ||
| 1355 | |||
| 1356 | if (!ice_vc_isvalid_q_id(vf, vqs->vsi_id, vf_q_id)) { | 1392 | if (!ice_vc_isvalid_q_id(vf, vqs->vsi_id, vf_q_id)) { |
| 1357 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1393 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 1358 | goto error_param; | 1394 | goto error_param; |
| 1359 | } | 1395 | } |
| 1360 | 1396 | ||
| 1361 | if (!test_bit(vf_q_id, vf->txq_ena)) | 1397 | if (ice_vf_vsi_dis_single_txq(vf, vsi, vf_q_id)) { |
| 1362 | dev_dbg(ice_pf_to_dev(vsi->back), "Queue %u on VSI %u is not enabled, but stopping it anyway\n", | ||
| 1363 | vf_q_id, vsi->vsi_num); | ||
| 1364 | |||
| 1365 | ice_fill_txq_meta(vsi, ring, &txq_meta); | ||
| 1366 | |||
| 1367 | if (ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, vf->vf_id, | ||
| 1368 | ring, &txq_meta)) { | ||
| 1369 | dev_err(ice_pf_to_dev(vsi->back), "Failed to stop Tx ring %d on VSI %d\n", | ||
| 1370 | vf_q_id, vsi->vsi_num); | ||
| 1371 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1398 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 1372 | goto error_param; | 1399 | goto error_param; |
| 1373 | } | 1400 | } |
| 1374 | |||
| 1375 | /* Clear enabled queues flag */ | ||
| 1376 | clear_bit(vf_q_id, vf->txq_ena); | ||
| 1377 | } | 1401 | } |
| 1378 | } | 1402 | } |
| 1379 | 1403 | ||
| @@ -1622,6 +1646,14 @@ static int ice_vc_cfg_qs_msg(struct ice_vf *vf, u8 *msg) · 242 unmodified lines | |||
| 1622 | if (qpi->txq.ring_len > 0) { | 1646 | if (qpi->txq.ring_len > 0) { |
| 1623 | vsi->tx_rings[i]->dma = qpi->txq.dma_ring_addr; | 1647 | vsi->tx_rings[i]->dma = qpi->txq.dma_ring_addr; |
| 1624 | vsi->tx_rings[i]->count = qpi->txq.ring_len; | 1648 | vsi->tx_rings[i]->count = qpi->txq.ring_len; |
| 1649 | |||
| 1650 | /* Disable any existing queue first */ | ||
| 1651 | if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx)) { | ||
| 1652 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | ||
| 1653 | goto error_param; | ||
| 1654 | } | ||
| 1655 | |||
| 1656 | /* Configure a queue with the requested settings */ | ||
| 1625 | if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) { | 1657 | if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) { |
| 1626 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; | 1658 | v_ret = VIRTCHNL_STATUS_ERR_PARAM; |
| 1627 | goto error_param; | 1659 | goto error_param; |
| @@ -3625,6 +3657,8 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event) · 1997 unmodified lines | |||
| 3625 | return; | 3657 | return; |
| 3626 | } | 3658 | } |
| 3627 | 3659 | ||
| 3660 | mutex_lock(&vf->cfg_lock); | ||
| 3661 | |||
| 3628 | /* Check if VF is disabled. */ | 3662 | /* Check if VF is disabled. */ |
| 3629 | if (test_bit(ICE_VF_STATE_DIS, vf->vf_states)) { | 3663 | if (test_bit(ICE_VF_STATE_DIS, vf->vf_states)) { |
| 3630 | err = -EPERM; | 3664 | err = -EPERM; |
| @@ -3642,32 +3676,20 @@ void ice_vc_process_vf_msg(struct ice_pf *pf, struct ice_rq_event_info *event) · 11 unmodified lines | |||
| 3642 | err = -EINVAL; | 3676 | err = -EINVAL; |
| 3643 | } | 3677 | } |
| 3644 | 3678 | ||
| 3645 | if (!ice_vc_is_opcode_allowed(vf, v_opcode)) { | ||
| 3646 | ice_vc_send_msg_to_vf(vf, v_opcode, | ||
| 3647 | VIRTCHNL_STATUS_ERR_NOT_SUPPORTED, NULL, | ||
| 3648 | 0); | ||
| 3649 | ice_put_vf(vf); | ||
| 3650 | return; | ||
| 3651 | } | ||
| 3652 | |||
| 3653 | error_handler: | 3679 | error_handler: |
| 3654 | if (err) { | 3680 | if (err) { |
| 3655 | ice_vc_send_msg_to_vf(vf, v_opcode, VIRTCHNL_STATUS_ERR_PARAM, | 3681 | ice_vc_send_msg_to_vf(vf, v_opcode, VIRTCHNL_STATUS_ERR_PARAM, |
| 3656 | NULL, 0); | 3682 | NULL, 0); |
| 3657 | dev_err(dev, "Invalid message from VF %d, opcode %d, len %d, error %d\n", | 3683 | dev_err(dev, "Invalid message from VF %d, opcode %d, len %d, error %d\n", |
| 3658 | vf_id, v_opcode, msglen, err); | 3684 | vf_id, v_opcode, msglen, err); |
| 3659 | ice_put_vf(vf); | 3685 | goto finish; |
| 3660 | return; | ||
| 3661 | } | 3686 | } |
| 3662 | 3687 | ||
| 3663 | /* VF is being configured in another context that triggers a VFR, so no | 3688 | if (!ice_vc_is_opcode_allowed(vf, v_opcode)) { |
| 3664 | * need to process this message | 3689 | ice_vc_send_msg_to_vf(vf, v_opcode, |
| 3665 | */ | 3690 | VIRTCHNL_STATUS_ERR_NOT_SUPPORTED, NULL, |
| 3666 | if (!mutex_trylock(&vf->cfg_lock)) { | 3691 | 0); |
| 3667 | dev_info(dev, "VF %u is being configured in another context that will trigger a VFR, so there is no need to handle this message\n", | 3692 | goto finish; |
| 3668 | vf->vf_id); | ||
| 3669 | ice_put_vf(vf); | ||
| 3670 | return; | ||
| 3671 | } | 3693 | } |
| 3672 | 3694 | ||
| 3673 | switch (v_opcode) { | 3695 | switch (v_opcode) { |
| @@ -3780,6 +3802,7 @@ error_handler: · 106 unmodified lines | |||
| 3780 | vf_id, v_opcode, err); | 3802 | vf_id, v_opcode, err); |
| 3781 | } | 3803 | } |
| 3782 | 3804 | ||
| 3805 | finish: | ||
| 3783 | mutex_unlock(&vf->cfg_lock); | 3806 | mutex_unlock(&vf->cfg_lock); |
| 3784 | ice_put_vf(vf); | 3807 | ice_put_vf(vf); |
| 3785 | } | 3808 | } |
| @@ -903,7 +903,8 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) · 902 unmodified lines | |||
| 903 | /* Tx IPsec offload doesn't seem to work on this | 903 | /* Tx IPsec offload doesn't seem to work on this |
| 904 | * device, so block these requests for now. | 904 | * device, so block these requests for now. |
| 905 | */ | 905 | */ |
| 906 | if (!(sam->flags & XFRM_OFFLOAD_INBOUND)) { | 906 | sam->flags = sam->flags & ~XFRM_OFFLOAD_IPV6; |
| 907 | if (sam->flags != XFRM_OFFLOAD_INBOUND) { | ||
| 907 | err = -EOPNOTSUPP; | 908 | err = -EOPNOTSUPP; |
| 908 | goto err_out; | 909 | goto err_out; |
| 909 | } | 910 | } |
| @@ -395,7 +395,7 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe) · 394 unmodified lines | |||
| 395 | static const u8 skip[] = { 12, 25, 38, 51, 76, 89, 102 }; | 395 | static const u8 skip[] = { 12, 25, 38, 51, 76, 89, 102 }; |
| 396 | int i, k; | 396 | int i, k; |
| 397 | 397 | ||
| 398 | memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(ppe->foe_table)); | 398 | memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(*ppe->foe_table)); |
| 399 | 399 | ||
| 400 | if (!IS_ENABLED(CONFIG_SOC_MT7621)) | 400 | if (!IS_ENABLED(CONFIG_SOC_MT7621)) |
| 401 | return; | 401 | return; |
| @@ -26,6 +26,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3) · 25 unmodified lines | |||
| 26 | break; | 26 | break; |
| 27 | 27 | ||
| 28 | ss->regmap[i] = syscon_node_to_regmap(np); | 28 | ss->regmap[i] = syscon_node_to_regmap(np); |
| 29 | of_node_put(np); | ||
| 29 | if (IS_ERR(ss->regmap[i])) | 30 | if (IS_ERR(ss->regmap[i])) |
| 30 | return PTR_ERR(ss->regmap[i]); | 31 | return PTR_ERR(ss->regmap[i]); |
| 31 | } | 32 | } |
| @@ -31,6 +31,7 @@ static const char *const mlx5_rsc_sgmt_name[] = { · 30 unmodified lines | |||
| 31 | struct mlx5_rsc_dump { | 31 | struct mlx5_rsc_dump { |
| 32 | u32 pdn; | 32 | u32 pdn; |
| 33 | u32 mkey; | 33 | u32 mkey; |
| 34 | u32 number_of_menu_items; | ||
| 34 | u16 fw_segment_type[MLX5_SGMT_TYPE_NUM]; | 35 | u16 fw_segment_type[MLX5_SGMT_TYPE_NUM]; |
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| @@ -50,21 +51,37 @@ static int mlx5_rsc_dump_sgmt_get_by_name(char *name) · 13 unmodified lines | |||
| 50 | return -EINVAL; | 51 | return -EINVAL; |
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | static void mlx5_rsc_dump_read_menu_sgmt(struct mlx5_rsc_dump *rsc_dump, struct page *page) | 54 | #define MLX5_RSC_DUMP_MENU_HEADER_SIZE (MLX5_ST_SZ_BYTES(resource_dump_info_segment) + \ |
| 55 | MLX5_ST_SZ_BYTES(resource_dump_command_segment) + \ | ||
| 56 | MLX5_ST_SZ_BYTES(resource_dump_menu_segment)) | ||
| 57 | |||
| 58 | static int mlx5_rsc_dump_read_menu_sgmt(struct mlx5_rsc_dump *rsc_dump, struct page *page, | ||
| 59 | int read_size, int start_idx) | ||
| 54 | { | 60 | { |
| 55 | void *data = page_address(page); | 61 | void *data = page_address(page); |
| 56 | enum mlx5_sgmt_type sgmt_idx; | 62 | enum mlx5_sgmt_type sgmt_idx; |
| 57 | int num_of_items; | 63 | int num_of_items; |
| 58 | char *sgmt_name; | 64 | char *sgmt_name; |
| 59 | void *member; | 65 | void *member; |
| 66 | int size = 0; | ||
| 60 | void *menu; | 67 | void *menu; |
| 61 | int i; | 68 | int i; |
| 62 | 69 | ||
| 63 | menu = MLX5_ADDR_OF(menu_resource_dump_response, data, menu); | 70 | if (!start_idx) { |
| 64 | num_of_items = MLX5_GET(resource_dump_menu_segment, menu, num_of_records); | 71 | menu = MLX5_ADDR_OF(menu_resource_dump_response, data, menu); |
| 72 | rsc_dump->number_of_menu_items = MLX5_GET(resource_dump_menu_segment, menu, | ||
| 73 | num_of_records); | ||
| 74 | size = MLX5_RSC_DUMP_MENU_HEADER_SIZE; | ||
| 75 | data += size; | ||
| 76 | } | ||
| 77 | num_of_items = rsc_dump->number_of_menu_items; | ||
| 78 | |||
| 79 | for (i = 0; start_idx + i < num_of_items; i++) { | ||
| 80 | size += MLX5_ST_SZ_BYTES(resource_dump_menu_record); | ||
| 81 | if (size >= read_size) | ||
| 82 | return start_idx + i; | ||
| 65 | 83 | ||
| 66 | for (i = 0; i < num_of_items; i++) { | 84 | member = data + MLX5_ST_SZ_BYTES(resource_dump_menu_record) * i; |
| 67 | member = MLX5_ADDR_OF(resource_dump_menu_segment, menu, record[i]); | ||
| 68 | sgmt_name = MLX5_ADDR_OF(resource_dump_menu_record, member, segment_name); | 85 | sgmt_name = MLX5_ADDR_OF(resource_dump_menu_record, member, segment_name); |
| 69 | sgmt_idx = mlx5_rsc_dump_sgmt_get_by_name(sgmt_name); | 86 | sgmt_idx = mlx5_rsc_dump_sgmt_get_by_name(sgmt_name); |
| 70 | if (sgmt_idx == -EINVAL) | 87 | if (sgmt_idx == -EINVAL) |
| @@ -72,6 +89,7 @@ static void mlx5_rsc_dump_read_menu_sgmt(struct mlx5_rsc_dump *rsc_dump, struct · 1 unmodified line | |||
| 72 | rsc_dump->fw_segment_type[sgmt_idx] = MLX5_GET(resource_dump_menu_record, | 89 | rsc_dump->fw_segment_type[sgmt_idx] = MLX5_GET(resource_dump_menu_record, |
| 73 | member, segment_type); | 90 | member, segment_type); |
| 74 | } | 91 | } |
| 92 | return 0; | ||
| 75 | } | 93 | } |
| 76 | 94 | ||
| 77 | static int mlx5_rsc_dump_trigger(struct mlx5_core_dev *dev, struct mlx5_rsc_dump_cmd *cmd, | 95 | static int mlx5_rsc_dump_trigger(struct mlx5_core_dev *dev, struct mlx5_rsc_dump_cmd *cmd, |
| @@ -168,6 +186,7 @@ static int mlx5_rsc_dump_menu(struct mlx5_core_dev *dev) · 90 unmodified lines | |||
| 168 | struct mlx5_rsc_dump_cmd *cmd = NULL; | 186 | struct mlx5_rsc_dump_cmd *cmd = NULL; |
| 169 | struct mlx5_rsc_key key = {}; | 187 | struct mlx5_rsc_key key = {}; |
| 170 | struct page *page; | 188 | struct page *page; |
| 189 | int start_idx = 0; | ||
| 171 | int size; | 190 | int size; |
| 172 | int err; | 191 | int err; |
| 173 | 192 | ||
| @@ -189,7 +208,7 @@ static int mlx5_rsc_dump_menu(struct mlx5_core_dev *dev) · 15 unmodified lines | |||
| 189 | if (err < 0) | 208 | if (err < 0) |
| 190 | goto destroy_cmd; | 209 | goto destroy_cmd; |
| 191 | 210 | ||
| 192 | mlx5_rsc_dump_read_menu_sgmt(dev->rsc_dump, page); | 211 | start_idx = mlx5_rsc_dump_read_menu_sgmt(dev->rsc_dump, page, size, start_idx); |
| 193 | 212 | ||
| 194 | } while (err > 0); | 213 | } while (err > 0); |
| 195 | 214 | ||
| @@ -309,8 +309,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, · 308 unmodified lines | |||
| 309 | if (err) | 309 | if (err) |
| 310 | return err; | 310 | return err; |
| 311 | 311 | ||
| 312 | err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer, port_buff_cell_sz, | 312 | err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer, xoff, |
| 313 | xoff, &port_buffer, &update_buffer); | 313 | port_buff_cell_sz, &port_buffer, &update_buffer); |
| 314 | if (err) | 314 | if (err) |
| 315 | return err; | 315 | return err; |
| 316 | } | 316 | } |
| @@ -145,8 +145,7 @@ mlx5e_tc_act_post_parse(struct mlx5e_tc_act_parse_state *parse_state, · 144 unmodified lines | |||
| 145 | 145 | ||
| 146 | flow_action_for_each(i, act, flow_action) { | 146 | flow_action_for_each(i, act, flow_action) { |
| 147 | tc_act = mlx5e_tc_act_get(act->id, ns_type); | 147 | tc_act = mlx5e_tc_act_get(act->id, ns_type); |
| 148 | if (!tc_act || !tc_act->post_parse || | 148 | if (!tc_act || !tc_act->post_parse) |
| 149 | !tc_act->can_offload(parse_state, act, i, attr)) | ||
| 150 | continue; | 149 | continue; |
| 151 | 150 | ||
| 152 | err = tc_act->post_parse(parse_state, priv, attr); | 151 | err = tc_act->post_parse(parse_state, priv, attr); |
| @@ -45,12 +45,41 @@ tc_act_parse_ct(struct mlx5e_tc_act_parse_state *parse_state, · 44 unmodified lines | |||
| 45 | if (mlx5e_is_eswitch_flow(parse_state->flow)) | 45 | if (mlx5e_is_eswitch_flow(parse_state->flow)) |
| 46 | attr->esw_attr->split_count = attr->esw_attr->out_count; | 46 | attr->esw_attr->split_count = attr->esw_attr->out_count; |
| 47 | 47 | ||
| 48 | if (!clear_action) { | 48 | if (clear_action) { |
| 49 | parse_state->ct_clear = true; | ||
| 50 | } else { | ||
| 49 | attr->flags |= MLX5_ATTR_FLAG_CT; | 51 | attr->flags |= MLX5_ATTR_FLAG_CT; |
| 50 | flow_flag_set(parse_state->flow, CT); | 52 | flow_flag_set(parse_state->flow, CT); |
| 51 | parse_state->ct = true; | 53 | parse_state->ct = true; |
| 52 | } | 54 | } |
| 53 | parse_state->ct_clear = clear_action; | 55 | |
| 56 | return 0; | ||
| 57 | } | ||
| 58 | |||
| 59 | static int | ||
| 60 | tc_act_post_parse_ct(struct mlx5e_tc_act_parse_state *parse_state, | ||
| 61 | struct mlx5e_priv *priv, | ||
| 62 | struct mlx5_flow_attr *attr) | ||
| 63 | { | ||
| 64 | struct mlx5e_tc_mod_hdr_acts *mod_acts = &attr->parse_attr->mod_hdr_acts; | ||
| 65 | int err; | ||
| 66 | |||
| 67 | /* If ct action exist, we can ignore previous ct_clear actions */ | ||
| 68 | if (parse_state->ct) | ||
| 69 | return 0; | ||
| 70 | |||
| 71 | if (parse_state->ct_clear) { | ||
| 72 | err = mlx5_tc_ct_set_ct_clear_regs(parse_state->ct_priv, mod_acts); | ||
| 73 | if (err) { | ||
| 74 | NL_SET_ERR_MSG_MOD(parse_state->extack, | ||
| 75 | "Failed to set registers for ct clear"); | ||
| 76 | return err; | ||
| 77 | } | ||
| 78 | attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; | ||
| 79 | |||
| 80 | /* Prevent handling of additional, redundant clear actions */ | ||
| 81 | parse_state->ct_clear = false; | ||
| 82 | } | ||
| 54 | 83 | ||
| 55 | return 0; | 84 | return 0; |
| 56 | } | 85 | } |
| @@ -70,5 +99,6 @@ struct mlx5e_tc_act mlx5e_tc_act_ct = { · 13 unmodified lines | |||
| 70 | .can_offload = tc_act_can_offload_ct, | 99 | .can_offload = tc_act_can_offload_ct, |
| 71 | .parse_action = tc_act_parse_ct, | 100 | .parse_action = tc_act_parse_ct, |
| 72 | .is_multi_table_act = tc_act_is_multi_table_act_ct, | 101 | .is_multi_table_act = tc_act_is_multi_table_act_ct, |
| 102 | .post_parse = tc_act_post_parse_ct, | ||
| 73 | }; | 103 | }; |
| 74 | 104 | ||
| @@ -582,6 +582,12 @@ mlx5_tc_ct_entry_set_registers(struct mlx5_tc_ct_priv *ct_priv, · 581 unmodified lines | |||
| 582 | return 0; | 582 | return 0; |
| 583 | } | 583 | } |
| 584 | 584 | ||
| 585 | int mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv, | ||
| 586 | struct mlx5e_tc_mod_hdr_acts *mod_acts) | ||
| 587 | { | ||
| 588 | return mlx5_tc_ct_entry_set_registers(priv, mod_acts, 0, 0, 0, 0); | ||
| 589 | } | ||
| 590 | |||
| 585 | static int | 591 | static int |
| 586 | mlx5_tc_ct_parse_mangle_to_mod_act(struct flow_action_entry *act, | 592 | mlx5_tc_ct_parse_mangle_to_mod_act(struct flow_action_entry *act, |
| 587 | char *modact) | 593 | char *modact) |
| @@ -1410,9 +1416,6 @@ mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, · 822 unmodified lines | |||
| 1410 | const struct flow_action_entry *act, | 1416 | const struct flow_action_entry *act, |
| 1411 | struct netlink_ext_ack *extack) | 1417 | struct netlink_ext_ack *extack) |
| 1412 | { | 1418 | { |
| 1413 | bool clear_action = act->ct.action & TCA_CT_ACT_CLEAR; | ||
| 1414 | int err; | ||
| 1415 | |||
| 1416 | if (!priv) { | 1419 | if (!priv) { |
| 1417 | NL_SET_ERR_MSG_MOD(extack, | 1420 | NL_SET_ERR_MSG_MOD(extack, |
| 1418 | "offload of ct action isn't available"); | 1421 | "offload of ct action isn't available"); |
| @@ -1423,17 +1426,6 @@ mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, · 4 unmodified lines | |||
| 1423 | attr->ct_attr.ct_action = act->ct.action; | 1426 | attr->ct_attr.ct_action = act->ct.action; |
| 1424 | attr->ct_attr.nf_ft = act->ct.flow_table; | 1427 | attr->ct_attr.nf_ft = act->ct.flow_table; |
| 1425 | 1428 | ||
| 1426 | if (!clear_action) | ||
| 1427 | goto out; | ||
| 1428 | |||
| 1429 | err = mlx5_tc_ct_entry_set_registers(priv, mod_acts, 0, 0, 0, 0); | ||
| 1430 | if (err) { | ||
| 1431 | NL_SET_ERR_MSG_MOD(extack, "Failed to set registers for ct clear"); | ||
| 1432 | return err; | ||
| 1433 | } | ||
| 1434 | attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; | ||
| 1435 | |||
| 1436 | out: | ||
| 1437 | return 0; | 1429 | return 0; |
| 1438 | } | 1430 | } |
| 1439 | 1431 | ||
| @@ -1749,6 +1741,8 @@ mlx5_tc_ct_flush_ft_entry(void *ptr, void *arg) · 309 unmodified lines | |||
| 1749 | static void | 1741 | static void |
| 1750 | mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft) | 1742 | mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft) |
| 1751 | { | 1743 | { |
| 1744 | struct mlx5e_priv *priv; | ||
| 1745 | |||
| 1752 | if (!refcount_dec_and_test(&ft->refcount)) | 1746 | if (!refcount_dec_and_test(&ft->refcount)) |
| 1753 | return; | 1747 | return; |
| 1754 | 1748 | ||
| @@ -1758,6 +1752,8 @@ mlx5_tc_ct_del_ft_cb(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_ct_ft *ft) · 3 unmodified lines | |||
| 1758 | rhashtable_free_and_destroy(&ft->ct_entries_ht, | 1752 | rhashtable_free_and_destroy(&ft->ct_entries_ht, |
| 1759 | mlx5_tc_ct_flush_ft_entry, | 1753 | mlx5_tc_ct_flush_ft_entry, |
| 1760 | ct_priv); | 1754 | ct_priv); |
| 1755 | priv = netdev_priv(ct_priv->netdev); | ||
| 1756 | flush_workqueue(priv->wq); | ||
| 1761 | mlx5_tc_ct_free_pre_ct_tables(ft); | 1757 | mlx5_tc_ct_free_pre_ct_tables(ft); |
| 1762 | mapping_remove(ct_priv->zone_mapping, ft->zone_restore_id); | 1758 | mapping_remove(ct_priv->zone_mapping, ft->zone_restore_id); |
| 1763 | kfree(ft); | 1759 | kfree(ft); |
| @@ -129,6 +129,10 @@ bool · 128 unmodified lines | |||
| 129 | mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv, | 129 | mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv, |
| 130 | struct sk_buff *skb, u8 zone_restore_id); | 130 | struct sk_buff *skb, u8 zone_restore_id); |
| 131 | 131 | ||
| 132 | int | ||
| 133 | mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv, | ||
| 134 | struct mlx5e_tc_mod_hdr_acts *mod_acts); | ||
| 135 | |||
| 132 | #else /* CONFIG_MLX5_TC_CT */ | 136 | #else /* CONFIG_MLX5_TC_CT */ |
| 133 | 137 | ||
| 134 | static inline struct mlx5_tc_ct_priv * | 138 | static inline struct mlx5_tc_ct_priv * |
| @@ -170,6 +174,13 @@ mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec) · 35 unmodified lines | |||
| 170 | return 0; | 174 | return 0; |
| 171 | } | 175 | } |
| 172 | 176 | ||
| 177 | static inline int | ||
| 178 | mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv, | ||
| 179 | struct mlx5e_tc_mod_hdr_acts *mod_acts) | ||
| 180 | { | ||
| 181 | return -EOPNOTSUPP; | ||
| 182 | } | ||
| 183 | |||
| 173 | static inline int | 184 | static inline int |
| 174 | mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, | 185 | mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, |
| 175 | struct mlx5_flow_attr *attr, | 186 | struct mlx5_flow_attr *attr, |
| @@ -713,6 +713,7 @@ int mlx5e_tc_tun_route_lookup(struct mlx5e_priv *priv, · 712 unmodified lines | |||
| 713 | struct net_device *filter_dev) | 713 | struct net_device *filter_dev) |
| 714 | { | 714 | { |
| 715 | struct mlx5_esw_flow_attr *esw_attr = flow_attr->esw_attr; | 715 | struct mlx5_esw_flow_attr *esw_attr = flow_attr->esw_attr; |
| 716 | struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; | ||
| 716 | struct mlx5e_tc_int_port *int_port; | 717 | struct mlx5e_tc_int_port *int_port; |
| 717 | TC_TUN_ROUTE_ATTR_INIT(attr); | 718 | TC_TUN_ROUTE_ATTR_INIT(attr); |
| 718 | u16 vport_num; | 719 | u16 vport_num; |
| @@ -747,7 +748,7 @@ int mlx5e_tc_tun_route_lookup(struct mlx5e_priv *priv, · 28 unmodified lines | |||
| 747 | esw_attr->rx_tun_attr->vni = MLX5_GET(fte_match_param, spec->match_value, | 748 | esw_attr->rx_tun_attr->vni = MLX5_GET(fte_match_param, spec->match_value, |
| 748 | misc_parameters.vxlan_vni); | 749 | misc_parameters.vxlan_vni); |
| 749 | esw_attr->rx_tun_attr->decap_vport = vport_num; | 750 | esw_attr->rx_tun_attr->decap_vport = vport_num; |
| 750 | } else if (netif_is_ovs_master(attr.route_dev)) { | 751 | } else if (netif_is_ovs_master(attr.route_dev) && mlx5e_tc_int_port_supported(esw)) { |
| 751 | int_port = mlx5e_tc_int_port_get(mlx5e_get_int_port_priv(priv), | 752 | int_port = mlx5e_tc_int_port_get(mlx5e_get_int_port_priv(priv), |
| 752 | attr.route_dev->ifindex, | 753 | attr.route_dev->ifindex, |
| 753 | MLX5E_TC_INT_PORT_INGRESS); | 754 | MLX5E_TC_INT_PORT_INGRESS); |
| @@ -1200,6 +1200,16 @@ static int mlx5e_trust_initialize(struct mlx5e_priv *priv) · 1199 unmodified lines | |||
| 1200 | return err; | 1200 | return err; |
| 1201 | WRITE_ONCE(priv->dcbx_dp.trust_state, trust_state); | 1201 | WRITE_ONCE(priv->dcbx_dp.trust_state, trust_state); |
| 1202 | 1202 | ||
| 1203 | if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_PCP && priv->dcbx.dscp_app_cnt) { | ||
| 1204 | /* | ||
| 1205 | * Align the driver state with the register state. | ||
| 1206 | * Temporary state change is required to enable the app list reset. | ||
| 1207 | */ | ||
| 1208 | priv->dcbx_dp.trust_state = MLX5_QPTS_TRUST_DSCP; | ||
| 1209 | mlx5e_dcbnl_delete_app(priv); | ||
| 1210 | priv->dcbx_dp.trust_state = MLX5_QPTS_TRUST_PCP; | ||
| 1211 | } | ||
| 1212 | |||
| 1203 | mlx5e_params_calc_trust_tx_min_inline_mode(priv->mdev, &priv->channels.params, | 1213 | mlx5e_params_calc_trust_tx_min_inline_mode(priv->mdev, &priv->channels.params, |
| 1204 | priv->dcbx_dp.trust_state); | 1214 | priv->dcbx_dp.trust_state); |
| 1205 | 1215 | ||
| @@ -2459,6 +2459,17 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, · 2458 unmodified lines | |||
| 2459 | match.key->vlan_priority); | 2459 | match.key->vlan_priority); |
| 2460 | 2460 | ||
| 2461 | *match_level = MLX5_MATCH_L2; | 2461 | *match_level = MLX5_MATCH_L2; |
| 2462 | |||
| 2463 | if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CVLAN) && | ||
| 2464 | match.mask->vlan_eth_type && | ||
| 2465 | MLX5_CAP_FLOWTABLE_TYPE(priv->mdev, | ||
| 2466 | ft_field_support.outer_second_vid, | ||
| 2467 | fs_type)) { | ||
| 2468 | MLX5_SET(fte_match_set_misc, misc_c, | ||
| 2469 | outer_second_cvlan_tag, 1); | ||
| 2470 | spec->match_criteria_enable |= | ||
| 2471 | MLX5_MATCH_MISC_PARAMETERS; | ||
| 2472 | } | ||
| 2462 | } | 2473 | } |
| 2463 | } else if (*match_level != MLX5_MATCH_NONE) { | 2474 | } else if (*match_level != MLX5_MATCH_NONE) { |
| 2464 | /* cvlan_tag enabled in match criteria and | 2475 | /* cvlan_tag enabled in match criteria and |
| @@ -139,7 +139,7 @@ mlx5_eswitch_set_rule_source_port(struct mlx5_eswitch *esw, · 138 unmodified lines | |||
| 139 | if (mlx5_esw_indir_table_decap_vport(attr)) | 139 | if (mlx5_esw_indir_table_decap_vport(attr)) |
| 140 | vport = mlx5_esw_indir_table_decap_vport(attr); | 140 | vport = mlx5_esw_indir_table_decap_vport(attr); |
| 141 | 141 | ||
| 142 | if (esw_attr->int_port) | 142 | if (attr && !attr->chain && esw_attr->int_port) |
| 143 | metadata = | 143 | metadata = |
| 144 | mlx5e_tc_int_port_get_metadata_for_match(esw_attr->int_port); | 144 | mlx5e_tc_int_port_get_metadata_for_match(esw_attr->int_port); |
| 145 | else | 145 | else |
| @@ -155,6 +155,28 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev) · 154 unmodified lines | |||
| 155 | } | 155 | } |
| 156 | } | 156 | } |
| 157 | 157 | ||
| 158 | static void mlx5_stop_sync_reset_poll(struct mlx5_core_dev *dev) | ||
| 159 | { | ||
| 160 | struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; | ||
| 161 | |||
| 162 | del_timer_sync(&fw_reset->timer); | ||
| 163 | } | ||
| 164 | |||
| 165 | static int mlx5_sync_reset_clear_reset_requested(struct mlx5_core_dev *dev, bool poll_health) | ||
| 166 | { | ||
| 167 | struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; | ||
| 168 | |||
| 169 | if (!test_and_clear_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags)) { | ||
| 170 | mlx5_core_warn(dev, "Reset request was already cleared\n"); | ||
| 171 | return -EALREADY; | ||
| 172 | } | ||
| 173 | |||
| 174 | mlx5_stop_sync_reset_poll(dev); | ||
| 175 | if (poll_health) | ||
| 176 | mlx5_start_health_poll(dev); | ||
| 177 | return 0; | ||
| 178 | } | ||
| 179 | |||
| 158 | static void mlx5_sync_reset_reload_work(struct work_struct *work) | 180 | static void mlx5_sync_reset_reload_work(struct work_struct *work) |
| 159 | { | 181 | { |
| 160 | struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset, | 182 | struct mlx5_fw_reset *fw_reset = container_of(work, struct mlx5_fw_reset, |
| @@ -162,6 +184,7 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work) · 1 unmodified line | |||
| 162 | struct mlx5_core_dev *dev = fw_reset->dev; | 184 | struct mlx5_core_dev *dev = fw_reset->dev; |
| 163 | int err; | 185 | int err; |
| 164 | 186 | ||
| 187 | mlx5_sync_reset_clear_reset_requested(dev, false); | ||
| 165 | mlx5_enter_error_state(dev, true); | 188 | mlx5_enter_error_state(dev, true); |
| 166 | mlx5_unload_one(dev); | 189 | mlx5_unload_one(dev); |
| 167 | err = mlx5_health_wait_pci_up(dev); | 190 | err = mlx5_health_wait_pci_up(dev); |
| @@ -171,23 +194,6 @@ static void mlx5_sync_reset_reload_work(struct work_struct *work) · 3 unmodified lines | |||
| 171 | mlx5_fw_reset_complete_reload(dev); | 194 | mlx5_fw_reset_complete_reload(dev); |
| 172 | } | 195 | } |
| 173 | 196 | ||
| 174 | static void mlx5_stop_sync_reset_poll(struct mlx5_core_dev *dev) | ||
| 175 | { | ||
| 176 | struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; | ||
| 177 | |||
| 178 | del_timer_sync(&fw_reset->timer); | ||
| 179 | } | ||
| 180 | |||
| 181 | static void mlx5_sync_reset_clear_reset_requested(struct mlx5_core_dev *dev, bool poll_health) | ||
| 182 | { | ||
| 183 | struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; | ||
| 184 | |||
| 185 | mlx5_stop_sync_reset_poll(dev); | ||
| 186 | clear_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags); | ||
| 187 | if (poll_health) | ||
| 188 | mlx5_start_health_poll(dev); | ||
| 189 | } | ||
| 190 | |||
| 191 | #define MLX5_RESET_POLL_INTERVAL (HZ / 10) | 197 | #define MLX5_RESET_POLL_INTERVAL (HZ / 10) |
| 192 | static void poll_sync_reset(struct timer_list *t) | 198 | static void poll_sync_reset(struct timer_list *t) |
| 193 | { | 199 | { |
| @@ -202,7 +208,6 @@ static void poll_sync_reset(struct timer_list *t) · 8 unmodified lines | |||
| 202 | 208 | ||
| 203 | if (fatal_error) { | 209 | if (fatal_error) { |
| 204 | mlx5_core_warn(dev, "Got Device Reset\n"); | 210 | mlx5_core_warn(dev, "Got Device Reset\n"); |
| 205 | mlx5_sync_reset_clear_reset_requested(dev, false); | ||
| 206 | queue_work(fw_reset->wq, &fw_reset->reset_reload_work); | 211 | queue_work(fw_reset->wq, &fw_reset->reset_reload_work); |
| 207 | return; | 212 | return; |
| 208 | } | 213 | } |
| @@ -229,13 +234,17 @@ static int mlx5_fw_reset_set_reset_sync_nack(struct mlx5_core_dev *dev) · 20 unmodified lines | |||
| 229 | return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL3, 0, 2, false); | 234 | return mlx5_reg_mfrl_set(dev, MLX5_MFRL_REG_RESET_LEVEL3, 0, 2, false); |
| 230 | } | 235 | } |
| 231 | 236 | ||
| 232 | static void mlx5_sync_reset_set_reset_requested(struct mlx5_core_dev *dev) | 237 | static int mlx5_sync_reset_set_reset_requested(struct mlx5_core_dev *dev) |
| 233 | { | 238 | { |
| 234 | struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; | 239 | struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset; |
| 235 | 240 | ||
| 241 | if (test_and_set_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags)) { | ||
| 242 | mlx5_core_warn(dev, "Reset request was already set\n"); | ||
| 243 | return -EALREADY; | ||
| 244 | } | ||
| 236 | mlx5_stop_health_poll(dev, true); | 245 | mlx5_stop_health_poll(dev, true); |
| 237 | set_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags); | ||
| 238 | mlx5_start_sync_reset_poll(dev); | 246 | mlx5_start_sync_reset_poll(dev); |
| 247 | return 0; | ||
| 239 | } | 248 | } |
| 240 | 249 | ||
| 241 | static void mlx5_fw_live_patch_event(struct work_struct *work) | 250 | static void mlx5_fw_live_patch_event(struct work_struct *work) |
| @@ -264,7 +273,9 @@ static void mlx5_sync_reset_request_event(struct work_struct *work) · 22 unmodified lines | |||
| 264 | err ? "Failed" : "Sent"); | 273 | err ? "Failed" : "Sent"); |
| 265 | return; | 274 | return; |
| 266 | } | 275 | } |
| 267 | mlx5_sync_reset_set_reset_requested(dev); | 276 | if (mlx5_sync_reset_set_reset_requested(dev)) |
| 277 | return; | ||
| 278 | |||
| 268 | err = mlx5_fw_reset_set_reset_sync_ack(dev); | 279 | err = mlx5_fw_reset_set_reset_sync_ack(dev); |
| 269 | if (err) | 280 | if (err) |
| 270 | mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack Failed. Error code: %d\n", err); | 281 | mlx5_core_warn(dev, "PCI Sync FW Update Reset Ack Failed. Error code: %d\n", err); |
| @@ -362,7 +373,8 @@ static void mlx5_sync_reset_now_event(struct work_struct *work) · 91 unmodified lines | |||
| 362 | struct mlx5_core_dev *dev = fw_reset->dev; | 373 | struct mlx5_core_dev *dev = fw_reset->dev; |
| 363 | int err; | 374 | int err; |
| 364 | 375 | ||
| 365 | mlx5_sync_reset_clear_reset_requested(dev, false); | 376 | if (mlx5_sync_reset_clear_reset_requested(dev, false)) |
| 377 | return; | ||
| 366 | 378 | ||
| 367 | mlx5_core_warn(dev, "Sync Reset now. Device is going to reset.\n"); | 379 | mlx5_core_warn(dev, "Sync Reset now. Device is going to reset.\n"); |
| 368 | 380 | ||
| @@ -391,10 +403,8 @@ static void mlx5_sync_reset_abort_event(struct work_struct *work) · 22 unmodified lines | |||
| 391 | reset_abort_work); | 403 | reset_abort_work); |
| 392 | struct mlx5_core_dev *dev = fw_reset->dev; | 404 | struct mlx5_core_dev *dev = fw_reset->dev; |
| 393 | 405 | ||
| 394 | if (!test_bit(MLX5_FW_RESET_FLAGS_RESET_REQUESTED, &fw_reset->reset_flags)) | 406 | if (mlx5_sync_reset_clear_reset_requested(dev, true)) |
| 395 | return; | 407 | return; |
| 396 | |||
| 397 | mlx5_sync_reset_clear_reset_requested(dev, true); | ||
| 398 | mlx5_core_warn(dev, "PCI Sync FW Update Reset Aborted.\n"); | 408 | mlx5_core_warn(dev, "PCI Sync FW Update Reset Aborted.\n"); |
| 399 | } | 409 | } |
| 400 | 410 | ||
| @@ -100,6 +100,14 @@ static void mlx5_lag_fib_event_flush(struct notifier_block *nb) · 99 unmodified lines | |||
| 100 | flush_workqueue(mp->wq); | 100 | flush_workqueue(mp->wq); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | static void mlx5_lag_fib_set(struct lag_mp *mp, struct fib_info *fi, u32 dst, int dst_len) | ||
| 104 | { | ||
| 105 | mp->fib.mfi = fi; | ||
| 106 | mp->fib.priority = fi->fib_priority; | ||
| 107 | mp->fib.dst = dst; | ||
| 108 | mp->fib.dst_len = dst_len; | ||
| 109 | } | ||
| 110 | |||
| 103 | struct mlx5_fib_event_work { | 111 | struct mlx5_fib_event_work { |
| 104 | struct work_struct work; | 112 | struct work_struct work; |
| 105 | struct mlx5_lag *ldev; | 113 | struct mlx5_lag *ldev; |
| @@ -110,10 +118,10 @@ struct mlx5_fib_event_work { · 4 unmodified lines | |||
| 110 | }; | 118 | }; |
| 111 | }; | 119 | }; |
| 112 | 120 | ||
| 113 | static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev, | 121 | static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev, unsigned long event, |
| 114 | unsigned long event, | 122 | struct fib_entry_notifier_info *fen_info) |
| 115 | struct fib_info *fi) | ||
| 116 | { | 123 | { |
| 124 | struct fib_info *fi = fen_info->fi; | ||
| 117 | struct lag_mp *mp = &ldev->lag_mp; | 125 | struct lag_mp *mp = &ldev->lag_mp; |
| 118 | struct fib_nh *fib_nh0, *fib_nh1; | 126 | struct fib_nh *fib_nh0, *fib_nh1; |
| 119 | unsigned int nhs; | 127 | unsigned int nhs; |
| @@ -121,13 +129,15 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev, · 1 unmodified line | |||
| 121 | /* Handle delete event */ | 129 | /* Handle delete event */ |
| 122 | if (event == FIB_EVENT_ENTRY_DEL) { | 130 | if (event == FIB_EVENT_ENTRY_DEL) { |
| 123 | /* stop track */ | 131 | /* stop track */ |
| 124 | if (mp->mfi == fi) | 132 | if (mp->fib.mfi == fi) |
| 125 | mp->mfi = NULL; | 133 | mp->fib.mfi = NULL; |
| 126 | return; | 134 | return; |
| 127 | } | 135 | } |
| 128 | 136 | ||
| 129 | /* Handle multipath entry with lower priority value */ | 137 | /* Handle multipath entry with lower priority value */ |
| 130 | if (mp->mfi && mp->mfi != fi && fi->fib_priority >= mp->mfi->fib_priority) | 138 | if (mp->fib.mfi && mp->fib.mfi != fi && |
| 139 | (mp->fib.dst != fen_info->dst || mp->fib.dst_len != fen_info->dst_len) && | ||
| 140 | fi->fib_priority >= mp->fib.priority) | ||
| 131 | return; | 141 | return; |
| 132 | 142 | ||
| 133 | /* Handle add/replace event */ | 143 | /* Handle add/replace event */ |
| @@ -143,9 +153,9 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev, · 9 unmodified lines | |||
| 143 | 153 | ||
| 144 | i++; | 154 | i++; |
| 145 | mlx5_lag_set_port_affinity(ldev, i); | 155 | mlx5_lag_set_port_affinity(ldev, i); |
| 156 | mlx5_lag_fib_set(mp, fi, fen_info->dst, fen_info->dst_len); | ||
| 146 | } | 157 | } |
| 147 | 158 | ||
| 148 | mp->mfi = fi; | ||
| 149 | return; | 159 | return; |
| 150 | } | 160 | } |
| 151 | 161 | ||
| @@ -165,7 +175,7 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev, · 13 unmodified lines | |||
| 165 | } | 175 | } |
| 166 | 176 | ||
| 167 | /* First time we see multipath route */ | 177 | /* First time we see multipath route */ |
| 168 | if (!mp->mfi && !__mlx5_lag_is_active(ldev)) { | 178 | if (!mp->fib.mfi && !__mlx5_lag_is_active(ldev)) { |
| 169 | struct lag_tracker tracker; | 179 | struct lag_tracker tracker; |
| 170 | 180 | ||
| 171 | tracker = ldev->tracker; | 181 | tracker = ldev->tracker; |
| @@ -173,7 +183,7 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev, · 1 unmodified line | |||
| 173 | } | 183 | } |
| 174 | 184 | ||
| 175 | mlx5_lag_set_port_affinity(ldev, MLX5_LAG_NORMAL_AFFINITY); | 185 | mlx5_lag_set_port_affinity(ldev, MLX5_LAG_NORMAL_AFFINITY); |
| 176 | mp->mfi = fi; | 186 | mlx5_lag_fib_set(mp, fi, fen_info->dst, fen_info->dst_len); |
| 177 | } | 187 | } |
| 178 | 188 | ||
| 179 | static void mlx5_lag_fib_nexthop_event(struct mlx5_lag *ldev, | 189 | static void mlx5_lag_fib_nexthop_event(struct mlx5_lag *ldev, |
| @@ -184,7 +194,7 @@ static void mlx5_lag_fib_nexthop_event(struct mlx5_lag *ldev, · 4 unmodified lines | |||
| 184 | struct lag_mp *mp = &ldev->lag_mp; | 194 | struct lag_mp *mp = &ldev->lag_mp; |
| 185 | 195 | ||
| 186 | /* Check the nh event is related to the route */ | 196 | /* Check the nh event is related to the route */ |
| 187 | if (!mp->mfi || mp->mfi != fi) | 197 | if (!mp->fib.mfi || mp->fib.mfi != fi) |
| 188 | return; | 198 | return; |
| 189 | 199 | ||
| 190 | /* nh added/removed */ | 200 | /* nh added/removed */ |
| @@ -214,7 +224,7 @@ static void mlx5_lag_fib_update(struct work_struct *work) · 23 unmodified lines | |||
| 214 | case FIB_EVENT_ENTRY_REPLACE: | 224 | case FIB_EVENT_ENTRY_REPLACE: |
| 215 | case FIB_EVENT_ENTRY_DEL: | 225 | case FIB_EVENT_ENTRY_DEL: |
| 216 | mlx5_lag_fib_route_event(ldev, fib_work->event, | 226 | mlx5_lag_fib_route_event(ldev, fib_work->event, |
| 217 | fib_work->fen_info.fi); | 227 | &fib_work->fen_info); |
| 218 | fib_info_put(fib_work->fen_info.fi); | 228 | fib_info_put(fib_work->fen_info.fi); |
| 219 | break; | 229 | break; |
| 220 | case FIB_EVENT_NH_ADD: | 230 | case FIB_EVENT_NH_ADD: |
| @@ -313,7 +323,7 @@ void mlx5_lag_mp_reset(struct mlx5_lag *ldev) · 92 unmodified lines | |||
| 313 | /* Clear mfi, as it might become stale when a route delete event | 323 | /* Clear mfi, as it might become stale when a route delete event |
| 314 | * has been missed, see mlx5_lag_fib_route_event(). | 324 | * has been missed, see mlx5_lag_fib_route_event(). |
| 315 | */ | 325 | */ |
| 316 | ldev->lag_mp.mfi = NULL; | 326 | ldev->lag_mp.fib.mfi = NULL; |
| 317 | } | 327 | } |
| 318 | 328 | ||
| 319 | int mlx5_lag_mp_init(struct mlx5_lag *ldev) | 329 | int mlx5_lag_mp_init(struct mlx5_lag *ldev) |
| @@ -324,7 +334,7 @@ int mlx5_lag_mp_init(struct mlx5_lag *ldev) · 4 unmodified lines | |||
| 324 | /* always clear mfi, as it might become stale when a route delete event | 334 | /* always clear mfi, as it might become stale when a route delete event |
| 325 | * has been missed | 335 | * has been missed |
| 326 | */ | 336 | */ |
| 327 | mp->mfi = NULL; | 337 | mp->fib.mfi = NULL; |
| 328 | 338 | ||
| 329 | if (mp->fib_nb.notifier_call) | 339 | if (mp->fib_nb.notifier_call) |
| 330 | return 0; | 340 | return 0; |
| @@ -354,5 +364,5 @@ void mlx5_lag_mp_cleanup(struct mlx5_lag *ldev) · 23 unmodified lines | |||
| 354 | unregister_fib_notifier(&init_net, &mp->fib_nb); | 364 | unregister_fib_notifier(&init_net, &mp->fib_nb); |
| 355 | destroy_workqueue(mp->wq); | 365 | destroy_workqueue(mp->wq); |
| 356 | mp->fib_nb.notifier_call = NULL; | 366 | mp->fib_nb.notifier_call = NULL; |
| 357 | mp->mfi = NULL; | 367 | mp->fib.mfi = NULL; |
| 358 | } | 368 | } |
| @@ -15,7 +15,12 @@ enum mlx5_lag_port_affinity { · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | struct lag_mp { | 16 | struct lag_mp { |
| 17 | struct notifier_block fib_nb; | 17 | struct notifier_block fib_nb; |
| 18 | struct fib_info *mfi; /* used in tracking fib events */ | 18 | struct { |
| 19 | const void *mfi; /* used in tracking fib events */ | ||
| 20 | u32 priority; | ||
| 21 | u32 dst; | ||
| 22 | int dst_len; | ||
| 23 | } fib; | ||
| 19 | struct workqueue_struct *wq; | 24 | struct workqueue_struct *wq; |
| 20 | }; | 25 | }; |
| 21 | 26 | ||
| @@ -505,7 +505,7 @@ static int mlx5_lag_create_inner_ttc_table(struct mlx5_lag *ldev) · 504 unmodified lines | |||
| 505 | struct ttc_params ttc_params = {}; | 505 | struct ttc_params ttc_params = {}; |
| 506 | 506 | ||
| 507 | mlx5_lag_set_inner_ttc_params(ldev, &ttc_params); | 507 | mlx5_lag_set_inner_ttc_params(ldev, &ttc_params); |
| 508 | port_sel->inner.ttc = mlx5_create_ttc_table(dev, &ttc_params); | 508 | port_sel->inner.ttc = mlx5_create_inner_ttc_table(dev, &ttc_params); |
| 509 | if (IS_ERR(port_sel->inner.ttc)) | 509 | if (IS_ERR(port_sel->inner.ttc)) |
| 510 | return PTR_ERR(port_sel->inner.ttc); | 510 | return PTR_ERR(port_sel->inner.ttc); |
| 511 | 511 | ||
| @@ -408,6 +408,8 @@ static int mlx5_generate_inner_ttc_table_rules(struct mlx5_core_dev *dev, · 407 unmodified lines | |||
| 408 | for (tt = 0; tt < MLX5_NUM_TT; tt++) { | 408 | for (tt = 0; tt < MLX5_NUM_TT; tt++) { |
| 409 | struct mlx5_ttc_rule *rule = &rules[tt]; | 409 | struct mlx5_ttc_rule *rule = &rules[tt]; |
| 410 | 410 | ||
| 411 | if (test_bit(tt, params->ignore_dests)) | ||
| 412 | continue; | ||
| 411 | rule->rule = mlx5_generate_inner_ttc_rule(dev, ft, | 413 | rule->rule = mlx5_generate_inner_ttc_rule(dev, ft, |
| 412 | ¶ms->dests[tt], | 414 | ¶ms->dests[tt], |
| 413 | ttc_rules[tt].etype, | 415 | ttc_rules[tt].etype, |
| @@ -568,10 +568,8 @@ static int · 567 unmodified lines | |||
| 568 | mlxsw_sp2_ipip_rem_addr_set_gre6(struct mlxsw_sp *mlxsw_sp, | 568 | mlxsw_sp2_ipip_rem_addr_set_gre6(struct mlxsw_sp *mlxsw_sp, |
| 569 | struct mlxsw_sp_ipip_entry *ipip_entry) | 569 | struct mlxsw_sp_ipip_entry *ipip_entry) |
| 570 | { | 570 | { |
| 571 | struct __ip6_tnl_parm parms6; | 571 | return mlxsw_sp_ipv6_addr_kvdl_index_get(mlxsw_sp, |
| 572 | 572 | &ipip_entry->parms.daddr.addr6, | |
| 573 | parms6 = mlxsw_sp_ipip_netdev_parms6(ipip_entry->ol_dev); | ||
| 574 | return mlxsw_sp_ipv6_addr_kvdl_index_get(mlxsw_sp, &parms6.raddr, | ||
| 575 | &ipip_entry->dip_kvdl_index); | 573 | &ipip_entry->dip_kvdl_index); |
| 576 | } | 574 | } |
| 577 | 575 | ||
| @@ -579,10 +577,7 @@ static void · 1 unmodified line | |||
| 579 | mlxsw_sp2_ipip_rem_addr_unset_gre6(struct mlxsw_sp *mlxsw_sp, | 577 | mlxsw_sp2_ipip_rem_addr_unset_gre6(struct mlxsw_sp *mlxsw_sp, |
| 580 | const struct mlxsw_sp_ipip_entry *ipip_entry) | 578 | const struct mlxsw_sp_ipip_entry *ipip_entry) |
| 581 | { | 579 | { |
| 582 | struct __ip6_tnl_parm parms6; | 580 | mlxsw_sp_ipv6_addr_put(mlxsw_sp, &ipip_entry->parms.daddr.addr6); |
| 583 | |||
| 584 | parms6 = mlxsw_sp_ipip_netdev_parms6(ipip_entry->ol_dev); | ||
| 585 | mlxsw_sp_ipv6_addr_put(mlxsw_sp, &parms6.raddr); | ||
| 586 | } | 581 | } |
| 587 | 582 | ||
| 588 | static const struct mlxsw_sp_ipip_ops mlxsw_sp2_ipip_gre6_ops = { | 583 | static const struct mlxsw_sp_ipip_ops mlxsw_sp2_ipip_gre6_ops = { |
| @@ -346,7 +346,7 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row, · 345 unmodified lines | |||
| 346 | 346 | ||
| 347 | lan966x_mac_process_raw_entry(&raw_entries[column], | 347 | lan966x_mac_process_raw_entry(&raw_entries[column], |
| 348 | mac, &vid, &dest_idx); | 348 | mac, &vid, &dest_idx); |
| 349 | if (WARN_ON(dest_idx > lan966x->num_phys_ports)) | 349 | if (WARN_ON(dest_idx >= lan966x->num_phys_ports)) |
| 350 | continue; | 350 | continue; |
| 351 | 351 | ||
| 352 | /* If the entry in SW is found, then there is nothing | 352 | /* If the entry in SW is found, then there is nothing |
| @@ -393,7 +393,7 @@ static void lan966x_mac_irq_process(struct lan966x *lan966x, u32 row, · 40 unmodified lines | |||
| 393 | 393 | ||
| 394 | lan966x_mac_process_raw_entry(&raw_entries[column], | 394 | lan966x_mac_process_raw_entry(&raw_entries[column], |
| 395 | mac, &vid, &dest_idx); | 395 | mac, &vid, &dest_idx); |
| 396 | if (WARN_ON(dest_idx > lan966x->num_phys_ports)) | 396 | if (WARN_ON(dest_idx >= lan966x->num_phys_ports)) |
| 397 | continue; | 397 | continue; |
| 398 | 398 | ||
| 399 | mac_entry = lan966x_mac_alloc_entry(mac, vid, dest_idx); | 399 | mac_entry = lan966x_mac_alloc_entry(mac, vid, dest_idx); |
| @@ -551,7 +551,7 @@ int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, · 550 unmodified lines | |||
| 551 | struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1]; | 551 | struct ocelot_vcap_block *block = &ocelot->block[VCAP_IS1]; |
| 552 | struct ocelot_port *ocelot_port = ocelot->ports[port]; | 552 | struct ocelot_port *ocelot_port = ocelot->ports[port]; |
| 553 | struct ocelot_vcap_filter *filter; | 553 | struct ocelot_vcap_filter *filter; |
| 554 | int err; | 554 | int err = 0; |
| 555 | u32 val; | 555 | u32 val; |
| 556 | 556 | ||
| 557 | list_for_each_entry(filter, &block->rules, list) { | 557 | list_for_each_entry(filter, &block->rules, list) { |
| @@ -570,7 +570,7 @@ int ocelot_port_vlan_filtering(struct ocelot *ocelot, int port, · 12 unmodified lines | |||
| 570 | if (vlan_aware) | 570 | if (vlan_aware) |
| 571 | err = ocelot_del_vlan_unaware_pvid(ocelot, port, | 571 | err = ocelot_del_vlan_unaware_pvid(ocelot, port, |
| 572 | ocelot_port->bridge); | 572 | ocelot_port->bridge); |
| 573 | else | 573 | else if (ocelot_port->bridge) |
| 574 | err = ocelot_add_vlan_unaware_pvid(ocelot, port, | 574 | err = ocelot_add_vlan_unaware_pvid(ocelot, port, |
| 575 | ocelot_port->bridge); | 575 | ocelot_port->bridge); |
| 576 | if (err) | 576 | if (err) |
| @@ -629,6 +629,13 @@ int ocelot_vlan_add(struct ocelot *ocelot, int port, u16 vid, bool pvid, · 52 unmodified lines | |||
| 629 | { | 629 | { |
| 630 | int err; | 630 | int err; |
| 631 | 631 | ||
| 632 | /* Ignore VID 0 added to our RX filter by the 8021q module, since | ||
| 633 | * that collides with OCELOT_STANDALONE_PVID and changes it from | ||
| 634 | * egress-untagged to egress-tagged. | ||
| 635 | */ | ||
| 636 | if (!vid) | ||
| 637 | return 0; | ||
| 638 | |||
| 632 | err = ocelot_vlan_member_add(ocelot, port, vid, untagged); | 639 | err = ocelot_vlan_member_add(ocelot, port, vid, untagged); |
| 633 | if (err) | 640 | if (err) |
| 634 | return err; | 641 | return err; |
| @@ -651,6 +658,9 @@ int ocelot_vlan_del(struct ocelot *ocelot, int port, u16 vid) · 16 unmodified lines | |||
| 651 | bool del_pvid = false; | 658 | bool del_pvid = false; |
| 652 | int err; | 659 | int err; |
| 653 | 660 | ||
| 661 | if (!vid) | ||
| 662 | return 0; | ||
| 663 | |||
| 654 | if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid) | 664 | if (ocelot_port->pvid_vlan && ocelot_port->pvid_vlan->vid == vid) |
| 655 | del_pvid = true; | 665 | del_pvid = true; |
| 656 | 666 | ||
| @@ -1612,7 +1622,7 @@ int ocelot_trap_add(struct ocelot *ocelot, int port, · 955 unmodified lines | |||
| 1612 | trap->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY; | 1622 | trap->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY; |
| 1613 | trap->action.port_mask = 0; | 1623 | trap->action.port_mask = 0; |
| 1614 | trap->take_ts = take_ts; | 1624 | trap->take_ts = take_ts; |
| 1615 | list_add_tail(&trap->trap_list, &ocelot->traps); | 1625 | trap->is_trap = true; |
| 1616 | new = true; | 1626 | new = true; |
| 1617 | } | 1627 | } |
| 1618 | 1628 | ||
| @@ -1624,10 +1634,8 @@ int ocelot_trap_add(struct ocelot *ocelot, int port, · 5 unmodified lines | |||
| 1624 | err = ocelot_vcap_filter_replace(ocelot, trap); | 1634 | err = ocelot_vcap_filter_replace(ocelot, trap); |
| 1625 | if (err) { | 1635 | if (err) { |
| 1626 | trap->ingress_port_mask &= ~BIT(port); | 1636 | trap->ingress_port_mask &= ~BIT(port); |
| 1627 | if (!trap->ingress_port_mask) { | 1637 | if (!trap->ingress_port_mask) |
| 1628 | list_del(&trap->trap_list); | ||
| 1629 | kfree(trap); | 1638 | kfree(trap); |
| 1630 | } | ||
| 1631 | return err; | 1639 | return err; |
| 1632 | } | 1640 | } |
| 1633 | 1641 | ||
| @@ -1647,11 +1655,8 @@ int ocelot_trap_del(struct ocelot *ocelot, int port, unsigned long cookie) · 13 unmodified lines | |||
| 1647 | return 0; | 1655 | return 0; |
| 1648 | 1656 | ||
| 1649 | trap->ingress_port_mask &= ~BIT(port); | 1657 | trap->ingress_port_mask &= ~BIT(port); |
| 1650 | if (!trap->ingress_port_mask) { | 1658 | if (!trap->ingress_port_mask) |
| 1651 | list_del(&trap->trap_list); | ||
| 1652 | |||
| 1653 | return ocelot_vcap_filter_del(ocelot, trap); | 1659 | return ocelot_vcap_filter_del(ocelot, trap); |
| 1654 | } | ||
| 1655 | 1660 | ||
| 1656 | return ocelot_vcap_filter_replace(ocelot, trap); | 1661 | return ocelot_vcap_filter_replace(ocelot, trap); |
| 1657 | } | 1662 | } |
| @@ -280,9 +280,10 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port, · 279 unmodified lines | |||
| 280 | filter->type = OCELOT_VCAP_FILTER_OFFLOAD; | 280 | filter->type = OCELOT_VCAP_FILTER_OFFLOAD; |
| 281 | break; | 281 | break; |
| 282 | case FLOW_ACTION_TRAP: | 282 | case FLOW_ACTION_TRAP: |
| 283 | if (filter->block_id != VCAP_IS2) { | 283 | if (filter->block_id != VCAP_IS2 || |
| 284 | filter->lookup != 0) { | ||
| 284 | NL_SET_ERR_MSG_MOD(extack, | 285 | NL_SET_ERR_MSG_MOD(extack, |
| 285 | "Trap action can only be offloaded to VCAP IS2"); | 286 | "Trap action can only be offloaded to VCAP IS2 lookup 0"); |
| 286 | return -EOPNOTSUPP; | 287 | return -EOPNOTSUPP; |
| 287 | } | 288 | } |
| 288 | if (filter->goto_target != -1) { | 289 | if (filter->goto_target != -1) { |
| @@ -295,7 +296,7 @@ static int ocelot_flower_parse_action(struct ocelot *ocelot, int port, · 6 unmodified lines | |||
| 295 | filter->action.cpu_copy_ena = true; | 296 | filter->action.cpu_copy_ena = true; |
| 296 | filter->action.cpu_qu_num = 0; | 297 | filter->action.cpu_qu_num = 0; |
| 297 | filter->type = OCELOT_VCAP_FILTER_OFFLOAD; | 298 | filter->type = OCELOT_VCAP_FILTER_OFFLOAD; |
| 298 | list_add_tail(&filter->trap_list, &ocelot->traps); | 299 | filter->is_trap = true; |
| 299 | break; | 300 | break; |
| 300 | case FLOW_ACTION_POLICE: | 301 | case FLOW_ACTION_POLICE: |
| 301 | if (filter->block_id == PSFP_BLOCK_ID) { | 302 | if (filter->block_id == PSFP_BLOCK_ID) { |
| @@ -878,8 +879,6 @@ int ocelot_cls_flower_replace(struct ocelot *ocelot, int port, · 576 unmodified lines | |||
| 878 | 879 | ||
| 879 | ret = ocelot_flower_parse(ocelot, port, ingress, f, filter); | 880 | ret = ocelot_flower_parse(ocelot, port, ingress, f, filter); |
| 880 | if (ret) { | 881 | if (ret) { |
| 881 | if (!list_empty(&filter->trap_list)) | ||
| 882 | list_del(&filter->trap_list); | ||
| 883 | kfree(filter); | 882 | kfree(filter); |
| 884 | return ret; | 883 | return ret; |
| 885 | } | 884 | } |
| @@ -374,7 +374,6 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, · 373 unmodified lines | |||
| 374 | OCELOT_VCAP_BIT_0); | 374 | OCELOT_VCAP_BIT_0); |
| 375 | vcap_key_set(vcap, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0, | 375 | vcap_key_set(vcap, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0, |
| 376 | ~filter->ingress_port_mask); | 376 | ~filter->ingress_port_mask); |
| 377 | vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_FIRST, OCELOT_VCAP_BIT_ANY); | ||
| 378 | vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_HOST_MATCH, | 377 | vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_HOST_MATCH, |
| 379 | OCELOT_VCAP_BIT_ANY); | 378 | OCELOT_VCAP_BIT_ANY); |
| 380 | vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L2_MC, filter->dmac_mc); | 379 | vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L2_MC, filter->dmac_mc); |
| @@ -1217,6 +1216,8 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot, · 836 unmodified lines | |||
| 1217 | struct ocelot_vcap_filter *tmp; | 1216 | struct ocelot_vcap_filter *tmp; |
| 1218 | 1217 | ||
| 1219 | tmp = ocelot_vcap_block_find_filter_by_index(block, i); | 1218 | tmp = ocelot_vcap_block_find_filter_by_index(block, i); |
| 1219 | /* Read back the filter's counters before moving it */ | ||
| 1220 | vcap_entry_get(ocelot, i - 1, tmp); | ||
| 1220 | vcap_entry_set(ocelot, i, tmp); | 1221 | vcap_entry_set(ocelot, i, tmp); |
| 1221 | } | 1222 | } |
| 1222 | 1223 | ||
| @@ -1250,7 +1251,11 @@ int ocelot_vcap_filter_del(struct ocelot *ocelot, · 27 unmodified lines | |||
| 1250 | struct ocelot_vcap_filter del_filter; | 1251 | struct ocelot_vcap_filter del_filter; |
| 1251 | int i, index; | 1252 | int i, index; |
| 1252 | 1253 | ||
| 1254 | /* Need to inherit the block_id so that vcap_entry_set() | ||
| 1255 | * does not get confused and knows where to install it. | ||
| 1256 | */ | ||
| 1253 | memset(&del_filter, 0, sizeof(del_filter)); | 1257 | memset(&del_filter, 0, sizeof(del_filter)); |
| 1258 | del_filter.block_id = filter->block_id; | ||
| 1254 | 1259 | ||
| 1255 | /* Gets index of the filter */ | 1260 | /* Gets index of the filter */ |
| 1256 | index = ocelot_vcap_block_get_filter_index(block, filter); | 1261 | index = ocelot_vcap_block_get_filter_index(block, filter); |
| @@ -1265,6 +1270,8 @@ int ocelot_vcap_filter_del(struct ocelot *ocelot, · 8 unmodified lines | |||
| 1265 | struct ocelot_vcap_filter *tmp; | 1270 | struct ocelot_vcap_filter *tmp; |
| 1266 | 1271 | ||
| 1267 | tmp = ocelot_vcap_block_find_filter_by_index(block, i); | 1272 | tmp = ocelot_vcap_block_find_filter_by_index(block, i); |
| 1273 | /* Read back the filter's counters before moving it */ | ||
| 1274 | vcap_entry_get(ocelot, i + 1, tmp); | ||
| 1268 | vcap_entry_set(ocelot, i, tmp); | 1275 | vcap_entry_set(ocelot, i, tmp); |
| 1269 | } | 1276 | } |
| 1270 | 1277 | ||
| @@ -256,7 +256,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 255 unmodified lines | |||
| 256 | 256 | ||
| 257 | err = ionic_map_bars(ionic); | 257 | err = ionic_map_bars(ionic); |
| 258 | if (err) | 258 | if (err) |
| 259 | goto err_out_pci_disable_device; | 259 | goto err_out_pci_release_regions; |
| 260 | 260 | ||
| 261 | /* Configure the device */ | 261 | /* Configure the device */ |
| 262 | err = ionic_setup(ionic); | 262 | err = ionic_setup(ionic); |
| @@ -360,6 +360,7 @@ err_out_teardown: · 97 unmodified lines | |||
| 360 | 360 | ||
| 361 | err_out_unmap_bars: | 361 | err_out_unmap_bars: |
| 362 | ionic_unmap_bars(ionic); | 362 | ionic_unmap_bars(ionic); |
| 363 | err_out_pci_release_regions: | ||
| 363 | pci_release_regions(pdev); | 364 | pci_release_regions(pdev); |
| 364 | err_out_pci_disable_device: | 365 | err_out_pci_disable_device: |
| 365 | pci_disable_device(pdev); | 366 | pci_disable_device(pdev); |
| @@ -3579,6 +3579,11 @@ static int efx_ef10_mtd_probe(struct efx_nic *efx) · 3578 unmodified lines | |||
| 3579 | n_parts++; | 3579 | n_parts++; |
| 3580 | } | 3580 | } |
| 3581 | 3581 | ||
| 3582 | if (!n_parts) { | ||
| 3583 | kfree(parts); | ||
| 3584 | return 0; | ||
| 3585 | } | ||
| 3586 | |||
| 3582 | rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts)); | 3587 | rc = efx_mtd_add(efx, &parts[0].common, n_parts, sizeof(*parts)); |
| 3583 | fail: | 3588 | fail: |
| 3584 | if (rc) | 3589 | if (rc) |
| @@ -867,7 +867,9 @@ static void efx_set_xdp_channels(struct efx_nic *efx) · 866 unmodified lines | |||
| 867 | 867 | ||
| 868 | int efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) | 868 | int efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) |
| 869 | { | 869 | { |
| 870 | struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel; | 870 | struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel, |
| 871 | *ptp_channel = efx_ptp_channel(efx); | ||
| 872 | struct efx_ptp_data *ptp_data = efx->ptp_data; | ||
| 871 | unsigned int i, next_buffer_table = 0; | 873 | unsigned int i, next_buffer_table = 0; |
| 872 | u32 old_rxq_entries, old_txq_entries; | 874 | u32 old_rxq_entries, old_txq_entries; |
| 873 | int rc, rc2; | 875 | int rc, rc2; |
| @@ -938,6 +940,7 @@ int efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) · 64 unmodified lines | |||
| 938 | 940 | ||
| 939 | efx_set_xdp_channels(efx); | 941 | efx_set_xdp_channels(efx); |
| 940 | out: | 942 | out: |
| 943 | efx->ptp_data = NULL; | ||
| 941 | /* Destroy unused channel structures */ | 944 | /* Destroy unused channel structures */ |
| 942 | for (i = 0; i < efx->n_channels; i++) { | 945 | for (i = 0; i < efx->n_channels; i++) { |
| 943 | channel = other_channel[i]; | 946 | channel = other_channel[i]; |
| @@ -948,6 +951,7 @@ out: · 4 unmodified lines | |||
| 948 | } | 951 | } |
| 949 | } | 952 | } |
| 950 | 953 | ||
| 954 | efx->ptp_data = ptp_data; | ||
| 951 | rc2 = efx_soft_enable_interrupts(efx); | 955 | rc2 = efx_soft_enable_interrupts(efx); |
| 952 | if (rc2) { | 956 | if (rc2) { |
| 953 | rc = rc ? rc : rc2; | 957 | rc = rc ? rc : rc2; |
| @@ -966,6 +970,7 @@ rollback: · 12 unmodified lines | |||
| 966 | efx->txq_entries = old_txq_entries; | 970 | efx->txq_entries = old_txq_entries; |
| 967 | for (i = 0; i < efx->n_channels; i++) | 971 | for (i = 0; i < efx->n_channels; i++) |
| 968 | swap(efx->channel[i], other_channel[i]); | 972 | swap(efx->channel[i], other_channel[i]); |
| 973 | efx_ptp_update_channel(efx, ptp_channel); | ||
| 969 | goto out; | 974 | goto out; |
| 970 | } | 975 | } |
| 971 | 976 | ||
| @@ -45,6 +45,7 @@ · 44 unmodified lines | |||
| 45 | #include "farch_regs.h" | 45 | #include "farch_regs.h" |
| 46 | #include "tx.h" | 46 | #include "tx.h" |
| 47 | #include "nic.h" /* indirectly includes ptp.h */ | 47 | #include "nic.h" /* indirectly includes ptp.h */ |
| 48 | #include "efx_channels.h" | ||
| 48 | 49 | ||
| 49 | /* Maximum number of events expected to make up a PTP event */ | 50 | /* Maximum number of events expected to make up a PTP event */ |
| 50 | #define MAX_EVENT_FRAGS 3 | 51 | #define MAX_EVENT_FRAGS 3 |
| @@ -541,6 +542,12 @@ struct efx_channel *efx_ptp_channel(struct efx_nic *efx) · 490 unmodified lines | |||
| 541 | return efx->ptp_data ? efx->ptp_data->channel : NULL; | 542 | return efx->ptp_data ? efx->ptp_data->channel : NULL; |
| 542 | } | 543 | } |
| 543 | 544 | ||
| 545 | void efx_ptp_update_channel(struct efx_nic *efx, struct efx_channel *channel) | ||
| 546 | { | ||
| 547 | if (efx->ptp_data) | ||
| 548 | efx->ptp_data->channel = channel; | ||
| 549 | } | ||
| 550 | |||
| 544 | static u32 last_sync_timestamp_major(struct efx_nic *efx) | 551 | static u32 last_sync_timestamp_major(struct efx_nic *efx) |
| 545 | { | 552 | { |
| 546 | struct efx_channel *channel = efx_ptp_channel(efx); | 553 | struct efx_channel *channel = efx_ptp_channel(efx); |
| @@ -1443,6 +1450,11 @@ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel) · 896 unmodified lines | |||
| 1443 | int rc = 0; | 1450 | int rc = 0; |
| 1444 | unsigned int pos; | 1451 | unsigned int pos; |
| 1445 | 1452 | ||
| 1453 | if (efx->ptp_data) { | ||
| 1454 | efx->ptp_data->channel = channel; | ||
| 1455 | return 0; | ||
| 1456 | } | ||
| 1457 | |||
| 1446 | ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL); | 1458 | ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL); |
| 1447 | efx->ptp_data = ptp; | 1459 | efx->ptp_data = ptp; |
| 1448 | if (!efx->ptp_data) | 1460 | if (!efx->ptp_data) |
| @@ -2176,7 +2188,7 @@ static const struct efx_channel_type efx_ptp_channel_type = { · 727 unmodified lines | |||
| 2176 | .pre_probe = efx_ptp_probe_channel, | 2188 | .pre_probe = efx_ptp_probe_channel, |
| 2177 | .post_remove = efx_ptp_remove_channel, | 2189 | .post_remove = efx_ptp_remove_channel, |
| 2178 | .get_name = efx_ptp_get_channel_name, | 2190 | .get_name = efx_ptp_get_channel_name, |
| 2179 | /* no copy operation; there is no need to reallocate this channel */ | 2191 | .copy = efx_copy_channel, |
| 2180 | .receive_skb = efx_ptp_rx, | 2192 | .receive_skb = efx_ptp_rx, |
| 2181 | .want_txqs = efx_ptp_want_txqs, | 2193 | .want_txqs = efx_ptp_want_txqs, |
| 2182 | .keep_eventq = false, | 2194 | .keep_eventq = false, |
| @@ -16,6 +16,7 @@ struct ethtool_ts_info; · 15 unmodified lines | |||
| 16 | int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel); | 16 | int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel); |
| 17 | void efx_ptp_defer_probe_with_channel(struct efx_nic *efx); | 17 | void efx_ptp_defer_probe_with_channel(struct efx_nic *efx); |
| 18 | struct efx_channel *efx_ptp_channel(struct efx_nic *efx); | 18 | struct efx_channel *efx_ptp_channel(struct efx_nic *efx); |
| 19 | void efx_ptp_update_channel(struct efx_nic *efx, struct efx_channel *channel); | ||
| 19 | void efx_ptp_remove(struct efx_nic *efx); | 20 | void efx_ptp_remove(struct efx_nic *efx); |
| 20 | int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr); | 21 | int efx_ptp_set_ts_config(struct efx_nic *efx, struct ifreq *ifr); |
| 21 | int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr); | 22 | int efx_ptp_get_ts_config(struct efx_nic *efx, struct ifreq *ifr); |
| @@ -2431,7 +2431,7 @@ static int smsc911x_drv_probe(struct platform_device *pdev) · 2430 unmodified lines | |||
| 2431 | if (irq == -EPROBE_DEFER) { | 2431 | if (irq == -EPROBE_DEFER) { |
| 2432 | retval = -EPROBE_DEFER; | 2432 | retval = -EPROBE_DEFER; |
| 2433 | goto out_0; | 2433 | goto out_0; |
| 2434 | } else if (irq <= 0) { | 2434 | } else if (irq < 0) { |
| 2435 | pr_warn("Could not allocate irq resource\n"); | 2435 | pr_warn("Could not allocate irq resource\n"); |
| 2436 | retval = -ENODEV; | 2436 | retval = -ENODEV; |
| 2437 | goto out_0; | 2437 | goto out_0; |
| @@ -454,6 +454,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev, · 453 unmodified lines | |||
| 454 | plat->has_gmac4 = 1; | 454 | plat->has_gmac4 = 1; |
| 455 | plat->force_sf_dma_mode = 0; | 455 | plat->force_sf_dma_mode = 0; |
| 456 | plat->tso_en = 1; | 456 | plat->tso_en = 1; |
| 457 | plat->sph_disable = 1; | ||
| 457 | 458 | ||
| 458 | /* Multiplying factor to the clk_eee_i clock time | 459 | /* Multiplying factor to the clk_eee_i clock time |
| 459 | * period to make it closer to 100 ns. This value | 460 | * period to make it closer to 100 ns. This value |
| @@ -65,8 +65,9 @@ static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed) · 64 unmodified lines | |||
| 65 | struct phy_device *phy_dev = ndev->phydev; | 65 | struct phy_device *phy_dev = ndev->phydev; |
| 66 | u32 val; | 66 | u32 val; |
| 67 | 67 | ||
| 68 | writew(SGMII_ADAPTER_DISABLE, | 68 | if (sgmii_adapter_base) |
| 69 | sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); | 69 | writew(SGMII_ADAPTER_DISABLE, |
| 70 | sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); | ||
| 70 | 71 | ||
| 71 | if (splitter_base) { | 72 | if (splitter_base) { |
| 72 | val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG); | 73 | val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG); |
| @@ -88,10 +89,11 @@ static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed) · 15 unmodified lines | |||
| 88 | writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG); | 89 | writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG); |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | writew(SGMII_ADAPTER_ENABLE, | 92 | if (phy_dev && sgmii_adapter_base) { |
| 92 | sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); | 93 | writew(SGMII_ADAPTER_ENABLE, |
| 93 | if (phy_dev) | 94 | sgmii_adapter_base + SGMII_ADAPTER_CTRL_REG); |
| 94 | tse_pcs_fix_mac_speed(&dwmac->pcs, phy_dev, speed); | 95 | tse_pcs_fix_mac_speed(&dwmac->pcs, phy_dev, speed); |
| 96 | } | ||
| 95 | } | 97 | } |
| 96 | 98 | ||
| 97 | static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) | 99 | static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) |
| @@ -907,6 +907,7 @@ static int sun8i_dwmac_register_mdio_mux(struct stmmac_priv *priv) · 906 unmodified lines | |||
| 907 | 907 | ||
| 908 | ret = mdio_mux_init(priv->device, mdio_mux, mdio_mux_syscon_switch_fn, | 908 | ret = mdio_mux_init(priv->device, mdio_mux, mdio_mux_syscon_switch_fn, |
| 909 | &gmac->mux_handle, priv, priv->mii); | 909 | &gmac->mux_handle, priv, priv->mii); |
| 910 | of_node_put(mdio_mux); | ||
| 910 | return ret; | 911 | return ret; |
| 911 | } | 912 | } |
| 912 | 913 | ||
| @@ -7021,7 +7021,7 @@ int stmmac_dvr_probe(struct device *device, · 7020 unmodified lines | |||
| 7021 | dev_info(priv->device, "TSO feature enabled\n"); | 7021 | dev_info(priv->device, "TSO feature enabled\n"); |
| 7022 | } | 7022 | } |
| 7023 | 7023 | ||
| 7024 | if (priv->dma_cap.sphen) { | 7024 | if (priv->dma_cap.sphen && !priv->plat->sph_disable) { |
| 7025 | ndev->hw_features |= NETIF_F_GRO; | 7025 | ndev->hw_features |= NETIF_F_GRO; |
| 7026 | priv->sph_cap = true; | 7026 | priv->sph_cap = true; |
| 7027 | priv->sph = priv->sph_cap; | 7027 | priv->sph = priv->sph_cap; |
| @@ -181,7 +181,7 @@ static int stmmac_pci_probe(struct pci_dev *pdev, · 180 unmodified lines | |||
| 181 | return -ENOMEM; | 181 | return -ENOMEM; |
| 182 | 182 | ||
| 183 | /* Enable pci device */ | 183 | /* Enable pci device */ |
| 184 | ret = pci_enable_device(pdev); | 184 | ret = pcim_enable_device(pdev); |
| 185 | if (ret) { | 185 | if (ret) { |
| 186 | dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", | 186 | dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", |
| 187 | __func__); | 187 | __func__); |
| @@ -241,8 +241,6 @@ static void stmmac_pci_remove(struct pci_dev *pdev) · 53 unmodified lines | |||
| 241 | pcim_iounmap_regions(pdev, BIT(i)); | 241 | pcim_iounmap_regions(pdev, BIT(i)); |
| 242 | break; | 242 | break; |
| 243 | } | 243 | } |
| 244 | |||
| 245 | pci_disable_device(pdev); | ||
| 246 | } | 244 | } |
| 247 | 245 | ||
| 248 | static int __maybe_unused stmmac_pci_suspend(struct device *dev) | 246 | static int __maybe_unused stmmac_pci_suspend(struct device *dev) |
| @@ -1246,8 +1246,10 @@ static int cpsw_probe_dt(struct cpsw_common *cpsw) · 1245 unmodified lines | |||
| 1246 | data->slave_data = devm_kcalloc(dev, CPSW_SLAVE_PORTS_NUM, | 1246 | data->slave_data = devm_kcalloc(dev, CPSW_SLAVE_PORTS_NUM, |
| 1247 | sizeof(struct cpsw_slave_data), | 1247 | sizeof(struct cpsw_slave_data), |
| 1248 | GFP_KERNEL); | 1248 | GFP_KERNEL); |
| 1249 | if (!data->slave_data) | 1249 | if (!data->slave_data) { |
| 1250 | of_node_put(tmp_node); | ||
| 1250 | return -ENOMEM; | 1251 | return -ENOMEM; |
| 1252 | } | ||
| 1251 | 1253 | ||
| 1252 | /* Populate all the child nodes here... | 1254 | /* Populate all the child nodes here... |
| 1253 | */ | 1255 | */ |
| @@ -1341,6 +1343,7 @@ static int cpsw_probe_dt(struct cpsw_common *cpsw) · 87 unmodified lines | |||
| 1341 | 1343 | ||
| 1342 | err_node_put: | 1344 | err_node_put: |
| 1343 | of_node_put(port_np); | 1345 | of_node_put(port_np); |
| 1346 | of_node_put(tmp_node); | ||
| 1344 | return ret; | 1347 | return ret; |
| 1345 | } | 1348 | } |
| 1346 | 1349 | ||
| @@ -823,10 +823,10 @@ static int xemaclite_mdio_write(struct mii_bus *bus, int phy_id, int reg, · 822 unmodified lines | |||
| 823 | static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) | 823 | static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) |
| 824 | { | 824 | { |
| 825 | struct mii_bus *bus; | 825 | struct mii_bus *bus; |
| 826 | int rc; | ||
| 827 | struct resource res; | 826 | struct resource res; |
| 828 | struct device_node *np = of_get_parent(lp->phy_node); | 827 | struct device_node *np = of_get_parent(lp->phy_node); |
| 829 | struct device_node *npp; | 828 | struct device_node *npp; |
| 829 | int rc, ret; | ||
| 830 | 830 | ||
| 831 | /* Don't register the MDIO bus if the phy_node or its parent node | 831 | /* Don't register the MDIO bus if the phy_node or its parent node |
| 832 | * can't be found. | 832 | * can't be found. |
| @@ -836,8 +836,14 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) · 3 unmodified lines | |||
| 836 | return -ENODEV; | 836 | return -ENODEV; |
| 837 | } | 837 | } |
| 838 | npp = of_get_parent(np); | 838 | npp = of_get_parent(np); |
| 839 | 839 | ret = of_address_to_resource(npp, 0, &res); | |
| 840 | of_address_to_resource(npp, 0, &res); | 840 | of_node_put(npp); |
| 841 | if (ret) { | ||
| 842 | dev_err(dev, "%s resource error!\n", | ||
| 843 | dev->of_node->full_name); | ||
| 844 | of_node_put(np); | ||
| 845 | return ret; | ||
| 846 | } | ||
| 841 | if (lp->ndev->mem_start != res.start) { | 847 | if (lp->ndev->mem_start != res.start) { |
| 842 | struct phy_device *phydev; | 848 | struct phy_device *phydev; |
| 843 | phydev = of_phy_find_device(lp->phy_node); | 849 | phydev = of_phy_find_device(lp->phy_node); |
| @@ -846,6 +852,7 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) · 2 unmodified lines | |||
| 846 | "MDIO of the phy is not registered yet\n"); | 852 | "MDIO of the phy is not registered yet\n"); |
| 847 | else | 853 | else |
| 848 | put_device(&phydev->mdio.dev); | 854 | put_device(&phydev->mdio.dev); |
| 855 | of_node_put(np); | ||
| 849 | return 0; | 856 | return 0; |
| 850 | } | 857 | } |
| 851 | 858 | ||
| @@ -858,6 +865,7 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) · 6 unmodified lines | |||
| 858 | bus = mdiobus_alloc(); | 865 | bus = mdiobus_alloc(); |
| 859 | if (!bus) { | 866 | if (!bus) { |
| 860 | dev_err(dev, "Failed to allocate mdiobus\n"); | 867 | dev_err(dev, "Failed to allocate mdiobus\n"); |
| 868 | of_node_put(np); | ||
| 861 | return -ENOMEM; | 869 | return -ENOMEM; |
| 862 | } | 870 | } |
| 863 | 871 | ||
| @@ -870,6 +878,7 @@ static int xemaclite_mdio_setup(struct net_local *lp, struct device *dev) · 6 unmodified lines | |||
| 870 | bus->parent = dev; | 878 | bus->parent = dev; |
| 871 | 879 | ||
| 872 | rc = of_mdiobus_register(bus, np); | 880 | rc = of_mdiobus_register(bus, np); |
| 881 | of_node_put(np); | ||
| 873 | if (rc) { | 882 | if (rc) { |
| 874 | dev_err(dev, "Failed to register mdio bus.\n"); | 883 | dev_err(dev, "Failed to register mdio bus.\n"); |
| 875 | goto err_register; | 884 | goto err_register; |
| @@ -926,8 +935,6 @@ static int xemaclite_open(struct net_device *dev) · 50 unmodified lines | |||
| 926 | xemaclite_disable_interrupts(lp); | 935 | xemaclite_disable_interrupts(lp); |
| 927 | 936 | ||
| 928 | if (lp->phy_node) { | 937 | if (lp->phy_node) { |
| 929 | u32 bmcr; | ||
| 930 | |||
| 931 | lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, | 938 | lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, |
| 932 | xemaclite_adjust_link, 0, | 939 | xemaclite_adjust_link, 0, |
| 933 | PHY_INTERFACE_MODE_MII); | 940 | PHY_INTERFACE_MODE_MII); |
| @@ -938,19 +945,6 @@ static int xemaclite_open(struct net_device *dev) · 4 unmodified lines | |||
| 938 | 945 | ||
| 939 | /* EmacLite doesn't support giga-bit speeds */ | 946 | /* EmacLite doesn't support giga-bit speeds */ |
| 940 | phy_set_max_speed(lp->phy_dev, SPEED_100); | 947 | phy_set_max_speed(lp->phy_dev, SPEED_100); |
| 941 | |||
| 942 | /* Don't advertise 1000BASE-T Full/Half duplex speeds */ | ||
| 943 | phy_write(lp->phy_dev, MII_CTRL1000, 0); | ||
| 944 | |||
| 945 | /* Advertise only 10 and 100mbps full/half duplex speeds */ | ||
| 946 | phy_write(lp->phy_dev, MII_ADVERTISE, ADVERTISE_ALL | | ||
| 947 | ADVERTISE_CSMA); | ||
| 948 | |||
| 949 | /* Restart auto negotiation */ | ||
| 950 | bmcr = phy_read(lp->phy_dev, MII_BMCR); | ||
| 951 | bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); | ||
| 952 | phy_write(lp->phy_dev, MII_BMCR, bmcr); | ||
| 953 | |||
| 954 | phy_start(lp->phy_dev); | 948 | phy_start(lp->phy_dev); |
| 955 | } | 949 | } |
| 956 | 950 | ||
| @@ -115,7 +115,7 @@ static int bcm6368_mdiomux_probe(struct platform_device *pdev) · 114 unmodified lines | |||
| 115 | md->mii_bus = devm_mdiobus_alloc(&pdev->dev); | 115 | md->mii_bus = devm_mdiobus_alloc(&pdev->dev); |
| 116 | if (!md->mii_bus) { | 116 | if (!md->mii_bus) { |
| 117 | dev_err(&pdev->dev, "mdiomux bus alloc failed\n"); | 117 | dev_err(&pdev->dev, "mdiomux bus alloc failed\n"); |
| 118 | return ENOMEM; | 118 | return -ENOMEM; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | bus = md->mii_bus; | 121 | bus = md->mii_bus; |
| @@ -880,7 +880,7 @@ static int mv3310_read_status_copper(struct phy_device *phydev) · 879 unmodified lines | |||
| 880 | 880 | ||
| 881 | cssr1 = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSSR1); | 881 | cssr1 = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSSR1); |
| 882 | if (cssr1 < 0) | 882 | if (cssr1 < 0) |
| 883 | return val; | 883 | return cssr1; |
| 884 | 884 | ||
| 885 | /* If the link settings are not resolved, mark the link down */ | 885 | /* If the link settings are not resolved, mark the link down */ |
| 886 | if (!(cssr1 & MV_PCS_CSSR1_RESOLVED)) { | 886 | if (!(cssr1 & MV_PCS_CSSR1_RESOLVED)) { |
| @@ -1743,7 +1743,7 @@ static int ksz886x_cable_test_get_status(struct phy_device *phydev, · 1742 unmodified lines | |||
| 1743 | 1743 | ||
| 1744 | static int lanphy_read_page_reg(struct phy_device *phydev, int page, u32 addr) | 1744 | static int lanphy_read_page_reg(struct phy_device *phydev, int page, u32 addr) |
| 1745 | { | 1745 | { |
| 1746 | u32 data; | 1746 | int data; |
| 1747 | 1747 | ||
| 1748 | phy_lock_mdio_bus(phydev); | 1748 | phy_lock_mdio_bus(phydev); |
| 1749 | __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page); | 1749 | __phy_write(phydev, LAN_EXT_PAGE_ACCESS_CONTROL, page); |
| @@ -2444,8 +2444,7 @@ static int lan8804_config_init(struct phy_device *phydev) · 694 unmodified lines | |||
| 2444 | 2444 | ||
| 2445 | static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev) | 2445 | static irqreturn_t lan8814_handle_interrupt(struct phy_device *phydev) |
| 2446 | { | 2446 | { |
| 2447 | u16 tsu_irq_status; | 2447 | int irq_status, tsu_irq_status; |
| 2448 | int irq_status; | ||
| 2449 | 2448 | ||
| 2450 | irq_status = phy_read(phydev, LAN8814_INTS); | 2449 | irq_status = phy_read(phydev, LAN8814_INTS); |
| 2451 | if (irq_status > 0 && (irq_status & LAN8814_INT_LINK)) | 2450 | if (irq_status > 0 && (irq_status & LAN8814_INT_LINK)) |
| @@ -2657,6 +2656,7 @@ static struct phy_driver ksphy_driver[] = { · 205 unmodified lines | |||
| 2657 | .name = "Micrel KS8737", | 2656 | .name = "Micrel KS8737", |
| 2658 | /* PHY_BASIC_FEATURES */ | 2657 | /* PHY_BASIC_FEATURES */ |
| 2659 | .driver_data = &ks8737_type, | 2658 | .driver_data = &ks8737_type, |
| 2659 | .probe = kszphy_probe, | ||
| 2660 | .config_init = kszphy_config_init, | 2660 | .config_init = kszphy_config_init, |
| 2661 | .config_intr = kszphy_config_intr, | 2661 | .config_intr = kszphy_config_intr, |
| 2662 | .handle_interrupt = kszphy_handle_interrupt, | 2662 | .handle_interrupt = kszphy_handle_interrupt, |
| @@ -2782,8 +2782,8 @@ static struct phy_driver ksphy_driver[] = { · 119 unmodified lines | |||
| 2782 | .config_init = ksz8061_config_init, | 2782 | .config_init = ksz8061_config_init, |
| 2783 | .config_intr = kszphy_config_intr, | 2783 | .config_intr = kszphy_config_intr, |
| 2784 | .handle_interrupt = kszphy_handle_interrupt, | 2784 | .handle_interrupt = kszphy_handle_interrupt, |
| 2785 | .suspend = kszphy_suspend, | 2785 | .suspend = genphy_suspend, |
| 2786 | .resume = kszphy_resume, | 2786 | .resume = genphy_resume, |
| 2787 | }, { | 2787 | }, { |
| 2788 | .phy_id = PHY_ID_KSZ9021, | 2788 | .phy_id = PHY_ID_KSZ9021, |
| 2789 | .phy_id_mask = 0x000ffffe, | 2789 | .phy_id_mask = 0x000ffffe, |
| @@ -970,8 +970,13 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat) · 969 unmodified lines | |||
| 970 | { | 970 | { |
| 971 | struct phy_device *phydev = phy_dat; | 971 | struct phy_device *phydev = phy_dat; |
| 972 | struct phy_driver *drv = phydev->drv; | 972 | struct phy_driver *drv = phydev->drv; |
| 973 | irqreturn_t ret; | ||
| 973 | 974 | ||
| 974 | return drv->handle_interrupt(phydev); | 975 | mutex_lock(&phydev->lock); |
| 976 | ret = drv->handle_interrupt(phydev); | ||
| 977 | mutex_unlock(&phydev->lock); | ||
| 978 | |||
| 979 | return ret; | ||
| 975 | } | 980 | } |
| 976 | 981 | ||
| 977 | /** | 982 | /** |
| @@ -250,6 +250,7 @@ struct sfp { · 249 unmodified lines | |||
| 250 | struct sfp_eeprom_id id; | 250 | struct sfp_eeprom_id id; |
| 251 | unsigned int module_power_mW; | 251 | unsigned int module_power_mW; |
| 252 | unsigned int module_t_start_up; | 252 | unsigned int module_t_start_up; |
| 253 | bool tx_fault_ignore; | ||
| 253 | 254 | ||
| 254 | #if IS_ENABLED(CONFIG_HWMON) | 255 | #if IS_ENABLED(CONFIG_HWMON) |
| 255 | struct sfp_diag diag; | 256 | struct sfp_diag diag; |
| @@ -1956,6 +1957,12 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report) · 1700 unmodified lines | |||
| 1956 | else | 1957 | else |
| 1957 | sfp->module_t_start_up = T_START_UP; | 1958 | sfp->module_t_start_up = T_START_UP; |
| 1958 | 1959 | ||
| 1960 | if (!memcmp(id.base.vendor_name, "HUAWEI ", 16) && | ||
| 1961 | !memcmp(id.base.vendor_pn, "MA5671A ", 16)) | ||
| 1962 | sfp->tx_fault_ignore = true; | ||
| 1963 | else | ||
| 1964 | sfp->tx_fault_ignore = false; | ||
| 1965 | |||
| 1959 | return 0; | 1966 | return 0; |
| 1960 | } | 1967 | } |
| 1961 | 1968 | ||
| @@ -2409,7 +2416,10 @@ static void sfp_check_state(struct sfp *sfp) · 447 unmodified lines | |||
| 2409 | mutex_lock(&sfp->st_mutex); | 2416 | mutex_lock(&sfp->st_mutex); |
| 2410 | state = sfp_get_state(sfp); | 2417 | state = sfp_get_state(sfp); |
| 2411 | changed = state ^ sfp->state; | 2418 | changed = state ^ sfp->state; |
| 2412 | changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT; | 2419 | if (sfp->tx_fault_ignore) |
| 2420 | changed &= SFP_F_PRESENT | SFP_F_LOS; | ||
| 2421 | else | ||
| 2422 | changed &= SFP_F_PRESENT | SFP_F_LOS | SFP_F_TX_FAULT; | ||
| 2413 | 2423 | ||
| 2414 | for (i = 0; i < GPIO_MAX; i++) | 2424 | for (i = 0; i < GPIO_MAX; i++) |
| 2415 | if (changed & BIT(i)) | 2425 | if (changed & BIT(i)) |
| @@ -1005,6 +1005,24 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, · 1004 unmodified lines | |||
| 1005 | * xdp.data_meta were adjusted | 1005 | * xdp.data_meta were adjusted |
| 1006 | */ | 1006 | */ |
| 1007 | len = xdp.data_end - xdp.data + vi->hdr_len + metasize; | 1007 | len = xdp.data_end - xdp.data + vi->hdr_len + metasize; |
| 1008 | |||
| 1009 | /* recalculate headroom if xdp.data or xdp_data_meta | ||
| 1010 | * were adjusted, note that offset should always point | ||
| 1011 | * to the start of the reserved bytes for virtio_net | ||
| 1012 | * header which are followed by xdp.data, that means | ||
| 1013 | * that offset is equal to the headroom (when buf is | ||
| 1014 | * starting at the beginning of the page, otherwise | ||
| 1015 | * there is a base offset inside the page) but it's used | ||
| 1016 | * with a different starting point (buf start) than | ||
| 1017 | * xdp.data (buf start + vnet hdr size). If xdp.data or | ||
| 1018 | * data_meta were adjusted by the xdp prog then the | ||
| 1019 | * headroom size has changed and so has the offset, we | ||
| 1020 | * can use data_hard_start, which points at buf start + | ||
| 1021 | * vnet hdr size, to calculate the new headroom and use | ||
| 1022 | * it later to compute buf start in page_to_skb() | ||
| 1023 | */ | ||
| 1024 | headroom = xdp.data - xdp.data_hard_start - metasize; | ||
| 1025 | |||
| 1008 | /* We can only create skb based on xdp_page. */ | 1026 | /* We can only create skb based on xdp_page. */ |
| 1009 | if (unlikely(xdp_page != page)) { | 1027 | if (unlikely(xdp_page != page)) { |
| 1010 | rcu_read_unlock(); | 1028 | rcu_read_unlock(); |
| @@ -1012,7 +1030,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, · 1 unmodified line | |||
| 1012 | head_skb = page_to_skb(vi, rq, xdp_page, offset, | 1030 | head_skb = page_to_skb(vi, rq, xdp_page, offset, |
| 1013 | len, PAGE_SIZE, false, | 1031 | len, PAGE_SIZE, false, |
| 1014 | metasize, | 1032 | metasize, |
| 1015 | VIRTIO_XDP_HEADROOM); | 1033 | headroom); |
| 1016 | return head_skb; | 1034 | return head_skb; |
| 1017 | } | 1035 | } |
| 1018 | break; | 1036 | break; |
| @@ -349,7 +349,7 @@ static int __init cosa_init(void) · 348 unmodified lines | |||
| 349 | } | 349 | } |
| 350 | } else { | 350 | } else { |
| 351 | cosa_major = register_chrdev(0, "cosa", &cosa_fops); | 351 | cosa_major = register_chrdev(0, "cosa", &cosa_fops); |
| 352 | if (!cosa_major) { | 352 | if (cosa_major < 0) { |
| 353 | pr_warn("unable to register chardev\n"); | 353 | pr_warn("unable to register chardev\n"); |
| 354 | err = -EIO; | 354 | err = -EIO; |
| 355 | goto out; | 355 | goto out; |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/if_arp.h> | 19 | #include <linux/if_arp.h> |
| 20 | #include <linux/icmp.h> | 20 | #include <linux/icmp.h> |
| 21 | #include <linux/suspend.h> | 21 | #include <linux/suspend.h> |
| 22 | #include <net/dst_metadata.h> | ||
| 22 | #include <net/icmp.h> | 23 | #include <net/icmp.h> |
| 23 | #include <net/rtnetlink.h> | 24 | #include <net/rtnetlink.h> |
| 24 | #include <net/ip_tunnels.h> | 25 | #include <net/ip_tunnels.h> |
| @@ -167,7 +168,7 @@ static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev) · 142 unmodified lines | |||
| 167 | goto err_peer; | 168 | goto err_peer; |
| 168 | } | 169 | } |
| 169 | 170 | ||
| 170 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; | 171 | mtu = skb_valid_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
| 171 | 172 | ||
| 172 | __skb_queue_head_init(&packets); | 173 | __skb_queue_head_init(&packets); |
| 173 | if (!skb_is_gso(skb)) { | 174 | if (!skb_is_gso(skb)) { |
| @@ -1288,6 +1288,7 @@ static void ath11k_core_restart(struct work_struct *work) · 1287 unmodified lines | |||
| 1288 | 1288 | ||
| 1289 | ieee80211_stop_queues(ar->hw); | 1289 | ieee80211_stop_queues(ar->hw); |
| 1290 | ath11k_mac_drain_tx(ar); | 1290 | ath11k_mac_drain_tx(ar); |
| 1291 | complete(&ar->completed_11d_scan); | ||
| 1291 | complete(&ar->scan.started); | 1292 | complete(&ar->scan.started); |
| 1292 | complete(&ar->scan.completed); | 1293 | complete(&ar->scan.completed); |
| 1293 | complete(&ar->peer_assoc_done); | 1294 | complete(&ar->peer_assoc_done); |
| @@ -38,6 +38,8 @@ · 37 unmodified lines | |||
| 38 | 38 | ||
| 39 | extern unsigned int ath11k_frame_mode; | 39 | extern unsigned int ath11k_frame_mode; |
| 40 | 40 | ||
| 41 | #define ATH11K_SCAN_TIMEOUT_HZ (20 * HZ) | ||
| 42 | |||
| 41 | #define ATH11K_MON_TIMER_INTERVAL 10 | 43 | #define ATH11K_MON_TIMER_INTERVAL 10 |
| 42 | 44 | ||
| 43 | enum ath11k_supported_bw { | 45 | enum ath11k_supported_bw { |
| @@ -189,6 +191,12 @@ enum ath11k_scan_state { · 145 unmodified lines | |||
| 189 | ATH11K_SCAN_ABORTING, | 191 | ATH11K_SCAN_ABORTING, |
| 190 | }; | 192 | }; |
| 191 | 193 | ||
| 194 | enum ath11k_11d_state { | ||
| 195 | ATH11K_11D_IDLE, | ||
| 196 | ATH11K_11D_PREPARING, | ||
| 197 | ATH11K_11D_RUNNING, | ||
| 198 | }; | ||
| 199 | |||
| 192 | enum ath11k_dev_flags { | 200 | enum ath11k_dev_flags { |
| 193 | ATH11K_CAC_RUNNING, | 201 | ATH11K_CAC_RUNNING, |
| 194 | ATH11K_FLAG_CORE_REGISTERED, | 202 | ATH11K_FLAG_CORE_REGISTERED, |
| @@ -607,9 +615,8 @@ struct ath11k { · 412 unmodified lines | |||
| 607 | bool dfs_block_radar_events; | 615 | bool dfs_block_radar_events; |
| 608 | struct ath11k_thermal thermal; | 616 | struct ath11k_thermal thermal; |
| 609 | u32 vdev_id_11d_scan; | 617 | u32 vdev_id_11d_scan; |
| 610 | struct completion finish_11d_scan; | 618 | struct completion completed_11d_scan; |
| 611 | struct completion finish_11d_ch_list; | 619 | enum ath11k_11d_state state_11d; |
| 612 | bool pending_11d; | ||
| 613 | bool regdom_set_by_user; | 620 | bool regdom_set_by_user; |
| 614 | int hw_rate_code; | 621 | int hw_rate_code; |
| 615 | u8 twt_enabled; | 622 | u8 twt_enabled; |
| @@ -3601,26 +3601,6 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, · 3600 unmodified lines | |||
| 3601 | if (ret) | 3601 | if (ret) |
| 3602 | goto exit; | 3602 | goto exit; |
| 3603 | 3603 | ||
| 3604 | /* Currently the pending_11d=true only happened 1 time while | ||
| 3605 | * wlan interface up in ath11k_mac_11d_scan_start(), it is called by | ||
| 3606 | * ath11k_mac_op_add_interface(), after wlan interface up, | ||
| 3607 | * pending_11d=false always. | ||
| 3608 | * If remove below wait, it always happened scan fail and lead connect | ||
| 3609 | * fail while wlan interface up, because it has a 11d scan which is running | ||
| 3610 | * in firmware, and lead this scan failed. | ||
| 3611 | */ | ||
| 3612 | if (ar->pending_11d) { | ||
| 3613 | long time_left; | ||
| 3614 | unsigned long timeout = 5 * HZ; | ||
| 3615 | |||
| 3616 | if (ar->supports_6ghz) | ||
| 3617 | timeout += 5 * HZ; | ||
| 3618 | |||
| 3619 | time_left = wait_for_completion_timeout(&ar->finish_11d_ch_list, timeout); | ||
| 3620 | ath11k_dbg(ar->ab, ATH11K_DBG_MAC, | ||
| 3621 | "mac wait 11d channel list time left %ld\n", time_left); | ||
| 3622 | } | ||
| 3623 | |||
| 3624 | memset(&arg, 0, sizeof(arg)); | 3604 | memset(&arg, 0, sizeof(arg)); |
| 3625 | ath11k_wmi_start_scan_init(ar, &arg); | 3605 | ath11k_wmi_start_scan_init(ar, &arg); |
| 3626 | arg.vdev_id = arvif->vdev_id; | 3606 | arg.vdev_id = arvif->vdev_id; |
| @@ -3686,6 +3666,10 @@ exit: · 59 unmodified lines | |||
| 3686 | kfree(arg.extraie.ptr); | 3666 | kfree(arg.extraie.ptr); |
| 3687 | 3667 | ||
| 3688 | mutex_unlock(&ar->conf_mutex); | 3668 | mutex_unlock(&ar->conf_mutex); |
| 3669 | |||
| 3670 | if (ar->state_11d == ATH11K_11D_PREPARING) | ||
| 3671 | ath11k_mac_11d_scan_start(ar, arvif->vdev_id); | ||
| 3672 | |||
| 3689 | return ret; | 3673 | return ret; |
| 3690 | } | 3674 | } |
| 3691 | 3675 | ||
| @@ -5814,7 +5798,7 @@ static int ath11k_mac_op_start(struct ieee80211_hw *hw) · 2122 unmodified lines | |||
| 5814 | 5798 | ||
| 5815 | /* TODO: Do we need to enable ANI? */ | 5799 | /* TODO: Do we need to enable ANI? */ |
| 5816 | 5800 | ||
| 5817 | ath11k_reg_update_chan_list(ar); | 5801 | ath11k_reg_update_chan_list(ar, false); |
| 5818 | 5802 | ||
| 5819 | ar->num_started_vdevs = 0; | 5803 | ar->num_started_vdevs = 0; |
| 5820 | ar->num_created_vdevs = 0; | 5804 | ar->num_created_vdevs = 0; |
| @@ -5881,6 +5865,11 @@ static void ath11k_mac_op_stop(struct ieee80211_hw *hw) · 60 unmodified lines | |||
| 5881 | cancel_work_sync(&ar->ab->update_11d_work); | 5865 | cancel_work_sync(&ar->ab->update_11d_work); |
| 5882 | cancel_work_sync(&ar->ab->rfkill_work); | 5866 | cancel_work_sync(&ar->ab->rfkill_work); |
| 5883 | 5867 | ||
| 5868 | if (ar->state_11d == ATH11K_11D_PREPARING) { | ||
| 5869 | ar->state_11d = ATH11K_11D_IDLE; | ||
| 5870 | complete(&ar->completed_11d_scan); | ||
| 5871 | } | ||
| 5872 | |||
| 5884 | spin_lock_bh(&ar->data_lock); | 5873 | spin_lock_bh(&ar->data_lock); |
| 5885 | list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { | 5874 | list_for_each_entry_safe(ppdu_stats, tmp, &ar->ppdu_stats_info, list) { |
| 5886 | list_del(&ppdu_stats->list); | 5875 | list_del(&ppdu_stats->list); |
| @@ -6051,7 +6040,7 @@ static bool ath11k_mac_vif_ap_active_any(struct ath11k_base *ab) · 164 unmodified lines | |||
| 6051 | return false; | 6040 | return false; |
| 6052 | } | 6041 | } |
| 6053 | 6042 | ||
| 6054 | void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id, bool wait) | 6043 | void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id) |
| 6055 | { | 6044 | { |
| 6056 | struct wmi_11d_scan_start_params param; | 6045 | struct wmi_11d_scan_start_params param; |
| 6057 | int ret; | 6046 | int ret; |
| @@ -6079,28 +6068,22 @@ void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id, bool wait) · 21 unmodified lines | |||
| 6079 | 6068 | ||
| 6080 | ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac start 11d scan\n"); | 6069 | ath11k_dbg(ar->ab, ATH11K_DBG_MAC, "mac start 11d scan\n"); |
| 6081 | 6070 | ||
| 6082 | if (wait) | ||
| 6083 | reinit_completion(&ar->finish_11d_scan); | ||
| 6084 | |||
| 6085 | ret = ath11k_wmi_send_11d_scan_start_cmd(ar, ¶m); | 6071 | ret = ath11k_wmi_send_11d_scan_start_cmd(ar, ¶m); |
| 6086 | if (ret) { | 6072 | if (ret) { |
| 6087 | ath11k_warn(ar->ab, "failed to start 11d scan vdev %d ret: %d\n", | 6073 | ath11k_warn(ar->ab, "failed to start 11d scan vdev %d ret: %d\n", |
| 6088 | vdev_id, ret); | 6074 | vdev_id, ret); |
| 6089 | } else { | 6075 | } else { |
| 6090 | ar->vdev_id_11d_scan = vdev_id; | 6076 | ar->vdev_id_11d_scan = vdev_id; |
| 6091 | if (wait) { | 6077 | if (ar->state_11d == ATH11K_11D_PREPARING) |
| 6092 | ar->pending_11d = true; | 6078 | ar->state_11d = ATH11K_11D_RUNNING; |
| 6093 | ret = wait_for_completion_timeout(&ar->finish_11d_scan, | ||
| 6094 | 5 * HZ); | ||
| 6095 | ath11k_dbg(ar->ab, ATH11K_DBG_MAC, | ||
| 6096 | "mac 11d scan left time %d\n", ret); | ||
| 6097 | |||
| 6098 | if (!ret) | ||
| 6099 | ar->pending_11d = false; | ||
| 6100 | } | ||
| 6101 | } | 6079 | } |
| 6102 | 6080 | ||
| 6103 | fin: | 6081 | fin: |
| 6082 | if (ar->state_11d == ATH11K_11D_PREPARING) { | ||
| 6083 | ar->state_11d = ATH11K_11D_IDLE; | ||
| 6084 | complete(&ar->completed_11d_scan); | ||
| 6085 | } | ||
| 6086 | |||
| 6104 | mutex_unlock(&ar->ab->vdev_id_11d_lock); | 6087 | mutex_unlock(&ar->ab->vdev_id_11d_lock); |
| 6105 | } | 6088 | } |
| 6106 | 6089 | ||
| @@ -6123,12 +6106,15 @@ void ath11k_mac_11d_scan_stop(struct ath11k *ar) · 16 unmodified lines | |||
| 6123 | vdev_id = ar->vdev_id_11d_scan; | 6106 | vdev_id = ar->vdev_id_11d_scan; |
| 6124 | 6107 | ||
| 6125 | ret = ath11k_wmi_send_11d_scan_stop_cmd(ar, vdev_id); | 6108 | ret = ath11k_wmi_send_11d_scan_stop_cmd(ar, vdev_id); |
| 6126 | if (ret) | 6109 | if (ret) { |
| 6127 | ath11k_warn(ar->ab, | 6110 | ath11k_warn(ar->ab, |
| 6128 | "failed to stopt 11d scan vdev %d ret: %d\n", | 6111 | "failed to stopt 11d scan vdev %d ret: %d\n", |
| 6129 | vdev_id, ret); | 6112 | vdev_id, ret); |
| 6130 | else | 6113 | } else { |
| 6131 | ar->vdev_id_11d_scan = ATH11K_11D_INVALID_VDEV_ID; | 6114 | ar->vdev_id_11d_scan = ATH11K_11D_INVALID_VDEV_ID; |
| 6115 | ar->state_11d = ATH11K_11D_IDLE; | ||
| 6116 | complete(&ar->completed_11d_scan); | ||
| 6117 | } | ||
| 6132 | } | 6118 | } |
| 6133 | mutex_unlock(&ar->ab->vdev_id_11d_lock); | 6119 | mutex_unlock(&ar->ab->vdev_id_11d_lock); |
| 6134 | } | 6120 | } |
| @@ -6324,8 +6310,10 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, · 189 unmodified lines | |||
| 6324 | goto err_peer_del; | 6310 | goto err_peer_del; |
| 6325 | } | 6311 | } |
| 6326 | 6312 | ||
| 6327 | ath11k_mac_11d_scan_start(ar, arvif->vdev_id, true); | 6313 | if (test_bit(WMI_TLV_SERVICE_11D_OFFLOAD, ab->wmi_ab.svc_map)) { |
| 6328 | 6314 | reinit_completion(&ar->completed_11d_scan); | |
| 6315 | ar->state_11d = ATH11K_11D_PREPARING; | ||
| 6316 | } | ||
| 6329 | break; | 6317 | break; |
| 6330 | case WMI_VDEV_TYPE_MONITOR: | 6318 | case WMI_VDEV_TYPE_MONITOR: |
| 6331 | set_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); | 6319 | set_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); |
| @@ -7190,7 +7178,7 @@ ath11k_mac_op_unassign_vif_chanctx(struct ieee80211_hw *hw, · 858 unmodified lines | |||
| 7190 | } | 7178 | } |
| 7191 | 7179 | ||
| 7192 | if (arvif->vdev_type == WMI_VDEV_TYPE_STA) | 7180 | if (arvif->vdev_type == WMI_VDEV_TYPE_STA) |
| 7193 | ath11k_mac_11d_scan_start(ar, arvif->vdev_id, false); | 7181 | ath11k_mac_11d_scan_start(ar, arvif->vdev_id); |
| 7194 | 7182 | ||
| 7195 | mutex_unlock(&ar->conf_mutex); | 7183 | mutex_unlock(&ar->conf_mutex); |
| 7196 | } | 7184 | } |
| @@ -8671,8 +8659,7 @@ int ath11k_mac_allocate(struct ath11k_base *ab) · 1474 unmodified lines | |||
| 8671 | ar->monitor_vdev_id = -1; | 8659 | ar->monitor_vdev_id = -1; |
| 8672 | clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); | 8660 | clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags); |
| 8673 | ar->vdev_id_11d_scan = ATH11K_11D_INVALID_VDEV_ID; | 8661 | ar->vdev_id_11d_scan = ATH11K_11D_INVALID_VDEV_ID; |
| 8674 | init_completion(&ar->finish_11d_scan); | 8662 | init_completion(&ar->completed_11d_scan); |
| 8675 | init_completion(&ar->finish_11d_ch_list); | ||
| 8676 | } | 8663 | } |
| 8677 | 8664 | ||
| 8678 | return 0; | 8665 | return 0; |
| @@ -130,7 +130,7 @@ extern const struct htt_rx_ring_tlv_filter ath11k_mac_mon_status_filter_default; · 129 unmodified lines | |||
| 130 | #define ATH11K_SCAN_11D_INTERVAL 600000 | 130 | #define ATH11K_SCAN_11D_INTERVAL 600000 |
| 131 | #define ATH11K_11D_INVALID_VDEV_ID 0xFFFF | 131 | #define ATH11K_11D_INVALID_VDEV_ID 0xFFFF |
| 132 | 132 | ||
| 133 | void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id, bool wait); | 133 | void ath11k_mac_11d_scan_start(struct ath11k *ar, u32 vdev_id); |
| 134 | void ath11k_mac_11d_scan_stop(struct ath11k *ar); | 134 | void ath11k_mac_11d_scan_stop(struct ath11k *ar); |
| 135 | void ath11k_mac_11d_scan_stop_all(struct ath11k_base *ab); | 135 | void ath11k_mac_11d_scan_stop_all(struct ath11k_base *ab); |
| 136 | 136 | ||
| @@ -102,7 +102,7 @@ ath11k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) · 101 unmodified lines | |||
| 102 | ar->regdom_set_by_user = true; | 102 | ar->regdom_set_by_user = true; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | int ath11k_reg_update_chan_list(struct ath11k *ar) | 105 | int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait) |
| 106 | { | 106 | { |
| 107 | struct ieee80211_supported_band **bands; | 107 | struct ieee80211_supported_band **bands; |
| 108 | struct scan_chan_list_params *params; | 108 | struct scan_chan_list_params *params; |
| @@ -111,7 +111,32 @@ int ath11k_reg_update_chan_list(struct ath11k *ar) · 2 unmodified lines | |||
| 111 | struct channel_param *ch; | 111 | struct channel_param *ch; |
| 112 | enum nl80211_band band; | 112 | enum nl80211_band band; |
| 113 | int num_channels = 0; | 113 | int num_channels = 0; |
| 114 | int i, ret; | 114 | int i, ret, left; |
| 115 | |||
| 116 | if (wait && ar->state_11d != ATH11K_11D_IDLE) { | ||
| 117 | left = wait_for_completion_timeout(&ar->completed_11d_scan, | ||
| 118 | ATH11K_SCAN_TIMEOUT_HZ); | ||
| 119 | if (!left) { | ||
| 120 | ath11k_dbg(ar->ab, ATH11K_DBG_REG, | ||
| 121 | "failed to receive 11d scan complete: timed out\n"); | ||
| 122 | ar->state_11d = ATH11K_11D_IDLE; | ||
| 123 | } | ||
| 124 | ath11k_dbg(ar->ab, ATH11K_DBG_REG, | ||
| 125 | "reg 11d scan wait left time %d\n", left); | ||
| 126 | } | ||
| 127 | |||
| 128 | if (wait && | ||
| 129 | (ar->scan.state == ATH11K_SCAN_STARTING || | ||
| 130 | ar->scan.state == ATH11K_SCAN_RUNNING)) { | ||
| 131 | left = wait_for_completion_timeout(&ar->scan.completed, | ||
| 132 | ATH11K_SCAN_TIMEOUT_HZ); | ||
| 133 | if (!left) | ||
| 134 | ath11k_dbg(ar->ab, ATH11K_DBG_REG, | ||
| 135 | "failed to receive hw scan complete: timed out\n"); | ||
| 136 | |||
| 137 | ath11k_dbg(ar->ab, ATH11K_DBG_REG, | ||
| 138 | "reg hw scan wait left time %d\n", left); | ||
| 139 | } | ||
| 115 | 140 | ||
| 116 | bands = hw->wiphy->bands; | 141 | bands = hw->wiphy->bands; |
| 117 | for (band = 0; band < NUM_NL80211_BANDS; band++) { | 142 | for (band = 0; band < NUM_NL80211_BANDS; band++) { |
| @@ -193,11 +218,6 @@ int ath11k_reg_update_chan_list(struct ath11k *ar) · 75 unmodified lines | |||
| 193 | ret = ath11k_wmi_send_scan_chan_list_cmd(ar, params); | 218 | ret = ath11k_wmi_send_scan_chan_list_cmd(ar, params); |
| 194 | kfree(params); | 219 | kfree(params); |
| 195 | 220 | ||
| 196 | if (ar->pending_11d) { | ||
| 197 | complete(&ar->finish_11d_ch_list); | ||
| 198 | ar->pending_11d = false; | ||
| 199 | } | ||
| 200 | |||
| 201 | return ret; | 221 | return ret; |
| 202 | } | 222 | } |
| 203 | 223 | ||
| @@ -263,15 +283,8 @@ int ath11k_regd_update(struct ath11k *ar) · 59 unmodified lines | |||
| 263 | goto err; | 283 | goto err; |
| 264 | } | 284 | } |
| 265 | 285 | ||
| 266 | if (ar->pending_11d) | ||
| 267 | complete(&ar->finish_11d_scan); | ||
| 268 | |||
| 269 | rtnl_lock(); | 286 | rtnl_lock(); |
| 270 | wiphy_lock(ar->hw->wiphy); | 287 | wiphy_lock(ar->hw->wiphy); |
| 271 | |||
| 272 | if (ar->pending_11d) | ||
| 273 | reinit_completion(&ar->finish_11d_ch_list); | ||
| 274 | |||
| 275 | ret = regulatory_set_wiphy_regd_sync(ar->hw->wiphy, regd_copy); | 288 | ret = regulatory_set_wiphy_regd_sync(ar->hw->wiphy, regd_copy); |
| 276 | wiphy_unlock(ar->hw->wiphy); | 289 | wiphy_unlock(ar->hw->wiphy); |
| 277 | rtnl_unlock(); | 290 | rtnl_unlock(); |
| @@ -282,7 +295,7 @@ int ath11k_regd_update(struct ath11k *ar) · 4 unmodified lines | |||
| 282 | goto err; | 295 | goto err; |
| 283 | 296 | ||
| 284 | if (ar->state == ATH11K_STATE_ON) { | 297 | if (ar->state == ATH11K_STATE_ON) { |
| 285 | ret = ath11k_reg_update_chan_list(ar); | 298 | ret = ath11k_reg_update_chan_list(ar, true); |
| 286 | if (ret) | 299 | if (ret) |
| 287 | goto err; | 300 | goto err; |
| 288 | } | 301 | } |
| @@ -32,5 +32,5 @@ struct ieee80211_regdomain * · 31 unmodified lines | |||
| 32 | ath11k_reg_build_regd(struct ath11k_base *ab, | 32 | ath11k_reg_build_regd(struct ath11k_base *ab, |
| 33 | struct cur_regulatory_info *reg_info, bool intersect); | 33 | struct cur_regulatory_info *reg_info, bool intersect); |
| 34 | int ath11k_regd_update(struct ath11k *ar); | 34 | int ath11k_regd_update(struct ath11k *ar); |
| 35 | int ath11k_reg_update_chan_list(struct ath11k *ar); | 35 | int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait); |
| 36 | #endif | 36 | #endif |
| @@ -2015,7 +2015,10 @@ void ath11k_wmi_start_scan_init(struct ath11k *ar, · 2014 unmodified lines | |||
| 2015 | { | 2015 | { |
| 2016 | /* setup commonly used values */ | 2016 | /* setup commonly used values */ |
| 2017 | arg->scan_req_id = 1; | 2017 | arg->scan_req_id = 1; |
| 2018 | arg->scan_priority = WMI_SCAN_PRIORITY_LOW; | 2018 | if (ar->state_11d == ATH11K_11D_PREPARING) |
| 2019 | arg->scan_priority = WMI_SCAN_PRIORITY_MEDIUM; | ||
| 2020 | else | ||
| 2021 | arg->scan_priority = WMI_SCAN_PRIORITY_LOW; | ||
| 2019 | arg->dwell_time_active = 50; | 2022 | arg->dwell_time_active = 50; |
| 2020 | arg->dwell_time_active_2g = 0; | 2023 | arg->dwell_time_active_2g = 0; |
| 2021 | arg->dwell_time_passive = 150; | 2024 | arg->dwell_time_passive = 150; |
| @@ -6350,8 +6353,10 @@ static void ath11k_wmi_op_ep_tx_credits(struct ath11k_base *ab) · 4328 unmodified lines | |||
| 6350 | static int ath11k_reg_11d_new_cc_event(struct ath11k_base *ab, struct sk_buff *skb) | 6353 | static int ath11k_reg_11d_new_cc_event(struct ath11k_base *ab, struct sk_buff *skb) |
| 6351 | { | 6354 | { |
| 6352 | const struct wmi_11d_new_cc_ev *ev; | 6355 | const struct wmi_11d_new_cc_ev *ev; |
| 6356 | struct ath11k *ar; | ||
| 6357 | struct ath11k_pdev *pdev; | ||
| 6353 | const void **tb; | 6358 | const void **tb; |
| 6354 | int ret; | 6359 | int ret, i; |
| 6355 | 6360 | ||
| 6356 | tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); | 6361 | tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC); |
| 6357 | if (IS_ERR(tb)) { | 6362 | if (IS_ERR(tb)) { |
| @@ -6377,6 +6382,13 @@ static int ath11k_reg_11d_new_cc_event(struct ath11k_base *ab, struct sk_buff *s · 19 unmodified lines | |||
| 6377 | 6382 | ||
| 6378 | kfree(tb); | 6383 | kfree(tb); |
| 6379 | 6384 | ||
| 6385 | for (i = 0; i < ab->num_radios; i++) { | ||
| 6386 | pdev = &ab->pdevs[i]; | ||
| 6387 | ar = pdev->ar; | ||
| 6388 | ar->state_11d = ATH11K_11D_IDLE; | ||
| 6389 | complete(&ar->completed_11d_scan); | ||
| 6390 | } | ||
| 6391 | |||
| 6380 | queue_work(ab->workqueue, &ab->update_11d_work); | 6392 | queue_work(ab->workqueue, &ab->update_11d_work); |
| 6381 | 6393 | ||
| 6382 | return 0; | 6394 | return 0; |
| @@ -371,7 +371,7 @@ void iwl_dbg_tlv_del_timers(struct iwl_trans *trans) · 370 unmodified lines | |||
| 371 | struct iwl_dbg_tlv_timer_node *node, *tmp; | 371 | struct iwl_dbg_tlv_timer_node *node, *tmp; |
| 372 | 372 | ||
| 373 | list_for_each_entry_safe(node, tmp, timer_list, list) { | 373 | list_for_each_entry_safe(node, tmp, timer_list, list) { |
| 374 | del_timer(&node->timer); | 374 | del_timer_sync(&node->timer); |
| 375 | list_del(&node->list); | 375 | list_del(&node->list); |
| 376 | kfree(node); | 376 | kfree(node); |
| 377 | } | 377 | } |
| @@ -2202,11 +2202,14 @@ mac80211_hwsim_sta_rc_update(struct ieee80211_hw *hw, · 2201 unmodified lines | |||
| 2202 | if (!data->use_chanctx) { | 2202 | if (!data->use_chanctx) { |
| 2203 | confbw = data->bw; | 2203 | confbw = data->bw; |
| 2204 | } else { | 2204 | } else { |
| 2205 | struct ieee80211_chanctx_conf *chanctx_conf = | 2205 | struct ieee80211_chanctx_conf *chanctx_conf; |
| 2206 | rcu_dereference(vif->chanctx_conf); | 2206 | |
| 2207 | rcu_read_lock(); | ||
| 2208 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | ||
| 2207 | 2209 | ||
| 2208 | if (!WARN_ON(!chanctx_conf)) | 2210 | if (!WARN_ON(!chanctx_conf)) |
| 2209 | confbw = chanctx_conf->def.width; | 2211 | confbw = chanctx_conf->def.width; |
| 2212 | rcu_read_unlock(); | ||
| 2210 | } | 2213 | } |
| 2211 | 2214 | ||
| 2212 | WARN(bw > hwsim_get_chanwidth(confbw), | 2215 | WARN(bw > hwsim_get_chanwidth(confbw), |
| @@ -2475,11 +2478,13 @@ static void hw_scan_work(struct work_struct *work) · 262 unmodified lines | |||
| 2475 | if (req->ie_len) | 2478 | if (req->ie_len) |
| 2476 | skb_put_data(probe, req->ie, req->ie_len); | 2479 | skb_put_data(probe, req->ie, req->ie_len); |
| 2477 | 2480 | ||
| 2481 | rcu_read_lock(); | ||
| 2478 | if (!ieee80211_tx_prepare_skb(hwsim->hw, | 2482 | if (!ieee80211_tx_prepare_skb(hwsim->hw, |
| 2479 | hwsim->hw_scan_vif, | 2483 | hwsim->hw_scan_vif, |
| 2480 | probe, | 2484 | probe, |
| 2481 | hwsim->tmp_chan->band, | 2485 | hwsim->tmp_chan->band, |
| 2482 | NULL)) { | 2486 | NULL)) { |
| 2487 | rcu_read_unlock(); | ||
| 2483 | kfree_skb(probe); | 2488 | kfree_skb(probe); |
| 2484 | continue; | 2489 | continue; |
| 2485 | } | 2490 | } |
| @@ -2487,6 +2492,7 @@ static void hw_scan_work(struct work_struct *work) · 1 unmodified line | |||
| 2487 | local_bh_disable(); | 2492 | local_bh_disable(); |
| 2488 | mac80211_hwsim_tx_frame(hwsim->hw, probe, | 2493 | mac80211_hwsim_tx_frame(hwsim->hw, probe, |
| 2489 | hwsim->tmp_chan); | 2494 | hwsim->tmp_chan); |
| 2495 | rcu_read_unlock(); | ||
| 2490 | local_bh_enable(); | 2496 | local_bh_enable(); |
| 2491 | } | 2497 | } |
| 2492 | } | 2498 | } |
| @@ -183,6 +183,7 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv) · 182 unmodified lines | |||
| 183 | { | 183 | { |
| 184 | struct nci_dev *ndev = priv->ndev; | 184 | struct nci_dev *ndev = priv->ndev; |
| 185 | 185 | ||
| 186 | nci_unregister_device(ndev); | ||
| 186 | if (priv->ndev->nfc_dev->fw_download_in_progress) | 187 | if (priv->ndev->nfc_dev->fw_download_in_progress) |
| 187 | nfcmrvl_fw_dnld_abort(priv); | 188 | nfcmrvl_fw_dnld_abort(priv); |
| 188 | 189 | ||
| @@ -191,7 +192,6 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv) · 2 unmodified lines | |||
| 191 | if (gpio_is_valid(priv->config.reset_n_io)) | 192 | if (gpio_is_valid(priv->config.reset_n_io)) |
| 192 | gpio_free(priv->config.reset_n_io); | 193 | gpio_free(priv->config.reset_n_io); |
| 193 | 194 | ||
| 194 | nci_unregister_device(ndev); | ||
| 195 | nci_free_device(ndev); | 195 | nci_free_device(ndev); |
| 196 | kfree(priv); | 196 | kfree(priv); |
| 197 | } | 197 | } |
| @@ -369,7 +369,6 @@ static int devm_of_pci_get_host_bridge_resources(struct device *dev, · 368 unmodified lines | |||
| 369 | 369 | ||
| 370 | dev_dbg(dev, "Parsing dma-ranges property...\n"); | 370 | dev_dbg(dev, "Parsing dma-ranges property...\n"); |
| 371 | for_each_of_pci_range(&parser, &range) { | 371 | for_each_of_pci_range(&parser, &range) { |
| 372 | struct resource_entry *entry; | ||
| 373 | /* | 372 | /* |
| 374 | * If we failed translation or got a zero-sized region | 373 | * If we failed translation or got a zero-sized region |
| 375 | * then skip this range | 374 | * then skip this range |
| @@ -393,12 +392,7 @@ static int devm_of_pci_get_host_bridge_resources(struct device *dev, · 17 unmodified lines | |||
| 393 | goto failed; | 392 | goto failed; |
| 394 | } | 393 | } |
| 395 | 394 | ||
| 396 | /* Keep the resource list sorted */ | 395 | pci_add_resource_offset(ib_resources, res, |
| 397 | resource_list_for_each_entry(entry, ib_resources) | ||
| 398 | if (entry->res->start > res->start) | ||
| 399 | break; | ||
| 400 | |||
| 401 | pci_add_resource_offset(&entry->node, res, | ||
| 402 | res->start - range.pci_addr); | 396 | res->start - range.pci_addr); |
| 403 | } | 397 | } |
| 404 | 398 | ||
| @@ -20,6 +20,7 @@ · 19 unmodified lines | |||
| 20 | #include <linux/of_device.h> | 20 | #include <linux/of_device.h> |
| 21 | #include <linux/acpi.h> | 21 | #include <linux/acpi.h> |
| 22 | #include <linux/dma-map-ops.h> | 22 | #include <linux/dma-map-ops.h> |
| 23 | #include <linux/iommu.h> | ||
| 23 | #include "pci.h" | 24 | #include "pci.h" |
| 24 | #include "pcie/portdrv.h" | 25 | #include "pcie/portdrv.h" |
| 25 | 26 | ||
| @@ -1601,6 +1602,7 @@ static int pci_bus_num_vf(struct device *dev) · 1575 unmodified lines | |||
| 1601 | */ | 1602 | */ |
| 1602 | static int pci_dma_configure(struct device *dev) | 1603 | static int pci_dma_configure(struct device *dev) |
| 1603 | { | 1604 | { |
| 1605 | struct pci_driver *driver = to_pci_driver(dev->driver); | ||
| 1604 | struct device *bridge; | 1606 | struct device *bridge; |
| 1605 | int ret = 0; | 1607 | int ret = 0; |
| 1606 | 1608 | ||
| @@ -1616,9 +1618,24 @@ static int pci_dma_configure(struct device *dev) · 9 unmodified lines | |||
| 1616 | } | 1618 | } |
| 1617 | 1619 | ||
| 1618 | pci_put_host_bridge_device(bridge); | 1620 | pci_put_host_bridge_device(bridge); |
| 1621 | |||
| 1622 | if (!ret && !driver->driver_managed_dma) { | ||
| 1623 | ret = iommu_device_use_default_domain(dev); | ||
| 1624 | if (ret) | ||
| 1625 | arch_teardown_dma_ops(dev); | ||
| 1626 | } | ||
| 1627 | |||
| 1619 | return ret; | 1628 | return ret; |
| 1620 | } | 1629 | } |
| 1621 | 1630 | ||
| 1631 | static void pci_dma_cleanup(struct device *dev) | ||
| 1632 | { | ||
| 1633 | struct pci_driver *driver = to_pci_driver(dev->driver); | ||
| 1634 | |||
| 1635 | if (!driver->driver_managed_dma) | ||
| 1636 | iommu_device_unuse_default_domain(dev); | ||
| 1637 | } | ||
| 1638 | |||
| 1622 | struct bus_type pci_bus_type = { | 1639 | struct bus_type pci_bus_type = { |
| 1623 | .name = "pci", | 1640 | .name = "pci", |
| 1624 | .match = pci_bus_match, | 1641 | .match = pci_bus_match, |
| @@ -1632,6 +1649,7 @@ struct bus_type pci_bus_type = { · 7 unmodified lines | |||
| 1632 | .pm = PCI_PM_OPS_PTR, | 1649 | .pm = PCI_PM_OPS_PTR, |
| 1633 | .num_vf = pci_bus_num_vf, | 1650 | .num_vf = pci_bus_num_vf, |
| 1634 | .dma_configure = pci_dma_configure, | 1651 | .dma_configure = pci_dma_configure, |
| 1652 | .dma_cleanup = pci_dma_cleanup, | ||
| 1635 | }; | 1653 | }; |
| 1636 | EXPORT_SYMBOL(pci_bus_type); | 1654 | EXPORT_SYMBOL(pci_bus_type); |
| 1637 | 1655 | ||
| @@ -36,6 +36,7 @@ static struct pci_driver stub_driver = { · 35 unmodified lines | |||
| 36 | .name = "pci-stub", | 36 | .name = "pci-stub", |
| 37 | .id_table = NULL, /* only dynamic id's */ | 37 | .id_table = NULL, /* only dynamic id's */ |
| 38 | .probe = pci_stub_probe, | 38 | .probe = pci_stub_probe, |
| 39 | .driver_managed_dma = true, | ||
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | static int __init pci_stub_init(void) | 42 | static int __init pci_stub_init(void) |
| @@ -202,6 +202,8 @@ static struct pci_driver pcie_portdriver = { · 201 unmodified lines | |||
| 202 | 202 | ||
| 203 | .err_handler = &pcie_portdrv_err_handler, | 203 | .err_handler = &pcie_portdrv_err_handler, |
| 204 | 204 | ||
| 205 | .driver_managed_dma = true, | ||
| 206 | |||
| 205 | .driver.pm = PCIE_PORTDRV_PM_OPS, | 207 | .driver.pm = PCIE_PORTDRV_PM_OPS, |
| 206 | }; | 208 | }; |
| 207 | 209 | ||
| @@ -414,19 +414,19 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev) · 413 unmodified lines | |||
| 414 | 414 | ||
| 415 | ret = clk_prepare_enable(priv->clk_ref); | 415 | ret = clk_prepare_enable(priv->clk_ref); |
| 416 | if (ret) | 416 | if (ret) |
| 417 | goto err_disable_clk_ref; | 417 | return ret; |
| 418 | 418 | ||
| 419 | priv->reset = devm_reset_control_array_get_exclusive(dev); | 419 | priv->reset = devm_reset_control_array_get_exclusive(dev); |
| 420 | if (IS_ERR(priv->reset)) | 420 | if (IS_ERR(priv->reset)) { |
| 421 | return PTR_ERR(priv->reset); | 421 | ret = PTR_ERR(priv->reset); |
| 422 | goto err_disable_clk_ref; | ||
| 423 | } | ||
| 422 | 424 | ||
| 423 | priv->phy = devm_phy_create(dev, np, &phy_g12a_usb3_pcie_ops); | 425 | priv->phy = devm_phy_create(dev, np, &phy_g12a_usb3_pcie_ops); |
| 424 | if (IS_ERR(priv->phy)) { | 426 | if (IS_ERR(priv->phy)) { |
| 425 | ret = PTR_ERR(priv->phy); | 427 | ret = PTR_ERR(priv->phy); |
| 426 | if (ret != -EPROBE_DEFER) | 428 | dev_err_probe(dev, ret, "failed to create PHY\n"); |
| 427 | dev_err(dev, "failed to create PHY\n"); | 429 | goto err_disable_clk_ref; |
| 428 | |||
| 429 | return ret; | ||
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | phy_set_drvdata(priv->phy, priv); | 432 | phy_set_drvdata(priv->phy, priv); |
| @@ -434,8 +434,12 @@ static int phy_g12a_usb3_pcie_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 434 | 434 | ||
| 435 | phy_provider = devm_of_phy_provider_register(dev, | 435 | phy_provider = devm_of_phy_provider_register(dev, |
| 436 | phy_g12a_usb3_pcie_xlate); | 436 | phy_g12a_usb3_pcie_xlate); |
| 437 | if (IS_ERR(phy_provider)) { | ||
| 438 | ret = PTR_ERR(phy_provider); | ||
| 439 | goto err_disable_clk_ref; | ||
| 440 | } | ||
| 437 | 441 | ||
| 438 | return PTR_ERR_OR_ZERO(phy_provider); | 442 | return 0; |
| 439 | 443 | ||
| 440 | err_disable_clk_ref: | 444 | err_disable_clk_ref: |
| 441 | clk_disable_unprepare(priv->clk_ref); | 445 | clk_disable_unprepare(priv->clk_ref); |
| @@ -629,7 +629,8 @@ idle: · 628 unmodified lines | |||
| 629 | cleanup: | 629 | cleanup: |
| 630 | if (error < 0) | 630 | if (error < 0) |
| 631 | phy_mdm6600_device_power_off(ddata); | 631 | phy_mdm6600_device_power_off(ddata); |
| 632 | 632 | pm_runtime_disable(ddata->dev); | |
| 633 | pm_runtime_dont_use_autosuspend(ddata->dev); | ||
| 633 | return error; | 634 | return error; |
| 634 | } | 635 | } |
| 635 | 636 | ||
| @@ -187,6 +187,7 @@ static int exynos_sata_phy_probe(struct platform_device *pdev) · 186 unmodified lines | |||
| 187 | return -EINVAL; | 187 | return -EINVAL; |
| 188 | 188 | ||
| 189 | sata_phy->client = of_find_i2c_device_by_node(node); | 189 | sata_phy->client = of_find_i2c_device_by_node(node); |
| 190 | of_node_put(node); | ||
| 190 | if (!sata_phy->client) | 191 | if (!sata_phy->client) |
| 191 | return -EPROBE_DEFER; | 192 | return -EPROBE_DEFER; |
| 192 | 193 | ||
| @@ -195,20 +196,21 @@ static int exynos_sata_phy_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 195 | sata_phy->phyclk = devm_clk_get(dev, "sata_phyctrl"); | 196 | sata_phy->phyclk = devm_clk_get(dev, "sata_phyctrl"); |
| 196 | if (IS_ERR(sata_phy->phyclk)) { | 197 | if (IS_ERR(sata_phy->phyclk)) { |
| 197 | dev_err(dev, "failed to get clk for PHY\n"); | 198 | dev_err(dev, "failed to get clk for PHY\n"); |
| 198 | return PTR_ERR(sata_phy->phyclk); | 199 | ret = PTR_ERR(sata_phy->phyclk); |
| 200 | goto put_dev; | ||
| 199 | } | 201 | } |
| 200 | 202 | ||
| 201 | ret = clk_prepare_enable(sata_phy->phyclk); | 203 | ret = clk_prepare_enable(sata_phy->phyclk); |
| 202 | if (ret < 0) { | 204 | if (ret < 0) { |
| 203 | dev_err(dev, "failed to enable source clk\n"); | 205 | dev_err(dev, "failed to enable source clk\n"); |
| 204 | return ret; | 206 | goto put_dev; |
| 205 | } | 207 | } |
| 206 | 208 | ||
| 207 | sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops); | 209 | sata_phy->phy = devm_phy_create(dev, NULL, &exynos_sata_phy_ops); |
| 208 | if (IS_ERR(sata_phy->phy)) { | 210 | if (IS_ERR(sata_phy->phy)) { |
| 209 | clk_disable_unprepare(sata_phy->phyclk); | ||
| 210 | dev_err(dev, "failed to create PHY\n"); | 211 | dev_err(dev, "failed to create PHY\n"); |
| 211 | return PTR_ERR(sata_phy->phy); | 212 | ret = PTR_ERR(sata_phy->phy); |
| 213 | goto clk_disable; | ||
| 212 | } | 214 | } |
| 213 | 215 | ||
| 214 | phy_set_drvdata(sata_phy->phy, sata_phy); | 216 | phy_set_drvdata(sata_phy->phy, sata_phy); |
| @@ -216,11 +218,18 @@ static int exynos_sata_phy_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 216 | phy_provider = devm_of_phy_provider_register(dev, | 218 | phy_provider = devm_of_phy_provider_register(dev, |
| 217 | of_phy_simple_xlate); | 219 | of_phy_simple_xlate); |
| 218 | if (IS_ERR(phy_provider)) { | 220 | if (IS_ERR(phy_provider)) { |
| 219 | clk_disable_unprepare(sata_phy->phyclk); | 221 | ret = PTR_ERR(phy_provider); |
| 220 | return PTR_ERR(phy_provider); | 222 | goto clk_disable; |
| 221 | } | 223 | } |
| 222 | 224 | ||
| 223 | return 0; | 225 | return 0; |
| 226 | |||
| 227 | clk_disable: | ||
| 228 | clk_disable_unprepare(sata_phy->phyclk); | ||
| 229 | put_dev: | ||
| 230 | put_device(&sata_phy->client->dev); | ||
| 231 | |||
| 232 | return ret; | ||
| 224 | } | 233 | } |
| 225 | 234 | ||
| 226 | static const struct of_device_id exynos_sata_phy_of_match[] = { | 235 | static const struct of_device_id exynos_sata_phy_of_match[] = { |
| @@ -838,7 +838,7 @@ static int serdes_am654_probe(struct platform_device *pdev) · 837 unmodified lines | |||
| 838 | 838 | ||
| 839 | clk_err: | 839 | clk_err: |
| 840 | of_clk_del_provider(node); | 840 | of_clk_del_provider(node); |
| 841 | 841 | pm_runtime_disable(dev); | |
| 842 | return ret; | 842 | return ret; |
| 843 | } | 843 | } |
| 844 | 844 | ||
| @@ -215,7 +215,7 @@ static int omap_usb2_enable_clocks(struct omap_usb *phy) · 214 unmodified lines | |||
| 215 | return 0; | 215 | return 0; |
| 216 | 216 | ||
| 217 | err1: | 217 | err1: |
| 218 | clk_disable(phy->wkupclk); | 218 | clk_disable_unprepare(phy->wkupclk); |
| 219 | 219 | ||
| 220 | err0: | 220 | err0: |
| 221 | return ret; | 221 | return ret; |
| @@ -696,6 +696,7 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy) · 695 unmodified lines | |||
| 696 | } | 696 | } |
| 697 | 697 | ||
| 698 | control_pdev = of_find_device_by_node(control_node); | 698 | control_pdev = of_find_device_by_node(control_node); |
| 699 | of_node_put(control_node); | ||
| 699 | if (!control_pdev) { | 700 | if (!control_pdev) { |
| 700 | dev_err(dev, "Failed to get control device\n"); | 701 | dev_err(dev, "Failed to get control device\n"); |
| 701 | return -EINVAL; | 702 | return -EINVAL; |
| @@ -155,7 +155,7 @@ static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode) · 154 unmodified lines | |||
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | #ifdef CONFIG_POWER_SUPPLY | 157 | #ifdef CONFIG_POWER_SUPPLY |
| 158 | const char * const tusb1210_chg_det_states[] = { | 158 | static const char * const tusb1210_chg_det_states[] = { |
| 159 | "CHG_DET_CONNECTING", | 159 | "CHG_DET_CONNECTING", |
| 160 | "CHG_DET_START_DET", | 160 | "CHG_DET_START_DET", |
| 161 | "CHG_DET_READ_DET", | 161 | "CHG_DET_READ_DET", |
| @@ -537,12 +537,18 @@ static int tusb1210_probe(struct ulpi *ulpi) · 375 unmodified lines | |||
| 537 | tusb1210_probe_charger_detect(tusb); | 537 | tusb1210_probe_charger_detect(tusb); |
| 538 | 538 | ||
| 539 | tusb->phy = ulpi_phy_create(ulpi, &phy_ops); | 539 | tusb->phy = ulpi_phy_create(ulpi, &phy_ops); |
| 540 | if (IS_ERR(tusb->phy)) | 540 | if (IS_ERR(tusb->phy)) { |
| 541 | return PTR_ERR(tusb->phy); | 541 | ret = PTR_ERR(tusb->phy); |
| 542 | goto err_remove_charger; | ||
| 543 | } | ||
| 542 | 544 | ||
| 543 | phy_set_drvdata(tusb->phy, tusb); | 545 | phy_set_drvdata(tusb->phy, tusb); |
| 544 | ulpi_set_drvdata(ulpi, tusb); | 546 | ulpi_set_drvdata(ulpi, tusb); |
| 545 | return 0; | 547 | return 0; |
| 548 | |||
| 549 | err_remove_charger: | ||
| 550 | tusb1210_remove_charger_detect(tusb); | ||
| 551 | return ret; | ||
| 546 | } | 552 | } |
| 547 | 553 | ||
| 548 | static void tusb1210_remove(struct ulpi *ulpi) | 554 | static void tusb1210_remove(struct ulpi *ulpi) |
| @@ -14,11 +14,17 @@ · 13 unmodified lines | |||
| 14 | 14 | ||
| 15 | #include "pinctrl-intel.h" | 15 | #include "pinctrl-intel.h" |
| 16 | 16 | ||
| 17 | #define ADL_PAD_OWN 0x0a0 | 17 | #define ADL_N_PAD_OWN 0x020 |
| 18 | #define ADL_PADCFGLOCK 0x110 | 18 | #define ADL_N_PADCFGLOCK 0x080 |
| 19 | #define ADL_HOSTSW_OWN 0x150 | 19 | #define ADL_N_HOSTSW_OWN 0x0b0 |
| 20 | #define ADL_GPI_IS 0x200 | 20 | #define ADL_N_GPI_IS 0x100 |
| 21 | #define ADL_GPI_IE 0x220 | 21 | #define ADL_N_GPI_IE 0x120 |
| 22 | |||
| 23 | #define ADL_S_PAD_OWN 0x0a0 | ||
| 24 | #define ADL_S_PADCFGLOCK 0x110 | ||
| 25 | #define ADL_S_HOSTSW_OWN 0x150 | ||
| 26 | #define ADL_S_GPI_IS 0x200 | ||
| 27 | #define ADL_S_GPI_IE 0x220 | ||
| 22 | 28 | ||
| 23 | #define ADL_GPP(r, s, e, g) \ | 29 | #define ADL_GPP(r, s, e, g) \ |
| 24 | { \ | 30 | { \ |
| @@ -28,14 +34,28 @@ · 3 unmodified lines | |||
| 28 | .gpio_base = (g), \ | 34 | .gpio_base = (g), \ |
| 29 | } | 35 | } |
| 30 | 36 | ||
| 31 | #define ADL_COMMUNITY(b, s, e, g) \ | 37 | #define ADL_N_COMMUNITY(b, s, e, g) \ |
| 38 | { \ | ||
| 39 | .barno = (b), \ | ||
| 40 | .padown_offset = ADL_N_PAD_OWN, \ | ||
| 41 | .padcfglock_offset = ADL_N_PADCFGLOCK, \ | ||
| 42 | .hostown_offset = ADL_N_HOSTSW_OWN, \ | ||
| 43 | .is_offset = ADL_N_GPI_IS, \ | ||
| 44 | .ie_offset = ADL_N_GPI_IE, \ | ||
| 45 | .pin_base = (s), \ | ||
| 46 | .npins = ((e) - (s) + 1), \ | ||
| 47 | .gpps = (g), \ | ||
| 48 | .ngpps = ARRAY_SIZE(g), \ | ||
| 49 | } | ||
| 50 | |||
| 51 | #define ADL_S_COMMUNITY(b, s, e, g) \ | ||
| 32 | { \ | 52 | { \ |
| 33 | .barno = (b), \ | 53 | .barno = (b), \ |
| 34 | .padown_offset = ADL_PAD_OWN, \ | 54 | .padown_offset = ADL_S_PAD_OWN, \ |
| 35 | .padcfglock_offset = ADL_PADCFGLOCK, \ | 55 | .padcfglock_offset = ADL_S_PADCFGLOCK, \ |
| 36 | .hostown_offset = ADL_HOSTSW_OWN, \ | 56 | .hostown_offset = ADL_S_HOSTSW_OWN, \ |
| 37 | .is_offset = ADL_GPI_IS, \ | 57 | .is_offset = ADL_S_GPI_IS, \ |
| 38 | .ie_offset = ADL_GPI_IE, \ | 58 | .ie_offset = ADL_S_GPI_IE, \ |
| 39 | .pin_base = (s), \ | 59 | .pin_base = (s), \ |
| 40 | .npins = ((e) - (s) + 1), \ | 60 | .npins = ((e) - (s) + 1), \ |
| 41 | .gpps = (g), \ | 61 | .gpps = (g), \ |
| @@ -342,10 +362,10 @@ static const struct intel_padgroup adln_community5_gpps[] = { · 300 unmodified lines | |||
| 342 | }; | 362 | }; |
| 343 | 363 | ||
| 344 | static const struct intel_community adln_communities[] = { | 364 | static const struct intel_community adln_communities[] = { |
| 345 | ADL_COMMUNITY(0, 0, 66, adln_community0_gpps), | 365 | ADL_N_COMMUNITY(0, 0, 66, adln_community0_gpps), |
| 346 | ADL_COMMUNITY(1, 67, 168, adln_community1_gpps), | 366 | ADL_N_COMMUNITY(1, 67, 168, adln_community1_gpps), |
| 347 | ADL_COMMUNITY(2, 169, 248, adln_community4_gpps), | 367 | ADL_N_COMMUNITY(2, 169, 248, adln_community4_gpps), |
| 348 | ADL_COMMUNITY(3, 249, 256, adln_community5_gpps), | 368 | ADL_N_COMMUNITY(3, 249, 256, adln_community5_gpps), |
| 349 | }; | 369 | }; |
| 350 | 370 | ||
| 351 | static const struct intel_pinctrl_soc_data adln_soc_data = { | 371 | static const struct intel_pinctrl_soc_data adln_soc_data = { |
| @@ -713,11 +733,11 @@ static const struct intel_padgroup adls_community5_gpps[] = { · 361 unmodified lines | |||
| 713 | }; | 733 | }; |
| 714 | 734 | ||
| 715 | static const struct intel_community adls_communities[] = { | 735 | static const struct intel_community adls_communities[] = { |
| 716 | ADL_COMMUNITY(0, 0, 94, adls_community0_gpps), | 736 | ADL_S_COMMUNITY(0, 0, 94, adls_community0_gpps), |
| 717 | ADL_COMMUNITY(1, 95, 150, adls_community1_gpps), | 737 | ADL_S_COMMUNITY(1, 95, 150, adls_community1_gpps), |
| 718 | ADL_COMMUNITY(2, 151, 199, adls_community3_gpps), | 738 | ADL_S_COMMUNITY(2, 151, 199, adls_community3_gpps), |
| 719 | ADL_COMMUNITY(3, 200, 269, adls_community4_gpps), | 739 | ADL_S_COMMUNITY(3, 200, 269, adls_community4_gpps), |
| 720 | ADL_COMMUNITY(4, 270, 303, adls_community5_gpps), | 740 | ADL_S_COMMUNITY(4, 270, 303, adls_community5_gpps), |
| 721 | }; | 741 | }; |
| 722 | 742 | ||
| 723 | static const struct intel_pinctrl_soc_data adls_soc_data = { | 743 | static const struct intel_pinctrl_soc_data adls_soc_data = { |
| @@ -30,6 +30,7 @@ config PINCTRL_MTK_MOORE · 29 unmodified lines | |||
| 30 | select GENERIC_PINMUX_FUNCTIONS | 30 | select GENERIC_PINMUX_FUNCTIONS |
| 31 | select GPIOLIB | 31 | select GPIOLIB |
| 32 | select OF_GPIO | 32 | select OF_GPIO |
| 33 | select EINT_MTK | ||
| 33 | select PINCTRL_MTK_V2 | 34 | select PINCTRL_MTK_V2 |
| 34 | 35 | ||
| 35 | config PINCTRL_MTK_PARIS | 36 | config PINCTRL_MTK_PARIS |
| @@ -1374,10 +1374,10 @@ static int pistachio_gpio_register(struct pistachio_pinctrl *pctl) · 1373 unmodified lines | |||
| 1374 | } | 1374 | } |
| 1375 | 1375 | ||
| 1376 | irq = irq_of_parse_and_map(child, 0); | 1376 | irq = irq_of_parse_and_map(child, 0); |
| 1377 | if (irq < 0) { | 1377 | if (!irq) { |
| 1378 | dev_err(pctl->dev, "No IRQ for bank %u: %d\n", i, irq); | 1378 | dev_err(pctl->dev, "No IRQ for bank %u\n", i); |
| 1379 | of_node_put(child); | 1379 | of_node_put(child); |
| 1380 | ret = irq; | 1380 | ret = -EINVAL; |
| 1381 | goto err; | 1381 | goto err; |
| 1382 | } | 1382 | } |
| 1383 | 1383 | ||
| @@ -457,95 +457,110 @@ static struct rockchip_mux_recalced_data rk3128_mux_recalced_data[] = { · 456 unmodified lines | |||
| 457 | 457 | ||
| 458 | static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { | 458 | static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = { |
| 459 | { | 459 | { |
| 460 | /* gpio1b6_sel */ | ||
| 460 | .num = 1, | 461 | .num = 1, |
| 461 | .pin = 14, | 462 | .pin = 14, |
| 462 | .reg = 0x28, | 463 | .reg = 0x28, |
| 463 | .bit = 12, | 464 | .bit = 12, |
| 464 | .mask = 0xf | 465 | .mask = 0xf |
| 465 | }, { | 466 | }, { |
| 467 | /* gpio1b7_sel */ | ||
| 466 | .num = 1, | 468 | .num = 1, |
| 467 | .pin = 15, | 469 | .pin = 15, |
| 468 | .reg = 0x2c, | 470 | .reg = 0x2c, |
| 469 | .bit = 0, | 471 | .bit = 0, |
| 470 | .mask = 0x3 | 472 | .mask = 0x3 |
| 471 | }, { | 473 | }, { |
| 474 | /* gpio1c2_sel */ | ||
| 472 | .num = 1, | 475 | .num = 1, |
| 473 | .pin = 18, | 476 | .pin = 18, |
| 474 | .reg = 0x30, | 477 | .reg = 0x30, |
| 475 | .bit = 4, | 478 | .bit = 4, |
| 476 | .mask = 0xf | 479 | .mask = 0xf |
| 477 | }, { | 480 | }, { |
| 481 | /* gpio1c3_sel */ | ||
| 478 | .num = 1, | 482 | .num = 1, |
| 479 | .pin = 19, | 483 | .pin = 19, |
| 480 | .reg = 0x30, | 484 | .reg = 0x30, |
| 481 | .bit = 8, | 485 | .bit = 8, |
| 482 | .mask = 0xf | 486 | .mask = 0xf |
| 483 | }, { | 487 | }, { |
| 488 | /* gpio1c4_sel */ | ||
| 484 | .num = 1, | 489 | .num = 1, |
| 485 | .pin = 20, | 490 | .pin = 20, |
| 486 | .reg = 0x30, | 491 | .reg = 0x30, |
| 487 | .bit = 12, | 492 | .bit = 12, |
| 488 | .mask = 0xf | 493 | .mask = 0xf |
| 489 | }, { | 494 | }, { |
| 495 | /* gpio1c5_sel */ | ||
| 490 | .num = 1, | 496 | .num = 1, |
| 491 | .pin = 21, | 497 | .pin = 21, |
| 492 | .reg = 0x34, | 498 | .reg = 0x34, |
| 493 | .bit = 0, | 499 | .bit = 0, |
| 494 | .mask = 0xf | 500 | .mask = 0xf |
| 495 | }, { | 501 | }, { |
| 502 | /* gpio1c6_sel */ | ||
| 496 | .num = 1, | 503 | .num = 1, |
| 497 | .pin = 22, | 504 | .pin = 22, |
| 498 | .reg = 0x34, | 505 | .reg = 0x34, |
| 499 | .bit = 4, | 506 | .bit = 4, |
| 500 | .mask = 0xf | 507 | .mask = 0xf |
| 501 | }, { | 508 | }, { |
| 509 | /* gpio1c7_sel */ | ||
| 502 | .num = 1, | 510 | .num = 1, |
| 503 | .pin = 23, | 511 | .pin = 23, |
| 504 | .reg = 0x34, | 512 | .reg = 0x34, |
| 505 | .bit = 8, | 513 | .bit = 8, |
| 506 | .mask = 0xf | 514 | .mask = 0xf |
| 507 | }, { | 515 | }, { |
| 508 | .num = 3, | 516 | /* gpio2a2_sel */ |
| 509 | .pin = 12, | ||
| 510 | .reg = 0x68, | ||
| 511 | .bit = 8, | ||
| 512 | .mask = 0xf | ||
| 513 | }, { | ||
| 514 | .num = 3, | ||
| 515 | .pin = 13, | ||
| 516 | .reg = 0x68, | ||
| 517 | .bit = 12, | ||
| 518 | .mask = 0xf | ||
| 519 | }, { | ||
| 520 | .num = 2, | 517 | .num = 2, |
| 521 | .pin = 2, | 518 | .pin = 2, |
| 522 | .reg = 0x608, | 519 | .reg = 0x40, |
| 523 | .bit = 0, | 520 | .bit = 4, |
| 524 | .mask = 0x7 | 521 | .mask = 0x3 |
| 525 | }, { | 522 | }, { |
| 523 | /* gpio2a3_sel */ | ||
| 526 | .num = 2, | 524 | .num = 2, |
| 527 | .pin = 3, | 525 | .pin = 3, |
| 528 | .reg = 0x608, | 526 | .reg = 0x40, |
| 529 | .bit = 4, | 527 | .bit = 6, |
| 530 | .mask = 0x7 | 528 | .mask = 0x3 |
| 531 | }, { | 529 | }, { |
| 530 | /* gpio2c0_sel */ | ||
| 532 | .num = 2, | 531 | .num = 2, |
| 533 | .pin = 16, | 532 | .pin = 16, |
| 534 | .reg = 0x610, | 533 | .reg = 0x50, |
| 535 | .bit = 8, | 534 | .bit = 0, |
| 536 | .mask = 0x7 | 535 | .mask = 0x3 |
| 537 | }, { | 536 | }, { |
| 537 | /* gpio3b2_sel */ | ||
| 538 | .num = 3, | 538 | .num = 3, |
| 539 | .pin = 10, | 539 | .pin = 10, |
| 540 | .reg = 0x610, | 540 | .reg = 0x68, |
| 541 | .bit = 0, | 541 | .bit = 4, |
| 542 | .mask = 0x7 | 542 | .mask = 0x3 |
| 543 | }, { | 543 | }, { |
| 544 | /* gpio3b3_sel */ | ||
| 544 | .num = 3, | 545 | .num = 3, |
| 545 | .pin = 11, | 546 | .pin = 11, |
| 546 | .reg = 0x610, | 547 | .reg = 0x68, |
| 547 | .bit = 4, | 548 | .bit = 6, |
| 548 | .mask = 0x7 | 549 | .mask = 0x3 |
| 550 | }, { | ||
| 551 | /* gpio3b4_sel */ | ||
| 552 | .num = 3, | ||
| 553 | .pin = 12, | ||
| 554 | .reg = 0x68, | ||
| 555 | .bit = 8, | ||
| 556 | .mask = 0xf | ||
| 557 | }, { | ||
| 558 | /* gpio3b5_sel */ | ||
| 559 | .num = 3, | ||
| 560 | .pin = 13, | ||
| 561 | .reg = 0x68, | ||
| 562 | .bit = 12, | ||
| 563 | .mask = 0xf | ||
| 549 | }, | 564 | }, |
| 550 | }; | 565 | }; |
| 551 | 566 | ||
| @@ -264,14 +264,14 @@ static const struct pinctrl_pin_desc sm6350_pins[] = { · 263 unmodified lines | |||
| 264 | PINCTRL_PIN(153, "GPIO_153"), | 264 | PINCTRL_PIN(153, "GPIO_153"), |
| 265 | PINCTRL_PIN(154, "GPIO_154"), | 265 | PINCTRL_PIN(154, "GPIO_154"), |
| 266 | PINCTRL_PIN(155, "GPIO_155"), | 266 | PINCTRL_PIN(155, "GPIO_155"), |
| 267 | PINCTRL_PIN(156, "SDC1_RCLK"), | 267 | PINCTRL_PIN(156, "UFS_RESET"), |
| 268 | PINCTRL_PIN(157, "SDC1_CLK"), | 268 | PINCTRL_PIN(157, "SDC1_RCLK"), |
| 269 | PINCTRL_PIN(158, "SDC1_CMD"), | 269 | PINCTRL_PIN(158, "SDC1_CLK"), |
| 270 | PINCTRL_PIN(159, "SDC1_DATA"), | 270 | PINCTRL_PIN(159, "SDC1_CMD"), |
| 271 | PINCTRL_PIN(160, "SDC2_CLK"), | 271 | PINCTRL_PIN(160, "SDC1_DATA"), |
| 272 | PINCTRL_PIN(161, "SDC2_CMD"), | 272 | PINCTRL_PIN(161, "SDC2_CLK"), |
| 273 | PINCTRL_PIN(162, "SDC2_DATA"), | 273 | PINCTRL_PIN(162, "SDC2_CMD"), |
| 274 | PINCTRL_PIN(163, "UFS_RESET"), | 274 | PINCTRL_PIN(163, "SDC2_DATA"), |
| 275 | }; | 275 | }; |
| 276 | 276 | ||
| 277 | #define DECLARE_MSM_GPIO_PINS(pin) \ | 277 | #define DECLARE_MSM_GPIO_PINS(pin) \ |
| @@ -4,14 +4,13 @@ · 3 unmodified lines | |||
| 4 | # | 4 | # |
| 5 | config PINCTRL_SAMSUNG | 5 | config PINCTRL_SAMSUNG |
| 6 | bool | 6 | bool |
| 7 | depends on OF_GPIO | 7 | select GPIOLIB |
| 8 | select PINMUX | 8 | select PINMUX |
| 9 | select PINCONF | 9 | select PINCONF |
| 10 | 10 | ||
| 11 | config PINCTRL_EXYNOS | 11 | config PINCTRL_EXYNOS |
| 12 | bool "Pinctrl common driver part for Samsung Exynos SoCs" | 12 | bool "Pinctrl common driver part for Samsung Exynos SoCs" |
| 13 | depends on OF_GPIO | 13 | depends on ARCH_EXYNOS || ARCH_S5PV210 || (COMPILE_TEST && OF) |
| 14 | depends on ARCH_EXYNOS || ARCH_S5PV210 || COMPILE_TEST | ||
| 15 | select PINCTRL_SAMSUNG | 14 | select PINCTRL_SAMSUNG |
| 16 | select PINCTRL_EXYNOS_ARM if ARM && (ARCH_EXYNOS || ARCH_S5PV210) | 15 | select PINCTRL_EXYNOS_ARM if ARM && (ARCH_EXYNOS || ARCH_S5PV210) |
| 17 | select PINCTRL_EXYNOS_ARM64 if ARM64 && ARCH_EXYNOS | 16 | select PINCTRL_EXYNOS_ARM64 if ARM64 && ARCH_EXYNOS |
| @@ -26,12 +25,10 @@ config PINCTRL_EXYNOS_ARM64 · 8 unmodified lines | |||
| 26 | 25 | ||
| 27 | config PINCTRL_S3C24XX | 26 | config PINCTRL_S3C24XX |
| 28 | bool "Samsung S3C24XX SoC pinctrl driver" | 27 | bool "Samsung S3C24XX SoC pinctrl driver" |
| 29 | depends on OF_GPIO | 28 | depends on ARCH_S3C24XX || (COMPILE_TEST && OF) |
| 30 | depends on ARCH_S3C24XX || COMPILE_TEST | ||
| 31 | select PINCTRL_SAMSUNG | 29 | select PINCTRL_SAMSUNG |
| 32 | 30 | ||
| 33 | config PINCTRL_S3C64XX | 31 | config PINCTRL_S3C64XX |
| 34 | bool "Samsung S3C64XX SoC pinctrl driver" | 32 | bool "Samsung S3C64XX SoC pinctrl driver" |
| 35 | depends on OF_GPIO | 33 | depends on ARCH_S3C64XX || (COMPILE_TEST && OF) |
| 36 | depends on ARCH_S3C64XX || COMPILE_TEST | ||
| 37 | select PINCTRL_SAMSUNG | 34 | select PINCTRL_SAMSUNG |
| @@ -770,7 +770,7 @@ static const struct samsung_pin_bank_data fsd_pin_banks2[] __initconst = { · 769 unmodified lines | |||
| 770 | EXYNOS850_PIN_BANK_EINTN(3, 0x00, "gpq0"), | 770 | EXYNOS850_PIN_BANK_EINTN(3, 0x00, "gpq0"), |
| 771 | }; | 771 | }; |
| 772 | 772 | ||
| 773 | const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = { | 773 | static const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = { |
| 774 | { | 774 | { |
| 775 | /* pin-controller instance 0 FSYS0 data */ | 775 | /* pin-controller instance 0 FSYS0 data */ |
| 776 | .pin_banks = fsd_pin_banks0, | 776 | .pin_banks = fsd_pin_banks0, |
| @@ -225,6 +225,13 @@ static void stm32_gpio_free(struct gpio_chip *chip, unsigned offset) · 224 unmodified lines | |||
| 225 | pinctrl_gpio_free(chip->base + offset); | 225 | pinctrl_gpio_free(chip->base + offset); |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | static int stm32_gpio_get_noclk(struct gpio_chip *chip, unsigned int offset) | ||
| 229 | { | ||
| 230 | struct stm32_gpio_bank *bank = gpiochip_get_data(chip); | ||
| 231 | |||
| 232 | return !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset)); | ||
| 233 | } | ||
| 234 | |||
| 228 | static int stm32_gpio_get(struct gpio_chip *chip, unsigned offset) | 235 | static int stm32_gpio_get(struct gpio_chip *chip, unsigned offset) |
| 229 | { | 236 | { |
| 230 | struct stm32_gpio_bank *bank = gpiochip_get_data(chip); | 237 | struct stm32_gpio_bank *bank = gpiochip_get_data(chip); |
| @@ -232,7 +239,7 @@ static int stm32_gpio_get(struct gpio_chip *chip, unsigned offset) · 1 unmodified line | |||
| 232 | 239 | ||
| 233 | clk_enable(bank->clk); | 240 | clk_enable(bank->clk); |
| 234 | 241 | ||
| 235 | ret = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset)); | 242 | ret = stm32_gpio_get_noclk(chip, offset); |
| 236 | 243 | ||
| 237 | clk_disable(bank->clk); | 244 | clk_disable(bank->clk); |
| 238 | 245 | ||
| @@ -311,8 +318,12 @@ static void stm32_gpio_irq_trigger(struct irq_data *d) · 72 unmodified lines | |||
| 311 | struct stm32_gpio_bank *bank = d->domain->host_data; | 318 | struct stm32_gpio_bank *bank = d->domain->host_data; |
| 312 | int level; | 319 | int level; |
| 313 | 320 | ||
| 321 | /* Do not access the GPIO if this is not LEVEL triggered IRQ. */ | ||
| 322 | if (!(bank->irq_type[d->hwirq] & IRQ_TYPE_LEVEL_MASK)) | ||
| 323 | return; | ||
| 324 | |||
| 314 | /* If level interrupt type then retrig */ | 325 | /* If level interrupt type then retrig */ |
| 315 | level = stm32_gpio_get(&bank->gpio_chip, d->hwirq); | 326 | level = stm32_gpio_get_noclk(&bank->gpio_chip, d->hwirq); |
| 316 | if ((level == 0 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_LOW) || | 327 | if ((level == 0 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_LOW) || |
| 317 | (level == 1 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_HIGH)) | 328 | (level == 1 && bank->irq_type[d->hwirq] == IRQ_TYPE_LEVEL_HIGH)) |
| 318 | irq_chip_retrigger_hierarchy(d); | 329 | irq_chip_retrigger_hierarchy(d); |
| @@ -354,6 +365,7 @@ static int stm32_gpio_irq_request_resources(struct irq_data *irq_data) · 35 unmodified lines | |||
| 354 | { | 365 | { |
| 355 | struct stm32_gpio_bank *bank = irq_data->domain->host_data; | 366 | struct stm32_gpio_bank *bank = irq_data->domain->host_data; |
| 356 | struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent); | 367 | struct stm32_pinctrl *pctl = dev_get_drvdata(bank->gpio_chip.parent); |
| 368 | unsigned long flags; | ||
| 357 | int ret; | 369 | int ret; |
| 358 | 370 | ||
| 359 | ret = stm32_gpio_direction_input(&bank->gpio_chip, irq_data->hwirq); | 371 | ret = stm32_gpio_direction_input(&bank->gpio_chip, irq_data->hwirq); |
| @@ -367,6 +379,10 @@ static int stm32_gpio_irq_request_resources(struct irq_data *irq_data) · 7 unmodified lines | |||
| 367 | return ret; | 379 | return ret; |
| 368 | } | 380 | } |
| 369 | 381 | ||
| 382 | flags = irqd_get_trigger_type(irq_data); | ||
| 383 | if (flags & IRQ_TYPE_LEVEL_MASK) | ||
| 384 | clk_enable(bank->clk); | ||
| 385 | |||
| 370 | return 0; | 386 | return 0; |
| 371 | } | 387 | } |
| 372 | 388 | ||
| @@ -374,6 +390,9 @@ static void stm32_gpio_irq_release_resources(struct irq_data *irq_data) · 1 unmodified line | |||
| 374 | { | 390 | { |
| 375 | struct stm32_gpio_bank *bank = irq_data->domain->host_data; | 391 | struct stm32_gpio_bank *bank = irq_data->domain->host_data; |
| 376 | 392 | ||
| 393 | if (bank->irq_type[irq_data->hwirq] & IRQ_TYPE_LEVEL_MASK) | ||
| 394 | clk_disable(bank->clk); | ||
| 395 | |||
| 377 | gpiochip_unlock_as_irq(&bank->gpio_chip, irq_data->hwirq); | 396 | gpiochip_unlock_as_irq(&bank->gpio_chip, irq_data->hwirq); |
| 378 | } | 397 | } |
| 379 | 398 | ||
| @@ -419,7 +419,15 @@ static const struct sppctl_grp sp7021grps_prbp[] = { · 418 unmodified lines | |||
| 419 | EGRP("PROBE_PORT2", 2, pins_prp2), | 419 | EGRP("PROBE_PORT2", 2, pins_prp2), |
| 420 | }; | 420 | }; |
| 421 | 421 | ||
| 422 | /* | ||
| 423 | * Due to compatible reason, the first valid item should start at the third | ||
| 424 | * position of the array. Please keep the first two items of the table | ||
| 425 | * no use (dummy). | ||
| 426 | */ | ||
| 422 | const struct sppctl_func sppctl_list_funcs[] = { | 427 | const struct sppctl_func sppctl_list_funcs[] = { |
| 428 | FNCN("", pinmux_type_fpmx, 0x00, 0, 0), | ||
| 429 | FNCN("", pinmux_type_fpmx, 0x00, 0, 0), | ||
| 430 | |||
| 423 | FNCN("L2SW_CLK_OUT", pinmux_type_fpmx, 0x00, 0, 7), | 431 | FNCN("L2SW_CLK_OUT", pinmux_type_fpmx, 0x00, 0, 7), |
| 424 | FNCN("L2SW_MAC_SMI_MDC", pinmux_type_fpmx, 0x00, 8, 7), | 432 | FNCN("L2SW_MAC_SMI_MDC", pinmux_type_fpmx, 0x00, 8, 7), |
| 425 | FNCN("L2SW_LED_FLASH0", pinmux_type_fpmx, 0x01, 0, 7), | 433 | FNCN("L2SW_LED_FLASH0", pinmux_type_fpmx, 0x01, 0, 7), |
| @@ -817,7 +817,7 @@ err_cpkg: · 816 unmodified lines | |||
| 817 | err_bus: | 817 | err_bus: |
| 818 | return status; | 818 | return status; |
| 819 | } | 819 | } |
| 820 | module_init(ssam_core_init); | 820 | subsys_initcall(ssam_core_init); |
| 821 | 821 | ||
| 822 | static void __exit ssam_core_exit(void) | 822 | static void __exit ssam_core_exit(void) |
| 823 | { | 823 | { |
| @@ -99,6 +99,14 @@ static const struct dmi_system_id dmi_lid_device_table[] = { · 98 unmodified lines | |||
| 99 | }, | 99 | }, |
| 100 | .driver_data = (void *)lid_device_props_l4D, | 100 | .driver_data = (void *)lid_device_props_l4D, |
| 101 | }, | 101 | }, |
| 102 | { | ||
| 103 | .ident = "Surface Pro 8", | ||
| 104 | .matches = { | ||
| 105 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), | ||
| 106 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Pro 8"), | ||
| 107 | }, | ||
| 108 | .driver_data = (void *)lid_device_props_l4B, | ||
| 109 | }, | ||
| 102 | { | 110 | { |
| 103 | .ident = "Surface Book 1", | 111 | .ident = "Surface Book 1", |
| 104 | .matches = { | 112 | .matches = { |
| @@ -371,10 +371,14 @@ static int asus_wmi_evaluate_method_buf(u32 method_id, · 370 unmodified lines | |||
| 371 | 371 | ||
| 372 | switch (obj->type) { | 372 | switch (obj->type) { |
| 373 | case ACPI_TYPE_BUFFER: | 373 | case ACPI_TYPE_BUFFER: |
| 374 | if (obj->buffer.length > size) | 374 | if (obj->buffer.length > size) { |
| 375 | err = -ENOSPC; | 375 | err = -ENOSPC; |
| 376 | if (obj->buffer.length == 0) | 376 | break; |
| 377 | } | ||
| 378 | if (obj->buffer.length == 0) { | ||
| 377 | err = -ENODATA; | 379 | err = -ENODATA; |
| 380 | break; | ||
| 381 | } | ||
| 378 | 382 | ||
| 379 | memcpy(ret_buffer, obj->buffer.pointer, obj->buffer.length); | 383 | memcpy(ret_buffer, obj->buffer.pointer, obj->buffer.length); |
| 380 | break; | 384 | break; |
| @@ -2223,9 +2227,10 @@ static int fan_curve_check_present(struct asus_wmi *asus, bool *available, · 1842 unmodified lines | |||
| 2223 | 2227 | ||
| 2224 | err = fan_curve_get_factory_default(asus, fan_dev); | 2228 | err = fan_curve_get_factory_default(asus, fan_dev); |
| 2225 | if (err) { | 2229 | if (err) { |
| 2226 | if (err == -ENODEV || err == -ENODATA) | 2230 | pr_debug("fan_curve_get_factory_default(0x%08x) failed: %d\n", |
| 2227 | return 0; | 2231 | fan_dev, err); |
| 2228 | return err; | 2232 | /* Don't cause probe to fail on devices without fan-curves */ |
| 2233 | return 0; | ||
| 2229 | } | 2234 | } |
| 2230 | 2235 | ||
| 2231 | *available = true; | 2236 | *available = true; |
| @@ -80,6 +80,10 @@ static struct quirk_entry quirk_dell_inspiron_1012 = { · 79 unmodified lines | |||
| 80 | .kbd_led_not_present = true, | 80 | .kbd_led_not_present = true, |
| 81 | }; | 81 | }; |
| 82 | 82 | ||
| 83 | static struct quirk_entry quirk_dell_latitude_7520 = { | ||
| 84 | .kbd_missing_ac_tag = true, | ||
| 85 | }; | ||
| 86 | |||
| 83 | static struct platform_driver platform_driver = { | 87 | static struct platform_driver platform_driver = { |
| 84 | .driver = { | 88 | .driver = { |
| 85 | .name = "dell-laptop", | 89 | .name = "dell-laptop", |
| @@ -336,6 +340,15 @@ static const struct dmi_system_id dell_quirks[] __initconst = { · 250 unmodified lines | |||
| 336 | }, | 340 | }, |
| 337 | .driver_data = &quirk_dell_inspiron_1012, | 341 | .driver_data = &quirk_dell_inspiron_1012, |
| 338 | }, | 342 | }, |
| 343 | { | ||
| 344 | .callback = dmi_matched, | ||
| 345 | .ident = "Dell Latitude 7520", | ||
| 346 | .matches = { | ||
| 347 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
| 348 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 7520"), | ||
| 349 | }, | ||
| 350 | .driver_data = &quirk_dell_latitude_7520, | ||
| 351 | }, | ||
| 339 | { } | 352 | { } |
| 340 | }; | 353 | }; |
| 341 | 354 | ||
| @@ -148,6 +148,7 @@ static const struct dmi_system_id gigabyte_wmi_known_working_platforms[] = { · 147 unmodified lines | |||
| 148 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550I AORUS PRO AX"), | 148 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550I AORUS PRO AX"), |
| 149 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M AORUS PRO-P"), | 149 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M AORUS PRO-P"), |
| 150 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M DS3H"), | 150 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B550M DS3H"), |
| 151 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("B660 GAMING X DDR4"), | ||
| 151 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("Z390 I AORUS PRO WIFI-CF"), | 152 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("Z390 I AORUS PRO WIFI-CF"), |
| 152 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 AORUS ELITE"), | 153 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 AORUS ELITE"), |
| 153 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 GAMING X"), | 154 | DMI_EXACT_MATCH_GIGABYTE_BOARD_NAME("X570 GAMING X"), |
| @@ -236,7 +236,7 @@ enum ppfear_regs { · 235 unmodified lines | |||
| 236 | #define ADL_LPM_STATUS_LATCH_EN_OFFSET 0x1704 | 236 | #define ADL_LPM_STATUS_LATCH_EN_OFFSET 0x1704 |
| 237 | #define ADL_LPM_LIVE_STATUS_OFFSET 0x1764 | 237 | #define ADL_LPM_LIVE_STATUS_OFFSET 0x1764 |
| 238 | 238 | ||
| 239 | const char *pmc_lpm_modes[] = { | 239 | static const char *pmc_lpm_modes[] = { |
| 240 | "S0i2.0", | 240 | "S0i2.0", |
| 241 | "S0i2.1", | 241 | "S0i2.1", |
| 242 | "S0i2.2", | 242 | "S0i2.2", |
| @@ -103,7 +103,7 @@ static int pmt_telem_probe(struct auxiliary_device *auxdev, const struct auxilia · 102 unmodified lines | |||
| 103 | auxiliary_set_drvdata(auxdev, priv); | 103 | auxiliary_set_drvdata(auxdev, priv); |
| 104 | 104 | ||
| 105 | for (i = 0; i < intel_vsec_dev->num_resources; i++) { | 105 | for (i = 0; i < intel_vsec_dev->num_resources; i++) { |
| 106 | struct intel_pmt_entry *entry = &priv->entry[i]; | 106 | struct intel_pmt_entry *entry = &priv->entry[priv->num_entries]; |
| 107 | 107 | ||
| 108 | ret = intel_pmt_dev_create(entry, &pmt_telem_ns, intel_vsec_dev, i); | 108 | ret = intel_pmt_dev_create(entry, &pmt_telem_ns, intel_vsec_dev, i); |
| 109 | if (ret < 0) | 109 | if (ret < 0) |
| @@ -51,6 +51,8 @@ · 50 unmodified lines | |||
| 51 | #define MBOX_TIMEOUT_US 2000 | 51 | #define MBOX_TIMEOUT_US 2000 |
| 52 | #define MBOX_TIMEOUT_ACQUIRE_US 1000 | 52 | #define MBOX_TIMEOUT_ACQUIRE_US 1000 |
| 53 | #define MBOX_POLLING_PERIOD_US 100 | 53 | #define MBOX_POLLING_PERIOD_US 100 |
| 54 | #define MBOX_ACQUIRE_NUM_RETRIES 5 | ||
| 55 | #define MBOX_ACQUIRE_RETRY_DELAY_MS 500 | ||
| 54 | #define MBOX_MAX_PACKETS 4 | 56 | #define MBOX_MAX_PACKETS 4 |
| 55 | 57 | ||
| 56 | #define MBOX_OWNER_NONE 0x00 | 58 | #define MBOX_OWNER_NONE 0x00 |
| @@ -81,7 +83,7 @@ enum sdsi_command { · 24 unmodified lines | |||
| 81 | 83 | ||
| 82 | struct sdsi_mbox_info { | 84 | struct sdsi_mbox_info { |
| 83 | u64 *payload; | 85 | u64 *payload; |
| 84 | u64 *buffer; | 86 | void *buffer; |
| 85 | int size; | 87 | int size; |
| 86 | }; | 88 | }; |
| 87 | 89 | ||
| @@ -163,9 +165,7 @@ static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, struct sdsi_mbox_info *inf · 75 unmodified lines | |||
| 163 | total = 0; | 165 | total = 0; |
| 164 | loop = 0; | 166 | loop = 0; |
| 165 | do { | 167 | do { |
| 166 | int offset = SDSI_SIZE_MAILBOX * loop; | 168 | void *buf = info->buffer + (SDSI_SIZE_MAILBOX * loop); |
| 167 | void __iomem *addr = priv->mbox_addr + offset; | ||
| 168 | u64 *buf = info->buffer + offset / SDSI_SIZE_CMD; | ||
| 169 | u32 packet_size; | 169 | u32 packet_size; |
| 170 | 170 | ||
| 171 | /* Poll on ready bit */ | 171 | /* Poll on ready bit */ |
| @@ -196,7 +196,7 @@ static int sdsi_mbox_cmd_read(struct sdsi_priv *priv, struct sdsi_mbox_info *inf · 24 unmodified lines | |||
| 196 | break; | 196 | break; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | sdsi_memcpy64_fromio(buf, addr, round_up(packet_size, SDSI_SIZE_CMD)); | 199 | sdsi_memcpy64_fromio(buf, priv->mbox_addr, round_up(packet_size, SDSI_SIZE_CMD)); |
| 200 | 200 | ||
| 201 | total += packet_size; | 201 | total += packet_size; |
| 202 | 202 | ||
| @@ -243,8 +243,8 @@ static int sdsi_mbox_cmd_write(struct sdsi_priv *priv, struct sdsi_mbox_info *in · 40 unmodified lines | |||
| 243 | FIELD_PREP(CTRL_PACKET_SIZE, info->size); | 243 | FIELD_PREP(CTRL_PACKET_SIZE, info->size); |
| 244 | writeq(control, priv->control_addr); | 244 | writeq(control, priv->control_addr); |
| 245 | 245 | ||
| 246 | /* Poll on run_busy bit */ | 246 | /* Poll on ready bit */ |
| 247 | ret = readq_poll_timeout(priv->control_addr, control, !(control & CTRL_RUN_BUSY), | 247 | ret = readq_poll_timeout(priv->control_addr, control, control & CTRL_READY, |
| 248 | MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US); | 248 | MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_US); |
| 249 | 249 | ||
| 250 | if (ret) | 250 | if (ret) |
| @@ -263,7 +263,7 @@ static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info · 12 unmodified lines | |||
| 263 | { | 263 | { |
| 264 | u64 control; | 264 | u64 control; |
| 265 | u32 owner; | 265 | u32 owner; |
| 266 | int ret; | 266 | int ret, retries = 0; |
| 267 | 267 | ||
| 268 | lockdep_assert_held(&priv->mb_lock); | 268 | lockdep_assert_held(&priv->mb_lock); |
| 269 | 269 | ||
| @@ -273,13 +273,29 @@ static int sdsi_mbox_acquire(struct sdsi_priv *priv, struct sdsi_mbox_info *info · 3 unmodified lines | |||
| 273 | if (owner != MBOX_OWNER_NONE) | 273 | if (owner != MBOX_OWNER_NONE) |
| 274 | return -EBUSY; | 274 | return -EBUSY; |
| 275 | 275 | ||
| 276 | /* Write first qword of payload */ | 276 | /* |
| 277 | writeq(info->payload[0], priv->mbox_addr); | 277 | * If there has been no recent transaction and no one owns the mailbox, |
| 278 | * we should acquire it in under 1ms. However, if we've accessed it | ||
| 279 | * recently it may take up to 2.1 seconds to acquire it again. | ||
| 280 | */ | ||
| 281 | do { | ||
| 282 | /* Write first qword of payload */ | ||
| 283 | writeq(info->payload[0], priv->mbox_addr); | ||
| 284 | |||
| 285 | /* Check for ownership */ | ||
| 286 | ret = readq_poll_timeout(priv->control_addr, control, | ||
| 287 | FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_INBAND, | ||
| 288 | MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US); | ||
| 289 | |||
| 290 | if (FIELD_GET(CTRL_OWNER, control) == MBOX_OWNER_NONE && | ||
| 291 | retries++ < MBOX_ACQUIRE_NUM_RETRIES) { | ||
| 292 | msleep(MBOX_ACQUIRE_RETRY_DELAY_MS); | ||
| 293 | continue; | ||
| 294 | } | ||
| 278 | 295 | ||
| 279 | /* Check for ownership */ | 296 | /* Either we got it or someone else did. */ |
| 280 | ret = readq_poll_timeout(priv->control_addr, control, | 297 | break; |
| 281 | FIELD_GET(CTRL_OWNER, control) & MBOX_OWNER_INBAND, | 298 | } while (true); |
| 282 | MBOX_POLLING_PERIOD_US, MBOX_TIMEOUT_ACQUIRE_US); | ||
| 283 | 299 | ||
| 284 | return ret; | 300 | return ret; |
| 285 | } | 301 | } |
| @@ -212,6 +212,9 @@ static int __init intel_uncore_init(void) · 211 unmodified lines | |||
| 212 | const struct x86_cpu_id *id; | 212 | const struct x86_cpu_id *id; |
| 213 | int ret; | 213 | int ret; |
| 214 | 214 | ||
| 215 | if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) | ||
| 216 | return -ENODEV; | ||
| 217 | |||
| 215 | id = x86_match_cpu(intel_uncore_cpu_ids); | 218 | id = x86_match_cpu(intel_uncore_cpu_ids); |
| 216 | if (!id) | 219 | if (!id) |
| 217 | return -ENODEV; | 220 | return -ENODEV; |
| @@ -309,6 +309,20 @@ struct ibm_init_struct { · 308 unmodified lines | |||
| 309 | struct ibm_struct *data; | 309 | struct ibm_struct *data; |
| 310 | }; | 310 | }; |
| 311 | 311 | ||
| 312 | /* DMI Quirks */ | ||
| 313 | struct quirk_entry { | ||
| 314 | bool btusb_bug; | ||
| 315 | u32 s2idle_bug_mmio; | ||
| 316 | }; | ||
| 317 | |||
| 318 | static struct quirk_entry quirk_btusb_bug = { | ||
| 319 | .btusb_bug = true, | ||
| 320 | }; | ||
| 321 | |||
| 322 | static struct quirk_entry quirk_s2idle_bug = { | ||
| 323 | .s2idle_bug_mmio = 0xfed80380, | ||
| 324 | }; | ||
| 325 | |||
| 312 | static struct { | 326 | static struct { |
| 313 | u32 bluetooth:1; | 327 | u32 bluetooth:1; |
| 314 | u32 hotkey:1; | 328 | u32 hotkey:1; |
| @@ -338,6 +352,7 @@ static struct { · 23 unmodified lines | |||
| 338 | u32 hotkey_poll_active:1; | 352 | u32 hotkey_poll_active:1; |
| 339 | u32 has_adaptive_kbd:1; | 353 | u32 has_adaptive_kbd:1; |
| 340 | u32 kbd_lang:1; | 354 | u32 kbd_lang:1; |
| 355 | struct quirk_entry *quirks; | ||
| 341 | } tp_features; | 356 | } tp_features; |
| 342 | 357 | ||
| 343 | static struct { | 358 | static struct { |
| @@ -4359,9 +4374,10 @@ static void bluetooth_exit(void) · 4015 unmodified lines | |||
| 4359 | bluetooth_shutdown(); | 4374 | bluetooth_shutdown(); |
| 4360 | } | 4375 | } |
| 4361 | 4376 | ||
| 4362 | static const struct dmi_system_id bt_fwbug_list[] __initconst = { | 4377 | static const struct dmi_system_id fwbug_list[] __initconst = { |
| 4363 | { | 4378 | { |
| 4364 | .ident = "ThinkPad E485", | 4379 | .ident = "ThinkPad E485", |
| 4380 | .driver_data = &quirk_btusb_bug, | ||
| 4365 | .matches = { | 4381 | .matches = { |
| 4366 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 4382 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
| 4367 | DMI_MATCH(DMI_BOARD_NAME, "20KU"), | 4383 | DMI_MATCH(DMI_BOARD_NAME, "20KU"), |
| @@ -4369,6 +4385,7 @@ static const struct dmi_system_id bt_fwbug_list[] __initconst = { · 1 unmodified line | |||
| 4369 | }, | 4385 | }, |
| 4370 | { | 4386 | { |
| 4371 | .ident = "ThinkPad E585", | 4387 | .ident = "ThinkPad E585", |
| 4388 | .driver_data = &quirk_btusb_bug, | ||
| 4372 | .matches = { | 4389 | .matches = { |
| 4373 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 4390 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
| 4374 | DMI_MATCH(DMI_BOARD_NAME, "20KV"), | 4391 | DMI_MATCH(DMI_BOARD_NAME, "20KV"), |
| @@ -4376,6 +4393,7 @@ static const struct dmi_system_id bt_fwbug_list[] __initconst = { · 1 unmodified line | |||
| 4376 | }, | 4393 | }, |
| 4377 | { | 4394 | { |
| 4378 | .ident = "ThinkPad A285 - 20MW", | 4395 | .ident = "ThinkPad A285 - 20MW", |
| 4396 | .driver_data = &quirk_btusb_bug, | ||
| 4379 | .matches = { | 4397 | .matches = { |
| 4380 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 4398 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
| 4381 | DMI_MATCH(DMI_BOARD_NAME, "20MW"), | 4399 | DMI_MATCH(DMI_BOARD_NAME, "20MW"), |
| @@ -4383,6 +4401,7 @@ static const struct dmi_system_id bt_fwbug_list[] __initconst = { · 1 unmodified line | |||
| 4383 | }, | 4401 | }, |
| 4384 | { | 4402 | { |
| 4385 | .ident = "ThinkPad A285 - 20MX", | 4403 | .ident = "ThinkPad A285 - 20MX", |
| 4404 | .driver_data = &quirk_btusb_bug, | ||
| 4386 | .matches = { | 4405 | .matches = { |
| 4387 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 4406 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
| 4388 | DMI_MATCH(DMI_BOARD_NAME, "20MX"), | 4407 | DMI_MATCH(DMI_BOARD_NAME, "20MX"), |
| @@ -4390,6 +4409,7 @@ static const struct dmi_system_id bt_fwbug_list[] __initconst = { · 1 unmodified line | |||
| 4390 | }, | 4409 | }, |
| 4391 | { | 4410 | { |
| 4392 | .ident = "ThinkPad A485 - 20MU", | 4411 | .ident = "ThinkPad A485 - 20MU", |
| 4412 | .driver_data = &quirk_btusb_bug, | ||
| 4393 | .matches = { | 4413 | .matches = { |
| 4394 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 4414 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
| 4395 | DMI_MATCH(DMI_BOARD_NAME, "20MU"), | 4415 | DMI_MATCH(DMI_BOARD_NAME, "20MU"), |
| @@ -4397,14 +4417,125 @@ static const struct dmi_system_id bt_fwbug_list[] __initconst = { · 1 unmodified line | |||
| 4397 | }, | 4417 | }, |
| 4398 | { | 4418 | { |
| 4399 | .ident = "ThinkPad A485 - 20MV", | 4419 | .ident = "ThinkPad A485 - 20MV", |
| 4420 | .driver_data = &quirk_btusb_bug, | ||
| 4400 | .matches = { | 4421 | .matches = { |
| 4401 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 4422 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
| 4402 | DMI_MATCH(DMI_BOARD_NAME, "20MV"), | 4423 | DMI_MATCH(DMI_BOARD_NAME, "20MV"), |
| 4403 | }, | 4424 | }, |
| 4404 | }, | 4425 | }, |
| 4426 | { | ||
| 4427 | .ident = "L14 Gen2 AMD", | ||
| 4428 | .driver_data = &quirk_s2idle_bug, | ||
| 4429 | .matches = { | ||
| 4430 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 4431 | DMI_MATCH(DMI_PRODUCT_NAME, "20X5"), | ||
| 4432 | } | ||
| 4433 | }, | ||
| 4434 | { | ||
| 4435 | .ident = "T14s Gen2 AMD", | ||
| 4436 | .driver_data = &quirk_s2idle_bug, | ||
| 4437 | .matches = { | ||
| 4438 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 4439 | DMI_MATCH(DMI_PRODUCT_NAME, "20XF"), | ||
| 4440 | } | ||
| 4441 | }, | ||
| 4442 | { | ||
| 4443 | .ident = "X13 Gen2 AMD", | ||
| 4444 | .driver_data = &quirk_s2idle_bug, | ||
| 4445 | .matches = { | ||
| 4446 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 4447 | DMI_MATCH(DMI_PRODUCT_NAME, "20XH"), | ||
| 4448 | } | ||
| 4449 | }, | ||
| 4450 | { | ||
| 4451 | .ident = "T14 Gen2 AMD", | ||
| 4452 | .driver_data = &quirk_s2idle_bug, | ||
| 4453 | .matches = { | ||
| 4454 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 4455 | DMI_MATCH(DMI_PRODUCT_NAME, "20XK"), | ||
| 4456 | } | ||
| 4457 | }, | ||
| 4458 | { | ||
| 4459 | .ident = "T14 Gen1 AMD", | ||
| 4460 | .driver_data = &quirk_s2idle_bug, | ||
| 4461 | .matches = { | ||
| 4462 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 4463 | DMI_MATCH(DMI_PRODUCT_NAME, "20UD"), | ||
| 4464 | } | ||
| 4465 | }, | ||
| 4466 | { | ||
| 4467 | .ident = "T14 Gen1 AMD", | ||
| 4468 | .driver_data = &quirk_s2idle_bug, | ||
| 4469 | .matches = { | ||
| 4470 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 4471 | DMI_MATCH(DMI_PRODUCT_NAME, "20UE"), | ||
| 4472 | } | ||
| 4473 | }, | ||
| 4474 | { | ||
| 4475 | .ident = "T14s Gen1 AMD", | ||
| 4476 | .driver_data = &quirk_s2idle_bug, | ||
| 4477 | .matches = { | ||
| 4478 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 4479 | DMI_MATCH(DMI_PRODUCT_NAME, "20UH"), | ||
| 4480 | } | ||
| 4481 | }, | ||
| 4482 | { | ||
| 4483 | .ident = "P14s Gen1 AMD", | ||
| 4484 | .driver_data = &quirk_s2idle_bug, | ||
| 4485 | .matches = { | ||
| 4486 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 4487 | DMI_MATCH(DMI_PRODUCT_NAME, "20Y1"), | ||
| 4488 | } | ||
| 4489 | }, | ||
| 4490 | { | ||
| 4491 | .ident = "P14s Gen2 AMD", | ||
| 4492 | .driver_data = &quirk_s2idle_bug, | ||
| 4493 | .matches = { | ||
| 4494 | DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), | ||
| 4495 | DMI_MATCH(DMI_PRODUCT_NAME, "21A0"), | ||
| 4496 | } | ||
| 4497 | }, | ||
| 4405 | {} | 4498 | {} |
| 4406 | }; | 4499 | }; |
| 4407 | 4500 | ||
| 4501 | #ifdef CONFIG_SUSPEND | ||
| 4502 | /* | ||
| 4503 | * Lenovo laptops from a variety of generations run a SMI handler during the D3->D0 | ||
| 4504 | * transition that occurs specifically when exiting suspend to idle which can cause | ||
| 4505 | * large delays during resume when the IOMMU translation layer is enabled (the default | ||
| 4506 | * behavior) for NVME devices: | ||
| 4507 | * | ||
| 4508 | * To avoid this firmware problem, skip the SMI handler on these machines before the | ||
| 4509 | * D0 transition occurs. | ||
| 4510 | */ | ||
| 4511 | static void thinkpad_acpi_amd_s2idle_restore(void) | ||
| 4512 | { | ||
| 4513 | struct resource *res; | ||
| 4514 | void __iomem *addr; | ||
| 4515 | u8 val; | ||
| 4516 | |||
| 4517 | res = request_mem_region_muxed(tp_features.quirks->s2idle_bug_mmio, 1, | ||
| 4518 | "thinkpad_acpi_pm80"); | ||
| 4519 | if (!res) | ||
| 4520 | return; | ||
| 4521 | |||
| 4522 | addr = ioremap(tp_features.quirks->s2idle_bug_mmio, 1); | ||
| 4523 | if (!addr) | ||
| 4524 | goto cleanup_resource; | ||
| 4525 | |||
| 4526 | val = ioread8(addr); | ||
| 4527 | iowrite8(val & ~BIT(0), addr); | ||
| 4528 | |||
| 4529 | iounmap(addr); | ||
| 4530 | cleanup_resource: | ||
| 4531 | release_resource(res); | ||
| 4532 | } | ||
| 4533 | |||
| 4534 | static struct acpi_s2idle_dev_ops thinkpad_acpi_s2idle_dev_ops = { | ||
| 4535 | .restore = thinkpad_acpi_amd_s2idle_restore, | ||
| 4536 | }; | ||
| 4537 | #endif | ||
| 4538 | |||
| 4408 | static const struct pci_device_id fwbug_cards_ids[] __initconst = { | 4539 | static const struct pci_device_id fwbug_cards_ids[] __initconst = { |
| 4409 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24F3) }, | 4540 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24F3) }, |
| 4410 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24FD) }, | 4541 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x24FD) }, |
| @@ -4419,7 +4550,8 @@ static int __init have_bt_fwbug(void) · 8 unmodified lines | |||
| 4419 | * Some AMD based ThinkPads have a firmware bug that calling | 4550 | * Some AMD based ThinkPads have a firmware bug that calling |
| 4420 | * "GBDC" will cause bluetooth on Intel wireless cards blocked | 4551 | * "GBDC" will cause bluetooth on Intel wireless cards blocked |
| 4421 | */ | 4552 | */ |
| 4422 | if (dmi_check_system(bt_fwbug_list) && pci_dev_present(fwbug_cards_ids)) { | 4553 | if (tp_features.quirks && tp_features.quirks->btusb_bug && |
| 4554 | pci_dev_present(fwbug_cards_ids)) { | ||
| 4423 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, | 4555 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL, |
| 4424 | FW_BUG "disable bluetooth subdriver for Intel cards\n"); | 4556 | FW_BUG "disable bluetooth subdriver for Intel cards\n"); |
| 4425 | return 1; | 4557 | return 1; |
| @@ -8748,24 +8880,27 @@ static int __init fan_init(struct ibm_init_struct *iibm) · 4322 unmodified lines | |||
| 8748 | fan_status_access_mode = TPACPI_FAN_RD_TPEC; | 8880 | fan_status_access_mode = TPACPI_FAN_RD_TPEC; |
| 8749 | if (quirks & TPACPI_FAN_Q1) | 8881 | if (quirks & TPACPI_FAN_Q1) |
| 8750 | fan_quirk1_setup(); | 8882 | fan_quirk1_setup(); |
| 8751 | if (quirks & TPACPI_FAN_2FAN) { | ||
| 8752 | tp_features.second_fan = 1; | ||
| 8753 | pr_info("secondary fan support enabled\n"); | ||
| 8754 | } | ||
| 8755 | if (quirks & TPACPI_FAN_2CTL) { | ||
| 8756 | tp_features.second_fan = 1; | ||
| 8757 | tp_features.second_fan_ctl = 1; | ||
| 8758 | pr_info("secondary fan control enabled\n"); | ||
| 8759 | } | ||
| 8760 | /* Try and probe the 2nd fan */ | 8883 | /* Try and probe the 2nd fan */ |
| 8884 | tp_features.second_fan = 1; /* needed for get_speed to work */ | ||
| 8761 | res = fan2_get_speed(&speed); | 8885 | res = fan2_get_speed(&speed); |
| 8762 | if (res >= 0) { | 8886 | if (res >= 0) { |
| 8763 | /* It responded - so let's assume it's there */ | 8887 | /* It responded - so let's assume it's there */ |
| 8764 | tp_features.second_fan = 1; | 8888 | tp_features.second_fan = 1; |
| 8765 | tp_features.second_fan_ctl = 1; | 8889 | tp_features.second_fan_ctl = 1; |
| 8766 | pr_info("secondary fan control detected & enabled\n"); | 8890 | pr_info("secondary fan control detected & enabled\n"); |
| 8891 | } else { | ||
| 8892 | /* Fan not auto-detected */ | ||
| 8893 | tp_features.second_fan = 0; | ||
| 8894 | if (quirks & TPACPI_FAN_2FAN) { | ||
| 8895 | tp_features.second_fan = 1; | ||
| 8896 | pr_info("secondary fan support enabled\n"); | ||
| 8897 | } | ||
| 8898 | if (quirks & TPACPI_FAN_2CTL) { | ||
| 8899 | tp_features.second_fan = 1; | ||
| 8900 | tp_features.second_fan_ctl = 1; | ||
| 8901 | pr_info("secondary fan control enabled\n"); | ||
| 8902 | } | ||
| 8767 | } | 8903 | } |
| 8768 | |||
| 8769 | } else { | 8904 | } else { |
| 8770 | pr_err("ThinkPad ACPI EC access misbehaving, fan status and control unavailable\n"); | 8905 | pr_err("ThinkPad ACPI EC access misbehaving, fan status and control unavailable\n"); |
| 8771 | return -ENODEV; | 8906 | return -ENODEV; |
| @@ -11455,6 +11590,10 @@ static void thinkpad_acpi_module_exit(void) · 2683 unmodified lines | |||
| 11455 | 11590 | ||
| 11456 | tpacpi_lifecycle = TPACPI_LIFE_EXITING; | 11591 | tpacpi_lifecycle = TPACPI_LIFE_EXITING; |
| 11457 | 11592 | ||
| 11593 | #ifdef CONFIG_SUSPEND | ||
| 11594 | if (tp_features.quirks && tp_features.quirks->s2idle_bug_mmio) | ||
| 11595 | acpi_unregister_lps0_dev(&thinkpad_acpi_s2idle_dev_ops); | ||
| 11596 | #endif | ||
| 11458 | if (tpacpi_hwmon) | 11597 | if (tpacpi_hwmon) |
| 11459 | hwmon_device_unregister(tpacpi_hwmon); | 11598 | hwmon_device_unregister(tpacpi_hwmon); |
| 11460 | if (tp_features.sensors_pdrv_registered) | 11599 | if (tp_features.sensors_pdrv_registered) |
| @@ -11496,6 +11635,7 @@ static void thinkpad_acpi_module_exit(void) · 35 unmodified lines | |||
| 11496 | 11635 | ||
| 11497 | static int __init thinkpad_acpi_module_init(void) | 11636 | static int __init thinkpad_acpi_module_init(void) |
| 11498 | { | 11637 | { |
| 11638 | const struct dmi_system_id *dmi_id; | ||
| 11499 | int ret, i; | 11639 | int ret, i; |
| 11500 | 11640 | ||
| 11501 | tpacpi_lifecycle = TPACPI_LIFE_INIT; | 11641 | tpacpi_lifecycle = TPACPI_LIFE_INIT; |
| @@ -11535,6 +11675,10 @@ static int __init thinkpad_acpi_module_init(void) · 33 unmodified lines | |||
| 11535 | return -ENODEV; | 11675 | return -ENODEV; |
| 11536 | } | 11676 | } |
| 11537 | 11677 | ||
| 11678 | dmi_id = dmi_first_match(fwbug_list); | ||
| 11679 | if (dmi_id) | ||
| 11680 | tp_features.quirks = dmi_id->driver_data; | ||
| 11681 | |||
| 11538 | /* Device initialization */ | 11682 | /* Device initialization */ |
| 11539 | tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, -1, | 11683 | tpacpi_pdev = platform_device_register_simple(TPACPI_DRVR_NAME, -1, |
| 11540 | NULL, 0); | 11684 | NULL, 0); |
| @@ -11623,6 +11767,13 @@ static int __init thinkpad_acpi_module_init(void) · 82 unmodified lines | |||
| 11623 | tp_features.input_device_registered = 1; | 11767 | tp_features.input_device_registered = 1; |
| 11624 | } | 11768 | } |
| 11625 | 11769 | ||
| 11770 | #ifdef CONFIG_SUSPEND | ||
| 11771 | if (tp_features.quirks && tp_features.quirks->s2idle_bug_mmio) { | ||
| 11772 | if (!acpi_register_lps0_dev(&thinkpad_acpi_s2idle_dev_ops)) | ||
| 11773 | pr_info("Using s2idle quirk to avoid %s platform firmware bug\n", | ||
| 11774 | (dmi_id && dmi_id->ident) ? dmi_id->ident : ""); | ||
| 11775 | } | ||
| 11776 | #endif | ||
| 11626 | return 0; | 11777 | return 0; |
| 11627 | } | 11778 | } |
| 11628 | 11779 | ||
| @@ -1557,7 +1557,7 @@ ptp_ocp_signal_set(struct ptp_ocp *bp, int gen, struct ptp_ocp_signal *s) · 1556 unmodified lines | |||
| 1557 | start_ns = ktime_set(ts.tv_sec, ts.tv_nsec) + NSEC_PER_MSEC; | 1557 | start_ns = ktime_set(ts.tv_sec, ts.tv_nsec) + NSEC_PER_MSEC; |
| 1558 | if (!s->start) { | 1558 | if (!s->start) { |
| 1559 | /* roundup() does not work on 32-bit systems */ | 1559 | /* roundup() does not work on 32-bit systems */ |
| 1560 | s->start = DIV_ROUND_UP_ULL(start_ns, s->period); | 1560 | s->start = DIV64_U64_ROUND_UP(start_ns, s->period); |
| 1561 | s->start = ktime_add(s->start, s->phase); | 1561 | s->start = ktime_add(s->start, s->phase); |
| 1562 | } | 1562 | } |
| 1563 | 1563 | ||
| @@ -1422,6 +1422,13 @@ int dasd_start_IO(struct dasd_ccw_req *cqr) · 1421 unmodified lines | |||
| 1422 | if (!cqr->lpm) | 1422 | if (!cqr->lpm) |
| 1423 | cqr->lpm = dasd_path_get_opm(device); | 1423 | cqr->lpm = dasd_path_get_opm(device); |
| 1424 | } | 1424 | } |
| 1425 | /* | ||
| 1426 | * remember the amount of formatted tracks to prevent double format on | ||
| 1427 | * ESE devices | ||
| 1428 | */ | ||
| 1429 | if (cqr->block) | ||
| 1430 | cqr->trkcount = atomic_read(&cqr->block->trkcount); | ||
| 1431 | |||
| 1425 | if (cqr->cpmode == 1) { | 1432 | if (cqr->cpmode == 1) { |
| 1426 | rc = ccw_device_tm_start(device->cdev, cqr->cpaddr, | 1433 | rc = ccw_device_tm_start(device->cdev, cqr->cpaddr, |
| 1427 | (long) cqr, cqr->lpm); | 1434 | (long) cqr, cqr->lpm); |
| @@ -1639,6 +1646,7 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, · 211 unmodified lines | |||
| 1639 | unsigned long now; | 1646 | unsigned long now; |
| 1640 | int nrf_suppressed = 0; | 1647 | int nrf_suppressed = 0; |
| 1641 | int fp_suppressed = 0; | 1648 | int fp_suppressed = 0; |
| 1649 | struct request *req; | ||
| 1642 | u8 *sense = NULL; | 1650 | u8 *sense = NULL; |
| 1643 | int expires; | 1651 | int expires; |
| 1644 | 1652 | ||
| @@ -1739,7 +1747,12 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, · 94 unmodified lines | |||
| 1739 | } | 1747 | } |
| 1740 | 1748 | ||
| 1741 | if (dasd_ese_needs_format(cqr->block, irb)) { | 1749 | if (dasd_ese_needs_format(cqr->block, irb)) { |
| 1742 | if (rq_data_dir((struct request *)cqr->callback_data) == READ) { | 1750 | req = dasd_get_callback_data(cqr); |
| 1751 | if (!req) { | ||
| 1752 | cqr->status = DASD_CQR_ERROR; | ||
| 1753 | return; | ||
| 1754 | } | ||
| 1755 | if (rq_data_dir(req) == READ) { | ||
| 1743 | device->discipline->ese_read(cqr, irb); | 1756 | device->discipline->ese_read(cqr, irb); |
| 1744 | cqr->status = DASD_CQR_SUCCESS; | 1757 | cqr->status = DASD_CQR_SUCCESS; |
| 1745 | cqr->stopclk = now; | 1758 | cqr->stopclk = now; |
| @@ -2765,8 +2778,7 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) · 1019 unmodified lines | |||
| 2765 | * complete a request partially. | 2778 | * complete a request partially. |
| 2766 | */ | 2779 | */ |
| 2767 | if (proc_bytes) { | 2780 | if (proc_bytes) { |
| 2768 | blk_update_request(req, BLK_STS_OK, | 2781 | blk_update_request(req, BLK_STS_OK, proc_bytes); |
| 2769 | blk_rq_bytes(req) - proc_bytes); | ||
| 2770 | blk_mq_requeue_request(req, true); | 2782 | blk_mq_requeue_request(req, true); |
| 2771 | } else if (likely(!blk_should_fake_timeout(req->q))) { | 2783 | } else if (likely(!blk_should_fake_timeout(req->q))) { |
| 2772 | blk_mq_complete_request(req); | 2784 | blk_mq_complete_request(req); |
| @@ -1480,7 +1480,7 @@ static int dasd_eckd_pe_handler(struct dasd_device *device, · 1479 unmodified lines | |||
| 1480 | { | 1480 | { |
| 1481 | struct pe_handler_work_data *data; | 1481 | struct pe_handler_work_data *data; |
| 1482 | 1482 | ||
| 1483 | data = kmalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA); | 1483 | data = kzalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA); |
| 1484 | if (!data) { | 1484 | if (!data) { |
| 1485 | if (mutex_trylock(&dasd_pe_handler_mutex)) { | 1485 | if (mutex_trylock(&dasd_pe_handler_mutex)) { |
| 1486 | data = pe_handler_worker; | 1486 | data = pe_handler_worker; |
| @@ -1488,9 +1488,6 @@ static int dasd_eckd_pe_handler(struct dasd_device *device, · 1 unmodified line | |||
| 1488 | } else { | 1488 | } else { |
| 1489 | return -ENOMEM; | 1489 | return -ENOMEM; |
| 1490 | } | 1490 | } |
| 1491 | } else { | ||
| 1492 | memset(data, 0, sizeof(*data)); | ||
| 1493 | data->isglobal = 0; | ||
| 1494 | } | 1491 | } |
| 1495 | INIT_WORK(&data->worker, do_pe_handler_work); | 1492 | INIT_WORK(&data->worker, do_pe_handler_work); |
| 1496 | dasd_get_device(device); | 1493 | dasd_get_device(device); |
| @@ -3083,13 +3080,24 @@ static int dasd_eckd_format_device(struct dasd_device *base, · 1586 unmodified lines | |||
| 3083 | } | 3080 | } |
| 3084 | 3081 | ||
| 3085 | static bool test_and_set_format_track(struct dasd_format_entry *to_format, | 3082 | static bool test_and_set_format_track(struct dasd_format_entry *to_format, |
| 3086 | struct dasd_block *block) | 3083 | struct dasd_ccw_req *cqr) |
| 3087 | { | 3084 | { |
| 3085 | struct dasd_block *block = cqr->block; | ||
| 3088 | struct dasd_format_entry *format; | 3086 | struct dasd_format_entry *format; |
| 3089 | unsigned long flags; | 3087 | unsigned long flags; |
| 3090 | bool rc = false; | 3088 | bool rc = false; |
| 3091 | 3089 | ||
| 3092 | spin_lock_irqsave(&block->format_lock, flags); | 3090 | spin_lock_irqsave(&block->format_lock, flags); |
| 3091 | if (cqr->trkcount != atomic_read(&block->trkcount)) { | ||
| 3092 | /* | ||
| 3093 | * The number of formatted tracks has changed after request | ||
| 3094 | * start and we can not tell if the current track was involved. | ||
| 3095 | * To avoid data corruption treat it as if the current track is | ||
| 3096 | * involved | ||
| 3097 | */ | ||
| 3098 | rc = true; | ||
| 3099 | goto out; | ||
| 3100 | } | ||
| 3093 | list_for_each_entry(format, &block->format_list, list) { | 3101 | list_for_each_entry(format, &block->format_list, list) { |
| 3094 | if (format->track == to_format->track) { | 3102 | if (format->track == to_format->track) { |
| 3095 | rc = true; | 3103 | rc = true; |
| @@ -3109,6 +3117,7 @@ static void clear_format_track(struct dasd_format_entry *format, · 13 unmodified lines | |||
| 3109 | unsigned long flags; | 3117 | unsigned long flags; |
| 3110 | 3118 | ||
| 3111 | spin_lock_irqsave(&block->format_lock, flags); | 3119 | spin_lock_irqsave(&block->format_lock, flags); |
| 3120 | atomic_inc(&block->trkcount); | ||
| 3112 | list_del_init(&format->list); | 3121 | list_del_init(&format->list); |
| 3113 | spin_unlock_irqrestore(&block->format_lock, flags); | 3122 | spin_unlock_irqrestore(&block->format_lock, flags); |
| 3114 | } | 3123 | } |
| @@ -3145,7 +3154,7 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr, · 30 unmodified lines | |||
| 3145 | sector_t curr_trk; | 3154 | sector_t curr_trk; |
| 3146 | int rc; | 3155 | int rc; |
| 3147 | 3156 | ||
| 3148 | req = cqr->callback_data; | 3157 | req = dasd_get_callback_data(cqr); |
| 3149 | block = cqr->block; | 3158 | block = cqr->block; |
| 3150 | base = block->base; | 3159 | base = block->base; |
| 3151 | private = base->private; | 3160 | private = base->private; |
| @@ -3170,8 +3179,11 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr, · 18 unmodified lines | |||
| 3170 | } | 3179 | } |
| 3171 | format->track = curr_trk; | 3180 | format->track = curr_trk; |
| 3172 | /* test if track is already in formatting by another thread */ | 3181 | /* test if track is already in formatting by another thread */ |
| 3173 | if (test_and_set_format_track(format, block)) | 3182 | if (test_and_set_format_track(format, cqr)) { |
| 3183 | /* this is no real error so do not count down retries */ | ||
| 3184 | cqr->retries++; | ||
| 3174 | return ERR_PTR(-EEXIST); | 3185 | return ERR_PTR(-EEXIST); |
| 3186 | } | ||
| 3175 | 3187 | ||
| 3176 | fdata.start_unit = curr_trk; | 3188 | fdata.start_unit = curr_trk; |
| 3177 | fdata.stop_unit = curr_trk; | 3189 | fdata.stop_unit = curr_trk; |
| @@ -3270,12 +3282,11 @@ static int dasd_eckd_ese_read(struct dasd_ccw_req *cqr, struct irb *irb) · 92 unmodified lines | |||
| 3270 | cqr->proc_bytes = blk_count * blksize; | 3282 | cqr->proc_bytes = blk_count * blksize; |
| 3271 | return 0; | 3283 | return 0; |
| 3272 | } | 3284 | } |
| 3273 | if (dst && !skip_block) { | 3285 | if (dst && !skip_block) |
| 3274 | dst += off; | ||
| 3275 | memset(dst, 0, blksize); | 3286 | memset(dst, 0, blksize); |
| 3276 | } else { | 3287 | else |
| 3277 | skip_block--; | 3288 | skip_block--; |
| 3278 | } | 3289 | dst += blksize; |
| 3279 | blk_count++; | 3290 | blk_count++; |
| 3280 | } | 3291 | } |
| 3281 | } | 3292 | } |
| @@ -187,6 +187,7 @@ struct dasd_ccw_req { · 186 unmodified lines | |||
| 187 | void (*callback)(struct dasd_ccw_req *, void *data); | 187 | void (*callback)(struct dasd_ccw_req *, void *data); |
| 188 | void *callback_data; | 188 | void *callback_data; |
| 189 | unsigned int proc_bytes; /* bytes for partial completion */ | 189 | unsigned int proc_bytes; /* bytes for partial completion */ |
| 190 | unsigned int trkcount; /* count formatted tracks */ | ||
| 190 | }; | 191 | }; |
| 191 | 192 | ||
| 192 | /* | 193 | /* |
| @@ -610,6 +611,7 @@ struct dasd_block { · 417 unmodified lines | |||
| 610 | 611 | ||
| 611 | struct list_head format_list; | 612 | struct list_head format_list; |
| 612 | spinlock_t format_lock; | 613 | spinlock_t format_lock; |
| 614 | atomic_t trkcount; | ||
| 613 | }; | 615 | }; |
| 614 | 616 | ||
| 615 | struct dasd_attention_data { | 617 | struct dasd_attention_data { |
| @@ -756,6 +758,18 @@ dasd_check_blocksize(int bsize) · 140 unmodified lines | |||
| 756 | return 0; | 758 | return 0; |
| 757 | } | 759 | } |
| 758 | 760 | ||
| 761 | /* | ||
| 762 | * return the callback data of the original request in case there are | ||
| 763 | * ERP requests build on top of it | ||
| 764 | */ | ||
| 765 | static inline void *dasd_get_callback_data(struct dasd_ccw_req *cqr) | ||
| 766 | { | ||
| 767 | while (cqr->refers) | ||
| 768 | cqr = cqr->refers; | ||
| 769 | |||
| 770 | return cqr->callback_data; | ||
| 771 | } | ||
| 772 | |||
| 759 | /* externals in dasd.c */ | 773 | /* externals in dasd.c */ |
| 760 | #define DASD_PROFILE_OFF 0 | 774 | #define DASD_PROFILE_OFF 0 |
| 761 | #define DASD_PROFILE_ON 1 | 775 | #define DASD_PROFILE_ON 1 |
| @@ -626,8 +626,6 @@ static void mpc_rcvd_sweep_resp(struct mpcg_info *mpcginfo) · 625 unmodified lines | |||
| 626 | ctcm_clear_busy_do(dev); | 626 | ctcm_clear_busy_do(dev); |
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | kfree(mpcginfo); | ||
| 630 | |||
| 631 | return; | 629 | return; |
| 632 | 630 | ||
| 633 | } | 631 | } |
| @@ -1192,10 +1190,10 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb) · 558 unmodified lines | |||
| 1192 | CTCM_FUNTAIL, dev->name); | 1190 | CTCM_FUNTAIL, dev->name); |
| 1193 | priv->stats.rx_dropped++; | 1191 | priv->stats.rx_dropped++; |
| 1194 | /* mpcginfo only used for non-data transfers */ | 1192 | /* mpcginfo only used for non-data transfers */ |
| 1195 | kfree(mpcginfo); | ||
| 1196 | if (do_debug_data) | 1193 | if (do_debug_data) |
| 1197 | ctcmpc_dump_skb(pskb, -8); | 1194 | ctcmpc_dump_skb(pskb, -8); |
| 1198 | } | 1195 | } |
| 1196 | kfree(mpcginfo); | ||
| 1199 | } | 1197 | } |
| 1200 | done: | 1198 | done: |
| 1201 | 1199 | ||
| @@ -1977,7 +1975,6 @@ static void mpc_action_rcvd_xid0(fsm_instance *fsm, int event, void *arg) · 775 unmodified lines | |||
| 1977 | } | 1975 | } |
| 1978 | break; | 1976 | break; |
| 1979 | } | 1977 | } |
| 1980 | kfree(mpcginfo); | ||
| 1981 | 1978 | ||
| 1982 | CTCM_PR_DEBUG("ctcmpc:%s() %s xid2:%i xid7:%i xidt_p2:%i \n", | 1979 | CTCM_PR_DEBUG("ctcmpc:%s() %s xid2:%i xid7:%i xidt_p2:%i \n", |
| 1983 | __func__, ch->id, grp->outstanding_xid2, | 1980 | __func__, ch->id, grp->outstanding_xid2, |
| @@ -2038,7 +2035,6 @@ static void mpc_action_rcvd_xid7(fsm_instance *fsm, int event, void *arg) · 54 unmodified lines | |||
| 2038 | mpc_validate_xid(mpcginfo); | 2035 | mpc_validate_xid(mpcginfo); |
| 2039 | break; | 2036 | break; |
| 2040 | } | 2037 | } |
| 2041 | kfree(mpcginfo); | ||
| 2042 | return; | 2038 | return; |
| 2043 | } | 2039 | } |
| 2044 | 2040 | ||
| @@ -39,11 +39,12 @@ static ssize_t ctcm_buffer_write(struct device *dev, · 38 unmodified lines | |||
| 39 | struct ctcm_priv *priv = dev_get_drvdata(dev); | 39 | struct ctcm_priv *priv = dev_get_drvdata(dev); |
| 40 | int rc; | 40 | int rc; |
| 41 | 41 | ||
| 42 | ndev = priv->channel[CTCM_READ]->netdev; | 42 | if (!(priv && priv->channel[CTCM_READ] && |
| 43 | if (!(priv && priv->channel[CTCM_READ] && ndev)) { | 43 | priv->channel[CTCM_READ]->netdev)) { |
| 44 | CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, "bfnondev"); | 44 | CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, "bfnondev"); |
| 45 | return -ENODEV; | 45 | return -ENODEV; |
| 46 | } | 46 | } |
| 47 | ndev = priv->channel[CTCM_READ]->netdev; | ||
| 47 | 48 | ||
| 48 | rc = kstrtouint(buf, 0, &bs1); | 49 | rc = kstrtouint(buf, 0, &bs1); |
| 49 | if (rc) | 50 | if (rc) |
| @@ -1736,10 +1736,11 @@ lcs_get_control(struct lcs_card *card, struct lcs_cmd *cmd) · 1735 unmodified lines | |||
| 1736 | lcs_schedule_recovery(card); | 1736 | lcs_schedule_recovery(card); |
| 1737 | break; | 1737 | break; |
| 1738 | case LCS_CMD_STOPLAN: | 1738 | case LCS_CMD_STOPLAN: |
| 1739 | pr_warn("Stoplan for %s initiated by LGW\n", | 1739 | if (card->dev) { |
| 1740 | card->dev->name); | 1740 | pr_warn("Stoplan for %s initiated by LGW\n", |
| 1741 | if (card->dev) | 1741 | card->dev->name); |
| 1742 | netif_carrier_off(card->dev); | 1742 | netif_carrier_off(card->dev); |
| 1743 | } | ||
| 1743 | break; | 1744 | break; |
| 1744 | default: | 1745 | default: |
| 1745 | LCS_DBF_TEXT(5, trace, "noLGWcmd"); | 1746 | LCS_DBF_TEXT(5, trace, "noLGWcmd"); |
| @@ -1172,9 +1172,8 @@ static blk_status_t alua_prep_fn(struct scsi_device *sdev, struct request *req) · 1171 unmodified lines | |||
| 1172 | case SCSI_ACCESS_STATE_OPTIMAL: | 1172 | case SCSI_ACCESS_STATE_OPTIMAL: |
| 1173 | case SCSI_ACCESS_STATE_ACTIVE: | 1173 | case SCSI_ACCESS_STATE_ACTIVE: |
| 1174 | case SCSI_ACCESS_STATE_LBA: | 1174 | case SCSI_ACCESS_STATE_LBA: |
| 1175 | return BLK_STS_OK; | ||
| 1176 | case SCSI_ACCESS_STATE_TRANSITIONING: | 1175 | case SCSI_ACCESS_STATE_TRANSITIONING: |
| 1177 | return BLK_STS_AGAIN; | 1176 | return BLK_STS_OK; |
| 1178 | default: | 1177 | default: |
| 1179 | req->rq_flags |= RQF_QUIET; | 1178 | req->rq_flags |= RQF_QUIET; |
| 1180 | return BLK_STS_IOERR; | 1179 | return BLK_STS_IOERR; |
| @@ -1330,7 +1330,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, · 1329 unmodified lines | |||
| 1330 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == | 1330 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == |
| 1331 | LPFC_SLI_INTF_IF_TYPE_0) { | 1331 | LPFC_SLI_INTF_IF_TYPE_0) { |
| 1332 | /* FLOGI needs to be 3 for WQE FCFI */ | 1332 | /* FLOGI needs to be 3 for WQE FCFI */ |
| 1333 | ct = ((SLI4_CT_FCFI >> 1) & 1) | (SLI4_CT_FCFI & 1); | 1333 | ct = SLI4_CT_FCFI; |
| 1334 | bf_set(wqe_ct, &wqe->els_req.wqe_com, ct); | 1334 | bf_set(wqe_ct, &wqe->els_req.wqe_com, ct); |
| 1335 | 1335 | ||
| 1336 | /* Set the fcfi to the fcfi we registered with */ | 1336 | /* Set the fcfi to the fcfi we registered with */ |
| @@ -10720,10 +10720,10 @@ __lpfc_sli_prep_gen_req_s4(struct lpfc_iocbq *cmdiocbq, struct lpfc_dmabuf *bmp, · 10719 unmodified lines | |||
| 10720 | 10720 | ||
| 10721 | /* Words 0 - 2 */ | 10721 | /* Words 0 - 2 */ |
| 10722 | bde = (struct ulp_bde64_le *)&cmdwqe->generic.bde; | 10722 | bde = (struct ulp_bde64_le *)&cmdwqe->generic.bde; |
| 10723 | bde->addr_low = cpu_to_le32(putPaddrLow(bmp->phys)); | 10723 | bde->addr_low = bpl->addr_low; |
| 10724 | bde->addr_high = cpu_to_le32(putPaddrHigh(bmp->phys)); | 10724 | bde->addr_high = bpl->addr_high; |
| 10725 | bde->type_size = cpu_to_le32(xmit_len); | 10725 | bde->type_size = cpu_to_le32(xmit_len); |
| 10726 | bde->type_size |= cpu_to_le32(ULP_BDE64_TYPE_BLP_64); | 10726 | bde->type_size |= cpu_to_le32(ULP_BDE64_TYPE_BDE_64); |
| 10727 | 10727 | ||
| 10728 | /* Word 3 */ | 10728 | /* Word 3 */ |
| 10729 | cmdwqe->gen_req.request_payload_len = xmit_len; | 10729 | cmdwqe->gen_req.request_payload_len = xmit_len; |
| @@ -3826,6 +3826,9 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd) · 3825 unmodified lines | |||
| 3826 | 3826 | ||
| 3827 | spin_lock_irqsave(&cmd->cmd_lock, flags); | 3827 | spin_lock_irqsave(&cmd->cmd_lock, flags); |
| 3828 | if (cmd->aborted) { | 3828 | if (cmd->aborted) { |
| 3829 | if (cmd->sg_mapped) | ||
| 3830 | qlt_unmap_sg(vha, cmd); | ||
| 3831 | |||
| 3829 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | 3832 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); |
| 3830 | /* | 3833 | /* |
| 3831 | * It's normal to see 2 calls in this path: | 3834 | * It's normal to see 2 calls in this path: |
| @@ -510,9 +510,9 @@ static int qcom_slim_probe(struct platform_device *pdev) · 509 unmodified lines | |||
| 510 | } | 510 | } |
| 511 | 511 | ||
| 512 | ctrl->irq = platform_get_irq(pdev, 0); | 512 | ctrl->irq = platform_get_irq(pdev, 0); |
| 513 | if (!ctrl->irq) { | 513 | if (ctrl->irq < 0) { |
| 514 | dev_err(&pdev->dev, "no slimbus IRQ\n"); | 514 | dev_err(&pdev->dev, "no slimbus IRQ\n"); |
| 515 | return -ENODEV; | 515 | return ctrl->irq; |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | sctrl = &ctrl->ctrl; | 518 | sctrl = &ctrl->ctrl; |
| @@ -50,7 +50,7 @@ struct imx8m_blk_ctrl_domain_data { · 49 unmodified lines | |||
| 50 | u32 mipi_phy_rst_mask; | 50 | u32 mipi_phy_rst_mask; |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | #define DOMAIN_MAX_CLKS 3 | 53 | #define DOMAIN_MAX_CLKS 4 |
| 54 | 54 | ||
| 55 | struct imx8m_blk_ctrl_domain { | 55 | struct imx8m_blk_ctrl_domain { |
| 56 | struct generic_pm_domain genpd; | 56 | struct generic_pm_domain genpd; |
| @@ -588,7 +588,7 @@ static void pscsi_destroy_device(struct se_device *dev) · 587 unmodified lines | |||
| 588 | } | 588 | } |
| 589 | 589 | ||
| 590 | static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status, | 590 | static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status, |
| 591 | unsigned char *req_sense) | 591 | unsigned char *req_sense, int valid_data) |
| 592 | { | 592 | { |
| 593 | struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev); | 593 | struct pscsi_dev_virt *pdv = PSCSI_DEV(cmd->se_dev); |
| 594 | struct scsi_device *sd = pdv->pdv_sd; | 594 | struct scsi_device *sd = pdv->pdv_sd; |
| @@ -681,7 +681,7 @@ after_mode_select: · 86 unmodified lines | |||
| 681 | * back despite framework assumption that a | 681 | * back despite framework assumption that a |
| 682 | * check condition means there is no data | 682 | * check condition means there is no data |
| 683 | */ | 683 | */ |
| 684 | if (sd->type == TYPE_TAPE && | 684 | if (sd->type == TYPE_TAPE && valid_data && |
| 685 | cmd->data_direction == DMA_FROM_DEVICE) { | 685 | cmd->data_direction == DMA_FROM_DEVICE) { |
| 686 | /* | 686 | /* |
| 687 | * is sense data valid, fixed format, | 687 | * is sense data valid, fixed format, |
| @@ -1032,6 +1032,7 @@ static void pscsi_req_done(struct request *req, blk_status_t status) · 344 unmodified lines | |||
| 1032 | struct se_cmd *cmd = req->end_io_data; | 1032 | struct se_cmd *cmd = req->end_io_data; |
| 1033 | struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req); | 1033 | struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req); |
| 1034 | enum sam_status scsi_status = scmd->result & 0xff; | 1034 | enum sam_status scsi_status = scmd->result & 0xff; |
| 1035 | int valid_data = cmd->data_length - scmd->resid_len; | ||
| 1035 | u8 *cdb = cmd->priv; | 1036 | u8 *cdb = cmd->priv; |
| 1036 | 1037 | ||
| 1037 | if (scsi_status != SAM_STAT_GOOD) { | 1038 | if (scsi_status != SAM_STAT_GOOD) { |
| @@ -1039,12 +1040,11 @@ static void pscsi_req_done(struct request *req, blk_status_t status) · 1 unmodified line | |||
| 1039 | " 0x%02x Result: 0x%08x\n", cmd, cdb[0], scmd->result); | 1040 | " 0x%02x Result: 0x%08x\n", cmd, cdb[0], scmd->result); |
| 1040 | } | 1041 | } |
| 1041 | 1042 | ||
| 1042 | pscsi_complete_cmd(cmd, scsi_status, scmd->sense_buffer); | 1043 | pscsi_complete_cmd(cmd, scsi_status, scmd->sense_buffer, valid_data); |
| 1043 | 1044 | ||
| 1044 | switch (host_byte(scmd->result)) { | 1045 | switch (host_byte(scmd->result)) { |
| 1045 | case DID_OK: | 1046 | case DID_OK: |
| 1046 | target_complete_cmd_with_length(cmd, scsi_status, | 1047 | target_complete_cmd_with_length(cmd, scsi_status, valid_data); |
| 1047 | cmd->data_length - scmd->resid_len); | ||
| 1048 | break; | 1048 | break; |
| 1049 | default: | 1049 | default: |
| 1050 | pr_debug("PSCSI Host Byte exception at cmd: %p CDB:" | 1050 | pr_debug("PSCSI Host Byte exception at cmd: %p CDB:" |
| @@ -865,6 +865,7 @@ err_rhashtable_free: · 864 unmodified lines | |||
| 865 | rhashtable_free_and_destroy(&optee->ffa.global_ids, rh_free_fn, NULL); | 865 | rhashtable_free_and_destroy(&optee->ffa.global_ids, rh_free_fn, NULL); |
| 866 | optee_supp_uninit(&optee->supp); | 866 | optee_supp_uninit(&optee->supp); |
| 867 | mutex_destroy(&optee->call_queue.mutex); | 867 | mutex_destroy(&optee->call_queue.mutex); |
| 868 | mutex_destroy(&optee->ffa.mutex); | ||
| 868 | err_unreg_supp_teedev: | 869 | err_unreg_supp_teedev: |
| 869 | tee_device_unregister(optee->supp_teedev); | 870 | tee_device_unregister(optee->supp_teedev); |
| 870 | err_unreg_teedev: | 871 | err_unreg_teedev: |
| @@ -113,8 +113,10 @@ config THERMAL_DEFAULT_GOV_USER_SPACE · 112 unmodified lines | |||
| 113 | bool "user_space" | 113 | bool "user_space" |
| 114 | select THERMAL_GOV_USER_SPACE | 114 | select THERMAL_GOV_USER_SPACE |
| 115 | help | 115 | help |
| 116 | Select this if you want to let the user space manage the | 116 | The Userspace governor allows to get trip point crossed |
| 117 | platform thermals. | 117 | notification from the kernel via uevents. It is recommended |
| 118 | to use the netlink interface instead which gives richer | ||
| 119 | information about the thermal framework events. | ||
| 118 | 120 | ||
| 119 | config THERMAL_DEFAULT_GOV_POWER_ALLOCATOR | 121 | config THERMAL_DEFAULT_GOV_POWER_ALLOCATOR |
| 120 | bool "power_allocator" | 122 | bool "power_allocator" |
| @@ -17,8 +17,7 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | static int user_space_bind(struct thermal_zone_device *tz) | 18 | static int user_space_bind(struct thermal_zone_device *tz) |
| 19 | { | 19 | { |
| 20 | pr_warn_once("Userspace governor deprecated: use thermal netlink " \ | 20 | pr_info_once("Consider using thermal netlink events interface\n"); |
| 21 | "notification instead\n"); | ||
| 22 | 21 | ||
| 23 | return 0; | 22 | return 0; |
| 24 | } | 23 | } |
| @@ -68,7 +68,7 @@ static int evaluate_odvp(struct int3400_thermal_priv *priv); · 67 unmodified lines | |||
| 68 | struct odvp_attr { | 68 | struct odvp_attr { |
| 69 | int odvp; | 69 | int odvp; |
| 70 | struct int3400_thermal_priv *priv; | 70 | struct int3400_thermal_priv *priv; |
| 71 | struct kobj_attribute attr; | 71 | struct device_attribute attr; |
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | static ssize_t data_vault_read(struct file *file, struct kobject *kobj, | 74 | static ssize_t data_vault_read(struct file *file, struct kobject *kobj, |
| @@ -311,7 +311,7 @@ end: · 236 unmodified lines | |||
| 311 | return result; | 311 | return result; |
| 312 | } | 312 | } |
| 313 | 313 | ||
| 314 | static ssize_t odvp_show(struct kobject *kobj, struct kobj_attribute *attr, | 314 | static ssize_t odvp_show(struct device *dev, struct device_attribute *attr, |
| 315 | char *buf) | 315 | char *buf) |
| 316 | { | 316 | { |
| 317 | struct odvp_attr *odvp_attr; | 317 | struct odvp_attr *odvp_attr; |
| @@ -610,9 +610,6 @@ cur_state_store(struct device *dev, struct device_attribute *attr, · 609 unmodified lines | |||
| 610 | unsigned long state; | 610 | unsigned long state; |
| 611 | int result; | 611 | int result; |
| 612 | 612 | ||
| 613 | dev_warn_once(&cdev->device, | ||
| 614 | "Setting cooling device state is deprecated\n"); | ||
| 615 | |||
| 616 | if (sscanf(buf, "%ld\n", &state) != 1) | 613 | if (sscanf(buf, "%ld\n", &state) != 1) |
| 617 | return -EINVAL; | 614 | return -EINVAL; |
| 618 | 615 | ||
| @@ -7,9 +7,7 @@ · 6 unmodified lines | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/device.h> | 9 | #include <linux/device.h> |
| 10 | #include <linux/dmar.h> | ||
| 11 | #include <linux/idr.h> | 10 | #include <linux/idr.h> |
| 12 | #include <linux/iommu.h> | ||
| 13 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 14 | #include <linux/pm_runtime.h> | 12 | #include <linux/pm_runtime.h> |
| 15 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| @@ -257,13 +255,9 @@ static ssize_t iommu_dma_protection_show(struct device *dev, · 241 unmodified lines | |||
| 257 | struct device_attribute *attr, | 255 | struct device_attribute *attr, |
| 258 | char *buf) | 256 | char *buf) |
| 259 | { | 257 | { |
| 260 | /* | 258 | struct tb *tb = container_of(dev, struct tb, dev); |
| 261 | * Kernel DMA protection is a feature where Thunderbolt security is | 259 | |
| 262 | * handled natively using IOMMU. It is enabled when IOMMU is | 260 | return sysfs_emit(buf, "%d\n", tb->nhi->iommu_dma_protection); |
| 263 | * enabled and ACPI DMAR table has DMAR_PLATFORM_OPT_IN set. | ||
| 264 | */ | ||
| 265 | return sprintf(buf, "%d\n", | ||
| 266 | iommu_present(&pci_bus_type) && dmar_platform_optin()); | ||
| 267 | } | 261 | } |
| 268 | static DEVICE_ATTR_RO(iommu_dma_protection); | 262 | static DEVICE_ATTR_RO(iommu_dma_protection); |
| 269 | 263 | ||
| @@ -15,9 +15,11 @@ · 14 unmodified lines | |||
| 15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
| 16 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/iommu.h> | ||
| 18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 19 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
| 20 | #include <linux/property.h> | 21 | #include <linux/property.h> |
| 22 | #include <linux/string_helpers.h> | ||
| 21 | 23 | ||
| 22 | #include "nhi.h" | 24 | #include "nhi.h" |
| 23 | #include "nhi_regs.h" | 25 | #include "nhi_regs.h" |
| @@ -1103,6 +1105,47 @@ static void nhi_check_quirks(struct tb_nhi *nhi) · 1079 unmodified lines | |||
| 1103 | nhi->quirks |= QUIRK_AUTO_CLEAR_INT; | 1105 | nhi->quirks |= QUIRK_AUTO_CLEAR_INT; |
| 1104 | } | 1106 | } |
| 1105 | 1107 | ||
| 1108 | static int nhi_check_iommu_pdev(struct pci_dev *pdev, void *data) | ||
| 1109 | { | ||
| 1110 | if (!pdev->external_facing || | ||
| 1111 | !device_iommu_capable(&pdev->dev, IOMMU_CAP_PRE_BOOT_PROTECTION)) | ||
| 1112 | return 0; | ||
| 1113 | *(bool *)data = true; | ||
| 1114 | return 1; /* Stop walking */ | ||
| 1115 | } | ||
| 1116 | |||
| 1117 | static void nhi_check_iommu(struct tb_nhi *nhi) | ||
| 1118 | { | ||
| 1119 | struct pci_bus *bus = nhi->pdev->bus; | ||
| 1120 | bool port_ok = false; | ||
| 1121 | |||
| 1122 | /* | ||
| 1123 | * Ideally what we'd do here is grab every PCI device that | ||
| 1124 | * represents a tunnelling adapter for this NHI and check their | ||
| 1125 | * status directly, but unfortunately USB4 seems to make it | ||
| 1126 | * obnoxiously difficult to reliably make any correlation. | ||
| 1127 | * | ||
| 1128 | * So for now we'll have to bodge it... Hoping that the system | ||
| 1129 | * is at least sane enough that an adapter is in the same PCI | ||
| 1130 | * segment as its NHI, if we can find *something* on that segment | ||
| 1131 | * which meets the requirements for Kernel DMA Protection, we'll | ||
| 1132 | * take that to imply that firmware is aware and has (hopefully) | ||
| 1133 | * done the right thing in general. We need to know that the PCI | ||
| 1134 | * layer has seen the ExternalFacingPort property which will then | ||
| 1135 | * inform the IOMMU layer to enforce the complete "untrusted DMA" | ||
| 1136 | * flow, but also that the IOMMU driver itself can be trusted not | ||
| 1137 | * to have been subverted by a pre-boot DMA attack. | ||
| 1138 | */ | ||
| 1139 | while (bus->parent) | ||
| 1140 | bus = bus->parent; | ||
| 1141 | |||
| 1142 | pci_walk_bus(bus, nhi_check_iommu_pdev, &port_ok); | ||
| 1143 | |||
| 1144 | nhi->iommu_dma_protection = port_ok; | ||
| 1145 | dev_dbg(&nhi->pdev->dev, "IOMMU DMA protection is %s\n", | ||
| 1146 | str_enabled_disabled(port_ok)); | ||
| 1147 | } | ||
| 1148 | |||
| 1106 | static int nhi_init_msi(struct tb_nhi *nhi) | 1149 | static int nhi_init_msi(struct tb_nhi *nhi) |
| 1107 | { | 1150 | { |
| 1108 | struct pci_dev *pdev = nhi->pdev; | 1151 | struct pci_dev *pdev = nhi->pdev; |
| @@ -1220,6 +1263,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 111 unmodified lines | |||
| 1220 | return -ENOMEM; | 1263 | return -ENOMEM; |
| 1221 | 1264 | ||
| 1222 | nhi_check_quirks(nhi); | 1265 | nhi_check_quirks(nhi); |
| 1266 | nhi_check_iommu(nhi); | ||
| 1223 | 1267 | ||
| 1224 | res = nhi_init_msi(nhi); | 1268 | res = nhi_init_msi(nhi); |
| 1225 | if (res) { | 1269 | if (res) { |
| @@ -73,6 +73,8 @@ module_param(debug, int, 0600); · 72 unmodified lines | |||
| 73 | */ | 73 | */ |
| 74 | #define MAX_MRU 1500 | 74 | #define MAX_MRU 1500 |
| 75 | #define MAX_MTU 1500 | 75 | #define MAX_MTU 1500 |
| 76 | /* SOF, ADDR, CTRL, LEN1, LEN2, ..., FCS, EOF */ | ||
| 77 | #define PROT_OVERHEAD 7 | ||
| 76 | #define GSM_NET_TX_TIMEOUT (HZ*10) | 78 | #define GSM_NET_TX_TIMEOUT (HZ*10) |
| 77 | 79 | ||
| 78 | /* | 80 | /* |
| @@ -135,6 +137,7 @@ struct gsm_dlci { · 56 unmodified lines | |||
| 135 | int retries; | 137 | int retries; |
| 136 | /* Uplink tty if active */ | 138 | /* Uplink tty if active */ |
| 137 | struct tty_port port; /* The tty bound to this DLCI if there is one */ | 139 | struct tty_port port; /* The tty bound to this DLCI if there is one */ |
| 140 | #define TX_SIZE 4096 /* Must be power of 2. */ | ||
| 138 | struct kfifo fifo; /* Queue fifo for the DLCI */ | 141 | struct kfifo fifo; /* Queue fifo for the DLCI */ |
| 139 | int adaption; /* Adaption layer in use */ | 142 | int adaption; /* Adaption layer in use */ |
| 140 | int prev_adaption; | 143 | int prev_adaption; |
| @@ -219,7 +222,6 @@ struct gsm_mux { · 78 unmodified lines | |||
| 219 | int encoding; | 222 | int encoding; |
| 220 | u8 control; | 223 | u8 control; |
| 221 | u8 fcs; | 224 | u8 fcs; |
| 222 | u8 received_fcs; | ||
| 223 | u8 *txframe; /* TX framing buffer */ | 225 | u8 *txframe; /* TX framing buffer */ |
| 224 | 226 | ||
| 225 | /* Method for the receiver side */ | 227 | /* Method for the receiver side */ |
| @@ -231,6 +233,7 @@ struct gsm_mux { · 5 unmodified lines | |||
| 231 | int initiator; /* Did we initiate connection */ | 233 | int initiator; /* Did we initiate connection */ |
| 232 | bool dead; /* Has the mux been shut down */ | 234 | bool dead; /* Has the mux been shut down */ |
| 233 | struct gsm_dlci *dlci[NUM_DLCI]; | 235 | struct gsm_dlci *dlci[NUM_DLCI]; |
| 236 | int old_c_iflag; /* termios c_iflag value before attach */ | ||
| 234 | bool constipated; /* Asked by remote to shut up */ | 237 | bool constipated; /* Asked by remote to shut up */ |
| 235 | 238 | ||
| 236 | spinlock_t tx_lock; | 239 | spinlock_t tx_lock; |
| @@ -271,10 +274,6 @@ static DEFINE_SPINLOCK(gsm_mux_lock); · 34 unmodified lines | |||
| 271 | 274 | ||
| 272 | static struct tty_driver *gsm_tty_driver; | 275 | static struct tty_driver *gsm_tty_driver; |
| 273 | 276 | ||
| 274 | /* Save dlci open address */ | ||
| 275 | static int addr_open[256] = { 0 }; | ||
| 276 | /* Save dlci open count */ | ||
| 277 | static int addr_cnt; | ||
| 278 | /* | 277 | /* |
| 279 | * This section of the driver logic implements the GSM encodings | 278 | * This section of the driver logic implements the GSM encodings |
| 280 | * both the basic and the 'advanced'. Reliable transport is not | 279 | * both the basic and the 'advanced'. Reliable transport is not |
| @@ -369,6 +368,7 @@ static const u8 gsm_fcs8[256] = { · 88 unmodified lines | |||
| 369 | #define GOOD_FCS 0xCF | 368 | #define GOOD_FCS 0xCF |
| 370 | 369 | ||
| 371 | static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len); | 370 | static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len); |
| 371 | static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk); | ||
| 372 | 372 | ||
| 373 | /** | 373 | /** |
| 374 | * gsm_fcs_add - update FCS | 374 | * gsm_fcs_add - update FCS |
| @@ -832,7 +832,7 @@ static int gsm_dlci_data_output(struct gsm_mux *gsm, struct gsm_dlci *dlci) · 457 unmodified lines | |||
| 832 | break; | 832 | break; |
| 833 | case 2: /* Unstructed with modem bits. | 833 | case 2: /* Unstructed with modem bits. |
| 834 | Always one byte as we never send inline break data */ | 834 | Always one byte as we never send inline break data */ |
| 835 | *dp++ = gsm_encode_modem(dlci); | 835 | *dp++ = (gsm_encode_modem(dlci) << 1) | EA; |
| 836 | break; | 836 | break; |
| 837 | } | 837 | } |
| 838 | WARN_ON(kfifo_out_locked(&dlci->fifo, dp , len, &dlci->lock) != len); | 838 | WARN_ON(kfifo_out_locked(&dlci->fifo, dp , len, &dlci->lock) != len); |
| @@ -916,6 +916,66 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, · 77 unmodified lines | |||
| 916 | return size; | 916 | return size; |
| 917 | } | 917 | } |
| 918 | 918 | ||
| 919 | /** | ||
| 920 | * gsm_dlci_modem_output - try and push modem status out of a DLCI | ||
| 921 | * @gsm: mux | ||
| 922 | * @dlci: the DLCI to pull modem status from | ||
| 923 | * @brk: break signal | ||
| 924 | * | ||
| 925 | * Push an empty frame in to the transmit queue to update the modem status | ||
| 926 | * bits and to transmit an optional break. | ||
| 927 | * | ||
| 928 | * Caller must hold the tx_lock of the mux. | ||
| 929 | */ | ||
| 930 | |||
| 931 | static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci, | ||
| 932 | u8 brk) | ||
| 933 | { | ||
| 934 | u8 *dp = NULL; | ||
| 935 | struct gsm_msg *msg; | ||
| 936 | int size = 0; | ||
| 937 | |||
| 938 | /* for modem bits without break data */ | ||
| 939 | switch (dlci->adaption) { | ||
| 940 | case 1: /* Unstructured */ | ||
| 941 | break; | ||
| 942 | case 2: /* Unstructured with modem bits. */ | ||
| 943 | size++; | ||
| 944 | if (brk > 0) | ||
| 945 | size++; | ||
| 946 | break; | ||
| 947 | default: | ||
| 948 | pr_err("%s: unsupported adaption %d\n", __func__, | ||
| 949 | dlci->adaption); | ||
| 950 | return -EINVAL; | ||
| 951 | } | ||
| 952 | |||
| 953 | msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype); | ||
| 954 | if (!msg) { | ||
| 955 | pr_err("%s: gsm_data_alloc error", __func__); | ||
| 956 | return -ENOMEM; | ||
| 957 | } | ||
| 958 | dp = msg->data; | ||
| 959 | switch (dlci->adaption) { | ||
| 960 | case 1: /* Unstructured */ | ||
| 961 | break; | ||
| 962 | case 2: /* Unstructured with modem bits. */ | ||
| 963 | if (brk == 0) { | ||
| 964 | *dp++ = (gsm_encode_modem(dlci) << 1) | EA; | ||
| 965 | } else { | ||
| 966 | *dp++ = gsm_encode_modem(dlci) << 1; | ||
| 967 | *dp++ = (brk << 4) | 2 | EA; /* Length, Break, EA */ | ||
| 968 | } | ||
| 969 | break; | ||
| 970 | default: | ||
| 971 | /* Handled above */ | ||
| 972 | break; | ||
| 973 | } | ||
| 974 | |||
| 975 | __gsm_data_queue(dlci, msg); | ||
| 976 | return size; | ||
| 977 | } | ||
| 978 | |||
| 919 | /** | 979 | /** |
| 920 | * gsm_dlci_data_sweep - look for data to send | 980 | * gsm_dlci_data_sweep - look for data to send |
| 921 | * @gsm: the GSM mux | 981 | * @gsm: the GSM mux |
| @@ -1093,7 +1153,6 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen) · 171 unmodified lines | |||
| 1093 | { | 1153 | { |
| 1094 | unsigned int addr = 0; | 1154 | unsigned int addr = 0; |
| 1095 | unsigned int modem = 0; | 1155 | unsigned int modem = 0; |
| 1096 | unsigned int brk = 0; | ||
| 1097 | struct gsm_dlci *dlci; | 1156 | struct gsm_dlci *dlci; |
| 1098 | int len = clen; | 1157 | int len = clen; |
| 1099 | int slen; | 1158 | int slen; |
| @@ -1123,17 +1182,8 @@ static void gsm_control_modem(struct gsm_mux *gsm, const u8 *data, int clen) · 23 unmodified lines | |||
| 1123 | return; | 1182 | return; |
| 1124 | } | 1183 | } |
| 1125 | len--; | 1184 | len--; |
| 1126 | if (len > 0) { | ||
| 1127 | while (gsm_read_ea(&brk, *dp++) == 0) { | ||
| 1128 | len--; | ||
| 1129 | if (len == 0) | ||
| 1130 | return; | ||
| 1131 | } | ||
| 1132 | modem <<= 7; | ||
| 1133 | modem |= (brk & 0x7f); | ||
| 1134 | } | ||
| 1135 | tty = tty_port_tty_get(&dlci->port); | 1185 | tty = tty_port_tty_get(&dlci->port); |
| 1136 | gsm_process_modem(tty, dlci, modem, slen); | 1186 | gsm_process_modem(tty, dlci, modem, slen - len); |
| 1137 | if (tty) { | 1187 | if (tty) { |
| 1138 | tty_wakeup(tty); | 1188 | tty_wakeup(tty); |
| 1139 | tty_kref_put(tty); | 1189 | tty_kref_put(tty); |
| @@ -1193,7 +1243,6 @@ static void gsm_control_rls(struct gsm_mux *gsm, const u8 *data, int clen) · 53 unmodified lines | |||
| 1193 | } | 1243 | } |
| 1194 | 1244 | ||
| 1195 | static void gsm_dlci_begin_close(struct gsm_dlci *dlci); | 1245 | static void gsm_dlci_begin_close(struct gsm_dlci *dlci); |
| 1196 | static void gsm_dlci_close(struct gsm_dlci *dlci); | ||
| 1197 | 1246 | ||
| 1198 | /** | 1247 | /** |
| 1199 | * gsm_control_message - DLCI 0 control processing | 1248 | * gsm_control_message - DLCI 0 control processing |
| @@ -1212,28 +1261,15 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, · 12 unmodified lines | |||
| 1212 | { | 1261 | { |
| 1213 | u8 buf[1]; | 1262 | u8 buf[1]; |
| 1214 | unsigned long flags; | 1263 | unsigned long flags; |
| 1215 | struct gsm_dlci *dlci; | ||
| 1216 | int i; | ||
| 1217 | int address; | ||
| 1218 | 1264 | ||
| 1219 | switch (command) { | 1265 | switch (command) { |
| 1220 | case CMD_CLD: { | 1266 | case CMD_CLD: { |
| 1221 | if (addr_cnt > 0) { | 1267 | struct gsm_dlci *dlci = gsm->dlci[0]; |
| 1222 | for (i = 0; i < addr_cnt; i++) { | ||
| 1223 | address = addr_open[i]; | ||
| 1224 | dlci = gsm->dlci[address]; | ||
| 1225 | gsm_dlci_close(dlci); | ||
| 1226 | addr_open[i] = 0; | ||
| 1227 | } | ||
| 1228 | } | ||
| 1229 | /* Modem wishes to close down */ | 1268 | /* Modem wishes to close down */ |
| 1230 | dlci = gsm->dlci[0]; | ||
| 1231 | if (dlci) { | 1269 | if (dlci) { |
| 1232 | dlci->dead = true; | 1270 | dlci->dead = true; |
| 1233 | gsm->dead = true; | 1271 | gsm->dead = true; |
| 1234 | gsm_dlci_close(dlci); | 1272 | gsm_dlci_begin_close(dlci); |
| 1235 | addr_cnt = 0; | ||
| 1236 | gsm_response(gsm, 0, UA|PF); | ||
| 1237 | } | 1273 | } |
| 1238 | } | 1274 | } |
| 1239 | break; | 1275 | break; |
| @@ -1326,11 +1362,12 @@ static void gsm_control_response(struct gsm_mux *gsm, unsigned int command, · 86 unmodified lines | |||
| 1326 | 1362 | ||
| 1327 | static void gsm_control_transmit(struct gsm_mux *gsm, struct gsm_control *ctrl) | 1363 | static void gsm_control_transmit(struct gsm_mux *gsm, struct gsm_control *ctrl) |
| 1328 | { | 1364 | { |
| 1329 | struct gsm_msg *msg = gsm_data_alloc(gsm, 0, ctrl->len + 1, gsm->ftype); | 1365 | struct gsm_msg *msg = gsm_data_alloc(gsm, 0, ctrl->len + 2, gsm->ftype); |
| 1330 | if (msg == NULL) | 1366 | if (msg == NULL) |
| 1331 | return; | 1367 | return; |
| 1332 | msg->data[0] = (ctrl->cmd << 1) | 2 | EA; /* command */ | 1368 | msg->data[0] = (ctrl->cmd << 1) | CR | EA; /* command */ |
| 1333 | memcpy(msg->data + 1, ctrl->data, ctrl->len); | 1369 | msg->data[1] = (ctrl->len << 1) | EA; |
| 1370 | memcpy(msg->data + 2, ctrl->data, ctrl->len); | ||
| 1334 | gsm_data_queue(gsm->dlci[0], msg); | 1371 | gsm_data_queue(gsm->dlci[0], msg); |
| 1335 | } | 1372 | } |
| 1336 | 1373 | ||
| @@ -1353,7 +1390,6 @@ static void gsm_control_retransmit(struct timer_list *t) · 16 unmodified lines | |||
| 1353 | spin_lock_irqsave(&gsm->control_lock, flags); | 1390 | spin_lock_irqsave(&gsm->control_lock, flags); |
| 1354 | ctrl = gsm->pending_cmd; | 1391 | ctrl = gsm->pending_cmd; |
| 1355 | if (ctrl) { | 1392 | if (ctrl) { |
| 1356 | gsm->cretries--; | ||
| 1357 | if (gsm->cretries == 0) { | 1393 | if (gsm->cretries == 0) { |
| 1358 | gsm->pending_cmd = NULL; | 1394 | gsm->pending_cmd = NULL; |
| 1359 | ctrl->error = -ETIMEDOUT; | 1395 | ctrl->error = -ETIMEDOUT; |
| @@ -1362,6 +1398,7 @@ static void gsm_control_retransmit(struct timer_list *t) · 2 unmodified lines | |||
| 1362 | wake_up(&gsm->event); | 1398 | wake_up(&gsm->event); |
| 1363 | return; | 1399 | return; |
| 1364 | } | 1400 | } |
| 1401 | gsm->cretries--; | ||
| 1365 | gsm_control_transmit(gsm, ctrl); | 1402 | gsm_control_transmit(gsm, ctrl); |
| 1366 | mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100); | 1403 | mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100); |
| 1367 | } | 1404 | } |
| @@ -1402,7 +1439,7 @@ retry: · 34 unmodified lines | |||
| 1402 | 1439 | ||
| 1403 | /* If DLCI0 is in ADM mode skip retries, it won't respond */ | 1440 | /* If DLCI0 is in ADM mode skip retries, it won't respond */ |
| 1404 | if (gsm->dlci[0]->mode == DLCI_MODE_ADM) | 1441 | if (gsm->dlci[0]->mode == DLCI_MODE_ADM) |
| 1405 | gsm->cretries = 1; | 1442 | gsm->cretries = 0; |
| 1406 | else | 1443 | else |
| 1407 | gsm->cretries = gsm->n2; | 1444 | gsm->cretries = gsm->n2; |
| 1408 | 1445 | ||
| @@ -1450,20 +1487,22 @@ static int gsm_control_wait(struct gsm_mux *gsm, struct gsm_control *control) · 41 unmodified lines | |||
| 1450 | 1487 | ||
| 1451 | static void gsm_dlci_close(struct gsm_dlci *dlci) | 1488 | static void gsm_dlci_close(struct gsm_dlci *dlci) |
| 1452 | { | 1489 | { |
| 1490 | unsigned long flags; | ||
| 1491 | |||
| 1453 | del_timer(&dlci->t1); | 1492 | del_timer(&dlci->t1); |
| 1454 | if (debug & 8) | 1493 | if (debug & 8) |
| 1455 | pr_debug("DLCI %d goes closed.\n", dlci->addr); | 1494 | pr_debug("DLCI %d goes closed.\n", dlci->addr); |
| 1456 | dlci->state = DLCI_CLOSED; | 1495 | dlci->state = DLCI_CLOSED; |
| 1457 | if (dlci->addr != 0) { | 1496 | if (dlci->addr != 0) { |
| 1458 | tty_port_tty_hangup(&dlci->port, false); | 1497 | tty_port_tty_hangup(&dlci->port, false); |
| 1498 | spin_lock_irqsave(&dlci->lock, flags); | ||
| 1459 | kfifo_reset(&dlci->fifo); | 1499 | kfifo_reset(&dlci->fifo); |
| 1500 | spin_unlock_irqrestore(&dlci->lock, flags); | ||
| 1460 | /* Ensure that gsmtty_open() can return. */ | 1501 | /* Ensure that gsmtty_open() can return. */ |
| 1461 | tty_port_set_initialized(&dlci->port, 0); | 1502 | tty_port_set_initialized(&dlci->port, 0); |
| 1462 | wake_up_interruptible(&dlci->port.open_wait); | 1503 | wake_up_interruptible(&dlci->port.open_wait); |
| 1463 | } else | 1504 | } else |
| 1464 | dlci->gsm->dead = true; | 1505 | dlci->gsm->dead = true; |
| 1465 | /* Unregister gsmtty driver,report gsmtty dev remove uevent for user */ | ||
| 1466 | tty_unregister_device(gsm_tty_driver, dlci->addr); | ||
| 1467 | wake_up(&dlci->gsm->event); | 1506 | wake_up(&dlci->gsm->event); |
| 1468 | /* A DLCI 0 close is a MUX termination so we need to kick that | 1507 | /* A DLCI 0 close is a MUX termination so we need to kick that |
| 1469 | back to userspace somehow */ | 1508 | back to userspace somehow */ |
| @@ -1485,8 +1524,9 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) · 15 unmodified lines | |||
| 1485 | dlci->state = DLCI_OPEN; | 1524 | dlci->state = DLCI_OPEN; |
| 1486 | if (debug & 8) | 1525 | if (debug & 8) |
| 1487 | pr_debug("DLCI %d goes open.\n", dlci->addr); | 1526 | pr_debug("DLCI %d goes open.\n", dlci->addr); |
| 1488 | /* Register gsmtty driver,report gsmtty dev add uevent for user */ | 1527 | /* Send current modem state */ |
| 1489 | tty_register_device(gsm_tty_driver, dlci->addr, NULL); | 1528 | if (dlci->addr) |
| 1529 | gsm_modem_update(dlci, 0); | ||
| 1490 | wake_up(&dlci->gsm->event); | 1530 | wake_up(&dlci->gsm->event); |
| 1491 | } | 1531 | } |
| 1492 | 1532 | ||
| @@ -1619,10 +1659,12 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, const u8 *data, int clen) · 126 unmodified lines | |||
| 1619 | if (len == 0) | 1659 | if (len == 0) |
| 1620 | return; | 1660 | return; |
| 1621 | } | 1661 | } |
| 1662 | len--; | ||
| 1622 | slen++; | 1663 | slen++; |
| 1623 | tty = tty_port_tty_get(port); | 1664 | tty = tty_port_tty_get(port); |
| 1624 | if (tty) { | 1665 | if (tty) { |
| 1625 | gsm_process_modem(tty, dlci, modem, slen); | 1666 | gsm_process_modem(tty, dlci, modem, slen); |
| 1667 | tty_wakeup(tty); | ||
| 1626 | tty_kref_put(tty); | 1668 | tty_kref_put(tty); |
| 1627 | } | 1669 | } |
| 1628 | fallthrough; | 1670 | fallthrough; |
| @@ -1690,7 +1732,7 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) · 61 unmodified lines | |||
| 1690 | return NULL; | 1732 | return NULL; |
| 1691 | spin_lock_init(&dlci->lock); | 1733 | spin_lock_init(&dlci->lock); |
| 1692 | mutex_init(&dlci->mutex); | 1734 | mutex_init(&dlci->mutex); |
| 1693 | if (kfifo_alloc(&dlci->fifo, 4096, GFP_KERNEL) < 0) { | 1735 | if (kfifo_alloc(&dlci->fifo, TX_SIZE, GFP_KERNEL) < 0) { |
| 1694 | kfree(dlci); | 1736 | kfree(dlci); |
| 1695 | return NULL; | 1737 | return NULL; |
| 1696 | } | 1738 | } |
| @@ -1793,19 +1835,7 @@ static void gsm_queue(struct gsm_mux *gsm) · 96 unmodified lines | |||
| 1793 | struct gsm_dlci *dlci; | 1835 | struct gsm_dlci *dlci; |
| 1794 | u8 cr; | 1836 | u8 cr; |
| 1795 | int address; | 1837 | int address; |
| 1796 | int i, j, k, address_tmp; | ||
| 1797 | /* We have to sneak a look at the packet body to do the FCS. | ||
| 1798 | A somewhat layering violation in the spec */ | ||
| 1799 | 1838 | ||
| 1800 | if ((gsm->control & ~PF) == UI) | ||
| 1801 | gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len); | ||
| 1802 | if (gsm->encoding == 0) { | ||
| 1803 | /* WARNING: gsm->received_fcs is used for | ||
| 1804 | gsm->encoding = 0 only. | ||
| 1805 | In this case it contain the last piece of data | ||
| 1806 | required to generate final CRC */ | ||
| 1807 | gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->received_fcs); | ||
| 1808 | } | ||
| 1809 | if (gsm->fcs != GOOD_FCS) { | 1839 | if (gsm->fcs != GOOD_FCS) { |
| 1810 | gsm->bad_fcs++; | 1840 | gsm->bad_fcs++; |
| 1811 | if (debug & 4) | 1841 | if (debug & 4) |
| @@ -1836,11 +1866,6 @@ static void gsm_queue(struct gsm_mux *gsm) · 24 unmodified lines | |||
| 1836 | else { | 1866 | else { |
| 1837 | gsm_response(gsm, address, UA|PF); | 1867 | gsm_response(gsm, address, UA|PF); |
| 1838 | gsm_dlci_open(dlci); | 1868 | gsm_dlci_open(dlci); |
| 1839 | /* Save dlci open address */ | ||
| 1840 | if (address) { | ||
| 1841 | addr_open[addr_cnt] = address; | ||
| 1842 | addr_cnt++; | ||
| 1843 | } | ||
| 1844 | } | 1869 | } |
| 1845 | break; | 1870 | break; |
| 1846 | case DISC|PF: | 1871 | case DISC|PF: |
| @@ -1851,35 +1876,9 @@ static void gsm_queue(struct gsm_mux *gsm) · 4 unmodified lines | |||
| 1851 | return; | 1876 | return; |
| 1852 | } | 1877 | } |
| 1853 | /* Real close complete */ | 1878 | /* Real close complete */ |
| 1854 | if (!address) { | 1879 | gsm_response(gsm, address, UA|PF); |
| 1855 | if (addr_cnt > 0) { | 1880 | gsm_dlci_close(dlci); |
| 1856 | for (i = 0; i < addr_cnt; i++) { | ||
| 1857 | address = addr_open[i]; | ||
| 1858 | dlci = gsm->dlci[address]; | ||
| 1859 | gsm_dlci_close(dlci); | ||
| 1860 | addr_open[i] = 0; | ||
| 1861 | } | ||
| 1862 | } | ||
| 1863 | dlci = gsm->dlci[0]; | ||
| 1864 | gsm_dlci_close(dlci); | ||
| 1865 | addr_cnt = 0; | ||
| 1866 | gsm_response(gsm, 0, UA|PF); | ||
| 1867 | } else { | ||
| 1868 | gsm_response(gsm, address, UA|PF); | ||
| 1869 | gsm_dlci_close(dlci); | ||
| 1870 | /* clear dlci address */ | ||
| 1871 | for (j = 0; j < addr_cnt; j++) { | ||
| 1872 | address_tmp = addr_open[j]; | ||
| 1873 | if (address_tmp == address) { | ||
| 1874 | for (k = j; k < addr_cnt; k++) | ||
| 1875 | addr_open[k] = addr_open[k+1]; | ||
| 1876 | addr_cnt--; | ||
| 1877 | break; | ||
| 1878 | } | ||
| 1879 | } | ||
| 1880 | } | ||
| 1881 | break; | 1881 | break; |
| 1882 | case UA: | ||
| 1883 | case UA|PF: | 1882 | case UA|PF: |
| 1884 | if (cr == 0 || dlci == NULL) | 1883 | if (cr == 0 || dlci == NULL) |
| 1885 | break; | 1884 | break; |
| @@ -1993,19 +1992,25 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) · 107 unmodified lines | |||
| 1993 | break; | 1992 | break; |
| 1994 | case GSM_DATA: /* Data */ | 1993 | case GSM_DATA: /* Data */ |
| 1995 | gsm->buf[gsm->count++] = c; | 1994 | gsm->buf[gsm->count++] = c; |
| 1996 | if (gsm->count == gsm->len) | 1995 | if (gsm->count == gsm->len) { |
| 1996 | /* Calculate final FCS for UI frames over all data */ | ||
| 1997 | if ((gsm->control & ~PF) != UIH) { | ||
| 1998 | gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, | ||
| 1999 | gsm->count); | ||
| 2000 | } | ||
| 1997 | gsm->state = GSM_FCS; | 2001 | gsm->state = GSM_FCS; |
| 2002 | } | ||
| 1998 | break; | 2003 | break; |
| 1999 | case GSM_FCS: /* FCS follows the packet */ | 2004 | case GSM_FCS: /* FCS follows the packet */ |
| 2000 | gsm->received_fcs = c; | 2005 | gsm->fcs = gsm_fcs_add(gsm->fcs, c); |
| 2001 | gsm_queue(gsm); | ||
| 2002 | gsm->state = GSM_SSOF; | 2006 | gsm->state = GSM_SSOF; |
| 2003 | break; | 2007 | break; |
| 2004 | case GSM_SSOF: | 2008 | case GSM_SSOF: |
| 2005 | if (c == GSM0_SOF) { | 2009 | gsm->state = GSM_SEARCH; |
| 2006 | gsm->state = GSM_SEARCH; | 2010 | if (c == GSM0_SOF) |
| 2007 | break; | 2011 | gsm_queue(gsm); |
| 2008 | } | 2012 | else |
| 2013 | gsm->bad_size++; | ||
| 2009 | break; | 2014 | break; |
| 2010 | default: | 2015 | default: |
| 2011 | pr_debug("%s: unhandled state: %d\n", __func__, gsm->state); | 2016 | pr_debug("%s: unhandled state: %d\n", __func__, gsm->state); |
| @@ -2023,12 +2028,35 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c) · 11 unmodified lines | |||
| 2023 | 2028 | ||
| 2024 | static void gsm1_receive(struct gsm_mux *gsm, unsigned char c) | 2029 | static void gsm1_receive(struct gsm_mux *gsm, unsigned char c) |
| 2025 | { | 2030 | { |
| 2031 | /* handle XON/XOFF */ | ||
| 2032 | if ((c & ISO_IEC_646_MASK) == XON) { | ||
| 2033 | gsm->constipated = true; | ||
| 2034 | return; | ||
| 2035 | } else if ((c & ISO_IEC_646_MASK) == XOFF) { | ||
| 2036 | gsm->constipated = false; | ||
| 2037 | /* Kick the link in case it is idling */ | ||
| 2038 | gsm_data_kick(gsm, NULL); | ||
| 2039 | return; | ||
| 2040 | } | ||
| 2026 | if (c == GSM1_SOF) { | 2041 | if (c == GSM1_SOF) { |
| 2027 | /* EOF is only valid in frame if we have got to the data state | 2042 | /* EOF is only valid in frame if we have got to the data state */ |
| 2028 | and received at least one byte (the FCS) */ | 2043 | if (gsm->state == GSM_DATA) { |
| 2029 | if (gsm->state == GSM_DATA && gsm->count) { | 2044 | if (gsm->count < 1) { |
| 2030 | /* Extract the FCS */ | 2045 | /* Missing FSC */ |
| 2046 | gsm->malformed++; | ||
| 2047 | gsm->state = GSM_START; | ||
| 2048 | return; | ||
| 2049 | } | ||
| 2050 | /* Remove the FCS from data */ | ||
| 2031 | gsm->count--; | 2051 | gsm->count--; |
| 2052 | if ((gsm->control & ~PF) != UIH) { | ||
| 2053 | /* Calculate final FCS for UI frames over all | ||
| 2054 | * data but FCS | ||
| 2055 | */ | ||
| 2056 | gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, | ||
| 2057 | gsm->count); | ||
| 2058 | } | ||
| 2059 | /* Add the FCS itself to test against GOOD_FCS */ | ||
| 2032 | gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->buf[gsm->count]); | 2060 | gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->buf[gsm->count]); |
| 2033 | gsm->len = gsm->count; | 2061 | gsm->len = gsm->count; |
| 2034 | gsm_queue(gsm); | 2062 | gsm_queue(gsm); |
| @@ -2037,7 +2065,8 @@ static void gsm1_receive(struct gsm_mux *gsm, unsigned char c) · 2 unmodified lines | |||
| 2037 | } | 2065 | } |
| 2038 | /* Any partial frame was a runt so go back to start */ | 2066 | /* Any partial frame was a runt so go back to start */ |
| 2039 | if (gsm->state != GSM_START) { | 2067 | if (gsm->state != GSM_START) { |
| 2040 | gsm->malformed++; | 2068 | if (gsm->state != GSM_SEARCH) |
| 2069 | gsm->malformed++; | ||
| 2041 | gsm->state = GSM_START; | 2070 | gsm->state = GSM_START; |
| 2042 | } | 2071 | } |
| 2043 | /* A SOF in GSM_START means we are still reading idling or | 2072 | /* A SOF in GSM_START means we are still reading idling or |
| @@ -2106,74 +2135,43 @@ static void gsm_error(struct gsm_mux *gsm) · 62 unmodified lines | |||
| 2106 | gsm->io_error++; | 2135 | gsm->io_error++; |
| 2107 | } | 2136 | } |
| 2108 | 2137 | ||
| 2109 | static int gsm_disconnect(struct gsm_mux *gsm) | ||
| 2110 | { | ||
| 2111 | struct gsm_dlci *dlci = gsm->dlci[0]; | ||
| 2112 | struct gsm_control *gc; | ||
| 2113 | |||
| 2114 | if (!dlci) | ||
| 2115 | return 0; | ||
| 2116 | |||
| 2117 | /* In theory disconnecting DLCI 0 is sufficient but for some | ||
| 2118 | modems this is apparently not the case. */ | ||
| 2119 | gc = gsm_control_send(gsm, CMD_CLD, NULL, 0); | ||
| 2120 | if (gc) | ||
| 2121 | gsm_control_wait(gsm, gc); | ||
| 2122 | |||
| 2123 | del_timer_sync(&gsm->t2_timer); | ||
| 2124 | /* Now we are sure T2 has stopped */ | ||
| 2125 | |||
| 2126 | gsm_dlci_begin_close(dlci); | ||
| 2127 | wait_event_interruptible(gsm->event, | ||
| 2128 | dlci->state == DLCI_CLOSED); | ||
| 2129 | |||
| 2130 | if (signal_pending(current)) | ||
| 2131 | return -EINTR; | ||
| 2132 | |||
| 2133 | return 0; | ||
| 2134 | } | ||
| 2135 | |||
| 2136 | /** | 2138 | /** |
| 2137 | * gsm_cleanup_mux - generic GSM protocol cleanup | 2139 | * gsm_cleanup_mux - generic GSM protocol cleanup |
| 2138 | * @gsm: our mux | 2140 | * @gsm: our mux |
| 2141 | * @disc: disconnect link? | ||
| 2139 | * | 2142 | * |
| 2140 | * Clean up the bits of the mux which are the same for all framing | 2143 | * Clean up the bits of the mux which are the same for all framing |
| 2141 | * protocols. Remove the mux from the mux table, stop all the timers | 2144 | * protocols. Remove the mux from the mux table, stop all the timers |
| 2142 | * and then shut down each device hanging up the channels as we go. | 2145 | * and then shut down each device hanging up the channels as we go. |
| 2143 | */ | 2146 | */ |
| 2144 | 2147 | ||
| 2145 | static void gsm_cleanup_mux(struct gsm_mux *gsm) | 2148 | static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) |
| 2146 | { | 2149 | { |
| 2147 | int i; | 2150 | int i; |
| 2148 | struct gsm_dlci *dlci = gsm->dlci[0]; | 2151 | struct gsm_dlci *dlci = gsm->dlci[0]; |
| 2149 | struct gsm_msg *txq, *ntxq; | 2152 | struct gsm_msg *txq, *ntxq; |
| 2150 | 2153 | ||
| 2151 | gsm->dead = true; | 2154 | gsm->dead = true; |
| 2155 | mutex_lock(&gsm->mutex); | ||
| 2152 | 2156 | ||
| 2153 | spin_lock(&gsm_mux_lock); | 2157 | if (dlci) { |
| 2154 | for (i = 0; i < MAX_MUX; i++) { | 2158 | if (disc && dlci->state != DLCI_CLOSED) { |
| 2155 | if (gsm_mux[i] == gsm) { | 2159 | gsm_dlci_begin_close(dlci); |
| 2156 | gsm_mux[i] = NULL; | 2160 | wait_event(gsm->event, dlci->state == DLCI_CLOSED); |
| 2157 | break; | ||
| 2158 | } | 2161 | } |
| 2162 | dlci->dead = true; | ||
| 2159 | } | 2163 | } |
| 2160 | spin_unlock(&gsm_mux_lock); | ||
| 2161 | /* open failed before registering => nothing to do */ | ||
| 2162 | if (i == MAX_MUX) | ||
| 2163 | return; | ||
| 2164 | 2164 | ||
| 2165 | /* Finish outstanding timers, making sure they are done */ | ||
| 2165 | del_timer_sync(&gsm->t2_timer); | 2166 | del_timer_sync(&gsm->t2_timer); |
| 2166 | /* Now we are sure T2 has stopped */ | ||
| 2167 | if (dlci) | ||
| 2168 | dlci->dead = true; | ||
| 2169 | 2167 | ||
| 2170 | /* Free up any link layer users */ | 2168 | /* Free up any link layer users and finally the control channel */ |
| 2171 | mutex_lock(&gsm->mutex); | 2169 | for (i = NUM_DLCI - 1; i >= 0; i--) |
| 2172 | for (i = 0; i < NUM_DLCI; i++) | ||
| 2173 | if (gsm->dlci[i]) | 2170 | if (gsm->dlci[i]) |
| 2174 | gsm_dlci_release(gsm->dlci[i]); | 2171 | gsm_dlci_release(gsm->dlci[i]); |
| 2175 | mutex_unlock(&gsm->mutex); | 2172 | mutex_unlock(&gsm->mutex); |
| 2176 | /* Now wipe the queues */ | 2173 | /* Now wipe the queues */ |
| 2174 | tty_ldisc_flush(gsm->tty); | ||
| 2177 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) | 2175 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) |
| 2178 | kfree(txq); | 2176 | kfree(txq); |
| 2179 | INIT_LIST_HEAD(&gsm->tx_list); | 2177 | INIT_LIST_HEAD(&gsm->tx_list); |
| @@ -2191,7 +2189,6 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm) · 11 unmodified lines | |||
| 2191 | static int gsm_activate_mux(struct gsm_mux *gsm) | 2189 | static int gsm_activate_mux(struct gsm_mux *gsm) |
| 2192 | { | 2190 | { |
| 2193 | struct gsm_dlci *dlci; | 2191 | struct gsm_dlci *dlci; |
| 2194 | int i = 0; | ||
| 2195 | 2192 | ||
| 2196 | timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); | 2193 | timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0); |
| 2197 | init_waitqueue_head(&gsm->event); | 2194 | init_waitqueue_head(&gsm->event); |
| @@ -2203,18 +2200,6 @@ static int gsm_activate_mux(struct gsm_mux *gsm) · 5 unmodified lines | |||
| 2203 | else | 2200 | else |
| 2204 | gsm->receive = gsm1_receive; | 2201 | gsm->receive = gsm1_receive; |
| 2205 | 2202 | ||
| 2206 | spin_lock(&gsm_mux_lock); | ||
| 2207 | for (i = 0; i < MAX_MUX; i++) { | ||
| 2208 | if (gsm_mux[i] == NULL) { | ||
| 2209 | gsm->num = i; | ||
| 2210 | gsm_mux[i] = gsm; | ||
| 2211 | break; | ||
| 2212 | } | ||
| 2213 | } | ||
| 2214 | spin_unlock(&gsm_mux_lock); | ||
| 2215 | if (i == MAX_MUX) | ||
| 2216 | return -EBUSY; | ||
| 2217 | |||
| 2218 | dlci = gsm_dlci_alloc(gsm, 0); | 2203 | dlci = gsm_dlci_alloc(gsm, 0); |
| 2219 | if (dlci == NULL) | 2204 | if (dlci == NULL) |
| 2220 | return -ENOMEM; | 2205 | return -ENOMEM; |
| @@ -2230,6 +2215,15 @@ static int gsm_activate_mux(struct gsm_mux *gsm) · 9 unmodified lines | |||
| 2230 | */ | 2215 | */ |
| 2231 | static void gsm_free_mux(struct gsm_mux *gsm) | 2216 | static void gsm_free_mux(struct gsm_mux *gsm) |
| 2232 | { | 2217 | { |
| 2218 | int i; | ||
| 2219 | |||
| 2220 | for (i = 0; i < MAX_MUX; i++) { | ||
| 2221 | if (gsm == gsm_mux[i]) { | ||
| 2222 | gsm_mux[i] = NULL; | ||
| 2223 | break; | ||
| 2224 | } | ||
| 2225 | } | ||
| 2226 | mutex_destroy(&gsm->mutex); | ||
| 2233 | kfree(gsm->txframe); | 2227 | kfree(gsm->txframe); |
| 2234 | kfree(gsm->buf); | 2228 | kfree(gsm->buf); |
| 2235 | kfree(gsm); | 2229 | kfree(gsm); |
| @@ -2249,12 +2243,20 @@ static void gsm_free_muxr(struct kref *ref) · 13 unmodified lines | |||
| 2249 | 2243 | ||
| 2250 | static inline void mux_get(struct gsm_mux *gsm) | 2244 | static inline void mux_get(struct gsm_mux *gsm) |
| 2251 | { | 2245 | { |
| 2246 | unsigned long flags; | ||
| 2247 | |||
| 2248 | spin_lock_irqsave(&gsm_mux_lock, flags); | ||
| 2252 | kref_get(&gsm->ref); | 2249 | kref_get(&gsm->ref); |
| 2250 | spin_unlock_irqrestore(&gsm_mux_lock, flags); | ||
| 2253 | } | 2251 | } |
| 2254 | 2252 | ||
| 2255 | static inline void mux_put(struct gsm_mux *gsm) | 2253 | static inline void mux_put(struct gsm_mux *gsm) |
| 2256 | { | 2254 | { |
| 2255 | unsigned long flags; | ||
| 2256 | |||
| 2257 | spin_lock_irqsave(&gsm_mux_lock, flags); | ||
| 2257 | kref_put(&gsm->ref, gsm_free_muxr); | 2258 | kref_put(&gsm->ref, gsm_free_muxr); |
| 2259 | spin_unlock_irqrestore(&gsm_mux_lock, flags); | ||
| 2258 | } | 2260 | } |
| 2259 | 2261 | ||
| 2260 | static inline unsigned int mux_num_to_base(struct gsm_mux *gsm) | 2262 | static inline unsigned int mux_num_to_base(struct gsm_mux *gsm) |
| @@ -2275,6 +2277,7 @@ static inline unsigned int mux_line_to_num(unsigned int line) · 14 unmodified lines | |||
| 2275 | 2277 | ||
| 2276 | static struct gsm_mux *gsm_alloc_mux(void) | 2278 | static struct gsm_mux *gsm_alloc_mux(void) |
| 2277 | { | 2279 | { |
| 2280 | int i; | ||
| 2278 | struct gsm_mux *gsm = kzalloc(sizeof(struct gsm_mux), GFP_KERNEL); | 2281 | struct gsm_mux *gsm = kzalloc(sizeof(struct gsm_mux), GFP_KERNEL); |
| 2279 | if (gsm == NULL) | 2282 | if (gsm == NULL) |
| 2280 | return NULL; | 2283 | return NULL; |
| @@ -2283,7 +2286,7 @@ static struct gsm_mux *gsm_alloc_mux(void) · 2 unmodified lines | |||
| 2283 | kfree(gsm); | 2286 | kfree(gsm); |
| 2284 | return NULL; | 2287 | return NULL; |
| 2285 | } | 2288 | } |
| 2286 | gsm->txframe = kmalloc(2 * MAX_MRU + 2, GFP_KERNEL); | 2289 | gsm->txframe = kmalloc(2 * (MAX_MTU + PROT_OVERHEAD - 1), GFP_KERNEL); |
| 2287 | if (gsm->txframe == NULL) { | 2290 | if (gsm->txframe == NULL) { |
| 2288 | kfree(gsm->buf); | 2291 | kfree(gsm->buf); |
| 2289 | kfree(gsm); | 2292 | kfree(gsm); |
| @@ -2304,6 +2307,26 @@ static struct gsm_mux *gsm_alloc_mux(void) · 14 unmodified lines | |||
| 2304 | gsm->mtu = 64; | 2307 | gsm->mtu = 64; |
| 2305 | gsm->dead = true; /* Avoid early tty opens */ | 2308 | gsm->dead = true; /* Avoid early tty opens */ |
| 2306 | 2309 | ||
| 2310 | /* Store the instance to the mux array or abort if no space is | ||
| 2311 | * available. | ||
| 2312 | */ | ||
| 2313 | spin_lock(&gsm_mux_lock); | ||
| 2314 | for (i = 0; i < MAX_MUX; i++) { | ||
| 2315 | if (!gsm_mux[i]) { | ||
| 2316 | gsm_mux[i] = gsm; | ||
| 2317 | gsm->num = i; | ||
| 2318 | break; | ||
| 2319 | } | ||
| 2320 | } | ||
| 2321 | spin_unlock(&gsm_mux_lock); | ||
| 2322 | if (i == MAX_MUX) { | ||
| 2323 | mutex_destroy(&gsm->mutex); | ||
| 2324 | kfree(gsm->txframe); | ||
| 2325 | kfree(gsm->buf); | ||
| 2326 | kfree(gsm); | ||
| 2327 | return NULL; | ||
| 2328 | } | ||
| 2329 | |||
| 2307 | return gsm; | 2330 | return gsm; |
| 2308 | } | 2331 | } |
| 2309 | 2332 | ||
| @@ -2330,6 +2353,7 @@ static void gsm_copy_config_values(struct gsm_mux *gsm, · 20 unmodified lines | |||
| 2330 | 2353 | ||
| 2331 | static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) | 2354 | static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) |
| 2332 | { | 2355 | { |
| 2356 | int ret = 0; | ||
| 2333 | int need_close = 0; | 2357 | int need_close = 0; |
| 2334 | int need_restart = 0; | 2358 | int need_restart = 0; |
| 2335 | 2359 | ||
| @@ -2339,7 +2363,7 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) · 3 unmodified lines | |||
| 2339 | /* Check the MRU/MTU range looks sane */ | 2363 | /* Check the MRU/MTU range looks sane */ |
| 2340 | if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8) | 2364 | if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8) |
| 2341 | return -EINVAL; | 2365 | return -EINVAL; |
| 2342 | if (c->n2 < 3) | 2366 | if (c->n2 > 255) |
| 2343 | return -EINVAL; | 2367 | return -EINVAL; |
| 2344 | if (c->encapsulation > 1) /* Basic, advanced, no I */ | 2368 | if (c->encapsulation > 1) /* Basic, advanced, no I */ |
| 2345 | return -EINVAL; | 2369 | return -EINVAL; |
| @@ -2370,19 +2394,11 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) · 24 unmodified lines | |||
| 2370 | 2394 | ||
| 2371 | /* | 2395 | /* |
| 2372 | * Close down what is needed, restart and initiate the new | 2396 | * Close down what is needed, restart and initiate the new |
| 2373 | * configuration | 2397 | * configuration. On the first time there is no DLCI[0] |
| 2398 | * and closing or cleaning up is not necessary. | ||
| 2374 | */ | 2399 | */ |
| 2375 | 2400 | if (need_close || need_restart) | |
| 2376 | if (gsm->initiator && (need_close || need_restart)) { | 2401 | gsm_cleanup_mux(gsm, true); |
| 2377 | int ret; | ||
| 2378 | |||
| 2379 | ret = gsm_disconnect(gsm); | ||
| 2380 | |||
| 2381 | if (ret) | ||
| 2382 | return ret; | ||
| 2383 | } | ||
| 2384 | if (need_restart) | ||
| 2385 | gsm_cleanup_mux(gsm); | ||
| 2386 | 2402 | ||
| 2387 | gsm->initiator = c->initiator; | 2403 | gsm->initiator = c->initiator; |
| 2388 | gsm->mru = c->mru; | 2404 | gsm->mru = c->mru; |
| @@ -2405,10 +2421,13 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c) · 16 unmodified lines | |||
| 2405 | * FIXME: We need to separate activation/deactivation from adding | 2421 | * FIXME: We need to separate activation/deactivation from adding |
| 2406 | * and removing from the mux array | 2422 | * and removing from the mux array |
| 2407 | */ | 2423 | */ |
| 2408 | if (need_restart) | 2424 | if (gsm->dead) { |
| 2409 | gsm_activate_mux(gsm); | 2425 | ret = gsm_activate_mux(gsm); |
| 2410 | if (gsm->initiator && need_close) | 2426 | if (ret) |
| 2411 | gsm_dlci_begin_open(gsm->dlci[0]); | 2427 | return ret; |
| 2428 | if (gsm->initiator) | ||
| 2429 | gsm_dlci_begin_open(gsm->dlci[0]); | ||
| 2430 | } | ||
| 2412 | return 0; | 2431 | return 0; |
| 2413 | } | 2432 | } |
| 2414 | 2433 | ||
| @@ -2450,25 +2469,26 @@ static int gsmld_attach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) · 35 unmodified lines | |||
| 2450 | int ret, i; | 2469 | int ret, i; |
| 2451 | 2470 | ||
| 2452 | gsm->tty = tty_kref_get(tty); | 2471 | gsm->tty = tty_kref_get(tty); |
| 2472 | /* Turn off tty XON/XOFF handling to handle it explicitly. */ | ||
| 2473 | gsm->old_c_iflag = tty->termios.c_iflag; | ||
| 2474 | tty->termios.c_iflag &= (IXON | IXOFF); | ||
| 2453 | ret = gsm_activate_mux(gsm); | 2475 | ret = gsm_activate_mux(gsm); |
| 2454 | if (ret != 0) | 2476 | if (ret != 0) |
| 2455 | tty_kref_put(gsm->tty); | 2477 | tty_kref_put(gsm->tty); |
| 2456 | else { | 2478 | else { |
| 2457 | /* Don't register device 0 - this is the control channel and not | 2479 | /* Don't register device 0 - this is the control channel and not |
| 2458 | a usable tty interface */ | 2480 | a usable tty interface */ |
| 2459 | if (gsm->initiator) { | 2481 | base = mux_num_to_base(gsm); /* Base for this MUX */ |
| 2460 | base = mux_num_to_base(gsm); /* Base for this MUX */ | 2482 | for (i = 1; i < NUM_DLCI; i++) { |
| 2461 | for (i = 1; i < NUM_DLCI; i++) { | 2483 | struct device *dev; |
| 2462 | struct device *dev; | ||
| 2463 | 2484 | ||
| 2464 | dev = tty_register_device(gsm_tty_driver, | 2485 | dev = tty_register_device(gsm_tty_driver, |
| 2465 | base + i, NULL); | 2486 | base + i, NULL); |
| 2466 | if (IS_ERR(dev)) { | 2487 | if (IS_ERR(dev)) { |
| 2467 | for (i--; i >= 1; i--) | 2488 | for (i--; i >= 1; i--) |
| 2468 | tty_unregister_device(gsm_tty_driver, | 2489 | tty_unregister_device(gsm_tty_driver, |
| 2469 | base + i); | 2490 | base + i); |
| 2470 | return PTR_ERR(dev); | 2491 | return PTR_ERR(dev); |
| 2471 | } | ||
| 2472 | } | 2492 | } |
| 2473 | } | 2493 | } |
| 2474 | } | 2494 | } |
| @@ -2490,11 +2510,10 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm) · 15 unmodified lines | |||
| 2490 | int i; | 2510 | int i; |
| 2491 | 2511 | ||
| 2492 | WARN_ON(tty != gsm->tty); | 2512 | WARN_ON(tty != gsm->tty); |
| 2493 | if (gsm->initiator) { | 2513 | for (i = 1; i < NUM_DLCI; i++) |
| 2494 | for (i = 1; i < NUM_DLCI; i++) | 2514 | tty_unregister_device(gsm_tty_driver, base + i); |
| 2495 | tty_unregister_device(gsm_tty_driver, base + i); | 2515 | /* Restore tty XON/XOFF handling. */ |
| 2496 | } | 2516 | gsm->tty->termios.c_iflag = gsm->old_c_iflag; |
| 2497 | gsm_cleanup_mux(gsm); | ||
| 2498 | tty_kref_put(gsm->tty); | 2517 | tty_kref_put(gsm->tty); |
| 2499 | gsm->tty = NULL; | 2518 | gsm->tty = NULL; |
| 2500 | } | 2519 | } |
| @@ -2559,6 +2578,12 @@ static void gsmld_close(struct tty_struct *tty) · 58 unmodified lines | |||
| 2559 | { | 2578 | { |
| 2560 | struct gsm_mux *gsm = tty->disc_data; | 2579 | struct gsm_mux *gsm = tty->disc_data; |
| 2561 | 2580 | ||
| 2581 | /* The ldisc locks and closes the port before calling our close. This | ||
| 2582 | * means we have no way to do a proper disconnect. We will not bother | ||
| 2583 | * to do one. | ||
| 2584 | */ | ||
| 2585 | gsm_cleanup_mux(gsm, false); | ||
| 2586 | |||
| 2562 | gsmld_detach_gsm(tty, gsm); | 2587 | gsmld_detach_gsm(tty, gsm); |
| 2563 | 2588 | ||
| 2564 | gsmld_flush_buffer(tty); | 2589 | gsmld_flush_buffer(tty); |
| @@ -2597,7 +2622,7 @@ static int gsmld_open(struct tty_struct *tty) · 32 unmodified lines | |||
| 2597 | 2622 | ||
| 2598 | ret = gsmld_attach_gsm(tty, gsm); | 2623 | ret = gsmld_attach_gsm(tty, gsm); |
| 2599 | if (ret != 0) { | 2624 | if (ret != 0) { |
| 2600 | gsm_cleanup_mux(gsm); | 2625 | gsm_cleanup_mux(gsm, false); |
| 2601 | mux_put(gsm); | 2626 | mux_put(gsm); |
| 2602 | } | 2627 | } |
| 2603 | return ret; | 2628 | return ret; |
| @@ -2952,28 +2977,78 @@ static struct tty_ldisc_ops tty_ldisc_packet = { · 348 unmodified lines | |||
| 2952 | * Virtual tty side | 2977 | * Virtual tty side |
| 2953 | */ | 2978 | */ |
| 2954 | 2979 | ||
| 2955 | #define TX_SIZE 512 | 2980 | /** |
| 2981 | * gsm_modem_upd_via_data - send modem bits via convergence layer | ||
| 2982 | * @dlci: channel | ||
| 2983 | * @brk: break signal | ||
| 2984 | * | ||
| 2985 | * Send an empty frame to signal mobile state changes and to transmit the | ||
| 2986 | * break signal for adaption 2. | ||
| 2987 | */ | ||
| 2988 | |||
| 2989 | static void gsm_modem_upd_via_data(struct gsm_dlci *dlci, u8 brk) | ||
| 2990 | { | ||
| 2991 | struct gsm_mux *gsm = dlci->gsm; | ||
| 2992 | unsigned long flags; | ||
| 2993 | |||
| 2994 | if (dlci->state != DLCI_OPEN || dlci->adaption != 2) | ||
| 2995 | return; | ||
| 2996 | |||
| 2997 | spin_lock_irqsave(&gsm->tx_lock, flags); | ||
| 2998 | gsm_dlci_modem_output(gsm, dlci, brk); | ||
| 2999 | spin_unlock_irqrestore(&gsm->tx_lock, flags); | ||
| 3000 | } | ||
| 3001 | |||
| 3002 | /** | ||
| 3003 | * gsm_modem_upd_via_msc - send modem bits via control frame | ||
| 3004 | * @dlci: channel | ||
| 3005 | * @brk: break signal | ||
| 3006 | */ | ||
| 2956 | 3007 | ||
| 2957 | static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk) | 3008 | static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk) |
| 2958 | { | 3009 | { |
| 2959 | u8 modembits[5]; | 3010 | u8 modembits[3]; |
| 2960 | struct gsm_control *ctrl; | 3011 | struct gsm_control *ctrl; |
| 2961 | int len = 2; | 3012 | int len = 2; |
| 2962 | 3013 | ||
| 2963 | if (brk) | 3014 | if (dlci->gsm->encoding != 0) |
| 2964 | len++; | 3015 | return 0; |
| 2965 | 3016 | ||
| 2966 | modembits[0] = len << 1 | EA; /* Data bytes */ | 3017 | modembits[0] = (dlci->addr << 2) | 2 | EA; /* DLCI, Valid, EA */ |
| 2967 | modembits[1] = dlci->addr << 2 | 3; /* DLCI, EA, 1 */ | 3018 | if (!brk) { |
| 2968 | modembits[2] = gsm_encode_modem(dlci) << 1 | EA; | 3019 | modembits[1] = (gsm_encode_modem(dlci) << 1) | EA; |
| 2969 | if (brk) | 3020 | } else { |
| 2970 | modembits[3] = brk << 4 | 2 | EA; /* Valid, EA */ | 3021 | modembits[1] = gsm_encode_modem(dlci) << 1; |
| 2971 | ctrl = gsm_control_send(dlci->gsm, CMD_MSC, modembits, len + 1); | 3022 | modembits[2] = (brk << 4) | 2 | EA; /* Length, Break, EA */ |
| 3023 | len++; | ||
| 3024 | } | ||
| 3025 | ctrl = gsm_control_send(dlci->gsm, CMD_MSC, modembits, len); | ||
| 2972 | if (ctrl == NULL) | 3026 | if (ctrl == NULL) |
| 2973 | return -ENOMEM; | 3027 | return -ENOMEM; |
| 2974 | return gsm_control_wait(dlci->gsm, ctrl); | 3028 | return gsm_control_wait(dlci->gsm, ctrl); |
| 2975 | } | 3029 | } |
| 2976 | 3030 | ||
| 3031 | /** | ||
| 3032 | * gsm_modem_update - send modem status line state | ||
| 3033 | * @dlci: channel | ||
| 3034 | * @brk: break signal | ||
| 3035 | */ | ||
| 3036 | |||
| 3037 | static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk) | ||
| 3038 | { | ||
| 3039 | if (dlci->adaption == 2) { | ||
| 3040 | /* Send convergence layer type 2 empty data frame. */ | ||
| 3041 | gsm_modem_upd_via_data(dlci, brk); | ||
| 3042 | return 0; | ||
| 3043 | } else if (dlci->gsm->encoding == 0) { | ||
| 3044 | /* Send as MSC control message. */ | ||
| 3045 | return gsm_modem_upd_via_msc(dlci, brk); | ||
| 3046 | } | ||
| 3047 | |||
| 3048 | /* Modem status lines are not supported. */ | ||
| 3049 | return -EPROTONOSUPPORT; | ||
| 3050 | } | ||
| 3051 | |||
| 2977 | static int gsm_carrier_raised(struct tty_port *port) | 3052 | static int gsm_carrier_raised(struct tty_port *port) |
| 2978 | { | 3053 | { |
| 2979 | struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port); | 3054 | struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port); |
| @@ -3006,7 +3081,7 @@ static void gsm_dtr_rts(struct tty_port *port, int onoff) · 26 unmodified lines | |||
| 3006 | modem_tx &= ~(TIOCM_DTR | TIOCM_RTS); | 3081 | modem_tx &= ~(TIOCM_DTR | TIOCM_RTS); |
| 3007 | if (modem_tx != dlci->modem_tx) { | 3082 | if (modem_tx != dlci->modem_tx) { |
| 3008 | dlci->modem_tx = modem_tx; | 3083 | dlci->modem_tx = modem_tx; |
| 3009 | gsmtty_modem_update(dlci, 0); | 3084 | gsm_modem_update(dlci, 0); |
| 3010 | } | 3085 | } |
| 3011 | } | 3086 | } |
| 3012 | 3087 | ||
| @@ -3141,7 +3216,7 @@ static unsigned int gsmtty_write_room(struct tty_struct *tty) · 128 unmodified lines | |||
| 3141 | struct gsm_dlci *dlci = tty->driver_data; | 3216 | struct gsm_dlci *dlci = tty->driver_data; |
| 3142 | if (dlci->state == DLCI_CLOSED) | 3217 | if (dlci->state == DLCI_CLOSED) |
| 3143 | return 0; | 3218 | return 0; |
| 3144 | return TX_SIZE - kfifo_len(&dlci->fifo); | 3219 | return kfifo_avail(&dlci->fifo); |
| 3145 | } | 3220 | } |
| 3146 | 3221 | ||
| 3147 | static unsigned int gsmtty_chars_in_buffer(struct tty_struct *tty) | 3222 | static unsigned int gsmtty_chars_in_buffer(struct tty_struct *tty) |
| @@ -3155,13 +3230,17 @@ static unsigned int gsmtty_chars_in_buffer(struct tty_struct *tty) · 7 unmodified lines | |||
| 3155 | static void gsmtty_flush_buffer(struct tty_struct *tty) | 3230 | static void gsmtty_flush_buffer(struct tty_struct *tty) |
| 3156 | { | 3231 | { |
| 3157 | struct gsm_dlci *dlci = tty->driver_data; | 3232 | struct gsm_dlci *dlci = tty->driver_data; |
| 3233 | unsigned long flags; | ||
| 3234 | |||
| 3158 | if (dlci->state == DLCI_CLOSED) | 3235 | if (dlci->state == DLCI_CLOSED) |
| 3159 | return; | 3236 | return; |
| 3160 | /* Caution needed: If we implement reliable transport classes | 3237 | /* Caution needed: If we implement reliable transport classes |
| 3161 | then the data being transmitted can't simply be junked once | 3238 | then the data being transmitted can't simply be junked once |
| 3162 | it has first hit the stack. Until then we can just blow it | 3239 | it has first hit the stack. Until then we can just blow it |
| 3163 | away */ | 3240 | away */ |
| 3241 | spin_lock_irqsave(&dlci->lock, flags); | ||
| 3164 | kfifo_reset(&dlci->fifo); | 3242 | kfifo_reset(&dlci->fifo); |
| 3243 | spin_unlock_irqrestore(&dlci->lock, flags); | ||
| 3165 | /* Need to unhook this DLCI from the transmit queue logic */ | 3244 | /* Need to unhook this DLCI from the transmit queue logic */ |
| 3166 | } | 3245 | } |
| 3167 | 3246 | ||
| @@ -3193,7 +3272,7 @@ static int gsmtty_tiocmset(struct tty_struct *tty, · 25 unmodified lines | |||
| 3193 | 3272 | ||
| 3194 | if (modem_tx != dlci->modem_tx) { | 3273 | if (modem_tx != dlci->modem_tx) { |
| 3195 | dlci->modem_tx = modem_tx; | 3274 | dlci->modem_tx = modem_tx; |
| 3196 | return gsmtty_modem_update(dlci, 0); | 3275 | return gsm_modem_update(dlci, 0); |
| 3197 | } | 3276 | } |
| 3198 | return 0; | 3277 | return 0; |
| 3199 | } | 3278 | } |
| @@ -3254,7 +3333,7 @@ static void gsmtty_throttle(struct tty_struct *tty) · 54 unmodified lines | |||
| 3254 | dlci->modem_tx &= ~TIOCM_RTS; | 3333 | dlci->modem_tx &= ~TIOCM_RTS; |
| 3255 | dlci->throttled = true; | 3334 | dlci->throttled = true; |
| 3256 | /* Send an MSC with RTS cleared */ | 3335 | /* Send an MSC with RTS cleared */ |
| 3257 | gsmtty_modem_update(dlci, 0); | 3336 | gsm_modem_update(dlci, 0); |
| 3258 | } | 3337 | } |
| 3259 | 3338 | ||
| 3260 | static void gsmtty_unthrottle(struct tty_struct *tty) | 3339 | static void gsmtty_unthrottle(struct tty_struct *tty) |
| @@ -3266,7 +3345,7 @@ static void gsmtty_unthrottle(struct tty_struct *tty) · 5 unmodified lines | |||
| 3266 | dlci->modem_tx |= TIOCM_RTS; | 3345 | dlci->modem_tx |= TIOCM_RTS; |
| 3267 | dlci->throttled = false; | 3346 | dlci->throttled = false; |
| 3268 | /* Send an MSC with RTS set */ | 3347 | /* Send an MSC with RTS set */ |
| 3269 | gsmtty_modem_update(dlci, 0); | 3348 | gsm_modem_update(dlci, 0); |
| 3270 | } | 3349 | } |
| 3271 | 3350 | ||
| 3272 | static int gsmtty_break_ctl(struct tty_struct *tty, int state) | 3351 | static int gsmtty_break_ctl(struct tty_struct *tty, int state) |
| @@ -3284,7 +3363,7 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state) · 11 unmodified lines | |||
| 3284 | if (encode > 0x0F) | 3363 | if (encode > 0x0F) |
| 3285 | encode = 0x0F; /* Best effort */ | 3364 | encode = 0x0F; /* Best effort */ |
| 3286 | } | 3365 | } |
| 3287 | return gsmtty_modem_update(dlci, encode); | 3366 | return gsm_modem_update(dlci, encode); |
| 3288 | } | 3367 | } |
| 3289 | 3368 | ||
| 3290 | static void gsmtty_cleanup(struct tty_struct *tty) | 3369 | static void gsmtty_cleanup(struct tty_struct *tty) |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | #define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */ | 37 | #define MTK_UART_IER_RTSI 0x40 /* Enable RTS Modem status interrupt */ |
| 38 | #define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */ | 38 | #define MTK_UART_IER_CTSI 0x80 /* Enable CTS Modem status interrupt */ |
| 39 | 39 | ||
| 40 | #define MTK_UART_EFR 38 /* I/O: Extended Features Register */ | ||
| 40 | #define MTK_UART_EFR_EN 0x10 /* Enable enhancement feature */ | 41 | #define MTK_UART_EFR_EN 0x10 /* Enable enhancement feature */ |
| 41 | #define MTK_UART_EFR_RTS 0x40 /* Enable hardware rx flow control */ | 42 | #define MTK_UART_EFR_RTS 0x40 /* Enable hardware rx flow control */ |
| 42 | #define MTK_UART_EFR_CTS 0x80 /* Enable hardware tx flow control */ | 43 | #define MTK_UART_EFR_CTS 0x80 /* Enable hardware tx flow control */ |
| @@ -53,6 +54,12 @@ · 10 unmodified lines | |||
| 53 | #define MTK_UART_TX_TRIGGER 1 | 54 | #define MTK_UART_TX_TRIGGER 1 |
| 54 | #define MTK_UART_RX_TRIGGER MTK_UART_RX_SIZE | 55 | #define MTK_UART_RX_TRIGGER MTK_UART_RX_SIZE |
| 55 | 56 | ||
| 57 | #define MTK_UART_FEATURE_SEL 39 /* Feature Selection register */ | ||
| 58 | #define MTK_UART_FEAT_NEWRMAP BIT(0) /* Use new register map */ | ||
| 59 | |||
| 60 | #define MTK_UART_XON1 40 /* I/O: Xon character 1 */ | ||
| 61 | #define MTK_UART_XOFF1 42 /* I/O: Xoff character 1 */ | ||
| 62 | |||
| 56 | #ifdef CONFIG_SERIAL_8250_DMA | 63 | #ifdef CONFIG_SERIAL_8250_DMA |
| 57 | enum dma_rx_status { | 64 | enum dma_rx_status { |
| 58 | DMA_RX_START = 0, | 65 | DMA_RX_START = 0, |
| @@ -169,7 +176,7 @@ static void mtk8250_dma_enable(struct uart_8250_port *up) · 110 unmodified lines | |||
| 169 | MTK_UART_DMA_EN_RX | MTK_UART_DMA_EN_TX); | 176 | MTK_UART_DMA_EN_RX | MTK_UART_DMA_EN_TX); |
| 170 | 177 | ||
| 171 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 178 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 172 | serial_out(up, UART_EFR, UART_EFR_ECB); | 179 | serial_out(up, MTK_UART_EFR, UART_EFR_ECB); |
| 173 | serial_out(up, UART_LCR, lcr); | 180 | serial_out(up, UART_LCR, lcr); |
| 174 | 181 | ||
| 175 | if (dmaengine_slave_config(dma->rxchan, &dma->rxconf) != 0) | 182 | if (dmaengine_slave_config(dma->rxchan, &dma->rxconf) != 0) |
| @@ -232,7 +239,7 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode) · 56 unmodified lines | |||
| 232 | int lcr = serial_in(up, UART_LCR); | 239 | int lcr = serial_in(up, UART_LCR); |
| 233 | 240 | ||
| 234 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 241 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 235 | serial_out(up, UART_EFR, UART_EFR_ECB); | 242 | serial_out(up, MTK_UART_EFR, UART_EFR_ECB); |
| 236 | serial_out(up, UART_LCR, lcr); | 243 | serial_out(up, UART_LCR, lcr); |
| 237 | lcr = serial_in(up, UART_LCR); | 244 | lcr = serial_in(up, UART_LCR); |
| 238 | 245 | ||
| @@ -241,7 +248,7 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode) · 2 unmodified lines | |||
| 241 | serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR); | 248 | serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR); |
| 242 | serial_out(up, MTK_UART_ESCAPE_EN, 0x00); | 249 | serial_out(up, MTK_UART_ESCAPE_EN, 0x00); |
| 243 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 250 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 244 | serial_out(up, UART_EFR, serial_in(up, UART_EFR) & | 251 | serial_out(up, MTK_UART_EFR, serial_in(up, MTK_UART_EFR) & |
| 245 | (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))); | 252 | (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK))); |
| 246 | serial_out(up, UART_LCR, lcr); | 253 | serial_out(up, UART_LCR, lcr); |
| 247 | mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI | | 254 | mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI | |
| @@ -255,8 +262,8 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode) · 7 unmodified lines | |||
| 255 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 262 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 256 | 263 | ||
| 257 | /*enable hw flow control*/ | 264 | /*enable hw flow control*/ |
| 258 | serial_out(up, UART_EFR, MTK_UART_EFR_HW_FC | | 265 | serial_out(up, MTK_UART_EFR, MTK_UART_EFR_HW_FC | |
| 259 | (serial_in(up, UART_EFR) & | 266 | (serial_in(up, MTK_UART_EFR) & |
| 260 | (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)))); | 267 | (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)))); |
| 261 | 268 | ||
| 262 | serial_out(up, UART_LCR, lcr); | 269 | serial_out(up, UART_LCR, lcr); |
| @@ -270,12 +277,12 @@ static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode) · 7 unmodified lines | |||
| 270 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 277 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
| 271 | 278 | ||
| 272 | /*enable sw flow control */ | 279 | /*enable sw flow control */ |
| 273 | serial_out(up, UART_EFR, MTK_UART_EFR_XON1_XOFF1 | | 280 | serial_out(up, MTK_UART_EFR, MTK_UART_EFR_XON1_XOFF1 | |
| 274 | (serial_in(up, UART_EFR) & | 281 | (serial_in(up, MTK_UART_EFR) & |
| 275 | (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)))); | 282 | (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)))); |
| 276 | 283 | ||
| 277 | serial_out(up, UART_XON1, START_CHAR(port->state->port.tty)); | 284 | serial_out(up, MTK_UART_XON1, START_CHAR(port->state->port.tty)); |
| 278 | serial_out(up, UART_XOFF1, STOP_CHAR(port->state->port.tty)); | 285 | serial_out(up, MTK_UART_XOFF1, STOP_CHAR(port->state->port.tty)); |
| 279 | serial_out(up, UART_LCR, lcr); | 286 | serial_out(up, UART_LCR, lcr); |
| 280 | mtk8250_disable_intrs(up, MTK_UART_IER_CTSI|MTK_UART_IER_RTSI); | 287 | mtk8250_disable_intrs(up, MTK_UART_IER_CTSI|MTK_UART_IER_RTSI); |
| 281 | mtk8250_enable_intrs(up, MTK_UART_IER_XOFFI); | 288 | mtk8250_enable_intrs(up, MTK_UART_IER_XOFFI); |
| @@ -568,6 +575,10 @@ static int mtk8250_probe(struct platform_device *pdev) · 286 unmodified lines | |||
| 568 | uart.dma = data->dma; | 575 | uart.dma = data->dma; |
| 569 | #endif | 576 | #endif |
| 570 | 577 | ||
| 578 | /* Set AP UART new register map */ | ||
| 579 | writel(MTK_UART_FEAT_NEWRMAP, uart.port.membase + | ||
| 580 | (MTK_UART_FEATURE_SEL << uart.port.regshift)); | ||
| 581 | |||
| 571 | /* Disable Rate Fix function */ | 582 | /* Disable Rate Fix function */ |
| 572 | writel(0x0, uart.port.membase + | 583 | writel(0x0, uart.port.membase + |
| 573 | (MTK_UART_RATE_FIX << uart.port.regshift)); | 584 | (MTK_UART_RATE_FIX << uart.port.regshift)); |
| @@ -2667,7 +2667,7 @@ enum pci_board_num_t { · 2666 unmodified lines | |||
| 2667 | pbn_panacom2, | 2667 | pbn_panacom2, |
| 2668 | pbn_panacom4, | 2668 | pbn_panacom4, |
| 2669 | pbn_plx_romulus, | 2669 | pbn_plx_romulus, |
| 2670 | pbn_endrun_2_4000000, | 2670 | pbn_endrun_2_3906250, |
| 2671 | pbn_oxsemi, | 2671 | pbn_oxsemi, |
| 2672 | pbn_oxsemi_1_3906250, | 2672 | pbn_oxsemi_1_3906250, |
| 2673 | pbn_oxsemi_2_3906250, | 2673 | pbn_oxsemi_2_3906250, |
| @@ -3195,10 +3195,10 @@ static struct pciserial_board pci_boards[] = { · 521 unmodified lines | |||
| 3195 | * signal now many ports are available | 3195 | * signal now many ports are available |
| 3196 | * 2 port 952 Uart support | 3196 | * 2 port 952 Uart support |
| 3197 | */ | 3197 | */ |
| 3198 | [pbn_endrun_2_4000000] = { | 3198 | [pbn_endrun_2_3906250] = { |
| 3199 | .flags = FL_BASE0, | 3199 | .flags = FL_BASE0, |
| 3200 | .num_ports = 2, | 3200 | .num_ports = 2, |
| 3201 | .base_baud = 4000000, | 3201 | .base_baud = 3906250, |
| 3202 | .uart_offset = 0x200, | 3202 | .uart_offset = 0x200, |
| 3203 | .first_offset = 0x1000, | 3203 | .first_offset = 0x1000, |
| 3204 | }, | 3204 | }, |
| @@ -4115,7 +4115,7 @@ static const struct pci_device_id serial_pci_tbl[] = { · 910 unmodified lines | |||
| 4115 | */ | 4115 | */ |
| 4116 | { PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588, | 4116 | { PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588, |
| 4117 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4117 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
| 4118 | pbn_endrun_2_4000000 }, | 4118 | pbn_endrun_2_3906250 }, |
| 4119 | /* | 4119 | /* |
| 4120 | * Quatech cards. These actually have configurable clocks but for | 4120 | * Quatech cards. These actually have configurable clocks but for |
| 4121 | * now we just use the default. | 4121 | * now we just use the default. |
| @@ -1675,11 +1675,11 @@ static void serial8250_start_tx(struct uart_port *port) · 1674 unmodified lines | |||
| 1675 | struct uart_8250_port *up = up_to_u8250p(port); | 1675 | struct uart_8250_port *up = up_to_u8250p(port); |
| 1676 | struct uart_8250_em485 *em485 = up->em485; | 1676 | struct uart_8250_em485 *em485 = up->em485; |
| 1677 | 1677 | ||
| 1678 | serial8250_rpm_get_tx(up); | ||
| 1679 | |||
| 1680 | if (!port->x_char && uart_circ_empty(&port->state->xmit)) | 1678 | if (!port->x_char && uart_circ_empty(&port->state->xmit)) |
| 1681 | return; | 1679 | return; |
| 1682 | 1680 | ||
| 1681 | serial8250_rpm_get_tx(up); | ||
| 1682 | |||
| 1683 | if (em485 && | 1683 | if (em485 && |
| 1684 | em485->active_timer == &em485->start_tx_timer) | 1684 | em485->active_timer == &em485->start_tx_timer) |
| 1685 | return; | 1685 | return; |
| @@ -3329,7 +3329,7 @@ static void serial8250_console_restore(struct uart_8250_port *up) · 1643 unmodified lines | |||
| 3329 | 3329 | ||
| 3330 | serial8250_set_divisor(port, baud, quot, frac); | 3330 | serial8250_set_divisor(port, baud, quot, frac); |
| 3331 | serial_port_out(port, UART_LCR, up->lcr); | 3331 | serial_port_out(port, UART_LCR, up->lcr); |
| 3332 | serial8250_out_MCR(up, UART_MCR_DTR | UART_MCR_RTS); | 3332 | serial8250_out_MCR(up, up->mcr | UART_MCR_DTR | UART_MCR_RTS); |
| 3333 | } | 3333 | } |
| 3334 | 3334 | ||
| 3335 | /* | 3335 | /* |
| @@ -1255,13 +1255,18 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap) · 1254 unmodified lines | |||
| 1255 | 1255 | ||
| 1256 | static void pl011_rs485_tx_stop(struct uart_amba_port *uap) | 1256 | static void pl011_rs485_tx_stop(struct uart_amba_port *uap) |
| 1257 | { | 1257 | { |
| 1258 | /* | ||
| 1259 | * To be on the safe side only time out after twice as many iterations | ||
| 1260 | * as fifo size. | ||
| 1261 | */ | ||
| 1262 | const int MAX_TX_DRAIN_ITERS = uap->port.fifosize * 2; | ||
| 1258 | struct uart_port *port = &uap->port; | 1263 | struct uart_port *port = &uap->port; |
| 1259 | int i = 0; | 1264 | int i = 0; |
| 1260 | u32 cr; | 1265 | u32 cr; |
| 1261 | 1266 | ||
| 1262 | /* Wait until hardware tx queue is empty */ | 1267 | /* Wait until hardware tx queue is empty */ |
| 1263 | while (!pl011_tx_empty(port)) { | 1268 | while (!pl011_tx_empty(port)) { |
| 1264 | if (i == port->fifosize) { | 1269 | if (i > MAX_TX_DRAIN_ITERS) { |
| 1265 | dev_warn(port->dev, | 1270 | dev_warn(port->dev, |
| 1266 | "timeout while draining hardware tx queue\n"); | 1271 | "timeout while draining hardware tx queue\n"); |
| 1267 | break; | 1272 | break; |
| @@ -2052,7 +2057,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, · 784 unmodified lines | |||
| 2052 | * with the given baud rate. We use this as the poll interval when we | 2057 | * with the given baud rate. We use this as the poll interval when we |
| 2053 | * wait for the tx queue to empty. | 2058 | * wait for the tx queue to empty. |
| 2054 | */ | 2059 | */ |
| 2055 | uap->rs485_tx_drain_interval = (bits * 1000 * 1000) / baud; | 2060 | uap->rs485_tx_drain_interval = DIV_ROUND_UP(bits * 1000 * 1000, baud); |
| 2056 | 2061 | ||
| 2057 | pl011_setup_status_masks(port, termios); | 2062 | pl011_setup_status_masks(port, termios); |
| 2058 | 2063 | ||
| @@ -471,11 +471,10 @@ static int digicolor_uart_probe(struct platform_device *pdev) · 470 unmodified lines | |||
| 471 | if (IS_ERR(uart_clk)) | 471 | if (IS_ERR(uart_clk)) |
| 472 | return PTR_ERR(uart_clk); | 472 | return PTR_ERR(uart_clk); |
| 473 | 473 | ||
| 474 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 474 | dp->port.membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res); |
| 475 | dp->port.mapbase = res->start; | ||
| 476 | dp->port.membase = devm_ioremap_resource(&pdev->dev, res); | ||
| 477 | if (IS_ERR(dp->port.membase)) | 475 | if (IS_ERR(dp->port.membase)) |
| 478 | return PTR_ERR(dp->port.membase); | 476 | return PTR_ERR(dp->port.membase); |
| 477 | dp->port.mapbase = res->start; | ||
| 479 | 478 | ||
| 480 | irq = platform_get_irq(pdev, 0); | 479 | irq = platform_get_irq(pdev, 0); |
| 481 | if (irq < 0) | 480 | if (irq < 0) |
| @@ -2664,6 +2664,7 @@ static int lpuart_probe(struct platform_device *pdev) · 2663 unmodified lines | |||
| 2664 | struct device_node *np = pdev->dev.of_node; | 2664 | struct device_node *np = pdev->dev.of_node; |
| 2665 | struct lpuart_port *sport; | 2665 | struct lpuart_port *sport; |
| 2666 | struct resource *res; | 2666 | struct resource *res; |
| 2667 | irq_handler_t handler; | ||
| 2667 | int ret; | 2668 | int ret; |
| 2668 | 2669 | ||
| 2669 | sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); | 2670 | sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); |
| @@ -2741,17 +2742,11 @@ static int lpuart_probe(struct platform_device *pdev) · 71 unmodified lines | |||
| 2741 | 2742 | ||
| 2742 | if (lpuart_is_32(sport)) { | 2743 | if (lpuart_is_32(sport)) { |
| 2743 | lpuart_reg.cons = LPUART32_CONSOLE; | 2744 | lpuart_reg.cons = LPUART32_CONSOLE; |
| 2744 | ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart32_int, 0, | 2745 | handler = lpuart32_int; |
| 2745 | DRIVER_NAME, sport); | ||
| 2746 | } else { | 2746 | } else { |
| 2747 | lpuart_reg.cons = LPUART_CONSOLE; | 2747 | lpuart_reg.cons = LPUART_CONSOLE; |
| 2748 | ret = devm_request_irq(&pdev->dev, sport->port.irq, lpuart_int, 0, | 2748 | handler = lpuart_int; |
| 2749 | DRIVER_NAME, sport); | ||
| 2750 | } | 2749 | } |
| 2751 | |||
| 2752 | if (ret) | ||
| 2753 | goto failed_irq_request; | ||
| 2754 | |||
| 2755 | ret = uart_add_one_port(&lpuart_reg, &sport->port); | 2750 | ret = uart_add_one_port(&lpuart_reg, &sport->port); |
| 2756 | if (ret) | 2751 | if (ret) |
| 2757 | goto failed_attach_port; | 2752 | goto failed_attach_port; |
| @@ -2773,13 +2768,18 @@ static int lpuart_probe(struct platform_device *pdev) · 15 unmodified lines | |||
| 2773 | 2768 | ||
| 2774 | sport->port.rs485_config(&sport->port, &sport->port.rs485); | 2769 | sport->port.rs485_config(&sport->port, &sport->port.rs485); |
| 2775 | 2770 | ||
| 2771 | ret = devm_request_irq(&pdev->dev, sport->port.irq, handler, 0, | ||
| 2772 | DRIVER_NAME, sport); | ||
| 2773 | if (ret) | ||
| 2774 | goto failed_irq_request; | ||
| 2775 | |||
| 2776 | return 0; | 2776 | return 0; |
| 2777 | 2777 | ||
| 2778 | failed_irq_request: | ||
| 2778 | failed_get_rs485: | 2779 | failed_get_rs485: |
| 2779 | failed_reset: | 2780 | failed_reset: |
| 2780 | uart_remove_one_port(&lpuart_reg, &sport->port); | 2781 | uart_remove_one_port(&lpuart_reg, &sport->port); |
| 2781 | failed_attach_port: | 2782 | failed_attach_port: |
| 2782 | failed_irq_request: | ||
| 2783 | lpuart_disable_clks(sport); | 2783 | lpuart_disable_clks(sport); |
| 2784 | failed_clock_enable: | 2784 | failed_clock_enable: |
| 2785 | failed_out_of_range: | 2785 | failed_out_of_range: |
| @@ -1448,7 +1448,7 @@ static int imx_uart_startup(struct uart_port *port) · 1447 unmodified lines | |||
| 1448 | imx_uart_writel(sport, ucr1, UCR1); | 1448 | imx_uart_writel(sport, ucr1, UCR1); |
| 1449 | 1449 | ||
| 1450 | ucr4 = imx_uart_readl(sport, UCR4) & ~(UCR4_OREN | UCR4_INVR); | 1450 | ucr4 = imx_uart_readl(sport, UCR4) & ~(UCR4_OREN | UCR4_INVR); |
| 1451 | if (!sport->dma_is_enabled) | 1451 | if (!dma_is_inited) |
| 1452 | ucr4 |= UCR4_OREN; | 1452 | ucr4 |= UCR4_OREN; |
| 1453 | if (sport->inverted_rx) | 1453 | if (sport->inverted_rx) |
| 1454 | ucr4 |= UCR4_INVR; | 1454 | ucr4 |= UCR4_INVR; |
| @@ -1238,12 +1238,10 @@ static void sc16is7xx_shutdown(struct uart_port *port) · 1237 unmodified lines | |||
| 1238 | 1238 | ||
| 1239 | /* Disable all interrupts */ | 1239 | /* Disable all interrupts */ |
| 1240 | sc16is7xx_port_write(port, SC16IS7XX_IER_REG, 0); | 1240 | sc16is7xx_port_write(port, SC16IS7XX_IER_REG, 0); |
| 1241 | /* Disable TX/RX, clear auto RS485 and RTS invert */ | 1241 | /* Disable TX/RX */ |
| 1242 | sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, | 1242 | sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, |
| 1243 | SC16IS7XX_EFCR_RXDISABLE_BIT | | 1243 | SC16IS7XX_EFCR_RXDISABLE_BIT | |
| 1244 | SC16IS7XX_EFCR_TXDISABLE_BIT | | 1244 | SC16IS7XX_EFCR_TXDISABLE_BIT, |
| 1245 | SC16IS7XX_EFCR_AUTO_RS485_BIT | | ||
| 1246 | SC16IS7XX_EFCR_RTS_INVERT_BIT, | ||
| 1247 | SC16IS7XX_EFCR_RXDISABLE_BIT | | 1245 | SC16IS7XX_EFCR_RXDISABLE_BIT | |
| 1248 | SC16IS7XX_EFCR_TXDISABLE_BIT); | 1246 | SC16IS7XX_EFCR_TXDISABLE_BIT); |
| 1249 | 1247 | ||
| @@ -2684,6 +2684,7 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep) · 2683 unmodified lines | |||
| 2684 | struct usb_request *request; | 2684 | struct usb_request *request; |
| 2685 | struct cdns3_request *priv_req; | 2685 | struct cdns3_request *priv_req; |
| 2686 | struct cdns3_trb *trb = NULL; | 2686 | struct cdns3_trb *trb = NULL; |
| 2687 | struct cdns3_trb trb_tmp; | ||
| 2687 | int ret; | 2688 | int ret; |
| 2688 | int val; | 2689 | int val; |
| 2689 | 2690 | ||
| @@ -2693,8 +2694,10 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep) · 3 unmodified lines | |||
| 2693 | if (request) { | 2694 | if (request) { |
| 2694 | priv_req = to_cdns3_request(request); | 2695 | priv_req = to_cdns3_request(request); |
| 2695 | trb = priv_req->trb; | 2696 | trb = priv_req->trb; |
| 2696 | if (trb) | 2697 | if (trb) { |
| 2698 | trb_tmp = *trb; | ||
| 2697 | trb->control = trb->control ^ cpu_to_le32(TRB_CYCLE); | 2699 | trb->control = trb->control ^ cpu_to_le32(TRB_CYCLE); |
| 2700 | } | ||
| 2698 | } | 2701 | } |
| 2699 | 2702 | ||
| 2700 | writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd); | 2703 | writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd); |
| @@ -2709,7 +2712,7 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep) · 8 unmodified lines | |||
| 2709 | 2712 | ||
| 2710 | if (request) { | 2713 | if (request) { |
| 2711 | if (trb) | 2714 | if (trb) |
| 2712 | trb->control = trb->control ^ cpu_to_le32(TRB_CYCLE); | 2715 | *trb = trb_tmp; |
| 2713 | 2716 | ||
| 2714 | cdns3_rearm_transfer(priv_ep, 1); | 2717 | cdns3_rearm_transfer(priv_ep, 1); |
| 2715 | } | 2718 | } |
| @@ -774,6 +774,7 @@ static int wdm_release(struct inode *inode, struct file *file) · 773 unmodified lines | |||
| 774 | poison_urbs(desc); | 774 | poison_urbs(desc); |
| 775 | spin_lock_irq(&desc->iuspin); | 775 | spin_lock_irq(&desc->iuspin); |
| 776 | desc->resp_count = 0; | 776 | desc->resp_count = 0; |
| 777 | clear_bit(WDM_RESPONDING, &desc->flags); | ||
| 777 | spin_unlock_irq(&desc->iuspin); | 778 | spin_unlock_irq(&desc->iuspin); |
| 778 | desc->manage_power(desc->intf, 0); | 779 | desc->manage_power(desc->intf, 0); |
| 779 | unpoison_urbs(desc); | 780 | unpoison_urbs(desc); |
| @@ -1209,12 +1209,16 @@ static int do_proc_control(struct usb_dev_state *ps, · 1208 unmodified lines | |||
| 1209 | 1209 | ||
| 1210 | usb_unlock_device(dev); | 1210 | usb_unlock_device(dev); |
| 1211 | i = usbfs_start_wait_urb(urb, tmo, &actlen); | 1211 | i = usbfs_start_wait_urb(urb, tmo, &actlen); |
| 1212 | |||
| 1213 | /* Linger a bit, prior to the next control message. */ | ||
| 1214 | if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) | ||
| 1215 | msleep(200); | ||
| 1212 | usb_lock_device(dev); | 1216 | usb_lock_device(dev); |
| 1213 | snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, tbuf, actlen); | 1217 | snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, tbuf, actlen); |
| 1214 | if (!i && actlen) { | 1218 | if (!i && actlen) { |
| 1215 | if (copy_to_user(ctrl->data, tbuf, actlen)) { | 1219 | if (copy_to_user(ctrl->data, tbuf, actlen)) { |
| 1216 | ret = -EFAULT; | 1220 | ret = -EFAULT; |
| 1217 | goto recv_fault; | 1221 | goto done; |
| 1218 | } | 1222 | } |
| 1219 | } | 1223 | } |
| 1220 | } else { | 1224 | } else { |
| @@ -1231,6 +1235,10 @@ static int do_proc_control(struct usb_dev_state *ps, · 10 unmodified lines | |||
| 1231 | 1235 | ||
| 1232 | usb_unlock_device(dev); | 1236 | usb_unlock_device(dev); |
| 1233 | i = usbfs_start_wait_urb(urb, tmo, &actlen); | 1237 | i = usbfs_start_wait_urb(urb, tmo, &actlen); |
| 1238 | |||
| 1239 | /* Linger a bit, prior to the next control message. */ | ||
| 1240 | if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) | ||
| 1241 | msleep(200); | ||
| 1234 | usb_lock_device(dev); | 1242 | usb_lock_device(dev); |
| 1235 | snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, NULL, 0); | 1243 | snoop_urb(dev, NULL, pipe, actlen, i, COMPLETE, NULL, 0); |
| 1236 | } | 1244 | } |
| @@ -1242,10 +1250,6 @@ static int do_proc_control(struct usb_dev_state *ps, · 5 unmodified lines | |||
| 1242 | } | 1250 | } |
| 1243 | ret = (i < 0 ? i : actlen); | 1251 | ret = (i < 0 ? i : actlen); |
| 1244 | 1252 | ||
| 1245 | recv_fault: | ||
| 1246 | /* Linger a bit, prior to the next control message. */ | ||
| 1247 | if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG) | ||
| 1248 | msleep(200); | ||
| 1249 | done: | 1253 | done: |
| 1250 | kfree(dr); | 1254 | kfree(dr); |
| 1251 | usb_free_urb(urb); | 1255 | usb_free_urb(urb); |
| @@ -404,6 +404,9 @@ static const struct usb_device_id usb_quirk_list[] = { · 403 unmodified lines | |||
| 404 | { USB_DEVICE(0x0b05, 0x17e0), .driver_info = | 404 | { USB_DEVICE(0x0b05, 0x17e0), .driver_info = |
| 405 | USB_QUIRK_IGNORE_REMOTE_WAKEUP }, | 405 | USB_QUIRK_IGNORE_REMOTE_WAKEUP }, |
| 406 | 406 | ||
| 407 | /* Realtek Semiconductor Corp. Mass Storage Device (Multicard Reader)*/ | ||
| 408 | { USB_DEVICE(0x0bda, 0x0151), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, | ||
| 409 | |||
| 407 | /* Realtek hub in Dell WD19 (Type-C) */ | 410 | /* Realtek hub in Dell WD19 (Type-C) */ |
| 408 | { USB_DEVICE(0x0bda, 0x0487), .driver_info = USB_QUIRK_NO_LPM }, | 411 | { USB_DEVICE(0x0bda, 0x0487), .driver_info = USB_QUIRK_NO_LPM }, |
| 409 | 412 | ||
| @@ -507,6 +510,9 @@ static const struct usb_device_id usb_quirk_list[] = { · 97 unmodified lines | |||
| 507 | /* DJI CineSSD */ | 510 | /* DJI CineSSD */ |
| 508 | { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, | 511 | { USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM }, |
| 509 | 512 | ||
| 513 | /* VCOM device */ | ||
| 514 | { USB_DEVICE(0x4296, 0x7570), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, | ||
| 515 | |||
| 510 | /* INTEL VALUE SSD */ | 516 | /* INTEL VALUE SSD */ |
| 511 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, | 517 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 512 | 518 | ||
| @@ -274,7 +274,8 @@ int dwc3_core_soft_reset(struct dwc3 *dwc) · 273 unmodified lines | |||
| 274 | 274 | ||
| 275 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); | 275 | reg = dwc3_readl(dwc->regs, DWC3_DCTL); |
| 276 | reg |= DWC3_DCTL_CSFTRST; | 276 | reg |= DWC3_DCTL_CSFTRST; |
| 277 | dwc3_writel(dwc->regs, DWC3_DCTL, reg); | 277 | reg &= ~DWC3_DCTL_RUN_STOP; |
| 278 | dwc3_gadget_dctl_write_safe(dwc, reg); | ||
| 278 | 279 | ||
| 279 | /* | 280 | /* |
| 280 | * For DWC_usb31 controller 1.90a and later, the DCTL.CSFRST bit | 281 | * For DWC_usb31 controller 1.90a and later, the DCTL.CSFRST bit |
| @@ -1377,10 +1378,10 @@ static void dwc3_get_properties(struct dwc3 *dwc) · 1096 unmodified lines | |||
| 1377 | u8 lpm_nyet_threshold; | 1378 | u8 lpm_nyet_threshold; |
| 1378 | u8 tx_de_emphasis; | 1379 | u8 tx_de_emphasis; |
| 1379 | u8 hird_threshold; | 1380 | u8 hird_threshold; |
| 1380 | u8 rx_thr_num_pkt_prd; | 1381 | u8 rx_thr_num_pkt_prd = 0; |
| 1381 | u8 rx_max_burst_prd; | 1382 | u8 rx_max_burst_prd = 0; |
| 1382 | u8 tx_thr_num_pkt_prd; | 1383 | u8 tx_thr_num_pkt_prd = 0; |
| 1383 | u8 tx_max_burst_prd; | 1384 | u8 tx_max_burst_prd = 0; |
| 1384 | u8 tx_fifo_resize_max_num; | 1385 | u8 tx_fifo_resize_max_num; |
| 1385 | const char *usb_psy_name; | 1386 | const char *usb_psy_name; |
| 1386 | int ret; | 1387 | int ret; |
| @@ -1690,21 +1691,44 @@ static int dwc3_probe(struct platform_device *pdev) · 303 unmodified lines | |||
| 1690 | /* | 1691 | /* |
| 1691 | * Clocks are optional, but new DT platforms should support all | 1692 | * Clocks are optional, but new DT platforms should support all |
| 1692 | * clocks as required by the DT-binding. | 1693 | * clocks as required by the DT-binding. |
| 1694 | * Some devices have different clock names in legacy device trees, | ||
| 1695 | * check for them to retain backwards compatibility. | ||
| 1693 | */ | 1696 | */ |
| 1694 | dwc->bus_clk = devm_clk_get_optional(dev, "bus_early"); | 1697 | dwc->bus_clk = devm_clk_get_optional(dev, "bus_early"); |
| 1695 | if (IS_ERR(dwc->bus_clk)) | 1698 | if (IS_ERR(dwc->bus_clk)) |
| 1696 | return dev_err_probe(dev, PTR_ERR(dwc->bus_clk), | 1699 | return dev_err_probe(dev, PTR_ERR(dwc->bus_clk), |
| 1697 | "could not get bus clock\n"); | 1700 | "could not get bus clock\n"); |
| 1698 | 1701 | ||
| 1702 | if (dwc->bus_clk == NULL) { | ||
| 1703 | dwc->bus_clk = devm_clk_get_optional(dev, "bus_clk"); | ||
| 1704 | if (IS_ERR(dwc->bus_clk)) | ||
| 1705 | return dev_err_probe(dev, PTR_ERR(dwc->bus_clk), | ||
| 1706 | "could not get bus clock\n"); | ||
| 1707 | } | ||
| 1708 | |||
| 1699 | dwc->ref_clk = devm_clk_get_optional(dev, "ref"); | 1709 | dwc->ref_clk = devm_clk_get_optional(dev, "ref"); |
| 1700 | if (IS_ERR(dwc->ref_clk)) | 1710 | if (IS_ERR(dwc->ref_clk)) |
| 1701 | return dev_err_probe(dev, PTR_ERR(dwc->ref_clk), | 1711 | return dev_err_probe(dev, PTR_ERR(dwc->ref_clk), |
| 1702 | "could not get ref clock\n"); | 1712 | "could not get ref clock\n"); |
| 1703 | 1713 | ||
| 1714 | if (dwc->ref_clk == NULL) { | ||
| 1715 | dwc->ref_clk = devm_clk_get_optional(dev, "ref_clk"); | ||
| 1716 | if (IS_ERR(dwc->ref_clk)) | ||
| 1717 | return dev_err_probe(dev, PTR_ERR(dwc->ref_clk), | ||
| 1718 | "could not get ref clock\n"); | ||
| 1719 | } | ||
| 1720 | |||
| 1704 | dwc->susp_clk = devm_clk_get_optional(dev, "suspend"); | 1721 | dwc->susp_clk = devm_clk_get_optional(dev, "suspend"); |
| 1705 | if (IS_ERR(dwc->susp_clk)) | 1722 | if (IS_ERR(dwc->susp_clk)) |
| 1706 | return dev_err_probe(dev, PTR_ERR(dwc->susp_clk), | 1723 | return dev_err_probe(dev, PTR_ERR(dwc->susp_clk), |
| 1707 | "could not get suspend clock\n"); | 1724 | "could not get suspend clock\n"); |
| 1725 | |||
| 1726 | if (dwc->susp_clk == NULL) { | ||
| 1727 | dwc->susp_clk = devm_clk_get_optional(dev, "suspend_clk"); | ||
| 1728 | if (IS_ERR(dwc->susp_clk)) | ||
| 1729 | return dev_err_probe(dev, PTR_ERR(dwc->susp_clk), | ||
| 1730 | "could not get suspend clock\n"); | ||
| 1731 | } | ||
| 1708 | } | 1732 | } |
| 1709 | 1733 | ||
| 1710 | ret = reset_control_deassert(dwc->reset); | 1734 | ret = reset_control_deassert(dwc->reset); |
| @@ -584,16 +584,15 @@ int dwc3_drd_init(struct dwc3 *dwc) · 583 unmodified lines | |||
| 584 | { | 584 | { |
| 585 | int ret, irq; | 585 | int ret, irq; |
| 586 | 586 | ||
| 587 | if (ROLE_SWITCH && | ||
| 588 | device_property_read_bool(dwc->dev, "usb-role-switch")) | ||
| 589 | return dwc3_setup_role_switch(dwc); | ||
| 590 | |||
| 587 | dwc->edev = dwc3_get_extcon(dwc); | 591 | dwc->edev = dwc3_get_extcon(dwc); |
| 588 | if (IS_ERR(dwc->edev)) | 592 | if (IS_ERR(dwc->edev)) |
| 589 | return PTR_ERR(dwc->edev); | 593 | return PTR_ERR(dwc->edev); |
| 590 | 594 | ||
| 591 | if (ROLE_SWITCH && | 595 | if (dwc->edev) { |
| 592 | device_property_read_bool(dwc->dev, "usb-role-switch")) { | ||
| 593 | ret = dwc3_setup_role_switch(dwc); | ||
| 594 | if (ret < 0) | ||
| 595 | return ret; | ||
| 596 | } else if (dwc->edev) { | ||
| 597 | dwc->edev_nb.notifier_call = dwc3_drd_notifier; | 596 | dwc->edev_nb.notifier_call = dwc3_drd_notifier; |
| 598 | ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST, | 597 | ret = extcon_register_notifier(dwc->edev, EXTCON_USB_HOST, |
| 599 | &dwc->edev_nb); | 598 | &dwc->edev_nb); |
| @@ -45,6 +45,8 @@ · 44 unmodified lines | |||
| 45 | #define PCI_DEVICE_ID_INTEL_ADLM 0x54ee | 45 | #define PCI_DEVICE_ID_INTEL_ADLM 0x54ee |
| 46 | #define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1 | 46 | #define PCI_DEVICE_ID_INTEL_ADLS 0x7ae1 |
| 47 | #define PCI_DEVICE_ID_INTEL_RPLS 0x7a61 | 47 | #define PCI_DEVICE_ID_INTEL_RPLS 0x7a61 |
| 48 | #define PCI_DEVICE_ID_INTEL_MTLP 0x7ec1 | ||
| 49 | #define PCI_DEVICE_ID_INTEL_MTL 0x7e7e | ||
| 48 | #define PCI_DEVICE_ID_INTEL_TGL 0x9a15 | 50 | #define PCI_DEVICE_ID_INTEL_TGL 0x9a15 |
| 49 | #define PCI_DEVICE_ID_AMD_MR 0x163a | 51 | #define PCI_DEVICE_ID_AMD_MR 0x163a |
| 50 | 52 | ||
| @@ -456,6 +458,12 @@ static const struct pci_device_id dwc3_pci_id_table[] = { · 405 unmodified lines | |||
| 456 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPLS), | 458 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_RPLS), |
| 457 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, | 459 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, |
| 458 | 460 | ||
| 461 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTLP), | ||
| 462 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, | ||
| 463 | |||
| 464 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_MTL), | ||
| 465 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, | ||
| 466 | |||
| 459 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TGL), | 467 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_TGL), |
| 460 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, | 468 | (kernel_ulong_t) &dwc3_pci_intel_swnode, }, |
| 461 | 469 | ||
| @@ -3274,6 +3274,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, · 3273 unmodified lines | |||
| 3274 | const struct dwc3_event_depevt *event, | 3274 | const struct dwc3_event_depevt *event, |
| 3275 | struct dwc3_request *req, int status) | 3275 | struct dwc3_request *req, int status) |
| 3276 | { | 3276 | { |
| 3277 | int request_status; | ||
| 3277 | int ret; | 3278 | int ret; |
| 3278 | 3279 | ||
| 3279 | if (req->request.num_mapped_sgs) | 3280 | if (req->request.num_mapped_sgs) |
| @@ -3294,7 +3295,35 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, · 14 unmodified lines | |||
| 3294 | req->needs_extra_trb = false; | 3295 | req->needs_extra_trb = false; |
| 3295 | } | 3296 | } |
| 3296 | 3297 | ||
| 3297 | dwc3_gadget_giveback(dep, req, status); | 3298 | /* |
| 3299 | * The event status only reflects the status of the TRB with IOC set. | ||
| 3300 | * For the requests that don't set interrupt on completion, the driver | ||
| 3301 | * needs to check and return the status of the completed TRBs associated | ||
| 3302 | * with the request. Use the status of the last TRB of the request. | ||
| 3303 | */ | ||
| 3304 | if (req->request.no_interrupt) { | ||
| 3305 | struct dwc3_trb *trb; | ||
| 3306 | |||
| 3307 | trb = dwc3_ep_prev_trb(dep, dep->trb_dequeue); | ||
| 3308 | switch (DWC3_TRB_SIZE_TRBSTS(trb->size)) { | ||
| 3309 | case DWC3_TRBSTS_MISSED_ISOC: | ||
| 3310 | /* Isoc endpoint only */ | ||
| 3311 | request_status = -EXDEV; | ||
| 3312 | break; | ||
| 3313 | case DWC3_TRB_STS_XFER_IN_PROG: | ||
| 3314 | /* Applicable when End Transfer with ForceRM=0 */ | ||
| 3315 | case DWC3_TRBSTS_SETUP_PENDING: | ||
| 3316 | /* Control endpoint only */ | ||
| 3317 | case DWC3_TRBSTS_OK: | ||
| 3318 | default: | ||
| 3319 | request_status = 0; | ||
| 3320 | break; | ||
| 3321 | } | ||
| 3322 | } else { | ||
| 3323 | request_status = status; | ||
| 3324 | } | ||
| 3325 | |||
| 3326 | dwc3_gadget_giveback(dep, req, request_status); | ||
| 3298 | 3327 | ||
| 3299 | out: | 3328 | out: |
| 3300 | return ret; | 3329 | return ret; |
| @@ -1438,6 +1438,8 @@ static void configfs_composite_unbind(struct usb_gadget *gadget) · 1437 unmodified lines | |||
| 1438 | usb_ep_autoconfig_reset(cdev->gadget); | 1438 | usb_ep_autoconfig_reset(cdev->gadget); |
| 1439 | spin_lock_irqsave(&gi->spinlock, flags); | 1439 | spin_lock_irqsave(&gi->spinlock, flags); |
| 1440 | cdev->gadget = NULL; | 1440 | cdev->gadget = NULL; |
| 1441 | cdev->deactivations = 0; | ||
| 1442 | gadget->deactivated = false; | ||
| 1441 | set_gadget_data(gadget, NULL); | 1443 | set_gadget_data(gadget, NULL); |
| 1442 | spin_unlock_irqrestore(&gi->spinlock, flags); | 1444 | spin_unlock_irqrestore(&gi->spinlock, flags); |
| 1443 | } | 1445 | } |
| @@ -890,13 +890,37 @@ static void uvc_function_unbind(struct usb_configuration *c, · 889 unmodified lines | |||
| 890 | { | 890 | { |
| 891 | struct usb_composite_dev *cdev = c->cdev; | 891 | struct usb_composite_dev *cdev = c->cdev; |
| 892 | struct uvc_device *uvc = to_uvc(f); | 892 | struct uvc_device *uvc = to_uvc(f); |
| 893 | long wait_ret = 1; | ||
| 893 | 894 | ||
| 894 | uvcg_info(f, "%s()\n", __func__); | 895 | uvcg_info(f, "%s()\n", __func__); |
| 895 | 896 | ||
| 897 | /* If we know we're connected via v4l2, then there should be a cleanup | ||
| 898 | * of the device from userspace either via UVC_EVENT_DISCONNECT or | ||
| 899 | * though the video device removal uevent. Allow some time for the | ||
| 900 | * application to close out before things get deleted. | ||
| 901 | */ | ||
| 902 | if (uvc->func_connected) { | ||
| 903 | uvcg_dbg(f, "waiting for clean disconnect\n"); | ||
| 904 | wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue, | ||
| 905 | uvc->func_connected == false, msecs_to_jiffies(500)); | ||
| 906 | uvcg_dbg(f, "done waiting with ret: %ld\n", wait_ret); | ||
| 907 | } | ||
| 908 | |||
| 896 | device_remove_file(&uvc->vdev.dev, &dev_attr_function_name); | 909 | device_remove_file(&uvc->vdev.dev, &dev_attr_function_name); |
| 897 | video_unregister_device(&uvc->vdev); | 910 | video_unregister_device(&uvc->vdev); |
| 898 | v4l2_device_unregister(&uvc->v4l2_dev); | 911 | v4l2_device_unregister(&uvc->v4l2_dev); |
| 899 | 912 | ||
| 913 | if (uvc->func_connected) { | ||
| 914 | /* Wait for the release to occur to ensure there are no longer any | ||
| 915 | * pending operations that may cause panics when resources are cleaned | ||
| 916 | * up. | ||
| 917 | */ | ||
| 918 | uvcg_warn(f, "%s no clean disconnect, wait for release\n", __func__); | ||
| 919 | wait_ret = wait_event_interruptible_timeout(uvc->func_connected_queue, | ||
| 920 | uvc->func_connected == false, msecs_to_jiffies(1000)); | ||
| 921 | uvcg_dbg(f, "done waiting for release with ret: %ld\n", wait_ret); | ||
| 922 | } | ||
| 923 | |||
| 900 | usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); | 924 | usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); |
| 901 | kfree(uvc->control_buf); | 925 | kfree(uvc->control_buf); |
| 902 | 926 | ||
| @@ -915,6 +939,7 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi) · 12 unmodified lines | |||
| 915 | 939 | ||
| 916 | mutex_init(&uvc->video.mutex); | 940 | mutex_init(&uvc->video.mutex); |
| 917 | uvc->state = UVC_STATE_DISCONNECTED; | 941 | uvc->state = UVC_STATE_DISCONNECTED; |
| 942 | init_waitqueue_head(&uvc->func_connected_queue); | ||
| 918 | opts = fi_to_f_uvc_opts(fi); | 943 | opts = fi_to_f_uvc_opts(fi); |
| 919 | 944 | ||
| 920 | mutex_lock(&opts->lock); | 945 | mutex_lock(&opts->lock); |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | |||
| 14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
| 15 | #include <linux/usb/composite.h> | 15 | #include <linux/usb/composite.h> |
| 16 | #include <linux/videodev2.h> | 16 | #include <linux/videodev2.h> |
| 17 | #include <linux/wait.h> | ||
| 17 | 18 | ||
| 18 | #include <media/v4l2-device.h> | 19 | #include <media/v4l2-device.h> |
| 19 | #include <media/v4l2-dev.h> | 20 | #include <media/v4l2-dev.h> |
| @@ -129,6 +130,7 @@ struct uvc_device { · 109 unmodified lines | |||
| 129 | struct usb_function func; | 130 | struct usb_function func; |
| 130 | struct uvc_video video; | 131 | struct uvc_video video; |
| 131 | bool func_connected; | 132 | bool func_connected; |
| 133 | wait_queue_head_t func_connected_queue; | ||
| 132 | 134 | ||
| 133 | /* Descriptors */ | 135 | /* Descriptors */ |
| 134 | struct { | 136 | struct { |
| @@ -264,6 +264,8 @@ void uvcg_queue_cancel(struct uvc_video_queue *queue, int disconnect) · 263 unmodified lines | |||
| 264 | buf->state = UVC_BUF_STATE_ERROR; | 264 | buf->state = UVC_BUF_STATE_ERROR; |
| 265 | vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR); | 265 | vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_ERROR); |
| 266 | } | 266 | } |
| 267 | queue->buf_used = 0; | ||
| 268 | |||
| 267 | /* This must be protected by the irqlock spinlock to avoid race | 269 | /* This must be protected by the irqlock spinlock to avoid race |
| 268 | * conditions between uvc_queue_buffer and the disconnection event that | 270 | * conditions between uvc_queue_buffer and the disconnection event that |
| 269 | * could result in an interruptible wait in uvc_dequeue_buffer. Do not | 271 | * could result in an interruptible wait in uvc_dequeue_buffer. Do not |
| @@ -253,10 +253,11 @@ uvc_v4l2_subscribe_event(struct v4l2_fh *fh, · 252 unmodified lines | |||
| 253 | 253 | ||
| 254 | static void uvc_v4l2_disable(struct uvc_device *uvc) | 254 | static void uvc_v4l2_disable(struct uvc_device *uvc) |
| 255 | { | 255 | { |
| 256 | uvc->func_connected = false; | ||
| 257 | uvc_function_disconnect(uvc); | 256 | uvc_function_disconnect(uvc); |
| 258 | uvcg_video_enable(&uvc->video, 0); | 257 | uvcg_video_enable(&uvc->video, 0); |
| 259 | uvcg_free_buffers(&uvc->video.queue); | 258 | uvcg_free_buffers(&uvc->video.queue); |
| 259 | uvc->func_connected = false; | ||
| 260 | wake_up_interruptible(&uvc->func_connected_queue); | ||
| 260 | } | 261 | } |
| 261 | 262 | ||
| 262 | static int | 263 | static int |
| @@ -145,6 +145,7 @@ enum dev_state { · 144 unmodified lines | |||
| 145 | STATE_DEV_INVALID = 0, | 145 | STATE_DEV_INVALID = 0, |
| 146 | STATE_DEV_OPENED, | 146 | STATE_DEV_OPENED, |
| 147 | STATE_DEV_INITIALIZED, | 147 | STATE_DEV_INITIALIZED, |
| 148 | STATE_DEV_REGISTERING, | ||
| 148 | STATE_DEV_RUNNING, | 149 | STATE_DEV_RUNNING, |
| 149 | STATE_DEV_CLOSED, | 150 | STATE_DEV_CLOSED, |
| 150 | STATE_DEV_FAILED | 151 | STATE_DEV_FAILED |
| @@ -508,6 +509,7 @@ static int raw_ioctl_run(struct raw_dev *dev, unsigned long value) · 357 unmodified lines | |||
| 508 | ret = -EINVAL; | 509 | ret = -EINVAL; |
| 509 | goto out_unlock; | 510 | goto out_unlock; |
| 510 | } | 511 | } |
| 512 | dev->state = STATE_DEV_REGISTERING; | ||
| 511 | spin_unlock_irqrestore(&dev->lock, flags); | 513 | spin_unlock_irqrestore(&dev->lock, flags); |
| 512 | 514 | ||
| 513 | ret = usb_gadget_probe_driver(&dev->driver); | 515 | ret = usb_gadget_probe_driver(&dev->driver); |
| @@ -1103,6 +1103,26 @@ static void ehci_remove_device(struct usb_hcd *hcd, struct usb_device *udev) · 1102 unmodified lines | |||
| 1103 | 1103 | ||
| 1104 | #ifdef CONFIG_PM | 1104 | #ifdef CONFIG_PM |
| 1105 | 1105 | ||
| 1106 | /* Clear wakeup signal locked in zhaoxin platform when device plug in. */ | ||
| 1107 | static void ehci_zx_wakeup_clear(struct ehci_hcd *ehci) | ||
| 1108 | { | ||
| 1109 | u32 __iomem *reg = &ehci->regs->port_status[4]; | ||
| 1110 | u32 t1 = ehci_readl(ehci, reg); | ||
| 1111 | |||
| 1112 | t1 &= (u32)~0xf0000; | ||
| 1113 | t1 |= PORT_TEST_FORCE; | ||
| 1114 | ehci_writel(ehci, t1, reg); | ||
| 1115 | t1 = ehci_readl(ehci, reg); | ||
| 1116 | msleep(1); | ||
| 1117 | t1 &= (u32)~0xf0000; | ||
| 1118 | ehci_writel(ehci, t1, reg); | ||
| 1119 | ehci_readl(ehci, reg); | ||
| 1120 | msleep(1); | ||
| 1121 | t1 = ehci_readl(ehci, reg); | ||
| 1122 | ehci_writel(ehci, t1 | PORT_CSC, reg); | ||
| 1123 | ehci_readl(ehci, reg); | ||
| 1124 | } | ||
| 1125 | |||
| 1106 | /* suspend/resume, section 4.3 */ | 1126 | /* suspend/resume, section 4.3 */ |
| 1107 | 1127 | ||
| 1108 | /* These routines handle the generic parts of controller suspend/resume */ | 1128 | /* These routines handle the generic parts of controller suspend/resume */ |
| @@ -1154,6 +1174,9 @@ int ehci_resume(struct usb_hcd *hcd, bool force_reset) · 45 unmodified lines | |||
| 1154 | if (ehci->shutdown) | 1174 | if (ehci->shutdown) |
| 1155 | return 0; /* Controller is dead */ | 1175 | return 0; /* Controller is dead */ |
| 1156 | 1176 | ||
| 1177 | if (ehci->zx_wakeup_clear_needed) | ||
| 1178 | ehci_zx_wakeup_clear(ehci); | ||
| 1179 | |||
| 1157 | /* | 1180 | /* |
| 1158 | * If CF is still set and reset isn't forced | 1181 | * If CF is still set and reset isn't forced |
| 1159 | * then we maintained suspend power. | 1182 | * then we maintained suspend power. |
| @@ -231,6 +231,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd) · 230 unmodified lines | |||
| 231 | ehci->is_aspeed = 1; | 231 | ehci->is_aspeed = 1; |
| 232 | } | 232 | } |
| 233 | break; | 233 | break; |
| 234 | case PCI_VENDOR_ID_ZHAOXIN: | ||
| 235 | if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x90) | ||
| 236 | ehci->zx_wakeup_clear_needed = 1; | ||
| 237 | break; | ||
| 234 | } | 238 | } |
| 235 | 239 | ||
| 236 | /* optional debug port, normally in the first BAR */ | 240 | /* optional debug port, normally in the first BAR */ |
| @@ -220,6 +220,7 @@ struct ehci_hcd { /* one per controller */ · 219 unmodified lines | |||
| 220 | unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ | 220 | unsigned imx28_write_fix:1; /* For Freescale i.MX28 */ |
| 221 | unsigned spurious_oc:1; | 221 | unsigned spurious_oc:1; |
| 222 | unsigned is_aspeed:1; | 222 | unsigned is_aspeed:1; |
| 223 | unsigned zx_wakeup_clear_needed:1; | ||
| 223 | 224 | ||
| 224 | /* required for usb32 quirk */ | 225 | /* required for usb32 quirk */ |
| 225 | #define OHCI_CTRL_HCFS (3 << 6) | 226 | #define OHCI_CTRL_HCFS (3 << 6) |
| @@ -1434,7 +1434,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 1433 unmodified lines | |||
| 1434 | } | 1434 | } |
| 1435 | spin_unlock_irqrestore(&xhci->lock, flags); | 1435 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 1436 | if (!wait_for_completion_timeout(&bus_state->u3exit_done[wIndex], | 1436 | if (!wait_for_completion_timeout(&bus_state->u3exit_done[wIndex], |
| 1437 | msecs_to_jiffies(100))) | 1437 | msecs_to_jiffies(500))) |
| 1438 | xhci_dbg(xhci, "missing U0 port change event for port %d-%d\n", | 1438 | xhci_dbg(xhci, "missing U0 port change event for port %d-%d\n", |
| 1439 | hcd->self.busnum, wIndex + 1); | 1439 | hcd->self.busnum, wIndex + 1); |
| 1440 | spin_lock_irqsave(&xhci->lock, flags); | 1440 | spin_lock_irqsave(&xhci->lock, flags); |
| @@ -19,11 +19,6 @@ · 18 unmodified lines | |||
| 19 | #define HS_BW_BOUNDARY 6144 | 19 | #define HS_BW_BOUNDARY 6144 |
| 20 | /* usb2 spec section11.18.1: at most 188 FS bytes per microframe */ | 20 | /* usb2 spec section11.18.1: at most 188 FS bytes per microframe */ |
| 21 | #define FS_PAYLOAD_MAX 188 | 21 | #define FS_PAYLOAD_MAX 188 |
| 22 | /* | ||
| 23 | * max number of microframes for split transfer, | ||
| 24 | * for fs isoc in : 1 ss + 1 idle + 7 cs | ||
| 25 | */ | ||
| 26 | #define TT_MICROFRAMES_MAX 9 | ||
| 27 | 22 | ||
| 28 | #define DBG_BUF_EN 64 | 23 | #define DBG_BUF_EN 64 |
| 29 | 24 | ||
| @@ -242,28 +237,17 @@ static void drop_tt(struct usb_device *udev) · 212 unmodified lines | |||
| 242 | 237 | ||
| 243 | static struct mu3h_sch_ep_info * | 238 | static struct mu3h_sch_ep_info * |
| 244 | create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, | 239 | create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, |
| 245 | struct usb_host_endpoint *ep, struct xhci_ep_ctx *ep_ctx) | 240 | struct usb_host_endpoint *ep) |
| 246 | { | 241 | { |
| 247 | struct mu3h_sch_ep_info *sch_ep; | 242 | struct mu3h_sch_ep_info *sch_ep; |
| 248 | struct mu3h_sch_bw_info *bw_info; | 243 | struct mu3h_sch_bw_info *bw_info; |
| 249 | struct mu3h_sch_tt *tt = NULL; | 244 | struct mu3h_sch_tt *tt = NULL; |
| 250 | u32 len_bw_budget_table; | ||
| 251 | 245 | ||
| 252 | bw_info = get_bw_info(mtk, udev, ep); | 246 | bw_info = get_bw_info(mtk, udev, ep); |
| 253 | if (!bw_info) | 247 | if (!bw_info) |
| 254 | return ERR_PTR(-ENODEV); | 248 | return ERR_PTR(-ENODEV); |
| 255 | 249 | ||
| 256 | if (is_fs_or_ls(udev->speed)) | 250 | sch_ep = kzalloc(sizeof(*sch_ep), GFP_KERNEL); |
| 257 | len_bw_budget_table = TT_MICROFRAMES_MAX; | ||
| 258 | else if ((udev->speed >= USB_SPEED_SUPER) | ||
| 259 | && usb_endpoint_xfer_isoc(&ep->desc)) | ||
| 260 | len_bw_budget_table = get_esit(ep_ctx); | ||
| 261 | else | ||
| 262 | len_bw_budget_table = 1; | ||
| 263 | |||
| 264 | sch_ep = kzalloc(struct_size(sch_ep, bw_budget_table, | ||
| 265 | len_bw_budget_table), | ||
| 266 | GFP_KERNEL); | ||
| 267 | if (!sch_ep) | 251 | if (!sch_ep) |
| 268 | return ERR_PTR(-ENOMEM); | 252 | return ERR_PTR(-ENOMEM); |
| 269 | 253 | ||
| @@ -295,8 +279,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, · 25 unmodified lines | |||
| 295 | u32 mult; | 279 | u32 mult; |
| 296 | u32 esit_pkts; | 280 | u32 esit_pkts; |
| 297 | u32 max_esit_payload; | 281 | u32 max_esit_payload; |
| 298 | u32 *bwb_table = sch_ep->bw_budget_table; | ||
| 299 | int i; | ||
| 300 | 282 | ||
| 301 | ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); | 283 | ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); |
| 302 | maxpkt = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); | 284 | maxpkt = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); |
| @@ -332,7 +314,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, · 29 unmodified lines | |||
| 332 | */ | 314 | */ |
| 333 | sch_ep->pkts = max_burst + 1; | 315 | sch_ep->pkts = max_burst + 1; |
| 334 | sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; | 316 | sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; |
| 335 | bwb_table[0] = sch_ep->bw_cost_per_microframe; | ||
| 336 | } else if (sch_ep->speed >= USB_SPEED_SUPER) { | 317 | } else if (sch_ep->speed >= USB_SPEED_SUPER) { |
| 337 | /* usb3_r1 spec section4.4.7 & 4.4.8 */ | 318 | /* usb3_r1 spec section4.4.7 & 4.4.8 */ |
| 338 | sch_ep->cs_count = 0; | 319 | sch_ep->cs_count = 0; |
| @@ -349,7 +330,6 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, · 10 unmodified lines | |||
| 349 | if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { | 330 | if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { |
| 350 | sch_ep->pkts = esit_pkts; | 331 | sch_ep->pkts = esit_pkts; |
| 351 | sch_ep->num_budget_microframes = 1; | 332 | sch_ep->num_budget_microframes = 1; |
| 352 | bwb_table[0] = maxpkt * sch_ep->pkts; | ||
| 353 | } | 333 | } |
| 354 | 334 | ||
| 355 | if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) { | 335 | if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) { |
| @@ -366,15 +346,8 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, · 10 unmodified lines | |||
| 366 | DIV_ROUND_UP(esit_pkts, sch_ep->pkts); | 346 | DIV_ROUND_UP(esit_pkts, sch_ep->pkts); |
| 367 | 347 | ||
| 368 | sch_ep->repeat = !!(sch_ep->num_budget_microframes > 1); | 348 | sch_ep->repeat = !!(sch_ep->num_budget_microframes > 1); |
| 369 | sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; | ||
| 370 | |||
| 371 | for (i = 0; i < sch_ep->num_budget_microframes - 1; i++) | ||
| 372 | bwb_table[i] = sch_ep->bw_cost_per_microframe; | ||
| 373 | |||
| 374 | /* last one <= bw_cost_per_microframe */ | ||
| 375 | bwb_table[i] = maxpkt * esit_pkts | ||
| 376 | - i * sch_ep->bw_cost_per_microframe; | ||
| 377 | } | 349 | } |
| 350 | sch_ep->bw_cost_per_microframe = maxpkt * sch_ep->pkts; | ||
| 378 | } else if (is_fs_or_ls(sch_ep->speed)) { | 351 | } else if (is_fs_or_ls(sch_ep->speed)) { |
| 379 | sch_ep->pkts = 1; /* at most one packet for each microframe */ | 352 | sch_ep->pkts = 1; /* at most one packet for each microframe */ |
| 380 | 353 | ||
| @@ -384,28 +357,7 @@ static void setup_sch_info(struct xhci_ep_ctx *ep_ctx, · 3 unmodified lines | |||
| 384 | */ | 357 | */ |
| 385 | sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX); | 358 | sch_ep->cs_count = DIV_ROUND_UP(maxpkt, FS_PAYLOAD_MAX); |
| 386 | sch_ep->num_budget_microframes = sch_ep->cs_count; | 359 | sch_ep->num_budget_microframes = sch_ep->cs_count; |
| 387 | sch_ep->bw_cost_per_microframe = | 360 | sch_ep->bw_cost_per_microframe = min_t(u32, maxpkt, FS_PAYLOAD_MAX); |
| 388 | (maxpkt < FS_PAYLOAD_MAX) ? maxpkt : FS_PAYLOAD_MAX; | ||
| 389 | |||
| 390 | /* init budget table */ | ||
| 391 | if (ep_type == ISOC_OUT_EP) { | ||
| 392 | for (i = 0; i < sch_ep->num_budget_microframes; i++) | ||
| 393 | bwb_table[i] = sch_ep->bw_cost_per_microframe; | ||
| 394 | } else if (ep_type == INT_OUT_EP) { | ||
| 395 | /* only first one consumes bandwidth, others as zero */ | ||
| 396 | bwb_table[0] = sch_ep->bw_cost_per_microframe; | ||
| 397 | } else { /* INT_IN_EP or ISOC_IN_EP */ | ||
| 398 | bwb_table[0] = 0; /* start split */ | ||
| 399 | bwb_table[1] = 0; /* idle */ | ||
| 400 | /* | ||
| 401 | * due to cs_count will be updated according to cs | ||
| 402 | * position, assign all remainder budget array | ||
| 403 | * elements as @bw_cost_per_microframe, but only first | ||
| 404 | * @num_budget_microframes elements will be used later | ||
| 405 | */ | ||
| 406 | for (i = 2; i < TT_MICROFRAMES_MAX; i++) | ||
| 407 | bwb_table[i] = sch_ep->bw_cost_per_microframe; | ||
| 408 | } | ||
| 409 | } | 361 | } |
| 410 | } | 362 | } |
| 411 | 363 | ||
| @@ -422,7 +374,7 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, · 10 unmodified lines | |||
| 422 | 374 | ||
| 423 | for (j = 0; j < sch_ep->num_budget_microframes; j++) { | 375 | for (j = 0; j < sch_ep->num_budget_microframes; j++) { |
| 424 | k = XHCI_MTK_BW_INDEX(base + j); | 376 | k = XHCI_MTK_BW_INDEX(base + j); |
| 425 | bw = sch_bw->bus_bw[k] + sch_ep->bw_budget_table[j]; | 377 | bw = sch_bw->bus_bw[k] + sch_ep->bw_cost_per_microframe; |
| 426 | if (bw > max_bw) | 378 | if (bw > max_bw) |
| 427 | max_bw = bw; | 379 | max_bw = bw; |
| 428 | } | 380 | } |
| @@ -433,18 +385,16 @@ static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, · 4 unmodified lines | |||
| 433 | static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, | 385 | static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, |
| 434 | struct mu3h_sch_ep_info *sch_ep, bool used) | 386 | struct mu3h_sch_ep_info *sch_ep, bool used) |
| 435 | { | 387 | { |
| 388 | int bw_updated; | ||
| 436 | u32 base; | 389 | u32 base; |
| 437 | int i, j, k; | 390 | int i, j; |
| 391 | |||
| 392 | bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1); | ||
| 438 | 393 | ||
| 439 | for (i = 0; i < sch_ep->num_esit; i++) { | 394 | for (i = 0; i < sch_ep->num_esit; i++) { |
| 440 | base = sch_ep->offset + i * sch_ep->esit; | 395 | base = sch_ep->offset + i * sch_ep->esit; |
| 441 | for (j = 0; j < sch_ep->num_budget_microframes; j++) { | 396 | for (j = 0; j < sch_ep->num_budget_microframes; j++) |
| 442 | k = XHCI_MTK_BW_INDEX(base + j); | 397 | sch_bw->bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated; |
| 443 | if (used) | ||
| 444 | sch_bw->bus_bw[k] += sch_ep->bw_budget_table[j]; | ||
| 445 | else | ||
| 446 | sch_bw->bus_bw[k] -= sch_ep->bw_budget_table[j]; | ||
| 447 | } | ||
| 448 | } | 398 | } |
| 449 | } | 399 | } |
| 450 | 400 | ||
| @@ -464,7 +414,7 @@ static int check_fs_bus_bw(struct mu3h_sch_ep_info *sch_ep, int offset) · 13 unmodified lines | |||
| 464 | */ | 414 | */ |
| 465 | for (j = 0; j < sch_ep->num_budget_microframes; j++) { | 415 | for (j = 0; j < sch_ep->num_budget_microframes; j++) { |
| 466 | k = XHCI_MTK_BW_INDEX(base + j); | 416 | k = XHCI_MTK_BW_INDEX(base + j); |
| 467 | tmp = tt->fs_bus_bw[k] + sch_ep->bw_budget_table[j]; | 417 | tmp = tt->fs_bus_bw[k] + sch_ep->bw_cost_per_microframe; |
| 468 | if (tmp > FS_PAYLOAD_MAX) | 418 | if (tmp > FS_PAYLOAD_MAX) |
| 469 | return -ESCH_BW_OVERFLOW; | 419 | return -ESCH_BW_OVERFLOW; |
| 470 | } | 420 | } |
| @@ -538,19 +488,17 @@ static int check_sch_tt(struct mu3h_sch_ep_info *sch_ep, u32 offset) · 67 unmodified lines | |||
| 538 | static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) | 488 | static void update_sch_tt(struct mu3h_sch_ep_info *sch_ep, bool used) |
| 539 | { | 489 | { |
| 540 | struct mu3h_sch_tt *tt = sch_ep->sch_tt; | 490 | struct mu3h_sch_tt *tt = sch_ep->sch_tt; |
| 491 | int bw_updated; | ||
| 541 | u32 base; | 492 | u32 base; |
| 542 | int i, j, k; | 493 | int i, j; |
| 494 | |||
| 495 | bw_updated = sch_ep->bw_cost_per_microframe * (used ? 1 : -1); | ||
| 543 | 496 | ||
| 544 | for (i = 0; i < sch_ep->num_esit; i++) { | 497 | for (i = 0; i < sch_ep->num_esit; i++) { |
| 545 | base = sch_ep->offset + i * sch_ep->esit; | 498 | base = sch_ep->offset + i * sch_ep->esit; |
| 546 | 499 | ||
| 547 | for (j = 0; j < sch_ep->num_budget_microframes; j++) { | 500 | for (j = 0; j < sch_ep->num_budget_microframes; j++) |
| 548 | k = XHCI_MTK_BW_INDEX(base + j); | 501 | tt->fs_bus_bw[XHCI_MTK_BW_INDEX(base + j)] += bw_updated; |
| 549 | if (used) | ||
| 550 | tt->fs_bus_bw[k] += sch_ep->bw_budget_table[j]; | ||
| 551 | else | ||
| 552 | tt->fs_bus_bw[k] -= sch_ep->bw_budget_table[j]; | ||
| 553 | } | ||
| 554 | } | 502 | } |
| 555 | 503 | ||
| 556 | if (used) | 504 | if (used) |
| @@ -710,7 +658,7 @@ static int add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, · 153 unmodified lines | |||
| 710 | 658 | ||
| 711 | xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed)); | 659 | xhci_dbg(xhci, "%s %s\n", __func__, decode_ep(ep, udev->speed)); |
| 712 | 660 | ||
| 713 | sch_ep = create_sch_ep(mtk, udev, ep, ep_ctx); | 661 | sch_ep = create_sch_ep(mtk, udev, ep); |
| 714 | if (IS_ERR_OR_NULL(sch_ep)) | 662 | if (IS_ERR_OR_NULL(sch_ep)) |
| 715 | return -ENOMEM; | 663 | return -ENOMEM; |
| 716 | 664 | ||
| @@ -83,7 +83,6 @@ struct mu3h_sch_bw_info { · 82 unmodified lines | |||
| 83 | * times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets | 83 | * times; 1: distribute the (bMaxBurst+1)*(Mult+1) packets |
| 84 | * according to @pkts and @repeat. normal mode is used by | 84 | * according to @pkts and @repeat. normal mode is used by |
| 85 | * default | 85 | * default |
| 86 | * @bw_budget_table: table to record bandwidth budget per microframe | ||
| 87 | */ | 86 | */ |
| 88 | struct mu3h_sch_ep_info { | 87 | struct mu3h_sch_ep_info { |
| 89 | u32 esit; | 88 | u32 esit; |
| @@ -109,7 +108,6 @@ struct mu3h_sch_ep_info { · 19 unmodified lines | |||
| 109 | u32 pkts; | 108 | u32 pkts; |
| 110 | u32 cs_count; | 109 | u32 cs_count; |
| 111 | u32 burst_mode; | 110 | u32 burst_mode; |
| 112 | u32 bw_budget_table[]; | ||
| 113 | }; | 111 | }; |
| 114 | 112 | ||
| 115 | #define MU3C_U3_PORT_MAX 4 | 113 | #define MU3C_U3_PORT_MAX 4 |
| @@ -59,6 +59,7 @@ · 58 unmodified lines | |||
| 59 | #define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13 | 59 | #define PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI 0x9a13 |
| 60 | #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138 | 60 | #define PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI 0x1138 |
| 61 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e | 61 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI 0x461e |
| 62 | #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI 0x51ed | ||
| 62 | 63 | ||
| 63 | #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 | 64 | #define PCI_DEVICE_ID_AMD_RENOIR_XHCI 0x1639 |
| 64 | #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 | 65 | #define PCI_DEVICE_ID_AMD_PROMONTORYA_4 0x43b9 |
| @@ -266,7 +267,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) · 201 unmodified lines | |||
| 266 | pdev->device == PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI || | 267 | pdev->device == PCI_DEVICE_ID_INTEL_ICE_LAKE_XHCI || |
| 267 | pdev->device == PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI || | 268 | pdev->device == PCI_DEVICE_ID_INTEL_TIGER_LAKE_XHCI || |
| 268 | pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI || | 269 | pdev->device == PCI_DEVICE_ID_INTEL_MAPLE_RIDGE_XHCI || |
| 269 | pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI)) | 270 | pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_XHCI || |
| 271 | pdev->device == PCI_DEVICE_ID_INTEL_ALDER_LAKE_PCH_XHCI)) | ||
| 270 | xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; | 272 | xhci->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; |
| 271 | 273 | ||
| 272 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && | 274 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && |
| @@ -3141,6 +3141,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) · 3140 unmodified lines | |||
| 3141 | if (event_loop++ < TRBS_PER_SEGMENT / 2) | 3141 | if (event_loop++ < TRBS_PER_SEGMENT / 2) |
| 3142 | continue; | 3142 | continue; |
| 3143 | xhci_update_erst_dequeue(xhci, event_ring_deq); | 3143 | xhci_update_erst_dequeue(xhci, event_ring_deq); |
| 3144 | event_ring_deq = xhci->event_ring->dequeue; | ||
| 3144 | 3145 | ||
| 3145 | /* ring is half-full, force isoc trbs to interrupt more often */ | 3146 | /* ring is half-full, force isoc trbs to interrupt more often */ |
| 3146 | if (xhci->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN) | 3147 | if (xhci->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN) |
| @@ -1034,13 +1034,13 @@ static int tegra_xusb_unpowergate_partitions(struct tegra_xusb *tegra) · 1033 unmodified lines | |||
| 1034 | int rc; | 1034 | int rc; |
| 1035 | 1035 | ||
| 1036 | if (tegra->use_genpd) { | 1036 | if (tegra->use_genpd) { |
| 1037 | rc = pm_runtime_get_sync(tegra->genpd_dev_ss); | 1037 | rc = pm_runtime_resume_and_get(tegra->genpd_dev_ss); |
| 1038 | if (rc < 0) { | 1038 | if (rc < 0) { |
| 1039 | dev_err(dev, "failed to enable XUSB SS partition\n"); | 1039 | dev_err(dev, "failed to enable XUSB SS partition\n"); |
| 1040 | return rc; | 1040 | return rc; |
| 1041 | } | 1041 | } |
| 1042 | 1042 | ||
| 1043 | rc = pm_runtime_get_sync(tegra->genpd_dev_host); | 1043 | rc = pm_runtime_resume_and_get(tegra->genpd_dev_host); |
| 1044 | if (rc < 0) { | 1044 | if (rc < 0) { |
| 1045 | dev_err(dev, "failed to enable XUSB Host partition\n"); | 1045 | dev_err(dev, "failed to enable XUSB Host partition\n"); |
| 1046 | pm_runtime_put_sync(tegra->genpd_dev_ss); | 1046 | pm_runtime_put_sync(tegra->genpd_dev_ss); |
| @@ -781,6 +781,17 @@ void xhci_shutdown(struct usb_hcd *hcd) · 780 unmodified lines | |||
| 781 | if (xhci->quirks & XHCI_SPURIOUS_REBOOT) | 781 | if (xhci->quirks & XHCI_SPURIOUS_REBOOT) |
| 782 | usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev)); | 782 | usb_disable_xhci_ports(to_pci_dev(hcd->self.sysdev)); |
| 783 | 783 | ||
| 784 | /* Don't poll the roothubs after shutdown. */ | ||
| 785 | xhci_dbg(xhci, "%s: stopping usb%d port polling.\n", | ||
| 786 | __func__, hcd->self.busnum); | ||
| 787 | clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); | ||
| 788 | del_timer_sync(&hcd->rh_timer); | ||
| 789 | |||
| 790 | if (xhci->shared_hcd) { | ||
| 791 | clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); | ||
| 792 | del_timer_sync(&xhci->shared_hcd->rh_timer); | ||
| 793 | } | ||
| 794 | |||
| 784 | spin_lock_irq(&xhci->lock); | 795 | spin_lock_irq(&xhci->lock); |
| 785 | xhci_halt(xhci); | 796 | xhci_halt(xhci); |
| 786 | /* Workaround for spurious wakeups at shutdown with HSW */ | 797 | /* Workaround for spurious wakeups at shutdown with HSW */ |
| @@ -186,16 +186,16 @@ static int eud_probe(struct platform_device *pdev) · 185 unmodified lines | |||
| 186 | 186 | ||
| 187 | chip->dev = &pdev->dev; | 187 | chip->dev = &pdev->dev; |
| 188 | 188 | ||
| 189 | ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip); | ||
| 190 | if (ret) | ||
| 191 | return dev_err_probe(chip->dev, ret, | ||
| 192 | "failed to add role switch release action\n"); | ||
| 193 | |||
| 194 | chip->role_sw = usb_role_switch_get(&pdev->dev); | 189 | chip->role_sw = usb_role_switch_get(&pdev->dev); |
| 195 | if (IS_ERR(chip->role_sw)) | 190 | if (IS_ERR(chip->role_sw)) |
| 196 | return dev_err_probe(chip->dev, PTR_ERR(chip->role_sw), | 191 | return dev_err_probe(chip->dev, PTR_ERR(chip->role_sw), |
| 197 | "failed to get role switch\n"); | 192 | "failed to get role switch\n"); |
| 198 | 193 | ||
| 194 | ret = devm_add_action_or_reset(chip->dev, eud_role_switch_release, chip); | ||
| 195 | if (ret) | ||
| 196 | return dev_err_probe(chip->dev, ret, | ||
| 197 | "failed to add role switch release action\n"); | ||
| 198 | |||
| 199 | chip->base = devm_platform_ioremap_resource(pdev, 0); | 199 | chip->base = devm_platform_ioremap_resource(pdev, 0); |
| 200 | if (IS_ERR(chip->base)) | 200 | if (IS_ERR(chip->base)) |
| 201 | return PTR_ERR(chip->base); | 201 | return PTR_ERR(chip->base); |
| @@ -71,6 +71,7 @@ static void destroy_priv(struct kref *kref) · 70 unmodified lines | |||
| 71 | 71 | ||
| 72 | dev_dbg(&priv->usbdev->dev, "destroying priv datastructure\n"); | 72 | dev_dbg(&priv->usbdev->dev, "destroying priv datastructure\n"); |
| 73 | usb_put_dev(priv->usbdev); | 73 | usb_put_dev(priv->usbdev); |
| 74 | priv->usbdev = NULL; | ||
| 74 | kfree(priv); | 75 | kfree(priv); |
| 75 | } | 76 | } |
| 76 | 77 | ||
| @@ -736,7 +737,6 @@ static int uss720_probe(struct usb_interface *intf, · 659 unmodified lines | |||
| 736 | parport_announce_port(pp); | 737 | parport_announce_port(pp); |
| 737 | 738 | ||
| 738 | usb_set_intfdata(intf, pp); | 739 | usb_set_intfdata(intf, pp); |
| 739 | usb_put_dev(usbdev); | ||
| 740 | return 0; | 740 | return 0; |
| 741 | 741 | ||
| 742 | probe_abort: | 742 | probe_abort: |
| @@ -754,7 +754,6 @@ static void uss720_disconnect(struct usb_interface *intf) · 11 unmodified lines | |||
| 754 | usb_set_intfdata(intf, NULL); | 754 | usb_set_intfdata(intf, NULL); |
| 755 | if (pp) { | 755 | if (pp) { |
| 756 | priv = pp->private_data; | 756 | priv = pp->private_data; |
| 757 | priv->usbdev = NULL; | ||
| 758 | priv->pp = NULL; | 757 | priv->pp = NULL; |
| 759 | dev_dbg(&intf->dev, "parport_remove_port\n"); | 758 | dev_dbg(&intf->dev, "parport_remove_port\n"); |
| 760 | parport_remove_port(pp); | 759 | parport_remove_port(pp); |
| @@ -21,10 +21,8 @@ static inline struct ssusb_mtk *otg_sx_to_ssusb(struct otg_switch_mtk *otg_sx) · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | static void toggle_opstate(struct ssusb_mtk *ssusb) | 22 | static void toggle_opstate(struct ssusb_mtk *ssusb) |
| 23 | { | 23 | { |
| 24 | if (!ssusb->otg_switch.is_u3_drd) { | 24 | mtu3_setbits(ssusb->mac_base, U3D_DEVICE_CONTROL, DC_SESSION); |
| 25 | mtu3_setbits(ssusb->mac_base, U3D_DEVICE_CONTROL, DC_SESSION); | 25 | mtu3_setbits(ssusb->mac_base, U3D_POWER_MANAGEMENT, SOFT_CONN); |
| 26 | mtu3_setbits(ssusb->mac_base, U3D_POWER_MANAGEMENT, SOFT_CONN); | ||
| 27 | } | ||
| 28 | } | 26 | } |
| 29 | 27 | ||
| 30 | /* only port0 supports dual-role mode */ | 28 | /* only port0 supports dual-role mode */ |
| @@ -268,6 +268,13 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop) · 267 unmodified lines | |||
| 268 | return -EPROBE_DEFER; | 268 | return -EPROBE_DEFER; |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | nop->vbus_draw = devm_regulator_get_exclusive(dev, "vbus"); | ||
| 272 | if (PTR_ERR(nop->vbus_draw) == -ENODEV) | ||
| 273 | nop->vbus_draw = NULL; | ||
| 274 | if (IS_ERR(nop->vbus_draw)) | ||
| 275 | return dev_err_probe(dev, PTR_ERR(nop->vbus_draw), | ||
| 276 | "could not get vbus regulator\n"); | ||
| 277 | |||
| 271 | nop->dev = dev; | 278 | nop->dev = dev; |
| 272 | nop->phy.dev = nop->dev; | 279 | nop->phy.dev = nop->dev; |
| 273 | nop->phy.label = "nop-xceiv"; | 280 | nop->phy.label = "nop-xceiv"; |
| @@ -194,6 +194,8 @@ static const struct usb_device_id id_table[] = { · 193 unmodified lines | |||
| 194 | { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */ | 194 | { USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */ |
| 195 | { USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */ | 195 | { USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */ |
| 196 | { USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */ | 196 | { USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */ |
| 197 | { USB_DEVICE(0x17A8, 0x0101) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Int Ant) */ | ||
| 198 | { USB_DEVICE(0x17A8, 0x0102) }, /* Kamstrup 868 MHz wM-Bus C-Mode Meter Reader (Ext Ant) */ | ||
| 197 | { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ | 199 | { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ |
| 198 | { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ | 200 | { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ |
| 199 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ | 201 | { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ |
| @@ -432,6 +432,8 @@ static void option_instat_callback(struct urb *urb); · 431 unmodified lines | |||
| 432 | #define CINTERION_PRODUCT_CLS8 0x00b0 | 432 | #define CINTERION_PRODUCT_CLS8 0x00b0 |
| 433 | #define CINTERION_PRODUCT_MV31_MBIM 0x00b3 | 433 | #define CINTERION_PRODUCT_MV31_MBIM 0x00b3 |
| 434 | #define CINTERION_PRODUCT_MV31_RMNET 0x00b7 | 434 | #define CINTERION_PRODUCT_MV31_RMNET 0x00b7 |
| 435 | #define CINTERION_PRODUCT_MV32_WA 0x00f1 | ||
| 436 | #define CINTERION_PRODUCT_MV32_WB 0x00f2 | ||
| 435 | 437 | ||
| 436 | /* Olivetti products */ | 438 | /* Olivetti products */ |
| 437 | #define OLIVETTI_VENDOR_ID 0x0b3c | 439 | #define OLIVETTI_VENDOR_ID 0x0b3c |
| @@ -1217,6 +1219,10 @@ static const struct usb_device_id option_ids[] = { · 779 unmodified lines | |||
| 1217 | .driver_info = NCTRL(0) | RSVD(1) }, | 1219 | .driver_info = NCTRL(0) | RSVD(1) }, |
| 1218 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1056, 0xff), /* Telit FD980 */ | 1220 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1056, 0xff), /* Telit FD980 */ |
| 1219 | .driver_info = NCTRL(2) | RSVD(3) }, | 1221 | .driver_info = NCTRL(2) | RSVD(3) }, |
| 1222 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1057, 0xff), /* Telit FN980 */ | ||
| 1223 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, | ||
| 1224 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1058, 0xff), /* Telit FN980 (PCIe) */ | ||
| 1225 | .driver_info = NCTRL(0) | RSVD(1) }, | ||
| 1220 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1060, 0xff), /* Telit LN920 (rmnet) */ | 1226 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1060, 0xff), /* Telit LN920 (rmnet) */ |
| 1221 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, | 1227 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, |
| 1222 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1061, 0xff), /* Telit LN920 (MBIM) */ | 1228 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1061, 0xff), /* Telit LN920 (MBIM) */ |
| @@ -1233,6 +1239,8 @@ static const struct usb_device_id option_ids[] = { · 10 unmodified lines | |||
| 1233 | .driver_info = NCTRL(2) | RSVD(3) }, | 1239 | .driver_info = NCTRL(2) | RSVD(3) }, |
| 1234 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */ | 1240 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff), /* Telit FN990 (ECM) */ |
| 1235 | .driver_info = NCTRL(0) | RSVD(1) }, | 1241 | .driver_info = NCTRL(0) | RSVD(1) }, |
| 1242 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff), /* Telit FN990 (PCIe) */ | ||
| 1243 | .driver_info = RSVD(0) }, | ||
| 1236 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), | 1244 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), |
| 1237 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, | 1245 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, |
| 1238 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), | 1246 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), |
| @@ -1969,6 +1977,10 @@ static const struct usb_device_id option_ids[] = { · 730 unmodified lines | |||
| 1969 | .driver_info = RSVD(3)}, | 1977 | .driver_info = RSVD(3)}, |
| 1970 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff), | 1978 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff), |
| 1971 | .driver_info = RSVD(0)}, | 1979 | .driver_info = RSVD(0)}, |
| 1980 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff), | ||
| 1981 | .driver_info = RSVD(3)}, | ||
| 1982 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff), | ||
| 1983 | .driver_info = RSVD(3)}, | ||
| 1972 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100), | 1984 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100), |
| 1973 | .driver_info = RSVD(4) }, | 1985 | .driver_info = RSVD(4) }, |
| 1974 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120), | 1986 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120), |
| @@ -2111,10 +2123,14 @@ static const struct usb_device_id option_ids[] = { · 136 unmodified lines | |||
| 2111 | .driver_info = RSVD(3) }, | 2123 | .driver_info = RSVD(3) }, |
| 2112 | { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */ | 2124 | { USB_DEVICE(0x1508, 0x1001), /* Fibocom NL668 (IOT version) */ |
| 2113 | .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, | 2125 | .driver_info = RSVD(4) | RSVD(5) | RSVD(6) }, |
| 2126 | { USB_DEVICE(0x1782, 0x4d10) }, /* Fibocom L610 (AT mode) */ | ||
| 2127 | { USB_DEVICE_INTERFACE_CLASS(0x1782, 0x4d11, 0xff) }, /* Fibocom L610 (ECM/RNDIS mode) */ | ||
| 2114 | { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */ | 2128 | { USB_DEVICE(0x2cb7, 0x0104), /* Fibocom NL678 series */ |
| 2115 | .driver_info = RSVD(4) | RSVD(5) }, | 2129 | .driver_info = RSVD(4) | RSVD(5) }, |
| 2116 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ | 2130 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ |
| 2117 | .driver_info = RSVD(6) }, | 2131 | .driver_info = RSVD(6) }, |
| 2132 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0106, 0xff) }, /* Fibocom MA510 (ECM mode w/ diag intf.) */ | ||
| 2133 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x010a, 0xff) }, /* Fibocom MA510 (ECM mode) */ | ||
| 2118 | { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */ | 2134 | { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */ |
| 2119 | { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */ | 2135 | { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */ |
| 2120 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ | 2136 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ |
| @@ -106,6 +106,7 @@ static const struct usb_device_id id_table[] = { · 105 unmodified lines | |||
| 106 | { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) }, | 106 | { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) }, |
| 107 | { USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) }, | 107 | { USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) }, |
| 108 | { USB_DEVICE(HP_VENDOR_ID, HP_LM920_PRODUCT_ID) }, | 108 | { USB_DEVICE(HP_VENDOR_ID, HP_LM920_PRODUCT_ID) }, |
| 109 | { USB_DEVICE(HP_VENDOR_ID, HP_LM930_PRODUCT_ID) }, | ||
| 109 | { USB_DEVICE(HP_VENDOR_ID, HP_LM940_PRODUCT_ID) }, | 110 | { USB_DEVICE(HP_VENDOR_ID, HP_LM940_PRODUCT_ID) }, |
| 110 | { USB_DEVICE(HP_VENDOR_ID, HP_TD620_PRODUCT_ID) }, | 111 | { USB_DEVICE(HP_VENDOR_ID, HP_TD620_PRODUCT_ID) }, |
| 111 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, | 112 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, |
| @@ -135,6 +135,7 @@ · 134 unmodified lines | |||
| 135 | #define HP_TD620_PRODUCT_ID 0x0956 | 135 | #define HP_TD620_PRODUCT_ID 0x0956 |
| 136 | #define HP_LD960_PRODUCT_ID 0x0b39 | 136 | #define HP_LD960_PRODUCT_ID 0x0b39 |
| 137 | #define HP_LD381_PRODUCT_ID 0x0f7f | 137 | #define HP_LD381_PRODUCT_ID 0x0f7f |
| 138 | #define HP_LM930_PRODUCT_ID 0x0f9b | ||
| 138 | #define HP_LCM220_PRODUCT_ID 0x3139 | 139 | #define HP_LCM220_PRODUCT_ID 0x3139 |
| 139 | #define HP_LCM960_PRODUCT_ID 0x3239 | 140 | #define HP_LCM960_PRODUCT_ID 0x3239 |
| 140 | #define HP_LD220_PRODUCT_ID 0x3524 | 141 | #define HP_LD220_PRODUCT_ID 0x3524 |
| @@ -166,6 +166,8 @@ static const struct usb_device_id id_table[] = { · 165 unmodified lines | |||
| 166 | {DEVICE_SWI(0x1199, 0x9090)}, /* Sierra Wireless EM7565 QDL */ | 166 | {DEVICE_SWI(0x1199, 0x9090)}, /* Sierra Wireless EM7565 QDL */ |
| 167 | {DEVICE_SWI(0x1199, 0x9091)}, /* Sierra Wireless EM7565 */ | 167 | {DEVICE_SWI(0x1199, 0x9091)}, /* Sierra Wireless EM7565 */ |
| 168 | {DEVICE_SWI(0x1199, 0x90d2)}, /* Sierra Wireless EM9191 QDL */ | 168 | {DEVICE_SWI(0x1199, 0x90d2)}, /* Sierra Wireless EM9191 QDL */ |
| 169 | {DEVICE_SWI(0x1199, 0xc080)}, /* Sierra Wireless EM7590 QDL */ | ||
| 170 | {DEVICE_SWI(0x1199, 0xc081)}, /* Sierra Wireless EM7590 */ | ||
| 169 | {DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ | 171 | {DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ |
| 170 | {DEVICE_SWI(0x413c, 0x81a3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */ | 172 | {DEVICE_SWI(0x413c, 0x81a3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */ |
| 171 | {DEVICE_SWI(0x413c, 0x81a4)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ | 173 | {DEVICE_SWI(0x413c, 0x81a4)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ |
| @@ -584,9 +584,8 @@ static int firm_send_command(struct usb_serial_port *port, __u8 command, · 583 unmodified lines | |||
| 584 | switch (command) { | 584 | switch (command) { |
| 585 | case WHITEHEAT_GET_DTR_RTS: | 585 | case WHITEHEAT_GET_DTR_RTS: |
| 586 | info = usb_get_serial_port_data(port); | 586 | info = usb_get_serial_port_data(port); |
| 587 | memcpy(&info->mcr, command_info->result_buffer, | 587 | info->mcr = command_info->result_buffer[0]; |
| 588 | sizeof(struct whiteheat_dr_info)); | 588 | break; |
| 589 | break; | ||
| 590 | } | 589 | } |
| 591 | } | 590 | } |
| 592 | exit: | 591 | exit: |
| @@ -56,6 +56,7 @@ config TYPEC_RT1719 · 55 unmodified lines | |||
| 56 | tristate "Richtek RT1719 Sink Only Type-C controller driver" | 56 | tristate "Richtek RT1719 Sink Only Type-C controller driver" |
| 57 | depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH | 57 | depends on USB_ROLE_SWITCH || !USB_ROLE_SWITCH |
| 58 | depends on I2C | 58 | depends on I2C |
| 59 | depends on POWER_SUPPLY | ||
| 59 | select REGMAP_I2C | 60 | select REGMAP_I2C |
| 60 | help | 61 | help |
| 61 | Say Y or M here if your system has Richtek RT1719 sink only | 62 | Say Y or M here if your system has Richtek RT1719 sink only |
| @@ -877,7 +877,7 @@ static int tcpci_remove(struct i2c_client *client) · 876 unmodified lines | |||
| 877 | /* Disable chip interrupts before unregistering port */ | 877 | /* Disable chip interrupts before unregistering port */ |
| 878 | err = tcpci_write16(chip->tcpci, TCPC_ALERT_MASK, 0); | 878 | err = tcpci_write16(chip->tcpci, TCPC_ALERT_MASK, 0); |
| 879 | if (err < 0) | 879 | if (err < 0) |
| 880 | return err; | 880 | dev_warn(&client->dev, "Failed to disable irqs (%pe)\n", ERR_PTR(err)); |
| 881 | 881 | ||
| 882 | tcpci_unregister_port(chip->tcpci); | 882 | tcpci_unregister_port(chip->tcpci); |
| 883 | 883 | ||
| @@ -15,6 +15,9 @@ · 14 unmodified lines | |||
| 15 | 15 | ||
| 16 | #include "tcpci.h" | 16 | #include "tcpci.h" |
| 17 | 17 | ||
| 18 | #define MT6360_REG_PHYCTRL1 0x80 | ||
| 19 | #define MT6360_REG_PHYCTRL3 0x82 | ||
| 20 | #define MT6360_REG_PHYCTRL7 0x86 | ||
| 18 | #define MT6360_REG_VCONNCTRL1 0x8C | 21 | #define MT6360_REG_VCONNCTRL1 0x8C |
| 19 | #define MT6360_REG_MODECTRL2 0x8F | 22 | #define MT6360_REG_MODECTRL2 0x8F |
| 20 | #define MT6360_REG_SWRESET 0xA0 | 23 | #define MT6360_REG_SWRESET 0xA0 |
| @@ -22,6 +25,8 @@ · 1 unmodified line | |||
| 22 | #define MT6360_REG_DRPCTRL1 0xA2 | 25 | #define MT6360_REG_DRPCTRL1 0xA2 |
| 23 | #define MT6360_REG_DRPCTRL2 0xA3 | 26 | #define MT6360_REG_DRPCTRL2 0xA3 |
| 24 | #define MT6360_REG_I2CTORST 0xBF | 27 | #define MT6360_REG_I2CTORST 0xBF |
| 28 | #define MT6360_REG_PHYCTRL11 0xCA | ||
| 29 | #define MT6360_REG_RXCTRL1 0xCE | ||
| 25 | #define MT6360_REG_RXCTRL2 0xCF | 30 | #define MT6360_REG_RXCTRL2 0xCF |
| 26 | #define MT6360_REG_CTDCTRL2 0xEC | 31 | #define MT6360_REG_CTDCTRL2 0xEC |
| 27 | 32 | ||
| @@ -106,6 +111,27 @@ static int mt6360_tcpc_init(struct tcpci *tcpci, struct tcpci_data *tdata) · 78 unmodified lines | |||
| 106 | if (ret) | 111 | if (ret) |
| 107 | return ret; | 112 | return ret; |
| 108 | 113 | ||
| 114 | /* BMC PHY */ | ||
| 115 | ret = mt6360_tcpc_write16(regmap, MT6360_REG_PHYCTRL1, 0x3A70); | ||
| 116 | if (ret) | ||
| 117 | return ret; | ||
| 118 | |||
| 119 | ret = regmap_write(regmap, MT6360_REG_PHYCTRL3, 0x82); | ||
| 120 | if (ret) | ||
| 121 | return ret; | ||
| 122 | |||
| 123 | ret = regmap_write(regmap, MT6360_REG_PHYCTRL7, 0x36); | ||
| 124 | if (ret) | ||
| 125 | return ret; | ||
| 126 | |||
| 127 | ret = mt6360_tcpc_write16(regmap, MT6360_REG_PHYCTRL11, 0x3C60); | ||
| 128 | if (ret) | ||
| 129 | return ret; | ||
| 130 | |||
| 131 | ret = regmap_write(regmap, MT6360_REG_RXCTRL1, 0xE8); | ||
| 132 | if (ret) | ||
| 133 | return ret; | ||
| 134 | |||
| 109 | /* Set shipping mode off, AUTOIDLE on */ | 135 | /* Set shipping mode off, AUTOIDLE on */ |
| 110 | return regmap_write(regmap, MT6360_REG_MODECTRL2, 0x7A); | 136 | return regmap_write(regmap, MT6360_REG_MODECTRL2, 0x7A); |
| 111 | } | 137 | } |
| @@ -949,6 +949,8 @@ static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role) · 948 unmodified lines | |||
| 949 | role == TYPEC_HOST)) | 949 | role == TYPEC_HOST)) |
| 950 | goto out_unlock; | 950 | goto out_unlock; |
| 951 | 951 | ||
| 952 | reinit_completion(&con->complete); | ||
| 953 | |||
| 952 | command = UCSI_SET_UOR | UCSI_CONNECTOR_NUMBER(con->num); | 954 | command = UCSI_SET_UOR | UCSI_CONNECTOR_NUMBER(con->num); |
| 953 | command |= UCSI_SET_UOR_ROLE(role); | 955 | command |= UCSI_SET_UOR_ROLE(role); |
| 954 | command |= UCSI_SET_UOR_ACCEPT_ROLE_SWAPS; | 956 | command |= UCSI_SET_UOR_ACCEPT_ROLE_SWAPS; |
| @@ -956,14 +958,18 @@ static int ucsi_dr_swap(struct typec_port *port, enum typec_data_role role) · 1 unmodified line | |||
| 956 | if (ret < 0) | 958 | if (ret < 0) |
| 957 | goto out_unlock; | 959 | goto out_unlock; |
| 958 | 960 | ||
| 961 | mutex_unlock(&con->lock); | ||
| 962 | |||
| 959 | if (!wait_for_completion_timeout(&con->complete, | 963 | if (!wait_for_completion_timeout(&con->complete, |
| 960 | msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS))) | 964 | msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS))) |
| 961 | ret = -ETIMEDOUT; | 965 | return -ETIMEDOUT; |
| 966 | |||
| 967 | return 0; | ||
| 962 | 968 | ||
| 963 | out_unlock: | 969 | out_unlock: |
| 964 | mutex_unlock(&con->lock); | 970 | mutex_unlock(&con->lock); |
| 965 | 971 | ||
| 966 | return ret < 0 ? ret : 0; | 972 | return ret; |
| 967 | } | 973 | } |
| 968 | 974 | ||
| 969 | static int ucsi_pr_swap(struct typec_port *port, enum typec_role role) | 975 | static int ucsi_pr_swap(struct typec_port *port, enum typec_role role) |
| @@ -985,6 +991,8 @@ static int ucsi_pr_swap(struct typec_port *port, enum typec_role role) · 15 unmodified lines | |||
| 985 | if (cur_role == role) | 991 | if (cur_role == role) |
| 986 | goto out_unlock; | 992 | goto out_unlock; |
| 987 | 993 | ||
| 994 | reinit_completion(&con->complete); | ||
| 995 | |||
| 988 | command = UCSI_SET_PDR | UCSI_CONNECTOR_NUMBER(con->num); | 996 | command = UCSI_SET_PDR | UCSI_CONNECTOR_NUMBER(con->num); |
| 989 | command |= UCSI_SET_PDR_ROLE(role); | 997 | command |= UCSI_SET_PDR_ROLE(role); |
| 990 | command |= UCSI_SET_PDR_ACCEPT_ROLE_SWAPS; | 998 | command |= UCSI_SET_PDR_ACCEPT_ROLE_SWAPS; |
| @@ -992,11 +1000,13 @@ static int ucsi_pr_swap(struct typec_port *port, enum typec_role role) · 1 unmodified line | |||
| 992 | if (ret < 0) | 1000 | if (ret < 0) |
| 993 | goto out_unlock; | 1001 | goto out_unlock; |
| 994 | 1002 | ||
| 1003 | mutex_unlock(&con->lock); | ||
| 1004 | |||
| 995 | if (!wait_for_completion_timeout(&con->complete, | 1005 | if (!wait_for_completion_timeout(&con->complete, |
| 996 | msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS))) { | 1006 | msecs_to_jiffies(UCSI_SWAP_TIMEOUT_MS))) |
| 997 | ret = -ETIMEDOUT; | 1007 | return -ETIMEDOUT; |
| 998 | goto out_unlock; | 1008 | |
| 999 | } | 1009 | mutex_lock(&con->lock); |
| 1000 | 1010 | ||
| 1001 | /* Something has gone wrong while swapping the role */ | 1011 | /* Something has gone wrong while swapping the role */ |
| 1002 | if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) != | 1012 | if (UCSI_CONSTAT_PWR_OPMODE(con->status.flags) != |
| @@ -588,6 +588,7 @@ static struct fsl_mc_driver vfio_fsl_mc_driver = { · 587 unmodified lines | |||
| 588 | .name = "vfio-fsl-mc", | 588 | .name = "vfio-fsl-mc", |
| 589 | .owner = THIS_MODULE, | 589 | .owner = THIS_MODULE, |
| 590 | }, | 590 | }, |
| 591 | .driver_managed_dma = true, | ||
| 591 | }; | 592 | }; |
| 592 | 593 | ||
| 593 | static int __init vfio_fsl_mc_driver_init(void) | 594 | static int __init vfio_fsl_mc_driver_init(void) |
| @@ -194,6 +194,7 @@ static struct pci_driver vfio_pci_driver = { · 193 unmodified lines | |||
| 194 | .remove = vfio_pci_remove, | 194 | .remove = vfio_pci_remove, |
| 195 | .sriov_configure = vfio_pci_sriov_configure, | 195 | .sriov_configure = vfio_pci_sriov_configure, |
| 196 | .err_handler = &vfio_pci_core_err_handlers, | 196 | .err_handler = &vfio_pci_core_err_handlers, |
| 197 | .driver_managed_dma = true, | ||
| 197 | }; | 198 | }; |
| 198 | 199 | ||
| 199 | static void __init vfio_pci_fill_ids(void) | 200 | static void __init vfio_pci_fill_ids(void) |
| @@ -95,6 +95,7 @@ static struct amba_driver vfio_amba_driver = { · 94 unmodified lines | |||
| 95 | .name = "vfio-amba", | 95 | .name = "vfio-amba", |
| 96 | .owner = THIS_MODULE, | 96 | .owner = THIS_MODULE, |
| 97 | }, | 97 | }, |
| 98 | .driver_managed_dma = true, | ||
| 98 | }; | 99 | }; |
| 99 | 100 | ||
| 100 | module_amba_driver(vfio_amba_driver); | 101 | module_amba_driver(vfio_amba_driver); |
| @@ -76,6 +76,7 @@ static struct platform_driver vfio_platform_driver = { · 75 unmodified lines | |||
| 76 | .driver = { | 76 | .driver = { |
| 77 | .name = "vfio-platform", | 77 | .name = "vfio-platform", |
| 78 | }, | 78 | }, |
| 79 | .driver_managed_dma = true, | ||
| 79 | }; | 80 | }; |
| 80 | 81 | ||
| 81 | module_platform_driver(vfio_platform_driver); | 82 | module_platform_driver(vfio_platform_driver); |
| @@ -62,11 +62,6 @@ struct vfio_container { · 61 unmodified lines | |||
| 62 | bool noiommu; | 62 | bool noiommu; |
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | struct vfio_unbound_dev { | ||
| 66 | struct device *dev; | ||
| 67 | struct list_head unbound_next; | ||
| 68 | }; | ||
| 69 | |||
| 70 | struct vfio_group { | 65 | struct vfio_group { |
| 71 | struct device dev; | 66 | struct device dev; |
| 72 | struct cdev cdev; | 67 | struct cdev cdev; |
| @@ -76,11 +71,8 @@ struct vfio_group { · 3 unmodified lines | |||
| 76 | struct vfio_container *container; | 71 | struct vfio_container *container; |
| 77 | struct list_head device_list; | 72 | struct list_head device_list; |
| 78 | struct mutex device_lock; | 73 | struct mutex device_lock; |
| 79 | struct notifier_block nb; | ||
| 80 | struct list_head vfio_next; | 74 | struct list_head vfio_next; |
| 81 | struct list_head container_next; | 75 | struct list_head container_next; |
| 82 | struct list_head unbound_list; | ||
| 83 | struct mutex unbound_lock; | ||
| 84 | atomic_t opened; | 76 | atomic_t opened; |
| 85 | wait_queue_head_t container_q; | 77 | wait_queue_head_t container_q; |
| 86 | enum vfio_group_type type; | 78 | enum vfio_group_type type; |
| @@ -281,8 +273,6 @@ void vfio_unregister_iommu_driver(const struct vfio_iommu_driver_ops *ops) · 194 unmodified lines | |||
| 281 | } | 273 | } |
| 282 | EXPORT_SYMBOL_GPL(vfio_unregister_iommu_driver); | 274 | EXPORT_SYMBOL_GPL(vfio_unregister_iommu_driver); |
| 283 | 275 | ||
| 284 | static int vfio_iommu_group_notifier(struct notifier_block *nb, | ||
| 285 | unsigned long action, void *data); | ||
| 286 | static void vfio_group_get(struct vfio_group *group); | 276 | static void vfio_group_get(struct vfio_group *group); |
| 287 | 277 | ||
| 288 | /* | 278 | /* |
| @@ -340,16 +330,8 @@ vfio_group_get_from_iommu(struct iommu_group *iommu_group) · 51 unmodified lines | |||
| 340 | static void vfio_group_release(struct device *dev) | 330 | static void vfio_group_release(struct device *dev) |
| 341 | { | 331 | { |
| 342 | struct vfio_group *group = container_of(dev, struct vfio_group, dev); | 332 | struct vfio_group *group = container_of(dev, struct vfio_group, dev); |
| 343 | struct vfio_unbound_dev *unbound, *tmp; | ||
| 344 | |||
347 more lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 19 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 8 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 9 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 26 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 30 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 44 lines aren’t shown here.
This diff is large: its 12 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 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 14 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 57 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 42 lines aren’t shown here.
This diff is large: its 30 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 58 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 81 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 293 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 409 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 28 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 22 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 137 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 18 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 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 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 11 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 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 24 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 14 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 67 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 12 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 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 48 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 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
Empty file deleted.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 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 39 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 80 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 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 17 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 29 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 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 44 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 41 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 212 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 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 26 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 13 lines aren’t shown here.
This diff is large: its 8 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 72 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 31 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 286 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 417 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 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 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 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 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.