Unified · Split
| @@ -86,6 +86,8 @@ ForEachMacros: · 85 unmodified lines | ||
| 86 | 86 | - 'bio_for_each_segment_all' |
| 87 | 87 | - 'bio_list_for_each' |
| 88 | 88 | - 'bip_for_each_vec' |
| 89 | + - 'bitmap_for_each_clear_region' | |
| 90 | + - 'bitmap_for_each_set_region' | |
| 89 | 91 | - 'blkg_for_each_descendant_post' |
| 90 | 92 | - 'blkg_for_each_descendant_pre' |
| 91 | 93 | - 'blk_queue_for_each_rl' |
| @@ -115,6 +117,7 @@ ForEachMacros: · 23 unmodified lines | ||
| 115 | 117 | - 'drm_client_for_each_connector_iter' |
| 116 | 118 | - 'drm_client_for_each_modeset' |
| 117 | 119 | - 'drm_connector_for_each_possible_encoder' |
| 120 | + - 'drm_for_each_bridge_in_chain' | |
| 118 | 121 | - 'drm_for_each_connector_iter' |
| 119 | 122 | - 'drm_for_each_crtc' |
| 120 | 123 | - 'drm_for_each_encoder' |
| @@ -136,9 +139,10 @@ ForEachMacros: · 15 unmodified lines | ||
| 136 | 139 | - 'for_each_bio' |
| 137 | 140 | - 'for_each_board_func_rsrc' |
| 138 | 141 | - 'for_each_bvec' |
| 142 | + - 'for_each_card_auxs' | |
| 143 | + - 'for_each_card_auxs_safe' | |
| 139 | 144 | - 'for_each_card_components' |
| 140 | − - 'for_each_card_links' | |
| 141 | − - 'for_each_card_links_safe' | |
| 145 | + - 'for_each_card_pre_auxs' | |
| 142 | 146 | - 'for_each_card_prelinks' |
| 143 | 147 | - 'for_each_card_rtds' |
| 144 | 148 | - 'for_each_card_rtds_safe' |
| @@ -166,6 +170,7 @@ ForEachMacros: · 21 unmodified lines | ||
| 166 | 170 | - 'for_each_dpcm_fe' |
| 167 | 171 | - 'for_each_drhd_unit' |
| 168 | 172 | - 'for_each_dss_dev' |
| 173 | + - 'for_each_efi_handle' | |
| 169 | 174 | - 'for_each_efi_memory_desc' |
| 170 | 175 | - 'for_each_efi_memory_desc_in_map' |
| 171 | 176 | - 'for_each_element' |
| @@ -190,6 +195,7 @@ ForEachMacros: · 18 unmodified lines | ||
| 190 | 195 | - 'for_each_lru' |
| 191 | 196 | - 'for_each_matching_node' |
| 192 | 197 | - 'for_each_matching_node_and_match' |
| 198 | + - 'for_each_member' | |
| 193 | 199 | - 'for_each_memblock' |
| 194 | 200 | - 'for_each_memblock_type' |
| 195 | 201 | - 'for_each_memcg_cache_index' |
| @@ -200,9 +206,11 @@ ForEachMacros: · 4 unmodified lines | ||
| 200 | 206 | - 'for_each_msi_entry' |
| 201 | 207 | - 'for_each_msi_entry_safe' |
| 202 | 208 | - 'for_each_net' |
| 209 | + - 'for_each_net_continue_reverse' | |
| 203 | 210 | - 'for_each_netdev' |
| 204 | 211 | - 'for_each_netdev_continue' |
| 205 | 212 | - 'for_each_netdev_continue_rcu' |
| 213 | + - 'for_each_netdev_continue_reverse' | |
| 206 | 214 | - 'for_each_netdev_feature' |
| 207 | 215 | - 'for_each_netdev_in_bond_rcu' |
| 208 | 216 | - 'for_each_netdev_rcu' |
| @@ -254,10 +262,10 @@ ForEachMacros: · 45 unmodified lines | ||
| 254 | 262 | - 'for_each_reserved_mem_region' |
| 255 | 263 | - 'for_each_rtd_codec_dai' |
| 256 | 264 | - 'for_each_rtd_codec_dai_rollback' |
| 257 | − - 'for_each_rtdcom' | |
| 258 | − - 'for_each_rtdcom_safe' | |
| 265 | + - 'for_each_rtd_components' | |
| 259 | 266 | - 'for_each_set_bit' |
| 260 | 267 | - 'for_each_set_bit_from' |
| 268 | + - 'for_each_set_clump8' | |
| 261 | 269 | - 'for_each_sg' |
| 262 | 270 | - 'for_each_sg_dma_page' |
| 263 | 271 | - 'for_each_sg_page' |
| @@ -267,6 +275,7 @@ ForEachMacros: · 3 unmodified lines | ||
| 267 | 275 | - 'for_each_subelement_id' |
| 268 | 276 | - '__for_each_thread' |
| 269 | 277 | - 'for_each_thread' |
| 278 | + - 'for_each_wakeup_source' | |
| 270 | 279 | - 'for_each_zone' |
| 271 | 280 | - 'for_each_zone_zonelist' |
| 272 | 281 | - 'for_each_zone_zonelist_nodemask' |
| @@ -330,6 +339,7 @@ ForEachMacros: · 57 unmodified lines | ||
| 330 | 339 | - 'list_for_each' |
| 331 | 340 | - 'list_for_each_codec' |
| 332 | 341 | - 'list_for_each_codec_safe' |
| 342 | + - 'list_for_each_continue' | |
| 333 | 343 | - 'list_for_each_entry' |
| 334 | 344 | - 'list_for_each_entry_continue' |
| 335 | 345 | - 'list_for_each_entry_continue_rcu' |
| @@ -351,6 +361,7 @@ ForEachMacros: · 15 unmodified lines | ||
| 351 | 361 | - 'llist_for_each_entry' |
| 352 | 362 | - 'llist_for_each_entry_safe' |
| 353 | 363 | - 'llist_for_each_safe' |
| 364 | + - 'mci_for_each_dimm' | |
| 354 | 365 | - 'media_device_for_each_entity' |
| 355 | 366 | - 'media_device_for_each_intf' |
| 356 | 367 | - 'media_device_for_each_link' |
| @@ -444,10 +455,16 @@ ForEachMacros: · 87 unmodified lines | ||
| 444 | 455 | - 'virtio_device_for_each_vq' |
| 445 | 456 | - 'xa_for_each' |
| 446 | 457 | - 'xa_for_each_marked' |
| 458 | + - 'xa_for_each_range' | |
| 447 | 459 | - 'xa_for_each_start' |
| 448 | 460 | - 'xas_for_each' |
| 449 | 461 | - 'xas_for_each_conflict' |
| 450 | 462 | - 'xas_for_each_marked' |
| 463 | + - 'xbc_array_for_each_value' | |
| 464 | + - 'xbc_for_each_key_value' | |
| 465 | + - 'xbc_node_for_each_array_value' | |
| 466 | + - 'xbc_node_for_each_child' | |
| 467 | + - 'xbc_node_for_each_key_value' | |
| 451 | 468 | - 'zorro_for_each_dev' |
| 452 | 469 | |
| 453 | 470 | #IncludeBlocks: Preserve # Unknown to clang-format-5.0 |
| @@ -567,6 +567,11 @@ D: Original author of Amiga FFS filesystem · 566 unmodified lines | ||
| 567 | 567 | S: Orlando, Florida |
| 568 | 568 | S: USA |
| 569 | 569 | |
| 570 | +N: Paul Burton | |
| 571 | +E: paulburton@kernel.org | |
| 572 | +W: https://pburton.com | |
| 573 | +D: MIPS maintainer 2018-2020 | |
| 574 | + | |
| 570 | 575 | N: Lennert Buytenhek |
| 571 | 576 | E: kernel@wantstofly.org |
| 572 | 577 | D: Original (2.4) rewrite of the ethernet bridging code |
| @@ -18,7 +18,7 @@ may look as follows:: · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | $ ls -l /sys/bus/acpi/devices/INT3404:00/ |
| 20 | 20 | total 0 |
| 21 | −... | |
| 21 | + ... | |
| 22 | 22 | -r--r--r-- 1 root root 4096 Dec 13 20:38 state0 |
| 23 | 23 | -r--r--r-- 1 root root 4096 Dec 13 20:38 state1 |
| 24 | 24 | -r--r--r-- 1 root root 4096 Dec 13 20:38 state10 |
| @@ -38,7 +38,7 @@ where each of the "state*" files represents one performance state of the fan · 13 unmodified lines | ||
| 38 | 38 | and contains a colon-separated list of 5 integer numbers (fields) with the |
| 39 | 39 | following interpretation:: |
| 40 | 40 | |
| 41 | −control_percent:trip_point_index:speed_rpm:noise_level_mdb:power_mw | |
| 41 | + control_percent:trip_point_index:speed_rpm:noise_level_mdb:power_mw | |
| 42 | 42 | |
| 43 | 43 | * ``control_percent``: The percent value to be used to set the fan speed to a |
| 44 | 44 | specific level using the _FSL object (0-100). |
| @@ -62,6 +62,30 @@ Or more shorter, written as following:: · 61 unmodified lines | ||
| 62 | 62 | In both styles, same key words are automatically merged when parsing it |
| 63 | 63 | at boot time. So you can append similar trees or key-values. |
| 64 | 64 | |
| 65 | +Same-key Values | |
| 66 | +--------------- | |
| 67 | + | |
| 68 | +It is prohibited that two or more values or arrays share a same-key. | |
| 69 | +For example,:: | |
| 70 | + | |
| 71 | + foo = bar, baz | |
| 72 | + foo = qux # !ERROR! we can not re-define same key | |
| 73 | + | |
| 74 | +If you want to append the value to existing key as an array member, | |
| 75 | +you can use ``+=`` operator. For example:: | |
| 76 | + | |
| 77 | + foo = bar, baz | |
| 78 | + foo += qux | |
| 79 | + | |
| 80 | +In this case, the key ``foo`` has ``bar``, ``baz`` and ``qux``. | |
| 81 | + | |
| 82 | +However, a sub-key and a value can not co-exist under a parent key. | |
| 83 | +For example, following config is NOT allowed.:: | |
| 84 | + | |
| 85 | + foo = value1 | |
| 86 | + foo.bar = value2 # !ERROR! subkey "bar" and value "value1" can NOT co-exist | |
| 87 | + | |
| 88 | + | |
| 65 | 89 | Comments |
| 66 | 90 | -------- |
| 67 | 91 | |
| @@ -102,9 +126,13 @@ Boot Kernel With a Boot Config · 34 unmodified lines | ||
| 102 | 126 | ============================== |
| 103 | 127 | |
| 104 | 128 | Since the boot configuration file is loaded with initrd, it will be added |
| 105 | −to the end of the initrd (initramfs) image file. The Linux kernel decodes | |
| 106 | −the last part of the initrd image in memory to get the boot configuration | |
| 107 | −data. | |
| 129 | +to the end of the initrd (initramfs) image file with size, checksum and | |
| 130 | +12-byte magic word as below. | |
| 131 | + | |
| 132 | +[initrd][bootconfig][size(u32)][checksum(u32)][#BOOTCONFIG\n] | |
| 133 | + | |
| 134 | +The Linux kernel decodes the last part of the initrd image in memory to | |
| 135 | +get the boot configuration data. | |
| 108 | 136 | Because of this "piggyback" method, there is no need to change or |
| 109 | 137 | update the boot loader and the kernel image itself. |
| 110 | 138 | |
| @@ -136,6 +136,10 @@ · 135 unmodified lines | ||
| 136 | 136 | dynamic table installation which will install SSDT |
| 137 | 137 | tables to /sys/firmware/acpi/tables/dynamic. |
| 138 | 138 | |
| 139 | + acpi_no_watchdog [HW,ACPI,WDT] | |
| 140 | + Ignore the ACPI-based watchdog interface (WDAT) and let | |
| 141 | + a native driver control the watchdog device instead. | |
| 142 | + | |
| 139 | 143 | acpi_rsdp= [ACPI,EFI,KEXEC] |
| 140 | 144 | Pass the RSDP address to the kernel, mostly used |
| 141 | 145 | on machines running EFI runtime service to boot the |
| @@ -110,6 +110,8 @@ stable kernels. · 109 unmodified lines | ||
| 110 | 110 | +----------------+-----------------+-----------------+-----------------------------+ |
| 111 | 111 | | Cavium | ThunderX GICv3 | #23154 | CAVIUM_ERRATUM_23154 | |
| 112 | 112 | +----------------+-----------------+-----------------+-----------------------------+ |
| 113 | +| Cavium | ThunderX GICv3 | #38539 | N/A | | |
| 114 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 113 | 115 | | Cavium | ThunderX Core | #27456 | CAVIUM_ERRATUM_27456 | |
| 114 | 116 | +----------------+-----------------+-----------------+-----------------------------+ |
| 115 | 117 | | Cavium | ThunderX Core | #30115 | CAVIUM_ERRATUM_30115 | |
| @@ -551,6 +551,7 @@ options to your ``.config``: · 550 unmodified lines | ||
| 551 | 551 | Once the kernel is built and installed, a simple |
| 552 | 552 | |
| 553 | 553 | .. code-block:: bash |
| 554 | + | |
| 554 | 555 | modprobe example-test |
| 555 | 556 | |
| 556 | 557 | ...will run the tests. |
| @@ -102,7 +102,7 @@ Required sub-node properties: · 101 unmodified lines | ||
| 102 | 102 | [1] Documentation/devicetree/bindings/clock/clock-bindings.txt |
| 103 | 103 | [2] Documentation/devicetree/bindings/power/power-domain.yaml |
| 104 | 104 | [3] Documentation/devicetree/bindings/thermal/thermal.txt |
| 105 | −[4] Documentation/devicetree/bindings/sram/sram.txt | |
| 105 | +[4] Documentation/devicetree/bindings/sram/sram.yaml | |
| 106 | 106 | [5] Documentation/devicetree/bindings/reset/reset.txt |
| 107 | 107 | |
| 108 | 108 | Example: |
| @@ -109,7 +109,7 @@ Required properties: · 108 unmodified lines | ||
| 109 | 109 | [0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html |
| 110 | 110 | [1] Documentation/devicetree/bindings/clock/clock-bindings.txt |
| 111 | 111 | [2] Documentation/devicetree/bindings/thermal/thermal.txt |
| 112 | −[3] Documentation/devicetree/bindings/sram/sram.txt | |
| 112 | +[3] Documentation/devicetree/bindings/sram/sram.yaml | |
| 113 | 113 | [4] Documentation/devicetree/bindings/power/power-domain.yaml |
| 114 | 114 | |
| 115 | 115 | Example: |
| @@ -62,7 +62,7 @@ Timer node: · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | Syscon reboot node: |
| 64 | 64 | |
| 65 | −See Documentation/devicetree/bindings/power/reset/syscon-reboot.txt for the | |
| 65 | +See Documentation/devicetree/bindings/power/reset/syscon-reboot.yaml for the | |
| 66 | 66 | detailed list of properties, the two values defined below are specific to the |
| 67 | 67 | BCM6328-style timer: |
| 68 | 68 | |
| @@ -216,7 +216,7 @@ properties: · 215 unmodified lines | ||
| 216 | 216 | $ref: '/schemas/types.yaml#/definitions/phandle-array' |
| 217 | 217 | description: | |
| 218 | 218 | List of phandles to idle state nodes supported |
| 219 | − by this cpu (see ./idle-states.txt). | |
| 219 | + by this cpu (see ./idle-states.yaml). | |
| 220 | 220 | |
| 221 | 221 | capacity-dmips-mhz: |
| 222 | 222 | $ref: '/schemas/types.yaml#/definitions/uint32' |
| @@ -160,7 +160,7 @@ properties: · 159 unmodified lines | ||
| 160 | 160 | items: |
| 161 | 161 | - enum: |
| 162 | 162 | - armadeus,imx6dl-apf6 # APF6 (Solo) SoM |
| 163 | − - armadeus,imx6dl-apf6dldev # APF6 (Solo) SoM on APF6Dev board | |
| 163 | + - armadeus,imx6dl-apf6dev # APF6 (Solo) SoM on APF6Dev board | |
| 164 | 164 | - eckelmann,imx6dl-ci4x10 |
| 165 | 165 | - emtrion,emcon-mx6 # emCON-MX6S or emCON-MX6DL SoM |
| 166 | 166 | - emtrion,emcon-mx6-avari # emCON-MX6S or emCON-MX6DL SoM on Avari Base |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | * Hisilicon Hi3519 System Controller Block |
| 2 | 2 | |
| 3 | 3 | This bindings use the following binding: |
| 4 | −Documentation/devicetree/bindings/mfd/syscon.txt | |
| 4 | +Documentation/devicetree/bindings/mfd/syscon.yaml | |
| 5 | 5 | |
| 6 | 6 | Required properties: |
| 7 | 7 | - compatible: "hisilicon,hi3519-sysctrl". |
| @@ -81,4 +81,4 @@ Example: · 80 unmodified lines | ||
| 81 | 81 | }; |
| 82 | 82 | }; |
| 83 | 83 | |
| 84 | −[1]. Documentation/devicetree/bindings/arm/idle-states.txt | |
| 84 | +[1]. Documentation/devicetree/bindings/arm/idle-states.yaml | |
| @@ -17,7 +17,7 @@ am335x and am437x only: · 16 unmodified lines | ||
| 17 | 17 | - pm-sram: Phandles to ocmcram nodes to be used for power management. |
| 18 | 18 | First should be type 'protect-exec' for the driver to use to copy |
| 19 | 19 | and run PM functions, second should be regular pool to be used for |
| 20 | − data region for code. See Documentation/devicetree/bindings/sram/sram.txt | |
| 20 | + data region for code. See Documentation/devicetree/bindings/sram/sram.yaml | |
| 21 | 21 | for more details. |
| 22 | 22 | |
| 23 | 23 | Examples: |
| @@ -100,13 +100,14 @@ properties: · 99 unmodified lines | ||
| 100 | 100 | bindings in [1]) must specify this property. |
| 101 | 101 | |
| 102 | 102 | [1] Kernel documentation - ARM idle states bindings |
| 103 | − Documentation/devicetree/bindings/arm/idle-states.txt | |
| 104 | − | |
| 105 | − "#power-domain-cells": | |
| 106 | − description: | |
| 107 | − The number of cells in a PM domain specifier as per binding in [3]. | |
| 108 | − Must be 0 as to represent a single PM domain. | |
| 103 | + Documentation/devicetree/bindings/arm/idle-states.yaml | |
| 109 | 104 | |
| 105 | +patternProperties: | |
| 106 | + "^power-domain-": | |
| 107 | + allOf: | |
| 108 | + - $ref: "../power/power-domain.yaml#" | |
| 109 | + type: object | |
| 110 | + description: | | |
| 110 | 111 | ARM systems can have multiple cores, sometimes in an hierarchical |
| 111 | 112 | arrangement. This often, but not always, maps directly to the processor |
| 112 | 113 | power topology of the system. Individual nodes in a topology have their |
| @@ -122,14 +123,8 @@ properties: · 9 unmodified lines | ||
| 122 | 123 | helps to implement support for OSI mode and OS implementations may choose |
| 123 | 124 | to mandate it. |
| 124 | 125 | |
| 125 | − [3] Documentation/devicetree/bindings/power/power_domain.txt | |
| 126 | − [4] Documentation/devicetree/bindings/power/domain-idle-state.txt | |
| 127 | − | |
| 128 | − power-domains: | |
| 129 | − $ref: '/schemas/types.yaml#/definitions/phandle-array' | |
| 130 | − description: | |
| 131 | − List of phandles and PM domain specifiers, as defined by bindings of the | |
| 132 | − PM domain provider. | |
| 126 | + [3] Documentation/devicetree/bindings/power/power-domain.yaml | |
| 127 | + [4] Documentation/devicetree/bindings/power/domain-idle-state.yaml | |
| 133 | 128 | |
| 134 | 129 | required: |
| 135 | 130 | - compatible |
| @@ -199,7 +194,7 @@ examples: · 63 unmodified lines | ||
| 199 | 194 | |
| 200 | 195 | CPU0: cpu@0 { |
| 201 | 196 | device_type = "cpu"; |
| 202 | − compatible = "arm,cortex-a53", "arm,armv8"; | |
| 197 | + compatible = "arm,cortex-a53"; | |
| 203 | 198 | reg = <0x0>; |
| 204 | 199 | enable-method = "psci"; |
| 205 | 200 | power-domains = <&CPU_PD0>; |
| @@ -208,7 +203,7 @@ examples: · 2 unmodified lines | ||
| 208 | 203 | |
| 209 | 204 | CPU1: cpu@1 { |
| 210 | 205 | device_type = "cpu"; |
| 211 | − compatible = "arm,cortex-a57", "arm,armv8"; | |
| 206 | + compatible = "arm,cortex-a53"; | |
| 212 | 207 | reg = <0x100>; |
| 213 | 208 | enable-method = "psci"; |
| 214 | 209 | power-domains = <&CPU_PD1>; |
| @@ -224,6 +219,9 @@ examples: · 9 unmodified lines | ||
| 224 | 219 | exit-latency-us = <10>; |
| 225 | 220 | min-residency-us = <100>; |
| 226 | 221 | }; |
| 222 | + }; | |
| 223 | + | |
| 224 | + domain-idle-states { | |
| 227 | 225 | |
| 228 | 226 | CLUSTER_RET: cluster-retention { |
| 229 | 227 | compatible = "domain-idle-state"; |
| @@ -247,19 +245,19 @@ examples: · 17 unmodified lines | ||
| 247 | 245 | compatible = "arm,psci-1.0"; |
| 248 | 246 | method = "smc"; |
| 249 | 247 | |
| 250 | − CPU_PD0: cpu-pd0 { | |
| 248 | + CPU_PD0: power-domain-cpu0 { | |
| 251 | 249 | #power-domain-cells = <0>; |
| 252 | 250 | domain-idle-states = <&CPU_PWRDN>; |
| 253 | 251 | power-domains = <&CLUSTER_PD>; |
| 254 | 252 | }; |
| 255 | 253 | |
| 256 | − CPU_PD1: cpu-pd1 { | |
| 254 | + CPU_PD1: power-domain-cpu1 { | |
| 257 | 255 | #power-domain-cells = <0>; |
| 258 | 256 | domain-idle-states = <&CPU_PWRDN>; |
| 259 | 257 | power-domains = <&CLUSTER_PD>; |
| 260 | 258 | }; |
| 261 | 259 | |
| 262 | − CLUSTER_PD: cluster-pd { | |
| 260 | + CLUSTER_PD: power-domain-cluster { | |
| 263 | 261 | #power-domain-cells = <0>; |
| 264 | 262 | domain-idle-states = <&CLUSTER_RET>, <&CLUSTER_PWRDN>; |
| 265 | 263 | }; |
| @@ -52,7 +52,7 @@ required: · 51 unmodified lines | ||
| 52 | 52 | |
| 53 | 53 | examples: |
| 54 | 54 | - | |
| 55 | − mlahb: ahb { | |
| 55 | + mlahb: ahb@38000000 { | |
| 56 | 56 | compatible = "st,mlahb", "simple-bus"; |
| 57 | 57 | #address-cells = <1>; |
| 58 | 58 | #size-cells = <1>; |
| @@ -70,7 +70,6 @@ examples: · 69 unmodified lines | ||
| 70 | 70 | #size-cells = <0>; |
| 71 | 71 | |
| 72 | 72 | pmic@3e3 { |
| 73 | − compatible = "..."; | |
| 74 | 73 | reg = <0x3e3>; |
| 75 | 74 | |
| 76 | 75 | /* ... */ |
| @@ -40,7 +40,7 @@ additionalProperties: false · 39 unmodified lines | ||
| 40 | 40 | |
| 41 | 41 | examples: |
| 42 | 42 | - | |
| 43 | − osc24M: clk@01c20050 { | |
| 43 | + osc24M: clk@1c20050 { | |
| 44 | 44 | #clock-cells = <0>; |
| 45 | 45 | compatible = "allwinner,sun4i-a10-osc-clk"; |
| 46 | 46 | reg = <0x01c20050 0x4>; |
| @@ -41,7 +41,7 @@ additionalProperties: false · 40 unmodified lines | ||
| 41 | 41 | |
| 42 | 42 | examples: |
| 43 | 43 | - | |
| 44 | − clk@0600005c { | |
| 44 | + clk@600005c { | |
| 45 | 45 | #clock-cells = <0>; |
| 46 | 46 | compatible = "allwinner,sun9i-a80-gt-clk"; |
| 47 | 47 | reg = <0x0600005c 0x4>; |
| @@ -42,7 +42,7 @@ properties: · 41 unmodified lines | ||
| 42 | 42 | be part of GCC and hence the TSENS properties can also be part |
| 43 | 43 | of the GCC/clock-controller node. |
| 44 | 44 | For more details on the TSENS properties please refer |
| 45 | − Documentation/devicetree/bindings/thermal/qcom-tsens.txt | |
| 45 | + Documentation/devicetree/bindings/thermal/qcom-tsens.yaml | |
| 46 | 46 | |
| 47 | 47 | nvmem-cell-names: |
| 48 | 48 | minItems: 1 |
| @@ -49,11 +49,7 @@ examples: · 48 unmodified lines | ||
| 49 | 49 | resets = <&tcon_ch0_clk 0>; |
| 50 | 50 | |
| 51 | 51 | port { |
| 52 | − #address-cells = <1>; | |
| 53 | − #size-cells = <0>; | |
| 54 | − | |
| 55 | − tve0_in_tcon0: endpoint@0 { | |
| 56 | − reg = <0>; | |
| 52 | + tve0_in_tcon0: endpoint { | |
| 57 | 53 | remote-endpoint = <&tcon0_out_tve0>; |
| 58 | 54 | }; |
| 59 | 55 | }; |
| @@ -79,21 +79,15 @@ examples: · 78 unmodified lines | ||
| 79 | 79 | #size-cells = <0>; |
| 80 | 80 | |
| 81 | 81 | anx6345_in: port@0 { |
| 82 | − #address-cells = <1>; | |
| 83 | − #size-cells = <0>; | |
| 84 | 82 | reg = <0>; |
| 85 | − anx6345_in_tcon0: endpoint@0 { | |
| 86 | − reg = <0>; | |
| 83 | + anx6345_in_tcon0: endpoint { | |
| 87 | 84 | remote-endpoint = <&tcon0_out_anx6345>; |
| 88 | 85 | }; |
| 89 | 86 | }; |
| 90 | 87 | |
| 91 | 88 | anx6345_out: port@1 { |
| 92 | − #address-cells = <1>; | |
| 93 | − #size-cells = <0>; | |
| 94 | 89 | reg = <1>; |
| 95 | − anx6345_out_panel: endpoint@0 { | |
| 96 | − reg = <0>; | |
| 90 | + anx6345_out_panel: endpoint { | |
| 97 | 91 | remote-endpoint = <&panel_in_edp>; |
| 98 | 92 | }; |
| 99 | 93 | }; |
| @@ -37,6 +37,8 @@ examples: · 36 unmodified lines | ||
| 37 | 37 | dsi@ff450000 { |
| 38 | 38 | #address-cells = <1>; |
| 39 | 39 | #size-cells = <0>; |
| 40 | + reg = <0xff450000 0x1000>; | |
| 41 | + | |
| 40 | 42 | panel@0 { |
| 41 | 43 | compatible = "leadtek,ltk500hd1829"; |
| 42 | 44 | reg = <0>; |
| @@ -37,6 +37,8 @@ examples: · 36 unmodified lines | ||
| 37 | 37 | dsi@ff450000 { |
| 38 | 38 | #address-cells = <1>; |
| 39 | 39 | #size-cells = <0>; |
| 40 | + reg = <0xff450000 0x1000>; | |
| 41 | + | |
| 40 | 42 | panel@0 { |
| 41 | 43 | compatible = "xinpeng,xpp055c272"; |
| 42 | 44 | reg = <0>; |
| @@ -174,10 +174,6 @@ examples: · 173 unmodified lines | ||
| 174 | 174 | }; |
| 175 | 175 | }; |
| 176 | 176 | |
| 177 | − soc@1c00000 { | |
| 178 | − lcdc0: lcdc@1c0c000 { | |
| 179 | − compatible = "allwinner,sun4i-a10-lcdc"; | |
| 180 | − }; | |
| 181 | − }; | |
| 177 | + lcdc0: lcdc { }; | |
| 182 | 178 | |
| 183 | 179 | ... |
| @@ -37,7 +37,7 @@ Optional nodes: · 36 unmodified lines | ||
| 37 | 37 | supports a single port with a single endpoint. |
| 38 | 38 | |
| 39 | 39 | - See also Documentation/devicetree/bindings/display/tilcdc/panel.txt and |
| 40 | − Documentation/devicetree/bindings/display/tilcdc/tfp410.txt for connecting | |
| 40 | + Documentation/devicetree/bindings/display/bridge/ti,tfp410.txt for connecting | |
| 41 | 41 | tfp410 DVI encoder or lcd panel to lcdc |
| 42 | 42 | |
| 43 | 43 | [1] There is an errata about AM335x color wiring. For 16-bit color mode |
| @@ -143,7 +143,7 @@ examples: · 142 unmodified lines | ||
| 143 | 143 | #size-cells = <2>; |
| 144 | 144 | dma-coherent; |
| 145 | 145 | dma-ranges; |
| 146 | − ranges; | |
| 146 | + ranges = <0x0 0x30800000 0x0 0x30800000 0x0 0x05000000>; | |
| 147 | 147 | |
| 148 | 148 | ti,sci-dev-id = <118>; |
| 149 | 149 | |
| @@ -169,16 +169,4 @@ examples: · 19 unmodified lines | ||
| 169 | 169 | ti,sci-rm-range-rflow = <0x6>; /* GP RFLOW */ |
| 170 | 170 | }; |
| 171 | 171 | }; |
| 172 | − | |
| 173 | − mcasp0: mcasp@02B00000 { | |
| 174 | − dmas = <&main_udmap 0xc400>, <&main_udmap 0x4400>; | |
| 175 | − dma-names = "tx", "rx"; | |
| 176 | − }; | |
| 177 | − | |
| 178 | − crypto: crypto@4E00000 { | |
| 179 | − compatible = "ti,sa2ul-crypto"; | |
| 180 | − | |
| 181 | − dmas = <&main_udmap 0xc000>, <&main_udmap 0x4000>, <&main_udmap 0x4001>; | |
| 182 | − dma-names = "tx", "rx1", "rx2"; | |
| 183 | − }; | |
| 184 | 172 | }; |
| @@ -84,31 +84,31 @@ examples: · 83 unmodified lines | ||
| 84 | 84 | gpu_opp_table: opp_table0 { |
| 85 | 85 | compatible = "operating-points-v2"; |
| 86 | 86 | |
| 87 | − opp@533000000 { | |
| 87 | + opp-533000000 { | |
| 88 | 88 | opp-hz = /bits/ 64 <533000000>; |
| 89 | 89 | opp-microvolt = <1250000>; |
| 90 | 90 | }; |
| 91 | − opp@450000000 { | |
| 91 | + opp-450000000 { | |
| 92 | 92 | opp-hz = /bits/ 64 <450000000>; |
| 93 | 93 | opp-microvolt = <1150000>; |
| 94 | 94 | }; |
| 95 | − opp@400000000 { | |
| 95 | + opp-400000000 { | |
| 96 | 96 | opp-hz = /bits/ 64 <400000000>; |
| 97 | 97 | opp-microvolt = <1125000>; |
| 98 | 98 | }; |
| 99 | − opp@350000000 { | |
| 99 | + opp-350000000 { | |
| 100 | 100 | opp-hz = /bits/ 64 <350000000>; |
| 101 | 101 | opp-microvolt = <1075000>; |
| 102 | 102 | }; |
| 103 | − opp@266000000 { | |
| 103 | + opp-266000000 { | |
| 104 | 104 | opp-hz = /bits/ 64 <266000000>; |
| 105 | 105 | opp-microvolt = <1025000>; |
| 106 | 106 | }; |
| 107 | − opp@160000000 { | |
| 107 | + opp-160000000 { | |
| 108 | 108 | opp-hz = /bits/ 64 <160000000>; |
| 109 | 109 | opp-microvolt = <925000>; |
| 110 | 110 | }; |
| 111 | − opp@100000000 { | |
| 111 | + opp-100000000 { | |
| 112 | 112 | opp-hz = /bits/ 64 <100000000>; |
| 113 | 113 | opp-microvolt = <912500>; |
| 114 | 114 | }; |
| @@ -138,31 +138,31 @@ examples: · 137 unmodified lines | ||
| 138 | 138 | gpu_opp_table: opp_table0 { |
| 139 | 139 | compatible = "operating-points-v2"; |
| 140 | 140 | |
| 141 | − opp@533000000 { | |
| 141 | + opp-533000000 { | |
| 142 | 142 | opp-hz = /bits/ 64 <533000000>; |
| 143 | 143 | opp-microvolt = <1250000>; |
| 144 | 144 | }; |
| 145 | − opp@450000000 { | |
| 145 | + opp-450000000 { | |
| 146 | 146 | opp-hz = /bits/ 64 <450000000>; |
| 147 | 147 | opp-microvolt = <1150000>; |
| 148 | 148 | }; |
| 149 | − opp@400000000 { | |
| 149 | + opp-400000000 { | |
| 150 | 150 | opp-hz = /bits/ 64 <400000000>; |
| 151 | 151 | opp-microvolt = <1125000>; |
| 152 | 152 | }; |
| 153 | − opp@350000000 { | |
| 153 | + opp-350000000 { | |
| 154 | 154 | opp-hz = /bits/ 64 <350000000>; |
| 155 | 155 | opp-microvolt = <1075000>; |
| 156 | 156 | }; |
| 157 | − opp@266000000 { | |
| 157 | + opp-266000000 { | |
| 158 | 158 | opp-hz = /bits/ 64 <266000000>; |
| 159 | 159 | opp-microvolt = <1025000>; |
| 160 | 160 | }; |
| 161 | − opp@160000000 { | |
| 161 | + opp-160000000 { | |
| 162 | 162 | opp-hz = /bits/ 64 <160000000>; |
| 163 | 163 | opp-microvolt = <925000>; |
| 164 | 164 | }; |
| 165 | − opp@100000000 { | |
| 165 | + opp-100000000 { | |
| 166 | 166 | opp-hz = /bits/ 64 <100000000>; |
| 167 | 167 | opp-microvolt = <912500>; |
| 168 | 168 | }; |
| @@ -123,7 +123,7 @@ examples: · 122 unmodified lines | ||
| 123 | 123 | samsung,syscon-phandle = <&pmu_system_controller>; |
| 124 | 124 | |
| 125 | 125 | /* NTC thermistor is a hwmon device */ |
| 126 | − ncp15wb473@0 { | |
| 126 | + ncp15wb473 { | |
| 127 | 127 | compatible = "murata,ncp15wb473"; |
| 128 | 128 | pullup-uv = <1800000>; |
| 129 | 129 | pullup-ohm = <47000>; |
| @@ -62,7 +62,7 @@ required: · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | examples: |
| 64 | 64 | - | |
| 65 | − i2c@00000000 { | |
| 65 | + i2c { | |
| 66 | 66 | #address-cells = <1>; |
| 67 | 67 | #size-cells = <0>; |
| 68 | 68 | gt928@5d { |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | Texas Instruments TWL family (twl4030) pwrbutton module |
| 2 | 2 | |
| 3 | 3 | This module is part of the TWL4030. For more details about the whole |
| 4 | −chip see Documentation/devicetree/bindings/mfd/twl-familly.txt. | |
| 4 | +chip see Documentation/devicetree/bindings/mfd/twl-family.txt. | |
| 5 | 5 | |
| 6 | 6 | This module provides a simple power button event via an Interrupt. |
| 7 | 7 | |
| @@ -85,7 +85,7 @@ properties: · 84 unmodified lines | ||
| 85 | 85 | # LED will act as a back-light, controlled by the framebuffer system |
| 86 | 86 | - backlight |
| 87 | 87 | # LED will turn on (but for leds-gpio see "default-state" property in |
| 88 | − # Documentation/devicetree/bindings/leds/leds-gpio.txt) | |
| 88 | + # Documentation/devicetree/bindings/leds/leds-gpio.yaml) | |
| 89 | 89 | - default-on |
| 90 | 90 | # LED "double" flashes at a load average based rate |
| 91 | 91 | - heartbeat |
| @@ -5,7 +5,7 @@ where single bits in a certain register can turn on/off a · 4 unmodified lines | ||
| 5 | 5 | single LED. The register bit LEDs appear as children to the |
| 6 | 6 | syscon device, with the proper compatible string. For the |
| 7 | 7 | syscon bindings see: |
| 8 | −Documentation/devicetree/bindings/mfd/syscon.txt | |
| 8 | +Documentation/devicetree/bindings/mfd/syscon.yaml | |
| 9 | 9 | |
| 10 | 10 | Each LED is represented as a sub-node of the syscon device. Each |
| 11 | 11 | node's name represents the name of the corresponding LED. |
| @@ -177,7 +177,7 @@ examples: · 176 unmodified lines | ||
| 177 | 177 | }; |
| 178 | 178 | }; |
| 179 | 179 | |
| 180 | − i2c5: i2c@4807c000 { | |
| 180 | + i2c { | |
| 181 | 181 | clock-frequency = <400000>; |
| 182 | 182 | #address-cells = <1>; |
| 183 | 183 | #size-cells = <0>; |
| @@ -32,7 +32,7 @@ Required only for "ti,emif-am3352" and "ti,emif-am4372": · 31 unmodified lines | ||
| 32 | 32 | - sram : Phandles for generic sram driver nodes, |
| 33 | 33 | first should be type 'protect-exec' for the driver to use to copy |
| 34 | 34 | and run PM functions, second should be regular pool to be used for |
| 35 | − data region for code. See Documentation/devicetree/bindings/sram/sram.txt | |
| 35 | + data region for code. See Documentation/devicetree/bindings/sram/sram.yaml | |
| 36 | 36 | for more details. |
| 37 | 37 | |
| 38 | 38 | Optional properties: |
| @@ -97,14 +97,14 @@ examples: · 96 unmodified lines | ||
| 97 | 97 | regulators { |
| 98 | 98 | compatible = "maxim,max77650-regulator"; |
| 99 | 99 | |
| 100 | − max77650_ldo: regulator@0 { | |
| 100 | + max77650_ldo: regulator-ldo { | |
| 101 | 101 | regulator-compatible = "ldo"; |
| 102 | 102 | regulator-name = "max77650-ldo"; |
| 103 | 103 | regulator-min-microvolt = <1350000>; |
| 104 | 104 | regulator-max-microvolt = <2937500>; |
| 105 | 105 | }; |
| 106 | 106 | |
| 107 | − max77650_sbb0: regulator@1 { | |
| 107 | + max77650_sbb0: regulator-sbb0 { | |
| 108 | 108 | regulator-compatible = "sbb0"; |
| 109 | 109 | regulator-name = "max77650-sbb0"; |
| 110 | 110 | regulator-min-microvolt = <800000>; |
| @@ -26,8 +26,8 @@ Required properties: · 25 unmodified lines | ||
| 26 | 26 | ldo6, ldo7, ldo8 |
| 27 | 27 | |
| 28 | 28 | - xxx-supply: Input voltage supply regulator. |
| 29 | − These entries are require if regulators are enabled for a device. Missing of these | |
| 30 | − properties can cause the regulator registration fails. | |
| 29 | + These entries are required if regulators are enabled for a device. Missing these | |
| 30 | + properties can cause the regulator registration to fail. | |
| 31 | 31 | If some of input supply is powered through battery or always-on supply then |
| 32 | 32 | also it is require to have these parameters with proper node handle of always |
| 33 | 33 | on power supply. |
File renamed without changes.
| @@ -20,7 +20,7 @@ RAVE SP consists of the following sub-devices: · 19 unmodified lines | ||
| 20 | 20 | Device Description |
| 21 | 21 | ------ ----------- |
| 22 | 22 | rave-sp-wdt : Watchdog |
| 23 | −rave-sp-nvmem : Interface to onborad EEPROM | |
| 23 | +rave-sp-nvmem : Interface to onboard EEPROM | |
| 24 | 24 | rave-sp-backlight : Display backlight |
| 25 | 25 | rave-sp-hwmon : Interface to onboard hardware sensors |
| 26 | 26 | rave-sp-leds : Interface to onboard LEDs |
| @@ -26,7 +26,7 @@ For generic IOMMU bindings, see · 25 unmodified lines | ||
| 26 | 26 | Documentation/devicetree/bindings/iommu/iommu.txt. |
| 27 | 27 | |
| 28 | 28 | For arm-smmu binding, see: |
| 29 | −Documentation/devicetree/bindings/iommu/arm,smmu.txt. | |
| 29 | +Documentation/devicetree/bindings/iommu/arm,smmu.yaml. | |
| 30 | 30 | |
| 31 | 31 | Required properties: |
| 32 | 32 | |
| @@ -370,6 +370,7 @@ examples: · 369 unmodified lines | ||
| 370 | 370 | mmc3: mmc@1c12000 { |
| 371 | 371 | #address-cells = <1>; |
| 372 | 372 | #size-cells = <0>; |
| 373 | + reg = <0x1c12000 0x200>; | |
| 373 | 374 | pinctrl-names = "default"; |
| 374 | 375 | pinctrl-0 = <&mmc3_pins_a>; |
| 375 | 376 | vmmc-supply = <®_vmmc3>; |
| @@ -27,7 +27,7 @@ Required properties of NAND chips: · 26 unmodified lines | ||
| 27 | 27 | - reg: shall contain the native Chip Select ids from 0 to max supported by |
| 28 | 28 | the cadence nand flash controller |
| 29 | 29 | |
| 30 | −See Documentation/devicetree/bindings/mtd/nand.txt for more details on | |
| 30 | +See Documentation/devicetree/bindings/mtd/nand-controller.yaml for more details on | |
| 31 | 31 | generic bindings. |
| 32 | 32 | |
| 33 | 33 | Example: |
| @@ -45,7 +45,7 @@ Optional properties: · 44 unmodified lines | ||
| 45 | 45 | switch queue |
| 46 | 46 | |
| 47 | 47 | - resets: a single phandle and reset identifier pair. See |
| 48 | − Documentation/devicetree/binding/reset/reset.txt for details. | |
| 48 | + Documentation/devicetree/bindings/reset/reset.txt for details. | |
| 49 | 49 | |
| 50 | 50 | - reset-names: If the "reset" property is specified, this property should have |
| 51 | 51 | the value "switch" to denote the switch reset line. |
| @@ -110,6 +110,13 @@ PROPERTIES · 109 unmodified lines | ||
| 110 | 110 | Usage: required |
| 111 | 111 | Definition: See soc/fsl/qman.txt and soc/fsl/bman.txt |
| 112 | 112 | |
| 113 | +- fsl,erratum-a050385 | |
| 114 | + Usage: optional | |
| 115 | + Value type: boolean | |
| 116 | + Definition: A boolean property. Indicates the presence of the | |
| 117 | + erratum A050385 which indicates that DMA transactions that are | |
| 118 | + split can result in a FMan lock. | |
| 119 | + | |
| 113 | 120 | ============================================================================= |
| 114 | 121 | FMan MURAM Node |
| 115 | 122 | |
| @@ -76,6 +76,8 @@ examples: · 75 unmodified lines | ||
| 76 | 76 | qfprom: eeprom@700000 { |
| 77 | 77 | #address-cells = <1>; |
| 78 | 78 | #size-cells = <1>; |
| 79 | + reg = <0x00700000 0x100000>; | |
| 80 | + | |
| 79 | 81 | wp-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>; |
| 80 | 82 | |
| 81 | 83 | /* ... */ |
| @@ -86,7 +86,7 @@ examples: · 85 unmodified lines | ||
| 86 | 86 | #include <dt-bindings/clock/sun4i-a10-ccu.h> |
| 87 | 87 | #include <dt-bindings/reset/sun4i-a10-ccu.h> |
| 88 | 88 | |
| 89 | − usbphy: phy@01c13400 { | |
| 89 | + usbphy: phy@1c13400 { | |
| 90 | 90 | #phy-cells = <1>; |
| 91 | 91 | compatible = "allwinner,sun4i-a10-usb-phy"; |
| 92 | 92 | reg = <0x01c13400 0x10>, <0x01c14800 0x4>, <0x01c1c800 0x4>; |
| @@ -17,7 +17,7 @@ description: |+ · 16 unmodified lines | ||
| 17 | 17 | "aspeed,ast2400-scu", "syscon", "simple-mfd" |
| 18 | 18 | |
| 19 | 19 | Refer to the the bindings described in |
| 20 | − Documentation/devicetree/bindings/mfd/syscon.txt | |
| 20 | + Documentation/devicetree/bindings/mfd/syscon.yaml | |
| 21 | 21 | |
| 22 | 22 | properties: |
| 23 | 23 | compatible: |
| @@ -18,7 +18,7 @@ description: |+ · 17 unmodified lines | ||
| 18 | 18 | "aspeed,g5-scu", "syscon", "simple-mfd" |
| 19 | 19 | |
| 20 | 20 | Refer to the the bindings described in |
| 21 | − Documentation/devicetree/bindings/mfd/syscon.txt | |
| 21 | + Documentation/devicetree/bindings/mfd/syscon.yaml | |
| 22 | 22 | |
| 23 | 23 | properties: |
| 24 | 24 | compatible: |
| @@ -17,7 +17,7 @@ description: |+ · 16 unmodified lines | ||
| 17 | 17 | "aspeed,ast2600-scu", "syscon", "simple-mfd" |
| 18 | 18 | |
| 19 | 19 | Refer to the the bindings described in |
| 20 | − Documentation/devicetree/bindings/mfd/syscon.txt | |
| 20 | + Documentation/devicetree/bindings/mfd/syscon.yaml | |
| 21 | 21 | |
| 22 | 22 | properties: |
| 23 | 23 | compatible: |
| @@ -248,7 +248,7 @@ examples: · 247 unmodified lines | ||
| 248 | 248 | }; |
| 249 | 249 | |
| 250 | 250 | //Example 3 pin groups |
| 251 | − pinctrl@60020000 { | |
| 251 | + pinctrl { | |
| 252 | 252 | usart1_pins_a: usart1-0 { |
| 253 | 253 | pins1 { |
| 254 | 254 | pinmux = <STM32_PINMUX('A', 9, AF7)>; |
| @@ -18,7 +18,7 @@ description: |+ · 17 unmodified lines | ||
| 18 | 18 | "amlogic,meson-gx-hhi-sysctrl", "simple-mfd", "syscon" |
| 19 | 19 | |
| 20 | 20 | Refer to the the bindings described in |
| 21 | − Documentation/devicetree/bindings/mfd/syscon.txt | |
| 21 | + Documentation/devicetree/bindings/mfd/syscon.yaml | |
| 22 | 22 | |
| 23 | 23 | properties: |
| 24 | 24 | compatible: |
| @@ -1,33 +0,0 @@ | ||
| 1 | −PM Domain Idle State Node: | |
| 2 | − | |
| 3 | −A domain idle state node represents the state parameters that will be used to | |
| 4 | −select the state when there are no active components in the domain. | |
| 5 | − | |
| 6 | −The state node has the following parameters - | |
| 7 | − | |
| 8 | −- compatible: | |
| 9 | − Usage: Required | |
| 10 | − Value type: <string> | |
| 11 | − Definition: Must be "domain-idle-state". | |
| 12 | − | |
| 13 | −- entry-latency-us | |
| 14 | − Usage: Required | |
| 15 | − Value type: <prop-encoded-array> | |
| 16 | − Definition: u32 value representing worst case latency in | |
| 17 | − microseconds required to enter the idle state. | |
| 18 | − The exit-latency-us duration may be guaranteed | |
| 19 | − only after entry-latency-us has passed. | |
| 20 | − | |
| 21 | −- exit-latency-us | |
| 22 | − Usage: Required | |
| 23 | − Value type: <prop-encoded-array> | |
| 24 | − Definition: u32 value representing worst case latency | |
| 25 | − in microseconds required to exit the idle state. | |
| 26 | − | |
| 27 | −- min-residency-us | |
| 28 | − Usage: Required | |
| 29 | − Value type: <prop-encoded-array> | |
| 30 | − Definition: u32 value representing minimum residency duration | |
| 31 | − in microseconds after which the idle state will yield | |
| 32 | − power benefits after overcoming the overhead in entering | |
| 33 | −i the idle state. | |
| @@ -0,0 +1,64 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/power/domain-idle-state.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: PM Domain Idle States binding description | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Ulf Hansson <ulf.hansson@linaro.org> | |
| 11 | + | |
| 12 | +description: | |
| 13 | + A domain idle state node represents the state parameters that will be used to | |
| 14 | + select the state when there are no active components in the PM domain. | |
| 15 | + | |
| 16 | +properties: | |
| 17 | + $nodename: | |
| 18 | + const: domain-idle-states | |
| 19 | + | |
| 20 | +patternProperties: | |
| 21 | + "^(cpu|cluster|domain)-": | |
| 22 | + type: object | |
| 23 | + description: | |
| 24 | + Each state node represents a domain idle state description. | |
| 25 | + | |
| 26 | + properties: | |
| 27 | + compatible: | |
| 28 | + const: domain-idle-state | |
| 29 | + | |
| 30 | + entry-latency-us: | |
| 31 | + description: | |
| 32 | + The worst case latency in microseconds required to enter the idle | |
| 33 | + state. Note that, the exit-latency-us duration may be guaranteed only | |
| 34 | + after the entry-latency-us has passed. | |
| 35 | + | |
| 36 | + exit-latency-us: | |
| 37 | + description: | |
| 38 | + The worst case latency in microseconds required to exit the idle | |
| 39 | + state. | |
| 40 | + | |
| 41 | + min-residency-us: | |
| 42 | + description: | |
| 43 | + The minimum residency duration in microseconds after which the idle | |
| 44 | + state will yield power benefits, after overcoming the overhead while | |
| 45 | + entering the idle state. | |
| 46 | + | |
| 47 | + required: | |
| 48 | + - compatible | |
| 49 | + - entry-latency-us | |
| 50 | + - exit-latency-us | |
| 51 | + - min-residency-us | |
| 52 | + | |
| 53 | +examples: | |
| 54 | + - | | |
| 55 | + | |
| 56 | + domain-idle-states { | |
| 57 | + domain_retention: domain-retention { | |
| 58 | + compatible = "domain-idle-state"; | |
| 59 | + entry-latency-us = <20>; | |
| 60 | + exit-latency-us = <40>; | |
| 61 | + min-residency-us = <80>; | |
| 62 | + }; | |
| 63 | + }; | |
| 64 | +... | |
| @@ -25,22 +25,20 @@ description: |+ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | properties: |
| 27 | 27 | $nodename: |
| 28 | − pattern: "^(power-controller|power-domain)(@.*)?$" | |
| 28 | + pattern: "^(power-controller|power-domain)([@-].*)?$" | |
| 29 | 29 | |
| 30 | 30 | domain-idle-states: |
| 31 | 31 | $ref: /schemas/types.yaml#/definitions/phandle-array |
| 32 | − description: | |
| 33 | − A phandle of an idle-state that shall be soaked into a generic domain | |
| 34 | − power state. The idle state definitions are compatible with | |
| 35 | − domain-idle-state specified in | |
| 36 | − Documentation/devicetree/bindings/power/domain-idle-state.txt | |
| 37 | − phandles that are not compatible with domain-idle-state will be ignored. | |
| 38 | − The domain-idle-state property reflects the idle state of this PM domain | |
| 39 | − and not the idle states of the devices or sub-domains in the PM domain. | |
| 40 | − Devices and sub-domains have their own idle-states independent | |
| 41 | − of the parent domain's idle states. In the absence of this property, | |
| 42 | − the domain would be considered as capable of being powered-on | |
| 43 | − or powered-off. | |
| 32 | + description: | | |
| 33 | + Phandles of idle states that defines the available states for the | |
| 34 | + power-domain provider. The idle state definitions are compatible with the | |
| 35 | + domain-idle-state bindings, specified in ./domain-idle-state.yaml. | |
| 36 | + | |
| 37 | + Note that, the domain-idle-state property reflects the idle states of this | |
| 38 | + PM domain and not the idle states of the devices or sub-domains in the PM | |
| 39 | + domain. Devices and sub-domains have their own idle states independent of | |
| 40 | + the parent domain's idle states. In the absence of this property, the | |
| 41 | + domain would be considered as capable of being powered-on or powered-off. | |
| 44 | 42 | |
| 45 | 43 | operating-points-v2: |
| 46 | 44 | $ref: /schemas/types.yaml#/definitions/phandle-array |
| @@ -109,4 +109,4 @@ Example: · 108 unmodified lines | ||
| 109 | 109 | required-opps = <&domain1_opp_1>; |
| 110 | 110 | }; |
| 111 | 111 | |
| 112 | −[1]. Documentation/devicetree/bindings/power/domain-idle-state.txt | |
| 112 | +[1]. Documentation/devicetree/bindings/power/domain-idle-state.yaml | |
| @@ -161,7 +161,7 @@ The regulator node houses sub-nodes for each regulator within the device. Each · 160 unmodified lines | ||
| 161 | 161 | sub-node is identified using the node's name, with valid values listed for each |
| 162 | 162 | of the PMICs below. |
| 163 | 163 | |
| 164 | −pm8005: | |
| 164 | +pm8004: | |
| 165 | 165 | s2, s5 |
| 166 | 166 | |
| 167 | 167 | pm8005: |
| @@ -191,7 +191,7 @@ patternProperties: · 190 unmodified lines | ||
| 191 | 191 | |
| 192 | 192 | examples: |
| 193 | 193 | - | |
| 194 | − xyzreg: regulator@0 { | |
| 194 | + xyzreg: regulator { | |
| 195 | 195 | regulator-min-microvolt = <1000000>; |
| 196 | 196 | regulator-max-microvolt = <2500000>; |
| 197 | 197 | regulator-always-on; |
| @@ -23,7 +23,11 @@ properties: · 22 unmodified lines | ||
| 23 | 23 | description: Global reset register offset and bit offset. |
| 24 | 24 | allOf: |
| 25 | 25 | - $ref: /schemas/types.yaml#/definitions/uint32-array |
| 26 | − - maxItems: 2 | |
| 26 | + items: | |
| 27 | + - description: Register offset | |
| 28 | + - description: Register bit offset | |
| 29 | + minimum: 0 | |
| 30 | + maximum: 31 | |
| 27 | 31 | |
| 28 | 32 | "#reset-cells": |
| 29 | 33 | minimum: 2 |
| @@ -3,4 +3,4 @@ STMicroelectronics STM32MP1 Peripheral Reset Controller · 2 unmodified lines | ||
| 3 | 3 | |
| 4 | 4 | The RCC IP is both a reset and a clock controller. |
| 5 | 5 | |
| 6 | −Please see Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.txt | |
| 6 | +Please see Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.yaml | |
| @@ -36,7 +36,7 @@ SAI subnodes required properties: · 35 unmodified lines | ||
| 36 | 36 | - clock-names: Must contain "sai_ck". |
| 37 | 37 | Must also contain "MCLK", if SAI shares a master clock, |
| 38 | 38 | with a SAI set as MCLK clock provider. |
| 39 | − - dmas: see Documentation/devicetree/bindings/dma/stm32-dma.txt | |
| 39 | + - dmas: see Documentation/devicetree/bindings/dma/st,stm32-dma.yaml | |
| 40 | 40 | - dma-names: identifier string for each DMA request line |
| 41 | 41 | "tx": if sai sub-block is configured as playback DAI |
| 42 | 42 | "rx": if sai sub-block is configured as capture DAI |
| @@ -10,7 +10,7 @@ Required properties: · 9 unmodified lines | ||
| 10 | 10 | - clock-names: must contain "kclk" |
| 11 | 11 | - interrupts: cpu DAI interrupt line |
| 12 | 12 | - dmas: DMA specifiers for audio data DMA and iec control flow DMA |
| 13 | − See STM32 DMA bindings, Documentation/devicetree/bindings/dma/stm32-dma.txt | |
| 13 | + See STM32 DMA bindings, Documentation/devicetree/bindings/dma/st,stm32-dma.yaml | |
| 14 | 14 | - dma-names: two dmas have to be defined, "rx" and "rx-ctrl" |
| 15 | 15 | |
| 16 | 16 | Optional properties: |
| @@ -49,7 +49,7 @@ properties: · 48 unmodified lines | ||
| 49 | 49 | dmas: |
| 50 | 50 | description: | |
| 51 | 51 | DMA specifiers for tx and rx dma. DMA fifo mode must be used. See |
| 52 | − the STM32 DMA bindings Documentation/devicetree/bindings/dma/stm32-dma.txt. | |
| 52 | + the STM32 DMA bindings Documentation/devicetree/bindings/dma/st,stm32-dma.yaml. | |
| 53 | 53 | items: |
| 54 | 54 | - description: rx DMA channel |
| 55 | 55 | - description: tx DMA channel |
| @@ -125,7 +125,7 @@ examples: · 124 unmodified lines | ||
| 125 | 125 | #size-cells = <1>; |
| 126 | 126 | ranges; |
| 127 | 127 | |
| 128 | − sram_a: sram@00000000 { | |
| 128 | + sram_a: sram@0 { | |
| 129 | 129 | compatible = "mmio-sram"; |
| 130 | 130 | reg = <0x00000000 0xc000>; |
| 131 | 131 | #address-cells = <1>; |
| @@ -17,7 +17,7 @@ description: |+ · 16 unmodified lines | ||
| 17 | 17 | "brcm,bcm2711-avs-monitor", "syscon", "simple-mfd" |
| 18 | 18 | |
| 19 | 19 | Refer to the the bindings described in |
| 20 | − Documentation/devicetree/bindings/mfd/syscon.txt | |
| 20 | + Documentation/devicetree/bindings/mfd/syscon.yaml | |
| 21 | 21 | |
| 22 | 22 | properties: |
| 23 | 23 | compatible: |
| @@ -87,7 +87,7 @@ additionalProperties: false · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | examples: |
| 89 | 89 | - | |
| 90 | − timer { | |
| 90 | + timer@1c20c00 { | |
| 91 | 91 | compatible = "allwinner,sun4i-a10-timer"; |
| 92 | 92 | reg = <0x01c20c00 0x400>; |
| 93 | 93 | interrupts = <22>, |
| @@ -151,8 +151,8 @@ The details of these operations are: · 150 unmodified lines | ||
| 151 | 151 | Note that callbacks will always be invoked from the DMA |
| 152 | 152 | engines tasklet, never from interrupt context. |
| 153 | 153 | |
| 154 | −Optional: per descriptor metadata | |
| 155 | −--------------------------------- | |
| 154 | + **Optional: per descriptor metadata** | |
| 155 | + | |
| 156 | 156 | DMAengine provides two ways for metadata support. |
| 157 | 157 | |
| 158 | 158 | DESC_METADATA_CLIENT |
| @@ -199,12 +199,15 @@ Optional: per descriptor metadata · 40 unmodified lines | ||
| 199 | 199 | DESC_METADATA_CLIENT |
| 200 | 200 | |
| 201 | 201 | - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM: |
| 202 | + | |
| 202 | 203 | 1. prepare the descriptor (dmaengine_prep_*) |
| 203 | 204 | construct the metadata in the client's buffer |
| 204 | 205 | 2. use dmaengine_desc_attach_metadata() to attach the buffer to the |
| 205 | 206 | descriptor |
| 206 | 207 | 3. submit the transfer |
| 208 | + | |
| 207 | 209 | - DMA_DEV_TO_MEM: |
| 210 | + | |
| 208 | 211 | 1. prepare the descriptor (dmaengine_prep_*) |
| 209 | 212 | 2. use dmaengine_desc_attach_metadata() to attach the buffer to the |
| 210 | 213 | descriptor |
| @@ -215,6 +218,7 @@ Optional: per descriptor metadata · 4 unmodified lines | ||
| 215 | 218 | DESC_METADATA_ENGINE |
| 216 | 219 | |
| 217 | 220 | - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM: |
| 221 | + | |
| 218 | 222 | 1. prepare the descriptor (dmaengine_prep_*) |
| 219 | 223 | 2. use dmaengine_desc_get_metadata_ptr() to get the pointer to the |
| 220 | 224 | engine's metadata area |
| @@ -222,7 +226,9 @@ Optional: per descriptor metadata · 1 unmodified line | ||
| 222 | 226 | 4. use dmaengine_desc_set_metadata_len() to tell the DMA engine the |
| 223 | 227 | amount of data the client has placed into the metadata buffer |
| 224 | 228 | 5. submit the transfer |
| 229 | + | |
| 225 | 230 | - DMA_DEV_TO_MEM: |
| 231 | + | |
| 226 | 232 | 1. prepare the descriptor (dmaengine_prep_*) |
| 227 | 233 | 2. submit the transfer |
| 228 | 234 | 3. on transfer completion, use dmaengine_desc_get_metadata_ptr() to get |
| @@ -278,8 +284,8 @@ Optional: per descriptor metadata · 49 unmodified lines | ||
| 278 | 284 | |
| 279 | 285 | void dma_async_issue_pending(struct dma_chan *chan); |
| 280 | 286 | |
| 281 | −Further APIs: | |
| 282 | −------------- | |
| 287 | +Further APIs | |
| 288 | +------------ | |
| 283 | 289 | |
| 284 | 290 | 1. Terminate APIs |
| 285 | 291 | |
| @@ -164,9 +164,9 @@ file. · 163 unmodified lines | ||
| 164 | 164 | void __iomem *base; |
| 165 | 165 | }; |
| 166 | 166 | |
| 167 | − struct dentry *debugfs_create_regset32(const char *name, umode_t mode, | |
| 168 | − struct dentry *parent, | |
| 169 | − struct debugfs_regset32 *regset); | |
| 167 | + debugfs_create_regset32(const char *name, umode_t mode, | |
| 168 | + struct dentry *parent, | |
| 169 | + struct debugfs_regset32 *regset); | |
| 170 | 170 | |
| 171 | 171 | void debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs, |
| 172 | 172 | int nregs, void __iomem *base, char *prefix); |
| @@ -850,3 +850,11 @@ business doing so. · 849 unmodified lines | ||
| 850 | 850 | d_alloc_pseudo() is internal-only; uses outside of alloc_file_pseudo() are |
| 851 | 851 | very suspect (and won't work in modules). Such uses are very likely to |
| 852 | 852 | be misspelled d_alloc_anon(). |
| 853 | + | |
| 854 | +--- | |
| 855 | + | |
| 856 | +**mandatory** | |
| 857 | + | |
| 858 | +[should've been added in 2016] stale comment in finish_open() nonwithstanding, | |
| 859 | +failure exits in ->atomic_open() instances should *NOT* fput() the file, | |
| 860 | +no matter what. Everything is handled by the caller. | |
| @@ -20,8 +20,7 @@ Usage Notes · 19 unmodified lines | ||
| 20 | 20 | ----------- |
| 21 | 21 | |
| 22 | 22 | This driver does not auto-detect devices. You will have to instantiate the |
| 23 | −devices explicitly. Please see Documentation/i2c/instantiating-devices for | |
| 24 | −details. | |
| 23 | +devices explicitly. Please see :doc:`/i2c/instantiating-devices` for details. | |
| 25 | 24 | |
| 26 | 25 | |
| 27 | 26 | Sysfs entries |
| @@ -237,7 +237,7 @@ This is solely useful to speed up test compiles. · 236 unmodified lines | ||
| 237 | 237 | KBUILD_EXTRA_SYMBOLS |
| 238 | 238 | -------------------- |
| 239 | 239 | For modules that use symbols from other modules. |
| 240 | −See more details in modules.txt. | |
| 240 | +See more details in modules.rst. | |
| 241 | 241 | |
| 242 | 242 | ALLSOURCE_ARCHS |
| 243 | 243 | --------------- |
| @@ -44,7 +44,7 @@ intermediate:: · 43 unmodified lines | ||
| 44 | 44 | def_bool y |
| 45 | 45 | |
| 46 | 46 | Then, Kconfig moves onto the evaluation stage to resolve inter-symbol |
| 47 | −dependency as explained in kconfig-language.txt. | |
| 47 | +dependency as explained in kconfig-language.rst. | |
| 48 | 48 | |
| 49 | 49 | |
| 50 | 50 | Variables |
| @@ -765,7 +765,7 @@ is not sufficient this sometimes needs to be explicit. · 764 unmodified lines | ||
| 765 | 765 | Example:: |
| 766 | 766 | |
| 767 | 767 | #arch/x86/boot/Makefile |
| 768 | − subdir- := compressed/ | |
| 768 | + subdir- := compressed | |
| 769 | 769 | |
| 770 | 770 | The above assignment instructs kbuild to descend down in the |
| 771 | 771 | directory compressed/ when "make clean" is executed. |
| @@ -924,7 +924,7 @@ When kbuild executes, the following steps are followed (roughly): · 152 unmodified lines | ||
| 924 | 924 | $(KBUILD_AFLAGS_MODULE) is used to add arch-specific options that |
| 925 | 925 | are used for assembler. |
| 926 | 926 | |
| 927 | − From commandline AFLAGS_MODULE shall be used (see kbuild.txt). | |
| 927 | + From commandline AFLAGS_MODULE shall be used (see kbuild.rst). | |
| 928 | 928 | |
| 929 | 929 | KBUILD_CFLAGS_KERNEL |
| 930 | 930 | $(CC) options specific for built-in |
| @@ -937,7 +937,7 @@ When kbuild executes, the following steps are followed (roughly): · 6 unmodified lines | ||
| 937 | 937 | |
| 938 | 938 | $(KBUILD_CFLAGS_MODULE) is used to add arch-specific options that |
| 939 | 939 | are used for $(CC). |
| 940 | − From commandline CFLAGS_MODULE shall be used (see kbuild.txt). | |
| 940 | + From commandline CFLAGS_MODULE shall be used (see kbuild.rst). | |
| 941 | 941 | |
| 942 | 942 | KBUILD_LDFLAGS_MODULE |
| 943 | 943 | Options for $(LD) when linking modules |
| @@ -945,7 +945,7 @@ When kbuild executes, the following steps are followed (roughly): · 1 unmodified line | ||
| 945 | 945 | $(KBUILD_LDFLAGS_MODULE) is used to add arch-specific options |
| 946 | 946 | used when linking modules. This is often a linker script. |
| 947 | 947 | |
| 948 | − From commandline LDFLAGS_MODULE shall be used (see kbuild.txt). | |
| 948 | + From commandline LDFLAGS_MODULE shall be used (see kbuild.rst). | |
| 949 | 949 | |
| 950 | 950 | KBUILD_LDS |
| 951 | 951 | |
| @@ -1379,9 +1379,6 @@ See subsequent chapter for the syntax of the Kbuild file. · 427 unmodified lines | ||
| 1379 | 1379 | in arch/$(ARCH)/include/(uapi/)/asm, Kbuild will automatically generate |
| 1380 | 1380 | a wrapper of the asm-generic one. |
| 1381 | 1381 | |
| 1382 | − The convention is to list one subdir per line and | |
| 1383 | − preferably in alphabetic order. | |
| 1384 | − | |
| 1385 | 1382 | 8 Kbuild Variables |
| 1386 | 1383 | ================== |
| 1387 | 1384 | |
| @@ -470,9 +470,9 @@ build. · 469 unmodified lines | ||
| 470 | 470 | |
| 471 | 471 | The syntax of the Module.symvers file is:: |
| 472 | 472 | |
| 473 | − <CRC> <Symbol> <Namespace> <Module> <Export Type> | |
| 473 | + <CRC> <Symbol> <Module> <Export Type> <Namespace> | |
| 474 | 474 | |
| 475 | − 0xe1cc2a05 usb_stor_suspend USB_STORAGE drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL | |
| 475 | + 0xe1cc2a05 usb_stor_suspend drivers/usb/storage/usb-storage EXPORT_SYMBOL_GPL USB_STORAGE | |
| 476 | 476 | |
| 477 | 477 | The fields are separated by tabs and values may be empty (e.g. |
| 478 | 478 | if no namespace is defined for an exported symbol). |
| @@ -40,9 +40,6 @@ example usage · 39 unmodified lines | ||
| 40 | 40 | # Delete a snapshot using: |
| 41 | 41 | $ devlink region del pci/0000:00:05.0/cr-space snapshot 1 |
| 42 | 42 | |
| 43 | − # Trigger (request) a snapshot be taken: | |
| 44 | − $ devlink region trigger pci/0000:00:05.0/cr-space | |
| 45 | − | |
| 46 | 43 | # Dump a snapshot: |
| 47 | 44 | $ devlink region dump pci/0000:00:05.0/fw-health snapshot 1 |
| 48 | 45 | 0000000000000000 0014 95dc 0014 9514 0035 1670 0034 db30 |
| @@ -8,9 +8,9 @@ Overview · 7 unmodified lines | ||
| 8 | 8 | ======== |
| 9 | 9 | |
| 10 | 10 | The net_failover driver provides an automated failover mechanism via APIs |
| 11 | −to create and destroy a failover master netdev and mananges a primary and | |
| 11 | +to create and destroy a failover master netdev and manages a primary and | |
| 12 | 12 | standby slave netdevs that get registered via the generic failover |
| 13 | −infrastructrure. | |
| 13 | +infrastructure. | |
| 14 | 14 | |
| 15 | 15 | The failover netdev acts a master device and controls 2 slave devices. The |
| 16 | 16 | original paravirtual interface is registered as 'standby' slave netdev and |
| @@ -29,7 +29,7 @@ virtio-net accelerated datapath: STANDBY mode · 12 unmodified lines | ||
| 29 | 29 | ============================================= |
| 30 | 30 | |
| 31 | 31 | net_failover enables hypervisor controlled accelerated datapath to virtio-net |
| 32 | −enabled VMs in a transparent manner with no/minimal guest userspace chanages. | |
| 32 | +enabled VMs in a transparent manner with no/minimal guest userspace changes. | |
| 33 | 33 | |
| 34 | 34 | To support this, the hypervisor needs to enable VIRTIO_NET_F_STANDBY |
| 35 | 35 | feature on the virtio-net interface and assign the same MAC address to both |
| @@ -487,8 +487,9 @@ phy_register_fixup_for_id():: · 486 unmodified lines | ||
| 487 | 487 | The stubs set one of the two matching criteria, and set the other one to |
| 488 | 488 | match anything. |
| 489 | 489 | |
| 490 | −When phy_register_fixup() or \*_for_uid()/\*_for_id() is called at module, | |
| 491 | −unregister fixup and free allocate memory are required. | |
| 490 | +When phy_register_fixup() or \*_for_uid()/\*_for_id() is called at module load | |
| 491 | +time, the module needs to unregister the fixup and free allocated memory when | |
| 492 | +it's unloaded. | |
| 492 | 493 | |
| 493 | 494 | Call one of following function before unloading module:: |
| 494 | 495 | |
| @@ -159,7 +159,7 @@ Socket Interface · 158 unmodified lines | ||
| 159 | 159 | set SO_RDS_TRANSPORT on a socket for which the transport has |
| 160 | 160 | been previously attached explicitly (by SO_RDS_TRANSPORT) or |
| 161 | 161 | implicitly (via bind(2)) will return an error of EOPNOTSUPP. |
| 162 | − An attempt to set SO_RDS_TRANSPPORT to RDS_TRANS_NONE will | |
| 162 | + An attempt to set SO_RDS_TRANSPORT to RDS_TRANS_NONE will | |
| 163 | 163 | always return EINVAL. |
| 164 | 164 | |
| 165 | 165 | RDMA for RDS |
| @@ -13,7 +13,6 @@ Power Management · 12 unmodified lines | ||
| 13 | 13 | drivers-testing |
| 14 | 14 | energy-model |
| 15 | 15 | freezing-of-tasks |
| 16 | − interface | |
| 17 | 16 | opp |
| 18 | 17 | pci |
| 19 | 18 | pm_qos_interface |
| @@ -30,4 +30,4 @@ if [ -n "$parallel" ] ; then · 29 unmodified lines | ||
| 30 | 30 | parallel="-j$parallel" |
| 31 | 31 | fi |
| 32 | 32 | |
| 33 | −exec "$sphinx" "$parallel" "$@" | |
| 33 | +exec "$sphinx" $parallel "$@" | |
| @@ -4611,35 +4611,38 @@ unpins the VPA pages and releases all the device pages that are used to · 4610 unmodified lines | ||
| 4611 | 4611 | track the secure pages by hypervisor. |
| 4612 | 4612 | |
| 4613 | 4613 | 4.122 KVM_S390_NORMAL_RESET |
| 4614 | +--------------------------- | |
| 4614 | 4615 | |
| 4615 | −Capability: KVM_CAP_S390_VCPU_RESETS | |
| 4616 | −Architectures: s390 | |
| 4617 | −Type: vcpu ioctl | |
| 4618 | −Parameters: none | |
| 4619 | −Returns: 0 | |
| 4616 | +:Capability: KVM_CAP_S390_VCPU_RESETS | |
| 4617 | +:Architectures: s390 | |
| 4618 | +:Type: vcpu ioctl | |
| 4619 | +:Parameters: none | |
| 4620 | +:Returns: 0 | |
| 4620 | 4621 | |
| 4621 | 4622 | This ioctl resets VCPU registers and control structures according to |
| 4622 | 4623 | the cpu reset definition in the POP (Principles Of Operation). |
| 4623 | 4624 | |
| 4624 | 4625 | 4.123 KVM_S390_INITIAL_RESET |
| 4626 | +---------------------------- | |
| 4625 | 4627 | |
| 4626 | −Capability: none | |
| 4627 | −Architectures: s390 | |
| 4628 | −Type: vcpu ioctl | |
| 4629 | −Parameters: none | |
| 4630 | −Returns: 0 | |
| 4628 | +:Capability: none | |
| 4629 | +:Architectures: s390 | |
| 4630 | +:Type: vcpu ioctl | |
| 4631 | +:Parameters: none | |
| 4632 | +:Returns: 0 | |
| 4631 | 4633 | |
| 4632 | 4634 | This ioctl resets VCPU registers and control structures according to |
| 4633 | 4635 | the initial cpu reset definition in the POP. However, the cpu is not |
| 4634 | 4636 | put into ESA mode. This reset is a superset of the normal reset. |
| 4635 | 4637 | |
| 4636 | 4638 | 4.124 KVM_S390_CLEAR_RESET |
| 4639 | +-------------------------- | |
| 4637 | 4640 | |
| 4638 | −Capability: KVM_CAP_S390_VCPU_RESETS | |
| 4639 | −Architectures: s390 | |
| 4640 | −Type: vcpu ioctl | |
| 4641 | −Parameters: none | |
| 4642 | −Returns: 0 | |
| 4641 | +:Capability: KVM_CAP_S390_VCPU_RESETS | |
| 4642 | +:Architectures: s390 | |
| 4643 | +:Type: vcpu ioctl | |
| 4644 | +:Parameters: none | |
| 4645 | +:Returns: 0 | |
| 4643 | 4646 | |
| 4644 | 4647 | This ioctl resets VCPU registers and control structures according to |
| 4645 | 4648 | the clear cpu reset definition in the POP. However, the cpu is not put |
| @@ -19,7 +19,6 @@ x86-specific Documentation · 18 unmodified lines | ||
| 19 | 19 | tlb |
| 20 | 20 | mtrr |
| 21 | 21 | pat |
| 22 | − intel_mpx | |
| 23 | 22 | intel-iommu |
| 24 | 23 | intel_txt |
| 25 | 24 | amd-memory-encryption |
| @@ -693,7 +693,7 @@ ALLWINNER CPUFREQ DRIVER · 692 unmodified lines | ||
| 693 | 693 | M: Yangtao Li <tiny.windzz@gmail.com> |
| 694 | 694 | L: linux-pm@vger.kernel.org |
| 695 | 695 | S: Maintained |
| 696 | −F: Documentation/devicetree/bindings/opp/sun50i-nvmem-cpufreq.txt | |
| 696 | +F: Documentation/devicetree/bindings/opp/allwinner,sun50i-h6-operating-points.yaml | |
| 697 | 697 | F: drivers/cpufreq/sun50i-cpufreq-nvmem.c |
| 698 | 698 | |
| 699 | 699 | ALLWINNER CRYPTO DRIVERS |
| @@ -4017,7 +4017,7 @@ M: Cheng-Yi Chiang <cychiang@chromium.org> · 3317 unmodified lines | ||
| 4017 | 4017 | S: Maintained |
| 4018 | 4018 | R: Enric Balletbo i Serra <enric.balletbo@collabora.com> |
| 4019 | 4019 | R: Guenter Roeck <groeck@chromium.org> |
| 4020 | −F: Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt | |
| 4020 | +F: Documentation/devicetree/bindings/sound/google,cros-ec-codec.yaml | |
| 4021 | 4021 | F: sound/soc/codecs/cros_ec_codec.* |
| 4022 | 4022 | |
| 4023 | 4023 | CIRRUS LOGIC AUDIO CODEC DRIVERS |
| @@ -4073,7 +4073,6 @@ F: drivers/scsi/snic/ · 49 unmodified lines | ||
| 4073 | 4073 | CISCO VIC ETHERNET NIC DRIVER |
| 4074 | 4074 | M: Christian Benvenuti <benve@cisco.com> |
| 4075 | 4075 | M: Govindarajulu Varadarajan <_govind@gmx.com> |
| 4076 | −M: Parvi Kaustubhi <pkaustub@cisco.com> | |
| 4077 | 4076 | S: Supported |
| 4078 | 4077 | F: drivers/net/ethernet/cisco/enic/ |
| 4079 | 4078 | |
| @@ -4475,7 +4474,7 @@ L: linux-media@vger.kernel.org · 395 unmodified lines | ||
| 4475 | 4474 | T: git git://linuxtv.org/media_tree.git |
| 4476 | 4475 | S: Maintained |
| 4477 | 4476 | F: drivers/media/platform/sunxi/sun6i-csi/ |
| 4478 | −F: Documentation/devicetree/bindings/media/sun6i-csi.txt | |
| 4477 | +F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml | |
| 4479 | 4478 | |
| 4480 | 4479 | CW1200 WLAN driver |
| 4481 | 4480 | M: Solomon Peachy <pizza@shaftnet.org> |
| @@ -4572,7 +4571,7 @@ F: drivers/infiniband/hw/cxgb4/ · 90 unmodified lines | ||
| 4572 | 4571 | F: include/uapi/rdma/cxgb4-abi.h |
| 4573 | 4572 | |
| 4574 | 4573 | CXGB4VF ETHERNET DRIVER (CXGB4VF) |
| 4575 | −M: Casey Leedom <leedom@chelsio.com> | |
| 4574 | +M: Vishal Kulkarni <vishal@gmail.com> | |
| 4576 | 4575 | L: netdev@vger.kernel.org |
| 4577 | 4576 | W: http://www.chelsio.com |
| 4578 | 4577 | S: Supported |
| @@ -5668,7 +5667,7 @@ L: dri-devel@lists.freedesktop.org · 1089 unmodified lines | ||
| 5668 | 5667 | T: git git://anongit.freedesktop.org/drm/drm-misc |
| 5669 | 5668 | S: Maintained |
| 5670 | 5669 | F: drivers/gpu/drm/stm |
| 5671 | −F: Documentation/devicetree/bindings/display/st,stm32-ltdc.txt | |
| 5670 | +F: Documentation/devicetree/bindings/display/st,stm32-ltdc.yaml | |
| 5672 | 5671 | |
| 5673 | 5672 | DRM DRIVERS FOR TI LCDC |
| 5674 | 5673 | M: Jyri Sarha <jsarha@ti.com> |
| @@ -6198,7 +6197,6 @@ S: Supported · 523 unmodified lines | ||
| 6198 | 6197 | F: drivers/scsi/be2iscsi/ |
| 6199 | 6198 | |
| 6200 | 6199 | Emulex 10Gbps NIC BE2, BE3-R, Lancer, Skyhawk-R DRIVER (be2net) |
| 6201 | −M: Sathya Perla <sathya.perla@broadcom.com> | |
| 6202 | 6200 | M: Ajit Khaparde <ajit.khaparde@broadcom.com> |
| 6203 | 6201 | M: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com> |
| 6204 | 6202 | M: Somnath Kotur <somnath.kotur@broadcom.com> |
| @@ -7738,7 +7736,7 @@ Hyper-V CORE AND DRIVERS · 1533 unmodified lines | ||
| 7738 | 7736 | M: "K. Y. Srinivasan" <kys@microsoft.com> |
| 7739 | 7737 | M: Haiyang Zhang <haiyangz@microsoft.com> |
| 7740 | 7738 | M: Stephen Hemminger <sthemmin@microsoft.com> |
| 7741 | −M: Sasha Levin <sashal@kernel.org> | |
| 7739 | +M: Wei Liu <wei.liu@kernel.org> | |
| 7742 | 7740 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git |
| 7743 | 7741 | L: linux-hyperv@vger.kernel.org |
| 7744 | 7742 | S: Supported |
| @@ -10175,7 +10173,7 @@ MAXBOTIX ULTRASONIC RANGER IIO DRIVER · 2430 unmodified lines | ||
| 10175 | 10173 | M: Andreas Klinger <ak@it-klinger.de> |
| 10176 | 10174 | L: linux-iio@vger.kernel.org |
| 10177 | 10175 | S: Maintained |
| 10178 | −F: Documentation/devicetree/bindings/iio/proximity/maxbotix,mb1232.txt | |
| 10176 | +F: Documentation/devicetree/bindings/iio/proximity/maxbotix,mb1232.yaml | |
| 10179 | 10177 | F: drivers/iio/proximity/mb1232.c |
| 10180 | 10178 | |
| 10181 | 10179 | MAXIM MAX77650 PMIC MFD DRIVER |
| @@ -10478,7 +10476,7 @@ M: Hugues Fruchet <hugues.fruchet@st.com> · 296 unmodified lines | ||
| 10478 | 10476 | L: linux-media@vger.kernel.org |
| 10479 | 10477 | T: git git://linuxtv.org/media_tree.git |
| 10480 | 10478 | S: Supported |
| 10481 | −F: Documentation/devicetree/bindings/media/st,stm32-dcmi.txt | |
| 10479 | +F: Documentation/devicetree/bindings/media/st,stm32-dcmi.yaml | |
| 10482 | 10480 | F: drivers/media/platform/stm32/stm32-dcmi.c |
| 10483 | 10481 | |
| 10484 | 10482 | MEDIA DRIVERS FOR NVIDIA TEGRA - VDE |
| @@ -11126,14 +11124,12 @@ S: Maintained · 641 unmodified lines | ||
| 11126 | 11124 | F: drivers/usb/image/microtek.* |
| 11127 | 11125 | |
| 11128 | 11126 | MIPS |
| 11129 | −M: Ralf Baechle <ralf@linux-mips.org> | |
| 11130 | −M: Paul Burton <paulburton@kernel.org> | |
| 11127 | +M: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | |
| 11131 | 11128 | L: linux-mips@vger.kernel.org |
| 11132 | 11129 | W: http://www.linux-mips.org/ |
| 11133 | −T: git git://git.linux-mips.org/pub/scm/ralf/linux.git | |
| 11134 | 11130 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux.git |
| 11135 | −Q: http://patchwork.linux-mips.org/project/linux-mips/list/ | |
| 11136 | −S: Supported | |
| 11131 | +Q: https://patchwork.kernel.org/project/linux-mips/list/ | |
| 11132 | +S: Maintained | |
| 11137 | 11133 | F: Documentation/devicetree/bindings/mips/ |
| 11138 | 11134 | F: Documentation/mips/ |
| 11139 | 11135 | F: arch/mips/ |
| @@ -12752,7 +12748,7 @@ M: Tom Joseph <tjoseph@cadence.com> · 1612 unmodified lines | ||
| 12752 | 12748 | L: linux-pci@vger.kernel.org |
| 12753 | 12749 | S: Maintained |
| 12754 | 12750 | F: Documentation/devicetree/bindings/pci/cdns,*.txt |
| 12755 | −F: drivers/pci/controller/pcie-cadence* | |
| 12751 | +F: drivers/pci/controller/cadence/ | |
| 12756 | 12752 | |
| 12757 | 12753 | PCI DRIVER FOR FREESCALE LAYERSCAPE |
| 12758 | 12754 | M: Minghuan Lian <minghuan.Lian@nxp.com> |
| @@ -12965,7 +12961,6 @@ M: Robert Richter <rrichter@marvell.com> · 206 unmodified lines | ||
| 12965 | 12961 | L: linux-pci@vger.kernel.org |
| 12966 | 12962 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 12967 | 12963 | S: Supported |
| 12968 | −F: Documentation/devicetree/bindings/pci/pci-thunder-* | |
| 12969 | 12964 | F: drivers/pci/controller/pci-thunder-* |
| 12970 | 12965 | |
| 12971 | 12966 | PCIE DRIVER FOR HISILICON |
| @@ -14240,7 +14235,7 @@ F: include/dt-bindings/reset/ · 1268 unmodified lines | ||
| 14240 | 14235 | F: include/linux/reset.h |
| 14241 | 14236 | F: include/linux/reset/ |
| 14242 | 14237 | F: include/linux/reset-controller.h |
| 14243 | −K: \b(?:devm_|of_)?reset_control(?:ler_[a-z]+|_[a-z_]+)?\b | |
| 14238 | +K: \b(?:devm_|of_)?reset_control(?:ler_[a-z]+|_[a-z_]+)?\b | |
| 14244 | 14239 | |
| 14245 | 14240 | RESTARTABLE SEQUENCES SUPPORT |
| 14246 | 14241 | M: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> |
| @@ -15935,7 +15930,7 @@ F: drivers/*/stm32-*timer* · 1688 unmodified lines | ||
| 15935 | 15930 | F: drivers/pwm/pwm-stm32* |
| 15936 | 15931 | F: include/linux/*/stm32-*tim* |
| 15937 | 15932 | F: Documentation/ABI/testing/*timer-stm32 |
| 15938 | −F: Documentation/devicetree/bindings/*/stm32-*timer* | |
| 15933 | +F: Documentation/devicetree/bindings/*/*stm32-*timer* | |
| 15939 | 15934 | F: Documentation/devicetree/bindings/pwm/pwm-stm32* |
| 15940 | 15935 | |
| 15941 | 15936 | STMMAC ETHERNET DRIVER |
| @@ -16094,6 +16089,8 @@ SYNOPSYS DESIGNWARE 8250 UART DRIVER · 152 unmodified lines | ||
| 16094 | 16089 | R: Andy Shevchenko <andriy.shevchenko@linux.intel.com> |
| 16095 | 16090 | S: Maintained |
| 16096 | 16091 | F: drivers/tty/serial/8250/8250_dw.c |
| 16092 | +F: drivers/tty/serial/8250/8250_dwlib.* | |
| 16093 | +F: drivers/tty/serial/8250/8250_lpss.c | |
| 16097 | 16094 | |
| 16098 | 16095 | SYNOPSYS DESIGNWARE APB GPIO DRIVER |
| 16099 | 16096 | M: Hoan Tran <hoan@os.amperecomputing.com> |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 6 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc3 | |
| 5 | +EXTRAVERSION = -rc6 | |
| 6 | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -68,6 +68,7 @@ unexport GREP_OPTIONS · 59 unmodified lines | ||
| 68 | 68 | # |
| 69 | 69 | # If KBUILD_VERBOSE equals 0 then the above command will be hidden. |
| 70 | 70 | # If KBUILD_VERBOSE equals 1 then the above command is displayed. |
| 71 | +# If KBUILD_VERBOSE equals 2 then give the reason why each target is rebuilt. | |
| 71 | 72 | # |
| 72 | 73 | # To put more focus on warnings, be less verbose as default |
| 73 | 74 | # Use 'make V=1' to see the full commands |
| @@ -1239,7 +1240,7 @@ ifneq ($(dtstree),) · 1165 unmodified lines | ||
| 1239 | 1240 | %.dtb: include/config/kernel.release scripts_dtc |
| 1240 | 1241 | $(Q)$(MAKE) $(build)=$(dtstree) $(dtstree)/$@ |
| 1241 | 1242 | |
| 1242 | −PHONY += dtbs dtbs_install dt_binding_check | |
| 1243 | +PHONY += dtbs dtbs_install dtbs_check | |
| 1243 | 1244 | dtbs dtbs_check: include/config/kernel.release scripts_dtc |
| 1244 | 1245 | $(Q)$(MAKE) $(build)=$(dtstree) |
| 1245 | 1246 | |
| @@ -1259,6 +1260,7 @@ PHONY += scripts_dtc · 13 unmodified lines | ||
| 1259 | 1260 | scripts_dtc: scripts_basic |
| 1260 | 1261 | $(Q)$(MAKE) $(build)=scripts/dtc |
| 1261 | 1262 | |
| 1263 | +PHONY += dt_binding_check | |
| 1262 | 1264 | dt_binding_check: scripts_dtc |
| 1263 | 1265 | $(Q)$(MAKE) $(build)=Documentation/devicetree/bindings |
| 1264 | 1266 | |
| @@ -1803,7 +1805,7 @@ existing-targets := $(wildcard $(sort $(targets))) · 538 unmodified lines | ||
| 1803 | 1805 | |
| 1804 | 1806 | -include $(foreach f,$(existing-targets),$(dir $(f)).$(notdir $(f)).cmd) |
| 1805 | 1807 | |
| 1806 | −endif # config-targets | |
| 1808 | +endif # config-build | |
| 1807 | 1809 | endif # mixed-build |
| 1808 | 1810 | endif # need-sub-make |
| 1809 | 1811 | |
| @@ -738,8 +738,9 @@ config HAVE_STACK_VALIDATION · 737 unmodified lines | ||
| 738 | 738 | config HAVE_RELIABLE_STACKTRACE |
| 739 | 739 | bool |
| 740 | 740 | help |
| 741 | − Architecture has a save_stack_trace_tsk_reliable() function which | |
| 742 | − only returns a stack trace if it can guarantee the trace is reliable. | |
| 741 | + Architecture has either save_stack_trace_tsk_reliable() or | |
| 742 | + arch_stack_walk_reliable() function which only returns a stack trace | |
| 743 | + if it can guarantee the trace is reliable. | |
| 743 | 744 | |
| 744 | 745 | config HAVE_ARCH_HASH |
| 745 | 746 | bool |
| @@ -154,7 +154,7 @@ config ARC_CPU_HS · 153 unmodified lines | ||
| 154 | 154 | help |
| 155 | 155 | Support for ARC HS38x Cores based on ARCv2 ISA |
| 156 | 156 | The notable features are: |
| 157 | − - SMP configurations of upto 4 core with coherency | |
| 157 | + - SMP configurations of up to 4 cores with coherency | |
| 158 | 158 | - Optional L2 Cache and IO-Coherency |
| 159 | 159 | - Revised Interrupt Architecture (multiple priorites, reg banks, |
| 160 | 160 | auto stack switch, auto regfile save/restore) |
| @@ -192,7 +192,7 @@ config ARC_SMP_HALT_ON_RESET · 31 unmodified lines | ||
| 192 | 192 | help |
| 193 | 193 | In SMP configuration cores can be configured as Halt-on-reset |
| 194 | 194 | or they could all start at same time. For Halt-on-reset, non |
| 195 | − masters are parked until Master kicks them so they can start of | |
| 195 | + masters are parked until Master kicks them so they can start off | |
| 196 | 196 | at designated entry point. For other case, all jump to common |
| 197 | 197 | entry point and spin wait for Master's signal. |
| 198 | 198 | |
| @@ -21,8 +21,6 @@ CONFIG_MODULES=y · 20 unmodified lines | ||
| 21 | 21 | CONFIG_MODULE_FORCE_LOAD=y |
| 22 | 22 | CONFIG_MODULE_UNLOAD=y |
| 23 | 23 | # CONFIG_BLK_DEV_BSG is not set |
| 24 | −# CONFIG_IOSCHED_DEADLINE is not set | |
| 25 | −# CONFIG_IOSCHED_CFQ is not set | |
| 26 | 24 | CONFIG_ARC_PLAT_EZNPS=y |
| 27 | 25 | CONFIG_SMP=y |
| 28 | 26 | CONFIG_NR_CPUS=4096 |
| @@ -20,8 +20,6 @@ CONFIG_ISA_ARCOMPACT=y · 19 unmodified lines | ||
| 20 | 20 | CONFIG_KPROBES=y |
| 21 | 21 | CONFIG_MODULES=y |
| 22 | 22 | # CONFIG_BLK_DEV_BSG is not set |
| 23 | −# CONFIG_IOSCHED_DEADLINE is not set | |
| 24 | −# CONFIG_IOSCHED_CFQ is not set | |
| 25 | 23 | CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci" |
| 26 | 24 | # CONFIG_COMPACTION is not set |
| 27 | 25 | CONFIG_NET=y |
| @@ -19,8 +19,6 @@ CONFIG_PERF_EVENTS=y · 18 unmodified lines | ||
| 19 | 19 | CONFIG_KPROBES=y |
| 20 | 20 | CONFIG_MODULES=y |
| 21 | 21 | # CONFIG_BLK_DEV_BSG is not set |
| 22 | −# CONFIG_IOSCHED_DEADLINE is not set | |
| 23 | −# CONFIG_IOSCHED_CFQ is not set | |
| 24 | 22 | CONFIG_ISA_ARCV2=y |
| 25 | 23 | CONFIG_ARC_BUILTIN_DTB_NAME="nsimosci_hs" |
| 26 | 24 | # CONFIG_COMPACTION is not set |
| @@ -14,8 +14,6 @@ CONFIG_PERF_EVENTS=y · 13 unmodified lines | ||
| 14 | 14 | CONFIG_KPROBES=y |
| 15 | 15 | CONFIG_MODULES=y |
| 16 | 16 | # CONFIG_BLK_DEV_BSG is not set |
| 17 | −# CONFIG_IOSCHED_DEADLINE is not set | |
| 18 | −# CONFIG_IOSCHED_CFQ is not set | |
| 19 | 17 | CONFIG_ISA_ARCV2=y |
| 20 | 18 | CONFIG_SMP=y |
| 21 | 19 | # CONFIG_ARC_TIMERS_64BIT is not set |
| @@ -43,6 +43,8 @@ extern void fpu_init_task(struct pt_regs *regs); · 42 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | #endif /* !CONFIG_ISA_ARCOMPACT */ |
| 45 | 45 | |
| 46 | +struct task_struct; | |
| 47 | + | |
| 46 | 48 | extern void fpu_save_restore(struct task_struct *p, struct task_struct *n); |
| 47 | 49 | |
| 48 | 50 | #else /* !CONFIG_ARC_FPU_SAVE_RESTORE */ |
| @@ -29,6 +29,8 @@ · 28 unmodified lines | ||
| 29 | 29 | .endm |
| 30 | 30 | |
| 31 | 31 | #define ASM_NL ` /* use '`' to mark new line in macro */ |
| 32 | +#define __ALIGN .align 4 | |
| 33 | +#define __ALIGN_STR __stringify(__ALIGN) | |
| 32 | 34 | |
| 33 | 35 | /* annotation for data we want in DCCM - if enabled in .config */ |
| 34 | 36 | .macro ARCFP_DATA nm |
| @@ -8,11 +8,11 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/delay.h> |
| 9 | 9 | #include <linux/root_dev.h> |
| 10 | 10 | #include <linux/clk.h> |
| 11 | −#include <linux/clk-provider.h> | |
| 12 | 11 | #include <linux/clocksource.h> |
| 13 | 12 | #include <linux/console.h> |
| 14 | 13 | #include <linux/module.h> |
| 15 | 14 | #include <linux/cpu.h> |
| 15 | +#include <linux/of_clk.h> | |
| 16 | 16 | #include <linux/of_fdt.h> |
| 17 | 17 | #include <linux/of.h> |
| 18 | 18 | #include <linux/cache.h> |
| @@ -104,8 +104,7 @@ static void show_faulting_vma(unsigned long address) · 103 unmodified lines | ||
| 104 | 104 | if (IS_ERR(nm)) |
| 105 | 105 | nm = "?"; |
| 106 | 106 | } |
| 107 | − pr_info(" @off 0x%lx in [%s]\n" | |
| 108 | − " VMA: 0x%08lx to 0x%08lx\n", | |
| 107 | + pr_info(" @off 0x%lx in [%s] VMA: 0x%08lx to 0x%08lx\n", | |
| 109 | 108 | vma->vm_start < TASK_UNMAPPED_BASE ? |
| 110 | 109 | address : address - vma->vm_start, |
| 111 | 110 | nm, vma->vm_start, vma->vm_end); |
| @@ -120,8 +119,6 @@ static void show_ecr_verbose(struct pt_regs *regs) · 8 unmodified lines | ||
| 120 | 119 | unsigned int vec, cause_code; |
| 121 | 120 | unsigned long address; |
| 122 | 121 | |
| 123 | − pr_info("\n[ECR ]: 0x%08lx => ", regs->event); | |
| 124 | − | |
| 125 | 122 | /* For Data fault, this is data address not instruction addr */ |
| 126 | 123 | address = current->thread.fault_address; |
| 127 | 124 | |
| @@ -130,10 +127,10 @@ static void show_ecr_verbose(struct pt_regs *regs) · 2 unmodified lines | ||
| 130 | 127 | |
| 131 | 128 | /* For DTLB Miss or ProtV, display the memory involved too */ |
| 132 | 129 | if (vec == ECR_V_DTLB_MISS) { |
| 133 | − pr_cont("Invalid %s @ 0x%08lx by insn @ 0x%08lx\n", | |
| 130 | + pr_cont("Invalid %s @ 0x%08lx by insn @ %pS\n", | |
| 134 | 131 | (cause_code == 0x01) ? "Read" : |
| 135 | 132 | ((cause_code == 0x02) ? "Write" : "EX"), |
| 136 | − address, regs->ret); | |
| 133 | + address, (void *)regs->ret); | |
| 137 | 134 | } else if (vec == ECR_V_ITLB_MISS) { |
| 138 | 135 | pr_cont("Insn could not be fetched\n"); |
| 139 | 136 | } else if (vec == ECR_V_MACH_CHK) { |
| @@ -191,31 +188,31 @@ void show_regs(struct pt_regs *regs) · 51 unmodified lines | ||
| 191 | 188 | |
| 192 | 189 | show_ecr_verbose(regs); |
| 193 | 190 | |
| 194 | − pr_info("[EFA ]: 0x%08lx\n[BLINK ]: %pS\n[ERET ]: %pS\n", | |
| 195 | − current->thread.fault_address, | |
| 196 | − (void *)regs->blink, (void *)regs->ret); | |
| 197 | − | |
| 198 | 191 | if (user_mode(regs)) |
| 199 | 192 | show_faulting_vma(regs->ret); /* faulting code, not data */ |
| 200 | 193 | |
| 201 | − pr_info("[STAT32]: 0x%08lx", regs->status32); | |
| 194 | + pr_info("ECR: 0x%08lx EFA: 0x%08lx ERET: 0x%08lx\n", | |
| 195 | + regs->event, current->thread.fault_address, regs->ret); | |
| 196 | + | |
| 197 | + pr_info("STAT32: 0x%08lx", regs->status32); | |
| 202 | 198 | |
| 203 | 199 | #define STS_BIT(r, bit) r->status32 & STATUS_##bit##_MASK ? #bit" " : "" |
| 204 | 200 | |
| 205 | 201 | #ifdef CONFIG_ISA_ARCOMPACT |
| 206 | − pr_cont(" : %2s%2s%2s%2s%2s%2s%2s\n", | |
| 202 | + pr_cont(" [%2s%2s%2s%2s%2s%2s%2s]", | |
| 207 | 203 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", |
| 208 | 204 | STS_BIT(regs, DE), STS_BIT(regs, AE), |
| 209 | 205 | STS_BIT(regs, A2), STS_BIT(regs, A1), |
| 210 | 206 | STS_BIT(regs, E2), STS_BIT(regs, E1)); |
| 211 | 207 | #else |
| 212 | − pr_cont(" : %2s%2s%2s%2s\n", | |
| 208 | + pr_cont(" [%2s%2s%2s%2s]", | |
| 213 | 209 | STS_BIT(regs, IE), |
| 214 | 210 | (regs->status32 & STATUS_U_MASK) ? "U " : "K ", |
| 215 | 211 | STS_BIT(regs, DE), STS_BIT(regs, AE)); |
| 216 | 212 | #endif |
| 217 | − pr_info("BTA: 0x%08lx\t SP: 0x%08lx\t FP: 0x%08lx\n", | |
| 218 | − regs->bta, regs->sp, regs->fp); | |
| 213 | + pr_cont(" BTA: 0x%08lx\n", regs->bta); | |
| 214 | + pr_info("BLK: %pS\n SP: 0x%08lx FP: 0x%08lx\n", | |
| 215 | + (void *)regs->blink, regs->sp, regs->fp); | |
| 219 | 216 | pr_info("LPS: 0x%08lx\tLPE: 0x%08lx\tLPC: 0x%08lx\n", |
| 220 | 217 | regs->lp_start, regs->lp_end, regs->lp_count); |
| 221 | 218 | |
| @@ -307,13 +307,15 @@ endif · 306 unmodified lines | ||
| 307 | 307 | ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y) |
| 308 | 308 | prepare: stack_protector_prepare |
| 309 | 309 | stack_protector_prepare: prepare0 |
| 310 | − $(eval KBUILD_CFLAGS += \ | |
| 310 | + $(eval SSP_PLUGIN_CFLAGS := \ | |
| 311 | 311 | -fplugin-arg-arm_ssp_per_task_plugin-tso=$(shell \ |
| 312 | 312 | awk '{if ($$2 == "THREAD_SZ_ORDER") print $$3;}'\ |
| 313 | 313 | include/generated/asm-offsets.h) \ |
| 314 | 314 | -fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell \ |
| 315 | 315 | awk '{if ($$2 == "TI_STACK_CANARY") print $$3;}'\ |
| 316 | 316 | include/generated/asm-offsets.h)) |
| 317 | + $(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS)) | |
| 318 | + $(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS)) | |
| 317 | 319 | endif |
| 318 | 320 | |
| 319 | 321 | all: $(notdir $(KBUILD_IMAGE)) |
| @@ -101,7 +101,6 @@ clean-files += piggy_data lib1funcs.S ashldi3.S bswapsdi2.S \ · 100 unmodified lines | ||
| 101 | 101 | $(libfdt) $(libfdt_hdrs) hyp-stub.S |
| 102 | 102 | |
| 103 | 103 | KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING |
| 104 | −KBUILD_CFLAGS += $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) | |
| 105 | 104 | |
| 106 | 105 | ifeq ($(CONFIG_FUNCTION_TRACER),y) |
| 107 | 106 | ORIG_CFLAGS := $(KBUILD_CFLAGS) |
| @@ -117,7 +116,8 @@ CFLAGS_fdt_ro.o := $(nossp-flags-y) · 9 unmodified lines | ||
| 117 | 116 | CFLAGS_fdt_rw.o := $(nossp-flags-y) |
| 118 | 117 | CFLAGS_fdt_wip.o := $(nossp-flags-y) |
| 119 | 118 | |
| 120 | −ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin -I$(obj) | |
| 119 | +ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \ | |
| 120 | + -I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN) | |
| 121 | 121 | asflags-y := -DZIMAGE |
| 122 | 122 | |
| 123 | 123 | # Supply kernel BSS size to the decompressor via a linker symbol. |
| @@ -526,11 +526,11 @@ · 525 unmodified lines | ||
| 526 | 526 | * Supply voltage supervisor on board will not allow opp50 so |
| 527 | 527 | * disable it and set opp100 as suspend OPP. |
| 528 | 528 | */ |
| 529 | − opp50@300000000 { | |
| 529 | + opp50-300000000 { | |
| 530 | 530 | status = "disabled"; |
| 531 | 531 | }; |
| 532 | 532 | |
| 533 | − opp100@600000000 { | |
| 533 | + opp100-600000000 { | |
| 534 | 534 | opp-suspend; |
| 535 | 535 | }; |
| 536 | 536 | }; |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | aliases { |
| 23 | 23 | ethernet0 = &genet; |
| 24 | + pcie0 = &pcie0; | |
| 24 | 25 | }; |
| 25 | 26 | |
| 26 | 27 | leds { |
| @@ -31,6 +32,8 @@ · 4 unmodified lines | ||
| 31 | 32 | pwr { |
| 32 | 33 | label = "PWR"; |
| 33 | 34 | gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; |
| 35 | + default-state = "keep"; | |
| 36 | + linux,default-trigger = "default-on"; | |
| 34 | 37 | }; |
| 35 | 38 | }; |
| 36 | 39 | |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | pwr { |
| 27 | 27 | label = "PWR"; |
| 28 | 28 | gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; |
| 29 | + default-state = "keep"; | |
| 30 | + linux,default-trigger = "default-on"; | |
| 29 | 31 | }; |
| 30 | 32 | }; |
| 31 | 33 | }; |
| @@ -27,6 +27,8 @@ · 26 unmodified lines | ||
| 27 | 27 | pwr { |
| 28 | 28 | label = "PWR"; |
| 29 | 29 | gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; |
| 30 | + default-state = "keep"; | |
| 31 | + linux,default-trigger = "default-on"; | |
| 30 | 32 | }; |
| 31 | 33 | }; |
| 32 | 34 | |
| @@ -61,10 +61,10 @@ · 60 unmodified lines | ||
| 61 | 61 | regulator-max-microvolt = <1800000>; |
| 62 | 62 | }; |
| 63 | 63 | |
| 64 | − evm_3v3: fixedregulator-evm3v3 { | |
| 64 | + vsys_3v3: fixedregulator-vsys3v3 { | |
| 65 | 65 | /* Output of Cntlr A of TPS43351-Q1 on dra7-evm */ |
| 66 | 66 | compatible = "regulator-fixed"; |
| 67 | − regulator-name = "evm_3v3"; | |
| 67 | + regulator-name = "vsys_3v3"; | |
| 68 | 68 | regulator-min-microvolt = <3300000>; |
| 69 | 69 | regulator-max-microvolt = <3300000>; |
| 70 | 70 | vin-supply = <&evm_12v0>; |
| @@ -3474,6 +3474,7 @@ · 3473 unmodified lines | ||
| 3474 | 3474 | clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER13_CLKCTRL 24>; |
| 3475 | 3475 | clock-names = "fck"; |
| 3476 | 3476 | interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>; |
| 3477 | + ti,timer-pwm; | |
| 3477 | 3478 | }; |
| 3478 | 3479 | }; |
| 3479 | 3480 | |
| @@ -3501,6 +3502,7 @@ · 21 unmodified lines | ||
| 3501 | 3502 | clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER14_CLKCTRL 24>; |
| 3502 | 3503 | clock-names = "fck"; |
| 3503 | 3504 | interrupts = <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>; |
| 3505 | + ti,timer-pwm; | |
| 3504 | 3506 | }; |
| 3505 | 3507 | }; |
| 3506 | 3508 | |
| @@ -3528,6 +3530,7 @@ · 21 unmodified lines | ||
| 3528 | 3530 | clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER15_CLKCTRL 24>; |
| 3529 | 3531 | clock-names = "fck"; |
| 3530 | 3532 | interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>; |
| 3533 | + ti,timer-pwm; | |
| 3531 | 3534 | }; |
| 3532 | 3535 | }; |
| 3533 | 3536 | |
| @@ -3555,6 +3558,7 @@ · 21 unmodified lines | ||
| 3555 | 3558 | clocks = <&l4per3_clkctrl DRA7_L4PER3_TIMER16_CLKCTRL 24>; |
| 3556 | 3559 | clock-names = "fck"; |
| 3557 | 3560 | interrupts = <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>; |
| 3561 | + ti,timer-pwm; | |
| 3558 | 3562 | }; |
| 3559 | 3563 | }; |
| 3560 | 3564 | |
| @@ -184,6 +184,7 @@ · 183 unmodified lines | ||
| 184 | 184 | device_type = "pci"; |
| 185 | 185 | ranges = <0x81000000 0 0 0x03000 0 0x00010000 |
| 186 | 186 | 0x82000000 0 0x20013000 0x13000 0 0xffed000>; |
| 187 | + dma-ranges = <0x02000000 0x0 0x00000000 0x00000000 0x1 0x00000000>; | |
| 187 | 188 | bus-range = <0x00 0xff>; |
| 188 | 189 | #interrupt-cells = <1>; |
| 189 | 190 | num-lanes = <1>; |
| @@ -238,6 +239,7 @@ · 48 unmodified lines | ||
| 238 | 239 | device_type = "pci"; |
| 239 | 240 | ranges = <0x81000000 0 0 0x03000 0 0x00010000 |
| 240 | 241 | 0x82000000 0 0x30013000 0x13000 0 0xffed000>; |
| 242 | + dma-ranges = <0x02000000 0x0 0x00000000 0x00000000 0x1 0x00000000>; | |
| 241 | 243 | bus-range = <0x00 0xff>; |
| 242 | 244 | #interrupt-cells = <1>; |
| 243 | 245 | num-lanes = <1>; |
| @@ -128,3 +128,8 @@ · 127 unmodified lines | ||
| 128 | 128 | &usb4_tm { |
| 129 | 129 | status = "disabled"; |
| 130 | 130 | }; |
| 131 | + | |
| 132 | +&mmc3 { | |
| 133 | + /* dra76x is not affected by i887 */ | |
| 134 | + max-frequency = <96000000>; | |
| 135 | +}; | |
| @@ -796,16 +796,6 @@ · 795 unmodified lines | ||
| 796 | 796 | clock-div = <1>; |
| 797 | 797 | }; |
| 798 | 798 | |
| 799 | − ipu1_gfclk_mux: ipu1_gfclk_mux@520 { | |
| 800 | − #clock-cells = <0>; | |
| 801 | − compatible = "ti,mux-clock"; | |
| 802 | − clocks = <&dpll_abe_m2x2_ck>, <&dpll_core_h22x2_ck>; | |
| 803 | − ti,bit-shift = <24>; | |
| 804 | − reg = <0x0520>; | |
| 805 | − assigned-clocks = <&ipu1_gfclk_mux>; | |
| 806 | − assigned-clock-parents = <&dpll_core_h22x2_ck>; | |
| 807 | − }; | |
| 808 | − | |
| 809 | 799 | dummy_ck: dummy_ck { |
| 810 | 800 | #clock-cells = <0>; |
| 811 | 801 | compatible = "fixed-clock"; |
| @@ -1564,6 +1554,8 @@ · 752 unmodified lines | ||
| 1564 | 1554 | compatible = "ti,clkctrl"; |
| 1565 | 1555 | reg = <0x20 0x4>; |
| 1566 | 1556 | #clock-cells = <2>; |
| 1557 | + assigned-clocks = <&ipu1_clkctrl DRA7_IPU1_MMU_IPU1_CLKCTRL 24>; | |
| 1558 | + assigned-clock-parents = <&dpll_core_h22x2_ck>; | |
| 1567 | 1559 | }; |
| 1568 | 1560 | |
| 1569 | 1561 | ipu_clkctrl: ipu-clkctrl@50 { |
| @@ -275,7 +275,7 @@ · 274 unmodified lines | ||
| 275 | 275 | |
| 276 | 276 | /* SRAM on Colibri nEXT_CS0 */ |
| 277 | 277 | sram@0,0 { |
| 278 | − compatible = "cypress,cy7c1019dv33-10zsxi, mtd-ram"; | |
| 278 | + compatible = "cypress,cy7c1019dv33-10zsxi", "mtd-ram"; | |
| 279 | 279 | reg = <0 0 0x00010000>; |
| 280 | 280 | #address-cells = <1>; |
| 281 | 281 | #size-cells = <1>; |
| @@ -286,7 +286,7 @@ · 4 unmodified lines | ||
| 286 | 286 | |
| 287 | 287 | /* SRAM on Colibri nEXT_CS1 */ |
| 288 | 288 | sram@1,0 { |
| 289 | − compatible = "cypress,cy7c1019dv33-10zsxi, mtd-ram"; | |
| 289 | + compatible = "cypress,cy7c1019dv33-10zsxi", "mtd-ram"; | |
| 290 | 290 | reg = <1 0 0x00010000>; |
| 291 | 291 | #address-cells = <1>; |
| 292 | 292 | #size-cells = <1>; |
| @@ -192,7 +192,6 @@ · 191 unmodified lines | ||
| 192 | 192 | pinctrl-0 = <&pinctrl_usdhc4>; |
| 193 | 193 | bus-width = <8>; |
| 194 | 194 | non-removable; |
| 195 | − vmmc-supply = <&vdd_emmc_1p8>; | |
| 196 | 195 | status = "disabled"; |
| 197 | 196 | }; |
| 198 | 197 | |
| @@ -336,7 +336,6 @@ · 335 unmodified lines | ||
| 336 | 336 | assigned-clock-rates = <400000000>; |
| 337 | 337 | bus-width = <8>; |
| 338 | 338 | fsl,tuning-step = <2>; |
| 339 | − max-frequency = <100000000>; | |
| 340 | 339 | vmmc-supply = <®_module_3v3>; |
| 341 | 340 | vqmmc-supply = <®_DCDC3>; |
| 342 | 341 | non-removable; |
| @@ -44,7 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | opp-hz = /bits/ 64 <792000000>; |
| 45 | 45 | opp-microvolt = <1000000>; |
| 46 | 46 | clock-latency-ns = <150000>; |
| 47 | − opp-supported-hw = <0xd>, <0xf>; | |
| 47 | + opp-supported-hw = <0xd>, <0x7>; | |
| 48 | 48 | opp-suspend; |
| 49 | 49 | }; |
| 50 | 50 | |
| @@ -52,7 +52,7 @@ · 1 unmodified line | ||
| 52 | 52 | opp-hz = /bits/ 64 <996000000>; |
| 53 | 53 | opp-microvolt = <1100000>; |
| 54 | 54 | clock-latency-ns = <150000>; |
| 55 | − opp-supported-hw = <0xc>, <0xf>; | |
| 55 | + opp-supported-hw = <0xc>, <0x7>; | |
| 56 | 56 | opp-suspend; |
| 57 | 57 | }; |
| 58 | 58 | |
| @@ -60,7 +60,7 @@ · 1 unmodified line | ||
| 60 | 60 | opp-hz = /bits/ 64 <1200000000>; |
| 61 | 61 | opp-microvolt = <1225000>; |
| 62 | 62 | clock-latency-ns = <150000>; |
| 63 | − opp-supported-hw = <0x8>, <0xf>; | |
| 63 | + opp-supported-hw = <0x8>, <0x3>; | |
| 64 | 64 | opp-suspend; |
| 65 | 65 | }; |
| 66 | 66 | }; |
| @@ -747,7 +747,7 @@ · 746 unmodified lines | ||
| 747 | 747 | }; |
| 748 | 748 | |
| 749 | 749 | mdio0: mdio@2d24000 { |
| 750 | − compatible = "fsl,etsec2-mdio"; | |
| 750 | + compatible = "gianfar"; | |
| 751 | 751 | device_type = "mdio"; |
| 752 | 752 | #address-cells = <1>; |
| 753 | 753 | #size-cells = <0>; |
| @@ -756,7 +756,7 @@ · 2 unmodified lines | ||
| 756 | 756 | }; |
| 757 | 757 | |
| 758 | 758 | mdio1: mdio@2d64000 { |
| 759 | − compatible = "fsl,etsec2-mdio"; | |
| 759 | + compatible = "gianfar"; | |
| 760 | 760 | device_type = "mdio"; |
| 761 | 761 | #address-cells = <1>; |
| 762 | 762 | #size-cells = <0>; |
| @@ -182,6 +182,14 @@ · 181 unmodified lines | ||
| 182 | 182 | pwm-names = "enable", "direction"; |
| 183 | 183 | direction-duty-cycle-ns = <10000000>; |
| 184 | 184 | }; |
| 185 | + | |
| 186 | + backlight: backlight { | |
| 187 | + compatible = "led-backlight"; | |
| 188 | + | |
| 189 | + leds = <&backlight_led>; | |
| 190 | + brightness-levels = <31 63 95 127 159 191 223 255>; | |
| 191 | + default-brightness-level = <6>; | |
| 192 | + }; | |
| 185 | 193 | }; |
| 186 | 194 | |
| 187 | 195 | &dss { |
| @@ -205,6 +213,8 @@ · 17 unmodified lines | ||
| 205 | 213 | vddi-supply = <&lcd_regulator>; |
| 206 | 214 | reset-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>; /* gpio101 */ |
| 207 | 215 | |
| 216 | + backlight = <&backlight>; | |
| 217 | + | |
| 208 | 218 | width-mm = <50>; |
| 209 | 219 | height-mm = <89>; |
| 210 | 220 | |
| @@ -393,12 +403,11 @@ · 182 unmodified lines | ||
| 393 | 403 | ramp-up-us = <1024>; |
| 394 | 404 | ramp-down-us = <8193>; |
| 395 | 405 | |
| 396 | − led@0 { | |
| 406 | + backlight_led: led@0 { | |
| 397 | 407 | reg = <0>; |
| 398 | 408 | led-sources = <2>; |
| 399 | 409 | ti,led-mode = <0>; |
| 400 | 410 | label = ":backlight"; |
| 401 | − linux,default-trigger = "backlight"; | |
| 402 | 411 | }; |
| 403 | 412 | |
| 404 | 413 | led@1 { |
| @@ -377,7 +377,7 @@ · 376 unmodified lines | ||
| 377 | 377 | }; |
| 378 | 378 | |
| 379 | 379 | sata: sata@fc600000 { |
| 380 | − compatible = "renesas,sata-r8a7779", "renesas,rcar-sata"; | |
| 380 | + compatible = "renesas,sata-r8a7779"; | |
| 381 | 381 | reg = <0xfc600000 0x200000>; |
| 382 | 382 | interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; |
| 383 | 383 | clocks = <&mstp1_clks R8A7779_CLK_SATA>; |
| @@ -178,6 +178,7 @@ CONFIG_SCHED_TRACER=y · 177 unmodified lines | ||
| 178 | 178 | CONFIG_STACK_TRACER=y |
| 179 | 179 | CONFIG_FUNCTION_PROFILER=y |
| 180 | 180 | CONFIG_TEST_KSTRTOX=y |
| 181 | +CONFIG_DEBUG_FS=y | |
| 181 | 182 | CONFIG_KGDB=y |
| 182 | 183 | CONFIG_KGDB_KDB=y |
| 183 | 184 | CONFIG_STRICT_DEVMEM=y |
| @@ -375,6 +375,7 @@ CONFIG_BACKLIGHT_GENERIC=m · 374 unmodified lines | ||
| 375 | 375 | CONFIG_BACKLIGHT_PWM=m |
| 376 | 376 | CONFIG_BACKLIGHT_PANDORA=m |
| 377 | 377 | CONFIG_BACKLIGHT_GPIO=m |
| 378 | +CONFIG_BACKLIGHT_LED=m | |
| 378 | 379 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 379 | 380 | CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y |
| 380 | 381 | CONFIG_LOGO=y |
| @@ -157,6 +157,7 @@ CONFIG_NLS_ISO8859_1=y · 156 unmodified lines | ||
| 157 | 157 | CONFIG_PRINTK_TIME=y |
| 158 | 158 | CONFIG_DEBUG_INFO=y |
| 159 | 159 | CONFIG_MAGIC_SYSRQ=y |
| 160 | +CONFIG_DEBUG_FS=y | |
| 160 | 161 | CONFIG_DETECT_HUNG_TASK=y |
| 161 | 162 | # CONFIG_SCHED_DEBUG is not set |
| 162 | 163 | CONFIG_FUNCTION_TRACER=y |
| @@ -392,9 +392,6 @@ static inline void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu) {} · 391 unmodified lines | ||
| 392 | 392 | static inline void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) {} |
| 393 | 393 | static inline void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) {} |
| 394 | 394 | |
| 395 | −static inline void kvm_arm_vhe_guest_enter(void) {} | |
| 396 | −static inline void kvm_arm_vhe_guest_exit(void) {} | |
| 397 | − | |
| 398 | 395 | #define KVM_BP_HARDEN_UNKNOWN -1 |
| 399 | 396 | #define KVM_BP_HARDEN_WA_NEEDED 0 |
| 400 | 397 | #define KVM_BP_HARDEN_NOT_REQUIRED 1 |
| @@ -94,6 +94,8 @@ static bool __init cntvct_functional(void) · 93 unmodified lines | ||
| 94 | 94 | * this. |
| 95 | 95 | */ |
| 96 | 96 | np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer"); |
| 97 | + if (!np) | |
| 98 | + np = of_find_compatible_node(NULL, NULL, "arm,armv8-timer"); | |
| 97 | 99 | if (!np) |
| 98 | 100 | goto out_put; |
| 99 | 101 | |
| @@ -118,7 +118,7 @@ ENTRY(arm_copy_from_user) · 117 unmodified lines | ||
| 118 | 118 | |
| 119 | 119 | ENDPROC(arm_copy_from_user) |
| 120 | 120 | |
| 121 | − .pushsection .fixup,"ax" | |
| 121 | + .pushsection .text.fixup,"ax" | |
| 122 | 122 | .align 0 |
| 123 | 123 | copy_abort_preamble |
| 124 | 124 | ldmfd sp!, {r1, r2, r3} |
| @@ -91,6 +91,8 @@ AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a · 90 unmodified lines | ||
| 91 | 91 | obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o |
| 92 | 92 | obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o |
| 93 | 93 | endif |
| 94 | +AFLAGS_resume-imx6.o :=-Wa,-march=armv7-a | |
| 95 | +obj-$(CONFIG_SOC_IMX6) += resume-imx6.o | |
| 94 | 96 | obj-$(CONFIG_SOC_IMX6) += pm-imx6.o |
| 95 | 97 | |
| 96 | 98 | obj-$(CONFIG_SOC_IMX1) += mach-imx1.o |
| @@ -109,17 +109,17 @@ void imx_cpu_die(unsigned int cpu); · 108 unmodified lines | ||
| 109 | 109 | int imx_cpu_kill(unsigned int cpu); |
| 110 | 110 | |
| 111 | 111 | #ifdef CONFIG_SUSPEND |
| 112 | −void v7_cpu_resume(void); | |
| 113 | 112 | void imx53_suspend(void __iomem *ocram_vbase); |
| 114 | 113 | extern const u32 imx53_suspend_sz; |
| 115 | 114 | void imx6_suspend(void __iomem *ocram_vbase); |
| 116 | 115 | #else |
| 117 | −static inline void v7_cpu_resume(void) {} | |
| 118 | 116 | static inline void imx53_suspend(void __iomem *ocram_vbase) {} |
| 119 | 117 | static const u32 imx53_suspend_sz; |
| 120 | 118 | static inline void imx6_suspend(void __iomem *ocram_vbase) {} |
| 121 | 119 | #endif |
| 122 | 120 | |
| 121 | +void v7_cpu_resume(void); | |
| 122 | + | |
| 123 | 123 | void imx6_pm_ccm_init(const char *ccm_compat); |
| 124 | 124 | void imx6q_pm_init(void); |
| 125 | 125 | void imx6dl_pm_init(void); |
| @@ -0,0 +1,24 @@ | ||
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ | |
| 2 | +/* | |
| 3 | + * Copyright 2014 Freescale Semiconductor, Inc. | |
| 4 | + */ | |
| 5 | + | |
| 6 | +#include <linux/linkage.h> | |
| 7 | +#include <asm/assembler.h> | |
| 8 | +#include <asm/asm-offsets.h> | |
| 9 | +#include <asm/hardware/cache-l2x0.h> | |
| 10 | +#include "hardware.h" | |
| 11 | + | |
| 12 | +/* | |
| 13 | + * The following code must assume it is running from physical address | |
| 14 | + * where absolute virtual addresses to the data section have to be | |
| 15 | + * turned into relative ones. | |
| 16 | + */ | |
| 17 | + | |
| 18 | +ENTRY(v7_cpu_resume) | |
| 19 | + bl v7_invalidate_l1 | |
| 20 | +#ifdef CONFIG_CACHE_L2X0 | |
| 21 | + bl l2c310_early_resume | |
| 22 | +#endif | |
| 23 | + b cpu_resume | |
| 24 | +ENDPROC(v7_cpu_resume) | |
| @@ -327,17 +327,3 @@ resume: · 326 unmodified lines | ||
| 327 | 327 | |
| 328 | 328 | ret lr |
| 329 | 329 | ENDPROC(imx6_suspend) |
| 330 | − | |
| 331 | −/* | |
| 332 | − * The following code must assume it is running from physical address | |
| 333 | − * where absolute virtual addresses to the data section have to be | |
| 334 | − * turned into relative ones. | |
| 335 | − */ | |
| 336 | − | |
| 337 | −ENTRY(v7_cpu_resume) | |
| 338 | − bl v7_invalidate_l1 | |
| 339 | −#ifdef CONFIG_CACHE_L2X0 | |
| 340 | − bl l2c310_early_resume | |
| 341 | −#endif | |
| 342 | − b cpu_resume | |
| 343 | −ENDPROC(v7_cpu_resume) | |
| @@ -9,7 +9,6 @@ menuconfig ARCH_MESON · 8 unmodified lines | ||
| 9 | 9 | select CACHE_L2X0 |
| 10 | 10 | select PINCTRL |
| 11 | 11 | select PINCTRL_MESON |
| 12 | − select COMMON_CLK | |
| 13 | 12 | select HAVE_ARM_SCU if SMP |
| 14 | 13 | select HAVE_ARM_TWD if SMP |
| 15 | 14 | |
| @@ -16,7 +16,7 @@ hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ · 15 unmodified lines | ||
| 16 | 16 | clock-common = clock.o |
| 17 | 17 | secure-common = omap-smc.o omap-secure.o |
| 18 | 18 | |
| 19 | −obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) $(secure-common) | |
| 19 | +obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) | |
| 20 | 20 | obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common) |
| 21 | 21 | obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common) |
| 22 | 22 | obj-$(CONFIG_SOC_AM33XX) += $(hwmod-common) $(secure-common) |
| @@ -431,7 +431,6 @@ void __init omap2420_init_early(void) · 430 unmodified lines | ||
| 431 | 431 | omap_hwmod_init_postsetup(); |
| 432 | 432 | omap_clk_soc_init = omap2420_dt_clk_init; |
| 433 | 433 | rate_table = omap2420_rate_table; |
| 434 | − omap_secure_init(); | |
| 435 | 434 | } |
| 436 | 435 | |
| 437 | 436 | void __init omap2420_init_late(void) |
| @@ -456,7 +455,6 @@ void __init omap2430_init_early(void) · 18 unmodified lines | ||
| 456 | 455 | omap_hwmod_init_postsetup(); |
| 457 | 456 | omap_clk_soc_init = omap2430_dt_clk_init; |
| 458 | 457 | rate_table = omap2430_rate_table; |
| 459 | − omap_secure_init(); | |
| 460 | 458 | } |
| 461 | 459 | |
| 462 | 460 | void __init omap2430_init_late(void) |
| @@ -327,7 +327,7 @@ · 326 unmodified lines | ||
| 327 | 327 | #size-cells = <0>; |
| 328 | 328 | |
| 329 | 329 | bus-width = <4>; |
| 330 | − max-frequency = <50000000>; | |
| 330 | + max-frequency = <60000000>; | |
| 331 | 331 | |
| 332 | 332 | non-removable; |
| 333 | 333 | disable-wp; |
| @@ -593,6 +593,7 @@ · 592 unmodified lines | ||
| 593 | 593 | compatible = "brcm,bcm43438-bt"; |
| 594 | 594 | interrupt-parent = <&gpio_intc>; |
| 595 | 595 | interrupts = <95 IRQ_TYPE_LEVEL_HIGH>; |
| 596 | + interrupt-names = "host-wakeup"; | |
| 596 | 597 | shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>; |
| 597 | 598 | max-speed = <2000000>; |
| 598 | 599 | clocks = <&wifi32k>; |
| @@ -20,6 +20,8 @@ · 19 unmodified lines | ||
| 20 | 20 | }; |
| 21 | 21 | |
| 22 | 22 | &fman0 { |
| 23 | + fsl,erratum-a050385; | |
| 24 | + | |
| 23 | 25 | /* these aliases provide the FMan ports mapping */ |
| 24 | 26 | enet0: ethernet@e0000 { |
| 25 | 27 | }; |
| @@ -52,11 +52,6 @@ · 51 unmodified lines | ||
| 52 | 52 | compatible = "ethernet-phy-ieee802.3-c22"; |
| 53 | 53 | reg = <0>; |
| 54 | 54 | }; |
| 55 | − | |
| 56 | − ethphy1: ethernet-phy@1 { | |
| 57 | − compatible = "ethernet-phy-ieee802.3-c22"; | |
| 58 | − reg = <1>; | |
| 59 | − }; | |
| 60 | 55 | }; |
| 61 | 56 | }; |
| 62 | 57 | |
| @@ -102,7 +102,7 @@ · 101 unmodified lines | ||
| 102 | 102 | }; |
| 103 | 103 | |
| 104 | 104 | gmac0: ethernet@ff800000 { |
| 105 | − compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; | |
| 105 | + compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; | |
| 106 | 106 | reg = <0xff800000 0x2000>; |
| 107 | 107 | interrupts = <0 90 4>; |
| 108 | 108 | interrupt-names = "macirq"; |
| @@ -118,7 +118,7 @@ · 9 unmodified lines | ||
| 118 | 118 | }; |
| 119 | 119 | |
| 120 | 120 | gmac1: ethernet@ff802000 { |
| 121 | − compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; | |
| 121 | + compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; | |
| 122 | 122 | reg = <0xff802000 0x2000>; |
| 123 | 123 | interrupts = <0 91 4>; |
| 124 | 124 | interrupt-names = "macirq"; |
| @@ -134,7 +134,7 @@ · 9 unmodified lines | ||
| 134 | 134 | }; |
| 135 | 135 | |
| 136 | 136 | gmac2: ethernet@ff804000 { |
| 137 | − compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac"; | |
| 137 | + compatible = "altr,socfpga-stmmac-a10-s10", "snps,dwmac-3.74a", "snps,dwmac"; | |
| 138 | 138 | reg = <0xff804000 0x2000>; |
| 139 | 139 | interrupts = <0 92 4>; |
| 140 | 140 | interrupt-names = "macirq"; |
| @@ -773,7 +773,7 @@ CONFIG_ARCH_R8A774A1=y · 772 unmodified lines | ||
| 773 | 773 | CONFIG_ARCH_R8A774B1=y |
| 774 | 774 | CONFIG_ARCH_R8A774C0=y |
| 775 | 775 | CONFIG_ARCH_R8A7795=y |
| 776 | −CONFIG_ARCH_R8A7796=y | |
| 776 | +CONFIG_ARCH_R8A77960=y | |
| 777 | 777 | CONFIG_ARCH_R8A77961=y |
| 778 | 778 | CONFIG_ARCH_R8A77965=y |
| 779 | 779 | CONFIG_ARCH_R8A77970=y |
| @@ -32,7 +32,7 @@ static inline void gic_write_eoir(u32 irq) · 31 unmodified lines | ||
| 32 | 32 | isb(); |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | −static inline void gic_write_dir(u32 irq) | |
| 35 | +static __always_inline void gic_write_dir(u32 irq) | |
| 36 | 36 | { |
| 37 | 37 | write_sysreg_s(irq, SYS_ICC_DIR_EL1); |
| 38 | 38 | isb(); |
| @@ -69,7 +69,7 @@ static inline int icache_is_aliasing(void) · 68 unmodified lines | ||
| 69 | 69 | return test_bit(ICACHEF_ALIASING, &__icache_flags); |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | −static inline int icache_is_vpipt(void) | |
| 72 | +static __always_inline int icache_is_vpipt(void) | |
| 73 | 73 | { |
| 74 | 74 | return test_bit(ICACHEF_VPIPT, &__icache_flags); |
| 75 | 75 | } |
| @@ -145,7 +145,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *, · 144 unmodified lines | ||
| 145 | 145 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
| 146 | 146 | extern void flush_dcache_page(struct page *); |
| 147 | 147 | |
| 148 | −static inline void __flush_icache_all(void) | |
| 148 | +static __always_inline void __flush_icache_all(void) | |
| 149 | 149 | { |
| 150 | 150 | if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC)) |
| 151 | 151 | return; |
| @@ -435,13 +435,13 @@ cpuid_feature_extract_signed_field(u64 features, int field) · 434 unmodified lines | ||
| 435 | 435 | return cpuid_feature_extract_signed_field_width(features, field, 4); |
| 436 | 436 | } |
| 437 | 437 | |
| 438 | −static inline unsigned int __attribute_const__ | |
| 438 | +static __always_inline unsigned int __attribute_const__ | |
| 439 | 439 | cpuid_feature_extract_unsigned_field_width(u64 features, int field, int width) |
| 440 | 440 | { |
| 441 | 441 | return (u64)(features << (64 - width - field)) >> (64 - width); |
| 442 | 442 | } |
| 443 | 443 | |
| 444 | −static inline unsigned int __attribute_const__ | |
| 444 | +static __always_inline unsigned int __attribute_const__ | |
| 445 | 445 | cpuid_feature_extract_unsigned_field(u64 features, int field) |
| 446 | 446 | { |
| 447 | 447 | return cpuid_feature_extract_unsigned_field_width(features, field, 4); |
| @@ -564,7 +564,7 @@ static inline bool system_supports_mixed_endian(void) · 116 unmodified lines | ||
| 564 | 564 | return val == 0x1; |
| 565 | 565 | } |
| 566 | 566 | |
| 567 | −static inline bool system_supports_fpsimd(void) | |
| 567 | +static __always_inline bool system_supports_fpsimd(void) | |
| 568 | 568 | { |
| 569 | 569 | return !cpus_have_const_cap(ARM64_HAS_NO_FPSIMD); |
| 570 | 570 | } |
| @@ -575,13 +575,13 @@ static inline bool system_uses_ttbr0_pan(void) · 4 unmodified lines | ||
| 575 | 575 | !cpus_have_const_cap(ARM64_HAS_PAN); |
| 576 | 576 | } |
| 577 | 577 | |
| 578 | −static inline bool system_supports_sve(void) | |
| 578 | +static __always_inline bool system_supports_sve(void) | |
| 579 | 579 | { |
| 580 | 580 | return IS_ENABLED(CONFIG_ARM64_SVE) && |
| 581 | 581 | cpus_have_const_cap(ARM64_SVE); |
| 582 | 582 | } |
| 583 | 583 | |
| 584 | −static inline bool system_supports_cnp(void) | |
| 584 | +static __always_inline bool system_supports_cnp(void) | |
| 585 | 585 | { |
| 586 | 586 | return IS_ENABLED(CONFIG_ARM64_CNP) && |
| 587 | 587 | cpus_have_const_cap(ARM64_HAS_CNP); |
| @@ -34,7 +34,7 @@ static inline void __raw_writew(u16 val, volatile void __iomem *addr) · 33 unmodified lines | ||
| 34 | 34 | } |
| 35 | 35 | |
| 36 | 36 | #define __raw_writel __raw_writel |
| 37 | −static inline void __raw_writel(u32 val, volatile void __iomem *addr) | |
| 37 | +static __always_inline void __raw_writel(u32 val, volatile void __iomem *addr) | |
| 38 | 38 | { |
| 39 | 39 | asm volatile("str %w0, [%1]" : : "rZ" (val), "r" (addr)); |
| 40 | 40 | } |
| @@ -69,7 +69,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr) · 28 unmodified lines | ||
| 69 | 69 | } |
| 70 | 70 | |
| 71 | 71 | #define __raw_readl __raw_readl |
| 72 | −static inline u32 __raw_readl(const volatile void __iomem *addr) | |
| 72 | +static __always_inline u32 __raw_readl(const volatile void __iomem *addr) | |
| 73 | 73 | { |
| 74 | 74 | u32 val; |
| 75 | 75 | asm volatile(ALTERNATIVE("ldr %w0, [%1]", |
| @@ -36,7 +36,7 @@ void kvm_inject_undef32(struct kvm_vcpu *vcpu); · 35 unmodified lines | ||
| 36 | 36 | void kvm_inject_dabt32(struct kvm_vcpu *vcpu, unsigned long addr); |
| 37 | 37 | void kvm_inject_pabt32(struct kvm_vcpu *vcpu, unsigned long addr); |
| 38 | 38 | |
| 39 | −static inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu) | |
| 39 | +static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu) | |
| 40 | 40 | { |
| 41 | 41 | return !(vcpu->arch.hcr_el2 & HCR_RW); |
| 42 | 42 | } |
| @@ -127,7 +127,7 @@ static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr) · 84 unmodified lines | ||
| 127 | 127 | vcpu->arch.vsesr_el2 = vsesr; |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | −static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu) | |
| 130 | +static __always_inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu) | |
| 131 | 131 | { |
| 132 | 132 | return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc; |
| 133 | 133 | } |
| @@ -153,17 +153,17 @@ static inline void vcpu_write_elr_el1(const struct kvm_vcpu *vcpu, unsigned long · 19 unmodified lines | ||
| 153 | 153 | *__vcpu_elr_el1(vcpu) = v; |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | −static inline unsigned long *vcpu_cpsr(const struct kvm_vcpu *vcpu) | |
| 156 | +static __always_inline unsigned long *vcpu_cpsr(const struct kvm_vcpu *vcpu) | |
| 157 | 157 | { |
| 158 | 158 | return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pstate; |
| 159 | 159 | } |
| 160 | 160 | |
| 161 | −static inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu) | |
| 161 | +static __always_inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu) | |
| 162 | 162 | { |
| 163 | 163 | return !!(*vcpu_cpsr(vcpu) & PSR_MODE32_BIT); |
| 164 | 164 | } |
| 165 | 165 | |
| 166 | −static inline bool kvm_condition_valid(const struct kvm_vcpu *vcpu) | |
| 166 | +static __always_inline bool kvm_condition_valid(const struct kvm_vcpu *vcpu) | |
| 167 | 167 | { |
| 168 | 168 | if (vcpu_mode_is_32bit(vcpu)) |
| 169 | 169 | return kvm_condition_valid32(vcpu); |
| @@ -181,13 +181,13 @@ static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu) · 11 unmodified lines | ||
| 181 | 181 | * coming from a read of ESR_EL2. Otherwise, it may give the wrong result on |
| 182 | 182 | * AArch32 with banked registers. |
| 183 | 183 | */ |
| 184 | −static inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu, | |
| 184 | +static __always_inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu, | |
| 185 | 185 | u8 reg_num) |
| 186 | 186 | { |
| 187 | 187 | return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)->regs.regs[reg_num]; |
| 188 | 188 | } |
| 189 | 189 | |
| 190 | −static inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num, | |
| 190 | +static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num, | |
| 191 | 191 | unsigned long val) |
| 192 | 192 | { |
| 193 | 193 | if (reg_num != 31) |
| @@ -264,12 +264,12 @@ static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu) · 70 unmodified lines | ||
| 264 | 264 | return mode != PSR_MODE_EL0t; |
| 265 | 265 | } |
| 266 | 266 | |
| 267 | −static inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu) | |
| 267 | +static __always_inline u32 kvm_vcpu_get_hsr(const struct kvm_vcpu *vcpu) | |
| 268 | 268 | { |
| 269 | 269 | return vcpu->arch.fault.esr_el2; |
| 270 | 270 | } |
| 271 | 271 | |
| 272 | −static inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu) | |
| 272 | +static __always_inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu) | |
| 273 | 273 | { |
| 274 | 274 | u32 esr = kvm_vcpu_get_hsr(vcpu); |
| 275 | 275 | |
| @@ -279,12 +279,12 @@ static inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu) · 3 unmodified lines | ||
| 279 | 279 | return -1; |
| 280 | 280 | } |
| 281 | 281 | |
| 282 | −static inline unsigned long kvm_vcpu_get_hfar(const struct kvm_vcpu *vcpu) | |
| 282 | +static __always_inline unsigned long kvm_vcpu_get_hfar(const struct kvm_vcpu *vcpu) | |
| 283 | 283 | { |
| 284 | 284 | return vcpu->arch.fault.far_el2; |
| 285 | 285 | } |
| 286 | 286 | |
| 287 | −static inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu) | |
| 287 | +static __always_inline phys_addr_t kvm_vcpu_get_fault_ipa(const struct kvm_vcpu *vcpu) | |
| 288 | 288 | { |
| 289 | 289 | return ((phys_addr_t)vcpu->arch.fault.hpfar_el2 & HPFAR_MASK) << 8; |
| 290 | 290 | } |
| @@ -299,7 +299,7 @@ static inline u32 kvm_vcpu_hvc_get_imm(const struct kvm_vcpu *vcpu) · 8 unmodified lines | ||
| 299 | 299 | return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_xVC_IMM_MASK; |
| 300 | 300 | } |
| 301 | 301 | |
| 302 | −static inline bool kvm_vcpu_dabt_isvalid(const struct kvm_vcpu *vcpu) | |
| 302 | +static __always_inline bool kvm_vcpu_dabt_isvalid(const struct kvm_vcpu *vcpu) | |
| 303 | 303 | { |
| 304 | 304 | return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_ISV); |
| 305 | 305 | } |
| @@ -319,17 +319,17 @@ static inline bool kvm_vcpu_dabt_issf(const struct kvm_vcpu *vcpu) · 13 unmodified lines | ||
| 319 | 319 | return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SF); |
| 320 | 320 | } |
| 321 | 321 | |
| 322 | −static inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu) | |
| 322 | +static __always_inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu) | |
| 323 | 323 | { |
| 324 | 324 | return (kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SRT_MASK) >> ESR_ELx_SRT_SHIFT; |
| 325 | 325 | } |
| 326 | 326 | |
| 327 | −static inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu) | |
| 327 | +static __always_inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu) | |
| 328 | 328 | { |
| 329 | 329 | return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_S1PTW); |
| 330 | 330 | } |
| 331 | 331 | |
| 332 | −static inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu) | |
| 332 | +static __always_inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu) | |
| 333 | 333 | { |
| 334 | 334 | return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WNR) || |
| 335 | 335 | kvm_vcpu_dabt_iss1tw(vcpu); /* AF/DBM update */ |
| @@ -340,18 +340,18 @@ static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu) · 4 unmodified lines | ||
| 340 | 340 | return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_CM); |
| 341 | 341 | } |
| 342 | 342 | |
| 343 | −static inline unsigned int kvm_vcpu_dabt_get_as(const struct kvm_vcpu *vcpu) | |
| 343 | +static __always_inline unsigned int kvm_vcpu_dabt_get_as(const struct kvm_vcpu *vcpu) | |
| 344 | 344 | { |
| 345 | 345 | return 1 << ((kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SAS) >> ESR_ELx_SAS_SHIFT); |
| 346 | 346 | } |
| 347 | 347 | |
| 348 | 348 | /* This one is not specific to Data Abort */ |
| 349 | −static inline bool kvm_vcpu_trap_il_is32bit(const struct kvm_vcpu *vcpu) | |
| 349 | +static __always_inline bool kvm_vcpu_trap_il_is32bit(const struct kvm_vcpu *vcpu) | |
| 350 | 350 | { |
| 351 | 351 | return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_IL); |
| 352 | 352 | } |
| 353 | 353 | |
| 354 | −static inline u8 kvm_vcpu_trap_get_class(const struct kvm_vcpu *vcpu) | |
| 354 | +static __always_inline u8 kvm_vcpu_trap_get_class(const struct kvm_vcpu *vcpu) | |
| 355 | 355 | { |
| 356 | 356 | return ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu)); |
| 357 | 357 | } |
| @@ -361,17 +361,17 @@ static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu) · 3 unmodified lines | ||
| 361 | 361 | return kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_IABT_LOW; |
| 362 | 362 | } |
| 363 | 363 | |
| 364 | −static inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu) | |
| 364 | +static __always_inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu) | |
| 365 | 365 | { |
| 366 | 366 | return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_FSC; |
| 367 | 367 | } |
| 368 | 368 | |
| 369 | −static inline u8 kvm_vcpu_trap_get_fault_type(const struct kvm_vcpu *vcpu) | |
| 369 | +static __always_inline u8 kvm_vcpu_trap_get_fault_type(const struct kvm_vcpu *vcpu) | |
| 370 | 370 | { |
| 371 | 371 | return kvm_vcpu_get_hsr(vcpu) & ESR_ELx_FSC_TYPE; |
| 372 | 372 | } |
| 373 | 373 | |
| 374 | −static inline bool kvm_vcpu_dabt_isextabt(const struct kvm_vcpu *vcpu) | |
| 374 | +static __always_inline bool kvm_vcpu_dabt_isextabt(const struct kvm_vcpu *vcpu) | |
| 375 | 375 | { |
| 376 | 376 | switch (kvm_vcpu_trap_get_fault(vcpu)) { |
| 377 | 377 | case FSC_SEA: |
| @@ -390,7 +390,7 @@ static inline bool kvm_vcpu_dabt_isextabt(const struct kvm_vcpu *vcpu) · 12 unmodified lines | ||
| 390 | 390 | } |
| 391 | 391 | } |
| 392 | 392 | |
| 393 | −static inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu) | |
| 393 | +static __always_inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu) | |
| 394 | 394 | { |
| 395 | 395 | u32 esr = kvm_vcpu_get_hsr(vcpu); |
| 396 | 396 | return ESR_ELx_SYS64_ISS_RT(esr); |
| @@ -504,7 +504,7 @@ static inline unsigned long vcpu_data_host_to_guest(struct kvm_vcpu *vcpu, · 107 unmodified lines | ||
| 504 | 504 | return data; /* Leave LE untouched */ |
| 505 | 505 | } |
| 506 | 506 | |
| 507 | −static inline void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr) | |
| 507 | +static __always_inline void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr) | |
| 508 | 508 | { |
| 509 | 509 | if (vcpu_mode_is_32bit(vcpu)) |
| 510 | 510 | kvm_skip_instr32(vcpu, is_wide_instr); |
| @@ -519,7 +519,7 @@ static inline void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_instr) · 8 unmodified lines | ||
| 519 | 519 | * Skip an instruction which has been emulated at hyp while most guest sysregs |
| 520 | 520 | * are live. |
| 521 | 521 | */ |
| 522 | −static inline void __hyp_text __kvm_skip_instr(struct kvm_vcpu *vcpu) | |
| 522 | +static __always_inline void __hyp_text __kvm_skip_instr(struct kvm_vcpu *vcpu) | |
| 523 | 523 | { |
| 524 | 524 | *vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR); |
| 525 | 525 | vcpu->arch.ctxt.gp_regs.regs.pstate = read_sysreg_el2(SYS_SPSR); |
| @@ -626,38 +626,6 @@ static inline void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) {} · 625 unmodified lines | ||
| 626 | 626 | static inline void kvm_clr_pmu_events(u32 clr) {} |
| 627 | 627 | #endif |
| 628 | 628 | |
| 629 | −static inline void kvm_arm_vhe_guest_enter(void) | |
| 630 | −{ | |
| 631 | − local_daif_mask(); | |
| 632 | − | |
| 633 | − /* | |
| 634 | − * Having IRQs masked via PMR when entering the guest means the GIC | |
| 635 | − * will not signal the CPU of interrupts of lower priority, and the | |
| 636 | − * only way to get out will be via guest exceptions. | |
| 637 | − * Naturally, we want to avoid this. | |
| 638 | − * | |
| 639 | − * local_daif_mask() already sets GIC_PRIO_PSR_I_SET, we just need a | |
| 640 | − * dsb to ensure the redistributor is forwards EL2 IRQs to the CPU. | |
| 641 | − */ | |
| 642 | − pmr_sync(); | |
| 643 | −} | |
| 644 | − | |
| 645 | −static inline void kvm_arm_vhe_guest_exit(void) | |
| 646 | −{ | |
| 647 | − /* | |
| 648 | − * local_daif_restore() takes care to properly restore PSTATE.DAIF | |
| 649 | − * and the GIC PMR if the host is using IRQ priorities. | |
| 650 | − */ | |
| 651 | − local_daif_restore(DAIF_PROCCTX_NOIRQ); | |
| 652 | − | |
| 653 | − /* | |
| 654 | − * When we exit from the guest we change a number of CPU configuration | |
| 655 | − * parameters, such as traps. Make sure these changes take effect | |
| 656 | − * before running the host or additional guests. | |
| 657 | − */ | |
| 658 | − isb(); | |
| 659 | −} | |
| 660 | − | |
| 661 | 629 | #define KVM_BP_HARDEN_UNKNOWN -1 |
| 662 | 630 | #define KVM_BP_HARDEN_WA_NEEDED 0 |
| 663 | 631 | #define KVM_BP_HARDEN_NOT_REQUIRED 1 |
| @@ -47,6 +47,13 @@ · 46 unmodified lines | ||
| 47 | 47 | #define read_sysreg_el2(r) read_sysreg_elx(r, _EL2, _EL1) |
| 48 | 48 | #define write_sysreg_el2(v,r) write_sysreg_elx(v, r, _EL2, _EL1) |
| 49 | 49 | |
| 50 | +/* | |
| 51 | + * Without an __arch_swab32(), we fall back to ___constant_swab32(), but the | |
| 52 | + * static inline can allow the compiler to out-of-line this. KVM always wants | |
| 53 | + * the macro version as its always inlined. | |
| 54 | + */ | |
| 55 | +#define __kvm_swab32(x) ___constant_swab32(x) | |
| 56 | + | |
| 50 | 57 | int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu); |
| 51 | 58 | |
| 52 | 59 | void __vgic_v3_save_state(struct kvm_vcpu *vcpu); |
| @@ -93,7 +93,7 @@ void kvm_update_va_mask(struct alt_instr *alt, · 92 unmodified lines | ||
| 93 | 93 | __le32 *origptr, __le32 *updptr, int nr_inst); |
| 94 | 94 | void kvm_compute_layout(void); |
| 95 | 95 | |
| 96 | −static inline unsigned long __kern_hyp_va(unsigned long v) | |
| 96 | +static __always_inline unsigned long __kern_hyp_va(unsigned long v) | |
| 97 | 97 | { |
| 98 | 98 | asm volatile(ALTERNATIVE_CB("and %0, %0, #1\n" |
| 99 | 99 | "ror %0, %0, #1\n" |
| @@ -473,6 +473,7 @@ static inline int kvm_write_guest_lock(struct kvm *kvm, gpa_t gpa, · 373 unmodified lines | ||
| 473 | 473 | extern void *__kvm_bp_vect_base; |
| 474 | 474 | extern int __kvm_harden_el2_vector_slot; |
| 475 | 475 | |
| 476 | +/* This is only called on a VHE system */ | |
| 476 | 477 | static inline void *kvm_get_hyp_vector(void) |
| 477 | 478 | { |
| 478 | 479 | struct bp_hardening_data *data = arm64_get_bp_hardening_data(); |
| @@ -29,11 +29,9 @@ typedef struct { · 28 unmodified lines | ||
| 29 | 29 | */ |
| 30 | 30 | #define ASID(mm) ((mm)->context.id.counter & 0xffff) |
| 31 | 31 | |
| 32 | −extern bool arm64_use_ng_mappings; | |
| 33 | − | |
| 34 | 32 | static inline bool arm64_kernel_unmapped_at_el0(void) |
| 35 | 33 | { |
| 36 | − return arm64_use_ng_mappings; | |
| 34 | + return cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0); | |
| 37 | 35 | } |
| 38 | 36 | |
| 39 | 37 | typedef void (*bp_hardening_cb_t)(void); |
| @@ -23,11 +23,13 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include <asm/pgtable-types.h> |
| 25 | 25 | |
| 26 | +extern bool arm64_use_ng_mappings; | |
| 27 | + | |
| 26 | 28 | #define _PROT_DEFAULT (PTE_TYPE_PAGE | PTE_AF | PTE_SHARED) |
| 27 | 29 | #define _PROT_SECT_DEFAULT (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_S) |
| 28 | 30 | |
| 29 | −#define PTE_MAYBE_NG (arm64_kernel_unmapped_at_el0() ? PTE_NG : 0) | |
| 30 | −#define PMD_MAYBE_NG (arm64_kernel_unmapped_at_el0() ? PMD_SECT_NG : 0) | |
| 31 | +#define PTE_MAYBE_NG (arm64_use_ng_mappings ? PTE_NG : 0) | |
| 32 | +#define PMD_MAYBE_NG (arm64_use_ng_mappings ? PMD_SECT_NG : 0) | |
| 31 | 33 | |
| 32 | 34 | #define PROT_DEFAULT (_PROT_DEFAULT | PTE_MAYBE_NG) |
| 33 | 35 | #define PROT_SECT_DEFAULT (_PROT_SECT_DEFAULT | PMD_MAYBE_NG) |
| @@ -25,8 +25,8 @@ · 24 unmodified lines | ||
| 25 | 25 | #define __NR_compat_gettimeofday 78 |
| 26 | 26 | #define __NR_compat_sigreturn 119 |
| 27 | 27 | #define __NR_compat_rt_sigreturn 173 |
| 28 | −#define __NR_compat_clock_getres 247 | |
| 29 | 28 | #define __NR_compat_clock_gettime 263 |
| 29 | +#define __NR_compat_clock_getres 264 | |
| 30 | 30 | #define __NR_compat_clock_gettime64 403 |
| 31 | 31 | #define __NR_compat_clock_getres_time64 406 |
| 32 | 32 | |
| @@ -83,7 +83,7 @@ static inline bool is_kernel_in_hyp_mode(void) · 82 unmodified lines | ||
| 83 | 83 | return read_sysreg(CurrentEL) == CurrentEL_EL2; |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | −static inline bool has_vhe(void) | |
| 86 | +static __always_inline bool has_vhe(void) | |
| 87 | 87 | { |
| 88 | 88 | if (cpus_have_const_cap(ARM64_HAS_VIRT_HOST_EXTN)) |
| 89 | 89 | return true; |
| @@ -958,11 +958,22 @@ void tick_broadcast(const struct cpumask *mask) · 957 unmodified lines | ||
| 958 | 958 | } |
| 959 | 959 | #endif |
| 960 | 960 | |
| 961 | +/* | |
| 962 | + * The number of CPUs online, not counting this CPU (which may not be | |
| 963 | + * fully online and so not counted in num_online_cpus()). | |
| 964 | + */ | |
| 965 | +static inline unsigned int num_other_online_cpus(void) | |
| 966 | +{ | |
| 967 | + unsigned int this_cpu_online = cpu_online(smp_processor_id()); | |
| 968 | + | |
| 969 | + return num_online_cpus() - this_cpu_online; | |
| 970 | +} | |
| 971 | + | |
| 961 | 972 | void smp_send_stop(void) |
| 962 | 973 | { |
| 963 | 974 | unsigned long timeout; |
| 964 | 975 | |
| 965 | − if (num_online_cpus() > 1) { | |
| 976 | + if (num_other_online_cpus()) { | |
| 966 | 977 | cpumask_t mask; |
| 967 | 978 | |
| 968 | 979 | cpumask_copy(&mask, cpu_online_mask); |
| @@ -975,10 +986,10 @@ void smp_send_stop(void) · 6 unmodified lines | ||
| 975 | 986 | |
| 976 | 987 | /* Wait up to one second for other CPUs to stop */ |
| 977 | 988 | timeout = USEC_PER_SEC; |
| 978 | − while (num_online_cpus() > 1 && timeout--) | |
| 989 | + while (num_other_online_cpus() && timeout--) | |
| 979 | 990 | udelay(1); |
| 980 | 991 | |
| 981 | − if (num_online_cpus() > 1) | |
| 992 | + if (num_other_online_cpus()) | |
| 982 | 993 | pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", |
| 983 | 994 | cpumask_pr_args(cpu_online_mask)); |
| 984 | 995 | |
| @@ -1001,7 +1012,11 @@ void crash_smp_send_stop(void) · 16 unmodified lines | ||
| 1001 | 1012 | |
| 1002 | 1013 | cpus_stopped = 1; |
| 1003 | 1014 | |
| 1004 | − if (num_online_cpus() == 1) { | |
| 1015 | + /* | |
| 1016 | + * If this cpu is the only one alive at this point in time, online or | |
| 1017 | + * not, there are no stop messages to be sent around, so just back out. | |
| 1018 | + */ | |
| 1019 | + if (num_other_online_cpus() == 0) { | |
| 1005 | 1020 | sdei_mask_local_cpu(); |
| 1006 | 1021 | return; |
| 1007 | 1022 | } |
| @@ -1009,7 +1024,7 @@ void crash_smp_send_stop(void) · 1 unmodified line | ||
| 1009 | 1024 | cpumask_copy(&mask, cpu_online_mask); |
| 1010 | 1025 | cpumask_clear_cpu(smp_processor_id(), &mask); |
| 1011 | 1026 | |
| 1012 | − atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); | |
| 1027 | + atomic_set(&waiting_for_crash_ipi, num_other_online_cpus()); | |
| 1013 | 1028 | |
| 1014 | 1029 | pr_crit("SMP: stopping secondary CPUs\n"); |
| 1015 | 1030 | smp_cross_call(&mask, IPI_CPU_CRASH_STOP); |
| @@ -625,7 +625,7 @@ static void __hyp_text __pmu_switch_to_host(struct kvm_cpu_context *host_ctxt) · 624 unmodified lines | ||
| 625 | 625 | } |
| 626 | 626 | |
| 627 | 627 | /* Switch to the guest for VHE systems running in EL2 */ |
| 628 | −int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) | |
| 628 | +static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) | |
| 629 | 629 | { |
| 630 | 630 | struct kvm_cpu_context *host_ctxt; |
| 631 | 631 | struct kvm_cpu_context *guest_ctxt; |
| @@ -678,7 +678,42 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) · 46 unmodified lines | ||
| 678 | 678 | |
| 679 | 679 | return exit_code; |
| 680 | 680 | } |
| 681 | −NOKPROBE_SYMBOL(kvm_vcpu_run_vhe); | |
| 681 | +NOKPROBE_SYMBOL(__kvm_vcpu_run_vhe); | |
| 682 | + | |
| 683 | +int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) | |
| 684 | +{ | |
| 685 | + int ret; | |
| 686 | + | |
| 687 | + local_daif_mask(); | |
| 688 | + | |
| 689 | + /* | |
| 690 | + * Having IRQs masked via PMR when entering the guest means the GIC | |
| 691 | + * will not signal the CPU of interrupts of lower priority, and the | |
| 692 | + * only way to get out will be via guest exceptions. | |
| 693 | + * Naturally, we want to avoid this. | |
| 694 | + * | |
| 695 | + * local_daif_mask() already sets GIC_PRIO_PSR_I_SET, we just need a | |
| 696 | + * dsb to ensure the redistributor is forwards EL2 IRQs to the CPU. | |
| 697 | + */ | |
| 698 | + pmr_sync(); | |
| 699 | + | |
| 700 | + ret = __kvm_vcpu_run_vhe(vcpu); | |
| 701 | + | |
| 702 | + /* | |
| 703 | + * local_daif_restore() takes care to properly restore PSTATE.DAIF | |
| 704 | + * and the GIC PMR if the host is using IRQ priorities. | |
| 705 | + */ | |
| 706 | + local_daif_restore(DAIF_PROCCTX_NOIRQ); | |
| 707 | + | |
| 708 | + /* | |
| 709 | + * When we exit from the guest we change a number of CPU configuration | |
| 710 | + * parameters, such as traps. Make sure these changes take effect | |
| 711 | + * before running the host or additional guests. | |
| 712 | + */ | |
| 713 | + isb(); | |
| 714 | + | |
| 715 | + return ret; | |
| 716 | +} | |
| 682 | 717 | |
| 683 | 718 | /* Switch to the guest for legacy non-VHE systems */ |
| 684 | 719 | int __hyp_text __kvm_vcpu_run_nvhe(struct kvm_vcpu *vcpu) |
| @@ -69,14 +69,14 @@ int __hyp_text __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu) · 68 unmodified lines | ||
| 69 | 69 | u32 data = vcpu_get_reg(vcpu, rd); |
| 70 | 70 | if (__is_be(vcpu)) { |
| 71 | 71 | /* guest pre-swabbed data, undo this for writel() */ |
| 72 | − data = swab32(data); | |
| 72 | + data = __kvm_swab32(data); | |
| 73 | 73 | } |
| 74 | 74 | writel_relaxed(data, addr); |
| 75 | 75 | } else { |
| 76 | 76 | u32 data = readl_relaxed(addr); |
| 77 | 77 | if (__is_be(vcpu)) { |
| 78 | 78 | /* guest expects swabbed data */ |
| 79 | − data = swab32(data); | |
| 79 | + data = __kvm_swab32(data); | |
| 80 | 80 | } |
| 81 | 81 | vcpu_set_reg(vcpu, rd, data); |
| 82 | 82 | } |
| @@ -260,14 +260,26 @@ asmlinkage void post_ttbr_update_workaround(void) · 259 unmodified lines | ||
| 260 | 260 | CONFIG_CAVIUM_ERRATUM_27456)); |
| 261 | 261 | } |
| 262 | 262 | |
| 263 | −static int asids_init(void) | |
| 263 | +static int asids_update_limit(void) | |
| 264 | 264 | { |
| 265 | − asid_bits = get_cpu_asid_bits(); | |
| 265 | + unsigned long num_available_asids = NUM_USER_ASIDS; | |
| 266 | + | |
| 267 | + if (arm64_kernel_unmapped_at_el0()) | |
| 268 | + num_available_asids /= 2; | |
| 266 | 269 | /* |
| 267 | 270 | * Expect allocation after rollover to fail if we don't have at least |
| 268 | 271 | * one more ASID than CPUs. ASID #0 is reserved for init_mm. |
| 269 | 272 | */ |
| 270 | − WARN_ON(NUM_USER_ASIDS - 1 <= num_possible_cpus()); | |
| 273 | + WARN_ON(num_available_asids - 1 <= num_possible_cpus()); | |
| 274 | + pr_info("ASID allocator initialised with %lu entries\n", | |
| 275 | + num_available_asids); | |
| 276 | + return 0; | |
| 277 | +} | |
| 278 | +arch_initcall(asids_update_limit); | |
| 279 | + | |
| 280 | +static int asids_init(void) | |
| 281 | +{ | |
| 282 | + asid_bits = get_cpu_asid_bits(); | |
| 271 | 283 | atomic64_set(&asid_generation, ASID_FIRST_VERSION); |
| 272 | 284 | asid_map = kcalloc(BITS_TO_LONGS(NUM_USER_ASIDS), sizeof(*asid_map), |
| 273 | 285 | GFP_KERNEL); |
| @@ -282,8 +294,6 @@ static int asids_init(void) · 8 unmodified lines | ||
| 282 | 294 | */ |
| 283 | 295 | if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) |
| 284 | 296 | set_kpti_asid_bits(); |
| 285 | − | |
| 286 | − pr_info("ASID allocator initialised with %lu entries\n", NUM_USER_ASIDS); | |
| 287 | 297 | return 0; |
| 288 | 298 | } |
| 289 | 299 | early_initcall(asids_init); |
| @@ -4,6 +4,8 @@ · 3 unmodified lines | ||
| 4 | 4 | #include "jz4780.dtsi" |
| 5 | 5 | #include <dt-bindings/clock/ingenic,tcu.h> |
| 6 | 6 | #include <dt-bindings/gpio/gpio.h> |
| 7 | +#include <dt-bindings/interrupt-controller/irq.h> | |
| 8 | +#include <dt-bindings/regulator/active-semi,8865-regulator.h> | |
| 7 | 9 | |
| 8 | 10 | / { |
| 9 | 11 | compatible = "img,ci20", "ingenic,jz4780"; |
| @@ -163,63 +165,71 @@ · 153 unmodified lines | ||
| 163 | 165 | |
| 164 | 166 | regulators { |
| 165 | 167 | vddcore: SUDCDC1 { |
| 166 | − regulator-name = "VDDCORE"; | |
| 168 | + regulator-name = "DCDC_REG1"; | |
| 167 | 169 | regulator-min-microvolt = <1100000>; |
| 168 | 170 | regulator-max-microvolt = <1100000>; |
| 169 | 171 | regulator-always-on; |
| 170 | 172 | }; |
| 171 | 173 | vddmem: SUDCDC2 { |
| 172 | − regulator-name = "VDDMEM"; | |
| 174 | + regulator-name = "DCDC_REG2"; | |
| 173 | 175 | regulator-min-microvolt = <1500000>; |
| 174 | 176 | regulator-max-microvolt = <1500000>; |
| 175 | 177 | regulator-always-on; |
| 176 | 178 | }; |
| 177 | 179 | vcc_33: SUDCDC3 { |
| 178 | − regulator-name = "VCC33"; | |
| 180 | + regulator-name = "DCDC_REG3"; | |
| 179 | 181 | regulator-min-microvolt = <3300000>; |
| 180 | 182 | regulator-max-microvolt = <3300000>; |
| 181 | 183 | regulator-always-on; |
| 182 | 184 | }; |
| 183 | 185 | vcc_50: SUDCDC4 { |
| 184 | − regulator-name = "VCC50"; | |
| 186 | + regulator-name = "SUDCDC_REG4"; | |
| 185 | 187 | regulator-min-microvolt = <5000000>; |
| 186 | 188 | regulator-max-microvolt = <5000000>; |
| 187 | 189 | regulator-always-on; |
| 188 | 190 | }; |
| 189 | 191 | vcc_25: LDO_REG5 { |
| 190 | − regulator-name = "VCC25"; | |
| 192 | + regulator-name = "LDO_REG5"; | |
| 191 | 193 | regulator-min-microvolt = <2500000>; |
| 192 | 194 | regulator-max-microvolt = <2500000>; |
| 193 | 195 | regulator-always-on; |
| 194 | 196 | }; |
| 195 | 197 | wifi_io: LDO_REG6 { |
| 196 | − regulator-name = "WIFIIO"; | |
| 198 | + regulator-name = "LDO_REG6"; | |
| 197 | 199 | regulator-min-microvolt = <2500000>; |
| 198 | 200 | regulator-max-microvolt = <2500000>; |
| 199 | 201 | regulator-always-on; |
| 200 | 202 | }; |
| 201 | 203 | vcc_28: LDO_REG7 { |
| 202 | − regulator-name = "VCC28"; | |
| 204 | + regulator-name = "LDO_REG7"; | |
| 203 | 205 | regulator-min-microvolt = <2800000>; |
| 204 | 206 | regulator-max-microvolt = <2800000>; |
| 205 | 207 | regulator-always-on; |
| 206 | 208 | }; |
| 207 | 209 | vcc_15: LDO_REG8 { |
| 208 | − regulator-name = "VCC15"; | |
| 210 | + regulator-name = "LDO_REG8"; | |
| 209 | 211 | regulator-min-microvolt = <1500000>; |
| 210 | 212 | regulator-max-microvolt = <1500000>; |
| 211 | 213 | regulator-always-on; |
| 212 | 214 | }; |
| 213 | − vcc_18: LDO_REG9 { | |
| 214 | − regulator-name = "VCC18"; | |
| 215 | − regulator-min-microvolt = <1800000>; | |
| 216 | − regulator-max-microvolt = <1800000>; | |
| 215 | + vrtc_18: LDO_REG9 { | |
| 216 | + regulator-name = "LDO_REG9"; | |
| 217 | + /* Despite the datasheet stating 3.3V | |
| 218 | + * for REG9 and the driver expecting that, | |
| 219 | + * REG9 outputs 1.8V. | |
| 220 | + * Likely the CI20 uses a proprietary | |
| 221 | + * factory programmed chip variant. | |
| 222 | + * Since this is a simple on/off LDO the | |
| 223 | + * exact values do not matter. | |
| 224 | + */ | |
| 225 | + regulator-min-microvolt = <3300000>; | |
| 226 | + regulator-max-microvolt = <3300000>; | |
| 217 | 227 | regulator-always-on; |
| 218 | 228 | }; |
| 219 | 229 | vcc_11: LDO_REG10 { |
| 220 | − regulator-name = "VCC11"; | |
| 221 | − regulator-min-microvolt = <1100000>; | |
| 222 | − regulator-max-microvolt = <1100000>; | |
| 230 | + regulator-name = "LDO_REG10"; | |
| 231 | + regulator-min-microvolt = <1200000>; | |
| 232 | + regulator-max-microvolt = <1200000>; | |
| 223 | 233 | regulator-always-on; |
| 224 | 234 | }; |
| 225 | 235 | }; |
| @@ -261,7 +271,9 @@ · 35 unmodified lines | ||
| 261 | 271 | rtc@51 { |
| 262 | 272 | compatible = "nxp,pcf8563"; |
| 263 | 273 | reg = <0x51>; |
| 264 | − interrupts = <110>; | |
| 274 | + | |
| 275 | + interrupt-parent = <&gpf>; | |
| 276 | + interrupts = <30 IRQ_TYPE_LEVEL_LOW>; | |
| 265 | 277 | }; |
| 266 | 278 | }; |
| 267 | 279 | |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <dt-bindings/clock/jz4740-cgu.h> |
| 3 | +#include <dt-bindings/clock/ingenic,tcu.h> | |
| 3 | 4 | |
| 4 | 5 | / { |
| 5 | 6 | #address-cells = <1>; |
| @@ -45,14 +46,6 @@ · 39 unmodified lines | ||
| 45 | 46 | #clock-cells = <1>; |
| 46 | 47 | }; |
| 47 | 48 | |
| 48 | − watchdog: watchdog@10002000 { | |
| 49 | − compatible = "ingenic,jz4740-watchdog"; | |
| 50 | − reg = <0x10002000 0x10>; | |
| 51 | − | |
| 52 | − clocks = <&cgu JZ4740_CLK_RTC>; | |
| 53 | − clock-names = "rtc"; | |
| 54 | − }; | |
| 55 | − | |
| 56 | 49 | tcu: timer@10002000 { |
| 57 | 50 | compatible = "ingenic,jz4740-tcu", "simple-mfd"; |
| 58 | 51 | reg = <0x10002000 0x1000>; |
| @@ -73,6 +66,14 @@ · 14 unmodified lines | ||
| 73 | 66 | |
| 74 | 67 | interrupt-parent = <&intc>; |
| 75 | 68 | interrupts = <23 22 21>; |
| 69 | + | |
| 70 | + watchdog: watchdog@0 { | |
| 71 | + compatible = "ingenic,jz4740-watchdog"; | |
| 72 | + reg = <0x0 0xc>; | |
| 73 | + | |
| 74 | + clocks = <&tcu TCU_CLK_WDT>; | |
| 75 | + clock-names = "wdt"; | |
| 76 | + }; | |
| 76 | 77 | }; |
| 77 | 78 | |
| 78 | 79 | rtc_dev: rtc@10003000 { |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <dt-bindings/clock/jz4780-cgu.h> |
| 3 | +#include <dt-bindings/clock/ingenic,tcu.h> | |
| 3 | 4 | #include <dt-bindings/dma/jz4780-dma.h> |
| 4 | 5 | |
| 5 | 6 | / { |
| @@ -67,6 +68,14 @@ · 61 unmodified lines | ||
| 67 | 68 | |
| 68 | 69 | interrupt-parent = <&intc>; |
| 69 | 70 | interrupts = <27 26 25>; |
| 71 | + | |
| 72 | + watchdog: watchdog@0 { | |
| 73 | + compatible = "ingenic,jz4780-watchdog"; | |
| 74 | + reg = <0x0 0xc>; | |
| 75 | + | |
| 76 | + clocks = <&tcu TCU_CLK_WDT>; | |
| 77 | + clock-names = "wdt"; | |
| 78 | + }; | |
| 70 | 79 | }; |
| 71 | 80 | |
| 72 | 81 | rtc_dev: rtc@10003000 { |
| @@ -348,14 +357,6 @@ · 275 unmodified lines | ||
| 348 | 357 | status = "disabled"; |
| 349 | 358 | }; |
| 350 | 359 | |
| 351 | − watchdog: watchdog@10002000 { | |
| 352 | − compatible = "ingenic,jz4780-watchdog"; | |
| 353 | − reg = <0x10002000 0x10>; | |
| 354 | − | |
| 355 | − clocks = <&cgu JZ4780_CLK_RTCLK>; | |
| 356 | − clock-names = "rtc"; | |
| 357 | − }; | |
| 358 | − | |
| 359 | 360 | nemc: nemc@13410000 { |
| 360 | 361 | compatible = "ingenic,jz4780-nemc"; |
| 361 | 362 | reg = <0x13410000 0x10000>; |
| @@ -1,4 +1,5 @@ | ||
| 1 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | +#include <dt-bindings/clock/ingenic,tcu.h> | |
| 2 | 3 | #include <dt-bindings/clock/x1000-cgu.h> |
| 3 | 4 | #include <dt-bindings/dma/x1000-dma.h> |
| 4 | 5 | |
| @@ -72,7 +73,7 @@ · 67 unmodified lines | ||
| 72 | 73 | compatible = "ingenic,x1000-watchdog", "ingenic,jz4780-watchdog"; |
| 73 | 74 | reg = <0x0 0x10>; |
| 74 | 75 | |
| 75 | − clocks = <&cgu X1000_CLK_RTCLK>; | |
| 76 | + clocks = <&tcu TCU_CLK_WDT>; | |
| 76 | 77 | clock-names = "wdt"; |
| 77 | 78 | }; |
| 78 | 79 | }; |
| @@ -158,7 +159,6 @@ · 79 unmodified lines | ||
| 158 | 159 | i2c0: i2c-controller@10050000 { |
| 159 | 160 | compatible = "ingenic,x1000-i2c"; |
| 160 | 161 | reg = <0x10050000 0x1000>; |
| 161 | − | |
| 162 | 162 | #address-cells = <1>; |
| 163 | 163 | #size-cells = <0>; |
| 164 | 164 | |
| @@ -173,7 +173,6 @@ · 8 unmodified lines | ||
| 173 | 173 | i2c1: i2c-controller@10051000 { |
| 174 | 174 | compatible = "ingenic,x1000-i2c"; |
| 175 | 175 | reg = <0x10051000 0x1000>; |
| 176 | − | |
| 177 | 176 | #address-cells = <1>; |
| 178 | 177 | #size-cells = <0>; |
| 179 | 178 | |
| @@ -188,7 +187,6 @@ · 8 unmodified lines | ||
| 188 | 187 | i2c2: i2c-controller@10052000 { |
| 189 | 188 | compatible = "ingenic,x1000-i2c"; |
| 190 | 189 | reg = <0x10052000 0x1000>; |
| 191 | − | |
| 192 | 190 | #address-cells = <1>; |
| 193 | 191 | #size-cells = <0>; |
| 194 | 192 | |
| @@ -155,9 +155,11 @@ · 154 unmodified lines | ||
| 155 | 155 | * effective barrier as noted by commit 6b07d38aaa52 ("MIPS: Octeon: Use |
| 156 | 156 | * optimized memory barrier primitives."). Here we specify that the affected |
| 157 | 157 | * sync instructions should be emitted twice. |
| 158 | + * Note that this expression is evaluated by the assembler (not the compiler), | |
| 159 | + * and that the assembler evaluates '==' as 0 or -1, not 0 or 1. | |
| 158 | 160 | */ |
| 159 | 161 | #ifdef CONFIG_CPU_CAVIUM_OCTEON |
| 160 | −# define __SYNC_rpt(type) (1 + (type == __SYNC_wmb)) | |
| 162 | +# define __SYNC_rpt(type) (1 - (type == __SYNC_wmb)) | |
| 161 | 163 | #else |
| 162 | 164 | # define __SYNC_rpt(type) 1 |
| 163 | 165 | #endif |
| @@ -605,7 +605,8 @@ static void __init bootcmdline_init(char **cmdline_p) · 604 unmodified lines | ||
| 605 | 605 | * If we're configured to take boot arguments from DT, look for those |
| 606 | 606 | * now. |
| 607 | 607 | */ |
| 608 | − if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)) | |
| 608 | + if (IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB) || | |
| 609 | + IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)) | |
| 609 | 610 | of_scan_flat_dt(bootcmdline_scan_chosen, &dt_bootargs); |
| 610 | 611 | #endif |
| 611 | 612 | |
| @@ -134,7 +134,7 @@ void release_vpe(struct vpe *v) · 133 unmodified lines | ||
| 134 | 134 | { |
| 135 | 135 | list_del(&v->list); |
| 136 | 136 | if (v->load_addr) |
| 137 | − release_progmem(v); | |
| 137 | + release_progmem(v->load_addr); | |
| 138 | 138 | kfree(v); |
| 139 | 139 | } |
| 140 | 140 | |
| @@ -33,6 +33,7 @@ endif · 32 unmodified lines | ||
| 33 | 33 | cflags-vdso := $(ccflags-vdso) \ |
| 34 | 34 | $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ |
| 35 | 35 | -O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \ |
| 36 | + -mrelax-pic-calls $(call cc-option, -mexplicit-relocs) \ | |
| 36 | 37 | -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \ |
| 37 | 38 | $(call cc-option, -fno-asynchronous-unwind-tables) \ |
| 38 | 39 | $(call cc-option, -fno-stack-protector) |
| @@ -51,6 +52,8 @@ endif · 12 unmodified lines | ||
| 51 | 52 | |
| 52 | 53 | CFLAGS_REMOVE_vgettimeofday.o = -pg |
| 53 | 54 | |
| 55 | +DISABLE_VDSO := n | |
| 56 | + | |
| 54 | 57 | # |
| 55 | 58 | # For the pre-R6 code in arch/mips/vdso/vdso.h for locating |
| 56 | 59 | # the base address of VDSO, the linker will emit a R_MIPS_PC32 |
| @@ -64,11 +67,24 @@ CFLAGS_REMOVE_vgettimeofday.o = -pg · 7 unmodified lines | ||
| 64 | 67 | ifndef CONFIG_CPU_MIPSR6 |
| 65 | 68 | ifeq ($(call ld-ifversion, -lt, 225000000, y),y) |
| 66 | 69 | $(warning MIPS VDSO requires binutils >= 2.25) |
| 67 | − obj-vdso-y := $(filter-out vgettimeofday.o, $(obj-vdso-y)) | |
| 68 | − ccflags-vdso += -DDISABLE_MIPS_VDSO | |
| 70 | + DISABLE_VDSO := y | |
| 69 | 71 | endif |
| 70 | 72 | endif |
| 71 | 73 | |
| 74 | +# | |
| 75 | +# GCC (at least up to version 9.2) appears to emit function calls that make use | |
| 76 | +# of the GOT when targeting microMIPS, which we can't use in the VDSO due to | |
| 77 | +# the lack of relocations. As such, we disable the VDSO for microMIPS builds. | |
| 78 | +# | |
| 79 | +ifdef CONFIG_CPU_MICROMIPS | |
| 80 | + DISABLE_VDSO := y | |
| 81 | +endif | |
| 82 | + | |
| 83 | +ifeq ($(DISABLE_VDSO),y) | |
| 84 | + obj-vdso-y := $(filter-out vgettimeofday.o, $(obj-vdso-y)) | |
| 85 | + ccflags-vdso += -DDISABLE_MIPS_VDSO | |
| 86 | +endif | |
| 87 | + | |
| 72 | 88 | # VDSO linker flags. |
| 73 | 89 | VDSO_LDFLAGS := \ |
| 74 | 90 | -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 \ |
| @@ -81,12 +97,18 @@ GCOV_PROFILE := n · 6 unmodified lines | ||
| 81 | 97 | UBSAN_SANITIZE := n |
| 82 | 98 | KCOV_INSTRUMENT := n |
| 83 | 99 | |
| 100 | +# Check that we don't have PIC 'jalr t9' calls left | |
| 101 | +quiet_cmd_vdso_mips_check = VDSOCHK $@ | |
| 102 | + cmd_vdso_mips_check = if $(OBJDUMP) --disassemble $@ | egrep -h "jalr.*t9" > /dev/null; \ | |
| 103 | + then (echo >&2 "$@: PIC 'jalr t9' calls are not supported"; \ | |
| 104 | + rm -f $@; /bin/false); fi | |
| 105 | + | |
| 84 | 106 | # |
| 85 | 107 | # Shared build commands. |
| 86 | 108 | # |
| 87 | 109 | |
| 88 | 110 | quiet_cmd_vdsold_and_vdso_check = LD $@ |
| 89 | − cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check) | |
| 111 | + cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check); $(cmd_vdso_mips_check) | |
| 90 | 112 | |
| 91 | 113 | quiet_cmd_vdsold = VDSO $@ |
| 92 | 114 | cmd_vdsold = $(CC) $(c_flags) $(VDSO_LDFLAGS) \ |
| @@ -2193,11 +2193,13 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset, · 2192 unmodified lines | ||
| 2193 | 2193 | * oprofile_cpu_type already has a value, then we are |
| 2194 | 2194 | * possibly overriding a real PVR with a logical one, |
| 2195 | 2195 | * and, in that case, keep the current value for |
| 2196 | − * oprofile_cpu_type. | |
| 2196 | + * oprofile_cpu_type. Futhermore, let's ensure that the | |
| 2197 | + * fix for the PMAO bug is enabled on compatibility mode. | |
| 2197 | 2198 | */ |
| 2198 | 2199 | if (old.oprofile_cpu_type != NULL) { |
| 2199 | 2200 | t->oprofile_cpu_type = old.oprofile_cpu_type; |
| 2200 | 2201 | t->oprofile_type = old.oprofile_type; |
| 2202 | + t->cpu_features |= old.cpu_features & CPU_FTR_PMAO_BUG; | |
| 2201 | 2203 | } |
| 2202 | 2204 | } |
| 2203 | 2205 | |
| @@ -331,11 +331,13 @@ int hw_breakpoint_handler(struct die_args *args) · 330 unmodified lines | ||
| 331 | 331 | } |
| 332 | 332 | |
| 333 | 333 | info->type &= ~HW_BRK_TYPE_EXTRANEOUS_IRQ; |
| 334 | − if (!dar_within_range(regs->dar, info)) | |
| 335 | − info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ; | |
| 336 | − | |
| 337 | − if (!IS_ENABLED(CONFIG_PPC_8xx) && !stepping_handler(regs, bp, info)) | |
| 338 | − goto out; | |
| 334 | + if (IS_ENABLED(CONFIG_PPC_8xx)) { | |
| 335 | + if (!dar_within_range(regs->dar, info)) | |
| 336 | + info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ; | |
| 337 | + } else { | |
| 338 | + if (!stepping_handler(regs, bp, info)) | |
| 339 | + goto out; | |
| 340 | + } | |
| 339 | 341 | |
| 340 | 342 | /* |
| 341 | 343 | * As a policy, the callback is invoked in a 'trigger-after-execute' |
| @@ -303,6 +303,12 @@ SECTIONS · 302 unmodified lines | ||
| 303 | 303 | *(.branch_lt) |
| 304 | 304 | } |
| 305 | 305 | |
| 306 | +#ifdef CONFIG_DEBUG_INFO_BTF | |
| 307 | + .BTF : AT(ADDR(.BTF) - LOAD_OFFSET) { | |
| 308 | + *(.BTF) | |
| 309 | + } | |
| 310 | +#endif | |
| 311 | + | |
| 306 | 312 | .opd : AT(ADDR(.opd) - LOAD_OFFSET) { |
| 307 | 313 | __start_opd = .; |
| 308 | 314 | KEEP(*(.opd)) |
| @@ -373,7 +373,9 @@ static inline bool flush_coherent_icache(unsigned long addr) · 372 unmodified lines | ||
| 373 | 373 | */ |
| 374 | 374 | if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) { |
| 375 | 375 | mb(); /* sync */ |
| 376 | + allow_read_from_user((const void __user *)addr, L1_CACHE_BYTES); | |
| 376 | 377 | icbi((void *)addr); |
| 378 | + prevent_read_from_user((const void __user *)addr, L1_CACHE_BYTES); | |
| 377 | 379 | mb(); /* sync */ |
| 378 | 380 | isync(); |
| 379 | 381 | return true; |
| @@ -121,6 +121,7 @@ config ARCH_FLATMEM_ENABLE · 120 unmodified lines | ||
| 121 | 121 | |
| 122 | 122 | config ARCH_SPARSEMEM_ENABLE |
| 123 | 123 | def_bool y |
| 124 | + depends on MMU | |
| 124 | 125 | select SPARSEMEM_VMEMMAP_ENABLE |
| 125 | 126 | |
| 126 | 127 | config ARCH_SELECT_MEMORY_MODEL |
| @@ -10,4 +10,28 @@ config SOC_SIFIVE · 9 unmodified lines | ||
| 10 | 10 | help |
| 11 | 11 | This enables support for SiFive SoC platform hardware. |
| 12 | 12 | |
| 13 | +config SOC_VIRT | |
| 14 | + bool "QEMU Virt Machine" | |
| 15 | + select VIRTIO_PCI | |
| 16 | + select VIRTIO_BALLOON | |
| 17 | + select VIRTIO_MMIO | |
| 18 | + select VIRTIO_CONSOLE | |
| 19 | + select VIRTIO_NET | |
| 20 | + select NET_9P_VIRTIO | |
| 21 | + select VIRTIO_BLK | |
| 22 | + select SCSI_VIRTIO | |
| 23 | + select DRM_VIRTIO_GPU | |
| 24 | + select HW_RANDOM_VIRTIO | |
| 25 | + select RPMSG_CHAR | |
| 26 | + select RPMSG_VIRTIO | |
| 27 | + select CRYPTO_DEV_VIRTIO | |
| 28 | + select VIRTIO_INPUT | |
| 29 | + select POWER_RESET_SYSCON | |
| 30 | + select POWER_RESET_SYSCON_POWEROFF | |
| 31 | + select GOLDFISH | |
| 32 | + select RTC_DRV_GOLDFISH | |
| 33 | + select SIFIVE_PLIC | |
| 34 | + help | |
| 35 | + This enables support for QEMU Virt Machine. | |
| 36 | + | |
| 13 | 37 | endmenu |
| @@ -13,8 +13,10 @@ LDFLAGS_vmlinux := · 12 unmodified lines | ||
| 13 | 13 | ifeq ($(CONFIG_DYNAMIC_FTRACE),y) |
| 14 | 14 | LDFLAGS_vmlinux := --no-relax |
| 15 | 15 | endif |
| 16 | −KBUILD_AFLAGS_MODULE += -fPIC | |
| 17 | −KBUILD_CFLAGS_MODULE += -fPIC | |
| 16 | + | |
| 17 | +ifeq ($(CONFIG_64BIT)$(CONFIG_CMODEL_MEDLOW),yy) | |
| 18 | +KBUILD_CFLAGS_MODULE += -mcmodel=medany | |
| 19 | +endif | |
| 18 | 20 | |
| 19 | 21 | export BITS |
| 20 | 22 | ifeq ($(CONFIG_ARCH_RV64I),y) |
| @@ -1,2 +1,4 @@ | ||
| 1 | 1 | Image |
| 2 | 2 | Image.gz |
| 3 | +loader | |
| 4 | +loader.lds | |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | /* Copyright (c) 2018-2019 SiFive, Inc */ |
| 3 | 3 | |
| 4 | 4 | #include "fu540-c000.dtsi" |
| 5 | +#include <dt-bindings/gpio/gpio.h> | |
| 5 | 6 | |
| 6 | 7 | /* Clock frequency (in Hz) of the PCB crystal for rtcclk */ |
| 7 | 8 | #define RTCCLK_FREQ 1000000 |
| @@ -41,6 +42,10 @@ · 33 unmodified lines | ||
| 41 | 42 | clock-frequency = <RTCCLK_FREQ>; |
| 42 | 43 | clock-output-names = "rtcclk"; |
| 43 | 44 | }; |
| 45 | + gpio-restart { | |
| 46 | + compatible = "gpio-restart"; | |
| 47 | + gpios = <&gpio 10 GPIO_ACTIVE_LOW>; | |
| 48 | + }; | |
| 44 | 49 | }; |
| 45 | 50 | |
| 46 | 51 | &uart0 { |
| @@ -15,6 +15,7 @@ CONFIG_BLK_DEV_INITRD=y · 14 unmodified lines | ||
| 15 | 15 | CONFIG_EXPERT=y |
| 16 | 16 | CONFIG_BPF_SYSCALL=y |
| 17 | 17 | CONFIG_SOC_SIFIVE=y |
| 18 | +CONFIG_SOC_VIRT=y | |
| 18 | 19 | CONFIG_SMP=y |
| 19 | 20 | CONFIG_MODULES=y |
| 20 | 21 | CONFIG_MODULE_UNLOAD=y |
| @@ -30,7 +31,6 @@ CONFIG_IP_PNP_BOOTP=y · 9 unmodified lines | ||
| 30 | 31 | CONFIG_IP_PNP_RARP=y |
| 31 | 32 | CONFIG_NETLINK_DIAG=y |
| 32 | 33 | CONFIG_NET_9P=y |
| 33 | −CONFIG_NET_9P_VIRTIO=y | |
| 34 | 34 | CONFIG_PCI=y |
| 35 | 35 | CONFIG_PCIEPORTBUS=y |
| 36 | 36 | CONFIG_PCI_HOST_GENERIC=y |
| @@ -38,15 +38,12 @@ CONFIG_PCIE_XILINX=y · 1 unmodified line | ||
| 38 | 38 | CONFIG_DEVTMPFS=y |
| 39 | 39 | CONFIG_DEVTMPFS_MOUNT=y |
| 40 | 40 | CONFIG_BLK_DEV_LOOP=y |
| 41 | −CONFIG_VIRTIO_BLK=y | |
| 42 | 41 | CONFIG_BLK_DEV_SD=y |
| 43 | 42 | CONFIG_BLK_DEV_SR=y |
| 44 | −CONFIG_SCSI_VIRTIO=y | |
| 45 | 43 | CONFIG_ATA=y |
| 46 | 44 | CONFIG_SATA_AHCI=y |
| 47 | 45 | CONFIG_SATA_AHCI_PLATFORM=y |
| 48 | 46 | CONFIG_NETDEVICES=y |
| 49 | −CONFIG_VIRTIO_NET=y | |
| 50 | 47 | CONFIG_MACB=y |
| 51 | 48 | CONFIG_E1000E=y |
| 52 | 49 | CONFIG_R8169=y |
| @@ -57,15 +54,13 @@ CONFIG_SERIAL_8250_CONSOLE=y · 4 unmodified lines | ||
| 57 | 54 | CONFIG_SERIAL_OF_PLATFORM=y |
| 58 | 55 | CONFIG_SERIAL_EARLYCON_RISCV_SBI=y |
| 59 | 56 | CONFIG_HVC_RISCV_SBI=y |
| 60 | −CONFIG_VIRTIO_CONSOLE=y | |
| 61 | 57 | CONFIG_HW_RANDOM=y |
| 62 | −CONFIG_HW_RANDOM_VIRTIO=y | |
| 63 | 58 | CONFIG_SPI=y |
| 64 | 59 | CONFIG_SPI_SIFIVE=y |
| 65 | 60 | # CONFIG_PTP_1588_CLOCK is not set |
| 61 | +CONFIG_POWER_RESET=y | |
| 66 | 62 | CONFIG_DRM=y |
| 67 | 63 | CONFIG_DRM_RADEON=y |
| 68 | −CONFIG_DRM_VIRTIO_GPU=y | |
| 69 | 64 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 70 | 65 | CONFIG_USB=y |
| 71 | 66 | CONFIG_USB_XHCI_HCD=y |
| @@ -78,12 +73,7 @@ CONFIG_USB_STORAGE=y · 6 unmodified lines | ||
| 78 | 73 | CONFIG_USB_UAS=y |
| 79 | 74 | CONFIG_MMC=y |
| 80 | 75 | CONFIG_MMC_SPI=y |
| 81 | −CONFIG_VIRTIO_PCI=y | |
| 82 | −CONFIG_VIRTIO_BALLOON=y | |
| 83 | −CONFIG_VIRTIO_INPUT=y | |
| 84 | −CONFIG_VIRTIO_MMIO=y | |
| 85 | −CONFIG_RPMSG_CHAR=y | |
| 86 | −CONFIG_RPMSG_VIRTIO=y | |
| 76 | +CONFIG_RTC_CLASS=y | |
| 87 | 77 | CONFIG_EXT4_FS=y |
| 88 | 78 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 89 | 79 | CONFIG_AUTOFS4_FS=y |
| @@ -98,7 +88,6 @@ CONFIG_NFS_V4_2=y · 8 unmodified lines | ||
| 98 | 88 | CONFIG_ROOT_NFS=y |
| 99 | 89 | CONFIG_9P_FS=y |
| 100 | 90 | CONFIG_CRYPTO_USER_API_HASH=y |
| 101 | −CONFIG_CRYPTO_DEV_VIRTIO=y | |
| 102 | 91 | CONFIG_PRINTK_TIME=y |
| 103 | 92 | CONFIG_DEBUG_FS=y |
| 104 | 93 | CONFIG_DEBUG_PAGEALLOC=y |
| @@ -14,6 +14,7 @@ CONFIG_CHECKPOINT_RESTORE=y · 13 unmodified lines | ||
| 14 | 14 | CONFIG_BLK_DEV_INITRD=y |
| 15 | 15 | CONFIG_EXPERT=y |
| 16 | 16 | CONFIG_BPF_SYSCALL=y |
| 17 | +CONFIG_SOC_VIRT=y | |
| 17 | 18 | CONFIG_ARCH_RV32I=y |
| 18 | 19 | CONFIG_SMP=y |
| 19 | 20 | CONFIG_MODULES=y |
| @@ -30,7 +31,6 @@ CONFIG_IP_PNP_BOOTP=y · 10 unmodified lines | ||
| 30 | 31 | CONFIG_IP_PNP_RARP=y |
| 31 | 32 | CONFIG_NETLINK_DIAG=y |
| 32 | 33 | CONFIG_NET_9P=y |
| 33 | −CONFIG_NET_9P_VIRTIO=y | |
| 34 | 34 | CONFIG_PCI=y |
| 35 | 35 | CONFIG_PCIEPORTBUS=y |
| 36 | 36 | CONFIG_PCI_HOST_GENERIC=y |
| @@ -38,15 +38,12 @@ CONFIG_PCIE_XILINX=y · 1 unmodified line | ||
| 38 | 38 | CONFIG_DEVTMPFS=y |
| 39 | 39 | CONFIG_DEVTMPFS_MOUNT=y |
| 40 | 40 | CONFIG_BLK_DEV_LOOP=y |
| 41 | −CONFIG_VIRTIO_BLK=y | |
| 42 | 41 | CONFIG_BLK_DEV_SD=y |
| 43 | 42 | CONFIG_BLK_DEV_SR=y |
| 44 | −CONFIG_SCSI_VIRTIO=y | |
| 45 | 43 | CONFIG_ATA=y |
| 46 | 44 | CONFIG_SATA_AHCI=y |
| 47 | 45 | CONFIG_SATA_AHCI_PLATFORM=y |
| 48 | 46 | CONFIG_NETDEVICES=y |
| 49 | −CONFIG_VIRTIO_NET=y | |
| 50 | 47 | CONFIG_MACB=y |
| 51 | 48 | CONFIG_E1000E=y |
| 52 | 49 | CONFIG_R8169=y |
| @@ -57,13 +54,11 @@ CONFIG_SERIAL_8250_CONSOLE=y · 4 unmodified lines | ||
| 57 | 54 | CONFIG_SERIAL_OF_PLATFORM=y |
| 58 | 55 | CONFIG_SERIAL_EARLYCON_RISCV_SBI=y |
| 59 | 56 | CONFIG_HVC_RISCV_SBI=y |
| 60 | −CONFIG_VIRTIO_CONSOLE=y | |
| 61 | 57 | CONFIG_HW_RANDOM=y |
| 62 | −CONFIG_HW_RANDOM_VIRTIO=y | |
| 63 | 58 | # CONFIG_PTP_1588_CLOCK is not set |
| 59 | +CONFIG_POWER_RESET=y | |
| 64 | 60 | CONFIG_DRM=y |
| 65 | 61 | CONFIG_DRM_RADEON=y |
| 66 | −CONFIG_DRM_VIRTIO_GPU=y | |
| 67 | 62 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 68 | 63 | CONFIG_USB=y |
| 69 | 64 | CONFIG_USB_XHCI_HCD=y |
| @@ -74,13 +69,7 @@ CONFIG_USB_OHCI_HCD=y · 4 unmodified lines | ||
| 74 | 69 | CONFIG_USB_OHCI_HCD_PLATFORM=y |
| 75 | 70 | CONFIG_USB_STORAGE=y |
| 76 | 71 | CONFIG_USB_UAS=y |
| 77 | −CONFIG_VIRTIO_PCI=y | |
| 78 | −CONFIG_VIRTIO_BALLOON=y | |
| 79 | −CONFIG_VIRTIO_INPUT=y | |
| 80 | −CONFIG_VIRTIO_MMIO=y | |
| 81 | −CONFIG_RPMSG_CHAR=y | |
| 82 | −CONFIG_RPMSG_VIRTIO=y | |
| 83 | −CONFIG_SIFIVE_PLIC=y | |
| 72 | +CONFIG_RTC_CLASS=y | |
| 84 | 73 | CONFIG_EXT4_FS=y |
| 85 | 74 | CONFIG_EXT4_FS_POSIX_ACL=y |
| 86 | 75 | CONFIG_AUTOFS4_FS=y |
| @@ -95,7 +84,6 @@ CONFIG_NFS_V4_2=y · 8 unmodified lines | ||
| 95 | 84 | CONFIG_ROOT_NFS=y |
| 96 | 85 | CONFIG_9P_FS=y |
| 97 | 86 | CONFIG_CRYPTO_USER_API_HASH=y |
| 98 | −CONFIG_CRYPTO_DEV_VIRTIO=y | |
| 99 | 87 | CONFIG_PRINTK_TIME=y |
| 100 | 88 | CONFIG_DEBUG_FS=y |
| 101 | 89 | CONFIG_DEBUG_PAGEALLOC=y |
| @@ -72,6 +72,16 @@ · 71 unmodified lines | ||
| 72 | 72 | #define EXC_LOAD_PAGE_FAULT 13 |
| 73 | 73 | #define EXC_STORE_PAGE_FAULT 15 |
| 74 | 74 | |
| 75 | +/* PMP configuration */ | |
| 76 | +#define PMP_R 0x01 | |
| 77 | +#define PMP_W 0x02 | |
| 78 | +#define PMP_X 0x04 | |
| 79 | +#define PMP_A 0x18 | |
| 80 | +#define PMP_A_TOR 0x08 | |
| 81 | +#define PMP_A_NA4 0x10 | |
| 82 | +#define PMP_A_NAPOT 0x18 | |
| 83 | +#define PMP_L 0x80 | |
| 84 | + | |
| 75 | 85 | /* symbolic CSR names: */ |
| 76 | 86 | #define CSR_CYCLE 0xc00 |
| 77 | 87 | #define CSR_TIME 0xc01 |
| @@ -100,6 +110,8 @@ · 22 unmodified lines | ||
| 100 | 110 | #define CSR_MCAUSE 0x342 |
| 101 | 111 | #define CSR_MTVAL 0x343 |
| 102 | 112 | #define CSR_MIP 0x344 |
| 113 | +#define CSR_PMPCFG0 0x3a0 | |
| 114 | +#define CSR_PMPADDR0 0x3b0 | |
| 103 | 115 | #define CSR_MHARTID 0xf14 |
| 104 | 116 | |
| 105 | 117 | #ifdef CONFIG_RISCV_M_MODE |
| @@ -28,13 +28,6 @@ static inline int syscall_get_nr(struct task_struct *task, · 27 unmodified lines | ||
| 28 | 28 | return regs->a7; |
| 29 | 29 | } |
| 30 | 30 | |
| 31 | −static inline void syscall_set_nr(struct task_struct *task, | |
| 32 | − struct pt_regs *regs, | |
| 33 | − int sysno) | |
| 34 | −{ | |
| 35 | − regs->a7 = sysno; | |
| 36 | −} | |
| 37 | − | |
| 38 | 31 | static inline void syscall_rollback(struct task_struct *task, |
| 39 | 32 | struct pt_regs *regs) |
| 40 | 33 | { |
| @@ -228,20 +228,13 @@ check_syscall_nr: · 227 unmodified lines | ||
| 228 | 228 | /* Check to make sure we don't jump to a bogus syscall number. */ |
| 229 | 229 | li t0, __NR_syscalls |
| 230 | 230 | la s0, sys_ni_syscall |
| 231 | − /* | |
| 232 | − * The tracer can change syscall number to valid/invalid value. | |
| 233 | − * We use syscall_set_nr helper in syscall_trace_enter thus we | |
| 234 | − * cannot trust the current value in a7 and have to reload from | |
| 235 | − * the current task pt_regs. | |
| 236 | − */ | |
| 237 | − REG_L a7, PT_A7(sp) | |
| 238 | 231 | /* |
| 239 | 232 | * Syscall number held in a7. |
| 240 | 233 | * If syscall number is above allowed value, redirect to ni_syscall. |
| 241 | 234 | */ |
| 242 | 235 | bge a7, t0, 1f |
| 243 | 236 | /* |
| 244 | − * Check if syscall is rejected by tracer or seccomp, i.e., a7 == -1. | |
| 237 | + * Check if syscall is rejected by tracer, i.e., a7 == -1. | |
| 245 | 238 | * If yes, we pretend it was executed. |
| 246 | 239 | */ |
| 247 | 240 | li t1, -1 |
| @@ -334,6 +327,7 @@ work_resched: · 86 unmodified lines | ||
| 334 | 327 | handle_syscall_trace_enter: |
| 335 | 328 | move a0, sp |
| 336 | 329 | call do_syscall_trace_enter |
| 330 | + move t0, a0 | |
| 337 | 331 | REG_L a0, PT_A0(sp) |
| 338 | 332 | REG_L a1, PT_A1(sp) |
| 339 | 333 | REG_L a2, PT_A2(sp) |
| @@ -342,6 +336,7 @@ handle_syscall_trace_enter: · 2 unmodified lines | ||
| 342 | 336 | REG_L a5, PT_A5(sp) |
| 343 | 337 | REG_L a6, PT_A6(sp) |
| 344 | 338 | REG_L a7, PT_A7(sp) |
| 339 | + bnez t0, ret_from_syscall_rejected | |
| 345 | 340 | j check_syscall_nr |
| 346 | 341 | handle_syscall_trace_exit: |
| 347 | 342 | move a0, sp |
| @@ -58,6 +58,12 @@ _start_kernel: · 57 unmodified lines | ||
| 58 | 58 | /* Reset all registers except ra, a0, a1 */ |
| 59 | 59 | call reset_regs |
| 60 | 60 | |
| 61 | + /* Setup a PMP to permit access to all of memory. */ | |
| 62 | + li a0, -1 | |
| 63 | + csrw CSR_PMPADDR0, a0 | |
| 64 | + li a0, (PMP_A_NAPOT | PMP_R | PMP_W | PMP_X) | |
| 65 | + csrw CSR_PMPCFG0, a0 | |
| 66 | + | |
| 61 | 67 | /* |
| 62 | 68 | * The hartid in a0 is expected later on, and we have no firmware |
| 63 | 69 | * to hand it to us. |
| @@ -8,6 +8,10 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/err.h> |
| 9 | 9 | #include <linux/errno.h> |
| 10 | 10 | #include <linux/moduleloader.h> |
| 11 | +#include <linux/vmalloc.h> | |
| 12 | +#include <linux/sizes.h> | |
| 13 | +#include <asm/pgtable.h> | |
| 14 | +#include <asm/sections.h> | |
| 11 | 15 | |
| 12 | 16 | static int apply_r_riscv_32_rela(struct module *me, u32 *location, Elf_Addr v) |
| 13 | 17 | { |
| @@ -386,3 +390,15 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, · 372 unmodified lines | ||
| 386 | 390 | |
| 387 | 391 | return 0; |
| 388 | 392 | } |
| 393 | + | |
| 394 | +#if defined(CONFIG_MMU) && defined(CONFIG_64BIT) | |
| 395 | +#define VMALLOC_MODULE_START \ | |
| 396 | + max(PFN_ALIGN((unsigned long)&_end - SZ_2G), VMALLOC_START) | |
| 397 | +void *module_alloc(unsigned long size) | |
| 398 | +{ | |
| 399 | + return __vmalloc_node_range(size, 1, VMALLOC_MODULE_START, | |
| 400 | + VMALLOC_END, GFP_KERNEL, | |
| 401 | + PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE, | |
| 402 | + __builtin_return_address(0)); | |
| 403 | +} | |
| 404 | +#endif | |
| @@ -148,21 +148,19 @@ long arch_ptrace(struct task_struct *child, long request, · 147 unmodified lines | ||
| 148 | 148 | * Allows PTRACE_SYSCALL to work. These are called from entry.S in |
| 149 | 149 | * {handle,ret_from}_syscall. |
| 150 | 150 | */ |
| 151 | −__visible void do_syscall_trace_enter(struct pt_regs *regs) | |
| 151 | +__visible int do_syscall_trace_enter(struct pt_regs *regs) | |
| 152 | 152 | { |
| 153 | 153 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
| 154 | 154 | if (tracehook_report_syscall_entry(regs)) |
| 155 | − syscall_set_nr(current, regs, -1); | |
| 155 | + return -1; | |
| 156 | 156 | |
| 157 | 157 | /* |
| 158 | 158 | * Do the secure computing after ptrace; failures should be fast. |
| 159 | 159 | * If this fails we might have return value in a0 from seccomp |
| 160 | 160 | * (via SECCOMP_RET_ERRNO/TRACE). |
| 161 | 161 | */ |
| 162 | − if (secure_computing() == -1) { | |
| 163 | − syscall_set_nr(current, regs, -1); | |
| 164 | − return; | |
| 165 | − } | |
| 162 | + if (secure_computing() == -1) | |
| 163 | + return -1; | |
| 166 | 164 | |
| 167 | 165 | #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS |
| 168 | 166 | if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) |
| @@ -170,6 +168,7 @@ __visible void do_syscall_trace_enter(struct pt_regs *regs) · 1 unmodified line | ||
| 170 | 168 | #endif |
| 171 | 169 | |
| 172 | 170 | audit_syscall_entry(regs->a7, regs->a0, regs->a1, regs->a2, regs->a3); |
| 171 | + return 0; | |
| 173 | 172 | } |
| 174 | 173 | |
| 175 | 174 | __visible void do_syscall_trace_exit(struct pt_regs *regs) |
| @@ -156,6 +156,6 @@ void __init trap_init(void) · 155 unmodified lines | ||
| 156 | 156 | csr_write(CSR_SCRATCH, 0); |
| 157 | 157 | /* Set the exception vector address */ |
| 158 | 158 | csr_write(CSR_TVEC, &handle_exception); |
| 159 | − /* Enable all interrupts */ | |
| 160 | − csr_write(CSR_IE, -1); | |
| 159 | + /* Enable interrupts */ | |
| 160 | + csr_write(CSR_IE, IE_SIE | IE_EIE); | |
| 161 | 161 | } |
| @@ -131,7 +131,7 @@ void __init setup_bootmem(void) · 130 unmodified lines | ||
| 131 | 131 | for_each_memblock(memory, reg) { |
| 132 | 132 | phys_addr_t end = reg->base + reg->size; |
| 133 | 133 | |
| 134 | − if (reg->base <= vmlinux_end && vmlinux_end <= end) { | |
| 134 | + if (reg->base <= vmlinux_start && vmlinux_end <= end) { | |
| 135 | 135 | mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET); |
| 136 | 136 | |
| 137 | 137 | /* |
| @@ -19,18 +19,20 @@ asmlinkage void __init kasan_early_init(void) · 18 unmodified lines | ||
| 19 | 19 | for (i = 0; i < PTRS_PER_PTE; ++i) |
| 20 | 20 | set_pte(kasan_early_shadow_pte + i, |
| 21 | 21 | mk_pte(virt_to_page(kasan_early_shadow_page), |
| 22 | − PAGE_KERNEL)); | |
| 22 | + PAGE_KERNEL)); | |
| 23 | 23 | |
| 24 | 24 | for (i = 0; i < PTRS_PER_PMD; ++i) |
| 25 | 25 | set_pmd(kasan_early_shadow_pmd + i, |
| 26 | − pfn_pmd(PFN_DOWN(__pa((uintptr_t)kasan_early_shadow_pte)), | |
| 27 | − __pgprot(_PAGE_TABLE))); | |
| 26 | + pfn_pmd(PFN_DOWN | |
| 27 | + (__pa((uintptr_t) kasan_early_shadow_pte)), | |
| 28 | + __pgprot(_PAGE_TABLE))); | |
| 28 | 29 | |
| 29 | 30 | for (i = KASAN_SHADOW_START; i < KASAN_SHADOW_END; |
| 30 | 31 | i += PGDIR_SIZE, ++pgd) |
| 31 | 32 | set_pgd(pgd, |
| 32 | − pfn_pgd(PFN_DOWN(__pa(((uintptr_t)kasan_early_shadow_pmd))), | |
| 33 | − __pgprot(_PAGE_TABLE))); | |
| 33 | + pfn_pgd(PFN_DOWN | |
| 34 | + (__pa(((uintptr_t) kasan_early_shadow_pmd))), | |
| 35 | + __pgprot(_PAGE_TABLE))); | |
| 34 | 36 | |
| 35 | 37 | /* init for swapper_pg_dir */ |
| 36 | 38 | pgd = pgd_offset_k(KASAN_SHADOW_START); |
| @@ -38,37 +40,43 @@ asmlinkage void __init kasan_early_init(void) · 1 unmodified line | ||
| 38 | 40 | for (i = KASAN_SHADOW_START; i < KASAN_SHADOW_END; |
| 39 | 41 | i += PGDIR_SIZE, ++pgd) |
| 40 | 42 | set_pgd(pgd, |
| 41 | − pfn_pgd(PFN_DOWN(__pa(((uintptr_t)kasan_early_shadow_pmd))), | |
| 42 | − __pgprot(_PAGE_TABLE))); | |
| 43 | + pfn_pgd(PFN_DOWN | |
| 44 | + (__pa(((uintptr_t) kasan_early_shadow_pmd))), | |
| 45 | + __pgprot(_PAGE_TABLE))); | |
| 43 | 46 | |
| 44 | 47 | flush_tlb_all(); |
| 45 | 48 | } |
| 46 | 49 | |
| 47 | 50 | static void __init populate(void *start, void *end) |
| 48 | 51 | { |
| 49 | − unsigned long i; | |
| 52 | + unsigned long i, offset; | |
| 50 | 53 | unsigned long vaddr = (unsigned long)start & PAGE_MASK; |
| 51 | 54 | unsigned long vend = PAGE_ALIGN((unsigned long)end); |
| 52 | 55 | unsigned long n_pages = (vend - vaddr) / PAGE_SIZE; |
| 56 | + unsigned long n_ptes = | |
| 57 | + ((n_pages + PTRS_PER_PTE) & -PTRS_PER_PTE) / PTRS_PER_PTE; | |
| 53 | 58 | unsigned long n_pmds = |
| 54 | − (n_pages % PTRS_PER_PTE) ? n_pages / PTRS_PER_PTE + 1 : | |
| 55 | − n_pages / PTRS_PER_PTE; | |
| 59 | + ((n_ptes + PTRS_PER_PMD) & -PTRS_PER_PMD) / PTRS_PER_PMD; | |
| 60 | + | |
| 61 | + pte_t *pte = | |
| 62 | + memblock_alloc(n_ptes * PTRS_PER_PTE * sizeof(pte_t), PAGE_SIZE); | |
| 63 | + pmd_t *pmd = | |
| 64 | + memblock_alloc(n_pmds * PTRS_PER_PMD * sizeof(pmd_t), PAGE_SIZE); | |
| 56 | 65 | pgd_t *pgd = pgd_offset_k(vaddr); |
| 57 | − pmd_t *pmd = memblock_alloc(n_pmds * sizeof(pmd_t), PAGE_SIZE); | |
| 58 | − pte_t *pte = memblock_alloc(n_pages * sizeof(pte_t), PAGE_SIZE); | |
| 59 | 66 | |
| 60 | 67 | for (i = 0; i < n_pages; i++) { |
| 61 | 68 | phys_addr_t phys = memblock_phys_alloc(PAGE_SIZE, PAGE_SIZE); |
| 62 | − | |
| 63 | − set_pte(pte + i, pfn_pte(PHYS_PFN(phys), PAGE_KERNEL)); | |
| 69 | + set_pte(&pte[i], pfn_pte(PHYS_PFN(phys), PAGE_KERNEL)); | |
| 64 | 70 | } |
| 65 | 71 | |
| 66 | − for (i = 0; i < n_pmds; ++pgd, i += PTRS_PER_PMD) | |
| 67 | − set_pgd(pgd, pfn_pgd(PFN_DOWN(__pa(((uintptr_t)(pmd + i)))), | |
| 72 | + for (i = 0, offset = 0; i < n_ptes; i++, offset += PTRS_PER_PTE) | |
| 73 | + set_pmd(&pmd[i], | |
| 74 | + pfn_pmd(PFN_DOWN(__pa(&pte[offset])), | |
| 68 | 75 | __pgprot(_PAGE_TABLE))); |
| 69 | 76 | |
| 70 | − for (i = 0; i < n_pages; ++pmd, i += PTRS_PER_PTE) | |
| 71 | − set_pmd(pmd, pfn_pmd(PFN_DOWN(__pa((uintptr_t)(pte + i))), | |
| 77 | + for (i = 0, offset = 0; i < n_pmds; i++, offset += PTRS_PER_PMD) | |
| 78 | + set_pgd(&pgd[i], | |
| 79 | + pfn_pgd(PFN_DOWN(__pa(&pmd[offset])), | |
| 72 | 80 | __pgprot(_PAGE_TABLE))); |
| 73 | 81 | |
| 74 | 82 | flush_tlb_all(); |
| @@ -81,7 +89,8 @@ void __init kasan_init(void) · 6 unmodified lines | ||
| 81 | 89 | unsigned long i; |
| 82 | 90 | |
| 83 | 91 | kasan_populate_early_shadow((void *)KASAN_SHADOW_START, |
| 84 | − (void *)kasan_mem_to_shadow((void *)VMALLOC_END)); | |
| 92 | + (void *)kasan_mem_to_shadow((void *) | |
| 93 | + VMALLOC_END)); | |
| 85 | 94 | |
| 86 | 95 | for_each_memblock(memory, reg) { |
| 87 | 96 | void *start = (void *)__va(reg->base); |
| @@ -90,14 +99,14 @@ void __init kasan_init(void) · 2 unmodified lines | ||
| 90 | 99 | if (start >= end) |
| 91 | 100 | break; |
| 92 | 101 | |
| 93 | − populate(kasan_mem_to_shadow(start), | |
| 94 | − kasan_mem_to_shadow(end)); | |
| 102 | + populate(kasan_mem_to_shadow(start), kasan_mem_to_shadow(end)); | |
| 95 | 103 | }; |
| 96 | 104 | |
| 97 | 105 | for (i = 0; i < PTRS_PER_PTE; i++) |
| 98 | 106 | set_pte(&kasan_early_shadow_pte[i], |
| 99 | 107 | mk_pte(virt_to_page(kasan_early_shadow_page), |
| 100 | − __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_ACCESSED))); | |
| 108 | + __pgprot(_PAGE_PRESENT | _PAGE_READ | | |
| 109 | + _PAGE_ACCESSED))); | |
| 101 | 110 | |
| 102 | 111 | memset(kasan_early_shadow_page, 0, PAGE_SIZE); |
| 103 | 112 | init_task.kasan_depth = 0; |
| @@ -752,6 +752,12 @@ static inline int pmd_write(pmd_t pmd) · 751 unmodified lines | ||
| 752 | 752 | return (pmd_val(pmd) & _SEGMENT_ENTRY_WRITE) != 0; |
| 753 | 753 | } |
| 754 | 754 | |
| 755 | +#define pud_write pud_write | |
| 756 | +static inline int pud_write(pud_t pud) | |
| 757 | +{ | |
| 758 | + return (pud_val(pud) & _REGION3_ENTRY_WRITE) != 0; | |
| 759 | +} | |
| 760 | + | |
| 755 | 761 | static inline int pmd_dirty(pmd_t pmd) |
| 756 | 762 | { |
| 757 | 763 | return (pmd_val(pmd) & _SEGMENT_ENTRY_DIRTY) != 0; |
| @@ -3268,7 +3268,10 @@ static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu) · 3267 unmodified lines | ||
| 3268 | 3268 | /* Initial reset is a superset of the normal reset */ |
| 3269 | 3269 | kvm_arch_vcpu_ioctl_normal_reset(vcpu); |
| 3270 | 3270 | |
| 3271 | − /* this equals initial cpu reset in pop, but we don't switch to ESA */ | |
| 3271 | + /* | |
| 3272 | + * This equals initial cpu reset in pop, but we don't switch to ESA. | |
| 3273 | + * We do not only reset the internal data, but also ... | |
| 3274 | + */ | |
| 3272 | 3275 | vcpu->arch.sie_block->gpsw.mask = 0; |
| 3273 | 3276 | vcpu->arch.sie_block->gpsw.addr = 0; |
| 3274 | 3277 | kvm_s390_set_prefix(vcpu, 0); |
| @@ -3278,6 +3281,19 @@ static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu) · 3 unmodified lines | ||
| 3278 | 3281 | memset(vcpu->arch.sie_block->gcr, 0, sizeof(vcpu->arch.sie_block->gcr)); |
| 3279 | 3282 | vcpu->arch.sie_block->gcr[0] = CR0_INITIAL_MASK; |
| 3280 | 3283 | vcpu->arch.sie_block->gcr[14] = CR14_INITIAL_MASK; |
| 3284 | + | |
| 3285 | + /* ... the data in sync regs */ | |
| 3286 | + memset(vcpu->run->s.regs.crs, 0, sizeof(vcpu->run->s.regs.crs)); | |
| 3287 | + vcpu->run->s.regs.ckc = 0; | |
| 3288 | + vcpu->run->s.regs.crs[0] = CR0_INITIAL_MASK; | |
| 3289 | + vcpu->run->s.regs.crs[14] = CR14_INITIAL_MASK; | |
| 3290 | + vcpu->run->psw_addr = 0; | |
| 3291 | + vcpu->run->psw_mask = 0; | |
| 3292 | + vcpu->run->s.regs.todpr = 0; | |
| 3293 | + vcpu->run->s.regs.cputm = 0; | |
| 3294 | + vcpu->run->s.regs.ckc = 0; | |
| 3295 | + vcpu->run->s.regs.pp = 0; | |
| 3296 | + vcpu->run->s.regs.gbea = 1; | |
| 3281 | 3297 | vcpu->run->s.regs.fpc = 0; |
| 3282 | 3298 | vcpu->arch.sie_block->gbea = 1; |
| 3283 | 3299 | vcpu->arch.sie_block->pp = 0; |
| @@ -424,7 +424,7 @@ static void zpci_map_resources(struct pci_dev *pdev) · 423 unmodified lines | ||
| 424 | 424 | |
| 425 | 425 | if (zpci_use_mio(zdev)) |
| 426 | 426 | pdev->resource[i].start = |
| 427 | − (resource_size_t __force) zdev->bars[i].mio_wb; | |
| 427 | + (resource_size_t __force) zdev->bars[i].mio_wt; | |
| 428 | 428 | else |
| 429 | 429 | pdev->resource[i].start = (resource_size_t __force) |
| 430 | 430 | pci_iomap_range_fh(pdev, i, 0, 0); |
| @@ -531,7 +531,7 @@ static int zpci_setup_bus_resources(struct zpci_dev *zdev, · 100 unmodified lines | ||
| 531 | 531 | flags |= IORESOURCE_MEM_64; |
| 532 | 532 | |
| 533 | 533 | if (zpci_use_mio(zdev)) |
| 534 | − addr = (unsigned long) zdev->bars[i].mio_wb; | |
| 534 | + addr = (unsigned long) zdev->bars[i].mio_wt; | |
| 535 | 535 | else |
| 536 | 536 | addr = ZPCI_ADDR(entry); |
| 537 | 537 | size = 1UL << zdev->bars[i].size; |
| @@ -194,9 +194,10 @@ avx2_instr :=$(call as-instr,vpbroadcastb %xmm0$(comma)%ymm1,-DCONFIG_AS_AVX2=1) · 193 unmodified lines | ||
| 194 | 194 | avx512_instr :=$(call as-instr,vpmovm2b %k1$(comma)%zmm5,-DCONFIG_AS_AVX512=1) |
| 195 | 195 | sha1_ni_instr :=$(call as-instr,sha1msg1 %xmm0$(comma)%xmm1,-DCONFIG_AS_SHA1_NI=1) |
| 196 | 196 | sha256_ni_instr :=$(call as-instr,sha256msg1 %xmm0$(comma)%xmm1,-DCONFIG_AS_SHA256_NI=1) |
| 197 | +adx_instr := $(call as-instr,adox %r10$(comma)%r10,-DCONFIG_AS_ADX=1) | |
| 197 | 198 | |
| 198 | −KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr) | |
| 199 | −KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr) | |
| 199 | +KBUILD_AFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr) $(adx_instr) | |
| 200 | +KBUILD_CFLAGS += $(cfi) $(cfi-sigframe) $(cfi-sections) $(asinstr) $(avx_instr) $(avx2_instr) $(avx512_instr) $(sha1_ni_instr) $(sha256_ni_instr) $(adx_instr) | |
| 200 | 201 | |
| 201 | 202 | KBUILD_LDFLAGS := -m elf_$(UTS_MACHINE) |
| 202 | 203 | |
| @@ -11,6 +11,7 @@ avx2_supported := $(call as-instr,vpgatherdd %ymm0$(comma)(%eax$(comma)%ymm1\ · 10 unmodified lines | ||
| 11 | 11 | avx512_supported :=$(call as-instr,vpmovm2b %k1$(comma)%zmm5,yes,no) |
| 12 | 12 | sha1_ni_supported :=$(call as-instr,sha1msg1 %xmm0$(comma)%xmm1,yes,no) |
| 13 | 13 | sha256_ni_supported :=$(call as-instr,sha256msg1 %xmm0$(comma)%xmm1,yes,no) |
| 14 | +adx_supported := $(call as-instr,adox %r10$(comma)%r10,yes,no) | |
| 14 | 15 | |
| 15 | 16 | obj-$(CONFIG_CRYPTO_GLUE_HELPER_X86) += glue_helper.o |
| 16 | 17 | |
| @@ -39,7 +40,11 @@ obj-$(CONFIG_CRYPTO_AEGIS128_AESNI_SSE2) += aegis128-aesni.o · 22 unmodified lines | ||
| 39 | 40 | |
| 40 | 41 | obj-$(CONFIG_CRYPTO_NHPOLY1305_SSE2) += nhpoly1305-sse2.o |
| 41 | 42 | obj-$(CONFIG_CRYPTO_NHPOLY1305_AVX2) += nhpoly1305-avx2.o |
| 42 | −obj-$(CONFIG_CRYPTO_CURVE25519_X86) += curve25519-x86_64.o | |
| 43 | + | |
| 44 | +# These modules require the assembler to support ADX. | |
| 45 | +ifeq ($(adx_supported),yes) | |
| 46 | + obj-$(CONFIG_CRYPTO_CURVE25519_X86) += curve25519-x86_64.o | |
| 47 | +endif | |
| 43 | 48 | |
| 44 | 49 | # These modules require assembler to support AVX. |
| 45 | 50 | ifeq ($(avx_supported),yes) |
| @@ -190,15 +190,12 @@ static int amd_uncore_event_init(struct perf_event *event) · 189 unmodified lines | ||
| 190 | 190 | |
| 191 | 191 | /* |
| 192 | 192 | * NB and Last level cache counters (MSRs) are shared across all cores |
| 193 | − * that share the same NB / Last level cache. Interrupts can be directed | |
| 194 | − * to a single target core, however, event counts generated by processes | |
| 195 | − * running on other cores cannot be masked out. So we do not support | |
| 196 | − * sampling and per-thread events. | |
| 193 | + * that share the same NB / Last level cache. On family 16h and below, | |
| 194 | + * Interrupts can be directed to a single target core, however, event | |
| 195 | + * counts generated by processes running on other cores cannot be masked | |
| 196 | + * out. So we do not support sampling and per-thread events via | |
| 197 | + * CAP_NO_INTERRUPT, and we do not enable counter overflow interrupts: | |
| 197 | 198 | */ |
| 198 | − if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) | |
| 199 | − return -EINVAL; | |
| 200 | − | |
| 201 | − /* and we do not enable counter overflow interrupts */ | |
| 202 | 199 | hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB; |
| 203 | 200 | hwc->idx = -1; |
| 204 | 201 | |
| @@ -306,7 +303,7 @@ static struct pmu amd_nb_pmu = { · 101 unmodified lines | ||
| 306 | 303 | .start = amd_uncore_start, |
| 307 | 304 | .stop = amd_uncore_stop, |
| 308 | 305 | .read = amd_uncore_read, |
| 309 | − .capabilities = PERF_PMU_CAP_NO_EXCLUDE, | |
| 306 | + .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT, | |
| 310 | 307 | }; |
| 311 | 308 | |
| 312 | 309 | static struct pmu amd_llc_pmu = { |
| @@ -317,7 +314,7 @@ static struct pmu amd_llc_pmu = { · 4 unmodified lines | ||
| 317 | 314 | .start = amd_uncore_start, |
| 318 | 315 | .stop = amd_uncore_stop, |
| 319 | 316 | .read = amd_uncore_read, |
| 320 | − .capabilities = PERF_PMU_CAP_NO_EXCLUDE, | |
| 317 | + .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT, | |
| 321 | 318 | }; |
| 322 | 319 | |
| 323 | 320 | static struct amd_uncore *amd_uncore_alloc(unsigned int cpu) |
| @@ -19,7 +19,14 @@ struct task_struct; · 18 unmodified lines | ||
| 19 | 19 | void io_bitmap_share(struct task_struct *tsk); |
| 20 | 20 | void io_bitmap_exit(void); |
| 21 | 21 | |
| 22 | −void tss_update_io_bitmap(void); | |
| 22 | +void native_tss_update_io_bitmap(void); | |
| 23 | + | |
| 24 | +#ifdef CONFIG_PARAVIRT_XXL | |
| 25 | +#include <asm/paravirt.h> | |
| 26 | +#else | |
| 27 | +#define tss_update_io_bitmap native_tss_update_io_bitmap | |
| 28 | +#endif | |
| 29 | + | |
| 23 | 30 | #else |
| 24 | 31 | static inline void io_bitmap_share(struct task_struct *tsk) { } |
| 25 | 32 | static inline void io_bitmap_exit(void) { } |
| @@ -292,6 +292,14 @@ enum x86emul_mode { · 291 unmodified lines | ||
| 292 | 292 | #define X86EMUL_SMM_MASK (1 << 6) |
| 293 | 293 | #define X86EMUL_SMM_INSIDE_NMI_MASK (1 << 7) |
| 294 | 294 | |
| 295 | +/* | |
| 296 | + * fastop functions are declared as taking a never-defined fastop parameter, | |
| 297 | + * so they can't be called from C directly. | |
| 298 | + */ | |
| 299 | +struct fastop; | |
| 300 | + | |
| 301 | +typedef void (*fastop_t)(struct fastop *); | |
| 302 | + | |
| 295 | 303 | struct x86_emulate_ctxt { |
| 296 | 304 | const struct x86_emulate_ops *ops; |
| 297 | 305 | |
| @@ -324,7 +332,10 @@ struct x86_emulate_ctxt { · 26 unmodified lines | ||
| 324 | 332 | struct operand src; |
| 325 | 333 | struct operand src2; |
| 326 | 334 | struct operand dst; |
| 327 | − int (*execute)(struct x86_emulate_ctxt *ctxt); | |
| 335 | + union { | |
| 336 | + int (*execute)(struct x86_emulate_ctxt *ctxt); | |
| 337 | + fastop_t fop; | |
| 338 | + }; | |
| 328 | 339 | int (*check_perm)(struct x86_emulate_ctxt *ctxt); |
| 329 | 340 | /* |
| 330 | 341 | * The following six fields are cleared together, |
| @@ -349,7 +360,6 @@ struct x86_emulate_ctxt { · 18 unmodified lines | ||
| 349 | 360 | u64 d; |
| 350 | 361 | unsigned long _eip; |
| 351 | 362 | struct operand memop; |
| 352 | − /* Fields above regs are cleared together. */ | |
| 353 | 363 | unsigned long _regs[NR_VCPU_REGS]; |
| 354 | 364 | struct operand *memopp; |
| 355 | 365 | struct fetch_cache fetch; |
| @@ -1122,6 +1122,7 @@ struct kvm_x86_ops { · 1121 unmodified lines | ||
| 1122 | 1122 | int (*handle_exit)(struct kvm_vcpu *vcpu, |
| 1123 | 1123 | enum exit_fastpath_completion exit_fastpath); |
| 1124 | 1124 | int (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); |
| 1125 | + void (*update_emulated_instruction)(struct kvm_vcpu *vcpu); | |
| 1125 | 1126 | void (*set_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask); |
| 1126 | 1127 | u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu); |
| 1127 | 1128 | void (*patch_hypercall)(struct kvm_vcpu *vcpu, |
| @@ -1146,7 +1147,7 @@ struct kvm_x86_ops { · 18 unmodified lines | ||
| 1146 | 1147 | void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap); |
| 1147 | 1148 | void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu); |
| 1148 | 1149 | void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa); |
| 1149 | − void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector); | |
| 1150 | + int (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector); | |
| 1150 | 1151 | int (*sync_pir_to_irr)(struct kvm_vcpu *vcpu); |
| 1151 | 1152 | int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); |
| 1152 | 1153 | int (*set_identity_map_addr)(struct kvm *kvm, u64 ident_addr); |
| @@ -295,6 +295,13 @@ static inline void write_idt_entry(gate_desc *dt, int entry, const gate_desc *g) · 294 unmodified lines | ||
| 295 | 295 | PVOP_VCALL3(cpu.write_idt_entry, dt, entry, g); |
| 296 | 296 | } |
| 297 | 297 | |
| 298 | +#ifdef CONFIG_X86_IOPL_IOPERM | |
| 299 | +static inline void tss_update_io_bitmap(void) | |
| 300 | +{ | |
| 301 | + PVOP_VCALL0(cpu.update_io_bitmap); | |
| 302 | +} | |
| 303 | +#endif | |
| 304 | + | |
| 298 | 305 | static inline void paravirt_activate_mm(struct mm_struct *prev, |
| 299 | 306 | struct mm_struct *next) |
| 300 | 307 | { |
| @@ -140,6 +140,10 @@ struct pv_cpu_ops { · 139 unmodified lines | ||
| 140 | 140 | |
| 141 | 141 | void (*load_sp0)(unsigned long sp0); |
| 142 | 142 | |
| 143 | +#ifdef CONFIG_X86_IOPL_IOPERM | |
| 144 | + void (*update_io_bitmap)(void); | |
| 145 | +#endif | |
| 146 | + | |
| 143 | 147 | void (*wbinvd)(void); |
| 144 | 148 | |
| 145 | 149 | /* cpuid emulation, mostly so that caps bits can be disabled */ |
| @@ -72,7 +72,7 @@ · 71 unmodified lines | ||
| 72 | 72 | #define SECONDARY_EXEC_MODE_BASED_EPT_EXEC VMCS_CONTROL_BIT(MODE_BASED_EPT_EXEC) |
| 73 | 73 | #define SECONDARY_EXEC_PT_USE_GPA VMCS_CONTROL_BIT(PT_USE_GPA) |
| 74 | 74 | #define SECONDARY_EXEC_TSC_SCALING VMCS_CONTROL_BIT(TSC_SCALING) |
| 75 | −#define SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE 0x04000000 | |
| 75 | +#define SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE VMCS_CONTROL_BIT(USR_WAIT_PAUSE) | |
| 76 | 76 | |
| 77 | 77 | #define PIN_BASED_EXT_INTR_MASK VMCS_CONTROL_BIT(INTR_EXITING) |
| 78 | 78 | #define PIN_BASED_NMI_EXITING VMCS_CONTROL_BIT(NMI_EXITING) |
| @@ -81,6 +81,7 @@ · 80 unmodified lines | ||
| 81 | 81 | #define VMX_FEATURE_MODE_BASED_EPT_EXEC ( 2*32+ 22) /* "ept_mode_based_exec" Enable separate EPT EXEC bits for supervisor vs. user */ |
| 82 | 82 | #define VMX_FEATURE_PT_USE_GPA ( 2*32+ 24) /* "" Processor Trace logs GPAs */ |
| 83 | 83 | #define VMX_FEATURE_TSC_SCALING ( 2*32+ 25) /* Scale hardware TSC when read in guest */ |
| 84 | +#define VMX_FEATURE_USR_WAIT_PAUSE ( 2*32+ 26) /* Enable TPAUSE, UMONITOR, UMWAIT in guest */ | |
| 84 | 85 | #define VMX_FEATURE_ENCLV_EXITING ( 2*32+ 28) /* "" VM-Exit on ENCLV (leaf dependent) */ |
| 85 | 86 | |
| 86 | 87 | #endif /* _ASM_X86_VMXFEATURES_H */ |
| @@ -390,6 +390,7 @@ struct kvm_sync_regs { · 389 unmodified lines | ||
| 390 | 390 | #define KVM_STATE_NESTED_GUEST_MODE 0x00000001 |
| 391 | 391 | #define KVM_STATE_NESTED_RUN_PENDING 0x00000002 |
| 392 | 392 | #define KVM_STATE_NESTED_EVMCS 0x00000004 |
| 393 | +#define KVM_STATE_NESTED_MTF_PENDING 0x00000008 | |
| 393 | 394 | |
| 394 | 395 | #define KVM_STATE_NESTED_SMM_GUEST_MODE 0x00000001 |
| 395 | 396 | #define KVM_STATE_NESTED_SMM_VMXON 0x00000002 |
| @@ -838,13 +838,15 @@ static void free_moved_vector(struct apic_chip_data *apicd) · 837 unmodified lines | ||
| 838 | 838 | bool managed = apicd->is_managed; |
| 839 | 839 | |
| 840 | 840 | /* |
| 841 | − * This should never happen. Managed interrupts are not | |
| 842 | − * migrated except on CPU down, which does not involve the | |
| 843 | − * cleanup vector. But try to keep the accounting correct | |
| 844 | − * nevertheless. | |
| 841 | + * Managed interrupts are usually not migrated away | |
| 842 | + * from an online CPU, but CPU isolation 'managed_irq' | |
| 843 | + * can make that happen. | |
| 844 | + * 1) Activation does not take the isolation into account | |
| 845 | + * to keep the code simple | |
| 846 | + * 2) Migration away from an isolated CPU can happen when | |
| 847 | + * a non-isolated CPU which is in the calculated | |
| 848 | + * affinity mask comes online. | |
| 845 | 849 | */ |
| 846 | − WARN_ON_ONCE(managed); | |
| 847 | − | |
| 848 | 850 | trace_vector_free_moved(apicd->irq, cpu, vector, managed); |
| 849 | 851 | irq_matrix_free(vector_matrix, cpu, vector, managed); |
| 850 | 852 | per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED; |
| @@ -445,7 +445,7 @@ static __always_inline void setup_pku(struct cpuinfo_x86 *c) · 444 unmodified lines | ||
| 445 | 445 | * cpuid bit to be set. We need to ensure that we |
| 446 | 446 | * update that bit in this CPU's "cpu_info". |
| 447 | 447 | */ |
| 448 | − get_cpu_cap(c); | |
| 448 | + set_cpu_cap(c, X86_FEATURE_OSPKE); | |
| 449 | 449 | } |
| 450 | 450 | |
| 451 | 451 | #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS |
| @@ -493,17 +493,18 @@ static void intel_ppin_init(struct cpuinfo_x86 *c) · 492 unmodified lines | ||
| 493 | 493 | return; |
| 494 | 494 | |
| 495 | 495 | if ((val & 3UL) == 1UL) { |
| 496 | − /* PPIN available but disabled: */ | |
| 496 | + /* PPIN locked in disabled mode */ | |
| 497 | 497 | return; |
| 498 | 498 | } |
| 499 | 499 | |
| 500 | − /* If PPIN is disabled, but not locked, try to enable: */ | |
| 501 | − if (!(val & 3UL)) { | |
| 500 | + /* If PPIN is disabled, try to enable */ | |
| 501 | + if (!(val & 2UL)) { | |
| 502 | 502 | wrmsrl_safe(MSR_PPIN_CTL, val | 2UL); |
| 503 | 503 | rdmsrl_safe(MSR_PPIN_CTL, &val); |
| 504 | 504 | } |
| 505 | 505 | |
| 506 | − if ((val & 3UL) == 2UL) | |
| 506 | + /* Is the enable bit set? */ | |
| 507 | + if (val & 2UL) | |
| 507 | 508 | set_cpu_cap(c, X86_FEATURE_INTEL_PPIN); |
| 508 | 509 | } |
| 509 | 510 | } |
| @@ -486,9 +486,14 @@ static int thermal_throttle_offline(unsigned int cpu) · 485 unmodified lines | ||
| 486 | 486 | { |
| 487 | 487 | struct thermal_state *state = &per_cpu(thermal_state, cpu); |
| 488 | 488 | struct device *dev = get_cpu_device(cpu); |
| 489 | + u32 l; | |
| 490 | + | |
| 491 | + /* Mask the thermal vector before draining evtl. pending work */ | |
| 492 | + l = apic_read(APIC_LVTTHMR); | |
| 493 | + apic_write(APIC_LVTTHMR, l | APIC_LVT_MASKED); | |
| 489 | 494 | |
| 490 | − cancel_delayed_work(&state->package_throttle.therm_work); | |
| 491 | − cancel_delayed_work(&state->core_throttle.therm_work); | |
| 495 | + cancel_delayed_work_sync(&state->package_throttle.therm_work); | |
| 496 | + cancel_delayed_work_sync(&state->core_throttle.therm_work); | |
| 492 | 497 | |
| 493 | 498 | state->package_throttle.rate_control_active = false; |
| 494 | 499 | state->core_throttle.rate_control_active = false; |
| @@ -425,7 +425,29 @@ static void __init sev_map_percpu_data(void) · 424 unmodified lines | ||
| 425 | 425 | } |
| 426 | 426 | } |
| 427 | 427 | |
| 428 | +static bool pv_tlb_flush_supported(void) | |
| 429 | +{ | |
| 430 | + return (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) && | |
| 431 | + !kvm_para_has_hint(KVM_HINTS_REALTIME) && | |
| 432 | + kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)); | |
| 433 | +} | |
| 434 | + | |
| 435 | +static DEFINE_PER_CPU(cpumask_var_t, __pv_cpu_mask); | |
| 436 | + | |
| 428 | 437 | #ifdef CONFIG_SMP |
| 438 | + | |
| 439 | +static bool pv_ipi_supported(void) | |
| 440 | +{ | |
| 441 | + return kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI); | |
| 442 | +} | |
| 443 | + | |
| 444 | +static bool pv_sched_yield_supported(void) | |
| 445 | +{ | |
| 446 | + return (kvm_para_has_feature(KVM_FEATURE_PV_SCHED_YIELD) && | |
| 447 | + !kvm_para_has_hint(KVM_HINTS_REALTIME) && | |
| 448 | + kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)); | |
| 449 | +} | |
| 450 | + | |
| 429 | 451 | #define KVM_IPI_CLUSTER_SIZE (2 * BITS_PER_LONG) |
| 430 | 452 | |
| 431 | 453 | static void __send_ipi_mask(const struct cpumask *mask, int vector) |
| @@ -490,12 +512,12 @@ static void kvm_send_ipi_mask(const struct cpumask *mask, int vector) · 58 unmodified lines | ||
| 490 | 512 | static void kvm_send_ipi_mask_allbutself(const struct cpumask *mask, int vector) |
| 491 | 513 | { |
| 492 | 514 | unsigned int this_cpu = smp_processor_id(); |
| 493 | − struct cpumask new_mask; | |
| 515 | + struct cpumask *new_mask = this_cpu_cpumask_var_ptr(__pv_cpu_mask); | |
| 494 | 516 | const struct cpumask *local_mask; |
| 495 | 517 | |
| 496 | − cpumask_copy(&new_mask, mask); | |
| 497 | − cpumask_clear_cpu(this_cpu, &new_mask); | |
| 498 | − local_mask = &new_mask; | |
| 518 | + cpumask_copy(new_mask, mask); | |
| 519 | + cpumask_clear_cpu(this_cpu, new_mask); | |
| 520 | + local_mask = new_mask; | |
| 499 | 521 | __send_ipi_mask(local_mask, vector); |
| 500 | 522 | } |
| 501 | 523 | |
| @@ -575,7 +597,6 @@ static void __init kvm_apf_trap_init(void) · 73 unmodified lines | ||
| 575 | 597 | update_intr_gate(X86_TRAP_PF, async_page_fault); |
| 576 | 598 | } |
| 577 | 599 | |
| 578 | −static DEFINE_PER_CPU(cpumask_var_t, __pv_tlb_mask); | |
| 579 | 600 | |
| 580 | 601 | static void kvm_flush_tlb_others(const struct cpumask *cpumask, |
| 581 | 602 | const struct flush_tlb_info *info) |
| @@ -583,7 +604,7 @@ static void kvm_flush_tlb_others(const struct cpumask *cpumask, · 1 unmodified line | ||
| 583 | 604 | u8 state; |
| 584 | 605 | int cpu; |
| 585 | 606 | struct kvm_steal_time *src; |
| 586 | − struct cpumask *flushmask = this_cpu_cpumask_var_ptr(__pv_tlb_mask); | |
| 607 | + struct cpumask *flushmask = this_cpu_cpumask_var_ptr(__pv_cpu_mask); | |
| 587 | 608 | |
| 588 | 609 | cpumask_copy(flushmask, cpumask); |
| 589 | 610 | /* |
| @@ -619,11 +640,10 @@ static void __init kvm_guest_init(void) · 29 unmodified lines | ||
| 619 | 640 | pv_ops.time.steal_clock = kvm_steal_clock; |
| 620 | 641 | } |
| 621 | 642 | |
| 622 | − if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) && | |
| 623 | − !kvm_para_has_hint(KVM_HINTS_REALTIME) && | |
| 624 | − kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { | |
| 643 | + if (pv_tlb_flush_supported()) { | |
| 625 | 644 | pv_ops.mmu.flush_tlb_others = kvm_flush_tlb_others; |
| 626 | 645 | pv_ops.mmu.tlb_remove_table = tlb_remove_table; |
| 646 | + pr_info("KVM setup pv remote TLB flush\n"); | |
| 627 | 647 | } |
| 628 | 648 | |
| 629 | 649 | if (kvm_para_has_feature(KVM_FEATURE_PV_EOI)) |
| @@ -632,9 +652,7 @@ static void __init kvm_guest_init(void) · 2 unmodified lines | ||
| 632 | 652 | #ifdef CONFIG_SMP |
| 633 | 653 | smp_ops.smp_prepare_cpus = kvm_smp_prepare_cpus; |
| 634 | 654 | smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu; |
| 635 | − if (kvm_para_has_feature(KVM_FEATURE_PV_SCHED_YIELD) && | |
| 636 | − !kvm_para_has_hint(KVM_HINTS_REALTIME) && | |
| 637 | − kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { | |
| 655 | + if (pv_sched_yield_supported()) { | |
| 638 | 656 | smp_ops.send_call_func_ipi = kvm_smp_send_call_func_ipi; |
| 639 | 657 | pr_info("KVM setup pv sched yield\n"); |
| 640 | 658 | } |
| @@ -700,7 +718,7 @@ static uint32_t __init kvm_detect(void) · 59 unmodified lines | ||
| 700 | 718 | static void __init kvm_apic_init(void) |
| 701 | 719 | { |
| 702 | 720 | #if defined(CONFIG_SMP) |
| 703 | − if (kvm_para_has_feature(KVM_FEATURE_PV_SEND_IPI)) | |
| 721 | + if (pv_ipi_supported()) | |
| 704 | 722 | kvm_setup_pv_ipi(); |
| 705 | 723 | #endif |
| 706 | 724 | } |
| @@ -732,26 +750,31 @@ static __init int activate_jump_labels(void) · 25 unmodified lines | ||
| 732 | 750 | } |
| 733 | 751 | arch_initcall(activate_jump_labels); |
| 734 | 752 | |
| 735 | −static __init int kvm_setup_pv_tlb_flush(void) | |
| 753 | +static __init int kvm_alloc_cpumask(void) | |
| 736 | 754 | { |
| 737 | 755 | int cpu; |
| 756 | + bool alloc = false; | |
| 738 | 757 | |
| 739 | 758 | if (!kvm_para_available() || nopv) |
| 740 | 759 | return 0; |
| 741 | 760 | |
| 742 | − if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) && | |
| 743 | − !kvm_para_has_hint(KVM_HINTS_REALTIME) && | |
| 744 | − kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) { | |
| 761 | + if (pv_tlb_flush_supported()) | |
| 762 | + alloc = true; | |
| 763 | + | |
| 764 | +#if defined(CONFIG_SMP) | |
| 765 | + if (pv_ipi_supported()) | |
| 766 | + alloc = true; | |
| 767 | +#endif | |
| 768 | + | |
| 769 | + if (alloc) | |
| 745 | 770 | for_each_possible_cpu(cpu) { |
| 746 | − zalloc_cpumask_var_node(per_cpu_ptr(&__pv_tlb_mask, cpu), | |
| 771 | + zalloc_cpumask_var_node(per_cpu_ptr(&__pv_cpu_mask, cpu), | |
| 747 | 772 | GFP_KERNEL, cpu_to_node(cpu)); |
| 748 | 773 | } |
| 749 | − pr_info("KVM setup pv remote TLB flush\n"); | |
| 750 | − } | |
| 751 | 774 | |
| 752 | 775 | return 0; |
| 753 | 776 | } |
| 754 | −arch_initcall(kvm_setup_pv_tlb_flush); | |
| 777 | +arch_initcall(kvm_alloc_cpumask); | |
| 755 | 778 | |
| 756 | 779 | #ifdef CONFIG_PARAVIRT_SPINLOCKS |
| 757 | 780 | |
| @@ -30,6 +30,7 @@ · 29 unmodified lines | ||
| 30 | 30 | #include <asm/timer.h> |
| 31 | 31 | #include <asm/special_insns.h> |
| 32 | 32 | #include <asm/tlb.h> |
| 33 | +#include <asm/io_bitmap.h> | |
| 33 | 34 | |
| 34 | 35 | /* |
| 35 | 36 | * nop stub, which must not clobber anything *including the stack* to |
| @@ -341,6 +342,10 @@ struct paravirt_patch_template pv_ops = { · 305 unmodified lines | ||
| 341 | 342 | .cpu.iret = native_iret, |
| 342 | 343 | .cpu.swapgs = native_swapgs, |
| 343 | 344 | |
| 345 | +#ifdef CONFIG_X86_IOPL_IOPERM | |
| 346 | + .cpu.update_io_bitmap = native_tss_update_io_bitmap, | |
| 347 | +#endif | |
| 348 | + | |
| 344 | 349 | .cpu.start_context_switch = paravirt_nop, |
| 345 | 350 | .cpu.end_context_switch = paravirt_nop, |
| 346 | 351 | |
| @@ -374,7 +374,7 @@ static void tss_copy_io_bitmap(struct tss_struct *tss, struct io_bitmap *iobm) · 373 unmodified lines | ||
| 374 | 374 | /** |
| 375 | 375 | * tss_update_io_bitmap - Update I/O bitmap before exiting to usermode |
| 376 | 376 | */ |
| 377 | −void tss_update_io_bitmap(void) | |
| 377 | +void native_tss_update_io_bitmap(void) | |
| 378 | 378 | { |
| 379 | 379 | struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw); |
| 380 | 380 | struct thread_struct *t = ¤t->thread; |
| @@ -59,6 +59,19 @@ config KVM · 58 unmodified lines | ||
| 59 | 59 | |
| 60 | 60 | If unsure, say N. |
| 61 | 61 | |
| 62 | +config KVM_WERROR | |
| 63 | + bool "Compile KVM with -Werror" | |
| 64 | + # KASAN may cause the build to fail due to larger frames | |
| 65 | + default y if X86_64 && !KASAN | |
| 66 | + # We use the dependency on !COMPILE_TEST to not be enabled | |
| 67 | + # blindly in allmodconfig or allyesconfig configurations | |
| 68 | + depends on (X86_64 && !KASAN) || !COMPILE_TEST | |
| 69 | + depends on EXPERT | |
| 70 | + help | |
| 71 | + Add -Werror to the build flags for KVM. | |
| 72 | + | |
| 73 | + If in doubt, say "N". | |
| 74 | + | |
| 62 | 75 | config KVM_INTEL |
| 63 | 76 | tristate "KVM for Intel (and compatible) processors support" |
| 64 | 77 | depends on KVM && IA32_FEAT_CTL |
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | |
| 3 | 3 | ccflags-y += -Iarch/x86/kvm |
| 4 | +ccflags-$(CONFIG_KVM_WERROR) += -Werror | |
| 4 | 5 | |
| 5 | 6 | KVM := ../../../virt/kvm |
| 6 | 7 | |
| @@ -191,25 +191,6 @@ · 190 unmodified lines | ||
| 191 | 191 | #define NR_FASTOP (ilog2(sizeof(ulong)) + 1) |
| 192 | 192 | #define FASTOP_SIZE 8 |
| 193 | 193 | |
| 194 | −/* | |
| 195 | − * fastop functions have a special calling convention: | |
| 196 | − * | |
| 197 | − * dst: rax (in/out) | |
| 198 | − * src: rdx (in/out) | |
| 199 | − * src2: rcx (in) | |
| 200 | − * flags: rflags (in/out) | |
| 201 | − * ex: rsi (in:fastop pointer, out:zero if exception) | |
| 202 | − * | |
| 203 | − * Moreover, they are all exactly FASTOP_SIZE bytes long, so functions for | |
| 204 | − * different operand sizes can be reached by calculation, rather than a jump | |
| 205 | − * table (which would be bigger than the code). | |
| 206 | − * | |
| 207 | − * fastop functions are declared as taking a never-defined fastop parameter, | |
| 208 | − * so they can't be called from C directly. | |
| 209 | − */ | |
| 210 | − | |
| 211 | −struct fastop; | |
| 212 | − | |
| 213 | 194 | struct opcode { |
| 214 | 195 | u64 flags : 56; |
| 215 | 196 | u64 intercept : 8; |
| @@ -311,8 +292,19 @@ static void invalidate_registers(struct x86_emulate_ctxt *ctxt) · 95 unmodified lines | ||
| 311 | 292 | #define ON64(x) |
| 312 | 293 | #endif |
| 313 | 294 | |
| 314 | −typedef void (*fastop_t)(struct fastop *); | |
| 315 | − | |
| 295 | +/* | |
| 296 | + * fastop functions have a special calling convention: | |
| 297 | + * | |
| 298 | + * dst: rax (in/out) | |
| 299 | + * src: rdx (in/out) | |
| 300 | + * src2: rcx (in) | |
| 301 | + * flags: rflags (in/out) | |
| 302 | + * ex: rsi (in:fastop pointer, out:zero if exception) | |
| 303 | + * | |
| 304 | + * Moreover, they are all exactly FASTOP_SIZE bytes long, so functions for | |
| 305 | + * different operand sizes can be reached by calculation, rather than a jump | |
| 306 | + * table (which would be bigger than the code). | |
| 307 | + */ | |
| 316 | 308 | static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop); |
| 317 | 309 | |
| 318 | 310 | #define __FOP_FUNC(name) \ |
| @@ -5181,6 +5173,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) · 4862 unmodified lines | ||
| 5181 | 5173 | ctxt->fetch.ptr = ctxt->fetch.data; |
| 5182 | 5174 | ctxt->fetch.end = ctxt->fetch.data + insn_len; |
| 5183 | 5175 | ctxt->opcode_len = 1; |
| 5176 | + ctxt->intercept = x86_intercept_none; | |
| 5184 | 5177 | if (insn_len > 0) |
| 5185 | 5178 | memcpy(ctxt->fetch.data, insn, insn_len); |
| 5186 | 5179 | else { |
| @@ -5683,7 +5676,7 @@ special_insn: · 496 unmodified lines | ||
| 5683 | 5676 | |
| 5684 | 5677 | if (ctxt->execute) { |
| 5685 | 5678 | if (ctxt->d & Fastop) |
| 5686 | − rc = fastop(ctxt, (fastop_t)ctxt->execute); | |
| 5679 | + rc = fastop(ctxt, ctxt->fop); | |
| 5687 | 5680 | else |
| 5688 | 5681 | rc = ctxt->execute(ctxt); |
| 5689 | 5682 | if (rc != X86EMUL_CONTINUE) |
| @@ -378,12 +378,15 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) · 377 unmodified lines | ||
| 378 | 378 | if (e->fields.delivery_mode == APIC_DM_FIXED) { |
| 379 | 379 | struct kvm_lapic_irq irq; |
| 380 | 380 | |
| 381 | − irq.shorthand = APIC_DEST_NOSHORT; | |
| 382 | 381 | irq.vector = e->fields.vector; |
| 383 | 382 | irq.delivery_mode = e->fields.delivery_mode << 8; |
| 384 | − irq.dest_id = e->fields.dest_id; | |
| 385 | 383 | irq.dest_mode = |
| 386 | 384 | kvm_lapic_irq_dest_mode(!!e->fields.dest_mode); |
| 385 | + irq.level = false; | |
| 386 | + irq.trig_mode = e->fields.trig_mode; | |
| 387 | + irq.shorthand = APIC_DEST_NOSHORT; | |
| 388 | + irq.dest_id = e->fields.dest_id; | |
| 389 | + irq.msi_redir_hint = false; | |
| 387 | 390 | bitmap_zero(&vcpu_bitmap, 16); |
| 388 | 391 | kvm_bitmap_or_dest_vcpus(ioapic->kvm, &irq, |
| 389 | 392 | &vcpu_bitmap); |
| @@ -417,7 +417,7 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, · 416 unmodified lines | ||
| 417 | 417 | |
| 418 | 418 | kvm_set_msi_irq(vcpu->kvm, entry, &irq); |
| 419 | 419 | |
| 420 | − if (irq.level && | |
| 420 | + if (irq.trig_mode && | |
| 421 | 421 | kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT, |
| 422 | 422 | irq.dest_id, irq.dest_mode)) |
| 423 | 423 | __set_bit(irq.vector, ioapic_handled_vectors); |
| @@ -627,9 +627,11 @@ static inline bool pv_eoi_enabled(struct kvm_vcpu *vcpu) · 626 unmodified lines | ||
| 627 | 627 | static bool pv_eoi_get_pending(struct kvm_vcpu *vcpu) |
| 628 | 628 | { |
| 629 | 629 | u8 val; |
| 630 | − if (pv_eoi_get_user(vcpu, &val) < 0) | |
| 630 | + if (pv_eoi_get_user(vcpu, &val) < 0) { | |
| 631 | 631 | printk(KERN_WARNING "Can't read EOI MSR value: 0x%llx\n", |
| 632 | 632 | (unsigned long long)vcpu->arch.pv_eoi.msr_val); |
| 633 | + return false; | |
| 634 | + } | |
| 633 | 635 | return val & 0x1; |
| 634 | 636 | } |
| 635 | 637 | |
| @@ -1046,11 +1048,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, · 410 unmodified lines | ||
| 1046 | 1048 | apic->regs + APIC_TMR); |
| 1047 | 1049 | } |
| 1048 | 1050 | |
| 1049 | − if (vcpu->arch.apicv_active) | |
| 1050 | − kvm_x86_ops->deliver_posted_interrupt(vcpu, vector); | |
| 1051 | − else { | |
| 1051 | + if (kvm_x86_ops->deliver_posted_interrupt(vcpu, vector)) { | |
| 1052 | 1052 | kvm_lapic_set_irr(vector, apic); |
| 1053 | − | |
| 1054 | 1053 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
| 1055 | 1054 | kvm_vcpu_kick(vcpu); |
| 1056 | 1055 | } |
| @@ -339,7 +339,7 @@ TRACE_EVENT( · 338 unmodified lines | ||
| 339 | 339 | /* These depend on page entry type, so compute them now. */ |
| 340 | 340 | __field(bool, r) |
| 341 | 341 | __field(bool, x) |
| 342 | − __field(u8, u) | |
| 342 | + __field(signed char, u) | |
| 343 | 343 | ), |
| 344 | 344 | |
| 345 | 345 | TP_fast_assign( |
| @@ -57,11 +57,13 @@ · 56 unmodified lines | ||
| 57 | 57 | MODULE_AUTHOR("Qumranet"); |
| 58 | 58 | MODULE_LICENSE("GPL"); |
| 59 | 59 | |
| 60 | +#ifdef MODULE | |
| 60 | 61 | static const struct x86_cpu_id svm_cpu_id[] = { |
| 61 | 62 | X86_FEATURE_MATCH(X86_FEATURE_SVM), |
| 62 | 63 | {} |
| 63 | 64 | }; |
| 64 | 65 | MODULE_DEVICE_TABLE(x86cpu, svm_cpu_id); |
| 66 | +#endif | |
| 65 | 67 | |
| 66 | 68 | #define IOPM_ALLOC_ORDER 2 |
| 67 | 69 | #define MSRPM_ALLOC_ORDER 1 |
| @@ -1005,33 +1007,32 @@ static void svm_cpu_uninit(int cpu) · 937 unmodified lines | ||
| 1005 | 1007 | static int svm_cpu_init(int cpu) |
| 1006 | 1008 | { |
| 1007 | 1009 | struct svm_cpu_data *sd; |
| 1008 | − int r; | |
| 1009 | 1010 | |
| 1010 | 1011 | sd = kzalloc(sizeof(struct svm_cpu_data), GFP_KERNEL); |
| 1011 | 1012 | if (!sd) |
| 1012 | 1013 | return -ENOMEM; |
| 1013 | 1014 | sd->cpu = cpu; |
| 1014 | − r = -ENOMEM; | |
| 1015 | 1015 | sd->save_area = alloc_page(GFP_KERNEL); |
| 1016 | 1016 | if (!sd->save_area) |
| 1017 | − goto err_1; | |
| 1017 | + goto free_cpu_data; | |
| 1018 | 1018 | |
| 1019 | 1019 | if (svm_sev_enabled()) { |
| 1020 | − r = -ENOMEM; | |
| 1021 | 1020 | sd->sev_vmcbs = kmalloc_array(max_sev_asid + 1, |
| 1022 | 1021 | sizeof(void *), |
| 1023 | 1022 | GFP_KERNEL); |
| 1024 | 1023 | if (!sd->sev_vmcbs) |
| 1025 | − goto err_1; | |
| 1024 | + goto free_save_area; | |
| 1026 | 1025 | } |
| 1027 | 1026 | |
| 1028 | 1027 | per_cpu(svm_data, cpu) = sd; |
| 1029 | 1028 | |
| 1030 | 1029 | return 0; |
| 1031 | 1030 | |
| 1032 | −err_1: | |
| 1031 | +free_save_area: | |
| 1032 | + __free_page(sd->save_area); | |
| 1033 | +free_cpu_data: | |
| 1033 | 1034 | kfree(sd); |
| 1034 | − return r; | |
| 1035 | + return -ENOMEM; | |
| 1035 | 1036 | |
| 1036 | 1037 | } |
| 1037 | 1038 | |
| @@ -1350,6 +1351,24 @@ static __init void svm_adjust_mmio_mask(void) · 312 unmodified lines | ||
| 1350 | 1351 | kvm_mmu_set_mmio_spte_mask(mask, mask, PT_WRITABLE_MASK | PT_USER_MASK); |
| 1351 | 1352 | } |
| 1352 | 1353 | |
| 1354 | +static void svm_hardware_teardown(void) | |
| 1355 | +{ | |
| 1356 | + int cpu; | |
| 1357 | + | |
| 1358 | + if (svm_sev_enabled()) { | |
| 1359 | + bitmap_free(sev_asid_bitmap); | |
| 1360 | + bitmap_free(sev_reclaim_asid_bitmap); | |
| 1361 | + | |
| 1362 | + sev_flush_asids(); | |
| 1363 | + } | |
| 1364 | + | |
| 1365 | + for_each_possible_cpu(cpu) | |
| 1366 | + svm_cpu_uninit(cpu); | |
| 1367 | + | |
| 1368 | + __free_pages(pfn_to_page(iopm_base >> PAGE_SHIFT), IOPM_ALLOC_ORDER); | |
| 1369 | + iopm_base = 0; | |
| 1370 | +} | |
| 1371 | + | |
| 1353 | 1372 | static __init int svm_hardware_setup(void) |
| 1354 | 1373 | { |
| 1355 | 1374 | int cpu; |
| @@ -1463,29 +1482,10 @@ static __init int svm_hardware_setup(void) · 107 unmodified lines | ||
| 1463 | 1482 | return 0; |
| 1464 | 1483 | |
| 1465 | 1484 | err: |
| 1466 | − __free_pages(iopm_pages, IOPM_ALLOC_ORDER); | |
| 1467 | − iopm_base = 0; | |
| 1485 | + svm_hardware_teardown(); | |
| 1468 | 1486 | return r; |
| 1469 | 1487 | } |
| 1470 | 1488 | |
| 1471 | −static __exit void svm_hardware_unsetup(void) | |
| 1472 | −{ | |
| 1473 | − int cpu; | |
| 1474 | − | |
| 1475 | − if (svm_sev_enabled()) { | |
| 1476 | − bitmap_free(sev_asid_bitmap); | |
| 1477 | − bitmap_free(sev_reclaim_asid_bitmap); | |
| 1478 | − | |
| 1479 | − sev_flush_asids(); | |
| 1480 | − } | |
| 1481 | − | |
| 1482 | − for_each_possible_cpu(cpu) | |
| 1483 | − svm_cpu_uninit(cpu); | |
| 1484 | − | |
| 1485 | − __free_pages(pfn_to_page(iopm_base >> PAGE_SHIFT), IOPM_ALLOC_ORDER); | |
| 1486 | − iopm_base = 0; | |
| 1487 | −} | |
| 1488 | − | |
| 1489 | 1489 | static void init_seg(struct vmcb_seg *seg) |
| 1490 | 1490 | { |
| 1491 | 1491 | seg->selector = 0; |
| @@ -2196,8 +2196,9 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 704 unmodified lines | ||
| 2196 | 2196 | static int avic_init_vcpu(struct vcpu_svm *svm) |
| 2197 | 2197 | { |
| 2198 | 2198 | int ret; |
| 2199 | + struct kvm_vcpu *vcpu = &svm->vcpu; | |
| 2199 | 2200 | |
| 2200 | − if (!kvm_vcpu_apicv_active(&svm->vcpu)) | |
| 2201 | + if (!avic || !irqchip_in_kernel(vcpu->kvm)) | |
| 2201 | 2202 | return 0; |
| 2202 | 2203 | |
| 2203 | 2204 | ret = avic_init_backing_page(&svm->vcpu); |
| @@ -5232,6 +5233,9 @@ static void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu) · 3028 unmodified lines | ||
| 5232 | 5233 | struct vmcb *vmcb = svm->vmcb; |
| 5233 | 5234 | bool activated = kvm_vcpu_apicv_active(vcpu); |
| 5234 | 5235 | |
| 5236 | + if (!avic) | |
| 5237 | + return; | |
| 5238 | + | |
| 5235 | 5239 | if (activated) { |
| 5236 | 5240 | /** |
| 5237 | 5241 | * During AVIC temporary deactivation, guest could update |
| @@ -5255,8 +5259,11 @@ static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) · 17 unmodified lines | ||
| 5255 | 5259 | return; |
| 5256 | 5260 | } |
| 5257 | 5261 | |
| 5258 | −static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec) | |
| 5262 | +static int svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec) | |
| 5259 | 5263 | { |
| 5264 | + if (!vcpu->arch.apicv_active) | |
| 5265 | + return -1; | |
| 5266 | + | |
| 5260 | 5267 | kvm_lapic_set_irr(vec, vcpu->arch.apic); |
| 5261 | 5268 | smp_mb__after_atomic(); |
| 5262 | 5269 | |
| @@ -5268,6 +5275,8 @@ static void svm_deliver_avic_intr(struct kvm_vcpu *vcpu, int vec) · 5 unmodified lines | ||
| 5268 | 5275 | put_cpu(); |
| 5269 | 5276 | } else |
| 5270 | 5277 | kvm_vcpu_wake_up(vcpu); |
| 5278 | + | |
| 5279 | + return 0; | |
| 5271 | 5280 | } |
| 5272 | 5281 | |
| 5273 | 5282 | static bool svm_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu) |
| @@ -6303,7 +6312,8 @@ static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu, · 1029 unmodified lines | ||
| 6303 | 6312 | enum exit_fastpath_completion *exit_fastpath) |
| 6304 | 6313 | { |
| 6305 | 6314 | if (!is_guest_mode(vcpu) && |
| 6306 | − to_svm(vcpu)->vmcb->control.exit_code == EXIT_REASON_MSR_WRITE) | |
| 6315 | + to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR && | |
| 6316 | + to_svm(vcpu)->vmcb->control.exit_info_1) | |
| 6307 | 6317 | *exit_fastpath = handle_fastpath_set_msr_irqoff(vcpu); |
| 6308 | 6318 | } |
| 6309 | 6319 | |
| @@ -7378,7 +7388,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { · 1068 unmodified lines | ||
| 7378 | 7388 | .cpu_has_kvm_support = has_svm, |
| 7379 | 7389 | .disabled_by_bios = is_disabled, |
| 7380 | 7390 | .hardware_setup = svm_hardware_setup, |
| 7381 | − .hardware_unsetup = svm_hardware_unsetup, | |
| 7391 | + .hardware_unsetup = svm_hardware_teardown, | |
| 7382 | 7392 | .check_processor_compatibility = svm_check_processor_compat, |
| 7383 | 7393 | .hardware_enable = svm_hardware_enable, |
| 7384 | 7394 | .hardware_disable = svm_hardware_disable, |
| @@ -7433,6 +7443,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { · 48 unmodified lines | ||
| 7433 | 7443 | .run = svm_vcpu_run, |
| 7434 | 7444 | .handle_exit = handle_exit, |
| 7435 | 7445 | .skip_emulated_instruction = skip_emulated_instruction, |
| 7446 | + .update_emulated_instruction = NULL, | |
| 7436 | 7447 | .set_interrupt_shadow = svm_set_interrupt_shadow, |
| 7437 | 7448 | .get_interrupt_shadow = svm_get_interrupt_shadow, |
| 7438 | 7449 | .patch_hypercall = svm_patch_hypercall, |
| @@ -12,6 +12,7 @@ extern bool __read_mostly enable_ept; · 11 unmodified lines | ||
| 12 | 12 | extern bool __read_mostly enable_unrestricted_guest; |
| 13 | 13 | extern bool __read_mostly enable_ept_ad_bits; |
| 14 | 14 | extern bool __read_mostly enable_pml; |
| 15 | +extern bool __read_mostly enable_apicv; | |
| 15 | 16 | extern int __read_mostly pt_mode; |
| 16 | 17 | |
| 17 | 18 | #define PT_MODE_SYSTEM 0 |
| @@ -224,7 +224,7 @@ static inline void nested_release_evmcs(struct kvm_vcpu *vcpu) · 223 unmodified lines | ||
| 224 | 224 | return; |
| 225 | 225 | |
| 226 | 226 | kvm_vcpu_unmap(vcpu, &vmx->nested.hv_evmcs_map, true); |
| 227 | − vmx->nested.hv_evmcs_vmptr = -1ull; | |
| 227 | + vmx->nested.hv_evmcs_vmptr = 0; | |
| 228 | 228 | vmx->nested.hv_evmcs = NULL; |
| 229 | 229 | } |
| 230 | 230 | |
| @@ -1923,7 +1923,8 @@ static int nested_vmx_handle_enlightened_vmptrld(struct kvm_vcpu *vcpu, · 1692 unmodified lines | ||
| 1923 | 1923 | if (!nested_enlightened_vmentry(vcpu, &evmcs_gpa)) |
| 1924 | 1924 | return 1; |
| 1925 | 1925 | |
| 1926 | − if (unlikely(evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) { | |
| 1926 | + if (unlikely(!vmx->nested.hv_evmcs || | |
| 1927 | + evmcs_gpa != vmx->nested.hv_evmcs_vmptr)) { | |
| 1927 | 1928 | if (!vmx->nested.hv_evmcs) |
| 1928 | 1929 | vmx->nested.current_vmptr = -1ull; |
| 1929 | 1930 | |
| @@ -3161,10 +3162,10 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu, · 1231 unmodified lines | ||
| 3161 | 3162 | * or KVM_SET_NESTED_STATE). Otherwise it's called from vmlaunch/vmresume. |
| 3162 | 3163 | * |
| 3163 | 3164 | * Returns: |
| 3164 | − * NVMX_ENTRY_SUCCESS: Entered VMX non-root mode | |
| 3165 | − * NVMX_ENTRY_VMFAIL: Consistency check VMFail | |
| 3166 | − * NVMX_ENTRY_VMEXIT: Consistency check VMExit | |
| 3167 | − * NVMX_ENTRY_KVM_INTERNAL_ERROR: KVM internal error | |
| 3165 | + * NVMX_VMENTRY_SUCCESS: Entered VMX non-root mode | |
| 3166 | + * NVMX_VMENTRY_VMFAIL: Consistency check VMFail | |
| 3167 | + * NVMX_VMENTRY_VMEXIT: Consistency check VMExit | |
| 3168 | + * NVMX_VMENTRY_KVM_INTERNAL_ERROR: KVM internal error | |
| 3168 | 3169 | */ |
| 3169 | 3170 | enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, |
| 3170 | 3171 | bool from_vmentry) |
| @@ -3609,8 +3610,15 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr) · 438 unmodified lines | ||
| 3609 | 3610 | unsigned long exit_qual; |
| 3610 | 3611 | bool block_nested_events = |
| 3611 | 3612 | vmx->nested.nested_run_pending || kvm_event_needs_reinjection(vcpu); |
| 3613 | + bool mtf_pending = vmx->nested.mtf_pending; | |
| 3612 | 3614 | struct kvm_lapic *apic = vcpu->arch.apic; |
| 3613 | 3615 | |
| 3616 | + /* | |
| 3617 | + * Clear the MTF state. If a higher priority VM-exit is delivered first, | |
| 3618 | + * this state is discarded. | |
| 3619 | + */ | |
| 3620 | + vmx->nested.mtf_pending = false; | |
| 3621 | + | |
| 3614 | 3622 | if (lapic_in_kernel(vcpu) && |
| 3615 | 3623 | test_bit(KVM_APIC_INIT, &apic->pending_events)) { |
| 3616 | 3624 | if (block_nested_events) |
| @@ -3621,8 +3629,28 @@ static int vmx_check_nested_events(struct kvm_vcpu *vcpu, bool external_intr) · 4 unmodified lines | ||
| 3621 | 3629 | return 0; |
| 3622 | 3630 | } |
| 3623 | 3631 | |
| 3632 | + /* | |
| 3633 | + * Process any exceptions that are not debug traps before MTF. | |
| 3634 | + */ | |
| 3635 | + if (vcpu->arch.exception.pending && | |
| 3636 | + !vmx_pending_dbg_trap(vcpu) && | |
| 3637 | + nested_vmx_check_exception(vcpu, &exit_qual)) { | |
| 3638 | + if (block_nested_events) | |
| 3639 | + return -EBUSY; | |
| 3640 | + nested_vmx_inject_exception_vmexit(vcpu, exit_qual); | |
| 3641 | + return 0; | |
| 3642 | + } | |
| 3643 | + | |
| 3644 | + if (mtf_pending) { | |
| 3645 | + if (block_nested_events) | |
| 3646 | + return -EBUSY; | |
| 3647 | + nested_vmx_update_pending_dbg(vcpu); | |
| 3648 | + nested_vmx_vmexit(vcpu, EXIT_REASON_MONITOR_TRAP_FLAG, 0, 0); | |
| 3649 | + return 0; | |
| 3650 | + } | |
| 3651 | + | |
| 3624 | 3652 | if (vcpu->arch.exception.pending && |
| 3625 | − nested_vmx_check_exception(vcpu, &exit_qual)) { | |
| 3653 | + nested_vmx_check_exception(vcpu, &exit_qual)) { | |
| 3626 | 3654 | if (block_nested_events) |
| 3627 | 3655 | return -EBUSY; |
| 3628 | 3656 | nested_vmx_inject_exception_vmexit(vcpu, exit_qual); |
| @@ -5285,24 +5313,17 @@ fail: · 1656 unmodified lines | ||
| 5285 | 5313 | return 1; |
| 5286 | 5314 | } |
| 5287 | 5315 | |
| 5288 | − | |
| 5289 | −static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, | |
| 5290 | − struct vmcs12 *vmcs12) | |
| 5316 | +/* | |
| 5317 | + * Return true if an IO instruction with the specified port and size should cause | |
| 5318 | + * a VM-exit into L1. | |
| 5319 | + */ | |
| 5320 | +bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port, | |
| 5321 | + int size) | |
| 5291 | 5322 | { |
| 5292 | − unsigned long exit_qualification; | |
| 5323 | + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); | |
| 5293 | 5324 | gpa_t bitmap, last_bitmap; |
| 5294 | − unsigned int port; | |
| 5295 | − int size; | |
| 5296 | 5325 | u8 b; |
| 5297 | 5326 | |
| 5298 | − if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) | |
| 5299 | − return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING); | |
| 5300 | − | |
| 5301 | − exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | |
| 5302 | − | |
| 5303 | − port = exit_qualification >> 16; | |
| 5304 | − size = (exit_qualification & 7) + 1; | |
| 5305 | − | |
| 5306 | 5327 | last_bitmap = (gpa_t)-1; |
| 5307 | 5328 | b = -1; |
| 5308 | 5329 | |
| @@ -5329,8 +5350,26 @@ static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, · 20 unmodified lines | ||
| 5329 | 5350 | return false; |
| 5330 | 5351 | } |
| 5331 | 5352 | |
| 5353 | +static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, | |
| 5354 | + struct vmcs12 *vmcs12) | |
| 5355 | +{ | |
| 5356 | + unsigned long exit_qualification; | |
| 5357 | + unsigned short port; | |
| 5358 | + int size; | |
| 5359 | + | |
| 5360 | + if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) | |
| 5361 | + return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING); | |
| 5362 | + | |
| 5363 | + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | |
| 5364 | + | |
| 5365 | + port = exit_qualification >> 16; | |
| 5366 | + size = (exit_qualification & 7) + 1; | |
| 5367 | + | |
| 5368 | + return nested_vmx_check_io_bitmaps(vcpu, port, size); | |
| 5369 | +} | |
| 5370 | + | |
| 5332 | 5371 | /* |
| 5333 | − * Return 1 if we should exit from L2 to L1 to handle an MSR access access, | |
| 5372 | + * Return 1 if we should exit from L2 to L1 to handle an MSR access, | |
| 5334 | 5373 | * rather than handle it ourselves in L0. I.e., check whether L1 expressed |
| 5335 | 5374 | * disinterest in the current event (read or write a specific MSR) by using an |
| 5336 | 5375 | * MSR bitmap. This may be the case even when L0 doesn't use MSR bitmaps. |
| @@ -5712,6 +5751,9 @@ static int vmx_get_nested_state(struct kvm_vcpu *vcpu, · 375 unmodified lines | ||
| 5712 | 5751 | |
| 5713 | 5752 | if (vmx->nested.nested_run_pending) |
| 5714 | 5753 | kvm_state.flags |= KVM_STATE_NESTED_RUN_PENDING; |
| 5754 | + | |
| 5755 | + if (vmx->nested.mtf_pending) | |
| 5756 | + kvm_state.flags |= KVM_STATE_NESTED_MTF_PENDING; | |
| 5715 | 5757 | } |
| 5716 | 5758 | } |
| 5717 | 5759 | |
| @@ -5892,6 +5934,9 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, · 174 unmodified lines | ||
| 5892 | 5934 | vmx->nested.nested_run_pending = |
| 5893 | 5935 | !!(kvm_state->flags & KVM_STATE_NESTED_RUN_PENDING); |
| 5894 | 5936 | |
| 5937 | + vmx->nested.mtf_pending = | |
| 5938 | + !!(kvm_state->flags & KVM_STATE_NESTED_MTF_PENDING); | |
| 5939 | + | |
| 5895 | 5940 | ret = -EINVAL; |
| 5896 | 5941 | if (nested_cpu_has_shadow_vmcs(vmcs12) && |
| 5897 | 5942 | vmcs12->vmcs_link_pointer != -1ull) { |
| @@ -5949,8 +5994,7 @@ void nested_vmx_set_vmcs_shadowing_bitmap(void) · 51 unmodified lines | ||
| 5949 | 5994 | * bit in the high half is on if the corresponding bit in the control field |
| 5950 | 5995 | * may be on. See also vmx_control_verify(). |
| 5951 | 5996 | */ |
| 5952 | −void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps, | |
| 5953 | − bool apicv) | |
| 5997 | +void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps) | |
| 5954 | 5998 | { |
| 5955 | 5999 | /* |
| 5956 | 6000 | * Note that as a general rule, the high half of the MSRs (bits in |
| @@ -5977,7 +6021,7 @@ void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps, · 20 unmodified lines | ||
| 5977 | 6021 | PIN_BASED_EXT_INTR_MASK | |
| 5978 | 6022 | PIN_BASED_NMI_EXITING | |
| 5979 | 6023 | PIN_BASED_VIRTUAL_NMIS | |
| 5980 | − (apicv ? PIN_BASED_POSTED_INTR : 0); | |
| 6024 | + (enable_apicv ? PIN_BASED_POSTED_INTR : 0); | |
| 5981 | 6025 | msrs->pinbased_ctls_high |= |
| 5982 | 6026 | PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR | |
| 5983 | 6027 | PIN_BASED_VMX_PREEMPTION_TIMER; |
| @@ -17,8 +17,7 @@ enum nvmx_vmentry_status { · 16 unmodified lines | ||
| 17 | 17 | }; |
| 18 | 18 | |
| 19 | 19 | void vmx_leave_nested(struct kvm_vcpu *vcpu); |
| 20 | −void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps, | |
| 21 | − bool apicv); | |
| 20 | +void nested_vmx_setup_ctls_msrs(struct nested_vmx_msrs *msrs, u32 ept_caps); | |
| 22 | 21 | void nested_vmx_hardware_unsetup(void); |
| 23 | 22 | __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *)); |
| 24 | 23 | void nested_vmx_set_vmcs_shadowing_bitmap(void); |
| @@ -34,6 +33,8 @@ int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32 msr_index, u64 *pdata); · 9 unmodified lines | ||
| 34 | 33 | int get_vmx_mem_address(struct kvm_vcpu *vcpu, unsigned long exit_qualification, |
| 35 | 34 | u32 vmx_instruction_info, bool wr, int len, gva_t *ret); |
| 36 | 35 | void nested_vmx_pmu_entry_exit_ctls_update(struct kvm_vcpu *vcpu); |
| 36 | +bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port, | |
| 37 | + int size); | |
| 37 | 38 | |
| 38 | 39 | static inline struct vmcs12 *get_vmcs12(struct kvm_vcpu *vcpu) |
| 39 | 40 | { |
| @@ -175,6 +176,11 @@ static inline bool nested_cpu_has_virtual_nmis(struct vmcs12 *vmcs12) · 135 unmodified lines | ||
| 175 | 176 | return vmcs12->pin_based_vm_exec_control & PIN_BASED_VIRTUAL_NMIS; |
| 176 | 177 | } |
| 177 | 178 | |
| 179 | +static inline int nested_cpu_has_mtf(struct vmcs12 *vmcs12) | |
| 180 | +{ | |
| 181 | + return nested_cpu_has(vmcs12, CPU_BASED_MONITOR_TRAP_FLAG); | |
| 182 | +} | |
| 183 | + | |
| 178 | 184 | static inline int nested_cpu_has_ept(struct vmcs12 *vmcs12) |
| 179 | 185 | { |
| 180 | 186 | return nested_cpu_has2(vmcs12, SECONDARY_EXEC_ENABLE_EPT); |
| @@ -64,11 +64,13 @@ · 63 unmodified lines | ||
| 64 | 64 | MODULE_AUTHOR("Qumranet"); |
| 65 | 65 | MODULE_LICENSE("GPL"); |
| 66 | 66 | |
| 67 | +#ifdef MODULE | |
| 67 | 68 | static const struct x86_cpu_id vmx_cpu_id[] = { |
| 68 | 69 | X86_FEATURE_MATCH(X86_FEATURE_VMX), |
| 69 | 70 | {} |
| 70 | 71 | }; |
| 71 | 72 | MODULE_DEVICE_TABLE(x86cpu, vmx_cpu_id); |
| 73 | +#endif | |
| 72 | 74 | |
| 73 | 75 | bool __read_mostly enable_vpid = 1; |
| 74 | 76 | module_param_named(vpid, enable_vpid, bool, 0444); |
| @@ -95,7 +97,7 @@ module_param(emulate_invalid_guest_state, bool, S_IRUGO); · 20 unmodified lines | ||
| 95 | 97 | static bool __read_mostly fasteoi = 1; |
| 96 | 98 | module_param(fasteoi, bool, S_IRUGO); |
| 97 | 99 | |
| 98 | −static bool __read_mostly enable_apicv = 1; | |
| 100 | +bool __read_mostly enable_apicv = 1; | |
| 99 | 101 | module_param(enable_apicv, bool, S_IRUGO); |
| 100 | 102 | |
| 101 | 103 | /* |
| @@ -1175,6 +1177,10 @@ void vmx_prepare_switch_to_guest(struct kvm_vcpu *vcpu) · 1073 unmodified lines | ||
| 1175 | 1177 | vmx->guest_msrs[i].mask); |
| 1176 | 1178 | |
| 1177 | 1179 | } |
| 1180 | + | |
| 1181 | + if (vmx->nested.need_vmcs12_to_shadow_sync) | |
| 1182 | + nested_sync_vmcs12_to_shadow(vcpu); | |
| 1183 | + | |
| 1178 | 1184 | if (vmx->guest_state_loaded) |
| 1179 | 1185 | return; |
| 1180 | 1186 | |
| @@ -1599,6 +1605,40 @@ static int skip_emulated_instruction(struct kvm_vcpu *vcpu) · 418 unmodified lines | ||
| 1599 | 1605 | return 1; |
| 1600 | 1606 | } |
| 1601 | 1607 | |
| 1608 | + | |
| 1609 | +/* | |
| 1610 | + * Recognizes a pending MTF VM-exit and records the nested state for later | |
| 1611 | + * delivery. | |
| 1612 | + */ | |
| 1613 | +static void vmx_update_emulated_instruction(struct kvm_vcpu *vcpu) | |
| 1614 | +{ | |
| 1615 | + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); | |
| 1616 | + struct vcpu_vmx *vmx = to_vmx(vcpu); | |
| 1617 | + | |
| 1618 | + if (!is_guest_mode(vcpu)) | |
| 1619 | + return; | |
| 1620 | + | |
| 1621 | + /* | |
| 1622 | + * Per the SDM, MTF takes priority over debug-trap exceptions besides | |
| 1623 | + * T-bit traps. As instruction emulation is completed (i.e. at the | |
| 1624 | + * instruction boundary), any #DB exception pending delivery must be a | |
| 1625 | + * debug-trap. Record the pending MTF state to be delivered in | |
| 1626 | + * vmx_check_nested_events(). | |
| 1627 | + */ | |
| 1628 | + if (nested_cpu_has_mtf(vmcs12) && | |
| 1629 | + (!vcpu->arch.exception.pending || | |
| 1630 | + vcpu->arch.exception.nr == DB_VECTOR)) | |
| 1631 | + vmx->nested.mtf_pending = true; | |
| 1632 | + else | |
| 1633 | + vmx->nested.mtf_pending = false; | |
| 1634 | +} | |
| 1635 | + | |
| 1636 | +static int vmx_skip_emulated_instruction(struct kvm_vcpu *vcpu) | |
| 1637 | +{ | |
| 1638 | + vmx_update_emulated_instruction(vcpu); | |
| 1639 | + return skip_emulated_instruction(vcpu); | |
| 1640 | +} | |
| 1641 | + | |
| 1602 | 1642 | static void vmx_clear_hlt(struct kvm_vcpu *vcpu) |
| 1603 | 1643 | { |
| 1604 | 1644 | /* |
| @@ -2298,6 +2338,17 @@ static void hardware_disable(void) · 693 unmodified lines | ||
| 2298 | 2338 | kvm_cpu_vmxoff(); |
| 2299 | 2339 | } |
| 2300 | 2340 | |
| 2341 | +/* | |
| 2342 | + * There is no X86_FEATURE for SGX yet, but anyway we need to query CPUID | |
| 2343 | + * directly instead of going through cpu_has(), to ensure KVM is trapping | |
| 2344 | + * ENCLS whenever it's supported in hardware. It does not matter whether | |
| 2345 | + * the host OS supports or has enabled SGX. | |
| 2346 | + */ | |
| 2347 | +static bool cpu_has_sgx(void) | |
| 2348 | +{ | |
| 2349 | + return cpuid_eax(0) >= 0x12 && (cpuid_eax(0x12) & BIT(0)); | |
| 2350 | +} | |
| 2351 | + | |
| 2301 | 2352 | static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, |
| 2302 | 2353 | u32 msr, u32 *result) |
| 2303 | 2354 | { |
| @@ -2378,8 +2429,9 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf, · 74 unmodified lines | ||
| 2378 | 2429 | SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE | |
| 2379 | 2430 | SECONDARY_EXEC_PT_USE_GPA | |
| 2380 | 2431 | SECONDARY_EXEC_PT_CONCEAL_VMX | |
| 2381 | − SECONDARY_EXEC_ENABLE_VMFUNC | | |
| 2382 | − SECONDARY_EXEC_ENCLS_EXITING; | |
| 2432 | + SECONDARY_EXEC_ENABLE_VMFUNC; | |
| 2433 | + if (cpu_has_sgx()) | |
| 2434 | + opt2 |= SECONDARY_EXEC_ENCLS_EXITING; | |
| 2383 | 2435 | if (adjust_vmx_controls(min2, opt2, |
| 2384 | 2436 | MSR_IA32_VMX_PROCBASED_CTLS2, |
| 2385 | 2437 | &_cpu_based_2nd_exec_control) < 0) |
| @@ -3818,24 +3870,29 @@ static int vmx_deliver_nested_posted_interrupt(struct kvm_vcpu *vcpu, · 1432 unmodified lines | ||
| 3818 | 3870 | * 2. If target vcpu isn't running(root mode), kick it to pick up the |
| 3819 | 3871 | * interrupt from PIR in next vmentry. |
| 3820 | 3872 | */ |
| 3821 | −static void vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector) | |
| 3873 | +static int vmx_deliver_posted_interrupt(struct kvm_vcpu *vcpu, int vector) | |
| 3822 | 3874 | { |
| 3823 | 3875 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
| 3824 | 3876 | int r; |
| 3825 | 3877 | |
| 3826 | 3878 | r = vmx_deliver_nested_posted_interrupt(vcpu, vector); |
| 3827 | 3879 | if (!r) |
| 3828 | − return; | |
| 3880 | + return 0; | |
| 3881 | + | |
| 3882 | + if (!vcpu->arch.apicv_active) | |
| 3883 | + return -1; | |
| 3829 | 3884 | |
| 3830 | 3885 | if (pi_test_and_set_pir(vector, &vmx->pi_desc)) |
| 3831 | − return; | |
| 3886 | + return 0; | |
| 3832 | 3887 | |
| 3833 | 3888 | /* If a previous notification has sent the IPI, nothing to do. */ |
| 3834 | 3889 | if (pi_test_and_set_on(&vmx->pi_desc)) |
| 3835 | − return; | |
| 3890 | + return 0; | |
| 3836 | 3891 | |
| 3837 | 3892 | if (!kvm_vcpu_trigger_posted_interrupt(vcpu, false)) |
| 3838 | 3893 | kvm_vcpu_kick(vcpu); |
| 3894 | + | |
| 3895 | + return 0; | |
| 3839 | 3896 | } |
| 3840 | 3897 | |
| 3841 | 3898 | /* |
| @@ -6482,8 +6539,11 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) · 2640 unmodified lines | ||
| 6482 | 6539 | vmcs_write32(PLE_WINDOW, vmx->ple_window); |
| 6483 | 6540 | } |
| 6484 | 6541 | |
| 6485 | − if (vmx->nested.need_vmcs12_to_shadow_sync) | |
| 6486 | − nested_sync_vmcs12_to_shadow(vcpu); | |
| 6542 | + /* | |
| 6543 | + * We did this in prepare_switch_to_guest, because it needs to | |
| 6544 | + * be within srcu_read_lock. | |
| 6545 | + */ | |
| 6546 | + WARN_ON_ONCE(vmx->nested.need_vmcs12_to_shadow_sync); | |
| 6487 | 6547 | |
| 6488 | 6548 | if (kvm_register_is_dirty(vcpu, VCPU_REGS_RSP)) |
| 6489 | 6549 | vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]); |
| @@ -6757,8 +6817,7 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) · 267 unmodified lines | ||
| 6757 | 6817 | |
| 6758 | 6818 | if (nested) |
| 6759 | 6819 | nested_vmx_setup_ctls_msrs(&vmx->nested.msrs, |
| 6760 | − vmx_capability.ept, | |
| 6761 | − kvm_vcpu_apicv_active(vcpu)); | |
| 6820 | + vmx_capability.ept); | |
| 6762 | 6821 | else |
| 6763 | 6822 | memset(&vmx->nested.msrs, 0, sizeof(vmx->nested.msrs)); |
| 6764 | 6823 | |
| @@ -6839,8 +6898,7 @@ static int __init vmx_check_processor_compat(void) · 74 unmodified lines | ||
| 6839 | 6898 | if (setup_vmcs_config(&vmcs_conf, &vmx_cap) < 0) |
| 6840 | 6899 | return -EIO; |
| 6841 | 6900 | if (nested) |
| 6842 | − nested_vmx_setup_ctls_msrs(&vmcs_conf.nested, vmx_cap.ept, | |
| 6843 | − enable_apicv); | |
| 6901 | + nested_vmx_setup_ctls_msrs(&vmcs_conf.nested, vmx_cap.ept); | |
| 6844 | 6902 | if (memcmp(&vmcs_config, &vmcs_conf, sizeof(struct vmcs_config)) != 0) { |
| 6845 | 6903 | printk(KERN_ERR "kvm: CPU %d feature inconsistency!\n", |
| 6846 | 6904 | smp_processor_id()); |
| @@ -7101,6 +7159,40 @@ static void vmx_request_immediate_exit(struct kvm_vcpu *vcpu) · 254 unmodified lines | ||
| 7101 | 7159 | to_vmx(vcpu)->req_immediate_exit = true; |
| 7102 | 7160 | } |
| 7103 | 7161 | |
| 7162 | +static int vmx_check_intercept_io(struct kvm_vcpu *vcpu, | |
| 7163 | + struct x86_instruction_info *info) | |
| 7164 | +{ | |
| 7165 | + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); | |
| 7166 | + unsigned short port; | |
| 7167 | + bool intercept; | |
| 7168 | + int size; | |
| 7169 | + | |
| 7170 | + if (info->intercept == x86_intercept_in || | |
| 7171 | + info->intercept == x86_intercept_ins) { | |
| 7172 | + port = info->src_val; | |
| 7173 | + size = info->dst_bytes; | |
| 7174 | + } else { | |
| 7175 | + port = info->dst_val; | |
| 7176 | + size = info->src_bytes; | |
| 7177 | + } | |
| 7178 | + | |
| 7179 | + /* | |
| 7180 | + * If the 'use IO bitmaps' VM-execution control is 0, IO instruction | |
| 7181 | + * VM-exits depend on the 'unconditional IO exiting' VM-execution | |
| 7182 | + * control. | |
| 7183 | + * | |
| 7184 | + * Otherwise, IO instruction VM-exits are controlled by the IO bitmaps. | |
| 7185 | + */ | |
| 7186 | + if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) | |
| 7187 | + intercept = nested_cpu_has(vmcs12, | |
| 7188 | + CPU_BASED_UNCOND_IO_EXITING); | |
| 7189 | + else | |
| 7190 | + intercept = nested_vmx_check_io_bitmaps(vcpu, port, size); | |
| 7191 | + | |
| 7192 | + /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */ | |
| 7193 | + return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE; | |
| 7194 | +} | |
| 7195 | + | |
| 7104 | 7196 | static int vmx_check_intercept(struct kvm_vcpu *vcpu, |
| 7105 | 7197 | struct x86_instruction_info *info, |
| 7106 | 7198 | enum x86_intercept_stage stage) |
| @@ -7108,19 +7200,45 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, · 1 unmodified line | ||
| 7108 | 7200 | struct vmcs12 *vmcs12 = get_vmcs12(vcpu); |
| 7109 | 7201 | struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt; |
| 7110 | 7202 | |
| 7203 | + switch (info->intercept) { | |
| 7111 | 7204 | /* |
| 7112 | 7205 | * RDPID causes #UD if disabled through secondary execution controls. |
| 7113 | 7206 | * Because it is marked as EmulateOnUD, we need to intercept it here. |
| 7114 | 7207 | */ |
| 7115 | − if (info->intercept == x86_intercept_rdtscp && | |
| 7116 | − !nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) { | |
| 7117 | − ctxt->exception.vector = UD_VECTOR; | |
| 7118 | − ctxt->exception.error_code_valid = false; | |
| 7119 | − return X86EMUL_PROPAGATE_FAULT; | |
| 7120 | − } | |
| 7208 | + case x86_intercept_rdtscp: | |
| 7209 | + if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) { | |
| 7210 | + ctxt->exception.vector = UD_VECTOR; | |
| 7211 | + ctxt->exception.error_code_valid = false; | |
| 7212 | + return X86EMUL_PROPAGATE_FAULT; | |
| 7213 | + } | |
| 7214 | + break; | |
| 7215 | + | |
| 7216 | + case x86_intercept_in: | |
| 7217 | + case x86_intercept_ins: | |
| 7218 | + case x86_intercept_out: | |
| 7219 | + case x86_intercept_outs: | |
| 7220 | + return vmx_check_intercept_io(vcpu, info); | |
| 7221 | + | |
| 7222 | + case x86_intercept_lgdt: | |
| 7223 | + case x86_intercept_lidt: | |
| 7224 | + case x86_intercept_lldt: | |
| 7225 | + case x86_intercept_ltr: | |
| 7226 | + case x86_intercept_sgdt: | |
| 7227 | + case x86_intercept_sidt: | |
| 7228 | + case x86_intercept_sldt: | |
| 7229 | + case x86_intercept_str: | |
| 7230 | + if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_DESC)) | |
| 7231 | + return X86EMUL_CONTINUE; | |
| 7232 | + | |
| 7233 | + /* FIXME: produce nested vmexit and return X86EMUL_INTERCEPTED. */ | |
| 7234 | + break; | |
| 7121 | 7235 | |
| 7122 | 7236 | /* TODO: check more intercepts... */ |
| 7123 | − return X86EMUL_CONTINUE; | |
| 7237 | + default: | |
| 7238 | + break; | |
| 7239 | + } | |
| 7240 | + | |
| 7241 | + return X86EMUL_UNHANDLEABLE; | |
| 7124 | 7242 | } |
| 7125 | 7243 | |
| 7126 | 7244 | #ifdef CONFIG_X86_64 |
| @@ -7702,7 +7820,7 @@ static __init int hardware_setup(void) · 575 unmodified lines | ||
| 7702 | 7820 | |
| 7703 | 7821 | if (nested) { |
| 7704 | 7822 | nested_vmx_setup_ctls_msrs(&vmcs_config.nested, |
| 7705 | − vmx_capability.ept, enable_apicv); | |
| 7823 | + vmx_capability.ept); | |
| 7706 | 7824 | |
| 7707 | 7825 | r = nested_vmx_hardware_setup(kvm_vmx_exit_handlers); |
| 7708 | 7826 | if (r) |
| @@ -7786,7 +7904,8 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = { · 77 unmodified lines | ||
| 7786 | 7904 | |
| 7787 | 7905 | .run = vmx_vcpu_run, |
| 7788 | 7906 | .handle_exit = vmx_handle_exit, |
| 7789 | − .skip_emulated_instruction = skip_emulated_instruction, | |
| 7907 | + .skip_emulated_instruction = vmx_skip_emulated_instruction, | |
| 7908 | + .update_emulated_instruction = vmx_update_emulated_instruction, | |
| 7790 | 7909 | .set_interrupt_shadow = vmx_set_interrupt_shadow, |
| 7791 | 7910 | .get_interrupt_shadow = vmx_get_interrupt_shadow, |
| 7792 | 7911 | .patch_hypercall = vmx_patch_hypercall, |
| @@ -150,6 +150,9 @@ struct nested_vmx { · 149 unmodified lines | ||
| 150 | 150 | /* L2 must run next, and mustn't decide to exit to L1. */ |
| 151 | 151 | bool nested_run_pending; |
| 152 | 152 | |
| 153 | + /* Pending MTF VM-exit into L1. */ | |
| 154 | + bool mtf_pending; | |
| 155 | + | |
| 153 | 156 | struct loaded_vmcs vmcs02; |
| 154 | 157 | |
| 155 | 158 | /* |
| @@ -6891,6 +6891,8 @@ restart: · 6890 unmodified lines | ||
| 6891 | 6891 | kvm_rip_write(vcpu, ctxt->eip); |
| 6892 | 6892 | if (r && ctxt->tf) |
| 6893 | 6893 | r = kvm_vcpu_do_singlestep(vcpu); |
| 6894 | + if (kvm_x86_ops->update_emulated_instruction) | |
| 6895 | + kvm_x86_ops->update_emulated_instruction(vcpu); | |
| 6894 | 6896 | __kvm_set_rflags(vcpu, ctxt->eflags); |
| 6895 | 6897 | } |
| 6896 | 6898 | |
| @@ -7188,14 +7190,16 @@ static void kvm_timer_init(void) · 291 unmodified lines | ||
| 7188 | 7190 | |
| 7189 | 7191 | if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) { |
| 7190 | 7192 | #ifdef CONFIG_CPU_FREQ |
| 7191 | − struct cpufreq_policy policy; | |
| 7193 | + struct cpufreq_policy *policy; | |
| 7192 | 7194 | int cpu; |
| 7193 | 7195 | |
| 7194 | − memset(&policy, 0, sizeof(policy)); | |
| 7195 | 7196 | cpu = get_cpu(); |
| 7196 | − cpufreq_get_policy(&policy, cpu); | |
| 7197 | − if (policy.cpuinfo.max_freq) | |
| 7198 | − max_tsc_khz = policy.cpuinfo.max_freq; | |
| 7197 | + policy = cpufreq_cpu_get(cpu); | |
| 7198 | + if (policy) { | |
| 7199 | + if (policy->cpuinfo.max_freq) | |
| 7200 | + max_tsc_khz = policy->cpuinfo.max_freq; | |
| 7201 | + cpufreq_cpu_put(policy); | |
| 7202 | + } | |
| 7199 | 7203 | put_cpu(); |
| 7200 | 7204 | #endif |
| 7201 | 7205 | cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, |
| @@ -7306,12 +7310,12 @@ int kvm_arch_init(void *opaque) · 104 unmodified lines | ||
| 7306 | 7310 | } |
| 7307 | 7311 | |
| 7308 | 7312 | if (!ops->cpu_has_kvm_support()) { |
| 7309 | − printk(KERN_ERR "kvm: no hardware support\n"); | |
| 7313 | + pr_err_ratelimited("kvm: no hardware support\n"); | |
| 7310 | 7314 | r = -EOPNOTSUPP; |
| 7311 | 7315 | goto out; |
| 7312 | 7316 | } |
| 7313 | 7317 | if (ops->disabled_by_bios()) { |
| 7314 | − printk(KERN_ERR "kvm: disabled by bios\n"); | |
| 7318 | + pr_err_ratelimited("kvm: disabled by bios\n"); | |
| 7315 | 7319 | r = -EOPNOTSUPP; |
| 7316 | 7320 | goto out; |
| 7317 | 7321 | } |
| @@ -363,13 +363,8 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, · 362 unmodified lines | ||
| 363 | 363 | { |
| 364 | 364 | const struct ptdump_range ptdump_ranges[] = { |
| 365 | 365 | #ifdef CONFIG_X86_64 |
| 366 | − | |
| 367 | −#define normalize_addr_shift (64 - (__VIRTUAL_MASK_SHIFT + 1)) | |
| 368 | −#define normalize_addr(u) ((signed long)((u) << normalize_addr_shift) >> \ | |
| 369 | − normalize_addr_shift) | |
| 370 | − | |
| 371 | 366 | {0, PTRS_PER_PGD * PGD_LEVEL_MULT / 2}, |
| 372 | − {normalize_addr(PTRS_PER_PGD * PGD_LEVEL_MULT / 2), ~0UL}, | |
| 367 | + {GUARD_HOLE_END_ADDR, ~0UL}, | |
| 373 | 368 | #else |
| 374 | 369 | {0, ~0UL}, |
| 375 | 370 | #endif |
| @@ -106,6 +106,19 @@ static unsigned int __ioremap_check_encrypted(struct resource *res) · 105 unmodified lines | ||
| 106 | 106 | return 0; |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | +/* | |
| 110 | + * The EFI runtime services data area is not covered by walk_mem_res(), but must | |
| 111 | + * be mapped encrypted when SEV is active. | |
| 112 | + */ | |
| 113 | +static void __ioremap_check_other(resource_size_t addr, struct ioremap_desc *desc) | |
| 114 | +{ | |
| 115 | + if (!sev_active()) | |
| 116 | + return; | |
| 117 | + | |
| 118 | + if (efi_mem_type(addr) == EFI_RUNTIME_SERVICES_DATA) | |
| 119 | + desc->flags |= IORES_MAP_ENCRYPTED; | |
| 120 | +} | |
| 121 | + | |
| 109 | 122 | static int __ioremap_collect_map_flags(struct resource *res, void *arg) |
| 110 | 123 | { |
| 111 | 124 | struct ioremap_desc *desc = arg; |
| @@ -124,6 +137,9 @@ static int __ioremap_collect_map_flags(struct resource *res, void *arg) · 12 unmodified lines | ||
| 124 | 137 | * To avoid multiple resource walks, this function walks resources marked as |
| 125 | 138 | * IORESOURCE_MEM and IORESOURCE_BUSY and looking for system RAM and/or a |
| 126 | 139 | * resource described not as IORES_DESC_NONE (e.g. IORES_DESC_ACPI_TABLES). |
| 140 | + * | |
| 141 | + * After that, deal with misc other ranges in __ioremap_check_other() which do | |
| 142 | + * not fall into the above category. | |
| 127 | 143 | */ |
| 128 | 144 | static void __ioremap_check_mem(resource_size_t addr, unsigned long size, |
| 129 | 145 | struct ioremap_desc *desc) |
| @@ -135,6 +151,8 @@ static void __ioremap_check_mem(resource_size_t addr, unsigned long size, · 5 unmodified lines | ||
| 135 | 151 | memset(desc, 0, sizeof(struct ioremap_desc)); |
| 136 | 152 | |
| 137 | 153 | walk_mem_res(start, end, desc, __ioremap_collect_map_flags); |
| 154 | + | |
| 155 | + __ioremap_check_other(addr, desc); | |
| 138 | 156 | } |
| 139 | 157 | |
| 140 | 158 | /* |
| @@ -180,7 +180,7 @@ void efi_sync_low_kernel_mappings(void) · 179 unmodified lines | ||
| 180 | 180 | static inline phys_addr_t |
| 181 | 181 | virt_to_phys_or_null_size(void *va, unsigned long size) |
| 182 | 182 | { |
| 183 | − bool bad_size; | |
| 183 | + phys_addr_t pa; | |
| 184 | 184 | |
| 185 | 185 | if (!va) |
| 186 | 186 | return 0; |
| @@ -188,16 +188,13 @@ virt_to_phys_or_null_size(void *va, unsigned long size) · 1 unmodified line | ||
| 188 | 188 | if (virt_addr_valid(va)) |
| 189 | 189 | return virt_to_phys(va); |
| 190 | 190 | |
| 191 | − /* | |
| 192 | − * A fully aligned variable on the stack is guaranteed not to | |
| 193 | − * cross a page bounary. Try to catch strings on the stack by | |
| 194 | − * checking that 'size' is a power of two. | |
| 195 | − */ | |
| 196 | − bad_size = size > PAGE_SIZE || !is_power_of_2(size); | |
| 191 | + pa = slow_virt_to_phys(va); | |
| 197 | 192 | |
| 198 | − WARN_ON(!IS_ALIGNED((unsigned long)va, size) || bad_size); | |
| 193 | + /* check if the object crosses a page boundary */ | |
| 194 | + if (WARN_ON((pa ^ (pa + size - 1)) & PAGE_MASK)) | |
| 195 | + return 0; | |
| 199 | 196 | |
| 200 | − return slow_virt_to_phys(va); | |
| 197 | + return pa; | |
| 201 | 198 | } |
| 202 | 199 | |
| 203 | 200 | #define virt_to_phys_or_null(addr) \ |
| @@ -568,85 +565,25 @@ efi_thunk_set_virtual_address_map(unsigned long memory_map_size, · 364 unmodified lines | ||
| 568 | 565 | |
| 569 | 566 | static efi_status_t efi_thunk_get_time(efi_time_t *tm, efi_time_cap_t *tc) |
| 570 | 567 | { |
| 571 | − efi_status_t status; | |
| 572 | − u32 phys_tm, phys_tc; | |
| 573 | − unsigned long flags; | |
| 574 | − | |
| 575 | − spin_lock(&rtc_lock); | |
| 576 | − spin_lock_irqsave(&efi_runtime_lock, flags); | |
| 577 | − | |
| 578 | − phys_tm = virt_to_phys_or_null(tm); | |
| 579 | − phys_tc = virt_to_phys_or_null(tc); | |
| 580 | − | |
| 581 | − status = efi_thunk(get_time, phys_tm, phys_tc); | |
| 582 | − | |
| 583 | − spin_unlock_irqrestore(&efi_runtime_lock, flags); | |
| 584 | − spin_unlock(&rtc_lock); | |
| 585 | − | |
| 586 | − return status; | |
| 568 | + return EFI_UNSUPPORTED; | |
| 587 | 569 | } |
| 588 | 570 | |
| 589 | 571 | static efi_status_t efi_thunk_set_time(efi_time_t *tm) |
| 590 | 572 | { |
| 591 | − efi_status_t status; | |
| 592 | − u32 phys_tm; | |
| 593 | − unsigned long flags; | |
| 594 | − | |
| 595 | − spin_lock(&rtc_lock); | |
| 596 | − spin_lock_irqsave(&efi_runtime_lock, flags); | |
| 597 | − | |
| 598 | − phys_tm = virt_to_phys_or_null(tm); | |
| 599 | − | |
| 600 | − status = efi_thunk(set_time, phys_tm); | |
| 601 | − | |
| 602 | − spin_unlock_irqrestore(&efi_runtime_lock, flags); | |
| 603 | − spin_unlock(&rtc_lock); | |
| 604 | − | |
| 605 | − return status; | |
| 573 | + return EFI_UNSUPPORTED; | |
| 606 | 574 | } |
| 607 | 575 | |
| 608 | 576 | static efi_status_t |
| 609 | 577 | efi_thunk_get_wakeup_time(efi_bool_t *enabled, efi_bool_t *pending, |
| 610 | 578 | efi_time_t *tm) |
| 611 | 579 | { |
| 612 | − efi_status_t status; | |
| 613 | − u32 phys_enabled, phys_pending, phys_tm; | |
| 614 | − unsigned long flags; | |
| 615 | − | |
| 616 | − spin_lock(&rtc_lock); | |
| 617 | − spin_lock_irqsave(&efi_runtime_lock, flags); | |
| 618 | − | |
| 619 | − phys_enabled = virt_to_phys_or_null(enabled); | |
| 620 | − phys_pending = virt_to_phys_or_null(pending); | |
| 621 | − phys_tm = virt_to_phys_or_null(tm); | |
| 622 | − | |
| 623 | − status = efi_thunk(get_wakeup_time, phys_enabled, | |
| 624 | − phys_pending, phys_tm); | |
| 625 | − | |
| 626 | − spin_unlock_irqrestore(&efi_runtime_lock, flags); | |
| 627 | − spin_unlock(&rtc_lock); | |
| 628 | − | |
| 629 | − return status; | |
| 580 | + return EFI_UNSUPPORTED; | |
| 630 | 581 | } |
| 631 | 582 | |
| 632 | 583 | static efi_status_t |
| 633 | 584 | efi_thunk_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) |
| 634 | 585 | { |
| 635 | − efi_status_t status; | |
| 636 | − u32 phys_tm; | |
| 637 | − unsigned long flags; | |
| 638 | − | |
| 639 | − spin_lock(&rtc_lock); | |
| 640 | − spin_lock_irqsave(&efi_runtime_lock, flags); | |
| 641 | − | |
| 642 | − phys_tm = virt_to_phys_or_null(tm); | |
| 643 | − | |
| 644 | − status = efi_thunk(set_wakeup_time, enabled, phys_tm); | |
| 645 | − | |
| 646 | − spin_unlock_irqrestore(&efi_runtime_lock, flags); | |
| 647 | − spin_unlock(&rtc_lock); | |
| 648 | − | |
| 649 | − return status; | |
| 586 | + return EFI_UNSUPPORTED; | |
| 650 | 587 | } |
| 651 | 588 | |
| 652 | 589 | static unsigned long efi_name_size(efi_char16_t *name) |
| @@ -658,6 +595,8 @@ static efi_status_t · 5 unmodified lines | ||
| 658 | 595 | efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor, |
| 659 | 596 | u32 *attr, unsigned long *data_size, void *data) |
| 660 | 597 | { |
| 598 | + u8 buf[24] __aligned(8); | |
| 599 | + efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); | |
| 661 | 600 | efi_status_t status; |
| 662 | 601 | u32 phys_name, phys_vendor, phys_attr; |
| 663 | 602 | u32 phys_data_size, phys_data; |
| @@ -665,14 +604,19 @@ efi_thunk_get_variable(efi_char16_t *name, efi_guid_t *vendor, · 1 unmodified line | ||
| 665 | 604 | |
| 666 | 605 | spin_lock_irqsave(&efi_runtime_lock, flags); |
| 667 | 606 | |
| 607 | + *vnd = *vendor; | |
| 608 | + | |
| 668 | 609 | phys_data_size = virt_to_phys_or_null(data_size); |
| 669 | − phys_vendor = virt_to_phys_or_null(vendor); | |
| 610 | + phys_vendor = virt_to_phys_or_null(vnd); | |
| 670 | 611 | phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); |
| 671 | 612 | phys_attr = virt_to_phys_or_null(attr); |
| 672 | 613 | phys_data = virt_to_phys_or_null_size(data, *data_size); |
| 673 | 614 | |
| 674 | − status = efi_thunk(get_variable, phys_name, phys_vendor, | |
| 675 | − phys_attr, phys_data_size, phys_data); | |
| 615 | + if (!phys_name || (data && !phys_data)) | |
| 616 | + status = EFI_INVALID_PARAMETER; | |
| 617 | + else | |
| 618 | + status = efi_thunk(get_variable, phys_name, phys_vendor, | |
| 619 | + phys_attr, phys_data_size, phys_data); | |
| 676 | 620 | |
| 677 | 621 | spin_unlock_irqrestore(&efi_runtime_lock, flags); |
| 678 | 622 | |
| @@ -683,19 +627,25 @@ static efi_status_t · 4 unmodified lines | ||
| 683 | 627 | efi_thunk_set_variable(efi_char16_t *name, efi_guid_t *vendor, |
| 684 | 628 | u32 attr, unsigned long data_size, void *data) |
| 685 | 629 | { |
| 630 | + u8 buf[24] __aligned(8); | |
| 631 | + efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); | |
| 686 | 632 | u32 phys_name, phys_vendor, phys_data; |
| 687 | 633 | efi_status_t status; |
| 688 | 634 | unsigned long flags; |
| 689 | 635 | |
| 690 | 636 | spin_lock_irqsave(&efi_runtime_lock, flags); |
| 691 | 637 | |
| 638 | + *vnd = *vendor; | |
| 639 | + | |
| 692 | 640 | phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); |
| 693 | − phys_vendor = virt_to_phys_or_null(vendor); | |
| 641 | + phys_vendor = virt_to_phys_or_null(vnd); | |
| 694 | 642 | phys_data = virt_to_phys_or_null_size(data, data_size); |
| 695 | 643 | |
| 696 | − /* If data_size is > sizeof(u32) we've got problems */ | |
| 697 | − status = efi_thunk(set_variable, phys_name, phys_vendor, | |
| 698 | − attr, data_size, phys_data); | |
| 644 | + if (!phys_name || !phys_data) | |
| 645 | + status = EFI_INVALID_PARAMETER; | |
| 646 | + else | |
| 647 | + status = efi_thunk(set_variable, phys_name, phys_vendor, | |
| 648 | + attr, data_size, phys_data); | |
| 699 | 649 | |
| 700 | 650 | spin_unlock_irqrestore(&efi_runtime_lock, flags); |
| 701 | 651 | |
| @@ -707,6 +657,8 @@ efi_thunk_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, · 5 unmodified lines | ||
| 707 | 657 | u32 attr, unsigned long data_size, |
| 708 | 658 | void *data) |
| 709 | 659 | { |
| 660 | + u8 buf[24] __aligned(8); | |
| 661 | + efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); | |
| 710 | 662 | u32 phys_name, phys_vendor, phys_data; |
| 711 | 663 | efi_status_t status; |
| 712 | 664 | unsigned long flags; |
| @@ -714,13 +666,17 @@ efi_thunk_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, · 1 unmodified line | ||
| 714 | 666 | if (!spin_trylock_irqsave(&efi_runtime_lock, flags)) |
| 715 | 667 | return EFI_NOT_READY; |
| 716 | 668 | |
| 669 | + *vnd = *vendor; | |
| 670 | + | |
| 717 | 671 | phys_name = virt_to_phys_or_null_size(name, efi_name_size(name)); |
| 718 | − phys_vendor = virt_to_phys_or_null(vendor); | |
| 672 | + phys_vendor = virt_to_phys_or_null(vnd); | |
| 719 | 673 | phys_data = virt_to_phys_or_null_size(data, data_size); |
| 720 | 674 | |
| 721 | − /* If data_size is > sizeof(u32) we've got problems */ | |
| 722 | − status = efi_thunk(set_variable, phys_name, phys_vendor, | |
| 723 | − attr, data_size, phys_data); | |
| 675 | + if (!phys_name || !phys_data) | |
| 676 | + status = EFI_INVALID_PARAMETER; | |
| 677 | + else | |
| 678 | + status = efi_thunk(set_variable, phys_name, phys_vendor, | |
| 679 | + attr, data_size, phys_data); | |
| 724 | 680 | |
| 725 | 681 | spin_unlock_irqrestore(&efi_runtime_lock, flags); |
| 726 | 682 | |
| @@ -732,39 +688,36 @@ efi_thunk_get_next_variable(unsigned long *name_size, · 5 unmodified lines | ||
| 732 | 688 | efi_char16_t *name, |
| 733 | 689 | efi_guid_t *vendor) |
| 734 | 690 | { |
| 691 | + u8 buf[24] __aligned(8); | |
| 692 | + efi_guid_t *vnd = PTR_ALIGN((efi_guid_t *)buf, sizeof(*vnd)); | |
| 735 | 693 | efi_status_t status; |
| 736 | 694 | u32 phys_name_size, phys_name, phys_vendor; |
| 737 | 695 | unsigned long flags; |
| 738 | 696 | |
| 739 | 697 | spin_lock_irqsave(&efi_runtime_lock, flags); |
| 740 | 698 | |
| 699 | + *vnd = *vendor; | |
| 700 | + | |
| 741 | 701 | phys_name_size = virt_to_phys_or_null(name_size); |
| 742 | − phys_vendor = virt_to_phys_or_null(vendor); | |
| 702 | + phys_vendor = virt_to_phys_or_null(vnd); | |
| 743 | 703 | phys_name = virt_to_phys_or_null_size(name, *name_size); |
| 744 | 704 | |
| 745 | − status = efi_thunk(get_next_variable, phys_name_size, | |
| 746 | − phys_name, phys_vendor); | |
| 705 | + if (!phys_name) | |
| 706 | + status = EFI_INVALID_PARAMETER; | |
| 707 | + else | |
| 708 | + status = efi_thunk(get_next_variable, phys_name_size, | |
| 709 | + phys_name, phys_vendor); | |
| 747 | 710 | |
| 748 | 711 | spin_unlock_irqrestore(&efi_runtime_lock, flags); |
| 749 | 712 | |
| 713 | + *vendor = *vnd; | |
| 750 | 714 | return status; |
| 751 | 715 | } |
| 752 | 716 | |
| 753 | 717 | static efi_status_t |
| 754 | 718 | efi_thunk_get_next_high_mono_count(u32 *count) |
| 755 | 719 | { |
| 756 | − efi_status_t status; | |
| 757 | − u32 phys_count; | |
| 758 | − unsigned long flags; | |
| 759 | − | |
| 760 | − spin_lock_irqsave(&efi_runtime_lock, flags); | |
| 761 | − | |
| 762 | − phys_count = virt_to_phys_or_null(count); | |
| 763 | − status = efi_thunk(get_next_high_mono_count, phys_count); | |
| 764 | − | |
| 765 | − spin_unlock_irqrestore(&efi_runtime_lock, flags); | |
| 766 | − | |
| 767 | − return status; | |
| 720 | + return EFI_UNSUPPORTED; | |
| 768 | 721 | } |
| 769 | 722 | |
| 770 | 723 | static void |
| @@ -72,6 +72,9 @@ · 71 unmodified lines | ||
| 72 | 72 | #include <asm/mwait.h> |
| 73 | 73 | #include <asm/pci_x86.h> |
| 74 | 74 | #include <asm/cpu.h> |
| 75 | +#ifdef CONFIG_X86_IOPL_IOPERM | |
| 76 | +#include <asm/io_bitmap.h> | |
| 77 | +#endif | |
| 75 | 78 | |
| 76 | 79 | #ifdef CONFIG_ACPI |
| 77 | 80 | #include <linux/acpi.h> |
| @@ -837,6 +840,25 @@ static void xen_load_sp0(unsigned long sp0) · 759 unmodified lines | ||
| 837 | 840 | this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0); |
| 838 | 841 | } |
| 839 | 842 | |
| 843 | +#ifdef CONFIG_X86_IOPL_IOPERM | |
| 844 | +static void xen_update_io_bitmap(void) | |
| 845 | +{ | |
| 846 | + struct physdev_set_iobitmap iobitmap; | |
| 847 | + struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw); | |
| 848 | + | |
| 849 | + native_tss_update_io_bitmap(); | |
| 850 | + | |
| 851 | + iobitmap.bitmap = (uint8_t *)(&tss->x86_tss) + | |
| 852 | + tss->x86_tss.io_bitmap_base; | |
| 853 | + if (tss->x86_tss.io_bitmap_base == IO_BITMAP_OFFSET_INVALID) | |
| 854 | + iobitmap.nr_ports = 0; | |
| 855 | + else | |
| 856 | + iobitmap.nr_ports = IO_BITMAP_BITS; | |
| 857 | + | |
| 858 | + HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &iobitmap); | |
| 859 | +} | |
| 860 | +#endif | |
| 861 | + | |
| 840 | 862 | static void xen_io_delay(void) |
| 841 | 863 | { |
| 842 | 864 | } |
| @@ -1047,6 +1069,9 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = { · 204 unmodified lines | ||
| 1047 | 1069 | .write_idt_entry = xen_write_idt_entry, |
| 1048 | 1070 | .load_sp0 = xen_load_sp0, |
| 1049 | 1071 | |
| 1072 | +#ifdef CONFIG_X86_IOPL_IOPERM | |
| 1073 | + .update_io_bitmap = xen_update_io_bitmap, | |
| 1074 | +#endif | |
| 1050 | 1075 | .io_delay = xen_io_delay, |
| 1051 | 1076 | |
| 1052 | 1077 | /* Xen takes care of %gs when switching to usermode for us */ |
| @@ -610,12 +610,13 @@ struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, · 609 unmodified lines | ||
| 610 | 610 | */ |
| 611 | 611 | entity = &bfqg->entity; |
| 612 | 612 | for_each_entity(entity) { |
| 613 | − bfqg = container_of(entity, struct bfq_group, entity); | |
| 614 | − if (bfqg != bfqd->root_group) { | |
| 615 | − parent = bfqg_parent(bfqg); | |
| 613 | + struct bfq_group *curr_bfqg = container_of(entity, | |
| 614 | + struct bfq_group, entity); | |
| 615 | + if (curr_bfqg != bfqd->root_group) { | |
| 616 | + parent = bfqg_parent(curr_bfqg); | |
| 616 | 617 | if (!parent) |
| 617 | 618 | parent = bfqd->root_group; |
| 618 | − bfq_group_set_parent(bfqg, parent); | |
| 619 | + bfq_group_set_parent(curr_bfqg, parent); | |
| 619 | 620 | } |
| 620 | 621 | } |
| 621 | 622 | |
| @@ -1663,12 +1663,6 @@ int kblockd_schedule_work(struct work_struct *work) · 1662 unmodified lines | ||
| 1663 | 1663 | } |
| 1664 | 1664 | EXPORT_SYMBOL(kblockd_schedule_work); |
| 1665 | 1665 | |
| 1666 | −int kblockd_schedule_work_on(int cpu, struct work_struct *work) | |
| 1667 | −{ | |
| 1668 | − return queue_work_on(cpu, kblockd_workqueue, work); | |
| 1669 | −} | |
| 1670 | −EXPORT_SYMBOL(kblockd_schedule_work_on); | |
| 1671 | − | |
| 1672 | 1666 | int kblockd_mod_delayed_work_on(int cpu, struct delayed_work *dwork, |
| 1673 | 1667 | unsigned long delay) |
| 1674 | 1668 | { |
| @@ -412,7 +412,7 @@ void blk_insert_flush(struct request *rq) · 411 unmodified lines | ||
| 412 | 412 | */ |
| 413 | 413 | if ((policy & REQ_FSEQ_DATA) && |
| 414 | 414 | !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) { |
| 415 | − blk_mq_request_bypass_insert(rq, false); | |
| 415 | + blk_mq_request_bypass_insert(rq, false, false); | |
| 416 | 416 | return; |
| 417 | 417 | } |
| 418 | 418 | |
| @@ -1318,7 +1318,7 @@ static bool iocg_is_idle(struct ioc_gq *iocg) · 1317 unmodified lines | ||
| 1318 | 1318 | return false; |
| 1319 | 1319 | |
| 1320 | 1320 | /* is something in flight? */ |
| 1321 | − if (atomic64_read(&iocg->done_vtime) < atomic64_read(&iocg->vtime)) | |
| 1321 | + if (atomic64_read(&iocg->done_vtime) != atomic64_read(&iocg->vtime)) | |
| 1322 | 1322 | return false; |
| 1323 | 1323 | |
| 1324 | 1324 | return true; |
| @@ -361,13 +361,19 @@ static bool blk_mq_sched_bypass_insert(struct blk_mq_hw_ctx *hctx, · 360 unmodified lines | ||
| 361 | 361 | bool has_sched, |
| 362 | 362 | struct request *rq) |
| 363 | 363 | { |
| 364 | − /* dispatch flush rq directly */ | |
| 365 | − if (rq->rq_flags & RQF_FLUSH_SEQ) { | |
| 366 | − spin_lock(&hctx->lock); | |
| 367 | − list_add(&rq->queuelist, &hctx->dispatch); | |
| 368 | − spin_unlock(&hctx->lock); | |
| 364 | + /* | |
| 365 | + * dispatch flush and passthrough rq directly | |
| 366 | + * | |
| 367 | + * passthrough request has to be added to hctx->dispatch directly. | |
| 368 | + * For some reason, device may be in one situation which can't | |
| 369 | + * handle FS request, so STS_RESOURCE is always returned and the | |
| 370 | + * FS request will be added to hctx->dispatch. However passthrough | |
| 371 | + * request may be required at that time for fixing the problem. If | |
| 372 | + * passthrough request is added to scheduler queue, there isn't any | |
| 373 | + * chance to dispatch it given we prioritize requests in hctx->dispatch. | |
| 374 | + */ | |
| 375 | + if ((rq->rq_flags & RQF_FLUSH_SEQ) || blk_rq_is_passthrough(rq)) | |
| 369 | 376 | return true; |
| 370 | − } | |
| 371 | 377 | |
| 372 | 378 | if (has_sched) |
| 373 | 379 | rq->rq_flags |= RQF_SORTED; |
| @@ -391,8 +397,32 @@ void blk_mq_sched_insert_request(struct request *rq, bool at_head, · 17 unmodified lines | ||
| 391 | 397 | |
| 392 | 398 | WARN_ON(e && (rq->tag != -1)); |
| 393 | 399 | |
| 394 | − if (blk_mq_sched_bypass_insert(hctx, !!e, rq)) | |
| 400 | + if (blk_mq_sched_bypass_insert(hctx, !!e, rq)) { | |
| 401 | + /* | |
| 402 | + * Firstly normal IO request is inserted to scheduler queue or | |
| 403 | + * sw queue, meantime we add flush request to dispatch queue( | |
| 404 | + * hctx->dispatch) directly and there is at most one in-flight | |
| 405 | + * flush request for each hw queue, so it doesn't matter to add | |
| 406 | + * flush request to tail or front of the dispatch queue. | |
| 407 | + * | |
| 408 | + * Secondly in case of NCQ, flush request belongs to non-NCQ | |
| 409 | + * command, and queueing it will fail when there is any | |
| 410 | + * in-flight normal IO request(NCQ command). When adding flush | |
| 411 | + * rq to the front of hctx->dispatch, it is easier to introduce | |
| 412 | + * extra time to flush rq's latency because of S_SCHED_RESTART | |
| 413 | + * compared with adding to the tail of dispatch queue, then | |
| 414 | + * chance of flush merge is increased, and less flush requests | |
| 415 | + * will be issued to controller. It is observed that ~10% time | |
| 416 | + * is saved in blktests block/004 on disk attached to AHCI/NCQ | |
| 417 | + * drive when adding flush rq to the front of hctx->dispatch. | |
| 418 | + * | |
| 419 | + * Simply queue flush rq to the front of hctx->dispatch so that | |
| 420 | + * intensive flush workloads can benefit in case of NCQ HW. | |
| 421 | + */ | |
| 422 | + at_head = (rq->rq_flags & RQF_FLUSH_SEQ) ? true : at_head; | |
| 423 | + blk_mq_request_bypass_insert(rq, at_head, false); | |
| 395 | 424 | goto run; |
| 425 | + } | |
| 396 | 426 | |
| 397 | 427 | if (e && e->type->ops.insert_requests) { |
| 398 | 428 | LIST_HEAD(list); |
| @@ -183,8 +183,8 @@ found_tag: · 182 unmodified lines | ||
| 183 | 183 | return tag + tag_offset; |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | −void blk_mq_put_tag(struct blk_mq_hw_ctx *hctx, struct blk_mq_tags *tags, | |
| 187 | − struct blk_mq_ctx *ctx, unsigned int tag) | |
| 186 | +void blk_mq_put_tag(struct blk_mq_tags *tags, struct blk_mq_ctx *ctx, | |
| 187 | + unsigned int tag) | |
| 188 | 188 | { |
| 189 | 189 | if (!blk_mq_tag_is_reserved(tags, tag)) { |
| 190 | 190 | const int real_tag = tag - tags->nr_reserved_tags; |
| @@ -26,8 +26,8 @@ extern struct blk_mq_tags *blk_mq_init_tags(unsigned int nr_tags, unsigned int r · 25 unmodified lines | ||
| 26 | 26 | extern void blk_mq_free_tags(struct blk_mq_tags *tags); |
| 27 | 27 | |
| 28 | 28 | extern unsigned int blk_mq_get_tag(struct blk_mq_alloc_data *data); |
| 29 | −extern void blk_mq_put_tag(struct blk_mq_hw_ctx *hctx, struct blk_mq_tags *tags, | |
| 30 | − struct blk_mq_ctx *ctx, unsigned int tag); | |
| 29 | +extern void blk_mq_put_tag(struct blk_mq_tags *tags, struct blk_mq_ctx *ctx, | |
| 30 | + unsigned int tag); | |
| 31 | 31 | extern int blk_mq_tag_update_depth(struct blk_mq_hw_ctx *hctx, |
| 32 | 32 | struct blk_mq_tags **tags, |
| 33 | 33 | unsigned int depth, bool can_grow); |
| @@ -477,9 +477,9 @@ static void __blk_mq_free_request(struct request *rq) · 476 unmodified lines | ||
| 477 | 477 | blk_pm_mark_last_busy(rq); |
| 478 | 478 | rq->mq_hctx = NULL; |
| 479 | 479 | if (rq->tag != -1) |
| 480 | − blk_mq_put_tag(hctx, hctx->tags, ctx, rq->tag); | |
| 480 | + blk_mq_put_tag(hctx->tags, ctx, rq->tag); | |
| 481 | 481 | if (sched_tag != -1) |
| 482 | − blk_mq_put_tag(hctx, hctx->sched_tags, ctx, sched_tag); | |
| 482 | + blk_mq_put_tag(hctx->sched_tags, ctx, sched_tag); | |
| 483 | 483 | blk_mq_sched_restart(hctx); |
| 484 | 484 | blk_queue_exit(q); |
| 485 | 485 | } |
| @@ -735,7 +735,7 @@ static void blk_mq_requeue_work(struct work_struct *work) · 249 unmodified lines | ||
| 735 | 735 | * merge. |
| 736 | 736 | */ |
| 737 | 737 | if (rq->rq_flags & RQF_DONTPREP) |
| 738 | − blk_mq_request_bypass_insert(rq, false); | |
| 738 | + blk_mq_request_bypass_insert(rq, false, false); | |
| 739 | 739 | else |
| 740 | 740 | blk_mq_sched_insert_request(rq, true, false, false); |
| 741 | 741 | } |
| @@ -1286,7 +1286,7 @@ bool blk_mq_dispatch_rq_list(struct request_queue *q, struct list_head *list, · 544 unmodified lines | ||
| 1286 | 1286 | q->mq_ops->commit_rqs(hctx); |
| 1287 | 1287 | |
| 1288 | 1288 | spin_lock(&hctx->lock); |
| 1289 | − list_splice_init(list, &hctx->dispatch); | |
| 1289 | + list_splice_tail_init(list, &hctx->dispatch); | |
| 1290 | 1290 | spin_unlock(&hctx->lock); |
| 1291 | 1291 | |
| 1292 | 1292 | /* |
| @@ -1677,12 +1677,16 @@ void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, · 384 unmodified lines | ||
| 1677 | 1677 | * Should only be used carefully, when the caller knows we want to |
| 1678 | 1678 | * bypass a potential IO scheduler on the target device. |
| 1679 | 1679 | */ |
| 1680 | −void blk_mq_request_bypass_insert(struct request *rq, bool run_queue) | |
| 1680 | +void blk_mq_request_bypass_insert(struct request *rq, bool at_head, | |
| 1681 | + bool run_queue) | |
| 1681 | 1682 | { |
| 1682 | 1683 | struct blk_mq_hw_ctx *hctx = rq->mq_hctx; |
| 1683 | 1684 | |
| 1684 | 1685 | spin_lock(&hctx->lock); |
| 1685 | − list_add_tail(&rq->queuelist, &hctx->dispatch); | |
| 1686 | + if (at_head) | |
| 1687 | + list_add(&rq->queuelist, &hctx->dispatch); | |
| 1688 | + else | |
| 1689 | + list_add_tail(&rq->queuelist, &hctx->dispatch); | |
| 1686 | 1690 | spin_unlock(&hctx->lock); |
| 1687 | 1691 | |
| 1688 | 1692 | if (run_queue) |
| @@ -1849,7 +1853,7 @@ insert: · 160 unmodified lines | ||
| 1849 | 1853 | if (bypass_insert) |
| 1850 | 1854 | return BLK_STS_RESOURCE; |
| 1851 | 1855 | |
| 1852 | − blk_mq_request_bypass_insert(rq, run_queue); | |
| 1856 | + blk_mq_request_bypass_insert(rq, false, run_queue); | |
| 1853 | 1857 | return BLK_STS_OK; |
| 1854 | 1858 | } |
| 1855 | 1859 | |
| @@ -1876,7 +1880,7 @@ static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx, · 20 unmodified lines | ||
| 1876 | 1880 | |
| 1877 | 1881 | ret = __blk_mq_try_issue_directly(hctx, rq, cookie, false, true); |
| 1878 | 1882 | if (ret == BLK_STS_RESOURCE || ret == BLK_STS_DEV_RESOURCE) |
| 1879 | − blk_mq_request_bypass_insert(rq, true); | |
| 1883 | + blk_mq_request_bypass_insert(rq, false, true); | |
| 1880 | 1884 | else if (ret != BLK_STS_OK) |
| 1881 | 1885 | blk_mq_end_request(rq, ret); |
| 1882 | 1886 | |
| @@ -1910,7 +1914,7 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx *hctx, · 27 unmodified lines | ||
| 1910 | 1914 | if (ret != BLK_STS_OK) { |
| 1911 | 1915 | if (ret == BLK_STS_RESOURCE || |
| 1912 | 1916 | ret == BLK_STS_DEV_RESOURCE) { |
| 1913 | − blk_mq_request_bypass_insert(rq, | |
| 1917 | + blk_mq_request_bypass_insert(rq, false, | |
| 1914 | 1918 | list_empty(list)); |
| 1915 | 1919 | break; |
| 1916 | 1920 | } |
| @@ -3398,7 +3402,6 @@ static void blk_mq_poll_stats_fn(struct blk_stat_callback *cb) · 1481 unmodified lines | ||
| 3398 | 3402 | } |
| 3399 | 3403 | |
| 3400 | 3404 | static unsigned long blk_mq_poll_nsecs(struct request_queue *q, |
| 3401 | − struct blk_mq_hw_ctx *hctx, | |
| 3402 | 3405 | struct request *rq) |
| 3403 | 3406 | { |
| 3404 | 3407 | unsigned long ret = 0; |
| @@ -3431,7 +3434,6 @@ static unsigned long blk_mq_poll_nsecs(struct request_queue *q, · 26 unmodified lines | ||
| 3431 | 3434 | } |
| 3432 | 3435 | |
| 3433 | 3436 | static bool blk_mq_poll_hybrid_sleep(struct request_queue *q, |
| 3434 | − struct blk_mq_hw_ctx *hctx, | |
| 3435 | 3437 | struct request *rq) |
| 3436 | 3438 | { |
| 3437 | 3439 | struct hrtimer_sleeper hs; |
| @@ -3451,7 +3453,7 @@ static bool blk_mq_poll_hybrid_sleep(struct request_queue *q, · 13 unmodified lines | ||
| 3451 | 3453 | if (q->poll_nsec > 0) |
| 3452 | 3454 | nsecs = q->poll_nsec; |
| 3453 | 3455 | else |
| 3454 | − nsecs = blk_mq_poll_nsecs(q, hctx, rq); | |
| 3456 | + nsecs = blk_mq_poll_nsecs(q, rq); | |
| 3455 | 3457 | |
| 3456 | 3458 | if (!nsecs) |
| 3457 | 3459 | return false; |
| @@ -3506,7 +3508,7 @@ static bool blk_mq_poll_hybrid(struct request_queue *q, · 48 unmodified lines | ||
| 3506 | 3508 | return false; |
| 3507 | 3509 | } |
| 3508 | 3510 | |
| 3509 | − return blk_mq_poll_hybrid_sleep(q, hctx, rq); | |
| 3511 | + return blk_mq_poll_hybrid_sleep(q, rq); | |
| 3510 | 3512 | } |
| 3511 | 3513 | |
| 3512 | 3514 | /** |
| @@ -66,7 +66,8 @@ int blk_mq_alloc_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags, · 65 unmodified lines | ||
| 66 | 66 | */ |
| 67 | 67 | void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, |
| 68 | 68 | bool at_head); |
| 69 | −void blk_mq_request_bypass_insert(struct request *rq, bool run_queue); | |
| 69 | +void blk_mq_request_bypass_insert(struct request *rq, bool at_head, | |
| 70 | + bool run_queue); | |
| 70 | 71 | void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx, |
| 71 | 72 | struct list_head *list); |
| 72 | 73 | |
| @@ -199,7 +200,7 @@ static inline bool blk_mq_get_dispatch_budget(struct blk_mq_hw_ctx *hctx) · 126 unmodified lines | ||
| 199 | 200 | static inline void __blk_mq_put_driver_tag(struct blk_mq_hw_ctx *hctx, |
| 200 | 201 | struct request *rq) |
| 201 | 202 | { |
| 202 | − blk_mq_put_tag(hctx, hctx->tags, rq->mq_ctx, rq->tag); | |
| 203 | + blk_mq_put_tag(hctx->tags, rq->mq_ctx, rq->tag); | |
| 203 | 204 | rq->tag = -1; |
| 204 | 205 | |
| 205 | 206 | if (rq->rq_flags & RQF_MQ_INFLIGHT) { |
| @@ -301,6 +301,42 @@ struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector) · 300 unmodified lines | ||
| 301 | 301 | } |
| 302 | 302 | EXPORT_SYMBOL_GPL(disk_map_sector_rcu); |
| 303 | 303 | |
| 304 | +/** | |
| 305 | + * disk_has_partitions | |
| 306 | + * @disk: gendisk of interest | |
| 307 | + * | |
| 308 | + * Walk through the partition table and check if valid partition exists. | |
| 309 | + * | |
| 310 | + * CONTEXT: | |
| 311 | + * Don't care. | |
| 312 | + * | |
| 313 | + * RETURNS: | |
| 314 | + * True if the gendisk has at least one valid non-zero size partition. | |
| 315 | + * Otherwise false. | |
| 316 | + */ | |
| 317 | +bool disk_has_partitions(struct gendisk *disk) | |
| 318 | +{ | |
| 319 | + struct disk_part_tbl *ptbl; | |
| 320 | + int i; | |
| 321 | + bool ret = false; | |
| 322 | + | |
| 323 | + rcu_read_lock(); | |
| 324 | + ptbl = rcu_dereference(disk->part_tbl); | |
| 325 | + | |
| 326 | + /* Iterate partitions skipping the whole device at index 0 */ | |
| 327 | + for (i = 1; i < ptbl->len; i++) { | |
| 328 | + if (rcu_dereference(ptbl->part[i])) { | |
| 329 | + ret = true; | |
| 330 | + break; | |
| 331 | + } | |
| 332 | + } | |
| 333 | + | |
| 334 | + rcu_read_unlock(); | |
| 335 | + | |
| 336 | + return ret; | |
| 337 | +} | |
| 338 | +EXPORT_SYMBOL_GPL(disk_has_partitions); | |
| 339 | + | |
| 304 | 340 | /* |
| 305 | 341 | * Can be deleted altogether. Later. |
| 306 | 342 | * |
| @@ -55,12 +55,14 @@ static bool acpi_watchdog_uses_rtc(const struct acpi_table_wdat *wdat) · 54 unmodified lines | ||
| 55 | 55 | } |
| 56 | 56 | #endif |
| 57 | 57 | |
| 58 | +static bool acpi_no_watchdog; | |
| 59 | + | |
| 58 | 60 | static const struct acpi_table_wdat *acpi_watchdog_get_wdat(void) |
| 59 | 61 | { |
| 60 | 62 | const struct acpi_table_wdat *wdat = NULL; |
| 61 | 63 | acpi_status status; |
| 62 | 64 | |
| 63 | − if (acpi_disabled) | |
| 65 | + if (acpi_disabled || acpi_no_watchdog) | |
| 64 | 66 | return NULL; |
| 65 | 67 | |
| 66 | 68 | status = acpi_get_table(ACPI_SIG_WDAT, 0, |
| @@ -88,6 +90,14 @@ bool acpi_has_watchdog(void) · 21 unmodified lines | ||
| 88 | 90 | } |
| 89 | 91 | EXPORT_SYMBOL_GPL(acpi_has_watchdog); |
| 90 | 92 | |
| 93 | +/* ACPI watchdog can be disabled on boot command line */ | |
| 94 | +static int __init disable_acpi_watchdog(char *str) | |
| 95 | +{ | |
| 96 | + acpi_no_watchdog = true; | |
| 97 | + return 1; | |
| 98 | +} | |
| 99 | +__setup("acpi_no_watchdog", disable_acpi_watchdog); | |
| 100 | + | |
| 91 | 101 | void __init acpi_watchdog_init(void) |
| 92 | 102 | { |
| 93 | 103 | const struct acpi_wdat_entry *entries; |
| @@ -126,12 +136,11 @@ void __init acpi_watchdog_init(void) · 32 unmodified lines | ||
| 126 | 136 | gas = &entries[i].register_region; |
| 127 | 137 | |
| 128 | 138 | res.start = gas->address; |
| 139 | + res.end = res.start + ACPI_ACCESS_BYTE_WIDTH(gas->access_width) - 1; | |
| 129 | 140 | if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { |
| 130 | 141 | res.flags = IORESOURCE_MEM; |
| 131 | − res.end = res.start + ALIGN(gas->access_width, 4) - 1; | |
| 132 | 142 | } else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { |
| 133 | 143 | res.flags = IORESOURCE_IO; |
| 134 | − res.end = res.start + gas->access_width - 1; | |
| 135 | 144 | } else { |
| 136 | 145 | pr_warn("Unsupported address space: %u\n", |
| 137 | 146 | gas->space_id); |
| @@ -5228,6 +5228,7 @@ static int binder_open(struct inode *nodp, struct file *filp) · 5227 unmodified lines | ||
| 5228 | 5228 | binder_dev = container_of(filp->private_data, |
| 5229 | 5229 | struct binder_device, miscdev); |
| 5230 | 5230 | } |
| 5231 | + refcount_inc(&binder_dev->ref); | |
| 5231 | 5232 | proc->context = &binder_dev->context; |
| 5232 | 5233 | binder_alloc_init(&proc->alloc); |
| 5233 | 5234 | |
| @@ -5405,6 +5406,7 @@ static int binder_node_release(struct binder_node *node, int refs) · 171 unmodified lines | ||
| 5405 | 5406 | static void binder_deferred_release(struct binder_proc *proc) |
| 5406 | 5407 | { |
| 5407 | 5408 | struct binder_context *context = proc->context; |
| 5409 | + struct binder_device *device; | |
| 5408 | 5410 | struct rb_node *n; |
| 5409 | 5411 | int threads, nodes, incoming_refs, outgoing_refs, active_transactions; |
| 5410 | 5412 | |
| @@ -5421,6 +5423,12 @@ static void binder_deferred_release(struct binder_proc *proc) · 10 unmodified lines | ||
| 5421 | 5423 | context->binder_context_mgr_node = NULL; |
| 5422 | 5424 | } |
| 5423 | 5425 | mutex_unlock(&context->context_mgr_node_lock); |
| 5426 | + device = container_of(proc->context, struct binder_device, context); | |
| 5427 | + if (refcount_dec_and_test(&device->ref)) { | |
| 5428 | + kfree(context->name); | |
| 5429 | + kfree(device); | |
| 5430 | + } | |
| 5431 | + proc->context = NULL; | |
| 5424 | 5432 | binder_inner_proc_lock(proc); |
| 5425 | 5433 | /* |
| 5426 | 5434 | * Make sure proc stays alive after we |
| @@ -6077,6 +6085,7 @@ static int __init init_binder_device(const char *name) · 650 unmodified lines | ||
| 6077 | 6085 | binder_device->miscdev.minor = MISC_DYNAMIC_MINOR; |
| 6078 | 6086 | binder_device->miscdev.name = name; |
| 6079 | 6087 | |
| 6088 | + refcount_set(&binder_device->ref, 1); | |
| 6080 | 6089 | binder_device->context.binder_context_mgr_uid = INVALID_UID; |
| 6081 | 6090 | binder_device->context.name = name; |
| 6082 | 6091 | mutex_init(&binder_device->context.context_mgr_node_lock); |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/list.h> |
| 9 | 9 | #include <linux/miscdevice.h> |
| 10 | 10 | #include <linux/mutex.h> |
| 11 | +#include <linux/refcount.h> | |
| 11 | 12 | #include <linux/stddef.h> |
| 12 | 13 | #include <linux/types.h> |
| 13 | 14 | #include <linux/uidgid.h> |
| @@ -33,6 +34,7 @@ struct binder_device { · 19 unmodified lines | ||
| 33 | 34 | struct miscdevice miscdev; |
| 34 | 35 | struct binder_context context; |
| 35 | 36 | struct inode *binderfs_inode; |
| 37 | + refcount_t ref; | |
| 36 | 38 | }; |
| 37 | 39 | |
| 38 | 40 | /** |
| @@ -154,6 +154,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode, · 153 unmodified lines | ||
| 154 | 154 | if (!name) |
| 155 | 155 | goto err; |
| 156 | 156 | |
| 157 | + refcount_set(&device->ref, 1); | |
| 157 | 158 | device->binderfs_inode = inode; |
| 158 | 159 | device->context.binder_context_mgr_uid = INVALID_UID; |
| 159 | 160 | device->context.name = name; |
| @@ -257,8 +258,10 @@ static void binderfs_evict_inode(struct inode *inode) · 97 unmodified lines | ||
| 257 | 258 | ida_free(&binderfs_minors, device->miscdev.minor); |
| 258 | 259 | mutex_unlock(&binderfs_minors_mutex); |
| 259 | 260 | |
| 260 | − kfree(device->context.name); | |
| 261 | − kfree(device); | |
| 261 | + if (refcount_dec_and_test(&device->ref)) { | |
| 262 | + kfree(device->context.name); | |
| 263 | + kfree(device); | |
| 264 | + } | |
| 262 | 265 | } |
| 263 | 266 | |
| 264 | 267 | /** |
| @@ -445,6 +448,7 @@ static int binderfs_binder_ctl_create(struct super_block *sb) · 180 unmodified lines | ||
| 445 | 448 | inode->i_uid = info->root_uid; |
| 446 | 449 | inode->i_gid = info->root_gid; |
| 447 | 450 | |
| 451 | + refcount_set(&device->ref, 1); | |
| 448 | 452 | device->binderfs_inode = inode; |
| 449 | 453 | device->miscdev.minor = minor; |
| 450 | 454 | |
| @@ -91,7 +91,7 @@ · 90 unmodified lines | ||
| 91 | 91 | #ifdef GENERAL_DEBUG |
| 92 | 92 | #define PRINTK(args...) printk(args) |
| 93 | 93 | #else |
| 94 | −#define PRINTK(args...) | |
| 94 | +#define PRINTK(args...) do {} while (0) | |
| 95 | 95 | #endif /* GENERAL_DEBUG */ |
| 96 | 96 | |
| 97 | 97 | #ifdef EXTRA_DEBUG |
| @@ -111,7 +111,7 @@ config CFAG12864B · 110 unmodified lines | ||
| 111 | 111 | If unsure, say N. |
| 112 | 112 | |
| 113 | 113 | config CFAG12864B_RATE |
| 114 | − int "Refresh rate (hertz)" | |
| 114 | + int "Refresh rate (hertz)" | |
| 115 | 115 | depends on CFAG12864B |
| 116 | 116 | default "20" |
| 117 | 117 | ---help--- |
| @@ -329,7 +329,7 @@ config PANEL_LCD_PROTO · 211 unmodified lines | ||
| 329 | 329 | |
| 330 | 330 | config PANEL_LCD_PIN_E |
| 331 | 331 | depends on PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO="0" |
| 332 | − int "Parallel port pin number & polarity connected to the LCD E signal (-17...17) " | |
| 332 | + int "Parallel port pin number & polarity connected to the LCD E signal (-17...17) " | |
| 333 | 333 | range -17 17 |
| 334 | 334 | default 14 |
| 335 | 335 | ---help--- |
| @@ -344,7 +344,7 @@ config PANEL_LCD_PIN_E · 8 unmodified lines | ||
| 344 | 344 | |
| 345 | 345 | config PANEL_LCD_PIN_RS |
| 346 | 346 | depends on PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO="0" |
| 347 | − int "Parallel port pin number & polarity connected to the LCD RS signal (-17...17) " | |
| 347 | + int "Parallel port pin number & polarity connected to the LCD RS signal (-17...17) " | |
| 348 | 348 | range -17 17 |
| 349 | 349 | default 17 |
| 350 | 350 | ---help--- |
| @@ -359,7 +359,7 @@ config PANEL_LCD_PIN_RS · 8 unmodified lines | ||
| 359 | 359 | |
| 360 | 360 | config PANEL_LCD_PIN_RW |
| 361 | 361 | depends on PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO="0" |
| 362 | − int "Parallel port pin number & polarity connected to the LCD RW signal (-17...17) " | |
| 362 | + int "Parallel port pin number & polarity connected to the LCD RW signal (-17...17) " | |
| 363 | 363 | range -17 17 |
| 364 | 364 | default 16 |
| 365 | 365 | ---help--- |
| @@ -374,7 +374,7 @@ config PANEL_LCD_PIN_RW · 8 unmodified lines | ||
| 374 | 374 | |
| 375 | 375 | config PANEL_LCD_PIN_SCL |
| 376 | 376 | depends on PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO!="0" |
| 377 | − int "Parallel port pin number & polarity connected to the LCD SCL signal (-17...17) " | |
| 377 | + int "Parallel port pin number & polarity connected to the LCD SCL signal (-17...17) " | |
| 378 | 378 | range -17 17 |
| 379 | 379 | default 1 |
| 380 | 380 | ---help--- |
| @@ -389,7 +389,7 @@ config PANEL_LCD_PIN_SCL · 8 unmodified lines | ||
| 389 | 389 | |
| 390 | 390 | config PANEL_LCD_PIN_SDA |
| 391 | 391 | depends on PANEL_PROFILE="0" && PANEL_LCD="1" && PANEL_LCD_PROTO!="0" |
| 392 | − int "Parallel port pin number & polarity connected to the LCD SDA signal (-17...17) " | |
| 392 | + int "Parallel port pin number & polarity connected to the LCD SDA signal (-17...17) " | |
| 393 | 393 | range -17 17 |
| 394 | 394 | default 2 |
| 395 | 395 | ---help--- |
| @@ -404,12 +404,12 @@ config PANEL_LCD_PIN_SDA · 8 unmodified lines | ||
| 404 | 404 | |
| 405 | 405 | config PANEL_LCD_PIN_BL |
| 406 | 406 | depends on PANEL_PROFILE="0" && PANEL_LCD="1" |
| 407 | − int "Parallel port pin number & polarity connected to the LCD backlight signal (-17...17) " | |
| 407 | + int "Parallel port pin number & polarity connected to the LCD backlight signal (-17...17) " | |
| 408 | 408 | range -17 17 |
| 409 | 409 | default 0 |
| 410 | 410 | ---help--- |
| 411 | 411 | This describes the number of the parallel port pin to which the LCD 'BL' signal |
| 412 | − has been connected. It can be : | |
| 412 | + has been connected. It can be : | |
| 413 | 413 | |
| 414 | 414 | 0 : no connection (eg: connected to ground) |
| 415 | 415 | 1..17 : directly connected to any of these pins on the DB25 plug |
| @@ -88,7 +88,7 @@ struct charlcd_priv { · 87 unmodified lines | ||
| 88 | 88 | int len; |
| 89 | 89 | } esc_seq; |
| 90 | 90 | |
| 91 | − unsigned long long drvdata[0]; | |
| 91 | + unsigned long long drvdata[]; | |
| 92 | 92 | }; |
| 93 | 93 | |
| 94 | 94 | #define charlcd_to_priv(p) container_of(p, struct charlcd_priv, lcd) |
| @@ -356,7 +356,6 @@ static int img_ascii_lcd_probe(struct platform_device *pdev) · 355 unmodified lines | ||
| 356 | 356 | const struct of_device_id *match; |
| 357 | 357 | const struct img_ascii_lcd_config *cfg; |
| 358 | 358 | struct img_ascii_lcd_ctx *ctx; |
| 359 | − struct resource *res; | |
| 360 | 359 | int err; |
| 361 | 360 | |
| 362 | 361 | match = of_match_device(img_ascii_lcd_matches, &pdev->dev); |
| @@ -378,8 +377,7 @@ static int img_ascii_lcd_probe(struct platform_device *pdev) · 15 unmodified lines | ||
| 378 | 377 | &ctx->offset)) |
| 379 | 378 | return -EINVAL; |
| 380 | 379 | } else { |
| 381 | − res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
| 382 | − ctx->base = devm_ioremap_resource(&pdev->dev, res); | |
| 380 | + ctx->base = devm_platform_ioremap_resource(pdev, 0); | |
| 383 | 381 | if (IS_ERR(ctx->base)) |
| 384 | 382 | return PTR_ERR(ctx->base); |
| 385 | 383 | } |
| @@ -718,6 +718,8 @@ static void __device_links_queue_sync_state(struct device *dev, · 717 unmodified lines | ||
| 718 | 718 | { |
| 719 | 719 | struct device_link *link; |
| 720 | 720 | |
| 721 | + if (!dev_has_sync_state(dev)) | |
| 722 | + return; | |
| 721 | 723 | if (dev->state_synced) |
| 722 | 724 | return; |
| 723 | 725 | |
| @@ -745,25 +747,31 @@ static void __device_links_queue_sync_state(struct device *dev, · 21 unmodified lines | ||
| 745 | 747 | /** |
| 746 | 748 | * device_links_flush_sync_list - Call sync_state() on a list of devices |
| 747 | 749 | * @list: List of devices to call sync_state() on |
| 750 | + * @dont_lock_dev: Device for which lock is already held by the caller | |
| 748 | 751 | * |
| 749 | 752 | * Calls sync_state() on all the devices that have been queued for it. This |
| 750 | − * function is used in conjunction with __device_links_queue_sync_state(). | |
| 753 | + * function is used in conjunction with __device_links_queue_sync_state(). The | |
| 754 | + * @dont_lock_dev parameter is useful when this function is called from a | |
| 755 | + * context where a device lock is already held. | |
| 751 | 756 | */ |
| 752 | −static void device_links_flush_sync_list(struct list_head *list) | |
| 757 | +static void device_links_flush_sync_list(struct list_head *list, | |
| 758 | + struct device *dont_lock_dev) | |
| 753 | 759 | { |
| 754 | 760 | struct device *dev, *tmp; |
| 755 | 761 | |
| 756 | 762 | list_for_each_entry_safe(dev, tmp, list, links.defer_sync) { |
| 757 | 763 | list_del_init(&dev->links.defer_sync); |
| 758 | 764 | |
| 759 | − device_lock(dev); | |
| 765 | + if (dev != dont_lock_dev) | |
| 766 | + device_lock(dev); | |
| 760 | 767 | |
| 761 | 768 | if (dev->bus->sync_state) |
| 762 | 769 | dev->bus->sync_state(dev); |
| 763 | 770 | else if (dev->driver && dev->driver->sync_state) |
| 764 | 771 | dev->driver->sync_state(dev); |
| 765 | 772 | |
| 766 | − device_unlock(dev); | |
| 773 | + if (dev != dont_lock_dev) | |
| 774 | + device_unlock(dev); | |
| 767 | 775 | |
| 768 | 776 | put_device(dev); |
| 769 | 777 | } |
| @@ -801,7 +809,7 @@ void device_links_supplier_sync_state_resume(void) · 31 unmodified lines | ||
| 801 | 809 | out: |
| 802 | 810 | device_links_write_unlock(); |
| 803 | 811 | |
| 804 | − device_links_flush_sync_list(&sync_list); | |
| 812 | + device_links_flush_sync_list(&sync_list, NULL); | |
| 805 | 813 | } |
| 806 | 814 | |
| 807 | 815 | static int sync_state_resume_initcall(void) |
| @@ -813,7 +821,7 @@ late_initcall(sync_state_resume_initcall); · 5 unmodified lines | ||
| 813 | 821 | |
| 814 | 822 | static void __device_links_supplier_defer_sync(struct device *sup) |
| 815 | 823 | { |
| 816 | − if (list_empty(&sup->links.defer_sync)) | |
| 824 | + if (list_empty(&sup->links.defer_sync) && dev_has_sync_state(sup)) | |
| 817 | 825 | list_add_tail(&sup->links.defer_sync, &deferred_sync); |
| 818 | 826 | } |
| 819 | 827 | |
| @@ -865,6 +873,11 @@ void device_links_driver_bound(struct device *dev) · 45 unmodified lines | ||
| 865 | 873 | driver_deferred_probe_add(link->consumer); |
| 866 | 874 | } |
| 867 | 875 | |
| 876 | + if (defer_sync_state_count) | |
| 877 | + __device_links_supplier_defer_sync(dev); | |
| 878 | + else | |
| 879 | + __device_links_queue_sync_state(dev, &sync_list); | |
| 880 | + | |
| 868 | 881 | list_for_each_entry(link, &dev->links.suppliers, c_node) { |
| 869 | 882 | if (!(link->flags & DL_FLAG_MANAGED)) |
| 870 | 883 | continue; |
| @@ -883,7 +896,7 @@ void device_links_driver_bound(struct device *dev) · 12 unmodified lines | ||
| 883 | 896 | |
| 884 | 897 | device_links_write_unlock(); |
| 885 | 898 | |
| 886 | − device_links_flush_sync_list(&sync_list); | |
| 899 | + device_links_flush_sync_list(&sync_list, dev); | |
| 887 | 900 | } |
| 888 | 901 | |
| 889 | 902 | static void device_link_drop_managed(struct device_link *link) |
| @@ -363,10 +363,10 @@ static void setup_pdev_dma_masks(struct platform_device *pdev) · 362 unmodified lines | ||
| 363 | 363 | { |
| 364 | 364 | if (!pdev->dev.coherent_dma_mask) |
| 365 | 365 | pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
| 366 | − if (!pdev->dma_mask) | |
| 367 | − pdev->dma_mask = DMA_BIT_MASK(32); | |
| 368 | − if (!pdev->dev.dma_mask) | |
| 369 | − pdev->dev.dma_mask = &pdev->dma_mask; | |
| 366 | + if (!pdev->dev.dma_mask) { | |
| 367 | + pdev->platform_dma_mask = DMA_BIT_MASK(32); | |
| 368 | + pdev->dev.dma_mask = &pdev->platform_dma_mask; | |
| 369 | + } | |
| 370 | 370 | }; |
| 371 | 371 | |
| 372 | 372 | /** |
| @@ -662,20 +662,8 @@ struct platform_device *platform_device_register_full( · 289 unmodified lines | ||
| 662 | 662 | pdev->dev.of_node_reused = pdevinfo->of_node_reused; |
| 663 | 663 | |
| 664 | 664 | if (pdevinfo->dma_mask) { |
| 665 | − /* | |
| 666 | − * This memory isn't freed when the device is put, | |
| 667 | − * I don't have a nice idea for that though. Conceptually | |
| 668 | − * dma_mask in struct device should not be a pointer. | |
| 669 | − * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 | |
| 670 | − */ | |
| 671 | − pdev->dev.dma_mask = | |
| 672 | − kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); | |
| 673 | − if (!pdev->dev.dma_mask) | |
| 674 | − goto err; | |
| 675 | − | |
| 676 | − kmemleak_ignore(pdev->dev.dma_mask); | |
| 677 | − | |
| 678 | − *pdev->dev.dma_mask = pdevinfo->dma_mask; | |
| 665 | + pdev->platform_dma_mask = pdevinfo->dma_mask; | |
| 666 | + pdev->dev.dma_mask = &pdev->platform_dma_mask; | |
| 679 | 667 | pdev->dev.coherent_dma_mask = pdevinfo->dma_mask; |
| 680 | 668 | } |
| 681 | 669 | |
| @@ -700,7 +688,6 @@ struct platform_device *platform_device_register_full( · 18 unmodified lines | ||
| 700 | 688 | if (ret) { |
| 701 | 689 | err: |
| 702 | 690 | ACPI_COMPANION_SET(&pdev->dev, NULL); |
| 703 | − kfree(pdev->dev.dma_mask); | |
| 704 | 691 | platform_device_put(pdev); |
| 705 | 692 | return ERR_PTR(ret); |
| 706 | 693 | } |
| @@ -608,6 +608,13 @@ static void software_node_release(struct kobject *kobj) · 607 unmodified lines | ||
| 608 | 608 | { |
| 609 | 609 | struct swnode *swnode = kobj_to_swnode(kobj); |
| 610 | 610 | |
| 611 | + if (swnode->parent) { | |
| 612 | + ida_simple_remove(&swnode->parent->child_ids, swnode->id); | |
| 613 | + list_del(&swnode->entry); | |
| 614 | + } else { | |
| 615 | + ida_simple_remove(&swnode_root_ids, swnode->id); | |
| 616 | + } | |
| 617 | + | |
| 611 | 618 | if (swnode->allocated) { |
| 612 | 619 | property_entries_free(swnode->node->properties); |
| 613 | 620 | kfree(swnode->node); |
| @@ -773,13 +780,6 @@ void fwnode_remove_software_node(struct fwnode_handle *fwnode) · 159 unmodified lines | ||
| 773 | 780 | if (!swnode) |
| 774 | 781 | return; |
| 775 | 782 | |
| 776 | − if (swnode->parent) { | |
| 777 | − ida_simple_remove(&swnode->parent->child_ids, swnode->id); | |
| 778 | − list_del(&swnode->entry); | |
| 779 | − } else { | |
| 780 | − ida_simple_remove(&swnode_root_ids, swnode->id); | |
| 781 | − } | |
| 782 | − | |
| 783 | 783 | kobject_put(&swnode->kobj); |
| 784 | 784 | } |
| 785 | 785 | EXPORT_SYMBOL_GPL(fwnode_remove_software_node); |
| @@ -853,14 +853,17 @@ static void reset_fdc_info(int mode) · 852 unmodified lines | ||
| 853 | 853 | /* selects the fdc and drive, and enables the fdc's input/dma. */ |
| 854 | 854 | static void set_fdc(int drive) |
| 855 | 855 | { |
| 856 | + unsigned int new_fdc = fdc; | |
| 857 | + | |
| 856 | 858 | if (drive >= 0 && drive < N_DRIVE) { |
| 857 | − fdc = FDC(drive); | |
| 859 | + new_fdc = FDC(drive); | |
| 858 | 860 | current_drive = drive; |
| 859 | 861 | } |
| 860 | − if (fdc != 1 && fdc != 0) { | |
| 862 | + if (new_fdc >= N_FDC) { | |
| 861 | 863 | pr_info("bad fdc value\n"); |
| 862 | 864 | return; |
| 863 | 865 | } |
| 866 | + fdc = new_fdc; | |
| 864 | 867 | set_dor(fdc, ~0, 8); |
| 865 | 868 | #if N_FDC > 1 |
| 866 | 869 | set_dor(1 - fdc, ~8, 0); |
| @@ -14,9 +14,6 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/fault-inject.h> |
| 15 | 15 | |
| 16 | 16 | struct nullb_cmd { |
| 17 | − struct list_head list; | |
| 18 | − struct llist_node ll_list; | |
| 19 | − struct __call_single_data csd; | |
| 20 | 17 | struct request *rq; |
| 21 | 18 | struct bio *bio; |
| 22 | 19 | unsigned int tag; |
| @@ -1518,8 +1518,6 @@ static int setup_commands(struct nullb_queue *nq) · 1517 unmodified lines | ||
| 1518 | 1518 | |
| 1519 | 1519 | for (i = 0; i < nq->queue_depth; i++) { |
| 1520 | 1520 | cmd = &nq->cmds[i]; |
| 1521 | − INIT_LIST_HEAD(&cmd->list); | |
| 1522 | − cmd->ll_list.next = NULL; | |
| 1523 | 1521 | cmd->tag = -1U; |
| 1524 | 1522 | } |
| 1525 | 1523 | |
| @@ -276,7 +276,7 @@ static const struct block_device_operations pcd_bdops = { · 275 unmodified lines | ||
| 276 | 276 | .release = pcd_block_release, |
| 277 | 277 | .ioctl = pcd_block_ioctl, |
| 278 | 278 | #ifdef CONFIG_COMPAT |
| 279 | − .ioctl = blkdev_compat_ptr_ioctl, | |
| 279 | + .compat_ioctl = blkdev_compat_ptr_ioctl, | |
| 280 | 280 | #endif |
| 281 | 281 | .check_events = pcd_block_check_events, |
| 282 | 282 | }; |
| @@ -245,13 +245,20 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, · 244 unmodified lines | ||
| 245 | 245 | err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num); |
| 246 | 246 | if (err) { |
| 247 | 247 | virtqueue_kick(vblk->vqs[qid].vq); |
| 248 | − blk_mq_stop_hw_queue(hctx); | |
| 248 | + /* Don't stop the queue if -ENOMEM: we may have failed to | |
| 249 | + * bounce the buffer due to global resource outage. | |
| 250 | + */ | |
| 251 | + if (err == -ENOSPC) | |
| 252 | + blk_mq_stop_hw_queue(hctx); | |
| 249 | 253 | spin_unlock_irqrestore(&vblk->vqs[qid].lock, flags); |
| 250 | − /* Out of mem doesn't actually happen, since we fall back | |
| 251 | − * to direct descriptors */ | |
| 252 | − if (err == -ENOMEM || err == -ENOSPC) | |
| 254 | + switch (err) { | |
| 255 | + case -ENOSPC: | |
| 253 | 256 | return BLK_STS_DEV_RESOURCE; |
| 254 | − return BLK_STS_IOERR; | |
| 257 | + case -ENOMEM: | |
| 258 | + return BLK_STS_RESOURCE; | |
| 259 | + default: | |
| 260 | + return BLK_STS_IOERR; | |
| 261 | + } | |
| 255 | 262 | } |
| 256 | 263 | |
| 257 | 264 | if (bd->last && virtqueue_kick_prepare(vblk->vqs[qid].vq)) |
| @@ -213,6 +213,7 @@ struct blkfront_info · 212 unmodified lines | ||
| 213 | 213 | struct blk_mq_tag_set tag_set; |
| 214 | 214 | struct blkfront_ring_info *rinfo; |
| 215 | 215 | unsigned int nr_rings; |
| 216 | + unsigned int rinfo_size; | |
| 216 | 217 | /* Save uncomplete reqs and bios for migration. */ |
| 217 | 218 | struct list_head requests; |
| 218 | 219 | struct bio_list bio_list; |
| @@ -259,6 +260,18 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo); · 40 unmodified lines | ||
| 259 | 260 | static void blkfront_gather_backend_features(struct blkfront_info *info); |
| 260 | 261 | static int negotiate_mq(struct blkfront_info *info); |
| 261 | 262 | |
| 263 | +#define for_each_rinfo(info, ptr, idx) \ | |
| 264 | + for ((ptr) = (info)->rinfo, (idx) = 0; \ | |
| 265 | + (idx) < (info)->nr_rings; \ | |
| 266 | + (idx)++, (ptr) = (void *)(ptr) + (info)->rinfo_size) | |
| 267 | + | |
| 268 | +static inline struct blkfront_ring_info * | |
| 269 | +get_rinfo(const struct blkfront_info *info, unsigned int i) | |
| 270 | +{ | |
| 271 | + BUG_ON(i >= info->nr_rings); | |
| 272 | + return (void *)info->rinfo + i * info->rinfo_size; | |
| 273 | +} | |
| 274 | + | |
| 262 | 275 | static int get_id_from_freelist(struct blkfront_ring_info *rinfo) |
| 263 | 276 | { |
| 264 | 277 | unsigned long free = rinfo->shadow_free; |
| @@ -883,8 +896,7 @@ static blk_status_t blkif_queue_rq(struct blk_mq_hw_ctx *hctx, · 618 unmodified lines | ||
| 883 | 896 | struct blkfront_info *info = hctx->queue->queuedata; |
| 884 | 897 | struct blkfront_ring_info *rinfo = NULL; |
| 885 | 898 | |
| 886 | − BUG_ON(info->nr_rings <= qid); | |
| 887 | − rinfo = &info->rinfo[qid]; | |
| 899 | + rinfo = get_rinfo(info, qid); | |
| 888 | 900 | blk_mq_start_request(qd->rq); |
| 889 | 901 | spin_lock_irqsave(&rinfo->ring_lock, flags); |
| 890 | 902 | if (RING_FULL(&rinfo->ring)) |
| @@ -1181,6 +1193,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, · 290 unmodified lines | ||
| 1181 | 1193 | static void xlvbd_release_gendisk(struct blkfront_info *info) |
| 1182 | 1194 | { |
| 1183 | 1195 | unsigned int minor, nr_minors, i; |
| 1196 | + struct blkfront_ring_info *rinfo; | |
| 1184 | 1197 | |
| 1185 | 1198 | if (info->rq == NULL) |
| 1186 | 1199 | return; |
| @@ -1188,9 +1201,7 @@ static void xlvbd_release_gendisk(struct blkfront_info *info) · 1 unmodified line | ||
| 1188 | 1201 | /* No more blkif_request(). */ |
| 1189 | 1202 | blk_mq_stop_hw_queues(info->rq); |
| 1190 | 1203 | |
| 1191 | − for (i = 0; i < info->nr_rings; i++) { | |
| 1192 | − struct blkfront_ring_info *rinfo = &info->rinfo[i]; | |
| 1193 | − | |
| 1204 | + for_each_rinfo(info, rinfo, i) { | |
| 1194 | 1205 | /* No more gnttab callback work. */ |
| 1195 | 1206 | gnttab_cancel_free_callback(&rinfo->callback); |
| 1196 | 1207 | |
| @@ -1339,6 +1350,7 @@ free_shadow: · 142 unmodified lines | ||
| 1339 | 1350 | static void blkif_free(struct blkfront_info *info, int suspend) |
| 1340 | 1351 | { |
| 1341 | 1352 | unsigned int i; |
| 1353 | + struct blkfront_ring_info *rinfo; | |
| 1342 | 1354 | |
| 1343 | 1355 | /* Prevent new requests being issued until we fix things up. */ |
| 1344 | 1356 | info->connected = suspend ? |
| @@ -1347,8 +1359,8 @@ static void blkif_free(struct blkfront_info *info, int suspend) · 2 unmodified lines | ||
| 1347 | 1359 | if (info->rq) |
| 1348 | 1360 | blk_mq_stop_hw_queues(info->rq); |
| 1349 | 1361 | |
| 1350 | − for (i = 0; i < info->nr_rings; i++) | |
| 1351 | − blkif_free_ring(&info->rinfo[i]); | |
| 1362 | + for_each_rinfo(info, rinfo, i) | |
| 1363 | + blkif_free_ring(rinfo); | |
| 1352 | 1364 | |
| 1353 | 1365 | kvfree(info->rinfo); |
| 1354 | 1366 | info->rinfo = NULL; |
| @@ -1775,6 +1787,7 @@ static int talk_to_blkback(struct xenbus_device *dev, · 420 unmodified lines | ||
| 1775 | 1787 | int err; |
| 1776 | 1788 | unsigned int i, max_page_order; |
| 1777 | 1789 | unsigned int ring_page_order; |
| 1790 | + struct blkfront_ring_info *rinfo; | |
| 1778 | 1791 | |
| 1779 | 1792 | if (!info) |
| 1780 | 1793 | return -ENODEV; |
| @@ -1788,9 +1801,7 @@ static int talk_to_blkback(struct xenbus_device *dev, · 7 unmodified lines | ||
| 1788 | 1801 | if (err) |
| 1789 | 1802 | goto destroy_blkring; |
| 1790 | 1803 | |
| 1791 | − for (i = 0; i < info->nr_rings; i++) { | |
| 1792 | − struct blkfront_ring_info *rinfo = &info->rinfo[i]; | |
| 1793 | − | |
| 1804 | + for_each_rinfo(info, rinfo, i) { | |
| 1794 | 1805 | /* Create shared ring, alloc event channel. */ |
| 1795 | 1806 | err = setup_blkring(dev, rinfo); |
| 1796 | 1807 | if (err) |
| @@ -1815,7 +1826,7 @@ again: · 18 unmodified lines | ||
| 1815 | 1826 | |
| 1816 | 1827 | /* We already got the number of queues/rings in _probe */ |
| 1817 | 1828 | if (info->nr_rings == 1) { |
| 1818 | − err = write_per_ring_nodes(xbt, &info->rinfo[0], dev->nodename); | |
| 1829 | + err = write_per_ring_nodes(xbt, info->rinfo, dev->nodename); | |
| 1819 | 1830 | if (err) |
| 1820 | 1831 | goto destroy_blkring; |
| 1821 | 1832 | } else { |
| @@ -1837,10 +1848,10 @@ again: · 15 unmodified lines | ||
| 1837 | 1848 | goto abort_transaction; |
| 1838 | 1849 | } |
| 1839 | 1850 | |
| 1840 | − for (i = 0; i < info->nr_rings; i++) { | |
| 1851 | + for_each_rinfo(info, rinfo, i) { | |
| 1841 | 1852 | memset(path, 0, pathsize); |
| 1842 | 1853 | snprintf(path, pathsize, "%s/queue-%u", dev->nodename, i); |
| 1843 | − err = write_per_ring_nodes(xbt, &info->rinfo[i], path); | |
| 1854 | + err = write_per_ring_nodes(xbt, rinfo, path); | |
| 1844 | 1855 | if (err) { |
| 1845 | 1856 | kfree(path); |
| 1846 | 1857 | goto destroy_blkring; |
| @@ -1868,9 +1879,8 @@ again: · 21 unmodified lines | ||
| 1868 | 1879 | goto destroy_blkring; |
| 1869 | 1880 | } |
| 1870 | 1881 | |
| 1871 | − for (i = 0; i < info->nr_rings; i++) { | |
| 1882 | + for_each_rinfo(info, rinfo, i) { | |
| 1872 | 1883 | unsigned int j; |
| 1873 | − struct blkfront_ring_info *rinfo = &info->rinfo[i]; | |
| 1874 | 1884 | |
| 1875 | 1885 | for (j = 0; j < BLK_RING_SIZE(info); j++) |
| 1876 | 1886 | rinfo->shadow[j].req.u.rw.id = j + 1; |
| @@ -1900,6 +1910,7 @@ static int negotiate_mq(struct blkfront_info *info) · 23 unmodified lines | ||
| 1900 | 1910 | { |
| 1901 | 1911 | unsigned int backend_max_queues; |
| 1902 | 1912 | unsigned int i; |
| 1913 | + struct blkfront_ring_info *rinfo; | |
| 1903 | 1914 | |
| 1904 | 1915 | BUG_ON(info->nr_rings); |
| 1905 | 1916 | |
| @@ -1911,20 +1922,16 @@ static int negotiate_mq(struct blkfront_info *info) · 5 unmodified lines | ||
| 1911 | 1922 | if (!info->nr_rings) |
| 1912 | 1923 | info->nr_rings = 1; |
| 1913 | 1924 | |
| 1914 | − info->rinfo = kvcalloc(info->nr_rings, | |
| 1915 | − struct_size(info->rinfo, shadow, | |
| 1916 | − BLK_RING_SIZE(info)), | |
| 1917 | − GFP_KERNEL); | |
| 1925 | + info->rinfo_size = struct_size(info->rinfo, shadow, | |
| 1926 | + BLK_RING_SIZE(info)); | |
| 1927 | + info->rinfo = kvcalloc(info->nr_rings, info->rinfo_size, GFP_KERNEL); | |
| 1918 | 1928 | if (!info->rinfo) { |
| 1919 | 1929 | xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure"); |
| 1920 | 1930 | info->nr_rings = 0; |
| 1921 | 1931 | return -ENOMEM; |
| 1922 | 1932 | } |
| 1923 | 1933 | |
| 1924 | − for (i = 0; i < info->nr_rings; i++) { | |
| 1925 | − struct blkfront_ring_info *rinfo; | |
| 1926 | − | |
| 1927 | − rinfo = &info->rinfo[i]; | |
| 1934 | + for_each_rinfo(info, rinfo, i) { | |
| 1928 | 1935 | INIT_LIST_HEAD(&rinfo->indirect_pages); |
| 1929 | 1936 | INIT_LIST_HEAD(&rinfo->grants); |
| 1930 | 1937 | rinfo->dev_info = info; |
| @@ -2017,6 +2024,7 @@ static int blkif_recover(struct blkfront_info *info) · 86 unmodified lines | ||
| 2017 | 2024 | int rc; |
| 2018 | 2025 | struct bio *bio; |
| 2019 | 2026 | unsigned int segs; |
| 2027 | + struct blkfront_ring_info *rinfo; | |
| 2020 | 2028 | |
| 2021 | 2029 | blkfront_gather_backend_features(info); |
| 2022 | 2030 | /* Reset limits changed by blk_mq_update_nr_hw_queues(). */ |
| @@ -2024,9 +2032,7 @@ static int blkif_recover(struct blkfront_info *info) · 1 unmodified line | ||
| 2024 | 2032 | segs = info->max_indirect_segments ? : BLKIF_MAX_SEGMENTS_PER_REQUEST; |
| 2025 | 2033 | blk_queue_max_segments(info->rq, segs / GRANTS_PER_PSEG); |
| 2026 | 2034 | |
| 2027 | − for (r_index = 0; r_index < info->nr_rings; r_index++) { | |
| 2028 | − struct blkfront_ring_info *rinfo = &info->rinfo[r_index]; | |
| 2029 | − | |
| 2035 | + for_each_rinfo(info, rinfo, r_index) { | |
| 2030 | 2036 | rc = blkfront_setup_indirect(rinfo); |
| 2031 | 2037 | if (rc) |
| 2032 | 2038 | return rc; |
| @@ -2036,10 +2042,7 @@ static int blkif_recover(struct blkfront_info *info) · 3 unmodified lines | ||
| 2036 | 2042 | /* Now safe for us to use the shared ring */ |
| 2037 | 2043 | info->connected = BLKIF_STATE_CONNECTED; |
| 2038 | 2044 | |
| 2039 | − for (r_index = 0; r_index < info->nr_rings; r_index++) { | |
| 2040 | − struct blkfront_ring_info *rinfo; | |
| 2041 | − | |
| 2042 | − rinfo = &info->rinfo[r_index]; | |
| 2045 | + for_each_rinfo(info, rinfo, r_index) { | |
| 2043 | 2046 | /* Kick any other new requests queued since we resumed */ |
| 2044 | 2047 | kick_pending_request_queues(rinfo); |
| 2045 | 2048 | } |
| @@ -2072,13 +2075,13 @@ static int blkfront_resume(struct xenbus_device *dev) · 26 unmodified lines | ||
| 2072 | 2075 | struct blkfront_info *info = dev_get_drvdata(&dev->dev); |
| 2073 | 2076 | int err = 0; |
| 2074 | 2077 | unsigned int i, j; |
| 2078 | + struct blkfront_ring_info *rinfo; | |
| 2075 | 2079 | |
| 2076 | 2080 | dev_dbg(&dev->dev, "blkfront_resume: %s\n", dev->nodename); |
| 2077 | 2081 | |
| 2078 | 2082 | bio_list_init(&info->bio_list); |
| 2079 | 2083 | INIT_LIST_HEAD(&info->requests); |
| 2080 | − for (i = 0; i < info->nr_rings; i++) { | |
| 2081 | − struct blkfront_ring_info *rinfo = &info->rinfo[i]; | |
| 2084 | + for_each_rinfo(info, rinfo, i) { | |
| 2082 | 2085 | struct bio_list merge_bio; |
| 2083 | 2086 | struct blk_shadow *shadow = rinfo->shadow; |
| 2084 | 2087 | |
| @@ -2337,6 +2340,7 @@ static void blkfront_connect(struct blkfront_info *info) · 252 unmodified lines | ||
| 2337 | 2340 | unsigned int binfo; |
| 2338 | 2341 | char *envp[] = { "RESIZE=1", NULL }; |
| 2339 | 2342 | int err, i; |
| 2343 | + struct blkfront_ring_info *rinfo; | |
| 2340 | 2344 | |
| 2341 | 2345 | switch (info->connected) { |
| 2342 | 2346 | case BLKIF_STATE_CONNECTED: |
| @@ -2394,8 +2398,8 @@ static void blkfront_connect(struct blkfront_info *info) · 51 unmodified lines | ||
| 2394 | 2398 | "physical-sector-size", |
| 2395 | 2399 | sector_size); |
| 2396 | 2400 | blkfront_gather_backend_features(info); |
| 2397 | − for (i = 0; i < info->nr_rings; i++) { | |
| 2398 | − err = blkfront_setup_indirect(&info->rinfo[i]); | |
| 2401 | + for_each_rinfo(info, rinfo, i) { | |
| 2402 | + err = blkfront_setup_indirect(rinfo); | |
| 2399 | 2403 | if (err) { |
| 2400 | 2404 | xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s", |
| 2401 | 2405 | info->xbdev->otherend); |
| @@ -2416,8 +2420,8 @@ static void blkfront_connect(struct blkfront_info *info) · 14 unmodified lines | ||
| 2416 | 2420 | |
| 2417 | 2421 | /* Kick pending requests. */ |
| 2418 | 2422 | info->connected = BLKIF_STATE_CONNECTED; |
| 2419 | − for (i = 0; i < info->nr_rings; i++) | |
| 2420 | − kick_pending_request_queues(&info->rinfo[i]); | |
| 2423 | + for_each_rinfo(info, rinfo, i) | |
| 2424 | + kick_pending_request_queues(rinfo); | |
| 2421 | 2425 | |
| 2422 | 2426 | device_add_disk(&info->xbdev->dev, info->gd, NULL); |
| 2423 | 2427 | |
| @@ -2652,9 +2656,9 @@ static void purge_persistent_grants(struct blkfront_info *info) · 228 unmodified lines | ||
| 2652 | 2656 | { |
| 2653 | 2657 | unsigned int i; |
| 2654 | 2658 | unsigned long flags; |
| 2659 | + struct blkfront_ring_info *rinfo; | |
| 2655 | 2660 | |
| 2656 | − for (i = 0; i < info->nr_rings; i++) { | |
| 2657 | − struct blkfront_ring_info *rinfo = &info->rinfo[i]; | |
| 2661 | + for_each_rinfo(info, rinfo, i) { | |
| 2658 | 2662 | struct grant *gnt_list_entry, *tmp; |
| 2659 | 2663 | |
| 2660 | 2664 | spin_lock_irqsave(&rinfo->ring_lock, flags); |
| @@ -1400,7 +1400,7 @@ static void sysc_init_revision_quirks(struct sysc *ddata) · 1399 unmodified lines | ||
| 1400 | 1400 | } |
| 1401 | 1401 | |
| 1402 | 1402 | /* 1-wire needs module's internal clocks enabled for reset */ |
| 1403 | −static void sysc_clk_enable_quirk_hdq1w(struct sysc *ddata) | |
| 1403 | +static void sysc_pre_reset_quirk_hdq1w(struct sysc *ddata) | |
| 1404 | 1404 | { |
| 1405 | 1405 | int offset = 0x0c; /* HDQ_CTRL_STATUS */ |
| 1406 | 1406 | u16 val; |
| @@ -1488,7 +1488,7 @@ static void sysc_init_module_quirks(struct sysc *ddata) · 81 unmodified lines | ||
| 1488 | 1488 | return; |
| 1489 | 1489 | |
| 1490 | 1490 | if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_HDQ1W) { |
| 1491 | − ddata->clk_enable_quirk = sysc_clk_enable_quirk_hdq1w; | |
| 1491 | + ddata->clk_disable_quirk = sysc_pre_reset_quirk_hdq1w; | |
| 1492 | 1492 | |
| 1493 | 1493 | return; |
| 1494 | 1494 | } |
| @@ -519,7 +519,7 @@ static const struct block_device_operations gdrom_bdops = { · 518 unmodified lines | ||
| 519 | 519 | .check_events = gdrom_bdops_check_events, |
| 520 | 520 | .ioctl = gdrom_bdops_ioctl, |
| 521 | 521 | #ifdef CONFIG_COMPAT |
| 522 | − .ioctl = blkdev_compat_ptr_ioctl, | |
| 522 | + .compat_ioctl = blkdev_compat_ptr_ioctl, | |
| 523 | 523 | #endif |
| 524 | 524 | }; |
| 525 | 525 | |
| @@ -194,7 +194,7 @@ static int platform_ipmi_probe(struct platform_device *pdev) · 193 unmodified lines | ||
| 194 | 194 | else |
| 195 | 195 | io.slave_addr = slave_addr; |
| 196 | 196 | |
| 197 | − io.irq = platform_get_irq(pdev, 0); | |
| 197 | + io.irq = platform_get_irq_optional(pdev, 0); | |
| 198 | 198 | if (io.irq > 0) |
| 199 | 199 | io.irq_setup = ipmi_std_irq_setup; |
| 200 | 200 | else |
| @@ -378,7 +378,7 @@ static int acpi_ipmi_probe(struct platform_device *pdev) · 177 unmodified lines | ||
| 378 | 378 | io.irq = tmp; |
| 379 | 379 | io.irq_setup = acpi_gpe_irq_setup; |
| 380 | 380 | } else { |
| 381 | − int irq = platform_get_irq(pdev, 0); | |
| 381 | + int irq = platform_get_irq_optional(pdev, 0); | |
| 382 | 382 | |
| 383 | 383 | if (irq > 0) { |
| 384 | 384 | io.irq = irq; |
| @@ -4713,7 +4713,7 @@ EXPORT_SYMBOL(of_clk_get_by_name); · 4712 unmodified lines | ||
| 4713 | 4713 | * |
| 4714 | 4714 | * Returns: The number of clocks that are possible parents of this node |
| 4715 | 4715 | */ |
| 4716 | −unsigned int of_clk_get_parent_count(struct device_node *np) | |
| 4716 | +unsigned int of_clk_get_parent_count(const struct device_node *np) | |
| 4717 | 4717 | { |
| 4718 | 4718 | int count; |
| 4719 | 4719 | |
| @@ -4725,7 +4725,7 @@ unsigned int of_clk_get_parent_count(struct device_node *np) · 5 unmodified lines | ||
| 4725 | 4725 | } |
| 4726 | 4726 | EXPORT_SYMBOL_GPL(of_clk_get_parent_count); |
| 4727 | 4727 | |
| 4728 | −const char *of_clk_get_parent_name(struct device_node *np, int index) | |
| 4728 | +const char *of_clk_get_parent_name(const struct device_node *np, int index) | |
| 4729 | 4729 | { |
| 4730 | 4730 | struct of_phandle_args clkspec; |
| 4731 | 4731 | struct property *prop; |
| @@ -592,24 +592,6 @@ static struct clk_branch disp_cc_mdss_rot_clk = { · 591 unmodified lines | ||
| 592 | 592 | }, |
| 593 | 593 | }; |
| 594 | 594 | |
| 595 | −static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { | |
| 596 | − .halt_reg = 0x400c, | |
| 597 | − .halt_check = BRANCH_HALT, | |
| 598 | − .clkr = { | |
| 599 | − .enable_reg = 0x400c, | |
| 600 | − .enable_mask = BIT(0), | |
| 601 | − .hw.init = &(struct clk_init_data){ | |
| 602 | − .name = "disp_cc_mdss_rscc_ahb_clk", | |
| 603 | − .parent_data = &(const struct clk_parent_data){ | |
| 604 | − .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw, | |
| 605 | − }, | |
| 606 | − .num_parents = 1, | |
| 607 | − .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, | |
| 608 | − .ops = &clk_branch2_ops, | |
| 609 | − }, | |
| 610 | − }, | |
| 611 | −}; | |
| 612 | − | |
| 613 | 595 | static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { |
| 614 | 596 | .halt_reg = 0x4008, |
| 615 | 597 | .halt_check = BRANCH_HALT, |
| @@ -687,7 +669,6 @@ static struct clk_regmap *disp_cc_sc7180_clocks[] = { · 71 unmodified lines | ||
| 687 | 669 | [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, |
| 688 | 670 | [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, |
| 689 | 671 | [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, |
| 690 | − [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, | |
| 691 | 672 | [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, |
| 692 | 673 | [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, |
| 693 | 674 | [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, |
| @@ -97,7 +97,7 @@ static struct clk_branch video_cc_vcodec0_axi_clk = { · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | static struct clk_branch video_cc_vcodec0_core_clk = { |
| 99 | 99 | .halt_reg = 0x890, |
| 100 | − .halt_check = BRANCH_HALT, | |
| 100 | + .halt_check = BRANCH_HALT_VOTED, | |
| 101 | 101 | .clkr = { |
| 102 | 102 | .enable_reg = 0x890, |
| 103 | 103 | .enable_mask = BIT(0), |
| @@ -1076,9 +1076,17 @@ static int cpufreq_init_policy(struct cpufreq_policy *policy) · 1075 unmodified lines | ||
| 1076 | 1076 | pol = policy->last_policy; |
| 1077 | 1077 | } else if (def_gov) { |
| 1078 | 1078 | pol = cpufreq_parse_policy(def_gov->name); |
| 1079 | − } else { | |
| 1080 | − return -ENODATA; | |
| 1079 | + /* | |
| 1080 | + * In case the default governor is neiter "performance" | |
| 1081 | + * nor "powersave", fall back to the initial policy | |
| 1082 | + * value set by the driver. | |
| 1083 | + */ | |
| 1084 | + if (pol == CPUFREQ_POLICY_UNKNOWN) | |
| 1085 | + pol = policy->policy; | |
| 1081 | 1086 | } |
| 1087 | + if (pol != CPUFREQ_POLICY_PERFORMANCE && | |
| 1088 | + pol != CPUFREQ_POLICY_POWERSAVE) | |
| 1089 | + return -ENODATA; | |
| 1082 | 1090 | } |
| 1083 | 1091 | |
| 1084 | 1092 | return cpufreq_set_policy(policy, gov, pol); |
| @@ -738,7 +738,6 @@ struct devfreq *devfreq_add_device(struct device *dev, · 737 unmodified lines | ||
| 738 | 738 | { |
| 739 | 739 | struct devfreq *devfreq; |
| 740 | 740 | struct devfreq_governor *governor; |
| 741 | − static atomic_t devfreq_no = ATOMIC_INIT(-1); | |
| 742 | 741 | int err = 0; |
| 743 | 742 | |
| 744 | 743 | if (!dev || !profile || !governor_name) { |
| @@ -800,8 +799,7 @@ struct devfreq *devfreq_add_device(struct device *dev, · 55 unmodified lines | ||
| 800 | 799 | devfreq->suspend_freq = dev_pm_opp_get_suspend_opp_freq(dev); |
| 801 | 800 | atomic_set(&devfreq->suspend_count, 0); |
| 802 | 801 | |
| 803 | − dev_set_name(&devfreq->dev, "devfreq%d", | |
| 804 | − atomic_inc_return(&devfreq_no)); | |
| 802 | + dev_set_name(&devfreq->dev, "%s", dev_name(dev)); | |
| 805 | 803 | err = device_register(&devfreq->dev); |
| 806 | 804 | if (err) { |
| 807 | 805 | mutex_unlock(&devfreq->lock); |
| @@ -108,6 +108,7 @@ static int dma_buf_release(struct inode *inode, struct file *file) · 107 unmodified lines | ||
| 108 | 108 | dma_resv_fini(dmabuf->resv); |
| 109 | 109 | |
| 110 | 110 | module_put(dmabuf->owner); |
| 111 | + kfree(dmabuf->name); | |
| 111 | 112 | kfree(dmabuf); |
| 112 | 113 | return 0; |
| 113 | 114 | } |
| @@ -1947,8 +1947,6 @@ static void dma_tc_handle(struct coh901318_chan *cohc) · 1946 unmodified lines | ||
| 1947 | 1947 | return; |
| 1948 | 1948 | } |
| 1949 | 1949 | |
| 1950 | − spin_lock(&cohc->lock); | |
| 1951 | − | |
| 1952 | 1950 | /* |
| 1953 | 1951 | * When we reach this point, at least one queue item |
| 1954 | 1952 | * should have been moved over from cohc->queue to |
| @@ -1969,8 +1967,6 @@ static void dma_tc_handle(struct coh901318_chan *cohc) · 14 unmodified lines | ||
| 1969 | 1967 | if (coh901318_queue_start(cohc) == NULL) |
| 1970 | 1968 | cohc->busy = 0; |
| 1971 | 1969 | |
| 1972 | − spin_unlock(&cohc->lock); | |
| 1973 | − | |
| 1974 | 1970 | /* |
| 1975 | 1971 | * This tasklet will remove items from cohc->active |
| 1976 | 1972 | * and thus terminates them. |
| @@ -204,6 +204,7 @@ static int idxd_wq_cdev_dev_setup(struct idxd_wq *wq) · 203 unmodified lines | ||
| 204 | 204 | minor = ida_simple_get(&cdev_ctx->minor_ida, 0, MINORMASK, GFP_KERNEL); |
| 205 | 205 | if (minor < 0) { |
| 206 | 206 | rc = minor; |
| 207 | + kfree(dev); | |
| 207 | 208 | goto ida_err; |
| 208 | 209 | } |
| 209 | 210 | |
| @@ -212,7 +213,6 @@ static int idxd_wq_cdev_dev_setup(struct idxd_wq *wq) · 2 unmodified lines | ||
| 212 | 213 | rc = device_register(dev); |
| 213 | 214 | if (rc < 0) { |
| 214 | 215 | dev_err(&idxd->pdev->dev, "device register failed\n"); |
| 215 | − put_device(dev); | |
| 216 | 216 | goto dev_reg_err; |
| 217 | 217 | } |
| 218 | 218 | idxd_cdev->minor = minor; |
| @@ -221,8 +221,8 @@ static int idxd_wq_cdev_dev_setup(struct idxd_wq *wq) · 2 unmodified lines | ||
| 221 | 221 | |
| 222 | 222 | dev_reg_err: |
| 223 | 223 | ida_simple_remove(&cdev_ctx->minor_ida, MINOR(dev->devt)); |
| 224 | + put_device(dev); | |
| 224 | 225 | ida_err: |
| 225 | − kfree(dev); | |
| 226 | 226 | idxd_cdev->dev = NULL; |
| 227 | 227 | return rc; |
| 228 | 228 | } |
| @@ -124,6 +124,7 @@ static int idxd_config_bus_probe(struct device *dev) · 123 unmodified lines | ||
| 124 | 124 | rc = idxd_device_config(idxd); |
| 125 | 125 | if (rc < 0) { |
| 126 | 126 | spin_unlock_irqrestore(&idxd->dev_lock, flags); |
| 127 | + module_put(THIS_MODULE); | |
| 127 | 128 | dev_warn(dev, "Device config failed: %d\n", rc); |
| 128 | 129 | return rc; |
| 129 | 130 | } |
| @@ -132,6 +133,7 @@ static int idxd_config_bus_probe(struct device *dev) · 2 unmodified lines | ||
| 132 | 133 | rc = idxd_device_enable(idxd); |
| 133 | 134 | if (rc < 0) { |
| 134 | 135 | spin_unlock_irqrestore(&idxd->dev_lock, flags); |
| 136 | + module_put(THIS_MODULE); | |
| 135 | 137 | dev_warn(dev, "Device enable failed: %d\n", rc); |
| 136 | 138 | return rc; |
| 137 | 139 | } |
| @@ -142,6 +144,7 @@ static int idxd_config_bus_probe(struct device *dev) · 4 unmodified lines | ||
| 142 | 144 | rc = idxd_register_dma_device(idxd); |
| 143 | 145 | if (rc < 0) { |
| 144 | 146 | spin_unlock_irqrestore(&idxd->dev_lock, flags); |
| 147 | + module_put(THIS_MODULE); | |
| 145 | 148 | dev_dbg(dev, "Failed to register dmaengine device\n"); |
| 146 | 149 | return rc; |
| 147 | 150 | } |
| @@ -516,7 +519,7 @@ static ssize_t group_tokens_reserved_store(struct device *dev, · 368 unmodified lines | ||
| 516 | 519 | if (val > idxd->max_tokens) |
| 517 | 520 | return -EINVAL; |
| 518 | 521 | |
| 519 | − if (val > idxd->nr_tokens) | |
| 522 | + if (val > idxd->nr_tokens + group->tokens_reserved) | |
| 520 | 523 | return -EINVAL; |
| 521 | 524 | |
| 522 | 525 | group->tokens_reserved = val; |
| @@ -901,6 +904,20 @@ static ssize_t wq_size_show(struct device *dev, struct device_attribute *attr, · 378 unmodified lines | ||
| 901 | 904 | return sprintf(buf, "%u\n", wq->size); |
| 902 | 905 | } |
| 903 | 906 | |
| 907 | +static int total_claimed_wq_size(struct idxd_device *idxd) | |
| 908 | +{ | |
| 909 | + int i; | |
| 910 | + int wq_size = 0; | |
| 911 | + | |
| 912 | + for (i = 0; i < idxd->max_wqs; i++) { | |
| 913 | + struct idxd_wq *wq = &idxd->wqs[i]; | |
| 914 | + | |
| 915 | + wq_size += wq->size; | |
| 916 | + } | |
| 917 | + | |
| 918 | + return wq_size; | |
| 919 | +} | |
| 920 | + | |
| 904 | 921 | static ssize_t wq_size_store(struct device *dev, |
| 905 | 922 | struct device_attribute *attr, const char *buf, |
| 906 | 923 | size_t count) |
| @@ -920,7 +937,7 @@ static ssize_t wq_size_store(struct device *dev, · 13 unmodified lines | ||
| 920 | 937 | if (wq->state != IDXD_WQ_DISABLED) |
| 921 | 938 | return -EPERM; |
| 922 | 939 | |
| 923 | − if (size > idxd->max_wq_size) | |
| 940 | + if (size + total_claimed_wq_size(idxd) - wq->size > idxd->max_wq_size) | |
| 924 | 941 | return -EINVAL; |
| 925 | 942 | |
| 926 | 943 | wq->size = size; |
| @@ -999,12 +1016,14 @@ static ssize_t wq_type_store(struct device *dev, · 72 unmodified lines | ||
| 999 | 1016 | return -EPERM; |
| 1000 | 1017 | |
| 1001 | 1018 | old_type = wq->type; |
| 1002 | − if (sysfs_streq(buf, idxd_wq_type_names[IDXD_WQT_KERNEL])) | |
| 1019 | + if (sysfs_streq(buf, idxd_wq_type_names[IDXD_WQT_NONE])) | |
| 1020 | + wq->type = IDXD_WQT_NONE; | |
| 1021 | + else if (sysfs_streq(buf, idxd_wq_type_names[IDXD_WQT_KERNEL])) | |
| 1003 | 1022 | wq->type = IDXD_WQT_KERNEL; |
| 1004 | 1023 | else if (sysfs_streq(buf, idxd_wq_type_names[IDXD_WQT_USER])) |
| 1005 | 1024 | wq->type = IDXD_WQT_USER; |
| 1006 | 1025 | else |
| 1007 | − wq->type = IDXD_WQT_NONE; | |
| 1026 | + return -EINVAL; | |
| 1008 | 1027 | |
| 1009 | 1028 | /* If we are changing queue type, clear the name */ |
| 1010 | 1029 | if (wq->type != old_type) |
| @@ -1331,13 +1331,14 @@ static void sdma_free_chan_resources(struct dma_chan *chan) · 1330 unmodified lines | ||
| 1331 | 1331 | |
| 1332 | 1332 | sdma_channel_synchronize(chan); |
| 1333 | 1333 | |
| 1334 | − if (sdmac->event_id0) | |
| 1334 | + if (sdmac->event_id0 >= 0) | |
| 1335 | 1335 | sdma_event_disable(sdmac, sdmac->event_id0); |
| 1336 | 1336 | if (sdmac->event_id1) |
| 1337 | 1337 | sdma_event_disable(sdmac, sdmac->event_id1); |
| 1338 | 1338 | |
| 1339 | 1339 | sdmac->event_id0 = 0; |
| 1340 | 1340 | sdmac->event_id1 = 0; |
| 1341 | + sdmac->context_loaded = false; | |
| 1341 | 1342 | |
| 1342 | 1343 | sdma_set_channel_priority(sdmac, 0); |
| 1343 | 1344 | |
| @@ -1631,7 +1632,7 @@ static int sdma_config(struct dma_chan *chan, · 287 unmodified lines | ||
| 1631 | 1632 | memcpy(&sdmac->slave_config, dmaengine_cfg, sizeof(*dmaengine_cfg)); |
| 1632 | 1633 | |
| 1633 | 1634 | /* Set ENBLn earlier to make sure dma request triggered after that */ |
| 1634 | − if (sdmac->event_id0) { | |
| 1635 | + if (sdmac->event_id0 >= 0) { | |
| 1635 | 1636 | if (sdmac->event_id0 >= sdmac->sdma->drvdata->num_events) |
| 1636 | 1637 | return -EINVAL; |
| 1637 | 1638 | sdma_event_enable(sdmac, sdmac->event_id0); |
| @@ -281,7 +281,7 @@ static struct tegra_dma_desc *tegra_dma_desc_get( · 280 unmodified lines | ||
| 281 | 281 | |
| 282 | 282 | /* Do not allocate if desc are waiting for ack */ |
| 283 | 283 | list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) { |
| 284 | − if (async_tx_test_ack(&dma_desc->txd)) { | |
| 284 | + if (async_tx_test_ack(&dma_desc->txd) && !dma_desc->cb_count) { | |
| 285 | 285 | list_del(&dma_desc->node); |
| 286 | 286 | spin_unlock_irqrestore(&tdc->lock, flags); |
| 287 | 287 | dma_desc->txd.flags = 0; |
| @@ -756,10 +756,6 @@ static int tegra_dma_terminate_all(struct dma_chan *dc) · 468 unmodified lines | ||
| 756 | 756 | bool was_busy; |
| 757 | 757 | |
| 758 | 758 | spin_lock_irqsave(&tdc->lock, flags); |
| 759 | − if (list_empty(&tdc->pending_sg_req)) { | |
| 760 | − spin_unlock_irqrestore(&tdc->lock, flags); | |
| 761 | − return 0; | |
| 762 | − } | |
| 763 | 759 | |
| 764 | 760 | if (!tdc->busy) |
| 765 | 761 | goto skip_dma_stop; |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | 7 | #include <linux/kernel.h> |
| 8 | +#include <linux/delay.h> | |
| 8 | 9 | #include <linux/dmaengine.h> |
| 9 | 10 | #include <linux/dma-mapping.h> |
| 10 | 11 | #include <linux/dmapool.h> |
| @@ -96,6 +97,24 @@ struct udma_match_data { · 85 unmodified lines | ||
| 96 | 97 | u32 level_start_idx[]; |
| 97 | 98 | }; |
| 98 | 99 | |
| 100 | +struct udma_hwdesc { | |
| 101 | + size_t cppi5_desc_size; | |
| 102 | + void *cppi5_desc_vaddr; | |
| 103 | + dma_addr_t cppi5_desc_paddr; | |
| 104 | + | |
| 105 | + /* TR descriptor internal pointers */ | |
| 106 | + void *tr_req_base; | |
| 107 | + struct cppi5_tr_resp_t *tr_resp_base; | |
| 108 | +}; | |
| 109 | + | |
| 110 | +struct udma_rx_flush { | |
| 111 | + struct udma_hwdesc hwdescs[2]; | |
| 112 | + | |
| 113 | + size_t buffer_size; | |
| 114 | + void *buffer_vaddr; | |
| 115 | + dma_addr_t buffer_paddr; | |
| 116 | +}; | |
| 117 | + | |
| 99 | 118 | struct udma_dev { |
| 100 | 119 | struct dma_device ddev; |
| 101 | 120 | struct device *dev; |
| @@ -112,6 +131,8 @@ struct udma_dev { · 10 unmodified lines | ||
| 112 | 131 | struct list_head desc_to_purge; |
| 113 | 132 | spinlock_t lock; |
| 114 | 133 | |
| 134 | + struct udma_rx_flush rx_flush; | |
| 135 | + | |
| 115 | 136 | int tchan_cnt; |
| 116 | 137 | int echan_cnt; |
| 117 | 138 | int rchan_cnt; |
| @@ -130,16 +151,6 @@ struct udma_dev { · 12 unmodified lines | ||
| 130 | 151 | u32 psil_base; |
| 131 | 152 | }; |
| 132 | 153 | |
| 133 | −struct udma_hwdesc { | |
| 134 | − size_t cppi5_desc_size; | |
| 135 | − void *cppi5_desc_vaddr; | |
| 136 | − dma_addr_t cppi5_desc_paddr; | |
| 137 | − | |
| 138 | − /* TR descriptor internal pointers */ | |
| 139 | − void *tr_req_base; | |
| 140 | − struct cppi5_tr_resp_t *tr_resp_base; | |
| 141 | −}; | |
| 142 | − | |
| 143 | 154 | struct udma_desc { |
| 144 | 155 | struct virt_dma_desc vd; |
| 145 | 156 | |
| @@ -169,7 +180,7 @@ enum udma_chan_state { · 23 unmodified lines | ||
| 169 | 180 | |
| 170 | 181 | struct udma_tx_drain { |
| 171 | 182 | struct delayed_work work; |
| 172 | − unsigned long jiffie; | |
| 183 | + ktime_t tstamp; | |
| 173 | 184 | u32 residue; |
| 174 | 185 | }; |
| 175 | 186 | |
| @@ -502,7 +513,7 @@ static bool udma_is_chan_paused(struct udma_chan *uc) · 326 unmodified lines | ||
| 502 | 513 | { |
| 503 | 514 | u32 val, pause_mask; |
| 504 | 515 | |
| 505 | − switch (uc->desc->dir) { | |
| 516 | + switch (uc->config.dir) { | |
| 506 | 517 | case DMA_DEV_TO_MEM: |
| 507 | 518 | val = udma_rchanrt_read(uc->rchan, |
| 508 | 519 | UDMA_RCHAN_RT_PEER_RT_EN_REG); |
| @@ -551,12 +562,17 @@ static void udma_sync_for_device(struct udma_chan *uc, int idx) · 42 unmodified lines | ||
| 551 | 562 | } |
| 552 | 563 | } |
| 553 | 564 | |
| 565 | +static inline dma_addr_t udma_get_rx_flush_hwdesc_paddr(struct udma_chan *uc) | |
| 566 | +{ | |
| 567 | + return uc->ud->rx_flush.hwdescs[uc->config.pkt_mode].cppi5_desc_paddr; | |
| 568 | +} | |
| 569 | + | |
| 554 | 570 | static int udma_push_to_ring(struct udma_chan *uc, int idx) |
| 555 | 571 | { |
| 556 | 572 | struct udma_desc *d = uc->desc; |
| 557 | − | |
| 558 | 573 | struct k3_ring *ring = NULL; |
| 559 | − int ret = -EINVAL; | |
| 574 | + dma_addr_t paddr; | |
| 575 | + int ret; | |
| 560 | 576 | |
| 561 | 577 | switch (uc->config.dir) { |
| 562 | 578 | case DMA_DEV_TO_MEM: |
| @@ -567,21 +583,37 @@ static int udma_push_to_ring(struct udma_chan *uc, int idx) · 4 unmodified lines | ||
| 567 | 583 | ring = uc->tchan->t_ring; |
| 568 | 584 | break; |
| 569 | 585 | default: |
| 570 | − break; | |
| 586 | + return -EINVAL; | |
| 571 | 587 | } |
| 572 | 588 | |
| 573 | − if (ring) { | |
| 574 | − dma_addr_t desc_addr = udma_curr_cppi5_desc_paddr(d, idx); | |
| 589 | + /* RX flush packet: idx == -1 is only passed in case of DEV_TO_MEM */ | |
| 590 | + if (idx == -1) { | |
| 591 | + paddr = udma_get_rx_flush_hwdesc_paddr(uc); | |
| 592 | + } else { | |
| 593 | + paddr = udma_curr_cppi5_desc_paddr(d, idx); | |
| 575 | 594 | |
| 576 | 595 | wmb(); /* Ensure that writes are not moved over this point */ |
| 577 | 596 | udma_sync_for_device(uc, idx); |
| 578 | − ret = k3_ringacc_ring_push(ring, &desc_addr); | |
| 579 | − uc->in_ring_cnt++; | |
| 580 | 597 | } |
| 581 | 598 | |
| 599 | + ret = k3_ringacc_ring_push(ring, &paddr); | |
| 600 | + if (!ret) | |
| 601 | + uc->in_ring_cnt++; | |
| 602 | + | |
| 582 | 603 | return ret; |
| 583 | 604 | } |
| 584 | 605 | |
| 606 | +static bool udma_desc_is_rx_flush(struct udma_chan *uc, dma_addr_t addr) | |
| 607 | +{ | |
| 608 | + if (uc->config.dir != DMA_DEV_TO_MEM) | |
| 609 | + return false; | |
| 610 | + | |
| 611 | + if (addr == udma_get_rx_flush_hwdesc_paddr(uc)) | |
| 612 | + return true; | |
| 613 | + | |
| 614 | + return false; | |
| 615 | +} | |
| 616 | + | |
| 585 | 617 | static int udma_pop_from_ring(struct udma_chan *uc, dma_addr_t *addr) |
| 586 | 618 | { |
| 587 | 619 | struct k3_ring *ring = NULL; |
| @@ -610,6 +642,10 @@ static int udma_pop_from_ring(struct udma_chan *uc, dma_addr_t *addr) · 22 unmodified lines | ||
| 610 | 642 | if (cppi5_desc_is_tdcm(*addr)) |
| 611 | 643 | return ret; |
| 612 | 644 | |
| 645 | + /* Check for flush descriptor */ | |
| 646 | + if (udma_desc_is_rx_flush(uc, *addr)) | |
| 647 | + return -ENOENT; | |
| 648 | + | |
| 613 | 649 | d = udma_udma_desc_from_paddr(uc, *addr); |
| 614 | 650 | |
| 615 | 651 | if (d) |
| @@ -890,6 +926,9 @@ static int udma_stop(struct udma_chan *uc) · 274 unmodified lines | ||
| 890 | 926 | |
| 891 | 927 | switch (uc->config.dir) { |
| 892 | 928 | case DMA_DEV_TO_MEM: |
| 929 | + if (!uc->cyclic && !uc->desc) | |
| 930 | + udma_push_to_ring(uc, -1); | |
| 931 | + | |
| 893 | 932 | udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PEER_RT_EN_REG, |
| 894 | 933 | UDMA_PEER_RT_EN_ENABLE | |
| 895 | 934 | UDMA_PEER_RT_EN_TEARDOWN); |
| @@ -946,9 +985,10 @@ static bool udma_is_desc_really_done(struct udma_chan *uc, struct udma_desc *d) · 50 unmodified lines | ||
| 946 | 985 | peer_bcnt = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_PEER_BCNT_REG); |
| 947 | 986 | bcnt = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_BCNT_REG); |
| 948 | 987 | |
| 988 | + /* Transfer is incomplete, store current residue and time stamp */ | |
| 949 | 989 | if (peer_bcnt < bcnt) { |
| 950 | 990 | uc->tx_drain.residue = bcnt - peer_bcnt; |
| 951 | − uc->tx_drain.jiffie = jiffies; | |
| 991 | + uc->tx_drain.tstamp = ktime_get(); | |
| 952 | 992 | return false; |
| 953 | 993 | } |
| 954 | 994 | |
| @@ -961,35 +1001,59 @@ static void udma_check_tx_completion(struct work_struct *work) · 6 unmodified lines | ||
| 961 | 1001 | tx_drain.work.work); |
| 962 | 1002 | bool desc_done = true; |
| 963 | 1003 | u32 residue_diff; |
| 964 | − unsigned long jiffie_diff, delay; | |
| 1004 | + ktime_t time_diff; | |
| 1005 | + unsigned long delay; | |
| 1006 | + | |
| 1007 | + while (1) { | |
| 1008 | + if (uc->desc) { | |
| 1009 | + /* Get previous residue and time stamp */ | |
| 1010 | + residue_diff = uc->tx_drain.residue; | |
| 1011 | + time_diff = uc->tx_drain.tstamp; | |
| 1012 | + /* | |
| 1013 | + * Get current residue and time stamp or see if | |
| 1014 | + * transfer is complete | |
| 1015 | + */ | |
| 1016 | + desc_done = udma_is_desc_really_done(uc, uc->desc); | |
| 1017 | + } | |
| 965 | 1018 | |
| 966 | − if (uc->desc) { | |
| 967 | − residue_diff = uc->tx_drain.residue; | |
| 968 | − jiffie_diff = uc->tx_drain.jiffie; | |
| 969 | − desc_done = udma_is_desc_really_done(uc, uc->desc); | |
| 970 | − } | |
| 971 | − | |
| 972 | − if (!desc_done) { | |
| 973 | − jiffie_diff = uc->tx_drain.jiffie - jiffie_diff; | |
| 974 | − residue_diff -= uc->tx_drain.residue; | |
| 975 | − if (residue_diff) { | |
| 976 | − /* Try to guess when we should check next time */ | |
| 977 | − residue_diff /= jiffie_diff; | |
| 978 | − delay = uc->tx_drain.residue / residue_diff / 3; | |
| 979 | − if (jiffies_to_msecs(delay) < 5) | |
| 980 | − delay = 0; | |
| 981 | − } else { | |
| 982 | − /* No progress, check again in 1 second */ | |
| 983 | − delay = HZ; | |
| 1019 | + if (!desc_done) { | |
| 1020 | + /* | |
| 1021 | + * Find the time delta and residue delta w.r.t | |
| 1022 | + * previous poll | |
| 1023 | + */ | |
| 1024 | + time_diff = ktime_sub(uc->tx_drain.tstamp, | |
| 1025 | + time_diff) + 1; | |
| 1026 | + residue_diff -= uc->tx_drain.residue; | |
| 1027 | + if (residue_diff) { | |
| 1028 | + /* | |
| 1029 | + * Try to guess when we should check | |
| 1030 | + * next time by calculating rate at | |
| 1031 | + * which data is being drained at the | |
| 1032 | + * peer device | |
| 1033 | + */ | |
| 1034 | + delay = (time_diff / residue_diff) * | |
| 1035 | + uc->tx_drain.residue; | |
| 1036 | + } else { | |
| 1037 | + /* No progress, check again in 1 second */ | |
| 1038 | + schedule_delayed_work(&uc->tx_drain.work, HZ); | |
| 1039 | + break; | |
| 1040 | + } | |
| 1041 | + | |
| 1042 | + usleep_range(ktime_to_us(delay), | |
| 1043 | + ktime_to_us(delay) + 10); | |
| 1044 | + continue; | |
| 984 | 1045 | } |
| 985 | 1046 | |
| 986 | − schedule_delayed_work(&uc->tx_drain.work, delay); | |
| 987 | − } else if (uc->desc) { | |
| 988 | − struct udma_desc *d = uc->desc; | |
| 1047 | + if (uc->desc) { | |
| 1048 | + struct udma_desc *d = uc->desc; | |
| 989 | 1049 | |
| 990 | − uc->bcnt += d->residue; | |
| 991 | − udma_start(uc); | |
| 992 | − vchan_cookie_complete(&d->vd); | |
| 1050 | + uc->bcnt += d->residue; | |
| 1051 | + udma_start(uc); | |
| 1052 | + vchan_cookie_complete(&d->vd); | |
| 1053 | + break; | |
| 1054 | + } | |
| 1055 | + | |
| 1056 | + break; | |
| 993 | 1057 | } |
| 994 | 1058 | } |
| 995 | 1059 | |
| @@ -1033,29 +1097,27 @@ static irqreturn_t udma_ring_irq_handler(int irq, void *data) · 37 unmodified lines | ||
| 1033 | 1097 | goto out; |
| 1034 | 1098 | } |
| 1035 | 1099 | |
| 1036 | − if (uc->cyclic) { | |
| 1037 | − /* push the descriptor back to the ring */ | |
| 1038 | − if (d == uc->desc) { | |
| 1100 | + if (d == uc->desc) { | |
| 1101 | + /* active descriptor */ | |
| 1102 | + if (uc->cyclic) { | |
| 1039 | 1103 | udma_cyclic_packet_elapsed(uc); |
| 1040 | 1104 | vchan_cyclic_callback(&d->vd); |
| 1041 | − } | |
| 1042 | − } else { | |
| 1043 | − bool desc_done = false; | |
| 1044 | − | |
| 1045 | − if (d == uc->desc) { | |
| 1046 | − desc_done = udma_is_desc_really_done(uc, d); | |
| 1047 | − | |
| 1048 | − if (desc_done) { | |
| 1105 | + } else { | |
| 1106 | + if (udma_is_desc_really_done(uc, d)) { | |
| 1049 | 1107 | uc->bcnt += d->residue; |
| 1050 | 1108 | udma_start(uc); |
| 1109 | + vchan_cookie_complete(&d->vd); | |
| 1051 | 1110 | } else { |
| 1052 | 1111 | schedule_delayed_work(&uc->tx_drain.work, |
| 1053 | 1112 | 0); |
| 1054 | 1113 | } |
| 1055 | 1114 | } |
| 1056 | − | |
| 1057 | − if (desc_done) | |
| 1058 | − vchan_cookie_complete(&d->vd); | |
| 1115 | + } else { | |
| 1116 | + /* | |
| 1117 | + * terminated descriptor, mark the descriptor as | |
| 1118 | + * completed to update the channel's cookie marker | |
| 1119 | + */ | |
| 1120 | + dma_cookie_complete(&d->vd.tx); | |
| 1059 | 1121 | } |
| 1060 | 1122 | } |
| 1061 | 1123 | out: |
| @@ -1965,36 +2027,81 @@ static struct udma_desc *udma_alloc_tr_desc(struct udma_chan *uc, · 903 unmodified lines | ||
| 1965 | 2027 | return d; |
| 1966 | 2028 | } |
| 1967 | 2029 | |
| 2030 | +/** | |
| 2031 | + * udma_get_tr_counters - calculate TR counters for a given length | |
| 2032 | + * @len: Length of the trasnfer | |
| 2033 | + * @align_to: Preferred alignment | |
| 2034 | + * @tr0_cnt0: First TR icnt0 | |
| 2035 | + * @tr0_cnt1: First TR icnt1 | |
| 2036 | + * @tr1_cnt0: Second (if used) TR icnt0 | |
| 2037 | + * | |
| 2038 | + * For len < SZ_64K only one TR is enough, tr1_cnt0 is not updated | |
| 2039 | + * For len >= SZ_64K two TRs are used in a simple way: | |
| 2040 | + * First TR: SZ_64K-alignment blocks (tr0_cnt0, tr0_cnt1) | |
| 2041 | + * Second TR: the remaining length (tr1_cnt0) | |
| 2042 | + * | |
| 2043 | + * Returns the number of TRs the length needs (1 or 2) | |
| 2044 | + * -EINVAL if the length can not be supported | |
| 2045 | + */ | |
| 2046 | +static int udma_get_tr_counters(size_t len, unsigned long align_to, | |
| 2047 | + u16 *tr0_cnt0, u16 *tr0_cnt1, u16 *tr1_cnt0) | |
| 2048 | +{ | |
| 2049 | + if (len < SZ_64K) { | |
| 2050 | + *tr0_cnt0 = len; | |
| 2051 | + *tr0_cnt1 = 1; | |
| 2052 | + | |
| 2053 | + return 1; | |
| 2054 | + } | |
| 2055 | + | |
| 2056 | + if (align_to > 3) | |
| 2057 | + align_to = 3; | |
| 2058 | + | |
| 2059 | +realign: | |
| 2060 | + *tr0_cnt0 = SZ_64K - BIT(align_to); | |
| 2061 | + if (len / *tr0_cnt0 >= SZ_64K) { | |
| 2062 | + if (align_to) { | |
| 2063 | + align_to--; | |
| 2064 | + goto realign; | |
| 2065 | + } | |
| 2066 | + return -EINVAL; | |
| 2067 | + } | |
| 2068 | + | |
| 2069 | + *tr0_cnt1 = len / *tr0_cnt0; | |
| 2070 | + *tr1_cnt0 = len % *tr0_cnt0; | |
| 2071 | + | |
| 2072 | + return 2; | |
| 2073 | +} | |
| 2074 | + | |
| 1968 | 2075 | static struct udma_desc * |
| 1969 | 2076 | udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, |
| 1970 | 2077 | unsigned int sglen, enum dma_transfer_direction dir, |
| 1971 | 2078 | unsigned long tx_flags, void *context) |
| 1972 | 2079 | { |
| 1973 | − enum dma_slave_buswidth dev_width; | |
| 1974 | 2080 | struct scatterlist *sgent; |
| 1975 | 2081 | struct udma_desc *d; |
| 1976 | − size_t tr_size; | |
| 1977 | 2082 | struct cppi5_tr_type1_t *tr_req = NULL; |
| 2083 | + u16 tr0_cnt0, tr0_cnt1, tr1_cnt0; | |
| 1978 | 2084 | unsigned int i; |
| 1979 | − u32 burst; | |
| 2085 | + size_t tr_size; | |
| 2086 | + int num_tr = 0; | |
| 2087 | + int tr_idx = 0; | |
| 1980 | 2088 | |
| 1981 | − if (dir == DMA_DEV_TO_MEM) { | |
| 1982 | − dev_width = uc->cfg.src_addr_width; | |
| 1983 | − burst = uc->cfg.src_maxburst; | |
| 1984 | − } else if (dir == DMA_MEM_TO_DEV) { | |
| 1985 | − dev_width = uc->cfg.dst_addr_width; | |
| 1986 | − burst = uc->cfg.dst_maxburst; | |
| 1987 | − } else { | |
| 1988 | − dev_err(uc->ud->dev, "%s: bad direction?\n", __func__); | |
| 2089 | + if (!is_slave_direction(dir)) { | |
| 2090 | + dev_err(uc->ud->dev, "Only slave cyclic is supported\n"); | |
| 1989 | 2091 | return NULL; |
| 1990 | 2092 | } |
| 1991 | 2093 | |
| 1992 | − if (!burst) | |
| 1993 | − burst = 1; | |
| 2094 | + /* estimate the number of TRs we will need */ | |
| 2095 | + for_each_sg(sgl, sgent, sglen, i) { | |
| 2096 | + if (sg_dma_len(sgent) < SZ_64K) | |
| 2097 | + num_tr++; | |
| 2098 | + else | |
| 2099 | + num_tr += 2; | |
| 2100 | + } | |
| 1994 | 2101 | |
| 1995 | 2102 | /* Now allocate and setup the descriptor. */ |
| 1996 | 2103 | tr_size = sizeof(struct cppi5_tr_type1_t); |
| 1997 | − d = udma_alloc_tr_desc(uc, tr_size, sglen, dir); | |
| 2104 | + d = udma_alloc_tr_desc(uc, tr_size, num_tr, dir); | |
| 1998 | 2105 | if (!d) |
| 1999 | 2106 | return NULL; |
| 2000 | 2107 | |
| @@ -2002,19 +2109,46 @@ udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl, · 1 unmodified line | ||
| 2002 | 2109 | |
| 2003 | 2110 | tr_req = d->hwdesc[0].tr_req_base; |
| 2004 | 2111 | for_each_sg(sgl, sgent, sglen, i) { |
| 2005 | − d->residue += sg_dma_len(sgent); | |
| 2112 | + dma_addr_t sg_addr = sg_dma_address(sgent); | |
| 2113 | + | |
| 2114 | + num_tr = udma_get_tr_counters(sg_dma_len(sgent), __ffs(sg_addr), | |
| 2115 | + &tr0_cnt0, &tr0_cnt1, &tr1_cnt0); | |
| 2116 | + if (num_tr < 0) { | |
| 2117 | + dev_err(uc->ud->dev, "size %u is not supported\n", | |
| 2118 | + sg_dma_len(sgent)); | |
| 2119 | + udma_free_hwdesc(uc, d); | |
| 2120 | + kfree(d); | |
| 2121 | + return NULL; | |
| 2122 | + } | |
| 2006 | 2123 | |
| 2007 | 2124 | cppi5_tr_init(&tr_req[i].flags, CPPI5_TR_TYPE1, false, false, |
| 2008 | 2125 | CPPI5_TR_EVENT_SIZE_COMPLETION, 0); |
| 2009 | 2126 | cppi5_tr_csf_set(&tr_req[i].flags, CPPI5_TR_CSF_SUPR_EVT); |
| 2010 | 2127 | |
| 2011 | − tr_req[i].addr = sg_dma_address(sgent); | |
| 2012 | − tr_req[i].icnt0 = burst * dev_width; | |
| 2013 | − tr_req[i].dim1 = burst * dev_width; | |
| 2014 | − tr_req[i].icnt1 = sg_dma_len(sgent) / tr_req[i].icnt0; | |
| 2128 | + tr_req[tr_idx].addr = sg_addr; | |
| 2129 | + tr_req[tr_idx].icnt0 = tr0_cnt0; | |
| 2130 | + tr_req[tr_idx].icnt1 = tr0_cnt1; | |
| 2131 | + tr_req[tr_idx].dim1 = tr0_cnt0; | |
| 2132 | + tr_idx++; | |
| 2133 | + | |
| 2134 | + if (num_tr == 2) { | |
| 2135 | + cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1, | |
| 2136 | + false, false, | |
| 2137 | + CPPI5_TR_EVENT_SIZE_COMPLETION, 0); | |
| 2138 | + cppi5_tr_csf_set(&tr_req[tr_idx].flags, | |
| 2139 | + CPPI5_TR_CSF_SUPR_EVT); | |
| 2140 | + | |
| 2141 | + tr_req[tr_idx].addr = sg_addr + tr0_cnt1 * tr0_cnt0; | |
| 2142 | + tr_req[tr_idx].icnt0 = tr1_cnt0; | |
| 2143 | + tr_req[tr_idx].icnt1 = 1; | |
| 2144 | + tr_req[tr_idx].dim1 = tr1_cnt0; | |
| 2145 | + tr_idx++; | |
| 2146 | + } | |
| 2147 | + | |
| 2148 | + d->residue += sg_dma_len(sgent); | |
| 2015 | 2149 | } |
| 2016 | 2150 | |
| 2017 | − cppi5_tr_csf_set(&tr_req[i - 1].flags, CPPI5_TR_CSF_EOP); | |
| 2151 | + cppi5_tr_csf_set(&tr_req[tr_idx - 1].flags, CPPI5_TR_CSF_EOP); | |
| 2018 | 2152 | |
| 2019 | 2153 | return d; |
| 2020 | 2154 | } |
| @@ -2319,47 +2453,66 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr, · 298 unmodified lines | ||
| 2319 | 2453 | size_t buf_len, size_t period_len, |
| 2320 | 2454 | enum dma_transfer_direction dir, unsigned long flags) |
| 2321 | 2455 | { |
| 2322 | − enum dma_slave_buswidth dev_width; | |
| 2323 | 2456 | struct udma_desc *d; |
| 2324 | − size_t tr_size; | |
| 2457 | + size_t tr_size, period_addr; | |
| 2325 | 2458 | struct cppi5_tr_type1_t *tr_req; |
| 2326 | − unsigned int i; | |
| 2327 | 2459 | unsigned int periods = buf_len / period_len; |
| 2328 | − u32 burst; | |
| 2460 | + u16 tr0_cnt0, tr0_cnt1, tr1_cnt0; | |
| 2461 | + unsigned int i; | |
| 2462 | + int num_tr; | |
| 2329 | 2463 | |
| 2330 | − if (dir == DMA_DEV_TO_MEM) { | |
| 2331 | − dev_width = uc->cfg.src_addr_width; | |
| 2332 | − burst = uc->cfg.src_maxburst; | |
| 2333 | − } else if (dir == DMA_MEM_TO_DEV) { | |
| 2334 | − dev_width = uc->cfg.dst_addr_width; | |
| 2335 | − burst = uc->cfg.dst_maxburst; | |
| 2336 | − } else { | |
| 2337 | − dev_err(uc->ud->dev, "%s: bad direction?\n", __func__); | |
| 2464 | + if (!is_slave_direction(dir)) { | |
| 2465 | + dev_err(uc->ud->dev, "Only slave cyclic is supported\n"); | |
| 2338 | 2466 | return NULL; |
| 2339 | 2467 | } |
| 2340 | 2468 | |
| 2341 | − if (!burst) | |
| 2342 | − burst = 1; | |
| 2469 | + num_tr = udma_get_tr_counters(period_len, __ffs(buf_addr), &tr0_cnt0, | |
| 2470 | + &tr0_cnt1, &tr1_cnt0); | |
| 2471 | + if (num_tr < 0) { | |
| 2472 | + dev_err(uc->ud->dev, "size %zu is not supported\n", | |
| 2473 | + period_len); | |
| 2474 | + return NULL; | |
| 2475 | + } | |
| 2343 | 2476 | |
| 2344 | 2477 | /* Now allocate and setup the descriptor. */ |
| 2345 | 2478 | tr_size = sizeof(struct cppi5_tr_type1_t); |
| 2346 | − d = udma_alloc_tr_desc(uc, tr_size, periods, dir); | |
| 2479 | + d = udma_alloc_tr_desc(uc, tr_size, periods * num_tr, dir); | |
| 2347 | 2480 | if (!d) |
| 2348 | 2481 | return NULL; |
| 2349 | 2482 | |
| 2350 | 2483 | tr_req = d->hwdesc[0].tr_req_base; |
| 2484 | + period_addr = buf_addr; | |
| 2351 | 2485 | for (i = 0; i < periods; i++) { |
| 2352 | − cppi5_tr_init(&tr_req[i].flags, CPPI5_TR_TYPE1, false, false, | |
| 2353 | − CPPI5_TR_EVENT_SIZE_COMPLETION, 0); | |
| 2486 | + int tr_idx = i * num_tr; | |
| 2354 | 2487 | |
| 2355 | − tr_req[i].addr = buf_addr + period_len * i; | |
| 2356 | − tr_req[i].icnt0 = dev_width; | |
| 2357 | − tr_req[i].icnt1 = period_len / dev_width; | |
| 2358 | − tr_req[i].dim1 = dev_width; | |
| 2488 | + cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1, false, | |
| 2489 | + false, CPPI5_TR_EVENT_SIZE_COMPLETION, 0); | |
| 2490 | + | |
| 2491 | + tr_req[tr_idx].addr = period_addr; | |
| 2492 | + tr_req[tr_idx].icnt0 = tr0_cnt0; | |
| 2493 | + tr_req[tr_idx].icnt1 = tr0_cnt1; | |
| 2494 | + tr_req[tr_idx].dim1 = tr0_cnt0; | |
| 2495 | + | |
| 2496 | + if (num_tr == 2) { | |
| 2497 | + cppi5_tr_csf_set(&tr_req[tr_idx].flags, | |
| 2498 | + CPPI5_TR_CSF_SUPR_EVT); | |
| 2499 | + tr_idx++; | |
| 2500 | + | |
| 2501 | + cppi5_tr_init(&tr_req[tr_idx].flags, CPPI5_TR_TYPE1, | |
| 2502 | + false, false, | |
| 2503 | + CPPI5_TR_EVENT_SIZE_COMPLETION, 0); | |
| 2504 | + | |
| 2505 | + tr_req[tr_idx].addr = period_addr + tr0_cnt1 * tr0_cnt0; | |
| 2506 | + tr_req[tr_idx].icnt0 = tr1_cnt0; | |
| 2507 | + tr_req[tr_idx].icnt1 = 1; | |
| 2508 | + tr_req[tr_idx].dim1 = tr1_cnt0; | |
| 2509 | + } | |
| 2359 | 2510 | |
| 2360 | 2511 | if (!(flags & DMA_PREP_INTERRUPT)) |
| 2361 | − cppi5_tr_csf_set(&tr_req[i].flags, | |
| 2512 | + cppi5_tr_csf_set(&tr_req[tr_idx].flags, | |
| 2362 | 2513 | CPPI5_TR_CSF_SUPR_EVT); |
| 2514 | + | |
| 2515 | + period_addr += period_len; | |
| 2363 | 2516 | } |
| 2364 | 2517 | |
| 2365 | 2518 | return d; |
| @@ -2517,29 +2670,12 @@ udma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, · 151 unmodified lines | ||
| 2517 | 2670 | return NULL; |
| 2518 | 2671 | } |
| 2519 | 2672 | |
| 2520 | − if (len < SZ_64K) { | |
| 2521 | − num_tr = 1; | |
| 2522 | − tr0_cnt0 = len; | |
| 2523 | − tr0_cnt1 = 1; | |
| 2524 | − } else { | |
| 2525 | − unsigned long align_to = __ffs(src | dest); | |
| 2526 | − | |
| 2527 | − if (align_to > 3) | |
| 2528 | − align_to = 3; | |
| 2529 | − /* | |
| 2530 | − * Keep simple: tr0: SZ_64K-alignment blocks, | |
| 2531 | − * tr1: the remaining | |
| 2532 | − */ | |
| 2533 | − num_tr = 2; | |
| 2534 | − tr0_cnt0 = (SZ_64K - BIT(align_to)); | |
| 2535 | − if (len / tr0_cnt0 >= SZ_64K) { | |
| 2536 | − dev_err(uc->ud->dev, "size %zu is not supported\n", | |
| 2537 | − len); | |
| 2538 | − return NULL; | |
| 2539 | − } | |
| 2540 | − | |
| 2541 | − tr0_cnt1 = len / tr0_cnt0; | |
| 2542 | − tr1_cnt0 = len % tr0_cnt0; | |
| 2673 | + num_tr = udma_get_tr_counters(len, __ffs(src | dest), &tr0_cnt0, | |
| 2674 | + &tr0_cnt1, &tr1_cnt0); | |
| 2675 | + if (num_tr < 0) { | |
| 2676 | + dev_err(uc->ud->dev, "size %zu is not supported\n", | |
| 2677 | + len); | |
| 2678 | + return NULL; | |
| 2543 | 2679 | } |
| 2544 | 2680 | |
| 2545 | 2681 | d = udma_alloc_tr_desc(uc, tr_size, num_tr, DMA_MEM_TO_MEM); |
| @@ -2631,6 +2767,9 @@ static enum dma_status udma_tx_status(struct dma_chan *chan, · 85 unmodified lines | ||
| 2631 | 2767 | |
| 2632 | 2768 | ret = dma_cookie_status(chan, cookie, txstate); |
| 2633 | 2769 | |
| 2770 | + if (!udma_is_chan_running(uc)) | |
| 2771 | + ret = DMA_COMPLETE; | |
| 2772 | + | |
| 2634 | 2773 | if (ret == DMA_IN_PROGRESS && udma_is_chan_paused(uc)) |
| 2635 | 2774 | ret = DMA_PAUSED; |
| 2636 | 2775 | |
| @@ -2697,11 +2836,8 @@ static int udma_pause(struct dma_chan *chan) · 60 unmodified lines | ||
| 2697 | 2836 | { |
| 2698 | 2837 | struct udma_chan *uc = to_udma_chan(chan); |
| 2699 | 2838 | |
| 2700 | − if (!uc->desc) | |
| 2701 | − return -EINVAL; | |
| 2702 | − | |
| 2703 | 2839 | /* pause the channel */ |
| 2704 | − switch (uc->desc->dir) { | |
| 2840 | + switch (uc->config.dir) { | |
| 2705 | 2841 | case DMA_DEV_TO_MEM: |
| 2706 | 2842 | udma_rchanrt_update_bits(uc->rchan, |
| 2707 | 2843 | UDMA_RCHAN_RT_PEER_RT_EN_REG, |
| @@ -2730,11 +2866,8 @@ static int udma_resume(struct dma_chan *chan) · 22 unmodified lines | ||
| 2730 | 2866 | { |
| 2731 | 2867 | struct udma_chan *uc = to_udma_chan(chan); |
| 2732 | 2868 | |
| 2733 | − if (!uc->desc) | |
| 2734 | − return -EINVAL; | |
| 2735 | − | |
| 2736 | 2869 | /* resume the channel */ |
| 2737 | − switch (uc->desc->dir) { | |
| 2870 | + switch (uc->config.dir) { | |
| 2738 | 2871 | case DMA_DEV_TO_MEM: |
| 2739 | 2872 | udma_rchanrt_update_bits(uc->rchan, |
| 2740 | 2873 | UDMA_RCHAN_RT_PEER_RT_EN_REG, |
| @@ -3248,6 +3381,98 @@ static int udma_setup_resources(struct udma_dev *ud) · 507 unmodified lines | ||
| 3248 | 3381 | return ch_count; |
| 3249 | 3382 | } |
| 3250 | 3383 | |
| 3384 | +static int udma_setup_rx_flush(struct udma_dev *ud) | |
| 3385 | +{ | |
| 3386 | + struct udma_rx_flush *rx_flush = &ud->rx_flush; | |
| 3387 | + struct cppi5_desc_hdr_t *tr_desc; | |
| 3388 | + struct cppi5_tr_type1_t *tr_req; | |
| 3389 | + struct cppi5_host_desc_t *desc; | |
| 3390 | + struct device *dev = ud->dev; | |
| 3391 | + struct udma_hwdesc *hwdesc; | |
| 3392 | + size_t tr_size; | |
| 3393 | + | |
| 3394 | + /* Allocate 1K buffer for discarded data on RX channel teardown */ | |
| 3395 | + rx_flush->buffer_size = SZ_1K; | |
| 3396 | + rx_flush->buffer_vaddr = devm_kzalloc(dev, rx_flush->buffer_size, | |
| 3397 | + GFP_KERNEL); | |
| 3398 | + if (!rx_flush->buffer_vaddr) | |
| 3399 | + return -ENOMEM; | |
| 3400 | + | |
| 3401 | + rx_flush->buffer_paddr = dma_map_single(dev, rx_flush->buffer_vaddr, | |
| 3402 | + rx_flush->buffer_size, | |
| 3403 | + DMA_TO_DEVICE); | |
| 3404 | + if (dma_mapping_error(dev, rx_flush->buffer_paddr)) | |
| 3405 | + return -ENOMEM; | |
| 3406 | + | |
| 3407 | + /* Set up descriptor to be used for TR mode */ | |
| 3408 | + hwdesc = &rx_flush->hwdescs[0]; | |
| 3409 | + tr_size = sizeof(struct cppi5_tr_type1_t); | |
| 3410 | + hwdesc->cppi5_desc_size = cppi5_trdesc_calc_size(tr_size, 1); | |
| 3411 | + hwdesc->cppi5_desc_size = ALIGN(hwdesc->cppi5_desc_size, | |
| 3412 | + ud->desc_align); | |
| 3413 | + | |
| 3414 | + hwdesc->cppi5_desc_vaddr = devm_kzalloc(dev, hwdesc->cppi5_desc_size, | |
| 3415 | + GFP_KERNEL); | |
| 3416 | + if (!hwdesc->cppi5_desc_vaddr) | |
| 3417 | + return -ENOMEM; | |
| 3418 | + | |
| 3419 | + hwdesc->cppi5_desc_paddr = dma_map_single(dev, hwdesc->cppi5_desc_vaddr, | |
| 3420 | + hwdesc->cppi5_desc_size, | |
| 3421 | + DMA_TO_DEVICE); | |
| 3422 | + if (dma_mapping_error(dev, hwdesc->cppi5_desc_paddr)) | |
| 3423 | + return -ENOMEM; | |
| 3424 | + | |
| 3425 | + /* Start of the TR req records */ | |
| 3426 | + hwdesc->tr_req_base = hwdesc->cppi5_desc_vaddr + tr_size; | |
| 3427 | + /* Start address of the TR response array */ | |
| 3428 | + hwdesc->tr_resp_base = hwdesc->tr_req_base + tr_size; | |
| 3429 | + | |
| 3430 | + tr_desc = hwdesc->cppi5_desc_vaddr; | |
| 3431 | + cppi5_trdesc_init(tr_desc, 1, tr_size, 0, 0); | |
| 3432 | + cppi5_desc_set_pktids(tr_desc, 0, CPPI5_INFO1_DESC_FLOWID_DEFAULT); | |
| 3433 | + cppi5_desc_set_retpolicy(tr_desc, 0, 0); | |
| 3434 | + | |
| 3435 | + tr_req = hwdesc->tr_req_base; | |
| 3436 | + cppi5_tr_init(&tr_req->flags, CPPI5_TR_TYPE1, false, false, | |
| 3437 | + CPPI5_TR_EVENT_SIZE_COMPLETION, 0); | |
| 3438 | + cppi5_tr_csf_set(&tr_req->flags, CPPI5_TR_CSF_SUPR_EVT); | |
| 3439 | + | |
| 3440 | + tr_req->addr = rx_flush->buffer_paddr; | |
| 3441 | + tr_req->icnt0 = rx_flush->buffer_size; | |
| 3442 | + tr_req->icnt1 = 1; | |
| 3443 | + | |
| 3444 | + /* Set up descriptor to be used for packet mode */ | |
| 3445 | + hwdesc = &rx_flush->hwdescs[1]; | |
| 3446 | + hwdesc->cppi5_desc_size = ALIGN(sizeof(struct cppi5_host_desc_t) + | |
| 3447 | + CPPI5_INFO0_HDESC_EPIB_SIZE + | |
| 3448 | + CPPI5_INFO0_HDESC_PSDATA_MAX_SIZE, | |
| 3449 | + ud->desc_align); | |
| 3450 | + | |
| 3451 | + hwdesc->cppi5_desc_vaddr = devm_kzalloc(dev, hwdesc->cppi5_desc_size, | |
| 3452 | + GFP_KERNEL); | |
| 3453 | + if (!hwdesc->cppi5_desc_vaddr) | |
| 3454 | + return -ENOMEM; | |
| 3455 | + | |
| 3456 | + hwdesc->cppi5_desc_paddr = dma_map_single(dev, hwdesc->cppi5_desc_vaddr, | |
| 3457 | + hwdesc->cppi5_desc_size, | |
| 3458 | + DMA_TO_DEVICE); | |
| 3459 | + if (dma_mapping_error(dev, hwdesc->cppi5_desc_paddr)) | |
| 3460 | + return -ENOMEM; | |
| 3461 | + | |
| 3462 | + desc = hwdesc->cppi5_desc_vaddr; | |
| 3463 | + cppi5_hdesc_init(desc, 0, 0); | |
| 3464 | + cppi5_desc_set_pktids(&desc->hdr, 0, CPPI5_INFO1_DESC_FLOWID_DEFAULT); | |
| 3465 | + cppi5_desc_set_retpolicy(&desc->hdr, 0, 0); | |
| 3466 | + | |
| 3467 | + cppi5_hdesc_attach_buf(desc, | |
| 3468 | + rx_flush->buffer_paddr, rx_flush->buffer_size, | |
| 3469 | + rx_flush->buffer_paddr, rx_flush->buffer_size); | |
| 3470 | + | |
| 3471 | + dma_sync_single_for_device(dev, hwdesc->cppi5_desc_paddr, | |
| 3472 | + hwdesc->cppi5_desc_size, DMA_TO_DEVICE); | |
| 3473 | + return 0; | |
| 3474 | +} | |
| 3475 | + | |
| 3251 | 3476 | #define TI_UDMAC_BUSWIDTHS (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ |
| 3252 | 3477 | BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ |
| 3253 | 3478 | BIT(DMA_SLAVE_BUSWIDTH_3_BYTES) | \ |
| @@ -3361,6 +3586,10 @@ static int udma_probe(struct platform_device *pdev) · 107 unmodified lines | ||
| 3361 | 3586 | if (ud->desc_align < dma_get_cache_alignment()) |
| 3362 | 3587 | ud->desc_align = dma_get_cache_alignment(); |
| 3363 | 3588 | |
| 3589 | + ret = udma_setup_rx_flush(ud); | |
| 3590 | + if (ret) | |
| 3591 | + return ret; | |
| 3592 | + | |
| 3364 | 3593 | for (i = 0; i < ud->tchan_cnt; i++) { |
| 3365 | 3594 | struct udma_tchan *tchan = &ud->tchans[i]; |
| 3366 | 3595 | |
| @@ -479,20 +479,14 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p) · 478 unmodified lines | ||
| 479 | 479 | pinf = &p->ceinfo; |
| 480 | 480 | if (!priv->p_data->quirks) { |
| 481 | 481 | snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, |
| 482 | − "DDR ECC error type:%s Row %d Bank %d Col %d ", | |
| 483 | − "CE", pinf->row, pinf->bank, pinf->col); | |
| 484 | − snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, | |
| 485 | − "Bit Position: %d Data: 0x%08x\n", | |
| 482 | + "DDR ECC error type:%s Row %d Bank %d Col %d Bit Position: %d Data: 0x%08x", | |
| 483 | + "CE", pinf->row, pinf->bank, pinf->col, | |
| 486 | 484 | pinf->bitpos, pinf->data); |
| 487 | 485 | } else { |
| 488 | 486 | snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, |
| 489 | − "DDR ECC error type:%s Row %d Bank %d Col %d ", | |
| 490 | − "CE", pinf->row, pinf->bank, pinf->col); | |
| 491 | − snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, | |
| 492 | − "BankGroup Number %d Block Number %d ", | |
| 493 | − pinf->bankgrpnr, pinf->blknr); | |
| 494 | − snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, | |
| 495 | − "Bit Position: %d Data: 0x%08x\n", | |
| 487 | + "DDR ECC error type:%s Row %d Bank %d Col %d BankGroup Number %d Block Number %d Bit Position: %d Data: 0x%08x", | |
| 488 | + "CE", pinf->row, pinf->bank, pinf->col, | |
| 489 | + pinf->bankgrpnr, pinf->blknr, | |
| 496 | 490 | pinf->bitpos, pinf->data); |
| 497 | 491 | } |
| 498 | 492 | |
| @@ -509,10 +503,8 @@ static void handle_error(struct mem_ctl_info *mci, struct synps_ecc_status *p) · 10 unmodified lines | ||
| 509 | 503 | "UE", pinf->row, pinf->bank, pinf->col); |
| 510 | 504 | } else { |
| 511 | 505 | snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, |
| 512 | − "DDR ECC error type :%s Row %d Bank %d Col %d ", | |
| 513 | − "UE", pinf->row, pinf->bank, pinf->col); | |
| 514 | − snprintf(priv->message, SYNPS_EDAC_MSG_SIZE, | |
| 515 | − "BankGroup Number %d Block Number %d", | |
| 506 | + "DDR ECC error type :%s Row %d Bank %d Col %d BankGroup Number %d Block Number %d", | |
| 507 | + "UE", pinf->row, pinf->bank, pinf->col, | |
| 516 | 508 | pinf->bankgrpnr, pinf->blknr); |
| 517 | 509 | } |
| 518 | 510 | |
| @@ -552,7 +552,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz, · 551 unmodified lines | ||
| 552 | 552 | |
| 553 | 553 | seed = early_memremap(efi.rng_seed, sizeof(*seed)); |
| 554 | 554 | if (seed != NULL) { |
| 555 | − size = seed->size; | |
| 555 | + size = READ_ONCE(seed->size); | |
| 556 | 556 | early_memunmap(seed, sizeof(*seed)); |
| 557 | 557 | } else { |
| 558 | 558 | pr_err("Could not map UEFI random seed!\n"); |
| @@ -562,7 +562,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz, · 3 unmodified lines | ||
| 562 | 562 | sizeof(*seed) + size); |
| 563 | 563 | if (seed != NULL) { |
| 564 | 564 | pr_notice("seeding entropy pool\n"); |
| 565 | − add_bootloader_randomness(seed->bits, seed->size); | |
| 565 | + add_bootloader_randomness(seed->bits, size); | |
| 566 | 566 | early_memunmap(seed, sizeof(*seed) + size); |
| 567 | 567 | } else { |
| 568 | 568 | pr_err("Could not map UEFI random seed!\n"); |
| @@ -83,13 +83,16 @@ static ssize_t · 82 unmodified lines | ||
| 83 | 83 | efivar_attr_read(struct efivar_entry *entry, char *buf) |
| 84 | 84 | { |
| 85 | 85 | struct efi_variable *var = &entry->var; |
| 86 | + unsigned long size = sizeof(var->Data); | |
| 86 | 87 | char *str = buf; |
| 88 | + int ret; | |
| 87 | 89 | |
| 88 | 90 | if (!entry || !buf) |
| 89 | 91 | return -EINVAL; |
| 90 | 92 | |
| 91 | − var->DataSize = 1024; | |
| 92 | − if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | |
| 93 | + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); | |
| 94 | + var->DataSize = size; | |
| 95 | + if (ret) | |
| 93 | 96 | return -EIO; |
| 94 | 97 | |
| 95 | 98 | if (var->Attributes & EFI_VARIABLE_NON_VOLATILE) |
| @@ -116,13 +119,16 @@ static ssize_t · 20 unmodified lines | ||
| 116 | 119 | efivar_size_read(struct efivar_entry *entry, char *buf) |
| 117 | 120 | { |
| 118 | 121 | struct efi_variable *var = &entry->var; |
| 122 | + unsigned long size = sizeof(var->Data); | |
| 119 | 123 | char *str = buf; |
| 124 | + int ret; | |
| 120 | 125 | |
| 121 | 126 | if (!entry || !buf) |
| 122 | 127 | return -EINVAL; |
| 123 | 128 | |
| 124 | − var->DataSize = 1024; | |
| 125 | − if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | |
| 129 | + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); | |
| 130 | + var->DataSize = size; | |
| 131 | + if (ret) | |
| 126 | 132 | return -EIO; |
| 127 | 133 | |
| 128 | 134 | str += sprintf(str, "0x%lx\n", var->DataSize); |
| @@ -133,12 +139,15 @@ static ssize_t · 4 unmodified lines | ||
| 133 | 139 | efivar_data_read(struct efivar_entry *entry, char *buf) |
| 134 | 140 | { |
| 135 | 141 | struct efi_variable *var = &entry->var; |
| 142 | + unsigned long size = sizeof(var->Data); | |
| 143 | + int ret; | |
| 136 | 144 | |
| 137 | 145 | if (!entry || !buf) |
| 138 | 146 | return -EINVAL; |
| 139 | 147 | |
| 140 | − var->DataSize = 1024; | |
| 141 | − if (efivar_entry_get(entry, &var->Attributes, &var->DataSize, var->Data)) | |
| 148 | + ret = efivar_entry_get(entry, &var->Attributes, &size, var->Data); | |
| 149 | + var->DataSize = size; | |
| 150 | + if (ret) | |
| 142 | 151 | return -EIO; |
| 143 | 152 | |
| 144 | 153 | memcpy(buf, var->Data, var->DataSize); |
| @@ -199,6 +208,9 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) · 54 unmodified lines | ||
| 199 | 208 | u8 *data; |
| 200 | 209 | int err; |
| 201 | 210 | |
| 211 | + if (!entry || !buf) | |
| 212 | + return -EINVAL; | |
| 213 | + | |
| 202 | 214 | if (in_compat_syscall()) { |
| 203 | 215 | struct compat_efi_variable *compat; |
| 204 | 216 | |
| @@ -250,14 +262,16 @@ efivar_show_raw(struct efivar_entry *entry, char *buf) · 45 unmodified lines | ||
| 250 | 262 | { |
| 251 | 263 | struct efi_variable *var = &entry->var; |
| 252 | 264 | struct compat_efi_variable *compat; |
| 265 | + unsigned long datasize = sizeof(var->Data); | |
| 253 | 266 | size_t size; |
| 267 | + int ret; | |
| 254 | 268 | |
| 255 | 269 | if (!entry || !buf) |
| 256 | 270 | return 0; |
| 257 | 271 | |
| 258 | − var->DataSize = 1024; | |
| 259 | − if (efivar_entry_get(entry, &entry->var.Attributes, | |
| 260 | − &entry->var.DataSize, entry->var.Data)) | |
| 272 | + ret = efivar_entry_get(entry, &var->Attributes, &datasize, var->Data); | |
| 273 | + var->DataSize = datasize; | |
| 274 | + if (ret) | |
| 261 | 275 | return -EIO; |
| 262 | 276 | |
| 263 | 277 | if (in_compat_syscall()) { |
| @@ -29,6 +29,7 @@ struct imx_sc_chan { · 28 unmodified lines | ||
| 29 | 29 | struct mbox_client cl; |
| 30 | 30 | struct mbox_chan *ch; |
| 31 | 31 | int idx; |
| 32 | + struct completion tx_done; | |
| 32 | 33 | }; |
| 33 | 34 | |
| 34 | 35 | struct imx_sc_ipc { |
| @@ -100,6 +101,14 @@ int imx_scu_get_handle(struct imx_sc_ipc **ipc) · 65 unmodified lines | ||
| 100 | 101 | } |
| 101 | 102 | EXPORT_SYMBOL(imx_scu_get_handle); |
| 102 | 103 | |
| 104 | +/* Callback called when the word of a message is ack-ed, eg read by SCU */ | |
| 105 | +static void imx_scu_tx_done(struct mbox_client *cl, void *mssg, int r) | |
| 106 | +{ | |
| 107 | + struct imx_sc_chan *sc_chan = container_of(cl, struct imx_sc_chan, cl); | |
| 108 | + | |
| 109 | + complete(&sc_chan->tx_done); | |
| 110 | +} | |
| 111 | + | |
| 103 | 112 | static void imx_scu_rx_callback(struct mbox_client *c, void *msg) |
| 104 | 113 | { |
| 105 | 114 | struct imx_sc_chan *sc_chan = container_of(c, struct imx_sc_chan, cl); |
| @@ -149,6 +158,19 @@ static int imx_scu_ipc_write(struct imx_sc_ipc *sc_ipc, void *msg) · 43 unmodified lines | ||
| 149 | 158 | |
| 150 | 159 | for (i = 0; i < hdr->size; i++) { |
| 151 | 160 | sc_chan = &sc_ipc->chans[i % 4]; |
| 161 | + | |
| 162 | + /* | |
| 163 | + * SCU requires that all messages words are written | |
| 164 | + * sequentially but linux MU driver implements multiple | |
| 165 | + * independent channels for each register so ordering between | |
| 166 | + * different channels must be ensured by SCU API interface. | |
| 167 | + * | |
| 168 | + * Wait for tx_done before every send to ensure that no | |
| 169 | + * queueing happens at the mailbox channel level. | |
| 170 | + */ | |
| 171 | + wait_for_completion(&sc_chan->tx_done); | |
| 172 | + reinit_completion(&sc_chan->tx_done); | |
| 173 | + | |
| 152 | 174 | ret = mbox_send_message(sc_chan->ch, &data[i]); |
| 153 | 175 | if (ret < 0) |
| 154 | 176 | return ret; |
| @@ -247,6 +269,11 @@ static int imx_scu_probe(struct platform_device *pdev) · 92 unmodified lines | ||
| 247 | 269 | cl->knows_txdone = true; |
| 248 | 270 | cl->rx_callback = imx_scu_rx_callback; |
| 249 | 271 | |
| 272 | + /* Initial tx_done completion as "done" */ | |
| 273 | + cl->tx_done = imx_scu_tx_done; | |
| 274 | + init_completion(&sc_chan->tx_done); | |
| 275 | + complete(&sc_chan->tx_done); | |
| 276 | + | |
| 250 | 277 | sc_chan->sc_ipc = sc_ipc; |
| 251 | 278 | sc_chan->idx = i % 4; |
| 252 | 279 | sc_chan->ch = mbox_request_channel_byname(cl, chan_name); |
| @@ -16,7 +16,7 @@ struct imx_sc_msg_req_misc_set_ctrl { · 15 unmodified lines | ||
| 16 | 16 | u32 ctrl; |
| 17 | 17 | u32 val; |
| 18 | 18 | u16 resource; |
| 19 | −} __packed; | |
| 19 | +} __packed __aligned(4); | |
| 20 | 20 | |
| 21 | 21 | struct imx_sc_msg_req_cpu_start { |
| 22 | 22 | struct imx_sc_rpc_msg hdr; |
| @@ -24,18 +24,18 @@ struct imx_sc_msg_req_cpu_start { · 1 unmodified line | ||
| 24 | 24 | u32 address_lo; |
| 25 | 25 | u16 resource; |
| 26 | 26 | u8 enable; |
| 27 | −} __packed; | |
| 27 | +} __packed __aligned(4); | |
| 28 | 28 | |
| 29 | 29 | struct imx_sc_msg_req_misc_get_ctrl { |
| 30 | 30 | struct imx_sc_rpc_msg hdr; |
| 31 | 31 | u32 ctrl; |
| 32 | 32 | u16 resource; |
| 33 | −} __packed; | |
| 33 | +} __packed __aligned(4); | |
| 34 | 34 | |
| 35 | 35 | struct imx_sc_msg_resp_misc_get_ctrl { |
| 36 | 36 | struct imx_sc_rpc_msg hdr; |
| 37 | 37 | u32 val; |
| 38 | −} __packed; | |
| 38 | +} __packed __aligned(4); | |
| 39 | 39 | |
| 40 | 40 | /* |
| 41 | 41 | * This function sets a miscellaneous control value. |
| @@ -61,7 +61,7 @@ struct imx_sc_msg_req_set_resource_power_mode { · 60 unmodified lines | ||
| 61 | 61 | struct imx_sc_rpc_msg hdr; |
| 62 | 62 | u16 resource; |
| 63 | 63 | u8 mode; |
| 64 | −} __packed; | |
| 64 | +} __packed __aligned(4); | |
| 65 | 65 | |
| 66 | 66 | #define IMX_SCU_PD_NAME_SIZE 20 |
| 67 | 67 | struct imx_sc_pm_domain { |
| @@ -781,11 +781,11 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, · 780 unmodified lines | ||
| 781 | 781 | ssize_t result = 0; |
| 782 | 782 | uint32_t offset, se, sh, cu, wave, simd, thread, bank, *data; |
| 783 | 783 | |
| 784 | − if (size & 3 || *pos & 3) | |
| 784 | + if (size > 4096 || size & 3 || *pos & 3) | |
| 785 | 785 | return -EINVAL; |
| 786 | 786 | |
| 787 | 787 | /* decode offset */ |
| 788 | − offset = *pos & GENMASK_ULL(11, 0); | |
| 788 | + offset = (*pos & GENMASK_ULL(11, 0)) >> 2; | |
| 789 | 789 | se = (*pos & GENMASK_ULL(19, 12)) >> 12; |
| 790 | 790 | sh = (*pos & GENMASK_ULL(27, 20)) >> 20; |
| 791 | 791 | cu = (*pos & GENMASK_ULL(35, 28)) >> 28; |
| @@ -823,7 +823,7 @@ static ssize_t amdgpu_debugfs_gpr_read(struct file *f, char __user *buf, · 31 unmodified lines | ||
| 823 | 823 | while (size) { |
| 824 | 824 | uint32_t value; |
| 825 | 825 | |
| 826 | − value = data[offset++]; | |
| 826 | + value = data[result >> 2]; | |
| 827 | 827 | r = put_user(value, (uint32_t *)buf); |
| 828 | 828 | if (r) { |
| 829 | 829 | result = r; |
| @@ -3913,6 +3913,8 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive, · 3912 unmodified lines | ||
| 3913 | 3913 | if (r) |
| 3914 | 3914 | goto out; |
| 3915 | 3915 | |
| 3916 | + amdgpu_fbdev_set_suspend(tmp_adev, 0); | |
| 3917 | + | |
| 3916 | 3918 | /* must succeed. */ |
| 3917 | 3919 | amdgpu_ras_resume(tmp_adev); |
| 3918 | 3920 | |
| @@ -4086,6 +4088,8 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, · 167 unmodified lines | ||
| 4086 | 4088 | */ |
| 4087 | 4089 | amdgpu_unregister_gpu_instance(tmp_adev); |
| 4088 | 4090 | |
| 4091 | + amdgpu_fbdev_set_suspend(adev, 1); | |
| 4092 | + | |
| 4089 | 4093 | /* disable ras on ALL IPs */ |
| 4090 | 4094 | if (!(in_ras_intr && !use_baco) && |
| 4091 | 4095 | amdgpu_device_ip_need_full_reset(tmp_adev)) |
| @@ -1389,7 +1389,7 @@ amdgpu_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, · 1388 unmodified lines | ||
| 1389 | 1389 | |
| 1390 | 1390 | static struct drm_driver kms_driver = { |
| 1391 | 1391 | .driver_features = |
| 1392 | − DRIVER_USE_AGP | DRIVER_ATOMIC | | |
| 1392 | + DRIVER_ATOMIC | | |
| 1393 | 1393 | DRIVER_GEM | |
| 1394 | 1394 | DRIVER_RENDER | DRIVER_MODESET | DRIVER_SYNCOBJ | |
| 1395 | 1395 | DRIVER_SYNCOBJ_TIMELINE, |
| @@ -195,6 +195,7 @@ struct amdgpu_gmc { · 194 unmodified lines | ||
| 195 | 195 | uint32_t srbm_soft_reset; |
| 196 | 196 | bool prt_warning; |
| 197 | 197 | uint64_t stolen_size; |
| 198 | + uint32_t sdpif_register; | |
| 198 | 199 | /* apertures */ |
| 199 | 200 | u64 shared_aperture_start; |
| 200 | 201 | u64 shared_aperture_end; |
| @@ -52,7 +52,7 @@ · 51 unmodified lines | ||
| 52 | 52 | * 1. Primary ring |
| 53 | 53 | * 2. Async ring |
| 54 | 54 | */ |
| 55 | −#define GFX10_NUM_GFX_RINGS 2 | |
| 55 | +#define GFX10_NUM_GFX_RINGS_NV1X 1 | |
| 56 | 56 | #define GFX10_MEC_HPD_SIZE 2048 |
| 57 | 57 | |
| 58 | 58 | #define F32_CE_PROGRAM_RAM_SIZE 65536 |
| @@ -1304,7 +1304,7 @@ static int gfx_v10_0_sw_init(void *handle) · 1245 unmodified lines | ||
| 1304 | 1304 | case CHIP_NAVI14: |
| 1305 | 1305 | case CHIP_NAVI12: |
| 1306 | 1306 | adev->gfx.me.num_me = 1; |
| 1307 | − adev->gfx.me.num_pipe_per_me = 2; | |
| 1307 | + adev->gfx.me.num_pipe_per_me = 1; | |
| 1308 | 1308 | adev->gfx.me.num_queue_per_pipe = 1; |
| 1309 | 1309 | adev->gfx.mec.num_mec = 2; |
| 1310 | 1310 | adev->gfx.mec.num_pipe_per_mec = 4; |
| @@ -2710,18 +2710,20 @@ static int gfx_v10_0_cp_gfx_start(struct amdgpu_device *adev) · 1399 unmodified lines | ||
| 2710 | 2710 | amdgpu_ring_commit(ring); |
| 2711 | 2711 | |
| 2712 | 2712 | /* submit cs packet to copy state 0 to next available state */ |
| 2713 | − ring = &adev->gfx.gfx_ring[1]; | |
| 2714 | − r = amdgpu_ring_alloc(ring, 2); | |
| 2715 | − if (r) { | |
| 2716 | − DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r); | |
| 2717 | − return r; | |
| 2718 | − } | |
| 2719 | − | |
| 2720 | − amdgpu_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); | |
| 2721 | − amdgpu_ring_write(ring, 0); | |
| 2713 | + if (adev->gfx.num_gfx_rings > 1) { | |
| 2714 | + /* maximum supported gfx ring is 2 */ | |
| 2715 | + ring = &adev->gfx.gfx_ring[1]; | |
| 2716 | + r = amdgpu_ring_alloc(ring, 2); | |
| 2717 | + if (r) { | |
| 2718 | + DRM_ERROR("amdgpu: cp failed to lock ring (%d).\n", r); | |
| 2719 | + return r; | |
| 2720 | + } | |
| 2722 | 2721 | |
| 2723 | − amdgpu_ring_commit(ring); | |
| 2722 | + amdgpu_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); | |
| 2723 | + amdgpu_ring_write(ring, 0); | |
| 2724 | 2724 | |
| 2725 | + amdgpu_ring_commit(ring); | |
| 2726 | + } | |
| 2725 | 2727 | return 0; |
| 2726 | 2728 | } |
| 2727 | 2729 | |
| @@ -2818,39 +2820,41 @@ static int gfx_v10_0_cp_gfx_resume(struct amdgpu_device *adev) · 90 unmodified lines | ||
| 2818 | 2820 | mutex_unlock(&adev->srbm_mutex); |
| 2819 | 2821 | |
| 2820 | 2822 | /* Init gfx ring 1 for pipe 1 */ |
| 2821 | − mutex_lock(&adev->srbm_mutex); | |
| 2822 | − gfx_v10_0_cp_gfx_switch_pipe(adev, PIPE_ID1); | |
| 2823 | − ring = &adev->gfx.gfx_ring[1]; | |
| 2824 | − rb_bufsz = order_base_2(ring->ring_size / 8); | |
| 2825 | − tmp = REG_SET_FIELD(0, CP_RB1_CNTL, RB_BUFSZ, rb_bufsz); | |
| 2826 | − tmp = REG_SET_FIELD(tmp, CP_RB1_CNTL, RB_BLKSZ, rb_bufsz - 2); | |
| 2827 | − WREG32_SOC15(GC, 0, mmCP_RB1_CNTL, tmp); | |
| 2828 | − /* Initialize the ring buffer's write pointers */ | |
| 2829 | − ring->wptr = 0; | |
| 2830 | − WREG32_SOC15(GC, 0, mmCP_RB1_WPTR, lower_32_bits(ring->wptr)); | |
| 2831 | − WREG32_SOC15(GC, 0, mmCP_RB1_WPTR_HI, upper_32_bits(ring->wptr)); | |
| 2832 | − /* Set the wb address wether it's enabled or not */ | |
| 2833 | − rptr_addr = adev->wb.gpu_addr + (ring->rptr_offs * 4); | |
| 2834 | − WREG32_SOC15(GC, 0, mmCP_RB1_RPTR_ADDR, lower_32_bits(rptr_addr)); | |
| 2835 | − WREG32_SOC15(GC, 0, mmCP_RB1_RPTR_ADDR_HI, upper_32_bits(rptr_addr) & | |
| 2836 | − CP_RB1_RPTR_ADDR_HI__RB_RPTR_ADDR_HI_MASK); | |
| 2837 | − wptr_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4); | |
| 2838 | − WREG32_SOC15(GC, 0, mmCP_RB_WPTR_POLL_ADDR_LO, | |
| 2839 | − lower_32_bits(wptr_gpu_addr)); | |
| 2840 | − WREG32_SOC15(GC, 0, mmCP_RB_WPTR_POLL_ADDR_HI, | |
| 2841 | − upper_32_bits(wptr_gpu_addr)); | |
| 2842 | − | |
| 2843 | − mdelay(1); | |
| 2844 | − WREG32_SOC15(GC, 0, mmCP_RB1_CNTL, tmp); | |
| 2845 | − | |
| 2846 | − rb_addr = ring->gpu_addr >> 8; | |
| 2847 | − WREG32_SOC15(GC, 0, mmCP_RB1_BASE, rb_addr); | |
| 2848 | − WREG32_SOC15(GC, 0, mmCP_RB1_BASE_HI, upper_32_bits(rb_addr)); | |
| 2849 | − WREG32_SOC15(GC, 0, mmCP_RB1_ACTIVE, 1); | |
| 2850 | − | |
| 2851 | − gfx_v10_0_cp_gfx_set_doorbell(adev, ring); | |
| 2852 | − mutex_unlock(&adev->srbm_mutex); | |
| 2853 | − | |
| 2823 | + if (adev->gfx.num_gfx_rings > 1) { | |
| 2824 | + mutex_lock(&adev->srbm_mutex); | |
| 2825 | + gfx_v10_0_cp_gfx_switch_pipe(adev, PIPE_ID1); | |
| 2826 | + /* maximum supported gfx ring is 2 */ | |
| 2827 | + ring = &adev->gfx.gfx_ring[1]; | |
| 2828 | + rb_bufsz = order_base_2(ring->ring_size / 8); | |
| 2829 | + tmp = REG_SET_FIELD(0, CP_RB1_CNTL, RB_BUFSZ, rb_bufsz); | |
| 2830 | + tmp = REG_SET_FIELD(tmp, CP_RB1_CNTL, RB_BLKSZ, rb_bufsz - 2); | |
| 2831 | + WREG32_SOC15(GC, 0, mmCP_RB1_CNTL, tmp); | |
| 2832 | + /* Initialize the ring buffer's write pointers */ | |
| 2833 | + ring->wptr = 0; | |
| 2834 | + WREG32_SOC15(GC, 0, mmCP_RB1_WPTR, lower_32_bits(ring->wptr)); | |
| 2835 | + WREG32_SOC15(GC, 0, mmCP_RB1_WPTR_HI, upper_32_bits(ring->wptr)); | |
| 2836 | + /* Set the wb address wether it's enabled or not */ | |
| 2837 | + rptr_addr = adev->wb.gpu_addr + (ring->rptr_offs * 4); | |
| 2838 | + WREG32_SOC15(GC, 0, mmCP_RB1_RPTR_ADDR, lower_32_bits(rptr_addr)); | |
| 2839 | + WREG32_SOC15(GC, 0, mmCP_RB1_RPTR_ADDR_HI, upper_32_bits(rptr_addr) & | |
| 2840 | + CP_RB1_RPTR_ADDR_HI__RB_RPTR_ADDR_HI_MASK); | |
| 2841 | + wptr_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4); | |
| 2842 | + WREG32_SOC15(GC, 0, mmCP_RB_WPTR_POLL_ADDR_LO, | |
| 2843 | + lower_32_bits(wptr_gpu_addr)); | |
| 2844 | + WREG32_SOC15(GC, 0, mmCP_RB_WPTR_POLL_ADDR_HI, | |
| 2845 | + upper_32_bits(wptr_gpu_addr)); | |
| 2846 | + | |
| 2847 | + mdelay(1); | |
| 2848 | + WREG32_SOC15(GC, 0, mmCP_RB1_CNTL, tmp); | |
| 2849 | + | |
| 2850 | + rb_addr = ring->gpu_addr >> 8; | |
| 2851 | + WREG32_SOC15(GC, 0, mmCP_RB1_BASE, rb_addr); | |
| 2852 | + WREG32_SOC15(GC, 0, mmCP_RB1_BASE_HI, upper_32_bits(rb_addr)); | |
| 2853 | + WREG32_SOC15(GC, 0, mmCP_RB1_ACTIVE, 1); | |
| 2854 | + | |
| 2855 | + gfx_v10_0_cp_gfx_set_doorbell(adev, ring); | |
| 2856 | + mutex_unlock(&adev->srbm_mutex); | |
| 2857 | + } | |
| 2854 | 2858 | /* Switch to pipe 0 */ |
| 2855 | 2859 | mutex_lock(&adev->srbm_mutex); |
| 2856 | 2860 | gfx_v10_0_cp_gfx_switch_pipe(adev, PIPE_ID0); |
| @@ -3513,6 +3517,7 @@ static int gfx_v10_0_kcq_init_queue(struct amdgpu_ring *ring) · 656 unmodified lines | ||
| 3513 | 3517 | |
| 3514 | 3518 | /* reset ring buffer */ |
| 3515 | 3519 | ring->wptr = 0; |
| 3520 | + atomic64_set((atomic64_t *)&adev->wb.wb[ring->wptr_offs], 0); | |
| 3516 | 3521 | amdgpu_ring_clear_ring(ring); |
| 3517 | 3522 | } else { |
| 3518 | 3523 | amdgpu_ring_clear_ring(ring); |
| @@ -3966,7 +3971,8 @@ static int gfx_v10_0_early_init(void *handle) · 447 unmodified lines | ||
| 3966 | 3971 | { |
| 3967 | 3972 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 3968 | 3973 | |
| 3969 | − adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS; | |
| 3974 | + adev->gfx.num_gfx_rings = GFX10_NUM_GFX_RINGS_NV1X; | |
| 3975 | + | |
| 3970 | 3976 | adev->gfx.num_compute_rings = AMDGPU_MAX_COMPUTE_RINGS; |
| 3971 | 3977 | |
| 3972 | 3978 | gfx_v10_0_set_kiq_pm4_funcs(adev); |
| @@ -3663,6 +3663,7 @@ static int gfx_v9_0_kcq_init_queue(struct amdgpu_ring *ring) · 3662 unmodified lines | ||
| 3663 | 3663 | |
| 3664 | 3664 | /* reset ring buffer */ |
| 3665 | 3665 | ring->wptr = 0; |
| 3666 | + atomic64_set((atomic64_t *)&adev->wb.wb[ring->wptr_offs], 0); | |
| 3666 | 3667 | amdgpu_ring_clear_ring(ring); |
| 3667 | 3668 | } else { |
| 3668 | 3669 | amdgpu_ring_clear_ring(ring); |
| @@ -1271,6 +1271,19 @@ static void gmc_v9_0_init_golden_registers(struct amdgpu_device *adev) · 1270 unmodified lines | ||
| 1271 | 1271 | } |
| 1272 | 1272 | } |
| 1273 | 1273 | |
| 1274 | +/** | |
| 1275 | + * gmc_v9_0_restore_registers - restores regs | |
| 1276 | + * | |
| 1277 | + * @adev: amdgpu_device pointer | |
| 1278 | + * | |
| 1279 | + * This restores register values, saved at suspend. | |
| 1280 | + */ | |
| 1281 | +static void gmc_v9_0_restore_registers(struct amdgpu_device *adev) | |
| 1282 | +{ | |
| 1283 | + if (adev->asic_type == CHIP_RAVEN) | |
| 1284 | + WREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0, adev->gmc.sdpif_register); | |
| 1285 | +} | |
| 1286 | + | |
| 1274 | 1287 | /** |
| 1275 | 1288 | * gmc_v9_0_gart_enable - gart enable |
| 1276 | 1289 | * |
| @@ -1376,6 +1389,20 @@ static int gmc_v9_0_hw_init(void *handle) · 99 unmodified lines | ||
| 1376 | 1389 | return r; |
| 1377 | 1390 | } |
| 1378 | 1391 | |
| 1392 | +/** | |
| 1393 | + * gmc_v9_0_save_registers - saves regs | |
| 1394 | + * | |
| 1395 | + * @adev: amdgpu_device pointer | |
| 1396 | + * | |
| 1397 | + * This saves potential register values that should be | |
| 1398 | + * restored upon resume | |
| 1399 | + */ | |
| 1400 | +static void gmc_v9_0_save_registers(struct amdgpu_device *adev) | |
| 1401 | +{ | |
| 1402 | + if (adev->asic_type == CHIP_RAVEN) | |
| 1403 | + adev->gmc.sdpif_register = RREG32(mmDCHUBBUB_SDPIF_MMIO_CNTRL_0); | |
| 1404 | +} | |
| 1405 | + | |
| 1379 | 1406 | /** |
| 1380 | 1407 | * gmc_v9_0_gart_disable - gart disable |
| 1381 | 1408 | * |
| @@ -1412,9 +1439,16 @@ static int gmc_v9_0_hw_fini(void *handle) · 30 unmodified lines | ||
| 1412 | 1439 | |
| 1413 | 1440 | static int gmc_v9_0_suspend(void *handle) |
| 1414 | 1441 | { |
| 1442 | + int r; | |
| 1415 | 1443 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1416 | 1444 | |
| 1417 | − return gmc_v9_0_hw_fini(adev); | |
| 1445 | + r = gmc_v9_0_hw_fini(adev); | |
| 1446 | + if (r) | |
| 1447 | + return r; | |
| 1448 | + | |
| 1449 | + gmc_v9_0_save_registers(adev); | |
| 1450 | + | |
| 1451 | + return 0; | |
| 1418 | 1452 | } |
| 1419 | 1453 | |
| 1420 | 1454 | static int gmc_v9_0_resume(void *handle) |
| @@ -1422,6 +1456,7 @@ static int gmc_v9_0_resume(void *handle) · 1 unmodified line | ||
| 1422 | 1456 | int r; |
| 1423 | 1457 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
| 1424 | 1458 | |
| 1459 | + gmc_v9_0_restore_registers(adev); | |
| 1425 | 1460 | r = gmc_v9_0_hw_init(adev); |
| 1426 | 1461 | if (r) |
| 1427 | 1462 | return r; |
| @@ -693,7 +693,7 @@ static int jpeg_v2_0_set_clockgating_state(void *handle, · 692 unmodified lines | ||
| 693 | 693 | bool enable = (state == AMD_CG_STATE_GATE); |
| 694 | 694 | |
| 695 | 695 | if (enable) { |
| 696 | − if (jpeg_v2_0_is_idle(handle)) | |
| 696 | + if (!jpeg_v2_0_is_idle(handle)) | |
| 697 | 697 | return -EBUSY; |
| 698 | 698 | jpeg_v2_0_enable_clock_gating(adev); |
| 699 | 699 | } else { |
| @@ -477,7 +477,7 @@ static int jpeg_v2_5_set_clockgating_state(void *handle, · 476 unmodified lines | ||
| 477 | 477 | continue; |
| 478 | 478 | |
| 479 | 479 | if (enable) { |
| 480 | − if (jpeg_v2_5_is_idle(handle)) | |
| 480 | + if (!jpeg_v2_5_is_idle(handle)) | |
| 481 | 481 | return -EBUSY; |
| 482 | 482 | jpeg_v2_5_enable_clock_gating(adev, i); |
| 483 | 483 | } else { |
| @@ -89,6 +89,13 @@ · 88 unmodified lines | ||
| 89 | 89 | #define HDP_MEM_POWER_CTRL__RC_MEM_POWER_CTRL_EN_MASK 0x00010000L |
| 90 | 90 | #define HDP_MEM_POWER_CTRL__RC_MEM_POWER_LS_EN_MASK 0x00020000L |
| 91 | 91 | #define mmHDP_MEM_POWER_CTRL_BASE_IDX 0 |
| 92 | + | |
| 93 | +/* for Vega20/arcturus regiter offset change */ | |
| 94 | +#define mmROM_INDEX_VG20 0x00e4 | |
| 95 | +#define mmROM_INDEX_VG20_BASE_IDX 0 | |
| 96 | +#define mmROM_DATA_VG20 0x00e5 | |
| 97 | +#define mmROM_DATA_VG20_BASE_IDX 0 | |
| 98 | + | |
| 92 | 99 | /* |
| 93 | 100 | * Indirect registers accessor |
| 94 | 101 | */ |
| @@ -309,6 +316,8 @@ static bool soc15_read_bios_from_rom(struct amdgpu_device *adev, · 214 unmodified lines | ||
| 309 | 316 | { |
| 310 | 317 | u32 *dw_ptr; |
| 311 | 318 | u32 i, length_dw; |
| 319 | + uint32_t rom_index_offset; | |
| 320 | + uint32_t rom_data_offset; | |
| 312 | 321 | |
| 313 | 322 | if (bios == NULL) |
| 314 | 323 | return false; |
| @@ -321,11 +330,23 @@ static bool soc15_read_bios_from_rom(struct amdgpu_device *adev, · 6 unmodified lines | ||
| 321 | 330 | dw_ptr = (u32 *)bios; |
| 322 | 331 | length_dw = ALIGN(length_bytes, 4) / 4; |
| 323 | 332 | |
| 333 | + switch (adev->asic_type) { | |
| 334 | + case CHIP_VEGA20: | |
| 335 | + case CHIP_ARCTURUS: | |
| 336 | + rom_index_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX_VG20); | |
| 337 | + rom_data_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA_VG20); | |
| 338 | + break; | |
| 339 | + default: | |
| 340 | + rom_index_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX); | |
| 341 | + rom_data_offset = SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA); | |
| 342 | + break; | |
| 343 | + } | |
| 344 | + | |
| 324 | 345 | /* set rom index to 0 */ |
| 325 | − WREG32(SOC15_REG_OFFSET(SMUIO, 0, mmROM_INDEX), 0); | |
| 346 | + WREG32(rom_index_offset, 0); | |
| 326 | 347 | /* read out the rom data */ |
| 327 | 348 | for (i = 0; i < length_dw; i++) |
| 328 | − dw_ptr[i] = RREG32(SOC15_REG_OFFSET(SMUIO, 0, mmROM_DATA)); | |
| 349 | + dw_ptr[i] = RREG32(rom_data_offset); | |
| 329 | 350 | |
| 330 | 351 | return true; |
| 331 | 352 | } |
| @@ -1352,7 +1352,7 @@ static int vcn_v1_0_set_clockgating_state(void *handle, · 1351 unmodified lines | ||
| 1352 | 1352 | |
| 1353 | 1353 | if (enable) { |
| 1354 | 1354 | /* wait for STATUS to clear */ |
| 1355 | − if (vcn_v1_0_is_idle(handle)) | |
| 1355 | + if (!vcn_v1_0_is_idle(handle)) | |
| 1356 | 1356 | return -EBUSY; |
| 1357 | 1357 | vcn_v1_0_enable_clock_gating(adev); |
| 1358 | 1358 | } else { |
| @@ -1217,7 +1217,7 @@ static int vcn_v2_0_set_clockgating_state(void *handle, · 1216 unmodified lines | ||
| 1217 | 1217 | |
| 1218 | 1218 | if (enable) { |
| 1219 | 1219 | /* wait for STATUS to clear */ |
| 1220 | − if (vcn_v2_0_is_idle(handle)) | |
| 1220 | + if (!vcn_v2_0_is_idle(handle)) | |
| 1221 | 1221 | return -EBUSY; |
| 1222 | 1222 | vcn_v2_0_enable_clock_gating(adev); |
| 1223 | 1223 | } else { |
| @@ -1672,7 +1672,7 @@ static int vcn_v2_5_set_clockgating_state(void *handle, · 1671 unmodified lines | ||
| 1672 | 1672 | return 0; |
| 1673 | 1673 | |
| 1674 | 1674 | if (enable) { |
| 1675 | − if (vcn_v2_5_is_idle(handle)) | |
| 1675 | + if (!vcn_v2_5_is_idle(handle)) | |
| 1676 | 1676 | return -EBUSY; |
| 1677 | 1677 | vcn_v2_5_enable_clock_gating(adev); |
| 1678 | 1678 | } else { |
| @@ -522,8 +522,9 @@ static void dm_dcn_crtc_high_irq(void *interrupt_params) · 521 unmodified lines | ||
| 522 | 522 | |
| 523 | 523 | acrtc_state = to_dm_crtc_state(acrtc->base.state); |
| 524 | 524 | |
| 525 | − DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d\n", acrtc->crtc_id, | |
| 526 | − amdgpu_dm_vrr_active(acrtc_state)); | |
| 525 | + DRM_DEBUG_DRIVER("crtc:%d, vupdate-vrr:%d, planes:%d\n", acrtc->crtc_id, | |
| 526 | + amdgpu_dm_vrr_active(acrtc_state), | |
| 527 | + acrtc_state->active_planes); | |
| 527 | 528 | |
| 528 | 529 | amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); |
| 529 | 530 | drm_crtc_handle_vblank(&acrtc->base); |
| @@ -543,7 +544,18 @@ static void dm_dcn_crtc_high_irq(void *interrupt_params) · 13 unmodified lines | ||
| 543 | 544 | &acrtc_state->vrr_params.adjust); |
| 544 | 545 | } |
| 545 | 546 | |
| 546 | − if (acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED) { | |
| 547 | + /* | |
| 548 | + * If there aren't any active_planes then DCH HUBP may be clock-gated. | |
| 549 | + * In that case, pageflip completion interrupts won't fire and pageflip | |
| 550 | + * completion events won't get delivered. Prevent this by sending | |
| 551 | + * pending pageflip events from here if a flip is still pending. | |
| 552 | + * | |
| 553 | + * If any planes are enabled, use dm_pflip_high_irq() instead, to | |
| 554 | + * avoid race conditions between flip programming and completion, | |
| 555 | + * which could cause too early flip completion events. | |
| 556 | + */ | |
| 557 | + if (acrtc->pflip_status == AMDGPU_FLIP_SUBMITTED && | |
| 558 | + acrtc_state->active_planes == 0) { | |
| 547 | 559 | if (acrtc->event) { |
| 548 | 560 | drm_crtc_send_vblank_event(&acrtc->base, acrtc->event); |
| 549 | 561 | acrtc->event = NULL; |
| @@ -1422,6 +1434,73 @@ static void s3_handle_mst(struct drm_device *dev, bool suspend) · 872 unmodified lines | ||
| 1422 | 1434 | drm_kms_helper_hotplug_event(dev); |
| 1423 | 1435 | } |
| 1424 | 1436 | |
| 1437 | +static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev) | |
| 1438 | +{ | |
| 1439 | + struct smu_context *smu = &adev->smu; | |
| 1440 | + int ret = 0; | |
| 1441 | + | |
| 1442 | + if (!is_support_sw_smu(adev)) | |
| 1443 | + return 0; | |
| 1444 | + | |
| 1445 | + /* This interface is for dGPU Navi1x.Linux dc-pplib interface depends | |
| 1446 | + * on window driver dc implementation. | |
| 1447 | + * For Navi1x, clock settings of dcn watermarks are fixed. the settings | |
| 1448 | + * should be passed to smu during boot up and resume from s3. | |
| 1449 | + * boot up: dc calculate dcn watermark clock settings within dc_create, | |
| 1450 | + * dcn20_resource_construct | |
| 1451 | + * then call pplib functions below to pass the settings to smu: | |
| 1452 | + * smu_set_watermarks_for_clock_ranges | |
| 1453 | + * smu_set_watermarks_table | |
| 1454 | + * navi10_set_watermarks_table | |
| 1455 | + * smu_write_watermarks_table | |
| 1456 | + * | |
| 1457 | + * For Renoir, clock settings of dcn watermark are also fixed values. | |
| 1458 | + * dc has implemented different flow for window driver: | |
| 1459 | + * dc_hardware_init / dc_set_power_state | |
| 1460 | + * dcn10_init_hw | |
| 1461 | + * notify_wm_ranges | |
| 1462 | + * set_wm_ranges | |
| 1463 | + * -- Linux | |
| 1464 | + * smu_set_watermarks_for_clock_ranges | |
| 1465 | + * renoir_set_watermarks_table | |
| 1466 | + * smu_write_watermarks_table | |
| 1467 | + * | |
| 1468 | + * For Linux, | |
| 1469 | + * dc_hardware_init -> amdgpu_dm_init | |
| 1470 | + * dc_set_power_state --> dm_resume | |
| 1471 | + * | |
| 1472 | + * therefore, this function apply to navi10/12/14 but not Renoir | |
| 1473 | + * * | |
| 1474 | + */ | |
| 1475 | + switch(adev->asic_type) { | |
| 1476 | + case CHIP_NAVI10: | |
| 1477 | + case CHIP_NAVI14: | |
| 1478 | + case CHIP_NAVI12: | |
| 1479 | + break; | |
| 1480 | + default: | |
| 1481 | + return 0; | |
| 1482 | + } | |
| 1483 | + | |
| 1484 | + mutex_lock(&smu->mutex); | |
| 1485 | + | |
| 1486 | + /* pass data to smu controller */ | |
| 1487 | + if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && | |
| 1488 | + !(smu->watermarks_bitmap & WATERMARKS_LOADED)) { | |
| 1489 | + ret = smu_write_watermarks_table(smu); | |
| 1490 | + | |
| 1491 | + if (ret) { | |
| 1492 | + mutex_unlock(&smu->mutex); | |
| 1493 | + DRM_ERROR("Failed to update WMTABLE!\n"); | |
| 1494 | + return ret; | |
| 1495 | + } | |
| 1496 | + smu->watermarks_bitmap |= WATERMARKS_LOADED; | |
| 1497 | + } | |
| 1498 | + | |
| 1499 | + mutex_unlock(&smu->mutex); | |
| 1500 | + | |
| 1501 | + return 0; | |
| 1502 | +} | |
| 1503 | + | |
| 1425 | 1504 | /** |
| 1426 | 1505 | * dm_hw_init() - Initialize DC device |
| 1427 | 1506 | * @handle: The base driver device containing the amdgpu_dm device. |
| @@ -1700,6 +1779,8 @@ static int dm_resume(void *handle) · 272 unmodified lines | ||
| 1700 | 1779 | |
| 1701 | 1780 | amdgpu_dm_irq_resume_late(adev); |
| 1702 | 1781 | |
| 1782 | + amdgpu_dm_smu_write_watermarks_table(adev); | |
| 1783 | + | |
| 1703 | 1784 | return 0; |
| 1704 | 1785 | } |
| 1705 | 1786 | |
| @@ -451,6 +451,7 @@ static void dm_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr, · 450 unmodified lines | ||
| 451 | 451 | aconnector->dc_sink); |
| 452 | 452 | dc_sink_release(aconnector->dc_sink); |
| 453 | 453 | aconnector->dc_sink = NULL; |
| 454 | + aconnector->dc_link->cur_link_settings.lane_count = 0; | |
| 454 | 455 | } |
| 455 | 456 | |
| 456 | 457 | drm_connector_unregister(connector); |
| @@ -3401,6 +3401,17 @@ static bool retrieve_link_cap(struct dc_link *link) · 3400 unmodified lines | ||
| 3401 | 3401 | sink_id.ieee_device_id, |
| 3402 | 3402 | sizeof(sink_id.ieee_device_id)); |
| 3403 | 3403 | |
| 3404 | + /* Quirk Apple MBP 2017 15" Retina panel: Wrong DP_MAX_LINK_RATE */ | |
| 3405 | + { | |
| 3406 | + uint8_t str_mbp_2017[] = { 101, 68, 21, 101, 98, 97 }; | |
| 3407 | + | |
| 3408 | + if ((link->dpcd_caps.sink_dev_id == 0x0010fa) && | |
| 3409 | + !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2017, | |
| 3410 | + sizeof(str_mbp_2017))) { | |
| 3411 | + link->reported_link_cap.link_rate = 0x0c; | |
| 3412 | + } | |
| 3413 | + } | |
| 3414 | + | |
| 3404 | 3415 | core_link_read_dpcd( |
| 3405 | 3416 | link, |
| 3406 | 3417 | DP_SINK_HW_REVISION_START, |
| @@ -840,8 +840,8 @@ static void hubbub1_det_request_size( · 839 unmodified lines | ||
| 840 | 840 | |
| 841 | 841 | hubbub1_get_blk256_size(&blk256_width, &blk256_height, bpe); |
| 842 | 842 | |
| 843 | − swath_bytes_horz_wc = height * blk256_height * bpe; | |
| 844 | − swath_bytes_vert_wc = width * blk256_width * bpe; | |
| 843 | + swath_bytes_horz_wc = width * blk256_height * bpe; | |
| 844 | + swath_bytes_vert_wc = height * blk256_width * bpe; | |
| 845 | 845 | |
| 846 | 846 | *req128_horz_wc = (2 * swath_bytes_horz_wc <= detile_buf_size) ? |
| 847 | 847 | false : /* full 256B request */ |
| @@ -108,7 +108,6 @@ static const struct hwseq_private_funcs dcn20_private_funcs = { · 107 unmodified lines | ||
| 108 | 108 | .enable_power_gating_plane = dcn20_enable_power_gating_plane, |
| 109 | 109 | .dpp_pg_control = dcn20_dpp_pg_control, |
| 110 | 110 | .hubp_pg_control = dcn20_hubp_pg_control, |
| 111 | − .dsc_pg_control = NULL, | |
| 112 | 111 | .update_odm = dcn20_update_odm, |
| 113 | 112 | .dsc_pg_control = dcn20_dsc_pg_control, |
| 114 | 113 | .get_surface_visual_confirm_color = dcn10_get_surface_visual_confirm_color, |
| @@ -335,6 +335,117 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_0_soc = { · 334 unmodified lines | ||
| 335 | 335 | .use_urgent_burst_bw = 0 |
| 336 | 336 | }; |
| 337 | 337 | |
| 338 | +struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv14_soc = { | |
| 339 | + .clock_limits = { | |
| 340 | + { | |
| 341 | + .state = 0, | |
| 342 | + .dcfclk_mhz = 560.0, | |
| 343 | + .fabricclk_mhz = 560.0, | |
| 344 | + .dispclk_mhz = 513.0, | |
| 345 | + .dppclk_mhz = 513.0, | |
| 346 | + .phyclk_mhz = 540.0, | |
| 347 | + .socclk_mhz = 560.0, | |
| 348 | + .dscclk_mhz = 171.0, | |
| 349 | + .dram_speed_mts = 8960.0, | |
| 350 | + }, | |
| 351 | + { | |
| 352 | + .state = 1, | |
| 353 | + .dcfclk_mhz = 694.0, | |
| 354 | + .fabricclk_mhz = 694.0, | |
| 355 | + .dispclk_mhz = 642.0, | |
| 356 | + .dppclk_mhz = 642.0, | |
| 357 | + .phyclk_mhz = 600.0, | |
| 358 | + .socclk_mhz = 694.0, | |
| 359 | + .dscclk_mhz = 214.0, | |
| 360 | + .dram_speed_mts = 11104.0, | |
| 361 | + }, | |
| 362 | + { | |
| 363 | + .state = 2, | |
| 364 | + .dcfclk_mhz = 875.0, | |
| 365 | + .fabricclk_mhz = 875.0, | |
| 366 | + .dispclk_mhz = 734.0, | |
| 367 | + .dppclk_mhz = 734.0, | |
| 368 | + .phyclk_mhz = 810.0, | |
| 369 | + .socclk_mhz = 875.0, | |
| 370 | + .dscclk_mhz = 245.0, | |
| 371 | + .dram_speed_mts = 14000.0, | |
| 372 | + }, | |
| 373 | + { | |
| 374 | + .state = 3, | |
| 375 | + .dcfclk_mhz = 1000.0, | |
| 376 | + .fabricclk_mhz = 1000.0, | |
| 377 | + .dispclk_mhz = 1100.0, | |
| 378 | + .dppclk_mhz = 1100.0, | |
| 379 | + .phyclk_mhz = 810.0, | |
| 380 | + .socclk_mhz = 1000.0, | |
| 381 | + .dscclk_mhz = 367.0, | |
| 382 | + .dram_speed_mts = 16000.0, | |
| 383 | + }, | |
| 384 | + { | |
| 385 | + .state = 4, | |
| 386 | + .dcfclk_mhz = 1200.0, | |
| 387 | + .fabricclk_mhz = 1200.0, | |
| 388 | + .dispclk_mhz = 1284.0, | |
| 389 | + .dppclk_mhz = 1284.0, | |
| 390 | + .phyclk_mhz = 810.0, | |
| 391 | + .socclk_mhz = 1200.0, | |
| 392 | + .dscclk_mhz = 428.0, | |
| 393 | + .dram_speed_mts = 16000.0, | |
| 394 | + }, | |
| 395 | + /*Extra state, no dispclk ramping*/ | |
| 396 | + { | |
| 397 | + .state = 5, | |
| 398 | + .dcfclk_mhz = 1200.0, | |
| 399 | + .fabricclk_mhz = 1200.0, | |
| 400 | + .dispclk_mhz = 1284.0, | |
| 401 | + .dppclk_mhz = 1284.0, | |
| 402 | + .phyclk_mhz = 810.0, | |
| 403 | + .socclk_mhz = 1200.0, | |
| 404 | + .dscclk_mhz = 428.0, | |
| 405 | + .dram_speed_mts = 16000.0, | |
| 406 | + }, | |
| 407 | + }, | |
| 408 | + .num_states = 5, | |
| 409 | + .sr_exit_time_us = 8.6, | |
| 410 | + .sr_enter_plus_exit_time_us = 10.9, | |
| 411 | + .urgent_latency_us = 4.0, | |
| 412 | + .urgent_latency_pixel_data_only_us = 4.0, | |
| 413 | + .urgent_latency_pixel_mixed_with_vm_data_us = 4.0, | |
| 414 | + .urgent_latency_vm_data_only_us = 4.0, | |
| 415 | + .urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096, | |
| 416 | + .urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096, | |
| 417 | + .urgent_out_of_order_return_per_channel_vm_only_bytes = 4096, | |
| 418 | + .pct_ideal_dram_sdp_bw_after_urgent_pixel_only = 40.0, | |
| 419 | + .pct_ideal_dram_sdp_bw_after_urgent_pixel_and_vm = 40.0, | |
| 420 | + .pct_ideal_dram_sdp_bw_after_urgent_vm_only = 40.0, | |
| 421 | + .max_avg_sdp_bw_use_normal_percent = 40.0, | |
| 422 | + .max_avg_dram_bw_use_normal_percent = 40.0, | |
| 423 | + .writeback_latency_us = 12.0, | |
| 424 | + .ideal_dram_bw_after_urgent_percent = 40.0, | |
| 425 | + .max_request_size_bytes = 256, | |
| 426 | + .dram_channel_width_bytes = 2, | |
| 427 | + .fabric_datapath_to_dcn_data_return_bytes = 64, | |
| 428 | + .dcn_downspread_percent = 0.5, | |
| 429 | + .downspread_percent = 0.38, | |
| 430 | + .dram_page_open_time_ns = 50.0, | |
| 431 | + .dram_rw_turnaround_time_ns = 17.5, | |
| 432 | + .dram_return_buffer_per_channel_bytes = 8192, | |
| 433 | + .round_trip_ping_latency_dcfclk_cycles = 131, | |
| 434 | + .urgent_out_of_order_return_per_channel_bytes = 256, | |
| 435 | + .channel_interleave_bytes = 256, | |
| 436 | + .num_banks = 8, | |
| 437 | + .num_chans = 8, | |
| 438 | + .vmm_page_size_bytes = 4096, | |
| 439 | + .dram_clock_change_latency_us = 404.0, | |
| 440 | + .dummy_pstate_latency_us = 5.0, | |
| 441 | + .writeback_dram_clock_change_latency_us = 23.0, | |
| 442 | + .return_bus_width_bytes = 64, | |
| 443 | + .dispclk_dppclk_vco_speed_mhz = 3850, | |
| 444 | + .xfc_bus_transport_time_us = 20, | |
| 445 | + .xfc_xbuf_latency_tolerance_us = 4, | |
| 446 | + .use_urgent_burst_bw = 0 | |
| 447 | +}; | |
| 448 | + | |
| 338 | 449 | struct _vcs_dpi_soc_bounding_box_st dcn2_0_nv12_soc = { 0 }; |
| 339 | 450 | |
| 340 | 451 | #ifndef mmDP0_DP_DPHY_INTERNAL_CTRL |
| @@ -3291,6 +3402,9 @@ void dcn20_patch_bounding_box(struct dc *dc, struct _vcs_dpi_soc_bounding_box_st · 2950 unmodified lines | ||
| 3291 | 3402 | static struct _vcs_dpi_soc_bounding_box_st *get_asic_rev_soc_bb( |
| 3292 | 3403 | uint32_t hw_internal_rev) |
| 3293 | 3404 | { |
| 3405 | + if (ASICREV_IS_NAVI14_M(hw_internal_rev)) | |
| 3406 | + return &dcn2_0_nv14_soc; | |
| 3407 | + | |
| 3294 | 3408 | if (ASICREV_IS_NAVI12_P(hw_internal_rev)) |
| 3295 | 3409 | return &dcn2_0_nv12_soc; |
| 3296 | 3410 | |
| @@ -116,7 +116,6 @@ static const struct hwseq_private_funcs dcn21_private_funcs = { · 115 unmodified lines | ||
| 116 | 116 | .enable_power_gating_plane = dcn20_enable_power_gating_plane, |
| 117 | 117 | .dpp_pg_control = dcn20_dpp_pg_control, |
| 118 | 118 | .hubp_pg_control = dcn20_hubp_pg_control, |
| 119 | − .dsc_pg_control = NULL, | |
| 120 | 119 | .update_odm = dcn20_update_odm, |
| 121 | 120 | .dsc_pg_control = dcn20_dsc_pg_control, |
| 122 | 121 | .get_surface_visual_confirm_color = dcn10_get_surface_visual_confirm_color, |
| @@ -7376,6 +7376,8 @@ · 7375 unmodified lines | ||
| 7376 | 7376 | #define mmCRTC4_CRTC_DRR_CONTROL 0x0f3e |
| 7377 | 7377 | #define mmCRTC4_CRTC_DRR_CONTROL_BASE_IDX 2 |
| 7378 | 7378 | |
| 7379 | +#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0 0x395d | |
| 7380 | +#define mmDCHUBBUB_SDPIF_MMIO_CNTRL_0_BASE_IDX 2 | |
| 7379 | 7381 | |
| 7380 | 7382 | // addressBlock: dce_dc_fmt4_dispdec |
| 7381 | 7383 | // base address: 0x2000 |
| @@ -222,7 +222,7 @@ int smu_set_soft_freq_range(struct smu_context *smu, enum smu_clk_type clk_type, · 221 unmodified lines | ||
| 222 | 222 | { |
| 223 | 223 | int ret = 0; |
| 224 | 224 | |
| 225 | − if (min <= 0 && max <= 0) | |
| 225 | + if (min < 0 && max < 0) | |
| 226 | 226 | return -EINVAL; |
| 227 | 227 | |
| 228 | 228 | if (!smu_clk_dpm_is_enabled(smu, clk_type)) |
| @@ -2006,8 +2006,11 @@ int smu_set_watermarks_for_clock_ranges(struct smu_context *smu, · 1777 unmodified lines | ||
| 2006 | 2006 | smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) && |
| 2007 | 2007 | smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) { |
| 2008 | 2008 | smu_set_watermarks_table(smu, table, clock_ranges); |
| 2009 | − smu->watermarks_bitmap |= WATERMARKS_EXIST; | |
| 2010 | − smu->watermarks_bitmap &= ~WATERMARKS_LOADED; | |
| 2009 | + | |
| 2010 | + if (!(smu->watermarks_bitmap & WATERMARKS_EXIST)) { | |
| 2011 | + smu->watermarks_bitmap |= WATERMARKS_EXIST; | |
| 2012 | + smu->watermarks_bitmap &= ~WATERMARKS_LOADED; | |
| 2013 | + } | |
| 2011 | 2014 | } |
| 2012 | 2015 | |
| 2013 | 2016 | mutex_unlock(&smu->mutex); |
| @@ -1062,15 +1062,6 @@ static int navi10_display_config_changed(struct smu_context *smu) · 1061 unmodified lines | ||
| 1062 | 1062 | { |
| 1063 | 1063 | int ret = 0; |
| 1064 | 1064 | |
| 1065 | − if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && | |
| 1066 | − !(smu->watermarks_bitmap & WATERMARKS_LOADED)) { | |
| 1067 | − ret = smu_write_watermarks_table(smu); | |
| 1068 | − if (ret) | |
| 1069 | − return ret; | |
| 1070 | − | |
| 1071 | − smu->watermarks_bitmap |= WATERMARKS_LOADED; | |
| 1072 | − } | |
| 1073 | − | |
| 1074 | 1065 | if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && |
| 1075 | 1066 | smu_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) && |
| 1076 | 1067 | smu_feature_is_supported(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) { |
| @@ -1493,6 +1484,7 @@ static int navi10_set_watermarks_table(struct smu_context *smu, · 416 unmodified lines | ||
| 1493 | 1484 | *clock_ranges) |
| 1494 | 1485 | { |
| 1495 | 1486 | int i; |
| 1487 | + int ret = 0; | |
| 1496 | 1488 | Watermarks_t *table = watermarks; |
| 1497 | 1489 | |
| 1498 | 1490 | if (!table || !clock_ranges) |
| @@ -1544,6 +1536,18 @@ static int navi10_set_watermarks_table(struct smu_context *smu, · 45 unmodified lines | ||
| 1544 | 1536 | clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id; |
| 1545 | 1537 | } |
| 1546 | 1538 | |
| 1539 | + smu->watermarks_bitmap |= WATERMARKS_EXIST; | |
| 1540 | + | |
| 1541 | + /* pass data to smu controller */ | |
| 1542 | + if (!(smu->watermarks_bitmap & WATERMARKS_LOADED)) { | |
| 1543 | + ret = smu_write_watermarks_table(smu); | |
| 1544 | + if (ret) { | |
| 1545 | + pr_err("Failed to update WMTABLE!"); | |
| 1546 | + return ret; | |
| 1547 | + } | |
| 1548 | + smu->watermarks_bitmap |= WATERMARKS_LOADED; | |
| 1549 | + } | |
| 1550 | + | |
| 1547 | 1551 | return 0; |
| 1548 | 1552 | } |
| 1549 | 1553 | |
| @@ -111,8 +111,8 @@ static struct smu_12_0_cmn2aisc_mapping renoir_clk_map[SMU_CLK_COUNT] = { · 110 unmodified lines | ||
| 111 | 111 | CLK_MAP(GFXCLK, CLOCK_GFXCLK), |
| 112 | 112 | CLK_MAP(SCLK, CLOCK_GFXCLK), |
| 113 | 113 | CLK_MAP(SOCCLK, CLOCK_SOCCLK), |
| 114 | − CLK_MAP(UCLK, CLOCK_UMCCLK), | |
| 115 | − CLK_MAP(MCLK, CLOCK_UMCCLK), | |
| 114 | + CLK_MAP(UCLK, CLOCK_FCLK), | |
| 115 | + CLK_MAP(MCLK, CLOCK_FCLK), | |
| 116 | 116 | }; |
| 117 | 117 | |
| 118 | 118 | static struct smu_12_0_cmn2aisc_mapping renoir_table_map[SMU_TABLE_COUNT] = { |
| @@ -280,7 +280,7 @@ static int renoir_print_clk_levels(struct smu_context *smu, · 161 unmodified lines | ||
| 280 | 280 | break; |
| 281 | 281 | case SMU_MCLK: |
| 282 | 282 | count = NUM_MEMCLK_DPM_LEVELS; |
| 283 | − cur_value = metrics.ClockFrequency[CLOCK_UMCCLK]; | |
| 283 | + cur_value = metrics.ClockFrequency[CLOCK_FCLK]; | |
| 284 | 284 | break; |
| 285 | 285 | case SMU_DCEFCLK: |
| 286 | 286 | count = NUM_DCFCLK_DPM_LEVELS; |
| @@ -806,9 +806,10 @@ static int renoir_set_watermarks_table( · 519 unmodified lines | ||
| 806 | 806 | clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id; |
| 807 | 807 | } |
| 808 | 808 | |
| 809 | + smu->watermarks_bitmap |= WATERMARKS_EXIST; | |
| 810 | + | |
| 809 | 811 | /* pass data to smu controller */ |
| 810 | − if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && | |
| 811 | − !(smu->watermarks_bitmap & WATERMARKS_LOADED)) { | |
| 812 | + if (!(smu->watermarks_bitmap & WATERMARKS_LOADED)) { | |
| 812 | 813 | ret = smu_write_watermarks_table(smu); |
| 813 | 814 | if (ret) { |
| 814 | 815 | pr_err("Failed to update WMTABLE!"); |
| @@ -978,8 +978,12 @@ int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu) · 977 unmodified lines | ||
| 978 | 978 | struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks; |
| 979 | 979 | int ret = 0; |
| 980 | 980 | |
| 981 | − max_sustainable_clocks = kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks), | |
| 981 | + if (!smu->smu_table.max_sustainable_clocks) | |
| 982 | + max_sustainable_clocks = kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks), | |
| 982 | 983 | GFP_KERNEL); |
| 984 | + else | |
| 985 | + max_sustainable_clocks = smu->smu_table.max_sustainable_clocks; | |
| 986 | + | |
| 983 | 987 | smu->smu_table.max_sustainable_clocks = (void *)max_sustainable_clocks; |
| 984 | 988 | |
| 985 | 989 | max_sustainable_clocks->uclock = smu->smu_table.boot_values.uclk / 100; |
| @@ -458,9 +458,6 @@ int smu_v12_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_ · 457 unmodified lines | ||
| 458 | 458 | { |
| 459 | 459 | int ret = 0; |
| 460 | 460 | |
| 461 | − if (max < min) | |
| 462 | − return -EINVAL; | |
| 463 | − | |
| 464 | 461 | switch (clk_type) { |
| 465 | 462 | case SMU_GFXCLK: |
| 466 | 463 | case SMU_SCLK: |
| @@ -146,14 +146,14 @@ static const struct of_device_id komeda_of_match[] = { · 145 unmodified lines | ||
| 146 | 146 | |
| 147 | 147 | MODULE_DEVICE_TABLE(of, komeda_of_match); |
| 148 | 148 | |
| 149 | −static int komeda_rt_pm_suspend(struct device *dev) | |
| 149 | +static int __maybe_unused komeda_rt_pm_suspend(struct device *dev) | |
| 150 | 150 | { |
| 151 | 151 | struct komeda_drv *mdrv = dev_get_drvdata(dev); |
| 152 | 152 | |
| 153 | 153 | return komeda_dev_suspend(mdrv->mdev); |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | −static int komeda_rt_pm_resume(struct device *dev) | |
| 156 | +static int __maybe_unused komeda_rt_pm_resume(struct device *dev) | |
| 157 | 157 | { |
| 158 | 158 | struct komeda_drv *mdrv = dev_get_drvdata(dev); |
| 159 | 159 | |
| @@ -156,10 +156,8 @@ int bochs_hw_init(struct drm_device *dev) · 155 unmodified lines | ||
| 156 | 156 | size = min(size, mem); |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | − if (pci_request_region(pdev, 0, "bochs-drm") != 0) { | |
| 160 | − DRM_ERROR("Cannot request framebuffer\n"); | |
| 161 | − return -EBUSY; | |
| 162 | − } | |
| 159 | + if (pci_request_region(pdev, 0, "bochs-drm") != 0) | |
| 160 | + DRM_WARN("Cannot request framebuffer, boot fb still active?\n"); | |
| 163 | 161 | |
| 164 | 162 | bochs->fb_map = ioremap(addr, size); |
| 165 | 163 | if (bochs->fb_map == NULL) { |
| @@ -210,8 +210,7 @@ static int anx6345_dp_link_training(struct anx6345 *anx6345) · 209 unmodified lines | ||
| 210 | 210 | if (err) |
| 211 | 211 | return err; |
| 212 | 212 | |
| 213 | − dpcd[0] = drm_dp_max_link_rate(anx6345->dpcd); | |
| 214 | − dpcd[0] = drm_dp_link_rate_to_bw_code(dpcd[0]); | |
| 213 | + dpcd[0] = dp_bw; | |
| 215 | 214 | err = regmap_write(anx6345->map[I2C_IDX_DPTX], |
| 216 | 215 | SP_DP_MAIN_LINK_BW_SET_REG, dpcd[0]); |
| 217 | 216 | if (err) |
| @@ -1624,28 +1624,34 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) · 1623 unmodified lines | ||
| 1624 | 1624 | frame.colorspace = HDMI_COLORSPACE_RGB; |
| 1625 | 1625 | |
| 1626 | 1626 | /* Set up colorimetry */ |
| 1627 | − switch (hdmi->hdmi_data.enc_out_encoding) { | |
| 1628 | − case V4L2_YCBCR_ENC_601: | |
| 1629 | − if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) | |
| 1630 | − frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; | |
| 1631 | − else | |
| 1627 | + if (!hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { | |
| 1628 | + switch (hdmi->hdmi_data.enc_out_encoding) { | |
| 1629 | + case V4L2_YCBCR_ENC_601: | |
| 1630 | + if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) | |
| 1631 | + frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; | |
| 1632 | + else | |
| 1633 | + frame.colorimetry = HDMI_COLORIMETRY_ITU_601; | |
| 1634 | + frame.extended_colorimetry = | |
| 1635 | + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; | |
| 1636 | + break; | |
| 1637 | + case V4L2_YCBCR_ENC_709: | |
| 1638 | + if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) | |
| 1639 | + frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; | |
| 1640 | + else | |
| 1641 | + frame.colorimetry = HDMI_COLORIMETRY_ITU_709; | |
| 1642 | + frame.extended_colorimetry = | |
| 1643 | + HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; | |
| 1644 | + break; | |
| 1645 | + default: /* Carries no data */ | |
| 1632 | 1646 | frame.colorimetry = HDMI_COLORIMETRY_ITU_601; |
| 1647 | + frame.extended_colorimetry = | |
| 1648 | + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; | |
| 1649 | + break; | |
| 1650 | + } | |
| 1651 | + } else { | |
| 1652 | + frame.colorimetry = HDMI_COLORIMETRY_NONE; | |
| 1633 | 1653 | frame.extended_colorimetry = |
| 1634 | − HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; | |
| 1635 | − break; | |
| 1636 | − case V4L2_YCBCR_ENC_709: | |
| 1637 | − if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) | |
| 1638 | − frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; | |
| 1639 | − else | |
| 1640 | − frame.colorimetry = HDMI_COLORIMETRY_ITU_709; | |
| 1641 | − frame.extended_colorimetry = | |
| 1642 | − HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; | |
| 1643 | − break; | |
| 1644 | − default: /* Carries no data */ | |
| 1645 | − frame.colorimetry = HDMI_COLORIMETRY_ITU_601; | |
| 1646 | − frame.extended_colorimetry = | |
| 1647 | − HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; | |
| 1648 | − break; | |
| 1654 | + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; | |
| 1649 | 1655 | } |
| 1650 | 1656 | |
| 1651 | 1657 | frame.scan_mode = HDMI_SCAN_MODE_NONE; |
| @@ -1935,7 +1935,7 @@ static u8 drm_dp_calculate_rad(struct drm_dp_mst_port *port, · 1934 unmodified lines | ||
| 1935 | 1935 | return parent_lct + 1; |
| 1936 | 1936 | } |
| 1937 | 1937 | |
| 1938 | −static bool drm_dp_mst_is_dp_mst_end_device(u8 pdt, bool mcs) | |
| 1938 | +static bool drm_dp_mst_is_end_device(u8 pdt, bool mcs) | |
| 1939 | 1939 | { |
| 1940 | 1940 | switch (pdt) { |
| 1941 | 1941 | case DP_PEER_DEVICE_DP_LEGACY_CONV: |
| @@ -1965,13 +1965,13 @@ drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt, · 23 unmodified lines | ||
| 1965 | 1965 | |
| 1966 | 1966 | /* Teardown the old pdt, if there is one */ |
| 1967 | 1967 | if (port->pdt != DP_PEER_DEVICE_NONE) { |
| 1968 | − if (drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) { | |
| 1968 | + if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) { | |
| 1969 | 1969 | /* |
| 1970 | 1970 | * If the new PDT would also have an i2c bus, |
| 1971 | 1971 | * don't bother with reregistering it |
| 1972 | 1972 | */ |
| 1973 | 1973 | if (new_pdt != DP_PEER_DEVICE_NONE && |
| 1974 | − drm_dp_mst_is_dp_mst_end_device(new_pdt, new_mcs)) { | |
| 1974 | + drm_dp_mst_is_end_device(new_pdt, new_mcs)) { | |
| 1975 | 1975 | port->pdt = new_pdt; |
| 1976 | 1976 | port->mcs = new_mcs; |
| 1977 | 1977 | return 0; |
| @@ -1991,7 +1991,7 @@ drm_dp_port_set_pdt(struct drm_dp_mst_port *port, u8 new_pdt, · 13 unmodified lines | ||
| 1991 | 1991 | port->mcs = new_mcs; |
| 1992 | 1992 | |
| 1993 | 1993 | if (port->pdt != DP_PEER_DEVICE_NONE) { |
| 1994 | − if (drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) { | |
| 1994 | + if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) { | |
| 1995 | 1995 | /* add i2c over sideband */ |
| 1996 | 1996 | ret = drm_dp_mst_register_i2c_bus(&port->aux); |
| 1997 | 1997 | } else { |
| @@ -2172,7 +2172,7 @@ drm_dp_mst_port_add_connector(struct drm_dp_mst_branch *mstb, · 174 unmodified lines | ||
| 2172 | 2172 | } |
| 2173 | 2173 | |
| 2174 | 2174 | if (port->pdt != DP_PEER_DEVICE_NONE && |
| 2175 | − drm_dp_mst_is_dp_mst_end_device(port->pdt, port->mcs)) { | |
| 2175 | + drm_dp_mst_is_end_device(port->pdt, port->mcs)) { | |
| 2176 | 2176 | port->cached_edid = drm_get_edid(port->connector, |
| 2177 | 2177 | &port->aux.ddc); |
| 2178 | 2178 | drm_connector_set_tile_property(port->connector); |
| @@ -2302,14 +2302,18 @@ drm_dp_mst_handle_link_address_port(struct drm_dp_mst_branch *mstb, · 123 unmodified lines | ||
| 2302 | 2302 | mutex_unlock(&mgr->lock); |
| 2303 | 2303 | } |
| 2304 | 2304 | |
| 2305 | − if (old_ddps != port->ddps) { | |
| 2306 | − if (port->ddps) { | |
| 2307 | − if (!port->input) { | |
| 2308 | − drm_dp_send_enum_path_resources(mgr, mstb, | |
| 2309 | − port); | |
| 2310 | − } | |
| 2305 | + /* | |
| 2306 | + * Reprobe PBN caps on both hotplug, and when re-probing the link | |
| 2307 | + * for our parent mstb | |
| 2308 | + */ | |
| 2309 | + if (old_ddps != port->ddps || !created) { | |
| 2310 | + if (port->ddps && !port->input) { | |
| 2311 | + ret = drm_dp_send_enum_path_resources(mgr, mstb, | |
| 2312 | + port); | |
| 2313 | + if (ret == 1) | |
| 2314 | + changed = true; | |
| 2311 | 2315 | } else { |
| 2312 | − port->available_pbn = 0; | |
| 2316 | + port->full_pbn = 0; | |
| 2313 | 2317 | } |
| 2314 | 2318 | } |
| 2315 | 2319 | |
| @@ -2401,11 +2405,10 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb, · 85 unmodified lines | ||
| 2401 | 2405 | port->ddps = conn_stat->displayport_device_plug_status; |
| 2402 | 2406 | |
| 2403 | 2407 | if (old_ddps != port->ddps) { |
| 2404 | − if (port->ddps) { | |
| 2405 | − dowork = true; | |
| 2406 | − } else { | |
| 2407 | − port->available_pbn = 0; | |
| 2408 | − } | |
| 2408 | + if (port->ddps && !port->input) | |
| 2409 | + drm_dp_send_enum_path_resources(mgr, mstb, port); | |
| 2410 | + else | |
| 2411 | + port->full_pbn = 0; | |
| 2409 | 2412 | } |
| 2410 | 2413 | |
| 2411 | 2414 | new_pdt = port->input ? DP_PEER_DEVICE_NONE : conn_stat->peer_device_type; |
| @@ -2556,13 +2559,6 @@ static int drm_dp_check_and_send_link_address(struct drm_dp_mst_topology_mgr *mg · 144 unmodified lines | ||
| 2556 | 2559 | if (port->input || !port->ddps) |
| 2557 | 2560 | continue; |
| 2558 | 2561 | |
| 2559 | − if (!port->available_pbn) { | |
| 2560 | − drm_modeset_lock(&mgr->base.lock, NULL); | |
| 2561 | − drm_dp_send_enum_path_resources(mgr, mstb, port); | |
| 2562 | − drm_modeset_unlock(&mgr->base.lock); | |
| 2563 | − changed = true; | |
| 2564 | − } | |
| 2565 | − | |
| 2566 | 2562 | if (port->mstb) |
| 2567 | 2563 | mstb_child = drm_dp_mst_topology_get_mstb_validated( |
| 2568 | 2564 | mgr, port->mstb); |
| @@ -2990,6 +2986,7 @@ drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, · 421 unmodified lines | ||
| 2990 | 2986 | |
| 2991 | 2987 | ret = drm_dp_mst_wait_tx_reply(mstb, txmsg); |
| 2992 | 2988 | if (ret > 0) { |
| 2989 | + ret = 0; | |
| 2993 | 2990 | path_res = &txmsg->reply.u.path_resources; |
| 2994 | 2991 | |
| 2995 | 2992 | if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) { |
| @@ -3002,14 +2999,22 @@ drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, · 6 unmodified lines | ||
| 3002 | 2999 | path_res->port_number, |
| 3003 | 3000 | path_res->full_payload_bw_number, |
| 3004 | 3001 | path_res->avail_payload_bw_number); |
| 3005 | − port->available_pbn = | |
| 3006 | − path_res->avail_payload_bw_number; | |
| 3002 | + | |
| 3003 | + /* | |
| 3004 | + * If something changed, make sure we send a | |
| 3005 | + * hotplug | |
| 3006 | + */ | |
| 3007 | + if (port->full_pbn != path_res->full_payload_bw_number || | |
| 3008 | + port->fec_capable != path_res->fec_capable) | |
| 3009 | + ret = 1; | |
| 3010 | + | |
| 3011 | + port->full_pbn = path_res->full_payload_bw_number; | |
| 3007 | 3012 | port->fec_capable = path_res->fec_capable; |
| 3008 | 3013 | } |
| 3009 | 3014 | } |
| 3010 | 3015 | |
| 3011 | 3016 | kfree(txmsg); |
| 3012 | − return 0; | |
| 3017 | + return ret; | |
| 3013 | 3018 | } |
| 3014 | 3019 | |
| 3015 | 3020 | static struct drm_dp_mst_port *drm_dp_get_last_connected_port_to_mstb(struct drm_dp_mst_branch *mstb) |
| @@ -3596,13 +3601,9 @@ drm_dp_mst_topology_mgr_invalidate_mstb(struct drm_dp_mst_branch *mstb) · 580 unmodified lines | ||
| 3596 | 3601 | /* The link address will need to be re-sent on resume */ |
| 3597 | 3602 | mstb->link_address_sent = false; |
| 3598 | 3603 | |
| 3599 | − list_for_each_entry(port, &mstb->ports, next) { | |
| 3600 | − /* The PBN for each port will also need to be re-probed */ | |
| 3601 | − port->available_pbn = 0; | |
| 3602 | − | |
| 3604 | + list_for_each_entry(port, &mstb->ports, next) | |
| 3603 | 3605 | if (port->mstb) |
| 3604 | 3606 | drm_dp_mst_topology_mgr_invalidate_mstb(port->mstb); |
| 3605 | − } | |
| 3606 | 3607 | } |
| 3607 | 3608 | |
| 3608 | 3609 | /** |
| @@ -4829,41 +4830,102 @@ static bool drm_dp_mst_port_downstream_of_branch(struct drm_dp_mst_port *port, · 1220 unmodified lines | ||
| 4829 | 4830 | return false; |
| 4830 | 4831 | } |
| 4831 | 4832 | |
| 4832 | −static inline | |
| 4833 | −int drm_dp_mst_atomic_check_bw_limit(struct drm_dp_mst_branch *branch, | |
| 4834 | − struct drm_dp_mst_topology_state *mst_state) | |
| 4833 | +static int | |
| 4834 | +drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, | |
| 4835 | + struct drm_dp_mst_topology_state *state); | |
| 4836 | + | |
| 4837 | +static int | |
| 4838 | +drm_dp_mst_atomic_check_mstb_bw_limit(struct drm_dp_mst_branch *mstb, | |
| 4839 | + struct drm_dp_mst_topology_state *state) | |
| 4835 | 4840 | { |
| 4836 | − struct drm_dp_mst_port *port; | |
| 4837 | 4841 | struct drm_dp_vcpi_allocation *vcpi; |
| 4838 | − int pbn_limit = 0, pbn_used = 0; | |
| 4842 | + struct drm_dp_mst_port *port; | |
| 4843 | + int pbn_used = 0, ret; | |
| 4844 | + bool found = false; | |
| 4839 | 4845 | |
| 4840 | − list_for_each_entry(port, &branch->ports, next) { | |
| 4841 | − if (port->mstb) | |
| 4842 | − if (drm_dp_mst_atomic_check_bw_limit(port->mstb, mst_state)) | |
| 4843 | − return -ENOSPC; | |
| 4846 | + /* Check that we have at least one port in our state that's downstream | |
| 4847 | + * of this branch, otherwise we can skip this branch | |
| 4848 | + */ | |
| 4849 | + list_for_each_entry(vcpi, &state->vcpis, next) { | |
| 4850 | + if (!vcpi->pbn || | |
| 4851 | + !drm_dp_mst_port_downstream_of_branch(vcpi->port, mstb)) | |
| 4852 | + continue; | |
| 4844 | 4853 | |
| 4845 | − if (port->available_pbn > 0) | |
| 4846 | − pbn_limit = port->available_pbn; | |
| 4854 | + found = true; | |
| 4855 | + break; | |
| 4847 | 4856 | } |
| 4848 | − DRM_DEBUG_ATOMIC("[MST BRANCH:%p] branch has %d PBN available\n", | |
| 4849 | − branch, pbn_limit); | |
| 4857 | + if (!found) | |
| 4858 | + return 0; | |
| 4850 | 4859 | |
| 4851 | − list_for_each_entry(vcpi, &mst_state->vcpis, next) { | |
| 4852 | − if (!vcpi->pbn) | |
| 4853 | − continue; | |
| 4860 | + if (mstb->port_parent) | |
| 4861 | + DRM_DEBUG_ATOMIC("[MSTB:%p] [MST PORT:%p] Checking bandwidth limits on [MSTB:%p]\n", | |
| 4862 | + mstb->port_parent->parent, mstb->port_parent, | |
| 4863 | + mstb); | |
| 4864 | + else | |
| 4865 | + DRM_DEBUG_ATOMIC("[MSTB:%p] Checking bandwidth limits\n", | |
| 4866 | + mstb); | |
| 4867 | + | |
| 4868 | + list_for_each_entry(port, &mstb->ports, next) { | |
| 4869 | + ret = drm_dp_mst_atomic_check_port_bw_limit(port, state); | |
| 4870 | + if (ret < 0) | |
| 4871 | + return ret; | |
| 4854 | 4872 | |
| 4855 | − if (drm_dp_mst_port_downstream_of_branch(vcpi->port, branch)) | |
| 4856 | − pbn_used += vcpi->pbn; | |
| 4873 | + pbn_used += ret; | |
| 4857 | 4874 | } |
| 4858 | − DRM_DEBUG_ATOMIC("[MST BRANCH:%p] branch used %d PBN\n", | |
| 4859 | − branch, pbn_used); | |
| 4860 | 4875 | |
| 4861 | − if (pbn_used > pbn_limit) { | |
| 4862 | − DRM_DEBUG_ATOMIC("[MST BRANCH:%p] No available bandwidth\n", | |
| 4863 | − branch); | |
| 4876 | + return pbn_used; | |
| 4877 | +} | |
| 4878 | + | |
| 4879 | +static int | |
| 4880 | +drm_dp_mst_atomic_check_port_bw_limit(struct drm_dp_mst_port *port, | |
| 4881 | + struct drm_dp_mst_topology_state *state) | |
| 4882 | +{ | |
| 4883 | + struct drm_dp_vcpi_allocation *vcpi; | |
| 4884 | + int pbn_used = 0; | |
| 4885 | + | |
| 4886 | + if (port->pdt == DP_PEER_DEVICE_NONE) | |
| 4887 | + return 0; | |
| 4888 | + | |
| 4889 | + if (drm_dp_mst_is_end_device(port->pdt, port->mcs)) { | |
| 4890 | + bool found = false; | |
| 4891 | + | |
| 4892 | + list_for_each_entry(vcpi, &state->vcpis, next) { | |
| 4893 | + if (vcpi->port != port) | |
| 4894 | + continue; | |
| 4895 | + if (!vcpi->pbn) | |
| 4896 | + return 0; | |
| 4897 | + | |
| 4898 | + found = true; | |
| 4899 | + break; | |
| 4900 | + } | |
| 4901 | + if (!found) | |
| 4902 | + return 0; | |
| 4903 | + | |
| 4904 | + /* This should never happen, as it means we tried to | |
| 4905 | + * set a mode before querying the full_pbn | |
| 4906 | + */ | |
| 4907 | + if (WARN_ON(!port->full_pbn)) | |
| 4908 | + return -EINVAL; | |
| 4909 | + | |
| 4910 | + pbn_used = vcpi->pbn; | |
| 4911 | + } else { | |
| 4912 | + pbn_used = drm_dp_mst_atomic_check_mstb_bw_limit(port->mstb, | |
| 4913 | + state); | |
| 4914 | + if (pbn_used <= 0) | |
| 4915 | + return pbn_used; | |
| 4916 | + } | |
| 4917 | + | |
| 4918 | + if (pbn_used > port->full_pbn) { | |
| 4919 | + DRM_DEBUG_ATOMIC("[MSTB:%p] [MST PORT:%p] required PBN of %d exceeds port limit of %d\n", | |
| 4920 | + port->parent, port, pbn_used, | |
| 4921 | + port->full_pbn); | |
| 4864 | 4922 | return -ENOSPC; |
| 4865 | 4923 | } |
| 4866 | − return 0; | |
| 4924 | + | |
| 4925 | + DRM_DEBUG_ATOMIC("[MSTB:%p] [MST PORT:%p] uses %d out of %d PBN\n", | |
| 4926 | + port->parent, port, pbn_used, port->full_pbn); | |
| 4927 | + | |
| 4928 | + return pbn_used; | |
| 4867 | 4929 | } |
| 4868 | 4930 | |
| 4869 | 4931 | static inline int |
| @@ -5061,9 +5123,15 @@ int drm_dp_mst_atomic_check(struct drm_atomic_state *state) · 191 unmodified lines | ||
| 5061 | 5123 | ret = drm_dp_mst_atomic_check_vcpi_alloc_limit(mgr, mst_state); |
| 5062 | 5124 | if (ret) |
| 5063 | 5125 | break; |
| 5064 | − ret = drm_dp_mst_atomic_check_bw_limit(mgr->mst_primary, mst_state); | |
| 5065 | − if (ret) | |
| 5126 | + | |
| 5127 | + mutex_lock(&mgr->lock); | |
| 5128 | + ret = drm_dp_mst_atomic_check_mstb_bw_limit(mgr->mst_primary, | |
| 5129 | + mst_state); | |
| 5130 | + mutex_unlock(&mgr->lock); | |
| 5131 | + if (ret < 0) | |
| 5066 | 5132 | break; |
| 5133 | + else | |
| 5134 | + ret = 0; | |
| 5067 | 5135 | } |
| 5068 | 5136 | |
| 5069 | 5137 | return ret; |
| @@ -254,11 +254,16 @@ static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem) · 253 unmodified lines | ||
| 254 | 254 | if (ret) |
| 255 | 255 | goto err_zero_use; |
| 256 | 256 | |
| 257 | − if (obj->import_attach) | |
| 257 | + if (obj->import_attach) { | |
| 258 | 258 | shmem->vaddr = dma_buf_vmap(obj->import_attach->dmabuf); |
| 259 | − else | |
| 259 | + } else { | |
| 260 | + pgprot_t prot = PAGE_KERNEL; | |
| 261 | + | |
| 262 | + if (!shmem->map_cached) | |
| 263 | + prot = pgprot_writecombine(prot); | |
| 260 | 264 | shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, |
| 261 | − VM_MAP, pgprot_writecombine(PAGE_KERNEL)); | |
| 265 | + VM_MAP, prot); | |
| 266 | + } | |
| 262 | 267 | |
| 263 | 268 | if (!shmem->vaddr) { |
| 264 | 269 | DRM_DEBUG_KMS("Failed to vmap pages\n"); |
| @@ -540,8 +545,9 @@ int drm_gem_shmem_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) · 275 unmodified lines | ||
| 540 | 545 | } |
| 541 | 546 | |
| 542 | 547 | vma->vm_flags |= VM_MIXEDMAP | VM_DONTEXPAND; |
| 543 | − vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); | |
| 544 | − vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); | |
| 548 | + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | |
| 549 | + if (!shmem->map_cached) | |
| 550 | + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); | |
| 545 | 551 | vma->vm_ops = &drm_gem_shmem_vm_ops; |
| 546 | 552 | |
| 547 | 553 | return 0; |
| @@ -542,10 +542,12 @@ int drm_mode_create_lease_ioctl(struct drm_device *dev, · 541 unmodified lines | ||
| 542 | 542 | } |
| 543 | 543 | |
| 544 | 544 | DRM_DEBUG_LEASE("Creating lease\n"); |
| 545 | + /* lessee will take the ownership of leases */ | |
| 545 | 546 | lessee = drm_lease_create(lessor, &leases); |
| 546 | 547 | |
| 547 | 548 | if (IS_ERR(lessee)) { |
| 548 | 549 | ret = PTR_ERR(lessee); |
| 550 | + idr_destroy(&leases); | |
| 549 | 551 | goto out_leases; |
| 550 | 552 | } |
| 551 | 553 | |
| @@ -580,7 +582,6 @@ out_lessee: · 28 unmodified lines | ||
| 580 | 582 | |
| 581 | 583 | out_leases: |
| 582 | 584 | put_unused_fd(fd); |
| 583 | − idr_destroy(&leases); | |
| 584 | 585 | |
| 585 | 586 | DRM_DEBUG_LEASE("drm_mode_create_lease_ioctl failed: %d\n", ret); |
| 586 | 587 | return ret; |
| @@ -55,6 +55,7 @@ static const char * const decon_clks_name[] = { · 54 unmodified lines | ||
| 55 | 55 | struct decon_context { |
| 56 | 56 | struct device *dev; |
| 57 | 57 | struct drm_device *drm_dev; |
| 58 | + void *dma_priv; | |
| 58 | 59 | struct exynos_drm_crtc *crtc; |
| 59 | 60 | struct exynos_drm_plane planes[WINDOWS_NR]; |
| 60 | 61 | struct exynos_drm_plane_config configs[WINDOWS_NR]; |
| @@ -644,7 +645,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) · 583 unmodified lines | ||
| 644 | 645 | |
| 645 | 646 | decon_clear_channels(ctx->crtc); |
| 646 | 647 | |
| 647 | − return exynos_drm_register_dma(drm_dev, dev); | |
| 648 | + return exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); | |
| 648 | 649 | } |
| 649 | 650 | |
| 650 | 651 | static void decon_unbind(struct device *dev, struct device *master, void *data) |
| @@ -654,7 +655,7 @@ static void decon_unbind(struct device *dev, struct device *master, void *data) · 3 unmodified lines | ||
| 654 | 655 | decon_atomic_disable(ctx->crtc); |
| 655 | 656 | |
| 656 | 657 | /* detach this sub driver from iommu mapping if supported. */ |
| 657 | − exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev); | |
| 658 | + exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv); | |
| 658 | 659 | } |
| 659 | 660 | |
| 660 | 661 | static const struct component_ops decon_component_ops = { |
| @@ -40,6 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | struct decon_context { |
| 41 | 41 | struct device *dev; |
| 42 | 42 | struct drm_device *drm_dev; |
| 43 | + void *dma_priv; | |
| 43 | 44 | struct exynos_drm_crtc *crtc; |
| 44 | 45 | struct exynos_drm_plane planes[WINDOWS_NR]; |
| 45 | 46 | struct exynos_drm_plane_config configs[WINDOWS_NR]; |
| @@ -127,13 +128,13 @@ static int decon_ctx_initialize(struct decon_context *ctx, · 81 unmodified lines | ||
| 127 | 128 | |
| 128 | 129 | decon_clear_channels(ctx->crtc); |
| 129 | 130 | |
| 130 | − return exynos_drm_register_dma(drm_dev, ctx->dev); | |
| 131 | + return exynos_drm_register_dma(drm_dev, ctx->dev, &ctx->dma_priv); | |
| 131 | 132 | } |
| 132 | 133 | |
| 133 | 134 | static void decon_ctx_remove(struct decon_context *ctx) |
| 134 | 135 | { |
| 135 | 136 | /* detach this sub driver from iommu mapping if supported. */ |
| 136 | − exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev); | |
| 137 | + exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv); | |
| 137 | 138 | } |
| 138 | 139 | |
| 139 | 140 | static u32 decon_calc_clkdiv(struct decon_context *ctx, |
| @@ -58,7 +58,7 @@ static inline void clear_dma_max_seg_size(struct device *dev) · 57 unmodified lines | ||
| 58 | 58 | * mapping. |
| 59 | 59 | */ |
| 60 | 60 | static int drm_iommu_attach_device(struct drm_device *drm_dev, |
| 61 | − struct device *subdrv_dev) | |
| 61 | + struct device *subdrv_dev, void **dma_priv) | |
| 62 | 62 | { |
| 63 | 63 | struct exynos_drm_private *priv = drm_dev->dev_private; |
| 64 | 64 | int ret; |
| @@ -74,7 +74,14 @@ static int drm_iommu_attach_device(struct drm_device *drm_dev, · 9 unmodified lines | ||
| 74 | 74 | return ret; |
| 75 | 75 | |
| 76 | 76 | if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { |
| 77 | − if (to_dma_iommu_mapping(subdrv_dev)) | |
| 77 | + /* | |
| 78 | + * Keep the original DMA mapping of the sub-device and | |
| 79 | + * restore it on Exynos DRM detach, otherwise the DMA | |
| 80 | + * framework considers it as IOMMU-less during the next | |
| 81 | + * probe (in case of deferred probe or modular build) | |
| 82 | + */ | |
| 83 | + *dma_priv = to_dma_iommu_mapping(subdrv_dev); | |
| 84 | + if (*dma_priv) | |
| 78 | 85 | arm_iommu_detach_device(subdrv_dev); |
| 79 | 86 | |
| 80 | 87 | ret = arm_iommu_attach_device(subdrv_dev, priv->mapping); |
| @@ -98,19 +105,21 @@ static int drm_iommu_attach_device(struct drm_device *drm_dev, · 17 unmodified lines | ||
| 98 | 105 | * mapping |
| 99 | 106 | */ |
| 100 | 107 | static void drm_iommu_detach_device(struct drm_device *drm_dev, |
| 101 | − struct device *subdrv_dev) | |
| 108 | + struct device *subdrv_dev, void **dma_priv) | |
| 102 | 109 | { |
| 103 | 110 | struct exynos_drm_private *priv = drm_dev->dev_private; |
| 104 | 111 | |
| 105 | − if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) | |
| 112 | + if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { | |
| 106 | 113 | arm_iommu_detach_device(subdrv_dev); |
| 107 | − else if (IS_ENABLED(CONFIG_IOMMU_DMA)) | |
| 114 | + arm_iommu_attach_device(subdrv_dev, *dma_priv); | |
| 115 | + } else if (IS_ENABLED(CONFIG_IOMMU_DMA)) | |
| 108 | 116 | iommu_detach_device(priv->mapping, subdrv_dev); |
| 109 | 117 | |
| 110 | 118 | clear_dma_max_seg_size(subdrv_dev); |
| 111 | 119 | } |
| 112 | 120 | |
| 113 | −int exynos_drm_register_dma(struct drm_device *drm, struct device *dev) | |
| 121 | +int exynos_drm_register_dma(struct drm_device *drm, struct device *dev, | |
| 122 | + void **dma_priv) | |
| 114 | 123 | { |
| 115 | 124 | struct exynos_drm_private *priv = drm->dev_private; |
| 116 | 125 | |
| @@ -137,13 +146,14 @@ int exynos_drm_register_dma(struct drm_device *drm, struct device *dev) · 20 unmodified lines | ||
| 137 | 146 | priv->mapping = mapping; |
| 138 | 147 | } |
| 139 | 148 | |
| 140 | − return drm_iommu_attach_device(drm, dev); | |
| 149 | + return drm_iommu_attach_device(drm, dev, dma_priv); | |
| 141 | 150 | } |
| 142 | 151 | |
| 143 | −void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev) | |
| 152 | +void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev, | |
| 153 | + void **dma_priv) | |
| 144 | 154 | { |
| 145 | 155 | if (IS_ENABLED(CONFIG_EXYNOS_IOMMU)) |
| 146 | − drm_iommu_detach_device(drm, dev); | |
| 156 | + drm_iommu_detach_device(drm, dev, dma_priv); | |
| 147 | 157 | } |
| 148 | 158 | |
| 149 | 159 | void exynos_drm_cleanup_dma(struct drm_device *drm) |
| @@ -223,8 +223,10 @@ static inline bool is_drm_iommu_supported(struct drm_device *drm_dev) · 222 unmodified lines | ||
| 223 | 223 | return priv->mapping ? true : false; |
| 224 | 224 | } |
| 225 | 225 | |
| 226 | −int exynos_drm_register_dma(struct drm_device *drm, struct device *dev); | |
| 227 | −void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev); | |
| 226 | +int exynos_drm_register_dma(struct drm_device *drm, struct device *dev, | |
| 227 | + void **dma_priv); | |
| 228 | +void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev, | |
| 229 | + void **dma_priv); | |
| 228 | 230 | void exynos_drm_cleanup_dma(struct drm_device *drm); |
| 229 | 231 | |
| 230 | 232 | #ifdef CONFIG_DRM_EXYNOS_DPI |
| @@ -1773,8 +1773,9 @@ static int exynos_dsi_probe(struct platform_device *pdev) · 1772 unmodified lines | ||
| 1773 | 1773 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dsi->supplies), |
| 1774 | 1774 | dsi->supplies); |
| 1775 | 1775 | if (ret) { |
| 1776 | − dev_info(dev, "failed to get regulators: %d\n", ret); | |
| 1777 | − return -EPROBE_DEFER; | |
| 1776 | + if (ret != -EPROBE_DEFER) | |
| 1777 | + dev_info(dev, "failed to get regulators: %d\n", ret); | |
| 1778 | + return ret; | |
| 1778 | 1779 | } |
| 1779 | 1780 | |
| 1780 | 1781 | dsi->clks = devm_kcalloc(dev, |
| @@ -1787,9 +1788,10 @@ static int exynos_dsi_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 1787 | 1788 | dsi->clks[i] = devm_clk_get(dev, clk_names[i]); |
| 1788 | 1789 | if (IS_ERR(dsi->clks[i])) { |
| 1789 | 1790 | if (strcmp(clk_names[i], "sclk_mipi") == 0) { |
| 1790 | − strcpy(clk_names[i], OLD_SCLK_MIPI_CLK_NAME); | |
| 1791 | − i--; | |
| 1792 | − continue; | |
| 1791 | + dsi->clks[i] = devm_clk_get(dev, | |
| 1792 | + OLD_SCLK_MIPI_CLK_NAME); | |
| 1793 | + if (!IS_ERR(dsi->clks[i])) | |
| 1794 | + continue; | |
| 1793 | 1795 | } |
| 1794 | 1796 | |
| 1795 | 1797 | dev_info(dev, "failed to get the clock: %s\n", |
| @@ -97,6 +97,7 @@ struct fimc_scaler { · 96 unmodified lines | ||
| 97 | 97 | struct fimc_context { |
| 98 | 98 | struct exynos_drm_ipp ipp; |
| 99 | 99 | struct drm_device *drm_dev; |
| 100 | + void *dma_priv; | |
| 100 | 101 | struct device *dev; |
| 101 | 102 | struct exynos_drm_ipp_task *task; |
| 102 | 103 | struct exynos_drm_ipp_formats *formats; |
| @@ -1133,7 +1134,7 @@ static int fimc_bind(struct device *dev, struct device *master, void *data) · 1030 unmodified lines | ||
| 1133 | 1134 | |
| 1134 | 1135 | ctx->drm_dev = drm_dev; |
| 1135 | 1136 | ipp->drm_dev = drm_dev; |
| 1136 | − exynos_drm_register_dma(drm_dev, dev); | |
| 1137 | + exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); | |
| 1137 | 1138 | |
| 1138 | 1139 | exynos_drm_ipp_register(dev, ipp, &ipp_funcs, |
| 1139 | 1140 | DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | |
| @@ -1153,7 +1154,7 @@ static void fimc_unbind(struct device *dev, struct device *master, · 13 unmodified lines | ||
| 1153 | 1154 | struct exynos_drm_ipp *ipp = &ctx->ipp; |
| 1154 | 1155 | |
| 1155 | 1156 | exynos_drm_ipp_unregister(dev, ipp); |
| 1156 | − exynos_drm_unregister_dma(drm_dev, dev); | |
| 1157 | + exynos_drm_unregister_dma(drm_dev, dev, &ctx->dma_priv); | |
| 1157 | 1158 | } |
| 1158 | 1159 | |
| 1159 | 1160 | static const struct component_ops fimc_component_ops = { |
| @@ -167,6 +167,7 @@ static struct fimd_driver_data exynos5420_fimd_driver_data = { · 166 unmodified lines | ||
| 167 | 167 | struct fimd_context { |
| 168 | 168 | struct device *dev; |
| 169 | 169 | struct drm_device *drm_dev; |
| 170 | + void *dma_priv; | |
| 170 | 171 | struct exynos_drm_crtc *crtc; |
| 171 | 172 | struct exynos_drm_plane planes[WINDOWS_NR]; |
| 172 | 173 | struct exynos_drm_plane_config configs[WINDOWS_NR]; |
| @@ -1090,7 +1091,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) · 917 unmodified lines | ||
| 1090 | 1091 | if (is_drm_iommu_supported(drm_dev)) |
| 1091 | 1092 | fimd_clear_channels(ctx->crtc); |
| 1092 | 1093 | |
| 1093 | − return exynos_drm_register_dma(drm_dev, dev); | |
| 1094 | + return exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); | |
| 1094 | 1095 | } |
| 1095 | 1096 | |
| 1096 | 1097 | static void fimd_unbind(struct device *dev, struct device *master, |
| @@ -1100,7 +1101,7 @@ static void fimd_unbind(struct device *dev, struct device *master, · 3 unmodified lines | ||
| 1100 | 1101 | |
| 1101 | 1102 | fimd_atomic_disable(ctx->crtc); |
| 1102 | 1103 | |
| 1103 | − exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev); | |
| 1104 | + exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev, &ctx->dma_priv); | |
| 1104 | 1105 | |
| 1105 | 1106 | if (ctx->encoder) |
| 1106 | 1107 | exynos_dpi_remove(ctx->encoder); |
| @@ -232,6 +232,7 @@ struct g2d_runqueue_node { · 231 unmodified lines | ||
| 232 | 232 | |
| 233 | 233 | struct g2d_data { |
| 234 | 234 | struct device *dev; |
| 235 | + void *dma_priv; | |
| 235 | 236 | struct clk *gate_clk; |
| 236 | 237 | void __iomem *regs; |
| 237 | 238 | int irq; |
| @@ -1409,7 +1410,7 @@ static int g2d_bind(struct device *dev, struct device *master, void *data) · 1171 unmodified lines | ||
| 1409 | 1410 | return ret; |
| 1410 | 1411 | } |
| 1411 | 1412 | |
| 1412 | − ret = exynos_drm_register_dma(drm_dev, dev); | |
| 1413 | + ret = exynos_drm_register_dma(drm_dev, dev, &g2d->dma_priv); | |
| 1413 | 1414 | if (ret < 0) { |
| 1414 | 1415 | dev_err(dev, "failed to enable iommu.\n"); |
| 1415 | 1416 | g2d_fini_cmdlist(g2d); |
| @@ -1434,7 +1435,7 @@ static void g2d_unbind(struct device *dev, struct device *master, void *data) · 18 unmodified lines | ||
| 1434 | 1435 | priv->g2d_dev = NULL; |
| 1435 | 1436 | |
| 1436 | 1437 | cancel_work_sync(&g2d->runqueue_work); |
| 1437 | − exynos_drm_unregister_dma(g2d->drm_dev, dev); | |
| 1438 | + exynos_drm_unregister_dma(g2d->drm_dev, dev, &g2d->dma_priv); | |
| 1438 | 1439 | } |
| 1439 | 1440 | |
| 1440 | 1441 | static const struct component_ops g2d_component_ops = { |
| @@ -97,6 +97,7 @@ struct gsc_scaler { · 96 unmodified lines | ||
| 97 | 97 | struct gsc_context { |
| 98 | 98 | struct exynos_drm_ipp ipp; |
| 99 | 99 | struct drm_device *drm_dev; |
| 100 | + void *dma_priv; | |
| 100 | 101 | struct device *dev; |
| 101 | 102 | struct exynos_drm_ipp_task *task; |
| 102 | 103 | struct exynos_drm_ipp_formats *formats; |
| @@ -1169,7 +1170,7 @@ static int gsc_bind(struct device *dev, struct device *master, void *data) · 1066 unmodified lines | ||
| 1169 | 1170 | |
| 1170 | 1171 | ctx->drm_dev = drm_dev; |
| 1171 | 1172 | ctx->drm_dev = drm_dev; |
| 1172 | − exynos_drm_register_dma(drm_dev, dev); | |
| 1173 | + exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv); | |
| 1173 | 1174 | |
| 1174 | 1175 | exynos_drm_ipp_register(dev, ipp, &ipp_funcs, |
| 1175 | 1176 | DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | |
| @@ -1189,7 +1190,7 @@ static void gsc_unbind(struct device *dev, struct device *master, · 13 unmodified lines | ||
| 1189 | 1190 | struct exynos_drm_ipp *ipp = &ctx->ipp; |
| 1190 | 1191 | |
| 1191 | 1192 | exynos_drm_ipp_unregister(dev, ipp); |
| 1192 | − exynos_drm_unregister_dma(drm_dev, dev); | |
| 1193 | + exynos_drm_unregister_dma(drm_dev, dev, &ctx->dma_priv); | |
| 1193 | 1194 | } |
| 1194 | 1195 | |
| 1195 | 1196 | static const struct component_ops gsc_component_ops = { |
| @@ -56,6 +56,7 @@ struct rot_variant { · 55 unmodified lines | ||
| 56 | 56 | struct rot_context { |
| 57 | 57 | struct exynos_drm_ipp ipp; |
| 58 | 58 | struct drm_device *drm_dev; |
| 59 | + void *dma_priv; | |
| 59 | 60 | struct device *dev; |
| 60 | 61 | void __iomem *regs; |
| 61 | 62 | struct clk *clock; |
| @@ -243,7 +244,7 @@ static int rotator_bind(struct device *dev, struct device *master, void *data) · 181 unmodified lines | ||
| 243 | 244 | |
| 244 | 245 | rot->drm_dev = drm_dev; |
| 245 | 246 | ipp->drm_dev = drm_dev; |
| 246 | − exynos_drm_register_dma(drm_dev, dev); | |
| 247 | + exynos_drm_register_dma(drm_dev, dev, &rot->dma_priv); | |
| 247 | 248 | |
| 248 | 249 | exynos_drm_ipp_register(dev, ipp, &ipp_funcs, |
| 249 | 250 | DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE, |
| @@ -261,7 +262,7 @@ static void rotator_unbind(struct device *dev, struct device *master, · 11 unmodified lines | ||
| 261 | 262 | struct exynos_drm_ipp *ipp = &rot->ipp; |
| 262 | 263 | |
| 263 | 264 | exynos_drm_ipp_unregister(dev, ipp); |
| 264 | − exynos_drm_unregister_dma(rot->drm_dev, rot->dev); | |
| 265 | + exynos_drm_unregister_dma(rot->drm_dev, rot->dev, &rot->dma_priv); | |
| 265 | 266 | } |
| 266 | 267 | |
| 267 | 268 | static const struct component_ops rotator_component_ops = { |
| @@ -39,6 +39,7 @@ struct scaler_data { · 38 unmodified lines | ||
| 39 | 39 | struct scaler_context { |
| 40 | 40 | struct exynos_drm_ipp ipp; |
| 41 | 41 | struct drm_device *drm_dev; |
| 42 | + void *dma_priv; | |
| 42 | 43 | struct device *dev; |
| 43 | 44 | void __iomem *regs; |
| 44 | 45 | struct clk *clock[SCALER_MAX_CLK]; |
| @@ -450,7 +451,7 @@ static int scaler_bind(struct device *dev, struct device *master, void *data) · 405 unmodified lines | ||
| 450 | 451 | |
| 451 | 452 | scaler->drm_dev = drm_dev; |
| 452 | 453 | ipp->drm_dev = drm_dev; |
| 453 | − exynos_drm_register_dma(drm_dev, dev); | |
| 454 | + exynos_drm_register_dma(drm_dev, dev, &scaler->dma_priv); | |
| 454 | 455 | |
| 455 | 456 | exynos_drm_ipp_register(dev, ipp, &ipp_funcs, |
| 456 | 457 | DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE | |
| @@ -470,7 +471,8 @@ static void scaler_unbind(struct device *dev, struct device *master, · 13 unmodified lines | ||
| 470 | 471 | struct exynos_drm_ipp *ipp = &scaler->ipp; |
| 471 | 472 | |
| 472 | 473 | exynos_drm_ipp_unregister(dev, ipp); |
| 473 | − exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev); | |
| 474 | + exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev, | |
| 475 | + &scaler->dma_priv); | |
| 474 | 476 | } |
| 475 | 477 | |
| 476 | 478 | static const struct component_ops scaler_component_ops = { |
| @@ -1805,18 +1805,10 @@ static int hdmi_resources_init(struct hdmi_context *hdata) · 1804 unmodified lines | ||
| 1805 | 1805 | |
| 1806 | 1806 | hdata->reg_hdmi_en = devm_regulator_get_optional(dev, "hdmi-en"); |
| 1807 | 1807 | |
| 1808 | − if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV) { | |
| 1808 | + if (PTR_ERR(hdata->reg_hdmi_en) != -ENODEV) | |
| 1809 | 1809 | if (IS_ERR(hdata->reg_hdmi_en)) |
| 1810 | 1810 | return PTR_ERR(hdata->reg_hdmi_en); |
| 1811 | 1811 | |
| 1812 | − ret = regulator_enable(hdata->reg_hdmi_en); | |
| 1813 | − if (ret) { | |
| 1814 | − DRM_DEV_ERROR(dev, | |
| 1815 | − "failed to enable hdmi-en regulator\n"); | |
| 1816 | − return ret; | |
| 1817 | − } | |
| 1818 | − } | |
| 1819 | − | |
| 1820 | 1812 | return hdmi_bridge_init(hdata); |
| 1821 | 1813 | } |
| 1822 | 1814 | |
| @@ -2023,6 +2015,15 @@ static int hdmi_probe(struct platform_device *pdev) · 200 unmodified lines | ||
| 2023 | 2015 | } |
| 2024 | 2016 | } |
| 2025 | 2017 | |
| 2018 | + if (!IS_ERR(hdata->reg_hdmi_en)) { | |
| 2019 | + ret = regulator_enable(hdata->reg_hdmi_en); | |
| 2020 | + if (ret) { | |
| 2021 | + DRM_DEV_ERROR(dev, | |
| 2022 | + "failed to enable hdmi-en regulator\n"); | |
| 2023 | + goto err_hdmiphy; | |
| 2024 | + } | |
| 2025 | + } | |
| 2026 | + | |
| 2026 | 2027 | pm_runtime_enable(dev); |
| 2027 | 2028 | |
| 2028 | 2029 | audio_infoframe = &hdata->audio.infoframe; |
| @@ -2047,7 +2048,8 @@ err_unregister_audio: · 18 unmodified lines | ||
| 2047 | 2048 | |
| 2048 | 2049 | err_rpm_disable: |
| 2049 | 2050 | pm_runtime_disable(dev); |
| 2050 | − | |
| 2051 | + if (!IS_ERR(hdata->reg_hdmi_en)) | |
| 2052 | + regulator_disable(hdata->reg_hdmi_en); | |
| 2051 | 2053 | err_hdmiphy: |
| 2052 | 2054 | if (hdata->hdmiphy_port) |
| 2053 | 2055 | put_device(&hdata->hdmiphy_port->dev); |
| @@ -94,6 +94,7 @@ struct mixer_context { · 93 unmodified lines | ||
| 94 | 94 | struct platform_device *pdev; |
| 95 | 95 | struct device *dev; |
| 96 | 96 | struct drm_device *drm_dev; |
| 97 | + void *dma_priv; | |
| 97 | 98 | struct exynos_drm_crtc *crtc; |
| 98 | 99 | struct exynos_drm_plane planes[MIXER_WIN_NR]; |
| 99 | 100 | unsigned long flags; |
| @@ -894,12 +895,14 @@ static int mixer_initialize(struct mixer_context *mixer_ctx, · 794 unmodified lines | ||
| 894 | 895 | } |
| 895 | 896 | } |
| 896 | 897 | |
| 897 | − return exynos_drm_register_dma(drm_dev, mixer_ctx->dev); | |
| 898 | + return exynos_drm_register_dma(drm_dev, mixer_ctx->dev, | |
| 899 | + &mixer_ctx->dma_priv); | |
| 898 | 900 | } |
| 899 | 901 | |
| 900 | 902 | static void mixer_ctx_remove(struct mixer_context *mixer_ctx) |
| 901 | 903 | { |
| 902 | − exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev); | |
| 904 | + exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev, | |
| 905 | + &mixer_ctx->dma_priv); | |
| 903 | 906 | } |
| 904 | 907 | |
| 905 | 908 | static int mixer_enable_vblank(struct exynos_drm_crtc *crtc) |
| @@ -83,7 +83,6 @@ · 82 unmodified lines | ||
| 83 | 83 | #define VSIZE_OFST 20 |
| 84 | 84 | #define LDI_INT_EN 0x741C |
| 85 | 85 | #define FRAME_END_INT_EN_OFST 1 |
| 86 | −#define UNDERFLOW_INT_EN_OFST 2 | |
| 87 | 86 | #define LDI_CTRL 0x7420 |
| 88 | 87 | #define BPP_OFST 3 |
| 89 | 88 | #define DATA_GATE_EN BIT(2) |
| @@ -46,7 +46,6 @@ struct ade_hw_ctx { · 45 unmodified lines | ||
| 46 | 46 | struct clk *media_noc_clk; |
| 47 | 47 | struct clk *ade_pix_clk; |
| 48 | 48 | struct reset_control *reset; |
| 49 | − struct work_struct display_reset_wq; | |
| 50 | 49 | bool power_on; |
| 51 | 50 | int irq; |
| 52 | 51 | |
| @@ -136,7 +135,6 @@ static void ade_init(struct ade_hw_ctx *ctx) · 83 unmodified lines | ||
| 136 | 135 | */ |
| 137 | 136 | ade_update_bits(base + ADE_CTRL, FRM_END_START_OFST, |
| 138 | 137 | FRM_END_START_MASK, REG_EFFECTIVE_IN_ADEEN_FRMEND); |
| 139 | − ade_update_bits(base + LDI_INT_EN, UNDERFLOW_INT_EN_OFST, MASK(1), 1); | |
| 140 | 138 | } |
| 141 | 139 | |
| 142 | 140 | static bool ade_crtc_mode_fixup(struct drm_crtc *crtc, |
| @@ -304,17 +302,6 @@ static void ade_crtc_disable_vblank(struct drm_crtc *crtc) · 161 unmodified lines | ||
| 304 | 302 | MASK(1), 0); |
| 305 | 303 | } |
| 306 | 304 | |
| 307 | −static void drm_underflow_wq(struct work_struct *work) | |
| 308 | −{ | |
| 309 | − struct ade_hw_ctx *ctx = container_of(work, struct ade_hw_ctx, | |
| 310 | − display_reset_wq); | |
| 311 | − struct drm_device *drm_dev = ctx->crtc->dev; | |
| 312 | − struct drm_atomic_state *state; | |
| 313 | − | |
| 314 | − state = drm_atomic_helper_suspend(drm_dev); | |
| 315 | − drm_atomic_helper_resume(drm_dev, state); | |
| 316 | −} | |
| 317 | − | |
| 318 | 305 | static irqreturn_t ade_irq_handler(int irq, void *data) |
| 319 | 306 | { |
| 320 | 307 | struct ade_hw_ctx *ctx = data; |
| @@ -331,12 +318,6 @@ static irqreturn_t ade_irq_handler(int irq, void *data) · 10 unmodified lines | ||
| 331 | 318 | MASK(1), 1); |
| 332 | 319 | drm_crtc_handle_vblank(crtc); |
| 333 | 320 | } |
| 334 | − if (status & BIT(UNDERFLOW_INT_EN_OFST)) { | |
| 335 | − ade_update_bits(base + LDI_INT_CLR, UNDERFLOW_INT_EN_OFST, | |
| 336 | − MASK(1), 1); | |
| 337 | − DRM_ERROR("LDI underflow!"); | |
| 338 | − schedule_work(&ctx->display_reset_wq); | |
| 339 | − } | |
| 340 | 321 | |
| 341 | 322 | return IRQ_HANDLED; |
| 342 | 323 | } |
| @@ -919,7 +900,6 @@ static void *ade_hw_ctx_alloc(struct platform_device *pdev, · 576 unmodified lines | ||
| 919 | 900 | if (ret) |
| 920 | 901 | return ERR_PTR(-EIO); |
| 921 | 902 | |
| 922 | − INIT_WORK(&ctx->display_reset_wq, drm_underflow_wq); | |
| 923 | 903 | ctx->crtc = crtc; |
| 924 | 904 | |
| 925 | 905 | return ctx; |
| @@ -294,7 +294,7 @@ extra-$(CONFIG_DRM_I915_WERROR) += \ · 293 unmodified lines | ||
| 294 | 294 | $(shell cd $(srctree)/$(src) && find * -name '*.h'))) |
| 295 | 295 | |
| 296 | 296 | quiet_cmd_hdrtest = HDRTEST $(patsubst %.hdrtest,%.h,$@) |
| 297 | − cmd_hdrtest = $(CC) $(c_flags) -S -o /dev/null -x c /dev/null -include $<; touch $@ | |
| 297 | + cmd_hdrtest = $(CC) $(filter-out $(CFLAGS_GCOV), $(c_flags)) -S -o /dev/null -x c /dev/null -include $<; touch $@ | |
| 298 | 298 | |
| 299 | 299 | $(obj)/%.hdrtest: $(src)/%.h FORCE |
| 300 | 300 | $(call if_changed_dep,hdrtest) |
| @@ -4466,13 +4466,19 @@ static void icl_dbuf_disable(struct drm_i915_private *dev_priv) · 4465 unmodified lines | ||
| 4466 | 4466 | |
| 4467 | 4467 | static void icl_mbus_init(struct drm_i915_private *dev_priv) |
| 4468 | 4468 | { |
| 4469 | − u32 val; | |
| 4469 | + u32 mask, val; | |
| 4470 | 4470 | |
| 4471 | − val = MBUS_ABOX_BT_CREDIT_POOL1(16) | | |
| 4472 | − MBUS_ABOX_BT_CREDIT_POOL2(16) | | |
| 4473 | − MBUS_ABOX_B_CREDIT(1) | | |
| 4474 | − MBUS_ABOX_BW_CREDIT(1); | |
| 4471 | + mask = MBUS_ABOX_BT_CREDIT_POOL1_MASK | | |
| 4472 | + MBUS_ABOX_BT_CREDIT_POOL2_MASK | | |
| 4473 | + MBUS_ABOX_B_CREDIT_MASK | | |
| 4474 | + MBUS_ABOX_BW_CREDIT_MASK; | |
| 4475 | 4475 | |
| 4476 | + val = I915_READ(MBUS_ABOX_CTL); | |
| 4477 | + val &= ~mask; | |
| 4478 | + val |= MBUS_ABOX_BT_CREDIT_POOL1(16) | | |
| 4479 | + MBUS_ABOX_BT_CREDIT_POOL2(16) | | |
| 4480 | + MBUS_ABOX_B_CREDIT(1) | | |
| 4481 | + MBUS_ABOX_BW_CREDIT(1); | |
| 4476 | 4482 | I915_WRITE(MBUS_ABOX_CTL, val); |
| 4477 | 4483 | } |
| 4478 | 4484 | |
| @@ -4968,8 +4974,21 @@ static void tgl_bw_buddy_init(struct drm_i915_private *dev_priv) · 489 unmodified lines | ||
| 4968 | 4974 | I915_WRITE(BW_BUDDY1_CTL, BW_BUDDY_DISABLE); |
| 4969 | 4975 | I915_WRITE(BW_BUDDY2_CTL, BW_BUDDY_DISABLE); |
| 4970 | 4976 | } else { |
| 4977 | + u32 val; | |
| 4978 | + | |
| 4971 | 4979 | I915_WRITE(BW_BUDDY1_PAGE_MASK, table[i].page_mask); |
| 4972 | 4980 | I915_WRITE(BW_BUDDY2_PAGE_MASK, table[i].page_mask); |
| 4981 | + | |
| 4982 | + /* Wa_22010178259:tgl */ | |
| 4983 | + val = I915_READ(BW_BUDDY1_CTL); | |
| 4984 | + val &= ~BW_BUDDY_TLB_REQ_TIMER_MASK; | |
| 4985 | + val |= REG_FIELD_PREP(BW_BUDDY_TLB_REQ_TIMER_MASK, 0x8); | |
| 4986 | + I915_WRITE(BW_BUDDY1_CTL, val); | |
| 4987 | + | |
| 4988 | + val = I915_READ(BW_BUDDY2_CTL); | |
| 4989 | + val &= ~BW_BUDDY_TLB_REQ_TIMER_MASK; | |
| 4990 | + val |= REG_FIELD_PREP(BW_BUDDY_TLB_REQ_TIMER_MASK, 0x8); | |
| 4991 | + I915_WRITE(BW_BUDDY2_CTL, val); | |
| 4973 | 4992 | } |
| 4974 | 4993 | } |
| 4975 | 4994 | |
| @@ -852,10 +852,12 @@ void intel_psr_enable(struct intel_dp *intel_dp, · 851 unmodified lines | ||
| 852 | 852 | { |
| 853 | 853 | struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); |
| 854 | 854 | |
| 855 | − if (!crtc_state->has_psr) | |
| 855 | + if (!CAN_PSR(dev_priv) || dev_priv->psr.dp != intel_dp) | |
| 856 | 856 | return; |
| 857 | 857 | |
| 858 | − if (WARN_ON(!CAN_PSR(dev_priv))) | |
| 858 | + dev_priv->psr.force_mode_changed = false; | |
| 859 | + | |
| 860 | + if (!crtc_state->has_psr) | |
| 859 | 861 | return; |
| 860 | 862 | |
| 861 | 863 | WARN_ON(dev_priv->drrs.dp); |
| @@ -1009,6 +1011,8 @@ void intel_psr_update(struct intel_dp *intel_dp, · 147 unmodified lines | ||
| 1009 | 1011 | if (!CAN_PSR(dev_priv) || READ_ONCE(psr->dp) != intel_dp) |
| 1010 | 1012 | return; |
| 1011 | 1013 | |
| 1014 | + dev_priv->psr.force_mode_changed = false; | |
| 1015 | + | |
| 1012 | 1016 | mutex_lock(&dev_priv->psr.lock); |
| 1013 | 1017 | |
| 1014 | 1018 | enable = crtc_state->has_psr && psr_global_enabled(psr->debug); |
| @@ -1534,7 +1538,7 @@ void intel_psr_atomic_check(struct drm_connector *connector, · 519 unmodified lines | ||
| 1534 | 1538 | struct drm_crtc_state *crtc_state; |
| 1535 | 1539 | |
| 1536 | 1540 | if (!CAN_PSR(dev_priv) || !new_state->crtc || |
| 1537 | − dev_priv->psr.initially_probed) | |
| 1541 | + !dev_priv->psr.force_mode_changed) | |
| 1538 | 1542 | return; |
| 1539 | 1543 | |
| 1540 | 1544 | intel_connector = to_intel_connector(connector); |
| @@ -1545,5 +1549,18 @@ void intel_psr_atomic_check(struct drm_connector *connector, · 4 unmodified lines | ||
| 1545 | 1549 | crtc_state = drm_atomic_get_new_crtc_state(new_state->state, |
| 1546 | 1550 | new_state->crtc); |
| 1547 | 1551 | crtc_state->mode_changed = true; |
| 1548 | − dev_priv->psr.initially_probed = true; | |
| 1552 | +} | |
| 1553 | + | |
| 1554 | +void intel_psr_set_force_mode_changed(struct intel_dp *intel_dp) | |
| 1555 | +{ | |
| 1556 | + struct drm_i915_private *dev_priv; | |
| 1557 | + | |
| 1558 | + if (!intel_dp) | |
| 1559 | + return; | |
| 1560 | + | |
| 1561 | + dev_priv = dp_to_i915(intel_dp); | |
| 1562 | + if (!CAN_PSR(dev_priv) || intel_dp != dev_priv->psr.dp) | |
| 1563 | + return; | |
| 1564 | + | |
| 1565 | + dev_priv->psr.force_mode_changed = true; | |
| 1549 | 1566 | } |
| @@ -40,5 +40,6 @@ bool intel_psr_enabled(struct intel_dp *intel_dp); · 39 unmodified lines | ||
| 40 | 40 | void intel_psr_atomic_check(struct drm_connector *connector, |
| 41 | 41 | struct drm_connector_state *old_state, |
| 42 | 42 | struct drm_connector_state *new_state); |
| 43 | +void intel_psr_set_force_mode_changed(struct intel_dp *intel_dp); | |
| 43 | 44 | |
| 44 | 45 | #endif /* __INTEL_PSR_H__ */ |
| @@ -423,7 +423,8 @@ eb_validate_vma(struct i915_execbuffer *eb, · 422 unmodified lines | ||
| 423 | 423 | if (unlikely(entry->flags & eb->invalid_flags)) |
| 424 | 424 | return -EINVAL; |
| 425 | 425 | |
| 426 | − if (unlikely(entry->alignment && !is_power_of_2(entry->alignment))) | |
| 426 | + if (unlikely(entry->alignment && | |
| 427 | + !is_power_of_2_u64(entry->alignment))) | |
| 427 | 428 | return -EINVAL; |
| 428 | 429 | |
| 429 | 430 | /* |
| @@ -225,6 +225,7 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, · 224 unmodified lines | ||
| 225 | 225 | |
| 226 | 226 | /* But keep the pointer alive for RCU-protected lookups */ |
| 227 | 227 | call_rcu(&obj->rcu, __i915_gem_free_object_rcu); |
| 228 | + cond_resched(); | |
| 228 | 229 | } |
| 229 | 230 | intel_runtime_pm_put(&i915->runtime_pm, wakeref); |
| 230 | 231 | } |
| @@ -256,8 +256,7 @@ unsigned long i915_gem_shrink_all(struct drm_i915_private *i915) · 255 unmodified lines | ||
| 256 | 256 | with_intel_runtime_pm(&i915->runtime_pm, wakeref) { |
| 257 | 257 | freed = i915_gem_shrink(i915, -1UL, NULL, |
| 258 | 258 | I915_SHRINK_BOUND | |
| 259 | − I915_SHRINK_UNBOUND | | |
| 260 | − I915_SHRINK_ACTIVE); | |
| 259 | + I915_SHRINK_UNBOUND); | |
| 261 | 260 | } |
| 262 | 261 | |
| 263 | 262 | return freed; |
| @@ -336,7 +335,6 @@ i915_gem_shrinker_oom(struct notifier_block *nb, unsigned long event, void *ptr) · 72 unmodified lines | ||
| 336 | 335 | freed_pages = 0; |
| 337 | 336 | with_intel_runtime_pm(&i915->runtime_pm, wakeref) |
| 338 | 337 | freed_pages += i915_gem_shrink(i915, -1UL, NULL, |
| 339 | − I915_SHRINK_ACTIVE | | |
| 340 | 338 | I915_SHRINK_BOUND | |
| 341 | 339 | I915_SHRINK_UNBOUND | |
| 342 | 340 | I915_SHRINK_WRITEBACK); |
| @@ -570,7 +570,7 @@ static bool assert_mmap_offset(struct drm_i915_private *i915, · 569 unmodified lines | ||
| 570 | 570 | |
| 571 | 571 | obj = i915_gem_object_create_internal(i915, size); |
| 572 | 572 | if (IS_ERR(obj)) |
| 573 | − return PTR_ERR(obj); | |
| 573 | + return false; | |
| 574 | 574 | |
| 575 | 575 | mmo = mmap_offset_attach(obj, I915_MMAP_OFFSET_GTT, NULL); |
| 576 | 576 | i915_gem_object_put(obj); |
| @@ -147,24 +147,32 @@ long intel_gt_retire_requests_timeout(struct intel_gt *gt, long timeout) · 146 unmodified lines | ||
| 147 | 147 | |
| 148 | 148 | fence = i915_active_fence_get(&tl->last_request); |
| 149 | 149 | if (fence) { |
| 150 | + mutex_unlock(&tl->mutex); | |
| 151 | + | |
| 150 | 152 | timeout = dma_fence_wait_timeout(fence, |
| 151 | 153 | interruptible, |
| 152 | 154 | timeout); |
| 153 | 155 | dma_fence_put(fence); |
| 156 | + | |
| 157 | + /* Retirement is best effort */ | |
| 158 | + if (!mutex_trylock(&tl->mutex)) { | |
| 159 | + active_count++; | |
| 160 | + goto out_active; | |
| 161 | + } | |
| 154 | 162 | } |
| 155 | 163 | } |
| 156 | 164 | |
| 157 | 165 | if (!retire_requests(tl) || flush_submission(gt)) |
| 158 | 166 | active_count++; |
| 167 | + mutex_unlock(&tl->mutex); | |
| 159 | 168 | |
| 160 | − spin_lock(&timelines->lock); | |
| 169 | +out_active: spin_lock(&timelines->lock); | |
| 161 | 170 | |
| 162 | − /* Resume iteration after dropping lock */ | |
| 171 | + /* Resume list iteration after reacquiring spinlock */ | |
| 163 | 172 | list_safe_reset_next(tl, tn, link); |
| 164 | 173 | if (atomic_dec_and_test(&tl->active_count)) |
| 165 | 174 | list_del(&tl->link); |
| 166 | 175 | |
| 167 | − mutex_unlock(&tl->mutex); | |
| 168 | 176 | |
| 169 | 177 | /* Defer the final release to after the spinlock */ |
| 170 | 178 | if (refcount_dec_and_test(&tl->kref.refcount)) { |
| @@ -1600,17 +1600,6 @@ static void virtual_xfer_breadcrumbs(struct virtual_engine *ve, · 1599 unmodified lines | ||
| 1600 | 1600 | spin_unlock(&old->breadcrumbs.irq_lock); |
| 1601 | 1601 | } |
| 1602 | 1602 | |
| 1603 | −static struct i915_request * | |
| 1604 | −last_active(const struct intel_engine_execlists *execlists) | |
| 1605 | −{ | |
| 1606 | − struct i915_request * const *last = READ_ONCE(execlists->active); | |
| 1607 | − | |
| 1608 | − while (*last && i915_request_completed(*last)) | |
| 1609 | − last++; | |
| 1610 | − | |
| 1611 | − return *last; | |
| 1612 | −} | |
| 1613 | − | |
| 1614 | 1603 | #define for_each_waiter(p__, rq__) \ |
| 1615 | 1604 | list_for_each_entry_lockless(p__, \ |
| 1616 | 1605 | &(rq__)->sched.waiters_list, \ |
| @@ -1679,11 +1668,9 @@ need_timeslice(struct intel_engine_cs *engine, const struct i915_request *rq) · 62 unmodified lines | ||
| 1679 | 1668 | if (!intel_engine_has_timeslices(engine)) |
| 1680 | 1669 | return false; |
| 1681 | 1670 | |
| 1682 | − if (list_is_last(&rq->sched.link, &engine->active.requests)) | |
| 1683 | − return false; | |
| 1684 | − | |
| 1685 | − hint = max(rq_prio(list_next_entry(rq, sched.link)), | |
| 1686 | − engine->execlists.queue_priority_hint); | |
| 1671 | + hint = engine->execlists.queue_priority_hint; | |
| 1672 | + if (!list_is_last(&rq->sched.link, &engine->active.requests)) | |
| 1673 | + hint = max(hint, rq_prio(list_next_entry(rq, sched.link))); | |
| 1687 | 1674 | |
| 1688 | 1675 | return hint >= effective_prio(rq); |
| 1689 | 1676 | } |
| @@ -1725,16 +1712,26 @@ static void set_timeslice(struct intel_engine_cs *engine) · 35 unmodified lines | ||
| 1725 | 1712 | set_timer_ms(&engine->execlists.timer, active_timeslice(engine)); |
| 1726 | 1713 | } |
| 1727 | 1714 | |
| 1715 | +static void start_timeslice(struct intel_engine_cs *engine) | |
| 1716 | +{ | |
| 1717 | + struct intel_engine_execlists *execlists = &engine->execlists; | |
| 1718 | + | |
| 1719 | + execlists->switch_priority_hint = execlists->queue_priority_hint; | |
| 1720 | + | |
| 1721 | + if (timer_pending(&execlists->timer)) | |
| 1722 | + return; | |
| 1723 | + | |
| 1724 | + set_timer_ms(&execlists->timer, timeslice(engine)); | |
| 1725 | +} | |
| 1726 | + | |
| 1728 | 1727 | static void record_preemption(struct intel_engine_execlists *execlists) |
| 1729 | 1728 | { |
| 1730 | 1729 | (void)I915_SELFTEST_ONLY(execlists->preempt_hang.count++); |
| 1731 | 1730 | } |
| 1732 | 1731 | |
| 1733 | −static unsigned long active_preempt_timeout(struct intel_engine_cs *engine) | |
| 1732 | +static unsigned long active_preempt_timeout(struct intel_engine_cs *engine, | |
| 1733 | + const struct i915_request *rq) | |
| 1734 | 1734 | { |
| 1735 | − struct i915_request *rq; | |
| 1736 | − | |
| 1737 | − rq = last_active(&engine->execlists); | |
| 1738 | 1735 | if (!rq) |
| 1739 | 1736 | return 0; |
| 1740 | 1737 | |
| @@ -1745,13 +1742,14 @@ static unsigned long active_preempt_timeout(struct intel_engine_cs *engine) · 4 unmodified lines | ||
| 1745 | 1742 | return READ_ONCE(engine->props.preempt_timeout_ms); |
| 1746 | 1743 | } |
| 1747 | 1744 | |
| 1748 | −static void set_preempt_timeout(struct intel_engine_cs *engine) | |
| 1745 | +static void set_preempt_timeout(struct intel_engine_cs *engine, | |
| 1746 | + const struct i915_request *rq) | |
| 1749 | 1747 | { |
| 1750 | 1748 | if (!intel_engine_has_preempt_reset(engine)) |
| 1751 | 1749 | return; |
| 1752 | 1750 | |
| 1753 | 1751 | set_timer_ms(&engine->execlists.preempt, |
| 1754 | − active_preempt_timeout(engine)); | |
| 1752 | + active_preempt_timeout(engine, rq)); | |
| 1755 | 1753 | } |
| 1756 | 1754 | |
| 1757 | 1755 | static inline void clear_ports(struct i915_request **ports, int count) |
| @@ -1764,6 +1762,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 6 unmodified lines | ||
| 1764 | 1762 | struct intel_engine_execlists * const execlists = &engine->execlists; |
| 1765 | 1763 | struct i915_request **port = execlists->pending; |
| 1766 | 1764 | struct i915_request ** const last_port = port + execlists->port_mask; |
| 1765 | + struct i915_request * const *active; | |
| 1767 | 1766 | struct i915_request *last; |
| 1768 | 1767 | struct rb_node *rb; |
| 1769 | 1768 | bool submit = false; |
| @@ -1818,7 +1817,10 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 48 unmodified lines | ||
| 1818 | 1817 | * i.e. we will retrigger preemption following the ack in case |
| 1819 | 1818 | * of trouble. |
| 1820 | 1819 | */ |
| 1821 | − last = last_active(execlists); | |
| 1820 | + active = READ_ONCE(execlists->active); | |
| 1821 | + while ((last = *active) && i915_request_completed(last)) | |
| 1822 | + active++; | |
| 1823 | + | |
| 1822 | 1824 | if (last) { |
| 1823 | 1825 | if (need_preempt(engine, last, rb)) { |
| 1824 | 1826 | ENGINE_TRACE(engine, |
| @@ -1888,11 +1890,7 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 63 unmodified lines | ||
| 1888 | 1890 | * Even if ELSP[1] is occupied and not worthy |
| 1889 | 1891 | * of timeslices, our queue might be. |
| 1890 | 1892 | */ |
| 1891 | − if (!execlists->timer.expires && | |
| 1892 | − need_timeslice(engine, last)) | |
| 1893 | − set_timer_ms(&execlists->timer, | |
| 1894 | − timeslice(engine)); | |
| 1895 | − | |
| 1893 | + start_timeslice(engine); | |
| 1896 | 1894 | return; |
| 1897 | 1895 | } |
| 1898 | 1896 | } |
| @@ -1927,7 +1925,8 @@ static void execlists_dequeue(struct intel_engine_cs *engine) · 28 unmodified lines | ||
| 1927 | 1925 | |
| 1928 | 1926 | if (last && !can_merge_rq(last, rq)) { |
| 1929 | 1927 | spin_unlock(&ve->base.active.lock); |
| 1930 | − return; /* leave this for another */ | |
| 1928 | + start_timeslice(engine); | |
| 1929 | + return; /* leave this for another sibling */ | |
| 1931 | 1930 | } |
| 1932 | 1931 | |
| 1933 | 1932 | ENGINE_TRACE(engine, |
| @@ -2103,7 +2102,7 @@ done: · 169 unmodified lines | ||
| 2103 | 2102 | * Skip if we ended up with exactly the same set of requests, |
| 2104 | 2103 | * e.g. trying to timeslice a pair of ordered contexts |
| 2105 | 2104 | */ |
| 2106 | − if (!memcmp(execlists->active, execlists->pending, | |
| 2105 | + if (!memcmp(active, execlists->pending, | |
| 2107 | 2106 | (port - execlists->pending + 1) * sizeof(*port))) { |
| 2108 | 2107 | do |
| 2109 | 2108 | execlists_schedule_out(fetch_and_zero(port)); |
| @@ -2114,7 +2113,7 @@ done: · 4 unmodified lines | ||
| 2114 | 2113 | clear_ports(port + 1, last_port - port); |
| 2115 | 2114 | |
| 2116 | 2115 | execlists_submit_ports(engine); |
| 2117 | − set_preempt_timeout(engine); | |
| 2116 | + set_preempt_timeout(engine, *active); | |
| 2118 | 2117 | } else { |
| 2119 | 2118 | skip_submit: |
| 2120 | 2119 | ring_set_paused(engine, 0); |
| @@ -4001,26 +4000,6 @@ static int gen12_emit_flush_render(struct i915_request *request, · 1880 unmodified lines | ||
| 4001 | 4000 | |
| 4002 | 4001 | *cs++ = preparser_disable(false); |
| 4003 | 4002 | intel_ring_advance(request, cs); |
| 4004 | − | |
| 4005 | − /* | |
| 4006 | − * Wa_1604544889:tgl | |
| 4007 | − */ | |
| 4008 | − if (IS_TGL_REVID(request->i915, TGL_REVID_A0, TGL_REVID_A0)) { | |
| 4009 | − flags = 0; | |
| 4010 | − flags |= PIPE_CONTROL_CS_STALL; | |
| 4011 | − flags |= PIPE_CONTROL_HDC_PIPELINE_FLUSH; | |
| 4012 | − | |
| 4013 | − flags |= PIPE_CONTROL_STORE_DATA_INDEX; | |
| 4014 | − flags |= PIPE_CONTROL_QW_WRITE; | |
| 4015 | − | |
| 4016 | − cs = intel_ring_begin(request, 6); | |
| 4017 | − if (IS_ERR(cs)) | |
| 4018 | − return PTR_ERR(cs); | |
| 4019 | − | |
| 4020 | − cs = gen8_emit_pipe_control(cs, flags, | |
| 4021 | − LRC_PPHWSP_SCRATCH_ADDR); | |
| 4022 | − intel_ring_advance(request, cs); | |
| 4023 | − } | |
| 4024 | 4003 | } |
| 4025 | 4004 | |
| 4026 | 4005 | return 0; |
| @@ -192,11 +192,15 @@ static void cacheline_release(struct intel_timeline_cacheline *cl) · 191 unmodified lines | ||
| 192 | 192 | |
| 193 | 193 | static void cacheline_free(struct intel_timeline_cacheline *cl) |
| 194 | 194 | { |
| 195 | + if (!i915_active_acquire_if_busy(&cl->active)) { | |
| 196 | + __idle_cacheline_free(cl); | |
| 197 | + return; | |
| 198 | + } | |
| 199 | + | |
| 195 | 200 | GEM_BUG_ON(ptr_test_bit(cl->vaddr, CACHELINE_FREE)); |
| 196 | 201 | cl->vaddr = ptr_set_bit(cl->vaddr, CACHELINE_FREE); |
| 197 | 202 | |
| 198 | − if (i915_active_is_idle(&cl->active)) | |
| 199 | − __idle_cacheline_free(cl); | |
| 203 | + i915_active_release(&cl->active); | |
| 200 | 204 | } |
| 201 | 205 | |
| 202 | 206 | int intel_timeline_init(struct intel_timeline *timeline, |
| @@ -575,24 +575,19 @@ static void icl_ctx_workarounds_init(struct intel_engine_cs *engine, · 574 unmodified lines | ||
| 575 | 575 | static void tgl_ctx_workarounds_init(struct intel_engine_cs *engine, |
| 576 | 576 | struct i915_wa_list *wal) |
| 577 | 577 | { |
| 578 | − u32 val; | |
| 579 | − | |
| 580 | 578 | /* Wa_1409142259:tgl */ |
| 581 | 579 | WA_SET_BIT_MASKED(GEN11_COMMON_SLICE_CHICKEN3, |
| 582 | 580 | GEN12_DISABLE_CPS_AWARE_COLOR_PIPE); |
| 583 | 581 | |
| 584 | − /* Wa_1604555607:tgl */ | |
| 585 | − val = intel_uncore_read(engine->uncore, FF_MODE2); | |
| 586 | − val &= ~FF_MODE2_TDS_TIMER_MASK; | |
| 587 | − val |= FF_MODE2_TDS_TIMER_128; | |
| 588 | 582 | /* |
| 589 | − * FIXME: FF_MODE2 register is not readable till TGL B0. We can | |
| 590 | − * enable verification of WA from the later steppings, which enables | |
| 591 | − * the read of FF_MODE2. | |
| 583 | + * Wa_1604555607:gen12 and Wa_1608008084:gen12 | |
| 584 | + * FF_MODE2 register will return the wrong value when read. The default | |
| 585 | + * value for this register is zero for all fields and there are no bit | |
| 586 | + * masks. So instead of doing a RMW we should just write the TDS timer | |
| 587 | + * value for Wa_1604555607. | |
| 592 | 588 | */ |
| 593 | − wa_add(wal, FF_MODE2, FF_MODE2_TDS_TIMER_MASK, val, | |
| 594 | − IS_TGL_REVID(engine->i915, TGL_REVID_A0, TGL_REVID_A0) ? 0 : | |
| 595 | − FF_MODE2_TDS_TIMER_MASK); | |
| 589 | + wa_add(wal, FF_MODE2, FF_MODE2_TDS_TIMER_MASK, | |
| 590 | + FF_MODE2_TDS_TIMER_128, 0); | |
| 596 | 591 | } |
| 597 | 592 | |
| 598 | 593 | static void |
| @@ -1534,15 +1529,34 @@ err_obj: · 935 unmodified lines | ||
| 1534 | 1529 | return ERR_PTR(err); |
| 1535 | 1530 | } |
| 1536 | 1531 | |
| 1532 | +static const struct { | |
| 1533 | + u32 start; | |
| 1534 | + u32 end; | |
| 1535 | +} mcr_ranges_gen8[] = { | |
| 1536 | + { .start = 0x5500, .end = 0x55ff }, | |
| 1537 | + { .start = 0x7000, .end = 0x7fff }, | |
| 1538 | + { .start = 0x9400, .end = 0x97ff }, | |
| 1539 | + { .start = 0xb000, .end = 0xb3ff }, | |
| 1540 | + { .start = 0xe000, .end = 0xe7ff }, | |
| 1541 | + {}, | |
| 1542 | +}; | |
| 1543 | + | |
| 1537 | 1544 | static bool mcr_range(struct drm_i915_private *i915, u32 offset) |
| 1538 | 1545 | { |
| 1546 | + int i; | |
| 1547 | + | |
| 1548 | + if (INTEL_GEN(i915) < 8) | |
| 1549 | + return false; | |
| 1550 | + | |
| 1539 | 1551 | /* |
| 1540 | − * Registers in this range are affected by the MCR selector | |
| 1552 | + * Registers in these ranges are affected by the MCR selector | |
| 1541 | 1553 | * which only controls CPU initiated MMIO. Routing does not |
| 1542 | 1554 | * work for CS access so we cannot verify them on this path. |
| 1543 | 1555 | */ |
| 1544 | − if (INTEL_GEN(i915) >= 8 && (offset >= 0xb000 && offset <= 0xb4ff)) | |
| 1545 | − return true; | |
| 1556 | + for (i = 0; mcr_ranges_gen8[i].start; i++) | |
| 1557 | + if (offset >= mcr_ranges_gen8[i].start && | |
| 1558 | + offset <= mcr_ranges_gen8[i].end) | |
| 1559 | + return true; | |
| 1546 | 1560 | |
| 1547 | 1561 | return false; |
| 1548 | 1562 | } |
| @@ -457,7 +457,8 @@ void intel_vgpu_emulate_hotplug(struct intel_vgpu *vgpu, bool connected) · 456 unmodified lines | ||
| 457 | 457 | struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv; |
| 458 | 458 | |
| 459 | 459 | /* TODO: add more platforms support */ |
| 460 | − if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { | |
| 460 | + if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv) || | |
| 461 | + IS_COFFEELAKE(dev_priv)) { | |
| 461 | 462 | if (connected) { |
| 462 | 463 | vgpu_vreg_t(vgpu, SFUSE_STRAP) |= |
| 463 | 464 | SFUSE_STRAP_DDID_DETECTED; |
| @@ -151,12 +151,12 @@ static void dmabuf_gem_object_free(struct kref *kref) · 150 unmodified lines | ||
| 151 | 151 | dmabuf_obj = container_of(pos, |
| 152 | 152 | struct intel_vgpu_dmabuf_obj, list); |
| 153 | 153 | if (dmabuf_obj == obj) { |
| 154 | + list_del(pos); | |
| 154 | 155 | intel_gvt_hypervisor_put_vfio_device(vgpu); |
| 155 | 156 | idr_remove(&vgpu->object_idr, |
| 156 | 157 | dmabuf_obj->dmabuf_id); |
| 157 | 158 | kfree(dmabuf_obj->info); |
| 158 | 159 | kfree(dmabuf_obj); |
| 159 | − list_del(pos); | |
| 160 | 160 | break; |
| 161 | 161 | } |
| 162 | 162 | } |
| @@ -147,15 +147,14 @@ static void virt_vbt_generation(struct vbt *v) · 146 unmodified lines | ||
| 147 | 147 | /* there's features depending on version! */ |
| 148 | 148 | v->header.version = 155; |
| 149 | 149 | v->header.header_size = sizeof(v->header); |
| 150 | − v->header.vbt_size = sizeof(struct vbt) - sizeof(v->header); | |
| 150 | + v->header.vbt_size = sizeof(struct vbt); | |
| 151 | 151 | v->header.bdb_offset = offsetof(struct vbt, bdb_header); |
| 152 | 152 | |
| 153 | 153 | strcpy(&v->bdb_header.signature[0], "BIOS_DATA_BLOCK"); |
| 154 | 154 | v->bdb_header.version = 186; /* child_dev_size = 33 */ |
| 155 | 155 | v->bdb_header.header_size = sizeof(v->bdb_header); |
| 156 | 156 | |
| 157 | − v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header) | |
| 158 | − - sizeof(struct bdb_header); | |
| 157 | + v->bdb_header.bdb_size = sizeof(struct vbt) - sizeof(struct vbt_header); | |
| 159 | 158 | |
| 160 | 159 | /* general features */ |
| 161 | 160 | v->general_features_header.id = BDB_GENERAL_FEATURES; |
| @@ -272,10 +272,17 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu) · 271 unmodified lines | ||
| 272 | 272 | { |
| 273 | 273 | struct intel_gvt *gvt = vgpu->gvt; |
| 274 | 274 | |
| 275 | − mutex_lock(&vgpu->vgpu_lock); | |
| 276 | − | |
| 277 | 275 | WARN(vgpu->active, "vGPU is still active!\n"); |
| 278 | 276 | |
| 277 | + /* | |
| 278 | + * remove idr first so later clean can judge if need to stop | |
| 279 | + * service if no active vgpu. | |
| 280 | + */ | |
| 281 | + mutex_lock(&gvt->lock); | |
| 282 | + idr_remove(&gvt->vgpu_idr, vgpu->id); | |
| 283 | + mutex_unlock(&gvt->lock); | |
| 284 | + | |
| 285 | + mutex_lock(&vgpu->vgpu_lock); | |
| 279 | 286 | intel_gvt_debugfs_remove_vgpu(vgpu); |
| 280 | 287 | intel_vgpu_clean_sched_policy(vgpu); |
| 281 | 288 | intel_vgpu_clean_submission(vgpu); |
| @@ -290,7 +297,6 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu) · 8 unmodified lines | ||
| 290 | 297 | mutex_unlock(&vgpu->vgpu_lock); |
| 291 | 298 | |
| 292 | 299 | mutex_lock(&gvt->lock); |
| 293 | − idr_remove(&gvt->vgpu_idr, vgpu->id); | |
| 294 | 300 | if (idr_is_empty(&gvt->vgpu_idr)) |
| 295 | 301 | intel_gvt_clean_irq(gvt); |
| 296 | 302 | intel_gvt_update_vgpu_types(gvt); |
| @@ -560,9 +566,9 @@ void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, · 263 unmodified lines | ||
| 560 | 566 | |
| 561 | 567 | intel_vgpu_reset_mmio(vgpu, dmlr); |
| 562 | 568 | populate_pvinfo_page(vgpu); |
| 563 | − intel_vgpu_reset_display(vgpu); | |
| 564 | 569 | |
| 565 | 570 | if (dmlr) { |
| 571 | + intel_vgpu_reset_display(vgpu); | |
| 566 | 572 | intel_vgpu_reset_cfg_space(vgpu); |
| 567 | 573 | /* only reset the failsafe mode when dmlr reset */ |
| 568 | 574 | vgpu->failsafe = false; |
| @@ -56,6 +56,7 @@ · 55 unmodified lines | ||
| 56 | 56 | #include "display/intel_hotplug.h" |
| 57 | 57 | #include "display/intel_overlay.h" |
| 58 | 58 | #include "display/intel_pipe_crc.h" |
| 59 | +#include "display/intel_psr.h" | |
| 59 | 60 | #include "display/intel_sprite.h" |
| 60 | 61 | #include "display/intel_vga.h" |
| 61 | 62 | |
| @@ -330,6 +331,8 @@ static int i915_driver_modeset_probe(struct drm_i915_private *i915) · 268 unmodified lines | ||
| 330 | 331 | |
| 331 | 332 | intel_init_ipc(i915); |
| 332 | 333 | |
| 334 | + intel_psr_set_force_mode_changed(i915->psr.dp); | |
| 335 | + | |
| 333 | 336 | return 0; |
| 334 | 337 | |
| 335 | 338 | cleanup_gem: |
| @@ -505,7 +505,7 @@ struct i915_psr { · 504 unmodified lines | ||
| 505 | 505 | bool dc3co_enabled; |
| 506 | 506 | u32 dc3co_exit_delay; |
| 507 | 507 | struct delayed_work idle_work; |
| 508 | − bool initially_probed; | |
| 508 | + bool force_mode_changed; | |
| 509 | 509 | }; |
| 510 | 510 | |
| 511 | 511 | #define QUIRK_LVDS_SSC_DISABLE (1<<1) |
| @@ -437,7 +437,7 @@ static const struct intel_device_info snb_m_gt2_info = { · 436 unmodified lines | ||
| 437 | 437 | .has_rc6 = 1, \ |
| 438 | 438 | .has_rc6p = 1, \ |
| 439 | 439 | .has_rps = true, \ |
| 440 | − .ppgtt_type = INTEL_PPGTT_FULL, \ | |
| 440 | + .ppgtt_type = INTEL_PPGTT_ALIASING, \ | |
| 441 | 441 | .ppgtt_size = 31, \ |
| 442 | 442 | IVB_PIPE_OFFSETS, \ |
| 443 | 443 | IVB_CURSOR_OFFSETS, \ |
| @@ -494,7 +494,7 @@ static const struct intel_device_info vlv_info = { · 50 unmodified lines | ||
| 494 | 494 | .has_rps = true, |
| 495 | 495 | .display.has_gmch = 1, |
| 496 | 496 | .display.has_hotplug = 1, |
| 497 | − .ppgtt_type = INTEL_PPGTT_FULL, | |
| 497 | + .ppgtt_type = INTEL_PPGTT_ALIASING, | |
| 498 | 498 | .ppgtt_size = 31, |
| 499 | 499 | .has_snoop = true, |
| 500 | 500 | .has_coherent_ggtt = false, |
| @@ -1954,9 +1954,10 @@ out: · 1953 unmodified lines | ||
| 1954 | 1954 | return i915_vma_get(oa_bo->vma); |
| 1955 | 1955 | } |
| 1956 | 1956 | |
| 1957 | −static int emit_oa_config(struct i915_perf_stream *stream, | |
| 1958 | − struct i915_oa_config *oa_config, | |
| 1959 | − struct intel_context *ce) | |
| 1957 | +static struct i915_request * | |
| 1958 | +emit_oa_config(struct i915_perf_stream *stream, | |
| 1959 | + struct i915_oa_config *oa_config, | |
| 1960 | + struct intel_context *ce) | |
| 1960 | 1961 | { |
| 1961 | 1962 | struct i915_request *rq; |
| 1962 | 1963 | struct i915_vma *vma; |
| @@ -1964,7 +1965,7 @@ static int emit_oa_config(struct i915_perf_stream *stream, · 1 unmodified line | ||
| 1964 | 1965 | |
| 1965 | 1966 | vma = get_oa_vma(stream, oa_config); |
| 1966 | 1967 | if (IS_ERR(vma)) |
| 1967 | − return PTR_ERR(vma); | |
| 1968 | + return ERR_CAST(vma); | |
| 1968 | 1969 | |
| 1969 | 1970 | err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL | PIN_HIGH); |
| 1970 | 1971 | if (err) |
| @@ -1989,13 +1990,17 @@ static int emit_oa_config(struct i915_perf_stream *stream, · 18 unmodified lines | ||
| 1989 | 1990 | err = rq->engine->emit_bb_start(rq, |
| 1990 | 1991 | vma->node.start, 0, |
| 1991 | 1992 | I915_DISPATCH_SECURE); |
| 1993 | + if (err) | |
| 1994 | + goto err_add_request; | |
| 1995 | + | |
| 1996 | + i915_request_get(rq); | |
| 1992 | 1997 | err_add_request: |
| 1993 | 1998 | i915_request_add(rq); |
| 1994 | 1999 | err_vma_unpin: |
| 1995 | 2000 | i915_vma_unpin(vma); |
| 1996 | 2001 | err_vma_put: |
| 1997 | 2002 | i915_vma_put(vma); |
| 1998 | − return err; | |
| 2003 | + return err ? ERR_PTR(err) : rq; | |
| 1999 | 2004 | } |
| 2000 | 2005 | |
| 2001 | 2006 | static struct intel_context *oa_context(struct i915_perf_stream *stream) |
| @@ -2003,7 +2008,8 @@ static struct intel_context *oa_context(struct i915_perf_stream *stream) · 1 unmodified line | ||
| 2003 | 2008 | return stream->pinned_ctx ?: stream->engine->kernel_context; |
| 2004 | 2009 | } |
| 2005 | 2010 | |
| 2006 | −static int hsw_enable_metric_set(struct i915_perf_stream *stream) | |
| 2011 | +static struct i915_request * | |
| 2012 | +hsw_enable_metric_set(struct i915_perf_stream *stream) | |
| 2007 | 2013 | { |
| 2008 | 2014 | struct intel_uncore *uncore = stream->uncore; |
| 2009 | 2015 | |
| @@ -2406,7 +2412,8 @@ static int lrc_configure_all_contexts(struct i915_perf_stream *stream, · 396 unmodified lines | ||
| 2406 | 2412 | return oa_configure_all_contexts(stream, regs, ARRAY_SIZE(regs)); |
| 2407 | 2413 | } |
| 2408 | 2414 | |
| 2409 | −static int gen8_enable_metric_set(struct i915_perf_stream *stream) | |
| 2415 | +static struct i915_request * | |
| 2416 | +gen8_enable_metric_set(struct i915_perf_stream *stream) | |
| 2410 | 2417 | { |
| 2411 | 2418 | struct intel_uncore *uncore = stream->uncore; |
| 2412 | 2419 | struct i915_oa_config *oa_config = stream->oa_config; |
| @@ -2448,7 +2455,7 @@ static int gen8_enable_metric_set(struct i915_perf_stream *stream) · 35 unmodified lines | ||
| 2448 | 2455 | */ |
| 2449 | 2456 | ret = lrc_configure_all_contexts(stream, oa_config); |
| 2450 | 2457 | if (ret) |
| 2451 | − return ret; | |
| 2458 | + return ERR_PTR(ret); | |
| 2452 | 2459 | |
| 2453 | 2460 | return emit_oa_config(stream, oa_config, oa_context(stream)); |
| 2454 | 2461 | } |
| @@ -2460,7 +2467,8 @@ static u32 oag_report_ctx_switches(const struct i915_perf_stream *stream) · 5 unmodified lines | ||
| 2460 | 2467 | 0 : GEN12_OAG_OA_DEBUG_DISABLE_CTX_SWITCH_REPORTS); |
| 2461 | 2468 | } |
| 2462 | 2469 | |
| 2463 | −static int gen12_enable_metric_set(struct i915_perf_stream *stream) | |
| 2470 | +static struct i915_request * | |
| 2471 | +gen12_enable_metric_set(struct i915_perf_stream *stream) | |
| 2464 | 2472 | { |
| 2465 | 2473 | struct intel_uncore *uncore = stream->uncore; |
| 2466 | 2474 | struct i915_oa_config *oa_config = stream->oa_config; |
| @@ -2491,7 +2499,7 @@ static int gen12_enable_metric_set(struct i915_perf_stream *stream) · 24 unmodified lines | ||
| 2491 | 2499 | */ |
| 2492 | 2500 | ret = gen12_configure_all_contexts(stream, oa_config); |
| 2493 | 2501 | if (ret) |
| 2494 | − return ret; | |
| 2502 | + return ERR_PTR(ret); | |
| 2495 | 2503 | |
| 2496 | 2504 | /* |
| 2497 | 2505 | * For Gen12, performance counters are context |
| @@ -2501,7 +2509,7 @@ static int gen12_enable_metric_set(struct i915_perf_stream *stream) · 3 unmodified lines | ||
| 2501 | 2509 | if (stream->ctx) { |
| 2502 | 2510 | ret = gen12_configure_oar_context(stream, true); |
| 2503 | 2511 | if (ret) |
| 2504 | − return ret; | |
| 2512 | + return ERR_PTR(ret); | |
| 2505 | 2513 | } |
| 2506 | 2514 | |
| 2507 | 2515 | return emit_oa_config(stream, oa_config, oa_context(stream)); |
| @@ -2696,6 +2704,20 @@ static const struct i915_perf_stream_ops i915_oa_stream_ops = { · 188 unmodified lines | ||
| 2696 | 2704 | .read = i915_oa_read, |
| 2697 | 2705 | }; |
| 2698 | 2706 | |
| 2707 | +static int i915_perf_stream_enable_sync(struct i915_perf_stream *stream) | |
| 2708 | +{ | |
| 2709 | + struct i915_request *rq; | |
| 2710 | + | |
| 2711 | + rq = stream->perf->ops.enable_metric_set(stream); | |
| 2712 | + if (IS_ERR(rq)) | |
| 2713 | + return PTR_ERR(rq); | |
| 2714 | + | |
| 2715 | + i915_request_wait(rq, 0, MAX_SCHEDULE_TIMEOUT); | |
| 2716 | + i915_request_put(rq); | |
| 2717 | + | |
| 2718 | + return 0; | |
| 2719 | +} | |
| 2720 | + | |
| 2699 | 2721 | /** |
| 2700 | 2722 | * i915_oa_stream_init - validate combined props for OA stream and init |
| 2701 | 2723 | * @stream: An i915 perf stream |
| @@ -2829,7 +2851,7 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream, · 127 unmodified lines | ||
| 2829 | 2851 | stream->ops = &i915_oa_stream_ops; |
| 2830 | 2852 | perf->exclusive_stream = stream; |
| 2831 | 2853 | |
| 2832 | − ret = perf->ops.enable_metric_set(stream); | |
| 2854 | + ret = i915_perf_stream_enable_sync(stream); | |
| 2833 | 2855 | if (ret) { |
| 2834 | 2856 | DRM_DEBUG("Unable to enable metric set\n"); |
| 2835 | 2857 | goto err_enable; |
| @@ -3147,7 +3169,7 @@ static long i915_perf_config_locked(struct i915_perf_stream *stream, · 311 unmodified lines | ||
| 3147 | 3169 | return -EINVAL; |
| 3148 | 3170 | |
| 3149 | 3171 | if (config != stream->oa_config) { |
| 3150 | − int err; | |
| 3172 | + struct i915_request *rq; | |
| 3151 | 3173 | |
| 3152 | 3174 | /* |
| 3153 | 3175 | * If OA is bound to a specific context, emit the |
| @@ -3158,11 +3180,13 @@ static long i915_perf_config_locked(struct i915_perf_stream *stream, · 4 unmodified lines | ||
| 3158 | 3180 | * When set globally, we use a low priority kernel context, |
| 3159 | 3181 | * so it will effectively take effect when idle. |
| 3160 | 3182 | */ |
| 3161 | − err = emit_oa_config(stream, config, oa_context(stream)); | |
| 3162 | − if (err == 0) | |
| 3183 | + rq = emit_oa_config(stream, config, oa_context(stream)); | |
| 3184 | + if (!IS_ERR(rq)) { | |
| 3163 | 3185 | config = xchg(&stream->oa_config, config); |
| 3164 | − else | |
| 3165 | − ret = err; | |
| 3186 | + i915_request_put(rq); | |
| 3187 | + } else { | |
| 3188 | + ret = PTR_ERR(rq); | |
| 3189 | + } | |
| 3166 | 3190 | } |
| 3167 | 3191 | |
| 3168 | 3192 | i915_oa_config_put(config); |
| @@ -339,7 +339,8 @@ struct i915_oa_ops { · 338 unmodified lines | ||
| 339 | 339 | * counter reports being sampled. May apply system constraints such as |
| 340 | 340 | * disabling EU clock gating as required. |
| 341 | 341 | */ |
| 342 | − int (*enable_metric_set)(struct i915_perf_stream *stream); | |
| 342 | + struct i915_request * | |
| 343 | + (*enable_metric_set)(struct i915_perf_stream *stream); | |
| 343 | 344 | |
| 344 | 345 | /** |
| 345 | 346 | * @disable_metric_set: Remove system constraints associated with using |
| @@ -822,11 +822,6 @@ static ssize_t i915_pmu_event_show(struct device *dev, · 821 unmodified lines | ||
| 822 | 822 | return sprintf(buf, "config=0x%lx\n", eattr->val); |
| 823 | 823 | } |
| 824 | 824 | |
| 825 | −static struct attribute_group i915_pmu_events_attr_group = { | |
| 826 | − .name = "events", | |
| 827 | − /* Patch in attrs at runtime. */ | |
| 828 | −}; | |
| 829 | − | |
| 830 | 825 | static ssize_t |
| 831 | 826 | i915_pmu_get_attr_cpumask(struct device *dev, |
| 832 | 827 | struct device_attribute *attr, |
| @@ -846,13 +841,6 @@ static const struct attribute_group i915_pmu_cpumask_attr_group = { · 13 unmodified lines | ||
| 846 | 841 | .attrs = i915_cpumask_attrs, |
| 847 | 842 | }; |
| 848 | 843 | |
| 849 | −static const struct attribute_group *i915_pmu_attr_groups[] = { | |
| 850 | − &i915_pmu_format_attr_group, | |
| 851 | − &i915_pmu_events_attr_group, | |
| 852 | − &i915_pmu_cpumask_attr_group, | |
| 853 | − NULL | |
| 854 | −}; | |
| 855 | − | |
| 856 | 844 | #define __event(__config, __name, __unit) \ |
| 857 | 845 | { \ |
| 858 | 846 | .config = (__config), \ |
| @@ -1026,23 +1014,23 @@ err_alloc: · 167 unmodified lines | ||
| 1026 | 1014 | |
| 1027 | 1015 | static void free_event_attributes(struct i915_pmu *pmu) |
| 1028 | 1016 | { |
| 1029 | − struct attribute **attr_iter = i915_pmu_events_attr_group.attrs; | |
| 1017 | + struct attribute **attr_iter = pmu->events_attr_group.attrs; | |
| 1030 | 1018 | |
| 1031 | 1019 | for (; *attr_iter; attr_iter++) |
| 1032 | 1020 | kfree((*attr_iter)->name); |
| 1033 | 1021 | |
| 1034 | − kfree(i915_pmu_events_attr_group.attrs); | |
| 1022 | + kfree(pmu->events_attr_group.attrs); | |
| 1035 | 1023 | kfree(pmu->i915_attr); |
| 1036 | 1024 | kfree(pmu->pmu_attr); |
| 1037 | 1025 | |
| 1038 | − i915_pmu_events_attr_group.attrs = NULL; | |
| 1026 | + pmu->events_attr_group.attrs = NULL; | |
| 1039 | 1027 | pmu->i915_attr = NULL; |
| 1040 | 1028 | pmu->pmu_attr = NULL; |
| 1041 | 1029 | } |
| 1042 | 1030 | |
| 1043 | 1031 | static int i915_pmu_cpu_online(unsigned int cpu, struct hlist_node *node) |
| 1044 | 1032 | { |
| 1045 | − struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), node); | |
| 1033 | + struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node); | |
| 1046 | 1034 | |
| 1047 | 1035 | GEM_BUG_ON(!pmu->base.event_init); |
| 1048 | 1036 | |
| @@ -1055,7 +1043,7 @@ static int i915_pmu_cpu_online(unsigned int cpu, struct hlist_node *node) · 6 unmodified lines | ||
| 1055 | 1043 | |
| 1056 | 1044 | static int i915_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node) |
| 1057 | 1045 | { |
| 1058 | − struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), node); | |
| 1046 | + struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node); | |
| 1059 | 1047 | unsigned int target; |
| 1060 | 1048 | |
| 1061 | 1049 | GEM_BUG_ON(!pmu->base.event_init); |
| @@ -1072,8 +1060,6 @@ static int i915_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node) · 10 unmodified lines | ||
| 1072 | 1060 | return 0; |
| 1073 | 1061 | } |
| 1074 | 1062 | |
| 1075 | −static enum cpuhp_state cpuhp_slot = CPUHP_INVALID; | |
| 1076 | − | |
| 1077 | 1063 | static int i915_pmu_register_cpuhp_state(struct i915_pmu *pmu) |
| 1078 | 1064 | { |
| 1079 | 1065 | enum cpuhp_state slot; |
| @@ -1087,21 +1073,22 @@ static int i915_pmu_register_cpuhp_state(struct i915_pmu *pmu) · 7 unmodified lines | ||
| 1087 | 1073 | return ret; |
| 1088 | 1074 | |
| 1089 | 1075 | slot = ret; |
| 1090 | − ret = cpuhp_state_add_instance(slot, &pmu->node); | |
| 1076 | + ret = cpuhp_state_add_instance(slot, &pmu->cpuhp.node); | |
| 1091 | 1077 | if (ret) { |
| 1092 | 1078 | cpuhp_remove_multi_state(slot); |
| 1093 | 1079 | return ret; |
| 1094 | 1080 | } |
| 1095 | 1081 | |
| 1096 | − cpuhp_slot = slot; | |
| 1082 | + pmu->cpuhp.slot = slot; | |
| 1097 | 1083 | return 0; |
| 1098 | 1084 | } |
| 1099 | 1085 | |
| 1100 | 1086 | static void i915_pmu_unregister_cpuhp_state(struct i915_pmu *pmu) |
| 1101 | 1087 | { |
| 1102 | − WARN_ON(cpuhp_slot == CPUHP_INVALID); | |
| 1103 | − WARN_ON(cpuhp_state_remove_instance(cpuhp_slot, &pmu->node)); | |
| 1104 | − cpuhp_remove_multi_state(cpuhp_slot); | |
| 1088 | + WARN_ON(pmu->cpuhp.slot == CPUHP_INVALID); | |
| 1089 | + WARN_ON(cpuhp_state_remove_instance(pmu->cpuhp.slot, &pmu->cpuhp.node)); | |
| 1090 | + cpuhp_remove_multi_state(pmu->cpuhp.slot); | |
| 1091 | + pmu->cpuhp.slot = CPUHP_INVALID; | |
| 1105 | 1092 | } |
| 1106 | 1093 | |
| 1107 | 1094 | static bool is_igp(struct drm_i915_private *i915) |
| @@ -1118,6 +1105,13 @@ static bool is_igp(struct drm_i915_private *i915) · 10 unmodified lines | ||
| 1118 | 1105 | void i915_pmu_register(struct drm_i915_private *i915) |
| 1119 | 1106 | { |
| 1120 | 1107 | struct i915_pmu *pmu = &i915->pmu; |
| 1108 | + const struct attribute_group *attr_groups[] = { | |
| 1109 | + &i915_pmu_format_attr_group, | |
| 1110 | + &pmu->events_attr_group, | |
| 1111 | + &i915_pmu_cpumask_attr_group, | |
| 1112 | + NULL | |
| 1113 | + }; | |
| 1114 | + | |
| 1121 | 1115 | int ret = -ENOMEM; |
| 1122 | 1116 | |
| 1123 | 1117 | if (INTEL_GEN(i915) <= 2) { |
| @@ -1128,6 +1122,7 @@ void i915_pmu_register(struct drm_i915_private *i915) · 4 unmodified lines | ||
| 1128 | 1122 | spin_lock_init(&pmu->lock); |
| 1129 | 1123 | hrtimer_init(&pmu->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 1130 | 1124 | pmu->timer.function = i915_sample; |
| 1125 | + pmu->cpuhp.slot = CPUHP_INVALID; | |
| 1131 | 1126 | |
| 1132 | 1127 | if (!is_igp(i915)) { |
| 1133 | 1128 | pmu->name = kasprintf(GFP_KERNEL, |
| @@ -1143,11 +1138,16 @@ void i915_pmu_register(struct drm_i915_private *i915) · 9 unmodified lines | ||
| 1143 | 1138 | if (!pmu->name) |
| 1144 | 1139 | goto err; |
| 1145 | 1140 | |
| 1146 | − i915_pmu_events_attr_group.attrs = create_event_attributes(pmu); | |
| 1147 | − if (!i915_pmu_events_attr_group.attrs) | |
| 1141 | + pmu->events_attr_group.name = "events"; | |
| 1142 | + pmu->events_attr_group.attrs = create_event_attributes(pmu); | |
| 1143 | + if (!pmu->events_attr_group.attrs) | |
| 1148 | 1144 | goto err_name; |
| 1149 | 1145 | |
| 1150 | − pmu->base.attr_groups = i915_pmu_attr_groups; | |
| 1146 | + pmu->base.attr_groups = kmemdup(attr_groups, sizeof(attr_groups), | |
| 1147 | + GFP_KERNEL); | |
| 1148 | + if (!pmu->base.attr_groups) | |
| 1149 | + goto err_attr; | |
| 1150 | + | |
| 1151 | 1151 | pmu->base.task_ctx_nr = perf_invalid_context; |
| 1152 | 1152 | pmu->base.event_init = i915_pmu_event_init; |
| 1153 | 1153 | pmu->base.add = i915_pmu_event_add; |
| @@ -1159,7 +1159,7 @@ void i915_pmu_register(struct drm_i915_private *i915) · 5 unmodified lines | ||
| 1159 | 1159 | |
| 1160 | 1160 | ret = perf_pmu_register(&pmu->base, pmu->name, -1); |
| 1161 | 1161 | if (ret) |
| 1162 | − goto err_attr; | |
| 1162 | + goto err_groups; | |
| 1163 | 1163 | |
| 1164 | 1164 | ret = i915_pmu_register_cpuhp_state(pmu); |
| 1165 | 1165 | if (ret) |
| @@ -1169,6 +1169,8 @@ void i915_pmu_register(struct drm_i915_private *i915) · 3 unmodified lines | ||
| 1169 | 1169 | |
| 1170 | 1170 | err_unreg: |
| 1171 | 1171 | perf_pmu_unregister(&pmu->base); |
| 1172 | +err_groups: | |
| 1173 | + kfree(pmu->base.attr_groups); | |
| 1172 | 1174 | err_attr: |
| 1173 | 1175 | pmu->base.event_init = NULL; |
| 1174 | 1176 | free_event_attributes(pmu); |
| @@ -1194,6 +1196,7 @@ void i915_pmu_unregister(struct drm_i915_private *i915) · 19 unmodified lines | ||
| 1194 | 1196 | |
| 1195 | 1197 | perf_pmu_unregister(&pmu->base); |
| 1196 | 1198 | pmu->base.event_init = NULL; |
| 1199 | + kfree(pmu->base.attr_groups); | |
| 1197 | 1200 | if (!is_igp(i915)) |
| 1198 | 1201 | kfree(pmu->name); |
| 1199 | 1202 | free_event_attributes(pmu); |
| @@ -39,9 +39,12 @@ struct i915_pmu_sample { · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | struct i915_pmu { |
| 41 | 41 | /** |
| 42 | − * @node: List node for CPU hotplug handling. | |
| 42 | + * @cpuhp: Struct used for CPU hotplug handling. | |
| 43 | 43 | */ |
| 44 | − struct hlist_node node; | |
| 44 | + struct { | |
| 45 | + struct hlist_node node; | |
| 46 | + enum cpuhp_state slot; | |
| 47 | + } cpuhp; | |
| 45 | 48 | /** |
| 46 | 49 | * @base: PMU base. |
| 47 | 50 | */ |
| @@ -104,6 +107,10 @@ struct i915_pmu { · 56 unmodified lines | ||
| 104 | 107 | * @sleep_last: Last time GT parked for RC6 estimation. |
| 105 | 108 | */ |
| 106 | 109 | ktime_t sleep_last; |
| 110 | + /** | |
| 111 | + * @events_attr_group: Device events attribute group. | |
| 112 | + */ | |
| 113 | + struct attribute_group events_attr_group; | |
| 107 | 114 | /** |
| 108 | 115 | * @i915_attr: Memory block holding device attributes. |
| 109 | 116 | */ |
| @@ -7757,6 +7757,7 @@ enum { · 7756 unmodified lines | ||
| 7757 | 7757 | #define BW_BUDDY1_CTL _MMIO(0x45140) |
| 7758 | 7758 | #define BW_BUDDY2_CTL _MMIO(0x45150) |
| 7759 | 7759 | #define BW_BUDDY_DISABLE REG_BIT(31) |
| 7760 | +#define BW_BUDDY_TLB_REQ_TIMER_MASK REG_GENMASK(21, 16) | |
| 7760 | 7761 | |
| 7761 | 7762 | #define BW_BUDDY1_PAGE_MASK _MMIO(0x45144) |
| 7762 | 7763 | #define BW_BUDDY2_PAGE_MASK _MMIO(0x45154) |
| @@ -275,7 +275,7 @@ bool i915_request_retire(struct i915_request *rq) · 274 unmodified lines | ||
| 275 | 275 | spin_unlock_irq(&rq->lock); |
| 276 | 276 | |
| 277 | 277 | remove_from_client(rq); |
| 278 | − list_del(&rq->link); | |
| 278 | + list_del_rcu(&rq->link); | |
| 279 | 279 | |
| 280 | 280 | intel_context_exit(rq->context); |
| 281 | 281 | intel_context_unpin(rq->context); |
| @@ -527,19 +527,31 @@ submit_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) · 245 unmodified lines | ||
| 527 | 527 | return NOTIFY_DONE; |
| 528 | 528 | } |
| 529 | 529 | |
| 530 | +static void irq_semaphore_cb(struct irq_work *wrk) | |
| 531 | +{ | |
| 532 | + struct i915_request *rq = | |
| 533 | + container_of(wrk, typeof(*rq), semaphore_work); | |
| 534 | + | |
| 535 | + i915_schedule_bump_priority(rq, I915_PRIORITY_NOSEMAPHORE); | |
| 536 | + i915_request_put(rq); | |
| 537 | +} | |
| 538 | + | |
| 530 | 539 | static int __i915_sw_fence_call |
| 531 | 540 | semaphore_notify(struct i915_sw_fence *fence, enum i915_sw_fence_notify state) |
| 532 | 541 | { |
| 533 | − struct i915_request *request = | |
| 534 | − container_of(fence, typeof(*request), semaphore); | |
| 542 | + struct i915_request *rq = container_of(fence, typeof(*rq), semaphore); | |
| 535 | 543 | |
| 536 | 544 | switch (state) { |
| 537 | 545 | case FENCE_COMPLETE: |
| 538 | − i915_schedule_bump_priority(request, I915_PRIORITY_NOSEMAPHORE); | |
| 546 | + if (!(READ_ONCE(rq->sched.attr.priority) & I915_PRIORITY_NOSEMAPHORE)) { | |
| 547 | + i915_request_get(rq); | |
| 548 | + init_irq_work(&rq->semaphore_work, irq_semaphore_cb); | |
| 549 | + irq_work_queue(&rq->semaphore_work); | |
| 550 | + } | |
| 539 | 551 | break; |
| 540 | 552 | |
| 541 | 553 | case FENCE_FREE: |
| 542 | − i915_request_put(request); | |
| 554 | + i915_request_put(rq); | |
| 543 | 555 | break; |
| 544 | 556 | } |
| 545 | 557 | |
| @@ -721,6 +733,8 @@ __i915_request_create(struct intel_context *ce, gfp_t gfp) · 175 unmodified lines | ||
| 721 | 733 | rq->infix = rq->ring->emit; /* end of header; start of user payload */ |
| 722 | 734 | |
| 723 | 735 | intel_context_mark_active(ce); |
| 736 | + list_add_tail_rcu(&rq->link, &tl->requests); | |
| 737 | + | |
| 724 | 738 | return rq; |
| 725 | 739 | |
| 726 | 740 | err_unwind: |
| @@ -774,16 +788,26 @@ i915_request_await_start(struct i915_request *rq, struct i915_request *signal) · 47 unmodified lines | ||
| 774 | 788 | struct dma_fence *fence; |
| 775 | 789 | int err; |
| 776 | 790 | |
| 777 | − GEM_BUG_ON(i915_request_timeline(rq) == | |
| 778 | − rcu_access_pointer(signal->timeline)); | |
| 791 | + if (i915_request_timeline(rq) == rcu_access_pointer(signal->timeline)) | |
| 792 | + return 0; | |
| 793 | + | |
| 794 | + if (i915_request_started(signal)) | |
| 795 | + return 0; | |
| 779 | 796 | |
| 780 | 797 | fence = NULL; |
| 781 | 798 | rcu_read_lock(); |
| 782 | 799 | spin_lock_irq(&signal->lock); |
| 783 | − if (!i915_request_started(signal) && | |
| 784 | − !list_is_first(&signal->link, | |
| 785 | − &rcu_dereference(signal->timeline)->requests)) { | |
| 786 | − struct i915_request *prev = list_prev_entry(signal, link); | |
| 800 | + do { | |
| 801 | + struct list_head *pos = READ_ONCE(signal->link.prev); | |
| 802 | + struct i915_request *prev; | |
| 803 | + | |
| 804 | + /* Confirm signal has not been retired, the link is valid */ | |
| 805 | + if (unlikely(i915_request_started(signal))) | |
| 806 | + break; | |
| 807 | + | |
| 808 | + /* Is signal the earliest request on its timeline? */ | |
| 809 | + if (pos == &rcu_dereference(signal->timeline)->requests) | |
| 810 | + break; | |
| 787 | 811 | |
| 788 | 812 | /* |
| 789 | 813 | * Peek at the request before us in the timeline. That |
| @@ -791,20 +815,25 @@ i915_request_await_start(struct i915_request *rq, struct i915_request *signal) · 1 unmodified line | ||
| 791 | 815 | * after acquiring a reference to it, confirm that it is |
| 792 | 816 | * still part of the signaler's timeline. |
| 793 | 817 | */ |
| 794 | − if (i915_request_get_rcu(prev)) { | |
| 795 | − if (list_next_entry(prev, link) == signal) | |
| 796 | − fence = &prev->fence; | |
| 797 | − else | |
| 798 | − i915_request_put(prev); | |
| 818 | + prev = list_entry(pos, typeof(*prev), link); | |
| 819 | + if (!i915_request_get_rcu(prev)) | |
| 820 | + break; | |
| 821 | + | |
| 822 | + /* After the strong barrier, confirm prev is still attached */ | |
| 823 | + if (unlikely(READ_ONCE(prev->link.next) != &signal->link)) { | |
| 824 | + i915_request_put(prev); | |
| 825 | + break; | |
| 799 | 826 | } |
| 800 | − } | |
| 827 | + | |
| 828 | + fence = &prev->fence; | |
| 829 | + } while (0); | |
| 801 | 830 | spin_unlock_irq(&signal->lock); |
| 802 | 831 | rcu_read_unlock(); |
| 803 | 832 | if (!fence) |
| 804 | 833 | return 0; |
| 805 | 834 | |
| 806 | 835 | err = 0; |
| 807 | − if (intel_timeline_sync_is_later(i915_request_timeline(rq), fence)) | |
| 836 | + if (!intel_timeline_sync_is_later(i915_request_timeline(rq), fence)) | |
| 808 | 837 | err = i915_sw_fence_await_dma_fence(&rq->submit, |
| 809 | 838 | fence, 0, |
| 810 | 839 | I915_FENCE_GFP); |
| @@ -1242,8 +1271,6 @@ __i915_request_add_to_timeline(struct i915_request *rq) · 431 unmodified lines | ||
| 1242 | 1271 | 0); |
| 1243 | 1272 | } |
| 1244 | 1273 | |
| 1245 | − list_add_tail(&rq->link, &timeline->requests); | |
| 1246 | − | |
| 1247 | 1274 | /* |
| 1248 | 1275 | * Make sure that no request gazumped us - if it was allocated after |
| 1249 | 1276 | * our i915_request_alloc() and called __i915_request_add() before |
| @@ -1303,9 +1330,9 @@ void __i915_request_queue(struct i915_request *rq, · 53 unmodified lines | ||
| 1303 | 1330 | * decide whether to preempt the entire chain so that it is ready to |
| 1304 | 1331 | * run at the earliest possible convenience. |
| 1305 | 1332 | */ |
| 1306 | − i915_sw_fence_commit(&rq->semaphore); | |
| 1307 | 1333 | if (attr && rq->engine->schedule) |
| 1308 | 1334 | rq->engine->schedule(rq, attr); |
| 1335 | + i915_sw_fence_commit(&rq->semaphore); | |
| 1309 | 1336 | i915_sw_fence_commit(&rq->submit); |
| 1310 | 1337 | } |
| 1311 | 1338 | |
| @@ -26,6 +26,7 @@ · 25 unmodified lines | ||
| 26 | 26 | #define I915_REQUEST_H |
| 27 | 27 | |
| 28 | 28 | #include <linux/dma-fence.h> |
| 29 | +#include <linux/irq_work.h> | |
| 29 | 30 | #include <linux/lockdep.h> |
| 30 | 31 | |
| 31 | 32 | #include "gem/i915_gem_context_types.h" |
| @@ -208,6 +209,7 @@ struct i915_request { · 176 unmodified lines | ||
| 208 | 209 | }; |
| 209 | 210 | struct list_head execute_cb; |
| 210 | 211 | struct i915_sw_fence semaphore; |
| 212 | + struct irq_work semaphore_work; | |
| 211 | 213 | |
| 212 | 214 | /* |
| 213 | 215 | * A list of everyone we wait upon, and everyone who waits upon us. |
| @@ -234,6 +234,11 @@ static inline u64 ptr_to_u64(const void *ptr) · 233 unmodified lines | ||
| 234 | 234 | __idx; \ |
| 235 | 235 | }) |
| 236 | 236 | |
| 237 | +static inline bool is_power_of_2_u64(u64 n) | |
| 238 | +{ | |
| 239 | + return (n != 0 && ((n & (n - 1)) == 0)); | |
| 240 | +} | |
| 241 | + | |
| 237 | 242 | static inline void __list_del_many(struct list_head *head, |
| 238 | 243 | struct list_head *first) |
| 239 | 244 | { |
| @@ -486,6 +486,7 @@ static void mtk_drm_crtc_hw_config(struct mtk_drm_crtc *mtk_crtc) · 485 unmodified lines | ||
| 486 | 486 | } |
| 487 | 487 | #if IS_REACHABLE(CONFIG_MTK_CMDQ) |
| 488 | 488 | if (mtk_crtc->cmdq_client) { |
| 489 | + mbox_flush(mtk_crtc->cmdq_client->chan, 2000); | |
| 489 | 490 | cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE); |
| 490 | 491 | cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event); |
| 491 | 492 | cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event); |
| @@ -636,10 +637,18 @@ static const struct drm_crtc_helper_funcs mtk_crtc_helper_funcs = { · 144 unmodified lines | ||
| 636 | 637 | |
| 637 | 638 | static int mtk_drm_crtc_init(struct drm_device *drm, |
| 638 | 639 | struct mtk_drm_crtc *mtk_crtc, |
| 639 | − struct drm_plane *primary, | |
| 640 | − struct drm_plane *cursor, unsigned int pipe) | |
| 640 | + unsigned int pipe) | |
| 641 | 641 | { |
| 642 | − int ret; | |
| 642 | + struct drm_plane *primary = NULL; | |
| 643 | + struct drm_plane *cursor = NULL; | |
| 644 | + int i, ret; | |
| 645 | + | |
| 646 | + for (i = 0; i < mtk_crtc->layer_nr; i++) { | |
| 647 | + if (mtk_crtc->planes[i].type == DRM_PLANE_TYPE_PRIMARY) | |
| 648 | + primary = &mtk_crtc->planes[i]; | |
| 649 | + else if (mtk_crtc->planes[i].type == DRM_PLANE_TYPE_CURSOR) | |
| 650 | + cursor = &mtk_crtc->planes[i]; | |
| 651 | + } | |
| 643 | 652 | |
| 644 | 653 | ret = drm_crtc_init_with_planes(drm, &mtk_crtc->base, primary, cursor, |
| 645 | 654 | &mtk_crtc_funcs, NULL); |
| @@ -689,11 +698,12 @@ static int mtk_drm_crtc_num_comp_planes(struct mtk_drm_crtc *mtk_crtc, · 43 unmodified lines | ||
| 689 | 698 | } |
| 690 | 699 | |
| 691 | 700 | static inline |
| 692 | −enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx) | |
| 701 | +enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int plane_idx, | |
| 702 | + unsigned int num_planes) | |
| 693 | 703 | { |
| 694 | 704 | if (plane_idx == 0) |
| 695 | 705 | return DRM_PLANE_TYPE_PRIMARY; |
| 696 | − else if (plane_idx == 1) | |
| 706 | + else if (plane_idx == (num_planes - 1)) | |
| 697 | 707 | return DRM_PLANE_TYPE_CURSOR; |
| 698 | 708 | else |
| 699 | 709 | return DRM_PLANE_TYPE_OVERLAY; |
| @@ -712,7 +722,8 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev, · 12 unmodified lines | ||
| 712 | 722 | ret = mtk_plane_init(drm_dev, |
| 713 | 723 | &mtk_crtc->planes[mtk_crtc->layer_nr], |
| 714 | 724 | BIT(pipe), |
| 715 | − mtk_drm_crtc_plane_type(mtk_crtc->layer_nr), | |
| 725 | + mtk_drm_crtc_plane_type(mtk_crtc->layer_nr, | |
| 726 | + num_planes), | |
| 716 | 727 | mtk_ddp_comp_supported_rotations(comp)); |
| 717 | 728 | if (ret) |
| 718 | 729 | return ret; |
| @@ -807,9 +818,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, · 88 unmodified lines | ||
| 807 | 818 | return ret; |
| 808 | 819 | } |
| 809 | 820 | |
| 810 | − ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, &mtk_crtc->planes[0], | |
| 811 | − mtk_crtc->layer_nr > 1 ? &mtk_crtc->planes[1] : | |
| 812 | − NULL, pipe); | |
| 821 | + ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe); | |
| 813 | 822 | if (ret < 0) |
| 814 | 823 | return ret; |
| 815 | 824 | |
| @@ -828,7 +837,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev, · 12 unmodified lines | ||
| 828 | 837 | drm_crtc_index(&mtk_crtc->base)); |
| 829 | 838 | mtk_crtc->cmdq_client = NULL; |
| 830 | 839 | } |
| 831 | − ret = of_property_read_u32_index(dev->of_node, "mediatek,gce-events", | |
| 840 | + ret = of_property_read_u32_index(priv->mutex_node, | |
| 841 | + "mediatek,gce-events", | |
| 832 | 842 | drm_crtc_index(&mtk_crtc->base), |
| 833 | 843 | &mtk_crtc->cmdq_event); |
| 834 | 844 | if (ret) |
| @@ -471,6 +471,7 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node, · 470 unmodified lines | ||
| 471 | 471 | /* Only DMA capable components need the LARB property */ |
| 472 | 472 | comp->larb_dev = NULL; |
| 473 | 473 | if (type != MTK_DISP_OVL && |
| 474 | + type != MTK_DISP_OVL_2L && | |
| 474 | 475 | type != MTK_DISP_RDMA && |
| 475 | 476 | type != MTK_DISP_WDMA) |
| 476 | 477 | return 0; |
| @@ -80,6 +80,7 @@ static int mtk_plane_atomic_async_check(struct drm_plane *plane, · 79 unmodified lines | ||
| 80 | 80 | struct drm_plane_state *state) |
| 81 | 81 | { |
| 82 | 82 | struct drm_crtc_state *crtc_state; |
| 83 | + int ret; | |
| 83 | 84 | |
| 84 | 85 | if (plane != state->crtc->cursor) |
| 85 | 86 | return -EINVAL; |
| @@ -90,6 +91,11 @@ static int mtk_plane_atomic_async_check(struct drm_plane *plane, · 4 unmodified lines | ||
| 90 | 91 | if (!plane->state->fb) |
| 91 | 92 | return -EINVAL; |
| 92 | 93 | |
| 94 | + ret = mtk_drm_crtc_plane_check(state->crtc, plane, | |
| 95 | + to_mtk_plane_state(state)); | |
| 96 | + if (ret) | |
| 97 | + return ret; | |
| 98 | + | |
| 93 | 99 | if (state->state) |
| 94 | 100 | crtc_state = drm_atomic_get_existing_crtc_state(state->state, |
| 95 | 101 | state->crtc); |
| @@ -115,6 +121,7 @@ static void mtk_plane_atomic_async_update(struct drm_plane *plane, · 19 unmodified lines | ||
| 115 | 121 | plane->state->src_y = new_state->src_y; |
| 116 | 122 | plane->state->src_h = new_state->src_h; |
| 117 | 123 | plane->state->src_w = new_state->src_w; |
| 124 | + swap(plane->state->fb, new_state->fb); | |
| 118 | 125 | state->pending.async_dirty = true; |
| 119 | 126 | |
| 120 | 127 | mtk_drm_crtc_async_update(new_state->crtc, plane, new_state); |
| @@ -601,33 +601,27 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) · 600 unmodified lines | ||
| 601 | 601 | source_id = (fault_status >> 16); |
| 602 | 602 | |
| 603 | 603 | /* Page fault only */ |
| 604 | − if ((status & mask) == BIT(i)) { | |
| 605 | − WARN_ON(exception_type < 0xC1 || exception_type > 0xC4); | |
| 606 | − | |
| 604 | + ret = -1; | |
| 605 | + if ((status & mask) == BIT(i) && (exception_type & 0xF8) == 0xC0) | |
| 607 | 606 | ret = panfrost_mmu_map_fault_addr(pfdev, i, addr); |
| 608 | − if (!ret) { | |
| 609 | − mmu_write(pfdev, MMU_INT_CLEAR, BIT(i)); | |
| 610 | − status &= ~mask; | |
| 611 | − continue; | |
| 612 | − } | |
| 613 | − } | |
| 614 | 607 | |
| 615 | − /* terminal fault, print info about the fault */ | |
| 616 | − dev_err(pfdev->dev, | |
| 617 | − "Unhandled Page fault in AS%d at VA 0x%016llX\n" | |
| 618 | − "Reason: %s\n" | |
| 619 | − "raw fault status: 0x%X\n" | |
| 620 | − "decoded fault status: %s\n" | |
| 621 | − "exception type 0x%X: %s\n" | |
| 622 | − "access type 0x%X: %s\n" | |
| 623 | − "source id 0x%X\n", | |
| 624 | − i, addr, | |
| 625 | − "TODO", | |
| 626 | − fault_status, | |
| 627 | − (fault_status & (1 << 10) ? "DECODER FAULT" : "SLAVE FAULT"), | |
| 628 | − exception_type, panfrost_exception_name(pfdev, exception_type), | |
| 629 | − access_type, access_type_name(pfdev, fault_status), | |
| 630 | − source_id); | |
| 608 | + if (ret) | |
| 609 | + /* terminal fault, print info about the fault */ | |
| 610 | + dev_err(pfdev->dev, | |
| 611 | + "Unhandled Page fault in AS%d at VA 0x%016llX\n" | |
| 612 | + "Reason: %s\n" | |
| 613 | + "raw fault status: 0x%X\n" | |
| 614 | + "decoded fault status: %s\n" | |
| 615 | + "exception type 0x%X: %s\n" | |
| 616 | + "access type 0x%X: %s\n" | |
| 617 | + "source id 0x%X\n", | |
| 618 | + i, addr, | |
| 619 | + "TODO", | |
| 620 | + fault_status, | |
| 621 | + (fault_status & (1 << 10) ? "DECODER FAULT" : "SLAVE FAULT"), | |
| 622 | + exception_type, panfrost_exception_name(pfdev, exception_type), | |
| 623 | + access_type, access_type_name(pfdev, fault_status), | |
| 624 | + source_id); | |
| 631 | 625 | |
| 632 | 626 | mmu_write(pfdev, MMU_INT_CLEAR, mask); |
| 633 | 627 | |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <linux/vga_switcheroo.h> |
| 38 | 38 | #include <linux/mmu_notifier.h> |
| 39 | 39 | |
| 40 | +#include <drm/drm_agpsupport.h> | |
| 40 | 41 | #include <drm/drm_crtc_helper.h> |
| 41 | 42 | #include <drm/drm_drv.h> |
| 42 | 43 | #include <drm/drm_fb_helper.h> |
| @@ -325,6 +326,7 @@ static int radeon_pci_probe(struct pci_dev *pdev, · 282 unmodified lines | ||
| 325 | 326 | const struct pci_device_id *ent) |
| 326 | 327 | { |
| 327 | 328 | unsigned long flags = 0; |
| 329 | + struct drm_device *dev; | |
| 328 | 330 | int ret; |
| 329 | 331 | |
| 330 | 332 | if (!ent) |
| @@ -365,7 +367,44 @@ static int radeon_pci_probe(struct pci_dev *pdev, · 34 unmodified lines | ||
| 365 | 367 | if (ret) |
| 366 | 368 | return ret; |
| 367 | 369 | |
| 368 | − return drm_get_pci_dev(pdev, ent, &kms_driver); | |
| 370 | + dev = drm_dev_alloc(&kms_driver, &pdev->dev); | |
| 371 | + if (IS_ERR(dev)) | |
| 372 | + return PTR_ERR(dev); | |
| 373 | + | |
| 374 | + ret = pci_enable_device(pdev); | |
| 375 | + if (ret) | |
| 376 | + goto err_free; | |
| 377 | + | |
| 378 | + dev->pdev = pdev; | |
| 379 | +#ifdef __alpha__ | |
| 380 | + dev->hose = pdev->sysdata; | |
| 381 | +#endif | |
| 382 | + | |
| 383 | + pci_set_drvdata(pdev, dev); | |
| 384 | + | |
| 385 | + if (pci_find_capability(dev->pdev, PCI_CAP_ID_AGP)) | |
| 386 | + dev->agp = drm_agp_init(dev); | |
| 387 | + if (dev->agp) { | |
| 388 | + dev->agp->agp_mtrr = arch_phys_wc_add( | |
| 389 | + dev->agp->agp_info.aper_base, | |
| 390 | + dev->agp->agp_info.aper_size * | |
| 391 | + 1024 * 1024); | |
| 392 | + } | |
| 393 | + | |
| 394 | + ret = drm_dev_register(dev, ent->driver_data); | |
| 395 | + if (ret) | |
| 396 | + goto err_agp; | |
| 397 | + | |
| 398 | + return 0; | |
| 399 | + | |
| 400 | +err_agp: | |
| 401 | + if (dev->agp) | |
| 402 | + arch_phys_wc_del(dev->agp->agp_mtrr); | |
| 403 | + kfree(dev->agp); | |
| 404 | + pci_disable_device(pdev); | |
| 405 | +err_free: | |
| 406 | + drm_dev_put(dev); | |
| 407 | + return ret; | |
| 369 | 408 | } |
| 370 | 409 | |
| 371 | 410 | static void |
| @@ -575,7 +614,7 @@ radeon_get_crtc_scanout_position(struct drm_device *dev, unsigned int pipe, · 203 unmodified lines | ||
| 575 | 614 | |
| 576 | 615 | static struct drm_driver kms_driver = { |
| 577 | 616 | .driver_features = |
| 578 | − DRIVER_USE_AGP | DRIVER_GEM | DRIVER_RENDER, | |
| 617 | + DRIVER_GEM | DRIVER_RENDER, | |
| 579 | 618 | .load = radeon_driver_load_kms, |
| 580 | 619 | .open = radeon_driver_open_kms, |
| 581 | 620 | .postclose = radeon_driver_postclose_kms, |
| @@ -32,6 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | #include <linux/uaccess.h> |
| 33 | 33 | #include <linux/vga_switcheroo.h> |
| 34 | 34 | |
| 35 | +#include <drm/drm_agpsupport.h> | |
| 35 | 36 | #include <drm/drm_fb_helper.h> |
| 36 | 37 | #include <drm/drm_file.h> |
| 37 | 38 | #include <drm/drm_ioctl.h> |
| @@ -77,6 +78,11 @@ void radeon_driver_unload_kms(struct drm_device *dev) · 39 unmodified lines | ||
| 77 | 78 | radeon_modeset_fini(rdev); |
| 78 | 79 | radeon_device_fini(rdev); |
| 79 | 80 | |
| 81 | + if (dev->agp) | |
| 82 | + arch_phys_wc_del(dev->agp->agp_mtrr); | |
| 83 | + kfree(dev->agp); | |
| 84 | + dev->agp = NULL; | |
| 85 | + | |
| 80 | 86 | done_free: |
| 81 | 87 | kfree(rdev); |
| 82 | 88 | dev->dev_private = NULL; |
| @@ -106,48 +106,128 @@ static const struct de2_fmt_info de2_formats[] = { · 105 unmodified lines | ||
| 106 | 106 | .rgb = true, |
| 107 | 107 | .csc = SUN8I_CSC_MODE_OFF, |
| 108 | 108 | }, |
| 109 | + { | |
| 110 | + /* for DE2 VI layer which ignores alpha */ | |
| 111 | + .drm_fmt = DRM_FORMAT_XRGB4444, | |
| 112 | + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB4444, | |
| 113 | + .rgb = true, | |
| 114 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 115 | + }, | |
| 109 | 116 | { |
| 110 | 117 | .drm_fmt = DRM_FORMAT_ABGR4444, |
| 111 | 118 | .de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444, |
| 112 | 119 | .rgb = true, |
| 113 | 120 | .csc = SUN8I_CSC_MODE_OFF, |
| 114 | 121 | }, |
| 122 | + { | |
| 123 | + /* for DE2 VI layer which ignores alpha */ | |
| 124 | + .drm_fmt = DRM_FORMAT_XBGR4444, | |
| 125 | + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444, | |
| 126 | + .rgb = true, | |
| 127 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 128 | + }, | |
| 115 | 129 | { |
| 116 | 130 | .drm_fmt = DRM_FORMAT_RGBA4444, |
| 117 | 131 | .de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444, |
| 118 | 132 | .rgb = true, |
| 119 | 133 | .csc = SUN8I_CSC_MODE_OFF, |
| 120 | 134 | }, |
| 135 | + { | |
| 136 | + /* for DE2 VI layer which ignores alpha */ | |
| 137 | + .drm_fmt = DRM_FORMAT_RGBX4444, | |
| 138 | + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444, | |
| 139 | + .rgb = true, | |
| 140 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 141 | + }, | |
| 121 | 142 | { |
| 122 | 143 | .drm_fmt = DRM_FORMAT_BGRA4444, |
| 123 | 144 | .de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444, |
| 124 | 145 | .rgb = true, |
| 125 | 146 | .csc = SUN8I_CSC_MODE_OFF, |
| 126 | 147 | }, |
| 148 | + { | |
| 149 | + /* for DE2 VI layer which ignores alpha */ | |
| 150 | + .drm_fmt = DRM_FORMAT_BGRX4444, | |
| 151 | + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444, | |
| 152 | + .rgb = true, | |
| 153 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 154 | + }, | |
| 127 | 155 | { |
| 128 | 156 | .drm_fmt = DRM_FORMAT_ARGB1555, |
| 129 | 157 | .de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555, |
| 130 | 158 | .rgb = true, |
| 131 | 159 | .csc = SUN8I_CSC_MODE_OFF, |
| 132 | 160 | }, |
| 161 | + { | |
| 162 | + /* for DE2 VI layer which ignores alpha */ | |
| 163 | + .drm_fmt = DRM_FORMAT_XRGB1555, | |
| 164 | + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555, | |
| 165 | + .rgb = true, | |
| 166 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 167 | + }, | |
| 133 | 168 | { |
| 134 | 169 | .drm_fmt = DRM_FORMAT_ABGR1555, |
| 135 | 170 | .de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555, |
| 136 | 171 | .rgb = true, |
| 137 | 172 | .csc = SUN8I_CSC_MODE_OFF, |
| 138 | 173 | }, |
| 174 | + { | |
| 175 | + /* for DE2 VI layer which ignores alpha */ | |
| 176 | + .drm_fmt = DRM_FORMAT_XBGR1555, | |
| 177 | + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555, | |
| 178 | + .rgb = true, | |
| 179 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 180 | + }, | |
| 139 | 181 | { |
| 140 | 182 | .drm_fmt = DRM_FORMAT_RGBA5551, |
| 141 | 183 | .de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551, |
| 142 | 184 | .rgb = true, |
| 143 | 185 | .csc = SUN8I_CSC_MODE_OFF, |
| 144 | 186 | }, |
| 187 | + { | |
| 188 | + /* for DE2 VI layer which ignores alpha */ | |
| 189 | + .drm_fmt = DRM_FORMAT_RGBX5551, | |
| 190 | + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551, | |
| 191 | + .rgb = true, | |
| 192 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 193 | + }, | |
| 145 | 194 | { |
| 146 | 195 | .drm_fmt = DRM_FORMAT_BGRA5551, |
| 147 | 196 | .de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551, |
| 148 | 197 | .rgb = true, |
| 149 | 198 | .csc = SUN8I_CSC_MODE_OFF, |
| 150 | 199 | }, |
| 200 | + { | |
| 201 | + /* for DE2 VI layer which ignores alpha */ | |
| 202 | + .drm_fmt = DRM_FORMAT_BGRX5551, | |
| 203 | + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551, | |
| 204 | + .rgb = true, | |
| 205 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 206 | + }, | |
| 207 | + { | |
| 208 | + .drm_fmt = DRM_FORMAT_ARGB2101010, | |
| 209 | + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB2101010, | |
| 210 | + .rgb = true, | |
| 211 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 212 | + }, | |
| 213 | + { | |
| 214 | + .drm_fmt = DRM_FORMAT_ABGR2101010, | |
| 215 | + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR2101010, | |
| 216 | + .rgb = true, | |
| 217 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 218 | + }, | |
| 219 | + { | |
| 220 | + .drm_fmt = DRM_FORMAT_RGBA1010102, | |
| 221 | + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA1010102, | |
| 222 | + .rgb = true, | |
| 223 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 224 | + }, | |
| 225 | + { | |
| 226 | + .drm_fmt = DRM_FORMAT_BGRA1010102, | |
| 227 | + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA1010102, | |
| 228 | + .rgb = true, | |
| 229 | + .csc = SUN8I_CSC_MODE_OFF, | |
| 230 | + }, | |
| 151 | 231 | { |
| 152 | 232 | .drm_fmt = DRM_FORMAT_UYVY, |
| 153 | 233 | .de2_fmt = SUN8I_MIXER_FBFMT_UYVY, |
| @@ -196,12 +276,6 @@ static const struct de2_fmt_info de2_formats[] = { · 42 unmodified lines | ||
| 196 | 276 | .rgb = false, |
| 197 | 277 | .csc = SUN8I_CSC_MODE_YUV2RGB, |
| 198 | 278 | }, |
| 199 | − { | |
| 200 | − .drm_fmt = DRM_FORMAT_YUV444, | |
| 201 | − .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, | |
| 202 | − .rgb = true, | |
| 203 | − .csc = SUN8I_CSC_MODE_YUV2RGB, | |
| 204 | − }, | |
| 205 | 279 | { |
| 206 | 280 | .drm_fmt = DRM_FORMAT_YUV422, |
| 207 | 281 | .de2_fmt = SUN8I_MIXER_FBFMT_YUV422, |
| @@ -220,12 +294,6 @@ static const struct de2_fmt_info de2_formats[] = { · 12 unmodified lines | ||
| 220 | 294 | .rgb = false, |
| 221 | 295 | .csc = SUN8I_CSC_MODE_YUV2RGB, |
| 222 | 296 | }, |
| 223 | − { | |
| 224 | − .drm_fmt = DRM_FORMAT_YVU444, | |
| 225 | − .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, | |
| 226 | − .rgb = true, | |
| 227 | − .csc = SUN8I_CSC_MODE_YVU2RGB, | |
| 228 | − }, | |
| 229 | 297 | { |
| 230 | 298 | .drm_fmt = DRM_FORMAT_YVU422, |
| 231 | 299 | .de2_fmt = SUN8I_MIXER_FBFMT_YUV422, |
| @@ -244,6 +312,18 @@ static const struct de2_fmt_info de2_formats[] = { · 12 unmodified lines | ||
| 244 | 312 | .rgb = false, |
| 245 | 313 | .csc = SUN8I_CSC_MODE_YVU2RGB, |
| 246 | 314 | }, |
| 315 | + { | |
| 316 | + .drm_fmt = DRM_FORMAT_P010, | |
| 317 | + .de2_fmt = SUN8I_MIXER_FBFMT_P010_YUV, | |
| 318 | + .rgb = false, | |
| 319 | + .csc = SUN8I_CSC_MODE_YUV2RGB, | |
| 320 | + }, | |
| 321 | + { | |
| 322 | + .drm_fmt = DRM_FORMAT_P210, | |
| 323 | + .de2_fmt = SUN8I_MIXER_FBFMT_P210_YUV, | |
| 324 | + .rgb = false, | |
| 325 | + .csc = SUN8I_CSC_MODE_YUV2RGB, | |
| 326 | + }, | |
| 247 | 327 | }; |
| 248 | 328 | |
| 249 | 329 | const struct de2_fmt_info *sun8i_mixer_format_info(u32 format) |
| @@ -93,6 +93,10 @@ · 92 unmodified lines | ||
| 93 | 93 | #define SUN8I_MIXER_FBFMT_ABGR1555 17 |
| 94 | 94 | #define SUN8I_MIXER_FBFMT_RGBA5551 18 |
| 95 | 95 | #define SUN8I_MIXER_FBFMT_BGRA5551 19 |
| 96 | +#define SUN8I_MIXER_FBFMT_ARGB2101010 20 | |
| 97 | +#define SUN8I_MIXER_FBFMT_ABGR2101010 21 | |
| 98 | +#define SUN8I_MIXER_FBFMT_RGBA1010102 22 | |
| 99 | +#define SUN8I_MIXER_FBFMT_BGRA1010102 23 | |
| 96 | 100 | |
| 97 | 101 | #define SUN8I_MIXER_FBFMT_YUYV 0 |
| 98 | 102 | #define SUN8I_MIXER_FBFMT_UYVY 1 |
| @@ -109,6 +113,13 @@ · 10 unmodified lines | ||
| 109 | 113 | /* format 12 is semi-planar YUV411 UVUV */ |
| 110 | 114 | /* format 13 is semi-planar YUV411 VUVU */ |
| 111 | 115 | #define SUN8I_MIXER_FBFMT_YUV411 14 |
| 116 | +/* format 15 doesn't exist */ | |
| 117 | +/* format 16 is P010 YVU */ | |
| 118 | +#define SUN8I_MIXER_FBFMT_P010_YUV 17 | |
| 119 | +/* format 18 is P210 YVU */ | |
| 120 | +#define SUN8I_MIXER_FBFMT_P210_YUV 19 | |
| 121 | +/* format 20 is packed YVU444 10-bit */ | |
| 122 | +/* format 21 is packed YUV444 10-bit */ | |
| 112 | 123 | |
| 113 | 124 | /* |
| 114 | 125 | * Sub-engines listed bellow are unused for now. The EN registers are here only |
| @@ -398,24 +398,66 @@ static const struct drm_plane_funcs sun8i_vi_layer_funcs = { · 397 unmodified lines | ||
| 398 | 398 | }; |
| 399 | 399 | |
| 400 | 400 | /* |
| 401 | − * While all RGB formats are supported, VI planes don't support | |
| 402 | − * alpha blending, so there is no point having formats with alpha | |
| 403 | − * channel if their opaque analog exist. | |
| 401 | + * While DE2 VI layer supports same RGB formats as UI layer, alpha | |
| 402 | + * channel is ignored. This structure lists all unique variants | |
| 403 | + * where alpha channel is replaced with "don't care" (X) channel. | |
| 404 | 404 | */ |
| 405 | 405 | static const u32 sun8i_vi_layer_formats[] = { |
| 406 | + DRM_FORMAT_BGR565, | |
| 407 | + DRM_FORMAT_BGR888, | |
| 408 | + DRM_FORMAT_BGRX4444, | |
| 409 | + DRM_FORMAT_BGRX5551, | |
| 410 | + DRM_FORMAT_BGRX8888, | |
| 411 | + DRM_FORMAT_RGB565, | |
| 412 | + DRM_FORMAT_RGB888, | |
| 413 | + DRM_FORMAT_RGBX4444, | |
| 414 | + DRM_FORMAT_RGBX5551, | |
| 415 | + DRM_FORMAT_RGBX8888, | |
| 416 | + DRM_FORMAT_XBGR1555, | |
| 417 | + DRM_FORMAT_XBGR4444, | |
| 418 | + DRM_FORMAT_XBGR8888, | |
| 419 | + DRM_FORMAT_XRGB1555, | |
| 420 | + DRM_FORMAT_XRGB4444, | |
| 421 | + DRM_FORMAT_XRGB8888, | |
| 422 | + | |
| 423 | + DRM_FORMAT_NV16, | |
| 424 | + DRM_FORMAT_NV12, | |
| 425 | + DRM_FORMAT_NV21, | |
| 426 | + DRM_FORMAT_NV61, | |
| 427 | + DRM_FORMAT_UYVY, | |
| 428 | + DRM_FORMAT_VYUY, | |
| 429 | + DRM_FORMAT_YUYV, | |
| 430 | + DRM_FORMAT_YVYU, | |
| 431 | + DRM_FORMAT_YUV411, | |
| 432 | + DRM_FORMAT_YUV420, | |
| 433 | + DRM_FORMAT_YUV422, | |
| 434 | + DRM_FORMAT_YVU411, | |
| 435 | + DRM_FORMAT_YVU420, | |
| 436 | + DRM_FORMAT_YVU422, | |
| 437 | +}; | |
| 438 | + | |
| 439 | +static const u32 sun8i_vi_layer_de3_formats[] = { | |
| 406 | 440 | DRM_FORMAT_ABGR1555, |
| 441 | + DRM_FORMAT_ABGR2101010, | |
| 407 | 442 | DRM_FORMAT_ABGR4444, |
| 443 | + DRM_FORMAT_ABGR8888, | |
| 408 | 444 | DRM_FORMAT_ARGB1555, |
| 445 | + DRM_FORMAT_ARGB2101010, | |
| 409 | 446 | DRM_FORMAT_ARGB4444, |
| 447 | + DRM_FORMAT_ARGB8888, | |
| 410 | 448 | DRM_FORMAT_BGR565, |
| 411 | 449 | DRM_FORMAT_BGR888, |
| 450 | + DRM_FORMAT_BGRA1010102, | |
| 412 | 451 | DRM_FORMAT_BGRA5551, |
| 413 | 452 | DRM_FORMAT_BGRA4444, |
| 453 | + DRM_FORMAT_BGRA8888, | |
| 414 | 454 | DRM_FORMAT_BGRX8888, |
| 415 | 455 | DRM_FORMAT_RGB565, |
| 416 | 456 | DRM_FORMAT_RGB888, |
| 457 | + DRM_FORMAT_RGBA1010102, | |
| 417 | 458 | DRM_FORMAT_RGBA4444, |
| 418 | 459 | DRM_FORMAT_RGBA5551, |
| 460 | + DRM_FORMAT_RGBA8888, | |
| 419 | 461 | DRM_FORMAT_RGBX8888, |
| 420 | 462 | DRM_FORMAT_XBGR8888, |
| 421 | 463 | DRM_FORMAT_XRGB8888, |
| @@ -424,6 +466,8 @@ static const u32 sun8i_vi_layer_formats[] = { · 2 unmodified lines | ||
| 424 | 466 | DRM_FORMAT_NV12, |
| 425 | 467 | DRM_FORMAT_NV21, |
| 426 | 468 | DRM_FORMAT_NV61, |
| 469 | + DRM_FORMAT_P010, | |
| 470 | + DRM_FORMAT_P210, | |
| 427 | 471 | DRM_FORMAT_UYVY, |
| 428 | 472 | DRM_FORMAT_VYUY, |
| 429 | 473 | DRM_FORMAT_YUYV, |
| @@ -431,11 +475,9 @@ static const u32 sun8i_vi_layer_formats[] = { · 1 unmodified line | ||
| 431 | 475 | DRM_FORMAT_YUV411, |
| 432 | 476 | DRM_FORMAT_YUV420, |
| 433 | 477 | DRM_FORMAT_YUV422, |
| 434 | − DRM_FORMAT_YUV444, | |
| 435 | 478 | DRM_FORMAT_YVU411, |
| 436 | 479 | DRM_FORMAT_YVU420, |
| 437 | 480 | DRM_FORMAT_YVU422, |
| 438 | − DRM_FORMAT_YVU444, | |
| 439 | 481 | }; |
| 440 | 482 | |
| 441 | 483 | struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, |
| @@ -443,19 +485,27 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, · 1 unmodified line | ||
| 443 | 485 | int index) |
| 444 | 486 | { |
| 445 | 487 | u32 supported_encodings, supported_ranges; |
| 488 | + unsigned int plane_cnt, format_count; | |
| 446 | 489 | struct sun8i_vi_layer *layer; |
| 447 | − unsigned int plane_cnt; | |
| 490 | + const u32 *formats; | |
| 448 | 491 | int ret; |
| 449 | 492 | |
| 450 | 493 | layer = devm_kzalloc(drm->dev, sizeof(*layer), GFP_KERNEL); |
| 451 | 494 | if (!layer) |
| 452 | 495 | return ERR_PTR(-ENOMEM); |
| 453 | 496 | |
| 497 | + if (mixer->cfg->is_de3) { | |
| 498 | + formats = sun8i_vi_layer_de3_formats; | |
| 499 | + format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); | |
| 500 | + } else { | |
| 501 | + formats = sun8i_vi_layer_formats; | |
| 502 | + format_count = ARRAY_SIZE(sun8i_vi_layer_formats); | |
| 503 | + } | |
| 504 | + | |
| 454 | 505 | /* possible crtcs are set later */ |
| 455 | 506 | ret = drm_universal_plane_init(drm, &layer->plane, 0, |
| 456 | 507 | &sun8i_vi_layer_funcs, |
| 457 | − sun8i_vi_layer_formats, | |
| 458 | − ARRAY_SIZE(sun8i_vi_layer_formats), | |
| 508 | + formats, format_count, | |
| 459 | 509 | NULL, DRM_PLANE_TYPE_OVERLAY, NULL); |
| 460 | 510 | if (ret) { |
| 461 | 511 | dev_err(drm->dev, "Couldn't initialize layer\n"); |
| @@ -515,6 +515,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, · 514 unmodified lines | ||
| 515 | 515 | fbo->base.base.resv = &fbo->base.base._resv; |
| 516 | 516 | |
| 517 | 517 | dma_resv_init(&fbo->base.base._resv); |
| 518 | + fbo->base.base.dev = NULL; | |
| 518 | 519 | ret = dma_resv_trylock(&fbo->base.base._resv); |
| 519 | 520 | WARN_ON(!ret); |
| 520 | 521 | |
| @@ -42,8 +42,8 @@ static int virtio_gpu_resource_id_get(struct virtio_gpu_device *vgdev, · 41 unmodified lines | ||
| 42 | 42 | * "f91a9dd35715 Fix unlinking resources from hash |
| 43 | 43 | * table." (Feb 2019) fixes the bug. |
| 44 | 44 | */ |
| 45 | − static int handle; | |
| 46 | − handle++; | |
| 45 | + static atomic_t seqno = ATOMIC_INIT(0); | |
| 46 | + int handle = atomic_inc_return(&seqno); | |
| 47 | 47 | *resid = handle + 1; |
| 48 | 48 | } else { |
| 49 | 49 | int handle = ida_alloc(&vgdev->resource_ida, GFP_KERNEL); |
| @@ -99,6 +99,7 @@ struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev, · 49 unmodified lines | ||
| 99 | 99 | return NULL; |
| 100 | 100 | |
| 101 | 101 | bo->base.base.funcs = &virtio_gpu_gem_funcs; |
| 102 | + bo->base.map_cached = true; | |
| 102 | 103 | return &bo->base.base; |
| 103 | 104 | } |
| 104 | 105 | |
| @@ -730,7 +730,7 @@ static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi) · 729 unmodified lines | ||
| 730 | 730 | if (data->has_sp) { |
| 731 | 731 | input2 = input_allocate_device(); |
| 732 | 732 | if (!input2) { |
| 733 | − input_free_device(input2); | |
| 733 | + ret = -ENOMEM; | |
| 734 | 734 | goto exit; |
| 735 | 735 | } |
| 736 | 736 | |
| @@ -340,7 +340,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, · 339 unmodified lines | ||
| 340 | 340 | unsigned long **bit, int *max) |
| 341 | 341 | { |
| 342 | 342 | if (usage->hid == (HID_UP_CUSTOM | 0x0003) || |
| 343 | − usage->hid == (HID_UP_MSVENDOR | 0x0003)) { | |
| 343 | + usage->hid == (HID_UP_MSVENDOR | 0x0003) || | |
| 344 | + usage->hid == (HID_UP_HPVENDOR2 | 0x0003)) { | |
| 344 | 345 | /* The fn key on Apple USB keyboards */ |
| 345 | 346 | set_bit(EV_REP, hi->input->evbit); |
| 346 | 347 | hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN); |
| @@ -174,6 +174,7 @@ static __u8 pid0902_rdesc_fixed[] = { · 173 unmodified lines | ||
| 174 | 174 | struct bigben_device { |
| 175 | 175 | struct hid_device *hid; |
| 176 | 176 | struct hid_report *report; |
| 177 | + bool removed; | |
| 177 | 178 | u8 led_state; /* LED1 = 1 .. LED4 = 8 */ |
| 178 | 179 | u8 right_motor_on; /* right motor off/on 0/1 */ |
| 179 | 180 | u8 left_motor_force; /* left motor force 0-255 */ |
| @@ -190,6 +191,9 @@ static void bigben_worker(struct work_struct *work) · 10 unmodified lines | ||
| 190 | 191 | struct bigben_device, worker); |
| 191 | 192 | struct hid_field *report_field = bigben->report->field[0]; |
| 192 | 193 | |
| 194 | + if (bigben->removed) | |
| 195 | + return; | |
| 196 | + | |
| 193 | 197 | if (bigben->work_led) { |
| 194 | 198 | bigben->work_led = false; |
| 195 | 199 | report_field->value[0] = 0x01; /* 1 = led message */ |
| @@ -220,10 +224,16 @@ static void bigben_worker(struct work_struct *work) · 24 unmodified lines | ||
| 220 | 224 | static int hid_bigben_play_effect(struct input_dev *dev, void *data, |
| 221 | 225 | struct ff_effect *effect) |
| 222 | 226 | { |
| 223 | − struct bigben_device *bigben = data; | |
| 227 | + struct hid_device *hid = input_get_drvdata(dev); | |
| 228 | + struct bigben_device *bigben = hid_get_drvdata(hid); | |
| 224 | 229 | u8 right_motor_on; |
| 225 | 230 | u8 left_motor_force; |
| 226 | 231 | |
| 232 | + if (!bigben) { | |
| 233 | + hid_err(hid, "no device data\n"); | |
| 234 | + return 0; | |
| 235 | + } | |
| 236 | + | |
| 227 | 237 | if (effect->type != FF_RUMBLE) |
| 228 | 238 | return 0; |
| 229 | 239 | |
| @@ -298,8 +308,8 @@ static void bigben_remove(struct hid_device *hid) · 68 unmodified lines | ||
| 298 | 308 | { |
| 299 | 309 | struct bigben_device *bigben = hid_get_drvdata(hid); |
| 300 | 310 | |
| 311 | + bigben->removed = true; | |
| 301 | 312 | cancel_work_sync(&bigben->worker); |
| 302 | − hid_hw_close(hid); | |
| 303 | 313 | hid_hw_stop(hid); |
| 304 | 314 | } |
| 305 | 315 | |
| @@ -319,6 +329,7 @@ static int bigben_probe(struct hid_device *hid, · 13 unmodified lines | ||
| 319 | 329 | return -ENOMEM; |
| 320 | 330 | hid_set_drvdata(hid, bigben); |
| 321 | 331 | bigben->hid = hid; |
| 332 | + bigben->removed = false; | |
| 322 | 333 | |
| 323 | 334 | error = hid_parse(hid); |
| 324 | 335 | if (error) { |
| @@ -341,10 +352,10 @@ static int bigben_probe(struct hid_device *hid, · 16 unmodified lines | ||
| 341 | 352 | |
| 342 | 353 | INIT_WORK(&bigben->worker, bigben_worker); |
| 343 | 354 | |
| 344 | − error = input_ff_create_memless(hidinput->input, bigben, | |
| 355 | + error = input_ff_create_memless(hidinput->input, NULL, | |
| 345 | 356 | hid_bigben_play_effect); |
| 346 | 357 | if (error) |
| 347 | − return error; | |
| 358 | + goto error_hw_stop; | |
| 348 | 359 | |
| 349 | 360 | name_sz = strlen(dev_name(&hid->dev)) + strlen(":red:bigben#") + 1; |
| 350 | 361 | |
| @@ -354,8 +365,10 @@ static int bigben_probe(struct hid_device *hid, · 3 unmodified lines | ||
| 354 | 365 | sizeof(struct led_classdev) + name_sz, |
| 355 | 366 | GFP_KERNEL |
| 356 | 367 | ); |
| 357 | − if (!led) | |
| 358 | − return -ENOMEM; | |
| 368 | + if (!led) { | |
| 369 | + error = -ENOMEM; | |
| 370 | + goto error_hw_stop; | |
| 371 | + } | |
| 359 | 372 | name = (void *)(&led[1]); |
| 360 | 373 | snprintf(name, name_sz, |
| 361 | 374 | "%s:red:bigben%d", |
| @@ -369,7 +382,7 @@ static int bigben_probe(struct hid_device *hid, · 7 unmodified lines | ||
| 369 | 382 | bigben->leds[n] = led; |
| 370 | 383 | error = devm_led_classdev_register(&hid->dev, led); |
| 371 | 384 | if (error) |
| 372 | − return error; | |
| 385 | + goto error_hw_stop; | |
| 373 | 386 | } |
| 374 | 387 | |
| 375 | 388 | /* initial state: LED1 is on, no rumble effect */ |
| @@ -383,6 +396,10 @@ static int bigben_probe(struct hid_device *hid, · 7 unmodified lines | ||
| 383 | 396 | hid_info(hid, "LED and force feedback support for BigBen gamepad\n"); |
| 384 | 397 | |
| 385 | 398 | return 0; |
| 399 | + | |
| 400 | +error_hw_stop: | |
| 401 | + hid_hw_stop(hid); | |
| 402 | + return error; | |
| 386 | 403 | } |
| 387 | 404 | |
| 388 | 405 | static __u8 *bigben_report_fixup(struct hid_device *hid, __u8 *rdesc, |
| @@ -1741,7 +1741,9 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size, · 1740 unmodified lines | ||
| 1741 | 1741 | |
| 1742 | 1742 | rsize = ((report->size - 1) >> 3) + 1; |
| 1743 | 1743 | |
| 1744 | − if (rsize > HID_MAX_BUFFER_SIZE) | |
| 1744 | + if (report_enum->numbered && rsize >= HID_MAX_BUFFER_SIZE) | |
| 1745 | + rsize = HID_MAX_BUFFER_SIZE - 1; | |
| 1746 | + else if (rsize > HID_MAX_BUFFER_SIZE) | |
| 1745 | 1747 | rsize = HID_MAX_BUFFER_SIZE; |
| 1746 | 1748 | |
| 1747 | 1749 | if (csize < rsize) { |
| @@ -532,6 +532,8 @@ static const struct hid_device_id hammer_devices[] = { · 531 unmodified lines | ||
| 532 | 532 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MAGNEMITE) }, |
| 533 | 533 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 534 | 534 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MASTERBALL) }, |
| 535 | + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | |
| 536 | + USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_MOONBALL) }, | |
| 535 | 537 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 536 | 538 | USB_VENDOR_ID_GOOGLE, USB_DEVICE_ID_GOOGLE_STAFF) }, |
| 537 | 539 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| @@ -193,8 +193,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, · 192 unmodified lines | ||
| 193 | 193 | goto cleanup; |
| 194 | 194 | |
| 195 | 195 | /* The pointer is not NULL when we resume from hibernation */ |
| 196 | − if (input_device->hid_desc != NULL) | |
| 197 | − kfree(input_device->hid_desc); | |
| 196 | + kfree(input_device->hid_desc); | |
| 198 | 197 | input_device->hid_desc = kmemdup(desc, desc->bLength, GFP_ATOMIC); |
| 199 | 198 | |
| 200 | 199 | if (!input_device->hid_desc) |
| @@ -207,8 +206,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, · 6 unmodified lines | ||
| 207 | 206 | } |
| 208 | 207 | |
| 209 | 208 | /* The pointer is not NULL when we resume from hibernation */ |
| 210 | − if (input_device->report_desc != NULL) | |
| 211 | − kfree(input_device->report_desc); | |
| 209 | + kfree(input_device->report_desc); | |
| 212 | 210 | input_device->report_desc = kzalloc(input_device->report_desc_size, |
| 213 | 211 | GFP_ATOMIC); |
| 214 | 212 | |
| @@ -478,6 +478,7 @@ · 477 unmodified lines | ||
| 478 | 478 | #define USB_DEVICE_ID_GOOGLE_WHISKERS 0x5030 |
| 479 | 479 | #define USB_DEVICE_ID_GOOGLE_MASTERBALL 0x503c |
| 480 | 480 | #define USB_DEVICE_ID_GOOGLE_MAGNEMITE 0x503d |
| 481 | +#define USB_DEVICE_ID_GOOGLE_MOONBALL 0x5044 | |
| 481 | 482 | |
| 482 | 483 | #define USB_VENDOR_ID_GOTOP 0x08f2 |
| 483 | 484 | #define USB_DEVICE_ID_SUPER_Q2 0x007f |
| @@ -726,6 +727,7 @@ · 242 unmodified lines | ||
| 726 | 727 | #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 |
| 727 | 728 | #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 |
| 728 | 729 | #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 |
| 730 | +#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d | |
| 729 | 731 | |
| 730 | 732 | #define USB_VENDOR_ID_LG 0x1fd2 |
| 731 | 733 | #define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 |
| @@ -41,8 +41,9 @@ static const struct hid_device_id ite_devices[] = { · 40 unmodified lines | ||
| 41 | 41 | { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) }, |
| 42 | 42 | { HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) }, |
| 43 | 43 | /* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */ |
| 44 | − { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, | |
| 45 | − USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, | |
| 44 | + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | |
| 45 | + USB_VENDOR_ID_SYNAPTICS, | |
| 46 | + USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) }, | |
| 46 | 47 | { } |
| 47 | 48 | }; |
| 48 | 49 | MODULE_DEVICE_TABLE(hid, ite_devices); |
| @@ -1256,36 +1256,35 @@ static int hidpp20_battery_map_status_voltage(u8 data[3], int *voltage, · 1255 unmodified lines | ||
| 1256 | 1256 | { |
| 1257 | 1257 | int status; |
| 1258 | 1258 | |
| 1259 | − long charge_sts = (long)data[2]; | |
| 1259 | + long flags = (long) data[2]; | |
| 1260 | 1260 | |
| 1261 | − *level = POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN; | |
| 1262 | − switch (data[2] & 0xe0) { | |
| 1263 | − case 0x00: | |
| 1264 | − status = POWER_SUPPLY_STATUS_CHARGING; | |
| 1265 | − break; | |
| 1266 | − case 0x20: | |
| 1267 | − status = POWER_SUPPLY_STATUS_FULL; | |
| 1268 | − *level = POWER_SUPPLY_CAPACITY_LEVEL_FULL; | |
| 1269 | − break; | |
| 1270 | − case 0x40: | |
| 1261 | + if (flags & 0x80) | |
| 1262 | + switch (flags & 0x07) { | |
| 1263 | + case 0: | |
| 1264 | + status = POWER_SUPPLY_STATUS_CHARGING; | |
| 1265 | + break; | |
| 1266 | + case 1: | |
| 1267 | + status = POWER_SUPPLY_STATUS_FULL; | |
| 1268 | + *level = POWER_SUPPLY_CAPACITY_LEVEL_FULL; | |
| 1269 | + break; | |
| 1270 | + case 2: | |
| 1271 | + status = POWER_SUPPLY_STATUS_NOT_CHARGING; | |
| 1272 | + break; | |
| 1273 | + default: | |
| 1274 | + status = POWER_SUPPLY_STATUS_UNKNOWN; | |
| 1275 | + break; | |
| 1276 | + } | |
| 1277 | + else | |
| 1271 | 1278 | status = POWER_SUPPLY_STATUS_DISCHARGING; |
| 1272 | − break; | |
| 1273 | − case 0xe0: | |
| 1274 | − status = POWER_SUPPLY_STATUS_NOT_CHARGING; | |
| 1275 | − break; | |
| 1276 | − default: | |
| 1277 | − status = POWER_SUPPLY_STATUS_UNKNOWN; | |
| 1278 | − } | |
| 1279 | 1279 | |
| 1280 | 1280 | *charge_type = POWER_SUPPLY_CHARGE_TYPE_STANDARD; |
| 1281 | − if (test_bit(3, &charge_sts)) { | |
| 1281 | + if (test_bit(3, &flags)) { | |
| 1282 | 1282 | *charge_type = POWER_SUPPLY_CHARGE_TYPE_FAST; |
| 1283 | 1283 | } |
| 1284 | − if (test_bit(4, &charge_sts)) { | |
| 1284 | + if (test_bit(4, &flags)) { | |
| 1285 | 1285 | *charge_type = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; |
| 1286 | 1286 | } |
| 1287 | − | |
| 1288 | − if (test_bit(5, &charge_sts)) { | |
| 1287 | + if (test_bit(5, &flags)) { | |
| 1289 | 1288 | *level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL; |
| 1290 | 1289 | } |
| 1291 | 1290 | |
| @@ -458,9 +458,9 @@ static ssize_t picolcd_fb_update_rate_show(struct device *dev, · 457 unmodified lines | ||
| 458 | 458 | if (ret >= PAGE_SIZE) |
| 459 | 459 | break; |
| 460 | 460 | else if (i == fb_update_rate) |
| 461 | − ret += snprintf(buf+ret, PAGE_SIZE-ret, "[%u] ", i); | |
| 461 | + ret += scnprintf(buf+ret, PAGE_SIZE-ret, "[%u] ", i); | |
| 462 | 462 | else |
| 463 | − ret += snprintf(buf+ret, PAGE_SIZE-ret, "%u ", i); | |
| 463 | + ret += scnprintf(buf+ret, PAGE_SIZE-ret, "%u ", i); | |
| 464 | 464 | if (ret > 0) |
| 465 | 465 | buf[min(ret, (size_t)PAGE_SIZE)-1] = '\n'; |
| 466 | 466 | return ret; |
| @@ -103,6 +103,7 @@ static const struct hid_device_id hid_quirks[] = { · 102 unmodified lines | ||
| 103 | 103 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT }, |
| 104 | 104 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT }, |
| 105 | 105 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL }, |
| 106 | + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL }, | |
| 106 | 107 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL }, |
| 107 | 108 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL }, |
| 108 | 109 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET }, |
| @@ -313,7 +313,7 @@ static ssize_t show_value(struct device *dev, struct device_attribute *attr, · 312 unmodified lines | ||
| 313 | 313 | |
| 314 | 314 | while (i < ret) { |
| 315 | 315 | if (i + attribute->size > ret) { |
| 316 | − len += snprintf(&buf[len], | |
| 316 | + len += scnprintf(&buf[len], | |
| 317 | 317 | PAGE_SIZE - len, |
| 318 | 318 | "%d ", values[i]); |
| 319 | 319 | break; |
| @@ -336,10 +336,10 @@ static ssize_t show_value(struct device *dev, struct device_attribute *attr, · 16 unmodified lines | ||
| 336 | 336 | ++i; |
| 337 | 337 | break; |
| 338 | 338 | } |
| 339 | − len += snprintf(&buf[len], PAGE_SIZE - len, | |
| 339 | + len += scnprintf(&buf[len], PAGE_SIZE - len, | |
| 340 | 340 | "%lld ", value); |
| 341 | 341 | } |
| 342 | − len += snprintf(&buf[len], PAGE_SIZE - len, "\n"); | |
| 342 | + len += scnprintf(&buf[len], PAGE_SIZE - len, "\n"); | |
| 343 | 343 | |
| 344 | 344 | return len; |
| 345 | 345 | } else if (input) |
| @@ -341,6 +341,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { · 340 unmodified lines | ||
| 341 | 341 | }, |
| 342 | 342 | .driver_data = (void *)&sipodev_desc |
| 343 | 343 | }, |
| 344 | + { | |
| 345 | + .ident = "Trekstor SURFBOOK E11B", | |
| 346 | + .matches = { | |
| 347 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TREKSTOR"), | |
| 348 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SURFBOOK E11B"), | |
| 349 | + }, | |
| 350 | + .driver_data = (void *)&sipodev_desc | |
| 351 | + }, | |
| 344 | 352 | { |
| 345 | 353 | .ident = "Direkt-Tek DTLAPY116-2", |
| 346 | 354 | .matches = { |
| @@ -932,9 +932,9 @@ void hiddev_disconnect(struct hid_device *hid) · 931 unmodified lines | ||
| 932 | 932 | hiddev->exist = 0; |
| 933 | 933 | |
| 934 | 934 | if (hiddev->open) { |
| 935 | − mutex_unlock(&hiddev->existancelock); | |
| 936 | 935 | hid_hw_close(hiddev->hid); |
| 937 | 936 | wake_up_interruptible(&hiddev->wait); |
| 937 | + mutex_unlock(&hiddev->existancelock); | |
| 938 | 938 | } else { |
| 939 | 939 | mutex_unlock(&hiddev->existancelock); |
| 940 | 940 | kfree(hiddev); |
| @@ -413,7 +413,7 @@ static int ADT7462_REG_VOLT(struct adt7462_data *data, int which) · 412 unmodified lines | ||
| 413 | 413 | return 0x95; |
| 414 | 414 | break; |
| 415 | 415 | } |
| 416 | − return -ENODEV; | |
| 416 | + return 0; | |
| 417 | 417 | } |
| 418 | 418 | |
| 419 | 419 | /* Provide labels for sysfs */ |
| @@ -18,6 +18,59 @@ · 17 unmodified lines | ||
| 18 | 18 | #define XDPE122_AMD_625MV 0x10 /* AMD mode 6.25mV */ |
| 19 | 19 | #define XDPE122_PAGE_NUM 2 |
| 20 | 20 | |
| 21 | +static int xdpe122_read_word_data(struct i2c_client *client, int page, int reg) | |
| 22 | +{ | |
| 23 | + const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | |
| 24 | + long val; | |
| 25 | + s16 exponent; | |
| 26 | + s32 mantissa; | |
| 27 | + int ret; | |
| 28 | + | |
| 29 | + switch (reg) { | |
| 30 | + case PMBUS_VOUT_OV_FAULT_LIMIT: | |
| 31 | + case PMBUS_VOUT_UV_FAULT_LIMIT: | |
| 32 | + ret = pmbus_read_word_data(client, page, reg); | |
| 33 | + if (ret < 0) | |
| 34 | + return ret; | |
| 35 | + | |
| 36 | + /* Convert register value to LINEAR11 data. */ | |
| 37 | + exponent = ((s16)ret) >> 11; | |
| 38 | + mantissa = ((s16)((ret & GENMASK(10, 0)) << 5)) >> 5; | |
| 39 | + val = mantissa * 1000L; | |
| 40 | + if (exponent >= 0) | |
| 41 | + val <<= exponent; | |
| 42 | + else | |
| 43 | + val >>= -exponent; | |
| 44 | + | |
| 45 | + /* Convert data to VID register. */ | |
| 46 | + switch (info->vrm_version[page]) { | |
| 47 | + case vr13: | |
| 48 | + if (val >= 500) | |
| 49 | + return 1 + DIV_ROUND_CLOSEST(val - 500, 10); | |
| 50 | + return 0; | |
| 51 | + case vr12: | |
| 52 | + if (val >= 250) | |
| 53 | + return 1 + DIV_ROUND_CLOSEST(val - 250, 5); | |
| 54 | + return 0; | |
| 55 | + case imvp9: | |
| 56 | + if (val >= 200) | |
| 57 | + return 1 + DIV_ROUND_CLOSEST(val - 200, 10); | |
| 58 | + return 0; | |
| 59 | + case amd625mv: | |
| 60 | + if (val >= 200 && val <= 1550) | |
| 61 | + return DIV_ROUND_CLOSEST((1550 - val) * 100, | |
| 62 | + 625); | |
| 63 | + return 0; | |
| 64 | + default: | |
| 65 | + return -EINVAL; | |
| 66 | + } | |
| 67 | + default: | |
| 68 | + return -ENODATA; | |
| 69 | + } | |
| 70 | + | |
| 71 | + return 0; | |
| 72 | +} | |
| 73 | + | |
| 21 | 74 | static int xdpe122_identify(struct i2c_client *client, |
| 22 | 75 | struct pmbus_driver_info *info) |
| 23 | 76 | { |
| @@ -70,6 +123,7 @@ static struct pmbus_driver_info xdpe122_info = { · 46 unmodified lines | ||
| 70 | 123 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | |
| 71 | 124 | PMBUS_HAVE_POUT | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT, |
| 72 | 125 | .identify = xdpe122_identify, |
| 126 | + .read_word_data = xdpe122_read_word_data, | |
| 73 | 127 | }; |
| 74 | 128 | |
| 75 | 129 | static int xdpe122_probe(struct i2c_client *client, |
| @@ -718,9 +718,6 @@ static int msc_win_set_lockout(struct msc_window *win, · 717 unmodified lines | ||
| 718 | 718 | |
| 719 | 719 | if (old != expect) { |
| 720 | 720 | ret = -EINVAL; |
| 721 | − dev_warn_ratelimited(msc_dev(win->msc), | |
| 722 | − "expected lockout state %d, got %d\n", | |
| 723 | − expect, old); | |
| 724 | 721 | goto unlock; |
| 725 | 722 | } |
| 726 | 723 | |
| @@ -741,6 +738,10 @@ unlock: · 14 unmodified lines | ||
| 741 | 738 | /* from intel_th_msc_window_unlock(), don't warn if not locked */ |
| 742 | 739 | if (expect == WIN_LOCKED && old == new) |
| 743 | 740 | return 0; |
| 741 | + | |
| 742 | + dev_warn_ratelimited(msc_dev(win->msc), | |
| 743 | + "expected lockout state %d, got %d\n", | |
| 744 | + expect, old); | |
| 744 | 745 | } |
| 745 | 746 | |
| 746 | 747 | return ret; |
| @@ -760,7 +761,7 @@ static int msc_configure(struct msc *msc) · 13 unmodified lines | ||
| 760 | 761 | lockdep_assert_held(&msc->buf_mutex); |
| 761 | 762 | |
| 762 | 763 | if (msc->mode > MSC_MODE_MULTI) |
| 763 | − return -ENOTSUPP; | |
| 764 | + return -EINVAL; | |
| 764 | 765 | |
| 765 | 766 | if (msc->mode == MSC_MODE_MULTI) { |
| 766 | 767 | if (msc_win_set_lockout(msc->cur_win, WIN_READY, WIN_INUSE)) |
| @@ -1294,7 +1295,7 @@ static int msc_buffer_alloc(struct msc *msc, unsigned long *nr_pages, · 527 unmodified lines | ||
| 1294 | 1295 | } else if (msc->mode == MSC_MODE_MULTI) { |
| 1295 | 1296 | ret = msc_buffer_multi_alloc(msc, nr_pages, nr_wins); |
| 1296 | 1297 | } else { |
| 1297 | − ret = -ENOTSUPP; | |
| 1298 | + ret = -EINVAL; | |
| 1298 | 1299 | } |
| 1299 | 1300 | |
| 1300 | 1301 | if (!ret) { |
| @@ -1530,7 +1531,7 @@ static ssize_t intel_th_msc_read(struct file *file, char __user *buf, · 229 unmodified lines | ||
| 1530 | 1531 | if (ret >= 0) |
| 1531 | 1532 | *ppos = iter->offset; |
| 1532 | 1533 | } else { |
| 1533 | − ret = -ENOTSUPP; | |
| 1534 | + ret = -EINVAL; | |
| 1534 | 1535 | } |
| 1535 | 1536 | |
| 1536 | 1537 | put_count: |
| @@ -234,6 +234,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = { · 233 unmodified lines | ||
| 234 | 234 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6), |
| 235 | 235 | .driver_data = (kernel_ulong_t)&intel_th_2x, |
| 236 | 236 | }, |
| 237 | + { | |
| 238 | + /* Elkhart Lake CPU */ | |
| 239 | + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529), | |
| 240 | + .driver_data = (kernel_ulong_t)&intel_th_2x, | |
| 241 | + }, | |
| 237 | 242 | { |
| 238 | 243 | /* Elkhart Lake */ |
| 239 | 244 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26), |
| @@ -238,7 +238,7 @@ static struct configfs_attribute *sys_t_policy_attrs[] = { · 237 unmodified lines | ||
| 238 | 238 | static inline bool sys_t_need_ts(struct sys_t_output *op) |
| 239 | 239 | { |
| 240 | 240 | if (op->node.ts_interval && |
| 241 | − time_after(op->ts_jiffies + op->node.ts_interval, jiffies)) { | |
| 241 | + time_after(jiffies, op->ts_jiffies + op->node.ts_interval)) { | |
| 242 | 242 | op->ts_jiffies = jiffies; |
| 243 | 243 | |
| 244 | 244 | return true; |
| @@ -250,8 +250,8 @@ static inline bool sys_t_need_ts(struct sys_t_output *op) · 5 unmodified lines | ||
| 250 | 250 | static bool sys_t_need_clock_sync(struct sys_t_output *op) |
| 251 | 251 | { |
| 252 | 252 | if (op->node.clocksync_interval && |
| 253 | − time_after(op->clocksync_jiffies + op->node.clocksync_interval, | |
| 254 | − jiffies)) { | |
| 253 | + time_after(jiffies, | |
| 254 | + op->clocksync_jiffies + op->node.clocksync_interval)) { | |
| 255 | 255 | op->clocksync_jiffies = jiffies; |
| 256 | 256 | |
| 257 | 257 | return true; |
| @@ -171,7 +171,7 @@ static void altr_i2c_init(struct altr_i2c_dev *idev) · 170 unmodified lines | ||
| 171 | 171 | /* SCL Low Time */ |
| 172 | 172 | writel(t_low, idev->base + ALTR_I2C_SCL_LOW); |
| 173 | 173 | /* SDA Hold Time, 300ns */ |
| 174 | − writel(div_u64(300 * clk_mhz, 1000), idev->base + ALTR_I2C_SDA_HOLD); | |
| 174 | + writel(3 * clk_mhz / 10, idev->base + ALTR_I2C_SDA_HOLD); | |
| 175 | 175 | |
| 176 | 176 | /* Mask all master interrupt bits */ |
| 177 | 177 | altr_i2c_int_enable(idev, ALTR_I2C_ALL_IRQ, false); |
| @@ -313,6 +313,7 @@ static void i2c_dw_pci_remove(struct pci_dev *pdev) · 312 unmodified lines | ||
| 313 | 313 | pm_runtime_get_noresume(&pdev->dev); |
| 314 | 314 | |
| 315 | 315 | i2c_del_adapter(&dev->adapter); |
| 316 | + devm_free_irq(&pdev->dev, dev->irq, dev); | |
| 316 | 317 | pci_free_irq_vectors(pdev); |
| 317 | 318 | } |
| 318 | 319 | |
| @@ -348,7 +348,7 @@ static struct gpio_desc *i2c_gpio_get_desc(struct device *dev, · 347 unmodified lines | ||
| 348 | 348 | if (ret == -ENOENT) |
| 349 | 349 | retdesc = ERR_PTR(-EPROBE_DEFER); |
| 350 | 350 | |
| 351 | − if (ret != -EPROBE_DEFER) | |
| 351 | + if (PTR_ERR(retdesc) != -EPROBE_DEFER) | |
| 352 | 352 | dev_err(dev, "error trying to get descriptor: %d\n", ret); |
| 353 | 353 | |
| 354 | 354 | return retdesc; |
| @@ -132,11 +132,6 @@ · 131 unmodified lines | ||
| 132 | 132 | #define TCOBASE 0x050 |
| 133 | 133 | #define TCOCTL 0x054 |
| 134 | 134 | |
| 135 | −#define ACPIBASE 0x040 | |
| 136 | −#define ACPIBASE_SMI_OFF 0x030 | |
| 137 | −#define ACPICTRL 0x044 | |
| 138 | −#define ACPICTRL_EN 0x080 | |
| 139 | − | |
| 140 | 135 | #define SBREG_BAR 0x10 |
| 141 | 136 | #define SBREG_SMBCTRL 0xc6000c |
| 142 | 137 | #define SBREG_SMBCTRL_DNV 0xcf000c |
| @@ -1553,7 +1548,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev, · 1410 unmodified lines | ||
| 1553 | 1548 | pci_bus_write_config_byte(pci_dev->bus, devfn, 0xe1, hidden); |
| 1554 | 1549 | spin_unlock(&p2sb_spinlock); |
| 1555 | 1550 | |
| 1556 | − res = &tco_res[ICH_RES_MEM_OFF]; | |
| 1551 | + res = &tco_res[1]; | |
| 1557 | 1552 | if (pci_dev->device == PCI_DEVICE_ID_INTEL_DNV_SMBUS) |
| 1558 | 1553 | res->start = (resource_size_t)base64_addr + SBREG_SMBCTRL_DNV; |
| 1559 | 1554 | else |
| @@ -1563,7 +1558,7 @@ i801_add_tco_spt(struct i801_priv *priv, struct pci_dev *pci_dev, · 3 unmodified lines | ||
| 1563 | 1558 | res->flags = IORESOURCE_MEM; |
| 1564 | 1559 | |
| 1565 | 1560 | return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, |
| 1566 | − tco_res, 3, &spt_tco_platform_data, | |
| 1561 | + tco_res, 2, &spt_tco_platform_data, | |
| 1567 | 1562 | sizeof(spt_tco_platform_data)); |
| 1568 | 1563 | } |
| 1569 | 1564 | |
| @@ -1576,17 +1571,16 @@ static struct platform_device * · 6 unmodified lines | ||
| 1576 | 1571 | i801_add_tco_cnl(struct i801_priv *priv, struct pci_dev *pci_dev, |
| 1577 | 1572 | struct resource *tco_res) |
| 1578 | 1573 | { |
| 1579 | − return platform_device_register_resndata(&pci_dev->dev, "iTCO_wdt", -1, | |
| 1580 | − tco_res, 2, &cnl_tco_platform_data, | |
| 1581 | − sizeof(cnl_tco_platform_data)); | |
| 1574 | + return platform_device_register_resndata(&pci_dev->dev, | |
| 1575 | + "iTCO_wdt", -1, tco_res, 1, &cnl_tco_platform_data, | |
| 1576 | + sizeof(cnl_tco_platform_data)); | |
| 1582 | 1577 | } |
| 1583 | 1578 | |
| 1584 | 1579 | static void i801_add_tco(struct i801_priv *priv) |
| 1585 | 1580 | { |
| 1586 | − u32 base_addr, tco_base, tco_ctl, ctrl_val; | |
| 1587 | 1581 | struct pci_dev *pci_dev = priv->pci_dev; |
| 1588 | − struct resource tco_res[3], *res; | |
| 1589 | − unsigned int devfn; | |
| 1582 | + struct resource tco_res[2], *res; | |
| 1583 | + u32 tco_base, tco_ctl; | |
| 1590 | 1584 | |
| 1591 | 1585 | /* If we have ACPI based watchdog use that instead */ |
| 1592 | 1586 | if (acpi_has_watchdog()) |
| @@ -1601,30 +1595,15 @@ static void i801_add_tco(struct i801_priv *priv) · 8 unmodified lines | ||
| 1601 | 1595 | return; |
| 1602 | 1596 | |
| 1603 | 1597 | memset(tco_res, 0, sizeof(tco_res)); |
| 1604 | − | |
| 1605 | − res = &tco_res[ICH_RES_IO_TCO]; | |
| 1606 | − res->start = tco_base & ~1; | |
| 1607 | − res->end = res->start + 32 - 1; | |
| 1608 | − res->flags = IORESOURCE_IO; | |
| 1609 | − | |
| 1610 | 1598 | /* |
| 1611 | − * Power Management registers. | |
| 1599 | + * Always populate the main iTCO IO resource here. The second entry | |
| 1600 | + * for NO_REBOOT MMIO is filled by the SPT specific function. | |
| 1612 | 1601 | */ |
| 1613 | − devfn = PCI_DEVFN(PCI_SLOT(pci_dev->devfn), 2); | |
| 1614 | − pci_bus_read_config_dword(pci_dev->bus, devfn, ACPIBASE, &base_addr); | |
| 1615 | − | |
| 1616 | − res = &tco_res[ICH_RES_IO_SMI]; | |
| 1617 | − res->start = (base_addr & ~1) + ACPIBASE_SMI_OFF; | |
| 1618 | − res->end = res->start + 3; | |
| 1602 | + res = &tco_res[0]; | |
| 1603 | + res->start = tco_base & ~1; | |
| 1604 | + res->end = res->start + 32 - 1; | |
| 1619 | 1605 | res->flags = IORESOURCE_IO; |
| 1620 | 1606 | |
| 1621 | − /* | |
| 1622 | − * Enable the ACPI I/O space. | |
| 1623 | − */ | |
| 1624 | − pci_bus_read_config_dword(pci_dev->bus, devfn, ACPICTRL, &ctrl_val); | |
| 1625 | − ctrl_val |= ACPICTRL_EN; | |
| 1626 | − pci_bus_write_config_dword(pci_dev->bus, devfn, ACPICTRL, ctrl_val); | |
| 1627 | − | |
| 1628 | 1607 | if (priv->features & FEATURE_TCO_CNL) |
| 1629 | 1608 | priv->tco_pdev = i801_add_tco_cnl(priv, pci_dev, tco_res); |
| 1630 | 1609 | else |
| @@ -78,25 +78,6 @@ · 77 unmodified lines | ||
| 78 | 78 | |
| 79 | 79 | #define X1000_I2C_DC_STOP BIT(9) |
| 80 | 80 | |
| 81 | −static const char * const jz4780_i2c_abrt_src[] = { | |
| 82 | − "ABRT_7B_ADDR_NOACK", | |
| 83 | − "ABRT_10ADDR1_NOACK", | |
| 84 | − "ABRT_10ADDR2_NOACK", | |
| 85 | − "ABRT_XDATA_NOACK", | |
| 86 | − "ABRT_GCALL_NOACK", | |
| 87 | − "ABRT_GCALL_READ", | |
| 88 | − "ABRT_HS_ACKD", | |
| 89 | − "SBYTE_ACKDET", | |
| 90 | − "ABRT_HS_NORSTRT", | |
| 91 | − "SBYTE_NORSTRT", | |
| 92 | − "ABRT_10B_RD_NORSTRT", | |
| 93 | − "ABRT_MASTER_DIS", | |
| 94 | − "ARB_LOST", | |
| 95 | − "SLVFLUSH_TXFIFO", | |
| 96 | − "SLV_ARBLOST", | |
| 97 | − "SLVRD_INTX", | |
| 98 | −}; | |
| 99 | − | |
| 100 | 81 | #define JZ4780_I2C_INTST_IGC BIT(11) |
| 101 | 82 | #define JZ4780_I2C_INTST_ISTT BIT(10) |
| 102 | 83 | #define JZ4780_I2C_INTST_ISTP BIT(9) |
| @@ -576,21 +557,8 @@ done: · 473 unmodified lines | ||
| 576 | 557 | |
| 577 | 558 | static void jz4780_i2c_txabrt(struct jz4780_i2c *i2c, int src) |
| 578 | 559 | { |
| 579 | − int i; | |
| 580 | − | |
| 581 | − dev_err(&i2c->adap.dev, "txabrt: 0x%08x\n", src); | |
| 582 | − dev_err(&i2c->adap.dev, "device addr=%x\n", | |
| 583 | − jz4780_i2c_readw(i2c, JZ4780_I2C_TAR)); | |
| 584 | − dev_err(&i2c->adap.dev, "send cmd count:%d %d\n", | |
| 585 | − i2c->cmd, i2c->cmd_buf[i2c->cmd]); | |
| 586 | − dev_err(&i2c->adap.dev, "receive data count:%d %d\n", | |
| 587 | − i2c->cmd, i2c->data_buf[i2c->cmd]); | |
| 588 | − | |
| 589 | − for (i = 0; i < 16; i++) { | |
| 590 | − if (src & BIT(i)) | |
| 591 | − dev_dbg(&i2c->adap.dev, "I2C TXABRT[%d]=%s\n", | |
| 592 | − i, jz4780_i2c_abrt_src[i]); | |
| 593 | − } | |
| 560 | + dev_dbg(&i2c->adap.dev, "txabrt: 0x%08x, cmd: %d, send: %d, recv: %d\n", | |
| 561 | + src, i2c->cmd, i2c->cmd_buf[i2c->cmd], i2c->data_buf[i2c->cmd]); | |
| 594 | 562 | } |
| 595 | 563 | |
| 596 | 564 | static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c, |
| @@ -394,9 +394,17 @@ EXPORT_SYMBOL_GPL(i2c_acpi_find_adapter_by_handle); · 393 unmodified lines | ||
| 394 | 394 | static struct i2c_client *i2c_acpi_find_client_by_adev(struct acpi_device *adev) |
| 395 | 395 | { |
| 396 | 396 | struct device *dev; |
| 397 | + struct i2c_client *client; | |
| 397 | 398 | |
| 398 | 399 | dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev); |
| 399 | − return dev ? i2c_verify_client(dev) : NULL; | |
| 400 | + if (!dev) | |
| 401 | + return NULL; | |
| 402 | + | |
| 403 | + client = i2c_verify_client(dev); | |
| 404 | + if (!client) | |
| 405 | + put_device(dev); | |
| 406 | + | |
| 407 | + return client; | |
| 400 | 408 | } |
| 401 | 409 | |
| 402 | 410 | static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, |
| @@ -361,7 +361,7 @@ static const struct block_device_operations ide_gd_ops = { · 360 unmodified lines | ||
| 361 | 361 | .release = ide_gd_release, |
| 362 | 362 | .ioctl = ide_gd_ioctl, |
| 363 | 363 | #ifdef CONFIG_COMPAT |
| 364 | − .ioctl = ide_gd_compat_ioctl, | |
| 364 | + .compat_ioctl = ide_gd_compat_ioctl, | |
| 365 | 365 | #endif |
| 366 | 366 | .getgeo = ide_gd_getgeo, |
| 367 | 367 | .check_events = ide_gd_check_events, |
| @@ -237,6 +237,7 @@ static const struct adxl372_axis_lookup adxl372_axis_lookup_table[] = { · 236 unmodified lines | ||
| 237 | 237 | .realbits = 12, \ |
| 238 | 238 | .storagebits = 16, \ |
| 239 | 239 | .shift = 4, \ |
| 240 | + .endianness = IIO_BE, \ | |
| 240 | 241 | }, \ |
| 241 | 242 | } |
| 242 | 243 | |
| @@ -110,7 +110,7 @@ MODULE_DEVICE_TABLE(of, st_accel_of_match); · 109 unmodified lines | ||
| 110 | 110 | |
| 111 | 111 | #ifdef CONFIG_ACPI |
| 112 | 112 | static const struct acpi_device_id st_accel_acpi_match[] = { |
| 113 | − {"SMO8840", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME}, | |
| 113 | + {"SMO8840", (kernel_ulong_t)LIS2DH12_ACCEL_DEV_NAME}, | |
| 114 | 114 | {"SMO8A90", (kernel_ulong_t)LNG2DM_ACCEL_DEV_NAME}, |
| 115 | 115 | { }, |
| 116 | 116 | }; |
| @@ -723,6 +723,7 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) · 722 unmodified lines | ||
| 723 | 723 | |
| 724 | 724 | for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) { |
| 725 | 725 | struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit); |
| 726 | + u32 cor; | |
| 726 | 727 | |
| 727 | 728 | if (!chan) |
| 728 | 729 | continue; |
| @@ -731,6 +732,20 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) · 2 unmodified lines | ||
| 731 | 732 | chan->type == IIO_PRESSURE) |
| 732 | 733 | continue; |
| 733 | 734 | |
| 735 | + if (state) { | |
| 736 | + cor = at91_adc_readl(st, AT91_SAMA5D2_COR); | |
| 737 | + | |
| 738 | + if (chan->differential) | |
| 739 | + cor |= (BIT(chan->channel) | | |
| 740 | + BIT(chan->channel2)) << | |
| 741 | + AT91_SAMA5D2_COR_DIFF_OFFSET; | |
| 742 | + else | |
| 743 | + cor &= ~(BIT(chan->channel) << | |
| 744 | + AT91_SAMA5D2_COR_DIFF_OFFSET); | |
| 745 | + | |
| 746 | + at91_adc_writel(st, AT91_SAMA5D2_COR, cor); | |
| 747 | + } | |
| 748 | + | |
| 734 | 749 | if (state) { |
| 735 | 750 | at91_adc_writel(st, AT91_SAMA5D2_CHER, |
| 736 | 751 | BIT(chan->channel)); |
| @@ -842,31 +842,6 @@ static inline void stm32_dfsdm_process_data(struct stm32_dfsdm_adc *adc, · 841 unmodified lines | ||
| 842 | 842 | } |
| 843 | 843 | } |
| 844 | 844 | |
| 845 | −static irqreturn_t stm32_dfsdm_adc_trigger_handler(int irq, void *p) | |
| 846 | −{ | |
| 847 | − struct iio_poll_func *pf = p; | |
| 848 | − struct iio_dev *indio_dev = pf->indio_dev; | |
| 849 | − struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | |
| 850 | − int available = stm32_dfsdm_adc_dma_residue(adc); | |
| 851 | − | |
| 852 | − while (available >= indio_dev->scan_bytes) { | |
| 853 | − s32 *buffer = (s32 *)&adc->rx_buf[adc->bufi]; | |
| 854 | − | |
| 855 | − stm32_dfsdm_process_data(adc, buffer); | |
| 856 | − | |
| 857 | − iio_push_to_buffers_with_timestamp(indio_dev, buffer, | |
| 858 | − pf->timestamp); | |
| 859 | − available -= indio_dev->scan_bytes; | |
| 860 | − adc->bufi += indio_dev->scan_bytes; | |
| 861 | − if (adc->bufi >= adc->buf_sz) | |
| 862 | − adc->bufi = 0; | |
| 863 | − } | |
| 864 | − | |
| 865 | − iio_trigger_notify_done(indio_dev->trig); | |
| 866 | − | |
| 867 | − return IRQ_HANDLED; | |
| 868 | −} | |
| 869 | − | |
| 870 | 845 | static void stm32_dfsdm_dma_buffer_done(void *data) |
| 871 | 846 | { |
| 872 | 847 | struct iio_dev *indio_dev = data; |
| @@ -874,11 +849,6 @@ static void stm32_dfsdm_dma_buffer_done(void *data) · 1 unmodified line | ||
| 874 | 849 | int available = stm32_dfsdm_adc_dma_residue(adc); |
| 875 | 850 | size_t old_pos; |
| 876 | 851 | |
| 877 | − if (indio_dev->currentmode & INDIO_BUFFER_TRIGGERED) { | |
| 878 | − iio_trigger_poll_chained(indio_dev->trig); | |
| 879 | − return; | |
| 880 | − } | |
| 881 | − | |
| 882 | 852 | /* |
| 883 | 853 | * FIXME: In Kernel interface does not support cyclic DMA buffer,and |
| 884 | 854 | * offers only an interface to push data samples per samples. |
| @@ -906,7 +876,15 @@ static void stm32_dfsdm_dma_buffer_done(void *data) · 21 unmodified lines | ||
| 906 | 876 | adc->bufi = 0; |
| 907 | 877 | old_pos = 0; |
| 908 | 878 | } |
| 909 | − /* regular iio buffer without trigger */ | |
| 879 | + /* | |
| 880 | + * In DMA mode the trigger services of IIO are not used | |
| 881 | + * (e.g. no call to iio_trigger_poll). | |
| 882 | + * Calling irq handler associated to the hardware trigger is not | |
| 883 | + * relevant as the conversions have already been done. Data | |
| 884 | + * transfers are performed directly in DMA callback instead. | |
| 885 | + * This implementation avoids to call trigger irq handler that | |
| 886 | + * may sleep, in an atomic context (DMA irq handler context). | |
| 887 | + */ | |
| 910 | 888 | if (adc->dev_data->type == DFSDM_IIO) |
| 911 | 889 | iio_push_to_buffers(indio_dev, buffer); |
| 912 | 890 | } |
| @@ -1536,8 +1514,7 @@ static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev) · 623 unmodified lines | ||
| 1536 | 1514 | } |
| 1537 | 1515 | |
| 1538 | 1516 | ret = iio_triggered_buffer_setup(indio_dev, |
| 1539 | − &iio_pollfunc_store_time, | |
| 1540 | − &stm32_dfsdm_adc_trigger_handler, | |
| 1517 | + &iio_pollfunc_store_time, NULL, | |
| 1541 | 1518 | &stm32_dfsdm_buffer_setup_ops); |
| 1542 | 1519 | if (ret) { |
| 1543 | 1520 | stm32_dfsdm_dma_release(indio_dev); |
| @@ -91,6 +91,8 @@ config SPS30 · 90 unmodified lines | ||
| 91 | 91 | tristate "SPS30 particulate matter sensor" |
| 92 | 92 | depends on I2C |
| 93 | 93 | select CRC8 |
| 94 | + select IIO_BUFFER | |
| 95 | + select IIO_TRIGGERED_BUFFER | |
| 94 | 96 | help |
| 95 | 97 | Say Y here to build support for the Sensirion SPS30 particulate |
| 96 | 98 | matter sensor. |
| @@ -167,16 +167,17 @@ static int vcnl4200_init(struct vcnl4000_data *data) · 166 unmodified lines | ||
| 167 | 167 | data->vcnl4200_ps.reg = VCNL4200_PS_DATA; |
| 168 | 168 | switch (id) { |
| 169 | 169 | case VCNL4200_PROD_ID: |
| 170 | − /* Integration time is 50ms, but the experiments */ | |
| 171 | − /* show 54ms in total. */ | |
| 172 | − data->vcnl4200_al.sampling_rate = ktime_set(0, 54000 * 1000); | |
| 173 | − data->vcnl4200_ps.sampling_rate = ktime_set(0, 4200 * 1000); | |
| 170 | + /* Default wait time is 50ms, add 20% tolerance. */ | |
| 171 | + data->vcnl4200_al.sampling_rate = ktime_set(0, 60000 * 1000); | |
| 172 | + /* Default wait time is 4.8ms, add 20% tolerance. */ | |
| 173 | + data->vcnl4200_ps.sampling_rate = ktime_set(0, 5760 * 1000); | |
| 174 | 174 | data->al_scale = 24000; |
| 175 | 175 | break; |
| 176 | 176 | case VCNL4040_PROD_ID: |
| 177 | − /* Integration time is 80ms, add 10ms. */ | |
| 178 | − data->vcnl4200_al.sampling_rate = ktime_set(0, 100000 * 1000); | |
| 179 | − data->vcnl4200_ps.sampling_rate = ktime_set(0, 100000 * 1000); | |
| 177 | + /* Default wait time is 80ms, add 20% tolerance. */ | |
| 178 | + data->vcnl4200_al.sampling_rate = ktime_set(0, 96000 * 1000); | |
| 179 | + /* Default wait time is 5ms, add 20% tolerance. */ | |
| 180 | + data->vcnl4200_ps.sampling_rate = ktime_set(0, 6000 * 1000); | |
| 180 | 181 | data->al_scale = 120000; |
| 181 | 182 | break; |
| 182 | 183 | } |
| @@ -564,7 +564,7 @@ static int ak8974_read_raw(struct iio_dev *indio_dev, · 563 unmodified lines | ||
| 564 | 564 | * We read all axes and discard all but one, for optimized |
| 565 | 565 | * reading, use the triggered buffer. |
| 566 | 566 | */ |
| 567 | − *val = le16_to_cpu(hw_values[chan->address]); | |
| 567 | + *val = (s16)le16_to_cpu(hw_values[chan->address]); | |
| 568 | 568 | |
| 569 | 569 | ret = IIO_VAL_INT; |
| 570 | 570 | } |
| @@ -269,7 +269,7 @@ static const struct iio_chan_spec ping_chan_spec[] = { · 268 unmodified lines | ||
| 269 | 269 | |
| 270 | 270 | static const struct of_device_id of_ping_match[] = { |
| 271 | 271 | { .compatible = "parallax,ping", .data = &pa_ping_cfg}, |
| 272 | − { .compatible = "parallax,laserping", .data = &pa_ping_cfg}, | |
| 272 | + { .compatible = "parallax,laserping", .data = &pa_laser_ping_cfg}, | |
| 273 | 273 | {}, |
| 274 | 274 | }; |
| 275 | 275 | |
| @@ -161,7 +161,8 @@ static int stm32_timer_start(struct stm32_timer_trigger *priv, · 160 unmodified lines | ||
| 161 | 161 | return 0; |
| 162 | 162 | } |
| 163 | 163 | |
| 164 | −static void stm32_timer_stop(struct stm32_timer_trigger *priv) | |
| 164 | +static void stm32_timer_stop(struct stm32_timer_trigger *priv, | |
| 165 | + struct iio_trigger *trig) | |
| 165 | 166 | { |
| 166 | 167 | u32 ccer, cr1; |
| 167 | 168 | |
| @@ -179,6 +180,12 @@ static void stm32_timer_stop(struct stm32_timer_trigger *priv) · 11 unmodified lines | ||
| 179 | 180 | regmap_write(priv->regmap, TIM_PSC, 0); |
| 180 | 181 | regmap_write(priv->regmap, TIM_ARR, 0); |
| 181 | 182 | |
| 183 | + /* Force disable master mode */ | |
| 184 | + if (stm32_timer_is_trgo2_name(trig->name)) | |
| 185 | + regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS2, 0); | |
| 186 | + else | |
| 187 | + regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0); | |
| 188 | + | |
| 182 | 189 | /* Make sure that registers are updated */ |
| 183 | 190 | regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); |
| 184 | 191 | } |
| @@ -197,7 +204,7 @@ static ssize_t stm32_tt_store_frequency(struct device *dev, · 12 unmodified lines | ||
| 197 | 204 | return ret; |
| 198 | 205 | |
| 199 | 206 | if (freq == 0) { |
| 200 | − stm32_timer_stop(priv); | |
| 207 | + stm32_timer_stop(priv, trig); | |
| 201 | 208 | } else { |
| 202 | 209 | ret = stm32_timer_start(priv, trig, freq); |
| 203 | 210 | if (ret) |
| @@ -1191,6 +1191,7 @@ struct ib_cm_id *ib_cm_insert_listen(struct ib_device *device, · 1190 unmodified lines | ||
| 1191 | 1191 | /* Sharing an ib_cm_id with different handlers is not |
| 1192 | 1192 | * supported */ |
| 1193 | 1193 | spin_unlock_irqrestore(&cm.lock, flags); |
| 1194 | + ib_destroy_cm_id(cm_id); | |
| 1194 | 1195 | return ERR_PTR(-EINVAL); |
| 1195 | 1196 | } |
| 1196 | 1197 | refcount_inc(&cm_id_priv->refcount); |
| @@ -3212,19 +3212,26 @@ int rdma_resolve_addr(struct rdma_cm_id *id, struct sockaddr *src_addr, · 3211 unmodified lines | ||
| 3212 | 3212 | int ret; |
| 3213 | 3213 | |
| 3214 | 3214 | id_priv = container_of(id, struct rdma_id_private, id); |
| 3215 | + memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); | |
| 3215 | 3216 | if (id_priv->state == RDMA_CM_IDLE) { |
| 3216 | 3217 | ret = cma_bind_addr(id, src_addr, dst_addr); |
| 3217 | − if (ret) | |
| 3218 | + if (ret) { | |
| 3219 | + memset(cma_dst_addr(id_priv), 0, | |
| 3220 | + rdma_addr_size(dst_addr)); | |
| 3218 | 3221 | return ret; |
| 3222 | + } | |
| 3219 | 3223 | } |
| 3220 | 3224 | |
| 3221 | − if (cma_family(id_priv) != dst_addr->sa_family) | |
| 3225 | + if (cma_family(id_priv) != dst_addr->sa_family) { | |
| 3226 | + memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); | |
| 3222 | 3227 | return -EINVAL; |
| 3228 | + } | |
| 3223 | 3229 | |
| 3224 | − if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) | |
| 3230 | + if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY)) { | |
| 3231 | + memset(cma_dst_addr(id_priv), 0, rdma_addr_size(dst_addr)); | |
| 3225 | 3232 | return -EINVAL; |
| 3233 | + } | |
| 3226 | 3234 | |
| 3227 | − memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); | |
| 3228 | 3235 | if (cma_any_addr(dst_addr)) { |
| 3229 | 3236 | ret = cma_resolve_loopback(id_priv); |
| 3230 | 3237 | } else { |
| @@ -338,6 +338,20 @@ static inline struct ib_qp *_ib_create_qp(struct ib_device *dev, · 337 unmodified lines | ||
| 338 | 338 | qp->pd = pd; |
| 339 | 339 | qp->uobject = uobj; |
| 340 | 340 | qp->real_qp = qp; |
| 341 | + | |
| 342 | + qp->qp_type = attr->qp_type; | |
| 343 | + qp->rwq_ind_tbl = attr->rwq_ind_tbl; | |
| 344 | + qp->send_cq = attr->send_cq; | |
| 345 | + qp->recv_cq = attr->recv_cq; | |
| 346 | + qp->srq = attr->srq; | |
| 347 | + qp->rwq_ind_tbl = attr->rwq_ind_tbl; | |
| 348 | + qp->event_handler = attr->event_handler; | |
| 349 | + | |
| 350 | + atomic_set(&qp->usecnt, 0); | |
| 351 | + spin_lock_init(&qp->mr_lock); | |
| 352 | + INIT_LIST_HEAD(&qp->rdma_mrs); | |
| 353 | + INIT_LIST_HEAD(&qp->sig_mrs); | |
| 354 | + | |
| 341 | 355 | /* |
| 342 | 356 | * We don't track XRC QPs for now, because they don't have PD |
| 343 | 357 | * and more importantly they are created internaly by driver, |
| @@ -159,8 +159,10 @@ static void dealloc_work_entries(struct iwcm_id_private *cm_id_priv) · 158 unmodified lines | ||
| 159 | 159 | { |
| 160 | 160 | struct list_head *e, *tmp; |
| 161 | 161 | |
| 162 | − list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) | |
| 162 | + list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) { | |
| 163 | + list_del(e); | |
| 163 | 164 | kfree(list_entry(e, struct iwcm_work, free_list)); |
| 165 | + } | |
| 164 | 166 | } |
| 165 | 167 | |
| 166 | 168 | static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count) |
| @@ -1757,6 +1757,8 @@ static int nldev_stat_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 1756 unmodified lines | ||
| 1757 | 1757 | if (ret) |
| 1758 | 1758 | goto err_msg; |
| 1759 | 1759 | } else { |
| 1760 | + if (!tb[RDMA_NLDEV_ATTR_RES_LQPN]) | |
| 1761 | + goto err_msg; | |
| 1760 | 1762 | qpn = nla_get_u32(tb[RDMA_NLDEV_ATTR_RES_LQPN]); |
| 1761 | 1763 | if (tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]) { |
| 1762 | 1764 | cntn = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]); |
| @@ -273,6 +273,23 @@ static int rdma_rw_init_single_wr(struct rdma_rw_ctx *ctx, struct ib_qp *qp, · 272 unmodified lines | ||
| 273 | 273 | return 1; |
| 274 | 274 | } |
| 275 | 275 | |
| 276 | +static void rdma_rw_unmap_sg(struct ib_device *dev, struct scatterlist *sg, | |
| 277 | + u32 sg_cnt, enum dma_data_direction dir) | |
| 278 | +{ | |
| 279 | + if (is_pci_p2pdma_page(sg_page(sg))) | |
| 280 | + pci_p2pdma_unmap_sg(dev->dma_device, sg, sg_cnt, dir); | |
| 281 | + else | |
| 282 | + ib_dma_unmap_sg(dev, sg, sg_cnt, dir); | |
| 283 | +} | |
| 284 | + | |
| 285 | +static int rdma_rw_map_sg(struct ib_device *dev, struct scatterlist *sg, | |
| 286 | + u32 sg_cnt, enum dma_data_direction dir) | |
| 287 | +{ | |
| 288 | + if (is_pci_p2pdma_page(sg_page(sg))) | |
| 289 | + return pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir); | |
| 290 | + return ib_dma_map_sg(dev, sg, sg_cnt, dir); | |
| 291 | +} | |
| 292 | + | |
| 276 | 293 | /** |
| 277 | 294 | * rdma_rw_ctx_init - initialize a RDMA READ/WRITE context |
| 278 | 295 | * @ctx: context to initialize |
| @@ -295,11 +312,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num, · 16 unmodified lines | ||
| 295 | 312 | struct ib_device *dev = qp->pd->device; |
| 296 | 313 | int ret; |
| 297 | 314 | |
| 298 | − if (is_pci_p2pdma_page(sg_page(sg))) | |
| 299 | − ret = pci_p2pdma_map_sg(dev->dma_device, sg, sg_cnt, dir); | |
| 300 | − else | |
| 301 | − ret = ib_dma_map_sg(dev, sg, sg_cnt, dir); | |
| 302 | − | |
| 315 | + ret = rdma_rw_map_sg(dev, sg, sg_cnt, dir); | |
| 303 | 316 | if (!ret) |
| 304 | 317 | return -ENOMEM; |
| 305 | 318 | sg_cnt = ret; |
| @@ -338,7 +351,7 @@ int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num, · 32 unmodified lines | ||
| 338 | 351 | return ret; |
| 339 | 352 | |
| 340 | 353 | out_unmap_sg: |
| 341 | − ib_dma_unmap_sg(dev, sg, sg_cnt, dir); | |
| 354 | + rdma_rw_unmap_sg(dev, sg, sg_cnt, dir); | |
| 342 | 355 | return ret; |
| 343 | 356 | } |
| 344 | 357 | EXPORT_SYMBOL(rdma_rw_ctx_init); |
| @@ -588,11 +601,7 @@ void rdma_rw_ctx_destroy(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u8 port_num, · 243 unmodified lines | ||
| 588 | 601 | break; |
| 589 | 602 | } |
| 590 | 603 | |
| 591 | − if (is_pci_p2pdma_page(sg_page(sg))) | |
| 592 | − pci_p2pdma_unmap_sg(qp->pd->device->dma_device, sg, | |
| 593 | − sg_cnt, dir); | |
| 594 | − else | |
| 595 | − ib_dma_unmap_sg(qp->pd->device, sg, sg_cnt, dir); | |
| 604 | + rdma_rw_unmap_sg(qp->pd->device, sg, sg_cnt, dir); | |
| 596 | 605 | } |
| 597 | 606 | EXPORT_SYMBOL(rdma_rw_ctx_destroy); |
| 598 | 607 | |
| @@ -340,15 +340,19 @@ static struct ib_ports_pkeys *get_new_pps(const struct ib_qp *qp, · 339 unmodified lines | ||
| 340 | 340 | return NULL; |
| 341 | 341 | |
| 342 | 342 | if (qp_attr_mask & IB_QP_PORT) |
| 343 | − new_pps->main.port_num = | |
| 344 | − (qp_pps) ? qp_pps->main.port_num : qp_attr->port_num; | |
| 343 | + new_pps->main.port_num = qp_attr->port_num; | |
| 344 | + else if (qp_pps) | |
| 345 | + new_pps->main.port_num = qp_pps->main.port_num; | |
| 346 | + | |
| 345 | 347 | if (qp_attr_mask & IB_QP_PKEY_INDEX) |
| 346 | − new_pps->main.pkey_index = (qp_pps) ? qp_pps->main.pkey_index : | |
| 347 | − qp_attr->pkey_index; | |
| 348 | + new_pps->main.pkey_index = qp_attr->pkey_index; | |
| 349 | + else if (qp_pps) | |
| 350 | + new_pps->main.pkey_index = qp_pps->main.pkey_index; | |
| 351 | + | |
| 348 | 352 | if ((qp_attr_mask & IB_QP_PKEY_INDEX) && (qp_attr_mask & IB_QP_PORT)) |
| 349 | 353 | new_pps->main.state = IB_PORT_PKEY_VALID; |
| 350 | 354 | |
| 351 | − if (!(qp_attr_mask & (IB_QP_PKEY_INDEX || IB_QP_PORT)) && qp_pps) { | |
| 355 | + if (!(qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) && qp_pps) { | |
| 352 | 356 | new_pps->main.port_num = qp_pps->main.port_num; |
| 353 | 357 | new_pps->main.pkey_index = qp_pps->main.pkey_index; |
| 354 | 358 | if (qp_pps->main.state != IB_PORT_PKEY_NOT_VALID) |
| @@ -181,14 +181,28 @@ ib_umem_odp_alloc_child(struct ib_umem_odp *root, unsigned long addr, · 180 unmodified lines | ||
| 181 | 181 | odp_data->page_shift = PAGE_SHIFT; |
| 182 | 182 | odp_data->notifier.ops = ops; |
| 183 | 183 | |
| 184 | + /* | |
| 185 | + * A mmget must be held when registering a notifier, the owming_mm only | |
| 186 | + * has a mm_grab at this point. | |
| 187 | + */ | |
| 188 | + if (!mmget_not_zero(umem->owning_mm)) { | |
| 189 | + ret = -EFAULT; | |
| 190 | + goto out_free; | |
| 191 | + } | |
| 192 | + | |
| 184 | 193 | odp_data->tgid = get_pid(root->tgid); |
| 185 | 194 | ret = ib_init_umem_odp(odp_data, ops); |
| 186 | − if (ret) { | |
| 187 | − put_pid(odp_data->tgid); | |
| 188 | − kfree(odp_data); | |
| 189 | − return ERR_PTR(ret); | |
| 190 | − } | |
| 195 | + if (ret) | |
| 196 | + goto out_tgid; | |
| 197 | + mmput(umem->owning_mm); | |
| 191 | 198 | return odp_data; |
| 199 | + | |
| 200 | +out_tgid: | |
| 201 | + put_pid(odp_data->tgid); | |
| 202 | + mmput(umem->owning_mm); | |
| 203 | +out_free: | |
| 204 | + kfree(odp_data); | |
| 205 | + return ERR_PTR(ret); | |
| 192 | 206 | } |
| 193 | 207 | EXPORT_SYMBOL(ib_umem_odp_alloc_child); |
| 194 | 208 | |
| @@ -1445,16 +1445,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs, · 1444 unmodified lines | ||
| 1445 | 1445 | if (ret) |
| 1446 | 1446 | goto err_cb; |
| 1447 | 1447 | |
| 1448 | − qp->pd = pd; | |
| 1449 | − qp->send_cq = attr.send_cq; | |
| 1450 | − qp->recv_cq = attr.recv_cq; | |
| 1451 | − qp->srq = attr.srq; | |
| 1452 | − qp->rwq_ind_tbl = ind_tbl; | |
| 1453 | − qp->event_handler = attr.event_handler; | |
| 1454 | − qp->qp_type = attr.qp_type; | |
| 1455 | − atomic_set(&qp->usecnt, 0); | |
| 1456 | 1448 | atomic_inc(&pd->usecnt); |
| 1457 | − qp->port = 0; | |
| 1458 | 1449 | if (attr.send_cq) |
| 1459 | 1450 | atomic_inc(&attr.send_cq->usecnt); |
| 1460 | 1451 | if (attr.recv_cq) |
| @@ -1185,16 +1185,6 @@ struct ib_qp *ib_create_qp_user(struct ib_pd *pd, · 1184 unmodified lines | ||
| 1185 | 1185 | if (ret) |
| 1186 | 1186 | goto err; |
| 1187 | 1187 | |
| 1188 | − qp->qp_type = qp_init_attr->qp_type; | |
| 1189 | − qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl; | |
| 1190 | − | |
| 1191 | − atomic_set(&qp->usecnt, 0); | |
| 1192 | − qp->mrs_used = 0; | |
| 1193 | − spin_lock_init(&qp->mr_lock); | |
| 1194 | − INIT_LIST_HEAD(&qp->rdma_mrs); | |
| 1195 | − INIT_LIST_HEAD(&qp->sig_mrs); | |
| 1196 | − qp->port = 0; | |
| 1197 | − | |
| 1198 | 1188 | if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) { |
| 1199 | 1189 | struct ib_qp *xrc_qp = |
| 1200 | 1190 | create_xrc_qp_user(qp, qp_init_attr, udata); |
| @@ -515,10 +515,11 @@ static inline void hfi1_handle_packet(struct hfi1_packet *packet, · 514 unmodified lines | ||
| 515 | 515 | opa_get_lid(packet->dlid, 9B)); |
| 516 | 516 | if (!mcast) |
| 517 | 517 | goto drop; |
| 518 | + rcu_read_lock(); | |
| 518 | 519 | list_for_each_entry_rcu(p, &mcast->qp_list, list) { |
| 519 | 520 | packet->qp = p->qp; |
| 520 | 521 | if (hfi1_do_pkey_check(packet)) |
| 521 | − goto drop; | |
| 522 | + goto unlock_drop; | |
| 522 | 523 | spin_lock_irqsave(&packet->qp->r_lock, flags); |
| 523 | 524 | packet_handler = qp_ok(packet); |
| 524 | 525 | if (likely(packet_handler)) |
| @@ -527,6 +528,7 @@ static inline void hfi1_handle_packet(struct hfi1_packet *packet, · 2 unmodified lines | ||
| 527 | 528 | ibp->rvp.n_pkt_drops++; |
| 528 | 529 | spin_unlock_irqrestore(&packet->qp->r_lock, flags); |
| 529 | 530 | } |
| 531 | + rcu_read_unlock(); | |
| 530 | 532 | /* |
| 531 | 533 | * Notify rvt_multicast_detach() if it is waiting for us |
| 532 | 534 | * to finish. |
| @@ -636,6 +636,7 @@ struct mlx5_ib_mr { · 635 unmodified lines | ||
| 636 | 636 | |
| 637 | 637 | /* For ODP and implicit */ |
| 638 | 638 | atomic_t num_deferred_work; |
| 639 | + wait_queue_head_t q_deferred_work; | |
| 639 | 640 | struct xarray implicit_children; |
| 640 | 641 | union { |
| 641 | 642 | struct rcu_head rcu; |
| @@ -235,7 +235,8 @@ static void free_implicit_child_mr(struct mlx5_ib_mr *mr, bool need_imr_xlt) · 234 unmodified lines | ||
| 235 | 235 | mr->parent = NULL; |
| 236 | 236 | mlx5_mr_cache_free(mr->dev, mr); |
| 237 | 237 | ib_umem_odp_release(odp); |
| 238 | − atomic_dec(&imr->num_deferred_work); | |
| 238 | + if (atomic_dec_and_test(&imr->num_deferred_work)) | |
| 239 | + wake_up(&imr->q_deferred_work); | |
| 239 | 240 | } |
| 240 | 241 | |
| 241 | 242 | static void free_implicit_child_mr_work(struct work_struct *work) |
| @@ -554,6 +555,7 @@ struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd, · 312 unmodified lines | ||
| 554 | 555 | imr->umem = &umem_odp->umem; |
| 555 | 556 | imr->is_odp_implicit = true; |
| 556 | 557 | atomic_set(&imr->num_deferred_work, 0); |
| 558 | + init_waitqueue_head(&imr->q_deferred_work); | |
| 557 | 559 | xa_init(&imr->implicit_children); |
| 558 | 560 | |
| 559 | 561 | err = mlx5_ib_update_xlt(imr, 0, |
| @@ -611,10 +613,7 @@ void mlx5_ib_free_implicit_mr(struct mlx5_ib_mr *imr) · 51 unmodified lines | ||
| 611 | 613 | * under xa_lock while the child is in the xarray. Thus at this point |
| 612 | 614 | * it is only decreasing, and all work holding it is now on the wq. |
| 613 | 615 | */ |
| 614 | − if (atomic_read(&imr->num_deferred_work)) { | |
| 615 | − flush_workqueue(system_unbound_wq); | |
| 616 | − WARN_ON(atomic_read(&imr->num_deferred_work)); | |
| 617 | − } | |
| 616 | + wait_event(imr->q_deferred_work, !atomic_read(&imr->num_deferred_work)); | |
| 618 | 617 | |
| 619 | 618 | /* |
| 620 | 619 | * Fence the imr before we destroy the children. This allows us to |
| @@ -645,10 +644,7 @@ void mlx5_ib_fence_odp_mr(struct mlx5_ib_mr *mr) · 24 unmodified lines | ||
| 645 | 644 | /* Wait for all running page-fault handlers to finish. */ |
| 646 | 645 | synchronize_srcu(&mr->dev->odp_srcu); |
| 647 | 646 | |
| 648 | − if (atomic_read(&mr->num_deferred_work)) { | |
| 649 | − flush_workqueue(system_unbound_wq); | |
| 650 | − WARN_ON(atomic_read(&mr->num_deferred_work)); | |
| 651 | − } | |
| 647 | + wait_event(mr->q_deferred_work, !atomic_read(&mr->num_deferred_work)); | |
| 652 | 648 | |
| 653 | 649 | dma_fence_odp_mr(mr); |
| 654 | 650 | } |
| @@ -1720,7 +1716,8 @@ static void destroy_prefetch_work(struct prefetch_mr_work *work) · 1065 unmodified lines | ||
| 1720 | 1716 | u32 i; |
| 1721 | 1717 | |
| 1722 | 1718 | for (i = 0; i < work->num_sge; ++i) |
| 1723 | − atomic_dec(&work->frags[i].mr->num_deferred_work); | |
| 1719 | + if (atomic_dec_and_test(&work->frags[i].mr->num_deferred_work)) | |
| 1720 | + wake_up(&work->frags[i].mr->q_deferred_work); | |
| 1724 | 1721 | kvfree(work); |
| 1725 | 1722 | } |
| 1726 | 1723 | |
| @@ -329,8 +329,10 @@ void qib_ib_rcv(struct qib_ctxtdata *rcd, void *rhdr, void *data, u32 tlen) · 328 unmodified lines | ||
| 329 | 329 | if (mcast == NULL) |
| 330 | 330 | goto drop; |
| 331 | 331 | this_cpu_inc(ibp->pmastats->n_multicast_rcv); |
| 332 | + rcu_read_lock(); | |
| 332 | 333 | list_for_each_entry_rcu(p, &mcast->qp_list, list) |
| 333 | 334 | qib_qp_rcv(rcd, hdr, 1, data, tlen, p->qp); |
| 335 | + rcu_read_unlock(); | |
| 334 | 336 | /* |
| 335 | 337 | * Notify rvt_multicast_detach() if it is waiting for us |
| 336 | 338 | * to finish. |
| @@ -388,6 +388,9 @@ static struct siw_device *siw_device_create(struct net_device *netdev) · 387 unmodified lines | ||
| 388 | 388 | { .max_segment_size = SZ_2G }; |
| 389 | 389 | base_dev->num_comp_vectors = num_possible_cpus(); |
| 390 | 390 | |
| 391 | + xa_init_flags(&sdev->qp_xa, XA_FLAGS_ALLOC1); | |
| 392 | + xa_init_flags(&sdev->mem_xa, XA_FLAGS_ALLOC1); | |
| 393 | + | |
| 391 | 394 | ib_set_device_ops(base_dev, &siw_device_ops); |
| 392 | 395 | rv = ib_device_set_netdev(base_dev, netdev, 1); |
| 393 | 396 | if (rv) |
| @@ -415,9 +418,6 @@ static struct siw_device *siw_device_create(struct net_device *netdev) · 21 unmodified lines | ||
| 415 | 418 | sdev->attrs.max_srq_wr = SIW_MAX_SRQ_WR; |
| 416 | 419 | sdev->attrs.max_srq_sge = SIW_MAX_SGE; |
| 417 | 420 | |
| 418 | − xa_init_flags(&sdev->qp_xa, XA_FLAGS_ALLOC1); | |
| 419 | − xa_init_flags(&sdev->mem_xa, XA_FLAGS_ALLOC1); | |
| 420 | − | |
| 421 | 421 | INIT_LIST_HEAD(&sdev->cep_list); |
| 422 | 422 | INIT_LIST_HEAD(&sdev->qp_list); |
| 423 | 423 | |
| @@ -445,6 +445,11 @@ struct icc_path *of_icc_get(struct device *dev, const char *name) · 444 unmodified lines | ||
| 445 | 445 | path->name = kasprintf(GFP_KERNEL, "%s-%s", |
| 446 | 446 | src_node->name, dst_node->name); |
| 447 | 447 | |
| 448 | + if (!path->name) { | |
| 449 | + kfree(path); | |
| 450 | + return ERR_PTR(-ENOMEM); | |
| 451 | + } | |
| 452 | + | |
| 448 | 453 | return path; |
| 449 | 454 | } |
| 450 | 455 | EXPORT_SYMBOL_GPL(of_icc_get); |
| @@ -579,6 +584,10 @@ struct icc_path *icc_get(struct device *dev, const int src_id, const int dst_id) · 128 unmodified lines | ||
| 579 | 584 | } |
| 580 | 585 | |
| 581 | 586 | path->name = kasprintf(GFP_KERNEL, "%s-%s", src->name, dst->name); |
| 587 | + if (!path->name) { | |
| 588 | + kfree(path); | |
| 589 | + path = ERR_PTR(-ENOMEM); | |
| 590 | + } | |
| 582 | 591 | out: |
| 583 | 592 | mutex_unlock(&icc_lock); |
| 584 | 593 | return path; |
| @@ -3826,7 +3826,7 @@ int amd_iommu_activate_guest_mode(void *data) · 3825 unmodified lines | ||
| 3826 | 3826 | entry->lo.fields_vapic.ga_tag = ir_data->ga_tag; |
| 3827 | 3827 | |
| 3828 | 3828 | return modify_irte_ga(ir_data->irq_2_irte.devid, |
| 3829 | − ir_data->irq_2_irte.index, entry, NULL); | |
| 3829 | + ir_data->irq_2_irte.index, entry, ir_data); | |
| 3830 | 3830 | } |
| 3831 | 3831 | EXPORT_SYMBOL(amd_iommu_activate_guest_mode); |
| 3832 | 3832 | |
| @@ -3852,7 +3852,7 @@ int amd_iommu_deactivate_guest_mode(void *data) · 19 unmodified lines | ||
| 3852 | 3852 | APICID_TO_IRTE_DEST_HI(cfg->dest_apicid); |
| 3853 | 3853 | |
| 3854 | 3854 | return modify_irte_ga(ir_data->irq_2_irte.devid, |
| 3855 | − ir_data->irq_2_irte.index, entry, NULL); | |
| 3855 | + ir_data->irq_2_irte.index, entry, ir_data); | |
| 3856 | 3856 | } |
| 3857 | 3857 | EXPORT_SYMBOL(amd_iommu_deactivate_guest_mode); |
| 3858 | 3858 | |
| @@ -177,15 +177,15 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie, · 176 unmodified lines | ||
| 177 | 177 | start -= iova_offset(iovad, start); |
| 178 | 178 | num_pages = iova_align(iovad, end - start) >> iova_shift(iovad); |
| 179 | 179 | |
| 180 | − msi_page = kcalloc(num_pages, sizeof(*msi_page), GFP_KERNEL); | |
| 181 | − if (!msi_page) | |
| 182 | − return -ENOMEM; | |
| 183 | − | |
| 184 | 180 | for (i = 0; i < num_pages; i++) { |
| 185 | − msi_page[i].phys = start; | |
| 186 | − msi_page[i].iova = start; | |
| 187 | − INIT_LIST_HEAD(&msi_page[i].list); | |
| 188 | − list_add(&msi_page[i].list, &cookie->msi_page_list); | |
| 181 | + msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL); | |
| 182 | + if (!msi_page) | |
| 183 | + return -ENOMEM; | |
| 184 | + | |
| 185 | + msi_page->phys = start; | |
| 186 | + msi_page->iova = start; | |
| 187 | + INIT_LIST_HEAD(&msi_page->list); | |
| 188 | + list_add(&msi_page->list, &cookie->msi_page_list); | |
| 189 | 189 | start += iovad->granule; |
| 190 | 190 | } |
| 191 | 191 | |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #include <linux/slab.h> |
| 29 | 29 | #include <linux/iommu.h> |
| 30 | 30 | #include <linux/numa.h> |
| 31 | +#include <linux/limits.h> | |
| 31 | 32 | #include <asm/irq_remapping.h> |
| 32 | 33 | #include <asm/iommu_table.h> |
| 33 | 34 | |
| @@ -128,6 +129,13 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event) · 94 unmodified lines | ||
| 128 | 129 | |
| 129 | 130 | BUG_ON(dev->is_virtfn); |
| 130 | 131 | |
| 132 | + /* | |
| 133 | + * Ignore devices that have a domain number higher than what can | |
| 134 | + * be looked up in DMAR, e.g. VMD subdevices with domain 0x10000 | |
| 135 | + */ | |
| 136 | + if (pci_domain_nr(dev->bus) > U16_MAX) | |
| 137 | + return NULL; | |
| 138 | + | |
| 131 | 139 | /* Only generate path[] for device addition event */ |
| 132 | 140 | if (event == BUS_NOTIFY_ADD_DEVICE) |
| 133 | 141 | for (tmp = dev; tmp; tmp = tmp->bus->self) |
| @@ -363,7 +371,8 @@ dmar_find_dmaru(struct acpi_dmar_hardware_unit *drhd) · 229 unmodified lines | ||
| 363 | 371 | { |
| 364 | 372 | struct dmar_drhd_unit *dmaru; |
| 365 | 373 | |
| 366 | − list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list) | |
| 374 | + list_for_each_entry_rcu(dmaru, &dmar_drhd_units, list, | |
| 375 | + dmar_rcu_check()) | |
| 367 | 376 | if (dmaru->segment == drhd->segment && |
| 368 | 377 | dmaru->reg_base_addr == drhd->address) |
| 369 | 378 | return dmaru; |
| @@ -440,12 +449,13 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header, · 70 unmodified lines | ||
| 440 | 449 | |
| 441 | 450 | /* Check for NUL termination within the designated length */ |
| 442 | 451 | if (strnlen(andd->device_name, header->length - 8) == header->length - 8) { |
| 443 | − WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, | |
| 452 | + pr_warn(FW_BUG | |
| 444 | 453 | "Your BIOS is broken; ANDD object name is not NUL-terminated\n" |
| 445 | 454 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 446 | 455 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 447 | 456 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 448 | 457 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 458 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
| 449 | 459 | return -EINVAL; |
| 450 | 460 | } |
| 451 | 461 | pr_info("ANDD device: %x name: %s\n", andd->device_number, |
| @@ -471,14 +481,14 @@ static int dmar_parse_one_rhsa(struct acpi_dmar_header *header, void *arg) · 19 unmodified lines | ||
| 471 | 481 | return 0; |
| 472 | 482 | } |
| 473 | 483 | } |
| 474 | − WARN_TAINT( | |
| 475 | − 1, TAINT_FIRMWARE_WORKAROUND, | |
| 484 | + pr_warn(FW_BUG | |
| 476 | 485 | "Your BIOS is broken; RHSA refers to non-existent DMAR unit at %llx\n" |
| 477 | 486 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 478 | − drhd->reg_base_addr, | |
| 487 | + rhsa->base_address, | |
| 479 | 488 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 480 | 489 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 481 | 490 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 491 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
| 482 | 492 | |
| 483 | 493 | return 0; |
| 484 | 494 | } |
| @@ -827,14 +837,14 @@ int __init dmar_table_init(void) · 342 unmodified lines | ||
| 827 | 837 | |
| 828 | 838 | static void warn_invalid_dmar(u64 addr, const char *message) |
| 829 | 839 | { |
| 830 | − WARN_TAINT_ONCE( | |
| 831 | − 1, TAINT_FIRMWARE_WORKAROUND, | |
| 840 | + pr_warn_once(FW_BUG | |
| 832 | 841 | "Your BIOS is broken; DMAR reported at address %llx%s!\n" |
| 833 | 842 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 834 | 843 | addr, message, |
| 835 | 844 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 836 | 845 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 837 | 846 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 847 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
| 838 | 848 | } |
| 839 | 849 | |
| 840 | 850 | static int __ref |
| @@ -33,38 +33,42 @@ struct iommu_regset { · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | #define IOMMU_REGSET_ENTRY(_reg_) \ |
| 35 | 35 | { DMAR_##_reg_##_REG, __stringify(_reg_) } |
| 36 | −static const struct iommu_regset iommu_regs[] = { | |
| 36 | + | |
| 37 | +static const struct iommu_regset iommu_regs_32[] = { | |
| 37 | 38 | IOMMU_REGSET_ENTRY(VER), |
| 38 | − IOMMU_REGSET_ENTRY(CAP), | |
| 39 | − IOMMU_REGSET_ENTRY(ECAP), | |
| 40 | 39 | IOMMU_REGSET_ENTRY(GCMD), |
| 41 | 40 | IOMMU_REGSET_ENTRY(GSTS), |
| 42 | − IOMMU_REGSET_ENTRY(RTADDR), | |
| 43 | − IOMMU_REGSET_ENTRY(CCMD), | |
| 44 | 41 | IOMMU_REGSET_ENTRY(FSTS), |
| 45 | 42 | IOMMU_REGSET_ENTRY(FECTL), |
| 46 | 43 | IOMMU_REGSET_ENTRY(FEDATA), |
| 47 | 44 | IOMMU_REGSET_ENTRY(FEADDR), |
| 48 | 45 | IOMMU_REGSET_ENTRY(FEUADDR), |
| 49 | − IOMMU_REGSET_ENTRY(AFLOG), | |
| 50 | 46 | IOMMU_REGSET_ENTRY(PMEN), |
| 51 | 47 | IOMMU_REGSET_ENTRY(PLMBASE), |
| 52 | 48 | IOMMU_REGSET_ENTRY(PLMLIMIT), |
| 49 | + IOMMU_REGSET_ENTRY(ICS), | |
| 50 | + IOMMU_REGSET_ENTRY(PRS), | |
| 51 | + IOMMU_REGSET_ENTRY(PECTL), | |
| 52 | + IOMMU_REGSET_ENTRY(PEDATA), | |
| 53 | + IOMMU_REGSET_ENTRY(PEADDR), | |
| 54 | + IOMMU_REGSET_ENTRY(PEUADDR), | |
| 55 | +}; | |
| 56 | + | |
| 57 | +static const struct iommu_regset iommu_regs_64[] = { | |
| 58 | + IOMMU_REGSET_ENTRY(CAP), | |
| 59 | + IOMMU_REGSET_ENTRY(ECAP), | |
| 60 | + IOMMU_REGSET_ENTRY(RTADDR), | |
| 61 | + IOMMU_REGSET_ENTRY(CCMD), | |
| 62 | + IOMMU_REGSET_ENTRY(AFLOG), | |
| 53 | 63 | IOMMU_REGSET_ENTRY(PHMBASE), |
| 54 | 64 | IOMMU_REGSET_ENTRY(PHMLIMIT), |
| 55 | 65 | IOMMU_REGSET_ENTRY(IQH), |
| 56 | 66 | IOMMU_REGSET_ENTRY(IQT), |
| 57 | 67 | IOMMU_REGSET_ENTRY(IQA), |
| 58 | − IOMMU_REGSET_ENTRY(ICS), | |
| 59 | 68 | IOMMU_REGSET_ENTRY(IRTA), |
| 60 | 69 | IOMMU_REGSET_ENTRY(PQH), |
| 61 | 70 | IOMMU_REGSET_ENTRY(PQT), |
| 62 | 71 | IOMMU_REGSET_ENTRY(PQA), |
| 63 | − IOMMU_REGSET_ENTRY(PRS), | |
| 64 | − IOMMU_REGSET_ENTRY(PECTL), | |
| 65 | − IOMMU_REGSET_ENTRY(PEDATA), | |
| 66 | − IOMMU_REGSET_ENTRY(PEADDR), | |
| 67 | − IOMMU_REGSET_ENTRY(PEUADDR), | |
| 68 | 72 | IOMMU_REGSET_ENTRY(MTRRCAP), |
| 69 | 73 | IOMMU_REGSET_ENTRY(MTRRDEF), |
| 70 | 74 | IOMMU_REGSET_ENTRY(MTRR_FIX64K_00000), |
| @@ -127,10 +131,16 @@ static int iommu_regset_show(struct seq_file *m, void *unused) · 56 unmodified lines | ||
| 127 | 131 | * by adding the offset to the pointer (virtual address). |
| 128 | 132 | */ |
| 129 | 133 | raw_spin_lock_irqsave(&iommu->register_lock, flag); |
| 130 | − for (i = 0 ; i < ARRAY_SIZE(iommu_regs); i++) { | |
| 131 | − value = dmar_readq(iommu->reg + iommu_regs[i].offset); | |
| 134 | + for (i = 0 ; i < ARRAY_SIZE(iommu_regs_32); i++) { | |
| 135 | + value = dmar_readl(iommu->reg + iommu_regs_32[i].offset); | |
| 136 | + seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n", | |
| 137 | + iommu_regs_32[i].regs, iommu_regs_32[i].offset, | |
| 138 | + value); | |
| 139 | + } | |
| 140 | + for (i = 0 ; i < ARRAY_SIZE(iommu_regs_64); i++) { | |
| 141 | + value = dmar_readq(iommu->reg + iommu_regs_64[i].offset); | |
| 132 | 142 | seq_printf(m, "%-16s\t0x%02x\t\t0x%016llx\n", |
| 133 | − iommu_regs[i].regs, iommu_regs[i].offset, | |
| 143 | + iommu_regs_64[i].regs, iommu_regs_64[i].offset, | |
| 134 | 144 | value); |
| 135 | 145 | } |
| 136 | 146 | raw_spin_unlock_irqrestore(&iommu->register_lock, flag); |
| @@ -272,9 +282,16 @@ static int dmar_translation_struct_show(struct seq_file *m, void *unused) · 135 unmodified lines | ||
| 272 | 282 | { |
| 273 | 283 | struct dmar_drhd_unit *drhd; |
| 274 | 284 | struct intel_iommu *iommu; |
| 285 | + u32 sts; | |
| 275 | 286 | |
| 276 | 287 | rcu_read_lock(); |
| 277 | 288 | for_each_active_iommu(iommu, drhd) { |
| 289 | + sts = dmar_readl(iommu->reg + DMAR_GSTS_REG); | |
| 290 | + if (!(sts & DMA_GSTS_TES)) { | |
| 291 | + seq_printf(m, "DMA Remapping is not enabled on %s\n", | |
| 292 | + iommu->name); | |
| 293 | + continue; | |
| 294 | + } | |
| 278 | 295 | root_tbl_walk(m, iommu); |
| 279 | 296 | seq_putc(m, '\n'); |
| 280 | 297 | } |
| @@ -415,6 +432,7 @@ static int ir_translation_struct_show(struct seq_file *m, void *unused) · 134 unmodified lines | ||
| 415 | 432 | struct dmar_drhd_unit *drhd; |
| 416 | 433 | struct intel_iommu *iommu; |
| 417 | 434 | u64 irta; |
| 435 | + u32 sts; | |
| 418 | 436 | |
| 419 | 437 | rcu_read_lock(); |
| 420 | 438 | for_each_active_iommu(iommu, drhd) { |
| @@ -424,7 +442,8 @@ static int ir_translation_struct_show(struct seq_file *m, void *unused) · 3 unmodified lines | ||
| 424 | 442 | seq_printf(m, "Remapped Interrupt supported on IOMMU: %s\n", |
| 425 | 443 | iommu->name); |
| 426 | 444 | |
| 427 | − if (iommu->ir_table) { | |
| 445 | + sts = dmar_readl(iommu->reg + DMAR_GSTS_REG); | |
| 446 | + if (iommu->ir_table && (sts & DMA_GSTS_IRES)) { | |
| 428 | 447 | irta = virt_to_phys(iommu->ir_table->base); |
| 429 | 448 | seq_printf(m, " IR table address:%llx\n", irta); |
| 430 | 449 | ir_tbl_remap_entry_show(m, iommu); |
| @@ -4261,10 +4261,11 @@ static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev) · 4260 unmodified lines | ||
| 4261 | 4261 | |
| 4262 | 4262 | /* we know that the this iommu should be at offset 0xa000 from vtbar */ |
| 4263 | 4263 | drhd = dmar_find_matched_drhd_unit(pdev); |
| 4264 | − if (WARN_TAINT_ONCE(!drhd || drhd->reg_base_addr - vtbar != 0xa000, | |
| 4265 | − TAINT_FIRMWARE_WORKAROUND, | |
| 4266 | − "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n")) | |
| 4264 | + if (!drhd || drhd->reg_base_addr - vtbar != 0xa000) { | |
| 4265 | + pr_warn_once(FW_BUG "BIOS assigned incorrect VT-d unit for Intel(R) QuickData Technology device\n"); | |
| 4266 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
| 4267 | 4267 | pdev->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO; |
| 4268 | + } | |
| 4268 | 4269 | } |
| 4269 | 4270 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB, quirk_ioat_snb_local_iommu); |
| 4270 | 4271 | |
| @@ -4460,14 +4461,16 @@ int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg) · 189 unmodified lines | ||
| 4460 | 4461 | struct dmar_rmrr_unit *rmrru; |
| 4461 | 4462 | |
| 4462 | 4463 | rmrr = (struct acpi_dmar_reserved_memory *)header; |
| 4463 | − if (rmrr_sanity_check(rmrr)) | |
| 4464 | − WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, | |
| 4464 | + if (rmrr_sanity_check(rmrr)) { | |
| 4465 | + pr_warn(FW_BUG | |
| 4465 | 4466 | "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n" |
| 4466 | 4467 | "BIOS vendor: %s; Ver: %s; Product Version: %s\n", |
| 4467 | 4468 | rmrr->base_address, rmrr->end_address, |
| 4468 | 4469 | dmi_get_system_info(DMI_BIOS_VENDOR), |
| 4469 | 4470 | dmi_get_system_info(DMI_BIOS_VERSION), |
| 4470 | 4471 | dmi_get_system_info(DMI_PRODUCT_VERSION)); |
| 4472 | + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); | |
| 4473 | + } | |
| 4471 | 4474 | |
| 4472 | 4475 | rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL); |
| 4473 | 4476 | if (!rmrru) |
| @@ -5130,6 +5133,9 @@ int __init intel_iommu_init(void) · 656 unmodified lines | ||
| 5130 | 5133 | |
| 5131 | 5134 | down_write(&dmar_global_lock); |
| 5132 | 5135 | |
| 5136 | + if (!no_iommu) | |
| 5137 | + intel_iommu_debugfs_init(); | |
| 5138 | + | |
| 5133 | 5139 | if (no_iommu || dmar_disabled) { |
| 5134 | 5140 | /* |
| 5135 | 5141 | * We exit the function here to ensure IOMMU's remapping and |
| @@ -5193,6 +5199,7 @@ int __init intel_iommu_init(void) · 57 unmodified lines | ||
| 5193 | 5199 | |
| 5194 | 5200 | init_iommu_pm_ops(); |
| 5195 | 5201 | |
| 5202 | + down_read(&dmar_global_lock); | |
| 5196 | 5203 | for_each_active_iommu(iommu, drhd) { |
| 5197 | 5204 | iommu_device_sysfs_add(&iommu->iommu, NULL, |
| 5198 | 5205 | intel_iommu_groups, |
| @@ -5200,6 +5207,7 @@ int __init intel_iommu_init(void) · 1 unmodified line | ||
| 5200 | 5207 | iommu_device_set_ops(&iommu->iommu, &intel_iommu_ops); |
| 5201 | 5208 | iommu_device_register(&iommu->iommu); |
| 5202 | 5209 | } |
| 5210 | + up_read(&dmar_global_lock); | |
| 5203 | 5211 | |
| 5204 | 5212 | bus_set_iommu(&pci_bus_type, &intel_iommu_ops); |
| 5205 | 5213 | if (si_domain && !hw_pass_through) |
| @@ -5210,7 +5218,6 @@ int __init intel_iommu_init(void) · 4 unmodified lines | ||
| 5210 | 5218 | down_read(&dmar_global_lock); |
| 5211 | 5219 | if (probe_acpi_namespace_devices()) |
| 5212 | 5220 | pr_warn("ACPI name space devices didn't probe correctly\n"); |
| 5213 | − up_read(&dmar_global_lock); | |
| 5214 | 5221 | |
| 5215 | 5222 | /* Finally, we enable the DMA remapping hardware. */ |
| 5216 | 5223 | for_each_iommu(iommu, drhd) { |
| @@ -5219,10 +5226,11 @@ int __init intel_iommu_init(void) · 2 unmodified lines | ||
| 5219 | 5226 | |
| 5220 | 5227 | iommu_disable_protect_mem_regions(iommu); |
| 5221 | 5228 | } |
| 5229 | + up_read(&dmar_global_lock); | |
| 5230 | + | |
| 5222 | 5231 | pr_info("Intel(R) Virtualization Technology for Directed I/O\n"); |
| 5223 | 5232 | |
| 5224 | 5233 | intel_iommu_enabled = 1; |
| 5225 | − intel_iommu_debugfs_init(); | |
| 5226 | 5234 | |
| 5227 | 5235 | return 0; |
| 5228 | 5236 | |
| @@ -5700,8 +5708,10 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain, · 471 unmodified lines | ||
| 5700 | 5708 | u64 phys = 0; |
| 5701 | 5709 | |
| 5702 | 5710 | pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, &level); |
| 5703 | − if (pte) | |
| 5704 | − phys = dma_pte_addr(pte); | |
| 5711 | + if (pte && dma_pte_present(pte)) | |
| 5712 | + phys = dma_pte_addr(pte) + | |
| 5713 | + (iova & (BIT_MASK(level_to_offset_bits(level) + | |
| 5714 | + VTD_PAGE_SHIFT) - 1)); | |
| 5705 | 5715 | |
| 5706 | 5716 | return phys; |
| 5707 | 5717 | } |
| @@ -468,7 +468,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova, · 467 unmodified lines | ||
| 468 | 468 | arm_lpae_iopte *ptep = data->pgd; |
| 469 | 469 | int ret, lvl = data->start_level; |
| 470 | 470 | arm_lpae_iopte prot; |
| 471 | − long iaext = (long)iova >> cfg->ias; | |
| 471 | + long iaext = (s64)iova >> cfg->ias; | |
| 472 | 472 | |
| 473 | 473 | /* If no access, then nothing to do */ |
| 474 | 474 | if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE))) |
| @@ -645,7 +645,7 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova, · 170 unmodified lines | ||
| 645 | 645 | struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops); |
| 646 | 646 | struct io_pgtable_cfg *cfg = &data->iop.cfg; |
| 647 | 647 | arm_lpae_iopte *ptep = data->pgd; |
| 648 | − long iaext = (long)iova >> cfg->ias; | |
| 648 | + long iaext = (s64)iova >> cfg->ias; | |
| 649 | 649 | |
| 650 | 650 | if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size)) |
| 651 | 651 | return 0; |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #define GICD_INT_NMI_PRI (GICD_INT_DEF_PRI & ~0x80) |
| 35 | 35 | |
| 36 | 36 | #define FLAGS_WORKAROUND_GICR_WAKER_MSM8996 (1ULL << 0) |
| 37 | +#define FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539 (1ULL << 1) | |
| 37 | 38 | |
| 38 | 39 | struct redist_region { |
| 39 | 40 | void __iomem *redist_base; |
| @@ -1464,6 +1465,15 @@ static bool gic_enable_quirk_msm8996(void *data) · 1424 unmodified lines | ||
| 1464 | 1465 | return true; |
| 1465 | 1466 | } |
| 1466 | 1467 | |
| 1468 | +static bool gic_enable_quirk_cavium_38539(void *data) | |
| 1469 | +{ | |
| 1470 | + struct gic_chip_data *d = data; | |
| 1471 | + | |
| 1472 | + d->flags |= FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539; | |
| 1473 | + | |
| 1474 | + return true; | |
| 1475 | +} | |
| 1476 | + | |
| 1467 | 1477 | static bool gic_enable_quirk_hip06_07(void *data) |
| 1468 | 1478 | { |
| 1469 | 1479 | struct gic_chip_data *d = data; |
| @@ -1502,6 +1512,19 @@ static const struct gic_quirk gic_quirks[] = { · 32 unmodified lines | ||
| 1502 | 1512 | .mask = 0xffffffff, |
| 1503 | 1513 | .init = gic_enable_quirk_hip06_07, |
| 1504 | 1514 | }, |
| 1515 | + { | |
| 1516 | + /* | |
| 1517 | + * Reserved register accesses generate a Synchronous | |
| 1518 | + * External Abort. This erratum applies to: | |
| 1519 | + * - ThunderX: CN88xx | |
| 1520 | + * - OCTEON TX: CN83xx, CN81xx | |
| 1521 | + * - OCTEON TX2: CN93xx, CN96xx, CN98xx, CNF95xx* | |
| 1522 | + */ | |
| 1523 | + .desc = "GICv3: Cavium erratum 38539", | |
| 1524 | + .iidr = 0xa000034c, | |
| 1525 | + .mask = 0xe8f00fff, | |
| 1526 | + .init = gic_enable_quirk_cavium_38539, | |
| 1527 | + }, | |
| 1505 | 1528 | { |
| 1506 | 1529 | } |
| 1507 | 1530 | }; |
| @@ -1577,7 +1600,12 @@ static int __init gic_init_bases(void __iomem *dist_base, · 69 unmodified lines | ||
| 1577 | 1600 | pr_info("%d SPIs implemented\n", GIC_LINE_NR - 32); |
| 1578 | 1601 | pr_info("%d Extended SPIs implemented\n", GIC_ESPI_NR); |
| 1579 | 1602 | |
| 1580 | − gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2); | |
| 1603 | + /* | |
| 1604 | + * ThunderX1 explodes on reading GICD_TYPER2, in violation of the | |
| 1605 | + * architecture spec (which says that reserved registers are RES0). | |
| 1606 | + */ | |
| 1607 | + if (!(gic_data.flags & FLAGS_WORKAROUND_CAVIUM_ERRATUM_38539)) | |
| 1608 | + gic_data.rdists.gicd_typer2 = readl_relaxed(gic_data.dist_base + GICD_TYPER2); | |
| 1581 | 1609 | |
| 1582 | 1610 | gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops, |
| 1583 | 1611 | &gic_data); |
| @@ -300,9 +300,11 @@ static int control_loop(void *dummy) · 299 unmodified lines | ||
| 300 | 300 | /* i2c probing and setup */ |
| 301 | 301 | /************************************************************************/ |
| 302 | 302 | |
| 303 | −static int | |
| 304 | −do_attach( struct i2c_adapter *adapter ) | |
| 303 | +static void do_attach(struct i2c_adapter *adapter) | |
| 305 | 304 | { |
| 305 | + struct i2c_board_info info = { }; | |
| 306 | + struct device_node *np; | |
| 307 | + | |
| 306 | 308 | /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */ |
| 307 | 309 | static const unsigned short scan_ds1775[] = { |
| 308 | 310 | 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, |
| @@ -313,25 +315,24 @@ do_attach( struct i2c_adapter *adapter ) · 4 unmodified lines | ||
| 313 | 315 | I2C_CLIENT_END |
| 314 | 316 | }; |
| 315 | 317 | |
| 316 | − if( strncmp(adapter->name, "uni-n", 5) ) | |
| 317 | − return 0; | |
| 318 | − | |
| 319 | − if( !x.running ) { | |
| 320 | − struct i2c_board_info info; | |
| 318 | + if (x.running || strncmp(adapter->name, "uni-n", 5)) | |
| 319 | + return; | |
| 321 | 320 | |
| 322 | − memset(&info, 0, sizeof(struct i2c_board_info)); | |
| 323 | − strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE); | |
| 321 | + np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,ds1775"); | |
| 322 | + if (np) { | |
| 323 | + of_node_put(np); | |
| 324 | + } else { | |
| 325 | + strlcpy(info.type, "MAC,ds1775", I2C_NAME_SIZE); | |
| 324 | 326 | i2c_new_probed_device(adapter, &info, scan_ds1775, NULL); |
| 327 | + } | |
| 325 | 328 | |
| 326 | − strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE); | |
| 329 | + np = of_find_compatible_node(adapter->dev.of_node, NULL, "MAC,adm1030"); | |
| 330 | + if (np) { | |
| 331 | + of_node_put(np); | |
| 332 | + } else { | |
| 333 | + strlcpy(info.type, "MAC,adm1030", I2C_NAME_SIZE); | |
| 327 | 334 | i2c_new_probed_device(adapter, &info, scan_adm1030, NULL); |
| 328 | − | |
| 329 | − if( x.thermostat && x.fan ) { | |
| 330 | − x.running = 1; | |
| 331 | − x.poll_task = kthread_run(control_loop, NULL, "g4fand"); | |
| 332 | − } | |
| 333 | 335 | } |
| 334 | − return 0; | |
| 335 | 336 | } |
| 336 | 337 | |
| 337 | 338 | static int |
| @@ -404,8 +405,8 @@ out: · 66 unmodified lines | ||
| 404 | 405 | enum chip { ds1775, adm1030 }; |
| 405 | 406 | |
| 406 | 407 | static const struct i2c_device_id therm_windtunnel_id[] = { |
| 407 | − { "therm_ds1775", ds1775 }, | |
| 408 | − { "therm_adm1030", adm1030 }, | |
| 408 | + { "MAC,ds1775", ds1775 }, | |
| 409 | + { "MAC,adm1030", adm1030 }, | |
| 409 | 410 | { } |
| 410 | 411 | }; |
| 411 | 412 | MODULE_DEVICE_TABLE(i2c, therm_windtunnel_id); |
| @@ -414,6 +415,7 @@ static int · 2 unmodified lines | ||
| 414 | 415 | do_probe(struct i2c_client *cl, const struct i2c_device_id *id) |
| 415 | 416 | { |
| 416 | 417 | struct i2c_adapter *adapter = cl->adapter; |
| 418 | + int ret = 0; | |
| 417 | 419 | |
| 418 | 420 | if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA |
| 419 | 421 | | I2C_FUNC_SMBUS_WRITE_BYTE) ) |
| @@ -421,11 +423,19 @@ do_probe(struct i2c_client *cl, const struct i2c_device_id *id) · 1 unmodified line | ||
| 421 | 423 | |
| 422 | 424 | switch (id->driver_data) { |
| 423 | 425 | case adm1030: |
| 424 | − return attach_fan( cl ); | |
| 426 | + ret = attach_fan(cl); | |
| 427 | + break; | |
| 425 | 428 | case ds1775: |
| 426 | − return attach_thermostat(cl); | |
| 429 | + ret = attach_thermostat(cl); | |
| 430 | + break; | |
| 427 | 431 | } |
| 428 | − return 0; | |
| 432 | + | |
| 433 | + if (!x.running && x.thermostat && x.fan) { | |
| 434 | + x.running = 1; | |
| 435 | + x.poll_task = kthread_run(control_loop, NULL, "g4fand"); | |
| 436 | + } | |
| 437 | + | |
| 438 | + return ret; | |
| 429 | 439 | } |
| 430 | 440 | |
| 431 | 441 | static struct i2c_driver g4fan_driver = { |
| @@ -312,9 +312,16 @@ static const struct i2c_device_id wf_ad7417_id[] = { · 311 unmodified lines | ||
| 312 | 312 | }; |
| 313 | 313 | MODULE_DEVICE_TABLE(i2c, wf_ad7417_id); |
| 314 | 314 | |
| 315 | +static const struct of_device_id wf_ad7417_of_id[] = { | |
| 316 | + { .compatible = "ad7417", }, | |
| 317 | + { } | |
| 318 | +}; | |
| 319 | +MODULE_DEVICE_TABLE(of, wf_ad7417_of_id); | |
| 320 | + | |
| 315 | 321 | static struct i2c_driver wf_ad7417_driver = { |
| 316 | 322 | .driver = { |
| 317 | 323 | .name = "wf_ad7417", |
| 324 | + .of_match_table = wf_ad7417_of_id, | |
| 318 | 325 | }, |
| 319 | 326 | .probe = wf_ad7417_probe, |
| 320 | 327 | .remove = wf_ad7417_remove, |
| @@ -580,9 +580,16 @@ static const struct i2c_device_id wf_fcu_id[] = { · 579 unmodified lines | ||
| 580 | 580 | }; |
| 581 | 581 | MODULE_DEVICE_TABLE(i2c, wf_fcu_id); |
| 582 | 582 | |
| 583 | +static const struct of_device_id wf_fcu_of_id[] = { | |
| 584 | + { .compatible = "fcu", }, | |
| 585 | + { } | |
| 586 | +}; | |
| 587 | +MODULE_DEVICE_TABLE(of, wf_fcu_of_id); | |
| 588 | + | |
| 583 | 589 | static struct i2c_driver wf_fcu_driver = { |
| 584 | 590 | .driver = { |
| 585 | 591 | .name = "wf_fcu", |
| 592 | + .of_match_table = wf_fcu_of_id, | |
| 586 | 593 | }, |
| 587 | 594 | .probe = wf_fcu_probe, |
| 588 | 595 | .remove = wf_fcu_remove, |
| @@ -14,6 +14,7 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/init.h> |
| 15 | 15 | #include <linux/wait.h> |
| 16 | 16 | #include <linux/i2c.h> |
| 17 | +#include <linux/of_device.h> | |
| 17 | 18 | #include <asm/prom.h> |
| 18 | 19 | #include <asm/machdep.h> |
| 19 | 20 | #include <asm/io.h> |
| @@ -91,9 +92,14 @@ static int wf_lm75_probe(struct i2c_client *client, · 71 unmodified lines | ||
| 91 | 92 | const struct i2c_device_id *id) |
| 92 | 93 | { |
| 93 | 94 | struct wf_lm75_sensor *lm; |
| 94 | − int rc, ds1775 = id->driver_data; | |
| 95 | + int rc, ds1775; | |
| 95 | 96 | const char *name, *loc; |
| 96 | 97 | |
| 98 | + if (id) | |
| 99 | + ds1775 = id->driver_data; | |
| 100 | + else | |
| 101 | + ds1775 = !!of_device_get_match_data(&client->dev); | |
| 102 | + | |
| 97 | 103 | DBG("wf_lm75: creating %s device at address 0x%02x\n", |
| 98 | 104 | ds1775 ? "ds1775" : "lm75", client->addr); |
| 99 | 105 | |
| @@ -164,9 +170,17 @@ static const struct i2c_device_id wf_lm75_id[] = { · 64 unmodified lines | ||
| 164 | 170 | }; |
| 165 | 171 | MODULE_DEVICE_TABLE(i2c, wf_lm75_id); |
| 166 | 172 | |
| 173 | +static const struct of_device_id wf_lm75_of_id[] = { | |
| 174 | + { .compatible = "lm75", .data = (void *)0}, | |
| 175 | + { .compatible = "ds1775", .data = (void *)1 }, | |
| 176 | + { } | |
| 177 | +}; | |
| 178 | +MODULE_DEVICE_TABLE(of, wf_lm75_of_id); | |
| 179 | + | |
| 167 | 180 | static struct i2c_driver wf_lm75_driver = { |
| 168 | 181 | .driver = { |
| 169 | 182 | .name = "wf_lm75", |
| 183 | + .of_match_table = wf_lm75_of_id, | |
| 170 | 184 | }, |
| 171 | 185 | .probe = wf_lm75_probe, |
| 172 | 186 | .remove = wf_lm75_remove, |
| @@ -166,9 +166,16 @@ static const struct i2c_device_id wf_lm87_id[] = { · 165 unmodified lines | ||
| 166 | 166 | }; |
| 167 | 167 | MODULE_DEVICE_TABLE(i2c, wf_lm87_id); |
| 168 | 168 | |
| 169 | +static const struct of_device_id wf_lm87_of_id[] = { | |
| 170 | + { .compatible = "lm87cimt", }, | |
| 171 | + { } | |
| 172 | +}; | |
| 173 | +MODULE_DEVICE_TABLE(of, wf_lm87_of_id); | |
| 174 | + | |
| 169 | 175 | static struct i2c_driver wf_lm87_driver = { |
| 170 | 176 | .driver = { |
| 171 | 177 | .name = "wf_lm87", |
| 178 | + .of_match_table = wf_lm87_of_id, | |
| 172 | 179 | }, |
| 173 | 180 | .probe = wf_lm87_probe, |
| 174 | 181 | .remove = wf_lm87_remove, |
| @@ -120,9 +120,16 @@ static const struct i2c_device_id wf_max6690_id[] = { · 119 unmodified lines | ||
| 120 | 120 | }; |
| 121 | 121 | MODULE_DEVICE_TABLE(i2c, wf_max6690_id); |
| 122 | 122 | |
| 123 | +static const struct of_device_id wf_max6690_of_id[] = { | |
| 124 | + { .compatible = "max6690", }, | |
| 125 | + { } | |
| 126 | +}; | |
| 127 | +MODULE_DEVICE_TABLE(of, wf_max6690_of_id); | |
| 128 | + | |
| 123 | 129 | static struct i2c_driver wf_max6690_driver = { |
| 124 | 130 | .driver = { |
| 125 | 131 | .name = "wf_max6690", |
| 132 | + .of_match_table = wf_max6690_of_id, | |
| 126 | 133 | }, |
| 127 | 134 | .probe = wf_max6690_probe, |
| 128 | 135 | .remove = wf_max6690_remove, |
| @@ -341,9 +341,16 @@ static const struct i2c_device_id wf_sat_id[] = { · 340 unmodified lines | ||
| 341 | 341 | }; |
| 342 | 342 | MODULE_DEVICE_TABLE(i2c, wf_sat_id); |
| 343 | 343 | |
| 344 | +static const struct of_device_id wf_sat_of_id[] = { | |
| 345 | + { .compatible = "smu-sat", }, | |
| 346 | + { } | |
| 347 | +}; | |
| 348 | +MODULE_DEVICE_TABLE(of, wf_sat_of_id); | |
| 349 | + | |
| 344 | 350 | static struct i2c_driver wf_sat_driver = { |
| 345 | 351 | .driver = { |
| 346 | 352 | .name = "wf_smu_sat", |
| 353 | + .of_match_table = wf_sat_of_id, | |
| 347 | 354 | }, |
| 348 | 355 | .probe = wf_sat_probe, |
| 349 | 356 | .remove = wf_sat_remove, |
| @@ -67,7 +67,6 @@ · 66 unmodified lines | ||
| 67 | 67 | #include <linux/blkdev.h> |
| 68 | 68 | #include <linux/kthread.h> |
| 69 | 69 | #include <linux/random.h> |
| 70 | −#include <linux/sched/signal.h> | |
| 71 | 70 | #include <trace/events/bcache.h> |
| 72 | 71 | |
| 73 | 72 | #define MAX_OPEN_BUCKETS 128 |
| @@ -734,21 +733,8 @@ int bch_open_buckets_alloc(struct cache_set *c) · 660 unmodified lines | ||
| 734 | 733 | |
| 735 | 734 | int bch_cache_allocator_start(struct cache *ca) |
| 736 | 735 | { |
| 737 | − struct task_struct *k; | |
| 738 | − | |
| 739 | − /* | |
| 740 | − * In case previous btree check operation occupies too many | |
| 741 | − * system memory for bcache btree node cache, and the | |
| 742 | − * registering process is selected by OOM killer. Here just | |
| 743 | − * ignore the SIGKILL sent by OOM killer if there is, to | |
| 744 | − * avoid kthread_run() being failed by pending signals. The | |
| 745 | − * bcache registering process will exit after the registration | |
| 746 | − * done. | |
| 747 | − */ | |
| 748 | − if (signal_pending(current)) | |
| 749 | − flush_signals(current); | |
| 750 | − | |
| 751 | − k = kthread_run(bch_allocator_thread, ca, "bcache_allocator"); | |
| 736 | + struct task_struct *k = kthread_run(bch_allocator_thread, | |
| 737 | + ca, "bcache_allocator"); | |
| 752 | 738 | if (IS_ERR(k)) |
| 753 | 739 | return PTR_ERR(k); |
| 754 | 740 | |
| @@ -34,7 +34,6 @@ · 33 unmodified lines | ||
| 34 | 34 | #include <linux/random.h> |
| 35 | 35 | #include <linux/rcupdate.h> |
| 36 | 36 | #include <linux/sched/clock.h> |
| 37 | −#include <linux/sched/signal.h> | |
| 38 | 37 | #include <linux/rculist.h> |
| 39 | 38 | #include <linux/delay.h> |
| 40 | 39 | #include <trace/events/bcache.h> |
| @@ -1914,18 +1913,6 @@ static int bch_gc_thread(void *arg) · 1873 unmodified lines | ||
| 1914 | 1913 | |
| 1915 | 1914 | int bch_gc_thread_start(struct cache_set *c) |
| 1916 | 1915 | { |
| 1917 | − /* | |
| 1918 | − * In case previous btree check operation occupies too many | |
| 1919 | − * system memory for bcache btree node cache, and the | |
| 1920 | − * registering process is selected by OOM killer. Here just | |
| 1921 | − * ignore the SIGKILL sent by OOM killer if there is, to | |
| 1922 | − * avoid kthread_run() being failed by pending signals. The | |
| 1923 | − * bcache registering process will exit after the registration | |
| 1924 | − * done. | |
| 1925 | − */ | |
| 1926 | − if (signal_pending(current)) | |
| 1927 | − flush_signals(current); | |
| 1928 | − | |
| 1929 | 1916 | c->gc_thread = kthread_run(bch_gc_thread, c, "bcache_gc"); |
| 1930 | 1917 | return PTR_ERR_OR_ZERO(c->gc_thread); |
| 1931 | 1918 | } |
| @@ -20,8 +20,13 @@ · 19 unmodified lines | ||
| 20 | 20 | struct dm_bio_details { |
| 21 | 21 | struct gendisk *bi_disk; |
| 22 | 22 | u8 bi_partno; |
| 23 | + int __bi_remaining; | |
| 23 | 24 | unsigned long bi_flags; |
| 24 | 25 | struct bvec_iter bi_iter; |
| 26 | + bio_end_io_t *bi_end_io; | |
| 27 | +#if defined(CONFIG_BLK_DEV_INTEGRITY) | |
| 28 | + struct bio_integrity_payload *bi_integrity; | |
| 29 | +#endif | |
| 25 | 30 | }; |
| 26 | 31 | |
| 27 | 32 | static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio) |
| @@ -30,6 +35,11 @@ static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio) · 2 unmodified lines | ||
| 30 | 35 | bd->bi_partno = bio->bi_partno; |
| 31 | 36 | bd->bi_flags = bio->bi_flags; |
| 32 | 37 | bd->bi_iter = bio->bi_iter; |
| 38 | + bd->__bi_remaining = atomic_read(&bio->__bi_remaining); | |
| 39 | + bd->bi_end_io = bio->bi_end_io; | |
| 40 | +#if defined(CONFIG_BLK_DEV_INTEGRITY) | |
| 41 | + bd->bi_integrity = bio_integrity(bio); | |
| 42 | +#endif | |
| 33 | 43 | } |
| 34 | 44 | |
| 35 | 45 | static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio) |
| @@ -38,6 +48,11 @@ static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio) · 2 unmodified lines | ||
| 38 | 48 | bio->bi_partno = bd->bi_partno; |
| 39 | 49 | bio->bi_flags = bd->bi_flags; |
| 40 | 50 | bio->bi_iter = bd->bi_iter; |
| 51 | + atomic_set(&bio->__bi_remaining, bd->__bi_remaining); | |
| 52 | + bio->bi_end_io = bd->bi_end_io; | |
| 53 | +#if defined(CONFIG_BLK_DEV_INTEGRITY) | |
| 54 | + bio->bi_integrity = bd->bi_integrity; | |
| 55 | +#endif | |
| 41 | 56 | } |
| 42 | 57 | |
| 43 | 58 | #endif |
| @@ -2846,8 +2846,8 @@ static void cache_postsuspend(struct dm_target *ti) · 2845 unmodified lines | ||
| 2846 | 2846 | prevent_background_work(cache); |
| 2847 | 2847 | BUG_ON(atomic_read(&cache->nr_io_migrations)); |
| 2848 | 2848 | |
| 2849 | − cancel_delayed_work(&cache->waker); | |
| 2850 | − flush_workqueue(cache->wq); | |
| 2849 | + cancel_delayed_work_sync(&cache->waker); | |
| 2850 | + drain_workqueue(cache->wq); | |
| 2851 | 2851 | WARN_ON(cache->tracker.in_flight); |
| 2852 | 2852 | |
| 2853 | 2853 | /* |
| @@ -3492,7 +3492,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits) · 638 unmodified lines | ||
| 3492 | 3492 | |
| 3493 | 3493 | static struct target_type cache_target = { |
| 3494 | 3494 | .name = "cache", |
| 3495 | − .version = {2, 1, 0}, | |
| 3495 | + .version = {2, 2, 0}, | |
| 3496 | 3496 | .module = THIS_MODULE, |
| 3497 | 3497 | .ctr = cache_ctr, |
| 3498 | 3498 | .dtr = cache_dtr, |
| @@ -6,6 +6,8 @@ · 5 unmodified lines | ||
| 6 | 6 | * This file is released under the GPL. |
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | +#include "dm-bio-record.h" | |
| 10 | + | |
| 9 | 11 | #include <linux/compiler.h> |
| 10 | 12 | #include <linux/module.h> |
| 11 | 13 | #include <linux/device-mapper.h> |
| @@ -201,17 +203,19 @@ struct dm_integrity_c { · 189 unmodified lines | ||
| 201 | 203 | __u8 log2_blocks_per_bitmap_bit; |
| 202 | 204 | |
| 203 | 205 | unsigned char mode; |
| 204 | − int suspending; | |
| 205 | 206 | |
| 206 | 207 | int failed; |
| 207 | 208 | |
| 208 | 209 | struct crypto_shash *internal_hash; |
| 209 | 210 | |
| 211 | + struct dm_target *ti; | |
| 212 | + | |
| 210 | 213 | /* these variables are locked with endio_wait.lock */ |
| 211 | 214 | struct rb_root in_progress; |
| 212 | 215 | struct list_head wait_list; |
| 213 | 216 | wait_queue_head_t endio_wait; |
| 214 | 217 | struct workqueue_struct *wait_wq; |
| 218 | + struct workqueue_struct *offload_wq; | |
| 215 | 219 | |
| 216 | 220 | unsigned char commit_seq; |
| 217 | 221 | commit_id_t commit_ids[N_COMMIT_IDS]; |
| @@ -293,11 +297,7 @@ struct dm_integrity_io { · 75 unmodified lines | ||
| 293 | 297 | |
| 294 | 298 | struct completion *completion; |
| 295 | 299 | |
| 296 | − struct gendisk *orig_bi_disk; | |
| 297 | − u8 orig_bi_partno; | |
| 298 | − bio_end_io_t *orig_bi_end_io; | |
| 299 | − struct bio_integrity_payload *orig_bi_integrity; | |
| 300 | − struct bvec_iter orig_bi_iter; | |
| 300 | + struct dm_bio_details bio_details; | |
| 301 | 301 | }; |
| 302 | 302 | |
| 303 | 303 | struct journal_completion { |
| @@ -1439,7 +1439,7 @@ static void dec_in_flight(struct dm_integrity_io *dio) · 1135 unmodified lines | ||
| 1439 | 1439 | dio->range.logical_sector += dio->range.n_sectors; |
| 1440 | 1440 | bio_advance(bio, dio->range.n_sectors << SECTOR_SHIFT); |
| 1441 | 1441 | INIT_WORK(&dio->work, integrity_bio_wait); |
| 1442 | − queue_work(ic->wait_wq, &dio->work); | |
| 1442 | + queue_work(ic->offload_wq, &dio->work); | |
| 1443 | 1443 | return; |
| 1444 | 1444 | } |
| 1445 | 1445 | do_endio_flush(ic, dio); |
| @@ -1450,14 +1450,9 @@ static void integrity_end_io(struct bio *bio) · 4 unmodified lines | ||
| 1450 | 1450 | { |
| 1451 | 1451 | struct dm_integrity_io *dio = dm_per_bio_data(bio, sizeof(struct dm_integrity_io)); |
| 1452 | 1452 | |
| 1453 | − bio->bi_iter = dio->orig_bi_iter; | |
| 1454 | − bio->bi_disk = dio->orig_bi_disk; | |
| 1455 | − bio->bi_partno = dio->orig_bi_partno; | |
| 1456 | − if (dio->orig_bi_integrity) { | |
| 1457 | − bio->bi_integrity = dio->orig_bi_integrity; | |
| 1453 | + dm_bio_restore(&dio->bio_details, bio); | |
| 1454 | + if (bio->bi_integrity) | |
| 1458 | 1455 | bio->bi_opf |= REQ_INTEGRITY; |
| 1459 | − } | |
| 1460 | − bio->bi_end_io = dio->orig_bi_end_io; | |
| 1461 | 1456 | |
| 1462 | 1457 | if (dio->completion) |
| 1463 | 1458 | complete(dio->completion); |
| @@ -1542,7 +1537,7 @@ static void integrity_metadata(struct work_struct *w) · 78 unmodified lines | ||
| 1542 | 1537 | } |
| 1543 | 1538 | } |
| 1544 | 1539 | |
| 1545 | − __bio_for_each_segment(bv, bio, iter, dio->orig_bi_iter) { | |
| 1540 | + __bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) { | |
| 1546 | 1541 | unsigned pos; |
| 1547 | 1542 | char *mem, *checksums_ptr; |
| 1548 | 1543 | |
| @@ -1586,7 +1581,7 @@ again: · 37 unmodified lines | ||
| 1586 | 1581 | if (likely(checksums != checksums_onstack)) |
| 1587 | 1582 | kfree(checksums); |
| 1588 | 1583 | } else { |
| 1589 | − struct bio_integrity_payload *bip = dio->orig_bi_integrity; | |
| 1584 | + struct bio_integrity_payload *bip = dio->bio_details.bi_integrity; | |
| 1590 | 1585 | |
| 1591 | 1586 | if (bip) { |
| 1592 | 1587 | struct bio_vec biv; |
| @@ -1865,7 +1860,7 @@ static void dm_integrity_map_continue(struct dm_integrity_io *dio, bool from_map · 272 unmodified lines | ||
| 1865 | 1860 | |
| 1866 | 1861 | if (need_sync_io && from_map) { |
| 1867 | 1862 | INIT_WORK(&dio->work, integrity_bio_wait); |
| 1868 | − queue_work(ic->metadata_wq, &dio->work); | |
| 1863 | + queue_work(ic->offload_wq, &dio->work); | |
| 1869 | 1864 | return; |
| 1870 | 1865 | } |
| 1871 | 1866 | |
| @@ -2005,20 +2000,13 @@ offload_to_thread: · 133 unmodified lines | ||
| 2005 | 2000 | } else |
| 2006 | 2001 | dio->completion = NULL; |
| 2007 | 2002 | |
| 2008 | − dio->orig_bi_iter = bio->bi_iter; | |
| 2009 | − | |
| 2010 | − dio->orig_bi_disk = bio->bi_disk; | |
| 2011 | − dio->orig_bi_partno = bio->bi_partno; | |
| 2003 | + dm_bio_record(&dio->bio_details, bio); | |
| 2012 | 2004 | bio_set_dev(bio, ic->dev->bdev); |
| 2013 | − | |
| 2014 | − dio->orig_bi_integrity = bio_integrity(bio); | |
| 2015 | 2005 | bio->bi_integrity = NULL; |
| 2016 | 2006 | bio->bi_opf &= ~REQ_INTEGRITY; |
| 2017 | − | |
| 2018 | − dio->orig_bi_end_io = bio->bi_end_io; | |
| 2019 | 2007 | bio->bi_end_io = integrity_end_io; |
| 2020 | − | |
| 2021 | 2008 | bio->bi_iter.bi_size = dio->range.n_sectors << SECTOR_SHIFT; |
| 2009 | + | |
| 2022 | 2010 | generic_make_request(bio); |
| 2023 | 2011 | |
| 2024 | 2012 | if (need_sync_io) { |
| @@ -2315,7 +2303,7 @@ static void integrity_writer(struct work_struct *w) · 290 unmodified lines | ||
| 2315 | 2303 | unsigned prev_free_sectors; |
| 2316 | 2304 | |
| 2317 | 2305 | /* the following test is not needed, but it tests the replay code */ |
| 2318 | − if (READ_ONCE(ic->suspending) && !ic->meta_dev) | |
| 2306 | + if (unlikely(dm_suspended(ic->ti)) && !ic->meta_dev) | |
| 2319 | 2307 | return; |
| 2320 | 2308 | |
| 2321 | 2309 | spin_lock_irq(&ic->endio_wait.lock); |
| @@ -2376,7 +2364,7 @@ static void integrity_recalc(struct work_struct *w) · 54 unmodified lines | ||
| 2376 | 2364 | |
| 2377 | 2365 | next_chunk: |
| 2378 | 2366 | |
| 2379 | − if (unlikely(READ_ONCE(ic->suspending))) | |
| 2367 | + if (unlikely(dm_suspended(ic->ti))) | |
| 2380 | 2368 | goto unlock_ret; |
| 2381 | 2369 | |
| 2382 | 2370 | range.logical_sector = le64_to_cpu(ic->sb->recalc_sector); |
| @@ -2501,7 +2489,7 @@ static void bitmap_block_work(struct work_struct *w) · 118 unmodified lines | ||
| 2501 | 2489 | dio->range.n_sectors, BITMAP_OP_TEST_ALL_SET)) { |
| 2502 | 2490 | remove_range(ic, &dio->range); |
| 2503 | 2491 | INIT_WORK(&dio->work, integrity_bio_wait); |
| 2504 | − queue_work(ic->wait_wq, &dio->work); | |
| 2492 | + queue_work(ic->offload_wq, &dio->work); | |
| 2505 | 2493 | } else { |
| 2506 | 2494 | block_bitmap_op(ic, ic->journal, dio->range.logical_sector, |
| 2507 | 2495 | dio->range.n_sectors, BITMAP_OP_SET); |
| @@ -2524,7 +2512,7 @@ static void bitmap_block_work(struct work_struct *w) · 16 unmodified lines | ||
| 2524 | 2512 | |
| 2525 | 2513 | remove_range(ic, &dio->range); |
| 2526 | 2514 | INIT_WORK(&dio->work, integrity_bio_wait); |
| 2527 | − queue_work(ic->wait_wq, &dio->work); | |
| 2515 | + queue_work(ic->offload_wq, &dio->work); | |
| 2528 | 2516 | } |
| 2529 | 2517 | |
| 2530 | 2518 | queue_delayed_work(ic->commit_wq, &ic->bitmap_flush_work, ic->bitmap_flush_interval); |
| @@ -2804,8 +2792,6 @@ static void dm_integrity_postsuspend(struct dm_target *ti) · 273 unmodified lines | ||
| 2804 | 2792 | |
| 2805 | 2793 | del_timer_sync(&ic->autocommit_timer); |
| 2806 | 2794 | |
| 2807 | − WRITE_ONCE(ic->suspending, 1); | |
| 2808 | − | |
| 2809 | 2795 | if (ic->recalc_wq) |
| 2810 | 2796 | drain_workqueue(ic->recalc_wq); |
| 2811 | 2797 | |
| @@ -2834,8 +2820,6 @@ static void dm_integrity_postsuspend(struct dm_target *ti) · 22 unmodified lines | ||
| 2834 | 2820 | #endif |
| 2835 | 2821 | } |
| 2836 | 2822 | |
| 2837 | − WRITE_ONCE(ic->suspending, 0); | |
| 2838 | − | |
| 2839 | 2823 | BUG_ON(!RB_EMPTY_ROOT(&ic->in_progress)); |
| 2840 | 2824 | |
| 2841 | 2825 | ic->journal_uptodate = true; |
| @@ -2888,17 +2872,24 @@ static void dm_integrity_resume(struct dm_target *ti) · 46 unmodified lines | ||
| 2888 | 2872 | } else { |
| 2889 | 2873 | replay_journal(ic); |
| 2890 | 2874 | if (ic->mode == 'B') { |
| 2891 | − int mode; | |
| 2892 | 2875 | ic->sb->flags |= cpu_to_le32(SB_FLAG_DIRTY_BITMAP); |
| 2893 | 2876 | ic->sb->log2_blocks_per_bitmap_bit = ic->log2_blocks_per_bitmap_bit; |
| 2894 | 2877 | r = sync_rw_sb(ic, REQ_OP_WRITE, REQ_FUA); |
| 2895 | 2878 | if (unlikely(r)) |
| 2896 | 2879 | dm_integrity_io_error(ic, "writing superblock", r); |
| 2897 | 2880 | |
| 2898 | − mode = ic->recalculate_flag ? BITMAP_OP_SET : BITMAP_OP_CLEAR; | |
| 2899 | − block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, mode); | |
| 2900 | − block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, mode); | |
| 2901 | − block_bitmap_op(ic, ic->may_write_bitmap, 0, ic->provided_data_sectors, mode); | |
| 2881 | + block_bitmap_op(ic, ic->journal, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR); | |
| 2882 | + block_bitmap_op(ic, ic->recalc_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR); | |
| 2883 | + block_bitmap_op(ic, ic->may_write_bitmap, 0, ic->provided_data_sectors, BITMAP_OP_CLEAR); | |
| 2884 | + if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) && | |
| 2885 | + le64_to_cpu(ic->sb->recalc_sector) < ic->provided_data_sectors) { | |
| 2886 | + block_bitmap_op(ic, ic->journal, le64_to_cpu(ic->sb->recalc_sector), | |
| 2887 | + ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET); | |
| 2888 | + block_bitmap_op(ic, ic->recalc_bitmap, le64_to_cpu(ic->sb->recalc_sector), | |
| 2889 | + ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET); | |
| 2890 | + block_bitmap_op(ic, ic->may_write_bitmap, le64_to_cpu(ic->sb->recalc_sector), | |
| 2891 | + ic->provided_data_sectors - le64_to_cpu(ic->sb->recalc_sector), BITMAP_OP_SET); | |
| 2892 | + } | |
| 2902 | 2893 | rw_journal_sectors(ic, REQ_OP_WRITE, REQ_FUA | REQ_SYNC, 0, |
| 2903 | 2894 | ic->n_bitmap_blocks * (BITMAP_BLOCK_SIZE >> SECTOR_SHIFT), NULL); |
| 2904 | 2895 | } |
| @@ -2967,7 +2958,7 @@ static void dm_integrity_status(struct dm_target *ti, status_type_t type, · 62 unmodified lines | ||
| 2967 | 2958 | DMEMIT(" meta_device:%s", ic->meta_dev->name); |
| 2968 | 2959 | if (ic->sectors_per_block != 1) |
| 2969 | 2960 | DMEMIT(" block_size:%u", ic->sectors_per_block << SECTOR_SHIFT); |
| 2970 | − if (ic->recalculate_flag) | |
| 2961 | + if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING)) | |
| 2971 | 2962 | DMEMIT(" recalculate"); |
| 2972 | 2963 | DMEMIT(" journal_sectors:%u", ic->initial_sectors - SB_SECTORS); |
| 2973 | 2964 | DMEMIT(" interleave_sectors:%u", 1U << ic->sb->log2_interleave_sectors); |
| @@ -3623,6 +3614,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) · 649 unmodified lines | ||
| 3623 | 3614 | } |
| 3624 | 3615 | ti->private = ic; |
| 3625 | 3616 | ti->per_io_data_size = sizeof(struct dm_integrity_io); |
| 3617 | + ic->ti = ti; | |
| 3626 | 3618 | |
| 3627 | 3619 | ic->in_progress = RB_ROOT; |
| 3628 | 3620 | INIT_LIST_HEAD(&ic->wait_list); |
| @@ -3836,6 +3828,14 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv) · 207 unmodified lines | ||
| 3836 | 3828 | goto bad; |
| 3837 | 3829 | } |
| 3838 | 3830 | |
| 3831 | + ic->offload_wq = alloc_workqueue("dm-integrity-offload", WQ_MEM_RECLAIM, | |
| 3832 | + METADATA_WORKQUEUE_MAX_ACTIVE); | |
| 3833 | + if (!ic->offload_wq) { | |
| 3834 | + ti->error = "Cannot allocate workqueue"; | |
| 3835 | + r = -ENOMEM; | |
| 3836 | + goto bad; | |
| 3837 | + } | |
| 3838 | + | |
| 3839 | 3839 | ic->commit_wq = alloc_workqueue("dm-integrity-commit", WQ_MEM_RECLAIM, 1); |
| 3840 | 3840 | if (!ic->commit_wq) { |
| 3841 | 3841 | ti->error = "Cannot allocate workqueue"; |
| @@ -4140,6 +4140,8 @@ static void dm_integrity_dtr(struct dm_target *ti) · 298 unmodified lines | ||
| 4140 | 4140 | destroy_workqueue(ic->metadata_wq); |
| 4141 | 4141 | if (ic->wait_wq) |
| 4142 | 4142 | destroy_workqueue(ic->wait_wq); |
| 4143 | + if (ic->offload_wq) | |
| 4144 | + destroy_workqueue(ic->offload_wq); | |
| 4143 | 4145 | if (ic->commit_wq) |
| 4144 | 4146 | destroy_workqueue(ic->commit_wq); |
| 4145 | 4147 | if (ic->writer_wq) |
| @@ -4200,7 +4202,7 @@ static void dm_integrity_dtr(struct dm_target *ti) · 54 unmodified lines | ||
| 4200 | 4202 | |
| 4201 | 4203 | static struct target_type integrity_target = { |
| 4202 | 4204 | .name = "integrity", |
| 4203 | − .version = {1, 4, 0}, | |
| 4205 | + .version = {1, 5, 0}, | |
| 4204 | 4206 | .module = THIS_MODULE, |
| 4205 | 4207 | .features = DM_TARGET_SINGLETON | DM_TARGET_INTEGRITY, |
| 4206 | 4208 | .ctr = dm_integrity_ctr, |
| @@ -2053,7 +2053,7 @@ static int multipath_busy(struct dm_target *ti) · 2052 unmodified lines | ||
| 2053 | 2053 | *---------------------------------------------------------------*/ |
| 2054 | 2054 | static struct target_type multipath_target = { |
| 2055 | 2055 | .name = "multipath", |
| 2056 | − .version = {1, 13, 0}, | |
| 2056 | + .version = {1, 14, 0}, | |
| 2057 | 2057 | .features = DM_TARGET_SINGLETON | DM_TARGET_IMMUTABLE | |
| 2058 | 2058 | DM_TARGET_PASSES_INTEGRITY, |
| 2059 | 2059 | .module = THIS_MODULE, |
| @@ -960,9 +960,9 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd) · 959 unmodified lines | ||
| 960 | 960 | DMWARN("%s: __commit_transaction() failed, error = %d", |
| 961 | 961 | __func__, r); |
| 962 | 962 | } |
| 963 | + pmd_write_unlock(pmd); | |
| 963 | 964 | if (!pmd->fail_io) |
| 964 | 965 | __destroy_persistent_data_objects(pmd); |
| 965 | − pmd_write_unlock(pmd); | |
| 966 | 966 | |
| 967 | 967 | kfree(pmd); |
| 968 | 968 | return 0; |
| @@ -1221,7 +1221,7 @@ bad: · 1220 unmodified lines | ||
| 1221 | 1221 | |
| 1222 | 1222 | static struct target_type verity_target = { |
| 1223 | 1223 | .name = "verity", |
| 1224 | − .version = {1, 5, 0}, | |
| 1224 | + .version = {1, 6, 0}, | |
| 1225 | 1225 | .module = THIS_MODULE, |
| 1226 | 1226 | .ctr = verity_ctr, |
| 1227 | 1227 | .dtr = verity_dtr, |
| @@ -625,6 +625,12 @@ static void writecache_add_to_freelist(struct dm_writecache *wc, struct wc_entry · 624 unmodified lines | ||
| 625 | 625 | wc->freelist_size++; |
| 626 | 626 | } |
| 627 | 627 | |
| 628 | +static inline void writecache_verify_watermark(struct dm_writecache *wc) | |
| 629 | +{ | |
| 630 | + if (unlikely(wc->freelist_size + wc->writeback_size <= wc->freelist_high_watermark)) | |
| 631 | + queue_work(wc->writeback_wq, &wc->writeback_work); | |
| 632 | +} | |
| 633 | + | |
| 628 | 634 | static struct wc_entry *writecache_pop_from_freelist(struct dm_writecache *wc, sector_t expected_sector) |
| 629 | 635 | { |
| 630 | 636 | struct wc_entry *e; |
| @@ -650,8 +656,8 @@ static struct wc_entry *writecache_pop_from_freelist(struct dm_writecache *wc, s · 19 unmodified lines | ||
| 650 | 656 | list_del(&e->lru); |
| 651 | 657 | } |
| 652 | 658 | wc->freelist_size--; |
| 653 | − if (unlikely(wc->freelist_size + wc->writeback_size <= wc->freelist_high_watermark)) | |
| 654 | − queue_work(wc->writeback_wq, &wc->writeback_work); | |
| 659 | + | |
| 660 | + writecache_verify_watermark(wc); | |
| 655 | 661 | |
| 656 | 662 | return e; |
| 657 | 663 | } |
| @@ -842,7 +848,7 @@ static void writecache_suspend(struct dm_target *ti) · 184 unmodified lines | ||
| 842 | 848 | } |
| 843 | 849 | wc_unlock(wc); |
| 844 | 850 | |
| 845 | − flush_workqueue(wc->writeback_wq); | |
| 851 | + drain_workqueue(wc->writeback_wq); | |
| 846 | 852 | |
| 847 | 853 | wc_lock(wc); |
| 848 | 854 | if (flush_on_suspend) |
| @@ -965,6 +971,8 @@ erase_this: · 116 unmodified lines | ||
| 965 | 971 | writecache_commit_flushed(wc, false); |
| 966 | 972 | } |
| 967 | 973 | |
| 974 | + writecache_verify_watermark(wc); | |
| 975 | + | |
| 968 | 976 | wc_unlock(wc); |
| 969 | 977 | } |
| 970 | 978 | |
| @@ -2312,7 +2320,7 @@ static void writecache_status(struct dm_target *ti, status_type_t type, · 1341 unmodified lines | ||
| 2312 | 2320 | |
| 2313 | 2321 | static struct target_type writecache_target = { |
| 2314 | 2322 | .name = "writecache", |
| 2315 | − .version = {1, 1, 1}, | |
| 2323 | + .version = {1, 2, 0}, | |
| 2316 | 2324 | .module = THIS_MODULE, |
| 2317 | 2325 | .ctr = writecache_ctr, |
| 2318 | 2326 | .dtr = writecache_dtr, |
| @@ -533,8 +533,9 @@ static int dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio) · 532 unmodified lines | ||
| 533 | 533 | |
| 534 | 534 | /* Get the BIO chunk work. If one is not active yet, create one */ |
| 535 | 535 | cw = radix_tree_lookup(&dmz->chunk_rxtree, chunk); |
| 536 | − if (!cw) { | |
| 537 | − | |
| 536 | + if (cw) { | |
| 537 | + dmz_get_chunk_work(cw); | |
| 538 | + } else { | |
| 538 | 539 | /* Create a new chunk work */ |
| 539 | 540 | cw = kmalloc(sizeof(struct dm_chunk_work), GFP_NOIO); |
| 540 | 541 | if (unlikely(!cw)) { |
| @@ -543,7 +544,7 @@ static int dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio) · 2 unmodified lines | ||
| 543 | 544 | } |
| 544 | 545 | |
| 545 | 546 | INIT_WORK(&cw->work, dmz_chunk_work); |
| 546 | − refcount_set(&cw->refcount, 0); | |
| 547 | + refcount_set(&cw->refcount, 1); | |
| 547 | 548 | cw->target = dmz; |
| 548 | 549 | cw->chunk = chunk; |
| 549 | 550 | bio_list_init(&cw->bio_list); |
| @@ -556,7 +557,6 @@ static int dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio) · 6 unmodified lines | ||
| 556 | 557 | } |
| 557 | 558 | |
| 558 | 559 | bio_list_add(&cw->bio_list, bio); |
| 559 | − dmz_get_chunk_work(cw); | |
| 560 | 560 | |
| 561 | 561 | dmz_reclaim_bio_acc(dmz->reclaim); |
| 562 | 562 | if (queue_work(dmz->chunk_wq, &cw->work)) |
| @@ -967,7 +967,7 @@ static int dmz_iterate_devices(struct dm_target *ti, · 404 unmodified lines | ||
| 967 | 967 | |
| 968 | 968 | static struct target_type dmz_type = { |
| 969 | 969 | .name = "zoned", |
| 970 | − .version = {1, 0, 0}, | |
| 970 | + .version = {1, 1, 0}, | |
| 971 | 971 | .features = DM_TARGET_SINGLETON | DM_TARGET_ZONED_HM, |
| 972 | 972 | .module = THIS_MODULE, |
| 973 | 973 | .ctr = dmz_ctr, |
| @@ -1788,7 +1788,8 @@ static int dm_any_congested(void *congested_data, int bdi_bits) · 1787 unmodified lines | ||
| 1788 | 1788 | * With request-based DM we only need to check the |
| 1789 | 1789 | * top-level queue for congestion. |
| 1790 | 1790 | */ |
| 1791 | − r = md->queue->backing_dev_info->wb.state & bdi_bits; | |
| 1791 | + struct backing_dev_info *bdi = md->queue->backing_dev_info; | |
| 1792 | + r = bdi->wb.congested->state & bdi_bits; | |
| 1792 | 1793 | } else { |
| 1793 | 1794 | map = dm_get_live_table_fast(md); |
| 1794 | 1795 | if (map) |
| @@ -1854,15 +1855,6 @@ static const struct dax_operations dm_dax_ops; · 59 unmodified lines | ||
| 1854 | 1855 | |
| 1855 | 1856 | static void dm_wq_work(struct work_struct *work); |
| 1856 | 1857 | |
| 1857 | −static void dm_init_normal_md_queue(struct mapped_device *md) | |
| 1858 | −{ | |
| 1859 | − /* | |
| 1860 | − * Initialize aspects of queue that aren't relevant for blk-mq | |
| 1861 | − */ | |
| 1862 | − md->queue->backing_dev_info->congested_data = md; | |
| 1863 | − md->queue->backing_dev_info->congested_fn = dm_any_congested; | |
| 1864 | −} | |
| 1865 | − | |
| 1866 | 1858 | static void cleanup_mapped_device(struct mapped_device *md) |
| 1867 | 1859 | { |
| 1868 | 1860 | if (md->wq) |
| @@ -2249,6 +2241,12 @@ struct queue_limits *dm_get_queue_limits(struct mapped_device *md) · 380 unmodified lines | ||
| 2249 | 2241 | } |
| 2250 | 2242 | EXPORT_SYMBOL_GPL(dm_get_queue_limits); |
| 2251 | 2243 | |
| 2244 | +static void dm_init_congested_fn(struct mapped_device *md) | |
| 2245 | +{ | |
| 2246 | + md->queue->backing_dev_info->congested_data = md; | |
| 2247 | + md->queue->backing_dev_info->congested_fn = dm_any_congested; | |
| 2248 | +} | |
| 2249 | + | |
| 2252 | 2250 | /* |
| 2253 | 2251 | * Setup the DM device's queue based on md's type |
| 2254 | 2252 | */ |
| @@ -2265,11 +2263,12 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t) · 10 unmodified lines | ||
| 2265 | 2263 | DMERR("Cannot initialize queue for request-based dm-mq mapped device"); |
| 2266 | 2264 | return r; |
| 2267 | 2265 | } |
| 2266 | + dm_init_congested_fn(md); | |
| 2268 | 2267 | break; |
| 2269 | 2268 | case DM_TYPE_BIO_BASED: |
| 2270 | 2269 | case DM_TYPE_DAX_BIO_BASED: |
| 2271 | 2270 | case DM_TYPE_NVME_BIO_BASED: |
| 2272 | − dm_init_normal_md_queue(md); | |
| 2271 | + dm_init_congested_fn(md); | |
| 2273 | 2272 | break; |
| 2274 | 2273 | case DM_TYPE_NONE: |
| 2275 | 2274 | WARN_ON_ONCE(true); |
| @@ -2368,6 +2367,7 @@ static void __dm_destroy(struct mapped_device *md, bool wait) · 92 unmodified lines | ||
| 2368 | 2367 | map = dm_get_live_table(md, &srcu_idx); |
| 2369 | 2368 | if (!dm_suspended_md(md)) { |
| 2370 | 2369 | dm_table_presuspend_targets(map); |
| 2370 | + set_bit(DMF_SUSPENDED, &md->flags); | |
| 2371 | 2371 | dm_table_postsuspend_targets(map); |
| 2372 | 2372 | } |
| 2373 | 2373 | /* dm_put_live_table must be before msleep, otherwise deadlock is possible */ |
| @@ -639,9 +639,9 @@ int media_get_pad_index(struct media_entity *entity, bool is_sink, · 638 unmodified lines | ||
| 639 | 639 | return -EINVAL; |
| 640 | 640 | |
| 641 | 641 | for (i = 0; i < entity->num_pads; i++) { |
| 642 | − if (entity->pads[i].flags == MEDIA_PAD_FL_SINK) | |
| 642 | + if (entity->pads[i].flags & MEDIA_PAD_FL_SINK) | |
| 643 | 643 | pad_is_sink = true; |
| 644 | − else if (entity->pads[i].flags == MEDIA_PAD_FL_SOURCE) | |
| 644 | + else if (entity->pads[i].flags & MEDIA_PAD_FL_SOURCE) | |
| 645 | 645 | pad_is_sink = false; |
| 646 | 646 | else |
| 647 | 647 | continue; /* This is an error! */ |
| @@ -27,17 +27,17 @@ static const struct v4l2_fwht_pixfmt_info v4l2_fwht_pixfmts[] = { · 26 unmodified lines | ||
| 27 | 27 | { V4L2_PIX_FMT_BGR24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, |
| 28 | 28 | { V4L2_PIX_FMT_RGB24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, |
| 29 | 29 | { V4L2_PIX_FMT_HSV24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, |
| 30 | − { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
| 31 | − { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
| 30 | + { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, | |
| 31 | + { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, | |
| 32 | 32 | { V4L2_PIX_FMT_ABGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, |
| 33 | − { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
| 34 | − { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
| 33 | + { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, | |
| 34 | + { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, | |
| 35 | 35 | { V4L2_PIX_FMT_ARGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, |
| 36 | − { V4L2_PIX_FMT_BGRX32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
| 36 | + { V4L2_PIX_FMT_BGRX32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, | |
| 37 | 37 | { V4L2_PIX_FMT_BGRA32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, |
| 38 | − { V4L2_PIX_FMT_RGBX32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, | |
| 38 | + { V4L2_PIX_FMT_RGBX32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, | |
| 39 | 39 | { V4L2_PIX_FMT_RGBA32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, |
| 40 | − { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, | |
| 40 | + { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_HSV}, | |
| 41 | 41 | { V4L2_PIX_FMT_GREY, 1, 1, 1, 1, 0, 1, 1, 1, 1, FWHT_FL_PIXENC_RGB}, |
| 42 | 42 | }; |
| 43 | 43 | |
| @@ -175,22 +175,14 @@ static int prepare_raw_frame(struct fwht_raw_frame *rf, · 131 unmodified lines | ||
| 175 | 175 | case V4L2_PIX_FMT_RGB32: |
| 176 | 176 | case V4L2_PIX_FMT_XRGB32: |
| 177 | 177 | case V4L2_PIX_FMT_HSV32: |
| 178 | − rf->cr = rf->luma + 1; | |
| 179 | − rf->cb = rf->cr + 2; | |
| 180 | − rf->luma += 2; | |
| 181 | − break; | |
| 182 | − case V4L2_PIX_FMT_BGR32: | |
| 183 | − case V4L2_PIX_FMT_XBGR32: | |
| 184 | − rf->cb = rf->luma; | |
| 185 | − rf->cr = rf->cb + 2; | |
| 186 | − rf->luma++; | |
| 187 | − break; | |
| 188 | 178 | case V4L2_PIX_FMT_ARGB32: |
| 189 | 179 | rf->alpha = rf->luma; |
| 190 | 180 | rf->cr = rf->luma + 1; |
| 191 | 181 | rf->cb = rf->cr + 2; |
| 192 | 182 | rf->luma += 2; |
| 193 | 183 | break; |
| 184 | + case V4L2_PIX_FMT_BGR32: | |
| 185 | + case V4L2_PIX_FMT_XBGR32: | |
| 194 | 186 | case V4L2_PIX_FMT_ABGR32: |
| 195 | 187 | rf->cb = rf->luma; |
| 196 | 188 | rf->cr = rf->cb + 2; |
| @@ -198,10 +190,6 @@ static int prepare_raw_frame(struct fwht_raw_frame *rf, · 1 unmodified line | ||
| 198 | 190 | rf->alpha = rf->cr + 1; |
| 199 | 191 | break; |
| 200 | 192 | case V4L2_PIX_FMT_BGRX32: |
| 201 | − rf->cb = rf->luma + 1; | |
| 202 | − rf->cr = rf->cb + 2; | |
| 203 | − rf->luma += 2; | |
| 204 | − break; | |
| 205 | 193 | case V4L2_PIX_FMT_BGRA32: |
| 206 | 194 | rf->alpha = rf->luma; |
| 207 | 195 | rf->cb = rf->luma + 1; |
| @@ -209,10 +197,6 @@ static int prepare_raw_frame(struct fwht_raw_frame *rf, · 1 unmodified line | ||
| 209 | 197 | rf->luma += 2; |
| 210 | 198 | break; |
| 211 | 199 | case V4L2_PIX_FMT_RGBX32: |
| 212 | − rf->cr = rf->luma; | |
| 213 | − rf->cb = rf->cr + 2; | |
| 214 | − rf->luma++; | |
| 215 | − break; | |
| 216 | 200 | case V4L2_PIX_FMT_RGBA32: |
| 217 | 201 | rf->alpha = rf->luma + 3; |
| 218 | 202 | rf->cr = rf->luma; |
| @@ -635,8 +635,6 @@ static void pulse8_cec_adap_free(struct cec_adapter *adap) · 634 unmodified lines | ||
| 635 | 635 | cancel_delayed_work_sync(&pulse8->ping_eeprom_work); |
| 636 | 636 | cancel_work_sync(&pulse8->irq_work); |
| 637 | 637 | cancel_work_sync(&pulse8->tx_work); |
| 638 | − serio_close(pulse8->serio); | |
| 639 | − serio_set_drvdata(pulse8->serio, NULL); | |
| 640 | 638 | kfree(pulse8); |
| 641 | 639 | } |
| 642 | 640 | |
| @@ -652,6 +650,9 @@ static void pulse8_disconnect(struct serio *serio) · 9 unmodified lines | ||
| 652 | 650 | struct pulse8 *pulse8 = serio_get_drvdata(serio); |
| 653 | 651 | |
| 654 | 652 | cec_unregister_adapter(pulse8->adap); |
| 653 | + pulse8->serio = NULL; | |
| 654 | + serio_set_drvdata(serio, NULL); | |
| 655 | + serio_close(serio); | |
| 655 | 656 | } |
| 656 | 657 | |
| 657 | 658 | static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio, |
| @@ -840,6 +841,8 @@ static int pulse8_connect(struct serio *serio, struct serio_driver *drv) · 182 unmodified lines | ||
| 840 | 841 | serio_set_drvdata(serio, pulse8); |
| 841 | 842 | INIT_WORK(&pulse8->irq_work, pulse8_irq_work_handler); |
| 842 | 843 | INIT_WORK(&pulse8->tx_work, pulse8_tx_work_handler); |
| 844 | + INIT_DELAYED_WORK(&pulse8->ping_eeprom_work, | |
| 845 | + pulse8_ping_eeprom_work_handler); | |
| 843 | 846 | mutex_init(&pulse8->lock); |
| 844 | 847 | spin_lock_init(&pulse8->msg_lock); |
| 845 | 848 | pulse8->config_pending = false; |
| @@ -865,17 +868,16 @@ static int pulse8_connect(struct serio *serio, struct serio_driver *drv) · 19 unmodified lines | ||
| 865 | 868 | pulse8->restoring_config = true; |
| 866 | 869 | } |
| 867 | 870 | |
| 868 | − INIT_DELAYED_WORK(&pulse8->ping_eeprom_work, | |
| 869 | − pulse8_ping_eeprom_work_handler); | |
| 870 | 871 | schedule_delayed_work(&pulse8->ping_eeprom_work, PING_PERIOD); |
| 871 | 872 | |
| 872 | 873 | return 0; |
| 873 | 874 | |
| 874 | 875 | close_serio: |
| 876 | + pulse8->serio = NULL; | |
| 877 | + serio_set_drvdata(serio, NULL); | |
| 875 | 878 | serio_close(serio); |
| 876 | 879 | delete_adap: |
| 877 | 880 | cec_delete_adapter(pulse8->adap); |
| 878 | − serio_set_drvdata(serio, NULL); | |
| 879 | 881 | free_device: |
| 880 | 882 | kfree(pulse8); |
| 881 | 883 | return err; |
| @@ -880,12 +880,12 @@ int v4l2_m2m_register_media_controller(struct v4l2_m2m_dev *m2m_dev, · 879 unmodified lines | ||
| 880 | 880 | goto err_rel_entity1; |
| 881 | 881 | |
| 882 | 882 | /* Connect the three entities */ |
| 883 | − ret = media_create_pad_link(m2m_dev->source, 0, &m2m_dev->proc, 1, | |
| 883 | + ret = media_create_pad_link(m2m_dev->source, 0, &m2m_dev->proc, 0, | |
| 884 | 884 | MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); |
| 885 | 885 | if (ret) |
| 886 | 886 | goto err_rel_entity2; |
| 887 | 887 | |
| 888 | − ret = media_create_pad_link(&m2m_dev->proc, 0, &m2m_dev->sink, 0, | |
| 888 | + ret = media_create_pad_link(&m2m_dev->proc, 1, &m2m_dev->sink, 0, | |
| 889 | 889 | MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED); |
| 890 | 890 | if (ret) |
| 891 | 891 | goto err_rm_links0; |
| @@ -2112,8 +2112,8 @@ exit_done: · 2111 unmodified lines | ||
| 2112 | 2112 | return status; |
| 2113 | 2113 | } |
| 2114 | 2114 | |
| 2115 | −static int altera_get_note(u8 *p, s32 program_size, | |
| 2116 | − s32 *offset, char *key, char *value, int length) | |
| 2115 | +static int altera_get_note(u8 *p, s32 program_size, s32 *offset, | |
| 2116 | + char *key, char *value, int keylen, int vallen) | |
| 2117 | 2117 | /* |
| 2118 | 2118 | * Gets key and value of NOTE fields in the JBC file. |
| 2119 | 2119 | * Can be called in two modes: if offset pointer is NULL, |
| @@ -2170,7 +2170,7 @@ static int altera_get_note(u8 *p, s32 program_size, · 50 unmodified lines | ||
| 2170 | 2170 | &p[note_table + (8 * i) + 4])]; |
| 2171 | 2171 | |
| 2172 | 2172 | if (value != NULL) |
| 2173 | − strlcpy(value, value_ptr, length); | |
| 2173 | + strlcpy(value, value_ptr, vallen); | |
| 2174 | 2174 | |
| 2175 | 2175 | } |
| 2176 | 2176 | } |
| @@ -2189,13 +2189,13 @@ static int altera_get_note(u8 *p, s32 program_size, · 12 unmodified lines | ||
| 2189 | 2189 | strlcpy(key, &p[note_strings + |
| 2190 | 2190 | get_unaligned_be32( |
| 2191 | 2191 | &p[note_table + (8 * i)])], |
| 2192 | − length); | |
| 2192 | + keylen); | |
| 2193 | 2193 | |
| 2194 | 2194 | if (value != NULL) |
| 2195 | 2195 | strlcpy(value, &p[note_strings + |
| 2196 | 2196 | get_unaligned_be32( |
| 2197 | 2197 | &p[note_table + (8 * i) + 4])], |
| 2198 | − length); | |
| 2198 | + vallen); | |
| 2199 | 2199 | |
| 2200 | 2200 | *offset = i + 1; |
| 2201 | 2201 | } |
| @@ -2449,7 +2449,7 @@ int altera_init(struct altera_config *config, const struct firmware *fw) · 247 unmodified lines | ||
| 2449 | 2449 | __func__, (format_version == 2) ? "Jam STAPL" : |
| 2450 | 2450 | "pre-standardized Jam 1.1"); |
| 2451 | 2451 | while (altera_get_note((u8 *)fw->data, fw->size, |
| 2452 | − &offset, key, value, 256) == 0) | |
| 2452 | + &offset, key, value, 32, 256) == 0) | |
| 2453 | 2453 | printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n", |
| 2454 | 2454 | __func__, key, value); |
| 2455 | 2455 | } |
| @@ -394,7 +394,7 @@ static const struct pcr_ops rts522a_pcr_ops = { · 393 unmodified lines | ||
| 394 | 394 | void rts522a_init_params(struct rtsx_pcr *pcr) |
| 395 | 395 | { |
| 396 | 396 | rts5227_init_params(pcr); |
| 397 | − | |
| 397 | + pcr->tx_initial_phase = SET_CLOCK_PHASE(20, 20, 11); | |
| 398 | 398 | pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3; |
| 399 | 399 | |
| 400 | 400 | pcr->option.ocp_en = 1; |
| @@ -618,6 +618,7 @@ static const struct pcr_ops rts524a_pcr_ops = { · 617 unmodified lines | ||
| 618 | 618 | void rts524a_init_params(struct rtsx_pcr *pcr) |
| 619 | 619 | { |
| 620 | 620 | rts5249_init_params(pcr); |
| 621 | + pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); | |
| 621 | 622 | pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; |
| 622 | 623 | pcr->option.ltr_l1off_snooze_sspwrgate = |
| 623 | 624 | LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; |
| @@ -733,6 +734,7 @@ static const struct pcr_ops rts525a_pcr_ops = { · 109 unmodified lines | ||
| 733 | 734 | void rts525a_init_params(struct rtsx_pcr *pcr) |
| 734 | 735 | { |
| 735 | 736 | rts5249_init_params(pcr); |
| 737 | + pcr->tx_initial_phase = SET_CLOCK_PHASE(25, 29, 11); | |
| 736 | 738 | pcr->option.ltr_l1off_sspwrgate = LTR_L1OFF_SSPWRGATE_5250_DEF; |
| 737 | 739 | pcr->option.ltr_l1off_snooze_sspwrgate = |
| 738 | 740 | LTR_L1OFF_SNOOZE_SSPWRGATE_5250_DEF; |
| @@ -662,7 +662,7 @@ void rts5260_init_params(struct rtsx_pcr *pcr) · 661 unmodified lines | ||
| 662 | 662 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; |
| 663 | 663 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; |
| 664 | 664 | pcr->aspm_en = ASPM_L1_EN; |
| 665 | − pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16); | |
| 665 | + pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 29, 11); | |
| 666 | 666 | pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); |
| 667 | 667 | |
| 668 | 668 | pcr->ic_version = rts5260_get_ic_version(pcr); |
| @@ -764,7 +764,7 @@ void rts5261_init_params(struct rtsx_pcr *pcr) · 763 unmodified lines | ||
| 764 | 764 | pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B; |
| 765 | 765 | pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B; |
| 766 | 766 | pcr->aspm_en = ASPM_L1_EN; |
| 767 | − pcr->tx_initial_phase = SET_CLOCK_PHASE(20, 27, 16); | |
| 767 | + pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 11); | |
| 768 | 768 | pcr->rx_initial_phase = SET_CLOCK_PHASE(24, 6, 5); |
| 769 | 769 | |
| 770 | 770 | pcr->ic_version = rts5261_get_ic_version(pcr); |
| @@ -712,13 +712,14 @@ static int at24_probe(struct i2c_client *client) · 711 unmodified lines | ||
| 712 | 712 | * chip is functional. |
| 713 | 713 | */ |
| 714 | 714 | err = at24_read(at24, 0, &test_byte, 1); |
| 715 | − pm_runtime_idle(dev); | |
| 716 | 715 | if (err) { |
| 717 | 716 | pm_runtime_disable(dev); |
| 718 | 717 | regulator_disable(at24->vcc_reg); |
| 719 | 718 | return -ENODEV; |
| 720 | 719 | } |
| 721 | 720 | |
| 721 | + pm_runtime_idle(dev); | |
| 722 | + | |
| 722 | 723 | if (writable) |
| 723 | 724 | dev_info(dev, "%u byte %s EEPROM, writable, %u bytes/write\n", |
| 724 | 725 | byte_len, client->name, at24->write_max); |
| @@ -1732,8 +1732,11 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, · 1731 unmodified lines | ||
| 1732 | 1732 | * the erase operation does not exceed the max_busy_timeout, we should |
| 1733 | 1733 | * use R1B response. Or we need to prevent the host from doing hw busy |
| 1734 | 1734 | * detection, which is done by converting to a R1 response instead. |
| 1735 | + * Note, some hosts requires R1B, which also means they are on their own | |
| 1736 | + * when it comes to deal with the busy timeout. | |
| 1735 | 1737 | */ |
| 1736 | − if (card->host->max_busy_timeout && | |
| 1738 | + if (!(card->host->caps & MMC_CAP_NEED_RSP_BUSY) && | |
| 1739 | + card->host->max_busy_timeout && | |
| 1737 | 1740 | busy_timeout > card->host->max_busy_timeout) { |
| 1738 | 1741 | cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; |
| 1739 | 1742 | } else { |
| @@ -1910,9 +1910,12 @@ static int mmc_sleep(struct mmc_host *host) · 1909 unmodified lines | ||
| 1910 | 1910 | * If the max_busy_timeout of the host is specified, validate it against |
| 1911 | 1911 | * the sleep cmd timeout. A failure means we need to prevent the host |
| 1912 | 1912 | * from doing hw busy detection, which is done by converting to a R1 |
| 1913 | − * response instead of a R1B. | |
| 1913 | + * response instead of a R1B. Note, some hosts requires R1B, which also | |
| 1914 | + * means they are on their own when it comes to deal with the busy | |
| 1915 | + * timeout. | |
| 1914 | 1916 | */ |
| 1915 | − if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) { | |
| 1917 | + if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout && | |
| 1918 | + (timeout_ms > host->max_busy_timeout)) { | |
| 1916 | 1919 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 1917 | 1920 | } else { |
| 1918 | 1921 | cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; |
| @@ -542,9 +542,11 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, · 541 unmodified lines | ||
| 542 | 542 | * If the max_busy_timeout of the host is specified, make sure it's |
| 543 | 543 | * enough to fit the used timeout_ms. In case it's not, let's instruct |
| 544 | 544 | * the host to avoid HW busy detection, by converting to a R1 response |
| 545 | − * instead of a R1B. | |
| 545 | + * instead of a R1B. Note, some hosts requires R1B, which also means | |
| 546 | + * they are on their own when it comes to deal with the busy timeout. | |
| 546 | 547 | */ |
| 547 | − if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) | |
| 548 | + if (!(host->caps & MMC_CAP_NEED_RSP_BUSY) && host->max_busy_timeout && | |
| 549 | + (timeout_ms > host->max_busy_timeout)) | |
| 548 | 550 | use_r1b_resp = false; |
| 549 | 551 | |
| 550 | 552 | cmd.opcode = MMC_SWITCH; |
| @@ -606,19 +606,22 @@ static int sd_change_phase(struct realtek_pci_sdmmc *host, · 605 unmodified lines | ||
| 606 | 606 | u8 sample_point, bool rx) |
| 607 | 607 | { |
| 608 | 608 | struct rtsx_pcr *pcr = host->pcr; |
| 609 | − | |
| 609 | + u16 SD_VP_CTL = 0; | |
| 610 | 610 | dev_dbg(sdmmc_dev(host), "%s(%s): sample_point = %d\n", |
| 611 | 611 | __func__, rx ? "RX" : "TX", sample_point); |
| 612 | 612 | |
| 613 | 613 | rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, CHANGE_CLK); |
| 614 | − if (rx) | |
| 614 | + if (rx) { | |
| 615 | + SD_VP_CTL = SD_VPRX_CTL; | |
| 615 | 616 | rtsx_pci_write_register(pcr, SD_VPRX_CTL, |
| 616 | 617 | PHASE_SELECT_MASK, sample_point); |
| 617 | − else | |
| 618 | + } else { | |
| 619 | + SD_VP_CTL = SD_VPTX_CTL; | |
| 618 | 620 | rtsx_pci_write_register(pcr, SD_VPTX_CTL, |
| 619 | 621 | PHASE_SELECT_MASK, sample_point); |
| 620 | − rtsx_pci_write_register(pcr, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); | |
| 621 | − rtsx_pci_write_register(pcr, SD_VPCLK0_CTL, PHASE_NOT_RESET, | |
| 622 | + } | |
| 623 | + rtsx_pci_write_register(pcr, SD_VP_CTL, PHASE_NOT_RESET, 0); | |
| 624 | + rtsx_pci_write_register(pcr, SD_VP_CTL, PHASE_NOT_RESET, | |
| 622 | 625 | PHASE_NOT_RESET); |
| 623 | 626 | rtsx_pci_write_register(pcr, CLK_CTL, CHANGE_CLK, 0); |
| 624 | 627 | rtsx_pci_write_register(pcr, SD_CFG1, SD_ASYNC_FIFO_NOT_RST, 0); |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/pm.h> |
| 24 | 24 | #include <linux/pm_runtime.h> |
| 25 | 25 | #include <linux/delay.h> |
| 26 | +#include <linux/dmi.h> | |
| 26 | 27 | |
| 27 | 28 | #include <linux/mmc/host.h> |
| 28 | 29 | #include <linux/mmc/pm.h> |
| @@ -72,9 +73,16 @@ struct sdhci_acpi_host { · 43 unmodified lines | ||
| 72 | 73 | const struct sdhci_acpi_slot *slot; |
| 73 | 74 | struct platform_device *pdev; |
| 74 | 75 | bool use_runtime_pm; |
| 76 | + bool is_intel; | |
| 77 | + bool reset_signal_volt_on_suspend; | |
| 75 | 78 | unsigned long private[0] ____cacheline_aligned; |
| 76 | 79 | }; |
| 77 | 80 | |
| 81 | +enum { | |
| 82 | + DMI_QUIRK_RESET_SD_SIGNAL_VOLT_ON_SUSP = BIT(0), | |
| 83 | + DMI_QUIRK_SD_NO_WRITE_PROTECT = BIT(1), | |
| 84 | +}; | |
| 85 | + | |
| 78 | 86 | static inline void *sdhci_acpi_priv(struct sdhci_acpi_host *c) |
| 79 | 87 | { |
| 80 | 88 | return (void *)c->private; |
| @@ -391,6 +399,8 @@ static int intel_probe_slot(struct platform_device *pdev, struct acpi_device *ad · 310 unmodified lines | ||
| 391 | 399 | host->mmc_host_ops.start_signal_voltage_switch = |
| 392 | 400 | intel_start_signal_voltage_switch; |
| 393 | 401 | |
| 402 | + c->is_intel = true; | |
| 403 | + | |
| 394 | 404 | return 0; |
| 395 | 405 | } |
| 396 | 406 | |
| @@ -647,6 +657,36 @@ static const struct acpi_device_id sdhci_acpi_ids[] = { · 250 unmodified lines | ||
| 647 | 657 | }; |
| 648 | 658 | MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids); |
| 649 | 659 | |
| 660 | +static const struct dmi_system_id sdhci_acpi_quirks[] = { | |
| 661 | + { | |
| 662 | + /* | |
| 663 | + * The Lenovo Miix 320-10ICR has a bug in the _PS0 method of | |
| 664 | + * the SHC1 ACPI device, this bug causes it to reprogram the | |
| 665 | + * wrong LDO (DLDO3) to 1.8V if 1.8V modes are used and the | |
| 666 | + * card is (runtime) suspended + resumed. DLDO3 is used for | |
| 667 | + * the LCD and setting it to 1.8V causes the LCD to go black. | |
| 668 | + */ | |
| 669 | + .matches = { | |
| 670 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
| 671 | + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), | |
| 672 | + }, | |
| 673 | + .driver_data = (void *)DMI_QUIRK_RESET_SD_SIGNAL_VOLT_ON_SUSP, | |
| 674 | + }, | |
| 675 | + { | |
| 676 | + /* | |
| 677 | + * The Acer Aspire Switch 10 (SW5-012) microSD slot always | |
| 678 | + * reports the card being write-protected even though microSD | |
| 679 | + * cards do not have a write-protect switch at all. | |
| 680 | + */ | |
| 681 | + .matches = { | |
| 682 | + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | |
| 683 | + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), | |
| 684 | + }, | |
| 685 | + .driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT, | |
| 686 | + }, | |
| 687 | + {} /* Terminating entry */ | |
| 688 | +}; | |
| 689 | + | |
| 650 | 690 | static const struct sdhci_acpi_slot *sdhci_acpi_get_slot(struct acpi_device *adev) |
| 651 | 691 | { |
| 652 | 692 | const struct sdhci_acpi_uid_slot *u; |
| @@ -663,17 +703,23 @@ static int sdhci_acpi_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 663 | 703 | struct device *dev = &pdev->dev; |
| 664 | 704 | const struct sdhci_acpi_slot *slot; |
| 665 | 705 | struct acpi_device *device, *child; |
| 706 | + const struct dmi_system_id *id; | |
| 666 | 707 | struct sdhci_acpi_host *c; |
| 667 | 708 | struct sdhci_host *host; |
| 668 | 709 | struct resource *iomem; |
| 669 | 710 | resource_size_t len; |
| 670 | 711 | size_t priv_size; |
| 712 | + int quirks = 0; | |
| 671 | 713 | int err; |
| 672 | 714 | |
| 673 | 715 | device = ACPI_COMPANION(dev); |
| 674 | 716 | if (!device) |
| 675 | 717 | return -ENODEV; |
| 676 | 718 | |
| 719 | + id = dmi_first_match(sdhci_acpi_quirks); | |
| 720 | + if (id) | |
| 721 | + quirks = (long)id->driver_data; | |
| 722 | + | |
| 677 | 723 | slot = sdhci_acpi_get_slot(device); |
| 678 | 724 | |
| 679 | 725 | /* Power on the SDHCI controller and its children */ |
| @@ -759,6 +805,12 @@ static int sdhci_acpi_probe(struct platform_device *pdev) · 79 unmodified lines | ||
| 759 | 805 | dev_warn(dev, "failed to setup card detect gpio\n"); |
| 760 | 806 | c->use_runtime_pm = false; |
| 761 | 807 | } |
| 808 | + | |
| 809 | + if (quirks & DMI_QUIRK_RESET_SD_SIGNAL_VOLT_ON_SUSP) | |
| 810 | + c->reset_signal_volt_on_suspend = true; | |
| 811 | + | |
| 812 | + if (quirks & DMI_QUIRK_SD_NO_WRITE_PROTECT) | |
| 813 | + host->mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT; | |
| 762 | 814 | } |
| 763 | 815 | |
| 764 | 816 | err = sdhci_setup_host(host); |
| @@ -823,17 +875,39 @@ static int sdhci_acpi_remove(struct platform_device *pdev) · 58 unmodified lines | ||
| 823 | 875 | return 0; |
| 824 | 876 | } |
| 825 | 877 | |
| 878 | +static void __maybe_unused sdhci_acpi_reset_signal_voltage_if_needed( | |
| 879 | + struct device *dev) | |
| 880 | +{ | |
| 881 | + struct sdhci_acpi_host *c = dev_get_drvdata(dev); | |
| 882 | + struct sdhci_host *host = c->host; | |
| 883 | + | |
| 884 | + if (c->is_intel && c->reset_signal_volt_on_suspend && | |
| 885 | + host->mmc->ios.signal_voltage != MMC_SIGNAL_VOLTAGE_330) { | |
| 886 | + struct intel_host *intel_host = sdhci_acpi_priv(c); | |
| 887 | + unsigned int fn = INTEL_DSM_V33_SWITCH; | |
| 888 | + u32 result = 0; | |
| 889 | + | |
| 890 | + intel_dsm(intel_host, dev, fn, &result); | |
| 891 | + } | |
| 892 | +} | |
| 893 | + | |
| 826 | 894 | #ifdef CONFIG_PM_SLEEP |
| 827 | 895 | |
| 828 | 896 | static int sdhci_acpi_suspend(struct device *dev) |
| 829 | 897 | { |
| 830 | 898 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); |
| 831 | 899 | struct sdhci_host *host = c->host; |
| 900 | + int ret; | |
| 832 | 901 | |
| 833 | 902 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) |
| 834 | 903 | mmc_retune_needed(host->mmc); |
| 835 | 904 | |
| 836 | − return sdhci_suspend_host(host); | |
| 905 | + ret = sdhci_suspend_host(host); | |
| 906 | + if (ret) | |
| 907 | + return ret; | |
| 908 | + | |
| 909 | + sdhci_acpi_reset_signal_voltage_if_needed(dev); | |
| 910 | + return 0; | |
| 837 | 911 | } |
| 838 | 912 | |
| 839 | 913 | static int sdhci_acpi_resume(struct device *dev) |
| @@ -853,11 +927,17 @@ static int sdhci_acpi_runtime_suspend(struct device *dev) · 13 unmodified lines | ||
| 853 | 927 | { |
| 854 | 928 | struct sdhci_acpi_host *c = dev_get_drvdata(dev); |
| 855 | 929 | struct sdhci_host *host = c->host; |
| 930 | + int ret; | |
| 856 | 931 | |
| 857 | 932 | if (host->tuning_mode != SDHCI_TUNING_MODE_3) |
| 858 | 933 | mmc_retune_needed(host->mmc); |
| 859 | 934 | |
| 860 | − return sdhci_runtime_suspend_host(host); | |
| 935 | + ret = sdhci_runtime_suspend_host(host); | |
| 936 | + if (ret) | |
| 937 | + return ret; | |
| 938 | + | |
| 939 | + sdhci_acpi_reset_signal_voltage_if_needed(dev); | |
| 940 | + return 0; | |
| 861 | 941 | } |
| 862 | 942 | |
| 863 | 943 | static int sdhci_acpi_runtime_resume(struct device *dev) |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/mmc/host.h> |
| 12 | 12 | #include <linux/mmc/mmc.h> |
| 13 | 13 | #include <linux/of.h> |
| 14 | +#include <linux/of_device.h> | |
| 14 | 15 | |
| 15 | 16 | #include "sdhci-pltfm.h" |
| 16 | 17 | |
| @@ -235,6 +236,11 @@ static const struct sdhci_ops sdhci_cdns_ops = { · 218 unmodified lines | ||
| 235 | 236 | .set_uhs_signaling = sdhci_cdns_set_uhs_signaling, |
| 236 | 237 | }; |
| 237 | 238 | |
| 239 | +static const struct sdhci_pltfm_data sdhci_cdns_uniphier_pltfm_data = { | |
| 240 | + .ops = &sdhci_cdns_ops, | |
| 241 | + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, | |
| 242 | +}; | |
| 243 | + | |
| 238 | 244 | static const struct sdhci_pltfm_data sdhci_cdns_pltfm_data = { |
| 239 | 245 | .ops = &sdhci_cdns_ops, |
| 240 | 246 | }; |
| @@ -334,6 +340,7 @@ static void sdhci_cdns_hs400_enhanced_strobe(struct mmc_host *mmc, · 93 unmodified lines | ||
| 334 | 340 | static int sdhci_cdns_probe(struct platform_device *pdev) |
| 335 | 341 | { |
| 336 | 342 | struct sdhci_host *host; |
| 343 | + const struct sdhci_pltfm_data *data; | |
| 337 | 344 | struct sdhci_pltfm_host *pltfm_host; |
| 338 | 345 | struct sdhci_cdns_priv *priv; |
| 339 | 346 | struct clk *clk; |
| @@ -350,8 +357,12 @@ static int sdhci_cdns_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 350 | 357 | if (ret) |
| 351 | 358 | return ret; |
| 352 | 359 | |
| 360 | + data = of_device_get_match_data(dev); | |
| 361 | + if (!data) | |
| 362 | + data = &sdhci_cdns_pltfm_data; | |
| 363 | + | |
| 353 | 364 | nr_phy_params = sdhci_cdns_phy_param_count(dev->of_node); |
| 354 | − host = sdhci_pltfm_init(pdev, &sdhci_cdns_pltfm_data, | |
| 365 | + host = sdhci_pltfm_init(pdev, data, | |
| 355 | 366 | struct_size(priv, phy_params, nr_phy_params)); |
| 356 | 367 | if (IS_ERR(host)) { |
| 357 | 368 | ret = PTR_ERR(host); |
| @@ -431,7 +442,10 @@ static const struct dev_pm_ops sdhci_cdns_pm_ops = { · 73 unmodified lines | ||
| 431 | 442 | }; |
| 432 | 443 | |
| 433 | 444 | static const struct of_device_id sdhci_cdns_match[] = { |
| 434 | − { .compatible = "socionext,uniphier-sd4hc" }, | |
| 445 | + { | |
| 446 | + .compatible = "socionext,uniphier-sd4hc", | |
| 447 | + .data = &sdhci_cdns_uniphier_pltfm_data, | |
| 448 | + }, | |
| 435 | 449 | { .compatible = "cdns,sd4hc" }, |
| 436 | 450 | { /* sentinel */ } |
| 437 | 451 | }; |
| @@ -1590,7 +1590,7 @@ static u32 sdhci_msm_cqe_irq(struct sdhci_host *host, u32 intmask) · 1589 unmodified lines | ||
| 1590 | 1590 | return 0; |
| 1591 | 1591 | } |
| 1592 | 1592 | |
| 1593 | −void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery) | |
| 1593 | +static void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery) | |
| 1594 | 1594 | { |
| 1595 | 1595 | struct sdhci_host *host = mmc_priv(mmc); |
| 1596 | 1596 | unsigned long flags; |
| @@ -132,7 +132,8 @@ static void sdhci_at91_reset(struct sdhci_host *host, u8 mask) · 131 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | sdhci_reset(host, mask); |
| 134 | 134 | |
| 135 | − if (host->mmc->caps & MMC_CAP_NONREMOVABLE) | |
| 135 | + if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) | |
| 136 | + || mmc_gpio_get_cd(host->mmc) >= 0) | |
| 136 | 137 | sdhci_at91_set_force_card_detect(host); |
| 137 | 138 | |
| 138 | 139 | if (priv->cal_always_on && (mask & SDHCI_RESET_ALL)) |
| @@ -427,8 +428,11 @@ static int sdhci_at91_probe(struct platform_device *pdev) · 288 unmodified lines | ||
| 427 | 428 | * detection procedure using the SDMCC_CD signal is bypassed. |
| 428 | 429 | * This bit is reset when a software reset for all command is performed |
| 429 | 430 | * so we need to implement our own reset function to set back this bit. |
| 431 | + * | |
| 432 | + * WA: SAMA5D2 doesn't drive CMD if using CD GPIO line. | |
| 430 | 433 | */ |
| 431 | − if (host->mmc->caps & MMC_CAP_NONREMOVABLE) | |
| 434 | + if ((host->mmc->caps & MMC_CAP_NONREMOVABLE) | |
| 435 | + || mmc_gpio_get_cd(host->mmc) >= 0) | |
| 432 | 436 | sdhci_at91_set_force_card_detect(host); |
| 433 | 437 | |
| 434 | 438 | pm_runtime_put_autosuspend(&pdev->dev); |
| @@ -1192,6 +1192,9 @@ static int sdhci_omap_probe(struct platform_device *pdev) · 1191 unmodified lines | ||
| 1192 | 1192 | if (of_find_property(dev->of_node, "dmas", NULL)) |
| 1193 | 1193 | sdhci_switch_external_dma(host, true); |
| 1194 | 1194 | |
| 1195 | + /* R1B responses is required to properly manage HW busy detection. */ | |
| 1196 | + mmc->caps |= MMC_CAP_NEED_RSP_BUSY; | |
| 1197 | + | |
| 1195 | 1198 | ret = sdhci_setup_host(host); |
| 1196 | 1199 | if (ret) |
| 1197 | 1200 | goto err_put_sync; |
| @@ -262,10 +262,26 @@ static int gl9750_execute_tuning(struct sdhci_host *host, u32 opcode) · 261 unmodified lines | ||
| 262 | 262 | return 0; |
| 263 | 263 | } |
| 264 | 264 | |
| 265 | +static void gli_pcie_enable_msi(struct sdhci_pci_slot *slot) | |
| 266 | +{ | |
| 267 | + int ret; | |
| 268 | + | |
| 269 | + ret = pci_alloc_irq_vectors(slot->chip->pdev, 1, 1, | |
| 270 | + PCI_IRQ_MSI | PCI_IRQ_MSIX); | |
| 271 | + if (ret < 0) { | |
| 272 | + pr_warn("%s: enable PCI MSI failed, error=%d\n", | |
| 273 | + mmc_hostname(slot->host->mmc), ret); | |
| 274 | + return; | |
| 275 | + } | |
| 276 | + | |
| 277 | + slot->host->irq = pci_irq_vector(slot->chip->pdev, 0); | |
| 278 | +} | |
| 279 | + | |
| 265 | 280 | static int gli_probe_slot_gl9750(struct sdhci_pci_slot *slot) |
| 266 | 281 | { |
| 267 | 282 | struct sdhci_host *host = slot->host; |
| 268 | 283 | |
| 284 | + gli_pcie_enable_msi(slot); | |
| 269 | 285 | slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO; |
| 270 | 286 | sdhci_enable_v4_mode(host); |
| 271 | 287 | |
| @@ -276,6 +292,7 @@ static int gli_probe_slot_gl9755(struct sdhci_pci_slot *slot) · 4 unmodified lines | ||
| 276 | 292 | { |
| 277 | 293 | struct sdhci_host *host = slot->host; |
| 278 | 294 | |
| 295 | + gli_pcie_enable_msi(slot); | |
| 279 | 296 | slot->host->mmc->caps2 |= MMC_CAP2_NO_SDIO; |
| 280 | 297 | sdhci_enable_v4_mode(host); |
| 281 | 298 | |
| @@ -1552,6 +1552,9 @@ static int sdhci_tegra_probe(struct platform_device *pdev) · 1551 unmodified lines | ||
| 1552 | 1552 | if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50) |
| 1553 | 1553 | host->mmc->caps |= MMC_CAP_1_8V_DDR; |
| 1554 | 1554 | |
| 1555 | + /* R1B responses is required to properly manage HW busy detection. */ | |
| 1556 | + host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY; | |
| 1557 | + | |
| 1555 | 1558 | tegra_sdhci_parse_dt(host); |
| 1556 | 1559 | |
| 1557 | 1560 | tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power", |
| @@ -50,11 +50,6 @@ struct arp_pkt { · 49 unmodified lines | ||
| 50 | 50 | }; |
| 51 | 51 | #pragma pack() |
| 52 | 52 | |
| 53 | −static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb) | |
| 54 | −{ | |
| 55 | − return (struct arp_pkt *)skb_network_header(skb); | |
| 56 | −} | |
| 57 | − | |
| 58 | 53 | /* Forward declaration */ |
| 59 | 54 | static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[], |
| 60 | 55 | bool strict_match); |
| @@ -553,10 +548,11 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip) · 492 unmodified lines | ||
| 553 | 548 | spin_unlock(&bond->mode_lock); |
| 554 | 549 | } |
| 555 | 550 | |
| 556 | −static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond) | |
| 551 | +static struct slave *rlb_choose_channel(struct sk_buff *skb, | |
| 552 | + struct bonding *bond, | |
| 553 | + const struct arp_pkt *arp) | |
| 557 | 554 | { |
| 558 | 555 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); |
| 559 | − struct arp_pkt *arp = arp_pkt(skb); | |
| 560 | 556 | struct slave *assigned_slave, *curr_active_slave; |
| 561 | 557 | struct rlb_client_info *client_info; |
| 562 | 558 | u32 hash_index = 0; |
| @@ -653,8 +649,12 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon · 90 unmodified lines | ||
| 653 | 649 | */ |
| 654 | 650 | static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) |
| 655 | 651 | { |
| 656 | − struct arp_pkt *arp = arp_pkt(skb); | |
| 657 | 652 | struct slave *tx_slave = NULL; |
| 653 | + struct arp_pkt *arp; | |
| 654 | + | |
| 655 | + if (!pskb_network_may_pull(skb, sizeof(*arp))) | |
| 656 | + return NULL; | |
| 657 | + arp = (struct arp_pkt *)skb_network_header(skb); | |
| 658 | 658 | |
| 659 | 659 | /* Don't modify or load balance ARPs that do not originate locally |
| 660 | 660 | * (e.g.,arrive via a bridge). |
| @@ -664,7 +664,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) · 3 unmodified lines | ||
| 664 | 664 | |
| 665 | 665 | if (arp->op_code == htons(ARPOP_REPLY)) { |
| 666 | 666 | /* the arp must be sent on the selected rx channel */ |
| 667 | − tx_slave = rlb_choose_channel(skb, bond); | |
| 667 | + tx_slave = rlb_choose_channel(skb, bond, arp); | |
| 668 | 668 | if (tx_slave) |
| 669 | 669 | bond_hw_addr_copy(arp->mac_src, tx_slave->dev->dev_addr, |
| 670 | 670 | tx_slave->dev->addr_len); |
| @@ -676,7 +676,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) · 5 unmodified lines | ||
| 676 | 676 | * When the arp reply is received the entry will be updated |
| 677 | 677 | * with the correct unicast address of the client. |
| 678 | 678 | */ |
| 679 | − tx_slave = rlb_choose_channel(skb, bond); | |
| 679 | + tx_slave = rlb_choose_channel(skb, bond, arp); | |
| 680 | 680 | |
| 681 | 681 | /* The ARP reply packets must be delayed so that |
| 682 | 682 | * they can cancel out the influence of the ARP request. |
| @@ -883,6 +883,7 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = { · 882 unmodified lines | ||
| 883 | 883 | = { .len = sizeof(struct can_bittiming) }, |
| 884 | 884 | [IFLA_CAN_DATA_BITTIMING_CONST] |
| 885 | 885 | = { .len = sizeof(struct can_bittiming_const) }, |
| 886 | + [IFLA_CAN_TERMINATION] = { .type = NLA_U16 }, | |
| 886 | 887 | }; |
| 887 | 888 | |
| 888 | 889 | static int can_validate(struct nlattr *tb[], struct nlattr *data[], |
| @@ -69,8 +69,7 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port) · 68 unmodified lines | ||
| 69 | 69 | /* Force link status for IMP port */ |
| 70 | 70 | reg = core_readl(priv, offset); |
| 71 | 71 | reg |= (MII_SW_OR | LINK_STS); |
| 72 | − if (priv->type == BCM7278_DEVICE_ID) | |
| 73 | − reg |= GMII_SPEED_UP_2G; | |
| 72 | + reg &= ~GMII_SPEED_UP_2G; | |
| 74 | 73 | core_writel(priv, reg, offset); |
| 75 | 74 | |
| 76 | 75 | /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */ |
| @@ -2769,6 +2769,8 @@ static u64 mv88e6xxx_devlink_atu_bin_get(struct mv88e6xxx_chip *chip, · 2768 unmodified lines | ||
| 2769 | 2769 | goto unlock; |
| 2770 | 2770 | } |
| 2771 | 2771 | |
| 2772 | + occupancy &= MV88E6XXX_G2_ATU_STATS_MASK; | |
| 2773 | + | |
| 2772 | 2774 | unlock: |
| 2773 | 2775 | mv88e6xxx_reg_unlock(chip); |
| 2774 | 2776 | |
| @@ -278,13 +278,13 @@ int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, · 277 unmodified lines | ||
| 278 | 278 | switch (direction) { |
| 279 | 279 | case MV88E6XXX_EGRESS_DIR_INGRESS: |
| 280 | 280 | dest_port_chip = &chip->ingress_dest_port; |
| 281 | − reg &= MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK; | |
| 281 | + reg &= ~MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK; | |
| 282 | 282 | reg |= port << |
| 283 | 283 | __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK); |
| 284 | 284 | break; |
| 285 | 285 | case MV88E6XXX_EGRESS_DIR_EGRESS: |
| 286 | 286 | dest_port_chip = &chip->egress_dest_port; |
| 287 | − reg &= MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK; | |
| 287 | + reg &= ~MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK; | |
| 288 | 288 | reg |= port << |
| 289 | 289 | __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK); |
| 290 | 290 | break; |
| @@ -1099,6 +1099,13 @@ int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip) · 1098 unmodified lines | ||
| 1099 | 1099 | { |
| 1100 | 1100 | int err, irq, virq; |
| 1101 | 1101 | |
| 1102 | + chip->g2_irq.masked = ~0; | |
| 1103 | + mv88e6xxx_reg_lock(chip); | |
| 1104 | + err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked); | |
| 1105 | + mv88e6xxx_reg_unlock(chip); | |
| 1106 | + if (err) | |
| 1107 | + return err; | |
| 1108 | + | |
| 1102 | 1109 | chip->g2_irq.domain = irq_domain_add_simple( |
| 1103 | 1110 | chip->dev->of_node, 16, 0, &mv88e6xxx_g2_irq_domain_ops, chip); |
| 1104 | 1111 | if (!chip->g2_irq.domain) |
| @@ -1108,7 +1115,6 @@ int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip) · 3 unmodified lines | ||
| 1108 | 1115 | irq_create_mapping(chip->g2_irq.domain, irq); |
| 1109 | 1116 | |
| 1110 | 1117 | chip->g2_irq.chip = mv88e6xxx_g2_irq_chip; |
| 1111 | − chip->g2_irq.masked = ~0; | |
| 1112 | 1118 | |
| 1113 | 1119 | chip->device_irq = irq_find_mapping(chip->g1_irq.domain, |
| 1114 | 1120 | MV88E6XXX_G1_STS_IRQ_DEVICE); |
| @@ -1741,7 +1741,8 @@ static void sja1105_teardown(struct dsa_switch *ds) · 1740 unmodified lines | ||
| 1741 | 1741 | if (!dsa_is_user_port(ds, port)) |
| 1742 | 1742 | continue; |
| 1743 | 1743 | |
| 1744 | − kthread_destroy_worker(sp->xmit_worker); | |
| 1744 | + if (sp->xmit_worker) | |
| 1745 | + kthread_destroy_worker(sp->xmit_worker); | |
| 1745 | 1746 | } |
| 1746 | 1747 | |
| 1747 | 1748 | sja1105_tas_teardown(ds); |
| @@ -2135,7 +2135,7 @@ static int bcm_sysport_rule_set(struct bcm_sysport_priv *priv, · 2134 unmodified lines | ||
| 2135 | 2135 | return -ENOSPC; |
| 2136 | 2136 | |
| 2137 | 2137 | index = find_first_zero_bit(priv->filters, RXCHK_BRCM_TAG_MAX); |
| 2138 | − if (index > RXCHK_BRCM_TAG_MAX) | |
| 2138 | + if (index >= RXCHK_BRCM_TAG_MAX) | |
| 2139 | 2139 | return -ENOSPC; |
| 2140 | 2140 | |
| 2141 | 2141 | /* Location is the classification ID, and index is the position |
| @@ -10982,13 +10982,13 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu) · 10981 unmodified lines | ||
| 10982 | 10982 | struct bnxt *bp = netdev_priv(dev); |
| 10983 | 10983 | |
| 10984 | 10984 | if (netif_running(dev)) |
| 10985 | − bnxt_close_nic(bp, false, false); | |
| 10985 | + bnxt_close_nic(bp, true, false); | |
| 10986 | 10986 | |
| 10987 | 10987 | dev->mtu = new_mtu; |
| 10988 | 10988 | bnxt_set_ring_params(bp); |
| 10989 | 10989 | |
| 10990 | 10990 | if (netif_running(dev)) |
| 10991 | − return bnxt_open_nic(bp, false, false); | |
| 10991 | + return bnxt_open_nic(bp, true, false); | |
| 10992 | 10992 | |
| 10993 | 10993 | return 0; |
| 10994 | 10994 | } |
| @@ -11252,7 +11252,7 @@ static void bnxt_cfg_ntp_filters(struct bnxt *bp) · 257 unmodified lines | ||
| 11252 | 11252 | } |
| 11253 | 11253 | } |
| 11254 | 11254 | if (test_and_clear_bit(BNXT_HWRM_PF_UNLOAD_SP_EVENT, &bp->sp_event)) |
| 11255 | − netdev_info(bp->dev, "Receive PF driver unload event!"); | |
| 11255 | + netdev_info(bp->dev, "Receive PF driver unload event!\n"); | |
| 11256 | 11256 | } |
| 11257 | 11257 | |
| 11258 | 11258 | #else |
| @@ -11759,7 +11759,7 @@ static int bnxt_pcie_dsn_get(struct bnxt *bp, u8 dsn[]) · 500 unmodified lines | ||
| 11759 | 11759 | u32 dw; |
| 11760 | 11760 | |
| 11761 | 11761 | if (!pos) { |
| 11762 | − netdev_info(bp->dev, "Unable do read adapter's DSN"); | |
| 11762 | + netdev_info(bp->dev, "Unable do read adapter's DSN\n"); | |
| 11763 | 11763 | return -EOPNOTSUPP; |
| 11764 | 11764 | } |
| 11765 | 11765 | |
| @@ -641,14 +641,14 @@ static int bnxt_dl_params_register(struct bnxt *bp) · 640 unmodified lines | ||
| 641 | 641 | rc = devlink_params_register(bp->dl, bnxt_dl_params, |
| 642 | 642 | ARRAY_SIZE(bnxt_dl_params)); |
| 643 | 643 | if (rc) { |
| 644 | − netdev_warn(bp->dev, "devlink_params_register failed. rc=%d", | |
| 644 | + netdev_warn(bp->dev, "devlink_params_register failed. rc=%d\n", | |
| 645 | 645 | rc); |
| 646 | 646 | return rc; |
| 647 | 647 | } |
| 648 | 648 | rc = devlink_port_params_register(&bp->dl_port, bnxt_dl_port_params, |
| 649 | 649 | ARRAY_SIZE(bnxt_dl_port_params)); |
| 650 | 650 | if (rc) { |
| 651 | − netdev_err(bp->dev, "devlink_port_params_register failed"); | |
| 651 | + netdev_err(bp->dev, "devlink_port_params_register failed\n"); | |
| 652 | 652 | devlink_params_unregister(bp->dl, bnxt_dl_params, |
| 653 | 653 | ARRAY_SIZE(bnxt_dl_params)); |
| 654 | 654 | return rc; |
| @@ -679,7 +679,7 @@ int bnxt_dl_register(struct bnxt *bp) · 24 unmodified lines | ||
| 679 | 679 | else |
| 680 | 680 | dl = devlink_alloc(&bnxt_vf_dl_ops, sizeof(struct bnxt_dl)); |
| 681 | 681 | if (!dl) { |
| 682 | − netdev_warn(bp->dev, "devlink_alloc failed"); | |
| 682 | + netdev_warn(bp->dev, "devlink_alloc failed\n"); | |
| 683 | 683 | return -ENOMEM; |
| 684 | 684 | } |
| 685 | 685 | |
| @@ -692,7 +692,7 @@ int bnxt_dl_register(struct bnxt *bp) · 6 unmodified lines | ||
| 692 | 692 | |
| 693 | 693 | rc = devlink_register(dl, &bp->pdev->dev); |
| 694 | 694 | if (rc) { |
| 695 | − netdev_warn(bp->dev, "devlink_register failed. rc=%d", rc); | |
| 695 | + netdev_warn(bp->dev, "devlink_register failed. rc=%d\n", rc); | |
| 696 | 696 | goto err_dl_free; |
| 697 | 697 | } |
| 698 | 698 | |
| @@ -704,7 +704,7 @@ int bnxt_dl_register(struct bnxt *bp) · 5 unmodified lines | ||
| 704 | 704 | sizeof(bp->dsn)); |
| 705 | 705 | rc = devlink_port_register(dl, &bp->dl_port, bp->pf.port_id); |
| 706 | 706 | if (rc) { |
| 707 | − netdev_err(bp->dev, "devlink_port_register failed"); | |
| 707 | + netdev_err(bp->dev, "devlink_port_register failed\n"); | |
| 708 | 708 | goto err_dl_unreg; |
| 709 | 709 | } |
| 710 | 710 | |
| @@ -2007,8 +2007,8 @@ int bnxt_flash_package_from_file(struct net_device *dev, const char *filename, · 2006 unmodified lines | ||
| 2007 | 2007 | struct hwrm_nvm_install_update_output *resp = bp->hwrm_cmd_resp_addr; |
| 2008 | 2008 | struct hwrm_nvm_install_update_input install = {0}; |
| 2009 | 2009 | const struct firmware *fw; |
| 2010 | − int rc, hwrm_err = 0; | |
| 2011 | 2010 | u32 item_len; |
| 2011 | + int rc = 0; | |
| 2012 | 2012 | u16 index; |
| 2013 | 2013 | |
| 2014 | 2014 | bnxt_hwrm_fw_set_time(bp); |
| @@ -2028,7 +2028,7 @@ int bnxt_flash_package_from_file(struct net_device *dev, const char *filename, · 13 unmodified lines | ||
| 2028 | 2028 | } |
| 2029 | 2029 | |
| 2030 | 2030 | if (fw->size > item_len) { |
| 2031 | − netdev_err(dev, "PKG insufficient update area in nvram: %lu", | |
| 2031 | + netdev_err(dev, "PKG insufficient update area in nvram: %lu\n", | |
| 2032 | 2032 | (unsigned long)fw->size); |
| 2033 | 2033 | rc = -EFBIG; |
| 2034 | 2034 | } else { |
| @@ -2052,15 +2052,14 @@ int bnxt_flash_package_from_file(struct net_device *dev, const char *filename, · 17 unmodified lines | ||
| 2052 | 2052 | memcpy(kmem, fw->data, fw->size); |
| 2053 | 2053 | modify.host_src_addr = cpu_to_le64(dma_handle); |
| 2054 | 2054 | |
| 2055 | − hwrm_err = hwrm_send_message(bp, &modify, | |
| 2056 | − sizeof(modify), | |
| 2057 | − FLASH_PACKAGE_TIMEOUT); | |
| 2055 | + rc = hwrm_send_message(bp, &modify, sizeof(modify), | |
| 2056 | + FLASH_PACKAGE_TIMEOUT); | |
| 2058 | 2057 | dma_free_coherent(&bp->pdev->dev, fw->size, kmem, |
| 2059 | 2058 | dma_handle); |
| 2060 | 2059 | } |
| 2061 | 2060 | } |
| 2062 | 2061 | release_firmware(fw); |
| 2063 | − if (rc || hwrm_err) | |
| 2062 | + if (rc) | |
| 2064 | 2063 | goto err_exit; |
| 2065 | 2064 | |
| 2066 | 2065 | if ((install_type & 0xffff) == 0) |
| @@ -2069,20 +2068,19 @@ int bnxt_flash_package_from_file(struct net_device *dev, const char *filename, · 2 unmodified lines | ||
| 2069 | 2068 | install.install_type = cpu_to_le32(install_type); |
| 2070 | 2069 | |
| 2071 | 2070 | mutex_lock(&bp->hwrm_cmd_lock); |
| 2072 | − hwrm_err = _hwrm_send_message(bp, &install, sizeof(install), | |
| 2073 | − INSTALL_PACKAGE_TIMEOUT); | |
| 2074 | − if (hwrm_err) { | |
| 2071 | + rc = _hwrm_send_message(bp, &install, sizeof(install), | |
| 2072 | + INSTALL_PACKAGE_TIMEOUT); | |
| 2073 | + if (rc) { | |
| 2075 | 2074 | u8 error_code = ((struct hwrm_err_output *)resp)->cmd_err; |
| 2076 | 2075 | |
| 2077 | 2076 | if (resp->error_code && error_code == |
| 2078 | 2077 | NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) { |
| 2079 | 2078 | install.flags |= cpu_to_le16( |
| 2080 | 2079 | NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG); |
| 2081 | − hwrm_err = _hwrm_send_message(bp, &install, | |
| 2082 | − sizeof(install), | |
| 2083 | − INSTALL_PACKAGE_TIMEOUT); | |
| 2080 | + rc = _hwrm_send_message(bp, &install, sizeof(install), | |
| 2081 | + INSTALL_PACKAGE_TIMEOUT); | |
| 2084 | 2082 | } |
| 2085 | − if (hwrm_err) | |
| 2083 | + if (rc) | |
| 2086 | 2084 | goto flash_pkg_exit; |
| 2087 | 2085 | } |
| 2088 | 2086 | |
| @@ -2094,7 +2092,7 @@ int bnxt_flash_package_from_file(struct net_device *dev, const char *filename, · 5 unmodified lines | ||
| 2094 | 2092 | flash_pkg_exit: |
| 2095 | 2093 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 2096 | 2094 | err_exit: |
| 2097 | − if (hwrm_err == -EACCES) | |
| 2095 | + if (rc == -EACCES) | |
| 2098 | 2096 | bnxt_print_admin_err(bp); |
| 2099 | 2097 | return rc; |
| 2100 | 2098 | } |
| @@ -3338,7 +3336,7 @@ err: · 1237 unmodified lines | ||
| 3338 | 3336 | kfree(coredump.data); |
| 3339 | 3337 | *dump_len += sizeof(struct bnxt_coredump_record); |
| 3340 | 3338 | if (rc == -ENOBUFS) |
| 3341 | − netdev_err(bp->dev, "Firmware returned large coredump buffer"); | |
| 3339 | + netdev_err(bp->dev, "Firmware returned large coredump buffer\n"); | |
| 3342 | 3340 | return rc; |
| 3343 | 3341 | } |
| 3344 | 3342 | |
| @@ -50,7 +50,7 @@ static u16 bnxt_flow_get_dst_fid(struct bnxt *pf_bp, struct net_device *dev) · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | /* check if dev belongs to the same switch */ |
| 52 | 52 | if (!netdev_port_same_parent_id(pf_bp->dev, dev)) { |
| 53 | − netdev_info(pf_bp->dev, "dev(ifindex=%d) not on same switch", | |
| 53 | + netdev_info(pf_bp->dev, "dev(ifindex=%d) not on same switch\n", | |
| 54 | 54 | dev->ifindex); |
| 55 | 55 | return BNXT_FID_INVALID; |
| 56 | 56 | } |
| @@ -70,7 +70,7 @@ static int bnxt_tc_parse_redir(struct bnxt *bp, · 13 unmodified lines | ||
| 70 | 70 | struct net_device *dev = act->dev; |
| 71 | 71 | |
| 72 | 72 | if (!dev) { |
| 73 | − netdev_info(bp->dev, "no dev in mirred action"); | |
| 73 | + netdev_info(bp->dev, "no dev in mirred action\n"); | |
| 74 | 74 | return -EINVAL; |
| 75 | 75 | } |
| 76 | 76 | |
| @@ -106,7 +106,7 @@ static int bnxt_tc_parse_tunnel_set(struct bnxt *bp, · 29 unmodified lines | ||
| 106 | 106 | const struct ip_tunnel_key *tun_key = &tun_info->key; |
| 107 | 107 | |
| 108 | 108 | if (ip_tunnel_info_af(tun_info) != AF_INET) { |
| 109 | − netdev_info(bp->dev, "only IPv4 tunnel-encap is supported"); | |
| 109 | + netdev_info(bp->dev, "only IPv4 tunnel-encap is supported\n"); | |
| 110 | 110 | return -EOPNOTSUPP; |
| 111 | 111 | } |
| 112 | 112 | |
| @@ -295,7 +295,7 @@ static int bnxt_tc_parse_actions(struct bnxt *bp, · 182 unmodified lines | ||
| 295 | 295 | int i, rc; |
| 296 | 296 | |
| 297 | 297 | if (!flow_action_has_entries(flow_action)) { |
| 298 | − netdev_info(bp->dev, "no actions"); | |
| 298 | + netdev_info(bp->dev, "no actions\n"); | |
| 299 | 299 | return -EINVAL; |
| 300 | 300 | } |
| 301 | 301 | |
| @@ -370,7 +370,7 @@ static int bnxt_tc_parse_flow(struct bnxt *bp, · 68 unmodified lines | ||
| 370 | 370 | /* KEY_CONTROL and KEY_BASIC are needed for forming a meaningful key */ |
| 371 | 371 | if ((dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_CONTROL)) == 0 || |
| 372 | 372 | (dissector->used_keys & BIT(FLOW_DISSECTOR_KEY_BASIC)) == 0) { |
| 373 | − netdev_info(bp->dev, "cannot form TC key: used_keys = 0x%x", | |
| 373 | + netdev_info(bp->dev, "cannot form TC key: used_keys = 0x%x\n", | |
| 374 | 374 | dissector->used_keys); |
| 375 | 375 | return -EOPNOTSUPP; |
| 376 | 376 | } |
| @@ -508,7 +508,7 @@ static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp, · 131 unmodified lines | ||
| 508 | 508 | |
| 509 | 509 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 510 | 510 | if (rc) |
| 511 | − netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | |
| 511 | + netdev_info(bp->dev, "%s: Error rc=%d\n", __func__, rc); | |
| 512 | 512 | |
| 513 | 513 | return rc; |
| 514 | 514 | } |
| @@ -841,7 +841,7 @@ static int hwrm_cfa_decap_filter_alloc(struct bnxt *bp, · 326 unmodified lines | ||
| 841 | 841 | resp = bnxt_get_hwrm_resp_addr(bp, &req); |
| 842 | 842 | *decap_filter_handle = resp->decap_filter_id; |
| 843 | 843 | } else { |
| 844 | − netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | |
| 844 | + netdev_info(bp->dev, "%s: Error rc=%d\n", __func__, rc); | |
| 845 | 845 | } |
| 846 | 846 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 847 | 847 | |
| @@ -859,7 +859,7 @@ static int hwrm_cfa_decap_filter_free(struct bnxt *bp, · 11 unmodified lines | ||
| 859 | 859 | |
| 860 | 860 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 861 | 861 | if (rc) |
| 862 | − netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | |
| 862 | + netdev_info(bp->dev, "%s: Error rc=%d\n", __func__, rc); | |
| 863 | 863 | |
| 864 | 864 | return rc; |
| 865 | 865 | } |
| @@ -906,7 +906,7 @@ static int hwrm_cfa_encap_record_alloc(struct bnxt *bp, · 40 unmodified lines | ||
| 906 | 906 | resp = bnxt_get_hwrm_resp_addr(bp, &req); |
| 907 | 907 | *encap_record_handle = resp->encap_record_id; |
| 908 | 908 | } else { |
| 909 | − netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | |
| 909 | + netdev_info(bp->dev, "%s: Error rc=%d\n", __func__, rc); | |
| 910 | 910 | } |
| 911 | 911 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 912 | 912 | |
| @@ -924,7 +924,7 @@ static int hwrm_cfa_encap_record_free(struct bnxt *bp, · 11 unmodified lines | ||
| 924 | 924 | |
| 925 | 925 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 926 | 926 | if (rc) |
| 927 | − netdev_info(bp->dev, "%s: Error rc=%d", __func__, rc); | |
| 927 | + netdev_info(bp->dev, "%s: Error rc=%d\n", __func__, rc); | |
| 928 | 928 | |
| 929 | 929 | return rc; |
| 930 | 930 | } |
| @@ -943,7 +943,7 @@ static int bnxt_tc_put_l2_node(struct bnxt *bp, · 12 unmodified lines | ||
| 943 | 943 | tc_info->l2_ht_params); |
| 944 | 944 | if (rc) |
| 945 | 945 | netdev_err(bp->dev, |
| 946 | − "Error: %s: rhashtable_remove_fast: %d", | |
| 946 | + "Error: %s: rhashtable_remove_fast: %d\n", | |
| 947 | 947 | __func__, rc); |
| 948 | 948 | kfree_rcu(l2_node, rcu); |
| 949 | 949 | } |
| @@ -972,7 +972,7 @@ bnxt_tc_get_l2_node(struct bnxt *bp, struct rhashtable *l2_table, · 22 unmodified lines | ||
| 972 | 972 | if (rc) { |
| 973 | 973 | kfree_rcu(l2_node, rcu); |
| 974 | 974 | netdev_err(bp->dev, |
| 975 | − "Error: %s: rhashtable_insert_fast: %d", | |
| 975 | + "Error: %s: rhashtable_insert_fast: %d\n", | |
| 976 | 976 | __func__, rc); |
| 977 | 977 | return NULL; |
| 978 | 978 | } |
| @@ -1031,7 +1031,7 @@ static bool bnxt_tc_can_offload(struct bnxt *bp, struct bnxt_tc_flow *flow) · 52 unmodified lines | ||
| 1031 | 1031 | if ((flow->flags & BNXT_TC_FLOW_FLAGS_PORTS) && |
| 1032 | 1032 | (flow->l4_key.ip_proto != IPPROTO_TCP && |
| 1033 | 1033 | flow->l4_key.ip_proto != IPPROTO_UDP)) { |
| 1034 | − netdev_info(bp->dev, "Cannot offload non-TCP/UDP (%d) ports", | |
| 1034 | + netdev_info(bp->dev, "Cannot offload non-TCP/UDP (%d) ports\n", | |
| 1035 | 1035 | flow->l4_key.ip_proto); |
| 1036 | 1036 | return false; |
| 1037 | 1037 | } |
| @@ -1088,7 +1088,7 @@ static int bnxt_tc_put_tunnel_node(struct bnxt *bp, · 50 unmodified lines | ||
| 1088 | 1088 | rc = rhashtable_remove_fast(tunnel_table, &tunnel_node->node, |
| 1089 | 1089 | *ht_params); |
| 1090 | 1090 | if (rc) { |
| 1091 | − netdev_err(bp->dev, "rhashtable_remove_fast rc=%d", rc); | |
| 1091 | + netdev_err(bp->dev, "rhashtable_remove_fast rc=%d\n", rc); | |
| 1092 | 1092 | rc = -1; |
| 1093 | 1093 | } |
| 1094 | 1094 | kfree_rcu(tunnel_node, rcu); |
| @@ -1129,7 +1129,7 @@ bnxt_tc_get_tunnel_node(struct bnxt *bp, struct rhashtable *tunnel_table, · 34 unmodified lines | ||
| 1129 | 1129 | tunnel_node->refcount++; |
| 1130 | 1130 | return tunnel_node; |
| 1131 | 1131 | err: |
| 1132 | − netdev_info(bp->dev, "error rc=%d", rc); | |
| 1132 | + netdev_info(bp->dev, "error rc=%d\n", rc); | |
| 1133 | 1133 | return NULL; |
| 1134 | 1134 | } |
| 1135 | 1135 | |
| @@ -1187,7 +1187,7 @@ static void bnxt_tc_put_decap_l2_node(struct bnxt *bp, · 51 unmodified lines | ||
| 1187 | 1187 | &decap_l2_node->node, |
| 1188 | 1188 | tc_info->decap_l2_ht_params); |
| 1189 | 1189 | if (rc) |
| 1190 | − netdev_err(bp->dev, "rhashtable_remove_fast rc=%d", rc); | |
| 1190 | + netdev_err(bp->dev, "rhashtable_remove_fast rc=%d\n", rc); | |
| 1191 | 1191 | kfree_rcu(decap_l2_node, rcu); |
| 1192 | 1192 | } |
| 1193 | 1193 | } |
| @@ -1227,7 +1227,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp, · 33 unmodified lines | ||
| 1227 | 1227 | |
| 1228 | 1228 | rt = ip_route_output_key(dev_net(real_dst_dev), &flow); |
| 1229 | 1229 | if (IS_ERR(rt)) { |
| 1230 | − netdev_info(bp->dev, "no route to %pI4b", &flow.daddr); | |
| 1230 | + netdev_info(bp->dev, "no route to %pI4b\n", &flow.daddr); | |
| 1231 | 1231 | return -EOPNOTSUPP; |
| 1232 | 1232 | } |
| 1233 | 1233 | |
| @@ -1241,7 +1241,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp, · 7 unmodified lines | ||
| 1241 | 1241 | |
| 1242 | 1242 | if (vlan->real_dev != real_dst_dev) { |
| 1243 | 1243 | netdev_info(bp->dev, |
| 1244 | − "dst_dev(%s) doesn't use PF-if(%s)", | |
| 1244 | + "dst_dev(%s) doesn't use PF-if(%s)\n", | |
| 1245 | 1245 | netdev_name(dst_dev), |
| 1246 | 1246 | netdev_name(real_dst_dev)); |
| 1247 | 1247 | rc = -EOPNOTSUPP; |
| @@ -1253,7 +1253,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp, · 5 unmodified lines | ||
| 1253 | 1253 | #endif |
| 1254 | 1254 | } else if (dst_dev != real_dst_dev) { |
| 1255 | 1255 | netdev_info(bp->dev, |
| 1256 | − "dst_dev(%s) for %pI4b is not PF-if(%s)", | |
| 1256 | + "dst_dev(%s) for %pI4b is not PF-if(%s)\n", | |
| 1257 | 1257 | netdev_name(dst_dev), &flow.daddr, |
| 1258 | 1258 | netdev_name(real_dst_dev)); |
| 1259 | 1259 | rc = -EOPNOTSUPP; |
| @@ -1262,7 +1262,7 @@ static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp, · 2 unmodified lines | ||
| 1262 | 1262 | |
| 1263 | 1263 | nbr = dst_neigh_lookup(&rt->dst, &flow.daddr); |
| 1264 | 1264 | if (!nbr) { |
| 1265 | − netdev_info(bp->dev, "can't lookup neighbor for %pI4b", | |
| 1265 | + netdev_info(bp->dev, "can't lookup neighbor for %pI4b\n", | |
| 1266 | 1266 | &flow.daddr); |
| 1267 | 1267 | rc = -EOPNOTSUPP; |
| 1268 | 1268 | goto put_rt; |
| @@ -1472,7 +1472,7 @@ static int __bnxt_tc_del_flow(struct bnxt *bp, · 203 unmodified lines | ||
| 1472 | 1472 | rc = rhashtable_remove_fast(&tc_info->flow_table, &flow_node->node, |
| 1473 | 1473 | tc_info->flow_ht_params); |
| 1474 | 1474 | if (rc) |
| 1475 | − netdev_err(bp->dev, "Error: %s: rhashtable_remove_fast rc=%d", | |
| 1475 | + netdev_err(bp->dev, "Error: %s: rhashtable_remove_fast rc=%d\n", | |
| 1476 | 1476 | __func__, rc); |
| 1477 | 1477 | |
| 1478 | 1478 | kfree_rcu(flow_node, rcu); |
| @@ -1587,7 +1587,7 @@ unlock: · 108 unmodified lines | ||
| 1587 | 1587 | free_node: |
| 1588 | 1588 | kfree_rcu(new_node, rcu); |
| 1589 | 1589 | done: |
| 1590 | − netdev_err(bp->dev, "Error: %s: cookie=0x%lx error=%d", | |
| 1590 | + netdev_err(bp->dev, "Error: %s: cookie=0x%lx error=%d\n", | |
| 1591 | 1591 | __func__, tc_flow_cmd->cookie, rc); |
| 1592 | 1592 | return rc; |
| 1593 | 1593 | } |
| @@ -1700,7 +1700,7 @@ bnxt_hwrm_cfa_flow_stats_get(struct bnxt *bp, int num_flows, · 106 unmodified lines | ||
| 1700 | 1700 | le64_to_cpu(resp_bytes[i]); |
| 1701 | 1701 | } |
| 1702 | 1702 | } else { |
| 1703 | − netdev_info(bp->dev, "error rc=%d", rc); | |
| 1703 | + netdev_info(bp->dev, "error rc=%d\n", rc); | |
| 1704 | 1704 | } |
| 1705 | 1705 | mutex_unlock(&bp->hwrm_cmd_lock); |
| 1706 | 1706 | |
| @@ -1970,7 +1970,7 @@ static int bnxt_tc_indr_block_event(struct notifier_block *nb, · 263 unmodified lines | ||
| 1970 | 1970 | bp); |
| 1971 | 1971 | if (rc) |
| 1972 | 1972 | netdev_info(bp->dev, |
| 1973 | − "Failed to register indirect blk: dev: %s", | |
| 1973 | + "Failed to register indirect blk: dev: %s\n", | |
| 1974 | 1974 | netdev->name); |
| 1975 | 1975 | break; |
| 1976 | 1976 | case NETDEV_UNREGISTER: |
| @@ -43,7 +43,7 @@ static int hwrm_cfa_vfr_alloc(struct bnxt *bp, u16 vf_idx, · 42 unmodified lines | ||
| 43 | 43 | netdev_dbg(bp->dev, "tx_cfa_action=0x%x, rx_cfa_code=0x%x", |
| 44 | 44 | *tx_cfa_action, *rx_cfa_code); |
| 45 | 45 | } else { |
| 46 | − netdev_info(bp->dev, "%s error rc=%d", __func__, rc); | |
| 46 | + netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc); | |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | 49 | mutex_unlock(&bp->hwrm_cmd_lock); |
| @@ -60,7 +60,7 @@ static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx) · 10 unmodified lines | ||
| 60 | 60 | |
| 61 | 61 | rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 62 | 62 | if (rc) |
| 63 | − netdev_info(bp->dev, "%s error rc=%d", __func__, rc); | |
| 63 | + netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc); | |
| 64 | 64 | return rc; |
| 65 | 65 | } |
| 66 | 66 | |
| @@ -465,7 +465,7 @@ static int bnxt_vf_reps_create(struct bnxt *bp) · 398 unmodified lines | ||
| 465 | 465 | return 0; |
| 466 | 466 | |
| 467 | 467 | err: |
| 468 | − netdev_info(bp->dev, "%s error=%d", __func__, rc); | |
| 468 | + netdev_info(bp->dev, "%s error=%d\n", __func__, rc); | |
| 469 | 469 | kfree(cfa_code_map); |
| 470 | 470 | __bnxt_vf_reps_destroy(bp); |
| 471 | 471 | return rc; |
| @@ -488,7 +488,7 @@ int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode, · 16 unmodified lines | ||
| 488 | 488 | |
| 489 | 489 | mutex_lock(&bp->sriov_lock); |
| 490 | 490 | if (bp->eswitch_mode == mode) { |
| 491 | − netdev_info(bp->dev, "already in %s eswitch mode", | |
| 491 | + netdev_info(bp->dev, "already in %s eswitch mode\n", | |
| 492 | 492 | mode == DEVLINK_ESWITCH_MODE_LEGACY ? |
| 493 | 493 | "legacy" : "switchdev"); |
| 494 | 494 | rc = -EINVAL; |
| @@ -508,7 +508,7 @@ int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode, · 13 unmodified lines | ||
| 508 | 508 | } |
| 509 | 509 | |
| 510 | 510 | if (pci_num_vf(bp->pdev) == 0) { |
| 511 | − netdev_info(bp->dev, "Enable VFs before setting switchdev mode"); | |
| 511 | + netdev_info(bp->dev, "Enable VFs before setting switchdev mode\n"); | |
| 512 | 512 | rc = -EPERM; |
| 513 | 513 | goto done; |
| 514 | 514 | } |
| @@ -294,6 +294,7 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) · 293 unmodified lines | ||
| 294 | 294 | */ |
| 295 | 295 | if (priv->ext_phy) { |
| 296 | 296 | reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL); |
| 297 | + reg &= ~ID_MODE_DIS; | |
| 297 | 298 | reg |= id_mode_dis; |
| 298 | 299 | if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv)) |
| 299 | 300 | reg |= RGMII_MODE_EN_V123; |
| @@ -5381,12 +5381,11 @@ static inline bool is_x_10g_port(const struct link_config *lc) · 5380 unmodified lines | ||
| 5381 | 5381 | static int cfg_queues(struct adapter *adap) |
| 5382 | 5382 | { |
| 5383 | 5383 | u32 avail_qsets, avail_eth_qsets, avail_uld_qsets; |
| 5384 | + u32 i, n10g = 0, qidx = 0, n1g = 0; | |
| 5385 | + u32 ncpus = num_online_cpus(); | |
| 5384 | 5386 | u32 niqflint, neq, num_ulds; |
| 5385 | 5387 | struct sge *s = &adap->sge; |
| 5386 | − u32 i, n10g = 0, qidx = 0; | |
| 5387 | −#ifndef CONFIG_CHELSIO_T4_DCB | |
| 5388 | − int q10g = 0; | |
| 5389 | −#endif | |
| 5388 | + u32 q10g = 0, q1g; | |
| 5390 | 5389 | |
| 5391 | 5390 | /* Reduce memory usage in kdump environment, disable all offload. */ |
| 5392 | 5391 | if (is_kdump_kernel() || (is_uld(adap) && t4_uld_mem_alloc(adap))) { |
| @@ -5424,44 +5423,50 @@ static int cfg_queues(struct adapter *adap) · 31 unmodified lines | ||
| 5424 | 5423 | n10g += is_x_10g_port(&adap2pinfo(adap, i)->link_cfg); |
| 5425 | 5424 | |
| 5426 | 5425 | avail_eth_qsets = min_t(u32, avail_qsets, MAX_ETH_QSETS); |
| 5426 | + | |
| 5427 | + /* We default to 1 queue per non-10G port and up to # of cores queues | |
| 5428 | + * per 10G port. | |
| 5429 | + */ | |
| 5430 | + if (n10g) | |
| 5431 | + q10g = (avail_eth_qsets - (adap->params.nports - n10g)) / n10g; | |
| 5432 | + | |
| 5433 | + n1g = adap->params.nports - n10g; | |
| 5427 | 5434 | #ifdef CONFIG_CHELSIO_T4_DCB |
| 5428 | 5435 | /* For Data Center Bridging support we need to be able to support up |
| 5429 | 5436 | * to 8 Traffic Priorities; each of which will be assigned to its |
| 5430 | 5437 | * own TX Queue in order to prevent Head-Of-Line Blocking. |
| 5431 | 5438 | */ |
| 5439 | + q1g = 8; | |
| 5432 | 5440 | if (adap->params.nports * 8 > avail_eth_qsets) { |
| 5433 | 5441 | dev_err(adap->pdev_dev, "DCB avail_eth_qsets=%d < %d!\n", |
| 5434 | 5442 | avail_eth_qsets, adap->params.nports * 8); |
| 5435 | 5443 | return -ENOMEM; |
| 5436 | 5444 | } |
| 5437 | 5445 | |
| 5438 | − for_each_port(adap, i) { | |
| 5439 | − struct port_info *pi = adap2pinfo(adap, i); | |
| 5446 | + if (adap->params.nports * ncpus < avail_eth_qsets) | |
| 5447 | + q10g = max(8U, ncpus); | |
| 5448 | + else | |
| 5449 | + q10g = max(8U, q10g); | |
| 5440 | 5450 | |
| 5441 | − pi->first_qset = qidx; | |
| 5442 | − pi->nqsets = is_kdump_kernel() ? 1 : 8; | |
| 5443 | − qidx += pi->nqsets; | |
| 5444 | − } | |
| 5445 | −#else /* !CONFIG_CHELSIO_T4_DCB */ | |
| 5446 | − /* We default to 1 queue per non-10G port and up to # of cores queues | |
| 5447 | − * per 10G port. | |
| 5448 | − */ | |
| 5449 | − if (n10g) | |
| 5450 | − q10g = (avail_eth_qsets - (adap->params.nports - n10g)) / n10g; | |
| 5451 | − if (q10g > netif_get_num_default_rss_queues()) | |
| 5452 | − q10g = netif_get_num_default_rss_queues(); | |
| 5451 | + while ((q10g * n10g) > (avail_eth_qsets - n1g * q1g)) | |
| 5452 | + q10g--; | |
| 5453 | 5453 | |
| 5454 | − if (is_kdump_kernel()) | |
| 5454 | +#else /* !CONFIG_CHELSIO_T4_DCB */ | |
| 5455 | + q1g = 1; | |
| 5456 | + q10g = min(q10g, ncpus); | |
| 5457 | +#endif /* !CONFIG_CHELSIO_T4_DCB */ | |
| 5458 | + if (is_kdump_kernel()) { | |
| 5455 | 5459 | q10g = 1; |
| 5460 | + q1g = 1; | |
| 5461 | + } | |
| 5456 | 5462 | |
| 5457 | 5463 | for_each_port(adap, i) { |
| 5458 | 5464 | struct port_info *pi = adap2pinfo(adap, i); |
| 5459 | 5465 | |
| 5460 | 5466 | pi->first_qset = qidx; |
| 5461 | − pi->nqsets = is_x_10g_port(&pi->link_cfg) ? q10g : 1; | |
| 5467 | + pi->nqsets = is_x_10g_port(&pi->link_cfg) ? q10g : q1g; | |
| 5462 | 5468 | qidx += pi->nqsets; |
| 5463 | 5469 | } |
| 5464 | −#endif /* !CONFIG_CHELSIO_T4_DCB */ | |
| 5465 | 5470 | |
| 5466 | 5471 | s->ethqsets = qidx; |
| 5467 | 5472 | s->max_ethqsets = qidx; /* MSI-X may lower it later */ |
| @@ -5473,7 +5478,7 @@ static int cfg_queues(struct adapter *adap) · 5 unmodified lines | ||
| 5473 | 5478 | * capped by the number of available cores. |
| 5474 | 5479 | */ |
| 5475 | 5480 | num_ulds = adap->num_uld + adap->num_ofld_uld; |
| 5476 | − i = min_t(u32, MAX_OFLD_QSETS, num_online_cpus()); | |
| 5481 | + i = min_t(u32, MAX_OFLD_QSETS, ncpus); | |
| 5477 | 5482 | avail_uld_qsets = roundup(i, adap->params.nports); |
| 5478 | 5483 | if (avail_qsets < num_ulds * adap->params.nports) { |
| 5479 | 5484 | adap->params.offload = 0; |
| @@ -1,4 +1,5 @@ | ||
| 1 | 1 | /* Copyright 2008 - 2016 Freescale Semiconductor Inc. |
| 2 | + * Copyright 2020 NXP | |
| 2 | 3 | * |
| 3 | 4 | * Redistribution and use in source and binary forms, with or without |
| 4 | 5 | * modification, are permitted provided that the following conditions are met: |
| @@ -123,7 +124,22 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms"); · 118 unmodified lines | ||
| 123 | 124 | #define FSL_QMAN_MAX_OAL 127 |
| 124 | 125 | |
| 125 | 126 | /* Default alignment for start of data in an Rx FD */ |
| 127 | +#ifdef CONFIG_DPAA_ERRATUM_A050385 | |
| 128 | +/* aligning data start to 64 avoids DMA transaction splits, unless the buffer | |
| 129 | + * is crossing a 4k page boundary | |
| 130 | + */ | |
| 131 | +#define DPAA_FD_DATA_ALIGNMENT (fman_has_errata_a050385() ? 64 : 16) | |
| 132 | +/* aligning to 256 avoids DMA transaction splits caused by 4k page boundary | |
| 133 | + * crossings; also, all SG fragments except the last must have a size multiple | |
| 134 | + * of 256 to avoid DMA transaction splits | |
| 135 | + */ | |
| 136 | +#define DPAA_A050385_ALIGN 256 | |
| 137 | +#define DPAA_FD_RX_DATA_ALIGNMENT (fman_has_errata_a050385() ? \ | |
| 138 | + DPAA_A050385_ALIGN : 16) | |
| 139 | +#else | |
| 126 | 140 | #define DPAA_FD_DATA_ALIGNMENT 16 |
| 141 | +#define DPAA_FD_RX_DATA_ALIGNMENT DPAA_FD_DATA_ALIGNMENT | |
| 142 | +#endif | |
| 127 | 143 | |
| 128 | 144 | /* The DPAA requires 256 bytes reserved and mapped for the SGT */ |
| 129 | 145 | #define DPAA_SGT_SIZE 256 |
| @@ -158,8 +174,13 @@ MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms"); · 28 unmodified lines | ||
| 158 | 174 | #define DPAA_PARSE_RESULTS_SIZE sizeof(struct fman_prs_result) |
| 159 | 175 | #define DPAA_TIME_STAMP_SIZE 8 |
| 160 | 176 | #define DPAA_HASH_RESULTS_SIZE 8 |
| 177 | +#ifdef CONFIG_DPAA_ERRATUM_A050385 | |
| 178 | +#define DPAA_RX_PRIV_DATA_SIZE (DPAA_A050385_ALIGN - (DPAA_PARSE_RESULTS_SIZE\ | |
| 179 | + + DPAA_TIME_STAMP_SIZE + DPAA_HASH_RESULTS_SIZE)) | |
| 180 | +#else | |
| 161 | 181 | #define DPAA_RX_PRIV_DATA_SIZE (u16)(DPAA_TX_PRIV_DATA_SIZE + \ |
| 162 | 182 | dpaa_rx_extra_headroom) |
| 183 | +#endif | |
| 163 | 184 | |
| 164 | 185 | #define DPAA_ETH_PCD_RXQ_NUM 128 |
| 165 | 186 | |
| @@ -180,7 +201,12 @@ static struct dpaa_bp *dpaa_bp_array[BM_MAX_NUM_OF_POOLS]; · 14 unmodified lines | ||
| 180 | 201 | |
| 181 | 202 | #define DPAA_BP_RAW_SIZE 4096 |
| 182 | 203 | |
| 204 | +#ifdef CONFIG_DPAA_ERRATUM_A050385 | |
| 205 | +#define dpaa_bp_size(raw_size) (SKB_WITH_OVERHEAD(raw_size) & \ | |
| 206 | + ~(DPAA_A050385_ALIGN - 1)) | |
| 207 | +#else | |
| 183 | 208 | #define dpaa_bp_size(raw_size) SKB_WITH_OVERHEAD(raw_size) |
| 209 | +#endif | |
| 184 | 210 | |
| 185 | 211 | static int dpaa_max_frm; |
| 186 | 212 | |
| @@ -1192,7 +1218,7 @@ static int dpaa_eth_init_rx_port(struct fman_port *port, struct dpaa_bp *bp, · 1005 unmodified lines | ||
| 1192 | 1218 | buf_prefix_content.pass_prs_result = true; |
| 1193 | 1219 | buf_prefix_content.pass_hash_result = true; |
| 1194 | 1220 | buf_prefix_content.pass_time_stamp = true; |
| 1195 | − buf_prefix_content.data_align = DPAA_FD_DATA_ALIGNMENT; | |
| 1221 | + buf_prefix_content.data_align = DPAA_FD_RX_DATA_ALIGNMENT; | |
| 1196 | 1222 | |
| 1197 | 1223 | rx_p = ¶ms.specific_params.rx_params; |
| 1198 | 1224 | rx_p->err_fqid = errq->fqid; |
| @@ -1662,6 +1688,8 @@ static u8 rx_csum_offload(const struct dpaa_priv *priv, const struct qm_fd *fd) · 463 unmodified lines | ||
| 1662 | 1688 | return CHECKSUM_NONE; |
| 1663 | 1689 | } |
| 1664 | 1690 | |
| 1691 | +#define PTR_IS_ALIGNED(x, a) (IS_ALIGNED((unsigned long)(x), (a))) | |
| 1692 | + | |
| 1665 | 1693 | /* Build a linear skb around the received buffer. |
| 1666 | 1694 | * We are guaranteed there is enough room at the end of the data buffer to |
| 1667 | 1695 | * accommodate the shared info area of the skb. |
| @@ -1733,8 +1761,7 @@ static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv, · 65 unmodified lines | ||
| 1733 | 1761 | |
| 1734 | 1762 | sg_addr = qm_sg_addr(&sgt[i]); |
| 1735 | 1763 | sg_vaddr = phys_to_virt(sg_addr); |
| 1736 | − WARN_ON(!IS_ALIGNED((unsigned long)sg_vaddr, | |
| 1737 | − SMP_CACHE_BYTES)); | |
| 1764 | + WARN_ON(!PTR_IS_ALIGNED(sg_vaddr, SMP_CACHE_BYTES)); | |
| 1738 | 1765 | |
| 1739 | 1766 | dma_unmap_page(priv->rx_dma_dev, sg_addr, |
| 1740 | 1767 | DPAA_BP_RAW_SIZE, DMA_FROM_DEVICE); |
| @@ -2022,6 +2049,75 @@ static inline int dpaa_xmit(struct dpaa_priv *priv, · 281 unmodified lines | ||
| 2022 | 2049 | return 0; |
| 2023 | 2050 | } |
| 2024 | 2051 | |
| 2052 | +#ifdef CONFIG_DPAA_ERRATUM_A050385 | |
| 2053 | +int dpaa_a050385_wa(struct net_device *net_dev, struct sk_buff **s) | |
| 2054 | +{ | |
| 2055 | + struct dpaa_priv *priv = netdev_priv(net_dev); | |
| 2056 | + struct sk_buff *new_skb, *skb = *s; | |
| 2057 | + unsigned char *start, i; | |
| 2058 | + | |
| 2059 | + /* check linear buffer alignment */ | |
| 2060 | + if (!PTR_IS_ALIGNED(skb->data, DPAA_A050385_ALIGN)) | |
| 2061 | + goto workaround; | |
| 2062 | + | |
| 2063 | + /* linear buffers just need to have an aligned start */ | |
| 2064 | + if (!skb_is_nonlinear(skb)) | |
| 2065 | + return 0; | |
| 2066 | + | |
| 2067 | + /* linear data size for nonlinear skbs needs to be aligned */ | |
| 2068 | + if (!IS_ALIGNED(skb_headlen(skb), DPAA_A050385_ALIGN)) | |
| 2069 | + goto workaround; | |
| 2070 | + | |
| 2071 | + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { | |
| 2072 | + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | |
| 2073 | + | |
| 2074 | + /* all fragments need to have aligned start addresses */ | |
| 2075 | + if (!IS_ALIGNED(skb_frag_off(frag), DPAA_A050385_ALIGN)) | |
| 2076 | + goto workaround; | |
| 2077 | + | |
| 2078 | + /* all but last fragment need to have aligned sizes */ | |
| 2079 | + if (!IS_ALIGNED(skb_frag_size(frag), DPAA_A050385_ALIGN) && | |
| 2080 | + (i < skb_shinfo(skb)->nr_frags - 1)) | |
| 2081 | + goto workaround; | |
| 2082 | + } | |
| 2083 | + | |
| 2084 | + return 0; | |
| 2085 | + | |
| 2086 | +workaround: | |
| 2087 | + /* copy all the skb content into a new linear buffer */ | |
| 2088 | + new_skb = netdev_alloc_skb(net_dev, skb->len + DPAA_A050385_ALIGN - 1 + | |
| 2089 | + priv->tx_headroom); | |
| 2090 | + if (!new_skb) | |
| 2091 | + return -ENOMEM; | |
| 2092 | + | |
| 2093 | + /* NET_SKB_PAD bytes already reserved, adding up to tx_headroom */ | |
| 2094 | + skb_reserve(new_skb, priv->tx_headroom - NET_SKB_PAD); | |
| 2095 | + | |
| 2096 | + /* Workaround for DPAA_A050385 requires data start to be aligned */ | |
| 2097 | + start = PTR_ALIGN(new_skb->data, DPAA_A050385_ALIGN); | |
| 2098 | + if (start - new_skb->data != 0) | |
| 2099 | + skb_reserve(new_skb, start - new_skb->data); | |
| 2100 | + | |
| 2101 | + skb_put(new_skb, skb->len); | |
| 2102 | + skb_copy_bits(skb, 0, new_skb->data, skb->len); | |
| 2103 | + skb_copy_header(new_skb, skb); | |
| 2104 | + new_skb->dev = skb->dev; | |
| 2105 | + | |
| 2106 | + /* We move the headroom when we align it so we have to reset the | |
| 2107 | + * network and transport header offsets relative to the new data | |
| 2108 | + * pointer. The checksum offload relies on these offsets. | |
| 2109 | + */ | |
| 2110 | + skb_set_network_header(new_skb, skb_network_offset(skb)); | |
| 2111 | + skb_set_transport_header(new_skb, skb_transport_offset(skb)); | |
| 2112 | + | |
| 2113 | + /* TODO: does timestamping need the result in the old skb? */ | |
| 2114 | + dev_kfree_skb(skb); | |
| 2115 | + *s = new_skb; | |
| 2116 | + | |
| 2117 | + return 0; | |
| 2118 | +} | |
| 2119 | +#endif | |
| 2120 | + | |
| 2025 | 2121 | static netdev_tx_t |
| 2026 | 2122 | dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev) |
| 2027 | 2123 | { |
| @@ -2068,6 +2164,14 @@ dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev) · 40 unmodified lines | ||
| 2068 | 2164 | nonlinear = skb_is_nonlinear(skb); |
| 2069 | 2165 | } |
| 2070 | 2166 | |
| 2167 | +#ifdef CONFIG_DPAA_ERRATUM_A050385 | |
| 2168 | + if (unlikely(fman_has_errata_a050385())) { | |
| 2169 | + if (dpaa_a050385_wa(net_dev, &skb)) | |
| 2170 | + goto enomem; | |
| 2171 | + nonlinear = skb_is_nonlinear(skb); | |
| 2172 | + } | |
| 2173 | +#endif | |
| 2174 | + | |
| 2071 | 2175 | if (nonlinear) { |
| 2072 | 2176 | /* Just create a S/G fd based on the skb */ |
| 2073 | 2177 | err = skb_to_sg_fd(priv, skb, &fd); |
| @@ -2741,9 +2845,7 @@ static inline u16 dpaa_get_headroom(struct dpaa_buffer_layout *bl) · 667 unmodified lines | ||
| 2741 | 2845 | headroom = (u16)(bl->priv_data_size + DPAA_PARSE_RESULTS_SIZE + |
| 2742 | 2846 | DPAA_TIME_STAMP_SIZE + DPAA_HASH_RESULTS_SIZE); |
| 2743 | 2847 | |
| 2744 | − return DPAA_FD_DATA_ALIGNMENT ? ALIGN(headroom, | |
| 2745 | − DPAA_FD_DATA_ALIGNMENT) : | |
| 2746 | − headroom; | |
| 2848 | + return ALIGN(headroom, DPAA_FD_DATA_ALIGNMENT); | |
| 2747 | 2849 | } |
| 2748 | 2850 | |
| 2749 | 2851 | static int dpaa_eth_probe(struct platform_device *pdev) |
| @@ -2529,15 +2529,15 @@ fec_enet_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec) · 2528 unmodified lines | ||
| 2529 | 2529 | return -EINVAL; |
| 2530 | 2530 | } |
| 2531 | 2531 | |
| 2532 | − cycle = fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr); | |
| 2532 | + cycle = fec_enet_us_to_itr_clock(ndev, ec->rx_coalesce_usecs); | |
| 2533 | 2533 | if (cycle > 0xFFFF) { |
| 2534 | 2534 | dev_err(dev, "Rx coalesced usec exceed hardware limitation\n"); |
| 2535 | 2535 | return -EINVAL; |
| 2536 | 2536 | } |
| 2537 | 2537 | |
| 2538 | − cycle = fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr); | |
| 2538 | + cycle = fec_enet_us_to_itr_clock(ndev, ec->tx_coalesce_usecs); | |
| 2539 | 2539 | if (cycle > 0xFFFF) { |
| 2540 | − dev_err(dev, "Rx coalesced usec exceed hardware limitation\n"); | |
| 2540 | + dev_err(dev, "Tx coalesced usec exceed hardware limitation\n"); | |
| 2541 | 2541 | return -EINVAL; |
| 2542 | 2542 | } |
| 2543 | 2543 | |
| @@ -8,3 +8,31 @@ config FSL_FMAN · 7 unmodified lines | ||
| 8 | 8 | help |
| 9 | 9 | Freescale Data-Path Acceleration Architecture Frame Manager |
| 10 | 10 | (FMan) support |
| 11 | + | |
| 12 | +config DPAA_ERRATUM_A050385 | |
| 13 | + bool | |
| 14 | + depends on ARM64 && FSL_DPAA | |
| 15 | + default y | |
| 16 | + help | |
| 17 | + DPAA FMan erratum A050385 software workaround implementation: | |
| 18 | + align buffers, data start, SG fragment length to avoid FMan DMA | |
| 19 | + splits. | |
| 20 | + FMAN DMA read or writes under heavy traffic load may cause FMAN | |
| 21 | + internal resource leak thus stopping further packet processing. | |
| 22 | + The FMAN internal queue can overflow when FMAN splits single | |
| 23 | + read or write transactions into multiple smaller transactions | |
| 24 | + such that more than 17 AXI transactions are in flight from FMAN | |
| 25 | + to interconnect. When the FMAN internal queue overflows, it can | |
| 26 | + stall further packet processing. The issue can occur with any | |
| 27 | + one of the following three conditions: | |
| 28 | + 1. FMAN AXI transaction crosses 4K address boundary (Errata | |
| 29 | + A010022) | |
| 30 | + 2. FMAN DMA address for an AXI transaction is not 16 byte | |
| 31 | + aligned, i.e. the last 4 bits of an address are non-zero | |
| 32 | + 3. Scatter Gather (SG) frames have more than one SG buffer in | |
| 33 | + the SG list and any one of the buffers, except the last | |
| 34 | + buffer in the SG list has data size that is not a multiple | |
| 35 | + of 16 bytes, i.e., other than 16, 32, 48, 64, etc. | |
| 36 | + With any one of the above three conditions present, there is | |
| 37 | + likelihood of stalled FMAN packet processing, especially under | |
| 38 | + stress with multiple ports injecting line-rate traffic. | |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * Copyright 2008-2015 Freescale Semiconductor Inc. |
| 3 | + * Copyright 2020 NXP | |
| 3 | 4 | * |
| 4 | 5 | * Redistribution and use in source and binary forms, with or without |
| 5 | 6 | * modification, are permitted provided that the following conditions are met: |
| @@ -566,6 +567,10 @@ struct fman_cfg { · 560 unmodified lines | ||
| 566 | 567 | u32 qmi_def_tnums_thresh; |
| 567 | 568 | }; |
| 568 | 569 | |
| 570 | +#ifdef CONFIG_DPAA_ERRATUM_A050385 | |
| 571 | +static bool fman_has_err_a050385; | |
| 572 | +#endif | |
| 573 | + | |
| 569 | 574 | static irqreturn_t fman_exceptions(struct fman *fman, |
| 570 | 575 | enum fman_exceptions exception) |
| 571 | 576 | { |
| @@ -2518,6 +2523,14 @@ struct fman *fman_bind(struct device *fm_dev) · 1946 unmodified lines | ||
| 2518 | 2523 | } |
| 2519 | 2524 | EXPORT_SYMBOL(fman_bind); |
| 2520 | 2525 | |
| 2526 | +#ifdef CONFIG_DPAA_ERRATUM_A050385 | |
| 2527 | +bool fman_has_errata_a050385(void) | |
| 2528 | +{ | |
| 2529 | + return fman_has_err_a050385; | |
| 2530 | +} | |
| 2531 | +EXPORT_SYMBOL(fman_has_errata_a050385); | |
| 2532 | +#endif | |
| 2533 | + | |
| 2521 | 2534 | static irqreturn_t fman_err_irq(int irq, void *handle) |
| 2522 | 2535 | { |
| 2523 | 2536 | struct fman *fman = (struct fman *)handle; |
| @@ -2845,6 +2858,11 @@ static struct fman *read_dts_node(struct platform_device *of_dev) · 321 unmodified lines | ||
| 2845 | 2858 | goto fman_free; |
| 2846 | 2859 | } |
| 2847 | 2860 | |
| 2861 | +#ifdef CONFIG_DPAA_ERRATUM_A050385 | |
| 2862 | + fman_has_err_a050385 = | |
| 2863 | + of_property_read_bool(fm_node, "fsl,erratum-a050385"); | |
| 2864 | +#endif | |
| 2865 | + | |
| 2848 | 2866 | return fman; |
| 2849 | 2867 | |
| 2850 | 2868 | fman_node_put: |
| @@ -1,5 +1,6 @@ | ||
| 1 | 1 | /* |
| 2 | 2 | * Copyright 2008-2015 Freescale Semiconductor Inc. |
| 3 | + * Copyright 2020 NXP | |
| 3 | 4 | * |
| 4 | 5 | * Redistribution and use in source and binary forms, with or without |
| 5 | 6 | * modification, are permitted provided that the following conditions are met: |
| @@ -398,6 +399,10 @@ u16 fman_get_max_frm(void); · 392 unmodified lines | ||
| 398 | 399 | |
| 399 | 400 | int fman_get_rx_extra_headroom(void); |
| 400 | 401 | |
| 402 | +#ifdef CONFIG_DPAA_ERRATUM_A050385 | |
| 403 | +bool fman_has_errata_a050385(void); | |
| 404 | +#endif | |
| 405 | + | |
| 401 | 406 | struct fman *fman_bind(struct device *dev); |
| 402 | 407 | |
| 403 | 408 | #endif /* __FM_H */ |
| @@ -46,6 +46,7 @@ enum HCLGE_MBX_OPCODE { · 45 unmodified lines | ||
| 46 | 46 | HCLGE_MBX_PUSH_VLAN_INFO, /* (PF -> VF) push port base vlan */ |
| 47 | 47 | HCLGE_MBX_GET_MEDIA_TYPE, /* (VF -> PF) get media type */ |
| 48 | 48 | HCLGE_MBX_PUSH_PROMISC_INFO, /* (PF -> VF) push vf promisc info */ |
| 49 | + HCLGE_MBX_VF_UNINIT, /* (VF -> PF) vf is unintializing */ | |
| 49 | 50 | |
| 50 | 51 | HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf flr status */ |
| 51 | 52 | HCLGE_MBX_PUSH_LINK_STATUS, /* (M7 -> PF) get port link status */ |
| @@ -1711,7 +1711,7 @@ static int hns3_setup_tc(struct net_device *netdev, void *type_data) · 1710 unmodified lines | ||
| 1711 | 1711 | netif_dbg(h, drv, netdev, "setup tc: num_tc=%u\n", tc); |
| 1712 | 1712 | |
| 1713 | 1713 | return (kinfo->dcb_ops && kinfo->dcb_ops->setup_tc) ? |
| 1714 | − kinfo->dcb_ops->setup_tc(h, tc, prio_tc) : -EOPNOTSUPP; | |
| 1714 | + kinfo->dcb_ops->setup_tc(h, tc ? tc : 1, prio_tc) : -EOPNOTSUPP; | |
| 1715 | 1715 | } |
| 1716 | 1716 | |
| 1717 | 1717 | static int hns3_nic_setup_tc(struct net_device *dev, enum tc_setup_type type, |
| @@ -2446,10 +2446,12 @@ static int hclge_cfg_mac_speed_dup_hw(struct hclge_dev *hdev, int speed, · 2445 unmodified lines | ||
| 2446 | 2446 | |
| 2447 | 2447 | int hclge_cfg_mac_speed_dup(struct hclge_dev *hdev, int speed, u8 duplex) |
| 2448 | 2448 | { |
| 2449 | + struct hclge_mac *mac = &hdev->hw.mac; | |
| 2449 | 2450 | int ret; |
| 2450 | 2451 | |
| 2451 | 2452 | duplex = hclge_check_speed_dup(duplex, speed); |
| 2452 | − if (hdev->hw.mac.speed == speed && hdev->hw.mac.duplex == duplex) | |
| 2453 | + if (!mac->support_autoneg && mac->speed == speed && | |
| 2454 | + mac->duplex == duplex) | |
| 2453 | 2455 | return 0; |
| 2454 | 2456 | |
| 2455 | 2457 | ret = hclge_cfg_mac_speed_dup_hw(hdev, speed, duplex); |
| @@ -7743,16 +7745,27 @@ static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type, · 5287 unmodified lines | ||
| 7743 | 7745 | struct hclge_desc desc; |
| 7744 | 7746 | int ret; |
| 7745 | 7747 | |
| 7746 | − hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_FILTER_CTRL, false); | |
| 7747 | − | |
| 7748 | + /* read current vlan filter parameter */ | |
| 7749 | + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_FILTER_CTRL, true); | |
| 7748 | 7750 | req = (struct hclge_vlan_filter_ctrl_cmd *)desc.data; |
| 7749 | 7751 | req->vlan_type = vlan_type; |
| 7750 | − req->vlan_fe = filter_en ? fe_type : 0; | |
| 7751 | 7752 | req->vf_id = vf_id; |
| 7752 | 7753 | |
| 7754 | + ret = hclge_cmd_send(&hdev->hw, &desc, 1); | |
| 7755 | + if (ret) { | |
| 7756 | + dev_err(&hdev->pdev->dev, | |
| 7757 | + "failed to get vlan filter config, ret = %d.\n", ret); | |
| 7758 | + return ret; | |
| 7759 | + } | |
| 7760 | + | |
| 7761 | + /* modify and write new config parameter */ | |
| 7762 | + hclge_cmd_reuse_desc(&desc, false); | |
| 7763 | + req->vlan_fe = filter_en ? | |
| 7764 | + (req->vlan_fe | fe_type) : (req->vlan_fe & ~fe_type); | |
| 7765 | + | |
| 7753 | 7766 | ret = hclge_cmd_send(&hdev->hw, &desc, 1); |
| 7754 | 7767 | if (ret) |
| 7755 | − dev_err(&hdev->pdev->dev, "set vlan filter fail, ret =%d.\n", | |
| 7768 | + dev_err(&hdev->pdev->dev, "failed to set vlan filter, ret = %d.\n", | |
| 7756 | 7769 | ret); |
| 7757 | 7770 | |
| 7758 | 7771 | return ret; |
| @@ -8270,6 +8283,7 @@ void hclge_rm_vport_all_vlan_table(struct hclge_vport *vport, bool is_del_list) · 511 unmodified lines | ||
| 8270 | 8283 | kfree(vlan); |
| 8271 | 8284 | } |
| 8272 | 8285 | } |
| 8286 | + clear_bit(vport->vport_id, hdev->vf_vlan_full); | |
| 8273 | 8287 | } |
| 8274 | 8288 | |
| 8275 | 8289 | void hclge_uninit_vport_vlan_table(struct hclge_dev *hdev) |
| @@ -8486,6 +8500,28 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid, · 210 unmodified lines | ||
| 8486 | 8500 | } |
| 8487 | 8501 | } |
| 8488 | 8502 | |
| 8503 | +static void hclge_clear_vf_vlan(struct hclge_dev *hdev) | |
| 8504 | +{ | |
| 8505 | + struct hclge_vlan_info *vlan_info; | |
| 8506 | + struct hclge_vport *vport; | |
| 8507 | + int ret; | |
| 8508 | + int vf; | |
| 8509 | + | |
| 8510 | + /* clear port base vlan for all vf */ | |
| 8511 | + for (vf = HCLGE_VF_VPORT_START_NUM; vf < hdev->num_alloc_vport; vf++) { | |
| 8512 | + vport = &hdev->vport[vf]; | |
| 8513 | + vlan_info = &vport->port_base_vlan_cfg.vlan_info; | |
| 8514 | + | |
| 8515 | + ret = hclge_set_vlan_filter_hw(hdev, htons(ETH_P_8021Q), | |
| 8516 | + vport->vport_id, | |
| 8517 | + vlan_info->vlan_tag, true); | |
| 8518 | + if (ret) | |
| 8519 | + dev_err(&hdev->pdev->dev, | |
| 8520 | + "failed to clear vf vlan for vf%d, ret = %d\n", | |
| 8521 | + vf - HCLGE_VF_VPORT_START_NUM, ret); | |
| 8522 | + } | |
| 8523 | +} | |
| 8524 | + | |
| 8489 | 8525 | int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, |
| 8490 | 8526 | u16 vlan_id, bool is_kill) |
| 8491 | 8527 | { |
| @@ -9895,6 +9931,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) · 1403 unmodified lines | ||
| 9895 | 9931 | struct hclge_mac *mac = &hdev->hw.mac; |
| 9896 | 9932 | |
| 9897 | 9933 | hclge_reset_vf_rate(hdev); |
| 9934 | + hclge_clear_vf_vlan(hdev); | |
| 9898 | 9935 | hclge_misc_affinity_teardown(hdev); |
| 9899 | 9936 | hclge_state_uninit(hdev); |
| 9900 | 9937 | |
| @@ -799,6 +799,7 @@ void hclge_mbx_handler(struct hclge_dev *hdev) · 798 unmodified lines | ||
| 799 | 799 | hclge_get_link_mode(vport, req); |
| 800 | 800 | break; |
| 801 | 801 | case HCLGE_MBX_GET_VF_FLR_STATUS: |
| 802 | + case HCLGE_MBX_VF_UNINIT: | |
| 802 | 803 | hclge_rm_vport_all_mac_table(vport, true, |
| 803 | 804 | HCLGE_MAC_ADDR_UC); |
| 804 | 805 | hclge_rm_vport_all_mac_table(vport, true, |
| @@ -2803,6 +2803,9 @@ static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev) · 2802 unmodified lines | ||
| 2803 | 2803 | { |
| 2804 | 2804 | hclgevf_state_uninit(hdev); |
| 2805 | 2805 | |
| 2806 | + hclgevf_send_mbx_msg(hdev, HCLGE_MBX_VF_UNINIT, 0, NULL, 0, | |
| 2807 | + false, NULL, 0); | |
| 2808 | + | |
| 2806 | 2809 | if (test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) { |
| 2807 | 2810 | hclgevf_misc_irq_uninit(hdev); |
| 2808 | 2811 | hclgevf_uninit_msi(hdev); |
| @@ -297,6 +297,7 @@ static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth, · 296 unmodified lines | ||
| 297 | 297 | } |
| 298 | 298 | |
| 299 | 299 | hw_ioctxt.func_idx = HINIC_HWIF_FUNC_IDX(hwif); |
| 300 | + hw_ioctxt.ppf_idx = HINIC_HWIF_PPF_IDX(hwif); | |
| 300 | 301 | |
| 301 | 302 | hw_ioctxt.set_cmdq_depth = HW_IOCTXT_SET_CMDQ_DEPTH_DEFAULT; |
| 302 | 303 | hw_ioctxt.cmdq_depth = 0; |
| @@ -151,8 +151,8 @@ struct hinic_cmd_hw_ioctxt { · 150 unmodified lines | ||
| 151 | 151 | |
| 152 | 152 | u8 lro_en; |
| 153 | 153 | u8 rsvd3; |
| 154 | + u8 ppf_idx; | |
| 154 | 155 | u8 rsvd4; |
| 155 | − u8 rsvd5; | |
| 156 | 156 | |
| 157 | 157 | u16 rq_depth; |
| 158 | 158 | u16 rx_buf_sz_idx; |
| @@ -137,6 +137,7 @@ · 136 unmodified lines | ||
| 137 | 137 | #define HINIC_HWIF_FUNC_IDX(hwif) ((hwif)->attr.func_idx) |
| 138 | 138 | #define HINIC_HWIF_PCI_INTF(hwif) ((hwif)->attr.pci_intf_idx) |
| 139 | 139 | #define HINIC_HWIF_PF_IDX(hwif) ((hwif)->attr.pf_idx) |
| 140 | +#define HINIC_HWIF_PPF_IDX(hwif) ((hwif)->attr.ppf_idx) | |
| 140 | 141 | |
| 141 | 142 | #define HINIC_FUNC_TYPE(hwif) ((hwif)->attr.func_type) |
| 142 | 143 | #define HINIC_IS_PF(hwif) (HINIC_FUNC_TYPE(hwif) == HINIC_PF) |
| @@ -94,6 +94,7 @@ struct hinic_rq { · 93 unmodified lines | ||
| 94 | 94 | |
| 95 | 95 | struct hinic_wq *wq; |
| 96 | 96 | |
| 97 | + struct cpumask affinity_mask; | |
| 97 | 98 | u32 irq; |
| 98 | 99 | u16 msix_entry; |
| 99 | 100 | |
| @@ -356,7 +356,8 @@ static void hinic_enable_rss(struct hinic_dev *nic_dev) · 355 unmodified lines | ||
| 356 | 356 | if (!num_cpus) |
| 357 | 357 | num_cpus = num_online_cpus(); |
| 358 | 358 | |
| 359 | − nic_dev->num_qps = min_t(u16, nic_dev->max_qps, num_cpus); | |
| 359 | + nic_dev->num_qps = hinic_hwdev_num_qps(hwdev); | |
| 360 | + nic_dev->num_qps = min_t(u16, nic_dev->num_qps, num_cpus); | |
| 360 | 361 | |
| 361 | 362 | nic_dev->rss_limit = nic_dev->num_qps; |
| 362 | 363 | nic_dev->num_rss = nic_dev->num_qps; |
| @@ -475,7 +475,6 @@ static int rx_request_irq(struct hinic_rxq *rxq) · 474 unmodified lines | ||
| 475 | 475 | struct hinic_hwdev *hwdev = nic_dev->hwdev; |
| 476 | 476 | struct hinic_rq *rq = rxq->rq; |
| 477 | 477 | struct hinic_qp *qp; |
| 478 | − struct cpumask mask; | |
| 479 | 478 | int err; |
| 480 | 479 | |
| 481 | 480 | rx_add_napi(rxq); |
| @@ -492,8 +491,8 @@ static int rx_request_irq(struct hinic_rxq *rxq) · 10 unmodified lines | ||
| 492 | 491 | } |
| 493 | 492 | |
| 494 | 493 | qp = container_of(rq, struct hinic_qp, rq); |
| 495 | − cpumask_set_cpu(qp->q_id % num_online_cpus(), &mask); | |
| 496 | − return irq_set_affinity_hint(rq->irq, &mask); | |
| 494 | + cpumask_set_cpu(qp->q_id % num_online_cpus(), &rq->affinity_mask); | |
| 495 | + return irq_set_affinity_hint(rq->irq, &rq->affinity_mask); | |
| 497 | 496 | } |
| 498 | 497 | |
| 499 | 498 | static void rx_free_irq(struct hinic_rxq *rxq) |
| @@ -2142,6 +2142,8 @@ static void __ibmvnic_reset(struct work_struct *work) · 2141 unmodified lines | ||
| 2142 | 2142 | { |
| 2143 | 2143 | struct ibmvnic_rwi *rwi; |
| 2144 | 2144 | struct ibmvnic_adapter *adapter; |
| 2145 | + bool saved_state = false; | |
| 2146 | + unsigned long flags; | |
| 2145 | 2147 | u32 reset_state; |
| 2146 | 2148 | int rc = 0; |
| 2147 | 2149 | |
| @@ -2153,17 +2155,25 @@ static void __ibmvnic_reset(struct work_struct *work) · 5 unmodified lines | ||
| 2153 | 2155 | return; |
| 2154 | 2156 | } |
| 2155 | 2157 | |
| 2156 | − reset_state = adapter->state; | |
| 2157 | − | |
| 2158 | 2158 | rwi = get_next_rwi(adapter); |
| 2159 | 2159 | while (rwi) { |
| 2160 | + spin_lock_irqsave(&adapter->state_lock, flags); | |
| 2161 | + | |
| 2160 | 2162 | if (adapter->state == VNIC_REMOVING || |
| 2161 | 2163 | adapter->state == VNIC_REMOVED) { |
| 2164 | + spin_unlock_irqrestore(&adapter->state_lock, flags); | |
| 2162 | 2165 | kfree(rwi); |
| 2163 | 2166 | rc = EBUSY; |
| 2164 | 2167 | break; |
| 2165 | 2168 | } |
| 2166 | 2169 | |
| 2170 | + if (!saved_state) { | |
| 2171 | + reset_state = adapter->state; | |
| 2172 | + adapter->state = VNIC_RESETTING; | |
| 2173 | + saved_state = true; | |
| 2174 | + } | |
| 2175 | + spin_unlock_irqrestore(&adapter->state_lock, flags); | |
| 2176 | + | |
| 2167 | 2177 | if (rwi->reset_reason == VNIC_RESET_CHANGE_PARAM) { |
| 2168 | 2178 | /* CHANGE_PARAM requestor holds rtnl_lock */ |
| 2169 | 2179 | rc = do_change_param_reset(adapter, rwi, reset_state); |
| @@ -5091,6 +5101,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id) · 2921 unmodified lines | ||
| 5091 | 5101 | __ibmvnic_delayed_reset); |
| 5092 | 5102 | INIT_LIST_HEAD(&adapter->rwi_list); |
| 5093 | 5103 | spin_lock_init(&adapter->rwi_lock); |
| 5104 | + spin_lock_init(&adapter->state_lock); | |
| 5094 | 5105 | mutex_init(&adapter->fw_lock); |
| 5095 | 5106 | init_completion(&adapter->init_done); |
| 5096 | 5107 | init_completion(&adapter->fw_done); |
| @@ -5163,8 +5174,17 @@ static int ibmvnic_remove(struct vio_dev *dev) · 66 unmodified lines | ||
| 5163 | 5174 | { |
| 5164 | 5175 | struct net_device *netdev = dev_get_drvdata(&dev->dev); |
| 5165 | 5176 | struct ibmvnic_adapter *adapter = netdev_priv(netdev); |
| 5177 | + unsigned long flags; | |
| 5178 | + | |
| 5179 | + spin_lock_irqsave(&adapter->state_lock, flags); | |
| 5180 | + if (adapter->state == VNIC_RESETTING) { | |
| 5181 | + spin_unlock_irqrestore(&adapter->state_lock, flags); | |
| 5182 | + return -EBUSY; | |
| 5183 | + } | |
| 5166 | 5184 | |
| 5167 | 5185 | adapter->state = VNIC_REMOVING; |
| 5186 | + spin_unlock_irqrestore(&adapter->state_lock, flags); | |
| 5187 | + | |
| 5168 | 5188 | rtnl_lock(); |
| 5169 | 5189 | unregister_netdevice(netdev); |
| 5170 | 5190 | |
| @@ -941,7 +941,8 @@ enum vnic_state {VNIC_PROBING = 1, · 940 unmodified lines | ||
| 941 | 941 | VNIC_CLOSING, |
| 942 | 942 | VNIC_CLOSED, |
| 943 | 943 | VNIC_REMOVING, |
| 944 | − VNIC_REMOVED}; | |
| 944 | + VNIC_REMOVED, | |
| 945 | + VNIC_RESETTING}; | |
| 945 | 946 | |
| 946 | 947 | enum ibmvnic_reset_reason {VNIC_RESET_FAILOVER = 1, |
| 947 | 948 | VNIC_RESET_MOBILITY, |
| @@ -1090,4 +1091,7 @@ struct ibmvnic_adapter { · 142 unmodified lines | ||
| 1090 | 1091 | |
| 1091 | 1092 | struct ibmvnic_tunables desired; |
| 1092 | 1093 | struct ibmvnic_tunables fallback; |
| 1094 | + | |
| 1095 | + /* Used for serializatin of state field */ | |
| 1096 | + spinlock_t state_lock; | |
| 1093 | 1097 | }; |
| @@ -347,7 +347,7 @@ static int orion_mdio_probe(struct platform_device *pdev) · 346 unmodified lines | ||
| 347 | 347 | } |
| 348 | 348 | |
| 349 | 349 | |
| 350 | − dev->err_interrupt = platform_get_irq(pdev, 0); | |
| 350 | + dev->err_interrupt = platform_get_irq_optional(pdev, 0); | |
| 351 | 351 | if (dev->err_interrupt > 0 && |
| 352 | 352 | resource_size(r) < MVMDIO_ERR_INT_MASK + 4) { |
| 353 | 353 | dev_err(&pdev->dev, |
| @@ -364,8 +364,8 @@ static int orion_mdio_probe(struct platform_device *pdev) · 10 unmodified lines | ||
| 364 | 364 | writel(MVMDIO_ERR_INT_SMI_DONE, |
| 365 | 365 | dev->regs + MVMDIO_ERR_INT_MASK); |
| 366 | 366 | |
| 367 | − } else if (dev->err_interrupt == -EPROBE_DEFER) { | |
| 368 | − ret = -EPROBE_DEFER; | |
| 367 | + } else if (dev->err_interrupt < 0) { | |
| 368 | + ret = dev->err_interrupt; | |
| 369 | 369 | goto out_mdio; |
| 370 | 370 | } |
| 371 | 371 | |
| @@ -5147,7 +5147,6 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv) · 5146 unmodified lines | ||
| 5147 | 5147 | |
| 5148 | 5148 | static void mlx5e_nic_disable(struct mlx5e_priv *priv) |
| 5149 | 5149 | { |
| 5150 | − struct net_device *netdev = priv->netdev; | |
| 5151 | 5150 | struct mlx5_core_dev *mdev = priv->mdev; |
| 5152 | 5151 | |
| 5153 | 5152 | #ifdef CONFIG_MLX5_CORE_EN_DCB |
| @@ -5168,7 +5167,7 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv) · 14 unmodified lines | ||
| 5168 | 5167 | mlx5e_monitor_counter_cleanup(priv); |
| 5169 | 5168 | |
| 5170 | 5169 | mlx5e_disable_async_events(priv); |
| 5171 | − mlx5_lag_remove(mdev, netdev); | |
| 5170 | + mlx5_lag_remove(mdev); | |
| 5172 | 5171 | } |
| 5173 | 5172 | |
| 5174 | 5173 | int mlx5e_update_nic_rx(struct mlx5e_priv *priv) |
| @@ -1861,7 +1861,6 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) · 1860 unmodified lines | ||
| 1861 | 1861 | |
| 1862 | 1862 | static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv) |
| 1863 | 1863 | { |
| 1864 | − struct net_device *netdev = priv->netdev; | |
| 1865 | 1864 | struct mlx5_core_dev *mdev = priv->mdev; |
| 1866 | 1865 | struct mlx5e_rep_priv *rpriv = priv->ppriv; |
| 1867 | 1866 | |
| @@ -1870,7 +1869,7 @@ static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv) · 2 unmodified lines | ||
| 1870 | 1869 | #endif |
| 1871 | 1870 | mlx5_notifier_unregister(mdev, &priv->events_nb); |
| 1872 | 1871 | cancel_work_sync(&rpriv->uplink_priv.reoffload_flows_work); |
| 1873 | − mlx5_lag_remove(mdev, netdev); | |
| 1872 | + mlx5_lag_remove(mdev); | |
| 1874 | 1873 | } |
| 1875 | 1874 | |
| 1876 | 1875 | static MLX5E_DEFINE_STATS_GRP(sw_rep, 0); |
| @@ -464,9 +464,6 @@ static int mlx5_lag_netdev_event(struct notifier_block *this, · 463 unmodified lines | ||
| 464 | 464 | struct mlx5_lag *ldev; |
| 465 | 465 | int changed = 0; |
| 466 | 466 | |
| 467 | − if (!net_eq(dev_net(ndev), &init_net)) | |
| 468 | − return NOTIFY_DONE; | |
| 469 | − | |
| 470 | 467 | if ((event != NETDEV_CHANGEUPPER) && (event != NETDEV_CHANGELOWERSTATE)) |
| 471 | 468 | return NOTIFY_DONE; |
| 472 | 469 | |
| @@ -586,8 +583,7 @@ void mlx5_lag_add(struct mlx5_core_dev *dev, struct net_device *netdev) · 113 unmodified lines | ||
| 586 | 583 | |
| 587 | 584 | if (!ldev->nb.notifier_call) { |
| 588 | 585 | ldev->nb.notifier_call = mlx5_lag_netdev_event; |
| 589 | − if (register_netdevice_notifier_dev_net(netdev, &ldev->nb, | |
| 590 | − &ldev->nn)) { | |
| 586 | + if (register_netdevice_notifier_net(&init_net, &ldev->nb)) { | |
| 591 | 587 | ldev->nb.notifier_call = NULL; |
| 592 | 588 | mlx5_core_err(dev, "Failed to register LAG netdev notifier\n"); |
| 593 | 589 | } |
| @@ -600,7 +596,7 @@ void mlx5_lag_add(struct mlx5_core_dev *dev, struct net_device *netdev) · 6 unmodified lines | ||
| 600 | 596 | } |
| 601 | 597 | |
| 602 | 598 | /* Must be called with intf_mutex held */ |
| 603 | −void mlx5_lag_remove(struct mlx5_core_dev *dev, struct net_device *netdev) | |
| 599 | +void mlx5_lag_remove(struct mlx5_core_dev *dev) | |
| 604 | 600 | { |
| 605 | 601 | struct mlx5_lag *ldev; |
| 606 | 602 | int i; |
| @@ -620,8 +616,7 @@ void mlx5_lag_remove(struct mlx5_core_dev *dev, struct net_device *netdev) · 13 unmodified lines | ||
| 620 | 616 | |
| 621 | 617 | if (i == MLX5_MAX_PORTS) { |
| 622 | 618 | if (ldev->nb.notifier_call) |
| 623 | − unregister_netdevice_notifier_dev_net(netdev, &ldev->nb, | |
| 624 | − &ldev->nn); | |
| 619 | + unregister_netdevice_notifier_net(&init_net, &ldev->nb); | |
| 625 | 620 | mlx5_lag_mp_cleanup(ldev); |
| 626 | 621 | cancel_delayed_work_sync(&ldev->bond_work); |
| 627 | 622 | mlx5_lag_dev_free(ldev); |
| @@ -44,7 +44,6 @@ struct mlx5_lag { · 43 unmodified lines | ||
| 44 | 44 | struct workqueue_struct *wq; |
| 45 | 45 | struct delayed_work bond_work; |
| 46 | 46 | struct notifier_block nb; |
| 47 | − struct netdev_net_notifier nn; | |
| 48 | 47 | struct lag_mp lag_mp; |
| 49 | 48 | }; |
| 50 | 49 | |
| @@ -157,7 +157,7 @@ int mlx5_query_qcam_reg(struct mlx5_core_dev *mdev, u32 *qcam, · 156 unmodified lines | ||
| 157 | 157 | u8 feature_group, u8 access_reg_group); |
| 158 | 158 | |
| 159 | 159 | void mlx5_lag_add(struct mlx5_core_dev *dev, struct net_device *netdev); |
| 160 | −void mlx5_lag_remove(struct mlx5_core_dev *dev, struct net_device *netdev); | |
| 160 | +void mlx5_lag_remove(struct mlx5_core_dev *dev); | |
| 161 | 161 | |
| 162 | 162 | int mlx5_irq_table_init(struct mlx5_core_dev *dev); |
| 163 | 163 | void mlx5_irq_table_cleanup(struct mlx5_core_dev *dev); |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #define MLXSW_PCI_SW_RESET 0xF0010 |
| 29 | 29 | #define MLXSW_PCI_SW_RESET_RST_BIT BIT(0) |
| 30 | 30 | #define MLXSW_PCI_SW_RESET_TIMEOUT_MSECS 900000 |
| 31 | −#define MLXSW_PCI_SW_RESET_WAIT_MSECS 100 | |
| 31 | +#define MLXSW_PCI_SW_RESET_WAIT_MSECS 200 | |
| 32 | 32 | #define MLXSW_PCI_FW_READY 0xA1844 |
| 33 | 33 | #define MLXSW_PCI_FW_READY_MASK 0xFFFF |
| 34 | 34 | #define MLXSW_PCI_FW_READY_MAGIC 0x5E |
| @@ -513,14 +513,17 @@ static irqreturn_t ks_irq(int irq, void *pw) · 512 unmodified lines | ||
| 513 | 513 | { |
| 514 | 514 | struct net_device *netdev = pw; |
| 515 | 515 | struct ks_net *ks = netdev_priv(netdev); |
| 516 | + unsigned long flags; | |
| 516 | 517 | u16 status; |
| 517 | 518 | |
| 519 | + spin_lock_irqsave(&ks->statelock, flags); | |
| 518 | 520 | /*this should be the first in IRQ handler */ |
| 519 | 521 | ks_save_cmd_reg(ks); |
| 520 | 522 | |
| 521 | 523 | status = ks_rdreg16(ks, KS_ISR); |
| 522 | 524 | if (unlikely(!status)) { |
| 523 | 525 | ks_restore_cmd_reg(ks); |
| 526 | + spin_unlock_irqrestore(&ks->statelock, flags); | |
| 524 | 527 | return IRQ_NONE; |
| 525 | 528 | } |
| 526 | 529 | |
| @@ -546,6 +549,7 @@ static irqreturn_t ks_irq(int irq, void *pw) · 19 unmodified lines | ||
| 546 | 549 | ks->netdev->stats.rx_over_errors++; |
| 547 | 550 | /* this should be the last in IRQ handler*/ |
| 548 | 551 | ks_restore_cmd_reg(ks); |
| 552 | + spin_unlock_irqrestore(&ks->statelock, flags); | |
| 549 | 553 | return IRQ_HANDLED; |
| 550 | 554 | } |
| 551 | 555 | |
| @@ -615,6 +619,7 @@ static int ks_net_stop(struct net_device *netdev) · 63 unmodified lines | ||
| 615 | 619 | |
| 616 | 620 | /* shutdown RX/TX QMU */ |
| 617 | 621 | ks_disable_qmu(ks); |
| 622 | + ks_disable_int(ks); | |
| 618 | 623 | |
| 619 | 624 | /* set powermode to soft power down to save power */ |
| 620 | 625 | ks_set_powermode(ks, PMECR_PM_SOFTDOWN); |
| @@ -671,10 +676,9 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) · 50 unmodified lines | ||
| 671 | 676 | { |
| 672 | 677 | netdev_tx_t retv = NETDEV_TX_OK; |
| 673 | 678 | struct ks_net *ks = netdev_priv(netdev); |
| 679 | + unsigned long flags; | |
| 674 | 680 | |
| 675 | − disable_irq(netdev->irq); | |
| 676 | − ks_disable_int(ks); | |
| 677 | − spin_lock(&ks->statelock); | |
| 681 | + spin_lock_irqsave(&ks->statelock, flags); | |
| 678 | 682 | |
| 679 | 683 | /* Extra space are required: |
| 680 | 684 | * 4 byte for alignment, 4 for status/length, 4 for CRC |
| @@ -688,9 +692,7 @@ static netdev_tx_t ks_start_xmit(struct sk_buff *skb, struct net_device *netdev) · 7 unmodified lines | ||
| 688 | 692 | dev_kfree_skb(skb); |
| 689 | 693 | } else |
| 690 | 694 | retv = NETDEV_TX_BUSY; |
| 691 | − spin_unlock(&ks->statelock); | |
| 692 | − ks_enable_int(ks); | |
| 693 | − enable_irq(netdev->irq); | |
| 695 | + spin_unlock_irqrestore(&ks->statelock, flags); | |
| 694 | 696 | return retv; |
| 695 | 697 | } |
| 696 | 698 | |
| @@ -2176,24 +2176,29 @@ static int ocelot_init_timestamp(struct ocelot *ocelot) · 2175 unmodified lines | ||
| 2176 | 2176 | return 0; |
| 2177 | 2177 | } |
| 2178 | 2178 | |
| 2179 | −static void ocelot_port_set_mtu(struct ocelot *ocelot, int port, size_t mtu) | |
| 2179 | +/* Configure the maximum SDU (L2 payload) on RX to the value specified in @sdu. | |
| 2180 | + * The length of VLAN tags is accounted for automatically via DEV_MAC_TAGS_CFG. | |
| 2181 | + */ | |
| 2182 | +static void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu) | |
| 2180 | 2183 | { |
| 2181 | 2184 | struct ocelot_port *ocelot_port = ocelot->ports[port]; |
| 2185 | + int maxlen = sdu + ETH_HLEN + ETH_FCS_LEN; | |
| 2182 | 2186 | int atop_wm; |
| 2183 | 2187 | |
| 2184 | − ocelot_port_writel(ocelot_port, mtu, DEV_MAC_MAXLEN_CFG); | |
| 2188 | + ocelot_port_writel(ocelot_port, maxlen, DEV_MAC_MAXLEN_CFG); | |
| 2185 | 2189 | |
| 2186 | 2190 | /* Set Pause WM hysteresis |
| 2187 | − * 152 = 6 * mtu / OCELOT_BUFFER_CELL_SZ | |
| 2188 | − * 101 = 4 * mtu / OCELOT_BUFFER_CELL_SZ | |
| 2191 | + * 152 = 6 * maxlen / OCELOT_BUFFER_CELL_SZ | |
| 2192 | + * 101 = 4 * maxlen / OCELOT_BUFFER_CELL_SZ | |
| 2189 | 2193 | */ |
| 2190 | 2194 | ocelot_write_rix(ocelot, SYS_PAUSE_CFG_PAUSE_ENA | |
| 2191 | 2195 | SYS_PAUSE_CFG_PAUSE_STOP(101) | |
| 2192 | 2196 | SYS_PAUSE_CFG_PAUSE_START(152), SYS_PAUSE_CFG, port); |
| 2193 | 2197 | |
| 2194 | 2198 | /* Tail dropping watermark */ |
| 2195 | − atop_wm = (ocelot->shared_queue_sz - 9 * mtu) / OCELOT_BUFFER_CELL_SZ; | |
| 2196 | − ocelot_write_rix(ocelot, ocelot_wm_enc(9 * mtu), | |
| 2199 | + atop_wm = (ocelot->shared_queue_sz - 9 * maxlen) / | |
| 2200 | + OCELOT_BUFFER_CELL_SZ; | |
| 2201 | + ocelot_write_rix(ocelot, ocelot_wm_enc(9 * maxlen), | |
| 2197 | 2202 | SYS_ATOP, port); |
| 2198 | 2203 | ocelot_write(ocelot, ocelot_wm_enc(atop_wm), SYS_ATOP_TOT_CFG); |
| 2199 | 2204 | } |
| @@ -2222,9 +2227,10 @@ void ocelot_init_port(struct ocelot *ocelot, int port) · 22 unmodified lines | ||
| 2222 | 2227 | DEV_MAC_HDX_CFG); |
| 2223 | 2228 | |
| 2224 | 2229 | /* Set Max Length and maximum tags allowed */ |
| 2225 | − ocelot_port_set_mtu(ocelot, port, VLAN_ETH_FRAME_LEN); | |
| 2230 | + ocelot_port_set_maxlen(ocelot, port, ETH_DATA_LEN); | |
| 2226 | 2231 | ocelot_port_writel(ocelot_port, DEV_MAC_TAGS_CFG_TAG_ID(ETH_P_8021AD) | |
| 2227 | 2232 | DEV_MAC_TAGS_CFG_VLAN_AWR_ENA | |
| 2233 | + DEV_MAC_TAGS_CFG_VLAN_DBL_AWR_ENA | | |
| 2228 | 2234 | DEV_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, |
| 2229 | 2235 | DEV_MAC_TAGS_CFG); |
| 2230 | 2236 | |
| @@ -2310,18 +2316,18 @@ void ocelot_set_cpu_port(struct ocelot *ocelot, int cpu, · 79 unmodified lines | ||
| 2310 | 2316 | * Only one port can be an NPI at the same time. |
| 2311 | 2317 | */ |
| 2312 | 2318 | if (cpu < ocelot->num_phys_ports) { |
| 2313 | − int mtu = VLAN_ETH_FRAME_LEN + OCELOT_TAG_LEN; | |
| 2319 | + int sdu = ETH_DATA_LEN + OCELOT_TAG_LEN; | |
| 2314 | 2320 | |
| 2315 | 2321 | ocelot_write(ocelot, QSYS_EXT_CPU_CFG_EXT_CPUQ_MSK_M | |
| 2316 | 2322 | QSYS_EXT_CPU_CFG_EXT_CPU_PORT(cpu), |
| 2317 | 2323 | QSYS_EXT_CPU_CFG); |
| 2318 | 2324 | |
| 2319 | 2325 | if (injection == OCELOT_TAG_PREFIX_SHORT) |
| 2320 | − mtu += OCELOT_SHORT_PREFIX_LEN; | |
| 2326 | + sdu += OCELOT_SHORT_PREFIX_LEN; | |
| 2321 | 2327 | else if (injection == OCELOT_TAG_PREFIX_LONG) |
| 2322 | − mtu += OCELOT_LONG_PREFIX_LEN; | |
| 2328 | + sdu += OCELOT_LONG_PREFIX_LEN; | |
| 2323 | 2329 | |
| 2324 | − ocelot_port_set_mtu(ocelot, cpu, mtu); | |
| 2330 | + ocelot_port_set_maxlen(ocelot, cpu, sdu); | |
| 2325 | 2331 | } |
| 2326 | 2332 | |
| 2327 | 2333 | /* CPU port Injection/Extraction configuration */ |
| @@ -1688,7 +1688,7 @@ static int ionic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) · 1687 unmodified lines | ||
| 1688 | 1688 | if (!(is_zero_ether_addr(mac) || is_valid_ether_addr(mac))) |
| 1689 | 1689 | return -EINVAL; |
| 1690 | 1690 | |
| 1691 | − down_read(&ionic->vf_op_lock); | |
| 1691 | + down_write(&ionic->vf_op_lock); | |
| 1692 | 1692 | |
| 1693 | 1693 | if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) { |
| 1694 | 1694 | ret = -EINVAL; |
| @@ -1698,7 +1698,7 @@ static int ionic_set_vf_mac(struct net_device *netdev, int vf, u8 *mac) · 3 unmodified lines | ||
| 1698 | 1698 | ether_addr_copy(ionic->vfs[vf].macaddr, mac); |
| 1699 | 1699 | } |
| 1700 | 1700 | |
| 1701 | − up_read(&ionic->vf_op_lock); | |
| 1701 | + up_write(&ionic->vf_op_lock); | |
| 1702 | 1702 | return ret; |
| 1703 | 1703 | } |
| 1704 | 1704 | |
| @@ -1719,7 +1719,7 @@ static int ionic_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, · 14 unmodified lines | ||
| 1719 | 1719 | if (proto != htons(ETH_P_8021Q)) |
| 1720 | 1720 | return -EPROTONOSUPPORT; |
| 1721 | 1721 | |
| 1722 | − down_read(&ionic->vf_op_lock); | |
| 1722 | + down_write(&ionic->vf_op_lock); | |
| 1723 | 1723 | |
| 1724 | 1724 | if (vf >= pci_num_vf(ionic->pdev) || !ionic->vfs) { |
| 1725 | 1725 | ret = -EINVAL; |
| @@ -1730,7 +1730,7 @@ static int ionic_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, · 4 unmodified lines | ||
| 1730 | 1730 | ionic->vfs[vf].vlanid = vlan; |
| 1731 | 1731 | } |
| 1732 | 1732 | |
| 1733 | − up_read(&ionic->vf_op_lock); | |
| 1733 | + up_write(&ionic->vf_op_lock); | |
| 1734 | 1734 | return ret; |
| 1735 | 1735 | } |
| 1736 | 1736 | |
| @@ -13,25 +13,6 @@ · 12 unmodified lines | ||
| 13 | 13 | #include "rmnet_vnd.h" |
| 14 | 14 | #include "rmnet_private.h" |
| 15 | 15 | |
| 16 | −/* Locking scheme - | |
| 17 | − * The shared resource which needs to be protected is realdev->rx_handler_data. | |
| 18 | − * For the writer path, this is using rtnl_lock(). The writer paths are | |
| 19 | − * rmnet_newlink(), rmnet_dellink() and rmnet_force_unassociate_device(). These | |
| 20 | − * paths are already called with rtnl_lock() acquired in. There is also an | |
| 21 | − * ASSERT_RTNL() to ensure that we are calling with rtnl acquired. For | |
| 22 | − * dereference here, we will need to use rtnl_dereference(). Dev list writing | |
| 23 | − * needs to happen with rtnl_lock() acquired for netdev_master_upper_dev_link(). | |
| 24 | − * For the reader path, the real_dev->rx_handler_data is called in the TX / RX | |
| 25 | − * path. We only need rcu_read_lock() for these scenarios. In these cases, | |
| 26 | − * the rcu_read_lock() is held in __dev_queue_xmit() and | |
| 27 | − * netif_receive_skb_internal(), so readers need to use rcu_dereference_rtnl() | |
| 28 | − * to get the relevant information. For dev list reading, we again acquire | |
| 29 | − * rcu_read_lock() in rmnet_dellink() for netdev_master_upper_dev_get_rcu(). | |
| 30 | − * We also use unregister_netdevice_many() to free all rmnet devices in | |
| 31 | − * rmnet_force_unassociate_device() so we dont lose the rtnl_lock() and free in | |
| 32 | − * same context. | |
| 33 | − */ | |
| 34 | − | |
| 35 | 16 | /* Local Definitions and Declarations */ |
| 36 | 17 | |
| 37 | 18 | static const struct nla_policy rmnet_policy[IFLA_RMNET_MAX + 1] = { |
| @@ -51,9 +32,10 @@ rmnet_get_port_rtnl(const struct net_device *real_dev) · 13 unmodified lines | ||
| 51 | 32 | return rtnl_dereference(real_dev->rx_handler_data); |
| 52 | 33 | } |
| 53 | 34 | |
| 54 | −static int rmnet_unregister_real_device(struct net_device *real_dev, | |
| 55 | − struct rmnet_port *port) | |
| 35 | +static int rmnet_unregister_real_device(struct net_device *real_dev) | |
| 56 | 36 | { |
| 37 | + struct rmnet_port *port = rmnet_get_port_rtnl(real_dev); | |
| 38 | + | |
| 57 | 39 | if (port->nr_rmnet_devs) |
| 58 | 40 | return -EINVAL; |
| 59 | 41 | |
| @@ -61,9 +43,6 @@ static int rmnet_unregister_real_device(struct net_device *real_dev, · 1 unmodified line | ||
| 61 | 43 | |
| 62 | 44 | kfree(port); |
| 63 | 45 | |
| 64 | − /* release reference on real_dev */ | |
| 65 | − dev_put(real_dev); | |
| 66 | − | |
| 67 | 46 | netdev_dbg(real_dev, "Removed from rmnet\n"); |
| 68 | 47 | return 0; |
| 69 | 48 | } |
| @@ -89,9 +68,6 @@ static int rmnet_register_real_device(struct net_device *real_dev) · 19 unmodified lines | ||
| 89 | 68 | return -EBUSY; |
| 90 | 69 | } |
| 91 | 70 | |
| 92 | − /* hold on to real dev for MAP data */ | |
| 93 | − dev_hold(real_dev); | |
| 94 | − | |
| 95 | 71 | for (entry = 0; entry < RMNET_MAX_LOGICAL_EP; entry++) |
| 96 | 72 | INIT_HLIST_HEAD(&port->muxed_ep[entry]); |
| 97 | 73 | |
| @@ -99,28 +75,33 @@ static int rmnet_register_real_device(struct net_device *real_dev) · 1 unmodified line | ||
| 99 | 75 | return 0; |
| 100 | 76 | } |
| 101 | 77 | |
| 102 | −static void rmnet_unregister_bridge(struct net_device *dev, | |
| 103 | − struct rmnet_port *port) | |
| 78 | +static void rmnet_unregister_bridge(struct rmnet_port *port) | |
| 104 | 79 | { |
| 105 | − struct rmnet_port *bridge_port; | |
| 106 | − struct net_device *bridge_dev; | |
| 80 | + struct net_device *bridge_dev, *real_dev, *rmnet_dev; | |
| 81 | + struct rmnet_port *real_port; | |
| 107 | 82 | |
| 108 | 83 | if (port->rmnet_mode != RMNET_EPMODE_BRIDGE) |
| 109 | 84 | return; |
| 110 | 85 | |
| 111 | − /* bridge slave handling */ | |
| 86 | + rmnet_dev = port->rmnet_dev; | |
| 112 | 87 | if (!port->nr_rmnet_devs) { |
| 113 | − bridge_dev = port->bridge_ep; | |
| 88 | + /* bridge device */ | |
| 89 | + real_dev = port->bridge_ep; | |
| 90 | + bridge_dev = port->dev; | |
| 114 | 91 | |
| 115 | − bridge_port = rmnet_get_port_rtnl(bridge_dev); | |
| 116 | − bridge_port->bridge_ep = NULL; | |
| 117 | − bridge_port->rmnet_mode = RMNET_EPMODE_VND; | |
| 92 | + real_port = rmnet_get_port_rtnl(real_dev); | |
| 93 | + real_port->bridge_ep = NULL; | |
| 94 | + real_port->rmnet_mode = RMNET_EPMODE_VND; | |
| 118 | 95 | } else { |
| 96 | + /* real device */ | |
| 119 | 97 | bridge_dev = port->bridge_ep; |
| 120 | 98 | |
| 121 | − bridge_port = rmnet_get_port_rtnl(bridge_dev); | |
| 122 | − rmnet_unregister_real_device(bridge_dev, bridge_port); | |
| 99 | + port->bridge_ep = NULL; | |
| 100 | + port->rmnet_mode = RMNET_EPMODE_VND; | |
| 123 | 101 | } |
| 102 | + | |
| 103 | + netdev_upper_dev_unlink(bridge_dev, rmnet_dev); | |
| 104 | + rmnet_unregister_real_device(bridge_dev); | |
| 124 | 105 | } |
| 125 | 106 | |
| 126 | 107 | static int rmnet_newlink(struct net *src_net, struct net_device *dev, |
| @@ -135,6 +116,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, · 8 unmodified lines | ||
| 135 | 116 | int err = 0; |
| 136 | 117 | u16 mux_id; |
| 137 | 118 | |
| 119 | + if (!tb[IFLA_LINK]) { | |
| 120 | + NL_SET_ERR_MSG_MOD(extack, "link not specified"); | |
| 121 | + return -EINVAL; | |
| 122 | + } | |
| 123 | + | |
| 138 | 124 | real_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK])); |
| 139 | 125 | if (!real_dev || !dev) |
| 140 | 126 | return -ENODEV; |
| @@ -157,7 +143,12 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, · 16 unmodified lines | ||
| 157 | 143 | if (err) |
| 158 | 144 | goto err1; |
| 159 | 145 | |
| 146 | + err = netdev_upper_dev_link(real_dev, dev, extack); | |
| 147 | + if (err < 0) | |
| 148 | + goto err2; | |
| 149 | + | |
| 160 | 150 | port->rmnet_mode = mode; |
| 151 | + port->rmnet_dev = dev; | |
| 161 | 152 | |
| 162 | 153 | hlist_add_head_rcu(&ep->hlnode, &port->muxed_ep[mux_id]); |
| 163 | 154 | |
| @@ -173,8 +164,11 @@ static int rmnet_newlink(struct net *src_net, struct net_device *dev, · 9 unmodified lines | ||
| 173 | 164 | |
| 174 | 165 | return 0; |
| 175 | 166 | |
| 167 | +err2: | |
| 168 | + unregister_netdevice(dev); | |
| 169 | + rmnet_vnd_dellink(mux_id, port, ep); | |
| 176 | 170 | err1: |
| 177 | − rmnet_unregister_real_device(real_dev, port); | |
| 171 | + rmnet_unregister_real_device(real_dev); | |
| 178 | 172 | err0: |
| 179 | 173 | kfree(ep); |
| 180 | 174 | return err; |
| @@ -183,77 +177,74 @@ err0: · 2 unmodified lines | ||
| 183 | 177 | static void rmnet_dellink(struct net_device *dev, struct list_head *head) |
| 184 | 178 | { |
| 185 | 179 | struct rmnet_priv *priv = netdev_priv(dev); |
| 186 | − struct net_device *real_dev; | |
| 180 | + struct net_device *real_dev, *bridge_dev; | |
| 181 | + struct rmnet_port *real_port, *bridge_port; | |
| 187 | 182 | struct rmnet_endpoint *ep; |
| 188 | − struct rmnet_port *port; | |
| 189 | − u8 mux_id; | |
| 183 | + u8 mux_id = priv->mux_id; | |
| 190 | 184 | |
| 191 | 185 | real_dev = priv->real_dev; |
| 192 | 186 | |
| 193 | − if (!real_dev || !rmnet_is_real_dev_registered(real_dev)) | |
| 187 | + if (!rmnet_is_real_dev_registered(real_dev)) | |
| 194 | 188 | return; |
| 195 | 189 | |
| 196 | − port = rmnet_get_port_rtnl(real_dev); | |
| 197 | − | |
| 198 | − mux_id = rmnet_vnd_get_mux(dev); | |
| 190 | + real_port = rmnet_get_port_rtnl(real_dev); | |
| 191 | + bridge_dev = real_port->bridge_ep; | |
| 192 | + if (bridge_dev) { | |
| 193 | + bridge_port = rmnet_get_port_rtnl(bridge_dev); | |
| 194 | + rmnet_unregister_bridge(bridge_port); | |
| 195 | + } | |
| 199 | 196 | |
| 200 | − ep = rmnet_get_endpoint(port, mux_id); | |
| 197 | + ep = rmnet_get_endpoint(real_port, mux_id); | |
| 201 | 198 | if (ep) { |
| 202 | 199 | hlist_del_init_rcu(&ep->hlnode); |
| 203 | − rmnet_unregister_bridge(dev, port); | |
| 204 | − rmnet_vnd_dellink(mux_id, port, ep); | |
| 200 | + rmnet_vnd_dellink(mux_id, real_port, ep); | |
| 205 | 201 | kfree(ep); |
| 206 | 202 | } |
| 207 | − rmnet_unregister_real_device(real_dev, port); | |
| 208 | 203 | |
| 204 | + netdev_upper_dev_unlink(real_dev, dev); | |
| 205 | + rmnet_unregister_real_device(real_dev); | |
| 209 | 206 | unregister_netdevice_queue(dev, head); |
| 210 | 207 | } |
| 211 | 208 | |
| 212 | −static void rmnet_force_unassociate_device(struct net_device *dev) | |
| 209 | +static void rmnet_force_unassociate_device(struct net_device *real_dev) | |
| 213 | 210 | { |
| 214 | − struct net_device *real_dev = dev; | |
| 215 | 211 | struct hlist_node *tmp_ep; |
| 216 | 212 | struct rmnet_endpoint *ep; |
| 217 | 213 | struct rmnet_port *port; |
| 218 | 214 | unsigned long bkt_ep; |
| 219 | 215 | LIST_HEAD(list); |
| 220 | 216 | |
| 221 | − if (!rmnet_is_real_dev_registered(real_dev)) | |
| 222 | − return; | |
| 223 | − | |
| 224 | − ASSERT_RTNL(); | |
| 225 | − | |
| 226 | − port = rmnet_get_port_rtnl(dev); | |
| 227 | − | |
| 228 | − rcu_read_lock(); | |
| 229 | − rmnet_unregister_bridge(dev, port); | |
| 230 | − | |
| 231 | − hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { | |
| 232 | − unregister_netdevice_queue(ep->egress_dev, &list); | |
| 233 | − rmnet_vnd_dellink(ep->mux_id, port, ep); | |
| 217 | + port = rmnet_get_port_rtnl(real_dev); | |
| 234 | 218 | |
| 235 | − hlist_del_init_rcu(&ep->hlnode); | |
| 236 | − kfree(ep); | |
| 219 | + if (port->nr_rmnet_devs) { | |
| 220 | + /* real device */ | |
| 221 | + rmnet_unregister_bridge(port); | |
| 222 | + hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { | |
| 223 | + unregister_netdevice_queue(ep->egress_dev, &list); | |
| 224 | + netdev_upper_dev_unlink(real_dev, ep->egress_dev); | |
| 225 | + rmnet_vnd_dellink(ep->mux_id, port, ep); | |
| 226 | + hlist_del_init_rcu(&ep->hlnode); | |
| 227 | + kfree(ep); | |
| 228 | + } | |
| 229 | + rmnet_unregister_real_device(real_dev); | |
| 230 | + unregister_netdevice_many(&list); | |
| 231 | + } else { | |
| 232 | + rmnet_unregister_bridge(port); | |
| 237 | 233 | } |
| 238 | − | |
| 239 | − rcu_read_unlock(); | |
| 240 | − unregister_netdevice_many(&list); | |
| 241 | − | |
| 242 | − rmnet_unregister_real_device(real_dev, port); | |
| 243 | 234 | } |
| 244 | 235 | |
| 245 | 236 | static int rmnet_config_notify_cb(struct notifier_block *nb, |
| 246 | 237 | unsigned long event, void *data) |
| 247 | 238 | { |
| 248 | − struct net_device *dev = netdev_notifier_info_to_dev(data); | |
| 239 | + struct net_device *real_dev = netdev_notifier_info_to_dev(data); | |
| 249 | 240 | |
| 250 | − if (!dev) | |
| 241 | + if (!rmnet_is_real_dev_registered(real_dev)) | |
| 251 | 242 | return NOTIFY_DONE; |
| 252 | 243 | |
| 253 | 244 | switch (event) { |
| 254 | 245 | case NETDEV_UNREGISTER: |
| 255 | − netdev_dbg(dev, "Kernel unregister\n"); | |
| 256 | − rmnet_force_unassociate_device(dev); | |
| 246 | + netdev_dbg(real_dev, "Kernel unregister\n"); | |
| 247 | + rmnet_force_unassociate_device(real_dev); | |
| 257 | 248 | break; |
| 258 | 249 | |
| 259 | 250 | default: |
| @@ -295,16 +286,18 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[], · 35 unmodified lines | ||
| 295 | 286 | if (!dev) |
| 296 | 287 | return -ENODEV; |
| 297 | 288 | |
| 298 | − real_dev = __dev_get_by_index(dev_net(dev), | |
| 299 | − nla_get_u32(tb[IFLA_LINK])); | |
| 300 | − | |
| 301 | − if (!real_dev || !rmnet_is_real_dev_registered(real_dev)) | |
| 289 | + real_dev = priv->real_dev; | |
| 290 | + if (!rmnet_is_real_dev_registered(real_dev)) | |
| 302 | 291 | return -ENODEV; |
| 303 | 292 | |
| 304 | 293 | port = rmnet_get_port_rtnl(real_dev); |
| 305 | 294 | |
| 306 | 295 | if (data[IFLA_RMNET_MUX_ID]) { |
| 307 | 296 | mux_id = nla_get_u16(data[IFLA_RMNET_MUX_ID]); |
| 297 | + if (rmnet_get_endpoint(port, mux_id)) { | |
| 298 | + NL_SET_ERR_MSG_MOD(extack, "MUX ID already exists"); | |
| 299 | + return -EINVAL; | |
| 300 | + } | |
| 308 | 301 | ep = rmnet_get_endpoint(port, priv->mux_id); |
| 309 | 302 | if (!ep) |
| 310 | 303 | return -ENODEV; |
| @@ -379,11 +372,10 @@ struct rtnl_link_ops rmnet_link_ops __read_mostly = { · 68 unmodified lines | ||
| 379 | 372 | .fill_info = rmnet_fill_info, |
| 380 | 373 | }; |
| 381 | 374 | |
| 382 | −/* Needs either rcu_read_lock() or rtnl lock */ | |
| 383 | −struct rmnet_port *rmnet_get_port(struct net_device *real_dev) | |
| 375 | +struct rmnet_port *rmnet_get_port_rcu(struct net_device *real_dev) | |
| 384 | 376 | { |
| 385 | 377 | if (rmnet_is_real_dev_registered(real_dev)) |
| 386 | − return rcu_dereference_rtnl(real_dev->rx_handler_data); | |
| 378 | + return rcu_dereference_bh(real_dev->rx_handler_data); | |
| 387 | 379 | else |
| 388 | 380 | return NULL; |
| 389 | 381 | } |
| @@ -409,7 +401,7 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, · 19 unmodified lines | ||
| 409 | 401 | struct rmnet_port *port, *slave_port; |
| 410 | 402 | int err; |
| 411 | 403 | |
| 412 | − port = rmnet_get_port(real_dev); | |
| 404 | + port = rmnet_get_port_rtnl(real_dev); | |
| 413 | 405 | |
| 414 | 406 | /* If there is more than one rmnet dev attached, its probably being |
| 415 | 407 | * used for muxing. Skip the briding in that case |
| @@ -417,6 +409,9 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, · 1 unmodified line | ||
| 417 | 409 | if (port->nr_rmnet_devs > 1) |
| 418 | 410 | return -EINVAL; |
| 419 | 411 | |
| 412 | + if (port->rmnet_mode != RMNET_EPMODE_VND) | |
| 413 | + return -EINVAL; | |
| 414 | + | |
| 420 | 415 | if (rmnet_is_real_dev_registered(slave_dev)) |
| 421 | 416 | return -EBUSY; |
| 422 | 417 | |
| @@ -424,9 +419,17 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, · 1 unmodified line | ||
| 424 | 419 | if (err) |
| 425 | 420 | return -EBUSY; |
| 426 | 421 | |
| 427 | − slave_port = rmnet_get_port(slave_dev); | |
| 422 | + err = netdev_master_upper_dev_link(slave_dev, rmnet_dev, NULL, NULL, | |
| 423 | + extack); | |
| 424 | + if (err) { | |
| 425 | + rmnet_unregister_real_device(slave_dev); | |
| 426 | + return err; | |
| 427 | + } | |
| 428 | + | |
| 429 | + slave_port = rmnet_get_port_rtnl(slave_dev); | |
| 428 | 430 | slave_port->rmnet_mode = RMNET_EPMODE_BRIDGE; |
| 429 | 431 | slave_port->bridge_ep = real_dev; |
| 432 | + slave_port->rmnet_dev = rmnet_dev; | |
| 430 | 433 | |
| 431 | 434 | port->rmnet_mode = RMNET_EPMODE_BRIDGE; |
| 432 | 435 | port->bridge_ep = slave_dev; |
| @@ -438,16 +441,9 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, · 5 unmodified lines | ||
| 438 | 441 | int rmnet_del_bridge(struct net_device *rmnet_dev, |
| 439 | 442 | struct net_device *slave_dev) |
| 440 | 443 | { |
| 441 | − struct rmnet_priv *priv = netdev_priv(rmnet_dev); | |
| 442 | − struct net_device *real_dev = priv->real_dev; | |
| 443 | − struct rmnet_port *port, *slave_port; | |
| 444 | + struct rmnet_port *port = rmnet_get_port_rtnl(slave_dev); | |
| 444 | 445 | |
| 445 | − port = rmnet_get_port(real_dev); | |
| 446 | − port->rmnet_mode = RMNET_EPMODE_VND; | |
| 447 | − port->bridge_ep = NULL; | |
| 448 | − | |
| 449 | − slave_port = rmnet_get_port(slave_dev); | |
| 450 | − rmnet_unregister_real_device(slave_dev, slave_port); | |
| 446 | + rmnet_unregister_bridge(port); | |
| 451 | 447 | |
| 452 | 448 | netdev_dbg(slave_dev, "removed from rmnet as slave\n"); |
| 453 | 449 | return 0; |
| @@ -473,8 +469,8 @@ static int __init rmnet_init(void) · 19 unmodified lines | ||
| 473 | 469 | |
| 474 | 470 | static void __exit rmnet_exit(void) |
| 475 | 471 | { |
| 476 | − unregister_netdevice_notifier(&rmnet_dev_notifier); | |
| 477 | 472 | rtnl_link_unregister(&rmnet_link_ops); |
| 473 | + unregister_netdevice_notifier(&rmnet_dev_notifier); | |
| 478 | 474 | } |
| 479 | 475 | |
| 480 | 476 | module_init(rmnet_init) |
| @@ -28,6 +28,7 @@ struct rmnet_port { · 27 unmodified lines | ||
| 28 | 28 | u8 rmnet_mode; |
| 29 | 29 | struct hlist_head muxed_ep[RMNET_MAX_LOGICAL_EP]; |
| 30 | 30 | struct net_device *bridge_ep; |
| 31 | + struct net_device *rmnet_dev; | |
| 31 | 32 | }; |
| 32 | 33 | |
| 33 | 34 | extern struct rtnl_link_ops rmnet_link_ops; |
| @@ -65,7 +66,7 @@ struct rmnet_priv { · 31 unmodified lines | ||
| 65 | 66 | struct rmnet_priv_stats stats; |
| 66 | 67 | }; |
| 67 | 68 | |
| 68 | −struct rmnet_port *rmnet_get_port(struct net_device *real_dev); | |
| 69 | +struct rmnet_port *rmnet_get_port_rcu(struct net_device *real_dev); | |
| 69 | 70 | struct rmnet_endpoint *rmnet_get_endpoint(struct rmnet_port *port, u8 mux_id); |
| 70 | 71 | int rmnet_add_bridge(struct net_device *rmnet_dev, |
| 71 | 72 | struct net_device *slave_dev, |
| @@ -159,6 +159,9 @@ static int rmnet_map_egress_handler(struct sk_buff *skb, · 158 unmodified lines | ||
| 159 | 159 | static void |
| 160 | 160 | rmnet_bridge_handler(struct sk_buff *skb, struct net_device *bridge_dev) |
| 161 | 161 | { |
| 162 | + if (skb_mac_header_was_set(skb)) | |
| 163 | + skb_push(skb, skb->mac_len); | |
| 164 | + | |
| 162 | 165 | if (bridge_dev) { |
| 163 | 166 | skb->dev = bridge_dev; |
| 164 | 167 | dev_queue_xmit(skb); |
| @@ -184,7 +187,7 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb) · 19 unmodified lines | ||
| 184 | 187 | return RX_HANDLER_PASS; |
| 185 | 188 | |
| 186 | 189 | dev = skb->dev; |
| 187 | − port = rmnet_get_port(dev); | |
| 190 | + port = rmnet_get_port_rcu(dev); | |
| 188 | 191 | |
| 189 | 192 | switch (port->rmnet_mode) { |
| 190 | 193 | case RMNET_EPMODE_VND: |
| @@ -217,7 +220,7 @@ void rmnet_egress_handler(struct sk_buff *skb) · 26 unmodified lines | ||
| 217 | 220 | skb->dev = priv->real_dev; |
| 218 | 221 | mux_id = priv->mux_id; |
| 219 | 222 | |
| 220 | − port = rmnet_get_port(skb->dev); | |
| 223 | + port = rmnet_get_port_rcu(skb->dev); | |
| 221 | 224 | if (!port) |
| 222 | 225 | goto drop; |
| 223 | 226 | |
| @@ -266,14 +266,6 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port, · 265 unmodified lines | ||
| 266 | 266 | return 0; |
| 267 | 267 | } |
| 268 | 268 | |
| 269 | −u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev) | |
| 270 | −{ | |
| 271 | − struct rmnet_priv *priv; | |
| 272 | − | |
| 273 | − priv = netdev_priv(rmnet_dev); | |
| 274 | − return priv->mux_id; | |
| 275 | −} | |
| 276 | − | |
| 277 | 269 | int rmnet_vnd_do_flow_control(struct net_device *rmnet_dev, int enable) |
| 278 | 270 | { |
| 279 | 271 | netdev_dbg(rmnet_dev, "Setting VND TX queue state to %d\n", enable); |
| @@ -16,6 +16,5 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port, · 15 unmodified lines | ||
| 16 | 16 | struct rmnet_endpoint *ep); |
| 17 | 17 | void rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev); |
| 18 | 18 | void rmnet_vnd_tx_fixup(struct sk_buff *skb, struct net_device *dev); |
| 19 | −u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev); | |
| 20 | 19 | void rmnet_vnd_setup(struct net_device *dev); |
| 21 | 20 | #endif /* _RMNET_VND_H_ */ |
| @@ -2277,7 +2277,7 @@ static int __init sxgbe_cmdline_opt(char *str) · 2276 unmodified lines | ||
| 2277 | 2277 | if (!str || !*str) |
| 2278 | 2278 | return -EINVAL; |
| 2279 | 2279 | while ((opt = strsep(&str, ",")) != NULL) { |
| 2280 | − if (!strncmp(opt, "eee_timer:", 6)) { | |
| 2280 | + if (!strncmp(opt, "eee_timer:", 10)) { | |
| 2281 | 2281 | if (kstrtoint(opt + 10, 0, &eee_timer)) |
| 2282 | 2282 | goto err; |
| 2283 | 2283 | } |
| @@ -2853,11 +2853,24 @@ efx_ef10_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) · 2852 unmodified lines | ||
| 2853 | 2853 | } |
| 2854 | 2854 | |
| 2855 | 2855 | /* Transmit timestamps are only available for 8XXX series. They result |
| 2856 | − * in three events per packet. These occur in order, and are: | |
| 2857 | − * - the normal completion event | |
| 2856 | + * in up to three events per packet. These occur in order, and are: | |
| 2857 | + * - the normal completion event (may be omitted) | |
| 2858 | 2858 | * - the low part of the timestamp |
| 2859 | 2859 | * - the high part of the timestamp |
| 2860 | 2860 | * |
| 2861 | + * It's possible for multiple completion events to appear before the | |
| 2862 | + * corresponding timestamps. So we can for example get: | |
| 2863 | + * COMP N | |
| 2864 | + * COMP N+1 | |
| 2865 | + * TS_LO N | |
| 2866 | + * TS_HI N | |
| 2867 | + * TS_LO N+1 | |
| 2868 | + * TS_HI N+1 | |
| 2869 | + * | |
| 2870 | + * In addition it's also possible for the adjacent completions to be | |
| 2871 | + * merged, so we may not see COMP N above. As such, the completion | |
| 2872 | + * events are not very useful here. | |
| 2873 | + * | |
| 2861 | 2874 | * Each part of the timestamp is itself split across two 16 bit |
| 2862 | 2875 | * fields in the event. |
| 2863 | 2876 | */ |
| @@ -2865,17 +2878,7 @@ efx_ef10_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) · 1 unmodified line | ||
| 2865 | 2878 | |
| 2866 | 2879 | switch (tx_ev_type) { |
| 2867 | 2880 | case TX_TIMESTAMP_EVENT_TX_EV_COMPLETION: |
| 2868 | − /* In case of Queue flush or FLR, we might have received | |
| 2869 | − * the previous TX completion event but not the Timestamp | |
| 2870 | − * events. | |
| 2871 | − */ | |
| 2872 | − if (tx_queue->completed_desc_ptr != tx_queue->ptr_mask) | |
| 2873 | − efx_xmit_done(tx_queue, tx_queue->completed_desc_ptr); | |
| 2874 | − | |
| 2875 | − tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, | |
| 2876 | − ESF_DZ_TX_DESCR_INDX); | |
| 2877 | − tx_queue->completed_desc_ptr = | |
| 2878 | − tx_ev_desc_ptr & tx_queue->ptr_mask; | |
| 2881 | + /* Ignore this event - see above. */ | |
| 2879 | 2882 | break; |
| 2880 | 2883 | |
| 2881 | 2884 | case TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_LO: |
| @@ -2887,8 +2890,7 @@ efx_ef10_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) · 5 unmodified lines | ||
| 2887 | 2890 | ts_part = efx_ef10_extract_event_ts(event); |
| 2888 | 2891 | tx_queue->completed_timestamp_major = ts_part; |
| 2889 | 2892 | |
| 2890 | − efx_xmit_done(tx_queue, tx_queue->completed_desc_ptr); | |
| 2891 | − tx_queue->completed_desc_ptr = tx_queue->ptr_mask; | |
| 2893 | + efx_xmit_done_single(tx_queue); | |
| 2892 | 2894 | break; |
| 2893 | 2895 | |
| 2894 | 2896 | default: |
| @@ -20,6 +20,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb, · 19 unmodified lines | ||
| 20 | 20 | struct net_device *net_dev); |
| 21 | 21 | netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); |
| 22 | 22 | void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); |
| 23 | +void efx_xmit_done_single(struct efx_tx_queue *tx_queue); | |
| 23 | 24 | int efx_setup_tc(struct net_device *net_dev, enum tc_setup_type type, |
| 24 | 25 | void *type_data); |
| 25 | 26 | extern unsigned int efx_piobuf_size; |
| @@ -583,6 +583,7 @@ struct efx_channel *efx_copy_channel(const struct efx_channel *old_channel) · 582 unmodified lines | ||
| 583 | 583 | if (tx_queue->channel) |
| 584 | 584 | tx_queue->channel = channel; |
| 585 | 585 | tx_queue->buffer = NULL; |
| 586 | + tx_queue->cb_page = NULL; | |
| 586 | 587 | memset(&tx_queue->txd, 0, sizeof(tx_queue->txd)); |
| 587 | 588 | } |
| 588 | 589 | |
| @@ -208,8 +208,6 @@ struct efx_tx_buffer { · 207 unmodified lines | ||
| 208 | 208 | * avoid cache-line ping-pong between the xmit path and the |
| 209 | 209 | * completion path. |
| 210 | 210 | * @merge_events: Number of TX merged completion events |
| 211 | − * @completed_desc_ptr: Most recent completed pointer - only used with | |
| 212 | − * timestamping. | |
| 213 | 211 | * @completed_timestamp_major: Top part of the most recent tx timestamp. |
| 214 | 212 | * @completed_timestamp_minor: Low part of the most recent tx timestamp. |
| 215 | 213 | * @insert_count: Current insert pointer |
| @@ -269,7 +267,6 @@ struct efx_tx_queue { · 53 unmodified lines | ||
| 269 | 267 | unsigned int merge_events; |
| 270 | 268 | unsigned int bytes_compl; |
| 271 | 269 | unsigned int pkts_compl; |
| 272 | − unsigned int completed_desc_ptr; | |
| 273 | 270 | u32 completed_timestamp_major; |
| 274 | 271 | u32 completed_timestamp_minor; |
| 275 | 272 | |
| @@ -560,13 +560,45 @@ efx_ptp_mac_nic_to_ktime_correction(struct efx_nic *efx, · 559 unmodified lines | ||
| 560 | 560 | u32 nic_major, u32 nic_minor, |
| 561 | 561 | s32 correction) |
| 562 | 562 | { |
| 563 | + u32 sync_timestamp; | |
| 563 | 564 | ktime_t kt = { 0 }; |
| 565 | + s16 delta; | |
| 564 | 566 | |
| 565 | 567 | if (!(nic_major & 0x80000000)) { |
| 566 | 568 | WARN_ON_ONCE(nic_major >> 16); |
| 567 | − /* Use the top bits from the latest sync event. */ | |
| 568 | − nic_major &= 0xffff; | |
| 569 | − nic_major |= (last_sync_timestamp_major(efx) & 0xffff0000); | |
| 569 | + | |
| 570 | + /* Medford provides 48 bits of timestamp, so we must get the top | |
| 571 | + * 16 bits from the timesync event state. | |
| 572 | + * | |
| 573 | + * We only have the lower 16 bits of the time now, but we do | |
| 574 | + * have a full resolution timestamp at some point in past. As | |
| 575 | + * long as the difference between the (real) now and the sync | |
| 576 | + * is less than 2^15, then we can reconstruct the difference | |
| 577 | + * between those two numbers using only the lower 16 bits of | |
| 578 | + * each. | |
| 579 | + * | |
| 580 | + * Put another way | |
| 581 | + * | |
| 582 | + * a - b = ((a mod k) - b) mod k | |
| 583 | + * | |
| 584 | + * when -k/2 < (a-b) < k/2. In our case k is 2^16. We know | |
| 585 | + * (a mod k) and b, so can calculate the delta, a - b. | |
| 586 | + * | |
| 587 | + */ | |
| 588 | + sync_timestamp = last_sync_timestamp_major(efx); | |
| 589 | + | |
| 590 | + /* Because delta is s16 this does an implicit mask down to | |
| 591 | + * 16 bits which is what we need, assuming | |
| 592 | + * MEDFORD_TX_SECS_EVENT_BITS is 16. delta is signed so that | |
| 593 | + * we can deal with the (unlikely) case of sync timestamps | |
| 594 | + * arriving from the future. | |
| 595 | + */ | |
| 596 | + delta = nic_major - sync_timestamp; | |
| 597 | + | |
| 598 | + /* Recover the fully specified time now, by applying the offset | |
| 599 | + * to the (fully specified) sync time. | |
| 600 | + */ | |
| 601 | + nic_major = sync_timestamp + delta; | |
| 570 | 602 | |
| 571 | 603 | kt = ptp->nic_to_kernel_time(nic_major, nic_minor, |
| 572 | 604 | correction); |
| @@ -535,6 +535,44 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb, · 534 unmodified lines | ||
| 535 | 535 | return efx_enqueue_skb(tx_queue, skb); |
| 536 | 536 | } |
| 537 | 537 | |
| 538 | +void efx_xmit_done_single(struct efx_tx_queue *tx_queue) | |
| 539 | +{ | |
| 540 | + unsigned int pkts_compl = 0, bytes_compl = 0; | |
| 541 | + unsigned int read_ptr; | |
| 542 | + bool finished = false; | |
| 543 | + | |
| 544 | + read_ptr = tx_queue->read_count & tx_queue->ptr_mask; | |
| 545 | + | |
| 546 | + while (!finished) { | |
| 547 | + struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr]; | |
| 548 | + | |
| 549 | + if (!efx_tx_buffer_in_use(buffer)) { | |
| 550 | + struct efx_nic *efx = tx_queue->efx; | |
| 551 | + | |
| 552 | + netif_err(efx, hw, efx->net_dev, | |
| 553 | + "TX queue %d spurious single TX completion\n", | |
| 554 | + tx_queue->queue); | |
| 555 | + efx_schedule_reset(efx, RESET_TYPE_TX_SKIP); | |
| 556 | + return; | |
| 557 | + } | |
| 558 | + | |
| 559 | + /* Need to check the flag before dequeueing. */ | |
| 560 | + if (buffer->flags & EFX_TX_BUF_SKB) | |
| 561 | + finished = true; | |
| 562 | + efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl); | |
| 563 | + | |
| 564 | + ++tx_queue->read_count; | |
| 565 | + read_ptr = tx_queue->read_count & tx_queue->ptr_mask; | |
| 566 | + } | |
| 567 | + | |
| 568 | + tx_queue->pkts_compl += pkts_compl; | |
| 569 | + tx_queue->bytes_compl += bytes_compl; | |
| 570 | + | |
| 571 | + EFX_WARN_ON_PARANOID(pkts_compl != 1); | |
| 572 | + | |
| 573 | + efx_xmit_done_check_empty(tx_queue); | |
| 574 | +} | |
| 575 | + | |
| 538 | 576 | void efx_init_tx_queue_core_txq(struct efx_tx_queue *tx_queue) |
| 539 | 577 | { |
| 540 | 578 | struct efx_nic *efx = tx_queue->efx; |
| @@ -80,7 +80,6 @@ void efx_init_tx_queue(struct efx_tx_queue *tx_queue) · 79 unmodified lines | ||
| 80 | 80 | tx_queue->xmit_more_available = false; |
| 81 | 81 | tx_queue->timestamping = (efx_ptp_use_mac_tx_timestamps(efx) && |
| 82 | 82 | tx_queue->channel == efx_ptp_channel(efx)); |
| 83 | − tx_queue->completed_desc_ptr = tx_queue->ptr_mask; | |
| 84 | 83 | tx_queue->completed_timestamp_major = 0; |
| 85 | 84 | tx_queue->completed_timestamp_minor = 0; |
| 86 | 85 | |
| @@ -210,10 +209,9 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue, · 123 unmodified lines | ||
| 210 | 209 | while (read_ptr != stop_index) { |
| 211 | 210 | struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr]; |
| 212 | 211 | |
| 213 | − if (!(buffer->flags & EFX_TX_BUF_OPTION) && | |
| 214 | − unlikely(buffer->len == 0)) { | |
| 212 | + if (!efx_tx_buffer_in_use(buffer)) { | |
| 215 | 213 | netif_err(efx, tx_err, efx->net_dev, |
| 216 | − "TX queue %d spurious TX completion id %x\n", | |
| 214 | + "TX queue %d spurious TX completion id %d\n", | |
| 217 | 215 | tx_queue->queue, read_ptr); |
| 218 | 216 | efx_schedule_reset(efx, RESET_TYPE_TX_SKIP); |
| 219 | 217 | return; |
| @@ -226,6 +224,19 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue, · 6 unmodified lines | ||
| 226 | 224 | } |
| 227 | 225 | } |
| 228 | 226 | |
| 227 | +void efx_xmit_done_check_empty(struct efx_tx_queue *tx_queue) | |
| 228 | +{ | |
| 229 | + if ((int)(tx_queue->read_count - tx_queue->old_write_count) >= 0) { | |
| 230 | + tx_queue->old_write_count = READ_ONCE(tx_queue->write_count); | |
| 231 | + if (tx_queue->read_count == tx_queue->old_write_count) { | |
| 232 | + /* Ensure that read_count is flushed. */ | |
| 233 | + smp_mb(); | |
| 234 | + tx_queue->empty_read_count = | |
| 235 | + tx_queue->read_count | EFX_EMPTY_COUNT_VALID; | |
| 236 | + } | |
| 237 | + } | |
| 238 | +} | |
| 239 | + | |
| 229 | 240 | void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) |
| 230 | 241 | { |
| 231 | 242 | unsigned int fill_level, pkts_compl = 0, bytes_compl = 0; |
| @@ -256,15 +267,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) · 24 unmodified lines | ||
| 256 | 267 | netif_tx_wake_queue(tx_queue->core_txq); |
| 257 | 268 | } |
| 258 | 269 | |
| 259 | − /* Check whether the hardware queue is now empty */ | |
| 260 | − if ((int)(tx_queue->read_count - tx_queue->old_write_count) >= 0) { | |
| 261 | − tx_queue->old_write_count = READ_ONCE(tx_queue->write_count); | |
| 262 | − if (tx_queue->read_count == tx_queue->old_write_count) { | |
| 263 | − smp_mb(); | |
| 264 | − tx_queue->empty_read_count = | |
| 265 | − tx_queue->read_count | EFX_EMPTY_COUNT_VALID; | |
| 266 | − } | |
| 267 | − } | |
| 270 | + efx_xmit_done_check_empty(tx_queue); | |
| 268 | 271 | } |
| 269 | 272 | |
| 270 | 273 | /* Remove buffers put into a tx_queue for the current packet. |
| @@ -21,6 +21,12 @@ void efx_dequeue_buffer(struct efx_tx_queue *tx_queue, · 20 unmodified lines | ||
| 21 | 21 | unsigned int *pkts_compl, |
| 22 | 22 | unsigned int *bytes_compl); |
| 23 | 23 | |
| 24 | +static inline bool efx_tx_buffer_in_use(struct efx_tx_buffer *buffer) | |
| 25 | +{ | |
| 26 | + return buffer->len || (buffer->flags & EFX_TX_BUF_OPTION); | |
| 27 | +} | |
| 28 | + | |
| 29 | +void efx_xmit_done_check_empty(struct efx_tx_queue *tx_queue); | |
| 24 | 30 | void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); |
| 25 | 31 | |
| 26 | 32 | void efx_enqueue_unwind(struct efx_tx_queue *tx_queue, |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | static void dwmac1000_core_init(struct mac_device_info *hw, |
| 25 | 25 | struct net_device *dev) |
| 26 | 26 | { |
| 27 | + struct stmmac_priv *priv = netdev_priv(dev); | |
| 27 | 28 | void __iomem *ioaddr = hw->pcsr; |
| 28 | 29 | u32 value = readl(ioaddr + GMAC_CONTROL); |
| 29 | 30 | int mtu = dev->mtu; |
| @@ -35,7 +36,7 @@ static void dwmac1000_core_init(struct mac_device_info *hw, · 5 unmodified lines | ||
| 35 | 36 | * Broadcom tags can look like invalid LLC/SNAP packets and cause the |
| 36 | 37 | * hardware to truncate packets on reception. |
| 37 | 38 | */ |
| 38 | − if (netdev_uses_dsa(dev)) | |
| 39 | + if (netdev_uses_dsa(dev) || !priv->plat->enh_desc) | |
| 39 | 40 | value &= ~GMAC_CONTROL_ACS; |
| 40 | 41 | |
| 41 | 42 | if (mtu > 1500) |
| @@ -4405,6 +4405,8 @@ static void stmmac_init_fs(struct net_device *dev) · 4404 unmodified lines | ||
| 4405 | 4405 | { |
| 4406 | 4406 | struct stmmac_priv *priv = netdev_priv(dev); |
| 4407 | 4407 | |
| 4408 | + rtnl_lock(); | |
| 4409 | + | |
| 4408 | 4410 | /* Create per netdev entries */ |
| 4409 | 4411 | priv->dbgfs_dir = debugfs_create_dir(dev->name, stmmac_fs_dir); |
| 4410 | 4412 | |
| @@ -4416,14 +4418,13 @@ static void stmmac_init_fs(struct net_device *dev) · 5 unmodified lines | ||
| 4416 | 4418 | debugfs_create_file("dma_cap", 0444, priv->dbgfs_dir, dev, |
| 4417 | 4419 | &stmmac_dma_cap_fops); |
| 4418 | 4420 | |
| 4419 | − register_netdevice_notifier(&stmmac_notifier); | |
| 4421 | + rtnl_unlock(); | |
| 4420 | 4422 | } |
| 4421 | 4423 | |
| 4422 | 4424 | static void stmmac_exit_fs(struct net_device *dev) |
| 4423 | 4425 | { |
| 4424 | 4426 | struct stmmac_priv *priv = netdev_priv(dev); |
| 4425 | 4427 | |
| 4426 | − unregister_netdevice_notifier(&stmmac_notifier); | |
| 4427 | 4428 | debugfs_remove_recursive(priv->dbgfs_dir); |
| 4428 | 4429 | } |
| 4429 | 4430 | #endif /* CONFIG_DEBUG_FS */ |
| @@ -4940,14 +4941,14 @@ int stmmac_dvr_remove(struct device *dev) · 510 unmodified lines | ||
| 4940 | 4941 | |
| 4941 | 4942 | netdev_info(priv->dev, "%s: removing driver", __func__); |
| 4942 | 4943 | |
| 4943 | −#ifdef CONFIG_DEBUG_FS | |
| 4944 | − stmmac_exit_fs(ndev); | |
| 4945 | −#endif | |
| 4946 | 4944 | stmmac_stop_all_dma(priv); |
| 4947 | 4945 | |
| 4948 | 4946 | stmmac_mac_set(priv, priv->ioaddr, false); |
| 4949 | 4947 | netif_carrier_off(ndev); |
| 4950 | 4948 | unregister_netdev(ndev); |
| 4949 | +#ifdef CONFIG_DEBUG_FS | |
| 4950 | + stmmac_exit_fs(ndev); | |
| 4951 | +#endif | |
| 4951 | 4952 | phylink_destroy(priv->phylink); |
| 4952 | 4953 | if (priv->plat->stmmac_rst) |
| 4953 | 4954 | reset_control_assert(priv->plat->stmmac_rst); |
| @@ -5166,6 +5167,7 @@ static int __init stmmac_init(void) · 212 unmodified lines | ||
| 5166 | 5167 | /* Create debugfs main directory if it doesn't exist yet */ |
| 5167 | 5168 | if (!stmmac_fs_dir) |
| 5168 | 5169 | stmmac_fs_dir = debugfs_create_dir(STMMAC_RESOURCE_NAME, NULL); |
| 5170 | + register_netdevice_notifier(&stmmac_notifier); | |
| 5169 | 5171 | #endif |
| 5170 | 5172 | |
| 5171 | 5173 | return 0; |
| @@ -5174,6 +5176,7 @@ static int __init stmmac_init(void) · 2 unmodified lines | ||
| 5174 | 5176 | static void __exit stmmac_exit(void) |
| 5175 | 5177 | { |
| 5176 | 5178 | #ifdef CONFIG_DEBUG_FS |
| 5179 | + unregister_netdevice_notifier(&stmmac_notifier); | |
| 5177 | 5180 | debugfs_remove_recursive(stmmac_fs_dir); |
| 5178 | 5181 | #endif |
| 5179 | 5182 | } |
| @@ -375,10 +375,14 @@ struct temac_local { · 374 unmodified lines | ||
| 375 | 375 | int tx_bd_next; |
| 376 | 376 | int tx_bd_tail; |
| 377 | 377 | int rx_bd_ci; |
| 378 | + int rx_bd_tail; | |
| 378 | 379 | |
| 379 | 380 | /* DMA channel control setup */ |
| 380 | 381 | u32 tx_chnl_ctrl; |
| 381 | 382 | u32 rx_chnl_ctrl; |
| 383 | + u8 coalesce_count_rx; | |
| 384 | + | |
| 385 | + struct delayed_work restart_work; | |
| 382 | 386 | }; |
| 383 | 387 | |
| 384 | 388 | /* Wrappers for temac_ior()/temac_iow() function pointers above */ |
| @@ -51,6 +51,7 @@ · 50 unmodified lines | ||
| 51 | 51 | #include <linux/ip.h> |
| 52 | 52 | #include <linux/slab.h> |
| 53 | 53 | #include <linux/interrupt.h> |
| 54 | +#include <linux/workqueue.h> | |
| 54 | 55 | #include <linux/dma-mapping.h> |
| 55 | 56 | #include <linux/processor.h> |
| 56 | 57 | #include <linux/platform_data/xilinx-ll-temac.h> |
| @@ -367,6 +368,8 @@ static int temac_dma_bd_init(struct net_device *ndev) · 310 unmodified lines | ||
| 367 | 368 | skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, |
| 368 | 369 | XTE_MAX_JUMBO_FRAME_SIZE, |
| 369 | 370 | DMA_FROM_DEVICE); |
| 371 | + if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) | |
| 372 | + goto out; | |
| 370 | 373 | lp->rx_bd_v[i].phys = cpu_to_be32(skb_dma_addr); |
| 371 | 374 | lp->rx_bd_v[i].len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); |
| 372 | 375 | lp->rx_bd_v[i].app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); |
| @@ -387,12 +390,13 @@ static int temac_dma_bd_init(struct net_device *ndev) · 14 unmodified lines | ||
| 387 | 390 | lp->tx_bd_next = 0; |
| 388 | 391 | lp->tx_bd_tail = 0; |
| 389 | 392 | lp->rx_bd_ci = 0; |
| 393 | + lp->rx_bd_tail = RX_BD_NUM - 1; | |
| 390 | 394 | |
| 391 | 395 | /* Enable RX DMA transfers */ |
| 392 | 396 | wmb(); |
| 393 | 397 | lp->dma_out(lp, RX_CURDESC_PTR, lp->rx_bd_p); |
| 394 | 398 | lp->dma_out(lp, RX_TAILDESC_PTR, |
| 395 | − lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); | |
| 399 | + lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * lp->rx_bd_tail)); | |
| 396 | 400 | |
| 397 | 401 | /* Prepare for TX DMA transfer */ |
| 398 | 402 | lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); |
| @@ -788,6 +792,9 @@ static void temac_start_xmit_done(struct net_device *ndev) · 389 unmodified lines | ||
| 788 | 792 | stat = be32_to_cpu(cur_p->app0); |
| 789 | 793 | } |
| 790 | 794 | |
| 795 | + /* Matches barrier in temac_start_xmit */ | |
| 796 | + smp_mb(); | |
| 797 | + | |
| 791 | 798 | netif_wake_queue(ndev); |
| 792 | 799 | } |
| 793 | 800 | |
| @@ -830,9 +837,19 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 36 unmodified lines | ||
| 830 | 837 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
| 831 | 838 | |
| 832 | 839 | if (temac_check_tx_bd_space(lp, num_frag + 1)) { |
| 833 | − if (!netif_queue_stopped(ndev)) | |
| 834 | − netif_stop_queue(ndev); | |
| 835 | − return NETDEV_TX_BUSY; | |
| 840 | + if (netif_queue_stopped(ndev)) | |
| 841 | + return NETDEV_TX_BUSY; | |
| 842 | + | |
| 843 | + netif_stop_queue(ndev); | |
| 844 | + | |
| 845 | + /* Matches barrier in temac_start_xmit_done */ | |
| 846 | + smp_mb(); | |
| 847 | + | |
| 848 | + /* Space might have just been freed - check again */ | |
| 849 | + if (temac_check_tx_bd_space(lp, num_frag)) | |
| 850 | + return NETDEV_TX_BUSY; | |
| 851 | + | |
| 852 | + netif_wake_queue(ndev); | |
| 836 | 853 | } |
| 837 | 854 | |
| 838 | 855 | cur_p->app0 = 0; |
| @@ -850,12 +867,16 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 11 unmodified lines | ||
| 850 | 867 | skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, |
| 851 | 868 | skb_headlen(skb), DMA_TO_DEVICE); |
| 852 | 869 | cur_p->len = cpu_to_be32(skb_headlen(skb)); |
| 870 | + if (WARN_ON_ONCE(dma_mapping_error(ndev->dev.parent, skb_dma_addr))) { | |
| 871 | + dev_kfree_skb_any(skb); | |
| 872 | + ndev->stats.tx_dropped++; | |
| 873 | + return NETDEV_TX_OK; | |
| 874 | + } | |
| 853 | 875 | cur_p->phys = cpu_to_be32(skb_dma_addr); |
| 854 | 876 | ptr_to_txbd((void *)skb, cur_p); |
| 855 | 877 | |
| 856 | 878 | for (ii = 0; ii < num_frag; ii++) { |
| 857 | − lp->tx_bd_tail++; | |
| 858 | − if (lp->tx_bd_tail >= TX_BD_NUM) | |
| 879 | + if (++lp->tx_bd_tail >= TX_BD_NUM) | |
| 859 | 880 | lp->tx_bd_tail = 0; |
| 860 | 881 | |
| 861 | 882 | cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
| @@ -863,6 +884,27 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 1 unmodified line | ||
| 863 | 884 | skb_frag_address(frag), |
| 864 | 885 | skb_frag_size(frag), |
| 865 | 886 | DMA_TO_DEVICE); |
| 887 | + if (dma_mapping_error(ndev->dev.parent, skb_dma_addr)) { | |
| 888 | + if (--lp->tx_bd_tail < 0) | |
| 889 | + lp->tx_bd_tail = TX_BD_NUM - 1; | |
| 890 | + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; | |
| 891 | + while (--ii >= 0) { | |
| 892 | + --frag; | |
| 893 | + dma_unmap_single(ndev->dev.parent, | |
| 894 | + be32_to_cpu(cur_p->phys), | |
| 895 | + skb_frag_size(frag), | |
| 896 | + DMA_TO_DEVICE); | |
| 897 | + if (--lp->tx_bd_tail < 0) | |
| 898 | + lp->tx_bd_tail = TX_BD_NUM - 1; | |
| 899 | + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; | |
| 900 | + } | |
| 901 | + dma_unmap_single(ndev->dev.parent, | |
| 902 | + be32_to_cpu(cur_p->phys), | |
| 903 | + skb_headlen(skb), DMA_TO_DEVICE); | |
| 904 | + dev_kfree_skb_any(skb); | |
| 905 | + ndev->stats.tx_dropped++; | |
| 906 | + return NETDEV_TX_OK; | |
| 907 | + } | |
| 866 | 908 | cur_p->phys = cpu_to_be32(skb_dma_addr); |
| 867 | 909 | cur_p->len = cpu_to_be32(skb_frag_size(frag)); |
| 868 | 910 | cur_p->app0 = 0; |
| @@ -884,31 +926,56 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 15 unmodified lines | ||
| 884 | 926 | return NETDEV_TX_OK; |
| 885 | 927 | } |
| 886 | 928 | |
| 929 | +static int ll_temac_recv_buffers_available(struct temac_local *lp) | |
| 930 | +{ | |
| 931 | + int available; | |
| 932 | + | |
| 933 | + if (!lp->rx_skb[lp->rx_bd_ci]) | |
| 934 | + return 0; | |
| 935 | + available = 1 + lp->rx_bd_tail - lp->rx_bd_ci; | |
| 936 | + if (available <= 0) | |
| 937 | + available += RX_BD_NUM; | |
| 938 | + return available; | |
| 939 | +} | |
| 887 | 940 | |
| 888 | 941 | static void ll_temac_recv(struct net_device *ndev) |
| 889 | 942 | { |
| 890 | 943 | struct temac_local *lp = netdev_priv(ndev); |
| 891 | − struct sk_buff *skb, *new_skb; | |
| 892 | − unsigned int bdstat; | |
| 893 | − struct cdmac_bd *cur_p; | |
| 894 | − dma_addr_t tail_p, skb_dma_addr; | |
| 895 | − int length; | |
| 896 | 944 | unsigned long flags; |
| 945 | + int rx_bd; | |
| 946 | + bool update_tail = false; | |
| 897 | 947 | |
| 898 | 948 | spin_lock_irqsave(&lp->rx_lock, flags); |
| 899 | 949 | |
| 900 | − tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; | |
| 901 | − cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; | |
| 902 | − | |
| 903 | − bdstat = be32_to_cpu(cur_p->app0); | |
| 904 | − while ((bdstat & STS_CTRL_APP0_CMPLT)) { | |
| 950 | + /* Process all received buffers, passing them on network | |
| 951 | + * stack. After this, the buffer descriptors will be in an | |
| 952 | + * un-allocated stage, where no skb is allocated for it, and | |
| 953 | + * they are therefore not available for TEMAC/DMA. | |
| 954 | + */ | |
| 955 | + do { | |
| 956 | + struct cdmac_bd *bd = &lp->rx_bd_v[lp->rx_bd_ci]; | |
| 957 | + struct sk_buff *skb = lp->rx_skb[lp->rx_bd_ci]; | |
| 958 | + unsigned int bdstat = be32_to_cpu(bd->app0); | |
| 959 | + int length; | |
| 960 | + | |
| 961 | + /* While this should not normally happen, we can end | |
| 962 | + * here when GFP_ATOMIC allocations fail, and we | |
| 963 | + * therefore have un-allocated buffers. | |
| 964 | + */ | |
| 965 | + if (!skb) | |
| 966 | + break; | |
| 905 | 967 | |
| 906 | − skb = lp->rx_skb[lp->rx_bd_ci]; | |
| 907 | − length = be32_to_cpu(cur_p->app4) & 0x3FFF; | |
| 968 | + /* Loop over all completed buffer descriptors */ | |
| 969 | + if (!(bdstat & STS_CTRL_APP0_CMPLT)) | |
| 970 | + break; | |
| 908 | 971 | |
| 909 | − dma_unmap_single(ndev->dev.parent, be32_to_cpu(cur_p->phys), | |
| 972 | + dma_unmap_single(ndev->dev.parent, be32_to_cpu(bd->phys), | |
| 910 | 973 | XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); |
| 974 | + /* The buffer is not valid for DMA anymore */ | |
| 975 | + bd->phys = 0; | |
| 976 | + bd->len = 0; | |
| 911 | 977 | |
| 978 | + length = be32_to_cpu(bd->app4) & 0x3FFF; | |
| 912 | 979 | skb_put(skb, length); |
| 913 | 980 | skb->protocol = eth_type_trans(skb, ndev); |
| 914 | 981 | skb_checksum_none_assert(skb); |
| @@ -923,43 +990,102 @@ static void ll_temac_recv(struct net_device *ndev) · 8 unmodified lines | ||
| 923 | 990 | * (back) for proper IP checksum byte order |
| 924 | 991 | * (be16). |
| 925 | 992 | */ |
| 926 | − skb->csum = htons(be32_to_cpu(cur_p->app3) & 0xFFFF); | |
| 993 | + skb->csum = htons(be32_to_cpu(bd->app3) & 0xFFFF); | |
| 927 | 994 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 928 | 995 | } |
| 929 | 996 | |
| 930 | 997 | if (!skb_defer_rx_timestamp(skb)) |
| 931 | 998 | netif_rx(skb); |
| 999 | + /* The skb buffer is now owned by network stack above */ | |
| 1000 | + lp->rx_skb[lp->rx_bd_ci] = NULL; | |
| 932 | 1001 | |
| 933 | 1002 | ndev->stats.rx_packets++; |
| 934 | 1003 | ndev->stats.rx_bytes += length; |
| 935 | 1004 | |
| 936 | − new_skb = netdev_alloc_skb_ip_align(ndev, | |
| 937 | − XTE_MAX_JUMBO_FRAME_SIZE); | |
| 938 | − if (!new_skb) { | |
| 939 | − spin_unlock_irqrestore(&lp->rx_lock, flags); | |
| 940 | − return; | |
| 1005 | + rx_bd = lp->rx_bd_ci; | |
| 1006 | + if (++lp->rx_bd_ci >= RX_BD_NUM) | |
| 1007 | + lp->rx_bd_ci = 0; | |
| 1008 | + } while (rx_bd != lp->rx_bd_tail); | |
| 1009 | + | |
| 1010 | + /* DMA operations will halt when the last buffer descriptor is | |
| 1011 | + * processed (ie. the one pointed to by RX_TAILDESC_PTR). | |
| 1012 | + * When that happens, no more interrupt events will be | |
| 1013 | + * generated. No IRQ_COAL or IRQ_DLY, and not even an | |
| 1014 | + * IRQ_ERR. To avoid stalling, we schedule a delayed work | |
| 1015 | + * when there is a potential risk of that happening. The work | |
| 1016 | + * will call this function, and thus re-schedule itself until | |
| 1017 | + * enough buffers are available again. | |
| 1018 | + */ | |
| 1019 | + if (ll_temac_recv_buffers_available(lp) < lp->coalesce_count_rx) | |
| 1020 | + schedule_delayed_work(&lp->restart_work, HZ / 1000); | |
| 1021 | + | |
| 1022 | + /* Allocate new buffers for those buffer descriptors that were | |
| 1023 | + * passed to network stack. Note that GFP_ATOMIC allocations | |
| 1024 | + * can fail (e.g. when a larger burst of GFP_ATOMIC | |
| 1025 | + * allocations occurs), so while we try to allocate all | |
| 1026 | + * buffers in the same interrupt where they were processed, we | |
| 1027 | + * continue with what we could get in case of allocation | |
| 1028 | + * failure. Allocation of remaining buffers will be retried | |
| 1029 | + * in following calls. | |
| 1030 | + */ | |
| 1031 | + while (1) { | |
| 1032 | + struct sk_buff *skb; | |
| 1033 | + struct cdmac_bd *bd; | |
| 1034 | + dma_addr_t skb_dma_addr; | |
| 1035 | + | |
| 1036 | + rx_bd = lp->rx_bd_tail + 1; | |
| 1037 | + if (rx_bd >= RX_BD_NUM) | |
| 1038 | + rx_bd = 0; | |
| 1039 | + bd = &lp->rx_bd_v[rx_bd]; | |
| 1040 | + | |
| 1041 | + if (bd->phys) | |
| 1042 | + break; /* All skb's allocated */ | |
| 1043 | + | |
| 1044 | + skb = netdev_alloc_skb_ip_align(ndev, XTE_MAX_JUMBO_FRAME_SIZE); | |
| 1045 | + if (!skb) { | |
| 1046 | + dev_warn(&ndev->dev, "skb alloc failed\n"); | |
| 1047 | + break; | |
| 941 | 1048 | } |
| 942 | 1049 | |
| 943 | − cur_p->app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); | |
| 944 | − skb_dma_addr = dma_map_single(ndev->dev.parent, new_skb->data, | |
| 1050 | + skb_dma_addr = dma_map_single(ndev->dev.parent, skb->data, | |
| 945 | 1051 | XTE_MAX_JUMBO_FRAME_SIZE, |
| 946 | 1052 | DMA_FROM_DEVICE); |
| 947 | − cur_p->phys = cpu_to_be32(skb_dma_addr); | |
| 948 | − cur_p->len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); | |
| 949 | − lp->rx_skb[lp->rx_bd_ci] = new_skb; | |
| 1053 | + if (WARN_ON_ONCE(dma_mapping_error(ndev->dev.parent, | |
| 1054 | + skb_dma_addr))) { | |
| 1055 | + dev_kfree_skb_any(skb); | |
| 1056 | + break; | |
| 1057 | + } | |
| 950 | 1058 | |
| 951 | − lp->rx_bd_ci++; | |
| 952 | − if (lp->rx_bd_ci >= RX_BD_NUM) | |
| 953 | − lp->rx_bd_ci = 0; | |
| 1059 | + bd->phys = cpu_to_be32(skb_dma_addr); | |
| 1060 | + bd->len = cpu_to_be32(XTE_MAX_JUMBO_FRAME_SIZE); | |
| 1061 | + bd->app0 = cpu_to_be32(STS_CTRL_APP0_IRQONEND); | |
| 1062 | + lp->rx_skb[rx_bd] = skb; | |
| 954 | 1063 | |
| 955 | − cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; | |
| 956 | − bdstat = be32_to_cpu(cur_p->app0); | |
| 1064 | + lp->rx_bd_tail = rx_bd; | |
| 1065 | + update_tail = true; | |
| 1066 | + } | |
| 1067 | + | |
| 1068 | + /* Move tail pointer when buffers have been allocated */ | |
| 1069 | + if (update_tail) { | |
| 1070 | + lp->dma_out(lp, RX_TAILDESC_PTR, | |
| 1071 | + lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_tail); | |
| 957 | 1072 | } |
| 958 | − lp->dma_out(lp, RX_TAILDESC_PTR, tail_p); | |
| 959 | 1073 | |
| 960 | 1074 | spin_unlock_irqrestore(&lp->rx_lock, flags); |
| 961 | 1075 | } |
| 962 | 1076 | |
| 1077 | +/* Function scheduled to ensure a restart in case of DMA halt | |
| 1078 | + * condition caused by running out of buffer descriptors. | |
| 1079 | + */ | |
| 1080 | +static void ll_temac_restart_work_func(struct work_struct *work) | |
| 1081 | +{ | |
| 1082 | + struct temac_local *lp = container_of(work, struct temac_local, | |
| 1083 | + restart_work.work); | |
| 1084 | + struct net_device *ndev = lp->ndev; | |
| 1085 | + | |
| 1086 | + ll_temac_recv(ndev); | |
| 1087 | +} | |
| 1088 | + | |
| 963 | 1089 | static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev) |
| 964 | 1090 | { |
| 965 | 1091 | struct net_device *ndev = _ndev; |
| @@ -1052,6 +1178,8 @@ static int temac_stop(struct net_device *ndev) · 86 unmodified lines | ||
| 1052 | 1178 | |
| 1053 | 1179 | dev_dbg(&ndev->dev, "temac_close()\n"); |
| 1054 | 1180 | |
| 1181 | + cancel_delayed_work_sync(&lp->restart_work); | |
| 1182 | + | |
| 1055 | 1183 | free_irq(lp->tx_irq, ndev); |
| 1056 | 1184 | free_irq(lp->rx_irq, ndev); |
| 1057 | 1185 | |
| @@ -1173,6 +1301,7 @@ static int temac_probe(struct platform_device *pdev) · 115 unmodified lines | ||
| 1173 | 1301 | lp->dev = &pdev->dev; |
| 1174 | 1302 | lp->options = XTE_OPTION_DEFAULTS; |
| 1175 | 1303 | spin_lock_init(&lp->rx_lock); |
| 1304 | + INIT_DELAYED_WORK(&lp->restart_work, ll_temac_restart_work_func); | |
| 1176 | 1305 | |
| 1177 | 1306 | /* Setup mutex for synchronization of indirect register access */ |
| 1178 | 1307 | if (pdata) { |
| @@ -1279,6 +1408,7 @@ static int temac_probe(struct platform_device *pdev) · 100 unmodified lines | ||
| 1279 | 1408 | */ |
| 1280 | 1409 | lp->tx_chnl_ctrl = 0x10220000; |
| 1281 | 1410 | lp->rx_chnl_ctrl = 0xff070000; |
| 1411 | + lp->coalesce_count_rx = 0x07; | |
| 1282 | 1412 | |
| 1283 | 1413 | /* Finished with the DMA node; drop the reference */ |
| 1284 | 1414 | of_node_put(dma_np); |
| @@ -1310,11 +1440,14 @@ static int temac_probe(struct platform_device *pdev) · 25 unmodified lines | ||
| 1310 | 1440 | (pdata->tx_irq_count << 16); |
| 1311 | 1441 | else |
| 1312 | 1442 | lp->tx_chnl_ctrl = 0x10220000; |
| 1313 | − if (pdata->rx_irq_timeout || pdata->rx_irq_count) | |
| 1443 | + if (pdata->rx_irq_timeout || pdata->rx_irq_count) { | |
| 1314 | 1444 | lp->rx_chnl_ctrl = (pdata->rx_irq_timeout << 24) | |
| 1315 | 1445 | (pdata->rx_irq_count << 16); |
| 1316 | − else | |
| 1446 | + lp->coalesce_count_rx = pdata->rx_irq_count; | |
| 1447 | + } else { | |
| 1317 | 1448 | lp->rx_chnl_ctrl = 0xff070000; |
| 1449 | + lp->coalesce_count_rx = 0x07; | |
| 1450 | + } | |
| 1318 | 1451 | } |
| 1319 | 1452 | |
| 1320 | 1453 | /* Error handle returned DMA RX and TX interrupts */ |
| @@ -99,7 +99,7 @@ static struct netvsc_device *alloc_net_device(void) · 98 unmodified lines | ||
| 99 | 99 | |
| 100 | 100 | init_waitqueue_head(&net_device->wait_drain); |
| 101 | 101 | net_device->destroy = false; |
| 102 | − net_device->tx_disable = false; | |
| 102 | + net_device->tx_disable = true; | |
| 103 | 103 | |
| 104 | 104 | net_device->max_pkt = RNDIS_MAX_PKT_DEFAULT; |
| 105 | 105 | net_device->pkt_align = RNDIS_PKT_ALIGN_DEFAULT; |
| @@ -1068,6 +1068,7 @@ static int netvsc_attach(struct net_device *ndev, · 1067 unmodified lines | ||
| 1068 | 1068 | } |
| 1069 | 1069 | |
| 1070 | 1070 | /* In any case device is now ready */ |
| 1071 | + nvdev->tx_disable = false; | |
| 1071 | 1072 | netif_device_attach(ndev); |
| 1072 | 1073 | |
| 1073 | 1074 | /* Note: enable and attach happen when sub-channels setup */ |
| @@ -2476,6 +2477,8 @@ static int netvsc_probe(struct hv_device *dev, · 1402 unmodified lines | ||
| 2476 | 2477 | else |
| 2477 | 2478 | net->max_mtu = ETH_DATA_LEN; |
| 2478 | 2479 | |
| 2480 | + nvdev->tx_disable = false; | |
| 2481 | + | |
| 2479 | 2482 | ret = register_netdevice(net); |
| 2480 | 2483 | if (ret != 0) { |
| 2481 | 2484 | pr_err("Unable to register netdev.\n"); |
| @@ -293,6 +293,7 @@ void ipvlan_process_multicast(struct work_struct *work) · 292 unmodified lines | ||
| 293 | 293 | } |
| 294 | 294 | if (dev) |
| 295 | 295 | dev_put(dev); |
| 296 | + cond_resched(); | |
| 296 | 297 | } |
| 297 | 298 | } |
| 298 | 299 | |
| @@ -498,19 +499,21 @@ static int ipvlan_process_outbound(struct sk_buff *skb) · 199 unmodified lines | ||
| 498 | 499 | struct ethhdr *ethh = eth_hdr(skb); |
| 499 | 500 | int ret = NET_XMIT_DROP; |
| 500 | 501 | |
| 501 | − /* In this mode we dont care about multicast and broadcast traffic */ | |
| 502 | − if (is_multicast_ether_addr(ethh->h_dest)) { | |
| 503 | − pr_debug_ratelimited("Dropped {multi|broad}cast of type=[%x]\n", | |
| 504 | − ntohs(skb->protocol)); | |
| 505 | − kfree_skb(skb); | |
| 506 | − goto out; | |
| 507 | − } | |
| 508 | − | |
| 509 | 502 | /* The ipvlan is a pseudo-L2 device, so the packets that we receive |
| 510 | 503 | * will have L2; which need to discarded and processed further |
| 511 | 504 | * in the net-ns of the main-device. |
| 512 | 505 | */ |
| 513 | 506 | if (skb_mac_header_was_set(skb)) { |
| 507 | + /* In this mode we dont care about | |
| 508 | + * multicast and broadcast traffic */ | |
| 509 | + if (is_multicast_ether_addr(ethh->h_dest)) { | |
| 510 | + pr_debug_ratelimited( | |
| 511 | + "Dropped {multi|broad}cast of type=[%x]\n", | |
| 512 | + ntohs(skb->protocol)); | |
| 513 | + kfree_skb(skb); | |
| 514 | + goto out; | |
| 515 | + } | |
| 516 | + | |
| 514 | 517 | skb_pull(skb, sizeof(*ethh)); |
| 515 | 518 | skb->mac_header = (typeof(skb->mac_header))~0U; |
| 516 | 519 | skb_reset_network_header(skb); |
| @@ -164,7 +164,6 @@ static void ipvlan_uninit(struct net_device *dev) · 163 unmodified lines | ||
| 164 | 164 | static int ipvlan_open(struct net_device *dev) |
| 165 | 165 | { |
| 166 | 166 | struct ipvl_dev *ipvlan = netdev_priv(dev); |
| 167 | − struct net_device *phy_dev = ipvlan->phy_dev; | |
| 168 | 167 | struct ipvl_addr *addr; |
| 169 | 168 | |
| 170 | 169 | if (ipvlan->port->mode == IPVLAN_MODE_L3 || |
| @@ -178,7 +177,7 @@ static int ipvlan_open(struct net_device *dev) · 7 unmodified lines | ||
| 178 | 177 | ipvlan_ht_addr_add(ipvlan, addr); |
| 179 | 178 | rcu_read_unlock(); |
| 180 | 179 | |
| 181 | − return dev_uc_add(phy_dev, phy_dev->dev_addr); | |
| 180 | + return 0; | |
| 182 | 181 | } |
| 183 | 182 | |
| 184 | 183 | static int ipvlan_stop(struct net_device *dev) |
| @@ -190,8 +189,6 @@ static int ipvlan_stop(struct net_device *dev) · 5 unmodified lines | ||
| 190 | 189 | dev_uc_unsync(phy_dev, dev); |
| 191 | 190 | dev_mc_unsync(phy_dev, dev); |
| 192 | 191 | |
| 193 | − dev_uc_del(phy_dev, phy_dev->dev_addr); | |
| 194 | − | |
| 195 | 192 | rcu_read_lock(); |
| 196 | 193 | list_for_each_entry_rcu(addr, &ipvlan->addrs, anode) |
| 197 | 194 | ipvlan_ht_addr_del(addr); |
| @@ -424,6 +424,11 @@ static struct macsec_eth_header *macsec_ethhdr(struct sk_buff *skb) · 423 unmodified lines | ||
| 424 | 424 | return (struct macsec_eth_header *)skb_mac_header(skb); |
| 425 | 425 | } |
| 426 | 426 | |
| 427 | +static sci_t dev_to_sci(struct net_device *dev, __be16 port) | |
| 428 | +{ | |
| 429 | + return make_sci(dev->dev_addr, port); | |
| 430 | +} | |
| 431 | + | |
| 427 | 432 | static void __macsec_pn_wrapped(struct macsec_secy *secy, |
| 428 | 433 | struct macsec_tx_sa *tx_sa) |
| 429 | 434 | { |
| @@ -3268,6 +3273,20 @@ static int macsec_set_mac_address(struct net_device *dev, void *p) · 2838 unmodified lines | ||
| 3268 | 3273 | |
| 3269 | 3274 | out: |
| 3270 | 3275 | ether_addr_copy(dev->dev_addr, addr->sa_data); |
| 3276 | + macsec->secy.sci = dev_to_sci(dev, MACSEC_PORT_ES); | |
| 3277 | + | |
| 3278 | + /* If h/w offloading is available, propagate to the device */ | |
| 3279 | + if (macsec_is_offloaded(macsec)) { | |
| 3280 | + const struct macsec_ops *ops; | |
| 3281 | + struct macsec_context ctx; | |
| 3282 | + | |
| 3283 | + ops = macsec_get_ops(macsec, &ctx); | |
| 3284 | + if (ops) { | |
| 3285 | + ctx.secy = &macsec->secy; | |
| 3286 | + macsec_offload(ops->mdo_upd_secy, &ctx); | |
| 3287 | + } | |
| 3288 | + } | |
| 3289 | + | |
| 3271 | 3290 | return 0; |
| 3272 | 3291 | } |
| 3273 | 3292 | |
| @@ -3342,6 +3361,7 @@ static const struct device_type macsec_type = { · 68 unmodified lines | ||
| 3342 | 3361 | |
| 3343 | 3362 | static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = { |
| 3344 | 3363 | [IFLA_MACSEC_SCI] = { .type = NLA_U64 }, |
| 3364 | + [IFLA_MACSEC_PORT] = { .type = NLA_U16 }, | |
| 3345 | 3365 | [IFLA_MACSEC_ICV_LEN] = { .type = NLA_U8 }, |
| 3346 | 3366 | [IFLA_MACSEC_CIPHER_SUITE] = { .type = NLA_U64 }, |
| 3347 | 3367 | [IFLA_MACSEC_WINDOW] = { .type = NLA_U32 }, |
| @@ -3592,11 +3612,6 @@ static bool sci_exists(struct net_device *dev, sci_t sci) · 244 unmodified lines | ||
| 3592 | 3612 | return false; |
| 3593 | 3613 | } |
| 3594 | 3614 | |
| 3595 | −static sci_t dev_to_sci(struct net_device *dev, __be16 port) | |
| 3596 | −{ | |
| 3597 | − return make_sci(dev->dev_addr, port); | |
| 3598 | −} | |
| 3599 | − | |
| 3600 | 3615 | static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len) |
| 3601 | 3616 | { |
| 3602 | 3617 | struct macsec_dev *macsec = macsec_priv(dev); |
| @@ -334,6 +334,8 @@ static void macvlan_process_broadcast(struct work_struct *w) · 333 unmodified lines | ||
| 334 | 334 | if (src) |
| 335 | 335 | dev_put(src->dev); |
| 336 | 336 | consume_skb(skb); |
| 337 | + | |
| 338 | + cond_resched(); | |
| 337 | 339 | } |
| 338 | 340 | } |
| 339 | 341 | |
| @@ -73,6 +73,7 @@ static struct phy_driver bcm63xx_driver[] = { · 72 unmodified lines | ||
| 73 | 73 | /* same phy as above, with just a different OUI */ |
| 74 | 74 | .phy_id = 0x002bdc00, |
| 75 | 75 | .phy_id_mask = 0xfffffc00, |
| 76 | + .name = "Broadcom BCM63XX (2)", | |
| 76 | 77 | /* PHY_BASIC_FEATURES */ |
| 77 | 78 | .flags = PHY_IS_INTERNAL, |
| 78 | 79 | .config_init = bcm63xx_config_init, |
| @@ -1306,6 +1306,9 @@ static int marvell_read_status_page_an(struct phy_device *phydev, · 1305 unmodified lines | ||
| 1306 | 1306 | } |
| 1307 | 1307 | } |
| 1308 | 1308 | |
| 1309 | + if (!(status & MII_M1011_PHY_STATUS_RESOLVED)) | |
| 1310 | + return 0; | |
| 1311 | + | |
| 1309 | 1312 | if (status & MII_M1011_PHY_STATUS_FULLDUPLEX) |
| 1310 | 1313 | phydev->duplex = DUPLEX_FULL; |
| 1311 | 1314 | else |
| @@ -1365,6 +1368,8 @@ static int marvell_read_status_page(struct phy_device *phydev, int page) · 53 unmodified lines | ||
| 1365 | 1368 | linkmode_zero(phydev->lp_advertising); |
| 1366 | 1369 | phydev->pause = 0; |
| 1367 | 1370 | phydev->asym_pause = 0; |
| 1371 | + phydev->speed = SPEED_UNKNOWN; | |
| 1372 | + phydev->duplex = DUPLEX_UNKNOWN; | |
| 1368 | 1373 | |
| 1369 | 1374 | if (phydev->autoneg == AUTONEG_ENABLE) |
| 1370 | 1375 | err = marvell_read_status_page_an(phydev, fiber, status); |
| @@ -345,11 +345,11 @@ enum macsec_bank { · 344 unmodified lines | ||
| 345 | 345 | BIT(VSC8531_FORCE_LED_OFF) | \ |
| 346 | 346 | BIT(VSC8531_FORCE_LED_ON)) |
| 347 | 347 | |
| 348 | −#define MSCC_VSC8584_REVB_INT8051_FW "mscc_vsc8584_revb_int8051_fb48.bin" | |
| 348 | +#define MSCC_VSC8584_REVB_INT8051_FW "microchip/mscc_vsc8584_revb_int8051_fb48.bin" | |
| 349 | 349 | #define MSCC_VSC8584_REVB_INT8051_FW_START_ADDR 0xe800 |
| 350 | 350 | #define MSCC_VSC8584_REVB_INT8051_FW_CRC 0xfb48 |
| 351 | 351 | |
| 352 | −#define MSCC_VSC8574_REVB_INT8051_FW "mscc_vsc8574_revb_int8051_29e8.bin" | |
| 352 | +#define MSCC_VSC8574_REVB_INT8051_FW "microchip/mscc_vsc8574_revb_int8051_29e8.bin" | |
| 353 | 353 | #define MSCC_VSC8574_REVB_INT8051_FW_START_ADDR 0x4000 |
| 354 | 354 | #define MSCC_VSC8574_REVB_INT8051_FW_CRC 0x29e8 |
| 355 | 355 | |
| @@ -167,7 +167,7 @@ EXPORT_SYMBOL_GPL(genphy_c45_restart_aneg); · 166 unmodified lines | ||
| 167 | 167 | */ |
| 168 | 168 | int genphy_c45_check_and_restart_aneg(struct phy_device *phydev, bool restart) |
| 169 | 169 | { |
| 170 | − int ret = 0; | |
| 170 | + int ret; | |
| 171 | 171 | |
| 172 | 172 | if (!restart) { |
| 173 | 173 | /* Configure and restart aneg if it wasn't set before */ |
| @@ -180,9 +180,9 @@ int genphy_c45_check_and_restart_aneg(struct phy_device *phydev, bool restart) · 6 unmodified lines | ||
| 180 | 180 | } |
| 181 | 181 | |
| 182 | 182 | if (restart) |
| 183 | − ret = genphy_c45_restart_aneg(phydev); | |
| 183 | + return genphy_c45_restart_aneg(phydev); | |
| 184 | 184 | |
| 185 | − return ret; | |
| 185 | + return 0; | |
| 186 | 186 | } |
| 187 | 187 | EXPORT_SYMBOL_GPL(genphy_c45_check_and_restart_aneg); |
| 188 | 188 | |
| @@ -727,7 +727,8 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat) · 726 unmodified lines | ||
| 727 | 727 | phy_trigger_machine(phydev); |
| 728 | 728 | } |
| 729 | 729 | |
| 730 | − if (phy_clear_interrupt(phydev)) | |
| 730 | + /* did_interrupt() may have cleared the interrupt already */ | |
| 731 | + if (!phydev->drv->did_interrupt && phy_clear_interrupt(phydev)) | |
| 731 | 732 | goto phy_err; |
| 732 | 733 | return IRQ_HANDLED; |
| 733 | 734 | |
| @@ -247,7 +247,7 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) · 246 unmodified lines | ||
| 247 | 247 | * MDIO bus driver and clock gated at this point. |
| 248 | 248 | */ |
| 249 | 249 | if (!netdev) |
| 250 | − return !phydev->suspended; | |
| 250 | + goto out; | |
| 251 | 251 | |
| 252 | 252 | if (netdev->wol_enabled) |
| 253 | 253 | return false; |
| @@ -267,7 +267,8 @@ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev) · 13 unmodified lines | ||
| 267 | 267 | if (device_may_wakeup(&netdev->dev)) |
| 268 | 268 | return false; |
| 269 | 269 | |
| 270 | − return true; | |
| 270 | +out: | |
| 271 | + return !phydev->suspended; | |
| 271 | 272 | } |
| 272 | 273 | |
| 273 | 274 | static int mdio_bus_phy_suspend(struct device *dev) |
| @@ -285,6 +286,8 @@ static int mdio_bus_phy_suspend(struct device *dev) · 11 unmodified lines | ||
| 285 | 286 | if (!mdio_bus_phy_may_suspend(phydev)) |
| 286 | 287 | return 0; |
| 287 | 288 | |
| 289 | + phydev->suspended_by_mdio_bus = 1; | |
| 290 | + | |
| 288 | 291 | return phy_suspend(phydev); |
| 289 | 292 | } |
| 290 | 293 | |
| @@ -293,9 +296,11 @@ static int mdio_bus_phy_resume(struct device *dev) · 2 unmodified lines | ||
| 293 | 296 | struct phy_device *phydev = to_phy_device(dev); |
| 294 | 297 | int ret; |
| 295 | 298 | |
| 296 | − if (!mdio_bus_phy_may_suspend(phydev)) | |
| 299 | + if (!phydev->suspended_by_mdio_bus) | |
| 297 | 300 | goto no_resume; |
| 298 | 301 | |
| 302 | + phydev->suspended_by_mdio_bus = 0; | |
| 303 | + | |
| 299 | 304 | ret = phy_resume(phydev); |
| 300 | 305 | if (ret < 0) |
| 301 | 306 | return ret; |
| @@ -1792,7 +1797,7 @@ EXPORT_SYMBOL(genphy_restart_aneg); · 1490 unmodified lines | ||
| 1792 | 1797 | */ |
| 1793 | 1798 | int genphy_check_and_restart_aneg(struct phy_device *phydev, bool restart) |
| 1794 | 1799 | { |
| 1795 | − int ret = 0; | |
| 1800 | + int ret; | |
| 1796 | 1801 | |
| 1797 | 1802 | if (!restart) { |
| 1798 | 1803 | /* Advertisement hasn't changed, but maybe aneg was never on to |
| @@ -1807,9 +1812,9 @@ int genphy_check_and_restart_aneg(struct phy_device *phydev, bool restart) · 8 unmodified lines | ||
| 1807 | 1812 | } |
| 1808 | 1813 | |
| 1809 | 1814 | if (restart) |
| 1810 | − ret = genphy_restart_aneg(phydev); | |
| 1815 | + return genphy_restart_aneg(phydev); | |
| 1811 | 1816 | |
| 1812 | − return ret; | |
| 1817 | + return 0; | |
| 1813 | 1818 | } |
| 1814 | 1819 | EXPORT_SYMBOL(genphy_check_and_restart_aneg); |
| 1815 | 1820 | |
| @@ -761,8 +761,14 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy, · 760 unmodified lines | ||
| 761 | 761 | config.interface = interface; |
| 762 | 762 | |
| 763 | 763 | ret = phylink_validate(pl, supported, &config); |
| 764 | − if (ret) | |
| 764 | + if (ret) { | |
| 765 | + phylink_warn(pl, "validation of %s with support %*pb and advertisement %*pb failed: %d\n", | |
| 766 | + phy_modes(config.interface), | |
| 767 | + __ETHTOOL_LINK_MODE_MASK_NBITS, phy->supported, | |
| 768 | + __ETHTOOL_LINK_MODE_MASK_NBITS, config.advertising, | |
| 769 | + ret); | |
| 765 | 770 | return ret; |
| 771 | + } | |
| 766 | 772 | |
| 767 | 773 | phy->phylink = pl; |
| 768 | 774 | phy->phy_link_change = phylink_phy_change; |
| @@ -232,7 +232,7 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, · 231 unmodified lines | ||
| 232 | 232 | struct cstate *cs = lcs->next; |
| 233 | 233 | unsigned long deltaS, deltaA; |
| 234 | 234 | short changes = 0; |
| 235 | − int hlen; | |
| 235 | + int nlen, hlen; | |
| 236 | 236 | unsigned char new_seq[16]; |
| 237 | 237 | unsigned char *cp = new_seq; |
| 238 | 238 | struct iphdr *ip; |
| @@ -248,6 +248,8 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, · 9 unmodified lines | ||
| 248 | 248 | return isize; |
| 249 | 249 | |
| 250 | 250 | ip = (struct iphdr *) icp; |
| 251 | + if (ip->version != 4 || ip->ihl < 5) | |
| 252 | + return isize; | |
| 251 | 253 | |
| 252 | 254 | /* Bail if this packet isn't TCP, or is an IP fragment */ |
| 253 | 255 | if (ip->protocol != IPPROTO_TCP || (ntohs(ip->frag_off) & 0x3fff)) { |
| @@ -258,10 +260,14 @@ slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, · 4 unmodified lines | ||
| 258 | 260 | comp->sls_o_tcp++; |
| 259 | 261 | return isize; |
| 260 | 262 | } |
| 261 | − /* Extract TCP header */ | |
| 263 | + nlen = ip->ihl * 4; | |
| 264 | + if (isize < nlen + sizeof(*th)) | |
| 265 | + return isize; | |
| 262 | 266 | |
| 263 | − th = (struct tcphdr *)(((unsigned char *)ip) + ip->ihl*4); | |
| 264 | − hlen = ip->ihl*4 + th->doff*4; | |
| 267 | + th = (struct tcphdr *)(icp + nlen); | |
| 268 | + if (th->doff < sizeof(struct tcphdr) / 4) | |
| 269 | + return isize; | |
| 270 | + hlen = nlen + th->doff * 4; | |
| 265 | 271 | |
| 266 | 272 | /* Bail if the TCP packet isn't `compressible' (i.e., ACK isn't set or |
| 267 | 273 | * some other control bit is set). Also uncompressible if |
| @@ -863,7 +863,10 @@ err_free_chan: · 862 unmodified lines | ||
| 863 | 863 | tty->disc_data = NULL; |
| 864 | 864 | clear_bit(SLF_INUSE, &sl->flags); |
| 865 | 865 | sl_free_netdev(sl->dev); |
| 866 | + /* do not call free_netdev before rtnl_unlock */ | |
| 867 | + rtnl_unlock(); | |
| 866 | 868 | free_netdev(sl->dev); |
| 869 | + return err; | |
| 867 | 870 | |
| 868 | 871 | err_exit: |
| 869 | 872 | rtnl_unlock(); |
| @@ -2240,6 +2240,8 @@ team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = { · 2239 unmodified lines | ||
| 2240 | 2240 | [TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG }, |
| 2241 | 2241 | [TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 }, |
| 2242 | 2242 | [TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY }, |
| 2243 | + [TEAM_ATTR_OPTION_PORT_IFINDEX] = { .type = NLA_U32 }, | |
| 2244 | + [TEAM_ATTR_OPTION_ARRAY_INDEX] = { .type = NLA_U32 }, | |
| 2243 | 2245 | }; |
| 2244 | 2246 | |
| 2245 | 2247 | static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info) |
| @@ -337,6 +337,9 @@ static void qmi_wwan_netdev_setup(struct net_device *net) · 336 unmodified lines | ||
| 337 | 337 | netdev_dbg(net, "mode: raw IP\n"); |
| 338 | 338 | } else if (!net->header_ops) { /* don't bother if already set */ |
| 339 | 339 | ether_setup(net); |
| 340 | + /* Restoring min/max mtu values set originally by usbnet */ | |
| 341 | + net->min_mtu = 0; | |
| 342 | + net->max_mtu = ETH_MAX_MTU; | |
| 340 | 343 | clear_bit(EVENT_NO_IP_ALIGN, &dev->flags); |
| 341 | 344 | netdev_dbg(net, "mode: Ethernet\n"); |
| 342 | 345 | } |
| @@ -3221,6 +3221,8 @@ static u16 r8153_phy_status(struct r8152 *tp, u16 desired) · 3220 unmodified lines | ||
| 3221 | 3221 | } |
| 3222 | 3222 | |
| 3223 | 3223 | msleep(20); |
| 3224 | + if (test_bit(RTL8152_UNPLUG, &tp->flags)) | |
| 3225 | + break; | |
| 3224 | 3226 | } |
| 3225 | 3227 | |
| 3226 | 3228 | return data; |
| @@ -5402,7 +5404,10 @@ static void r8153_init(struct r8152 *tp) · 2175 unmodified lines | ||
| 5402 | 5404 | if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & |
| 5403 | 5405 | AUTOLOAD_DONE) |
| 5404 | 5406 | break; |
| 5407 | + | |
| 5405 | 5408 | msleep(20); |
| 5409 | + if (test_bit(RTL8152_UNPLUG, &tp->flags)) | |
| 5410 | + break; | |
| 5406 | 5411 | } |
| 5407 | 5412 | |
| 5408 | 5413 | data = r8153_phy_status(tp, 0); |
| @@ -5539,7 +5544,10 @@ static void r8153b_init(struct r8152 *tp) · 130 unmodified lines | ||
| 5539 | 5544 | if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) & |
| 5540 | 5545 | AUTOLOAD_DONE) |
| 5541 | 5546 | break; |
| 5547 | + | |
| 5542 | 5548 | msleep(20); |
| 5549 | + if (test_bit(RTL8152_UNPLUG, &tp->flags)) | |
| 5550 | + break; | |
| 5543 | 5551 | } |
| 5544 | 5552 | |
| 5545 | 5553 | data = r8153_phy_status(tp, 0); |
| @@ -328,7 +328,7 @@ static void veth_get_stats64(struct net_device *dev, · 327 unmodified lines | ||
| 328 | 328 | rcu_read_lock(); |
| 329 | 329 | peer = rcu_dereference(priv->peer); |
| 330 | 330 | if (peer) { |
| 331 | − tot->rx_dropped += veth_stats_tx(peer, &packets, &bytes); | |
| 331 | + veth_stats_tx(peer, &packets, &bytes); | |
| 332 | 332 | tot->rx_bytes += bytes; |
| 333 | 333 | tot->rx_packets += packets; |
| 334 | 334 | |
| @@ -308,7 +308,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) · 307 unmodified lines | ||
| 308 | 308 | } |
| 309 | 309 | |
| 310 | 310 | /* PHY_SKU section is mandatory in B0 */ |
| 311 | − if (!mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { | |
| 311 | + if (mvm->trans->cfg->nvm_type == IWL_NVM_EXT && | |
| 312 | + !mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) { | |
| 312 | 313 | IWL_ERR(mvm, |
| 313 | 314 | "Can't parse phy_sku in B0, empty sections\n"); |
| 314 | 315 | return NULL; |
| @@ -447,10 +447,13 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data, · 446 unmodified lines | ||
| 447 | 447 | struct page *page = virt_to_head_page(data); |
| 448 | 448 | int offset = data - page_address(page); |
| 449 | 449 | struct sk_buff *skb = q->rx_head; |
| 450 | + struct skb_shared_info *shinfo = skb_shinfo(skb); | |
| 450 | 451 | |
| 451 | − offset += q->buf_offset; | |
| 452 | − skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page, offset, len, | |
| 453 | − q->buf_size); | |
| 452 | + if (shinfo->nr_frags < ARRAY_SIZE(shinfo->frags)) { | |
| 453 | + offset += q->buf_offset; | |
| 454 | + skb_add_rx_frag(skb, shinfo->nr_frags, page, offset, len, | |
| 455 | + q->buf_size); | |
| 456 | + } | |
| 454 | 457 | |
| 455 | 458 | if (more) |
| 456 | 459 | return; |
| @@ -1078,9 +1078,9 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx) · 1077 unmodified lines | ||
| 1078 | 1078 | |
| 1079 | 1079 | spin_lock(&nvmeq->cq_poll_lock); |
| 1080 | 1080 | found = nvme_process_cq(nvmeq, &start, &end, -1); |
| 1081 | + nvme_complete_cqes(nvmeq, start, end); | |
| 1081 | 1082 | spin_unlock(&nvmeq->cq_poll_lock); |
| 1082 | 1083 | |
| 1083 | − nvme_complete_cqes(nvmeq, start, end); | |
| 1084 | 1084 | return found; |
| 1085 | 1085 | } |
| 1086 | 1086 | |
| @@ -306,6 +306,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) · 305 unmodified lines | ||
| 306 | 306 | rc = of_mdiobus_register_phy(mdio, child, addr); |
| 307 | 307 | if (rc && rc != -ENODEV) |
| 308 | 308 | goto unregister; |
| 309 | + break; | |
| 309 | 310 | } |
| 310 | 311 | } |
| 311 | 312 | } |
| @@ -670,7 +670,7 @@ static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie, · 669 unmodified lines | ||
| 670 | 670 | * outbound memory @ 3GB). So instead it will start at the 1x |
| 671 | 671 | * multiple of its size |
| 672 | 672 | */ |
| 673 | − if (!*rc_bar2_size || *rc_bar2_offset % *rc_bar2_size || | |
| 673 | + if (!*rc_bar2_size || (*rc_bar2_offset & (*rc_bar2_size - 1)) || | |
| 674 | 674 | (*rc_bar2_offset < SZ_4G && *rc_bar2_offset > SZ_2G)) { |
| 675 | 675 | dev_err(dev, "Invalid rc_bar2_offset/size: size 0x%llx, off 0x%llx\n", |
| 676 | 676 | *rc_bar2_size, *rc_bar2_offset); |
| @@ -24,8 +24,6 @@ static int arm_pmu_acpi_register_irq(int cpu) · 23 unmodified lines | ||
| 24 | 24 | int gsi, trigger; |
| 25 | 25 | |
| 26 | 26 | gicc = acpi_cpu_get_madt_gicc(cpu); |
| 27 | − if (WARN_ON(!gicc)) | |
| 28 | − return -EINVAL; | |
| 29 | 27 | |
| 30 | 28 | gsi = gicc->performance_interrupt; |
| 31 | 29 | |
| @@ -64,11 +62,10 @@ static void arm_pmu_acpi_unregister_irq(int cpu) · 32 unmodified lines | ||
| 64 | 62 | int gsi; |
| 65 | 63 | |
| 66 | 64 | gicc = acpi_cpu_get_madt_gicc(cpu); |
| 67 | − if (!gicc) | |
| 68 | − return; | |
| 69 | 65 | |
| 70 | 66 | gsi = gicc->performance_interrupt; |
| 71 | − acpi_unregister_gsi(gsi); | |
| 67 | + if (gsi) | |
| 68 | + acpi_unregister_gsi(gsi); | |
| 72 | 69 | } |
| 73 | 70 | |
| 74 | 71 | #if IS_ENABLED(CONFIG_ARM_SPE_PMU) |
| @@ -388,9 +388,10 @@ static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config, · 387 unmodified lines | ||
| 388 | 388 | |
| 389 | 389 | if (enable) { |
| 390 | 390 | /* |
| 391 | − * must disable first, then enable again | |
| 392 | − * otherwise, cycle counter will not work | |
| 393 | − * if previous state is enabled. | |
| 391 | + * cycle counter is special which should firstly write 0 then | |
| 392 | + * write 1 into CLEAR bit to clear it. Other counters only | |
| 393 | + * need write 0 into CLEAR bit and it turns out to be 1 by | |
| 394 | + * hardware. Below enable flow is harmless for all counters. | |
| 394 | 395 | */ |
| 395 | 396 | writel(0, pmu->base + reg); |
| 396 | 397 | val = CNTL_EN | CNTL_CLEAR; |
| @@ -398,7 +399,8 @@ static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config, · 1 unmodified line | ||
| 398 | 399 | writel(val, pmu->base + reg); |
| 399 | 400 | } else { |
| 400 | 401 | /* Disable counter */ |
| 401 | − writel(0, pmu->base + reg); | |
| 402 | + val = readl_relaxed(pmu->base + reg) & CNTL_EN_MASK; | |
| 403 | + writel(val, pmu->base + reg); | |
| 402 | 404 | } |
| 403 | 405 | } |
| 404 | 406 | |
| @@ -49,7 +49,7 @@ · 48 unmodified lines | ||
| 49 | 49 | #define SUNXI_LOS_BIAS(n) ((n) << 3) |
| 50 | 50 | #define SUNXI_LOS_BIAS_MASK GENMASK(5, 3) |
| 51 | 51 | #define SUNXI_TXVBOOSTLVL(n) ((n) << 0) |
| 52 | −#define SUNXI_TXVBOOSTLVL_MASK GENMASK(0, 2) | |
| 52 | +#define SUNXI_TXVBOOSTLVL_MASK GENMASK(2, 0) | |
| 53 | 53 | |
| 54 | 54 | struct sun50i_usb3_phy { |
| 55 | 55 | struct phy *phy; |
| @@ -186,29 +186,6 @@ enum sata_phy_ctrl_regs { · 185 unmodified lines | ||
| 186 | 186 | PHY_CTRL_1_RESET = BIT(0), |
| 187 | 187 | }; |
| 188 | 188 | |
| 189 | −static inline void __iomem *brcm_sata_pcb_base(struct brcm_sata_port *port) | |
| 190 | −{ | |
| 191 | − struct brcm_sata_phy *priv = port->phy_priv; | |
| 192 | − u32 size = 0; | |
| 193 | − | |
| 194 | − switch (priv->version) { | |
| 195 | − case BRCM_SATA_PHY_STB_16NM: | |
| 196 | − case BRCM_SATA_PHY_STB_28NM: | |
| 197 | − case BRCM_SATA_PHY_IPROC_NS2: | |
| 198 | − case BRCM_SATA_PHY_DSL_28NM: | |
| 199 | − size = SATA_PCB_REG_28NM_SPACE_SIZE; | |
| 200 | − break; | |
| 201 | − case BRCM_SATA_PHY_STB_40NM: | |
| 202 | − size = SATA_PCB_REG_40NM_SPACE_SIZE; | |
| 203 | − break; | |
| 204 | − default: | |
| 205 | − dev_err(priv->dev, "invalid phy version\n"); | |
| 206 | − break; | |
| 207 | − } | |
| 208 | − | |
| 209 | − return priv->phy_base + (port->portnum * size); | |
| 210 | −} | |
| 211 | − | |
| 212 | 189 | static inline void __iomem *brcm_sata_ctrl_base(struct brcm_sata_port *port) |
| 213 | 190 | { |
| 214 | 191 | struct brcm_sata_phy *priv = port->phy_priv; |
| @@ -226,19 +203,34 @@ static inline void __iomem *brcm_sata_ctrl_base(struct brcm_sata_port *port) · 11 unmodified lines | ||
| 226 | 203 | return priv->ctrl_base + (port->portnum * size); |
| 227 | 204 | } |
| 228 | 205 | |
| 229 | −static void brcm_sata_phy_wr(void __iomem *pcb_base, u32 bank, | |
| 206 | +static void brcm_sata_phy_wr(struct brcm_sata_port *port, u32 bank, | |
| 230 | 207 | u32 ofs, u32 msk, u32 value) |
| 231 | 208 | { |
| 209 | + struct brcm_sata_phy *priv = port->phy_priv; | |
| 210 | + void __iomem *pcb_base = priv->phy_base; | |
| 232 | 211 | u32 tmp; |
| 233 | 212 | |
| 213 | + if (priv->version == BRCM_SATA_PHY_STB_40NM) | |
| 214 | + bank += (port->portnum * SATA_PCB_REG_40NM_SPACE_SIZE); | |
| 215 | + else | |
| 216 | + pcb_base += (port->portnum * SATA_PCB_REG_28NM_SPACE_SIZE); | |
| 217 | + | |
| 234 | 218 | writel(bank, pcb_base + SATA_PCB_BANK_OFFSET); |
| 235 | 219 | tmp = readl(pcb_base + SATA_PCB_REG_OFFSET(ofs)); |
| 236 | 220 | tmp = (tmp & msk) | value; |
| 237 | 221 | writel(tmp, pcb_base + SATA_PCB_REG_OFFSET(ofs)); |
| 238 | 222 | } |
| 239 | 223 | |
| 240 | −static u32 brcm_sata_phy_rd(void __iomem *pcb_base, u32 bank, u32 ofs) | |
| 224 | +static u32 brcm_sata_phy_rd(struct brcm_sata_port *port, u32 bank, u32 ofs) | |
| 241 | 225 | { |
| 226 | + struct brcm_sata_phy *priv = port->phy_priv; | |
| 227 | + void __iomem *pcb_base = priv->phy_base; | |
| 228 | + | |
| 229 | + if (priv->version == BRCM_SATA_PHY_STB_40NM) | |
| 230 | + bank += (port->portnum * SATA_PCB_REG_40NM_SPACE_SIZE); | |
| 231 | + else | |
| 232 | + pcb_base += (port->portnum * SATA_PCB_REG_28NM_SPACE_SIZE); | |
| 233 | + | |
| 242 | 234 | writel(bank, pcb_base + SATA_PCB_BANK_OFFSET); |
| 243 | 235 | return readl(pcb_base + SATA_PCB_REG_OFFSET(ofs)); |
| 244 | 236 | } |
| @@ -250,16 +242,15 @@ static u32 brcm_sata_phy_rd(void __iomem *pcb_base, u32 bank, u32 ofs) · 5 unmodified lines | ||
| 250 | 242 | |
| 251 | 243 | static void brcm_stb_sata_ssc_init(struct brcm_sata_port *port) |
| 252 | 244 | { |
| 253 | − void __iomem *base = brcm_sata_pcb_base(port); | |
| 254 | 245 | struct brcm_sata_phy *priv = port->phy_priv; |
| 255 | 246 | u32 tmp; |
| 256 | 247 | |
| 257 | 248 | /* override the TX spread spectrum setting */ |
| 258 | 249 | tmp = TXPMD_CONTROL1_TX_SSC_EN_FRC_VAL | TXPMD_CONTROL1_TX_SSC_EN_FRC; |
| 259 | − brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_CONTROL1, ~tmp, tmp); | |
| 250 | + brcm_sata_phy_wr(port, TXPMD_REG_BANK, TXPMD_CONTROL1, ~tmp, tmp); | |
| 260 | 251 | |
| 261 | 252 | /* set fixed min freq */ |
| 262 | − brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL2, | |
| 253 | + brcm_sata_phy_wr(port, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL2, | |
| 263 | 254 | ~TXPMD_TX_FREQ_CTRL_CONTROL2_FMIN_MASK, |
| 264 | 255 | STB_FMIN_VAL_DEFAULT); |
| 265 | 256 | |
| @@ -271,7 +262,7 @@ static void brcm_stb_sata_ssc_init(struct brcm_sata_port *port) · 5 unmodified lines | ||
| 271 | 262 | tmp = STB_FMAX_VAL_DEFAULT; |
| 272 | 263 | } |
| 273 | 264 | |
| 274 | − brcm_sata_phy_wr(base, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL3, | |
| 265 | + brcm_sata_phy_wr(port, TXPMD_REG_BANK, TXPMD_TX_FREQ_CTRL_CONTROL3, | |
| 275 | 266 | ~TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK, tmp); |
| 276 | 267 | } |
| 277 | 268 | |
| @@ -280,7 +271,6 @@ static void brcm_stb_sata_ssc_init(struct brcm_sata_port *port) · 2 unmodified lines | ||
| 280 | 271 | |
| 281 | 272 | static int brcm_stb_sata_rxaeq_init(struct brcm_sata_port *port) |
| 282 | 273 | { |
| 283 | − void __iomem *base = brcm_sata_pcb_base(port); | |
| 284 | 274 | u32 tmp = 0, reg = 0; |
| 285 | 275 | |
| 286 | 276 | switch (port->rxaeq_mode) { |
| @@ -301,8 +291,8 @@ static int brcm_stb_sata_rxaeq_init(struct brcm_sata_port *port) · 14 unmodified lines | ||
| 301 | 291 | break; |
| 302 | 292 | } |
| 303 | 293 | |
| 304 | − brcm_sata_phy_wr(base, AEQRX_REG_BANK_0, reg, ~tmp, tmp); | |
| 305 | − brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, reg, ~tmp, tmp); | |
| 294 | + brcm_sata_phy_wr(port, AEQRX_REG_BANK_0, reg, ~tmp, tmp); | |
| 295 | + brcm_sata_phy_wr(port, AEQRX_REG_BANK_1, reg, ~tmp, tmp); | |
| 306 | 296 | |
| 307 | 297 | return 0; |
| 308 | 298 | } |
| @@ -316,18 +306,17 @@ static int brcm_stb_sata_init(struct brcm_sata_port *port) · 7 unmodified lines | ||
| 316 | 306 | |
| 317 | 307 | static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port) |
| 318 | 308 | { |
| 319 | − void __iomem *base = brcm_sata_pcb_base(port); | |
| 320 | 309 | u32 tmp, value; |
| 321 | 310 | |
| 322 | 311 | /* Reduce CP tail current to 1/16th of its default value */ |
| 323 | − brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0x141); | |
| 312 | + brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0x141); | |
| 324 | 313 | |
| 325 | 314 | /* Turn off CP tail current boost */ |
| 326 | − brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL8, 0, 0xc006); | |
| 315 | + brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL8, 0, 0xc006); | |
| 327 | 316 | |
| 328 | 317 | /* Set a specific AEQ equalizer value */ |
| 329 | 318 | tmp = AEQ_FRC_EQ_FORCE_VAL | AEQ_FRC_EQ_FORCE; |
| 330 | − brcm_sata_phy_wr(base, AEQRX_REG_BANK_0, AEQ_FRC_EQ, | |
| 319 | + brcm_sata_phy_wr(port, AEQRX_REG_BANK_0, AEQ_FRC_EQ, | |
| 331 | 320 | ~(tmp | AEQ_RFZ_FRC_VAL | |
| 332 | 321 | AEQ_FRC_EQ_VAL_MASK << AEQ_FRC_EQ_VAL_SHIFT), |
| 333 | 322 | tmp | 32 << AEQ_FRC_EQ_VAL_SHIFT); |
| @@ -337,7 +326,7 @@ static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port) · 3 unmodified lines | ||
| 337 | 326 | value = 0x52; |
| 338 | 327 | else |
| 339 | 328 | value = 0; |
| 340 | − brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_CDR_CONTROL1, | |
| 329 | + brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CONTROL1, | |
| 341 | 330 | ~RXPMD_RX_PPM_VAL_MASK, value); |
| 342 | 331 | |
| 343 | 332 | /* Set proportional loop bandwith Gen1/2/3 */ |
| @@ -352,7 +341,7 @@ static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port) · 8 unmodified lines | ||
| 352 | 341 | value = 1 << RXPMD_G1_CDR_PROP_BW_SHIFT | |
| 353 | 342 | 1 << RXPMD_G2_CDR_PROP_BW_SHIFT | |
| 354 | 343 | 1 << RXPMD_G3_CDR_PROB_BW_SHIFT; |
| 355 | − brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_PROP_BW, ~tmp, | |
| 344 | + brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_PROP_BW, ~tmp, | |
| 356 | 345 | value); |
| 357 | 346 | |
| 358 | 347 | /* Set CDR integral loop acquisition bandwidth for Gen1/2/3 */ |
| @@ -365,7 +354,7 @@ static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port) · 6 unmodified lines | ||
| 365 | 354 | 1 << RXPMD_G3_CDR_ACQ_INT_BW_SHIFT; |
| 366 | 355 | else |
| 367 | 356 | value = 0; |
| 368 | − brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_ACQ_INTEG_BW, | |
| 357 | + brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_ACQ_INTEG_BW, | |
| 369 | 358 | ~tmp, value); |
| 370 | 359 | |
| 371 | 360 | /* Set CDR integral loop locking bandwidth to 1 for Gen 1/2/3 */ |
| @@ -378,7 +367,7 @@ static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port) · 6 unmodified lines | ||
| 378 | 367 | 1 << RXPMD_G3_CDR_LOCK_INT_BW_SHIFT; |
| 379 | 368 | else |
| 380 | 369 | value = 0; |
| 381 | − brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_LOCK_INTEG_BW, | |
| 370 | + brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_LOCK_INTEG_BW, | |
| 382 | 371 | ~tmp, value); |
| 383 | 372 | |
| 384 | 373 | /* Set no guard band and clamp CDR */ |
| @@ -387,11 +376,11 @@ static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port) · 2 unmodified lines | ||
| 387 | 376 | value = 0x51; |
| 388 | 377 | else |
| 389 | 378 | value = 0; |
| 390 | − brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1, | |
| 379 | + brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1, | |
| 391 | 380 | ~tmp, RXPMD_MON_CORRECT_EN | value); |
| 392 | 381 | |
| 393 | 382 | /* Turn on/off SSC */ |
| 394 | − brcm_sata_phy_wr(base, TX_REG_BANK, TX_ACTRL5, ~TX_ACTRL5_SSC_EN, | |
| 383 | + brcm_sata_phy_wr(port, TX_REG_BANK, TX_ACTRL5, ~TX_ACTRL5_SSC_EN, | |
| 395 | 384 | port->ssc_en ? TX_ACTRL5_SSC_EN : 0); |
| 396 | 385 | |
| 397 | 386 | return 0; |
| @@ -411,7 +400,6 @@ static int brcm_ns2_sata_init(struct brcm_sata_port *port) · 13 unmodified lines | ||
| 411 | 400 | { |
| 412 | 401 | int try; |
| 413 | 402 | unsigned int val; |
| 414 | − void __iomem *base = brcm_sata_pcb_base(port); | |
| 415 | 403 | void __iomem *ctrl_base = brcm_sata_ctrl_base(port); |
| 416 | 404 | struct device *dev = port->phy_priv->dev; |
| 417 | 405 | |
| @@ -421,24 +409,24 @@ static int brcm_ns2_sata_init(struct brcm_sata_port *port) · 3 unmodified lines | ||
| 421 | 409 | val |= (0x4 << OOB_CTRL1_BURST_MIN_SHIFT); |
| 422 | 410 | val |= (0x9 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT); |
| 423 | 411 | val |= (0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT); |
| 424 | − brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val); | |
| 412 | + brcm_sata_phy_wr(port, OOB_REG_BANK, OOB_CTRL1, 0x0, val); | |
| 425 | 413 | val = 0x0; |
| 426 | 414 | val |= (0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT); |
| 427 | 415 | val |= (0x2 << OOB_CTRL2_BURST_CNT_SHIFT); |
| 428 | 416 | val |= (0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT); |
| 429 | − brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val); | |
| 417 | + brcm_sata_phy_wr(port, OOB_REG_BANK, OOB_CTRL2, 0x0, val); | |
| 430 | 418 | |
| 431 | 419 | /* Configure PHY PLL register bank 1 */ |
| 432 | 420 | val = NS2_PLL1_ACTRL2_MAGIC; |
| 433 | − brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val); | |
| 421 | + brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val); | |
| 434 | 422 | val = NS2_PLL1_ACTRL3_MAGIC; |
| 435 | − brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val); | |
| 423 | + brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val); | |
| 436 | 424 | val = NS2_PLL1_ACTRL4_MAGIC; |
| 437 | − brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val); | |
| 425 | + brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val); | |
| 438 | 426 | |
| 439 | 427 | /* Configure PHY BLOCK0 register bank */ |
| 440 | 428 | /* Set oob_clk_sel to refclk/2 */ |
| 441 | − brcm_sata_phy_wr(base, BLOCK0_REG_BANK, BLOCK0_SPARE, | |
| 429 | + brcm_sata_phy_wr(port, BLOCK0_REG_BANK, BLOCK0_SPARE, | |
| 442 | 430 | ~BLOCK0_SPARE_OOB_CLK_SEL_MASK, |
| 443 | 431 | BLOCK0_SPARE_OOB_CLK_SEL_REFBY2); |
| 444 | 432 | |
| @@ -451,7 +439,7 @@ static int brcm_ns2_sata_init(struct brcm_sata_port *port) · 6 unmodified lines | ||
| 451 | 439 | /* Wait for PHY PLL lock by polling pll_lock bit */ |
| 452 | 440 | try = 50; |
| 453 | 441 | while (try) { |
| 454 | − val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK, | |
| 442 | + val = brcm_sata_phy_rd(port, BLOCK0_REG_BANK, | |
| 455 | 443 | BLOCK0_XGXSSTATUS); |
| 456 | 444 | if (val & BLOCK0_XGXSSTATUS_PLL_LOCK) |
| 457 | 445 | break; |
| @@ -471,9 +459,7 @@ static int brcm_ns2_sata_init(struct brcm_sata_port *port) · 13 unmodified lines | ||
| 471 | 459 | |
| 472 | 460 | static int brcm_nsp_sata_init(struct brcm_sata_port *port) |
| 473 | 461 | { |
| 474 | − struct brcm_sata_phy *priv = port->phy_priv; | |
| 475 | 462 | struct device *dev = port->phy_priv->dev; |
| 476 | − void __iomem *base = priv->phy_base; | |
| 477 | 463 | unsigned int oob_bank; |
| 478 | 464 | unsigned int val, try; |
| 479 | 465 | |
| @@ -490,36 +476,36 @@ static int brcm_nsp_sata_init(struct brcm_sata_port *port) · 10 unmodified lines | ||
| 490 | 476 | val |= (0x06 << OOB_CTRL1_BURST_MIN_SHIFT); |
| 491 | 477 | val |= (0x0f << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT); |
| 492 | 478 | val |= (0x06 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT); |
| 493 | − brcm_sata_phy_wr(base, oob_bank, OOB_CTRL1, 0x0, val); | |
| 479 | + brcm_sata_phy_wr(port, oob_bank, OOB_CTRL1, 0x0, val); | |
| 494 | 480 | |
| 495 | 481 | val = 0x0; |
| 496 | 482 | val |= (0x2e << OOB_CTRL2_RESET_IDLE_MAX_SHIFT); |
| 497 | 483 | val |= (0x02 << OOB_CTRL2_BURST_CNT_SHIFT); |
| 498 | 484 | val |= (0x16 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT); |
| 499 | − brcm_sata_phy_wr(base, oob_bank, OOB_CTRL2, 0x0, val); | |
| 485 | + brcm_sata_phy_wr(port, oob_bank, OOB_CTRL2, 0x0, val); | |
| 500 | 486 | |
| 501 | 487 | |
| 502 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL2, | |
| 488 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_ACTRL2, | |
| 503 | 489 | ~(PLL_ACTRL2_SELDIV_MASK << PLL_ACTRL2_SELDIV_SHIFT), |
| 504 | 490 | 0x0c << PLL_ACTRL2_SELDIV_SHIFT); |
| 505 | 491 | |
| 506 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_CAP_CONTROL, | |
| 492 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_CAP_CONTROL, | |
| 507 | 493 | 0xff0, 0x4f0); |
| 508 | 494 | |
| 509 | 495 | val = PLLCONTROL_0_FREQ_DET_RESTART | PLLCONTROL_0_FREQ_MONITOR; |
| 510 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, | |
| 496 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, | |
| 511 | 497 | ~val, val); |
| 512 | 498 | val = PLLCONTROL_0_SEQ_START; |
| 513 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, | |
| 499 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, | |
| 514 | 500 | ~val, 0); |
| 515 | 501 | mdelay(10); |
| 516 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, | |
| 502 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, | |
| 517 | 503 | ~val, val); |
| 518 | 504 | |
| 519 | 505 | /* Wait for pll_seq_done bit */ |
| 520 | 506 | try = 50; |
| 521 | 507 | while (--try) { |
| 522 | − val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK, | |
| 508 | + val = brcm_sata_phy_rd(port, BLOCK0_REG_BANK, | |
| 523 | 509 | BLOCK0_XGXSSTATUS); |
| 524 | 510 | if (val & BLOCK0_XGXSSTATUS_PLL_LOCK) |
| 525 | 511 | break; |
| @@ -546,27 +532,25 @@ static int brcm_nsp_sata_init(struct brcm_sata_port *port) · 20 unmodified lines | ||
| 546 | 532 | |
| 547 | 533 | static int brcm_sr_sata_init(struct brcm_sata_port *port) |
| 548 | 534 | { |
| 549 | − struct brcm_sata_phy *priv = port->phy_priv; | |
| 550 | 535 | struct device *dev = port->phy_priv->dev; |
| 551 | − void __iomem *base = priv->phy_base; | |
| 552 | 536 | unsigned int val, try; |
| 553 | 537 | |
| 554 | 538 | /* Configure PHY PLL register bank 1 */ |
| 555 | 539 | val = SR_PLL1_ACTRL2_MAGIC; |
| 556 | − brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val); | |
| 540 | + brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val); | |
| 557 | 541 | val = SR_PLL1_ACTRL3_MAGIC; |
| 558 | − brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val); | |
| 542 | + brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val); | |
| 559 | 543 | val = SR_PLL1_ACTRL4_MAGIC; |
| 560 | − brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val); | |
| 544 | + brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val); | |
| 561 | 545 | |
| 562 | 546 | /* Configure PHY PLL register bank 0 */ |
| 563 | 547 | val = SR_PLL0_ACTRL6_MAGIC; |
| 564 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL6, 0x0, val); | |
| 548 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_ACTRL6, 0x0, val); | |
| 565 | 549 | |
| 566 | 550 | /* Wait for PHY PLL lock by polling pll_lock bit */ |
| 567 | 551 | try = 50; |
| 568 | 552 | do { |
| 569 | − val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK, | |
| 553 | + val = brcm_sata_phy_rd(port, BLOCK0_REG_BANK, | |
| 570 | 554 | BLOCK0_XGXSSTATUS); |
| 571 | 555 | if (val & BLOCK0_XGXSSTATUS_PLL_LOCK) |
| 572 | 556 | break; |
| @@ -581,7 +565,7 @@ static int brcm_sr_sata_init(struct brcm_sata_port *port) · 8 unmodified lines | ||
| 581 | 565 | } |
| 582 | 566 | |
| 583 | 567 | /* Invert Tx polarity */ |
| 584 | − brcm_sata_phy_wr(base, TX_REG_BANK, TX_ACTRL0, | |
| 568 | + brcm_sata_phy_wr(port, TX_REG_BANK, TX_ACTRL0, | |
| 585 | 569 | ~TX_ACTRL0_TXPOL_FLIP, TX_ACTRL0_TXPOL_FLIP); |
| 586 | 570 | |
| 587 | 571 | /* Configure OOB control to handle 100MHz reference clock */ |
| @@ -589,52 +573,51 @@ static int brcm_sr_sata_init(struct brcm_sata_port *port) · 1 unmodified line | ||
| 589 | 573 | (0x4 << OOB_CTRL1_BURST_MIN_SHIFT) | |
| 590 | 574 | (0x8 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT) | |
| 591 | 575 | (0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT)); |
| 592 | − brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val); | |
| 576 | + brcm_sata_phy_wr(port, OOB_REG_BANK, OOB_CTRL1, 0x0, val); | |
| 593 | 577 | val = ((0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT) | |
| 594 | 578 | (0x2 << OOB_CTRL2_BURST_CNT_SHIFT) | |
| 595 | 579 | (0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT)); |
| 596 | − brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val); | |
| 580 | + brcm_sata_phy_wr(port, OOB_REG_BANK, OOB_CTRL2, 0x0, val); | |
| 597 | 581 | |
| 598 | 582 | return 0; |
| 599 | 583 | } |
| 600 | 584 | |
| 601 | 585 | static int brcm_dsl_sata_init(struct brcm_sata_port *port) |
| 602 | 586 | { |
| 603 | − void __iomem *base = brcm_sata_pcb_base(port); | |
| 604 | 587 | struct device *dev = port->phy_priv->dev; |
| 605 | 588 | unsigned int try; |
| 606 | 589 | u32 tmp; |
| 607 | 590 | |
| 608 | − brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL7, 0, 0x873); | |
| 591 | + brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL7, 0, 0x873); | |
| 609 | 592 | |
| 610 | − brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0xc000); | |
| 593 | + brcm_sata_phy_wr(port, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0xc000); | |
| 611 | 594 | |
| 612 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, | |
| 595 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, | |
| 613 | 596 | 0, 0x3089); |
| 614 | 597 | usleep_range(1000, 2000); |
| 615 | 598 | |
| 616 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, | |
| 599 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_REG_BANK_0_PLLCONTROL_0, | |
| 617 | 600 | 0, 0x3088); |
| 618 | 601 | usleep_range(1000, 2000); |
| 619 | 602 | |
| 620 | − brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, AEQRX_SLCAL0_CTRL0, | |
| 603 | + brcm_sata_phy_wr(port, AEQRX_REG_BANK_1, AEQRX_SLCAL0_CTRL0, | |
| 621 | 604 | 0, 0x3000); |
| 622 | 605 | |
| 623 | − brcm_sata_phy_wr(base, AEQRX_REG_BANK_1, AEQRX_SLCAL1_CTRL0, | |
| 606 | + brcm_sata_phy_wr(port, AEQRX_REG_BANK_1, AEQRX_SLCAL1_CTRL0, | |
| 624 | 607 | 0, 0x3000); |
| 625 | 608 | usleep_range(1000, 2000); |
| 626 | 609 | |
| 627 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_CAP_CHARGE_TIME, 0, 0x32); | |
| 610 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_CAP_CHARGE_TIME, 0, 0x32); | |
| 628 | 611 | |
| 629 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_VCO_CAL_THRESH, 0, 0xa); | |
| 612 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_VCO_CAL_THRESH, 0, 0xa); | |
| 630 | 613 | |
| 631 | − brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_FREQ_DET_TIME, 0, 0x64); | |
| 614 | + brcm_sata_phy_wr(port, PLL_REG_BANK_0, PLL_FREQ_DET_TIME, 0, 0x64); | |
| 632 | 615 | usleep_range(1000, 2000); |
| 633 | 616 | |
| 634 | 617 | /* Acquire PLL lock */ |
| 635 | 618 | try = 50; |
| 636 | 619 | while (try) { |
| 637 | − tmp = brcm_sata_phy_rd(base, BLOCK0_REG_BANK, | |
| 620 | + tmp = brcm_sata_phy_rd(port, BLOCK0_REG_BANK, | |
| 638 | 621 | BLOCK0_XGXSSTATUS); |
| 639 | 622 | if (tmp & BLOCK0_XGXSSTATUS_PLL_LOCK) |
| 640 | 623 | break; |
| @@ -687,10 +670,9 @@ static int brcm_sata_phy_init(struct phy *phy) · 46 unmodified lines | ||
| 687 | 670 | |
| 688 | 671 | static void brcm_stb_sata_calibrate(struct brcm_sata_port *port) |
| 689 | 672 | { |
| 690 | − void __iomem *base = brcm_sata_pcb_base(port); | |
| 691 | 673 | u32 tmp = BIT(8); |
| 692 | 674 | |
| 693 | − brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1, | |
| 675 | + brcm_sata_phy_wr(port, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1, | |
| 694 | 676 | ~tmp, tmp); |
| 695 | 677 | } |
| 696 | 678 | |
| @@ -20,6 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #define PHY_MDM6600_PHY_DELAY_MS 4000 /* PHY enable 2.2s to 3.5s */ |
| 22 | 22 | #define PHY_MDM6600_ENABLED_DELAY_MS 8000 /* 8s more total for MDM6600 */ |
| 23 | +#define PHY_MDM6600_WAKE_KICK_MS 600 /* time on after GPIO toggle */ | |
| 23 | 24 | #define MDM6600_MODEM_IDLE_DELAY_MS 1000 /* modem after USB suspend */ |
| 24 | 25 | #define MDM6600_MODEM_WAKE_DELAY_MS 200 /* modem response after idle */ |
| 25 | 26 | |
| @@ -243,10 +244,24 @@ static irqreturn_t phy_mdm6600_wakeirq_thread(int irq, void *data) · 217 unmodified lines | ||
| 243 | 244 | { |
| 244 | 245 | struct phy_mdm6600 *ddata = data; |
| 245 | 246 | struct gpio_desc *mode_gpio1; |
| 247 | + int error, wakeup; | |
| 246 | 248 | |
| 247 | 249 | mode_gpio1 = ddata->mode_gpios->desc[PHY_MDM6600_MODE1]; |
| 248 | − dev_dbg(ddata->dev, "OOB wake on mode_gpio1: %i\n", | |
| 249 | − gpiod_get_value(mode_gpio1)); | |
| 250 | + wakeup = gpiod_get_value(mode_gpio1); | |
| 251 | + if (!wakeup) | |
| 252 | + return IRQ_NONE; | |
| 253 | + | |
| 254 | + dev_dbg(ddata->dev, "OOB wake on mode_gpio1: %i\n", wakeup); | |
| 255 | + error = pm_runtime_get_sync(ddata->dev); | |
| 256 | + if (error < 0) { | |
| 257 | + pm_runtime_put_noidle(ddata->dev); | |
| 258 | + | |
| 259 | + return IRQ_NONE; | |
| 260 | + } | |
| 261 | + | |
| 262 | + /* Just wake-up and kick the autosuspend timer */ | |
| 263 | + pm_runtime_mark_last_busy(ddata->dev); | |
| 264 | + pm_runtime_put_autosuspend(ddata->dev); | |
| 250 | 265 | |
| 251 | 266 | return IRQ_HANDLED; |
| 252 | 267 | } |
| @@ -496,8 +511,14 @@ static void phy_mdm6600_modem_wake(struct work_struct *work) · 243 unmodified lines | ||
| 496 | 511 | |
| 497 | 512 | ddata = container_of(work, struct phy_mdm6600, modem_wake_work.work); |
| 498 | 513 | phy_mdm6600_wake_modem(ddata); |
| 514 | + | |
| 515 | + /* | |
| 516 | + * The modem does not always stay awake 1.2 seconds after toggling | |
| 517 | + * the wake GPIO, and sometimes it idles after about some 600 ms | |
| 518 | + * making writes time out. | |
| 519 | + */ | |
| 499 | 520 | schedule_delayed_work(&ddata->modem_wake_work, |
| 500 | − msecs_to_jiffies(MDM6600_MODEM_IDLE_DELAY_MS)); | |
| 521 | + msecs_to_jiffies(PHY_MDM6600_WAKE_KICK_MS)); | |
| 501 | 522 | } |
| 502 | 523 | |
| 503 | 524 | static int __maybe_unused phy_mdm6600_runtime_suspend(struct device *dev) |
| @@ -688,11 +688,9 @@ struct phy *phy_get(struct device *dev, const char *string) · 687 unmodified lines | ||
| 688 | 688 | get_device(&phy->dev); |
| 689 | 689 | |
| 690 | 690 | link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); |
| 691 | − if (!link) { | |
| 692 | − dev_err(dev, "failed to create device link to %s\n", | |
| 691 | + if (!link) | |
| 692 | + dev_dbg(dev, "failed to create device link to %s\n", | |
| 693 | 693 | dev_name(phy->dev.parent)); |
| 694 | − return ERR_PTR(-EINVAL); | |
| 695 | − } | |
| 696 | 694 | |
| 697 | 695 | return phy; |
| 698 | 696 | } |
| @@ -803,11 +801,9 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np, · 104 unmodified lines | ||
| 803 | 801 | } |
| 804 | 802 | |
| 805 | 803 | link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); |
| 806 | − if (!link) { | |
| 807 | − dev_err(dev, "failed to create device link to %s\n", | |
| 804 | + if (!link) | |
| 805 | + dev_dbg(dev, "failed to create device link to %s\n", | |
| 808 | 806 | dev_name(phy->dev.parent)); |
| 809 | − return ERR_PTR(-EINVAL); | |
| 810 | − } | |
| 811 | 807 | |
| 812 | 808 | return phy; |
| 813 | 809 | } |
| @@ -852,11 +848,9 @@ struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np, · 38 unmodified lines | ||
| 852 | 848 | devres_add(dev, ptr); |
| 853 | 849 | |
| 854 | 850 | link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS); |
| 855 | − if (!link) { | |
| 856 | − dev_err(dev, "failed to create device link to %s\n", | |
| 851 | + if (!link) | |
| 852 | + dev_dbg(dev, "failed to create device link to %s\n", | |
| 857 | 853 | dev_name(phy->dev.parent)); |
| 858 | − return ERR_PTR(-EINVAL); | |
| 859 | − } | |
| 860 | 854 | |
| 861 | 855 | return phy; |
| 862 | 856 | } |
| @@ -80,20 +80,20 @@ static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode) · 79 unmodified lines | ||
| 80 | 80 | break; |
| 81 | 81 | |
| 82 | 82 | case PHY_INTERFACE_MODE_MII: |
| 83 | − mode = AM33XX_GMII_SEL_MODE_MII; | |
| 83 | + case PHY_INTERFACE_MODE_GMII: | |
| 84 | + gmii_sel_mode = AM33XX_GMII_SEL_MODE_MII; | |
| 84 | 85 | break; |
| 85 | 86 | |
| 86 | 87 | default: |
| 87 | − dev_warn(dev, | |
| 88 | − "port%u: unsupported mode: \"%s\". Defaulting to MII.\n", | |
| 89 | − if_phy->id, phy_modes(rgmii_id)); | |
| 88 | + dev_warn(dev, "port%u: unsupported mode: \"%s\"\n", | |
| 89 | + if_phy->id, phy_modes(submode)); | |
| 90 | 90 | return -EINVAL; |
| 91 | 91 | } |
| 92 | 92 | |
| 93 | 93 | if_phy->phy_if_mode = submode; |
| 94 | 94 | |
| 95 | 95 | dev_dbg(dev, "%s id:%u mode:%u rgmii_id:%d rmii_clk_ext:%d\n", |
| 96 | − __func__, if_phy->id, mode, rgmii_id, | |
| 96 | + __func__, if_phy->id, submode, rgmii_id, | |
| 97 | 97 | if_phy->rmii_clock_external); |
| 98 | 98 | |
| 99 | 99 | regfield = if_phy->fields[PHY_GMII_SEL_PORT_MODE]; |
| @@ -1073,13 +1073,26 @@ static int madera_pin_probe(struct platform_device *pdev) · 1072 unmodified lines | ||
| 1073 | 1073 | return ret; |
| 1074 | 1074 | } |
| 1075 | 1075 | |
| 1076 | + platform_set_drvdata(pdev, priv); | |
| 1077 | + | |
| 1076 | 1078 | dev_dbg(priv->dev, "pinctrl probed ok\n"); |
| 1077 | 1079 | |
| 1078 | 1080 | return 0; |
| 1079 | 1081 | } |
| 1080 | 1082 | |
| 1083 | +static int madera_pin_remove(struct platform_device *pdev) | |
| 1084 | +{ | |
| 1085 | + struct madera_pin_private *priv = platform_get_drvdata(pdev); | |
| 1086 | + | |
| 1087 | + if (priv->madera->pdata.gpio_configs) | |
| 1088 | + pinctrl_unregister_mappings(priv->madera->pdata.gpio_configs); | |
| 1089 | + | |
| 1090 | + return 0; | |
| 1091 | +} | |
| 1092 | + | |
| 1081 | 1093 | static struct platform_driver madera_pin_driver = { |
| 1082 | 1094 | .probe = madera_pin_probe, |
| 1095 | + .remove = madera_pin_remove, | |
| 1083 | 1096 | .driver = { |
| 1084 | 1097 | .name = "madera-pinctrl", |
| 1085 | 1098 | }, |
| @@ -2021,7 +2021,6 @@ static int pinctrl_claim_hogs(struct pinctrl_dev *pctldev) · 2020 unmodified lines | ||
| 2021 | 2021 | return PTR_ERR(pctldev->p); |
| 2022 | 2022 | } |
| 2023 | 2023 | |
| 2024 | − kref_get(&pctldev->p->users); | |
| 2025 | 2024 | pctldev->hog_default = |
| 2026 | 2025 | pinctrl_lookup_state(pctldev->p, PINCTRL_STATE_DEFAULT); |
| 2027 | 2026 | if (IS_ERR(pctldev->hog_default)) { |
| @@ -23,12 +23,12 @@ struct imx_sc_msg_req_pad_set { · 22 unmodified lines | ||
| 23 | 23 | struct imx_sc_rpc_msg hdr; |
| 24 | 24 | u32 val; |
| 25 | 25 | u16 pad; |
| 26 | −} __packed; | |
| 26 | +} __packed __aligned(4); | |
| 27 | 27 | |
| 28 | 28 | struct imx_sc_msg_req_pad_get { |
| 29 | 29 | struct imx_sc_rpc_msg hdr; |
| 30 | 30 | u16 pad; |
| 31 | −} __packed; | |
| 31 | +} __packed __aligned(4); | |
| 32 | 32 | |
| 33 | 33 | struct imx_sc_msg_resp_pad_get { |
| 34 | 34 | struct imx_sc_rpc_msg hdr; |
| @@ -147,8 +147,8 @@ static const unsigned int sdio_d0_pins[] = { GPIOX_0 }; · 146 unmodified lines | ||
| 147 | 147 | static const unsigned int sdio_d1_pins[] = { GPIOX_1 }; |
| 148 | 148 | static const unsigned int sdio_d2_pins[] = { GPIOX_2 }; |
| 149 | 149 | static const unsigned int sdio_d3_pins[] = { GPIOX_3 }; |
| 150 | −static const unsigned int sdio_cmd_pins[] = { GPIOX_4 }; | |
| 151 | −static const unsigned int sdio_clk_pins[] = { GPIOX_5 }; | |
| 150 | +static const unsigned int sdio_clk_pins[] = { GPIOX_4 }; | |
| 151 | +static const unsigned int sdio_cmd_pins[] = { GPIOX_5 }; | |
| 152 | 152 | static const unsigned int sdio_irq_pins[] = { GPIOX_7 }; |
| 153 | 153 | |
| 154 | 154 | static const unsigned int nand_ce0_pins[] = { BOOT_8 }; |
| @@ -451,7 +451,7 @@ static int pinctrl_falcon_probe(struct platform_device *pdev) · 450 unmodified lines | ||
| 451 | 451 | falcon_info.clk[*bank] = clk_get(&ppdev->dev, NULL); |
| 452 | 452 | if (IS_ERR(falcon_info.clk[*bank])) { |
| 453 | 453 | dev_err(&ppdev->dev, "failed to get clock\n"); |
| 454 | − of_node_put(np) | |
| 454 | + of_node_put(np); | |
| 455 | 455 | return PTR_ERR(falcon_info.clk[*bank]); |
| 456 | 456 | } |
| 457 | 457 | falcon_info.membase[*bank] = devm_ioremap_resource(&pdev->dev, |
| @@ -1104,7 +1104,6 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) · 1103 unmodified lines | ||
| 1104 | 1104 | pctrl->irq_chip.irq_mask = msm_gpio_irq_mask; |
| 1105 | 1105 | pctrl->irq_chip.irq_unmask = msm_gpio_irq_unmask; |
| 1106 | 1106 | pctrl->irq_chip.irq_ack = msm_gpio_irq_ack; |
| 1107 | − pctrl->irq_chip.irq_eoi = irq_chip_eoi_parent; | |
| 1108 | 1107 | pctrl->irq_chip.irq_set_type = msm_gpio_irq_set_type; |
| 1109 | 1108 | pctrl->irq_chip.irq_set_wake = msm_gpio_irq_set_wake; |
| 1110 | 1109 | pctrl->irq_chip.irq_request_resources = msm_gpio_irq_reqres; |
| @@ -1118,7 +1117,7 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) · 7 unmodified lines | ||
| 1118 | 1117 | if (!chip->irq.parent_domain) |
| 1119 | 1118 | return -EPROBE_DEFER; |
| 1120 | 1119 | chip->irq.child_to_parent_hwirq = msm_gpio_wakeirq; |
| 1121 | − | |
| 1120 | + pctrl->irq_chip.irq_eoi = irq_chip_eoi_parent; | |
| 1122 | 1121 | /* |
| 1123 | 1122 | * Let's skip handling the GPIOs, if the parent irqchip |
| 1124 | 1123 | * is handling the direct connect IRQ of the GPIO. |
| @@ -794,7 +794,7 @@ static int pm8xxx_gpio_probe(struct platform_device *pdev) · 793 unmodified lines | ||
| 794 | 794 | girq->fwnode = of_node_to_fwnode(pctrl->dev->of_node); |
| 795 | 795 | girq->parent_domain = parent_domain; |
| 796 | 796 | girq->child_to_parent_hwirq = pm8xxx_child_to_parent_hwirq; |
| 797 | − girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_fourcell; | |
| 797 | + girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell; | |
| 798 | 798 | girq->child_offset_to_irq = pm8xxx_child_offset_to_irq; |
| 799 | 799 | girq->child_irq_domain_ops.translate = pm8xxx_domain_translate; |
| 800 | 800 | |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | #include <linux/platform_data/wilco-ec.h> |
| 7 | 7 | #include <linux/string.h> |
| 8 | −#include <linux/unaligned/le_memmove.h> | |
| 8 | +#include <asm/unaligned.h> | |
| 9 | 9 | |
| 10 | 10 | /* Operation code; what the EC should do with the property */ |
| 11 | 11 | enum ec_property_op { |
| @@ -88,7 +88,7 @@ static int stm32_vrefbuf_disable(struct regulator_dev *rdev) · 87 unmodified lines | ||
| 88 | 88 | } |
| 89 | 89 | |
| 90 | 90 | val = readl_relaxed(priv->base + STM32_VREFBUF_CSR); |
| 91 | − val = (val & ~STM32_ENVR) | STM32_HIZ; | |
| 91 | + val &= ~STM32_ENVR; | |
| 92 | 92 | writel_relaxed(val, priv->base + STM32_VREFBUF_CSR); |
| 93 | 93 | |
| 94 | 94 | pm_runtime_mark_last_busy(priv->dev); |
| @@ -175,6 +175,7 @@ static const struct regulator_desc stm32_vrefbuf_regu = { · 80 unmodified lines | ||
| 175 | 175 | .volt_table = stm32_vrefbuf_voltages, |
| 176 | 176 | .n_voltages = ARRAY_SIZE(stm32_vrefbuf_voltages), |
| 177 | 177 | .ops = &stm32_vrefbuf_volt_ops, |
| 178 | + .off_on_delay = 1000, | |
| 178 | 179 | .type = REGULATOR_VOLTAGE, |
| 179 | 180 | .owner = THIS_MODULE, |
| 180 | 181 | }; |
| @@ -51,6 +51,7 @@ config RESET_BRCMSTB · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | config RESET_BRCMSTB_RESCAL |
| 53 | 53 | bool "Broadcom STB RESCAL reset controller" |
| 54 | + depends on HAS_IOMEM | |
| 54 | 55 | default ARCH_BRCMSTB || COMPILE_TEST |
| 55 | 56 | help |
| 56 | 57 | This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on |
| @@ -73,7 +74,7 @@ config RESET_IMX7 · 16 unmodified lines | ||
| 73 | 74 | |
| 74 | 75 | config RESET_INTEL_GW |
| 75 | 76 | bool "Intel Reset Controller Driver" |
| 76 | − depends on OF | |
| 77 | + depends on OF && HAS_IOMEM | |
| 77 | 78 | select REGMAP_MMIO |
| 78 | 79 | help |
| 79 | 80 | This enables the reset controller driver for Intel Gateway SoCs. |
| @@ -327,6 +327,7 @@ config RTC_DRV_MAX6900 · 326 unmodified lines | ||
| 327 | 327 | config RTC_DRV_MAX8907 |
| 328 | 328 | tristate "Maxim MAX8907" |
| 329 | 329 | depends on MFD_MAX8907 || COMPILE_TEST |
| 330 | + select REGMAP_IRQ | |
| 330 | 331 | help |
| 331 | 332 | If you say yes here you will get support for the |
| 332 | 333 | RTC of Maxim MAX8907 PMIC. |
| @@ -178,6 +178,8 @@ struct dasd_block *dasd_alloc_block(void) · 177 unmodified lines | ||
| 178 | 178 | (unsigned long) block); |
| 179 | 179 | INIT_LIST_HEAD(&block->ccw_queue); |
| 180 | 180 | spin_lock_init(&block->queue_lock); |
| 181 | + INIT_LIST_HEAD(&block->format_list); | |
| 182 | + spin_lock_init(&block->format_lock); | |
| 181 | 183 | timer_setup(&block->timer, dasd_block_timeout, 0); |
| 182 | 184 | spin_lock_init(&block->profile.lock); |
| 183 | 185 | |
| @@ -1779,20 +1781,26 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, · 1595 unmodified lines | ||
| 1779 | 1781 | |
| 1780 | 1782 | if (dasd_ese_needs_format(cqr->block, irb)) { |
| 1781 | 1783 | if (rq_data_dir((struct request *)cqr->callback_data) == READ) { |
| 1782 | − device->discipline->ese_read(cqr); | |
| 1784 | + device->discipline->ese_read(cqr, irb); | |
| 1783 | 1785 | cqr->status = DASD_CQR_SUCCESS; |
| 1784 | 1786 | cqr->stopclk = now; |
| 1785 | 1787 | dasd_device_clear_timer(device); |
| 1786 | 1788 | dasd_schedule_device_bh(device); |
| 1787 | 1789 | return; |
| 1788 | 1790 | } |
| 1789 | − fcqr = device->discipline->ese_format(device, cqr); | |
| 1791 | + fcqr = device->discipline->ese_format(device, cqr, irb); | |
| 1790 | 1792 | if (IS_ERR(fcqr)) { |
| 1793 | + if (PTR_ERR(fcqr) == -EINVAL) { | |
| 1794 | + cqr->status = DASD_CQR_ERROR; | |
| 1795 | + return; | |
| 1796 | + } | |
| 1791 | 1797 | /* |
| 1792 | 1798 | * If we can't format now, let the request go |
| 1793 | 1799 | * one extra round. Maybe we can format later. |
| 1794 | 1800 | */ |
| 1795 | 1801 | cqr->status = DASD_CQR_QUEUED; |
| 1802 | + dasd_schedule_device_bh(device); | |
| 1803 | + return; | |
| 1796 | 1804 | } else { |
| 1797 | 1805 | fcqr->status = DASD_CQR_QUEUED; |
| 1798 | 1806 | cqr->status = DASD_CQR_QUEUED; |
| @@ -2748,11 +2756,13 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) · 949 unmodified lines | ||
| 2748 | 2756 | { |
| 2749 | 2757 | struct request *req; |
| 2750 | 2758 | blk_status_t error = BLK_STS_OK; |
| 2759 | + unsigned int proc_bytes; | |
| 2751 | 2760 | int status; |
| 2752 | 2761 | |
| 2753 | 2762 | req = (struct request *) cqr->callback_data; |
| 2754 | 2763 | dasd_profile_end(cqr->block, cqr, req); |
| 2755 | 2764 | |
| 2765 | + proc_bytes = cqr->proc_bytes; | |
| 2756 | 2766 | status = cqr->block->base->discipline->free_cp(cqr, req); |
| 2757 | 2767 | if (status < 0) |
| 2758 | 2768 | error = errno_to_blk_status(status); |
| @@ -2783,7 +2793,18 @@ static void __dasd_cleanup_cqr(struct dasd_ccw_req *cqr) · 24 unmodified lines | ||
| 2783 | 2793 | blk_mq_end_request(req, error); |
| 2784 | 2794 | blk_mq_run_hw_queues(req->q, true); |
| 2785 | 2795 | } else { |
| 2786 | − blk_mq_complete_request(req); | |
| 2796 | + /* | |
| 2797 | + * Partial completed requests can happen with ESE devices. | |
| 2798 | + * During read we might have gotten a NRF error and have to | |
| 2799 | + * complete a request partially. | |
| 2800 | + */ | |
| 2801 | + if (proc_bytes) { | |
| 2802 | + blk_update_request(req, BLK_STS_OK, | |
| 2803 | + blk_rq_bytes(req) - proc_bytes); | |
| 2804 | + blk_mq_requeue_request(req, true); | |
| 2805 | + } else { | |
| 2806 | + blk_mq_complete_request(req); | |
| 2807 | + } | |
| 2787 | 2808 | } |
| 2788 | 2809 | } |
| 2789 | 2810 | |
| @@ -207,6 +207,45 @@ static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head) · 206 unmodified lines | ||
| 207 | 207 | geo->head |= head; |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | +/* | |
| 211 | + * calculate failing track from sense data depending if | |
| 212 | + * it is an EAV device or not | |
| 213 | + */ | |
| 214 | +static int dasd_eckd_track_from_irb(struct irb *irb, struct dasd_device *device, | |
| 215 | + sector_t *track) | |
| 216 | +{ | |
| 217 | + struct dasd_eckd_private *private = device->private; | |
| 218 | + u8 *sense = NULL; | |
| 219 | + u32 cyl; | |
| 220 | + u8 head; | |
| 221 | + | |
| 222 | + sense = dasd_get_sense(irb); | |
| 223 | + if (!sense) { | |
| 224 | + DBF_DEV_EVENT(DBF_WARNING, device, "%s", | |
| 225 | + "ESE error no sense data\n"); | |
| 226 | + return -EINVAL; | |
| 227 | + } | |
| 228 | + if (!(sense[27] & DASD_SENSE_BIT_2)) { | |
| 229 | + DBF_DEV_EVENT(DBF_WARNING, device, "%s", | |
| 230 | + "ESE error no valid track data\n"); | |
| 231 | + return -EINVAL; | |
| 232 | + } | |
| 233 | + | |
| 234 | + if (sense[27] & DASD_SENSE_BIT_3) { | |
| 235 | + /* enhanced addressing */ | |
| 236 | + cyl = sense[30] << 20; | |
| 237 | + cyl |= (sense[31] & 0xF0) << 12; | |
| 238 | + cyl |= sense[28] << 8; | |
| 239 | + cyl |= sense[29]; | |
| 240 | + } else { | |
| 241 | + cyl = sense[29] << 8; | |
| 242 | + cyl |= sense[30]; | |
| 243 | + } | |
| 244 | + head = sense[31] & 0x0F; | |
| 245 | + *track = cyl * private->rdc_data.trk_per_cyl + head; | |
| 246 | + return 0; | |
| 247 | +} | |
| 248 | + | |
| 210 | 249 | static int set_timestamp(struct ccw1 *ccw, struct DE_eckd_data *data, |
| 211 | 250 | struct dasd_device *device) |
| 212 | 251 | { |
| @@ -2986,6 +3025,37 @@ static int dasd_eckd_format_device(struct dasd_device *base, · 2773 unmodified lines | ||
| 2986 | 3025 | 0, NULL); |
| 2987 | 3026 | } |
| 2988 | 3027 | |
| 3028 | +static bool test_and_set_format_track(struct dasd_format_entry *to_format, | |
| 3029 | + struct dasd_block *block) | |
| 3030 | +{ | |
| 3031 | + struct dasd_format_entry *format; | |
| 3032 | + unsigned long flags; | |
| 3033 | + bool rc = false; | |
| 3034 | + | |
| 3035 | + spin_lock_irqsave(&block->format_lock, flags); | |
| 3036 | + list_for_each_entry(format, &block->format_list, list) { | |
| 3037 | + if (format->track == to_format->track) { | |
| 3038 | + rc = true; | |
| 3039 | + goto out; | |
| 3040 | + } | |
| 3041 | + } | |
| 3042 | + list_add_tail(&to_format->list, &block->format_list); | |
| 3043 | + | |
| 3044 | +out: | |
| 3045 | + spin_unlock_irqrestore(&block->format_lock, flags); | |
| 3046 | + return rc; | |
| 3047 | +} | |
| 3048 | + | |
| 3049 | +static void clear_format_track(struct dasd_format_entry *format, | |
| 3050 | + struct dasd_block *block) | |
| 3051 | +{ | |
| 3052 | + unsigned long flags; | |
| 3053 | + | |
| 3054 | + spin_lock_irqsave(&block->format_lock, flags); | |
| 3055 | + list_del_init(&format->list); | |
| 3056 | + spin_unlock_irqrestore(&block->format_lock, flags); | |
| 3057 | +} | |
| 3058 | + | |
| 2989 | 3059 | /* |
| 2990 | 3060 | * Callback function to free ESE format requests. |
| 2991 | 3061 | */ |
| @@ -2993,15 +3063,19 @@ static void dasd_eckd_ese_format_cb(struct dasd_ccw_req *cqr, void *data) · 1 unmodified line | ||
| 2993 | 3063 | { |
| 2994 | 3064 | struct dasd_device *device = cqr->startdev; |
| 2995 | 3065 | struct dasd_eckd_private *private = device->private; |
| 3066 | + struct dasd_format_entry *format = data; | |
| 2996 | 3067 | |
| 3068 | + clear_format_track(format, cqr->basedev->block); | |
| 2997 | 3069 | private->count--; |
| 2998 | 3070 | dasd_ffree_request(cqr, device); |
| 2999 | 3071 | } |
| 3000 | 3072 | |
| 3001 | 3073 | static struct dasd_ccw_req * |
| 3002 | −dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) | |
| 3074 | +dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr, | |
| 3075 | + struct irb *irb) | |
| 3003 | 3076 | { |
| 3004 | 3077 | struct dasd_eckd_private *private; |
| 3078 | + struct dasd_format_entry *format; | |
| 3005 | 3079 | struct format_data_t fdata; |
| 3006 | 3080 | unsigned int recs_per_trk; |
| 3007 | 3081 | struct dasd_ccw_req *fcqr; |
| @@ -3011,23 +3085,39 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) · 3 unmodified lines | ||
| 3011 | 3085 | struct request *req; |
| 3012 | 3086 | sector_t first_trk; |
| 3013 | 3087 | sector_t last_trk; |
| 3088 | + sector_t curr_trk; | |
| 3014 | 3089 | int rc; |
| 3015 | 3090 | |
| 3016 | 3091 | req = cqr->callback_data; |
| 3017 | − base = cqr->block->base; | |
| 3092 | + block = cqr->block; | |
| 3093 | + base = block->base; | |
| 3018 | 3094 | private = base->private; |
| 3019 | − block = base->block; | |
| 3020 | 3095 | blksize = block->bp_block; |
| 3021 | 3096 | recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); |
| 3097 | + format = &startdev->format_entry; | |
| 3022 | 3098 | |
| 3023 | 3099 | first_trk = blk_rq_pos(req) >> block->s2b_shift; |
| 3024 | 3100 | sector_div(first_trk, recs_per_trk); |
| 3025 | 3101 | last_trk = |
| 3026 | 3102 | (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; |
| 3027 | 3103 | sector_div(last_trk, recs_per_trk); |
| 3104 | + rc = dasd_eckd_track_from_irb(irb, base, &curr_trk); | |
| 3105 | + if (rc) | |
| 3106 | + return ERR_PTR(rc); | |
| 3028 | 3107 | |
| 3029 | − fdata.start_unit = first_trk; | |
| 3030 | − fdata.stop_unit = last_trk; | |
| 3108 | + if (curr_trk < first_trk || curr_trk > last_trk) { | |
| 3109 | + DBF_DEV_EVENT(DBF_WARNING, startdev, | |
| 3110 | + "ESE error track %llu not within range %llu - %llu\n", | |
| 3111 | + curr_trk, first_trk, last_trk); | |
| 3112 | + return ERR_PTR(-EINVAL); | |
| 3113 | + } | |
| 3114 | + format->track = curr_trk; | |
| 3115 | + /* test if track is already in formatting by another thread */ | |
| 3116 | + if (test_and_set_format_track(format, block)) | |
| 3117 | + return ERR_PTR(-EEXIST); | |
| 3118 | + | |
| 3119 | + fdata.start_unit = curr_trk; | |
| 3120 | + fdata.stop_unit = curr_trk; | |
| 3031 | 3121 | fdata.blksize = blksize; |
| 3032 | 3122 | fdata.intensity = private->uses_cdl ? DASD_FMT_INT_COMPAT : 0; |
| 3033 | 3123 | |
| @@ -3044,6 +3134,7 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) · 10 unmodified lines | ||
| 3044 | 3134 | return fcqr; |
| 3045 | 3135 | |
| 3046 | 3136 | fcqr->callback = dasd_eckd_ese_format_cb; |
| 3137 | + fcqr->callback_data = (void *) format; | |
| 3047 | 3138 | |
| 3048 | 3139 | return fcqr; |
| 3049 | 3140 | } |
| @@ -3051,29 +3142,87 @@ dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr) · 1 unmodified line | ||
| 3051 | 3142 | /* |
| 3052 | 3143 | * When data is read from an unformatted area of an ESE volume, this function |
| 3053 | 3144 | * returns zeroed data and thereby mimics a read of zero data. |
| 3145 | + * | |
| 3146 | + * The first unformatted track is the one that got the NRF error, the address is | |
| 3147 | + * encoded in the sense data. | |
| 3148 | + * | |
| 3149 | + * All tracks before have returned valid data and should not be touched. | |
| 3150 | + * All tracks after the unformatted track might be formatted or not. This is | |
| 3151 | + * currently not known, remember the processed data and return the remainder of | |
| 3152 | + * the request to the blocklayer in __dasd_cleanup_cqr(). | |
| 3054 | 3153 | */ |
| 3055 | −static void dasd_eckd_ese_read(struct dasd_ccw_req *cqr) | |
| 3154 | +static int dasd_eckd_ese_read(struct dasd_ccw_req *cqr, struct irb *irb) | |
| 3056 | 3155 | { |
| 3156 | + struct dasd_eckd_private *private; | |
| 3157 | + sector_t first_trk, last_trk; | |
| 3158 | + sector_t first_blk, last_blk; | |
| 3057 | 3159 | unsigned int blksize, off; |
| 3160 | + unsigned int recs_per_trk; | |
| 3058 | 3161 | struct dasd_device *base; |
| 3059 | 3162 | struct req_iterator iter; |
| 3163 | + struct dasd_block *block; | |
| 3164 | + unsigned int skip_block; | |
| 3165 | + unsigned int blk_count; | |
| 3060 | 3166 | struct request *req; |
| 3061 | 3167 | struct bio_vec bv; |
| 3168 | + sector_t curr_trk; | |
| 3169 | + sector_t end_blk; | |
| 3062 | 3170 | char *dst; |
| 3171 | + int rc; | |
| 3063 | 3172 | |
| 3064 | 3173 | req = (struct request *) cqr->callback_data; |
| 3065 | 3174 | base = cqr->block->base; |
| 3066 | 3175 | blksize = base->block->bp_block; |
| 3176 | + block = cqr->block; | |
| 3177 | + private = base->private; | |
| 3178 | + skip_block = 0; | |
| 3179 | + blk_count = 0; | |
| 3180 | + | |
| 3181 | + recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize); | |
| 3182 | + first_trk = first_blk = blk_rq_pos(req) >> block->s2b_shift; | |
| 3183 | + sector_div(first_trk, recs_per_trk); | |
| 3184 | + last_trk = last_blk = | |
| 3185 | + (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; | |
| 3186 | + sector_div(last_trk, recs_per_trk); | |
| 3187 | + rc = dasd_eckd_track_from_irb(irb, base, &curr_trk); | |
| 3188 | + if (rc) | |
| 3189 | + return rc; | |
| 3190 | + | |
| 3191 | + /* sanity check if the current track from sense data is valid */ | |
| 3192 | + if (curr_trk < first_trk || curr_trk > last_trk) { | |
| 3193 | + DBF_DEV_EVENT(DBF_WARNING, base, | |
| 3194 | + "ESE error track %llu not within range %llu - %llu\n", | |
| 3195 | + curr_trk, first_trk, last_trk); | |
| 3196 | + return -EINVAL; | |
| 3197 | + } | |
| 3198 | + | |
| 3199 | + /* | |
| 3200 | + * if not the first track got the NRF error we have to skip over valid | |
| 3201 | + * blocks | |
| 3202 | + */ | |
| 3203 | + if (curr_trk != first_trk) | |
| 3204 | + skip_block = curr_trk * recs_per_trk - first_blk; | |
| 3205 | + | |
| 3206 | + /* we have no information beyond the current track */ | |
| 3207 | + end_blk = (curr_trk + 1) * recs_per_trk; | |
| 3067 | 3208 | |
| 3068 | 3209 | rq_for_each_segment(bv, req, iter) { |
| 3069 | 3210 | dst = page_address(bv.bv_page) + bv.bv_offset; |
| 3070 | 3211 | for (off = 0; off < bv.bv_len; off += blksize) { |
| 3071 | − if (dst && rq_data_dir(req) == READ) { | |
| 3212 | + if (first_blk + blk_count >= end_blk) { | |
| 3213 | + cqr->proc_bytes = blk_count * blksize; | |
| 3214 | + return 0; | |
| 3215 | + } | |
| 3216 | + if (dst && !skip_block) { | |
| 3072 | 3217 | dst += off; |
| 3073 | 3218 | memset(dst, 0, blksize); |
| 3219 | + } else { | |
| 3220 | + skip_block--; | |
| 3074 | 3221 | } |
| 3222 | + blk_count++; | |
| 3075 | 3223 | } |
| 3076 | 3224 | } |
| 3225 | + return 0; | |
| 3077 | 3226 | } |
| 3078 | 3227 | |
| 3079 | 3228 | /* |
| @@ -187,6 +187,7 @@ struct dasd_ccw_req { · 186 unmodified lines | ||
| 187 | 187 | |
| 188 | 188 | void (*callback)(struct dasd_ccw_req *, void *data); |
| 189 | 189 | void *callback_data; |
| 190 | + unsigned int proc_bytes; /* bytes for partial completion */ | |
| 190 | 191 | }; |
| 191 | 192 | |
| 192 | 193 | /* |
| @@ -387,8 +388,9 @@ struct dasd_discipline { · 194 unmodified lines | ||
| 387 | 388 | int (*ext_pool_warn_thrshld)(struct dasd_device *); |
| 388 | 389 | int (*ext_pool_oos)(struct dasd_device *); |
| 389 | 390 | int (*ext_pool_exhaust)(struct dasd_device *, struct dasd_ccw_req *); |
| 390 | − struct dasd_ccw_req *(*ese_format)(struct dasd_device *, struct dasd_ccw_req *); | |
| 391 | − void (*ese_read)(struct dasd_ccw_req *); | |
| 391 | + struct dasd_ccw_req *(*ese_format)(struct dasd_device *, | |
| 392 | + struct dasd_ccw_req *, struct irb *); | |
| 393 | + int (*ese_read)(struct dasd_ccw_req *, struct irb *); | |
| 392 | 394 | }; |
| 393 | 395 | |
| 394 | 396 | extern struct dasd_discipline *dasd_diag_discipline_pointer; |
| @@ -474,6 +476,11 @@ struct dasd_profile { · 79 unmodified lines | ||
| 474 | 476 | spinlock_t lock; |
| 475 | 477 | }; |
| 476 | 478 | |
| 479 | +struct dasd_format_entry { | |
| 480 | + struct list_head list; | |
| 481 | + sector_t track; | |
| 482 | +}; | |
| 483 | + | |
| 477 | 484 | struct dasd_device { |
| 478 | 485 | /* Block device stuff. */ |
| 479 | 486 | struct dasd_block *block; |
| @@ -539,6 +546,7 @@ struct dasd_device { · 59 unmodified lines | ||
| 539 | 546 | struct dentry *debugfs_dentry; |
| 540 | 547 | struct dentry *hosts_dentry; |
| 541 | 548 | struct dasd_profile profile; |
| 549 | + struct dasd_format_entry format_entry; | |
| 542 | 550 | }; |
| 543 | 551 | |
| 544 | 552 | struct dasd_block { |
| @@ -564,6 +572,9 @@ struct dasd_block { · 19 unmodified lines | ||
| 564 | 572 | |
| 565 | 573 | struct dentry *debugfs_dentry; |
| 566 | 574 | struct dasd_profile profile; |
| 575 | + | |
| 576 | + struct list_head format_list; | |
| 577 | + spinlock_t format_lock; | |
| 567 | 578 | }; |
| 568 | 579 | |
| 569 | 580 | struct dasd_attention_data { |
| @@ -369,7 +369,7 @@ enum qeth_qdio_info_states { · 368 unmodified lines | ||
| 369 | 369 | struct qeth_buffer_pool_entry { |
| 370 | 370 | struct list_head list; |
| 371 | 371 | struct list_head init_list; |
| 372 | − void *elements[QDIO_MAX_ELEMENTS_PER_BUFFER]; | |
| 372 | + struct page *elements[QDIO_MAX_ELEMENTS_PER_BUFFER]; | |
| 373 | 373 | }; |
| 374 | 374 | |
| 375 | 375 | struct qeth_qdio_buffer_pool { |
| @@ -983,7 +983,7 @@ extern const struct attribute_group qeth_device_blkt_group; · 607 unmodified lines | ||
| 983 | 983 | extern const struct device_type qeth_generic_devtype; |
| 984 | 984 | |
| 985 | 985 | const char *qeth_get_cardname_short(struct qeth_card *); |
| 986 | −int qeth_realloc_buffer_pool(struct qeth_card *, int); | |
| 986 | +int qeth_resize_buffer_pool(struct qeth_card *card, unsigned int count); | |
| 987 | 987 | int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id); |
| 988 | 988 | void qeth_core_free_discipline(struct qeth_card *); |
| 989 | 989 | |
| @@ -65,7 +65,6 @@ static struct lock_class_key qdio_out_skb_queue_key; · 64 unmodified lines | ||
| 65 | 65 | static void qeth_issue_next_read_cb(struct qeth_card *card, |
| 66 | 66 | struct qeth_cmd_buffer *iob, |
| 67 | 67 | unsigned int data_length); |
| 68 | −static void qeth_free_buffer_pool(struct qeth_card *); | |
| 69 | 68 | static int qeth_qdio_establish(struct qeth_card *); |
| 70 | 69 | static void qeth_free_qdio_queues(struct qeth_card *card); |
| 71 | 70 | static void qeth_notify_skbs(struct qeth_qdio_out_q *queue, |
| @@ -212,49 +211,121 @@ void qeth_clear_working_pool_list(struct qeth_card *card) · 140 unmodified lines | ||
| 212 | 211 | } |
| 213 | 212 | EXPORT_SYMBOL_GPL(qeth_clear_working_pool_list); |
| 214 | 213 | |
| 214 | +static void qeth_free_pool_entry(struct qeth_buffer_pool_entry *entry) | |
| 215 | +{ | |
| 216 | + unsigned int i; | |
| 217 | + | |
| 218 | + for (i = 0; i < ARRAY_SIZE(entry->elements); i++) { | |
| 219 | + if (entry->elements[i]) | |
| 220 | + __free_page(entry->elements[i]); | |
| 221 | + } | |
| 222 | + | |
| 223 | + kfree(entry); | |
| 224 | +} | |
| 225 | + | |
| 226 | +static void qeth_free_buffer_pool(struct qeth_card *card) | |
| 227 | +{ | |
| 228 | + struct qeth_buffer_pool_entry *entry, *tmp; | |
| 229 | + | |
| 230 | + list_for_each_entry_safe(entry, tmp, &card->qdio.init_pool.entry_list, | |
| 231 | + init_list) { | |
| 232 | + list_del(&entry->init_list); | |
| 233 | + qeth_free_pool_entry(entry); | |
| 234 | + } | |
| 235 | +} | |
| 236 | + | |
| 237 | +static struct qeth_buffer_pool_entry *qeth_alloc_pool_entry(unsigned int pages) | |
| 238 | +{ | |
| 239 | + struct qeth_buffer_pool_entry *entry; | |
| 240 | + unsigned int i; | |
| 241 | + | |
| 242 | + entry = kzalloc(sizeof(*entry), GFP_KERNEL); | |
| 243 | + if (!entry) | |
| 244 | + return NULL; | |
| 245 | + | |
| 246 | + for (i = 0; i < pages; i++) { | |
| 247 | + entry->elements[i] = alloc_page(GFP_KERNEL); | |
| 248 | + | |
| 249 | + if (!entry->elements[i]) { | |
| 250 | + qeth_free_pool_entry(entry); | |
| 251 | + return NULL; | |
| 252 | + } | |
| 253 | + } | |
| 254 | + | |
| 255 | + return entry; | |
| 256 | +} | |
| 257 | + | |
| 215 | 258 | static int qeth_alloc_buffer_pool(struct qeth_card *card) |
| 216 | 259 | { |
| 217 | − struct qeth_buffer_pool_entry *pool_entry; | |
| 218 | − void *ptr; | |
| 219 | − int i, j; | |
| 260 | + unsigned int buf_elements = QETH_MAX_BUFFER_ELEMENTS(card); | |
| 261 | + unsigned int i; | |
| 220 | 262 | |
| 221 | 263 | QETH_CARD_TEXT(card, 5, "alocpool"); |
| 222 | 264 | for (i = 0; i < card->qdio.init_pool.buf_count; ++i) { |
| 223 | − pool_entry = kzalloc(sizeof(*pool_entry), GFP_KERNEL); | |
| 224 | − if (!pool_entry) { | |
| 265 | + struct qeth_buffer_pool_entry *entry; | |
| 266 | + | |
| 267 | + entry = qeth_alloc_pool_entry(buf_elements); | |
| 268 | + if (!entry) { | |
| 225 | 269 | qeth_free_buffer_pool(card); |
| 226 | 270 | return -ENOMEM; |
| 227 | 271 | } |
| 228 | − for (j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j) { | |
| 229 | − ptr = (void *) __get_free_page(GFP_KERNEL); | |
| 230 | − if (!ptr) { | |
| 231 | − while (j > 0) | |
| 232 | − free_page((unsigned long) | |
| 233 | − pool_entry->elements[--j]); | |
| 234 | − kfree(pool_entry); | |
| 235 | − qeth_free_buffer_pool(card); | |
| 236 | − return -ENOMEM; | |
| 237 | − } | |
| 238 | − pool_entry->elements[j] = ptr; | |
| 239 | − } | |
| 240 | − list_add(&pool_entry->init_list, | |
| 241 | − &card->qdio.init_pool.entry_list); | |
| 272 | + | |
| 273 | + list_add(&entry->init_list, &card->qdio.init_pool.entry_list); | |
| 242 | 274 | } |
| 243 | 275 | return 0; |
| 244 | 276 | } |
| 245 | 277 | |
| 246 | −int qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt) | |
| 278 | +int qeth_resize_buffer_pool(struct qeth_card *card, unsigned int count) | |
| 247 | 279 | { |
| 280 | + unsigned int buf_elements = QETH_MAX_BUFFER_ELEMENTS(card); | |
| 281 | + struct qeth_qdio_buffer_pool *pool = &card->qdio.init_pool; | |
| 282 | + struct qeth_buffer_pool_entry *entry, *tmp; | |
| 283 | + int delta = count - pool->buf_count; | |
| 284 | + LIST_HEAD(entries); | |
| 285 | + | |
| 248 | 286 | QETH_CARD_TEXT(card, 2, "realcbp"); |
| 249 | 287 | |
| 250 | − /* TODO: steel/add buffers from/to a running card's buffer pool (?) */ | |
| 251 | − qeth_clear_working_pool_list(card); | |
| 252 | − qeth_free_buffer_pool(card); | |
| 253 | − card->qdio.in_buf_pool.buf_count = bufcnt; | |
| 254 | − card->qdio.init_pool.buf_count = bufcnt; | |
| 255 | − return qeth_alloc_buffer_pool(card); | |
| 288 | + /* Defer until queue is allocated: */ | |
| 289 | + if (!card->qdio.in_q) | |
| 290 | + goto out; | |
| 291 | + | |
| 292 | + /* Remove entries from the pool: */ | |
| 293 | + while (delta < 0) { | |
| 294 | + entry = list_first_entry(&pool->entry_list, | |
| 295 | + struct qeth_buffer_pool_entry, | |
| 296 | + init_list); | |
| 297 | + list_del(&entry->init_list); | |
| 298 | + qeth_free_pool_entry(entry); | |
| 299 | + | |
| 300 | + delta++; | |
| 301 | + } | |
| 302 | + | |
| 303 | + /* Allocate additional entries: */ | |
| 304 | + while (delta > 0) { | |
| 305 | + entry = qeth_alloc_pool_entry(buf_elements); | |
| 306 | + if (!entry) { | |
| 307 | + list_for_each_entry_safe(entry, tmp, &entries, | |
| 308 | + init_list) { | |
| 309 | + list_del(&entry->init_list); | |
| 310 | + qeth_free_pool_entry(entry); | |
| 311 | + } | |
| 312 | + | |
| 313 | + return -ENOMEM; | |
| 314 | + } | |
| 315 | + | |
| 316 | + list_add(&entry->init_list, &entries); | |
| 317 | + | |
| 318 | + delta--; | |
| 319 | + } | |
| 320 | + | |
| 321 | + list_splice(&entries, &pool->entry_list); | |
| 322 | + | |
| 323 | +out: | |
| 324 | + card->qdio.in_buf_pool.buf_count = count; | |
| 325 | + pool->buf_count = count; | |
| 326 | + return 0; | |
| 256 | 327 | } |
| 257 | −EXPORT_SYMBOL_GPL(qeth_realloc_buffer_pool); | |
| 328 | +EXPORT_SYMBOL_GPL(qeth_resize_buffer_pool); | |
| 258 | 329 | |
| 259 | 330 | static void qeth_free_qdio_queue(struct qeth_qdio_q *q) |
| 260 | 331 | { |
| @@ -1170,19 +1241,6 @@ void qeth_drain_output_queues(struct qeth_card *card) · 909 unmodified lines | ||
| 1170 | 1241 | } |
| 1171 | 1242 | EXPORT_SYMBOL_GPL(qeth_drain_output_queues); |
| 1172 | 1243 | |
| 1173 | −static void qeth_free_buffer_pool(struct qeth_card *card) | |
| 1174 | −{ | |
| 1175 | − struct qeth_buffer_pool_entry *pool_entry, *tmp; | |
| 1176 | − int i = 0; | |
| 1177 | − list_for_each_entry_safe(pool_entry, tmp, | |
| 1178 | − &card->qdio.init_pool.entry_list, init_list){ | |
| 1179 | − for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) | |
| 1180 | − free_page((unsigned long)pool_entry->elements[i]); | |
| 1181 | − list_del(&pool_entry->init_list); | |
| 1182 | − kfree(pool_entry); | |
| 1183 | − } | |
| 1184 | −} | |
| 1185 | − | |
| 1186 | 1244 | static int qeth_osa_set_output_queues(struct qeth_card *card, bool single) |
| 1187 | 1245 | { |
| 1188 | 1246 | unsigned int count = single ? 1 : card->dev->num_tx_queues; |
| @@ -1204,7 +1262,6 @@ static int qeth_osa_set_output_queues(struct qeth_card *card, bool single) · 15 unmodified lines | ||
| 1204 | 1262 | if (count == 1) |
| 1205 | 1263 | dev_info(&card->gdev->dev, "Priority Queueing not supported\n"); |
| 1206 | 1264 | |
| 1207 | − card->qdio.default_out_queue = single ? 0 : QETH_DEFAULT_QUEUE; | |
| 1208 | 1265 | card->qdio.no_out_queues = count; |
| 1209 | 1266 | return 0; |
| 1210 | 1267 | } |
| @@ -2393,7 +2450,6 @@ static void qeth_free_qdio_queues(struct qeth_card *card) · 1182 unmodified lines | ||
| 2393 | 2450 | return; |
| 2394 | 2451 | |
| 2395 | 2452 | qeth_free_cq(card); |
| 2396 | − cancel_delayed_work_sync(&card->buffer_reclaim_work); | |
| 2397 | 2453 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j) { |
| 2398 | 2454 | if (card->qdio.in_q->bufs[j].rx_skb) |
| 2399 | 2455 | dev_kfree_skb_any(card->qdio.in_q->bufs[j].rx_skb); |
| @@ -2575,7 +2631,6 @@ static struct qeth_buffer_pool_entry *qeth_find_free_buffer_pool_entry( · 175 unmodified lines | ||
| 2575 | 2631 | struct list_head *plh; |
| 2576 | 2632 | struct qeth_buffer_pool_entry *entry; |
| 2577 | 2633 | int i, free; |
| 2578 | − struct page *page; | |
| 2579 | 2634 | |
| 2580 | 2635 | if (list_empty(&card->qdio.in_buf_pool.entry_list)) |
| 2581 | 2636 | return NULL; |
| @@ -2584,7 +2639,7 @@ static struct qeth_buffer_pool_entry *qeth_find_free_buffer_pool_entry( · 2 unmodified lines | ||
| 2584 | 2639 | entry = list_entry(plh, struct qeth_buffer_pool_entry, list); |
| 2585 | 2640 | free = 1; |
| 2586 | 2641 | for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) { |
| 2587 | − if (page_count(virt_to_page(entry->elements[i])) > 1) { | |
| 2642 | + if (page_count(entry->elements[i]) > 1) { | |
| 2588 | 2643 | free = 0; |
| 2589 | 2644 | break; |
| 2590 | 2645 | } |
| @@ -2599,15 +2654,15 @@ static struct qeth_buffer_pool_entry *qeth_find_free_buffer_pool_entry( · 8 unmodified lines | ||
| 2599 | 2654 | entry = list_entry(card->qdio.in_buf_pool.entry_list.next, |
| 2600 | 2655 | struct qeth_buffer_pool_entry, list); |
| 2601 | 2656 | for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) { |
| 2602 | − if (page_count(virt_to_page(entry->elements[i])) > 1) { | |
| 2603 | − page = alloc_page(GFP_ATOMIC); | |
| 2604 | − if (!page) { | |
| 2657 | + if (page_count(entry->elements[i]) > 1) { | |
| 2658 | + struct page *page = alloc_page(GFP_ATOMIC); | |
| 2659 | + | |
| 2660 | + if (!page) | |
| 2605 | 2661 | return NULL; |
| 2606 | − } else { | |
| 2607 | − free_page((unsigned long)entry->elements[i]); | |
| 2608 | − entry->elements[i] = page_address(page); | |
| 2609 | − QETH_CARD_STAT_INC(card, rx_sg_alloc_page); | |
| 2610 | − } | |
| 2662 | + | |
| 2663 | + __free_page(entry->elements[i]); | |
| 2664 | + entry->elements[i] = page; | |
| 2665 | + QETH_CARD_STAT_INC(card, rx_sg_alloc_page); | |
| 2611 | 2666 | } |
| 2612 | 2667 | } |
| 2613 | 2668 | list_del_init(&entry->list); |
| @@ -2625,12 +2680,12 @@ static int qeth_init_input_buffer(struct qeth_card *card, · 11 unmodified lines | ||
| 2625 | 2680 | ETH_HLEN + |
| 2626 | 2681 | sizeof(struct ipv6hdr)); |
| 2627 | 2682 | if (!buf->rx_skb) |
| 2628 | − return 1; | |
| 2683 | + return -ENOMEM; | |
| 2629 | 2684 | } |
| 2630 | 2685 | |
| 2631 | 2686 | pool_entry = qeth_find_free_buffer_pool_entry(card); |
| 2632 | 2687 | if (!pool_entry) |
| 2633 | − return 1; | |
| 2688 | + return -ENOBUFS; | |
| 2634 | 2689 | |
| 2635 | 2690 | /* |
| 2636 | 2691 | * since the buffer is accessed only from the input_tasklet |
| @@ -2643,7 +2698,7 @@ static int qeth_init_input_buffer(struct qeth_card *card, · 6 unmodified lines | ||
| 2643 | 2698 | for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) { |
| 2644 | 2699 | buf->buffer->element[i].length = PAGE_SIZE; |
| 2645 | 2700 | buf->buffer->element[i].addr = |
| 2646 | − virt_to_phys(pool_entry->elements[i]); | |
| 2701 | + page_to_phys(pool_entry->elements[i]); | |
| 2647 | 2702 | if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1) |
| 2648 | 2703 | buf->buffer->element[i].eflags = SBAL_EFLAGS_LAST_ENTRY; |
| 2649 | 2704 | else |
| @@ -2675,10 +2730,15 @@ static int qeth_init_qdio_queues(struct qeth_card *card) · 25 unmodified lines | ||
| 2675 | 2730 | /* inbound queue */ |
| 2676 | 2731 | qdio_reset_buffers(card->qdio.in_q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q); |
| 2677 | 2732 | memset(&card->rx, 0, sizeof(struct qeth_rx)); |
| 2733 | + | |
| 2678 | 2734 | qeth_initialize_working_pool_list(card); |
| 2679 | 2735 | /*give only as many buffers to hardware as we have buffer pool entries*/ |
| 2680 | − for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i) | |
| 2681 | − qeth_init_input_buffer(card, &card->qdio.in_q->bufs[i]); | |
| 2736 | + for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; i++) { | |
| 2737 | + rc = qeth_init_input_buffer(card, &card->qdio.in_q->bufs[i]); | |
| 2738 | + if (rc) | |
| 2739 | + return rc; | |
| 2740 | + } | |
| 2741 | + | |
| 2682 | 2742 | card->qdio.in_q->next_buf_to_init = |
| 2683 | 2743 | card->qdio.in_buf_pool.buf_count - 1; |
| 2684 | 2744 | rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, |
| @@ -247,8 +247,8 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev, · 246 unmodified lines | ||
| 247 | 247 | struct device_attribute *attr, const char *buf, size_t count) |
| 248 | 248 | { |
| 249 | 249 | struct qeth_card *card = dev_get_drvdata(dev); |
| 250 | + unsigned int cnt; | |
| 250 | 251 | char *tmp; |
| 251 | − int cnt, old_cnt; | |
| 252 | 252 | int rc = 0; |
| 253 | 253 | |
| 254 | 254 | mutex_lock(&card->conf_mutex); |
| @@ -257,13 +257,12 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev, · 2 unmodified lines | ||
| 257 | 257 | goto out; |
| 258 | 258 | } |
| 259 | 259 | |
| 260 | − old_cnt = card->qdio.in_buf_pool.buf_count; | |
| 261 | 260 | cnt = simple_strtoul(buf, &tmp, 10); |
| 262 | 261 | cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN : |
| 263 | 262 | ((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt); |
| 264 | − if (old_cnt != cnt) { | |
| 265 | − rc = qeth_realloc_buffer_pool(card, cnt); | |
| 266 | − } | |
| 263 | + | |
| 264 | + rc = qeth_resize_buffer_pool(card, cnt); | |
| 265 | + | |
| 267 | 266 | out: |
| 268 | 267 | mutex_unlock(&card->conf_mutex); |
| 269 | 268 | return rc ? rc : count; |
| @@ -284,6 +284,7 @@ static void qeth_l2_stop_card(struct qeth_card *card) · 283 unmodified lines | ||
| 284 | 284 | if (card->state == CARD_STATE_SOFTSETUP) { |
| 285 | 285 | qeth_clear_ipacmd_list(card); |
| 286 | 286 | qeth_drain_output_queues(card); |
| 287 | + cancel_delayed_work_sync(&card->buffer_reclaim_work); | |
| 287 | 288 | card->state = CARD_STATE_DOWN; |
| 288 | 289 | } |
| 289 | 290 | |
| @@ -1178,6 +1178,7 @@ static void qeth_l3_stop_card(struct qeth_card *card) · 1177 unmodified lines | ||
| 1178 | 1178 | qeth_l3_clear_ip_htable(card, 1); |
| 1179 | 1179 | qeth_clear_ipacmd_list(card); |
| 1180 | 1180 | qeth_drain_output_queues(card); |
| 1181 | + cancel_delayed_work_sync(&card->buffer_reclaim_work); | |
| 1181 | 1182 | card->state = CARD_STATE_DOWN; |
| 1182 | 1183 | } |
| 1183 | 1184 | |
| @@ -206,12 +206,11 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev, · 205 unmodified lines | ||
| 206 | 206 | qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd); |
| 207 | 207 | if (card->ssqd.qdioac2 & CHSC_AC2_SNIFFER_AVAILABLE) { |
| 208 | 208 | card->options.sniffer = i; |
| 209 | − if (card->qdio.init_pool.buf_count != | |
| 210 | − QETH_IN_BUF_COUNT_MAX) | |
| 211 | − qeth_realloc_buffer_pool(card, | |
| 212 | − QETH_IN_BUF_COUNT_MAX); | |
| 213 | − } else | |
| 209 | + qeth_resize_buffer_pool(card, QETH_IN_BUF_COUNT_MAX); | |
| 210 | + } else { | |
| 214 | 211 | rc = -EPERM; |
| 212 | + } | |
| 213 | + | |
| 215 | 214 | break; |
| 216 | 215 | default: |
| 217 | 216 | rc = -EINVAL; |
| @@ -410,7 +410,7 @@ struct fsf_qtcb_bottom_port { · 409 unmodified lines | ||
| 410 | 410 | u8 cb_util; |
| 411 | 411 | u8 a_util; |
| 412 | 412 | u8 res2; |
| 413 | − u16 temperature; | |
| 413 | + s16 temperature; | |
| 414 | 414 | u16 vcc; |
| 415 | 415 | u16 tx_bias; |
| 416 | 416 | u16 tx_power; |
| @@ -800,7 +800,7 @@ static ZFCP_DEV_ATTR(adapter_diag, b2b_credit, 0400, · 799 unmodified lines | ||
| 800 | 800 | static ZFCP_DEV_ATTR(adapter_diag_sfp, _name, 0400, \ |
| 801 | 801 | zfcp_sysfs_adapter_diag_sfp_##_name##_show, NULL) |
| 802 | 802 | |
| 803 | −ZFCP_DEFINE_DIAG_SFP_ATTR(temperature, temperature, 5, "%hu"); | |
| 803 | +ZFCP_DEFINE_DIAG_SFP_ATTR(temperature, temperature, 6, "%hd"); | |
| 804 | 804 | ZFCP_DEFINE_DIAG_SFP_ATTR(vcc, vcc, 5, "%hu"); |
| 805 | 805 | ZFCP_DEFINE_DIAG_SFP_ATTR(tx_bias, tx_bias, 5, "%hu"); |
| 806 | 806 | ZFCP_DEFINE_DIAG_SFP_ATTR(tx_power, tx_power, 5, "%hu"); |
| @@ -9950,6 +9950,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, · 9949 unmodified lines | ||
| 9950 | 9950 | ioa_cfg->max_devs_supported = ipr_max_devs; |
| 9951 | 9951 | |
| 9952 | 9952 | if (ioa_cfg->sis64) { |
| 9953 | + host->max_channel = IPR_MAX_SIS64_BUSES; | |
| 9953 | 9954 | host->max_id = IPR_MAX_SIS64_TARGETS_PER_BUS; |
| 9954 | 9955 | host->max_lun = IPR_MAX_SIS64_LUNS_PER_TARGET; |
| 9955 | 9956 | if (ipr_max_devs > IPR_MAX_SIS64_DEVS) |
| @@ -9958,6 +9959,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, · 2 unmodified lines | ||
| 9958 | 9959 | + ((sizeof(struct ipr_config_table_entry64) |
| 9959 | 9960 | * ioa_cfg->max_devs_supported))); |
| 9960 | 9961 | } else { |
| 9962 | + host->max_channel = IPR_VSET_BUS; | |
| 9961 | 9963 | host->max_id = IPR_MAX_NUM_TARGETS_PER_BUS; |
| 9962 | 9964 | host->max_lun = IPR_MAX_NUM_LUNS_PER_TARGET; |
| 9963 | 9965 | if (ipr_max_devs > IPR_MAX_PHYSICAL_DEVS) |
| @@ -9967,7 +9969,6 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, · 3 unmodified lines | ||
| 9967 | 9969 | * ioa_cfg->max_devs_supported))); |
| 9968 | 9970 | } |
| 9969 | 9971 | |
| 9970 | − host->max_channel = IPR_VSET_BUS; | |
| 9971 | 9972 | host->unique_id = host->host_no; |
| 9972 | 9973 | host->max_cmd_len = IPR_MAX_CDB_LEN; |
| 9973 | 9974 | host->can_queue = ioa_cfg->max_cmds; |
| @@ -1300,6 +1300,7 @@ struct ipr_resource_entry { · 1299 unmodified lines | ||
| 1300 | 1300 | #define IPR_ARRAY_VIRTUAL_BUS 0x1 |
| 1301 | 1301 | #define IPR_VSET_VIRTUAL_BUS 0x2 |
| 1302 | 1302 | #define IPR_IOAFP_VIRTUAL_BUS 0x3 |
| 1303 | +#define IPR_MAX_SIS64_BUSES 0x4 | |
| 1303 | 1304 | |
| 1304 | 1305 | #define IPR_GET_RES_PHYS_LOC(res) \ |
| 1305 | 1306 | (((res)->bus << 24) | ((res)->target << 8) | (res)->lun) |
| @@ -628,6 +628,8 @@ redisc: · 627 unmodified lines | ||
| 628 | 628 | } |
| 629 | 629 | out: |
| 630 | 630 | kref_put(&rdata->kref, fc_rport_destroy); |
| 631 | + if (!IS_ERR(fp)) | |
| 632 | + fc_frame_free(fp); | |
| 631 | 633 | } |
| 632 | 634 | |
| 633 | 635 | /** |
| @@ -161,6 +161,7 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, · 160 unmodified lines | ||
| 161 | 161 | unsigned int nr_zones, report_zones_cb cb, void *data) |
| 162 | 162 | { |
| 163 | 163 | struct scsi_disk *sdkp = scsi_disk(disk); |
| 164 | + sector_t capacity = logical_to_sectors(sdkp->device, sdkp->capacity); | |
| 164 | 165 | unsigned int nr, i; |
| 165 | 166 | unsigned char *buf; |
| 166 | 167 | size_t offset, buflen = 0; |
| @@ -171,11 +172,15 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector, · 4 unmodified lines | ||
| 171 | 172 | /* Not a zoned device */ |
| 172 | 173 | return -EOPNOTSUPP; |
| 173 | 174 | |
| 175 | + if (!capacity) | |
| 176 | + /* Device gone or invalid */ | |
| 177 | + return -ENODEV; | |
| 178 | + | |
| 174 | 179 | buf = sd_zbc_alloc_report_buffer(sdkp, nr_zones, &buflen); |
| 175 | 180 | if (!buf) |
| 176 | 181 | return -ENOMEM; |
| 177 | 182 | |
| 178 | − while (zone_idx < nr_zones && sector < get_capacity(disk)) { | |
| 183 | + while (zone_idx < nr_zones && sector < capacity) { | |
| 179 | 184 | ret = sd_zbc_do_report_zones(sdkp, buf, buflen, |
| 180 | 185 | sectors_to_logical(sdkp->device, sector), true); |
| 181 | 186 | if (ret) |
| @@ -688,7 +688,7 @@ static const struct block_device_operations sr_bdops = · 687 unmodified lines | ||
| 688 | 688 | .release = sr_block_release, |
| 689 | 689 | .ioctl = sr_block_ioctl, |
| 690 | 690 | #ifdef CONFIG_COMPAT |
| 691 | − .ioctl = sr_block_compat_ioctl, | |
| 691 | + .compat_ioctl = sr_block_compat_ioctl, | |
| 692 | 692 | #endif |
| 693 | 693 | .check_events = sr_block_check_events, |
| 694 | 694 | .revalidate_disk = sr_block_revalidate_disk, |
| @@ -3884,18 +3884,25 @@ EXPORT_SYMBOL_GPL(ufshcd_uic_hibern8_exit); · 3883 unmodified lines | ||
| 3884 | 3884 | void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) |
| 3885 | 3885 | { |
| 3886 | 3886 | unsigned long flags; |
| 3887 | + bool update = false; | |
| 3887 | 3888 | |
| 3888 | − if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT)) | |
| 3889 | + if (!ufshcd_is_auto_hibern8_supported(hba)) | |
| 3889 | 3890 | return; |
| 3890 | 3891 | |
| 3891 | 3892 | spin_lock_irqsave(hba->host->host_lock, flags); |
| 3892 | − if (hba->ahit == ahit) | |
| 3893 | − goto out_unlock; | |
| 3894 | − hba->ahit = ahit; | |
| 3895 | − if (!pm_runtime_suspended(hba->dev)) | |
| 3896 | − ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER); | |
| 3897 | −out_unlock: | |
| 3893 | + if (hba->ahit != ahit) { | |
| 3894 | + hba->ahit = ahit; | |
| 3895 | + update = true; | |
| 3896 | + } | |
| 3898 | 3897 | spin_unlock_irqrestore(hba->host->host_lock, flags); |
| 3898 | + | |
| 3899 | + if (update && !pm_runtime_suspended(hba->dev)) { | |
| 3900 | + pm_runtime_get_sync(hba->dev); | |
| 3901 | + ufshcd_hold(hba, false); | |
| 3902 | + ufshcd_auto_hibern8_enable(hba); | |
| 3903 | + ufshcd_release(hba); | |
| 3904 | + pm_runtime_put(hba->dev); | |
| 3905 | + } | |
| 3899 | 3906 | } |
| 3900 | 3907 | EXPORT_SYMBOL_GPL(ufshcd_auto_hibern8_update); |
| 3901 | 3908 | |
| @@ -1320,6 +1320,9 @@ static const struct of_device_id qcom_slim_ngd_dt_match[] = { · 1319 unmodified lines | ||
| 1320 | 1320 | { |
| 1321 | 1321 | .compatible = "qcom,slim-ngd-v1.5.0", |
| 1322 | 1322 | .data = &ngd_v1_5_offset_info, |
| 1323 | + },{ | |
| 1324 | + .compatible = "qcom,slim-ngd-v2.1.0", | |
| 1325 | + .data = &ngd_v1_5_offset_info, | |
| 1323 | 1326 | }, |
| 1324 | 1327 | {} |
| 1325 | 1328 | }; |
| @@ -25,7 +25,7 @@ struct imx_sc_msg_misc_get_soc_id { · 24 unmodified lines | ||
| 25 | 25 | u32 id; |
| 26 | 26 | } resp; |
| 27 | 27 | } data; |
| 28 | −} __packed; | |
| 28 | +} __packed __aligned(4); | |
| 29 | 29 | |
| 30 | 30 | struct imx_sc_msg_misc_get_soc_uid { |
| 31 | 31 | struct imx_sc_rpc_msg hdr; |
| @@ -149,6 +149,7 @@ struct atmel_qspi { · 148 unmodified lines | ||
| 149 | 149 | struct clk *qspick; |
| 150 | 150 | struct platform_device *pdev; |
| 151 | 151 | const struct atmel_qspi_caps *caps; |
| 152 | + resource_size_t mmap_size; | |
| 152 | 153 | u32 pending; |
| 153 | 154 | u32 mr; |
| 154 | 155 | u32 scr; |
| @@ -329,6 +330,14 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) · 174 unmodified lines | ||
| 329 | 330 | u32 sr, offset; |
| 330 | 331 | int err; |
| 331 | 332 | |
| 333 | + /* | |
| 334 | + * Check if the address exceeds the MMIO window size. An improvement | |
| 335 | + * would be to add support for regular SPI mode and fall back to it | |
| 336 | + * when the flash memories overrun the controller's memory space. | |
| 337 | + */ | |
| 338 | + if (op->addr.val + op->data.nbytes > aq->mmap_size) | |
| 339 | + return -ENOTSUPP; | |
| 340 | + | |
| 332 | 341 | err = atmel_qspi_set_cfg(aq, op, &offset); |
| 333 | 342 | if (err) |
| 334 | 343 | return err; |
| @@ -480,6 +489,8 @@ static int atmel_qspi_probe(struct platform_device *pdev) · 145 unmodified lines | ||
| 480 | 489 | goto exit; |
| 481 | 490 | } |
| 482 | 491 | |
| 492 | + aq->mmap_size = resource_size(res); | |
| 493 | + | |
| 483 | 494 | /* Get the peripheral clock */ |
| 484 | 495 | aq->pclk = devm_clk_get(&pdev->dev, "pclk"); |
| 485 | 496 | if (IS_ERR(aq->pclk)) |
| @@ -366,7 +366,6 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev) · 365 unmodified lines | ||
| 366 | 366 | goto out_disable_clk; |
| 367 | 367 | |
| 368 | 368 | rate = clk_get_rate(pll_clk); |
| 369 | − clk_disable_unprepare(pll_clk); | |
| 370 | 369 | if (!rate) { |
| 371 | 370 | ret = -EINVAL; |
| 372 | 371 | goto out_disable_pll_clk; |
| @@ -130,6 +130,7 @@ struct omap2_mcspi { · 129 unmodified lines | ||
| 130 | 130 | int fifo_depth; |
| 131 | 131 | bool slave_aborted; |
| 132 | 132 | unsigned int pin_dir:1; |
| 133 | + size_t max_xfer_len; | |
| 133 | 134 | }; |
| 134 | 135 | |
| 135 | 136 | struct omap2_mcspi_cs { |
| @@ -974,20 +975,12 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, · 838 unmodified lines | ||
| 974 | 975 | * Note that we currently allow DMA only if we get a channel |
| 975 | 976 | * for both rx and tx. Otherwise we'll do PIO for both rx and tx. |
| 976 | 977 | */ |
| 977 | −static int omap2_mcspi_request_dma(struct spi_device *spi) | |
| 978 | +static int omap2_mcspi_request_dma(struct omap2_mcspi *mcspi, | |
| 979 | + struct omap2_mcspi_dma *mcspi_dma) | |
| 978 | 980 | { |
| 979 | − struct spi_master *master = spi->master; | |
| 980 | − struct omap2_mcspi *mcspi; | |
| 981 | − struct omap2_mcspi_dma *mcspi_dma; | |
| 982 | 981 | int ret = 0; |
| 983 | 982 | |
| 984 | − mcspi = spi_master_get_devdata(master); | |
| 985 | − mcspi_dma = mcspi->dma_channels + spi->chip_select; | |
| 986 | − | |
| 987 | − init_completion(&mcspi_dma->dma_rx_completion); | |
| 988 | − init_completion(&mcspi_dma->dma_tx_completion); | |
| 989 | − | |
| 990 | − mcspi_dma->dma_rx = dma_request_chan(&master->dev, | |
| 983 | + mcspi_dma->dma_rx = dma_request_chan(mcspi->dev, | |
| 991 | 984 | mcspi_dma->dma_rx_ch_name); |
| 992 | 985 | if (IS_ERR(mcspi_dma->dma_rx)) { |
| 993 | 986 | ret = PTR_ERR(mcspi_dma->dma_rx); |
| @@ -995,7 +988,7 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) · 1 unmodified line | ||
| 995 | 988 | goto no_dma; |
| 996 | 989 | } |
| 997 | 990 | |
| 998 | − mcspi_dma->dma_tx = dma_request_chan(&master->dev, | |
| 991 | + mcspi_dma->dma_tx = dma_request_chan(mcspi->dev, | |
| 999 | 992 | mcspi_dma->dma_tx_ch_name); |
| 1000 | 993 | if (IS_ERR(mcspi_dma->dma_tx)) { |
| 1001 | 994 | ret = PTR_ERR(mcspi_dma->dma_tx); |
| @@ -1004,20 +997,40 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) · 2 unmodified lines | ||
| 1004 | 997 | mcspi_dma->dma_rx = NULL; |
| 1005 | 998 | } |
| 1006 | 999 | |
| 1000 | + init_completion(&mcspi_dma->dma_rx_completion); | |
| 1001 | + init_completion(&mcspi_dma->dma_tx_completion); | |
| 1002 | + | |
| 1007 | 1003 | no_dma: |
| 1008 | 1004 | return ret; |
| 1009 | 1005 | } |
| 1010 | 1006 | |
| 1007 | +static void omap2_mcspi_release_dma(struct spi_master *master) | |
| 1008 | +{ | |
| 1009 | + struct omap2_mcspi *mcspi = spi_master_get_devdata(master); | |
| 1010 | + struct omap2_mcspi_dma *mcspi_dma; | |
| 1011 | + int i; | |
| 1012 | + | |
| 1013 | + for (i = 0; i < master->num_chipselect; i++) { | |
| 1014 | + mcspi_dma = &mcspi->dma_channels[i]; | |
| 1015 | + | |
| 1016 | + if (mcspi_dma->dma_rx) { | |
| 1017 | + dma_release_channel(mcspi_dma->dma_rx); | |
| 1018 | + mcspi_dma->dma_rx = NULL; | |
| 1019 | + } | |
| 1020 | + if (mcspi_dma->dma_tx) { | |
| 1021 | + dma_release_channel(mcspi_dma->dma_tx); | |
| 1022 | + mcspi_dma->dma_tx = NULL; | |
| 1023 | + } | |
| 1024 | + } | |
| 1025 | +} | |
| 1026 | + | |
| 1011 | 1027 | static int omap2_mcspi_setup(struct spi_device *spi) |
| 1012 | 1028 | { |
| 1013 | 1029 | int ret; |
| 1014 | 1030 | struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); |
| 1015 | 1031 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; |
| 1016 | − struct omap2_mcspi_dma *mcspi_dma; | |
| 1017 | 1032 | struct omap2_mcspi_cs *cs = spi->controller_state; |
| 1018 | 1033 | |
| 1019 | − mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | |
| 1020 | − | |
| 1021 | 1034 | if (!cs) { |
| 1022 | 1035 | cs = kzalloc(sizeof *cs, GFP_KERNEL); |
| 1023 | 1036 | if (!cs) |
| @@ -1042,13 +1055,6 @@ static int omap2_mcspi_setup(struct spi_device *spi) · 18 unmodified lines | ||
| 1042 | 1055 | } |
| 1043 | 1056 | } |
| 1044 | 1057 | |
| 1045 | − if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) { | |
| 1046 | − ret = omap2_mcspi_request_dma(spi); | |
| 1047 | − if (ret) | |
| 1048 | − dev_warn(&spi->dev, "not using DMA for McSPI (%d)\n", | |
| 1049 | − ret); | |
| 1050 | − } | |
| 1051 | − | |
| 1052 | 1058 | ret = pm_runtime_get_sync(mcspi->dev); |
| 1053 | 1059 | if (ret < 0) { |
| 1054 | 1060 | pm_runtime_put_noidle(mcspi->dev); |
| @@ -1065,12 +1071,8 @@ static int omap2_mcspi_setup(struct spi_device *spi) · 10 unmodified lines | ||
| 1065 | 1071 | |
| 1066 | 1072 | static void omap2_mcspi_cleanup(struct spi_device *spi) |
| 1067 | 1073 | { |
| 1068 | − struct omap2_mcspi *mcspi; | |
| 1069 | − struct omap2_mcspi_dma *mcspi_dma; | |
| 1070 | 1074 | struct omap2_mcspi_cs *cs; |
| 1071 | 1075 | |
| 1072 | − mcspi = spi_master_get_devdata(spi->master); | |
| 1073 | − | |
| 1074 | 1076 | if (spi->controller_state) { |
| 1075 | 1077 | /* Unlink controller state from context save list */ |
| 1076 | 1078 | cs = spi->controller_state; |
| @@ -1079,19 +1081,6 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) · 2 unmodified lines | ||
| 1079 | 1081 | kfree(cs); |
| 1080 | 1082 | } |
| 1081 | 1083 | |
| 1082 | − if (spi->chip_select < spi->master->num_chipselect) { | |
| 1083 | − mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | |
| 1084 | − | |
| 1085 | − if (mcspi_dma->dma_rx) { | |
| 1086 | − dma_release_channel(mcspi_dma->dma_rx); | |
| 1087 | − mcspi_dma->dma_rx = NULL; | |
| 1088 | − } | |
| 1089 | − if (mcspi_dma->dma_tx) { | |
| 1090 | − dma_release_channel(mcspi_dma->dma_tx); | |
| 1091 | − mcspi_dma->dma_tx = NULL; | |
| 1092 | − } | |
| 1093 | − } | |
| 1094 | − | |
| 1095 | 1084 | if (gpio_is_valid(spi->cs_gpio)) |
| 1096 | 1085 | gpio_free(spi->cs_gpio); |
| 1097 | 1086 | } |
| @@ -1302,9 +1291,24 @@ static bool omap2_mcspi_can_dma(struct spi_master *master, · 204 unmodified lines | ||
| 1302 | 1291 | if (spi_controller_is_slave(master)) |
| 1303 | 1292 | return true; |
| 1304 | 1293 | |
| 1294 | + master->dma_rx = mcspi_dma->dma_rx; | |
| 1295 | + master->dma_tx = mcspi_dma->dma_tx; | |
| 1296 | + | |
| 1305 | 1297 | return (xfer->len >= DMA_MIN_BYTES); |
| 1306 | 1298 | } |
| 1307 | 1299 | |
| 1300 | +static size_t omap2_mcspi_max_xfer_size(struct spi_device *spi) | |
| 1301 | +{ | |
| 1302 | + struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); | |
| 1303 | + struct omap2_mcspi_dma *mcspi_dma = | |
| 1304 | + &mcspi->dma_channels[spi->chip_select]; | |
| 1305 | + | |
| 1306 | + if (mcspi->max_xfer_len && mcspi_dma->dma_rx) | |
| 1307 | + return mcspi->max_xfer_len; | |
| 1308 | + | |
| 1309 | + return SIZE_MAX; | |
| 1310 | +} | |
| 1311 | + | |
| 1308 | 1312 | static int omap2_mcspi_controller_setup(struct omap2_mcspi *mcspi) |
| 1309 | 1313 | { |
| 1310 | 1314 | struct spi_master *master = mcspi->master; |
| @@ -1373,6 +1377,11 @@ static struct omap2_mcspi_platform_config omap4_pdata = { · 62 unmodified lines | ||
| 1373 | 1377 | .regs_offset = OMAP4_MCSPI_REG_OFFSET, |
| 1374 | 1378 | }; |
| 1375 | 1379 | |
| 1380 | +static struct omap2_mcspi_platform_config am654_pdata = { | |
| 1381 | + .regs_offset = OMAP4_MCSPI_REG_OFFSET, | |
| 1382 | + .max_xfer_len = SZ_4K - 1, | |
| 1383 | +}; | |
| 1384 | + | |
| 1376 | 1385 | static const struct of_device_id omap_mcspi_of_match[] = { |
| 1377 | 1386 | { |
| 1378 | 1387 | .compatible = "ti,omap2-mcspi", |
| @@ -1382,6 +1391,10 @@ static const struct of_device_id omap_mcspi_of_match[] = { · 3 unmodified lines | ||
| 1382 | 1391 | .compatible = "ti,omap4-mcspi", |
| 1383 | 1392 | .data = &omap4_pdata, |
| 1384 | 1393 | }, |
| 1394 | + { | |
| 1395 | + .compatible = "ti,am654-mcspi", | |
| 1396 | + .data = &am654_pdata, | |
| 1397 | + }, | |
| 1385 | 1398 | { }, |
| 1386 | 1399 | }; |
| 1387 | 1400 | MODULE_DEVICE_TABLE(of, omap_mcspi_of_match); |
| @@ -1439,6 +1452,10 @@ static int omap2_mcspi_probe(struct platform_device *pdev) · 51 unmodified lines | ||
| 1439 | 1452 | mcspi->pin_dir = pdata->pin_dir; |
| 1440 | 1453 | } |
| 1441 | 1454 | regs_offset = pdata->regs_offset; |
| 1455 | + if (pdata->max_xfer_len) { | |
| 1456 | + mcspi->max_xfer_len = pdata->max_xfer_len; | |
| 1457 | + master->max_transfer_size = omap2_mcspi_max_xfer_size; | |
| 1458 | + } | |
| 1442 | 1459 | |
| 1443 | 1460 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1444 | 1461 | mcspi->base = devm_ioremap_resource(&pdev->dev, r); |
| @@ -1464,6 +1481,11 @@ static int omap2_mcspi_probe(struct platform_device *pdev) · 19 unmodified lines | ||
| 1464 | 1481 | for (i = 0; i < master->num_chipselect; i++) { |
| 1465 | 1482 | sprintf(mcspi->dma_channels[i].dma_rx_ch_name, "rx%d", i); |
| 1466 | 1483 | sprintf(mcspi->dma_channels[i].dma_tx_ch_name, "tx%d", i); |
| 1484 | + | |
| 1485 | + status = omap2_mcspi_request_dma(mcspi, | |
| 1486 | + &mcspi->dma_channels[i]); | |
| 1487 | + if (status == -EPROBE_DEFER) | |
| 1488 | + goto free_master; | |
| 1467 | 1489 | } |
| 1468 | 1490 | |
| 1469 | 1491 | status = platform_get_irq(pdev, 0); |
| @@ -1501,6 +1523,7 @@ disable_pm: · 31 unmodified lines | ||
| 1501 | 1523 | pm_runtime_put_sync(&pdev->dev); |
| 1502 | 1524 | pm_runtime_disable(&pdev->dev); |
| 1503 | 1525 | free_master: |
| 1526 | + omap2_mcspi_release_dma(master); | |
| 1504 | 1527 | spi_master_put(master); |
| 1505 | 1528 | return status; |
| 1506 | 1529 | } |
| @@ -1510,6 +1533,8 @@ static int omap2_mcspi_remove(struct platform_device *pdev) · 3 unmodified lines | ||
| 1510 | 1533 | struct spi_master *master = platform_get_drvdata(pdev); |
| 1511 | 1534 | struct omap2_mcspi *mcspi = spi_master_get_devdata(master); |
| 1512 | 1535 | |
| 1536 | + omap2_mcspi_release_dma(master); | |
| 1537 | + | |
| 1513 | 1538 | pm_runtime_dont_use_autosuspend(mcspi->dev); |
| 1514 | 1539 | pm_runtime_put_sync(mcspi->dev); |
| 1515 | 1540 | pm_runtime_disable(&pdev->dev); |
| @@ -70,6 +70,10 @@ MODULE_ALIAS("platform:pxa2xx-spi"); · 69 unmodified lines | ||
| 70 | 70 | #define LPSS_CAPS_CS_EN_SHIFT 9 |
| 71 | 71 | #define LPSS_CAPS_CS_EN_MASK (0xf << LPSS_CAPS_CS_EN_SHIFT) |
| 72 | 72 | |
| 73 | +#define LPSS_PRIV_CLOCK_GATE 0x38 | |
| 74 | +#define LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK 0x3 | |
| 75 | +#define LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_ON 0x3 | |
| 76 | + | |
| 73 | 77 | struct lpss_config { |
| 74 | 78 | /* LPSS offset from drv_data->ioaddr */ |
| 75 | 79 | unsigned offset; |
| @@ -86,6 +90,8 @@ struct lpss_config { · 10 unmodified lines | ||
| 86 | 90 | unsigned cs_sel_shift; |
| 87 | 91 | unsigned cs_sel_mask; |
| 88 | 92 | unsigned cs_num; |
| 93 | + /* Quirks */ | |
| 94 | + unsigned cs_clk_stays_gated : 1; | |
| 89 | 95 | }; |
| 90 | 96 | |
| 91 | 97 | /* Keep these sorted with enum pxa_ssp_type */ |
| @@ -156,6 +162,7 @@ static const struct lpss_config lpss_platforms[] = { · 64 unmodified lines | ||
| 156 | 162 | .tx_threshold_hi = 56, |
| 157 | 163 | .cs_sel_shift = 8, |
| 158 | 164 | .cs_sel_mask = 3 << 8, |
| 165 | + .cs_clk_stays_gated = true, | |
| 159 | 166 | }, |
| 160 | 167 | }; |
| 161 | 168 | |
| @@ -383,6 +390,22 @@ static void lpss_ssp_cs_control(struct spi_device *spi, bool enable) · 221 unmodified lines | ||
| 383 | 390 | else |
| 384 | 391 | value |= LPSS_CS_CONTROL_CS_HIGH; |
| 385 | 392 | __lpss_ssp_write_priv(drv_data, config->reg_cs_ctrl, value); |
| 393 | + if (config->cs_clk_stays_gated) { | |
| 394 | + u32 clkgate; | |
| 395 | + | |
| 396 | + /* | |
| 397 | + * Changing CS alone when dynamic clock gating is on won't | |
| 398 | + * actually flip CS at that time. This ruins SPI transfers | |
| 399 | + * that specify delays, or have no data. Toggle the clock mode | |
| 400 | + * to force on briefly to poke the CS pin to move. | |
| 401 | + */ | |
| 402 | + clkgate = __lpss_ssp_read_priv(drv_data, LPSS_PRIV_CLOCK_GATE); | |
| 403 | + value = (clkgate & ~LPSS_PRIV_CLOCK_GATE_CLK_CTL_MASK) | | |
| 404 | + LPSS_PRIV_CLOCK_GATE_CLK_CTL_FORCE_ON; | |
| 405 | + | |
| 406 | + __lpss_ssp_write_priv(drv_data, LPSS_PRIV_CLOCK_GATE, value); | |
| 407 | + __lpss_ssp_write_priv(drv_data, LPSS_PRIV_CLOCK_GATE, clkgate); | |
| 408 | + } | |
| 386 | 409 | } |
| 387 | 410 | |
| 388 | 411 | static void cs_assert(struct spi_device *spi) |
| @@ -1217,6 +1217,11 @@ static int spi_qup_suspend(struct device *device) · 1216 unmodified lines | ||
| 1217 | 1217 | struct spi_qup *controller = spi_master_get_devdata(master); |
| 1218 | 1218 | int ret; |
| 1219 | 1219 | |
| 1220 | + if (pm_runtime_suspended(device)) { | |
| 1221 | + ret = spi_qup_pm_resume_runtime(device); | |
| 1222 | + if (ret) | |
| 1223 | + return ret; | |
| 1224 | + } | |
| 1220 | 1225 | ret = spi_master_suspend(master); |
| 1221 | 1226 | if (ret) |
| 1222 | 1227 | return ret; |
| @@ -1225,10 +1230,8 @@ static int spi_qup_suspend(struct device *device) · 2 unmodified lines | ||
| 1225 | 1230 | if (ret) |
| 1226 | 1231 | return ret; |
| 1227 | 1232 | |
| 1228 | − if (!pm_runtime_suspended(device)) { | |
| 1229 | − clk_disable_unprepare(controller->cclk); | |
| 1230 | − clk_disable_unprepare(controller->iclk); | |
| 1231 | − } | |
| 1233 | + clk_disable_unprepare(controller->cclk); | |
| 1234 | + clk_disable_unprepare(controller->iclk); | |
| 1232 | 1235 | return 0; |
| 1233 | 1236 | } |
| 1234 | 1237 | |
| @@ -401,9 +401,6 @@ static void zynqmp_qspi_chipselect(struct spi_device *qspi, bool is_high) · 400 unmodified lines | ||
| 401 | 401 | |
| 402 | 402 | zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, genfifoentry); |
| 403 | 403 | |
| 404 | − /* Dummy generic FIFO entry */ | |
| 405 | − zynqmp_gqspi_write(xqspi, GQSPI_GEN_FIFO_OFST, 0x0); | |
| 406 | − | |
| 407 | 404 | /* Manually start the generic FIFO command */ |
| 408 | 405 | zynqmp_gqspi_write(xqspi, GQSPI_CONFIG_OFST, |
| 409 | 406 | zynqmp_gqspi_read(xqspi, GQSPI_CONFIG_OFST) | |
| @@ -2639,7 +2639,7 @@ int spi_register_controller(struct spi_controller *ctlr) · 2638 unmodified lines | ||
| 2639 | 2639 | if (ctlr->use_gpio_descriptors) { |
| 2640 | 2640 | status = spi_get_gpio_descs(ctlr); |
| 2641 | 2641 | if (status) |
| 2642 | − return status; | |
| 2642 | + goto free_bus_id; | |
| 2643 | 2643 | /* |
| 2644 | 2644 | * A controller using GPIO descriptors always |
| 2645 | 2645 | * supports SPI_CS_HIGH if need be. |
| @@ -2649,7 +2649,7 @@ int spi_register_controller(struct spi_controller *ctlr) · 3 unmodified lines | ||
| 2649 | 2649 | /* Legacy code path for GPIOs from DT */ |
| 2650 | 2650 | status = of_spi_get_gpio_numbers(ctlr); |
| 2651 | 2651 | if (status) |
| 2652 | − return status; | |
| 2652 | + goto free_bus_id; | |
| 2653 | 2653 | } |
| 2654 | 2654 | } |
| 2655 | 2655 | |
| @@ -2657,17 +2657,14 @@ int spi_register_controller(struct spi_controller *ctlr) · 1 unmodified line | ||
| 2657 | 2657 | * Even if it's just one always-selected device, there must |
| 2658 | 2658 | * be at least one chipselect. |
| 2659 | 2659 | */ |
| 2660 | − if (!ctlr->num_chipselect) | |
| 2661 | − return -EINVAL; | |
| 2660 | + if (!ctlr->num_chipselect) { | |
| 2661 | + status = -EINVAL; | |
| 2662 | + goto free_bus_id; | |
| 2663 | + } | |
| 2662 | 2664 | |
| 2663 | 2665 | status = device_add(&ctlr->dev); |
| 2664 | − if (status < 0) { | |
| 2665 | − /* free bus id */ | |
| 2666 | − mutex_lock(&board_lock); | |
| 2667 | − idr_remove(&spi_master_idr, ctlr->bus_num); | |
| 2668 | − mutex_unlock(&board_lock); | |
| 2669 | − goto done; | |
| 2670 | − } | |
| 2666 | + if (status < 0) | |
| 2667 | + goto free_bus_id; | |
| 2671 | 2668 | dev_dbg(dev, "registered %s %s\n", |
| 2672 | 2669 | spi_controller_is_slave(ctlr) ? "slave" : "master", |
| 2673 | 2670 | dev_name(&ctlr->dev)); |
| @@ -2683,11 +2680,7 @@ int spi_register_controller(struct spi_controller *ctlr) · 9 unmodified lines | ||
| 2683 | 2680 | status = spi_controller_initialize_queue(ctlr); |
| 2684 | 2681 | if (status) { |
| 2685 | 2682 | device_del(&ctlr->dev); |
| 2686 | − /* free bus id */ | |
| 2687 | − mutex_lock(&board_lock); | |
| 2688 | − idr_remove(&spi_master_idr, ctlr->bus_num); | |
| 2689 | − mutex_unlock(&board_lock); | |
| 2690 | − goto done; | |
| 2683 | + goto free_bus_id; | |
| 2691 | 2684 | } |
| 2692 | 2685 | } |
| 2693 | 2686 | /* add statistics */ |
| @@ -2702,7 +2695,12 @@ int spi_register_controller(struct spi_controller *ctlr) · 8 unmodified lines | ||
| 2702 | 2695 | /* Register devices from the device tree and ACPI */ |
| 2703 | 2696 | of_register_spi_devices(ctlr); |
| 2704 | 2697 | acpi_register_spi_devices(ctlr); |
| 2705 | −done: | |
| 2698 | + return status; | |
| 2699 | + | |
| 2700 | +free_bus_id: | |
| 2701 | + mutex_lock(&board_lock); | |
| 2702 | + idr_remove(&spi_master_idr, ctlr->bus_num); | |
| 2703 | + mutex_unlock(&board_lock); | |
| 2706 | 2704 | return status; |
| 2707 | 2705 | } |
| 2708 | 2706 | EXPORT_SYMBOL_GPL(spi_register_controller); |
| @@ -396,6 +396,7 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) · 395 unmodified lines | ||
| 396 | 396 | else |
| 397 | 397 | retval = get_user(tmp, (u32 __user *)arg); |
| 398 | 398 | if (retval == 0) { |
| 399 | + struct spi_controller *ctlr = spi->controller; | |
| 399 | 400 | u32 save = spi->mode; |
| 400 | 401 | |
| 401 | 402 | if (tmp & ~SPI_MODE_MASK) { |
| @@ -403,6 +404,10 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) · 1 unmodified line | ||
| 403 | 404 | break; |
| 404 | 405 | } |
| 405 | 406 | |
| 407 | + if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods && | |
| 408 | + ctlr->cs_gpiods[spi->chip_select]) | |
| 409 | + tmp |= SPI_CS_HIGH; | |
| 410 | + | |
| 406 | 411 | tmp |= spi->mode & ~SPI_MODE_MASK; |
| 407 | 412 | spi->mode = (u16)tmp; |
| 408 | 413 | retval = spi_setup(spi); |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <signal.h> |
| 20 | 20 | |
| 21 | 21 | #define MAX_NUM_DEVICES 10 |
| 22 | +#define MAX_SYSFS_PREFIX 0x80 | |
| 22 | 23 | #define MAX_SYSFS_PATH 0x200 |
| 23 | 24 | #define CSV_MAX_LINE 0x1000 |
| 24 | 25 | #define SYSFS_MAX_INT 0x20 |
| @@ -67,7 +68,7 @@ struct loopback_results { · 42 unmodified lines | ||
| 67 | 68 | }; |
| 68 | 69 | |
| 69 | 70 | struct loopback_device { |
| 70 | − char name[MAX_SYSFS_PATH]; | |
| 71 | + char name[MAX_STR_LEN]; | |
| 71 | 72 | char sysfs_entry[MAX_SYSFS_PATH]; |
| 72 | 73 | char debugfs_entry[MAX_SYSFS_PATH]; |
| 73 | 74 | struct loopback_results results; |
| @@ -93,8 +94,8 @@ struct loopback_test { · 19 unmodified lines | ||
| 93 | 94 | int stop_all; |
| 94 | 95 | int poll_count; |
| 95 | 96 | char test_name[MAX_STR_LEN]; |
| 96 | − char sysfs_prefix[MAX_SYSFS_PATH]; | |
| 97 | − char debugfs_prefix[MAX_SYSFS_PATH]; | |
| 97 | + char sysfs_prefix[MAX_SYSFS_PREFIX]; | |
| 98 | + char debugfs_prefix[MAX_SYSFS_PREFIX]; | |
| 98 | 99 | struct timespec poll_timeout; |
| 99 | 100 | struct loopback_device devices[MAX_NUM_DEVICES]; |
| 100 | 101 | struct loopback_results aggregate_results; |
| @@ -637,7 +638,7 @@ baddir: · 536 unmodified lines | ||
| 637 | 638 | static int open_poll_files(struct loopback_test *t) |
| 638 | 639 | { |
| 639 | 640 | struct loopback_device *dev; |
| 640 | − char buf[MAX_STR_LEN]; | |
| 641 | + char buf[MAX_SYSFS_PATH + MAX_STR_LEN]; | |
| 641 | 642 | char dummy; |
| 642 | 643 | int fds_idx = 0; |
| 643 | 644 | int i; |
| @@ -655,7 +656,7 @@ static int open_poll_files(struct loopback_test *t) · 11 unmodified lines | ||
| 655 | 656 | goto err; |
| 656 | 657 | } |
| 657 | 658 | read(t->fds[fds_idx].fd, &dummy, 1); |
| 658 | − t->fds[fds_idx].events = EPOLLERR|EPOLLPRI; | |
| 659 | + t->fds[fds_idx].events = POLLERR | POLLPRI; | |
| 659 | 660 | t->fds[fds_idx].revents = 0; |
| 660 | 661 | fds_idx++; |
| 661 | 662 | } |
| @@ -748,7 +749,7 @@ static int wait_for_complete(struct loopback_test *t) · 86 unmodified lines | ||
| 748 | 749 | } |
| 749 | 750 | |
| 750 | 751 | for (i = 0; i < t->poll_count; i++) { |
| 751 | − if (t->fds[i].revents & EPOLLPRI) { | |
| 752 | + if (t->fds[i].revents & POLLPRI) { | |
| 752 | 753 | /* Dummy read to clear the event */ |
| 753 | 754 | read(t->fds[i].fd, &dummy, 1); |
| 754 | 755 | number_of_events++; |
| @@ -907,10 +908,10 @@ int main(int argc, char *argv[]) · 152 unmodified lines | ||
| 907 | 908 | t.iteration_max = atoi(optarg); |
| 908 | 909 | break; |
| 909 | 910 | case 'S': |
| 910 | − snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", optarg); | |
| 911 | + snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg); | |
| 911 | 912 | break; |
| 912 | 913 | case 'D': |
| 913 | − snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", optarg); | |
| 914 | + snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", optarg); | |
| 914 | 915 | break; |
| 915 | 916 | case 'm': |
| 916 | 917 | t.mask = atol(optarg); |
| @@ -961,10 +962,10 @@ int main(int argc, char *argv[]) · 44 unmodified lines | ||
| 961 | 962 | } |
| 962 | 963 | |
| 963 | 964 | if (!strcmp(t.sysfs_prefix, "")) |
| 964 | − snprintf(t.sysfs_prefix, MAX_SYSFS_PATH, "%s", sysfs_prefix); | |
| 965 | + snprintf(t.sysfs_prefix, MAX_SYSFS_PREFIX, "%s", sysfs_prefix); | |
| 965 | 966 | |
| 966 | 967 | if (!strcmp(t.debugfs_prefix, "")) |
| 967 | − snprintf(t.debugfs_prefix, MAX_SYSFS_PATH, "%s", debugfs_prefix); | |
| 968 | + snprintf(t.debugfs_prefix, MAX_SYSFS_PREFIX, "%s", debugfs_prefix); | |
| 968 | 969 | |
| 969 | 970 | ret = find_loopback_devices(&t); |
| 970 | 971 | if (ret) |
| @@ -558,13 +558,13 @@ static int hantro_attach_func(struct hantro_dev *vpu, · 557 unmodified lines | ||
| 558 | 558 | goto err_rel_entity1; |
| 559 | 559 | |
| 560 | 560 | /* Connect the three entities */ |
| 561 | − ret = media_create_pad_link(&func->vdev.entity, 0, &func->proc, 1, | |
| 561 | + ret = media_create_pad_link(&func->vdev.entity, 0, &func->proc, 0, | |
| 562 | 562 | MEDIA_LNK_FL_IMMUTABLE | |
| 563 | 563 | MEDIA_LNK_FL_ENABLED); |
| 564 | 564 | if (ret) |
| 565 | 565 | goto err_rel_entity2; |
| 566 | 566 | |
| 567 | − ret = media_create_pad_link(&func->proc, 0, &func->sink, 0, | |
| 567 | + ret = media_create_pad_link(&func->proc, 1, &func->sink, 0, | |
| 568 | 568 | MEDIA_LNK_FL_IMMUTABLE | |
| 569 | 569 | MEDIA_LNK_FL_ENABLED); |
| 570 | 570 | if (ret) |
| @@ -38,6 +38,7 @@ static const struct usb_device_id rtw_usb_id_tbl[] = { · 37 unmodified lines | ||
| 38 | 38 | {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */ |
| 39 | 39 | {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */ |
| 40 | 40 | {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */ |
| 41 | + {USB_DEVICE(0x2C4E, 0x0102)}, /* MERCUSYS MW150US v2 */ | |
| 41 | 42 | {USB_DEVICE(0x0df6, 0x0076)}, /* Sitecom N150 v2 */ |
| 42 | 43 | {USB_DEVICE(USB_VENDER_ID_REALTEK, 0xffef)}, /* Rosewill RNX-N150NUB */ |
| 43 | 44 | {} /* Terminating entry */ |
| @@ -561,7 +561,7 @@ static u_long get_word(struct vc_data *vc) · 560 unmodified lines | ||
| 561 | 561 | return 0; |
| 562 | 562 | } else if (tmpx < vc->vc_cols - 2 && |
| 563 | 563 | (ch == SPACE || ch == 0 || (ch < 0x100 && IS_WDLM(ch))) && |
| 564 | − get_char(vc, (u_short *)&tmp_pos + 1, &temp) > SPACE) { | |
| 564 | + get_char(vc, (u_short *)tmp_pos + 1, &temp) > SPACE) { | |
| 565 | 565 | tmp_pos += 2; |
| 566 | 566 | tmpx++; |
| 567 | 567 | } else { |
| @@ -51,9 +51,7 @@ static void __speakup_set_selection(struct work_struct *work) · 50 unmodified lines | ||
| 51 | 51 | goto unref; |
| 52 | 52 | } |
| 53 | 53 | |
| 54 | − console_lock(); | |
| 55 | 54 | set_selection_kernel(&sel, tty); |
| 56 | − console_unlock(); | |
| 57 | 55 | |
| 58 | 56 | unref: |
| 59 | 57 | tty_kref_put(tty); |
| @@ -93,5 +93,5 @@ Some properties are recognized either by SPI and SDIO versions: · 92 unmodified lines | ||
| 93 | 93 | Must contains 64 hexadecimal digits. Not supported in current version. |
| 94 | 94 | |
| 95 | 95 | WFx driver also supports `mac-address` and `local-mac-address` as described in |
| 96 | −Documentation/devicetree/binding/net/ethernet.txt | |
| 96 | +Documentation/devicetree/bindings/net/ethernet.txt | |
| 97 | 97 | |
| @@ -140,6 +140,7 @@ int hif_shutdown(struct wfx_dev *wdev) · 139 unmodified lines | ||
| 140 | 140 | else |
| 141 | 141 | control_reg_write(wdev, 0); |
| 142 | 142 | mutex_unlock(&wdev->hif_cmd.lock); |
| 143 | + mutex_unlock(&wdev->hif_cmd.key_renew_lock); | |
| 143 | 144 | kfree(hif); |
| 144 | 145 | return ret; |
| 145 | 146 | } |
| @@ -289,7 +290,7 @@ int hif_stop_scan(struct wfx_vif *wvif) · 143 unmodified lines | ||
| 289 | 290 | } |
| 290 | 291 | |
| 291 | 292 | int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, |
| 292 | − const struct ieee80211_channel *channel, const u8 *ssidie) | |
| 293 | + struct ieee80211_channel *channel, const u8 *ssid, int ssidlen) | |
| 293 | 294 | { |
| 294 | 295 | int ret; |
| 295 | 296 | struct hif_msg *hif; |
| @@ -307,9 +308,9 @@ int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, · 11 unmodified lines | ||
| 307 | 308 | body->basic_rate_set = |
| 308 | 309 | cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates)); |
| 309 | 310 | memcpy(body->bssid, conf->bssid, sizeof(body->bssid)); |
| 310 | − if (!conf->ibss_joined && ssidie) { | |
| 311 | − body->ssid_length = cpu_to_le32(ssidie[1]); | |
| 312 | − memcpy(body->ssid, &ssidie[2], ssidie[1]); | |
| 311 | + if (!conf->ibss_joined && ssid) { | |
| 312 | + body->ssid_length = cpu_to_le32(ssidlen); | |
| 313 | + memcpy(body->ssid, ssid, ssidlen); | |
| 313 | 314 | } |
| 314 | 315 | wfx_fill_header(hif, wvif->id, HIF_REQ_ID_JOIN, sizeof(*body)); |
| 315 | 316 | ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false); |
| @@ -427,9 +428,9 @@ int hif_start(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, · 111 unmodified lines | ||
| 427 | 428 | struct hif_msg *hif; |
| 428 | 429 | struct hif_req_start *body = wfx_alloc_hif(sizeof(*body), &hif); |
| 429 | 430 | |
| 430 | − body->dtim_period = conf->dtim_period, | |
| 431 | − body->short_preamble = conf->use_short_preamble, | |
| 432 | − body->channel_number = cpu_to_le16(channel->hw_value), | |
| 431 | + body->dtim_period = conf->dtim_period; | |
| 432 | + body->short_preamble = conf->use_short_preamble; | |
| 433 | + body->channel_number = cpu_to_le16(channel->hw_value); | |
| 433 | 434 | body->beacon_interval = cpu_to_le32(conf->beacon_int); |
| 434 | 435 | body->basic_rate_set = |
| 435 | 436 | cpu_to_le32(wfx_rate_mask_to_hw(wvif->wdev, conf->basic_rates)); |
| @@ -46,7 +46,7 @@ int hif_scan(struct wfx_vif *wvif, struct cfg80211_scan_request *req80211, · 45 unmodified lines | ||
| 46 | 46 | int chan_start, int chan_num); |
| 47 | 47 | int hif_stop_scan(struct wfx_vif *wvif); |
| 48 | 48 | int hif_join(struct wfx_vif *wvif, const struct ieee80211_bss_conf *conf, |
| 49 | − const struct ieee80211_channel *channel, const u8 *ssidie); | |
| 49 | + struct ieee80211_channel *channel, const u8 *ssid, int ssidlen); | |
| 50 | 50 | int hif_set_pm(struct wfx_vif *wvif, bool ps, int dynamic_ps_timeout); |
| 51 | 51 | int hif_set_bss_params(struct wfx_vif *wvif, |
| 52 | 52 | const struct hif_req_set_bss_params *arg); |
| @@ -191,10 +191,10 @@ static inline int hif_set_block_ack_policy(struct wfx_vif *wvif, · 190 unmodified lines | ||
| 191 | 191 | } |
| 192 | 192 | |
| 193 | 193 | static inline int hif_set_association_mode(struct wfx_vif *wvif, |
| 194 | − struct ieee80211_bss_conf *info, | |
| 195 | − struct ieee80211_sta_ht_cap *ht_cap) | |
| 194 | + struct ieee80211_bss_conf *info) | |
| 196 | 195 | { |
| 197 | 196 | int basic_rates = wfx_rate_mask_to_hw(wvif->wdev, info->basic_rates); |
| 197 | + struct ieee80211_sta *sta = NULL; | |
| 198 | 198 | struct hif_mib_set_association_mode val = { |
| 199 | 199 | .preambtype_use = 1, |
| 200 | 200 | .mode = 1, |
| @@ -204,12 +204,17 @@ static inline int hif_set_association_mode(struct wfx_vif *wvif, · 3 unmodified lines | ||
| 204 | 204 | .basic_rate_set = cpu_to_le32(basic_rates) |
| 205 | 205 | }; |
| 206 | 206 | |
| 207 | + rcu_read_lock(); // protect sta | |
| 208 | + if (info->bssid && !info->ibss_joined) | |
| 209 | + sta = ieee80211_find_sta(wvif->vif, info->bssid); | |
| 210 | + | |
| 207 | 211 | // FIXME: it is strange to not retrieve all information from bss_info |
| 208 | − if (ht_cap && ht_cap->ht_supported) { | |
| 209 | − val.mpdu_start_spacing = ht_cap->ampdu_density; | |
| 212 | + if (sta && sta->ht_cap.ht_supported) { | |
| 213 | + val.mpdu_start_spacing = sta->ht_cap.ampdu_density; | |
| 210 | 214 | if (!(info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)) |
| 211 | − val.greenfield = !!(ht_cap->cap & IEEE80211_HT_CAP_GRN_FLD); | |
| 215 | + val.greenfield = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD); | |
| 212 | 216 | } |
| 217 | + rcu_read_unlock(); | |
| 213 | 218 | |
| 214 | 219 | return hif_write_mib(wvif->wdev, wvif->id, |
| 215 | 220 | HIF_MIB_ID_SET_ASSOCIATION_MODE, &val, sizeof(val)); |
| @@ -491,9 +491,11 @@ static void wfx_set_mfp(struct wfx_vif *wvif, · 490 unmodified lines | ||
| 491 | 491 | static void wfx_do_join(struct wfx_vif *wvif) |
| 492 | 492 | { |
| 493 | 493 | int ret; |
| 494 | − const u8 *ssidie; | |
| 495 | 494 | struct ieee80211_bss_conf *conf = &wvif->vif->bss_conf; |
| 496 | 495 | struct cfg80211_bss *bss = NULL; |
| 496 | + u8 ssid[IEEE80211_MAX_SSID_LEN]; | |
| 497 | + const u8 *ssidie = NULL; | |
| 498 | + int ssidlen = 0; | |
| 497 | 499 | |
| 498 | 500 | wfx_tx_lock_flush(wvif->wdev); |
| 499 | 501 | |
| @@ -514,11 +516,14 @@ static void wfx_do_join(struct wfx_vif *wvif) · 14 unmodified lines | ||
| 514 | 516 | if (!wvif->beacon_int) |
| 515 | 517 | wvif->beacon_int = 1; |
| 516 | 518 | |
| 517 | − rcu_read_lock(); | |
| 519 | + rcu_read_lock(); // protect ssidie | |
| 518 | 520 | if (!conf->ibss_joined) |
| 519 | 521 | ssidie = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); |
| 520 | − else | |
| 521 | − ssidie = NULL; | |
| 522 | + if (ssidie) { | |
| 523 | + ssidlen = ssidie[1]; | |
| 524 | + memcpy(ssid, &ssidie[2], ssidie[1]); | |
| 525 | + } | |
| 526 | + rcu_read_unlock(); | |
| 522 | 527 | |
| 523 | 528 | wfx_tx_flush(wvif->wdev); |
| 524 | 529 | |
| @@ -527,10 +532,8 @@ static void wfx_do_join(struct wfx_vif *wvif) · 2 unmodified lines | ||
| 527 | 532 | |
| 528 | 533 | wfx_set_mfp(wvif, bss); |
| 529 | 534 | |
| 530 | − /* Perform actual join */ | |
| 531 | 535 | wvif->wdev->tx_burst_idx = -1; |
| 532 | − ret = hif_join(wvif, conf, wvif->channel, ssidie); | |
| 533 | − rcu_read_unlock(); | |
| 536 | + ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen); | |
| 534 | 537 | if (ret) { |
| 535 | 538 | ieee80211_connection_loss(wvif->vif); |
| 536 | 539 | wvif->join_complete_status = -1; |
| @@ -605,7 +608,9 @@ int wfx_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, · 68 unmodified lines | ||
| 605 | 608 | int i; |
| 606 | 609 | |
| 607 | 610 | for (i = 0; i < ARRAY_SIZE(sta_priv->buffered); i++) |
| 608 | − WARN(sta_priv->buffered[i], "release station while Tx is in progress"); | |
| 611 | + if (sta_priv->buffered[i]) | |
| 612 | + dev_warn(wvif->wdev->dev, "release station while %d pending frame on queue %d", | |
| 613 | + sta_priv->buffered[i], i); | |
| 609 | 614 | // FIXME: see note in wfx_sta_add() |
| 610 | 615 | if (vif->type == NL80211_IFTYPE_STATION) |
| 611 | 616 | return 0; |
| @@ -689,6 +694,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, · 77 unmodified lines | ||
| 689 | 694 | wfx_rate_mask_to_hw(wvif->wdev, sta->supp_rates[wvif->channel->band]); |
| 690 | 695 | else |
| 691 | 696 | wvif->bss_params.operational_rate_set = -1; |
| 697 | + rcu_read_unlock(); | |
| 692 | 698 | if (sta && |
| 693 | 699 | info->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) |
| 694 | 700 | hif_dual_cts_protection(wvif, true); |
| @@ -701,8 +707,7 @@ static void wfx_join_finalize(struct wfx_vif *wvif, · 6 unmodified lines | ||
| 701 | 707 | wvif->bss_params.beacon_lost_count = 20; |
| 702 | 708 | wvif->bss_params.aid = info->aid; |
| 703 | 709 | |
| 704 | − hif_set_association_mode(wvif, info, sta ? &sta->ht_cap : NULL); | |
| 705 | − rcu_read_unlock(); | |
| 710 | + hif_set_association_mode(wvif, info); | |
| 706 | 711 | |
| 707 | 712 | if (!info->ibss_joined) { |
| 708 | 713 | hif_keep_alive_period(wvif, 30 /* sec */); |
| @@ -3,6 +3,6 @@ · 2 unmodified lines | ||
| 3 | 3 | config AMDTEE |
| 4 | 4 | tristate "AMD-TEE" |
| 5 | 5 | default m |
| 6 | − depends on CRYPTO_DEV_SP_PSP | |
| 6 | + depends on CRYPTO_DEV_SP_PSP && CRYPTO_DEV_CCP_DD | |
| 7 | 7 | help |
| 8 | 8 | This implements AMD's Trusted Execution Environment (TEE) driver. |
| @@ -212,6 +212,19 @@ unlock: · 211 unmodified lines | ||
| 212 | 212 | return rc; |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | +static void destroy_session(struct kref *ref) | |
| 216 | +{ | |
| 217 | + struct amdtee_session *sess = container_of(ref, struct amdtee_session, | |
| 218 | + refcount); | |
| 219 | + | |
| 220 | + /* Unload the TA from TEE */ | |
| 221 | + handle_unload_ta(sess->ta_handle); | |
| 222 | + mutex_lock(&session_list_mutex); | |
| 223 | + list_del(&sess->list_node); | |
| 224 | + mutex_unlock(&session_list_mutex); | |
| 225 | + kfree(sess); | |
| 226 | +} | |
| 227 | + | |
| 215 | 228 | int amdtee_open_session(struct tee_context *ctx, |
| 216 | 229 | struct tee_ioctl_open_session_arg *arg, |
| 217 | 230 | struct tee_param *param) |
| @@ -236,15 +249,13 @@ int amdtee_open_session(struct tee_context *ctx, · 18 unmodified lines | ||
| 236 | 249 | |
| 237 | 250 | /* Load the TA binary into TEE environment */ |
| 238 | 251 | handle_load_ta(ta, ta_size, arg); |
| 239 | − if (arg->ret == TEEC_SUCCESS) { | |
| 240 | − mutex_lock(&session_list_mutex); | |
| 241 | − sess = alloc_session(ctxdata, arg->session); | |
| 242 | − mutex_unlock(&session_list_mutex); | |
| 243 | − } | |
| 244 | − | |
| 245 | 252 | if (arg->ret != TEEC_SUCCESS) |
| 246 | 253 | goto out; |
| 247 | 254 | |
| 255 | + mutex_lock(&session_list_mutex); | |
| 256 | + sess = alloc_session(ctxdata, arg->session); | |
| 257 | + mutex_unlock(&session_list_mutex); | |
| 258 | + | |
| 248 | 259 | if (!sess) { |
| 249 | 260 | rc = -ENOMEM; |
| 250 | 261 | goto out; |
| @@ -259,40 +270,29 @@ int amdtee_open_session(struct tee_context *ctx, · 8 unmodified lines | ||
| 259 | 270 | |
| 260 | 271 | if (i >= TEE_NUM_SESSIONS) { |
| 261 | 272 | pr_err("reached maximum session count %d\n", TEE_NUM_SESSIONS); |
| 273 | + kref_put(&sess->refcount, destroy_session); | |
| 262 | 274 | rc = -ENOMEM; |
| 263 | 275 | goto out; |
| 264 | 276 | } |
| 265 | 277 | |
| 266 | 278 | /* Open session with loaded TA */ |
| 267 | 279 | handle_open_session(arg, &session_info, param); |
| 268 | − | |
| 269 | − if (arg->ret == TEEC_SUCCESS) { | |
| 270 | − sess->session_info[i] = session_info; | |
| 271 | − set_session_id(sess->ta_handle, i, &arg->session); | |
| 272 | − } else { | |
| 280 | + if (arg->ret != TEEC_SUCCESS) { | |
| 273 | 281 | pr_err("open_session failed %d\n", arg->ret); |
| 274 | 282 | spin_lock(&sess->lock); |
| 275 | 283 | clear_bit(i, sess->sess_mask); |
| 276 | 284 | spin_unlock(&sess->lock); |
| 285 | + kref_put(&sess->refcount, destroy_session); | |
| 286 | + goto out; | |
| 277 | 287 | } |
| 288 | + | |
| 289 | + sess->session_info[i] = session_info; | |
| 290 | + set_session_id(sess->ta_handle, i, &arg->session); | |
| 278 | 291 | out: |
| 279 | 292 | free_pages((u64)ta, get_order(ta_size)); |
| 280 | 293 | return rc; |
| 281 | 294 | } |
| 282 | 295 | |
| 283 | −static void destroy_session(struct kref *ref) | |
| 284 | −{ | |
| 285 | − struct amdtee_session *sess = container_of(ref, struct amdtee_session, | |
| 286 | − refcount); | |
| 287 | − | |
| 288 | − /* Unload the TA from TEE */ | |
| 289 | − handle_unload_ta(sess->ta_handle); | |
| 290 | − mutex_lock(&session_list_mutex); | |
| 291 | − list_del(&sess->list_node); | |
| 292 | − mutex_unlock(&session_list_mutex); | |
| 293 | − kfree(sess); | |
| 294 | −} | |
| 295 | − | |
| 296 | 296 | int amdtee_close_session(struct tee_context *ctx, u32 session) |
| 297 | 297 | { |
| 298 | 298 | struct amdtee_context_data *ctxdata = ctx->data; |
| @@ -954,7 +954,7 @@ static bool tb_port_is_width_supported(struct tb_port *port, int width) · 953 unmodified lines | ||
| 954 | 954 | ret = tb_port_read(port, &phy, TB_CFG_PORT, |
| 955 | 955 | port->cap_phy + LANE_ADP_CS_0, 1); |
| 956 | 956 | if (ret) |
| 957 | − return ret; | |
| 957 | + return false; | |
| 958 | 958 | |
| 959 | 959 | widths = (phy & LANE_ADP_CS_0_SUPPORTED_WIDTH_MASK) >> |
| 960 | 960 | LANE_ADP_CS_0_SUPPORTED_WIDTH_SHIFT; |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/sched.h> |
| 19 | 19 | #include <linux/serdev.h> |
| 20 | 20 | #include <linux/slab.h> |
| 21 | +#include <linux/platform_data/x86/apple.h> | |
| 21 | 22 | |
| 22 | 23 | static bool is_registered; |
| 23 | 24 | static DEFINE_IDA(ctrl_ida); |
| @@ -631,6 +632,15 @@ static int acpi_serdev_check_resources(struct serdev_controller *ctrl, · 607 unmodified lines | ||
| 631 | 632 | if (ret) |
| 632 | 633 | return ret; |
| 633 | 634 | |
| 635 | + /* | |
| 636 | + * Apple machines provide an empty resource template, so on those | |
| 637 | + * machines just look for immediate children with a "baud" property | |
| 638 | + * (from the _DSM method) instead. | |
| 639 | + */ | |
| 640 | + if (!lookup.controller_handle && x86_apple_machine && | |
| 641 | + !acpi_dev_get_property(adev, "baud", ACPI_TYPE_BUFFER, NULL)) | |
| 642 | + acpi_get_parent(adev->handle, &lookup.controller_handle); | |
| 643 | + | |
| 634 | 644 | /* Make sure controller and ResourceSource handle match */ |
| 635 | 645 | if (ACPI_HANDLE(ctrl->dev.parent) != lookup.controller_handle) |
| 636 | 646 | return -ENODEV; |
| @@ -25,6 +25,14 @@ · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | #include "8250.h" |
| 27 | 27 | |
| 28 | +#define PCI_DEVICE_ID_ACCES_COM_2S 0x1052 | |
| 29 | +#define PCI_DEVICE_ID_ACCES_COM_4S 0x105d | |
| 30 | +#define PCI_DEVICE_ID_ACCES_COM_8S 0x106c | |
| 31 | +#define PCI_DEVICE_ID_ACCES_COM232_8 0x10a8 | |
| 32 | +#define PCI_DEVICE_ID_ACCES_COM_2SM 0x10d2 | |
| 33 | +#define PCI_DEVICE_ID_ACCES_COM_4SM 0x10db | |
| 34 | +#define PCI_DEVICE_ID_ACCES_COM_8SM 0x10ea | |
| 35 | + | |
| 28 | 36 | #define PCI_DEVICE_ID_COMMTECH_4224PCI335 0x0002 |
| 29 | 37 | #define PCI_DEVICE_ID_COMMTECH_4222PCI335 0x0004 |
| 30 | 38 | #define PCI_DEVICE_ID_COMMTECH_2324PCI335 0x000a |
| @@ -677,6 +685,22 @@ static int __maybe_unused exar_resume(struct device *dev) · 646 unmodified lines | ||
| 677 | 685 | |
| 678 | 686 | static SIMPLE_DEV_PM_OPS(exar_pci_pm, exar_suspend, exar_resume); |
| 679 | 687 | |
| 688 | +static const struct exar8250_board acces_com_2x = { | |
| 689 | + .num_ports = 2, | |
| 690 | + .setup = pci_xr17c154_setup, | |
| 691 | +}; | |
| 692 | + | |
| 693 | +static const struct exar8250_board acces_com_4x = { | |
| 694 | + .num_ports = 4, | |
| 695 | + .setup = pci_xr17c154_setup, | |
| 696 | +}; | |
| 697 | + | |
| 698 | +static const struct exar8250_board acces_com_8x = { | |
| 699 | + .num_ports = 8, | |
| 700 | + .setup = pci_xr17c154_setup, | |
| 701 | +}; | |
| 702 | + | |
| 703 | + | |
| 680 | 704 | static const struct exar8250_board pbn_fastcom335_2 = { |
| 681 | 705 | .num_ports = 2, |
| 682 | 706 | .setup = pci_fastcom335_setup, |
| @@ -745,6 +769,15 @@ static const struct exar8250_board pbn_exar_XR17V8358 = { · 62 unmodified lines | ||
| 745 | 769 | } |
| 746 | 770 | |
| 747 | 771 | static const struct pci_device_id exar_pci_tbl[] = { |
| 772 | + EXAR_DEVICE(ACCESSIO, ACCES_COM_2S, acces_com_2x), | |
| 773 | + EXAR_DEVICE(ACCESSIO, ACCES_COM_4S, acces_com_4x), | |
| 774 | + EXAR_DEVICE(ACCESSIO, ACCES_COM_8S, acces_com_8x), | |
| 775 | + EXAR_DEVICE(ACCESSIO, ACCES_COM232_8, acces_com_8x), | |
| 776 | + EXAR_DEVICE(ACCESSIO, ACCES_COM_2SM, acces_com_2x), | |
| 777 | + EXAR_DEVICE(ACCESSIO, ACCES_COM_4SM, acces_com_4x), | |
| 778 | + EXAR_DEVICE(ACCESSIO, ACCES_COM_8SM, acces_com_8x), | |
| 779 | + | |
| 780 | + | |
| 748 | 781 | CONNECT_DEVICE(XR17C152, UART_2_232, pbn_connect), |
| 749 | 782 | CONNECT_DEVICE(XR17C154, UART_4_232, pbn_connect), |
| 750 | 783 | CONNECT_DEVICE(XR17C158, UART_8_232, pbn_connect), |
| @@ -264,6 +264,7 @@ struct lpuart_port { · 263 unmodified lines | ||
| 264 | 264 | int rx_dma_rng_buf_len; |
| 265 | 265 | unsigned int dma_tx_nents; |
| 266 | 266 | wait_queue_head_t dma_wait; |
| 267 | + bool id_allocated; | |
| 267 | 268 | }; |
| 268 | 269 | |
| 269 | 270 | struct lpuart_soc_data { |
| @@ -2390,6 +2391,8 @@ static int __init lpuart32_imx_early_console_setup(struct earlycon_device *devic · 2120 unmodified lines | ||
| 2390 | 2391 | OF_EARLYCON_DECLARE(lpuart, "fsl,vf610-lpuart", lpuart_early_console_setup); |
| 2391 | 2392 | OF_EARLYCON_DECLARE(lpuart32, "fsl,ls1021a-lpuart", lpuart32_early_console_setup); |
| 2392 | 2393 | OF_EARLYCON_DECLARE(lpuart32, "fsl,imx7ulp-lpuart", lpuart32_imx_early_console_setup); |
| 2394 | +EARLYCON_DECLARE(lpuart, lpuart_early_console_setup); | |
| 2395 | +EARLYCON_DECLARE(lpuart32, lpuart32_early_console_setup); | |
| 2393 | 2396 | |
| 2394 | 2397 | #define LPUART_CONSOLE (&lpuart_console) |
| 2395 | 2398 | #define LPUART32_CONSOLE (&lpuart32_console) |
| @@ -2420,19 +2423,6 @@ static int lpuart_probe(struct platform_device *pdev) · 24 unmodified lines | ||
| 2420 | 2423 | if (!sport) |
| 2421 | 2424 | return -ENOMEM; |
| 2422 | 2425 | |
| 2423 | − ret = of_alias_get_id(np, "serial"); | |
| 2424 | − if (ret < 0) { | |
| 2425 | − ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL); | |
| 2426 | − if (ret < 0) { | |
| 2427 | − dev_err(&pdev->dev, "port line is full, add device failed\n"); | |
| 2428 | − return ret; | |
| 2429 | − } | |
| 2430 | − } | |
| 2431 | − if (ret >= ARRAY_SIZE(lpuart_ports)) { | |
| 2432 | − dev_err(&pdev->dev, "serial%d out of range\n", ret); | |
| 2433 | − return -EINVAL; | |
| 2434 | − } | |
| 2435 | − sport->port.line = ret; | |
| 2436 | 2426 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 2437 | 2427 | sport->port.membase = devm_ioremap_resource(&pdev->dev, res); |
| 2438 | 2428 | if (IS_ERR(sport->port.membase)) |
| @@ -2477,9 +2467,25 @@ static int lpuart_probe(struct platform_device *pdev) · 38 unmodified lines | ||
| 2477 | 2467 | } |
| 2478 | 2468 | } |
| 2479 | 2469 | |
| 2470 | + ret = of_alias_get_id(np, "serial"); | |
| 2471 | + if (ret < 0) { | |
| 2472 | + ret = ida_simple_get(&fsl_lpuart_ida, 0, UART_NR, GFP_KERNEL); | |
| 2473 | + if (ret < 0) { | |
| 2474 | + dev_err(&pdev->dev, "port line is full, add device failed\n"); | |
| 2475 | + return ret; | |
| 2476 | + } | |
| 2477 | + sport->id_allocated = true; | |
| 2478 | + } | |
| 2479 | + if (ret >= ARRAY_SIZE(lpuart_ports)) { | |
| 2480 | + dev_err(&pdev->dev, "serial%d out of range\n", ret); | |
| 2481 | + ret = -EINVAL; | |
| 2482 | + goto failed_out_of_range; | |
| 2483 | + } | |
| 2484 | + sport->port.line = ret; | |
| 2485 | + | |
| 2480 | 2486 | ret = lpuart_enable_clks(sport); |
| 2481 | 2487 | if (ret) |
| 2482 | − return ret; | |
| 2488 | + goto failed_clock_enable; | |
| 2483 | 2489 | sport->port.uartclk = lpuart_get_baud_clk_rate(sport); |
| 2484 | 2490 | |
| 2485 | 2491 | lpuart_ports[sport->port.line] = sport; |
| @@ -2529,6 +2535,10 @@ static int lpuart_probe(struct platform_device *pdev) · 43 unmodified lines | ||
| 2529 | 2535 | failed_attach_port: |
| 2530 | 2536 | failed_irq_request: |
| 2531 | 2537 | lpuart_disable_clks(sport); |
| 2538 | +failed_clock_enable: | |
| 2539 | +failed_out_of_range: | |
| 2540 | + if (sport->id_allocated) | |
| 2541 | + ida_simple_remove(&fsl_lpuart_ida, sport->port.line); | |
| 2532 | 2542 | return ret; |
| 2533 | 2543 | } |
| 2534 | 2544 | |
| @@ -2538,7 +2548,8 @@ static int lpuart_remove(struct platform_device *pdev) · 3 unmodified lines | ||
| 2538 | 2548 | |
| 2539 | 2549 | uart_remove_one_port(&lpuart_reg, &sport->port); |
| 2540 | 2550 | |
| 2541 | − ida_simple_remove(&fsl_lpuart_ida, sport->port.line); | |
| 2551 | + if (sport->id_allocated) | |
| 2552 | + ida_simple_remove(&fsl_lpuart_ida, sport->port.line); | |
| 2542 | 2553 | |
| 2543 | 2554 | lpuart_disable_clks(sport); |
| 2544 | 2555 | |
| @@ -851,7 +851,7 @@ static int mvebu_uart_probe(struct platform_device *pdev) · 850 unmodified lines | ||
| 851 | 851 | |
| 852 | 852 | port->membase = devm_ioremap_resource(&pdev->dev, reg); |
| 853 | 853 | if (IS_ERR(port->membase)) |
| 854 | − return -PTR_ERR(port->membase); | |
| 854 | + return PTR_ERR(port->membase); | |
| 855 | 855 | |
| 856 | 856 | mvuart = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_uart), |
| 857 | 857 | GFP_KERNEL); |
| @@ -1589,9 +1589,7 @@ void tty_kclose(struct tty_struct *tty) · 1588 unmodified lines | ||
| 1589 | 1589 | tty_debug_hangup(tty, "freeing structure\n"); |
| 1590 | 1590 | /* |
| 1591 | 1591 | * The release_tty function takes care of the details of clearing |
| 1592 | − * the slots and preserving the termios structure. The tty_unlock_pair | |
| 1593 | − * should be safe as we keep a kref while the tty is locked (so the | |
| 1594 | − * unlock never unlocks a freed tty). | |
| 1592 | + * the slots and preserving the termios structure. | |
| 1595 | 1593 | */ |
| 1596 | 1594 | mutex_lock(&tty_mutex); |
| 1597 | 1595 | tty_port_set_kopened(tty->port, 0); |
| @@ -1621,9 +1619,7 @@ void tty_release_struct(struct tty_struct *tty, int idx) · 23 unmodified lines | ||
| 1621 | 1619 | tty_debug_hangup(tty, "freeing structure\n"); |
| 1622 | 1620 | /* |
| 1623 | 1621 | * The release_tty function takes care of the details of clearing |
| 1624 | − * the slots and preserving the termios structure. The tty_unlock_pair | |
| 1625 | − * should be safe as we keep a kref while the tty is locked (so the | |
| 1626 | − * unlock never unlocks a freed tty). | |
| 1622 | + * the slots and preserving the termios structure. | |
| 1627 | 1623 | */ |
| 1628 | 1624 | mutex_lock(&tty_mutex); |
| 1629 | 1625 | release_tty(tty, idx); |
| @@ -2734,9 +2730,11 @@ static int compat_tty_tiocgserial(struct tty_struct *tty, · 1104 unmodified lines | ||
| 2734 | 2730 | struct serial_struct32 v32; |
| 2735 | 2731 | struct serial_struct v; |
| 2736 | 2732 | int err; |
| 2737 | − memset(&v, 0, sizeof(struct serial_struct)); | |
| 2738 | 2733 | |
| 2739 | − if (!tty->ops->set_serial) | |
| 2734 | + memset(&v, 0, sizeof(v)); | |
| 2735 | + memset(&v32, 0, sizeof(v32)); | |
| 2736 | + | |
| 2737 | + if (!tty->ops->get_serial) | |
| 2740 | 2738 | return -ENOTTY; |
| 2741 | 2739 | err = tty->ops->get_serial(tty, &v); |
| 2742 | 2740 | if (!err) { |
| @@ -181,7 +181,7 @@ int set_selection_user(const struct tiocl_selection __user *sel, · 180 unmodified lines | ||
| 181 | 181 | return set_selection_kernel(&v, tty); |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | −int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) | |
| 184 | +static int __set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) | |
| 185 | 185 | { |
| 186 | 186 | struct vc_data *vc = vc_cons[fg_console].d; |
| 187 | 187 | int new_sel_start, new_sel_end, spc; |
| @@ -214,7 +214,6 @@ int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) · 26 unmodified lines | ||
| 214 | 214 | if (ps > pe) /* make sel_start <= sel_end */ |
| 215 | 215 | swap(ps, pe); |
| 216 | 216 | |
| 217 | − mutex_lock(&sel_lock); | |
| 218 | 217 | if (sel_cons != vc_cons[fg_console].d) { |
| 219 | 218 | clear_selection(); |
| 220 | 219 | sel_cons = vc_cons[fg_console].d; |
| @@ -260,10 +259,9 @@ int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) · 39 unmodified lines | ||
| 260 | 259 | break; |
| 261 | 260 | case TIOCL_SELPOINTER: |
| 262 | 261 | highlight_pointer(pe); |
| 263 | − goto unlock; | |
| 262 | + return 0; | |
| 264 | 263 | default: |
| 265 | − ret = -EINVAL; | |
| 266 | − goto unlock; | |
| 264 | + return -EINVAL; | |
| 267 | 265 | } |
| 268 | 266 | |
| 269 | 267 | /* remove the pointer */ |
| @@ -285,7 +283,7 @@ int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) · 15 unmodified lines | ||
| 285 | 283 | else if (new_sel_start == sel_start) |
| 286 | 284 | { |
| 287 | 285 | if (new_sel_end == sel_end) /* no action required */ |
| 288 | − goto unlock; | |
| 286 | + return 0; | |
| 289 | 287 | else if (new_sel_end > sel_end) /* extend to right */ |
| 290 | 288 | highlight(sel_end + 2, new_sel_end); |
| 291 | 289 | else /* contract from right */ |
| @@ -313,8 +311,7 @@ int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) · 21 unmodified lines | ||
| 313 | 311 | if (!bp) { |
| 314 | 312 | printk(KERN_WARNING "selection: kmalloc() failed\n"); |
| 315 | 313 | clear_selection(); |
| 316 | − ret = -ENOMEM; | |
| 317 | − goto unlock; | |
| 314 | + return -ENOMEM; | |
| 318 | 315 | } |
| 319 | 316 | kfree(sel_buffer); |
| 320 | 317 | sel_buffer = bp; |
| @@ -339,8 +336,20 @@ int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) · 18 unmodified lines | ||
| 339 | 336 | } |
| 340 | 337 | } |
| 341 | 338 | sel_buffer_lth = bp - sel_buffer; |
| 342 | −unlock: | |
| 339 | + | |
| 340 | + return ret; | |
| 341 | +} | |
| 342 | + | |
| 343 | +int set_selection_kernel(struct tiocl_selection *v, struct tty_struct *tty) | |
| 344 | +{ | |
| 345 | + int ret; | |
| 346 | + | |
| 347 | + mutex_lock(&sel_lock); | |
| 348 | + console_lock(); | |
| 349 | + ret = __set_selection_kernel(v, tty); | |
| 350 | + console_unlock(); | |
| 343 | 351 | mutex_unlock(&sel_lock); |
| 352 | + | |
| 344 | 353 | return ret; |
| 345 | 354 | } |
| 346 | 355 | EXPORT_SYMBOL_GPL(set_selection_kernel); |
| @@ -3046,10 +3046,8 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) · 3045 unmodified lines | ||
| 3046 | 3046 | switch (type) |
| 3047 | 3047 | { |
| 3048 | 3048 | case TIOCL_SETSEL: |
| 3049 | − console_lock(); | |
| 3050 | 3049 | ret = set_selection_user((struct tiocl_selection |
| 3051 | 3050 | __user *)(p+1), tty); |
| 3052 | − console_unlock(); | |
| 3053 | 3051 | break; |
| 3054 | 3052 | case TIOCL_PASTESEL: |
| 3055 | 3053 | ret = paste_selection(tty); |
| @@ -2550,7 +2550,7 @@ found: · 2549 unmodified lines | ||
| 2550 | 2550 | /* Update ring only if removed request is on pending_req_list list */ |
| 2551 | 2551 | if (req_on_hw_ring) { |
| 2552 | 2552 | link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma + |
| 2553 | − (priv_req->start_trb * TRB_SIZE)); | |
| 2553 | + ((priv_req->end_trb + 1) * TRB_SIZE)); | |
| 2554 | 2554 | link_trb->control = (link_trb->control & TRB_CYCLE) | |
| 2555 | 2555 | TRB_TYPE(TRB_LINK) | TRB_CHAIN; |
| 2556 | 2556 | |
| @@ -2595,11 +2595,21 @@ int __cdns3_gadget_ep_clear_halt(struct cdns3_endpoint *priv_ep) · 38 unmodified lines | ||
| 2595 | 2595 | { |
| 2596 | 2596 | struct cdns3_device *priv_dev = priv_ep->cdns3_dev; |
| 2597 | 2597 | struct usb_request *request; |
| 2598 | + struct cdns3_request *priv_req; | |
| 2599 | + struct cdns3_trb *trb = NULL; | |
| 2598 | 2600 | int ret; |
| 2599 | 2601 | int val; |
| 2600 | 2602 | |
| 2601 | 2603 | trace_cdns3_halt(priv_ep, 0, 0); |
| 2602 | 2604 | |
| 2605 | + request = cdns3_next_request(&priv_ep->pending_req_list); | |
| 2606 | + if (request) { | |
| 2607 | + priv_req = to_cdns3_request(request); | |
| 2608 | + trb = priv_req->trb; | |
| 2609 | + if (trb) | |
| 2610 | + trb->control = trb->control ^ TRB_CYCLE; | |
| 2611 | + } | |
19 more lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 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 44 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 261 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 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 35 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 26 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 388 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 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 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 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 32 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 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 160 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 148 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 51 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 339 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 114 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 183 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 85 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 22 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 26 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 165 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 25 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 14 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 1139 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 51 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 16 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 31 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 12 lines aren’t shown here.
This diff is large: its 39 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 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 52 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 19 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
File mode changed from 100644 to 100755.
This diff is large: its 52 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 27 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 77 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 13 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 54 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 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 8 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 303 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 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 24 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 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 99 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 34 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.