Thierry needs fd70c7755bf0 ("drm/bridge: tc358767: fix max_tu_symbol value") to be able to merge his dp_link patch series. Some adjacent changes conflicts, plus some clashes in i915 due to cherry-picking and git trying to be helpful and leaving both versions in.
Unified · Split
| @@ -1637,6 +1637,10 @@ S: Panoramastrasse 18 · 1636 unmodified lines | ||
| 1637 | 1637 | S: D-69126 Heidelberg |
| 1638 | 1638 | S: Germany |
| 1639 | 1639 | |
| 1640 | +N: Simon Horman | |
| 1641 | +M: horms@verge.net.au | |
| 1642 | +D: Renesas ARM/ARM64 SoC maintainer | |
| 1643 | + | |
| 1640 | 1644 | N: Christopher Horn |
| 1641 | 1645 | E: chorn@warwick.net |
| 1642 | 1646 | D: Miscellaneous sysctl hacks |
| @@ -615,8 +615,8 @@ on an IO device and is an example of this type. · 614 unmodified lines | ||
| 615 | 615 | Protections |
| 616 | 616 | ----------- |
| 617 | 617 | |
| 618 | −A cgroup is protected to be allocated upto the configured amount of | |
| 619 | −the resource if the usages of all its ancestors are under their | |
| 618 | +A cgroup is protected upto the configured amount of the resource | |
| 619 | +as long as the usages of all its ancestors are under their | |
| 620 | 620 | protected levels. Protections can be hard guarantees or best effort |
| 621 | 621 | soft boundaries. Protections can also be over-committed in which case |
| 622 | 622 | only upto the amount available to the parent is protected among |
| @@ -1096,7 +1096,10 @@ PAGE_SIZE multiple when read back. · 473 unmodified lines | ||
| 1096 | 1096 | is within its effective min boundary, the cgroup's memory |
| 1097 | 1097 | won't be reclaimed under any conditions. If there is no |
| 1098 | 1098 | unprotected reclaimable memory available, OOM killer |
| 1099 | − is invoked. | |
| 1099 | + is invoked. Above the effective min boundary (or | |
| 1100 | + effective low boundary if it is higher), pages are reclaimed | |
| 1101 | + proportionally to the overage, reducing reclaim pressure for | |
| 1102 | + smaller overages. | |
| 1100 | 1103 | |
| 1101 | 1104 | Effective min boundary is limited by memory.min values of |
| 1102 | 1105 | all ancestor cgroups. If there is memory.min overcommitment |
| @@ -1118,7 +1121,10 @@ PAGE_SIZE multiple when read back. · 15 unmodified lines | ||
| 1118 | 1121 | Best-effort memory protection. If the memory usage of a |
| 1119 | 1122 | cgroup is within its effective low boundary, the cgroup's |
| 1120 | 1123 | memory won't be reclaimed unless memory can be reclaimed |
| 1121 | − from unprotected cgroups. | |
| 1124 | + from unprotected cgroups. Above the effective low boundary (or | |
| 1125 | + effective min boundary if it is higher), pages are reclaimed | |
| 1126 | + proportionally to the overage, reducing reclaim pressure for | |
| 1127 | + smaller overages. | |
| 1122 | 1128 | |
| 1123 | 1129 | Effective low boundary is limited by memory.low values of |
| 1124 | 1130 | all ancestor cgroups. If there is memory.low overcommitment |
| @@ -2482,8 +2488,10 @@ system performance due to overreclaim, to the point where the feature · 1357 unmodified lines | ||
| 2482 | 2488 | becomes self-defeating. |
| 2483 | 2489 | |
| 2484 | 2490 | The memory.low boundary on the other hand is a top-down allocated |
| 2485 | −reserve. A cgroup enjoys reclaim protection when it's within its low, | |
| 2486 | −which makes delegation of subtrees possible. | |
| 2491 | +reserve. A cgroup enjoys reclaim protection when it's within its | |
| 2492 | +effective low, which makes delegation of subtrees possible. It also | |
| 2493 | +enjoys having reclaim pressure proportional to its overage when | |
| 2494 | +above its effective low. | |
| 2487 | 2495 | |
| 2488 | 2496 | The original high boundary, the hard limit, is defined as a strict |
| 2489 | 2497 | limit that can not budge, even if the OOM killer has to be called. |
| @@ -5302,6 +5302,10 @@ · 5301 unmodified lines | ||
| 5302 | 5302 | the unplug protocol |
| 5303 | 5303 | never -- do not unplug even if version check succeeds |
| 5304 | 5304 | |
| 5305 | + xen_legacy_crash [X86,XEN] | |
| 5306 | + Crash from Xen panic notifier, without executing late | |
| 5307 | + panic() code such as dumping handler. | |
| 5308 | + | |
| 5305 | 5309 | xen_nopvspin [X86,XEN] |
| 5306 | 5310 | Disables the ticketlock slowpath using Xen PV |
| 5307 | 5311 | optimizations. |
| @@ -154,11 +154,18 @@ return virtual addresses to userspace from a 48-bit range. · 153 unmodified lines | ||
| 154 | 154 | |
| 155 | 155 | Software can "opt-in" to receiving VAs from a 52-bit space by |
| 156 | 156 | specifying an mmap hint parameter that is larger than 48-bit. |
| 157 | + | |
| 157 | 158 | For example: |
| 158 | − maybe_high_address = mmap(~0UL, size, prot, flags,...); | |
| 159 | + | |
| 160 | +.. code-block:: c | |
| 161 | + | |
| 162 | + maybe_high_address = mmap(~0UL, size, prot, flags,...); | |
| 159 | 163 | |
| 160 | 164 | It is also possible to build a debug kernel that returns addresses |
| 161 | 165 | from a 52-bit space by enabling the following kernel config options: |
| 166 | + | |
| 167 | +.. code-block:: sh | |
| 168 | + | |
| 162 | 169 | CONFIG_EXPERT=y && CONFIG_ARM64_FORCE_52BIT=y |
| 163 | 170 | |
| 164 | 171 | Note that this option is only intended for debugging applications |
| @@ -107,6 +107,8 @@ stable kernels. · 106 unmodified lines | ||
| 107 | 107 | +----------------+-----------------+-----------------+-----------------------------+ |
| 108 | 108 | | Cavium | ThunderX2 SMMUv3| #126 | N/A | |
| 109 | 109 | +----------------+-----------------+-----------------+-----------------------------+ |
| 110 | +| Cavium | ThunderX2 Core | #219 | CAVIUM_TX2_ERRATUM_219 | | |
| 111 | ++----------------+-----------------+-----------------+-----------------------------+ | |
| 110 | 112 | +----------------+-----------------+-----------------+-----------------------------+ |
| 111 | 113 | | Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585 | |
| 112 | 114 | +----------------+-----------------+-----------------+-----------------------------+ |
| @@ -38,6 +38,7 @@ Core utilities · 37 unmodified lines | ||
| 38 | 38 | protection-keys |
| 39 | 39 | ../RCU/index |
| 40 | 40 | gcc-plugins |
| 41 | + symbol-namespaces | |
| 41 | 42 | |
| 42 | 43 | |
| 43 | 44 | Interfaces for kernel debugging |
| @@ -98,6 +98,10 @@ limited. The actual limit depends on the hardware and the kernel · 97 unmodified lines | ||
| 98 | 98 | configuration, but it is a good practice to use `kmalloc` for objects |
| 99 | 99 | smaller than page size. |
| 100 | 100 | |
| 101 | +The address of a chunk allocated with `kmalloc` is aligned to at least | |
| 102 | +ARCH_KMALLOC_MINALIGN bytes. For sizes which are a power of two, the | |
| 103 | +alignment is also guaranteed to be at least the respective size. | |
| 104 | + | |
| 101 | 105 | For large allocations you can use :c:func:`vmalloc` and |
| 102 | 106 | :c:func:`vzalloc`, or directly request pages from the page |
| 103 | 107 | allocator. The memory allocated by `vmalloc` and related functions is |
File renamed without changes.
| @@ -41,6 +41,9 @@ smaller binary while the latter is 1.1 - 2 times faster. · 40 unmodified lines | ||
| 41 | 41 | Both KASAN modes work with both SLUB and SLAB memory allocators. |
| 42 | 42 | For better bug detection and nicer reporting, enable CONFIG_STACKTRACE. |
| 43 | 43 | |
| 44 | +To augment reports with last allocation and freeing stack of the physical page, | |
| 45 | +it is recommended to enable also CONFIG_PAGE_OWNER and boot with page_owner=on. | |
| 46 | + | |
| 44 | 47 | To disable instrumentation for specific files or directories, add a line |
| 45 | 48 | similar to the following to the respective kernel Makefile: |
| 46 | 49 | |
| @@ -89,6 +89,22 @@ To build, save output files in a separate directory with KBUILD_OUTPUT :: · 88 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | $ export KBUILD_OUTPUT=/tmp/kselftest; make TARGETS="size timers" kselftest |
| 91 | 91 | |
| 92 | +Additionally you can use the "SKIP_TARGETS" variable on the make command | |
| 93 | +line to specify one or more targets to exclude from the TARGETS list. | |
| 94 | + | |
| 95 | +To run all tests but a single subsystem:: | |
| 96 | + | |
| 97 | + $ make -C tools/testing/selftests SKIP_TARGETS=ptrace run_tests | |
| 98 | + | |
| 99 | +You can specify multiple tests to skip:: | |
| 100 | + | |
| 101 | + $ make SKIP_TARGETS="size timers" kselftest | |
| 102 | + | |
| 103 | +You can also specify a restricted list of tests to run together with a | |
| 104 | +dedicated skiplist:: | |
| 105 | + | |
| 106 | + $ make TARGETS="bpf breakpoints size timers" SKIP_TARGETS=bpf kselftest | |
| 107 | + | |
| 92 | 108 | See the top-level tools/testing/selftests/Makefile for the list of all |
| 93 | 109 | possible targets. |
| 94 | 110 | |
| @@ -1,8 +1,11 @@ | ||
| 1 | 1 | * Advanced Interrupt Controller (AIC) |
| 2 | 2 | |
| 3 | 3 | Required properties: |
| 4 | −- compatible: Should be "atmel,<chip>-aic" | |
| 5 | − <chip> can be "at91rm9200", "sama5d2", "sama5d3" or "sama5d4" | |
| 4 | +- compatible: Should be: | |
| 5 | + - "atmel,<chip>-aic" where <chip> can be "at91rm9200", "sama5d2", | |
| 6 | + "sama5d3" or "sama5d4" | |
| 7 | + - "microchip,<chip>-aic" where <chip> can be "sam9x60" | |
| 8 | + | |
| 6 | 9 | - interrupt-controller: Identifies the node as an interrupt controller. |
| 7 | 10 | - #interrupt-cells: The number of cells to define the interrupts. It should be 3. |
| 8 | 11 | The first cell is the IRQ number (aka "Peripheral IDentifier" on datasheet). |
| @@ -26,6 +26,8 @@ Required properties: · 25 unmodified lines | ||
| 26 | 26 | - "renesas,hscif-r8a77470" for R8A77470 (RZ/G1C) HSCIF compatible UART. |
| 27 | 27 | - "renesas,scif-r8a774a1" for R8A774A1 (RZ/G2M) SCIF compatible UART. |
| 28 | 28 | - "renesas,hscif-r8a774a1" for R8A774A1 (RZ/G2M) HSCIF compatible UART. |
| 29 | + - "renesas,scif-r8a774b1" for R8A774B1 (RZ/G2N) SCIF compatible UART. | |
| 30 | + - "renesas,hscif-r8a774b1" for R8A774B1 (RZ/G2N) HSCIF compatible UART. | |
| 29 | 31 | - "renesas,scif-r8a774c0" for R8A774C0 (RZ/G2E) SCIF compatible UART. |
| 30 | 32 | - "renesas,hscif-r8a774c0" for R8A774C0 (RZ/G2E) HSCIF compatible UART. |
| 31 | 33 | - "renesas,scif-r8a7778" for R8A7778 (R-Car M1) SCIF compatible UART. |
| @@ -85,8 +85,8 @@ A child node must exist to represent the core DWC2 IP block. The name of · 84 unmodified lines | ||
| 85 | 85 | the node is not important. The content of the node is defined in dwc2.txt. |
| 86 | 86 | |
| 87 | 87 | PHY documentation is provided in the following places: |
| 88 | −- Documentation/devicetree/bindings/phy/meson-g12a-usb2-phy.txt | |
| 89 | −- Documentation/devicetree/bindings/phy/meson-g12a-usb3-pcie-phy.txt | |
| 88 | +- Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb2-phy.yaml | |
| 89 | +- Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml | |
| 90 | 90 | |
| 91 | 91 | Example device nodes: |
| 92 | 92 | usb: usb@ffe09000 { |
| @@ -63,7 +63,11 @@ properties: · 62 unmodified lines | ||
| 63 | 63 | description: |
| 64 | 64 | Set this flag to force EHCI reset after resume. |
| 65 | 65 | |
| 66 | − phys: true | |
| 66 | + phys: | |
| 67 | + description: PHY specifier for the USB PHY | |
| 68 | + | |
| 69 | + phy-names: | |
| 70 | + const: usb | |
| 67 | 71 | |
| 68 | 72 | required: |
| 69 | 73 | - compatible |
| @@ -89,6 +93,7 @@ examples: · 19 unmodified lines | ||
| 89 | 93 | interrupts = <39>; |
| 90 | 94 | clocks = <&ahb_gates 1>; |
| 91 | 95 | phys = <&usbphy 1>; |
| 96 | + phy-names = "usb"; | |
| 92 | 97 | }; |
| 93 | 98 | |
| 94 | 99 | ... |
| @@ -67,7 +67,11 @@ properties: · 66 unmodified lines | ||
| 67 | 67 | description: |
| 68 | 68 | Overrides the detected port count |
| 69 | 69 | |
| 70 | − phys: true | |
| 70 | + phys: | |
| 71 | + description: PHY specifier for the USB PHY | |
| 72 | + | |
| 73 | + phy-names: | |
| 74 | + const: usb | |
| 71 | 75 | |
| 72 | 76 | required: |
| 73 | 77 | - compatible |
| @@ -84,6 +88,7 @@ examples: · 10 unmodified lines | ||
| 84 | 88 | interrupts = <64>; |
| 85 | 89 | clocks = <&usb_clk 6>, <&ahb_gates 2>; |
| 86 | 90 | phys = <&usbphy 1>; |
| 91 | + phy-names = "usb"; | |
| 87 | 92 | }; |
| 88 | 93 | |
| 89 | 94 | ... |
| @@ -33,7 +33,7 @@ Required properties: · 32 unmodified lines | ||
| 33 | 33 | "dma_ck": dma_bus clock for data transfer by DMA, |
| 34 | 34 | "xhci_ck": controller clock |
| 35 | 35 | |
| 36 | − - phys : see usb-hcd.txt in the current directory | |
| 36 | + - phys : see usb-hcd.yaml in the current directory | |
| 37 | 37 | |
| 38 | 38 | Optional properties: |
| 39 | 39 | - wakeup-source : enable USB remote wakeup; |
| @@ -53,7 +53,7 @@ Optional properties: · 13 unmodified lines | ||
| 53 | 53 | See: Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt |
| 54 | 54 | - imod-interval-ns: default interrupt moderation interval is 5000ns |
| 55 | 55 | |
| 56 | −additionally the properties from usb-hcd.txt (in the current directory) are | |
| 56 | +additionally the properties from usb-hcd.yaml (in the current directory) are | |
| 57 | 57 | supported. |
| 58 | 58 | |
| 59 | 59 | Example: |
| @@ -17,7 +17,7 @@ Required properties: · 16 unmodified lines | ||
| 17 | 17 | - clock-names : must contain "sys_ck" for clock of controller, |
| 18 | 18 | the following clocks are optional: |
| 19 | 19 | "ref_ck", "mcu_ck" and "dma_ck"; |
| 20 | − - phys : see usb-hcd.txt in the current directory | |
| 20 | + - phys : see usb-hcd.yaml in the current directory | |
| 21 | 21 | - dr_mode : should be one of "host", "peripheral" or "otg", |
| 22 | 22 | refer to usb/generic.txt |
| 23 | 23 | |
| @@ -60,7 +60,7 @@ Optional properties: · 36 unmodified lines | ||
| 60 | 60 | - mediatek,u3p-dis-msk : mask to disable u3ports, bit0 for u3port0, |
| 61 | 61 | bit1 for u3port1, ... etc; |
| 62 | 62 | |
| 63 | −additionally the properties from usb-hcd.txt (in the current directory) are | |
| 63 | +additionally the properties from usb-hcd.yaml (in the current directory) are | |
| 64 | 64 | supported. |
| 65 | 65 | |
| 66 | 66 | Sub-nodes: |
| @@ -18,8 +18,13 @@ properties: · 17 unmodified lines | ||
| 18 | 18 | description: |
| 19 | 19 | List of all the USB PHYs on this HCD |
| 20 | 20 | |
| 21 | + phy-names: | |
| 22 | + description: | |
| 23 | + Name specifier for the USB PHY | |
| 24 | + | |
| 21 | 25 | examples: |
| 22 | 26 | - | |
| 23 | 27 | usb { |
| 24 | 28 | phys = <&usb2_phy1>, <&usb3_phy1>; |
| 29 | + phy-names = "usb"; | |
| 25 | 30 | }; |
| @@ -6,7 +6,7 @@ Required properties: · 5 unmodified lines | ||
| 6 | 6 | - reg : Should contain 1 register ranges(address and length) |
| 7 | 7 | - interrupts : UHCI controller interrupt |
| 8 | 8 | |
| 9 | −additionally the properties from usb-hcd.txt (in the current directory) are | |
| 9 | +additionally the properties from usb-hcd.yaml (in the current directory) are | |
| 10 | 10 | supported. |
| 11 | 11 | |
| 12 | 12 | Example: |
| @@ -41,9 +41,9 @@ Optional properties: · 40 unmodified lines | ||
| 41 | 41 | - usb3-lpm-capable: determines if platform is USB3 LPM capable |
| 42 | 42 | - quirk-broken-port-ped: set if the controller has broken port disable mechanism |
| 43 | 43 | - imod-interval-ns: default interrupt moderation interval is 5000ns |
| 44 | − - phys : see usb-hcd.txt in the current directory | |
| 44 | + - phys : see usb-hcd.yaml in the current directory | |
| 45 | 45 | |
| 46 | −additionally the properties from usb-hcd.txt (in the current directory) are | |
| 46 | +additionally the properties from usb-hcd.yaml (in the current directory) are | |
| 47 | 47 | supported. |
| 48 | 48 | |
| 49 | 49 | |
| @@ -7,6 +7,7 @@ Linux Hardware Monitoring · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | hwmon-kernel-api |
| 9 | 9 | pmbus-core |
| 10 | + inspur-ipsps1 | |
| 10 | 11 | submitting-patches |
| 11 | 12 | sysfs-interface |
| 12 | 13 | userspace-tools |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | Kernel driver inspur-ipsps1 |
| 2 | −======================= | |
| 2 | +=========================== | |
| 3 | 3 | |
| 4 | 4 | Supported chips: |
| 5 | 5 | |
| @@ -21,10 +21,17 @@ Supported chips: · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | * AMD Family 14h processors: "Brazos" (C/E/G/Z-Series) |
| 23 | 23 | |
| 24 | −* AMD Family 15h processors: "Bulldozer" (FX-Series), "Trinity", "Kaveri", "Carrizo" | |
| 24 | +* AMD Family 15h processors: "Bulldozer" (FX-Series), "Trinity", "Kaveri", | |
| 25 | + "Carrizo", "Stoney Ridge", "Bristol Ridge" | |
| 25 | 26 | |
| 26 | 27 | * AMD Family 16h processors: "Kabini", "Mullins" |
| 27 | 28 | |
| 29 | +* AMD Family 17h processors: "Zen", "Zen 2" | |
| 30 | + | |
| 31 | +* AMD Family 18h processors: "Hygon Dhyana" | |
| 32 | + | |
| 33 | +* AMD Family 19h processors: "Zen 3" | |
| 34 | + | |
| 28 | 35 | Prefix: 'k10temp' |
| 29 | 36 | |
| 30 | 37 | Addresses scanned: PCI space |
| @@ -110,3 +117,12 @@ The maximum value for Tctl is available in the file temp1_max. · 79 unmodified lines | ||
| 110 | 117 | If the BIOS has enabled hardware temperature control, the threshold at |
| 111 | 118 | which the processor will throttle itself to avoid damage is available in |
| 112 | 119 | temp1_crit and temp1_crit_hyst. |
| 120 | + | |
| 121 | +On some AMD CPUs, there is a difference between the die temperature (Tdie) and | |
| 122 | +the reported temperature (Tctl). Tdie is the real measured temperature, and | |
| 123 | +Tctl is used for fan control. While Tctl is always available as temp1_input, | |
| 124 | +the driver exports Tdie temperature as temp2_input for those CPUs which support | |
| 125 | +it. | |
| 126 | + | |
| 127 | +Models from 17h family report relative temperature, the driver aims to | |
| 128 | +compensate and report the real temperature. | |
| @@ -36,8 +36,10 @@ Support · 35 unmodified lines | ||
| 36 | 36 | ======= |
| 37 | 37 | For general Linux networking support, please use the netdev mailing |
| 38 | 38 | list, which is monitored by Pensando personnel:: |
| 39 | + | |
| 39 | 40 | netdev@vger.kernel.org |
| 40 | 41 | |
| 41 | 42 | For more specific support needs, please use the Pensando driver support |
| 42 | 43 | email:: |
| 43 | − drivers@pensando.io | |
| 44 | + | |
| 45 | + drivers@pensando.io | |
| @@ -92,16 +92,16 @@ under some conditions. · 91 unmodified lines | ||
| 92 | 92 | Part III: Registering a Network Device to DIM |
| 93 | 93 | ============================================== |
| 94 | 94 | |
| 95 | −Net DIM API exposes the main function net_dim(struct net_dim *dim, | |
| 96 | −struct net_dim_sample end_sample). This function is the entry point to the Net | |
| 95 | +Net DIM API exposes the main function net_dim(struct dim *dim, | |
| 96 | +struct dim_sample end_sample). This function is the entry point to the Net | |
| 97 | 97 | DIM algorithm and has to be called every time the driver would like to check if |
| 98 | 98 | it should change interrupt moderation parameters. The driver should provide two |
| 99 | −data structures: struct net_dim and struct net_dim_sample. Struct net_dim | |
| 99 | +data structures: struct dim and struct dim_sample. Struct dim | |
| 100 | 100 | describes the state of DIM for a specific object (RX queue, TX queue, |
| 101 | 101 | other queues, etc.). This includes the current selected profile, previous data |
| 102 | 102 | samples, the callback function provided by the driver and more. |
| 103 | −Struct net_dim_sample describes a data sample, which will be compared to the | |
| 104 | −data sample stored in struct net_dim in order to decide on the algorithm's next | |
| 103 | +Struct dim_sample describes a data sample, which will be compared to the | |
| 104 | +data sample stored in struct dim in order to decide on the algorithm's next | |
| 105 | 105 | step. The sample should include bytes, packets and interrupts, measured by |
| 106 | 106 | the driver. |
| 107 | 107 | |
| @@ -110,9 +110,9 @@ main net_dim() function. The recommended method is to call net_dim() on each · 2 unmodified lines | ||
| 110 | 110 | interrupt. Since Net DIM has a built-in moderation and it might decide to skip |
| 111 | 111 | iterations under certain conditions, there is no need to moderate the net_dim() |
| 112 | 112 | calls as well. As mentioned above, the driver needs to provide an object of type |
| 113 | −struct net_dim to the net_dim() function call. It is advised for each entity | |
| 114 | −using Net DIM to hold a struct net_dim as part of its data structure and use it | |
| 115 | −as the main Net DIM API object. The struct net_dim_sample should hold the latest | |
| 113 | +struct dim to the net_dim() function call. It is advised for each entity | |
| 114 | +using Net DIM to hold a struct dim as part of its data structure and use it | |
| 115 | +as the main Net DIM API object. The struct dim_sample should hold the latest | |
| 116 | 116 | bytes, packets and interrupts count. No need to perform any calculations, just |
| 117 | 117 | include the raw data. |
| 118 | 118 | |
| @@ -132,19 +132,19 @@ usage is not complete but it should make the outline of the usage clear. · 13 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | my_driver.c: |
| 134 | 134 | |
| 135 | −#include <linux/net_dim.h> | |
| 135 | +#include <linux/dim.h> | |
| 136 | 136 | |
| 137 | 137 | /* Callback for net DIM to schedule on a decision to change moderation */ |
| 138 | 138 | void my_driver_do_dim_work(struct work_struct *work) |
| 139 | 139 | { |
| 140 | − /* Get struct net_dim from struct work_struct */ | |
| 141 | − struct net_dim *dim = container_of(work, struct net_dim, | |
| 142 | − work); | |
| 140 | + /* Get struct dim from struct work_struct */ | |
| 141 | + struct dim *dim = container_of(work, struct dim, | |
| 142 | + work); | |
| 143 | 143 | /* Do interrupt moderation related stuff */ |
| 144 | 144 | ... |
| 145 | 145 | |
| 146 | 146 | /* Signal net DIM work is done and it should move to next iteration */ |
| 147 | − dim->state = NET_DIM_START_MEASURE; | |
| 147 | + dim->state = DIM_START_MEASURE; | |
| 148 | 148 | } |
| 149 | 149 | |
| 150 | 150 | /* My driver's interrupt handler */ |
| @@ -152,13 +152,13 @@ int my_driver_handle_interrupt(struct my_driver_entity *my_entity, ...) · 1 unmodified line | ||
| 152 | 152 | { |
| 153 | 153 | ... |
| 154 | 154 | /* A struct to hold current measured data */ |
| 155 | − struct net_dim_sample dim_sample; | |
| 155 | + struct dim_sample dim_sample; | |
| 156 | 156 | ... |
| 157 | 157 | /* Initiate data sample struct with current data */ |
| 158 | − net_dim_sample(my_entity->events, | |
| 159 | − my_entity->packets, | |
| 160 | − my_entity->bytes, | |
| 161 | − &dim_sample); | |
| 158 | + dim_update_sample(my_entity->events, | |
| 159 | + my_entity->packets, | |
| 160 | + my_entity->bytes, | |
| 161 | + &dim_sample); | |
| 162 | 162 | /* Call net DIM */ |
| 163 | 163 | net_dim(&my_entity->dim, dim_sample); |
| 164 | 164 | ... |
| @@ -56,7 +56,7 @@ instead of ``double-indenting`` the ``case`` labels. E.g.: · 55 unmodified lines | ||
| 56 | 56 | case 'K': |
| 57 | 57 | case 'k': |
| 58 | 58 | mem <<= 10; |
| 59 | − /* fall through */ | |
| 59 | + fallthrough; | |
| 60 | 60 | default: |
| 61 | 61 | break; |
| 62 | 62 | } |
| @@ -122,14 +122,27 @@ memory adjacent to the stack (when built without `CONFIG_VMAP_STACK=y`) · 121 unmodified lines | ||
| 122 | 122 | |
| 123 | 123 | Implicit switch case fall-through |
| 124 | 124 | --------------------------------- |
| 125 | −The C language allows switch cases to "fall through" when | |
| 126 | −a "break" statement is missing at the end of a case. This, | |
| 127 | −however, introduces ambiguity in the code, as it's not always | |
| 128 | −clear if the missing break is intentional or a bug. As there | |
| 129 | −have been a long list of flaws `due to missing "break" statements | |
| 125 | +The C language allows switch cases to "fall-through" when a "break" statement | |
| 126 | +is missing at the end of a case. This, however, introduces ambiguity in the | |
| 127 | +code, as it's not always clear if the missing break is intentional or a bug. | |
| 128 | + | |
| 129 | +As there have been a long list of flaws `due to missing "break" statements | |
| 130 | 130 | <https://cwe.mitre.org/data/definitions/484.html>`_, we no longer allow |
| 131 | −"implicit fall-through". In order to identify an intentional fall-through | |
| 132 | −case, we have adopted the marking used by static analyzers: a comment | |
| 133 | −saying `/* Fall through */`. Once the C++17 `__attribute__((fallthrough))` | |
| 134 | −is more widely handled by C compilers, static analyzers, and IDEs, we can | |
| 135 | −switch to using that instead. | |
| 131 | +"implicit fall-through". | |
| 132 | + | |
| 133 | +In order to identify intentional fall-through cases, we have adopted a | |
| 134 | +pseudo-keyword macro 'fallthrough' which expands to gcc's extension | |
| 135 | +__attribute__((__fallthrough__)). `Statement Attributes | |
| 136 | +<https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_ | |
| 137 | + | |
| 138 | +When the C17/C18 [[fallthrough]] syntax is more commonly supported by | |
| 139 | +C compilers, static analyzers, and IDEs, we can switch to using that syntax | |
| 140 | +for the macro pseudo-keyword. | |
| 141 | + | |
| 142 | +All switch/case blocks must end in one of: | |
| 143 | + | |
| 144 | + break; | |
| 145 | + fallthrough; | |
| 146 | + continue; | |
| 147 | + goto <label>; | |
| 148 | + return [expression]; | |
| @@ -1,109 +0,0 @@ | ||
| 1 | −============ | |
| 2 | −Diamonds Rio | |
| 3 | −============ | |
| 4 | − | |
| 5 | −Copyright (C) 1999, 2000 Bruce Tenison | |
| 6 | − | |
| 7 | −Portions Copyright (C) 1999, 2000 David Nelson | |
| 8 | − | |
| 9 | −Thanks to David Nelson for guidance and the usage of the scanner.txt | |
| 10 | −and scanner.c files to model our driver and this informative file. | |
| 11 | − | |
| 12 | −Mar. 2, 2000 | |
| 13 | − | |
| 14 | −Changes | |
| 15 | −======= | |
| 16 | − | |
| 17 | −- Initial Revision | |
| 18 | − | |
| 19 | − | |
| 20 | −Overview | |
| 21 | −======== | |
| 22 | − | |
| 23 | −This README will address issues regarding how to configure the kernel | |
| 24 | −to access a RIO 500 mp3 player. | |
| 25 | −Before I explain how to use this to access the Rio500 please be warned: | |
| 26 | − | |
| 27 | −.. warning:: | |
| 28 | − | |
| 29 | − Please note that this software is still under development. The authors | |
| 30 | − are in no way responsible for any damage that may occur, no matter how | |
| 31 | − inconsequential. | |
| 32 | − | |
| 33 | −It seems that the Rio has a problem when sending .mp3 with low batteries. | |
| 34 | −I suggest when the batteries are low and you want to transfer stuff that you | |
| 35 | −replace it with a fresh one. In my case, what happened is I lost two 16kb | |
| 36 | −blocks (they are no longer usable to store information to it). But I don't | |
| 37 | −know if that's normal or not; it could simply be a problem with the flash | |
| 38 | −memory. | |
| 39 | − | |
| 40 | −In an extreme case, I left my Rio playing overnight and the batteries wore | |
| 41 | −down to nothing and appear to have corrupted the flash memory. My RIO | |
| 42 | −needed to be replaced as a result. Diamond tech support is aware of the | |
| 43 | −problem. Do NOT allow your batteries to wear down to nothing before | |
| 44 | −changing them. It appears RIO 500 firmware does not handle low battery | |
| 45 | −power well at all. | |
| 46 | − | |
| 47 | −On systems with OHCI controllers, the kernel OHCI code appears to have | |
| 48 | −power on problems with some chipsets. If you are having problems | |
| 49 | −connecting to your RIO 500, try turning it on first and then plugging it | |
| 50 | −into the USB cable. | |
| 51 | − | |
| 52 | −Contact Information | |
| 53 | −------------------- | |
| 54 | − | |
| 55 | − The main page for the project is hosted at sourceforge.net in the following | |
| 56 | − URL: <http://rio500.sourceforge.net>. You can also go to the project's | |
| 57 | − sourceforge home page at: <http://sourceforge.net/projects/rio500/>. | |
| 58 | − There is also a mailing list: rio500-users@lists.sourceforge.net | |
| 59 | − | |
| 60 | −Authors | |
| 61 | −------- | |
| 62 | − | |
| 63 | −Most of the code was written by Cesar Miquel <miquel@df.uba.ar>. Keith | |
| 64 | −Clayton <kclayton@jps.net> is incharge of the PPC port and making sure | |
| 65 | −things work there. Bruce Tenison <btenison@dibbs.net> is adding support | |
| 66 | −for .fon files and also does testing. The program will mostly sure be | |
| 67 | −re-written and Pete Ikusz along with the rest will re-design it. I would | |
| 68 | −also like to thank Tri Nguyen <tmn_3022000@hotmail.com> who provided use | |
| 69 | −with some important information regarding the communication with the Rio. | |
| 70 | − | |
| 71 | −Additional Information and userspace tools | |
| 72 | − | |
| 73 | − http://rio500.sourceforge.net/ | |
| 74 | − | |
| 75 | − | |
| 76 | −Requirements | |
| 77 | −============ | |
| 78 | − | |
| 79 | −A host with a USB port running a Linux kernel with RIO 500 support enabled. | |
| 80 | − | |
| 81 | −The driver is a module called rio500, which should be automatically loaded | |
| 82 | −as you plug in your device. If that fails you can manually load it with | |
| 83 | − | |
| 84 | − modprobe rio500 | |
| 85 | − | |
| 86 | −Udev should automatically create a device node as soon as plug in your device. | |
| 87 | −If that fails, you can manually add a device for the USB rio500:: | |
| 88 | − | |
| 89 | − mknod /dev/usb/rio500 c 180 64 | |
| 90 | − | |
| 91 | −In that case, set appropriate permissions for /dev/usb/rio500 (don't forget | |
| 92 | −about group and world permissions). Both read and write permissions are | |
| 93 | −required for proper operation. | |
| 94 | − | |
| 95 | −That's it. The Rio500 Utils at: http://rio500.sourceforge.net should | |
| 96 | −be able to access the rio500. | |
| 97 | − | |
| 98 | −Limits | |
| 99 | −====== | |
| 100 | − | |
| 101 | −You can use only a single rio500 device at a time with your computer. | |
| 102 | − | |
| 103 | −Bugs | |
| 104 | −==== | |
| 105 | − | |
| 106 | −If you encounter any problems feel free to drop me an email. | |
| 107 | − | |
| 108 | −Bruce Tenison | |
| 109 | −btenison@dibbs.net | |
| @@ -2167,12 +2167,10 @@ F: arch/arm64/boot/dts/realtek/ · 2166 unmodified lines | ||
| 2167 | 2167 | F: Documentation/devicetree/bindings/arm/realtek.yaml |
| 2168 | 2168 | |
| 2169 | 2169 | ARM/RENESAS ARM64 ARCHITECTURE |
| 2170 | −M: Simon Horman <horms@verge.net.au> | |
| 2171 | 2170 | M: Geert Uytterhoeven <geert+renesas@glider.be> |
| 2172 | 2171 | M: Magnus Damm <magnus.damm@gmail.com> |
| 2173 | 2172 | L: linux-renesas-soc@vger.kernel.org |
| 2174 | 2173 | Q: http://patchwork.kernel.org/project/linux-renesas-soc/list/ |
| 2175 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next | |
| 2176 | 2174 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next |
| 2177 | 2175 | S: Supported |
| 2178 | 2176 | F: arch/arm64/boot/dts/renesas/ |
| @@ -2284,12 +2282,10 @@ S: Maintained · 105 unmodified lines | ||
| 2284 | 2282 | F: drivers/media/platform/s5p-mfc/ |
| 2285 | 2283 | |
| 2286 | 2284 | ARM/SHMOBILE ARM ARCHITECTURE |
| 2287 | −M: Simon Horman <horms@verge.net.au> | |
| 2288 | 2285 | M: Geert Uytterhoeven <geert+renesas@glider.be> |
| 2289 | 2286 | M: Magnus Damm <magnus.damm@gmail.com> |
| 2290 | 2287 | L: linux-renesas-soc@vger.kernel.org |
| 2291 | 2288 | Q: http://patchwork.kernel.org/project/linux-renesas-soc/list/ |
| 2292 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas.git next | |
| 2293 | 2289 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-devel.git next |
| 2294 | 2290 | S: Supported |
| 2295 | 2291 | F: arch/arm/boot/dts/emev2* |
| @@ -9138,7 +9134,7 @@ F: drivers/auxdisplay/ks0108.c · 6842 unmodified lines | ||
| 9138 | 9134 | F: include/linux/ks0108.h |
| 9139 | 9135 | |
| 9140 | 9136 | L3MDEV |
| 9141 | −M: David Ahern <dsa@cumulusnetworks.com> | |
| 9137 | +M: David Ahern <dsahern@kernel.org> | |
| 9142 | 9138 | L: netdev@vger.kernel.org |
| 9143 | 9139 | S: Maintained |
| 9144 | 9140 | F: net/l3mdev |
| @@ -9199,6 +9195,7 @@ M: Pavel Machek <pavel@ucw.cz> · 54 unmodified lines | ||
| 9199 | 9195 | R: Dan Murphy <dmurphy@ti.com> |
| 9200 | 9196 | L: linux-leds@vger.kernel.org |
| 9201 | 9197 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/j.anaszewski/linux-leds.git |
| 9198 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/pavel/linux-leds.git | |
| 9202 | 9199 | S: Maintained |
| 9203 | 9200 | F: Documentation/devicetree/bindings/leds/ |
| 9204 | 9201 | F: drivers/leds/ |
| @@ -10270,7 +10267,7 @@ MEDIATEK ETHERNET DRIVER · 1065 unmodified lines | ||
| 10270 | 10267 | M: Felix Fietkau <nbd@openwrt.org> |
| 10271 | 10268 | M: John Crispin <john@phrozen.org> |
| 10272 | 10269 | M: Sean Wang <sean.wang@mediatek.com> |
| 10273 | −M: Nelson Chang <nelson.chang@mediatek.com> | |
| 10270 | +M: Mark Lee <Mark-MC.Lee@mediatek.com> | |
| 10274 | 10271 | L: netdev@vger.kernel.org |
| 10275 | 10272 | S: Maintained |
| 10276 | 10273 | F: drivers/net/ethernet/mediatek/ |
| @@ -11559,6 +11556,7 @@ NSDEPS · 1282 unmodified lines | ||
| 11559 | 11556 | M: Matthias Maennich <maennich@google.com> |
| 11560 | 11557 | S: Maintained |
| 11561 | 11558 | F: scripts/nsdeps |
| 11559 | +F: Documentation/core-api/symbol-namespaces.rst | |
| 11562 | 11560 | |
| 11563 | 11561 | NTB AMD DRIVER |
| 11564 | 11562 | M: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> |
| @@ -12326,12 +12324,15 @@ F: arch/parisc/ · 761 unmodified lines | ||
| 12326 | 12324 | F: Documentation/parisc/ |
| 12327 | 12325 | F: drivers/parisc/ |
| 12328 | 12326 | F: drivers/char/agp/parisc-agp.c |
| 12327 | +F: drivers/input/misc/hp_sdc_rtc.c | |
| 12329 | 12328 | F: drivers/input/serio/gscps2.c |
| 12329 | +F: drivers/input/serio/hp_sdc* | |
| 12330 | 12330 | F: drivers/parport/parport_gsc.* |
| 12331 | 12331 | F: drivers/tty/serial/8250/8250_gsc.c |
| 12332 | 12332 | F: drivers/video/fbdev/sti* |
| 12333 | 12333 | F: drivers/video/console/sti* |
| 12334 | 12334 | F: drivers/video/logo/logo_parisc* |
| 12335 | +F: include/linux/hp_sdc.h | |
| 12335 | 12336 | |
| 12336 | 12337 | PARMAN |
| 12337 | 12338 | M: Jiri Pirko <jiri@mellanox.com> |
| @@ -13375,7 +13376,7 @@ S: Maintained · 1037 unmodified lines | ||
| 13375 | 13376 | F: drivers/scsi/qla1280.[ch] |
| 13376 | 13377 | |
| 13377 | 13378 | QLOGIC QLA2XXX FC-SCSI DRIVER |
| 13378 | −M: qla2xxx-upstream@qlogic.com | |
| 13379 | +M: hmadhani@marvell.com | |
| 13379 | 13380 | L: linux-scsi@vger.kernel.org |
| 13380 | 13381 | S: Supported |
| 13381 | 13382 | F: Documentation/scsi/LICENSE.qla2xxx |
| @@ -16778,13 +16779,6 @@ W: http://www.linux-usb.org/usbnet · 3396 unmodified lines | ||
| 16778 | 16779 | S: Maintained |
| 16779 | 16780 | F: drivers/net/usb/dm9601.c |
| 16780 | 16781 | |
| 16781 | −USB DIAMOND RIO500 DRIVER | |
| 16782 | −M: Cesar Miquel <miquel@df.uba.ar> | |
| 16783 | −L: rio500-users@lists.sourceforge.net | |
| 16784 | −W: http://rio500.sourceforge.net | |
| 16785 | −S: Maintained | |
| 16786 | −F: drivers/usb/misc/rio500* | |
| 16787 | − | |
| 16788 | 16782 | USB EHCI DRIVER |
| 16789 | 16783 | M: Alan Stern <stern@rowland.harvard.edu> |
| 16790 | 16784 | L: linux-usb@vger.kernel.org |
| @@ -17451,7 +17445,7 @@ F: include/linux/regulator/ · 660 unmodified lines | ||
| 17451 | 17445 | K: regulator_get_optional |
| 17452 | 17446 | |
| 17453 | 17447 | VRF |
| 17454 | −M: David Ahern <dsa@cumulusnetworks.com> | |
| 17448 | +M: David Ahern <dsahern@kernel.org> | |
| 17455 | 17449 | M: Shrijeet Mukherjee <shrijeet@gmail.com> |
| 17456 | 17450 | L: netdev@vger.kernel.org |
| 17457 | 17451 | S: Maintained |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 5 |
| 3 | 3 | PATCHLEVEL = 4 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc2 | |
| 5 | +EXTRAVERSION = -rc4 | |
| 6 | 6 | NAME = Nesting Opossum |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -599,7 +599,7 @@ endif · 590 unmodified lines | ||
| 599 | 599 | # in addition to whatever we do anyway. |
| 600 | 600 | # Just "make" or "make all" shall build modules as well |
| 601 | 601 | |
| 602 | −ifneq ($(filter all _all modules,$(MAKECMDGOALS)),) | |
| 602 | +ifneq ($(filter all _all modules nsdeps,$(MAKECMDGOALS)),) | |
| 603 | 603 | KBUILD_MODULES := 1 |
| 604 | 604 | endif |
| 605 | 605 | |
| @@ -1037,7 +1037,7 @@ export KBUILD_VMLINUX_OBJS := $(head-y) $(init-y) $(core-y) $(libs-y2) \ · 431 unmodified lines | ||
| 1037 | 1037 | export KBUILD_VMLINUX_LIBS := $(libs-y1) |
| 1038 | 1038 | export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds |
| 1039 | 1039 | export LDFLAGS_vmlinux |
| 1040 | −# used by scripts/package/Makefile | |
| 1040 | +# used by scripts/Makefile.package | |
| 1041 | 1041 | export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) LICENSES arch include scripts tools) |
| 1042 | 1042 | |
| 1043 | 1043 | vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_OBJS) $(KBUILD_VMLINUX_LIBS) |
| @@ -1217,9 +1217,8 @@ PHONY += kselftest · 173 unmodified lines | ||
| 1217 | 1217 | kselftest: |
| 1218 | 1218 | $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests run_tests |
| 1219 | 1219 | |
| 1220 | −PHONY += kselftest-clean | |
| 1221 | −kselftest-clean: | |
| 1222 | − $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests clean | |
| 1220 | +kselftest-%: FORCE | |
| 1221 | + $(Q)$(MAKE) -C $(srctree)/tools/testing/selftests $* | |
| 1223 | 1222 | |
| 1224 | 1223 | PHONY += kselftest-merge |
| 1225 | 1224 | kselftest-merge: |
| @@ -66,9 +66,21 @@ · 65 unmodified lines | ||
| 66 | 66 | pinctrl-1 = <&ephy_leds_pins>; |
| 67 | 67 | status = "okay"; |
| 68 | 68 | |
| 69 | + gmac0: mac@0 { | |
| 70 | + compatible = "mediatek,eth-mac"; | |
| 71 | + reg = <0>; | |
| 72 | + phy-mode = "2500base-x"; | |
| 73 | + fixed-link { | |
| 74 | + speed = <2500>; | |
| 75 | + full-duplex; | |
| 76 | + pause; | |
| 77 | + }; | |
| 78 | + }; | |
| 79 | + | |
| 69 | 80 | gmac1: mac@1 { |
| 70 | 81 | compatible = "mediatek,eth-mac"; |
| 71 | 82 | reg = <1>; |
| 83 | + phy-mode = "gmii"; | |
| 72 | 84 | phy-handle = <&phy0>; |
| 73 | 85 | }; |
| 74 | 86 | |
| @@ -78,7 +90,6 @@ · 3 unmodified lines | ||
| 78 | 90 | |
| 79 | 91 | phy0: ethernet-phy@0 { |
| 80 | 92 | reg = <0>; |
| 81 | − phy-mode = "gmii"; | |
| 82 | 93 | }; |
| 83 | 94 | }; |
| 84 | 95 | }; |
| @@ -468,14 +468,12 @@ · 467 unmodified lines | ||
| 468 | 468 | compatible = "mediatek,mt7629-sgmiisys", "syscon"; |
| 469 | 469 | reg = <0x1b128000 0x3000>; |
| 470 | 470 | #clock-cells = <1>; |
| 471 | − mediatek,physpeed = "2500"; | |
| 472 | 471 | }; |
| 473 | 472 | |
| 474 | 473 | sgmiisys1: syscon@1b130000 { |
| 475 | 474 | compatible = "mediatek,mt7629-sgmiisys", "syscon"; |
| 476 | 475 | reg = <0x1b130000 0x3000>; |
| 477 | 476 | #clock-cells = <1>; |
| 478 | − mediatek,physpeed = "2500"; | |
| 479 | 477 | }; |
| 480 | 478 | }; |
| 481 | 479 | }; |
| @@ -520,6 +520,7 @@ · 519 unmodified lines | ||
| 520 | 520 | interrupts = <39>; |
| 521 | 521 | clocks = <&ccu CLK_AHB_EHCI0>; |
| 522 | 522 | phys = <&usbphy 1>; |
| 523 | + phy-names = "usb"; | |
| 523 | 524 | status = "disabled"; |
| 524 | 525 | }; |
| 525 | 526 | |
| @@ -529,6 +530,7 @@ · 3 unmodified lines | ||
| 529 | 530 | interrupts = <64>; |
| 530 | 531 | clocks = <&ccu CLK_USB_OHCI0>, <&ccu CLK_AHB_OHCI0>; |
| 531 | 532 | phys = <&usbphy 1>; |
| 533 | + phy-names = "usb"; | |
| 532 | 534 | status = "disabled"; |
| 533 | 535 | }; |
| 534 | 536 | |
| @@ -608,6 +610,7 @@ · 73 unmodified lines | ||
| 608 | 610 | interrupts = <40>; |
| 609 | 611 | clocks = <&ccu CLK_AHB_EHCI1>; |
| 610 | 612 | phys = <&usbphy 2>; |
| 613 | + phy-names = "usb"; | |
| 611 | 614 | status = "disabled"; |
| 612 | 615 | }; |
| 613 | 616 | |
| @@ -617,6 +620,7 @@ · 3 unmodified lines | ||
| 617 | 620 | interrupts = <65>; |
| 618 | 621 | clocks = <&ccu CLK_USB_OHCI1>, <&ccu CLK_AHB_OHCI1>; |
| 619 | 622 | phys = <&usbphy 2>; |
| 623 | + phy-names = "usb"; | |
| 620 | 624 | status = "disabled"; |
| 621 | 625 | }; |
| 622 | 626 | |
| @@ -391,6 +391,7 @@ · 390 unmodified lines | ||
| 391 | 391 | interrupts = <39>; |
| 392 | 392 | clocks = <&ccu CLK_AHB_EHCI>; |
| 393 | 393 | phys = <&usbphy 1>; |
| 394 | + phy-names = "usb"; | |
| 394 | 395 | status = "disabled"; |
| 395 | 396 | }; |
| 396 | 397 | |
| @@ -400,6 +401,7 @@ · 3 unmodified lines | ||
| 400 | 401 | interrupts = <40>; |
| 401 | 402 | clocks = <&ccu CLK_USB_OHCI>, <&ccu CLK_AHB_OHCI>; |
| 402 | 403 | phys = <&usbphy 1>; |
| 404 | + phy-names = "usb"; | |
| 403 | 405 | status = "disabled"; |
| 404 | 406 | }; |
| 405 | 407 | |
| @@ -545,6 +545,7 @@ · 544 unmodified lines | ||
| 545 | 545 | clocks = <&ccu CLK_AHB1_EHCI0>; |
| 546 | 546 | resets = <&ccu RST_AHB1_EHCI0>; |
| 547 | 547 | phys = <&usbphy 1>; |
| 548 | + phy-names = "usb"; | |
| 548 | 549 | status = "disabled"; |
| 549 | 550 | }; |
| 550 | 551 | |
| @@ -555,6 +556,7 @@ · 4 unmodified lines | ||
| 555 | 556 | clocks = <&ccu CLK_AHB1_OHCI0>, <&ccu CLK_USB_OHCI0>; |
| 556 | 557 | resets = <&ccu RST_AHB1_OHCI0>; |
| 557 | 558 | phys = <&usbphy 1>; |
| 559 | + phy-names = "usb"; | |
| 558 | 560 | status = "disabled"; |
| 559 | 561 | }; |
| 560 | 562 | |
| @@ -565,6 +567,7 @@ · 4 unmodified lines | ||
| 565 | 567 | clocks = <&ccu CLK_AHB1_EHCI1>; |
| 566 | 568 | resets = <&ccu RST_AHB1_EHCI1>; |
| 567 | 569 | phys = <&usbphy 2>; |
| 570 | + phy-names = "usb"; | |
| 568 | 571 | status = "disabled"; |
| 569 | 572 | }; |
| 570 | 573 | |
| @@ -575,6 +578,7 @@ · 4 unmodified lines | ||
| 575 | 578 | clocks = <&ccu CLK_AHB1_OHCI1>, <&ccu CLK_USB_OHCI1>; |
| 576 | 579 | resets = <&ccu RST_AHB1_OHCI1>; |
| 577 | 580 | phys = <&usbphy 2>; |
| 581 | + phy-names = "usb"; | |
| 578 | 582 | status = "disabled"; |
| 579 | 583 | }; |
| 580 | 584 | |
| @@ -623,6 +623,7 @@ · 622 unmodified lines | ||
| 623 | 623 | interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>; |
| 624 | 624 | clocks = <&ccu CLK_AHB_EHCI0>; |
| 625 | 625 | phys = <&usbphy 1>; |
| 626 | + phy-names = "usb"; | |
| 626 | 627 | status = "disabled"; |
| 627 | 628 | }; |
| 628 | 629 | |
| @@ -632,6 +633,7 @@ · 3 unmodified lines | ||
| 632 | 633 | interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; |
| 633 | 634 | clocks = <&ccu CLK_USB_OHCI0>, <&ccu CLK_AHB_OHCI0>; |
| 634 | 635 | phys = <&usbphy 1>; |
| 636 | + phy-names = "usb"; | |
| 635 | 637 | status = "disabled"; |
| 636 | 638 | }; |
| 637 | 639 | |
| @@ -714,6 +716,7 @@ · 76 unmodified lines | ||
| 714 | 716 | interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; |
| 715 | 717 | clocks = <&ccu CLK_AHB_EHCI1>; |
| 716 | 718 | phys = <&usbphy 2>; |
| 719 | + phy-names = "usb"; | |
| 717 | 720 | status = "disabled"; |
| 718 | 721 | }; |
| 719 | 722 | |
| @@ -723,6 +726,7 @@ · 3 unmodified lines | ||
| 723 | 726 | interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; |
| 724 | 727 | clocks = <&ccu CLK_USB_OHCI1>, <&ccu CLK_AHB_OHCI1>; |
| 725 | 728 | phys = <&usbphy 2>; |
| 729 | + phy-names = "usb"; | |
| 726 | 730 | status = "disabled"; |
| 727 | 731 | }; |
| 728 | 732 | |
| @@ -307,6 +307,7 @@ · 306 unmodified lines | ||
| 307 | 307 | clocks = <&ccu CLK_BUS_EHCI>; |
| 308 | 308 | resets = <&ccu RST_BUS_EHCI>; |
| 309 | 309 | phys = <&usbphy 1>; |
| 310 | + phy-names = "usb"; | |
| 310 | 311 | status = "disabled"; |
| 311 | 312 | }; |
| 312 | 313 | |
| @@ -317,6 +318,7 @@ · 4 unmodified lines | ||
| 317 | 318 | clocks = <&ccu CLK_BUS_OHCI>, <&ccu CLK_USB_OHCI>; |
| 318 | 319 | resets = <&ccu RST_BUS_OHCI>; |
| 319 | 320 | phys = <&usbphy 1>; |
| 321 | + phy-names = "usb"; | |
| 320 | 322 | status = "disabled"; |
| 321 | 323 | }; |
| 322 | 324 | |
| @@ -632,6 +632,7 @@ · 631 unmodified lines | ||
| 632 | 632 | clocks = <&ccu CLK_BUS_EHCI0>; |
| 633 | 633 | resets = <&ccu RST_BUS_EHCI0>; |
| 634 | 634 | phys = <&usbphy 1>; |
| 635 | + phy-names = "usb"; | |
| 635 | 636 | status = "disabled"; |
| 636 | 637 | }; |
| 637 | 638 | |
| @@ -643,6 +644,7 @@ · 5 unmodified lines | ||
| 643 | 644 | clocks = <&ccu CLK_BUS_OHCI0>, <&ccu CLK_USB_OHCI0>; |
| 644 | 645 | resets = <&ccu RST_BUS_OHCI0>; |
| 645 | 646 | phys = <&usbphy 1>; |
| 647 | + phy-names = "usb"; | |
| 646 | 648 | status = "disabled"; |
| 647 | 649 | }; |
| 648 | 650 | |
| @@ -654,6 +656,7 @@ · 5 unmodified lines | ||
| 654 | 656 | clocks = <&ccu CLK_BUS_EHCI1>; |
| 655 | 657 | resets = <&ccu RST_BUS_EHCI1>; |
| 656 | 658 | phys = <&usbphy 2>; |
| 659 | + phy-names = "usb"; | |
| 657 | 660 | status = "disabled"; |
| 658 | 661 | }; |
| 659 | 662 | |
| @@ -273,6 +273,7 @@ · 272 unmodified lines | ||
| 273 | 273 | clocks = <&ccu CLK_BUS_EHCI1>; |
| 274 | 274 | resets = <&ccu RST_BUS_EHCI1>; |
| 275 | 275 | phys = <&usbphy 1>; |
| 276 | + phy-names = "usb"; | |
| 276 | 277 | status = "disabled"; |
| 277 | 278 | }; |
| 278 | 279 | |
| @@ -284,6 +285,7 @@ · 5 unmodified lines | ||
| 284 | 285 | <&ccu CLK_USB_OHCI1>; |
| 285 | 286 | resets = <&ccu RST_BUS_OHCI1>; |
| 286 | 287 | phys = <&usbphy 1>; |
| 288 | + phy-names = "usb"; | |
| 287 | 289 | status = "disabled"; |
| 288 | 290 | }; |
| 289 | 291 | |
| @@ -294,6 +296,7 @@ · 4 unmodified lines | ||
| 294 | 296 | clocks = <&ccu CLK_BUS_EHCI2>; |
| 295 | 297 | resets = <&ccu RST_BUS_EHCI2>; |
| 296 | 298 | phys = <&usbphy 2>; |
| 299 | + phy-names = "usb"; | |
| 297 | 300 | status = "disabled"; |
| 298 | 301 | }; |
| 299 | 302 | |
| @@ -305,6 +308,7 @@ · 5 unmodified lines | ||
| 305 | 308 | <&ccu CLK_USB_OHCI2>; |
| 306 | 309 | resets = <&ccu RST_BUS_OHCI2>; |
| 307 | 310 | phys = <&usbphy 2>; |
| 311 | + phy-names = "usb"; | |
| 308 | 312 | status = "disabled"; |
| 309 | 313 | }; |
| 310 | 314 | |
| @@ -346,6 +346,7 @@ · 345 unmodified lines | ||
| 346 | 346 | clocks = <&usb_clocks CLK_BUS_HCI0>; |
| 347 | 347 | resets = <&usb_clocks RST_USB0_HCI>; |
| 348 | 348 | phys = <&usbphy1>; |
| 349 | + phy-names = "usb"; | |
| 349 | 350 | status = "disabled"; |
| 350 | 351 | }; |
| 351 | 352 | |
| @@ -357,6 +358,7 @@ · 5 unmodified lines | ||
| 357 | 358 | <&usb_clocks CLK_USB_OHCI0>; |
| 358 | 359 | resets = <&usb_clocks RST_USB0_HCI>; |
| 359 | 360 | phys = <&usbphy1>; |
| 361 | + phy-names = "usb"; | |
| 360 | 362 | status = "disabled"; |
| 361 | 363 | }; |
| 362 | 364 | |
| @@ -378,6 +380,7 @@ · 15 unmodified lines | ||
| 378 | 380 | clocks = <&usb_clocks CLK_BUS_HCI1>; |
| 379 | 381 | resets = <&usb_clocks RST_USB1_HCI>; |
| 380 | 382 | phys = <&usbphy2>; |
| 383 | + phy-names = "usb"; | |
| 381 | 384 | status = "disabled"; |
| 382 | 385 | }; |
| 383 | 386 | |
| @@ -407,6 +410,7 @@ · 23 unmodified lines | ||
| 407 | 410 | clocks = <&usb_clocks CLK_BUS_HCI2>; |
| 408 | 411 | resets = <&usb_clocks RST_USB2_HCI>; |
| 409 | 412 | phys = <&usbphy3>; |
| 413 | + phy-names = "usb"; | |
| 410 | 414 | status = "disabled"; |
| 411 | 415 | }; |
| 412 | 416 | |
| @@ -418,6 +422,7 @@ · 5 unmodified lines | ||
| 418 | 422 | <&usb_clocks CLK_USB_OHCI2>; |
| 419 | 423 | resets = <&usb_clocks RST_USB2_HCI>; |
| 420 | 424 | phys = <&usbphy3>; |
| 425 | + phy-names = "usb"; | |
| 421 | 426 | status = "disabled"; |
| 422 | 427 | }; |
| 423 | 428 | |
| @@ -304,6 +304,7 @@ · 303 unmodified lines | ||
| 304 | 304 | clocks = <&ccu CLK_BUS_EHCI1>, <&ccu CLK_BUS_OHCI1>; |
| 305 | 305 | resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>; |
| 306 | 306 | phys = <&usbphy 1>; |
| 307 | + phy-names = "usb"; | |
| 307 | 308 | status = "disabled"; |
| 308 | 309 | }; |
| 309 | 310 | |
| @@ -315,6 +316,7 @@ · 5 unmodified lines | ||
| 315 | 316 | <&ccu CLK_USB_OHCI1>; |
| 316 | 317 | resets = <&ccu RST_BUS_EHCI1>, <&ccu RST_BUS_OHCI1>; |
| 317 | 318 | phys = <&usbphy 1>; |
| 319 | + phy-names = "usb"; | |
| 318 | 320 | status = "disabled"; |
| 319 | 321 | }; |
| 320 | 322 | |
| @@ -325,6 +327,7 @@ · 4 unmodified lines | ||
| 325 | 327 | clocks = <&ccu CLK_BUS_EHCI2>, <&ccu CLK_BUS_OHCI2>; |
| 326 | 328 | resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>; |
| 327 | 329 | phys = <&usbphy 2>; |
| 330 | + phy-names = "usb"; | |
| 328 | 331 | status = "disabled"; |
| 329 | 332 | }; |
| 330 | 333 | |
| @@ -336,6 +339,7 @@ · 5 unmodified lines | ||
| 336 | 339 | <&ccu CLK_USB_OHCI2>; |
| 337 | 340 | resets = <&ccu RST_BUS_EHCI2>, <&ccu RST_BUS_OHCI2>; |
| 338 | 341 | phys = <&usbphy 2>; |
| 342 | + phy-names = "usb"; | |
| 339 | 343 | status = "disabled"; |
| 340 | 344 | }; |
| 341 | 345 | |
| @@ -346,6 +350,7 @@ · 4 unmodified lines | ||
| 346 | 350 | clocks = <&ccu CLK_BUS_EHCI3>, <&ccu CLK_BUS_OHCI3>; |
| 347 | 351 | resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>; |
| 348 | 352 | phys = <&usbphy 3>; |
| 353 | + phy-names = "usb"; | |
| 349 | 354 | status = "disabled"; |
| 350 | 355 | }; |
| 351 | 356 | |
| @@ -357,6 +362,7 @@ · 5 unmodified lines | ||
| 357 | 362 | <&ccu CLK_USB_OHCI3>; |
| 358 | 363 | resets = <&ccu RST_BUS_EHCI3>, <&ccu RST_BUS_OHCI3>; |
| 359 | 364 | phys = <&usbphy 3>; |
| 365 | + phy-names = "usb"; | |
| 360 | 366 | status = "disabled"; |
| 361 | 367 | }; |
| 362 | 368 | |
| @@ -91,7 +91,6 @@ CONFIG_USB_SERIAL_PL2303=m · 90 unmodified lines | ||
| 91 | 91 | CONFIG_USB_SERIAL_CYBERJACK=m |
| 92 | 92 | CONFIG_USB_SERIAL_XIRCOM=m |
| 93 | 93 | CONFIG_USB_SERIAL_OMNINET=m |
| 94 | −CONFIG_USB_RIO500=m | |
| 95 | 94 | CONFIG_EXT2_FS=m |
| 96 | 95 | CONFIG_EXT3_FS=m |
| 97 | 96 | CONFIG_MSDOS_FS=y |
| @@ -195,7 +195,6 @@ CONFIG_USB_SERIAL_XIRCOM=m · 194 unmodified lines | ||
| 195 | 195 | CONFIG_USB_SERIAL_OMNINET=m |
| 196 | 196 | CONFIG_USB_EMI62=m |
| 197 | 197 | CONFIG_USB_EMI26=m |
| 198 | −CONFIG_USB_RIO500=m | |
| 199 | 198 | CONFIG_USB_LEGOTOWER=m |
| 200 | 199 | CONFIG_USB_LCD=m |
| 201 | 200 | CONFIG_USB_CYTHERM=m |
| @@ -581,7 +581,6 @@ CONFIG_USB_SERIAL_XIRCOM=m · 580 unmodified lines | ||
| 581 | 581 | CONFIG_USB_SERIAL_OMNINET=m |
| 582 | 582 | CONFIG_USB_EMI62=m |
| 583 | 583 | CONFIG_USB_EMI26=m |
| 584 | −CONFIG_USB_RIO500=m | |
| 585 | 584 | CONFIG_USB_LEGOTOWER=m |
| 586 | 585 | CONFIG_USB_LCD=m |
| 587 | 586 | CONFIG_USB_CYTHERM=m |
| @@ -327,7 +327,6 @@ CONFIG_USB_EMI62=m · 326 unmodified lines | ||
| 327 | 327 | CONFIG_USB_EMI26=m |
| 328 | 328 | CONFIG_USB_ADUTUX=m |
| 329 | 329 | CONFIG_USB_SEVSEG=m |
| 330 | −CONFIG_USB_RIO500=m | |
| 331 | 330 | CONFIG_USB_LEGOTOWER=m |
| 332 | 331 | CONFIG_USB_LCD=m |
| 333 | 332 | CONFIG_USB_CYPRESS_CY7C63=m |
| @@ -189,7 +189,6 @@ CONFIG_USB_SERIAL_XIRCOM=m · 188 unmodified lines | ||
| 189 | 189 | CONFIG_USB_SERIAL_OMNINET=m |
| 190 | 190 | CONFIG_USB_EMI62=m |
| 191 | 191 | CONFIG_USB_EMI26=m |
| 192 | −CONFIG_USB_RIO500=m | |
| 193 | 192 | CONFIG_USB_LEGOTOWER=m |
| 194 | 193 | CONFIG_USB_LCD=m |
| 195 | 194 | CONFIG_USB_CYTHERM=m |
| @@ -98,6 +98,7 @@ config CRYPTO_AES_ARM_CE · 97 unmodified lines | ||
| 98 | 98 | tristate "Accelerated AES using ARMv8 Crypto Extensions" |
| 99 | 99 | depends on KERNEL_MODE_NEON |
| 100 | 100 | select CRYPTO_BLKCIPHER |
| 101 | + select CRYPTO_LIB_AES | |
| 101 | 102 | select CRYPTO_SIMD |
| 102 | 103 | help |
| 103 | 104 | Use an implementation of AES in CBC, CTR and XTS modes that uses |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <asm/assembler.h> |
| 10 | 10 | |
| 11 | 11 | .text |
| 12 | + .arch armv8-a | |
| 12 | 13 | .fpu crypto-neon-fp-armv8 |
| 13 | 14 | .align 3 |
| 14 | 15 | |
| @@ -110,7 +110,6 @@ config ARM64 · 109 unmodified lines | ||
| 110 | 110 | select GENERIC_STRNLEN_USER |
| 111 | 111 | select GENERIC_TIME_VSYSCALL |
| 112 | 112 | select GENERIC_GETTIMEOFDAY |
| 113 | − select GENERIC_COMPAT_VDSO if (!CPU_BIG_ENDIAN && COMPAT) | |
| 114 | 113 | select HANDLE_DOMAIN_IRQ |
| 115 | 114 | select HARDIRQS_SW_RESEND |
| 116 | 115 | select HAVE_PCI |
| @@ -617,6 +616,23 @@ config CAVIUM_ERRATUM_30115 · 500 unmodified lines | ||
| 617 | 616 | |
| 618 | 617 | If unsure, say Y. |
| 619 | 618 | |
| 619 | +config CAVIUM_TX2_ERRATUM_219 | |
| 620 | + bool "Cavium ThunderX2 erratum 219: PRFM between TTBR change and ISB fails" | |
| 621 | + default y | |
| 622 | + help | |
| 623 | + On Cavium ThunderX2, a load, store or prefetch instruction between a | |
| 624 | + TTBR update and the corresponding context synchronizing operation can | |
| 625 | + cause a spurious Data Abort to be delivered to any hardware thread in | |
| 626 | + the CPU core. | |
| 627 | + | |
| 628 | + Work around the issue by avoiding the problematic code sequence and | |
| 629 | + trapping KVM guest TTBRx_EL1 writes to EL2 when SMT is enabled. The | |
| 630 | + trap handler performs the corresponding register access, skips the | |
| 631 | + instruction and ensures context synchronization by virtue of the | |
| 632 | + exception return. | |
| 633 | + | |
| 634 | + If unsure, say Y. | |
| 635 | + | |
| 620 | 636 | config QCOM_FALKOR_ERRATUM_1003 |
| 621 | 637 | bool "Falkor E1003: Incorrect translation due to ASID change" |
| 622 | 638 | default y |
| @@ -1159,7 +1175,7 @@ menuconfig COMPAT · 536 unmodified lines | ||
| 1159 | 1175 | if COMPAT |
| 1160 | 1176 | |
| 1161 | 1177 | config KUSER_HELPERS |
| 1162 | − bool "Enable kuser helpers page for 32 bit applications" | |
| 1178 | + bool "Enable kuser helpers page for 32-bit applications" | |
| 1163 | 1179 | default y |
| 1164 | 1180 | help |
| 1165 | 1181 | Warning: disabling this option may break 32-bit user programs. |
| @@ -1185,6 +1201,18 @@ config KUSER_HELPERS · 19 unmodified lines | ||
| 1185 | 1201 | Say N here only if you are absolutely certain that you do not |
| 1186 | 1202 | need these helpers; otherwise, the safe option is to say Y. |
| 1187 | 1203 | |
| 1204 | +config COMPAT_VDSO | |
| 1205 | + bool "Enable vDSO for 32-bit applications" | |
| 1206 | + depends on !CPU_BIG_ENDIAN && "$(CROSS_COMPILE_COMPAT)" != "" | |
| 1207 | + select GENERIC_COMPAT_VDSO | |
| 1208 | + default y | |
| 1209 | + help | |
| 1210 | + Place in the process address space of 32-bit applications an | |
| 1211 | + ELF shared object providing fast implementations of gettimeofday | |
| 1212 | + and clock_gettime. | |
| 1213 | + | |
| 1214 | + You must have a 32-bit build of glibc 2.22 or later for programs | |
| 1215 | + to seamlessly take advantage of this. | |
| 1188 | 1216 | |
| 1189 | 1217 | menuconfig ARMV8_DEPRECATED |
| 1190 | 1218 | bool "Emulate deprecated/obsolete ARMv8 instructions" |
| @@ -53,22 +53,6 @@ $(warning Detected assembler with broken .inst; disassembly will be unreliable) · 52 unmodified lines | ||
| 53 | 53 | endif |
| 54 | 54 | endif |
| 55 | 55 | |
| 56 | −ifeq ($(CONFIG_GENERIC_COMPAT_VDSO), y) | |
| 57 | − CROSS_COMPILE_COMPAT ?= $(CONFIG_CROSS_COMPILE_COMPAT_VDSO:"%"=%) | |
| 58 | − | |
| 59 | − ifeq ($(CONFIG_CC_IS_CLANG), y) | |
| 60 | − $(warning CROSS_COMPILE_COMPAT is clang, the compat vDSO will not be built) | |
| 61 | − else ifeq ($(strip $(CROSS_COMPILE_COMPAT)),) | |
| 62 | − $(warning CROSS_COMPILE_COMPAT not defined or empty, the compat vDSO will not be built) | |
| 63 | − else ifeq ($(shell which $(CROSS_COMPILE_COMPAT)gcc 2> /dev/null),) | |
| 64 | − $(error $(CROSS_COMPILE_COMPAT)gcc not found, check CROSS_COMPILE_COMPAT) | |
| 65 | − else | |
| 66 | − export CROSS_COMPILE_COMPAT | |
| 67 | − export CONFIG_COMPAT_VDSO := y | |
| 68 | − compat_vdso := -DCONFIG_COMPAT_VDSO=1 | |
| 69 | − endif | |
| 70 | −endif | |
| 71 | − | |
| 72 | 56 | KBUILD_CFLAGS += -mgeneral-regs-only $(lseinstr) $(brokengasinst) \ |
| 73 | 57 | $(compat_vdso) $(cc_has_k_constraint) |
| 74 | 58 | KBUILD_CFLAGS += -fno-asynchronous-unwind-tables |
| @@ -104,6 +104,7 @@ · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | &ehci0 { |
| 106 | 106 | phys = <&usbphy 0>; |
| 107 | + phy-names = "usb"; | |
| 107 | 108 | status = "okay"; |
| 108 | 109 | }; |
| 109 | 110 | |
| @@ -150,6 +151,7 @@ · 40 unmodified lines | ||
| 150 | 151 | |
| 151 | 152 | &ohci0 { |
| 152 | 153 | phys = <&usbphy 0>; |
| 154 | + phy-names = "usb"; | |
| 153 | 155 | status = "okay"; |
| 154 | 156 | }; |
| 155 | 157 | |
| @@ -553,6 +553,7 @@ · 552 unmodified lines | ||
| 553 | 553 | resets = <&ccu RST_BUS_OHCI1>, |
| 554 | 554 | <&ccu RST_BUS_EHCI1>; |
| 555 | 555 | phys = <&usbphy 1>; |
| 556 | + phy-names = "usb"; | |
| 556 | 557 | status = "disabled"; |
| 557 | 558 | }; |
| 558 | 559 | |
| @@ -564,6 +565,7 @@ · 5 unmodified lines | ||
| 564 | 565 | <&ccu CLK_USB_OHCI1>; |
| 565 | 566 | resets = <&ccu RST_BUS_OHCI1>; |
| 566 | 567 | phys = <&usbphy 1>; |
| 568 | + phy-names = "usb"; | |
| 567 | 569 | status = "disabled"; |
| 568 | 570 | }; |
| 569 | 571 | |
| @@ -547,6 +547,7 @@ · 546 unmodified lines | ||
| 547 | 547 | resets = <&ccu RST_BUS_OHCI3>, |
| 548 | 548 | <&ccu RST_BUS_EHCI3>; |
| 549 | 549 | phys = <&usb2phy 3>; |
| 550 | + phy-names = "usb"; | |
| 550 | 551 | status = "disabled"; |
| 551 | 552 | }; |
| 552 | 553 | |
| @@ -558,6 +559,7 @@ · 5 unmodified lines | ||
| 558 | 559 | <&ccu CLK_USB_OHCI3>; |
| 559 | 560 | resets = <&ccu RST_BUS_OHCI3>; |
| 560 | 561 | phys = <&usb2phy 3>; |
| 562 | + phy-names = "usb"; | |
| 561 | 563 | status = "disabled"; |
| 562 | 564 | }; |
| 563 | 565 | |
| @@ -78,10 +78,9 @@ alternative_else_nop_endif · 77 unmodified lines | ||
| 78 | 78 | /* |
| 79 | 79 | * Remove the address tag from a virtual address, if present. |
| 80 | 80 | */ |
| 81 | − .macro clear_address_tag, dst, addr | |
| 82 | − tst \addr, #(1 << 55) | |
| 83 | − bic \dst, \addr, #(0xff << 56) | |
| 84 | − csel \dst, \dst, \addr, eq | |
| 81 | + .macro untagged_addr, dst, addr | |
| 82 | + sbfx \dst, \addr, #0, #56 | |
| 83 | + and \dst, \dst, \addr | |
| 85 | 84 | .endm |
| 86 | 85 | |
| 87 | 86 | #endif |
| @@ -321,7 +321,8 @@ static inline s64 __lse_atomic64_dec_if_positive(atomic64_t *v) · 320 unmodified lines | ||
| 321 | 321 | } |
| 322 | 322 | |
| 323 | 323 | #define __CMPXCHG_CASE(w, sfx, name, sz, mb, cl...) \ |
| 324 | −static inline u##sz __lse__cmpxchg_case_##name##sz(volatile void *ptr, \ | |
| 324 | +static __always_inline u##sz \ | |
| 325 | +__lse__cmpxchg_case_##name##sz(volatile void *ptr, \ | |
| 325 | 326 | u##sz old, \ |
| 326 | 327 | u##sz new) \ |
| 327 | 328 | { \ |
| @@ -362,7 +363,8 @@ __CMPXCHG_CASE(x, , mb_, 64, al, "memory") · 34 unmodified lines | ||
| 362 | 363 | #undef __CMPXCHG_CASE |
| 363 | 364 | |
| 364 | 365 | #define __CMPXCHG_DBL(name, mb, cl...) \ |
| 365 | −static inline long __lse__cmpxchg_double##name(unsigned long old1, \ | |
| 366 | +static __always_inline long \ | |
| 367 | +__lse__cmpxchg_double##name(unsigned long old1, \ | |
| 366 | 368 | unsigned long old2, \ |
| 367 | 369 | unsigned long new1, \ |
| 368 | 370 | unsigned long new2, \ |
| @@ -52,7 +52,9 @@ · 51 unmodified lines | ||
| 52 | 52 | #define ARM64_HAS_IRQ_PRIO_MASKING 42 |
| 53 | 53 | #define ARM64_HAS_DCPODP 43 |
| 54 | 54 | #define ARM64_WORKAROUND_1463225 44 |
| 55 | +#define ARM64_WORKAROUND_CAVIUM_TX2_219_TVM 45 | |
| 56 | +#define ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM 46 | |
| 55 | 57 | |
| 56 | −#define ARM64_NCAPS 45 | |
| 58 | +#define ARM64_NCAPS 47 | |
| 57 | 59 | |
| 58 | 60 | #endif /* __ASM_CPUCAPS_H */ |
| @@ -215,12 +215,18 @@ static inline unsigned long kaslr_offset(void) · 214 unmodified lines | ||
| 215 | 215 | * up with a tagged userland pointer. Clear the tag to get a sane pointer to |
| 216 | 216 | * pass on to access_ok(), for instance. |
| 217 | 217 | */ |
| 218 | −#define untagged_addr(addr) \ | |
| 218 | +#define __untagged_addr(addr) \ | |
| 219 | 219 | ((__force __typeof__(addr))sign_extend64((__force u64)(addr), 55)) |
| 220 | 220 | |
| 221 | +#define untagged_addr(addr) ({ \ | |
| 222 | + u64 __addr = (__force u64)addr; \ | |
| 223 | + __addr &= __untagged_addr(__addr); \ | |
| 224 | + (__force __typeof__(addr))__addr; \ | |
| 225 | +}) | |
| 226 | + | |
| 221 | 227 | #ifdef CONFIG_KASAN_SW_TAGS |
| 222 | 228 | #define __tag_shifted(tag) ((u64)(tag) << 56) |
| 223 | −#define __tag_reset(addr) untagged_addr(addr) | |
| 229 | +#define __tag_reset(addr) __untagged_addr(addr) | |
| 224 | 230 | #define __tag_get(addr) (__u8)((u64)(addr) >> 56) |
| 225 | 231 | #else |
| 226 | 232 | #define __tag_shifted(tag) 0UL |
| @@ -876,9 +876,6 @@ static inline void update_mmu_cache(struct vm_area_struct *vma, · 875 unmodified lines | ||
| 876 | 876 | |
| 877 | 877 | #define update_mmu_cache_pmd(vma, address, pmd) do { } while (0) |
| 878 | 878 | |
| 879 | −#define kc_vaddr_to_offset(v) ((v) & ~PAGE_END) | |
| 880 | −#define kc_offset_to_vaddr(o) ((o) | PAGE_END) | |
| 881 | − | |
| 882 | 879 | #ifdef CONFIG_ARM64_PA_BITS_52 |
| 883 | 880 | #define phys_to_ttbr(addr) (((addr) | ((addr) >> 46)) & TTBR_BADDR_MASK_52) |
| 884 | 881 | #else |
| @@ -212,7 +212,7 @@ · 211 unmodified lines | ||
| 212 | 212 | #define SYS_FAR_EL1 sys_reg(3, 0, 6, 0, 0) |
| 213 | 213 | #define SYS_PAR_EL1 sys_reg(3, 0, 7, 4, 0) |
| 214 | 214 | |
| 215 | −#define SYS_PAR_EL1_F BIT(1) | |
| 215 | +#define SYS_PAR_EL1_F BIT(0) | |
| 216 | 216 | #define SYS_PAR_EL1_FST GENMASK(6, 1) |
| 217 | 217 | |
| 218 | 218 | /*** Statistical Profiling Extension ***/ |
| @@ -20,7 +20,7 @@ · 19 unmodified lines | ||
| 20 | 20 | |
| 21 | 21 | #define dmb(option) __asm__ __volatile__ ("dmb " #option : : : "memory") |
| 22 | 22 | |
| 23 | −#if __LINUX_ARM_ARCH__ >= 8 | |
| 23 | +#if __LINUX_ARM_ARCH__ >= 8 && defined(CONFIG_AS_DMB_ISHLD) | |
| 24 | 24 | #define aarch32_smp_mb() dmb(ish) |
| 25 | 25 | #define aarch32_smp_rmb() dmb(ishld) |
| 26 | 26 | #define aarch32_smp_wmb() dmb(ishst) |
| @@ -1,33 +0,0 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0-only */ | |
| 2 | −/* | |
| 3 | − * Copyright (C) 2012 ARM Limited | |
| 4 | − */ | |
| 5 | −#ifndef __ASM_VDSO_DATAPAGE_H | |
| 6 | −#define __ASM_VDSO_DATAPAGE_H | |
| 7 | − | |
| 8 | −#ifndef __ASSEMBLY__ | |
| 9 | − | |
| 10 | −struct vdso_data { | |
| 11 | − __u64 cs_cycle_last; /* Timebase at clocksource init */ | |
| 12 | − __u64 raw_time_sec; /* Raw time */ | |
| 13 | − __u64 raw_time_nsec; | |
| 14 | − __u64 xtime_clock_sec; /* Kernel time */ | |
| 15 | − __u64 xtime_clock_nsec; | |
| 16 | − __u64 xtime_coarse_sec; /* Coarse time */ | |
| 17 | − __u64 xtime_coarse_nsec; | |
| 18 | − __u64 wtm_clock_sec; /* Wall to monotonic time */ | |
| 19 | − __u64 wtm_clock_nsec; | |
| 20 | − __u32 tb_seq_count; /* Timebase sequence counter */ | |
| 21 | − /* cs_* members must be adjacent and in this order (ldp accesses) */ | |
| 22 | − __u32 cs_mono_mult; /* NTP-adjusted clocksource multiplier */ | |
| 23 | − __u32 cs_shift; /* Clocksource shift (mono = raw) */ | |
| 24 | − __u32 cs_raw_mult; /* Raw clocksource multiplier */ | |
| 25 | − __u32 tz_minuteswest; /* Whacky timezone stuff */ | |
| 26 | − __u32 tz_dsttime; | |
| 27 | − __u32 use_syscall; | |
| 28 | − __u32 hrtimer_res; | |
| 29 | −}; | |
| 30 | − | |
| 31 | −#endif /* !__ASSEMBLY__ */ | |
| 32 | − | |
| 33 | −#endif /* __ASM_VDSO_DATAPAGE_H */ | |
| @@ -174,6 +174,9 @@ static void __init register_insn_emulation(struct insn_emulation_ops *ops) · 173 unmodified lines | ||
| 174 | 174 | struct insn_emulation *insn; |
| 175 | 175 | |
| 176 | 176 | insn = kzalloc(sizeof(*insn), GFP_KERNEL); |
| 177 | + if (!insn) | |
| 178 | + return; | |
| 179 | + | |
| 177 | 180 | insn->ops = ops; |
| 178 | 181 | insn->min = INSN_UNDEF; |
| 179 | 182 | |
| @@ -233,6 +236,8 @@ static void __init register_insn_emulation_sysctl(void) · 53 unmodified lines | ||
| 233 | 236 | |
| 234 | 237 | insns_sysctl = kcalloc(nr_insn_emulated + 1, sizeof(*sysctl), |
| 235 | 238 | GFP_KERNEL); |
| 239 | + if (!insns_sysctl) | |
| 240 | + return; | |
| 236 | 241 | |
| 237 | 242 | raw_spin_lock_irqsave(&insn_emulation_lock, flags); |
| 238 | 243 | list_for_each_entry(insn, &insn_emulation, node) { |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <asm/cpu.h> |
| 13 | 13 | #include <asm/cputype.h> |
| 14 | 14 | #include <asm/cpufeature.h> |
| 15 | +#include <asm/smp_plat.h> | |
| 15 | 16 | |
| 16 | 17 | static bool __maybe_unused |
| 17 | 18 | is_affected_midr_range(const struct arm64_cpu_capabilities *entry, int scope) |
| @@ -128,8 +129,8 @@ static void install_bp_hardening_cb(bp_hardening_cb_t fn, · 110 unmodified lines | ||
| 128 | 129 | int cpu, slot = -1; |
| 129 | 130 | |
| 130 | 131 | /* |
| 131 | − * enable_smccc_arch_workaround_1() passes NULL for the hyp_vecs | |
| 132 | − * start/end if we're a guest. Skip the hyp-vectors work. | |
| 132 | + * detect_harden_bp_fw() passes NULL for the hyp_vecs start/end if | |
| 133 | + * we're a guest. Skip the hyp-vectors work. | |
| 133 | 134 | */ |
| 134 | 135 | if (!hyp_vecs_start) { |
| 135 | 136 | __this_cpu_write(bp_hardening_data.fn, fn); |
| @@ -623,6 +624,30 @@ check_branch_predictor(const struct arm64_cpu_capabilities *entry, int scope) · 487 unmodified lines | ||
| 623 | 624 | return (need_wa > 0); |
| 624 | 625 | } |
| 625 | 626 | |
| 627 | +static const __maybe_unused struct midr_range tx2_family_cpus[] = { | |
| 628 | + MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), | |
| 629 | + MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), | |
| 630 | + {}, | |
| 631 | +}; | |
| 632 | + | |
| 633 | +static bool __maybe_unused | |
| 634 | +needs_tx2_tvm_workaround(const struct arm64_cpu_capabilities *entry, | |
| 635 | + int scope) | |
| 636 | +{ | |
| 637 | + int i; | |
| 638 | + | |
| 639 | + if (!is_affected_midr_range_list(entry, scope) || | |
| 640 | + !is_hyp_mode_available()) | |
| 641 | + return false; | |
| 642 | + | |
| 643 | + for_each_possible_cpu(i) { | |
| 644 | + if (MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 0) != 0) | |
| 645 | + return true; | |
| 646 | + } | |
| 647 | + | |
| 648 | + return false; | |
| 649 | +} | |
| 650 | + | |
| 626 | 651 | #ifdef CONFIG_HARDEN_EL2_VECTORS |
| 627 | 652 | |
| 628 | 653 | static const struct midr_range arm64_harden_el2_vectors[] = { |
| @@ -851,6 +876,19 @@ const struct arm64_cpu_capabilities arm64_errata[] = { · 222 unmodified lines | ||
| 851 | 876 | .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, |
| 852 | 877 | .matches = has_cortex_a76_erratum_1463225, |
| 853 | 878 | }, |
| 879 | +#endif | |
| 880 | +#ifdef CONFIG_CAVIUM_TX2_ERRATUM_219 | |
| 881 | + { | |
| 882 | + .desc = "Cavium ThunderX2 erratum 219 (KVM guest sysreg trapping)", | |
| 883 | + .capability = ARM64_WORKAROUND_CAVIUM_TX2_219_TVM, | |
| 884 | + ERRATA_MIDR_RANGE_LIST(tx2_family_cpus), | |
| 885 | + .matches = needs_tx2_tvm_workaround, | |
| 886 | + }, | |
| 887 | + { | |
| 888 | + .desc = "Cavium ThunderX2 erratum 219 (PRFM removal)", | |
| 889 | + .capability = ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM, | |
| 890 | + ERRATA_MIDR_RANGE_LIST(tx2_family_cpus), | |
| 891 | + }, | |
| 854 | 892 | #endif |
| 855 | 893 | { |
| 856 | 894 | } |
| @@ -136,6 +136,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar0[] = { · 135 unmodified lines | ||
| 136 | 136 | |
| 137 | 137 | static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { |
| 138 | 138 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_SB_SHIFT, 4, 0), |
| 139 | + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_FRINTTS_SHIFT, 4, 0), | |
| 139 | 140 | ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), |
| 140 | 141 | FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_GPI_SHIFT, 4, 0), |
| 141 | 142 | ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), |
| @@ -175,11 +176,16 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = { · 33 unmodified lines | ||
| 175 | 176 | }; |
| 176 | 177 | |
| 177 | 178 | static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = { |
| 178 | − ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SM4_SHIFT, 4, 0), | |
| 179 | − ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SHA3_SHIFT, 4, 0), | |
| 180 | − ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_BITPERM_SHIFT, 4, 0), | |
| 181 | − ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_AES_SHIFT, 4, 0), | |
| 182 | − ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SVEVER_SHIFT, 4, 0), | |
| 179 | + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), | |
| 180 | + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SM4_SHIFT, 4, 0), | |
| 181 | + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), | |
| 182 | + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SHA3_SHIFT, 4, 0), | |
| 183 | + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), | |
| 184 | + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_BITPERM_SHIFT, 4, 0), | |
| 185 | + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), | |
| 186 | + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_AES_SHIFT, 4, 0), | |
| 187 | + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SVE), | |
| 188 | + FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ZFR0_SVEVER_SHIFT, 4, 0), | |
| 183 | 189 | ARM64_FTR_END, |
| 184 | 190 | }; |
| 185 | 191 | |
| @@ -604,7 +604,7 @@ el1_da: · 603 unmodified lines | ||
| 604 | 604 | */ |
| 605 | 605 | mrs x3, far_el1 |
| 606 | 606 | inherit_daif pstate=x23, tmp=x2 |
| 607 | − clear_address_tag x0, x3 | |
| 607 | + untagged_addr x0, x3 | |
| 608 | 608 | mov x2, sp // struct pt_regs |
| 609 | 609 | bl do_mem_abort |
| 610 | 610 | |
| @@ -680,7 +680,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING · 69 unmodified lines | ||
| 680 | 680 | orr x24, x24, x0 |
| 681 | 681 | alternative_else_nop_endif |
| 682 | 682 | cbnz x24, 1f // preempt count != 0 || NMI return path |
| 683 | − bl preempt_schedule_irq // irq en/disable is done inside | |
| 683 | + bl arm64_preempt_schedule_irq // irq en/disable is done inside | |
| 684 | 684 | 1: |
| 685 | 685 | #endif |
| 686 | 686 | |
| @@ -775,6 +775,7 @@ el0_sync_compat: · 88 unmodified lines | ||
| 775 | 775 | b.ge el0_dbg |
| 776 | 776 | b el0_inv |
| 777 | 777 | el0_svc_compat: |
| 778 | + gic_prio_kentry_setup tmp=x1 | |
| 778 | 779 | mov x0, sp |
| 779 | 780 | bl el0_svc_compat_handler |
| 780 | 781 | b ret_to_user |
| @@ -807,7 +808,7 @@ el0_da: · 26 unmodified lines | ||
| 807 | 808 | mrs x26, far_el1 |
| 808 | 809 | ct_user_exit_irqoff |
| 809 | 810 | enable_daif |
| 810 | − clear_address_tag x0, x26 | |
| 811 | + untagged_addr x0, x26 | |
| 811 | 812 | mov x1, x25 |
| 812 | 813 | mov x2, sp |
| 813 | 814 | bl do_mem_abort |
| @@ -1070,7 +1071,9 @@ alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003 · 256 unmodified lines | ||
| 1070 | 1071 | #else |
| 1071 | 1072 | ldr x30, =vectors |
| 1072 | 1073 | #endif |
| 1074 | +alternative_if_not ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM | |
| 1073 | 1075 | prfm plil1strm, [x30, #(1b - tramp_vectors)] |
| 1076 | +alternative_else_nop_endif | |
| 1074 | 1077 | msr vbar_el1, x30 |
| 1075 | 1078 | add x30, x30, #(1b - tramp_vectors) |
| 1076 | 1079 | isb |
| @@ -121,10 +121,16 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) · 120 unmodified lines | ||
| 121 | 121 | |
| 122 | 122 | /* |
| 123 | 123 | * Ensure updated trampoline is visible to instruction |
| 124 | − * fetch before we patch in the branch. | |
| 124 | + * fetch before we patch in the branch. Although the | |
| 125 | + * architecture doesn't require an IPI in this case, | |
| 126 | + * Neoverse-N1 erratum #1542419 does require one | |
| 127 | + * if the TLB maintenance in module_enable_ro() is | |
| 128 | + * skipped due to rodata_enabled. It doesn't seem worth | |
| 129 | + * it to make it conditional given that this is | |
| 130 | + * certainly not a fast-path. | |
| 125 | 131 | */ |
| 126 | − __flush_icache_range((unsigned long)&dst[0], | |
| 127 | − (unsigned long)&dst[1]); | |
| 132 | + flush_icache_range((unsigned long)&dst[0], | |
| 133 | + (unsigned long)&dst[1]); | |
| 128 | 134 | } |
| 129 | 135 | addr = (unsigned long)dst; |
| 130 | 136 | #else /* CONFIG_ARM64_MODULE_PLTS */ |
| @@ -201,6 +201,7 @@ static int create_safe_exec_page(void *src_start, size_t length, · 200 unmodified lines | ||
| 201 | 201 | gfp_t mask) |
| 202 | 202 | { |
| 203 | 203 | int rc = 0; |
| 204 | + pgd_t *trans_pgd; | |
| 204 | 205 | pgd_t *pgdp; |
| 205 | 206 | pud_t *pudp; |
| 206 | 207 | pmd_t *pmdp; |
| @@ -215,7 +216,13 @@ static int create_safe_exec_page(void *src_start, size_t length, · 8 unmodified lines | ||
| 215 | 216 | memcpy((void *)dst, src_start, length); |
| 216 | 217 | __flush_icache_range(dst, dst + length); |
| 217 | 218 | |
| 218 | − pgdp = pgd_offset_raw(allocator(mask), dst_addr); | |
| 219 | + trans_pgd = allocator(mask); | |
| 220 | + if (!trans_pgd) { | |
| 221 | + rc = -ENOMEM; | |
| 222 | + goto out; | |
| 223 | + } | |
| 224 | + | |
| 225 | + pgdp = pgd_offset_raw(trans_pgd, dst_addr); | |
| 219 | 226 | if (pgd_none(READ_ONCE(*pgdp))) { |
| 220 | 227 | pudp = allocator(mask); |
| 221 | 228 | if (!pudp) { |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/sched/task.h> |
| 18 | 18 | #include <linux/sched/task_stack.h> |
| 19 | 19 | #include <linux/kernel.h> |
| 20 | +#include <linux/lockdep.h> | |
| 20 | 21 | #include <linux/mm.h> |
| 21 | 22 | #include <linux/stddef.h> |
| 22 | 23 | #include <linux/sysctl.h> |
| @@ -44,6 +45,7 @@ · 21 unmodified lines | ||
| 44 | 45 | #include <asm/alternative.h> |
| 45 | 46 | #include <asm/arch_gicv3.h> |
| 46 | 47 | #include <asm/compat.h> |
| 48 | +#include <asm/cpufeature.h> | |
| 47 | 49 | #include <asm/cacheflush.h> |
| 48 | 50 | #include <asm/exec.h> |
| 49 | 51 | #include <asm/fpsimd.h> |
| @@ -332,22 +334,27 @@ void arch_release_task_struct(struct task_struct *tsk) · 282 unmodified lines | ||
| 332 | 334 | fpsimd_release_task(tsk); |
| 333 | 335 | } |
| 334 | 336 | |
| 335 | −/* | |
| 336 | − * src and dst may temporarily have aliased sve_state after task_struct | |
| 337 | − * is copied. We cannot fix this properly here, because src may have | |
| 338 | − * live SVE state and dst's thread_info may not exist yet, so tweaking | |
| 339 | − * either src's or dst's TIF_SVE is not safe. | |
| 340 | − * | |
| 341 | − * The unaliasing is done in copy_thread() instead. This works because | |
| 342 | − * dst is not schedulable or traceable until both of these functions | |
| 343 | − * have been called. | |
| 344 | − */ | |
| 345 | 337 | int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) |
| 346 | 338 | { |
| 347 | 339 | if (current->mm) |
| 348 | 340 | fpsimd_preserve_current_state(); |
| 349 | 341 | *dst = *src; |
| 350 | 342 | |
| 343 | + /* We rely on the above assignment to initialize dst's thread_flags: */ | |
| 344 | + BUILD_BUG_ON(!IS_ENABLED(CONFIG_THREAD_INFO_IN_TASK)); | |
| 345 | + | |
| 346 | + /* | |
| 347 | + * Detach src's sve_state (if any) from dst so that it does not | |
| 348 | + * get erroneously used or freed prematurely. dst's sve_state | |
| 349 | + * will be allocated on demand later on if dst uses SVE. | |
| 350 | + * For consistency, also clear TIF_SVE here: this could be done | |
| 351 | + * later in copy_process(), but to avoid tripping up future | |
| 352 | + * maintainers it is best not to leave TIF_SVE and sve_state in | |
| 353 | + * an inconsistent state, even temporarily. | |
| 354 | + */ | |
| 355 | + dst->thread.sve_state = NULL; | |
| 356 | + clear_tsk_thread_flag(dst, TIF_SVE); | |
| 357 | + | |
| 351 | 358 | return 0; |
| 352 | 359 | } |
| 353 | 360 | |
| @@ -360,13 +367,6 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, · 6 unmodified lines | ||
| 360 | 367 | |
| 361 | 368 | memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context)); |
| 362 | 369 | |
| 363 | − /* | |
| 364 | − * Unalias p->thread.sve_state (if any) from the parent task | |
| 365 | − * and disable discard SVE state for p: | |
| 366 | − */ | |
| 367 | − clear_tsk_thread_flag(p, TIF_SVE); | |
| 368 | − p->thread.sve_state = NULL; | |
| 369 | − | |
| 370 | 370 | /* |
| 371 | 371 | * In case p was allocated the same task_struct pointer as some |
| 372 | 372 | * other recently-exited task, make sure p is disassociated from |
| @@ -633,3 +633,19 @@ static int __init tagged_addr_init(void) · 260 unmodified lines | ||
| 633 | 633 | |
| 634 | 634 | core_initcall(tagged_addr_init); |
| 635 | 635 | #endif /* CONFIG_ARM64_TAGGED_ADDR_ABI */ |
| 636 | + | |
| 637 | +asmlinkage void __sched arm64_preempt_schedule_irq(void) | |
| 638 | +{ | |
| 639 | + lockdep_assert_irqs_disabled(); | |
| 640 | + | |
| 641 | + /* | |
| 642 | + * Preempting a task from an IRQ means we leave copies of PSTATE | |
| 643 | + * on the stack. cpufeature's enable calls may modify PSTATE, but | |
| 644 | + * resuming one of these preempted tasks would undo those changes. | |
| 645 | + * | |
| 646 | + * Only allow a task to be preempted once cpufeatures have been | |
| 647 | + * enabled. | |
| 648 | + */ | |
| 649 | + if (static_branch_likely(&arm64_const_caps_ready)) | |
| 650 | + preempt_schedule_irq(); | |
| 651 | +} | |
| @@ -8,15 +8,21 @@ · 7 unmodified lines | ||
| 8 | 8 | ARCH_REL_TYPE_ABS := R_ARM_JUMP_SLOT|R_ARM_GLOB_DAT|R_ARM_ABS32 |
| 9 | 9 | include $(srctree)/lib/vdso/Makefile |
| 10 | 10 | |
| 11 | −COMPATCC := $(CROSS_COMPILE_COMPAT)gcc | |
| 11 | +# Same as cc-*option, but using CC_COMPAT instead of CC | |
| 12 | +ifeq ($(CONFIG_CC_IS_CLANG), y) | |
| 13 | +CC_COMPAT ?= $(CC) | |
| 14 | +else | |
| 15 | +CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc | |
| 16 | +endif | |
| 12 | 17 | |
| 13 | −# Same as cc-*option, but using COMPATCC instead of CC | |
| 14 | 18 | cc32-option = $(call try-run,\ |
| 15 | − $(COMPATCC) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) | |
| 19 | + $(CC_COMPAT) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2)) | |
| 16 | 20 | cc32-disable-warning = $(call try-run,\ |
| 17 | − $(COMPATCC) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) | |
| 21 | + $(CC_COMPAT) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) | |
| 18 | 22 | cc32-ldoption = $(call try-run,\ |
| 19 | − $(COMPATCC) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2)) | |
| 23 | + $(CC_COMPAT) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2)) | |
| 24 | +cc32-as-instr = $(call try-run,\ | |
| 25 | + printf "%b\n" "$(1)" | $(CC_COMPAT) $(VDSO_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3)) | |
| 20 | 26 | |
| 21 | 27 | # We cannot use the global flags to compile the vDSO files, the main reason |
| 22 | 28 | # being that the 32-bit compiler may be older than the main (64-bit) compiler |
| @@ -25,22 +31,21 @@ cc32-ldoption = $(call try-run,\ · 2 unmodified lines | ||
| 25 | 31 | # arm64 one. |
| 26 | 32 | # As a result we set our own flags here. |
| 27 | 33 | |
| 28 | −# From top-level Makefile | |
| 29 | −# NOSTDINC_FLAGS | |
| 30 | −VDSO_CPPFLAGS := -nostdinc -isystem $(shell $(COMPATCC) -print-file-name=include) | |
| 34 | +# KBUILD_CPPFLAGS and NOSTDINC_FLAGS from top-level Makefile | |
| 35 | +VDSO_CPPFLAGS := -D__KERNEL__ -nostdinc -isystem $(shell $(CC_COMPAT) -print-file-name=include) | |
| 31 | 36 | VDSO_CPPFLAGS += $(LINUXINCLUDE) |
| 32 | −VDSO_CPPFLAGS += $(KBUILD_CPPFLAGS) | |
| 33 | 37 | |
| 34 | 38 | # Common C and assembly flags |
| 35 | 39 | # From top-level Makefile |
| 36 | 40 | VDSO_CAFLAGS := $(VDSO_CPPFLAGS) |
| 41 | +ifneq ($(shell $(CC_COMPAT) --version 2>&1 | head -n 1 | grep clang),) | |
| 42 | +VDSO_CAFLAGS += --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%)) | |
| 43 | +endif | |
| 44 | + | |
| 37 | 45 | VDSO_CAFLAGS += $(call cc32-option,-fno-PIE) |
| 38 | 46 | ifdef CONFIG_DEBUG_INFO |
| 39 | 47 | VDSO_CAFLAGS += -g |
| 40 | 48 | endif |
| 41 | −ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(COMPATCC)), y) | |
| 42 | −VDSO_CAFLAGS += -DCC_HAVE_ASM_GOTO | |
| 43 | −endif | |
| 44 | 49 | |
| 45 | 50 | # From arm Makefile |
| 46 | 51 | VDSO_CAFLAGS += $(call cc32-option,-fno-dwarf2-cfi-asm) |
| @@ -55,6 +60,7 @@ endif · 8 unmodified lines | ||
| 55 | 60 | VDSO_CAFLAGS += -fPIC -fno-builtin -fno-stack-protector |
| 56 | 61 | VDSO_CAFLAGS += -DDISABLE_BRANCH_PROFILING |
| 57 | 62 | |
| 63 | + | |
| 58 | 64 | # Try to compile for ARMv8. If the compiler is too old and doesn't support it, |
| 59 | 65 | # fall back to v7. There is no easy way to check for what architecture the code |
| 60 | 66 | # is being compiled, so define a macro specifying that (see arch/arm/Makefile). |
| @@ -91,6 +97,12 @@ VDSO_CFLAGS += -Wno-int-to-pointer-cast · 30 unmodified lines | ||
| 91 | 97 | VDSO_AFLAGS := $(VDSO_CAFLAGS) |
| 92 | 98 | VDSO_AFLAGS += -D__ASSEMBLY__ |
| 93 | 99 | |
| 100 | +# Check for binutils support for dmb ishld | |
| 101 | +dmbinstr := $(call cc32-as-instr,dmb ishld,-DCONFIG_AS_DMB_ISHLD=1) | |
| 102 | + | |
| 103 | +VDSO_CFLAGS += $(dmbinstr) | |
| 104 | +VDSO_AFLAGS += $(dmbinstr) | |
| 105 | + | |
| 94 | 106 | VDSO_LDFLAGS := $(VDSO_CPPFLAGS) |
| 95 | 107 | # From arm vDSO Makefile |
| 96 | 108 | VDSO_LDFLAGS += -Wl,-Bsymbolic -Wl,--no-undefined -Wl,-soname=linux-vdso.so.1 |
| @@ -159,14 +171,14 @@ quiet_cmd_vdsold_and_vdso_check = LD32 $@ · 62 unmodified lines | ||
| 159 | 171 | cmd_vdsold_and_vdso_check = $(cmd_vdsold); $(cmd_vdso_check) |
| 160 | 172 | |
| 161 | 173 | quiet_cmd_vdsold = LD32 $@ |
| 162 | − cmd_vdsold = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_LDFLAGS) \ | |
| 174 | + cmd_vdsold = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_LDFLAGS) \ | |
| 163 | 175 | -Wl,-T $(filter %.lds,$^) $(filter %.o,$^) -o $@ |
| 164 | 176 | quiet_cmd_vdsocc = CC32 $@ |
| 165 | − cmd_vdsocc = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) -c -o $@ $< | |
| 177 | + cmd_vdsocc = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) -c -o $@ $< | |
| 166 | 178 | quiet_cmd_vdsocc_gettimeofday = CC32 $@ |
| 167 | − cmd_vdsocc_gettimeofday = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) $(VDSO_CFLAGS_gettimeofday_o) -c -o $@ $< | |
| 179 | + cmd_vdsocc_gettimeofday = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_CFLAGS) $(VDSO_CFLAGS_gettimeofday_o) -c -o $@ $< | |
| 168 | 180 | quiet_cmd_vdsoas = AS32 $@ |
| 169 | − cmd_vdsoas = $(COMPATCC) -Wp,-MD,$(depfile) $(VDSO_AFLAGS) -c -o $@ $< | |
| 181 | + cmd_vdsoas = $(CC_COMPAT) -Wp,-MD,$(depfile) $(VDSO_AFLAGS) -c -o $@ $< | |
| 170 | 182 | |
| 171 | 183 | quiet_cmd_vdsomunge = MUNGE $@ |
| 172 | 184 | cmd_vdsomunge = $(obj)/$(munge) $< $@ |
| @@ -124,6 +124,9 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu) · 123 unmodified lines | ||
| 124 | 124 | { |
| 125 | 125 | u64 hcr = vcpu->arch.hcr_el2; |
| 126 | 126 | |
| 127 | + if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM)) | |
| 128 | + hcr |= HCR_TVM; | |
| 129 | + | |
| 127 | 130 | write_sysreg(hcr, hcr_el2); |
| 128 | 131 | |
| 129 | 132 | if (cpus_have_const_cap(ARM64_HAS_RAS_EXTN) && (hcr & HCR_VSE)) |
| @@ -174,8 +177,10 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu) · 44 unmodified lines | ||
| 174 | 177 | * the crucial bit is "On taking a vSError interrupt, |
| 175 | 178 | * HCR_EL2.VSE is cleared to 0." |
| 176 | 179 | */ |
| 177 | − if (vcpu->arch.hcr_el2 & HCR_VSE) | |
| 178 | − vcpu->arch.hcr_el2 = read_sysreg(hcr_el2); | |
| 180 | + if (vcpu->arch.hcr_el2 & HCR_VSE) { | |
| 181 | + vcpu->arch.hcr_el2 &= ~HCR_VSE; | |
| 182 | + vcpu->arch.hcr_el2 |= read_sysreg(hcr_el2) & HCR_VSE; | |
| 183 | + } | |
| 179 | 184 | |
| 180 | 185 | if (has_vhe()) |
| 181 | 186 | deactivate_traps_vhe(); |
| @@ -380,6 +385,61 @@ static bool __hyp_text __hyp_handle_fpsimd(struct kvm_vcpu *vcpu) · 198 unmodified lines | ||
| 380 | 385 | return true; |
| 381 | 386 | } |
| 382 | 387 | |
| 388 | +static bool __hyp_text handle_tx2_tvm(struct kvm_vcpu *vcpu) | |
| 389 | +{ | |
| 390 | + u32 sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_hsr(vcpu)); | |
| 391 | + int rt = kvm_vcpu_sys_get_rt(vcpu); | |
| 392 | + u64 val = vcpu_get_reg(vcpu, rt); | |
| 393 | + | |
| 394 | + /* | |
| 395 | + * The normal sysreg handling code expects to see the traps, | |
| 396 | + * let's not do anything here. | |
| 397 | + */ | |
| 398 | + if (vcpu->arch.hcr_el2 & HCR_TVM) | |
| 399 | + return false; | |
| 400 | + | |
| 401 | + switch (sysreg) { | |
| 402 | + case SYS_SCTLR_EL1: | |
| 403 | + write_sysreg_el1(val, SYS_SCTLR); | |
| 404 | + break; | |
| 405 | + case SYS_TTBR0_EL1: | |
| 406 | + write_sysreg_el1(val, SYS_TTBR0); | |
| 407 | + break; | |
| 408 | + case SYS_TTBR1_EL1: | |
| 409 | + write_sysreg_el1(val, SYS_TTBR1); | |
| 410 | + break; | |
| 411 | + case SYS_TCR_EL1: | |
| 412 | + write_sysreg_el1(val, SYS_TCR); | |
| 413 | + break; | |
| 414 | + case SYS_ESR_EL1: | |
| 415 | + write_sysreg_el1(val, SYS_ESR); | |
| 416 | + break; | |
| 417 | + case SYS_FAR_EL1: | |
| 418 | + write_sysreg_el1(val, SYS_FAR); | |
| 419 | + break; | |
| 420 | + case SYS_AFSR0_EL1: | |
| 421 | + write_sysreg_el1(val, SYS_AFSR0); | |
| 422 | + break; | |
| 423 | + case SYS_AFSR1_EL1: | |
| 424 | + write_sysreg_el1(val, SYS_AFSR1); | |
| 425 | + break; | |
| 426 | + case SYS_MAIR_EL1: | |
| 427 | + write_sysreg_el1(val, SYS_MAIR); | |
| 428 | + break; | |
| 429 | + case SYS_AMAIR_EL1: | |
| 430 | + write_sysreg_el1(val, SYS_AMAIR); | |
| 431 | + break; | |
| 432 | + case SYS_CONTEXTIDR_EL1: | |
| 433 | + write_sysreg_el1(val, SYS_CONTEXTIDR); | |
| 434 | + break; | |
| 435 | + default: | |
| 436 | + return false; | |
| 437 | + } | |
| 438 | + | |
| 439 | + __kvm_skip_instr(vcpu); | |
| 440 | + return true; | |
| 441 | +} | |
| 442 | + | |
| 383 | 443 | /* |
| 384 | 444 | * Return true when we were able to fixup the guest exit and should return to |
| 385 | 445 | * the guest, false when we should restore the host state and return to the |
| @@ -399,6 +459,11 @@ static bool __hyp_text fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code) · 13 unmodified lines | ||
| 399 | 459 | if (*exit_code != ARM_EXCEPTION_TRAP) |
| 400 | 460 | goto exit; |
| 401 | 461 | |
| 462 | + if (cpus_have_const_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM) && | |
| 463 | + kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_SYS64 && | |
| 464 | + handle_tx2_tvm(vcpu)) | |
| 465 | + return true; | |
| 466 | + | |
| 402 | 467 | /* |
| 403 | 468 | * We trap the first access to the FP/SIMD to save the host context |
| 404 | 469 | * and restore the guest context lazily. |
| @@ -113,6 +113,15 @@ static inline bool is_ttbr1_addr(unsigned long addr) · 112 unmodified lines | ||
| 113 | 113 | return arch_kasan_reset_tag(addr) >= PAGE_OFFSET; |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | +static inline unsigned long mm_to_pgd_phys(struct mm_struct *mm) | |
| 117 | +{ | |
| 118 | + /* Either init_pg_dir or swapper_pg_dir */ | |
| 119 | + if (mm == &init_mm) | |
| 120 | + return __pa_symbol(mm->pgd); | |
| 121 | + | |
| 122 | + return (unsigned long)virt_to_phys(mm->pgd); | |
| 123 | +} | |
| 124 | + | |
| 116 | 125 | /* |
| 117 | 126 | * Dump out the page tables associated with 'addr' in the currently active mm. |
| 118 | 127 | */ |
| @@ -141,7 +150,7 @@ static void show_pte(unsigned long addr) · 22 unmodified lines | ||
| 141 | 150 | |
| 142 | 151 | pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp=%016lx\n", |
| 143 | 152 | mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K, |
| 144 | − vabits_actual, (unsigned long)virt_to_phys(mm->pgd)); | |
| 153 | + vabits_actual, mm_to_pgd_phys(mm)); | |
| 145 | 154 | pgdp = pgd_offset(mm, addr); |
| 146 | 155 | pgd = READ_ONCE(*pgdp); |
| 147 | 156 | pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd)); |
| @@ -259,14 +268,18 @@ static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr, · 111 unmodified lines | ||
| 259 | 268 | par = read_sysreg(par_el1); |
| 260 | 269 | local_irq_restore(flags); |
| 261 | 270 | |
| 271 | + /* | |
| 272 | + * If we now have a valid translation, treat the translation fault as | |
| 273 | + * spurious. | |
| 274 | + */ | |
| 262 | 275 | if (!(par & SYS_PAR_EL1_F)) |
| 263 | − return false; | |
| 276 | + return true; | |
| 264 | 277 | |
| 265 | 278 | /* |
| 266 | 279 | * If we got a different type of fault from the AT instruction, |
| 267 | 280 | * treat the translation fault as spurious. |
| 268 | 281 | */ |
| 269 | − dfsc = FIELD_PREP(SYS_PAR_EL1_FST, par); | |
| 282 | + dfsc = FIELD_GET(SYS_PAR_EL1_FST, par); | |
| 270 | 283 | return (dfsc & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT; |
| 271 | 284 | } |
| 272 | 285 | |
| @@ -571,7 +571,6 @@ CONFIG_USB_SERIAL_OMNINET=m · 570 unmodified lines | ||
| 571 | 571 | CONFIG_USB_EMI62=m |
| 572 | 572 | CONFIG_USB_EMI26=m |
| 573 | 573 | CONFIG_USB_ADUTUX=m |
| 574 | −CONFIG_USB_RIO500=m | |
| 575 | 574 | CONFIG_USB_LEGOTOWER=m |
| 576 | 575 | CONFIG_USB_LCD=m |
| 577 | 576 | CONFIG_USB_CYPRESS_CY7C63=m |
| @@ -314,7 +314,6 @@ CONFIG_USB_SERIAL_SAFE_PADDED=y · 313 unmodified lines | ||
| 314 | 314 | CONFIG_USB_SERIAL_CYBERJACK=m |
| 315 | 315 | CONFIG_USB_SERIAL_XIRCOM=m |
| 316 | 316 | CONFIG_USB_SERIAL_OMNINET=m |
| 317 | −CONFIG_USB_RIO500=m | |
| 318 | 317 | CONFIG_USB_LEGOTOWER=m |
| 319 | 318 | CONFIG_USB_LCD=m |
| 320 | 319 | CONFIG_USB_CYTHERM=m |
| @@ -43,7 +43,7 @@ · 42 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | /* O32 stack has to be 8-byte aligned. */ |
| 45 | 45 | static u64 o32_stk[4096]; |
| 46 | −#define O32_STK &o32_stk[sizeof(o32_stk)] | |
| 46 | +#define O32_STK (&o32_stk[ARRAY_SIZE(o32_stk)]) | |
| 47 | 47 | |
| 48 | 48 | #define __PROM_O32(fun, arg) fun arg __asm__(#fun); \ |
| 49 | 49 | __asm__(#fun " = call_o32") |
| @@ -77,8 +77,8 @@ extern unsigned long __xchg_called_with_bad_pointer(void) · 76 unmodified lines | ||
| 77 | 77 | extern unsigned long __xchg_small(volatile void *ptr, unsigned long val, |
| 78 | 78 | unsigned int size); |
| 79 | 79 | |
| 80 | −static inline unsigned long __xchg(volatile void *ptr, unsigned long x, | |
| 81 | − int size) | |
| 80 | +static __always_inline | |
| 81 | +unsigned long __xchg(volatile void *ptr, unsigned long x, int size) | |
| 82 | 82 | { |
| 83 | 83 | switch (size) { |
| 84 | 84 | case 1: |
| @@ -153,8 +153,9 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x, · 68 unmodified lines | ||
| 153 | 153 | extern unsigned long __cmpxchg_small(volatile void *ptr, unsigned long old, |
| 154 | 154 | unsigned long new, unsigned int size); |
| 155 | 155 | |
| 156 | −static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, | |
| 157 | − unsigned long new, unsigned int size) | |
| 156 | +static __always_inline | |
| 157 | +unsigned long __cmpxchg(volatile void *ptr, unsigned long old, | |
| 158 | + unsigned long new, unsigned int size) | |
| 158 | 159 | { |
| 159 | 160 | switch (size) { |
| 160 | 161 | case 1: |
| @@ -6,5 +6,16 @@ · 5 unmodified lines | ||
| 6 | 6 | #define HWCAP_MIPS_R6 (1 << 0) |
| 7 | 7 | #define HWCAP_MIPS_MSA (1 << 1) |
| 8 | 8 | #define HWCAP_MIPS_CRC32 (1 << 2) |
| 9 | +#define HWCAP_MIPS_MIPS16 (1 << 3) | |
| 10 | +#define HWCAP_MIPS_MDMX (1 << 4) | |
| 11 | +#define HWCAP_MIPS_MIPS3D (1 << 5) | |
| 12 | +#define HWCAP_MIPS_SMARTMIPS (1 << 6) | |
| 13 | +#define HWCAP_MIPS_DSP (1 << 7) | |
| 14 | +#define HWCAP_MIPS_DSP2 (1 << 8) | |
| 15 | +#define HWCAP_MIPS_DSP3 (1 << 9) | |
| 16 | +#define HWCAP_MIPS_MIPS16E2 (1 << 10) | |
| 17 | +#define HWCAP_LOONGSON_MMI (1 << 11) | |
| 18 | +#define HWCAP_LOONGSON_EXT (1 << 12) | |
| 19 | +#define HWCAP_LOONGSON_EXT2 (1 << 13) | |
| 9 | 20 | |
| 10 | 21 | #endif /* _UAPI_ASM_HWCAP_H */ |
| @@ -2180,6 +2180,39 @@ void cpu_probe(void) · 2179 unmodified lines | ||
| 2180 | 2180 | elf_hwcap |= HWCAP_MIPS_MSA; |
| 2181 | 2181 | } |
| 2182 | 2182 | |
| 2183 | + if (cpu_has_mips16) | |
| 2184 | + elf_hwcap |= HWCAP_MIPS_MIPS16; | |
| 2185 | + | |
| 2186 | + if (cpu_has_mdmx) | |
| 2187 | + elf_hwcap |= HWCAP_MIPS_MDMX; | |
| 2188 | + | |
| 2189 | + if (cpu_has_mips3d) | |
| 2190 | + elf_hwcap |= HWCAP_MIPS_MIPS3D; | |
| 2191 | + | |
| 2192 | + if (cpu_has_smartmips) | |
| 2193 | + elf_hwcap |= HWCAP_MIPS_SMARTMIPS; | |
| 2194 | + | |
| 2195 | + if (cpu_has_dsp) | |
| 2196 | + elf_hwcap |= HWCAP_MIPS_DSP; | |
| 2197 | + | |
| 2198 | + if (cpu_has_dsp2) | |
| 2199 | + elf_hwcap |= HWCAP_MIPS_DSP2; | |
| 2200 | + | |
| 2201 | + if (cpu_has_dsp3) | |
| 2202 | + elf_hwcap |= HWCAP_MIPS_DSP3; | |
| 2203 | + | |
| 2204 | + if (cpu_has_mips16e2) | |
| 2205 | + elf_hwcap |= HWCAP_MIPS_MIPS16E2; | |
| 2206 | + | |
| 2207 | + if (cpu_has_loongson_mmi) | |
| 2208 | + elf_hwcap |= HWCAP_LOONGSON_MMI; | |
| 2209 | + | |
| 2210 | + if (cpu_has_loongson_ext) | |
| 2211 | + elf_hwcap |= HWCAP_LOONGSON_EXT; | |
| 2212 | + | |
| 2213 | + if (cpu_has_loongson_ext2) | |
| 2214 | + elf_hwcap |= HWCAP_LOONGSON_EXT2; | |
| 2215 | + | |
| 2183 | 2216 | if (cpu_has_vz) |
| 2184 | 2217 | cpu_probe_vz(c); |
| 2185 | 2218 | |
| @@ -66,6 +66,10 @@ else · 65 unmodified lines | ||
| 66 | 66 | $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) |
| 67 | 67 | endif |
| 68 | 68 | |
| 69 | +# Some -march= flags enable MMI instructions, and GCC complains about that | |
| 70 | +# support being enabled alongside -msoft-float. Thus explicitly disable MMI. | |
| 71 | +cflags-y += $(call cc-option,-mno-loongson-mmi) | |
| 72 | + | |
| 69 | 73 | # |
| 70 | 74 | # Loongson Machines' Support |
| 71 | 75 | # |
| @@ -15,6 +15,7 @@ ccflags-vdso := \ · 14 unmodified lines | ||
| 15 | 15 | $(filter -mmicromips,$(KBUILD_CFLAGS)) \ |
| 16 | 16 | $(filter -march=%,$(KBUILD_CFLAGS)) \ |
| 17 | 17 | $(filter -m%-float,$(KBUILD_CFLAGS)) \ |
| 18 | + $(filter -mno-loongson-%,$(KBUILD_CFLAGS)) \ | |
| 18 | 19 | -D__VDSO__ |
| 19 | 20 | |
| 20 | 21 | ifdef CONFIG_CC_IS_CLANG |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | #define ARCH_DMA_MINALIGN L1_CACHE_BYTES |
| 24 | 24 | |
| 25 | −#define __read_mostly __attribute__((__section__(".data..read_mostly"))) | |
| 25 | +#define __read_mostly __section(.data..read_mostly) | |
| 26 | 26 | |
| 27 | 27 | void parisc_cache_init(void); /* initializes cache-flushing */ |
| 28 | 28 | void disable_sr_hashing_asm(int); /* low level support for above */ |
| @@ -52,7 +52,7 @@ · 51 unmodified lines | ||
| 52 | 52 | }) |
| 53 | 53 | |
| 54 | 54 | #ifdef CONFIG_SMP |
| 55 | −# define __lock_aligned __attribute__((__section__(".data..lock_aligned"))) | |
| 55 | +# define __lock_aligned __section(.data..lock_aligned) | |
| 56 | 56 | #endif |
| 57 | 57 | |
| 58 | 58 | #endif /* __PARISC_LDCW_H */ |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * arch/parisc/mm/ioremap.c |
| 4 | 4 | * |
| 5 | 5 | * (C) Copyright 1995 1996 Linus Torvalds |
| 6 | − * (C) Copyright 2001-2006 Helge Deller <deller@gmx.de> | |
| 6 | + * (C) Copyright 2001-2019 Helge Deller <deller@gmx.de> | |
| 7 | 7 | * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org> |
| 8 | 8 | */ |
| 9 | 9 | |
| @@ -84,7 +84,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l · 74 unmodified lines | ||
| 84 | 84 | addr = (void __iomem *) area->addr; |
| 85 | 85 | if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, |
| 86 | 86 | phys_addr, pgprot)) { |
| 87 | − vfree(addr); | |
| 87 | + vunmap(addr); | |
| 88 | 88 | return NULL; |
| 89 | 89 | } |
| 90 | 90 | |
| @@ -92,9 +92,11 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l · 1 unmodified line | ||
| 92 | 92 | } |
| 93 | 93 | EXPORT_SYMBOL(__ioremap); |
| 94 | 94 | |
| 95 | −void iounmap(const volatile void __iomem *addr) | |
| 95 | +void iounmap(const volatile void __iomem *io_addr) | |
| 96 | 96 | { |
| 97 | − if (addr > high_memory) | |
| 98 | − return vfree((void *) (PAGE_MASK & (unsigned long __force) addr)); | |
| 97 | + unsigned long addr = (unsigned long)io_addr & PAGE_MASK; | |
| 98 | + | |
| 99 | + if (is_vmalloc_addr((void *)addr)) | |
| 100 | + vunmap((void *)addr); | |
| 99 | 101 | } |
| 100 | 102 | EXPORT_SYMBOL(iounmap); |
| @@ -35,6 +35,10 @@ static inline void radix__flush_all_lpid(unsigned int lpid) · 34 unmodified lines | ||
| 35 | 35 | { |
| 36 | 36 | WARN_ON(1); |
| 37 | 37 | } |
| 38 | +static inline void radix__flush_all_lpid_guest(unsigned int lpid) | |
| 39 | +{ | |
| 40 | + WARN_ON(1); | |
| 41 | +} | |
| 38 | 42 | #endif |
| 39 | 43 | |
| 40 | 44 | extern void radix__flush_hugetlb_tlb_range(struct vm_area_struct *vma, |
| @@ -1921,6 +1921,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) · 1920 unmodified lines | ||
| 1921 | 1921 | mtspr SPRN_PCR, r6 |
| 1922 | 1922 | 18: |
| 1923 | 1923 | /* Signal secondary CPUs to continue */ |
| 1924 | + li r0, 0 | |
| 1924 | 1925 | stb r0,VCORE_IN_GUEST(r5) |
| 1925 | 1926 | 19: lis r8,0x7fff /* MAX_INT@h */ |
| 1926 | 1927 | mtspr SPRN_HDEC,r8 |
| @@ -761,6 +761,7 @@ static int spufs_init_fs_context(struct fs_context *fc) · 760 unmodified lines | ||
| 761 | 761 | ctx->gid = current_gid(); |
| 762 | 762 | ctx->mode = 0755; |
| 763 | 763 | |
| 764 | + fc->fs_private = ctx; | |
| 764 | 765 | fc->s_fs_info = sbi; |
| 765 | 766 | fc->ops = &spufs_context_ops; |
| 766 | 767 | return 0; |
| @@ -1419,6 +1419,9 @@ void __init pseries_lpar_read_hblkrm_characteristics(void) · 1418 unmodified lines | ||
| 1419 | 1419 | unsigned char local_buffer[SPLPAR_TLB_BIC_MAXLENGTH]; |
| 1420 | 1420 | int call_status, len, idx, bpsize; |
| 1421 | 1421 | |
| 1422 | + if (!firmware_has_feature(FW_FEATURE_BLOCK_REMOVE)) | |
| 1423 | + return; | |
| 1424 | + | |
| 1422 | 1425 | spin_lock(&rtas_data_buf_lock); |
| 1423 | 1426 | memset(rtas_data_buf, 0, RTAS_DATA_BUF_SIZE); |
| 1424 | 1427 | call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | ||
| 13 | 13 | compatible = "sifive,hifive-unleashed-a00", "sifive,fu540-c000"; |
| 14 | 14 | |
| 15 | 15 | chosen { |
| 16 | + stdout-path = "serial0"; | |
| 16 | 17 | }; |
| 17 | 18 | |
| 18 | 19 | cpus { |
| @@ -87,14 +87,6 @@ extern pgd_t swapper_pg_dir[]; · 86 unmodified lines | ||
| 87 | 87 | #define VMALLOC_END (PAGE_OFFSET - 1) |
| 88 | 88 | #define VMALLOC_START (PAGE_OFFSET - VMALLOC_SIZE) |
| 89 | 89 | |
| 90 | −#define FIXADDR_TOP VMALLOC_START | |
| 91 | −#ifdef CONFIG_64BIT | |
| 92 | −#define FIXADDR_SIZE PMD_SIZE | |
| 93 | −#else | |
| 94 | −#define FIXADDR_SIZE PGDIR_SIZE | |
| 95 | −#endif | |
| 96 | −#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) | |
| 97 | − | |
| 98 | 90 | /* |
| 99 | 91 | * Roughly size the vmemmap space to be large enough to fit enough |
| 100 | 92 | * struct pages to map half the virtual address space. Then |
| @@ -108,6 +100,14 @@ extern pgd_t swapper_pg_dir[]; · 7 unmodified lines | ||
| 108 | 100 | |
| 109 | 101 | #define vmemmap ((struct page *)VMEMMAP_START) |
| 110 | 102 | |
| 103 | +#define FIXADDR_TOP (VMEMMAP_START) | |
| 104 | +#ifdef CONFIG_64BIT | |
| 105 | +#define FIXADDR_SIZE PMD_SIZE | |
| 106 | +#else | |
| 107 | +#define FIXADDR_SIZE PGDIR_SIZE | |
| 108 | +#endif | |
| 109 | +#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) | |
| 110 | + | |
| 111 | 111 | /* |
| 112 | 112 | * ZERO_PAGE is a global shared page that is always zero, |
| 113 | 113 | * used for zero-mapped memory areas, etc. |
| @@ -10,10 +10,6 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/mm_types.h> |
| 11 | 11 | #include <asm/smp.h> |
| 12 | 12 | |
| 13 | −/* | |
| 14 | − * Flush entire local TLB. 'sfence.vma' implicitly fences with the instruction | |
| 15 | − * cache as well, so a 'fence.i' is not necessary. | |
| 16 | − */ | |
| 17 | 13 | static inline void local_flush_tlb_all(void) |
| 18 | 14 | { |
| 19 | 15 | __asm__ __volatile__ ("sfence.vma" : : : "memory"); |
| @@ -273,12 +273,11 @@ restore_all: · 272 unmodified lines | ||
| 273 | 273 | resume_kernel: |
| 274 | 274 | REG_L s0, TASK_TI_PREEMPT_COUNT(tp) |
| 275 | 275 | bnez s0, restore_all |
| 276 | −need_resched: | |
| 277 | 276 | REG_L s0, TASK_TI_FLAGS(tp) |
| 278 | 277 | andi s0, s0, _TIF_NEED_RESCHED |
| 279 | 278 | beqz s0, restore_all |
| 280 | 279 | call preempt_schedule_irq |
| 281 | − j need_resched | |
| 280 | + j restore_all | |
| 282 | 281 | #endif |
| 283 | 282 | |
| 284 | 283 | work_pending: |
| @@ -124,24 +124,24 @@ static inline unsigned long get_break_insn_length(unsigned long pc) · 123 unmodified lines | ||
| 124 | 124 | |
| 125 | 125 | asmlinkage void do_trap_break(struct pt_regs *regs) |
| 126 | 126 | { |
| 127 | + if (user_mode(regs)) { | |
| 128 | + force_sig_fault(SIGTRAP, TRAP_BRKPT, | |
| 129 | + (void __user *)(regs->sepc)); | |
| 130 | + return; | |
| 131 | + } | |
| 127 | 132 | #ifdef CONFIG_GENERIC_BUG |
| 128 | − if (!user_mode(regs)) { | |
| 133 | + { | |
| 129 | 134 | enum bug_trap_type type; |
| 130 | 135 | |
| 131 | 136 | type = report_bug(regs->sepc, regs); |
| 132 | − switch (type) { | |
| 133 | − case BUG_TRAP_TYPE_NONE: | |
| 134 | − break; | |
| 135 | − case BUG_TRAP_TYPE_WARN: | |
| 137 | + if (type == BUG_TRAP_TYPE_WARN) { | |
| 136 | 138 | regs->sepc += get_break_insn_length(regs->sepc); |
| 137 | − break; | |
| 138 | − case BUG_TRAP_TYPE_BUG: | |
| 139 | − die(regs, "Kernel BUG"); | |
| 139 | + return; | |
| 140 | 140 | } |
| 141 | 141 | } |
| 142 | 142 | #endif /* CONFIG_GENERIC_BUG */ |
| 143 | 143 | |
| 144 | − force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)(regs->sepc)); | |
| 144 | + die(regs, "Kernel BUG"); | |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | 147 | #ifdef CONFIG_GENERIC_BUG |
| @@ -83,7 +83,7 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n); · 82 unmodified lines | ||
| 83 | 83 | __rc; \ |
| 84 | 84 | }) |
| 85 | 85 | |
| 86 | −static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size) | |
| 86 | +static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size) | |
| 87 | 87 | { |
| 88 | 88 | unsigned long spec = 0x010000UL; |
| 89 | 89 | int rc; |
| @@ -113,7 +113,7 @@ static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size) · 23 unmodified lines | ||
| 113 | 113 | return rc; |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | −static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size) | |
| 116 | +static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size) | |
| 117 | 117 | { |
| 118 | 118 | unsigned long spec = 0x01UL; |
| 119 | 119 | int rc; |
| @@ -29,7 +29,6 @@ config SPARC · 28 unmodified lines | ||
| 29 | 29 | select RTC_DRV_M48T59 |
| 30 | 30 | select RTC_SYSTOHC |
| 31 | 31 | select HAVE_ARCH_JUMP_LABEL if SPARC64 |
| 32 | − select HAVE_FAST_GUP if SPARC64 | |
| 33 | 32 | select GENERIC_IRQ_SHOW |
| 34 | 33 | select ARCH_WANT_IPC_PARSE_VERSION |
| 35 | 34 | select GENERIC_PCI_IOMAP |
| @@ -20,30 +20,6 @@ · 19 unmodified lines | ||
| 20 | 20 | */ |
| 21 | 21 | struct mem_vector immovable_mem[MAX_NUMNODES*2]; |
| 22 | 22 | |
| 23 | −/* | |
| 24 | − * Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex | |
| 25 | − * digits, and '\0' for termination. | |
| 26 | − */ | |
| 27 | −#define MAX_ADDR_LEN 19 | |
| 28 | − | |
| 29 | −static acpi_physical_address get_cmdline_acpi_rsdp(void) | |
| 30 | −{ | |
| 31 | − acpi_physical_address addr = 0; | |
| 32 | − | |
| 33 | −#ifdef CONFIG_KEXEC | |
| 34 | − char val[MAX_ADDR_LEN] = { }; | |
| 35 | − int ret; | |
| 36 | − | |
| 37 | − ret = cmdline_find_option("acpi_rsdp", val, MAX_ADDR_LEN); | |
| 38 | − if (ret < 0) | |
| 39 | − return 0; | |
| 40 | − | |
| 41 | − if (kstrtoull(val, 16, &addr)) | |
| 42 | − return 0; | |
| 43 | −#endif | |
| 44 | − return addr; | |
| 45 | −} | |
| 46 | − | |
| 47 | 23 | /* |
| 48 | 24 | * Search EFI system tables for RSDP. If both ACPI_20_TABLE_GUID and |
| 49 | 25 | * ACPI_TABLE_GUID are found, take the former, which has more features. |
| @@ -298,6 +274,30 @@ acpi_physical_address get_rsdp_addr(void) · 248 unmodified lines | ||
| 298 | 274 | } |
| 299 | 275 | |
| 300 | 276 | #if defined(CONFIG_RANDOMIZE_BASE) && defined(CONFIG_MEMORY_HOTREMOVE) |
| 277 | +/* | |
| 278 | + * Max length of 64-bit hex address string is 19, prefix "0x" + 16 hex | |
| 279 | + * digits, and '\0' for termination. | |
| 280 | + */ | |
| 281 | +#define MAX_ADDR_LEN 19 | |
| 282 | + | |
| 283 | +static acpi_physical_address get_cmdline_acpi_rsdp(void) | |
| 284 | +{ | |
| 285 | + acpi_physical_address addr = 0; | |
| 286 | + | |
| 287 | +#ifdef CONFIG_KEXEC | |
| 288 | + char val[MAX_ADDR_LEN] = { }; | |
| 289 | + int ret; | |
| 290 | + | |
| 291 | + ret = cmdline_find_option("acpi_rsdp", val, MAX_ADDR_LEN); | |
| 292 | + if (ret < 0) | |
| 293 | + return 0; | |
| 294 | + | |
| 295 | + if (kstrtoull(val, 16, &addr)) | |
| 296 | + return 0; | |
| 297 | +#endif | |
| 298 | + return addr; | |
| 299 | +} | |
| 300 | + | |
| 301 | 301 | /* Compute SRAT address from RSDP. */ |
| 302 | 302 | static unsigned long get_acpi_srat_table(void) |
| 303 | 303 | { |
| @@ -345,6 +345,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, · 344 unmodified lines | ||
| 345 | 345 | { |
| 346 | 346 | const unsigned long kernel_total_size = VO__end - VO__text; |
| 347 | 347 | unsigned long virt_addr = LOAD_PHYSICAL_ADDR; |
| 348 | + unsigned long needed_size; | |
| 348 | 349 | |
| 349 | 350 | /* Retain x86 boot parameters pointer passed from startup_32/64. */ |
| 350 | 351 | boot_params = rmode; |
| @@ -379,26 +380,38 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, · 28 unmodified lines | ||
| 379 | 380 | free_mem_ptr = heap; /* Heap */ |
| 380 | 381 | free_mem_end_ptr = heap + BOOT_HEAP_SIZE; |
| 381 | 382 | |
| 383 | + /* | |
| 384 | + * The memory hole needed for the kernel is the larger of either | |
| 385 | + * the entire decompressed kernel plus relocation table, or the | |
| 386 | + * entire decompressed kernel plus .bss and .brk sections. | |
| 387 | + * | |
| 388 | + * On X86_64, the memory is mapped with PMD pages. Round the | |
| 389 | + * size up so that the full extent of PMD pages mapped is | |
| 390 | + * included in the check against the valid memory table | |
| 391 | + * entries. This ensures the full mapped area is usable RAM | |
| 392 | + * and doesn't include any reserved areas. | |
| 393 | + */ | |
| 394 | + needed_size = max(output_len, kernel_total_size); | |
| 395 | +#ifdef CONFIG_X86_64 | |
| 396 | + needed_size = ALIGN(needed_size, MIN_KERNEL_ALIGN); | |
| 397 | +#endif | |
| 398 | + | |
| 382 | 399 | /* Report initial kernel position details. */ |
| 383 | 400 | debug_putaddr(input_data); |
| 384 | 401 | debug_putaddr(input_len); |
| 385 | 402 | debug_putaddr(output); |
| 386 | 403 | debug_putaddr(output_len); |
| 387 | 404 | debug_putaddr(kernel_total_size); |
| 405 | + debug_putaddr(needed_size); | |
| 388 | 406 | |
| 389 | 407 | #ifdef CONFIG_X86_64 |
| 390 | 408 | /* Report address of 32-bit trampoline */ |
| 391 | 409 | debug_putaddr(trampoline_32bit); |
| 392 | 410 | #endif |
| 393 | 411 | |
| 394 | − /* | |
| 395 | − * The memory hole needed for the kernel is the larger of either | |
| 396 | − * the entire decompressed kernel plus relocation table, or the | |
| 397 | − * entire decompressed kernel plus .bss and .brk sections. | |
| 398 | − */ | |
| 399 | 412 | choose_random_location((unsigned long)input_data, input_len, |
| 400 | 413 | (unsigned long *)&output, |
| 401 | − max(output_len, kernel_total_size), | |
| 414 | + needed_size, | |
| 402 | 415 | &virt_addr); |
| 403 | 416 | |
| 404 | 417 | /* Validate memory location choices. */ |
| @@ -5,12 +5,14 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <linux/init.h> |
| 6 | 6 | #include <linux/slab.h> |
| 7 | 7 | #include <linux/delay.h> |
| 8 | +#include <linux/jiffies.h> | |
| 8 | 9 | #include <asm/apicdef.h> |
| 9 | 10 | #include <asm/nmi.h> |
| 10 | 11 | |
| 11 | 12 | #include "../perf_event.h" |
| 12 | 13 | |
| 13 | −static DEFINE_PER_CPU(unsigned int, perf_nmi_counter); | |
| 14 | +static DEFINE_PER_CPU(unsigned long, perf_nmi_tstamp); | |
| 15 | +static unsigned long perf_nmi_window; | |
| 14 | 16 | |
| 15 | 17 | static __initconst const u64 amd_hw_cache_event_ids |
| 16 | 18 | [PERF_COUNT_HW_CACHE_MAX] |
| @@ -641,11 +643,12 @@ static void amd_pmu_disable_event(struct perf_event *event) · 624 unmodified lines | ||
| 641 | 643 | * handler when multiple PMCs are active or PMC overflow while handling some |
| 642 | 644 | * other source of an NMI. |
| 643 | 645 | * |
| 644 | − * Attempt to mitigate this by using the number of active PMCs to determine | |
| 645 | − * whether to return NMI_HANDLED if the perf NMI handler did not handle/reset | |
| 646 | − * any PMCs. The per-CPU perf_nmi_counter variable is set to a minimum of the | |
| 647 | − * number of active PMCs or 2. The value of 2 is used in case an NMI does not | |
| 648 | − * arrive at the LAPIC in time to be collapsed into an already pending NMI. | |
| 646 | + * Attempt to mitigate this by creating an NMI window in which un-handled NMIs | |
| 647 | + * received during this window will be claimed. This prevents extending the | |
| 648 | + * window past when it is possible that latent NMIs should be received. The | |
| 649 | + * per-CPU perf_nmi_tstamp will be set to the window end time whenever perf has | |
| 650 | + * handled a counter. When an un-handled NMI is received, it will be claimed | |
| 651 | + * only if arriving within that window. | |
| 649 | 652 | */ |
| 650 | 653 | static int amd_pmu_handle_irq(struct pt_regs *regs) |
| 651 | 654 | { |
| @@ -663,21 +666,19 @@ static int amd_pmu_handle_irq(struct pt_regs *regs) · 11 unmodified lines | ||
| 663 | 666 | handled = x86_pmu_handle_irq(regs); |
| 664 | 667 | |
| 665 | 668 | /* |
| 666 | − * If a counter was handled, record the number of possible remaining | |
| 667 | − * NMIs that can occur. | |
| 669 | + * If a counter was handled, record a timestamp such that un-handled | |
| 670 | + * NMIs will be claimed if arriving within that window. | |
| 668 | 671 | */ |
| 669 | 672 | if (handled) { |
| 670 | − this_cpu_write(perf_nmi_counter, | |
| 671 | − min_t(unsigned int, 2, active)); | |
| 673 | + this_cpu_write(perf_nmi_tstamp, | |
| 674 | + jiffies + perf_nmi_window); | |
| 672 | 675 | |
| 673 | 676 | return handled; |
| 674 | 677 | } |
| 675 | 678 | |
| 676 | − if (!this_cpu_read(perf_nmi_counter)) | |
| 679 | + if (time_after(jiffies, this_cpu_read(perf_nmi_tstamp))) | |
| 677 | 680 | return NMI_DONE; |
| 678 | 681 | |
| 679 | − this_cpu_dec(perf_nmi_counter); | |
| 680 | − | |
| 681 | 682 | return NMI_HANDLED; |
| 682 | 683 | } |
| 683 | 684 | |
| @@ -909,6 +910,9 @@ static int __init amd_core_pmu_init(void) · 225 unmodified lines | ||
| 909 | 910 | if (!boot_cpu_has(X86_FEATURE_PERFCTR_CORE)) |
| 910 | 911 | return 0; |
| 911 | 912 | |
| 913 | + /* Avoid calulating the value each time in the NMI handler */ | |
| 914 | + perf_nmi_window = msecs_to_jiffies(100); | |
| 915 | + | |
| 912 | 916 | switch (boot_cpu_data.x86) { |
| 913 | 917 | case 0x15: |
| 914 | 918 | pr_cont("Fam15h "); |
| @@ -4983,6 +4983,8 @@ __init int intel_pmu_init(void) · 4982 unmodified lines | ||
| 4983 | 4983 | case INTEL_FAM6_SKYLAKE: |
| 4984 | 4984 | case INTEL_FAM6_KABYLAKE_L: |
| 4985 | 4985 | case INTEL_FAM6_KABYLAKE: |
| 4986 | + case INTEL_FAM6_COMETLAKE_L: | |
| 4987 | + case INTEL_FAM6_COMETLAKE: | |
| 4986 | 4988 | x86_add_quirk(intel_pebs_isolation_quirk); |
| 4987 | 4989 | x86_pmu.late_ack = true; |
| 4988 | 4990 | memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); |
| @@ -5031,6 +5033,8 @@ __init int intel_pmu_init(void) · 42 unmodified lines | ||
| 5031 | 5033 | /* fall through */ |
| 5032 | 5034 | case INTEL_FAM6_ICELAKE_L: |
| 5033 | 5035 | case INTEL_FAM6_ICELAKE: |
| 5036 | + case INTEL_FAM6_TIGERLAKE_L: | |
| 5037 | + case INTEL_FAM6_TIGERLAKE: | |
| 5034 | 5038 | x86_pmu.late_ack = true; |
| 5035 | 5039 | memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids)); |
| 5036 | 5040 | memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); |
| @@ -45,46 +45,49 @@ · 44 unmodified lines | ||
| 45 | 45 | * MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter |
| 46 | 46 | * perf code: 0x01 |
| 47 | 47 | * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,GLM, |
| 48 | − CNL | |
| 48 | + * CNL,KBL,CML | |
| 49 | 49 | * Scope: Core |
| 50 | 50 | * MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter |
| 51 | 51 | * perf code: 0x02 |
| 52 | 52 | * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW, |
| 53 | − * SKL,KNL,GLM,CNL | |
| 53 | + * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL | |
| 54 | 54 | * Scope: Core |
| 55 | 55 | * MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter |
| 56 | 56 | * perf code: 0x03 |
| 57 | − * Available model: SNB,IVB,HSW,BDW,SKL,CNL | |
| 57 | + * Available model: SNB,IVB,HSW,BDW,SKL,CNL,KBL,CML, | |
| 58 | + * ICL,TGL | |
| 58 | 59 | * Scope: Core |
| 59 | 60 | * MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter. |
| 60 | 61 | * perf code: 0x00 |
| 61 | − * Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL | |
| 62 | + * Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL, | |
| 63 | + * KBL,CML,ICL,TGL | |
| 62 | 64 | * Scope: Package (physical package) |
| 63 | 65 | * MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter. |
| 64 | 66 | * perf code: 0x01 |
| 65 | 67 | * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL, |
| 66 | − * GLM,CNL | |
| 68 | + * GLM,CNL,KBL,CML,ICL,TGL | |
| 67 | 69 | * Scope: Package (physical package) |
| 68 | 70 | * MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter. |
| 69 | 71 | * perf code: 0x02 |
| 70 | 72 | * Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW |
| 71 | − * SKL,KNL,GLM,CNL | |
| 73 | + * SKL,KNL,GLM,CNL,KBL,CML,ICL,TGL | |
| 72 | 74 | * Scope: Package (physical package) |
| 73 | 75 | * MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter. |
| 74 | 76 | * perf code: 0x03 |
| 75 | − * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,CNL | |
| 77 | + * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,CNL, | |
| 78 | + * KBL,CML,ICL,TGL | |
| 76 | 79 | * Scope: Package (physical package) |
| 77 | 80 | * MSR_PKG_C8_RESIDENCY: Package C8 Residency Counter. |
| 78 | 81 | * perf code: 0x04 |
| 79 | − * Available model: HSW ULT,KBL,CNL | |
| 82 | + * Available model: HSW ULT,KBL,CNL,CML,ICL,TGL | |
| 80 | 83 | * Scope: Package (physical package) |
| 81 | 84 | * MSR_PKG_C9_RESIDENCY: Package C9 Residency Counter. |
| 82 | 85 | * perf code: 0x05 |
| 83 | − * Available model: HSW ULT,KBL,CNL | |
| 86 | + * Available model: HSW ULT,KBL,CNL,CML,ICL,TGL | |
| 84 | 87 | * Scope: Package (physical package) |
| 85 | 88 | * MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter. |
| 86 | 89 | * perf code: 0x06 |
| 87 | − * Available model: HSW ULT,KBL,GLM,CNL | |
| 90 | + * Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL | |
| 88 | 91 | * Scope: Package (physical package) |
| 89 | 92 | * |
| 90 | 93 | */ |
| @@ -544,6 +547,19 @@ static const struct cstate_model cnl_cstates __initconst = { · 453 unmodified lines | ||
| 544 | 547 | BIT(PERF_CSTATE_PKG_C10_RES), |
| 545 | 548 | }; |
| 546 | 549 | |
| 550 | +static const struct cstate_model icl_cstates __initconst = { | |
| 551 | + .core_events = BIT(PERF_CSTATE_CORE_C6_RES) | | |
| 552 | + BIT(PERF_CSTATE_CORE_C7_RES), | |
| 553 | + | |
| 554 | + .pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) | | |
| 555 | + BIT(PERF_CSTATE_PKG_C3_RES) | | |
| 556 | + BIT(PERF_CSTATE_PKG_C6_RES) | | |
| 557 | + BIT(PERF_CSTATE_PKG_C7_RES) | | |
| 558 | + BIT(PERF_CSTATE_PKG_C8_RES) | | |
| 559 | + BIT(PERF_CSTATE_PKG_C9_RES) | | |
| 560 | + BIT(PERF_CSTATE_PKG_C10_RES), | |
| 561 | +}; | |
| 562 | + | |
| 547 | 563 | static const struct cstate_model slm_cstates __initconst = { |
| 548 | 564 | .core_events = BIT(PERF_CSTATE_CORE_C1_RES) | |
| 549 | 565 | BIT(PERF_CSTATE_CORE_C6_RES), |
| @@ -614,6 +630,8 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { · 64 unmodified lines | ||
| 614 | 630 | |
| 615 | 631 | X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE_L, hswult_cstates), |
| 616 | 632 | X86_CSTATES_MODEL(INTEL_FAM6_KABYLAKE, hswult_cstates), |
| 633 | + X86_CSTATES_MODEL(INTEL_FAM6_COMETLAKE_L, hswult_cstates), | |
| 634 | + X86_CSTATES_MODEL(INTEL_FAM6_COMETLAKE, hswult_cstates), | |
| 617 | 635 | |
| 618 | 636 | X86_CSTATES_MODEL(INTEL_FAM6_CANNONLAKE_L, cnl_cstates), |
| 619 | 637 | |
| @@ -625,8 +643,10 @@ static const struct x86_cpu_id intel_cstates_match[] __initconst = { · 5 unmodified lines | ||
| 625 | 643 | |
| 626 | 644 | X86_CSTATES_MODEL(INTEL_FAM6_ATOM_GOLDMONT_PLUS, glm_cstates), |
| 627 | 645 | |
| 628 | − X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_L, snb_cstates), | |
| 629 | − X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE, snb_cstates), | |
| 646 | + X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE_L, icl_cstates), | |
| 647 | + X86_CSTATES_MODEL(INTEL_FAM6_ICELAKE, icl_cstates), | |
| 648 | + X86_CSTATES_MODEL(INTEL_FAM6_TIGERLAKE_L, icl_cstates), | |
| 649 | + X86_CSTATES_MODEL(INTEL_FAM6_TIGERLAKE, icl_cstates), | |
| 630 | 650 | { }, |
| 631 | 651 | }; |
| 632 | 652 | MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match); |
| @@ -89,7 +89,14 @@ static bool test_intel(int idx, void *data) · 88 unmodified lines | ||
| 89 | 89 | case INTEL_FAM6_SKYLAKE_X: |
| 90 | 90 | case INTEL_FAM6_KABYLAKE_L: |
| 91 | 91 | case INTEL_FAM6_KABYLAKE: |
| 92 | + case INTEL_FAM6_COMETLAKE_L: | |
| 93 | + case INTEL_FAM6_COMETLAKE: | |
| 92 | 94 | case INTEL_FAM6_ICELAKE_L: |
| 95 | + case INTEL_FAM6_ICELAKE: | |
| 96 | + case INTEL_FAM6_ICELAKE_X: | |
| 97 | + case INTEL_FAM6_ICELAKE_D: | |
| 98 | + case INTEL_FAM6_TIGERLAKE_L: | |
| 99 | + case INTEL_FAM6_TIGERLAKE: | |
| 93 | 100 | if (idx == PERF_MSR_SMI || idx == PERF_MSR_PPERF) |
| 94 | 101 | return true; |
| 95 | 102 | break; |
| @@ -260,11 +260,21 @@ void __init hv_apic_init(void) · 259 unmodified lines | ||
| 260 | 260 | } |
| 261 | 261 | |
| 262 | 262 | if (ms_hyperv.hints & HV_X64_APIC_ACCESS_RECOMMENDED) { |
| 263 | − pr_info("Hyper-V: Using MSR based APIC access\n"); | |
| 263 | + pr_info("Hyper-V: Using enlightened APIC (%s mode)", | |
| 264 | + x2apic_enabled() ? "x2apic" : "xapic"); | |
| 265 | + /* | |
| 266 | + * With x2apic, architectural x2apic MSRs are equivalent to the | |
| 267 | + * respective synthetic MSRs, so there's no need to override | |
| 268 | + * the apic accessors. The only exception is | |
| 269 | + * hv_apic_eoi_write, because it benefits from lazy EOI when | |
| 270 | + * available, but it works for both xapic and x2apic modes. | |
| 271 | + */ | |
| 264 | 272 | apic_set_eoi_write(hv_apic_eoi_write); |
| 265 | − apic->read = hv_apic_read; | |
| 266 | − apic->write = hv_apic_write; | |
| 267 | − apic->icr_write = hv_apic_icr_write; | |
| 268 | − apic->icr_read = hv_apic_icr_read; | |
| 273 | + if (!x2apic_enabled()) { | |
| 274 | + apic->read = hv_apic_read; | |
| 275 | + apic->write = hv_apic_write; | |
| 276 | + apic->icr_write = hv_apic_icr_write; | |
| 277 | + apic->icr_read = hv_apic_icr_read; | |
| 278 | + } | |
| 269 | 279 | } |
| 270 | 280 | } |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | |
| 3 | 3 | #ifndef _ASM_X86_CPU_ENTRY_AREA_H |
| 4 | 4 | #define _ASM_X86_CPU_ENTRY_AREA_H |
| @@ -83,6 +83,9 @@ · 82 unmodified lines | ||
| 83 | 83 | #define INTEL_FAM6_TIGERLAKE_L 0x8C |
| 84 | 84 | #define INTEL_FAM6_TIGERLAKE 0x8D |
| 85 | 85 | |
| 86 | +#define INTEL_FAM6_COMETLAKE 0xA5 | |
| 87 | +#define INTEL_FAM6_COMETLAKE_L 0xA6 | |
| 88 | + | |
| 86 | 89 | /* "Small Core" Processors (Atom) */ |
| 87 | 90 | |
| 88 | 91 | #define INTEL_FAM6_ATOM_BONNELL 0x1C /* Diamondville, Pineview */ |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #define MWAIT_ECX_INTERRUPT_BREAK 0x1 |
| 22 | 22 | #define MWAITX_ECX_TIMER_ENABLE BIT(1) |
| 23 | 23 | #define MWAITX_MAX_LOOPS ((u32)-1) |
| 24 | −#define MWAITX_DISABLE_CSTATES 0xf | |
| 24 | +#define MWAITX_DISABLE_CSTATES 0xf0 | |
| 25 | 25 | |
| 26 | 26 | static inline void __monitor(const void *eax, unsigned long ecx, |
| 27 | 27 | unsigned long edx) |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | #ifndef _ASM_X86_PTI_H |
| 3 | 3 | #define _ASM_X86_PTI_H |
| 4 | 4 | #ifndef __ASSEMBLY__ |
| @@ -734,5 +734,28 @@ do { \ · 733 unmodified lines | ||
| 734 | 734 | if (unlikely(__gu_err)) goto err_label; \ |
| 735 | 735 | } while (0) |
| 736 | 736 | |
| 737 | +/* | |
| 738 | + * We want the unsafe accessors to always be inlined and use | |
| 739 | + * the error labels - thus the macro games. | |
| 740 | + */ | |
| 741 | +#define unsafe_copy_loop(dst, src, len, type, label) \ | |
| 742 | + while (len >= sizeof(type)) { \ | |
| 743 | + unsafe_put_user(*(type *)src,(type __user *)dst,label); \ | |
| 744 | + dst += sizeof(type); \ | |
| 745 | + src += sizeof(type); \ | |
| 746 | + len -= sizeof(type); \ | |
| 747 | + } | |
| 748 | + | |
| 749 | +#define unsafe_copy_to_user(_dst,_src,_len,label) \ | |
| 750 | +do { \ | |
| 751 | + char __user *__ucu_dst = (_dst); \ | |
| 752 | + const char *__ucu_src = (_src); \ | |
| 753 | + size_t __ucu_len = (_len); \ | |
| 754 | + unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u64, label); \ | |
| 755 | + unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u32, label); \ | |
| 756 | + unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u16, label); \ | |
| 757 | + unsafe_copy_loop(__ucu_dst, __ucu_src, __ucu_len, u8, label); \ | |
| 758 | +} while (0) | |
| 759 | + | |
| 737 | 760 | #endif /* _ASM_X86_UACCESS_H */ |
| 738 | 761 | |
| @@ -156,7 +156,8 @@ static int x2apic_dead_cpu(unsigned int dead_cpu) · 155 unmodified lines | ||
| 156 | 156 | { |
| 157 | 157 | struct cluster_mask *cmsk = per_cpu(cluster_masks, dead_cpu); |
| 158 | 158 | |
| 159 | − cpumask_clear_cpu(dead_cpu, &cmsk->mask); | |
| 159 | + if (cmsk) | |
| 160 | + cpumask_clear_cpu(dead_cpu, &cmsk->mask); | |
| 160 | 161 | free_cpumask_var(per_cpu(ipi_mask, dead_cpu)); |
| 161 | 162 | return 0; |
| 162 | 163 | } |
| @@ -216,6 +216,10 @@ static void __init ms_hyperv_init_platform(void) · 215 unmodified lines | ||
| 216 | 216 | int hv_host_info_ecx; |
| 217 | 217 | int hv_host_info_edx; |
| 218 | 218 | |
| 219 | +#ifdef CONFIG_PARAVIRT | |
| 220 | + pv_info.name = "Hyper-V"; | |
| 221 | +#endif | |
| 222 | + | |
| 219 | 223 | /* |
| 220 | 224 | * Extract the features and hints |
| 221 | 225 | */ |
| @@ -49,7 +49,7 @@ · 48 unmodified lines | ||
| 49 | 49 | #define VMWARE_CMD_VCPU_RESERVED 31 |
| 50 | 50 | |
| 51 | 51 | #define VMWARE_PORT(cmd, eax, ebx, ecx, edx) \ |
| 52 | − __asm__("inl (%%dx)" : \ | |
| 52 | + __asm__("inl (%%dx), %%eax" : \ | |
| 53 | 53 | "=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) : \ |
| 54 | 54 | "a"(VMWARE_HYPERVISOR_MAGIC), \ |
| 55 | 55 | "c"(VMWARE_CMD_##cmd), \ |
| @@ -222,13 +222,31 @@ unsigned long __head __startup_64(unsigned long physaddr, · 221 unmodified lines | ||
| 222 | 222 | * we might write invalid pmds, when the kernel is relocated |
| 223 | 223 | * cleanup_highmap() fixes this up along with the mappings |
| 224 | 224 | * beyond _end. |
| 225 | + * | |
| 226 | + * Only the region occupied by the kernel image has so far | |
| 227 | + * been checked against the table of usable memory regions | |
| 228 | + * provided by the firmware, so invalidate pages outside that | |
| 229 | + * region. A page table entry that maps to a reserved area of | |
| 230 | + * memory would allow processor speculation into that area, | |
| 231 | + * and on some hardware (particularly the UV platform) even | |
| 232 | + * speculative access to some reserved areas is caught as an | |
| 233 | + * error, causing the BIOS to halt the system. | |
| 225 | 234 | */ |
| 226 | 235 | |
| 227 | 236 | pmd = fixup_pointer(level2_kernel_pgt, physaddr); |
| 228 | − for (i = 0; i < PTRS_PER_PMD; i++) { | |
| 237 | + | |
| 238 | + /* invalidate pages before the kernel image */ | |
| 239 | + for (i = 0; i < pmd_index((unsigned long)_text); i++) | |
| 240 | + pmd[i] &= ~_PAGE_PRESENT; | |
| 241 | + | |
| 242 | + /* fixup pages that are part of the kernel image */ | |
| 243 | + for (; i <= pmd_index((unsigned long)_end); i++) | |
| 229 | 244 | if (pmd[i] & _PAGE_PRESENT) |
| 230 | 245 | pmd[i] += load_delta; |
| 231 | − } | |
| 246 | + | |
| 247 | + /* invalidate pages after the kernel image */ | |
| 248 | + for (; i < PTRS_PER_PMD; i++) | |
| 249 | + pmd[i] &= ~_PAGE_PRESENT; | |
| 232 | 250 | |
| 233 | 251 | /* |
| 234 | 252 | * Fixup phys_base - remove the memory encryption mask to obtain |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | // |
| 3 | 3 | // Code shared between 32 and 64 bit |
| 4 | 4 | |
| @@ -113,8 +113,8 @@ static void delay_mwaitx(unsigned long __loops) · 112 unmodified lines | ||
| 113 | 113 | __monitorx(raw_cpu_ptr(&cpu_tss_rw), 0, 0); |
| 114 | 114 | |
| 115 | 115 | /* |
| 116 | − * AMD, like Intel, supports the EAX hint and EAX=0xf | |
| 117 | − * means, do not enter any deep C-state and we use it | |
| 116 | + * AMD, like Intel's MWAIT version, supports the EAX hint and | |
| 117 | + * EAX=0xf0 means, do not enter any deep C-state and we use it | |
| 118 | 118 | * here in delay() to minimize wakeup latency. |
| 119 | 119 | */ |
| 120 | 120 | __mwaitx(MWAITX_DISABLE_CSTATES, delay, MWAITX_ECX_TIMER_ENABLE); |
| @@ -917,9 +917,6 @@ static void __init kexec_enter_virtual_mode(void) · 916 unmodified lines | ||
| 917 | 917 | |
| 918 | 918 | if (efi_enabled(EFI_OLD_MEMMAP) && (__supported_pte_mask & _PAGE_NX)) |
| 919 | 919 | runtime_code_page_mkexec(); |
| 920 | − | |
| 921 | − /* clean DUMMY object */ | |
| 922 | − efi_delete_dummy_variable(); | |
| 923 | 920 | #endif |
| 924 | 921 | } |
| 925 | 922 | |
| @@ -269,19 +269,41 @@ void xen_reboot(int reason) · 268 unmodified lines | ||
| 269 | 269 | BUG(); |
| 270 | 270 | } |
| 271 | 271 | |
| 272 | +static int reboot_reason = SHUTDOWN_reboot; | |
| 273 | +static bool xen_legacy_crash; | |
| 272 | 274 | void xen_emergency_restart(void) |
| 273 | 275 | { |
| 274 | − xen_reboot(SHUTDOWN_reboot); | |
| 276 | + xen_reboot(reboot_reason); | |
| 275 | 277 | } |
| 276 | 278 | |
| 277 | 279 | static int |
| 278 | 280 | xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr) |
| 279 | 281 | { |
| 280 | − if (!kexec_crash_loaded()) | |
| 281 | − xen_reboot(SHUTDOWN_crash); | |
| 282 | + if (!kexec_crash_loaded()) { | |
| 283 | + if (xen_legacy_crash) | |
| 284 | + xen_reboot(SHUTDOWN_crash); | |
| 285 | + | |
| 286 | + reboot_reason = SHUTDOWN_crash; | |
| 287 | + | |
| 288 | + /* | |
| 289 | + * If panic_timeout==0 then we are supposed to wait forever. | |
| 290 | + * However, to preserve original dom0 behavior we have to drop | |
| 291 | + * into hypervisor. (domU behavior is controlled by its | |
| 292 | + * config file) | |
| 293 | + */ | |
| 294 | + if (panic_timeout == 0) | |
| 295 | + panic_timeout = -1; | |
| 296 | + } | |
| 282 | 297 | return NOTIFY_DONE; |
| 283 | 298 | } |
| 284 | 299 | |
| 300 | +static int __init parse_xen_legacy_crash(char *arg) | |
| 301 | +{ | |
| 302 | + xen_legacy_crash = true; | |
| 303 | + return 0; | |
| 304 | +} | |
| 305 | +early_param("xen_legacy_crash", parse_xen_legacy_crash); | |
| 306 | + | |
| 285 | 307 | static struct notifier_block xen_panic_block = { |
| 286 | 308 | .notifier_call = xen_panic_event, |
| 287 | 309 | .priority = INT_MIN |
| @@ -56,7 +56,7 @@ · 55 unmodified lines | ||
| 56 | 56 | reg = <0xf0100000 0x03f00000>; |
| 57 | 57 | |
| 58 | 58 | // BUS_ADDRESS(3) CPU_PHYSICAL(1) SIZE(2) |
| 59 | − ranges = <0x01000000 0x0 0xf0000000 0xf0000000 0x0 0x00010000>, | |
| 59 | + ranges = <0x01000000 0x0 0x00000000 0xf0000000 0x0 0x00010000>, | |
| 60 | 60 | <0x02000000 0x0 0xf4000000 0xf4000000 0x0 0x08000000>; |
| 61 | 61 | |
| 62 | 62 | // PCI_DEVICE(3) INT#(1) CONTROLLER(PHANDLE) CONTROLLER_DATA(2) |
| @@ -148,7 +148,7 @@ static inline void change_bit(unsigned int bit, volatile unsigned long *p) · 147 unmodified lines | ||
| 148 | 148 | " getex %0\n" |
| 149 | 149 | " beqz %0, 1b\n" |
| 150 | 150 | : "=&a" (tmp) |
| 151 | − : "a" (~mask), "a" (p) | |
| 151 | + : "a" (mask), "a" (p) | |
| 152 | 152 | : "memory"); |
| 153 | 153 | } |
| 154 | 154 | |
| @@ -100,7 +100,7 @@ do { \ · 99 unmodified lines | ||
| 100 | 100 | case 4: __put_user_asm(x, ptr, retval, 4, "s32i", __cb); break; \ |
| 101 | 101 | case 8: { \ |
| 102 | 102 | __typeof__(*ptr) __v64 = x; \ |
| 103 | − retval = __copy_to_user(ptr, &__v64, 8); \ | |
| 103 | + retval = __copy_to_user(ptr, &__v64, 8) ? -EFAULT : 0; \ | |
| 104 | 104 | break; \ |
| 105 | 105 | } \ |
| 106 | 106 | default: __put_user_bad(); \ |
| @@ -132,14 +132,14 @@ do { \ · 25 unmodified lines | ||
| 132 | 132 | #define __check_align_1 "" |
| 133 | 133 | |
| 134 | 134 | #define __check_align_2 \ |
| 135 | − " _bbci.l %3, 0, 1f \n" \ | |
| 136 | − " movi %0, %4 \n" \ | |
| 135 | + " _bbci.l %[addr], 0, 1f \n" \ | |
| 136 | + " movi %[err], %[efault] \n" \ | |
| 137 | 137 | " _j 2f \n" |
| 138 | 138 | |
| 139 | 139 | #define __check_align_4 \ |
| 140 | − " _bbsi.l %3, 0, 0f \n" \ | |
| 141 | − " _bbci.l %3, 1, 1f \n" \ | |
| 142 | − "0: movi %0, %4 \n" \ | |
| 140 | + " _bbsi.l %[addr], 0, 0f \n" \ | |
| 141 | + " _bbci.l %[addr], 1, 1f \n" \ | |
| 142 | + "0: movi %[err], %[efault] \n" \ | |
| 143 | 143 | " _j 2f \n" |
| 144 | 144 | |
| 145 | 145 | |
| @@ -151,40 +151,40 @@ do { \ · 5 unmodified lines | ||
| 151 | 151 | * WARNING: If you modify this macro at all, verify that the |
| 152 | 152 | * __check_align_* macros still work. |
| 153 | 153 | */ |
| 154 | −#define __put_user_asm(x, addr, err, align, insn, cb) \ | |
| 154 | +#define __put_user_asm(x_, addr_, err_, align, insn, cb)\ | |
| 155 | 155 | __asm__ __volatile__( \ |
| 156 | 156 | __check_align_##align \ |
| 157 | − "1: "insn" %2, %3, 0 \n" \ | |
| 157 | + "1: "insn" %[x], %[addr], 0 \n" \ | |
| 158 | 158 | "2: \n" \ |
| 159 | 159 | " .section .fixup,\"ax\" \n" \ |
| 160 | 160 | " .align 4 \n" \ |
| 161 | 161 | " .literal_position \n" \ |
| 162 | 162 | "5: \n" \ |
| 163 | − " movi %1, 2b \n" \ | |
| 164 | − " movi %0, %4 \n" \ | |
| 165 | − " jx %1 \n" \ | |
| 163 | + " movi %[tmp], 2b \n" \ | |
| 164 | + " movi %[err], %[efault] \n" \ | |
| 165 | + " jx %[tmp] \n" \ | |
| 166 | 166 | " .previous \n" \ |
| 167 | 167 | " .section __ex_table,\"a\" \n" \ |
| 168 | 168 | " .long 1b, 5b \n" \ |
| 169 | 169 | " .previous" \ |
| 170 | − :"=r" (err), "=r" (cb) \ | |
| 171 | − :"r" ((int)(x)), "r" (addr), "i" (-EFAULT), "0" (err)) | |
| 170 | + :[err] "+r"(err_), [tmp] "=r"(cb) \ | |
| 171 | + :[x] "r"(x_), [addr] "r"(addr_), [efault] "i"(-EFAULT)) | |
| 172 | 172 | |
| 173 | 173 | #define __get_user_nocheck(x, ptr, size) \ |
| 174 | 174 | ({ \ |
| 175 | − long __gu_err, __gu_val; \ | |
| 176 | − __get_user_size(__gu_val, (ptr), (size), __gu_err); \ | |
| 177 | − (x) = (__force __typeof__(*(ptr)))__gu_val; \ | |
| 175 | + long __gu_err; \ | |
| 176 | + __get_user_size((x), (ptr), (size), __gu_err); \ | |
| 178 | 177 | __gu_err; \ |
| 179 | 178 | }) |
| 180 | 179 | |
| 181 | 180 | #define __get_user_check(x, ptr, size) \ |
| 182 | 181 | ({ \ |
| 183 | − long __gu_err = -EFAULT, __gu_val = 0; \ | |
| 182 | + long __gu_err = -EFAULT; \ | |
| 184 | 183 | const __typeof__(*(ptr)) *__gu_addr = (ptr); \ |
| 185 | − if (access_ok(__gu_addr, size)) \ | |
| 186 | − __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ | |
| 187 | − (x) = (__force __typeof__(*(ptr)))__gu_val; \ | |
| 184 | + if (access_ok(__gu_addr, size)) \ | |
| 185 | + __get_user_size((x), __gu_addr, (size), __gu_err); \ | |
| 186 | + else \ | |
| 187 | + (x) = 0; \ | |
| 188 | 188 | __gu_err; \ |
| 189 | 189 | }) |
| 190 | 190 | |
| @@ -198,8 +198,17 @@ do { \ · 7 unmodified lines | ||
| 198 | 198 | case 1: __get_user_asm(x, ptr, retval, 1, "l8ui", __cb); break;\ |
| 199 | 199 | case 2: __get_user_asm(x, ptr, retval, 2, "l16ui", __cb); break;\ |
| 200 | 200 | case 4: __get_user_asm(x, ptr, retval, 4, "l32i", __cb); break;\ |
| 201 | − case 8: retval = __copy_from_user(&x, ptr, 8); break; \ | |
| 202 | − default: (x) = __get_user_bad(); \ | |
| 201 | + case 8: { \ | |
| 202 | + u64 __x; \ | |
| 203 | + if (unlikely(__copy_from_user(&__x, ptr, 8))) { \ | |
| 204 | + retval = -EFAULT; \ | |
| 205 | + (x) = 0; \ | |
| 206 | + } else { \ | |
| 207 | + (x) = *(__force __typeof__((ptr)))&__x; \ | |
| 208 | + } \ | |
| 209 | + break; \ | |
| 210 | + } \ | |
| 211 | + default: (x) = 0; __get_user_bad(); \ | |
| 203 | 212 | } \ |
| 204 | 213 | } while (0) |
| 205 | 214 | |
| @@ -208,25 +217,28 @@ do { \ · 2 unmodified lines | ||
| 208 | 217 | * WARNING: If you modify this macro at all, verify that the |
| 209 | 218 | * __check_align_* macros still work. |
| 210 | 219 | */ |
| 211 | −#define __get_user_asm(x, addr, err, align, insn, cb) \ | |
| 212 | −__asm__ __volatile__( \ | |
| 213 | − __check_align_##align \ | |
| 214 | − "1: "insn" %2, %3, 0 \n" \ | |
| 215 | − "2: \n" \ | |
| 216 | − " .section .fixup,\"ax\" \n" \ | |
| 217 | − " .align 4 \n" \ | |
| 218 | − " .literal_position \n" \ | |
| 219 | − "5: \n" \ | |
| 220 | − " movi %1, 2b \n" \ | |
| 221 | − " movi %2, 0 \n" \ | |
| 222 | − " movi %0, %4 \n" \ | |
| 223 | − " jx %1 \n" \ | |
| 224 | − " .previous \n" \ | |
| 225 | − " .section __ex_table,\"a\" \n" \ | |
| 226 | − " .long 1b, 5b \n" \ | |
| 227 | − " .previous" \ | |
| 228 | − :"=r" (err), "=r" (cb), "=r" (x) \ | |
| 229 | − :"r" (addr), "i" (-EFAULT), "0" (err)) | |
| 220 | +#define __get_user_asm(x_, addr_, err_, align, insn, cb) \ | |
| 221 | +do { \ | |
| 222 | + u32 __x = 0; \ | |
| 223 | + __asm__ __volatile__( \ | |
| 224 | + __check_align_##align \ | |
| 225 | + "1: "insn" %[x], %[addr], 0 \n" \ | |
| 226 | + "2: \n" \ | |
| 227 | + " .section .fixup,\"ax\" \n" \ | |
| 228 | + " .align 4 \n" \ | |
| 229 | + " .literal_position \n" \ | |
| 230 | + "5: \n" \ | |
| 231 | + " movi %[tmp], 2b \n" \ | |
| 232 | + " movi %[err], %[efault] \n" \ | |
| 233 | + " jx %[tmp] \n" \ | |
| 234 | + " .previous \n" \ | |
| 235 | + " .section __ex_table,\"a\" \n" \ | |
| 236 | + " .long 1b, 5b \n" \ | |
| 237 | + " .previous" \ | |
| 238 | + :[err] "+r"(err_), [tmp] "=r"(cb), [x] "+r"(__x) \ | |
| 239 | + :[addr] "r"(addr_), [efault] "i"(-EFAULT)); \ | |
| 240 | + (x_) = (__force __typeof__(*(addr_)))__x; \ | |
| 241 | +} while (0) | |
| 230 | 242 | |
| 231 | 243 | |
| 232 | 244 | /* |
| @@ -119,13 +119,6 @@ EXPORT_SYMBOL(__invalidate_icache_range); · 118 unmodified lines | ||
| 119 | 119 | // FIXME EXPORT_SYMBOL(screen_info); |
| 120 | 120 | #endif |
| 121 | 121 | |
| 122 | −EXPORT_SYMBOL(outsb); | |
| 123 | −EXPORT_SYMBOL(outsw); | |
| 124 | −EXPORT_SYMBOL(outsl); | |
| 125 | −EXPORT_SYMBOL(insb); | |
| 126 | −EXPORT_SYMBOL(insw); | |
| 127 | −EXPORT_SYMBOL(insl); | |
| 128 | − | |
| 129 | 122 | extern long common_exception_return; |
| 130 | 123 | EXPORT_SYMBOL(common_exception_return); |
| 131 | 124 | |
| @@ -1362,7 +1362,7 @@ int blkcg_activate_policy(struct request_queue *q, · 1361 unmodified lines | ||
| 1362 | 1362 | const struct blkcg_policy *pol) |
| 1363 | 1363 | { |
| 1364 | 1364 | struct blkg_policy_data *pd_prealloc = NULL; |
| 1365 | − struct blkcg_gq *blkg; | |
| 1365 | + struct blkcg_gq *blkg, *pinned_blkg = NULL; | |
| 1366 | 1366 | int ret; |
| 1367 | 1367 | |
| 1368 | 1368 | if (blkcg_policy_enabled(q, pol)) |
| @@ -1370,49 +1370,82 @@ int blkcg_activate_policy(struct request_queue *q, · 1 unmodified line | ||
| 1370 | 1370 | |
| 1371 | 1371 | if (queue_is_mq(q)) |
| 1372 | 1372 | blk_mq_freeze_queue(q); |
| 1373 | −pd_prealloc: | |
| 1374 | − if (!pd_prealloc) { | |
| 1375 | − pd_prealloc = pol->pd_alloc_fn(GFP_KERNEL, q, &blkcg_root); | |
| 1376 | − if (!pd_prealloc) { | |
| 1377 | − ret = -ENOMEM; | |
| 1378 | − goto out_bypass_end; | |
| 1379 | − } | |
| 1380 | − } | |
| 1381 | − | |
| 1373 | +retry: | |
| 1382 | 1374 | spin_lock_irq(&q->queue_lock); |
| 1383 | 1375 | |
| 1384 | − /* blkg_list is pushed at the head, reverse walk to init parents first */ | |
| 1376 | + /* blkg_list is pushed at the head, reverse walk to allocate parents first */ | |
| 1385 | 1377 | list_for_each_entry_reverse(blkg, &q->blkg_list, q_node) { |
| 1386 | 1378 | struct blkg_policy_data *pd; |
| 1387 | 1379 | |
| 1388 | 1380 | if (blkg->pd[pol->plid]) |
| 1389 | 1381 | continue; |
| 1390 | 1382 | |
| 1391 | − pd = pol->pd_alloc_fn(GFP_NOWAIT | __GFP_NOWARN, q, &blkcg_root); | |
| 1392 | − if (!pd) | |
| 1393 | − swap(pd, pd_prealloc); | |
| 1383 | + /* If prealloc matches, use it; otherwise try GFP_NOWAIT */ | |
| 1384 | + if (blkg == pinned_blkg) { | |
| 1385 | + pd = pd_prealloc; | |
| 1386 | + pd_prealloc = NULL; | |
| 1387 | + } else { | |
| 1388 | + pd = pol->pd_alloc_fn(GFP_NOWAIT | __GFP_NOWARN, q, | |
| 1389 | + blkg->blkcg); | |
| 1390 | + } | |
| 1391 | + | |
| 1394 | 1392 | if (!pd) { |
| 1393 | + /* | |
| 1394 | + * GFP_NOWAIT failed. Free the existing one and | |
| 1395 | + * prealloc for @blkg w/ GFP_KERNEL. | |
| 1396 | + */ | |
| 1397 | + if (pinned_blkg) | |
| 1398 | + blkg_put(pinned_blkg); | |
| 1399 | + blkg_get(blkg); | |
| 1400 | + pinned_blkg = blkg; | |
| 1401 | + | |
| 1395 | 1402 | spin_unlock_irq(&q->queue_lock); |
| 1396 | − goto pd_prealloc; | |
| 1403 | + | |
| 1404 | + if (pd_prealloc) | |
| 1405 | + pol->pd_free_fn(pd_prealloc); | |
| 1406 | + pd_prealloc = pol->pd_alloc_fn(GFP_KERNEL, q, | |
| 1407 | + blkg->blkcg); | |
| 1408 | + if (pd_prealloc) | |
| 1409 | + goto retry; | |
| 1410 | + else | |
| 1411 | + goto enomem; | |
| 1397 | 1412 | } |
| 1398 | 1413 | |
| 1399 | 1414 | blkg->pd[pol->plid] = pd; |
| 1400 | 1415 | pd->blkg = blkg; |
| 1401 | 1416 | pd->plid = pol->plid; |
| 1402 | − if (pol->pd_init_fn) | |
| 1403 | − pol->pd_init_fn(pd); | |
| 1404 | 1417 | } |
| 1405 | 1418 | |
| 1419 | + /* all allocated, init in the same order */ | |
| 1420 | + if (pol->pd_init_fn) | |
| 1421 | + list_for_each_entry_reverse(blkg, &q->blkg_list, q_node) | |
| 1422 | + pol->pd_init_fn(blkg->pd[pol->plid]); | |
| 1423 | + | |
| 1406 | 1424 | __set_bit(pol->plid, q->blkcg_pols); |
| 1407 | 1425 | ret = 0; |
| 1408 | 1426 | |
| 1409 | 1427 | spin_unlock_irq(&q->queue_lock); |
| 1410 | −out_bypass_end: | |
| 1428 | +out: | |
| 1411 | 1429 | if (queue_is_mq(q)) |
| 1412 | 1430 | blk_mq_unfreeze_queue(q); |
| 1431 | + if (pinned_blkg) | |
| 1432 | + blkg_put(pinned_blkg); | |
| 1413 | 1433 | if (pd_prealloc) |
| 1414 | 1434 | pol->pd_free_fn(pd_prealloc); |
| 1415 | 1435 | return ret; |
| 1436 | + | |
| 1437 | +enomem: | |
| 1438 | + /* alloc failed, nothing's initialized yet, free everything */ | |
| 1439 | + spin_lock_irq(&q->queue_lock); | |
| 1440 | + list_for_each_entry(blkg, &q->blkg_list, q_node) { | |
| 1441 | + if (blkg->pd[pol->plid]) { | |
| 1442 | + pol->pd_free_fn(blkg->pd[pol->plid]); | |
| 1443 | + blkg->pd[pol->plid] = NULL; | |
| 1444 | + } | |
| 1445 | + } | |
| 1446 | + spin_unlock_irq(&q->queue_lock); | |
| 1447 | + ret = -ENOMEM; | |
| 1448 | + goto out; | |
| 1416 | 1449 | } |
| 1417 | 1450 | EXPORT_SYMBOL_GPL(blkcg_activate_policy); |
| 1418 | 1451 | |
| @@ -160,24 +160,27 @@ bool rq_depth_calc_max_depth(struct rq_depth *rqd) · 159 unmodified lines | ||
| 160 | 160 | return ret; |
| 161 | 161 | } |
| 162 | 162 | |
| 163 | −void rq_depth_scale_up(struct rq_depth *rqd) | |
| 163 | +/* Returns true on success and false if scaling up wasn't possible */ | |
| 164 | +bool rq_depth_scale_up(struct rq_depth *rqd) | |
| 164 | 165 | { |
| 165 | 166 | /* |
| 166 | 167 | * Hit max in previous round, stop here |
| 167 | 168 | */ |
| 168 | 169 | if (rqd->scaled_max) |
| 169 | − return; | |
| 170 | + return false; | |
| 170 | 171 | |
| 171 | 172 | rqd->scale_step--; |
| 172 | 173 | |
| 173 | 174 | rqd->scaled_max = rq_depth_calc_max_depth(rqd); |
| 175 | + return true; | |
| 174 | 176 | } |
| 175 | 177 | |
| 176 | 178 | /* |
| 177 | 179 | * Scale rwb down. If 'hard_throttle' is set, do it quicker, since we |
| 178 | − * had a latency violation. | |
| 180 | + * had a latency violation. Returns true on success and returns false if | |
| 181 | + * scaling down wasn't possible. | |
| 179 | 182 | */ |
| 180 | −void rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle) | |
| 183 | +bool rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle) | |
| 181 | 184 | { |
| 182 | 185 | /* |
| 183 | 186 | * Stop scaling down when we've hit the limit. This also prevents |
| @@ -185,7 +188,7 @@ void rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle) · 1 unmodified line | ||
| 185 | 188 | * keep up. |
| 186 | 189 | */ |
| 187 | 190 | if (rqd->max_depth == 1) |
| 188 | − return; | |
| 191 | + return false; | |
| 189 | 192 | |
| 190 | 193 | if (rqd->scale_step < 0 && hard_throttle) |
| 191 | 194 | rqd->scale_step = 0; |
| @@ -194,6 +197,7 @@ void rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle) · 2 unmodified lines | ||
| 194 | 197 | |
| 195 | 198 | rqd->scaled_max = false; |
| 196 | 199 | rq_depth_calc_max_depth(rqd); |
| 200 | + return true; | |
| 197 | 201 | } |
| 198 | 202 | |
| 199 | 203 | struct rq_qos_wait_data { |
| @@ -108,16 +108,13 @@ static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos) · 107 unmodified lines | ||
| 108 | 108 | |
| 109 | 109 | static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos) |
| 110 | 110 | { |
| 111 | − struct rq_qos *cur, *prev = NULL; | |
| 112 | − for (cur = q->rq_qos; cur; cur = cur->next) { | |
| 113 | − if (cur == rqos) { | |
| 114 | − if (prev) | |
| 115 | − prev->next = rqos->next; | |
| 116 | − else | |
| 117 | − q->rq_qos = cur; | |
| 111 | + struct rq_qos **cur; | |
| 112 | + | |
| 113 | + for (cur = &q->rq_qos; *cur; cur = &(*cur)->next) { | |
| 114 | + if (*cur == rqos) { | |
| 115 | + *cur = rqos->next; | |
| 118 | 116 | break; |
| 119 | 117 | } |
| 120 | − prev = cur; | |
| 121 | 118 | } |
| 122 | 119 | |
| 123 | 120 | blk_mq_debugfs_unregister_rqos(rqos); |
| @@ -130,8 +127,8 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data, · 6 unmodified lines | ||
| 130 | 127 | acquire_inflight_cb_t *acquire_inflight_cb, |
| 131 | 128 | cleanup_cb_t *cleanup_cb); |
| 132 | 129 | bool rq_wait_inc_below(struct rq_wait *rq_wait, unsigned int limit); |
| 133 | −void rq_depth_scale_up(struct rq_depth *rqd); | |
| 134 | −void rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle); | |
| 130 | +bool rq_depth_scale_up(struct rq_depth *rqd); | |
| 131 | +bool rq_depth_scale_down(struct rq_depth *rqd, bool hard_throttle); | |
| 135 | 132 | bool rq_depth_calc_max_depth(struct rq_depth *rqd); |
| 136 | 133 | |
| 137 | 134 | void __rq_qos_cleanup(struct rq_qos *rqos, struct bio *bio); |
| @@ -308,7 +308,8 @@ static void calc_wb_limits(struct rq_wb *rwb) · 307 unmodified lines | ||
| 308 | 308 | |
| 309 | 309 | static void scale_up(struct rq_wb *rwb) |
| 310 | 310 | { |
| 311 | − rq_depth_scale_up(&rwb->rq_depth); | |
| 311 | + if (!rq_depth_scale_up(&rwb->rq_depth)) | |
| 312 | + return; | |
| 312 | 313 | calc_wb_limits(rwb); |
| 313 | 314 | rwb->unknown_cnt = 0; |
| 314 | 315 | rwb_wake_all(rwb); |
| @@ -317,7 +318,8 @@ static void scale_up(struct rq_wb *rwb) · 2 unmodified lines | ||
| 317 | 318 | |
| 318 | 319 | static void scale_down(struct rq_wb *rwb, bool hard_throttle) |
| 319 | 320 | { |
| 320 | − rq_depth_scale_down(&rwb->rq_depth, hard_throttle); | |
| 321 | + if (!rq_depth_scale_down(&rwb->rq_depth, hard_throttle)) | |
| 322 | + return; | |
| 321 | 323 | calc_wb_limits(rwb); |
| 322 | 324 | rwb->unknown_cnt = 0; |
| 323 | 325 | rwb_trace_step(rwb, "scale down"); |
| @@ -616,7 +616,8 @@ out: · 615 unmodified lines | ||
| 616 | 616 | |
| 617 | 617 | static inline bool elv_support_iosched(struct request_queue *q) |
| 618 | 618 | { |
| 619 | − if (q->tag_set && (q->tag_set->flags & BLK_MQ_F_NO_SCHED)) | |
| 619 | + if (!q->mq_ops || | |
| 620 | + (q->tag_set && (q->tag_set->flags & BLK_MQ_F_NO_SCHED))) | |
| 620 | 621 | return false; |
| 621 | 622 | return true; |
| 622 | 623 | } |
| @@ -905,8 +905,8 @@ void acpi_cppc_processor_exit(struct acpi_processor *pr) · 904 unmodified lines | ||
| 905 | 905 | pcc_data[pcc_ss_id]->refcount--; |
| 906 | 906 | if (!pcc_data[pcc_ss_id]->refcount) { |
| 907 | 907 | pcc_mbox_free_channel(pcc_data[pcc_ss_id]->pcc_channel); |
| 908 | − pcc_data[pcc_ss_id]->pcc_channel_acquired = 0; | |
| 909 | 908 | kfree(pcc_data[pcc_ss_id]); |
| 909 | + pcc_data[pcc_ss_id] = NULL; | |
| 910 | 910 | } |
| 911 | 911 | } |
| 912 | 912 | } |
| @@ -403,7 +403,7 @@ static int __init hmat_parse_proximity_domain(union acpi_subtable_headers *heade · 402 unmodified lines | ||
| 403 | 403 | pr_info("HMAT: Memory Flags:%04x Processor Domain:%d Memory Domain:%d\n", |
| 404 | 404 | p->flags, p->processor_PD, p->memory_PD); |
| 405 | 405 | |
| 406 | − if (p->flags & ACPI_HMAT_MEMORY_PD_VALID) { | |
| 406 | + if (p->flags & ACPI_HMAT_MEMORY_PD_VALID && hmat_revision == 1) { | |
| 407 | 407 | target = find_mem_target(p->memory_PD); |
| 408 | 408 | if (!target) { |
| 409 | 409 | pr_debug("HMAT: Memory Domain missing from SRAT\n"); |
| @@ -162,21 +162,23 @@ void acpi_processor_ppc_init(int cpu) · 161 unmodified lines | ||
| 162 | 162 | struct acpi_processor *pr = per_cpu(processors, cpu); |
| 163 | 163 | int ret; |
| 164 | 164 | |
| 165 | + if (!pr) | |
| 166 | + return; | |
| 167 | + | |
| 165 | 168 | ret = dev_pm_qos_add_request(get_cpu_device(cpu), |
| 166 | 169 | &pr->perflib_req, DEV_PM_QOS_MAX_FREQUENCY, |
| 167 | 170 | INT_MAX); |
| 168 | − if (ret < 0) { | |
| 171 | + if (ret < 0) | |
| 169 | 172 | pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, |
| 170 | 173 | ret); |
| 171 | − return; | |
| 172 | − } | |
| 173 | 174 | } |
| 174 | 175 | |
| 175 | 176 | void acpi_processor_ppc_exit(int cpu) |
| 176 | 177 | { |
| 177 | 178 | struct acpi_processor *pr = per_cpu(processors, cpu); |
| 178 | 179 | |
| 179 | − dev_pm_qos_remove_request(&pr->perflib_req); | |
| 180 | + if (pr) | |
| 181 | + dev_pm_qos_remove_request(&pr->perflib_req); | |
| 180 | 182 | } |
| 181 | 183 | |
| 182 | 184 | static int acpi_processor_get_performance_control(struct acpi_processor *pr) |
| @@ -130,21 +130,23 @@ void acpi_thermal_cpufreq_init(int cpu) · 129 unmodified lines | ||
| 130 | 130 | struct acpi_processor *pr = per_cpu(processors, cpu); |
| 131 | 131 | int ret; |
| 132 | 132 | |
| 133 | + if (!pr) | |
| 134 | + return; | |
| 135 | + | |
| 133 | 136 | ret = dev_pm_qos_add_request(get_cpu_device(cpu), |
| 134 | 137 | &pr->thermal_req, DEV_PM_QOS_MAX_FREQUENCY, |
| 135 | 138 | INT_MAX); |
| 136 | − if (ret < 0) { | |
| 139 | + if (ret < 0) | |
| 137 | 140 | pr_err("Failed to add freq constraint for CPU%d (%d)\n", cpu, |
| 138 | 141 | ret); |
| 139 | − return; | |
| 140 | − } | |
| 141 | 142 | } |
| 142 | 143 | |
| 143 | 144 | void acpi_thermal_cpufreq_exit(int cpu) |
| 144 | 145 | { |
| 145 | 146 | struct acpi_processor *pr = per_cpu(processors, cpu); |
| 146 | 147 | |
| 147 | − dev_pm_qos_remove_request(&pr->thermal_req); | |
| 148 | + if (pr) | |
| 149 | + dev_pm_qos_remove_request(&pr->thermal_req); | |
| 148 | 150 | } |
| 149 | 151 | #else /* ! CONFIG_CPU_FREQ */ |
| 150 | 152 | static int cpufreq_get_max_state(unsigned int cpu) |
| @@ -361,19 +361,6 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { · 360 unmodified lines | ||
| 361 | 361 | DMI_MATCH(DMI_PRODUCT_NAME, "80E3"), |
| 362 | 362 | }, |
| 363 | 363 | }, |
| 364 | − /* | |
| 365 | − * https://bugzilla.kernel.org/show_bug.cgi?id=196907 | |
| 366 | − * Some Dell XPS13 9360 cannot do suspend-to-idle using the Low Power | |
| 367 | − * S0 Idle firmware interface. | |
| 368 | − */ | |
| 369 | − { | |
| 370 | − .callback = init_default_s3, | |
| 371 | − .ident = "Dell XPS13 9360", | |
| 372 | − .matches = { | |
| 373 | − DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | |
| 374 | − DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9360"), | |
| 375 | − }, | |
| 376 | − }, | |
| 377 | 364 | /* |
| 378 | 365 | * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using |
| 379 | 366 | * the Low Power S0 Idle firmware interface (see |
| @@ -57,6 +57,7 @@ · 56 unmodified lines | ||
| 57 | 57 | #include <linux/sched/signal.h> |
| 58 | 58 | #include <linux/sched/mm.h> |
| 59 | 59 | #include <linux/seq_file.h> |
| 60 | +#include <linux/string.h> | |
| 60 | 61 | #include <linux/uaccess.h> |
| 61 | 62 | #include <linux/pid_namespace.h> |
| 62 | 63 | #include <linux/security.h> |
| @@ -66,6 +67,7 @@ · 3 unmodified lines | ||
| 66 | 67 | #include <linux/task_work.h> |
| 67 | 68 | |
| 68 | 69 | #include <uapi/linux/android/binder.h> |
| 70 | +#include <uapi/linux/android/binderfs.h> | |
| 69 | 71 | |
| 70 | 72 | #include <asm/cacheflush.h> |
| 71 | 73 | |
| @@ -2876,7 +2878,7 @@ static void binder_transaction(struct binder_proc *proc, · 2804 unmodified lines | ||
| 2876 | 2878 | e->target_handle = tr->target.handle; |
| 2877 | 2879 | e->data_size = tr->data_size; |
| 2878 | 2880 | e->offsets_size = tr->offsets_size; |
| 2879 | − e->context_name = proc->context->name; | |
| 2881 | + strscpy(e->context_name, proc->context->name, BINDERFS_MAX_NAME); | |
| 2880 | 2882 | |
| 2881 | 2883 | if (reply) { |
| 2882 | 2884 | binder_inner_proc_lock(proc); |
| @@ -156,7 +156,7 @@ static struct binder_buffer *binder_alloc_prepare_to_free_locked( · 155 unmodified lines | ||
| 156 | 156 | } |
| 157 | 157 | |
| 158 | 158 | /** |
| 159 | − * binder_alloc_buffer_lookup() - get buffer given user ptr | |
| 159 | + * binder_alloc_prepare_to_free() - get buffer given user ptr | |
| 160 | 160 | * @alloc: binder_alloc for this proc |
| 161 | 161 | * @user_ptr: User pointer to buffer data |
| 162 | 162 | * |
| @@ -130,7 +130,7 @@ struct binder_transaction_log_entry { · 129 unmodified lines | ||
| 130 | 130 | int return_error_line; |
| 131 | 131 | uint32_t return_error; |
| 132 | 132 | uint32_t return_error_param; |
| 133 | − const char *context_name; | |
| 133 | + char context_name[BINDERFS_MAX_NAME + 1]; | |
| 134 | 134 | }; |
| 135 | 135 | |
| 136 | 136 | struct binder_transaction_log { |
| @@ -1600,7 +1600,9 @@ static void ahci_intel_pcs_quirk(struct pci_dev *pdev, struct ahci_host_priv *hp · 1599 unmodified lines | ||
| 1600 | 1600 | */ |
| 1601 | 1601 | if (!id || id->vendor != PCI_VENDOR_ID_INTEL) |
| 1602 | 1602 | return; |
| 1603 | − if (((enum board_ids) id->driver_data) < board_ahci_pcs7) | |
| 1603 | + | |
| 1604 | + /* Skip applying the quirk on Denverton and beyond */ | |
| 1605 | + if (((enum board_ids) id->driver_data) >= board_ahci_pcs7) | |
| 1604 | 1606 | return; |
| 1605 | 1607 | |
| 1606 | 1608 | /* |
| @@ -4791,27 +4791,6 @@ void ata_scsi_hotplug(struct work_struct *work) · 4790 unmodified lines | ||
| 4791 | 4791 | return; |
| 4792 | 4792 | } |
| 4793 | 4793 | |
| 4794 | − /* | |
| 4795 | − * XXX - UGLY HACK | |
| 4796 | − * | |
| 4797 | − * The block layer suspend/resume path is fundamentally broken due | |
| 4798 | − * to freezable kthreads and workqueue and may deadlock if a block | |
| 4799 | − * device gets removed while resume is in progress. I don't know | |
| 4800 | − * what the solution is short of removing freezable kthreads and | |
| 4801 | − * workqueues altogether. | |
| 4802 | − * | |
| 4803 | − * The following is an ugly hack to avoid kicking off device | |
| 4804 | − * removal while freezer is active. This is a joke but does avoid | |
| 4805 | − * this particular deadlock scenario. | |
| 4806 | − * | |
| 4807 | − * https://bugzilla.kernel.org/show_bug.cgi?id=62801 | |
| 4808 | − * http://marc.info/?l=linux-kernel&m=138695698516487 | |
| 4809 | − */ | |
| 4810 | −#ifdef CONFIG_FREEZER | |
| 4811 | − while (pm_freezing) | |
| 4812 | − msleep(10); | |
| 4813 | −#endif | |
| 4814 | − | |
| 4815 | 4794 | DPRINTK("ENTER\n"); |
| 4816 | 4795 | mutex_lock(&ap->scsi_scan_mutex); |
| 4817 | 4796 | |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | 11 | #include <linux/acpi.h> |
| 12 | +#include <linux/cpufreq.h> | |
| 12 | 13 | #include <linux/device.h> |
| 13 | 14 | #include <linux/err.h> |
| 14 | 15 | #include <linux/fwnode.h> |
| @@ -3179,6 +3180,8 @@ void device_shutdown(void) · 3164 unmodified lines | ||
| 3179 | 3180 | wait_for_device_probe(); |
| 3180 | 3181 | device_block_probing(); |
| 3181 | 3182 | |
| 3183 | + cpufreq_suspend(); | |
| 3184 | + | |
| 3182 | 3185 | spin_lock(&devices_kset->list_lock); |
| 3183 | 3186 | /* |
| 3184 | 3187 | * Walk the devices list backward, shutting down each in turn. |
| @@ -540,6 +540,9 @@ static ssize_t soft_offline_page_store(struct device *dev, · 539 unmodified lines | ||
| 540 | 540 | pfn >>= PAGE_SHIFT; |
| 541 | 541 | if (!pfn_valid(pfn)) |
| 542 | 542 | return -ENXIO; |
| 543 | + /* Only online pages can be soft-offlined (esp., not ZONE_DEVICE). */ | |
| 544 | + if (!pfn_to_online_page(pfn)) | |
| 545 | + return -EIO; | |
| 543 | 546 | ret = soft_offline_page(pfn_to_page(pfn), 0); |
| 544 | 547 | return ret == 0 ? count : ret; |
| 545 | 548 | } |
| @@ -241,12 +241,8 @@ struct resource *platform_get_resource_byname(struct platform_device *dev, · 240 unmodified lines | ||
| 241 | 241 | } |
| 242 | 242 | EXPORT_SYMBOL_GPL(platform_get_resource_byname); |
| 243 | 243 | |
| 244 | −/** | |
| 245 | − * platform_get_irq_byname - get an IRQ for a device by name | |
| 246 | − * @dev: platform device | |
| 247 | − * @name: IRQ name | |
| 248 | − */ | |
| 249 | −int platform_get_irq_byname(struct platform_device *dev, const char *name) | |
| 244 | +static int __platform_get_irq_byname(struct platform_device *dev, | |
| 245 | + const char *name) | |
| 250 | 246 | { |
| 251 | 247 | struct resource *r; |
| 252 | 248 | |
| @@ -262,11 +258,47 @@ int platform_get_irq_byname(struct platform_device *dev, const char *name) · 9 unmodified lines | ||
| 262 | 258 | if (r) |
| 263 | 259 | return r->start; |
| 264 | 260 | |
| 265 | − dev_err(&dev->dev, "IRQ %s not found\n", name); | |
| 266 | 261 | return -ENXIO; |
| 267 | 262 | } |
| 263 | + | |
| 264 | +/** | |
| 265 | + * platform_get_irq_byname - get an IRQ for a device by name | |
| 266 | + * @dev: platform device | |
| 267 | + * @name: IRQ name | |
| 268 | + * | |
| 269 | + * Get an IRQ like platform_get_irq(), but then by name rather then by index. | |
| 270 | + * | |
| 271 | + * Return: IRQ number on success, negative error number on failure. | |
| 272 | + */ | |
| 273 | +int platform_get_irq_byname(struct platform_device *dev, const char *name) | |
| 274 | +{ | |
| 275 | + int ret; | |
| 276 | + | |
| 277 | + ret = __platform_get_irq_byname(dev, name); | |
| 278 | + if (ret < 0 && ret != -EPROBE_DEFER) | |
| 279 | + dev_err(&dev->dev, "IRQ %s not found\n", name); | |
| 280 | + | |
| 281 | + return ret; | |
| 282 | +} | |
| 268 | 283 | EXPORT_SYMBOL_GPL(platform_get_irq_byname); |
| 269 | 284 | |
| 285 | +/** | |
| 286 | + * platform_get_irq_byname_optional - get an optional IRQ for a device by name | |
| 287 | + * @dev: platform device | |
| 288 | + * @name: IRQ name | |
| 289 | + * | |
| 290 | + * Get an optional IRQ by name like platform_get_irq_byname(). Except that it | |
| 291 | + * does not print an error message if an IRQ can not be obtained. | |
| 292 | + * | |
| 293 | + * Return: IRQ number on success, negative error number on failure. | |
| 294 | + */ | |
| 295 | +int platform_get_irq_byname_optional(struct platform_device *dev, | |
| 296 | + const char *name) | |
| 297 | +{ | |
| 298 | + return __platform_get_irq_byname(dev, name); | |
| 299 | +} | |
| 300 | +EXPORT_SYMBOL_GPL(platform_get_irq_byname_optional); | |
| 301 | + | |
| 270 | 302 | /** |
| 271 | 303 | * platform_add_devices - add a numbers of platform devices |
| 272 | 304 | * @devs: array of platform devices to add |
| @@ -248,8 +248,8 @@ static void nbd_put(struct nbd_device *nbd) · 247 unmodified lines | ||
| 248 | 248 | if (refcount_dec_and_mutex_lock(&nbd->refs, |
| 249 | 249 | &nbd_index_mutex)) { |
| 250 | 250 | idr_remove(&nbd_index_idr, nbd->index); |
| 251 | − mutex_unlock(&nbd_index_mutex); | |
| 252 | 251 | nbd_dev_remove(nbd); |
| 252 | + mutex_unlock(&nbd_index_mutex); | |
| 253 | 253 | } |
| 254 | 254 | } |
| 255 | 255 | |
| @@ -142,8 +142,7 @@ static blk_status_t null_zone_reset(struct nullb_cmd *cmd, sector_t sector) · 141 unmodified lines | ||
| 142 | 142 | zone->wp = zone->start; |
| 143 | 143 | break; |
| 144 | 144 | default: |
| 145 | − cmd->error = BLK_STS_NOTSUPP; | |
| 146 | − break; | |
| 145 | + return BLK_STS_NOTSUPP; | |
| 147 | 146 | } |
| 148 | 147 | return BLK_STS_OK; |
| 149 | 148 | } |
| @@ -6639,10 +6639,13 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev) · 6638 unmodified lines | ||
| 6639 | 6639 | queue_delayed_work(rbd_dev->task_wq, &rbd_dev->lock_dwork, 0); |
| 6640 | 6640 | ret = wait_for_completion_killable_timeout(&rbd_dev->acquire_wait, |
| 6641 | 6641 | ceph_timeout_jiffies(rbd_dev->opts->lock_timeout)); |
| 6642 | − if (ret > 0) | |
| 6642 | + if (ret > 0) { | |
| 6643 | 6643 | ret = rbd_dev->acquire_err; |
| 6644 | − else if (!ret) | |
| 6645 | − ret = -ETIMEDOUT; | |
| 6644 | + } else { | |
| 6645 | + cancel_delayed_work_sync(&rbd_dev->lock_dwork); | |
| 6646 | + if (!ret) | |
| 6647 | + ret = -ETIMEDOUT; | |
| 6648 | + } | |
| 6646 | 6649 | |
| 6647 | 6650 | if (ret) { |
| 6648 | 6651 | rbd_warn(rbd_dev, "failed to acquire exclusive lock: %ld", ret); |
| @@ -413,13 +413,14 @@ static void reset_bdev(struct zram *zram) · 412 unmodified lines | ||
| 413 | 413 | static ssize_t backing_dev_show(struct device *dev, |
| 414 | 414 | struct device_attribute *attr, char *buf) |
| 415 | 415 | { |
| 416 | + struct file *file; | |
| 416 | 417 | struct zram *zram = dev_to_zram(dev); |
| 417 | − struct file *file = zram->backing_dev; | |
| 418 | 418 | char *p; |
| 419 | 419 | ssize_t ret; |
| 420 | 420 | |
| 421 | 421 | down_read(&zram->init_lock); |
| 422 | − if (!zram->backing_dev) { | |
| 422 | + file = zram->backing_dev; | |
| 423 | + if (!file) { | |
| 423 | 424 | memcpy(buf, "none\n", 5); |
| 424 | 425 | up_read(&zram->init_lock); |
| 425 | 426 | return 5; |
| @@ -2737,14 +2737,6 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) · 2736 unmodified lines | ||
| 2737 | 2737 | } |
| 2738 | 2738 | EXPORT_SYMBOL_GPL(cpufreq_unregister_driver); |
| 2739 | 2739 | |
| 2740 | −/* | |
| 2741 | − * Stop cpufreq at shutdown to make sure it isn't holding any locks | |
| 2742 | − * or mutexes when secondary CPUs are halted. | |
| 2743 | − */ | |
| 2744 | −static struct syscore_ops cpufreq_syscore_ops = { | |
| 2745 | − .shutdown = cpufreq_suspend, | |
| 2746 | −}; | |
| 2747 | − | |
| 2748 | 2740 | struct kobject *cpufreq_global_kobject; |
| 2749 | 2741 | EXPORT_SYMBOL(cpufreq_global_kobject); |
| 2750 | 2742 | |
| @@ -2756,8 +2748,6 @@ static int __init cpufreq_core_init(void) · 5 unmodified lines | ||
| 2756 | 2748 | cpufreq_global_kobject = kobject_create_and_add("cpufreq", &cpu_subsys.dev_root->kobj); |
| 2757 | 2749 | BUG_ON(!cpufreq_global_kobject); |
| 2758 | 2750 | |
| 2759 | − register_syscore_ops(&cpufreq_syscore_ops); | |
| 2760 | − | |
| 2761 | 2751 | return 0; |
| 2762 | 2752 | } |
| 2763 | 2753 | module_param(off, int, 0444); |
| @@ -408,7 +408,7 @@ static void __init save_mem_devices(const struct dmi_header *dm, void *v) · 407 unmodified lines | ||
| 408 | 408 | bytes = ~0ull; |
| 409 | 409 | else if (size & 0x8000) |
| 410 | 410 | bytes = (u64)(size & 0x7fff) << 10; |
| 411 | − else if (size != 0x7fff) | |
| 411 | + else if (size != 0x7fff || dm->length < 0x20) | |
| 412 | 412 | bytes = (u64)size << 20; |
| 413 | 413 | else |
| 414 | 414 | bytes = (u64)get_unaligned((u32 *)&d[0x1C]) << 20; |
| @@ -381,7 +381,7 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, · 380 unmodified lines | ||
| 381 | 381 | printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx, |
| 382 | 382 | pcie->device_id.vendor_id, pcie->device_id.device_id); |
| 383 | 383 | p = pcie->device_id.class_code; |
| 384 | − printk("%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]); | |
| 384 | + printk("%s""class_code: %02x%02x%02x\n", pfx, p[2], p[1], p[0]); | |
| 385 | 385 | } |
| 386 | 386 | if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER) |
| 387 | 387 | printk("%s""serial number: 0x%04x, 0x%04x\n", pfx, |
| @@ -267,6 +267,9 @@ static __init int efivar_ssdt_load(void) · 266 unmodified lines | ||
| 267 | 267 | void *data; |
| 268 | 268 | int ret; |
| 269 | 269 | |
| 270 | + if (!efivar_ssdt[0]) | |
| 271 | + return 0; | |
| 272 | + | |
| 270 | 273 | ret = efivar_init(efivar_ssdt_iter, &entries, true, &entries); |
| 271 | 274 | |
| 272 | 275 | list_for_each_entry_safe(entry, aux, &entries, list) { |
| @@ -76,7 +76,7 @@ static u16 checksum(void) · 75 unmodified lines | ||
| 76 | 76 | return chksum; |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | −int __init efi_rci2_sysfs_init(void) | |
| 79 | +static int __init efi_rci2_sysfs_init(void) | |
| 80 | 80 | { |
| 81 | 81 | struct kobject *tables_kobj; |
| 82 | 82 | int ret = -ENOMEM; |
| @@ -40,7 +40,7 @@ int __init efi_tpm_eventlog_init(void) · 39 unmodified lines | ||
| 40 | 40 | { |
| 41 | 41 | struct linux_efi_tpm_eventlog *log_tbl; |
| 42 | 42 | struct efi_tcg2_final_events_table *final_tbl; |
| 43 | − unsigned int tbl_size; | |
| 43 | + int tbl_size; | |
| 44 | 44 | int ret = 0; |
| 45 | 45 | |
| 46 | 46 | if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) { |
| @@ -75,16 +75,28 @@ int __init efi_tpm_eventlog_init(void) · 28 unmodified lines | ||
| 75 | 75 | goto out; |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | − tbl_size = tpm2_calc_event_log_size((void *)efi.tpm_final_log | |
| 79 | − + sizeof(final_tbl->version) | |
| 80 | − + sizeof(final_tbl->nr_events), | |
| 81 | − final_tbl->nr_events, | |
| 82 | − log_tbl->log); | |
| 78 | + tbl_size = 0; | |
| 79 | + if (final_tbl->nr_events != 0) { | |
| 80 | + void *events = (void *)efi.tpm_final_log | |
| 81 | + + sizeof(final_tbl->version) | |
| 82 | + + sizeof(final_tbl->nr_events); | |
| 83 | + | |
| 84 | + tbl_size = tpm2_calc_event_log_size(events, | |
| 85 | + final_tbl->nr_events, | |
| 86 | + log_tbl->log); | |
| 87 | + } | |
| 88 | + | |
| 89 | + if (tbl_size < 0) { | |
| 90 | + pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n"); | |
| 91 | + goto out_calc; | |
| 92 | + } | |
| 93 | + | |
| 83 | 94 | memblock_reserve((unsigned long)final_tbl, |
| 84 | 95 | tbl_size + sizeof(*final_tbl)); |
| 85 | − early_memunmap(final_tbl, sizeof(*final_tbl)); | |
| 86 | 96 | efi_tpm_final_log_size = tbl_size; |
| 87 | 97 | |
| 98 | +out_calc: | |
| 99 | + early_memunmap(final_tbl, sizeof(*final_tbl)); | |
| 88 | 100 | out: |
| 89 | 101 | early_memunmap(log_tbl, sizeof(*log_tbl)); |
| 90 | 102 | return ret; |
| @@ -52,7 +52,7 @@ static int vpd_decode_entry(const u32 max_len, const u8 *input_buf, · 51 unmodified lines | ||
| 52 | 52 | if (max_len - consumed < *entry_len) |
| 53 | 53 | return VPD_FAIL; |
| 54 | 54 | |
| 55 | − consumed += decoded_len; | |
| 55 | + consumed += *entry_len; | |
| 56 | 56 | *_consumed = consumed; |
| 57 | 57 | return VPD_OK; |
| 58 | 58 | } |
| @@ -530,11 +530,12 @@ static void sprd_eic_handle_one_type(struct gpio_chip *chip) · 529 unmodified lines | ||
| 530 | 530 | } |
| 531 | 531 | |
| 532 | 532 | for_each_set_bit(n, ®, SPRD_EIC_PER_BANK_NR) { |
| 533 | − girq = irq_find_mapping(chip->irq.domain, | |
| 534 | − bank * SPRD_EIC_PER_BANK_NR + n); | |
| 533 | + u32 offset = bank * SPRD_EIC_PER_BANK_NR + n; | |
| 534 | + | |
| 535 | + girq = irq_find_mapping(chip->irq.domain, offset); | |
| 535 | 536 | |
| 536 | 537 | generic_handle_irq(girq); |
| 537 | − sprd_eic_toggle_trigger(chip, girq, n); | |
| 538 | + sprd_eic_toggle_trigger(chip, girq, offset); | |
| 538 | 539 | } |
| 539 | 540 | } |
| 540 | 541 | } |
| @@ -293,8 +293,9 @@ static void intel_mid_irq_handler(struct irq_desc *desc) · 292 unmodified lines | ||
| 293 | 293 | chip->irq_eoi(data); |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | −static void intel_mid_irq_init_hw(struct intel_mid_gpio *priv) | |
| 296 | +static int intel_mid_irq_init_hw(struct gpio_chip *chip) | |
| 297 | 297 | { |
| 298 | + struct intel_mid_gpio *priv = gpiochip_get_data(chip); | |
| 298 | 299 | void __iomem *reg; |
| 299 | 300 | unsigned base; |
| 300 | 301 | |
| @@ -309,6 +310,8 @@ static void intel_mid_irq_init_hw(struct intel_mid_gpio *priv) · 8 unmodified lines | ||
| 309 | 310 | reg = gpio_reg(&priv->chip, base, GEDR); |
| 310 | 311 | writel(~0, reg); |
| 311 | 312 | } |
| 313 | + | |
| 314 | + return 0; | |
| 312 | 315 | } |
| 313 | 316 | |
| 314 | 317 | static int __maybe_unused intel_gpio_runtime_idle(struct device *dev) |
| @@ -372,6 +375,7 @@ static int intel_gpio_probe(struct pci_dev *pdev, · 57 unmodified lines | ||
| 372 | 375 | |
| 373 | 376 | girq = &priv->chip.irq; |
| 374 | 377 | girq->chip = &intel_mid_irqchip; |
| 378 | + girq->init_hw = intel_mid_irq_init_hw; | |
| 375 | 379 | girq->parent_handler = intel_mid_irq_handler; |
| 376 | 380 | girq->num_parents = 1; |
| 377 | 381 | girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents, |
| @@ -384,9 +388,8 @@ static int intel_gpio_probe(struct pci_dev *pdev, · 6 unmodified lines | ||
| 384 | 388 | girq->default_type = IRQ_TYPE_NONE; |
| 385 | 389 | girq->handler = handle_simple_irq; |
| 386 | 390 | |
| 387 | − intel_mid_irq_init_hw(priv); | |
| 388 | − | |
| 389 | 391 | pci_set_drvdata(pdev, priv); |
| 392 | + | |
| 390 | 393 | retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv); |
| 391 | 394 | if (retval) { |
| 392 | 395 | dev_err(&pdev->dev, "gpiochip_add error %d\n", retval); |
| @@ -294,8 +294,9 @@ static struct irq_chip lp_irqchip = { · 293 unmodified lines | ||
| 294 | 294 | .flags = IRQCHIP_SKIP_SET_WAKE, |
| 295 | 295 | }; |
| 296 | 296 | |
| 297 | −static void lp_gpio_irq_init_hw(struct lp_gpio *lg) | |
| 297 | +static int lp_gpio_irq_init_hw(struct gpio_chip *chip) | |
| 298 | 298 | { |
| 299 | + struct lp_gpio *lg = gpiochip_get_data(chip); | |
| 299 | 300 | unsigned long reg; |
| 300 | 301 | unsigned base; |
| 301 | 302 | |
| @@ -307,6 +308,8 @@ static void lp_gpio_irq_init_hw(struct lp_gpio *lg) · 5 unmodified lines | ||
| 307 | 308 | reg = lp_gpio_reg(&lg->chip, base, LP_INT_STAT); |
| 308 | 309 | outl(0xffffffff, reg); |
| 309 | 310 | } |
| 311 | + | |
| 312 | + return 0; | |
| 310 | 313 | } |
| 311 | 314 | |
| 312 | 315 | static int lp_gpio_probe(struct platform_device *pdev) |
| @@ -364,6 +367,7 @@ static int lp_gpio_probe(struct platform_device *pdev) · 51 unmodified lines | ||
| 364 | 367 | |
| 365 | 368 | girq = &gc->irq; |
| 366 | 369 | girq->chip = &lp_irqchip; |
| 370 | + girq->init_hw = lp_gpio_irq_init_hw; | |
| 367 | 371 | girq->parent_handler = lp_gpio_irq_handler; |
| 368 | 372 | girq->num_parents = 1; |
| 369 | 373 | girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents, |
| @@ -373,9 +377,7 @@ static int lp_gpio_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 373 | 377 | return -ENOMEM; |
| 374 | 378 | girq->parents[0] = (unsigned)irq_rc->start; |
| 375 | 379 | girq->default_type = IRQ_TYPE_NONE; |
| 376 | − girq->handler = handle_simple_irq; | |
| 377 | − | |
| 378 | − lp_gpio_irq_init_hw(lg); | |
| 380 | + girq->handler = handle_bad_irq; | |
| 379 | 381 | } |
| 380 | 382 | |
| 381 | 383 | ret = devm_gpiochip_add_data(dev, gc, lg); |
| @@ -192,13 +192,13 @@ static int max77620_gpio_set_debounce(struct max77620_gpio *mgpio, · 191 unmodified lines | ||
| 192 | 192 | case 0: |
| 193 | 193 | val = MAX77620_CNFG_GPIO_DBNC_None; |
| 194 | 194 | break; |
| 195 | − case 1 ... 8: | |
| 195 | + case 1000 ... 8000: | |
| 196 | 196 | val = MAX77620_CNFG_GPIO_DBNC_8ms; |
| 197 | 197 | break; |
| 198 | − case 9 ... 16: | |
| 198 | + case 9000 ... 16000: | |
| 199 | 199 | val = MAX77620_CNFG_GPIO_DBNC_16ms; |
| 200 | 200 | break; |
| 201 | − case 17 ... 32: | |
| 201 | + case 17000 ... 32000: | |
| 202 | 202 | val = MAX77620_CNFG_GPIO_DBNC_32ms; |
| 203 | 203 | break; |
| 204 | 204 | default: |
| @@ -362,8 +362,9 @@ static void mrfld_irq_handler(struct irq_desc *desc) · 361 unmodified lines | ||
| 362 | 362 | chained_irq_exit(irqchip, desc); |
| 363 | 363 | } |
| 364 | 364 | |
| 365 | −static void mrfld_irq_init_hw(struct mrfld_gpio *priv) | |
| 365 | +static int mrfld_irq_init_hw(struct gpio_chip *chip) | |
| 366 | 366 | { |
| 367 | + struct mrfld_gpio *priv = gpiochip_get_data(chip); | |
| 367 | 368 | void __iomem *reg; |
| 368 | 369 | unsigned int base; |
| 369 | 370 | |
| @@ -375,6 +376,8 @@ static void mrfld_irq_init_hw(struct mrfld_gpio *priv) · 5 unmodified lines | ||
| 375 | 376 | reg = gpio_reg(&priv->chip, base, GFER); |
| 376 | 377 | writel(0, reg); |
| 377 | 378 | } |
| 379 | + | |
| 380 | + return 0; | |
| 378 | 381 | } |
| 379 | 382 | |
| 380 | 383 | static const char *mrfld_gpio_get_pinctrl_dev_name(struct mrfld_gpio *priv) |
| @@ -447,6 +450,7 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id · 66 unmodified lines | ||
| 447 | 450 | |
| 448 | 451 | girq = &priv->chip.irq; |
| 449 | 452 | girq->chip = &mrfld_irqchip; |
| 453 | + girq->init_hw = mrfld_irq_init_hw; | |
| 450 | 454 | girq->parent_handler = mrfld_irq_handler; |
| 451 | 455 | girq->num_parents = 1; |
| 452 | 456 | girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents, |
| @@ -455,11 +459,10 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id · 2 unmodified lines | ||
| 455 | 459 | if (!girq->parents) |
| 456 | 460 | return -ENOMEM; |
| 457 | 461 | girq->parents[0] = pdev->irq; |
| 462 | + girq->first = irq_base; | |
| 458 | 463 | girq->default_type = IRQ_TYPE_NONE; |
| 459 | 464 | girq->handler = handle_bad_irq; |
| 460 | 465 | |
| 461 | − mrfld_irq_init_hw(priv); | |
| 462 | − | |
| 463 | 466 | pci_set_drvdata(pdev, priv); |
| 464 | 467 | retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv); |
| 465 | 468 | if (retval) { |
| @@ -317,7 +317,7 @@ struct gpio_desc *gpiod_get_from_of_node(struct device_node *node, · 316 unmodified lines | ||
| 317 | 317 | transitory = flags & OF_GPIO_TRANSITORY; |
| 318 | 318 | |
| 319 | 319 | ret = gpiod_request(desc, label); |
| 320 | − if (ret == -EBUSY && (flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE)) | |
| 320 | + if (ret == -EBUSY && (dflags & GPIOD_FLAGS_BIT_NONEXCLUSIVE)) | |
| 321 | 321 | return desc; |
| 322 | 322 | if (ret) |
| 323 | 323 | return ERR_PTR(ret); |
| @@ -86,6 +86,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, · 85 unmodified lines | ||
| 86 | 86 | struct lock_class_key *lock_key, |
| 87 | 87 | struct lock_class_key *request_key); |
| 88 | 88 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); |
| 89 | +static int gpiochip_irqchip_init_hw(struct gpio_chip *gpiochip); | |
| 89 | 90 | static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip); |
| 90 | 91 | static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip); |
| 91 | 92 | |
| @@ -1406,6 +1407,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, · 1314 unmodified lines | ||
| 1406 | 1407 | |
| 1407 | 1408 | machine_gpiochip_add(chip); |
| 1408 | 1409 | |
| 1410 | + ret = gpiochip_irqchip_init_hw(chip); | |
| 1411 | + if (ret) | |
| 1412 | + goto err_remove_acpi_chip; | |
| 1413 | + | |
| 1409 | 1414 | ret = gpiochip_irqchip_init_valid_mask(chip); |
| 1410 | 1415 | if (ret) |
| 1411 | 1416 | goto err_remove_acpi_chip; |
| @@ -1622,6 +1627,16 @@ static struct gpio_chip *find_chip_by_name(const char *name) · 210 unmodified lines | ||
| 1622 | 1627 | * The following is irqchip helper code for gpiochips. |
| 1623 | 1628 | */ |
| 1624 | 1629 | |
| 1630 | +static int gpiochip_irqchip_init_hw(struct gpio_chip *gc) | |
| 1631 | +{ | |
| 1632 | + struct gpio_irq_chip *girq = &gc->irq; | |
| 1633 | + | |
| 1634 | + if (!girq->init_hw) | |
| 1635 | + return 0; | |
| 1636 | + | |
| 1637 | + return girq->init_hw(gc); | |
| 1638 | +} | |
| 1639 | + | |
| 1625 | 1640 | static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gc) |
| 1626 | 1641 | { |
| 1627 | 1642 | struct gpio_irq_chip *girq = &gc->irq; |
| @@ -2446,8 +2461,13 @@ static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip, · 818 unmodified lines | ||
| 2446 | 2461 | { |
| 2447 | 2462 | return 0; |
| 2448 | 2463 | } |
| 2449 | − | |
| 2450 | 2464 | static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) {} |
| 2465 | + | |
| 2466 | +static inline int gpiochip_irqchip_init_hw(struct gpio_chip *gpiochip) | |
| 2467 | +{ | |
| 2468 | + return 0; | |
| 2469 | +} | |
| 2470 | + | |
| 2451 | 2471 | static inline int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip) |
| 2452 | 2472 | { |
| 2453 | 2473 | return 0; |
| @@ -3070,8 +3090,10 @@ int gpiod_direction_output(struct gpio_desc *desc, int value) · 616 unmodified lines | ||
| 3070 | 3090 | if (!ret) |
| 3071 | 3091 | goto set_output_value; |
| 3072 | 3092 | /* Emulate open drain by not actively driving the line high */ |
| 3073 | − if (value) | |
| 3074 | − return gpiod_direction_input(desc); | |
| 3093 | + if (value) { | |
| 3094 | + ret = gpiod_direction_input(desc); | |
| 3095 | + goto set_output_flag; | |
| 3096 | + } | |
| 3075 | 3097 | } |
| 3076 | 3098 | else if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) { |
| 3077 | 3099 | ret = gpio_set_config(gc, gpio_chip_hwgpio(desc), |
| @@ -3079,8 +3101,10 @@ int gpiod_direction_output(struct gpio_desc *desc, int value) · 1 unmodified line | ||
| 3079 | 3101 | if (!ret) |
| 3080 | 3102 | goto set_output_value; |
| 3081 | 3103 | /* Emulate open source by not actively driving the line low */ |
| 3082 | − if (!value) | |
| 3083 | − return gpiod_direction_input(desc); | |
| 3104 | + if (!value) { | |
| 3105 | + ret = gpiod_direction_input(desc); | |
| 3106 | + goto set_output_flag; | |
| 3107 | + } | |
| 3084 | 3108 | } else { |
| 3085 | 3109 | gpio_set_config(gc, gpio_chip_hwgpio(desc), |
| 3086 | 3110 | PIN_CONFIG_DRIVE_PUSH_PULL); |
| @@ -3088,6 +3112,17 @@ int gpiod_direction_output(struct gpio_desc *desc, int value) · 1 unmodified line | ||
| 3088 | 3112 | |
| 3089 | 3113 | set_output_value: |
| 3090 | 3114 | return gpiod_direction_output_raw_commit(desc, value); |
| 3115 | + | |
| 3116 | +set_output_flag: | |
| 3117 | + /* | |
| 3118 | + * When emulating open-source or open-drain functionalities by not | |
| 3119 | + * actively driving the line (setting mode to input) we still need to | |
| 3120 | + * set the IS_OUT flag or otherwise we won't be able to set the line | |
| 3121 | + * value anymore. | |
| 3122 | + */ | |
| 3123 | + if (ret == 0) | |
| 3124 | + set_bit(FLAG_IS_OUT, &desc->flags); | |
| 3125 | + return ret; | |
| 3091 | 3126 | } |
| 3092 | 3127 | EXPORT_SYMBOL_GPL(gpiod_direction_output); |
| 3093 | 3128 | |
| @@ -3448,8 +3483,6 @@ static void gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value) · 354 unmodified lines | ||
| 3448 | 3483 | |
| 3449 | 3484 | if (value) { |
| 3450 | 3485 | ret = chip->direction_input(chip, offset); |
| 3451 | − if (!ret) | |
| 3452 | − clear_bit(FLAG_IS_OUT, &desc->flags); | |
| 3453 | 3486 | } else { |
| 3454 | 3487 | ret = chip->direction_output(chip, offset, 0); |
| 3455 | 3488 | if (!ret) |
| @@ -3479,8 +3512,6 @@ static void gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value · 23 unmodified lines | ||
| 3479 | 3512 | set_bit(FLAG_IS_OUT, &desc->flags); |
| 3480 | 3513 | } else { |
| 3481 | 3514 | ret = chip->direction_input(chip, offset); |
| 3482 | − if (!ret) | |
| 3483 | − clear_bit(FLAG_IS_OUT, &desc->flags); | |
| 3484 | 3515 | } |
| 3485 | 3516 | trace_gpio_direction(desc_to_gpio(desc), !value, ret); |
| 3486 | 3517 | if (ret < 0) |
| @@ -270,7 +270,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, · 269 unmodified lines | ||
| 270 | 270 | |
| 271 | 271 | r = amdgpu_bo_create_list_entry_array(&args->in, &info); |
| 272 | 272 | if (r) |
| 273 | − goto error_free; | |
| 273 | + return r; | |
| 274 | 274 | |
| 275 | 275 | switch (args->in.operation) { |
| 276 | 276 | case AMDGPU_BO_LIST_OP_CREATE: |
| @@ -283,8 +283,7 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, · 6 unmodified lines | ||
| 283 | 283 | r = idr_alloc(&fpriv->bo_list_handles, list, 1, 0, GFP_KERNEL); |
| 284 | 284 | mutex_unlock(&fpriv->bo_list_lock); |
| 285 | 285 | if (r < 0) { |
| 286 | − amdgpu_bo_list_put(list); | |
| 287 | − return r; | |
| 286 | + goto error_put_list; | |
| 288 | 287 | } |
| 289 | 288 | |
| 290 | 289 | handle = r; |
| @@ -306,9 +305,8 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, · 15 unmodified lines | ||
| 306 | 305 | mutex_unlock(&fpriv->bo_list_lock); |
| 307 | 306 | |
| 308 | 307 | if (IS_ERR(old)) { |
| 309 | − amdgpu_bo_list_put(list); | |
| 310 | 308 | r = PTR_ERR(old); |
| 311 | − goto error_free; | |
| 309 | + goto error_put_list; | |
| 312 | 310 | } |
| 313 | 311 | |
| 314 | 312 | amdgpu_bo_list_put(old); |
| @@ -325,8 +323,10 @@ int amdgpu_bo_list_ioctl(struct drm_device *dev, void *data, · 10 unmodified lines | ||
| 325 | 323 | |
| 326 | 324 | return 0; |
| 327 | 325 | |
| 326 | +error_put_list: | |
| 327 | + amdgpu_bo_list_put(list); | |
| 328 | + | |
| 328 | 329 | error_free: |
| 329 | − if (info) | |
| 330 | − kvfree(info); | |
| 330 | + kvfree(info); | |
| 331 | 331 | return r; |
| 332 | 332 | } |
| @@ -1048,6 +1048,41 @@ static int amdgpu_pci_probe(struct pci_dev *pdev, · 1047 unmodified lines | ||
| 1048 | 1048 | return -ENODEV; |
| 1049 | 1049 | } |
| 1050 | 1050 | |
| 1051 | +#ifdef CONFIG_DRM_AMDGPU_SI | |
| 1052 | + if (!amdgpu_si_support) { | |
| 1053 | + switch (flags & AMD_ASIC_MASK) { | |
| 1054 | + case CHIP_TAHITI: | |
| 1055 | + case CHIP_PITCAIRN: | |
| 1056 | + case CHIP_VERDE: | |
| 1057 | + case CHIP_OLAND: | |
| 1058 | + case CHIP_HAINAN: | |
| 1059 | + dev_info(&pdev->dev, | |
| 1060 | + "SI support provided by radeon.\n"); | |
| 1061 | + dev_info(&pdev->dev, | |
| 1062 | + "Use radeon.si_support=0 amdgpu.si_support=1 to override.\n" | |
| 1063 | + ); | |
| 1064 | + return -ENODEV; | |
| 1065 | + } | |
| 1066 | + } | |
| 1067 | +#endif | |
| 1068 | +#ifdef CONFIG_DRM_AMDGPU_CIK | |
| 1069 | + if (!amdgpu_cik_support) { | |
| 1070 | + switch (flags & AMD_ASIC_MASK) { | |
| 1071 | + case CHIP_KAVERI: | |
| 1072 | + case CHIP_BONAIRE: | |
| 1073 | + case CHIP_HAWAII: | |
| 1074 | + case CHIP_KABINI: | |
| 1075 | + case CHIP_MULLINS: | |
| 1076 | + dev_info(&pdev->dev, | |
| 1077 | + "CIK support provided by radeon.\n"); | |
| 1078 | + dev_info(&pdev->dev, | |
| 1079 | + "Use radeon.cik_support=0 amdgpu.cik_support=1 to override.\n" | |
| 1080 | + ); | |
| 1081 | + return -ENODEV; | |
| 1082 | + } | |
| 1083 | + } | |
| 1084 | +#endif | |
| 1085 | + | |
| 1051 | 1086 | /* Get rid of things like offb */ |
| 1052 | 1087 | ret = drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "amdgpudrmfb"); |
| 1053 | 1088 | if (ret) |
| @@ -144,41 +144,6 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags) · 143 unmodified lines | ||
| 144 | 144 | struct amdgpu_device *adev; |
| 145 | 145 | int r, acpi_status; |
| 146 | 146 | |
| 147 | −#ifdef CONFIG_DRM_AMDGPU_SI | |
| 148 | − if (!amdgpu_si_support) { | |
| 149 | − switch (flags & AMD_ASIC_MASK) { | |
| 150 | − case CHIP_TAHITI: | |
| 151 | − case CHIP_PITCAIRN: | |
| 152 | − case CHIP_VERDE: | |
| 153 | − case CHIP_OLAND: | |
| 154 | − case CHIP_HAINAN: | |
| 155 | − dev_info(dev->dev, | |
| 156 | − "SI support provided by radeon.\n"); | |
| 157 | − dev_info(dev->dev, | |
| 158 | − "Use radeon.si_support=0 amdgpu.si_support=1 to override.\n" | |
| 159 | − ); | |
| 160 | − return -ENODEV; | |
| 161 | − } | |
| 162 | − } | |
| 163 | −#endif | |
| 164 | −#ifdef CONFIG_DRM_AMDGPU_CIK | |
| 165 | − if (!amdgpu_cik_support) { | |
| 166 | − switch (flags & AMD_ASIC_MASK) { | |
| 167 | − case CHIP_KAVERI: | |
| 168 | − case CHIP_BONAIRE: | |
| 169 | − case CHIP_HAWAII: | |
| 170 | − case CHIP_KABINI: | |
| 171 | − case CHIP_MULLINS: | |
| 172 | − dev_info(dev->dev, | |
| 173 | − "CIK support provided by radeon.\n"); | |
| 174 | − dev_info(dev->dev, | |
| 175 | − "Use radeon.cik_support=0 amdgpu.cik_support=1 to override.\n" | |
| 176 | − ); | |
| 177 | − return -ENODEV; | |
| 178 | − } | |
| 179 | − } | |
| 180 | −#endif | |
| 181 | − | |
| 182 | 147 | adev = kzalloc(sizeof(struct amdgpu_device), GFP_KERNEL); |
| 183 | 148 | if (adev == NULL) { |
| 184 | 149 | return -ENOMEM; |
| @@ -1129,7 +1129,7 @@ static void sdma_v5_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring) · 1128 unmodified lines | ||
| 1129 | 1129 | amdgpu_ring_write(ring, addr & 0xfffffffc); |
| 1130 | 1130 | amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff); |
| 1131 | 1131 | amdgpu_ring_write(ring, seq); /* reference */ |
| 1132 | − amdgpu_ring_write(ring, 0xfffffff); /* mask */ | |
| 1132 | + amdgpu_ring_write(ring, 0xffffffff); /* mask */ | |
| 1133 | 1133 | amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) | |
| 1134 | 1134 | SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(4)); /* retry count, poll interval */ |
| 1135 | 1135 | } |
| @@ -655,7 +655,7 @@ static int polaris10_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, · 654 unmodified lines | ||
| 655 | 655 | count = SMU_MAX_SMIO_LEVELS; |
| 656 | 656 | for (level = 0; level < count; level++) { |
| 657 | 657 | table->SmioTable2.Pattern[level].Voltage = |
| 658 | − PP_HOST_TO_SMC_US(data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE); | |
| 658 | + PP_HOST_TO_SMC_US(data->mvdd_voltage_table.entries[level].value * VOLTAGE_SCALE); | |
| 659 | 659 | /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/ |
| 660 | 660 | table->SmioTable2.Pattern[level].Smio = |
| 661 | 661 | (uint8_t) level; |
| @@ -456,7 +456,7 @@ static int vegam_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr, · 455 unmodified lines | ||
| 456 | 456 | count = SMU_MAX_SMIO_LEVELS; |
| 457 | 457 | for (level = 0; level < count; level++) { |
| 458 | 458 | table->SmioTable2.Pattern[level].Voltage = PP_HOST_TO_SMC_US( |
| 459 | − data->mvdd_voltage_table.entries[count].value * VOLTAGE_SCALE); | |
| 459 | + data->mvdd_voltage_table.entries[level].value * VOLTAGE_SCALE); | |
| 460 | 460 | /* Index into DpmTable.Smio. Drive bits from Smio entry to get this voltage level.*/ |
| 461 | 461 | table->SmioTable2.Pattern[level].Smio = |
| 462 | 462 | (uint8_t) level; |
| @@ -729,6 +729,8 @@ static int tc_set_video_mode(struct tc_data *tc, · 728 unmodified lines | ||
| 729 | 729 | int lower_margin = mode->vsync_start - mode->vdisplay; |
| 730 | 730 | int vsync_len = mode->vsync_end - mode->vsync_start; |
| 731 | 731 | u32 dp0_syncval; |
| 732 | + u32 bits_per_pixel = 24; | |
| 733 | + u32 in_bw, out_bw; | |
| 732 | 734 | |
| 733 | 735 | /* |
| 734 | 736 | * Recommended maximum number of symbols transferred in a transfer unit: |
| @@ -736,7 +738,10 @@ static int tc_set_video_mode(struct tc_data *tc, · 1 unmodified line | ||
| 736 | 738 | * (output active video bandwidth in bytes)) |
| 737 | 739 | * Must be less than tu_size. |
| 738 | 740 | */ |
| 739 | − max_tu_symbol = TU_SIZE_RECOMMENDED - 1; | |
| 741 | + | |
| 742 | + in_bw = mode->clock * bits_per_pixel / 8; | |
| 743 | + out_bw = tc->link.base.num_lanes * tc->link.base.rate; | |
| 744 | + max_tu_symbol = DIV_ROUND_UP(in_bw * TU_SIZE_RECOMMENDED, out_bw); | |
| 740 | 745 | |
| 741 | 746 | dev_dbg(tc->dev, "set mode %dx%d\n", |
| 742 | 747 | mode->hdisplay, mode->vdisplay); |
| @@ -159,6 +159,9 @@ static const struct edid_quirk { · 158 unmodified lines | ||
| 159 | 159 | /* Medion MD 30217 PG */ |
| 160 | 160 | { "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 }, |
| 161 | 161 | |
| 162 | + /* Lenovo G50 */ | |
| 163 | + { "SDC", 18514, EDID_QUIRK_FORCE_6BPC }, | |
| 164 | + | |
| 162 | 165 | /* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */ |
| 163 | 166 | { "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC }, |
| 164 | 167 | |
| @@ -26,6 +26,8 @@ · 25 unmodified lines | ||
| 26 | 26 | #include "dsi_cfg.h" |
| 27 | 27 | #include "msm_kms.h" |
| 28 | 28 | |
| 29 | +#define DSI_RESET_TOGGLE_DELAY_MS 20 | |
| 30 | + | |
| 29 | 31 | static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) |
| 30 | 32 | { |
| 31 | 33 | u32 ver; |
| @@ -986,7 +988,7 @@ static void dsi_sw_reset(struct msm_dsi_host *msm_host) · 954 unmodified lines | ||
| 986 | 988 | wmb(); /* clocks need to be enabled before reset */ |
| 987 | 989 | |
| 988 | 990 | dsi_write(msm_host, REG_DSI_RESET, 1); |
| 989 | − wmb(); /* make sure reset happen */ | |
| 991 | + msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */ | |
| 990 | 992 | dsi_write(msm_host, REG_DSI_RESET, 0); |
| 991 | 993 | } |
| 992 | 994 | |
| @@ -1396,7 +1398,7 @@ static void dsi_sw_reset_restore(struct msm_dsi_host *msm_host) · 403 unmodified lines | ||
| 1396 | 1398 | |
| 1397 | 1399 | /* dsi controller can only be reset while clocks are running */ |
| 1398 | 1400 | dsi_write(msm_host, REG_DSI_RESET, 1); |
| 1399 | − wmb(); /* make sure reset happen */ | |
| 1401 | + msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */ | |
| 1400 | 1402 | dsi_write(msm_host, REG_DSI_RESET, 0); |
| 1401 | 1403 | wmb(); /* controller out of reset */ |
| 1402 | 1404 | dsi_write(msm_host, REG_DSI_CTRL, data0); |
| @@ -219,9 +219,17 @@ static const struct of_device_id lb035q02_of_match[] = { · 218 unmodified lines | ||
| 219 | 219 | |
| 220 | 220 | MODULE_DEVICE_TABLE(of, lb035q02_of_match); |
| 221 | 221 | |
| 222 | +static const struct spi_device_id lb035q02_ids[] = { | |
| 223 | + { "lb035q02", 0 }, | |
| 224 | + { /* sentinel */ } | |
| 225 | +}; | |
| 226 | + | |
| 227 | +MODULE_DEVICE_TABLE(spi, lb035q02_ids); | |
| 228 | + | |
| 222 | 229 | static struct spi_driver lb035q02_driver = { |
| 223 | 230 | .probe = lb035q02_probe, |
| 224 | 231 | .remove = lb035q02_remove, |
| 232 | + .id_table = lb035q02_ids, | |
| 225 | 233 | .driver = { |
| 226 | 234 | .name = "panel-lg-lb035q02", |
| 227 | 235 | .of_match_table = lb035q02_of_match, |
| @@ -230,7 +238,6 @@ static struct spi_driver lb035q02_driver = { · 2 unmodified lines | ||
| 230 | 238 | |
| 231 | 239 | module_spi_driver(lb035q02_driver); |
| 232 | 240 | |
| 233 | −MODULE_ALIAS("spi:lgphilips,lb035q02"); | |
| 234 | 241 | MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>"); |
| 235 | 242 | MODULE_DESCRIPTION("LG.Philips LB035Q02 LCD Panel driver"); |
| 236 | 243 | MODULE_LICENSE("GPL"); |
| @@ -229,9 +229,17 @@ static const struct of_device_id nl8048_of_match[] = { · 228 unmodified lines | ||
| 229 | 229 | |
| 230 | 230 | MODULE_DEVICE_TABLE(of, nl8048_of_match); |
| 231 | 231 | |
| 232 | +static const struct spi_device_id nl8048_ids[] = { | |
| 233 | + { "nl8048hl11", 0 }, | |
| 234 | + { /* sentinel */ } | |
| 235 | +}; | |
| 236 | + | |
| 237 | +MODULE_DEVICE_TABLE(spi, nl8048_ids); | |
| 238 | + | |
| 232 | 239 | static struct spi_driver nl8048_driver = { |
| 233 | 240 | .probe = nl8048_probe, |
| 234 | 241 | .remove = nl8048_remove, |
| 242 | + .id_table = nl8048_ids, | |
| 235 | 243 | .driver = { |
| 236 | 244 | .name = "panel-nec-nl8048hl11", |
| 237 | 245 | .pm = &nl8048_pm_ops, |
| @@ -241,7 +249,6 @@ static struct spi_driver nl8048_driver = { · 3 unmodified lines | ||
| 241 | 249 | |
| 242 | 250 | module_spi_driver(nl8048_driver); |
| 243 | 251 | |
| 244 | −MODULE_ALIAS("spi:nec,nl8048hl11"); | |
| 245 | 252 | MODULE_AUTHOR("Erik Gilling <konkers@android.com>"); |
| 246 | 253 | MODULE_DESCRIPTION("NEC-NL8048HL11 Driver"); |
| 247 | 254 | MODULE_LICENSE("GPL"); |
| @@ -683,9 +683,17 @@ static const struct of_device_id acx565akm_of_match[] = { · 682 unmodified lines | ||
| 683 | 683 | |
| 684 | 684 | MODULE_DEVICE_TABLE(of, acx565akm_of_match); |
| 685 | 685 | |
| 686 | +static const struct spi_device_id acx565akm_ids[] = { | |
| 687 | + { "acx565akm", 0 }, | |
| 688 | + { /* sentinel */ } | |
| 689 | +}; | |
| 690 | + | |
| 691 | +MODULE_DEVICE_TABLE(spi, acx565akm_ids); | |
| 692 | + | |
| 686 | 693 | static struct spi_driver acx565akm_driver = { |
| 687 | 694 | .probe = acx565akm_probe, |
| 688 | 695 | .remove = acx565akm_remove, |
| 696 | + .id_table = acx565akm_ids, | |
| 689 | 697 | .driver = { |
| 690 | 698 | .name = "panel-sony-acx565akm", |
| 691 | 699 | .of_match_table = acx565akm_of_match, |
| @@ -694,7 +702,6 @@ static struct spi_driver acx565akm_driver = { · 2 unmodified lines | ||
| 694 | 702 | |
| 695 | 703 | module_spi_driver(acx565akm_driver); |
| 696 | 704 | |
| 697 | −MODULE_ALIAS("spi:sony,acx565akm"); | |
| 698 | 705 | MODULE_AUTHOR("Nokia Corporation"); |
| 699 | 706 | MODULE_DESCRIPTION("Sony ACX565AKM LCD Panel Driver"); |
| 700 | 707 | MODULE_LICENSE("GPL"); |
| @@ -374,8 +374,7 @@ static const struct of_device_id td028ttec1_of_match[] = { · 373 unmodified lines | ||
| 374 | 374 | MODULE_DEVICE_TABLE(of, td028ttec1_of_match); |
| 375 | 375 | |
| 376 | 376 | static const struct spi_device_id td028ttec1_ids[] = { |
| 377 | − { "tpo,td028ttec1", 0}, | |
| 378 | − { "toppoly,td028ttec1", 0 }, | |
| 377 | + { "td028ttec1", 0 }, | |
| 379 | 378 | { /* sentinel */ } |
| 380 | 379 | }; |
| 381 | 380 | |
| @@ -490,9 +490,17 @@ static const struct of_device_id td043mtea1_of_match[] = { · 489 unmodified lines | ||
| 490 | 490 | |
| 491 | 491 | MODULE_DEVICE_TABLE(of, td043mtea1_of_match); |
| 492 | 492 | |
| 493 | +static const struct spi_device_id td043mtea1_ids[] = { | |
| 494 | + { "td043mtea1", 0 }, | |
| 495 | + { /* sentinel */ } | |
| 496 | +}; | |
| 497 | + | |
| 498 | +MODULE_DEVICE_TABLE(spi, td043mtea1_ids); | |
| 499 | + | |
| 493 | 500 | static struct spi_driver td043mtea1_driver = { |
| 494 | 501 | .probe = td043mtea1_probe, |
| 495 | 502 | .remove = td043mtea1_remove, |
| 503 | + .id_table = td043mtea1_ids, | |
| 496 | 504 | .driver = { |
| 497 | 505 | .name = "panel-tpo-td043mtea1", |
| 498 | 506 | .pm = &td043mtea1_pm_ops, |
| @@ -502,7 +510,6 @@ static struct spi_driver td043mtea1_driver = { · 3 unmodified lines | ||
| 502 | 510 | |
| 503 | 511 | module_spi_driver(td043mtea1_driver); |
| 504 | 512 | |
| 505 | −MODULE_ALIAS("spi:tpo,td043mtea1"); | |
| 506 | 513 | MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>"); |
| 507 | 514 | MODULE_DESCRIPTION("TPO TD043MTEA1 Panel Driver"); |
| 508 | 515 | MODULE_LICENSE("GPL"); |
| @@ -208,6 +208,9 @@ static void panfrost_gpu_init_features(struct panfrost_device *pfdev) · 207 unmodified lines | ||
| 208 | 208 | pfdev->features.mem_features = gpu_read(pfdev, GPU_MEM_FEATURES); |
| 209 | 209 | pfdev->features.mmu_features = gpu_read(pfdev, GPU_MMU_FEATURES); |
| 210 | 210 | pfdev->features.thread_features = gpu_read(pfdev, GPU_THREAD_FEATURES); |
| 211 | + pfdev->features.max_threads = gpu_read(pfdev, GPU_THREAD_MAX_THREADS); | |
| 212 | + pfdev->features.thread_max_workgroup_sz = gpu_read(pfdev, GPU_THREAD_MAX_WORKGROUP_SIZE); | |
| 213 | + pfdev->features.thread_max_barrier_sz = gpu_read(pfdev, GPU_THREAD_MAX_BARRIER_SIZE); | |
| 211 | 214 | pfdev->features.coherency_features = gpu_read(pfdev, GPU_COHERENCY_FEATURES); |
| 212 | 215 | for (i = 0; i < 4; i++) |
| 213 | 216 | pfdev->features.texture_features[i] = gpu_read(pfdev, GPU_TEXTURE_FEATURES(i)); |
| @@ -381,13 +381,19 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job) · 380 unmodified lines | ||
| 381 | 381 | job_read(pfdev, JS_TAIL_LO(js)), |
| 382 | 382 | sched_job); |
| 383 | 383 | |
| 384 | − mutex_lock(&pfdev->reset_lock); | |
| 384 | + if (!mutex_trylock(&pfdev->reset_lock)) | |
| 385 | + return; | |
| 385 | 386 | |
| 386 | − for (i = 0; i < NUM_JOB_SLOTS; i++) | |
| 387 | − drm_sched_stop(&pfdev->js->queue[i].sched, sched_job); | |
| 387 | + for (i = 0; i < NUM_JOB_SLOTS; i++) { | |
| 388 | + struct drm_gpu_scheduler *sched = &pfdev->js->queue[i].sched; | |
| 389 | + | |
| 390 | + drm_sched_stop(sched, sched_job); | |
| 391 | + if (js != i) | |
| 392 | + /* Ensure any timeouts on other slots have finished */ | |
| 393 | + cancel_delayed_work_sync(&sched->work_tdr); | |
| 394 | + } | |
| 388 | 395 | |
| 389 | − if (sched_job) | |
| 390 | − drm_sched_increase_karma(sched_job); | |
| 396 | + drm_sched_increase_karma(sched_job); | |
| 391 | 397 | |
| 392 | 398 | spin_lock_irqsave(&pfdev->js->job_lock, flags); |
| 393 | 399 | for (i = 0; i < NUM_JOB_SLOTS; i++) { |
| @@ -379,19 +379,11 @@ radeon_pci_remove(struct pci_dev *pdev) · 378 unmodified lines | ||
| 379 | 379 | static void |
| 380 | 380 | radeon_pci_shutdown(struct pci_dev *pdev) |
| 381 | 381 | { |
| 382 | − struct drm_device *ddev = pci_get_drvdata(pdev); | |
| 383 | − | |
| 384 | 382 | /* if we are running in a VM, make sure the device |
| 385 | 383 | * torn down properly on reboot/shutdown |
| 386 | 384 | */ |
| 387 | 385 | if (radeon_device_is_virtual()) |
| 388 | 386 | radeon_pci_remove(pdev); |
| 389 | − | |
| 390 | − /* Some adapters need to be suspended before a | |
| 391 | − * shutdown occurs in order to prevent an error | |
| 392 | − * during kexec. | |
| 393 | − */ | |
| 394 | − radeon_suspend_kms(ddev, true, true, false); | |
| 395 | 387 | } |
| 396 | 388 | |
| 397 | 389 | static int radeon_pmops_suspend(struct device *dev) |
| @@ -185,8 +185,9 @@ static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo, · 184 unmodified lines | ||
| 185 | 185 | list_add_tail(&bo->lru, &man->lru[bo->priority]); |
| 186 | 186 | kref_get(&bo->list_kref); |
| 187 | 187 | |
| 188 | − if (bo->ttm && !(bo->ttm->page_flags & | |
| 189 | − (TTM_PAGE_FLAG_SG | TTM_PAGE_FLAG_SWAPPED))) { | |
| 188 | + if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED) && bo->ttm && | |
| 189 | + !(bo->ttm->page_flags & (TTM_PAGE_FLAG_SG | | |
| 190 | + TTM_PAGE_FLAG_SWAPPED))) { | |
| 190 | 191 | list_add_tail(&bo->swap, &bdev->glob->swap_lru[bo->priority]); |
| 191 | 192 | kref_get(&bo->list_kref); |
| 192 | 193 | } |
| @@ -878,11 +879,11 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, · 685 unmodified lines | ||
| 878 | 879 | |
| 879 | 880 | if (!bo) { |
| 880 | 881 | if (busy_bo) |
| 881 | − ttm_bo_get(busy_bo); | |
| 882 | + kref_get(&busy_bo->list_kref); | |
| 882 | 883 | spin_unlock(&glob->lru_lock); |
| 883 | 884 | ret = ttm_mem_evict_wait_busy(busy_bo, ctx, ticket); |
| 884 | 885 | if (busy_bo) |
| 885 | − ttm_bo_put(busy_bo); | |
| 886 | + kref_put(&busy_bo->list_kref, ttm_bo_release_list); | |
| 886 | 887 | return ret; |
| 887 | 888 | } |
| 888 | 889 | |
| @@ -278,15 +278,13 @@ static vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf) · 277 unmodified lines | ||
| 278 | 278 | else |
| 279 | 279 | ret = vmf_insert_pfn(&cvma, address, pfn); |
| 280 | 280 | |
| 281 | − /* | |
| 282 | − * Somebody beat us to this PTE or prefaulting to | |
| 283 | − * an already populated PTE, or prefaulting error. | |
| 284 | − */ | |
| 285 | − | |
| 286 | − if (unlikely((ret == VM_FAULT_NOPAGE && i > 0))) | |
| 287 | − break; | |
| 288 | − else if (unlikely(ret & VM_FAULT_ERROR)) | |
| 289 | − goto out_io_unlock; | |
| 281 | + /* Never error on prefaulted PTEs */ | |
| 282 | + if (unlikely((ret & VM_FAULT_ERROR))) { | |
| 283 | + if (i == 0) | |
| 284 | + goto out_io_unlock; | |
| 285 | + else | |
| 286 | + break; | |
| 287 | + } | |
| 290 | 288 | |
| 291 | 289 | address += PAGE_SIZE; |
| 292 | 290 | if (unlikely(++page_offset >= page_last)) |
| @@ -718,17 +718,9 @@ static int xen_drv_probe(struct xenbus_device *xb_dev, · 717 unmodified lines | ||
| 718 | 718 | struct device *dev = &xb_dev->dev; |
| 719 | 719 | int ret; |
| 720 | 720 | |
| 721 | − /* | |
| 722 | − * The device is not spawn from a device tree, so arch_setup_dma_ops | |
| 723 | − * is not called, thus leaving the device with dummy DMA ops. | |
| 724 | − * This makes the device return error on PRIME buffer import, which | |
| 725 | − * is not correct: to fix this call of_dma_configure() with a NULL | |
| 726 | − * node to set default DMA ops. | |
| 727 | − */ | |
| 728 | − dev->coherent_dma_mask = DMA_BIT_MASK(32); | |
| 729 | − ret = of_dma_configure(dev, NULL, true); | |
| 721 | + ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(64)); | |
| 730 | 722 | if (ret < 0) { |
| 731 | − DRM_ERROR("Cannot setup DMA ops, ret %d", ret); | |
| 723 | + DRM_ERROR("Cannot setup DMA mask, ret %d", ret); | |
| 732 | 724 | return ret; |
| 733 | 725 | } |
| 734 | 726 | |
| @@ -314,60 +314,24 @@ static void mousevsc_on_receive(struct hv_device *device, · 313 unmodified lines | ||
| 314 | 314 | |
| 315 | 315 | static void mousevsc_on_channel_callback(void *context) |
| 316 | 316 | { |
| 317 | − const int packet_size = 0x100; | |
| 318 | − int ret; | |
| 319 | 317 | struct hv_device *device = context; |
| 320 | − u32 bytes_recvd; | |
| 321 | − u64 req_id; | |
| 322 | 318 | struct vmpacket_descriptor *desc; |
| 323 | − unsigned char *buffer; | |
| 324 | − int bufferlen = packet_size; | |
| 325 | − | |
| 326 | − buffer = kmalloc(bufferlen, GFP_ATOMIC); | |
| 327 | − if (!buffer) | |
| 328 | − return; | |
| 329 | − | |
| 330 | − do { | |
| 331 | − ret = vmbus_recvpacket_raw(device->channel, buffer, | |
| 332 | − bufferlen, &bytes_recvd, &req_id); | |
| 333 | − | |
| 334 | − switch (ret) { | |
| 335 | − case 0: | |
| 336 | − if (bytes_recvd <= 0) { | |
| 337 | − kfree(buffer); | |
| 338 | − return; | |
| 339 | − } | |
| 340 | − desc = (struct vmpacket_descriptor *)buffer; | |
| 341 | − | |
| 342 | − switch (desc->type) { | |
| 343 | − case VM_PKT_COMP: | |
| 344 | − break; | |
| 345 | − | |
| 346 | − case VM_PKT_DATA_INBAND: | |
| 347 | − mousevsc_on_receive(device, desc); | |
| 348 | − break; | |
| 349 | − | |
| 350 | − default: | |
| 351 | − pr_err("unhandled packet type %d, tid %llx len %d\n", | |
| 352 | − desc->type, req_id, bytes_recvd); | |
| 353 | − break; | |
| 354 | − } | |
| 355 | 319 | |
| 320 | + foreach_vmbus_pkt(desc, device->channel) { | |
| 321 | + switch (desc->type) { | |
| 322 | + case VM_PKT_COMP: | |
| 356 | 323 | break; |
| 357 | 324 | |
| 358 | − case -ENOBUFS: | |
| 359 | − kfree(buffer); | |
| 360 | − /* Handle large packet */ | |
| 361 | − bufferlen = bytes_recvd; | |
| 362 | − buffer = kmalloc(bytes_recvd, GFP_ATOMIC); | |
| 363 | − | |
| 364 | − if (!buffer) | |
| 365 | − return; | |
| 325 | + case VM_PKT_DATA_INBAND: | |
| 326 | + mousevsc_on_receive(device, desc); | |
| 327 | + break; | |
| 366 | 328 | |
| 329 | + default: | |
| 330 | + pr_err("Unhandled packet type %d, tid %llx len %d\n", | |
| 331 | + desc->type, desc->trans_id, desc->len8 * 8); | |
| 367 | 332 | break; |
| 368 | 333 | } |
| 369 | − } while (1); | |
| 370 | − | |
| 334 | + } | |
| 371 | 335 | } |
| 372 | 336 | |
| 373 | 337 | static int mousevsc_connect_to_vsp(struct hv_device *device) |
| @@ -912,6 +912,7 @@ static void vmbus_shutdown(struct device *child_device) · 911 unmodified lines | ||
| 912 | 912 | drv->shutdown(dev); |
| 913 | 913 | } |
| 914 | 914 | |
| 915 | +#ifdef CONFIG_PM_SLEEP | |
| 915 | 916 | /* |
| 916 | 917 | * vmbus_suspend - Suspend a vmbus device |
| 917 | 918 | */ |
| @@ -949,6 +950,7 @@ static int vmbus_resume(struct device *child_device) · 31 unmodified lines | ||
| 949 | 950 | |
| 950 | 951 | return drv->resume(dev); |
| 951 | 952 | } |
| 953 | +#endif /* CONFIG_PM_SLEEP */ | |
| 952 | 954 | |
| 953 | 955 | /* |
| 954 | 956 | * vmbus_device_release - Final callback release of the vmbus child device |
| @@ -1070,6 +1072,7 @@ msg_handled: · 115 unmodified lines | ||
| 1070 | 1072 | vmbus_signal_eom(msg, message_type); |
| 1071 | 1073 | } |
| 1072 | 1074 | |
| 1075 | +#ifdef CONFIG_PM_SLEEP | |
| 1073 | 1076 | /* |
| 1074 | 1077 | * Fake RESCIND_CHANNEL messages to clean up hv_sock channels by force for |
| 1075 | 1078 | * hibernation, because hv_sock connections can not persist across hibernation. |
| @@ -1105,6 +1108,7 @@ static void vmbus_force_channel_rescinded(struct vmbus_channel *channel) · 29 unmodified lines | ||
| 1105 | 1108 | vmbus_connection.work_queue, |
| 1106 | 1109 | &ctx->work); |
| 1107 | 1110 | } |
| 1111 | +#endif /* CONFIG_PM_SLEEP */ | |
| 1108 | 1112 | |
| 1109 | 1113 | /* |
| 1110 | 1114 | * Direct callback for channels using other deferred processing |
| @@ -2125,6 +2129,7 @@ acpi_walk_err: · 1014 unmodified lines | ||
| 2125 | 2129 | return ret_val; |
| 2126 | 2130 | } |
| 2127 | 2131 | |
| 2132 | +#ifdef CONFIG_PM_SLEEP | |
| 2128 | 2133 | static int vmbus_bus_suspend(struct device *dev) |
| 2129 | 2134 | { |
| 2130 | 2135 | struct vmbus_channel *channel, *sc; |
| @@ -2247,6 +2252,7 @@ static int vmbus_bus_resume(struct device *dev) · 116 unmodified lines | ||
| 2247 | 2252 | |
| 2248 | 2253 | return 0; |
| 2249 | 2254 | } |
| 2255 | +#endif /* CONFIG_PM_SLEEP */ | |
| 2250 | 2256 | |
| 2251 | 2257 | static const struct acpi_device_id vmbus_acpi_device_ids[] = { |
| 2252 | 2258 | {"VMBUS", 0}, |
| @@ -99,6 +99,8 @@ struct nct7904_data { · 98 unmodified lines | ||
| 99 | 99 | u8 enable_dts; |
| 100 | 100 | u8 has_dts; |
| 101 | 101 | u8 temp_mode; /* 0: TR mode, 1: TD mode */ |
| 102 | + u8 fan_alarm[2]; | |
| 103 | + u8 vsen_alarm[3]; | |
| 102 | 104 | }; |
| 103 | 105 | |
| 104 | 106 | /* Access functions */ |
| @@ -214,7 +216,15 @@ static int nct7904_read_fan(struct device *dev, u32 attr, int channel, · 109 unmodified lines | ||
| 214 | 216 | SMI_STS5_REG + (channel >> 3)); |
| 215 | 217 | if (ret < 0) |
| 216 | 218 | return ret; |
| 217 | − *val = (ret >> (channel & 0x07)) & 1; | |
| 219 | + if (!data->fan_alarm[channel >> 3]) | |
| 220 | + data->fan_alarm[channel >> 3] = ret & 0xff; | |
| 221 | + else | |
| 222 | + /* If there is new alarm showing up */ | |
| 223 | + data->fan_alarm[channel >> 3] |= (ret & 0xff); | |
| 224 | + *val = (data->fan_alarm[channel >> 3] >> (channel & 0x07)) & 1; | |
| 225 | + /* Needs to clean the alarm if alarm existing */ | |
| 226 | + if (*val) | |
| 227 | + data->fan_alarm[channel >> 3] ^= 1 << (channel & 0x07); | |
| 218 | 228 | return 0; |
| 219 | 229 | default: |
| 220 | 230 | return -EOPNOTSUPP; |
| @@ -298,7 +308,15 @@ static int nct7904_read_in(struct device *dev, u32 attr, int channel, · 77 unmodified lines | ||
| 298 | 308 | SMI_STS1_REG + (index >> 3)); |
| 299 | 309 | if (ret < 0) |
| 300 | 310 | return ret; |
| 301 | − *val = (ret >> (index & 0x07)) & 1; | |
| 311 | + if (!data->vsen_alarm[index >> 3]) | |
| 312 | + data->vsen_alarm[index >> 3] = ret & 0xff; | |
| 313 | + else | |
| 314 | + /* If there is new alarm showing up */ | |
| 315 | + data->vsen_alarm[index >> 3] |= (ret & 0xff); | |
| 316 | + *val = (data->vsen_alarm[index >> 3] >> (index & 0x07)) & 1; | |
| 317 | + /* Needs to clean the alarm if alarm existing */ | |
| 318 | + if (*val) | |
| 319 | + data->vsen_alarm[index >> 3] ^= 1 << (index & 0x07); | |
| 302 | 320 | return 0; |
| 303 | 321 | default: |
| 304 | 322 | return -EOPNOTSUPP; |
| @@ -915,12 +933,15 @@ static int nct7904_probe(struct i2c_client *client, · 610 unmodified lines | ||
| 915 | 933 | |
| 916 | 934 | data->temp_mode = 0; |
| 917 | 935 | for (i = 0; i < 4; i++) { |
| 918 | − val = (ret & (0x03 << i)) >> (i * 2); | |
| 936 | + val = (ret >> (i * 2)) & 0x03; | |
| 919 | 937 | bit = (1 << i); |
| 920 | − if (val == 0) | |
| 938 | + if (val == 0) { | |
| 921 | 939 | data->tcpu_mask &= ~bit; |
| 922 | − else if (val == 0x1 || val == 0x2) | |
| 923 | − data->temp_mode |= bit; | |
| 940 | + } else { | |
| 941 | + if (val == 0x1 || val == 0x2) | |
| 942 | + data->temp_mode |= bit; | |
| 943 | + data->vsen_mask &= ~(0x06 << (i * 2)); | |
| 944 | + } | |
| 924 | 945 | } |
| 925 | 946 | |
| 926 | 947 | /* PECI */ |
| @@ -474,12 +474,17 @@ static int adxl372_configure_fifo(struct adxl372_state *st) · 473 unmodified lines | ||
| 474 | 474 | if (ret < 0) |
| 475 | 475 | return ret; |
| 476 | 476 | |
| 477 | − fifo_samples = st->watermark & 0xFF; | |
| 477 | + /* | |
| 478 | + * watermark stores the number of sets; we need to write the FIFO | |
| 479 | + * registers with the number of samples | |
| 480 | + */ | |
| 481 | + fifo_samples = (st->watermark * st->fifo_set_size); | |
| 478 | 482 | fifo_ctl = ADXL372_FIFO_CTL_FORMAT_MODE(st->fifo_format) | |
| 479 | 483 | ADXL372_FIFO_CTL_MODE_MODE(st->fifo_mode) | |
| 480 | − ADXL372_FIFO_CTL_SAMPLES_MODE(st->watermark); | |
| 484 | + ADXL372_FIFO_CTL_SAMPLES_MODE(fifo_samples); | |
| 481 | 485 | |
| 482 | − ret = regmap_write(st->regmap, ADXL372_FIFO_SAMPLES, fifo_samples); | |
| 486 | + ret = regmap_write(st->regmap, | |
| 487 | + ADXL372_FIFO_SAMPLES, fifo_samples & 0xFF); | |
| 483 | 488 | if (ret < 0) |
| 484 | 489 | return ret; |
| 485 | 490 | |
| @@ -548,8 +553,7 @@ static irqreturn_t adxl372_trigger_handler(int irq, void *p) · 62 unmodified lines | ||
| 548 | 553 | goto err; |
| 549 | 554 | |
| 550 | 555 | /* Each sample is 2 bytes */ |
| 551 | − for (i = 0; i < fifo_entries * sizeof(u16); | |
| 552 | − i += st->fifo_set_size * sizeof(u16)) | |
| 556 | + for (i = 0; i < fifo_entries; i += st->fifo_set_size) | |
| 553 | 557 | iio_push_to_buffers(indio_dev, &st->fifo_buf[i]); |
| 554 | 558 | } |
| 555 | 559 | err: |
| @@ -571,6 +575,14 @@ static int adxl372_setup(struct adxl372_state *st) · 15 unmodified lines | ||
| 571 | 575 | return -ENODEV; |
| 572 | 576 | } |
| 573 | 577 | |
| 578 | + /* | |
| 579 | + * Perform a software reset to make sure the device is in a consistent | |
| 580 | + * state after start up. | |
| 581 | + */ | |
| 582 | + ret = regmap_write(st->regmap, ADXL372_RESET, ADXL372_RESET_CODE); | |
| 583 | + if (ret < 0) | |
| 584 | + return ret; | |
| 585 | + | |
| 574 | 586 | ret = adxl372_set_op_mode(st, ADXL372_STANDBY); |
| 575 | 587 | if (ret < 0) |
| 576 | 588 | return ret; |
| @@ -117,7 +117,7 @@ · 116 unmodified lines | ||
| 117 | 117 | #define BMC150_ACCEL_SLEEP_1_SEC 0x0F |
| 118 | 118 | |
| 119 | 119 | #define BMC150_ACCEL_REG_TEMP 0x08 |
| 120 | −#define BMC150_ACCEL_TEMP_CENTER_VAL 24 | |
| 120 | +#define BMC150_ACCEL_TEMP_CENTER_VAL 23 | |
| 121 | 121 | |
| 122 | 122 | #define BMC150_ACCEL_AXIS_TO_REG(axis) (BMC150_ACCEL_REG_XOUT_L + (axis * 2)) |
| 123 | 123 | #define BMC150_AUTO_SUSPEND_DELAY_MS 2000 |
| @@ -810,10 +810,10 @@ static int ad799x_probe(struct i2c_client *client, · 809 unmodified lines | ||
| 810 | 810 | |
| 811 | 811 | ret = ad799x_write_config(st, st->chip_config->default_config); |
| 812 | 812 | if (ret < 0) |
| 813 | − goto error_disable_reg; | |
| 813 | + goto error_disable_vref; | |
| 814 | 814 | ret = ad799x_read_config(st); |
| 815 | 815 | if (ret < 0) |
| 816 | − goto error_disable_reg; | |
| 816 | + goto error_disable_vref; | |
| 817 | 817 | st->config = ret; |
| 818 | 818 | |
| 819 | 819 | ret = iio_triggered_buffer_setup(indio_dev, NULL, |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | +#include <linux/dmi.h> | |
| 10 | 11 | #include <linux/module.h> |
| 11 | 12 | #include <linux/kernel.h> |
| 12 | 13 | #include <linux/device.h> |
| @@ -25,6 +26,11 @@ · 12 unmodified lines | ||
| 25 | 26 | #define AXP288_ADC_EN_MASK 0xF0 |
| 26 | 27 | #define AXP288_ADC_TS_ENABLE 0x01 |
| 27 | 28 | |
| 29 | +#define AXP288_ADC_TS_BIAS_MASK GENMASK(5, 4) | |
| 30 | +#define AXP288_ADC_TS_BIAS_20UA (0 << 4) | |
| 31 | +#define AXP288_ADC_TS_BIAS_40UA (1 << 4) | |
| 32 | +#define AXP288_ADC_TS_BIAS_60UA (2 << 4) | |
| 33 | +#define AXP288_ADC_TS_BIAS_80UA (3 << 4) | |
| 28 | 34 | #define AXP288_ADC_TS_CURRENT_ON_OFF_MASK GENMASK(1, 0) |
| 29 | 35 | #define AXP288_ADC_TS_CURRENT_OFF (0 << 0) |
| 30 | 36 | #define AXP288_ADC_TS_CURRENT_ON_WHEN_CHARGING (1 << 0) |
| @@ -177,10 +183,36 @@ static int axp288_adc_read_raw(struct iio_dev *indio_dev, · 146 unmodified lines | ||
| 177 | 183 | return ret; |
| 178 | 184 | } |
| 179 | 185 | |
| 186 | +/* | |
| 187 | + * We rely on the machine's firmware to correctly setup the TS pin bias current | |
| 188 | + * at boot. This lists systems with broken fw where we need to set it ourselves. | |
| 189 | + */ | |
| 190 | +static const struct dmi_system_id axp288_adc_ts_bias_override[] = { | |
| 191 | + { | |
| 192 | + /* Lenovo Ideapad 100S (11 inch) */ | |
| 193 | + .matches = { | |
| 194 | + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | |
| 195 | + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 100S-11IBY"), | |
| 196 | + }, | |
| 197 | + .driver_data = (void *)(uintptr_t)AXP288_ADC_TS_BIAS_80UA, | |
| 198 | + }, | |
| 199 | + {} | |
| 200 | +}; | |
| 201 | + | |
| 180 | 202 | static int axp288_adc_initialize(struct axp288_adc_info *info) |
| 181 | 203 | { |
| 204 | + const struct dmi_system_id *bias_override; | |
| 182 | 205 | int ret, adc_enable_val; |
| 183 | 206 | |
| 207 | + bias_override = dmi_first_match(axp288_adc_ts_bias_override); | |
| 208 | + if (bias_override) { | |
| 209 | + ret = regmap_update_bits(info->regmap, AXP288_ADC_TS_PIN_CTRL, | |
| 210 | + AXP288_ADC_TS_BIAS_MASK, | |
| 211 | + (uintptr_t)bias_override->driver_data); | |
| 212 | + if (ret) | |
| 213 | + return ret; | |
| 214 | + } | |
| 215 | + | |
| 184 | 216 | /* |
| 185 | 217 | * Determine if the TS pin is enabled and set the TS current-source |
| 186 | 218 | * accordingly. |
| @@ -100,14 +100,14 @@ struct hx711_data { · 99 unmodified lines | ||
| 100 | 100 | |
| 101 | 101 | static int hx711_cycle(struct hx711_data *hx711_data) |
| 102 | 102 | { |
| 103 | − int val; | |
| 103 | + unsigned long flags; | |
| 104 | 104 | |
| 105 | 105 | /* |
| 106 | 106 | * if preempted for more then 60us while PD_SCK is high: |
| 107 | 107 | * hx711 is going in reset |
| 108 | 108 | * ==> measuring is false |
| 109 | 109 | */ |
| 110 | − preempt_disable(); | |
| 110 | + local_irq_save(flags); | |
| 111 | 111 | gpiod_set_value(hx711_data->gpiod_pd_sck, 1); |
| 112 | 112 | |
| 113 | 113 | /* |
| @@ -117,7 +117,6 @@ static int hx711_cycle(struct hx711_data *hx711_data) · 3 unmodified lines | ||
| 117 | 117 | */ |
| 118 | 118 | ndelay(hx711_data->data_ready_delay_ns); |
| 119 | 119 | |
| 120 | − val = gpiod_get_value(hx711_data->gpiod_dout); | |
| 121 | 120 | /* |
| 122 | 121 | * here we are not waiting for 0.2 us as suggested by the datasheet, |
| 123 | 122 | * because the oscilloscope showed in a test scenario |
| @@ -125,7 +124,7 @@ static int hx711_cycle(struct hx711_data *hx711_data) · 1 unmodified line | ||
| 125 | 124 | * and 0.56 us for PD_SCK low on TI Sitara with 800 MHz |
| 126 | 125 | */ |
| 127 | 126 | gpiod_set_value(hx711_data->gpiod_pd_sck, 0); |
| 128 | − preempt_enable(); | |
| 127 | + local_irq_restore(flags); | |
| 129 | 128 | |
| 130 | 129 | /* |
| 131 | 130 | * make it a square wave for addressing cases with capacitance on |
| @@ -133,7 +132,8 @@ static int hx711_cycle(struct hx711_data *hx711_data) · 1 unmodified line | ||
| 133 | 132 | */ |
| 134 | 133 | ndelay(hx711_data->data_ready_delay_ns); |
| 135 | 134 | |
| 136 | − return val; | |
| 135 | + /* sample as late as possible */ | |
| 136 | + return gpiod_get_value(hx711_data->gpiod_dout); | |
| 137 | 137 | } |
| 138 | 138 | |
| 139 | 139 | static int hx711_read(struct hx711_data *hx711_data) |
| @@ -1219,6 +1219,11 @@ static int meson_sar_adc_probe(struct platform_device *pdev) · 1218 unmodified lines | ||
| 1219 | 1219 | if (IS_ERR(base)) |
| 1220 | 1220 | return PTR_ERR(base); |
| 1221 | 1221 | |
| 1222 | + priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, | |
| 1223 | + priv->param->regmap_config); | |
| 1224 | + if (IS_ERR(priv->regmap)) | |
| 1225 | + return PTR_ERR(priv->regmap); | |
| 1226 | + | |
| 1222 | 1227 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); |
| 1223 | 1228 | if (!irq) |
| 1224 | 1229 | return -EINVAL; |
| @@ -1228,11 +1233,6 @@ static int meson_sar_adc_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 1228 | 1233 | if (ret) |
| 1229 | 1234 | return ret; |
| 1230 | 1235 | |
| 1231 | − priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, | |
| 1232 | − priv->param->regmap_config); | |
| 1233 | − if (IS_ERR(priv->regmap)) | |
| 1234 | − return PTR_ERR(priv->regmap); | |
| 1235 | − | |
| 1236 | 1236 | priv->clkin = devm_clk_get(&pdev->dev, "clkin"); |
| 1237 | 1237 | if (IS_ERR(priv->clkin)) { |
| 1238 | 1238 | dev_err(&pdev->dev, "failed to get clkin\n"); |
| @@ -24,33 +24,6 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #include "stm32-adc-core.h" |
| 26 | 26 | |
| 27 | −/* STM32F4 - common registers for all ADC instances: 1, 2 & 3 */ | |
| 28 | −#define STM32F4_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00) | |
| 29 | −#define STM32F4_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x04) | |
| 30 | − | |
| 31 | −/* STM32F4_ADC_CSR - bit fields */ | |
| 32 | −#define STM32F4_EOC3 BIT(17) | |
| 33 | −#define STM32F4_EOC2 BIT(9) | |
| 34 | −#define STM32F4_EOC1 BIT(1) | |
| 35 | − | |
| 36 | −/* STM32F4_ADC_CCR - bit fields */ | |
| 37 | −#define STM32F4_ADC_ADCPRE_SHIFT 16 | |
| 38 | −#define STM32F4_ADC_ADCPRE_MASK GENMASK(17, 16) | |
| 39 | − | |
| 40 | −/* STM32H7 - common registers for all ADC instances */ | |
| 41 | −#define STM32H7_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00) | |
| 42 | −#define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08) | |
| 43 | − | |
| 44 | −/* STM32H7_ADC_CSR - bit fields */ | |
| 45 | −#define STM32H7_EOC_SLV BIT(18) | |
| 46 | −#define STM32H7_EOC_MST BIT(2) | |
| 47 | − | |
| 48 | −/* STM32H7_ADC_CCR - bit fields */ | |
| 49 | −#define STM32H7_PRESC_SHIFT 18 | |
| 50 | −#define STM32H7_PRESC_MASK GENMASK(21, 18) | |
| 51 | −#define STM32H7_CKMODE_SHIFT 16 | |
| 52 | −#define STM32H7_CKMODE_MASK GENMASK(17, 16) | |
| 53 | − | |
| 54 | 27 | #define STM32_ADC_CORE_SLEEP_DELAY_MS 2000 |
| 55 | 28 | |
| 56 | 29 | /* SYSCFG registers */ |
| @@ -71,6 +44,8 @@ · 14 unmodified lines | ||
| 71 | 44 | * @eoc1: adc1 end of conversion flag in @csr |
| 72 | 45 | * @eoc2: adc2 end of conversion flag in @csr |
| 73 | 46 | * @eoc3: adc3 end of conversion flag in @csr |
| 47 | + * @ier: interrupt enable register offset for each adc | |
| 48 | + * @eocie_msk: end of conversion interrupt enable mask in @ier | |
| 74 | 49 | */ |
| 75 | 50 | struct stm32_adc_common_regs { |
| 76 | 51 | u32 csr; |
| @@ -78,6 +53,8 @@ struct stm32_adc_common_regs { · 1 unmodified line | ||
| 78 | 53 | u32 eoc1_msk; |
| 79 | 54 | u32 eoc2_msk; |
| 80 | 55 | u32 eoc3_msk; |
| 56 | + u32 ier; | |
| 57 | + u32 eocie_msk; | |
| 81 | 58 | }; |
| 82 | 59 | |
| 83 | 60 | struct stm32_adc_priv; |
| @@ -303,6 +280,8 @@ static const struct stm32_adc_common_regs stm32f4_adc_common_regs = { · 219 unmodified lines | ||
| 303 | 280 | .eoc1_msk = STM32F4_EOC1, |
| 304 | 281 | .eoc2_msk = STM32F4_EOC2, |
| 305 | 282 | .eoc3_msk = STM32F4_EOC3, |
| 283 | + .ier = STM32F4_ADC_CR1, | |
| 284 | + .eocie_msk = STM32F4_EOCIE, | |
| 306 | 285 | }; |
| 307 | 286 | |
| 308 | 287 | /* STM32H7 common registers definitions */ |
| @@ -311,8 +290,24 @@ static const struct stm32_adc_common_regs stm32h7_adc_common_regs = { · 2 unmodified lines | ||
| 311 | 290 | .ccr = STM32H7_ADC_CCR, |
| 312 | 291 | .eoc1_msk = STM32H7_EOC_MST, |
| 313 | 292 | .eoc2_msk = STM32H7_EOC_SLV, |
| 293 | + .ier = STM32H7_ADC_IER, | |
| 294 | + .eocie_msk = STM32H7_EOCIE, | |
| 295 | +}; | |
| 296 | + | |
| 297 | +static const unsigned int stm32_adc_offset[STM32_ADC_MAX_ADCS] = { | |
| 298 | + 0, STM32_ADC_OFFSET, STM32_ADC_OFFSET * 2, | |
| 314 | 299 | }; |
| 315 | 300 | |
| 301 | +static unsigned int stm32_adc_eoc_enabled(struct stm32_adc_priv *priv, | |
| 302 | + unsigned int adc) | |
| 303 | +{ | |
| 304 | + u32 ier, offset = stm32_adc_offset[adc]; | |
| 305 | + | |
| 306 | + ier = readl_relaxed(priv->common.base + offset + priv->cfg->regs->ier); | |
| 307 | + | |
| 308 | + return ier & priv->cfg->regs->eocie_msk; | |
| 309 | +} | |
| 310 | + | |
| 316 | 311 | /* ADC common interrupt for all instances */ |
| 317 | 312 | static void stm32_adc_irq_handler(struct irq_desc *desc) |
| 318 | 313 | { |
| @@ -323,13 +318,28 @@ static void stm32_adc_irq_handler(struct irq_desc *desc) · 4 unmodified lines | ||
| 323 | 318 | chained_irq_enter(chip, desc); |
| 324 | 319 | status = readl_relaxed(priv->common.base + priv->cfg->regs->csr); |
| 325 | 320 | |
| 326 | − if (status & priv->cfg->regs->eoc1_msk) | |
| 321 | + /* | |
| 322 | + * End of conversion may be handled by using IRQ or DMA. There may be a | |
| 323 | + * race here when two conversions complete at the same time on several | |
| 324 | + * ADCs. EOC may be read 'set' for several ADCs, with: | |
| 325 | + * - an ADC configured to use DMA (EOC triggers the DMA request, and | |
| 326 | + * is then automatically cleared by DR read in hardware) | |
| 327 | + * - an ADC configured to use IRQs (EOCIE bit is set. The handler must | |
| 328 | + * be called in this case) | |
| 329 | + * So both EOC status bit in CSR and EOCIE control bit must be checked | |
| 330 | + * before invoking the interrupt handler (e.g. call ISR only for | |
| 331 | + * IRQ-enabled ADCs). | |
| 332 | + */ | |
| 333 | + if (status & priv->cfg->regs->eoc1_msk && | |
| 334 | + stm32_adc_eoc_enabled(priv, 0)) | |
| 327 | 335 | generic_handle_irq(irq_find_mapping(priv->domain, 0)); |
| 328 | 336 | |
| 329 | − if (status & priv->cfg->regs->eoc2_msk) | |
| 337 | + if (status & priv->cfg->regs->eoc2_msk && | |
| 338 | + stm32_adc_eoc_enabled(priv, 1)) | |
| 330 | 339 | generic_handle_irq(irq_find_mapping(priv->domain, 1)); |
| 331 | 340 | |
| 332 | − if (status & priv->cfg->regs->eoc3_msk) | |
| 341 | + if (status & priv->cfg->regs->eoc3_msk && | |
| 342 | + stm32_adc_eoc_enabled(priv, 2)) | |
| 333 | 343 | generic_handle_irq(irq_find_mapping(priv->domain, 2)); |
| 334 | 344 | |
| 335 | 345 | chained_irq_exit(chip, desc); |
| @@ -25,8 +25,145 @@ · 24 unmodified lines | ||
| 25 | 25 | * -------------------------------------------------------- |
| 26 | 26 | */ |
| 27 | 27 | #define STM32_ADC_MAX_ADCS 3 |
| 28 | +#define STM32_ADC_OFFSET 0x100 | |
| 28 | 29 | #define STM32_ADCX_COMN_OFFSET 0x300 |
| 29 | 30 | |
| 31 | +/* STM32F4 - Registers for each ADC instance */ | |
| 32 | +#define STM32F4_ADC_SR 0x00 | |
| 33 | +#define STM32F4_ADC_CR1 0x04 | |
| 34 | +#define STM32F4_ADC_CR2 0x08 | |
| 35 | +#define STM32F4_ADC_SMPR1 0x0C | |
| 36 | +#define STM32F4_ADC_SMPR2 0x10 | |
| 37 | +#define STM32F4_ADC_HTR 0x24 | |
| 38 | +#define STM32F4_ADC_LTR 0x28 | |
| 39 | +#define STM32F4_ADC_SQR1 0x2C | |
| 40 | +#define STM32F4_ADC_SQR2 0x30 | |
| 41 | +#define STM32F4_ADC_SQR3 0x34 | |
| 42 | +#define STM32F4_ADC_JSQR 0x38 | |
| 43 | +#define STM32F4_ADC_JDR1 0x3C | |
| 44 | +#define STM32F4_ADC_JDR2 0x40 | |
| 45 | +#define STM32F4_ADC_JDR3 0x44 | |
| 46 | +#define STM32F4_ADC_JDR4 0x48 | |
| 47 | +#define STM32F4_ADC_DR 0x4C | |
| 48 | + | |
| 49 | +/* STM32F4 - common registers for all ADC instances: 1, 2 & 3 */ | |
| 50 | +#define STM32F4_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00) | |
| 51 | +#define STM32F4_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x04) | |
| 52 | + | |
| 53 | +/* STM32F4_ADC_SR - bit fields */ | |
| 54 | +#define STM32F4_STRT BIT(4) | |
| 55 | +#define STM32F4_EOC BIT(1) | |
| 56 | + | |
| 57 | +/* STM32F4_ADC_CR1 - bit fields */ | |
| 58 | +#define STM32F4_RES_SHIFT 24 | |
| 59 | +#define STM32F4_RES_MASK GENMASK(25, 24) | |
| 60 | +#define STM32F4_SCAN BIT(8) | |
| 61 | +#define STM32F4_EOCIE BIT(5) | |
| 62 | + | |
| 63 | +/* STM32F4_ADC_CR2 - bit fields */ | |
| 64 | +#define STM32F4_SWSTART BIT(30) | |
| 65 | +#define STM32F4_EXTEN_SHIFT 28 | |
| 66 | +#define STM32F4_EXTEN_MASK GENMASK(29, 28) | |
| 67 | +#define STM32F4_EXTSEL_SHIFT 24 | |
| 68 | +#define STM32F4_EXTSEL_MASK GENMASK(27, 24) | |
| 69 | +#define STM32F4_EOCS BIT(10) | |
| 70 | +#define STM32F4_DDS BIT(9) | |
| 71 | +#define STM32F4_DMA BIT(8) | |
| 72 | +#define STM32F4_ADON BIT(0) | |
| 73 | + | |
| 74 | +/* STM32F4_ADC_CSR - bit fields */ | |
| 75 | +#define STM32F4_EOC3 BIT(17) | |
| 76 | +#define STM32F4_EOC2 BIT(9) | |
| 77 | +#define STM32F4_EOC1 BIT(1) | |
| 78 | + | |
| 79 | +/* STM32F4_ADC_CCR - bit fields */ | |
| 80 | +#define STM32F4_ADC_ADCPRE_SHIFT 16 | |
| 81 | +#define STM32F4_ADC_ADCPRE_MASK GENMASK(17, 16) | |
| 82 | + | |
| 83 | +/* STM32H7 - Registers for each ADC instance */ | |
| 84 | +#define STM32H7_ADC_ISR 0x00 | |
| 85 | +#define STM32H7_ADC_IER 0x04 | |
| 86 | +#define STM32H7_ADC_CR 0x08 | |
| 87 | +#define STM32H7_ADC_CFGR 0x0C | |
| 88 | +#define STM32H7_ADC_SMPR1 0x14 | |
| 89 | +#define STM32H7_ADC_SMPR2 0x18 | |
| 90 | +#define STM32H7_ADC_PCSEL 0x1C | |
| 91 | +#define STM32H7_ADC_SQR1 0x30 | |
| 92 | +#define STM32H7_ADC_SQR2 0x34 | |
| 93 | +#define STM32H7_ADC_SQR3 0x38 | |
| 94 | +#define STM32H7_ADC_SQR4 0x3C | |
| 95 | +#define STM32H7_ADC_DR 0x40 | |
| 96 | +#define STM32H7_ADC_DIFSEL 0xC0 | |
| 97 | +#define STM32H7_ADC_CALFACT 0xC4 | |
| 98 | +#define STM32H7_ADC_CALFACT2 0xC8 | |
| 99 | + | |
| 100 | +/* STM32H7 - common registers for all ADC instances */ | |
| 101 | +#define STM32H7_ADC_CSR (STM32_ADCX_COMN_OFFSET + 0x00) | |
| 102 | +#define STM32H7_ADC_CCR (STM32_ADCX_COMN_OFFSET + 0x08) | |
| 103 | + | |
| 104 | +/* STM32H7_ADC_ISR - bit fields */ | |
| 105 | +#define STM32MP1_VREGREADY BIT(12) | |
| 106 | +#define STM32H7_EOC BIT(2) | |
| 107 | +#define STM32H7_ADRDY BIT(0) | |
| 108 | + | |
| 109 | +/* STM32H7_ADC_IER - bit fields */ | |
| 110 | +#define STM32H7_EOCIE STM32H7_EOC | |
| 111 | + | |
| 112 | +/* STM32H7_ADC_CR - bit fields */ | |
| 113 | +#define STM32H7_ADCAL BIT(31) | |
| 114 | +#define STM32H7_ADCALDIF BIT(30) | |
| 115 | +#define STM32H7_DEEPPWD BIT(29) | |
| 116 | +#define STM32H7_ADVREGEN BIT(28) | |
| 117 | +#define STM32H7_LINCALRDYW6 BIT(27) | |
| 118 | +#define STM32H7_LINCALRDYW5 BIT(26) | |
| 119 | +#define STM32H7_LINCALRDYW4 BIT(25) | |
| 120 | +#define STM32H7_LINCALRDYW3 BIT(24) | |
| 121 | +#define STM32H7_LINCALRDYW2 BIT(23) | |
| 122 | +#define STM32H7_LINCALRDYW1 BIT(22) | |
| 123 | +#define STM32H7_ADCALLIN BIT(16) | |
| 124 | +#define STM32H7_BOOST BIT(8) | |
| 125 | +#define STM32H7_ADSTP BIT(4) | |
| 126 | +#define STM32H7_ADSTART BIT(2) | |
| 127 | +#define STM32H7_ADDIS BIT(1) | |
| 128 | +#define STM32H7_ADEN BIT(0) | |
| 129 | + | |
| 130 | +/* STM32H7_ADC_CFGR bit fields */ | |
| 131 | +#define STM32H7_EXTEN_SHIFT 10 | |
| 132 | +#define STM32H7_EXTEN_MASK GENMASK(11, 10) | |
| 133 | +#define STM32H7_EXTSEL_SHIFT 5 | |
| 134 | +#define STM32H7_EXTSEL_MASK GENMASK(9, 5) | |
| 135 | +#define STM32H7_RES_SHIFT 2 | |
| 136 | +#define STM32H7_RES_MASK GENMASK(4, 2) | |
| 137 | +#define STM32H7_DMNGT_SHIFT 0 | |
| 138 | +#define STM32H7_DMNGT_MASK GENMASK(1, 0) | |
| 139 | + | |
| 140 | +enum stm32h7_adc_dmngt { | |
| 141 | + STM32H7_DMNGT_DR_ONLY, /* Regular data in DR only */ | |
| 142 | + STM32H7_DMNGT_DMA_ONESHOT, /* DMA one shot mode */ | |
| 143 | + STM32H7_DMNGT_DFSDM, /* DFSDM mode */ | |
| 144 | + STM32H7_DMNGT_DMA_CIRC, /* DMA circular mode */ | |
| 145 | +}; | |
| 146 | + | |
| 147 | +/* STM32H7_ADC_CALFACT - bit fields */ | |
| 148 | +#define STM32H7_CALFACT_D_SHIFT 16 | |
| 149 | +#define STM32H7_CALFACT_D_MASK GENMASK(26, 16) | |
| 150 | +#define STM32H7_CALFACT_S_SHIFT 0 | |
| 151 | +#define STM32H7_CALFACT_S_MASK GENMASK(10, 0) | |
| 152 | + | |
| 153 | +/* STM32H7_ADC_CALFACT2 - bit fields */ | |
| 154 | +#define STM32H7_LINCALFACT_SHIFT 0 | |
| 155 | +#define STM32H7_LINCALFACT_MASK GENMASK(29, 0) | |
| 156 | + | |
| 157 | +/* STM32H7_ADC_CSR - bit fields */ | |
| 158 | +#define STM32H7_EOC_SLV BIT(18) | |
| 159 | +#define STM32H7_EOC_MST BIT(2) | |
| 160 | + | |
| 161 | +/* STM32H7_ADC_CCR - bit fields */ | |
| 162 | +#define STM32H7_PRESC_SHIFT 18 | |
| 163 | +#define STM32H7_PRESC_MASK GENMASK(21, 18) | |
| 164 | +#define STM32H7_CKMODE_SHIFT 16 | |
| 165 | +#define STM32H7_CKMODE_MASK GENMASK(17, 16) | |
| 166 | + | |
| 30 | 167 | /** |
| 31 | 168 | * struct stm32_adc_common - stm32 ADC driver common data (for all instances) |
| 32 | 169 | * @base: control registers base cpu addr |
| @@ -28,115 +28,6 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | #include "stm32-adc-core.h" |
| 30 | 30 | |
| 31 | −/* STM32F4 - Registers for each ADC instance */ | |
| 32 | −#define STM32F4_ADC_SR 0x00 | |
| 33 | −#define STM32F4_ADC_CR1 0x04 | |
| 34 | −#define STM32F4_ADC_CR2 0x08 | |
| 35 | −#define STM32F4_ADC_SMPR1 0x0C | |
| 36 | −#define STM32F4_ADC_SMPR2 0x10 | |
| 37 | −#define STM32F4_ADC_HTR 0x24 | |
| 38 | −#define STM32F4_ADC_LTR 0x28 | |
| 39 | −#define STM32F4_ADC_SQR1 0x2C | |
| 40 | −#define STM32F4_ADC_SQR2 0x30 | |
| 41 | −#define STM32F4_ADC_SQR3 0x34 | |
| 42 | −#define STM32F4_ADC_JSQR 0x38 | |
| 43 | −#define STM32F4_ADC_JDR1 0x3C | |
| 44 | −#define STM32F4_ADC_JDR2 0x40 | |
| 45 | −#define STM32F4_ADC_JDR3 0x44 | |
| 46 | −#define STM32F4_ADC_JDR4 0x48 | |
| 47 | −#define STM32F4_ADC_DR 0x4C | |
| 48 | − | |
| 49 | −/* STM32F4_ADC_SR - bit fields */ | |
| 50 | −#define STM32F4_STRT BIT(4) | |
| 51 | −#define STM32F4_EOC BIT(1) | |
| 52 | − | |
| 53 | −/* STM32F4_ADC_CR1 - bit fields */ | |
| 54 | −#define STM32F4_RES_SHIFT 24 | |
| 55 | −#define STM32F4_RES_MASK GENMASK(25, 24) | |
| 56 | −#define STM32F4_SCAN BIT(8) | |
| 57 | −#define STM32F4_EOCIE BIT(5) | |
| 58 | − | |
| 59 | −/* STM32F4_ADC_CR2 - bit fields */ | |
| 60 | −#define STM32F4_SWSTART BIT(30) | |
| 61 | −#define STM32F4_EXTEN_SHIFT 28 | |
| 62 | −#define STM32F4_EXTEN_MASK GENMASK(29, 28) | |
| 63 | −#define STM32F4_EXTSEL_SHIFT 24 | |
| 64 | −#define STM32F4_EXTSEL_MASK GENMASK(27, 24) | |
| 65 | −#define STM32F4_EOCS BIT(10) | |
| 66 | −#define STM32F4_DDS BIT(9) | |
| 67 | −#define STM32F4_DMA BIT(8) | |
| 68 | −#define STM32F4_ADON BIT(0) | |
| 69 | − | |
| 70 | −/* STM32H7 - Registers for each ADC instance */ | |
| 71 | −#define STM32H7_ADC_ISR 0x00 | |
| 72 | −#define STM32H7_ADC_IER 0x04 | |
| 73 | −#define STM32H7_ADC_CR 0x08 | |
| 74 | −#define STM32H7_ADC_CFGR 0x0C | |
| 75 | −#define STM32H7_ADC_SMPR1 0x14 | |
| 76 | −#define STM32H7_ADC_SMPR2 0x18 | |
| 77 | −#define STM32H7_ADC_PCSEL 0x1C | |
| 78 | −#define STM32H7_ADC_SQR1 0x30 | |
| 79 | −#define STM32H7_ADC_SQR2 0x34 | |
| 80 | −#define STM32H7_ADC_SQR3 0x38 | |
| 81 | −#define STM32H7_ADC_SQR4 0x3C | |
| 82 | −#define STM32H7_ADC_DR 0x40 | |
| 83 | −#define STM32H7_ADC_DIFSEL 0xC0 | |
| 84 | −#define STM32H7_ADC_CALFACT 0xC4 | |
| 85 | −#define STM32H7_ADC_CALFACT2 0xC8 | |
| 86 | − | |
| 87 | −/* STM32H7_ADC_ISR - bit fields */ | |
| 88 | −#define STM32MP1_VREGREADY BIT(12) | |
| 89 | −#define STM32H7_EOC BIT(2) | |
| 90 | −#define STM32H7_ADRDY BIT(0) | |
| 91 | − | |
| 92 | −/* STM32H7_ADC_IER - bit fields */ | |
| 93 | −#define STM32H7_EOCIE STM32H7_EOC | |
| 94 | − | |
| 95 | −/* STM32H7_ADC_CR - bit fields */ | |
| 96 | −#define STM32H7_ADCAL BIT(31) | |
| 97 | −#define STM32H7_ADCALDIF BIT(30) | |
| 98 | −#define STM32H7_DEEPPWD BIT(29) | |
| 99 | −#define STM32H7_ADVREGEN BIT(28) | |
| 100 | −#define STM32H7_LINCALRDYW6 BIT(27) | |
| 101 | −#define STM32H7_LINCALRDYW5 BIT(26) | |
| 102 | −#define STM32H7_LINCALRDYW4 BIT(25) | |
| 103 | −#define STM32H7_LINCALRDYW3 BIT(24) | |
| 104 | −#define STM32H7_LINCALRDYW2 BIT(23) | |
| 105 | −#define STM32H7_LINCALRDYW1 BIT(22) | |
| 106 | −#define STM32H7_ADCALLIN BIT(16) | |
| 107 | −#define STM32H7_BOOST BIT(8) | |
| 108 | −#define STM32H7_ADSTP BIT(4) | |
| 109 | −#define STM32H7_ADSTART BIT(2) | |
| 110 | −#define STM32H7_ADDIS BIT(1) | |
| 111 | −#define STM32H7_ADEN BIT(0) | |
| 112 | − | |
| 113 | −/* STM32H7_ADC_CFGR bit fields */ | |
| 114 | −#define STM32H7_EXTEN_SHIFT 10 | |
| 115 | −#define STM32H7_EXTEN_MASK GENMASK(11, 10) | |
| 116 | −#define STM32H7_EXTSEL_SHIFT 5 | |
| 117 | −#define STM32H7_EXTSEL_MASK GENMASK(9, 5) | |
| 118 | −#define STM32H7_RES_SHIFT 2 | |
| 119 | −#define STM32H7_RES_MASK GENMASK(4, 2) | |
| 120 | −#define STM32H7_DMNGT_SHIFT 0 | |
| 121 | −#define STM32H7_DMNGT_MASK GENMASK(1, 0) | |
| 122 | − | |
| 123 | −enum stm32h7_adc_dmngt { | |
| 124 | − STM32H7_DMNGT_DR_ONLY, /* Regular data in DR only */ | |
| 125 | − STM32H7_DMNGT_DMA_ONESHOT, /* DMA one shot mode */ | |
| 126 | − STM32H7_DMNGT_DFSDM, /* DFSDM mode */ | |
| 127 | − STM32H7_DMNGT_DMA_CIRC, /* DMA circular mode */ | |
| 128 | −}; | |
| 129 | − | |
| 130 | −/* STM32H7_ADC_CALFACT - bit fields */ | |
| 131 | −#define STM32H7_CALFACT_D_SHIFT 16 | |
| 132 | −#define STM32H7_CALFACT_D_MASK GENMASK(26, 16) | |
| 133 | −#define STM32H7_CALFACT_S_SHIFT 0 | |
| 134 | −#define STM32H7_CALFACT_S_MASK GENMASK(10, 0) | |
| 135 | − | |
| 136 | −/* STM32H7_ADC_CALFACT2 - bit fields */ | |
| 137 | −#define STM32H7_LINCALFACT_SHIFT 0 | |
| 138 | −#define STM32H7_LINCALFACT_MASK GENMASK(29, 0) | |
| 139 | − | |
| 140 | 31 | /* Number of linear calibration shadow registers / LINCALRDYW control bits */ |
| 141 | 32 | #define STM32H7_LINCALFACT_NUM 6 |
| 142 | 33 | |
| @@ -35,8 +35,11 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, · 34 unmodified lines | ||
| 35 | 35 | return -ENOMEM; |
| 36 | 36 | |
| 37 | 37 | adis->buffer = kzalloc(burst_length + sizeof(u16), GFP_KERNEL); |
| 38 | − if (!adis->buffer) | |
| 38 | + if (!adis->buffer) { | |
| 39 | + kfree(adis->xfer); | |
| 40 | + adis->xfer = NULL; | |
| 39 | 41 | return -ENOMEM; |
| 42 | + } | |
| 40 | 43 | |
| 41 | 44 | tx = adis->buffer + burst_length; |
| 42 | 45 | tx[0] = ADIS_READ_REG(adis->burst->reg_cmd); |
| @@ -78,8 +81,11 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, · 35 unmodified lines | ||
| 78 | 81 | return -ENOMEM; |
| 79 | 82 | |
| 80 | 83 | adis->buffer = kcalloc(indio_dev->scan_bytes, 2, GFP_KERNEL); |
| 81 | − if (!adis->buffer) | |
| 84 | + if (!adis->buffer) { | |
| 85 | + kfree(adis->xfer); | |
| 86 | + adis->xfer = NULL; | |
| 82 | 87 | return -ENOMEM; |
| 88 | + } | |
| 83 | 89 | |
| 84 | 90 | rx = adis->buffer; |
| 85 | 91 | tx = rx + scan_count; |
| @@ -99,7 +99,9 @@ struct st_lsm6dsx_fs { · 98 unmodified lines | ||
| 99 | 99 | #define ST_LSM6DSX_FS_LIST_SIZE 4 |
| 100 | 100 | struct st_lsm6dsx_fs_table_entry { |
| 101 | 101 | struct st_lsm6dsx_reg reg; |
| 102 | + | |
| 102 | 103 | struct st_lsm6dsx_fs fs_avl[ST_LSM6DSX_FS_LIST_SIZE]; |
| 104 | + int fs_len; | |
| 103 | 105 | }; |
| 104 | 106 | |
| 105 | 107 | /** |
| @@ -145,6 +145,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 144 unmodified lines | ||
| 145 | 145 | .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, |
| 146 | 146 | .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, |
| 147 | 147 | .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 }, |
| 148 | + .fs_len = 4, | |
| 148 | 149 | }, |
| 149 | 150 | [ST_LSM6DSX_ID_GYRO] = { |
| 150 | 151 | .reg = { |
| @@ -154,6 +155,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 3 unmodified lines | ||
| 154 | 155 | .fs_avl[0] = { IIO_DEGREE_TO_RAD(245), 0x0 }, |
| 155 | 156 | .fs_avl[1] = { IIO_DEGREE_TO_RAD(500), 0x1 }, |
| 156 | 157 | .fs_avl[2] = { IIO_DEGREE_TO_RAD(2000), 0x3 }, |
| 158 | + .fs_len = 3, | |
| 157 | 159 | }, |
| 158 | 160 | }, |
| 159 | 161 | }, |
| @@ -215,6 +217,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 55 unmodified lines | ||
| 215 | 217 | .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, |
| 216 | 218 | .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, |
| 217 | 219 | .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, |
| 220 | + .fs_len = 4, | |
| 218 | 221 | }, |
| 219 | 222 | [ST_LSM6DSX_ID_GYRO] = { |
| 220 | 223 | .reg = { |
| @@ -225,6 +228,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 4 unmodified lines | ||
| 225 | 228 | .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, |
| 226 | 229 | .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, |
| 227 | 230 | .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, |
| 231 | + .fs_len = 4, | |
| 228 | 232 | }, |
| 229 | 233 | }, |
| 230 | 234 | .decimator = { |
| @@ -327,6 +331,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 96 unmodified lines | ||
| 327 | 331 | .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, |
| 328 | 332 | .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, |
| 329 | 333 | .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, |
| 334 | + .fs_len = 4, | |
| 330 | 335 | }, |
| 331 | 336 | [ST_LSM6DSX_ID_GYRO] = { |
| 332 | 337 | .reg = { |
| @@ -337,6 +342,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 4 unmodified lines | ||
| 337 | 342 | .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, |
| 338 | 343 | .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, |
| 339 | 344 | .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, |
| 345 | + .fs_len = 4, | |
| 340 | 346 | }, |
| 341 | 347 | }, |
| 342 | 348 | .decimator = { |
| @@ -448,6 +454,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 105 unmodified lines | ||
| 448 | 454 | .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, |
| 449 | 455 | .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, |
| 450 | 456 | .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, |
| 457 | + .fs_len = 4, | |
| 451 | 458 | }, |
| 452 | 459 | [ST_LSM6DSX_ID_GYRO] = { |
| 453 | 460 | .reg = { |
| @@ -458,6 +465,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 4 unmodified lines | ||
| 458 | 465 | .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, |
| 459 | 466 | .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, |
| 460 | 467 | .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, |
| 468 | + .fs_len = 4, | |
| 461 | 469 | }, |
| 462 | 470 | }, |
| 463 | 471 | .decimator = { |
| @@ -563,6 +571,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 99 unmodified lines | ||
| 563 | 571 | .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, |
| 564 | 572 | .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, |
| 565 | 573 | .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, |
| 574 | + .fs_len = 4, | |
| 566 | 575 | }, |
| 567 | 576 | [ST_LSM6DSX_ID_GYRO] = { |
| 568 | 577 | .reg = { |
| @@ -573,6 +582,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 4 unmodified lines | ||
| 573 | 582 | .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, |
| 574 | 583 | .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, |
| 575 | 584 | .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, |
| 585 | + .fs_len = 4, | |
| 576 | 586 | }, |
| 577 | 587 | }, |
| 578 | 588 | .batch = { |
| @@ -693,6 +703,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 114 unmodified lines | ||
| 693 | 703 | .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, |
| 694 | 704 | .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, |
| 695 | 705 | .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, |
| 706 | + .fs_len = 4, | |
| 696 | 707 | }, |
| 697 | 708 | [ST_LSM6DSX_ID_GYRO] = { |
| 698 | 709 | .reg = { |
| @@ -703,6 +714,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 4 unmodified lines | ||
| 703 | 714 | .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, |
| 704 | 715 | .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, |
| 705 | 716 | .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, |
| 717 | + .fs_len = 4, | |
| 706 | 718 | }, |
| 707 | 719 | }, |
| 708 | 720 | .batch = { |
| @@ -800,6 +812,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 91 unmodified lines | ||
| 800 | 812 | .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, |
| 801 | 813 | .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, |
| 802 | 814 | .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, |
| 815 | + .fs_len = 4, | |
| 803 | 816 | }, |
| 804 | 817 | [ST_LSM6DSX_ID_GYRO] = { |
| 805 | 818 | .reg = { |
| @@ -810,6 +823,7 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { · 4 unmodified lines | ||
| 810 | 823 | .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, |
| 811 | 824 | .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, |
| 812 | 825 | .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, |
| 826 | + .fs_len = 4, | |
| 813 | 827 | }, |
| 814 | 828 | }, |
| 815 | 829 | .batch = { |
| @@ -933,11 +947,12 @@ static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, · 117 unmodified lines | ||
| 933 | 947 | int i, err; |
| 934 | 948 | |
| 935 | 949 | fs_table = &sensor->hw->settings->fs_table[sensor->id]; |
| 936 | − for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) | |
| 950 | + for (i = 0; i < fs_table->fs_len; i++) { | |
| 937 | 951 | if (fs_table->fs_avl[i].gain == gain) |
| 938 | 952 | break; |
| 953 | + } | |
| 939 | 954 | |
| 940 | − if (i == ST_LSM6DSX_FS_LIST_SIZE) | |
| 955 | + if (i == fs_table->fs_len) | |
| 941 | 956 | return -EINVAL; |
| 942 | 957 | |
| 943 | 958 | data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val, |
| @@ -1196,18 +1211,13 @@ static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, · 252 unmodified lines | ||
| 1196 | 1211 | { |
| 1197 | 1212 | struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); |
| 1198 | 1213 | const struct st_lsm6dsx_fs_table_entry *fs_table; |
| 1199 | − enum st_lsm6dsx_sensor_id id = sensor->id; | |
| 1200 | 1214 | struct st_lsm6dsx_hw *hw = sensor->hw; |
| 1201 | 1215 | int i, len = 0; |
| 1202 | 1216 | |
| 1203 | − fs_table = &hw->settings->fs_table[id]; | |
| 1204 | − for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) { | |
| 1205 | − if (!fs_table->fs_avl[i].gain) | |
| 1206 | − break; | |
| 1207 | − | |
| 1217 | + fs_table = &hw->settings->fs_table[sensor->id]; | |
| 1218 | + for (i = 0; i < fs_table->fs_len; i++) | |
| 1208 | 1219 | len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", |
| 1209 | 1220 | fs_table->fs_avl[i].gain); |
| 1210 | − } | |
| 1211 | 1221 | buf[len - 1] = '\n'; |
| 1212 | 1222 | |
| 1213 | 1223 | return len; |
| @@ -61,6 +61,7 @@ static const struct st_lsm6dsx_ext_dev_settings st_lsm6dsx_ext_dev_table[] = { · 60 unmodified lines | ||
| 61 | 61 | .gain = 1500, |
| 62 | 62 | .val = 0x0, |
| 63 | 63 | }, /* 1500 uG/LSB */ |
| 64 | + .fs_len = 1, | |
| 64 | 65 | }, |
| 65 | 66 | .temp_comp = { |
| 66 | 67 | .addr = 0x60, |
| @@ -92,9 +93,11 @@ static const struct st_lsm6dsx_ext_dev_settings st_lsm6dsx_ext_dev_table[] = { · 25 unmodified lines | ||
| 92 | 93 | static void st_lsm6dsx_shub_wait_complete(struct st_lsm6dsx_hw *hw) |
| 93 | 94 | { |
| 94 | 95 | struct st_lsm6dsx_sensor *sensor; |
| 96 | + u16 odr; | |
| 95 | 97 | |
| 96 | 98 | sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); |
| 97 | − msleep((2000U / sensor->odr) + 1); | |
| 99 | + odr = (hw->enable_mask & BIT(ST_LSM6DSX_ID_ACC)) ? sensor->odr : 13; | |
| 100 | + msleep((2000U / odr) + 1); | |
| 98 | 101 | } |
| 99 | 102 | |
| 100 | 103 | /** |
| @@ -555,13 +558,9 @@ static ssize_t st_lsm6dsx_shub_scale_avail(struct device *dev, · 454 unmodified lines | ||
| 555 | 558 | int i, len = 0; |
| 556 | 559 | |
| 557 | 560 | settings = sensor->ext_info.settings; |
| 558 | − for (i = 0; i < ST_LSM6DSX_FS_LIST_SIZE; i++) { | |
| 559 | − u16 val = settings->fs_table.fs_avl[i].gain; | |
| 560 | − | |
| 561 | − if (val > 0) | |
| 562 | − len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", | |
| 563 | − val); | |
| 564 | − } | |
| 561 | + for (i = 0; i < settings->fs_table.fs_len; i++) | |
| 562 | + len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", | |
| 563 | + settings->fs_table.fs_avl[i].gain); | |
| 565 | 564 | buf[len - 1] = '\n'; |
| 566 | 565 | |
| 567 | 566 | return len; |
| @@ -314,6 +314,7 @@ config MAX44009 · 313 unmodified lines | ||
| 314 | 314 | config NOA1305 |
| 315 | 315 | tristate "ON Semiconductor NOA1305 ambient light sensor" |
| 316 | 316 | depends on I2C |
| 317 | + select REGMAP_I2C | |
| 317 | 318 | help |
| 318 | 319 | Say Y here if you want to build support for the ON Semiconductor |
| 319 | 320 | NOA1305 ambient light sensor. |
| @@ -686,6 +686,7 @@ static irqreturn_t opt3001_irq(int irq, void *_iio) · 685 unmodified lines | ||
| 686 | 686 | struct iio_dev *iio = _iio; |
| 687 | 687 | struct opt3001 *opt = iio_priv(iio); |
| 688 | 688 | int ret; |
| 689 | + bool wake_result_ready_queue = false; | |
| 689 | 690 | |
| 690 | 691 | if (!opt->ok_to_ignore_lock) |
| 691 | 692 | mutex_lock(&opt->lock); |
| @@ -720,13 +721,16 @@ static irqreturn_t opt3001_irq(int irq, void *_iio) · 28 unmodified lines | ||
| 720 | 721 | } |
| 721 | 722 | opt->result = ret; |
| 722 | 723 | opt->result_ready = true; |
| 723 | − wake_up(&opt->result_ready_queue); | |
| 724 | + wake_result_ready_queue = true; | |
| 724 | 725 | } |
| 725 | 726 | |
| 726 | 727 | out: |
| 727 | 728 | if (!opt->ok_to_ignore_lock) |
| 728 | 729 | mutex_unlock(&opt->lock); |
| 729 | 730 | |
| 731 | + if (wake_result_ready_queue) | |
| 732 | + wake_up(&opt->result_ready_queue); | |
| 733 | + | |
| 730 | 734 | return IRQ_HANDLED; |
| 731 | 735 | } |
| 732 | 736 | |
| @@ -398,19 +398,23 @@ static int vcnl4000_probe(struct i2c_client *client, · 397 unmodified lines | ||
| 398 | 398 | static const struct of_device_id vcnl_4000_of_match[] = { |
| 399 | 399 | { |
| 400 | 400 | .compatible = "vishay,vcnl4000", |
| 401 | − .data = "VCNL4000", | |
| 401 | + .data = (void *)VCNL4000, | |
| 402 | 402 | }, |
| 403 | 403 | { |
| 404 | 404 | .compatible = "vishay,vcnl4010", |
| 405 | − .data = "VCNL4010", | |
| 405 | + .data = (void *)VCNL4010, | |
| 406 | 406 | }, |
| 407 | 407 | { |
| 408 | − .compatible = "vishay,vcnl4010", | |
| 409 | − .data = "VCNL4020", | |
| 408 | + .compatible = "vishay,vcnl4020", | |
| 409 | + .data = (void *)VCNL4010, | |
| 410 | + }, | |
| 411 | + { | |
| 412 | + .compatible = "vishay,vcnl4040", | |
| 413 | + .data = (void *)VCNL4040, | |
| 410 | 414 | }, |
| 411 | 415 | { |
| 412 | 416 | .compatible = "vishay,vcnl4200", |
| 413 | − .data = "VCNL4200", | |
| 417 | + .data = (void *)VCNL4200, | |
| 414 | 418 | }, |
| 415 | 419 | {}, |
| 416 | 420 | }; |
| @@ -4399,6 +4399,7 @@ error2: · 4398 unmodified lines | ||
| 4399 | 4399 | error1: |
| 4400 | 4400 | port_modify.set_port_cap_mask = 0; |
| 4401 | 4401 | port_modify.clr_port_cap_mask = IB_PORT_CM_SUP; |
| 4402 | + kfree(port); | |
| 4402 | 4403 | while (--i) { |
| 4403 | 4404 | if (!rdma_cap_ib_cm(ib_device, i)) |
| 4404 | 4405 | continue; |
| @@ -4407,6 +4408,7 @@ error1: · 2 unmodified lines | ||
| 4407 | 4408 | ib_modify_port(ib_device, port->port_num, 0, &port_modify); |
| 4408 | 4409 | ib_unregister_mad_agent(port->mad_agent); |
| 4409 | 4410 | cm_remove_port_fs(port); |
| 4411 | + kfree(port); | |
| 4410 | 4412 | } |
| 4411 | 4413 | free: |
| 4412 | 4414 | kfree(cm_dev); |
| @@ -4460,6 +4462,7 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data) · 47 unmodified lines | ||
| 4460 | 4462 | spin_unlock_irq(&cm.state_lock); |
| 4461 | 4463 | ib_unregister_mad_agent(cur_mad_agent); |
| 4462 | 4464 | cm_remove_port_fs(port); |
| 4465 | + kfree(port); | |
| 4463 | 4466 | } |
| 4464 | 4467 | |
| 4465 | 4468 | kfree(cm_dev); |
| @@ -2396,9 +2396,10 @@ static int iw_conn_req_handler(struct iw_cm_id *cm_id, · 2395 unmodified lines | ||
| 2396 | 2396 | conn_id->cm_id.iw = NULL; |
| 2397 | 2397 | cma_exch(conn_id, RDMA_CM_DESTROYING); |
| 2398 | 2398 | mutex_unlock(&conn_id->handler_mutex); |
| 2399 | + mutex_unlock(&listen_id->handler_mutex); | |
| 2399 | 2400 | cma_deref_id(conn_id); |
| 2400 | 2401 | rdma_destroy_id(&conn_id->id); |
| 2401 | − goto out; | |
| 2402 | + return ret; | |
| 2402 | 2403 | } |
| 2403 | 2404 | |
| 2404 | 2405 | mutex_unlock(&conn_id->handler_mutex); |
| @@ -1987,8 +1987,6 @@ static int iw_query_port(struct ib_device *device, · 1986 unmodified lines | ||
| 1987 | 1987 | if (!netdev) |
| 1988 | 1988 | return -ENODEV; |
| 1989 | 1989 | |
| 1990 | − dev_put(netdev); | |
| 1991 | − | |
| 1992 | 1990 | port_attr->max_mtu = IB_MTU_4096; |
| 1993 | 1991 | port_attr->active_mtu = ib_mtu_int_to_enum(netdev->mtu); |
| 1994 | 1992 | |
| @@ -1996,19 +1994,22 @@ static int iw_query_port(struct ib_device *device, · 1 unmodified line | ||
| 1996 | 1994 | port_attr->state = IB_PORT_DOWN; |
| 1997 | 1995 | port_attr->phys_state = IB_PORT_PHYS_STATE_DISABLED; |
| 1998 | 1996 | } else { |
| 1999 | − inetdev = in_dev_get(netdev); | |
| 1997 | + rcu_read_lock(); | |
| 1998 | + inetdev = __in_dev_get_rcu(netdev); | |
| 2000 | 1999 | |
| 2001 | 2000 | if (inetdev && inetdev->ifa_list) { |
| 2002 | 2001 | port_attr->state = IB_PORT_ACTIVE; |
| 2003 | 2002 | port_attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP; |
| 2004 | − in_dev_put(inetdev); | |
| 2005 | 2003 | } else { |
| 2006 | 2004 | port_attr->state = IB_PORT_INIT; |
| 2007 | 2005 | port_attr->phys_state = |
| 2008 | 2006 | IB_PORT_PHYS_STATE_PORT_CONFIGURATION_TRAINING; |
| 2009 | 2007 | } |
| 2008 | + | |
| 2009 | + rcu_read_unlock(); | |
| 2010 | 2010 | } |
| 2011 | 2011 | |
| 2012 | + dev_put(netdev); | |
| 2012 | 2013 | err = device->ops.query_port(device, port_num, port_attr); |
| 2013 | 2014 | if (err) |
| 2014 | 2015 | return err; |
| @@ -1230,7 +1230,7 @@ static int res_get_common_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 1229 unmodified lines | ||
| 1230 | 1230 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
| 1231 | 1231 | if (!msg) { |
| 1232 | 1232 | ret = -ENOMEM; |
| 1233 | − goto err; | |
| 1233 | + goto err_get; | |
| 1234 | 1234 | } |
| 1235 | 1235 | |
| 1236 | 1236 | nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq, |
| @@ -1787,10 +1787,6 @@ static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 550 unmodified lines | ||
| 1787 | 1787 | |
| 1788 | 1788 | cntn = nla_get_u32(tb[RDMA_NLDEV_ATTR_STAT_COUNTER_ID]); |
| 1789 | 1789 | qpn = nla_get_u32(tb[RDMA_NLDEV_ATTR_RES_LQPN]); |
| 1790 | − ret = rdma_counter_unbind_qpn(device, port, qpn, cntn); | |
| 1791 | − if (ret) | |
| 1792 | − goto err_unbind; | |
| 1793 | − | |
| 1794 | 1790 | if (fill_nldev_handle(msg, device) || |
| 1795 | 1791 | nla_put_u32(msg, RDMA_NLDEV_ATTR_PORT_INDEX, port) || |
| 1796 | 1792 | nla_put_u32(msg, RDMA_NLDEV_ATTR_STAT_COUNTER_ID, cntn) || |
| @@ -1799,13 +1795,15 @@ static int nldev_stat_del_doit(struct sk_buff *skb, struct nlmsghdr *nlh, · 2 unmodified lines | ||
| 1799 | 1795 | goto err_fill; |
| 1800 | 1796 | } |
| 1801 | 1797 | |
| 1798 | + ret = rdma_counter_unbind_qpn(device, port, qpn, cntn); | |
| 1799 | + if (ret) | |
| 1800 | + goto err_fill; | |
| 1801 | + | |
| 1802 | 1802 | nlmsg_end(msg, nlh); |
| 1803 | 1803 | ib_device_put(device); |
| 1804 | 1804 | return rdma_nl_unicast(sock_net(skb->sk), msg, NETLINK_CB(skb).portid); |
| 1805 | 1805 | |
| 1806 | 1806 | err_fill: |
| 1807 | − rdma_counter_bind_qpn(device, port, qpn, cntn); | |
| 1808 | −err_unbind: | |
| 1809 | 1807 | nlmsg_free(msg); |
| 1810 | 1808 | err: |
| 1811 | 1809 | ib_device_put(device); |
| @@ -426,7 +426,7 @@ int ib_create_qp_security(struct ib_qp *qp, struct ib_device *dev) · 425 unmodified lines | ||
| 426 | 426 | int ret; |
| 427 | 427 | |
| 428 | 428 | rdma_for_each_port (dev, i) { |
| 429 | − is_ib = rdma_protocol_ib(dev, i++); | |
| 429 | + is_ib = rdma_protocol_ib(dev, i); | |
| 430 | 430 | if (is_ib) |
| 431 | 431 | break; |
| 432 | 432 | } |
| @@ -451,8 +451,10 @@ void ib_umem_odp_release(struct ib_umem_odp *umem_odp) · 450 unmodified lines | ||
| 451 | 451 | * that the hardware will not attempt to access the MR any more. |
| 452 | 452 | */ |
| 453 | 453 | if (!umem_odp->is_implicit_odp) { |
| 454 | + mutex_lock(&umem_odp->umem_mutex); | |
| 454 | 455 | ib_umem_odp_unmap_dma_pages(umem_odp, ib_umem_start(umem_odp), |
| 455 | 456 | ib_umem_end(umem_odp)); |
| 457 | + mutex_unlock(&umem_odp->umem_mutex); | |
| 456 | 458 | kvfree(umem_odp->dma_list); |
| 457 | 459 | kvfree(umem_odp->page_list); |
| 458 | 460 | } |
| @@ -719,6 +721,8 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 virt, · 260 unmodified lines | ||
| 719 | 721 | u64 addr; |
| 720 | 722 | struct ib_device *dev = umem_odp->umem.ibdev; |
| 721 | 723 | |
| 724 | + lockdep_assert_held(&umem_odp->umem_mutex); | |
| 725 | + | |
| 722 | 726 | virt = max_t(u64, virt, ib_umem_start(umem_odp)); |
| 723 | 727 | bound = min_t(u64, bound, ib_umem_end(umem_odp)); |
| 724 | 728 | /* Note that during the run of this function, the |
| @@ -726,7 +730,6 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 virt, · 1 unmodified line | ||
| 726 | 730 | * faults from completion. We might be racing with other |
| 727 | 731 | * invalidations, so we must make sure we free each page only |
| 728 | 732 | * once. */ |
| 729 | − mutex_lock(&umem_odp->umem_mutex); | |
| 730 | 733 | for (addr = virt; addr < bound; addr += BIT(umem_odp->page_shift)) { |
| 731 | 734 | idx = (addr - ib_umem_start(umem_odp)) >> umem_odp->page_shift; |
| 732 | 735 | if (umem_odp->page_list[idx]) { |
| @@ -757,7 +760,6 @@ void ib_umem_odp_unmap_dma_pages(struct ib_umem_odp *umem_odp, u64 virt, · 24 unmodified lines | ||
| 757 | 760 | umem_odp->npages--; |
| 758 | 761 | } |
| 759 | 762 | } |
| 760 | − mutex_unlock(&umem_odp->umem_mutex); | |
| 761 | 763 | } |
| 762 | 764 | EXPORT_SYMBOL(ib_umem_odp_unmap_dma_pages); |
| 763 | 765 | |
| @@ -242,10 +242,13 @@ static void set_ep_sin6_addrs(struct c4iw_ep *ep, · 241 unmodified lines | ||
| 242 | 242 | } |
| 243 | 243 | } |
| 244 | 244 | |
| 245 | −static int dump_qp(struct c4iw_qp *qp, struct c4iw_debugfs_data *qpd) | |
| 245 | +static int dump_qp(unsigned long id, struct c4iw_qp *qp, | |
| 246 | + struct c4iw_debugfs_data *qpd) | |
| 246 | 247 | { |
| 247 | 248 | int space; |
| 248 | 249 | int cc; |
| 250 | + if (id != qp->wq.sq.qid) | |
| 251 | + return 0; | |
| 249 | 252 | |
| 250 | 253 | space = qpd->bufsize - qpd->pos - 1; |
| 251 | 254 | if (space == 0) |
| @@ -350,7 +353,7 @@ static int qp_open(struct inode *inode, struct file *file) · 98 unmodified lines | ||
| 350 | 353 | |
| 351 | 354 | xa_lock_irq(&qpd->devp->qps); |
| 352 | 355 | xa_for_each(&qpd->devp->qps, index, qp) |
| 353 | − dump_qp(qp, qpd); | |
| 356 | + dump_qp(index, qp, qpd); | |
| 354 | 357 | xa_unlock_irq(&qpd->devp->qps); |
| 355 | 358 | |
| 356 | 359 | qpd->buf[qpd->pos++] = 0; |
| @@ -275,13 +275,17 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, · 274 unmodified lines | ||
| 275 | 275 | struct sk_buff *skb, struct c4iw_wr_wait *wr_waitp) |
| 276 | 276 | { |
| 277 | 277 | int err; |
| 278 | − struct fw_ri_tpte tpt; | |
| 278 | + struct fw_ri_tpte *tpt; | |
| 279 | 279 | u32 stag_idx; |
| 280 | 280 | static atomic_t key; |
| 281 | 281 | |
| 282 | 282 | if (c4iw_fatal_error(rdev)) |
| 283 | 283 | return -EIO; |
| 284 | 284 | |
| 285 | + tpt = kmalloc(sizeof(*tpt), GFP_KERNEL); | |
| 286 | + if (!tpt) | |
| 287 | + return -ENOMEM; | |
| 288 | + | |
| 285 | 289 | stag_state = stag_state > 0; |
| 286 | 290 | stag_idx = (*stag) >> 8; |
| 287 | 291 | |
| @@ -291,6 +295,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, · 3 unmodified lines | ||
| 291 | 295 | mutex_lock(&rdev->stats.lock); |
| 292 | 296 | rdev->stats.stag.fail++; |
| 293 | 297 | mutex_unlock(&rdev->stats.lock); |
| 298 | + kfree(tpt); | |
| 294 | 299 | return -ENOMEM; |
| 295 | 300 | } |
| 296 | 301 | mutex_lock(&rdev->stats.lock); |
| @@ -305,28 +310,28 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, · 8 unmodified lines | ||
| 305 | 310 | |
| 306 | 311 | /* write TPT entry */ |
| 307 | 312 | if (reset_tpt_entry) |
| 308 | − memset(&tpt, 0, sizeof(tpt)); | |
| 313 | + memset(tpt, 0, sizeof(*tpt)); | |
| 309 | 314 | else { |
| 310 | − tpt.valid_to_pdid = cpu_to_be32(FW_RI_TPTE_VALID_F | | |
| 315 | + tpt->valid_to_pdid = cpu_to_be32(FW_RI_TPTE_VALID_F | | |
| 311 | 316 | FW_RI_TPTE_STAGKEY_V((*stag & FW_RI_TPTE_STAGKEY_M)) | |
| 312 | 317 | FW_RI_TPTE_STAGSTATE_V(stag_state) | |
| 313 | 318 | FW_RI_TPTE_STAGTYPE_V(type) | FW_RI_TPTE_PDID_V(pdid)); |
| 314 | − tpt.locread_to_qpid = cpu_to_be32(FW_RI_TPTE_PERM_V(perm) | | |
| 319 | + tpt->locread_to_qpid = cpu_to_be32(FW_RI_TPTE_PERM_V(perm) | | |
| 315 | 320 | (bind_enabled ? FW_RI_TPTE_MWBINDEN_F : 0) | |
| 316 | 321 | FW_RI_TPTE_ADDRTYPE_V((zbva ? FW_RI_ZERO_BASED_TO : |
| 317 | 322 | FW_RI_VA_BASED_TO))| |
| 318 | 323 | FW_RI_TPTE_PS_V(page_size)); |
| 319 | − tpt.nosnoop_pbladdr = !pbl_size ? 0 : cpu_to_be32( | |
| 324 | + tpt->nosnoop_pbladdr = !pbl_size ? 0 : cpu_to_be32( | |
| 320 | 325 | FW_RI_TPTE_PBLADDR_V(PBL_OFF(rdev, pbl_addr)>>3)); |
| 321 | − tpt.len_lo = cpu_to_be32((u32)(len & 0xffffffffUL)); | |
| 322 | − tpt.va_hi = cpu_to_be32((u32)(to >> 32)); | |
| 323 | − tpt.va_lo_fbo = cpu_to_be32((u32)(to & 0xffffffffUL)); | |
| 324 | − tpt.dca_mwbcnt_pstag = cpu_to_be32(0); | |
| 325 | − tpt.len_hi = cpu_to_be32((u32)(len >> 32)); | |
| 326 | + tpt->len_lo = cpu_to_be32((u32)(len & 0xffffffffUL)); | |
| 327 | + tpt->va_hi = cpu_to_be32((u32)(to >> 32)); | |
| 328 | + tpt->va_lo_fbo = cpu_to_be32((u32)(to & 0xffffffffUL)); | |
| 329 | + tpt->dca_mwbcnt_pstag = cpu_to_be32(0); | |
| 330 | + tpt->len_hi = cpu_to_be32((u32)(len >> 32)); | |
| 326 | 331 | } |
| 327 | 332 | err = write_adapter_mem(rdev, stag_idx + |
| 328 | 333 | (rdev->lldi.vr->stag.start >> 5), |
| 329 | − sizeof(tpt), &tpt, skb, wr_waitp); | |
| 334 | + sizeof(*tpt), tpt, skb, wr_waitp); | |
| 330 | 335 | |
| 331 | 336 | if (reset_tpt_entry) { |
| 332 | 337 | c4iw_put_resource(&rdev->resource.tpt_table, stag_idx); |
| @@ -334,6 +339,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, · 1 unmodified line | ||
| 334 | 339 | rdev->stats.stag.cur -= 32; |
| 335 | 340 | mutex_unlock(&rdev->stats.lock); |
| 336 | 341 | } |
| 342 | + kfree(tpt); | |
| 337 | 343 | return err; |
| 338 | 344 | } |
| 339 | 345 | |
| @@ -2737,15 +2737,11 @@ int c4iw_create_srq(struct ib_srq *ib_srq, struct ib_srq_init_attr *attrs, · 2736 unmodified lines | ||
| 2737 | 2737 | if (CHELSIO_CHIP_VERSION(rhp->rdev.lldi.adapter_type) > CHELSIO_T6) |
| 2738 | 2738 | srq->flags = T4_SRQ_LIMIT_SUPPORT; |
| 2739 | 2739 | |
| 2740 | − ret = xa_insert_irq(&rhp->qps, srq->wq.qid, srq, GFP_KERNEL); | |
| 2741 | − if (ret) | |
| 2742 | − goto err_free_queue; | |
| 2743 | − | |
| 2744 | 2740 | if (udata) { |
| 2745 | 2741 | srq_key_mm = kmalloc(sizeof(*srq_key_mm), GFP_KERNEL); |
| 2746 | 2742 | if (!srq_key_mm) { |
| 2747 | 2743 | ret = -ENOMEM; |
| 2748 | − goto err_remove_handle; | |
| 2744 | + goto err_free_queue; | |
| 2749 | 2745 | } |
| 2750 | 2746 | srq_db_key_mm = kmalloc(sizeof(*srq_db_key_mm), GFP_KERNEL); |
| 2751 | 2747 | if (!srq_db_key_mm) { |
| @@ -2789,8 +2785,6 @@ err_free_srq_db_key_mm: · 37 unmodified lines | ||
| 2789 | 2785 | kfree(srq_db_key_mm); |
| 2790 | 2786 | err_free_srq_key_mm: |
| 2791 | 2787 | kfree(srq_key_mm); |
| 2792 | −err_remove_handle: | |
| 2793 | − xa_erase_irq(&rhp->qps, srq->wq.qid); | |
| 2794 | 2788 | err_free_queue: |
| 2795 | 2789 | free_srq_queue(srq, ucontext ? &ucontext->uctx : &rhp->rdev.uctx, |
| 2796 | 2790 | srq->wr_waitp); |
| @@ -2813,8 +2807,6 @@ void c4iw_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata) · 16 unmodified lines | ||
| 2813 | 2807 | rhp = srq->rhp; |
| 2814 | 2808 | |
| 2815 | 2809 | pr_debug("%s id %d\n", __func__, srq->wq.qid); |
| 2816 | − | |
| 2817 | − xa_erase_irq(&rhp->qps, srq->wq.qid); | |
| 2818 | 2810 | ucontext = rdma_udata_to_drv_context(udata, struct c4iw_ucontext, |
| 2819 | 2811 | ibucontext); |
| 2820 | 2812 | free_srq_queue(srq, ucontext ? &ucontext->uctx : &rhp->rdev.uctx, |
| @@ -1526,8 +1526,11 @@ int sdma_init(struct hfi1_devdata *dd, u8 port) · 1525 unmodified lines | ||
| 1526 | 1526 | } |
| 1527 | 1527 | |
| 1528 | 1528 | ret = rhashtable_init(tmp_sdma_rht, &sdma_rht_params); |
| 1529 | − if (ret < 0) | |
| 1529 | + if (ret < 0) { | |
| 1530 | + kfree(tmp_sdma_rht); | |
| 1530 | 1531 | goto bail; |
| 1532 | + } | |
| 1533 | + | |
| 1531 | 1534 | dd->sdma_rht = tmp_sdma_rht; |
| 1532 | 1535 | |
| 1533 | 1536 | dd_dev_info(dd, "SDMA num_sdma: %u\n", dd->num_sdma); |
| @@ -2773,6 +2773,10 @@ int i40iw_register_rdma_device(struct i40iw_device *iwdev) · 2772 unmodified lines | ||
| 2773 | 2773 | return -ENOMEM; |
| 2774 | 2774 | iwibdev = iwdev->iwibdev; |
| 2775 | 2775 | rdma_set_device_sysfs_group(&iwibdev->ibdev, &i40iw_attr_group); |
| 2776 | + ret = ib_device_set_netdev(&iwibdev->ibdev, iwdev->netdev, 1); | |
| 2777 | + if (ret) | |
| 2778 | + goto error; | |
| 2779 | + | |
| 2776 | 2780 | ret = ib_register_device(&iwibdev->ibdev, "i40iw%d"); |
| 2777 | 2781 | if (ret) |
| 2778 | 2782 | goto error; |
| @@ -1298,29 +1298,6 @@ static int devx_handle_mkey_create(struct mlx5_ib_dev *dev, · 1297 unmodified lines | ||
| 1298 | 1298 | return 0; |
| 1299 | 1299 | } |
| 1300 | 1300 | |
| 1301 | −static void devx_free_indirect_mkey(struct rcu_head *rcu) | |
| 1302 | −{ | |
| 1303 | − kfree(container_of(rcu, struct devx_obj, devx_mr.rcu)); | |
| 1304 | −} | |
| 1305 | − | |
| 1306 | −/* This function to delete from the radix tree needs to be called before | |
| 1307 | − * destroying the underlying mkey. Otherwise a race might occur in case that | |
| 1308 | − * other thread will get the same mkey before this one will be deleted, | |
| 1309 | − * in that case it will fail via inserting to the tree its own data. | |
| 1310 | − * | |
| 1311 | − * Note: | |
| 1312 | − * An error in the destroy is not expected unless there is some other indirect | |
| 1313 | − * mkey which points to this one. In a kernel cleanup flow it will be just | |
| 1314 | − * destroyed in the iterative destruction call. In a user flow, in case | |
| 1315 | − * the application didn't close in the expected order it's its own problem, | |
| 1316 | − * the mkey won't be part of the tree, in both cases the kernel is safe. | |
| 1317 | − */ | |
| 1318 | −static void devx_cleanup_mkey(struct devx_obj *obj) | |
| 1319 | −{ | |
| 1320 | − xa_erase(&obj->ib_dev->mdev->priv.mkey_table, | |
| 1321 | − mlx5_base_mkey(obj->devx_mr.mmkey.key)); | |
| 1322 | −} | |
| 1323 | − | |
| 1324 | 1301 | static void devx_cleanup_subscription(struct mlx5_ib_dev *dev, |
| 1325 | 1302 | struct devx_event_subscription *sub) |
| 1326 | 1303 | { |
| @@ -1362,8 +1339,16 @@ static int devx_obj_cleanup(struct ib_uobject *uobject, · 35 unmodified lines | ||
| 1362 | 1339 | int ret; |
| 1363 | 1340 | |
| 1364 | 1341 | dev = mlx5_udata_to_mdev(&attrs->driver_udata); |
| 1365 | − if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) | |
| 1366 | − devx_cleanup_mkey(obj); | |
| 1342 | + if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) { | |
| 1343 | + /* | |
| 1344 | + * The pagefault_single_data_segment() does commands against | |
| 1345 | + * the mmkey, we must wait for that to stop before freeing the | |
| 1346 | + * mkey, as another allocation could get the same mkey #. | |
| 1347 | + */ | |
| 1348 | + xa_erase(&obj->ib_dev->mdev->priv.mkey_table, | |
| 1349 | + mlx5_base_mkey(obj->devx_mr.mmkey.key)); | |
| 1350 | + synchronize_srcu(&dev->mr_srcu); | |
| 1351 | + } | |
| 1367 | 1352 | |
| 1368 | 1353 | if (obj->flags & DEVX_OBJ_FLAGS_DCT) |
| 1369 | 1354 | ret = mlx5_core_destroy_dct(obj->ib_dev->mdev, &obj->core_dct); |
| @@ -1382,12 +1367,6 @@ static int devx_obj_cleanup(struct ib_uobject *uobject, · 12 unmodified lines | ||
| 1382 | 1367 | devx_cleanup_subscription(dev, sub_entry); |
| 1383 | 1368 | mutex_unlock(&devx_event_table->event_xa_lock); |
| 1384 | 1369 | |
| 1385 | − if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) { | |
| 1386 | − call_srcu(&dev->mr_srcu, &obj->devx_mr.rcu, | |
| 1387 | − devx_free_indirect_mkey); | |
| 1388 | − return ret; | |
| 1389 | − } | |
| 1390 | − | |
| 1391 | 1370 | kfree(obj); |
| 1392 | 1371 | return ret; |
| 1393 | 1372 | } |
| @@ -1491,26 +1470,21 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)( · 97 unmodified lines | ||
| 1491 | 1470 | &obj_id); |
| 1492 | 1471 | WARN_ON(obj->dinlen > MLX5_MAX_DESTROY_INBOX_SIZE_DW * sizeof(u32)); |
| 1493 | 1472 | |
| 1494 | − if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) { | |
| 1495 | − err = devx_handle_mkey_indirect(obj, dev, cmd_in, cmd_out); | |
| 1496 | − if (err) | |
| 1497 | − goto obj_destroy; | |
| 1498 | − } | |
| 1499 | − | |
| 1500 | 1473 | err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len); |
| 1501 | 1474 | if (err) |
| 1502 | − goto err_copy; | |
| 1475 | + goto obj_destroy; | |
| 1503 | 1476 | |
| 1504 | 1477 | if (opcode == MLX5_CMD_OP_CREATE_GENERAL_OBJECT) |
| 1505 | 1478 | obj_type = MLX5_GET(general_obj_in_cmd_hdr, cmd_in, obj_type); |
| 1506 | − | |
| 1507 | 1479 | obj->obj_id = get_enc_obj_id(opcode | obj_type << 16, obj_id); |
| 1508 | 1480 | |
| 1481 | + if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) { | |
| 1482 | + err = devx_handle_mkey_indirect(obj, dev, cmd_in, cmd_out); | |
| 1483 | + if (err) | |
| 1484 | + goto obj_destroy; | |
| 1485 | + } | |
| 1509 | 1486 | return 0; |
| 1510 | 1487 | |
| 1511 | −err_copy: | |
| 1512 | − if (obj->flags & DEVX_OBJ_FLAGS_INDIRECT_MKEY) | |
| 1513 | − devx_cleanup_mkey(obj); | |
| 1514 | 1488 | obj_destroy: |
| 1515 | 1489 | if (obj->flags & DEVX_OBJ_FLAGS_DCT) |
| 1516 | 1490 | mlx5_core_destroy_dct(obj->ib_dev->mdev, &obj->core_dct); |
| @@ -606,7 +606,7 @@ struct mlx5_ib_mr { · 605 unmodified lines | ||
| 606 | 606 | struct mlx5_ib_dev *dev; |
| 607 | 607 | u32 out[MLX5_ST_SZ_DW(create_mkey_out)]; |
| 608 | 608 | struct mlx5_core_sig_ctx *sig; |
| 609 | − int live; | |
| 609 | + unsigned int live; | |
| 610 | 610 | void *descs_alloc; |
| 611 | 611 | int access_flags; /* Needed for rereg MR */ |
| 612 | 612 | |
| @@ -639,7 +639,6 @@ struct mlx5_ib_mw { · 26 unmodified lines | ||
| 639 | 639 | struct mlx5_ib_devx_mr { |
| 640 | 640 | struct mlx5_core_mkey mmkey; |
| 641 | 641 | int ndescs; |
| 642 | − struct rcu_head rcu; | |
| 643 | 642 | }; |
| 644 | 643 | |
| 645 | 644 | struct mlx5_ib_umr_context { |
| @@ -84,32 +84,6 @@ static bool use_umr_mtt_update(struct mlx5_ib_mr *mr, u64 start, u64 length) · 83 unmodified lines | ||
| 84 | 84 | length + (start & (MLX5_ADAPTER_PAGE_SIZE - 1)); |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | −static void update_odp_mr(struct mlx5_ib_mr *mr) | |
| 88 | −{ | |
| 89 | − if (is_odp_mr(mr)) { | |
| 90 | − /* | |
| 91 | − * This barrier prevents the compiler from moving the | |
| 92 | − * setting of umem->odp_data->private to point to our | |
| 93 | − * MR, before reg_umr finished, to ensure that the MR | |
| 94 | − * initialization have finished before starting to | |
| 95 | − * handle invalidations. | |
| 96 | − */ | |
| 97 | − smp_wmb(); | |
| 98 | − to_ib_umem_odp(mr->umem)->private = mr; | |
| 99 | − /* | |
| 100 | − * Make sure we will see the new | |
| 101 | − * umem->odp_data->private value in the invalidation | |
| 102 | − * routines, before we can get page faults on the | |
| 103 | − * MR. Page faults can happen once we put the MR in | |
| 104 | − * the tree, below this line. Without the barrier, | |
| 105 | − * there can be a fault handling and an invalidation | |
| 106 | − * before umem->odp_data->private == mr is visible to | |
| 107 | − * the invalidation handler. | |
| 108 | − */ | |
| 109 | − smp_wmb(); | |
| 110 | − } | |
| 111 | −} | |
| 112 | − | |
| 113 | 87 | static void reg_mr_callback(int status, struct mlx5_async_work *context) |
| 114 | 88 | { |
| 115 | 89 | struct mlx5_ib_mr *mr = |
| @@ -1346,8 +1320,6 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, · 1230 unmodified lines | ||
| 1346 | 1320 | mr->umem = umem; |
| 1347 | 1321 | set_mr_fields(dev, mr, npages, length, access_flags); |
| 1348 | 1322 | |
| 1349 | − update_odp_mr(mr); | |
| 1350 | − | |
| 1351 | 1323 | if (use_umr) { |
| 1352 | 1324 | int update_xlt_flags = MLX5_IB_UPD_XLT_ENABLE; |
| 1353 | 1325 | |
| @@ -1363,10 +1335,12 @@ struct ib_mr *mlx5_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, · 9 unmodified lines | ||
| 1363 | 1335 | } |
| 1364 | 1336 | } |
| 1365 | 1337 | |
| 1366 | − if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) { | |
| 1367 | − mr->live = 1; | |
| 1338 | + if (is_odp_mr(mr)) { | |
| 1339 | + to_ib_umem_odp(mr->umem)->private = mr; | |
| 1368 | 1340 | atomic_set(&mr->num_pending_prefetch, 0); |
| 1369 | 1341 | } |
| 1342 | + if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) | |
| 1343 | + smp_store_release(&mr->live, 1); | |
| 1370 | 1344 | |
| 1371 | 1345 | return &mr->ibmr; |
| 1372 | 1346 | error: |
| @@ -1441,6 +1415,9 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, · 68 unmodified lines | ||
| 1441 | 1415 | if (!mr->umem) |
| 1442 | 1416 | return -EINVAL; |
| 1443 | 1417 | |
| 1418 | + if (is_odp_mr(mr)) | |
| 1419 | + return -EOPNOTSUPP; | |
| 1420 | + | |
| 1444 | 1421 | if (flags & IB_MR_REREG_TRANS) { |
| 1445 | 1422 | addr = virt_addr; |
| 1446 | 1423 | len = length; |
| @@ -1486,8 +1463,6 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, · 39 unmodified lines | ||
| 1486 | 1463 | } |
| 1487 | 1464 | |
| 1488 | 1465 | mr->allocated_from_cache = 0; |
| 1489 | − if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) | |
| 1490 | − mr->live = 1; | |
| 1491 | 1466 | } else { |
| 1492 | 1467 | /* |
| 1493 | 1468 | * Send a UMR WQE |
| @@ -1516,7 +1491,6 @@ int mlx5_ib_rereg_user_mr(struct ib_mr *ib_mr, int flags, u64 start, · 22 unmodified lines | ||
| 1516 | 1491 | |
| 1517 | 1492 | set_mr_fields(dev, mr, npages, len, access_flags); |
| 1518 | 1493 | |
| 1519 | − update_odp_mr(mr); | |
| 1520 | 1494 | return 0; |
| 1521 | 1495 | |
| 1522 | 1496 | err: |
| @@ -1607,15 +1581,16 @@ static void dereg_mr(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr) · 84 unmodified lines | ||
| 1607 | 1581 | /* Prevent new page faults and |
| 1608 | 1582 | * prefetch requests from succeeding |
| 1609 | 1583 | */ |
| 1610 | − mr->live = 0; | |
| 1584 | + WRITE_ONCE(mr->live, 0); | |
| 1585 | + | |
| 1586 | + /* Wait for all running page-fault handlers to finish. */ | |
| 1587 | + synchronize_srcu(&dev->mr_srcu); | |
| 1611 | 1588 | |
| 1612 | 1589 | /* dequeue pending prefetch requests for the mr */ |
| 1613 | 1590 | if (atomic_read(&mr->num_pending_prefetch)) |
| 1614 | 1591 | flush_workqueue(system_unbound_wq); |
| 1615 | 1592 | WARN_ON(atomic_read(&mr->num_pending_prefetch)); |
| 1616 | 1593 | |
| 1617 | − /* Wait for all running page-fault handlers to finish. */ | |
| 1618 | − synchronize_srcu(&dev->mr_srcu); | |
| 1619 | 1594 | /* Destroy all page mappings */ |
| 1620 | 1595 | if (!umem_odp->is_implicit_odp) |
| 1621 | 1596 | mlx5_ib_invalidate_range(umem_odp, |
| @@ -1987,14 +1962,25 @@ free: · 365 unmodified lines | ||
| 1987 | 1962 | |
| 1988 | 1963 | int mlx5_ib_dealloc_mw(struct ib_mw *mw) |
| 1989 | 1964 | { |
| 1965 | + struct mlx5_ib_dev *dev = to_mdev(mw->device); | |
| 1990 | 1966 | struct mlx5_ib_mw *mmw = to_mmw(mw); |
| 1991 | 1967 | int err; |
| 1992 | 1968 | |
| 1993 | − err = mlx5_core_destroy_mkey((to_mdev(mw->device))->mdev, | |
| 1994 | − &mmw->mmkey); | |
| 1995 | − if (!err) | |
| 1996 | − kfree(mmw); | |
| 1997 | − return err; | |
| 1969 | + if (IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING)) { | |
| 1970 | + xa_erase(&dev->mdev->priv.mkey_table, | |
| 1971 | + mlx5_base_mkey(mmw->mmkey.key)); | |
| 1972 | + /* | |
| 1973 | + * pagefault_single_data_segment() may be accessing mmw under | |
| 1974 | + * SRCU if the user bound an ODP MR to this MW. | |
| 1975 | + */ | |
| 1976 | + synchronize_srcu(&dev->mr_srcu); | |
| 1977 | + } | |
| 1978 | + | |
| 1979 | + err = mlx5_core_destroy_mkey(dev->mdev, &mmw->mmkey); | |
| 1980 | + if (err) | |
| 1981 | + return err; | |
| 1982 | + kfree(mmw); | |
| 1983 | + return 0; | |
| 1998 | 1984 | } |
| 1999 | 1985 | |
| 2000 | 1986 | int mlx5_ib_check_mr_status(struct ib_mr *ibmr, u32 check_mask, |
| @@ -178,6 +178,29 @@ void mlx5_odp_populate_klm(struct mlx5_klm *pklm, size_t offset, · 177 unmodified lines | ||
| 178 | 178 | return; |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | + /* | |
| 182 | + * The locking here is pretty subtle. Ideally the implicit children | |
| 183 | + * list would be protected by the umem_mutex, however that is not | |
| 184 | + * possible. Instead this uses a weaker update-then-lock pattern: | |
| 185 | + * | |
| 186 | + * srcu_read_lock() | |
| 187 | + * <change children list> | |
| 188 | + * mutex_lock(umem_mutex) | |
| 189 | + * mlx5_ib_update_xlt() | |
| 190 | + * mutex_unlock(umem_mutex) | |
| 191 | + * destroy lkey | |
| 192 | + * | |
| 193 | + * ie any change the children list must be followed by the locked | |
| 194 | + * update_xlt before destroying. | |
| 195 | + * | |
| 196 | + * The umem_mutex provides the acquire/release semantic needed to make | |
| 197 | + * the children list visible to a racing thread. While SRCU is not | |
| 198 | + * technically required, using it gives consistent use of the SRCU | |
| 199 | + * locking around the children list. | |
| 200 | + */ | |
| 201 | + lockdep_assert_held(&to_ib_umem_odp(mr->umem)->umem_mutex); | |
| 202 | + lockdep_assert_held(&mr->dev->mr_srcu); | |
| 203 | + | |
| 181 | 204 | odp = odp_lookup(offset * MLX5_IMR_MTT_SIZE, |
| 182 | 205 | nentries * MLX5_IMR_MTT_SIZE, mr); |
| 183 | 206 | |
| @@ -202,15 +225,22 @@ static void mr_leaf_free_action(struct work_struct *work) · 18 unmodified lines | ||
| 202 | 225 | struct ib_umem_odp *odp = container_of(work, struct ib_umem_odp, work); |
| 203 | 226 | int idx = ib_umem_start(odp) >> MLX5_IMR_MTT_SHIFT; |
| 204 | 227 | struct mlx5_ib_mr *mr = odp->private, *imr = mr->parent; |
| 228 | + struct ib_umem_odp *odp_imr = to_ib_umem_odp(imr->umem); | |
| 229 | + int srcu_key; | |
| 205 | 230 | |
| 206 | 231 | mr->parent = NULL; |
| 207 | 232 | synchronize_srcu(&mr->dev->mr_srcu); |
| 208 | 233 | |
| 209 | − ib_umem_odp_release(odp); | |
| 210 | − if (imr->live) | |
| 234 | + if (smp_load_acquire(&imr->live)) { | |
| 235 | + srcu_key = srcu_read_lock(&mr->dev->mr_srcu); | |
| 236 | + mutex_lock(&odp_imr->umem_mutex); | |
| 211 | 237 | mlx5_ib_update_xlt(imr, idx, 1, 0, |
| 212 | 238 | MLX5_IB_UPD_XLT_INDIRECT | |
| 213 | 239 | MLX5_IB_UPD_XLT_ATOMIC); |
| 240 | + mutex_unlock(&odp_imr->umem_mutex); | |
| 241 | + srcu_read_unlock(&mr->dev->mr_srcu, srcu_key); | |
| 242 | + } | |
| 243 | + ib_umem_odp_release(odp); | |
| 214 | 244 | mlx5_mr_cache_free(mr->dev, mr); |
| 215 | 245 | |
| 216 | 246 | if (atomic_dec_and_test(&imr->num_leaf_free)) |
| @@ -278,7 +308,6 @@ void mlx5_ib_invalidate_range(struct ib_umem_odp *umem_odp, unsigned long start, · 61 unmodified lines | ||
| 278 | 308 | idx - blk_start_idx + 1, 0, |
| 279 | 309 | MLX5_IB_UPD_XLT_ZAP | |
| 280 | 310 | MLX5_IB_UPD_XLT_ATOMIC); |
| 281 | − mutex_unlock(&umem_odp->umem_mutex); | |
| 282 | 311 | /* |
| 283 | 312 | * We are now sure that the device will not access the |
| 284 | 313 | * memory. We can safely unmap it, and mark it as dirty if |
| @@ -289,10 +318,12 @@ void mlx5_ib_invalidate_range(struct ib_umem_odp *umem_odp, unsigned long start, · 4 unmodified lines | ||
| 289 | 318 | |
| 290 | 319 | if (unlikely(!umem_odp->npages && mr->parent && |
| 291 | 320 | !umem_odp->dying)) { |
| 292 | − WRITE_ONCE(umem_odp->dying, 1); | |
| 321 | + WRITE_ONCE(mr->live, 0); | |
| 322 | + umem_odp->dying = 1; | |
| 293 | 323 | atomic_inc(&mr->parent->num_leaf_free); |
| 294 | 324 | schedule_work(&umem_odp->work); |
| 295 | 325 | } |
| 326 | + mutex_unlock(&umem_odp->umem_mutex); | |
| 296 | 327 | } |
| 297 | 328 | |
| 298 | 329 | void mlx5_ib_internal_fill_odp_caps(struct mlx5_ib_dev *dev) |
| @@ -429,8 +460,6 @@ static struct mlx5_ib_mr *implicit_mr_alloc(struct ib_pd *pd, · 130 unmodified lines | ||
| 429 | 460 | mr->ibmr.lkey = mr->mmkey.key; |
| 430 | 461 | mr->ibmr.rkey = mr->mmkey.key; |
| 431 | 462 | |
| 432 | − mr->live = 1; | |
| 433 | − | |
| 434 | 463 | mlx5_ib_dbg(dev, "key %x dev %p mr %p\n", |
| 435 | 464 | mr->mmkey.key, dev->mdev, mr); |
| 436 | 465 | |
| @@ -484,6 +513,8 @@ next_mr: · 47 unmodified lines | ||
| 484 | 513 | mtt->parent = mr; |
| 485 | 514 | INIT_WORK(&odp->work, mr_leaf_free_action); |
| 486 | 515 | |
| 516 | + smp_store_release(&mtt->live, 1); | |
| 517 | + | |
| 487 | 518 | if (!nentries) |
| 488 | 519 | start_idx = addr >> MLX5_IMR_MTT_SHIFT; |
| 489 | 520 | nentries++; |
| @@ -536,6 +567,7 @@ struct mlx5_ib_mr *mlx5_ib_alloc_implicit_mr(struct mlx5_ib_pd *pd, · 46 unmodified lines | ||
| 536 | 567 | init_waitqueue_head(&imr->q_leaf_free); |
| 537 | 568 | atomic_set(&imr->num_leaf_free, 0); |
| 538 | 569 | atomic_set(&imr->num_pending_prefetch, 0); |
| 570 | + smp_store_release(&imr->live, 1); | |
| 539 | 571 | |
| 540 | 572 | return imr; |
| 541 | 573 | } |
| @@ -555,15 +587,19 @@ void mlx5_ib_free_implicit_mr(struct mlx5_ib_mr *imr) · 13 unmodified lines | ||
| 555 | 587 | if (mr->parent != imr) |
| 556 | 588 | continue; |
| 557 | 589 | |
| 590 | + mutex_lock(&umem_odp->umem_mutex); | |
| 558 | 591 | ib_umem_odp_unmap_dma_pages(umem_odp, ib_umem_start(umem_odp), |
| 559 | 592 | ib_umem_end(umem_odp)); |
| 560 | 593 | |
| 561 | − if (umem_odp->dying) | |
| 594 | + if (umem_odp->dying) { | |
| 595 | + mutex_unlock(&umem_odp->umem_mutex); | |
| 562 | 596 | continue; |
| 597 | + } | |
| 563 | 598 | |
| 564 | − WRITE_ONCE(umem_odp->dying, 1); | |
| 599 | + umem_odp->dying = 1; | |
| 565 | 600 | atomic_inc(&imr->num_leaf_free); |
| 566 | 601 | schedule_work(&umem_odp->work); |
| 602 | + mutex_unlock(&umem_odp->umem_mutex); | |
| 567 | 603 | } |
| 568 | 604 | up_read(&per_mm->umem_rwsem); |
| 569 | 605 | |
| @@ -773,7 +809,7 @@ next_mr: · 203 unmodified lines | ||
| 773 | 809 | switch (mmkey->type) { |
| 774 | 810 | case MLX5_MKEY_MR: |
| 775 | 811 | mr = container_of(mmkey, struct mlx5_ib_mr, mmkey); |
| 776 | − if (!mr->live || !mr->ibmr.pd) { | |
| 812 | + if (!smp_load_acquire(&mr->live) || !mr->ibmr.pd) { | |
| 777 | 813 | mlx5_ib_dbg(dev, "got dead MR\n"); |
| 778 | 814 | ret = -EFAULT; |
| 779 | 815 | goto srcu_unlock; |
| @@ -1641,12 +1677,12 @@ static bool num_pending_prefetch_inc(struct ib_pd *pd, · 861 unmodified lines | ||
| 1641 | 1677 | |
| 1642 | 1678 | mr = container_of(mmkey, struct mlx5_ib_mr, mmkey); |
| 1643 | 1679 | |
| 1644 | − if (mr->ibmr.pd != pd) { | |
| 1680 | + if (!smp_load_acquire(&mr->live)) { | |
| 1645 | 1681 | ret = false; |
| 1646 | 1682 | break; |
| 1647 | 1683 | } |
| 1648 | 1684 | |
| 1649 | − if (!mr->live) { | |
| 1685 | + if (mr->ibmr.pd != pd) { | |
| 1650 | 1686 | ret = false; |
| 1651 | 1687 | break; |
| 1652 | 1688 | } |
| @@ -230,8 +230,6 @@ static void pvrdma_free_srq(struct pvrdma_dev *dev, struct pvrdma_srq *srq) · 229 unmodified lines | ||
| 230 | 230 | |
| 231 | 231 | pvrdma_page_dir_cleanup(dev, &srq->pdir); |
| 232 | 232 | |
| 233 | − kfree(srq); | |
| 234 | − | |
| 235 | 233 | atomic_dec(&dev->num_srqs); |
| 236 | 234 | } |
| 237 | 235 | |
| @@ -182,12 +182,19 @@ void siw_qp_llp_close(struct siw_qp *qp) · 181 unmodified lines | ||
| 182 | 182 | */ |
| 183 | 183 | void siw_qp_llp_write_space(struct sock *sk) |
| 184 | 184 | { |
| 185 | − struct siw_cep *cep = sk_to_cep(sk); | |
| 185 | + struct siw_cep *cep; | |
| 186 | 186 | |
| 187 | − cep->sk_write_space(sk); | |
| 187 | + read_lock(&sk->sk_callback_lock); | |
| 188 | + | |
| 189 | + cep = sk_to_cep(sk); | |
| 190 | + if (cep) { | |
| 191 | + cep->sk_write_space(sk); | |
| 188 | 192 | |
| 189 | − if (!test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) | |
| 190 | − (void)siw_sq_start(cep->qp); | |
| 193 | + if (!test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) | |
| 194 | + (void)siw_sq_start(cep->qp); | |
| 195 | + } | |
| 196 | + | |
| 197 | + read_unlock(&sk->sk_callback_lock); | |
| 191 | 198 | } |
| 192 | 199 | |
| 193 | 200 | static int siw_qp_readq_init(struct siw_qp *qp, int irq_size, int orq_size) |
| @@ -232,10 +232,7 @@ static int da9063_onkey_probe(struct platform_device *pdev) · 231 unmodified lines | ||
| 232 | 232 | onkey->input->phys = onkey->phys; |
| 233 | 233 | onkey->input->dev.parent = &pdev->dev; |
| 234 | 234 | |
| 235 | − if (onkey->key_power) | |
| 236 | − input_set_capability(onkey->input, EV_KEY, KEY_POWER); | |
| 237 | − | |
| 238 | − input_set_capability(onkey->input, EV_KEY, KEY_SLEEP); | |
| 235 | + input_set_capability(onkey->input, EV_KEY, KEY_POWER); | |
| 239 | 236 | |
| 240 | 237 | INIT_DELAYED_WORK(&onkey->work, da9063_poll_on); |
| 241 | 238 | |
| @@ -92,11 +92,18 @@ soc_button_device_create(struct platform_device *pdev, · 91 unmodified lines | ||
| 92 | 92 | continue; |
| 93 | 93 | |
| 94 | 94 | gpio = soc_button_lookup_gpio(&pdev->dev, info->acpi_index); |
| 95 | − if (gpio < 0 && gpio != -ENOENT) { | |
| 96 | − error = gpio; | |
| 97 | − goto err_free_mem; | |
| 98 | − } else if (!gpio_is_valid(gpio)) { | |
| 99 | − /* Skip GPIO if not present */ | |
| 95 | + if (!gpio_is_valid(gpio)) { | |
| 96 | + /* | |
| 97 | + * Skip GPIO if not present. Note we deliberately | |
| 98 | + * ignore -EPROBE_DEFER errors here. On some devices | |
| 99 | + * Intel is using so called virtual GPIOs which are not | |
| 100 | + * GPIOs at all but some way for AML code to check some | |
| 101 | + * random status bits without need a custom opregion. | |
| 102 | + * In some cases the resources table we parse points to | |
| 103 | + * such a virtual GPIO, since these are not real GPIOs | |
| 104 | + * we do not have a driver for these so they will never | |
| 105 | + * show up, therefore we ignore -EPROBE_DEFER. | |
| 106 | + */ | |
| 100 | 107 | continue; |
| 101 | 108 | } |
| 102 | 109 | |
| @@ -1827,31 +1827,6 @@ static int elantech_create_smbus(struct psmouse *psmouse, · 1826 unmodified lines | ||
| 1827 | 1827 | leave_breadcrumbs); |
| 1828 | 1828 | } |
| 1829 | 1829 | |
| 1830 | −static bool elantech_use_host_notify(struct psmouse *psmouse, | |
| 1831 | − struct elantech_device_info *info) | |
| 1832 | −{ | |
| 1833 | − if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) | |
| 1834 | − return true; | |
| 1835 | − | |
| 1836 | − switch (info->bus) { | |
| 1837 | − case ETP_BUS_PS2_ONLY: | |
| 1838 | − /* expected case */ | |
| 1839 | − break; | |
| 1840 | − case ETP_BUS_SMB_HST_NTFY_ONLY: | |
| 1841 | − case ETP_BUS_PS2_SMB_HST_NTFY: | |
| 1842 | − /* SMbus implementation is stable since 2018 */ | |
| 1843 | − if (dmi_get_bios_year() >= 2018) | |
| 1844 | − return true; | |
| 1845 | − /* fall through */ | |
| 1846 | − default: | |
| 1847 | − psmouse_dbg(psmouse, | |
| 1848 | − "Ignoring SMBus bus provider %d\n", info->bus); | |
| 1849 | − break; | |
| 1850 | − } | |
| 1851 | − | |
| 1852 | − return false; | |
| 1853 | −} | |
| 1854 | − | |
| 1855 | 1830 | /** |
| 1856 | 1831 | * elantech_setup_smbus - called once the PS/2 devices are enumerated |
| 1857 | 1832 | * and decides to instantiate a SMBus InterTouch device. |
| @@ -1871,7 +1846,7 @@ static int elantech_setup_smbus(struct psmouse *psmouse, · 13 unmodified lines | ||
| 1871 | 1846 | * i2c_blacklist_pnp_ids. |
| 1872 | 1847 | * Old ICs are up to the user to decide. |
| 1873 | 1848 | */ |
| 1874 | − if (!elantech_use_host_notify(psmouse, info) || | |
| 1849 | + if (!ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version) || | |
| 1875 | 1850 | psmouse_matches_pnp_id(psmouse, i2c_blacklist_pnp_ids)) |
| 1876 | 1851 | return -ENXIO; |
| 1877 | 1852 | } |
| @@ -1891,6 +1866,34 @@ static int elantech_setup_smbus(struct psmouse *psmouse, · 13 unmodified lines | ||
| 1891 | 1866 | return 0; |
| 1892 | 1867 | } |
| 1893 | 1868 | |
| 1869 | +static bool elantech_use_host_notify(struct psmouse *psmouse, | |
| 1870 | + struct elantech_device_info *info) | |
| 1871 | +{ | |
| 1872 | + if (ETP_NEW_IC_SMBUS_HOST_NOTIFY(info->fw_version)) | |
| 1873 | + return true; | |
| 1874 | + | |
| 1875 | + switch (info->bus) { | |
| 1876 | + case ETP_BUS_PS2_ONLY: | |
| 1877 | + /* expected case */ | |
| 1878 | + break; | |
| 1879 | + case ETP_BUS_SMB_ALERT_ONLY: | |
| 1880 | + /* fall-through */ | |
| 1881 | + case ETP_BUS_PS2_SMB_ALERT: | |
| 1882 | + psmouse_dbg(psmouse, "Ignoring SMBus provider through alert protocol.\n"); | |
| 1883 | + break; | |
| 1884 | + case ETP_BUS_SMB_HST_NTFY_ONLY: | |
| 1885 | + /* fall-through */ | |
| 1886 | + case ETP_BUS_PS2_SMB_HST_NTFY: | |
| 1887 | + return true; | |
| 1888 | + default: | |
| 1889 | + psmouse_dbg(psmouse, | |
| 1890 | + "Ignoring SMBus bus provider %d.\n", | |
| 1891 | + info->bus); | |
| 1892 | + } | |
| 1893 | + | |
| 1894 | + return false; | |
| 1895 | +} | |
| 1896 | + | |
| 1894 | 1897 | int elantech_init_smbus(struct psmouse *psmouse) |
| 1895 | 1898 | { |
| 1896 | 1899 | struct elantech_device_info info; |
| @@ -146,7 +146,7 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev) · 145 unmodified lines | ||
| 146 | 146 | } |
| 147 | 147 | |
| 148 | 148 | mutex_lock(&data->irq_mutex); |
| 149 | − bitmap_and(data->irq_status, data->irq_status, data->current_irq_mask, | |
| 149 | + bitmap_and(data->irq_status, data->irq_status, data->fn_irq_bits, | |
| 150 | 150 | data->irq_count); |
| 151 | 151 | /* |
| 152 | 152 | * At this point, irq_status has all bits that are set in the |
| @@ -385,6 +385,8 @@ static int rmi_driver_set_irq_bits(struct rmi_device *rmi_dev, · 232 unmodified lines | ||
| 385 | 385 | bitmap_copy(data->current_irq_mask, data->new_irq_mask, |
| 386 | 386 | data->num_of_irq_regs); |
| 387 | 387 | |
| 388 | + bitmap_or(data->fn_irq_bits, data->fn_irq_bits, mask, data->irq_count); | |
| 389 | + | |
| 388 | 390 | error_unlock: |
| 389 | 391 | mutex_unlock(&data->irq_mutex); |
| 390 | 392 | return error; |
| @@ -398,6 +400,8 @@ static int rmi_driver_clear_irq_bits(struct rmi_device *rmi_dev, · 7 unmodified lines | ||
| 398 | 400 | struct device *dev = &rmi_dev->dev; |
| 399 | 401 | |
| 400 | 402 | mutex_lock(&data->irq_mutex); |
| 403 | + bitmap_andnot(data->fn_irq_bits, | |
| 404 | + data->fn_irq_bits, mask, data->irq_count); | |
| 401 | 405 | bitmap_andnot(data->new_irq_mask, |
| 402 | 406 | data->current_irq_mask, mask, data->irq_count); |
| 403 | 407 | |
| @@ -53,6 +53,7 @@ struct goodix_ts_data { · 52 unmodified lines | ||
| 53 | 53 | const char *cfg_name; |
| 54 | 54 | struct completion firmware_loading_complete; |
| 55 | 55 | unsigned long irq_flags; |
| 56 | + unsigned int contact_size; | |
| 56 | 57 | }; |
| 57 | 58 | |
| 58 | 59 | #define GOODIX_GPIO_INT_NAME "irq" |
| @@ -62,6 +63,7 @@ struct goodix_ts_data { · 3 unmodified lines | ||
| 62 | 63 | #define GOODIX_MAX_WIDTH 4096 |
| 63 | 64 | #define GOODIX_INT_TRIGGER 1 |
| 64 | 65 | #define GOODIX_CONTACT_SIZE 8 |
| 66 | +#define GOODIX_MAX_CONTACT_SIZE 9 | |
| 65 | 67 | #define GOODIX_MAX_CONTACTS 10 |
| 66 | 68 | |
| 67 | 69 | #define GOODIX_CONFIG_MAX_LENGTH 240 |
| @@ -144,6 +146,19 @@ static const struct dmi_system_id rotated_screen[] = { · 76 unmodified lines | ||
| 144 | 146 | {} |
| 145 | 147 | }; |
| 146 | 148 | |
| 149 | +static const struct dmi_system_id nine_bytes_report[] = { | |
| 150 | +#if defined(CONFIG_DMI) && defined(CONFIG_X86) | |
| 151 | + { | |
| 152 | + .ident = "Lenovo YogaBook", | |
| 153 | + /* YB1-X91L/F and YB1-X90L/F */ | |
| 154 | + .matches = { | |
| 155 | + DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9") | |
| 156 | + } | |
| 157 | + }, | |
| 158 | +#endif | |
| 159 | + {} | |
| 160 | +}; | |
| 161 | + | |
| 147 | 162 | /** |
| 148 | 163 | * goodix_i2c_read - read data from a register of the i2c slave device. |
| 149 | 164 | * |
| @@ -249,7 +264,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) · 99 unmodified lines | ||
| 249 | 264 | max_timeout = jiffies + msecs_to_jiffies(GOODIX_BUFFER_STATUS_TIMEOUT); |
| 250 | 265 | do { |
| 251 | 266 | error = goodix_i2c_read(ts->client, GOODIX_READ_COOR_ADDR, |
| 252 | − data, GOODIX_CONTACT_SIZE + 1); | |
| 267 | + data, ts->contact_size + 1); | |
| 253 | 268 | if (error) { |
| 254 | 269 | dev_err(&ts->client->dev, "I2C transfer error: %d\n", |
| 255 | 270 | error); |
| @@ -262,12 +277,12 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) · 6 unmodified lines | ||
| 262 | 277 | return -EPROTO; |
| 263 | 278 | |
| 264 | 279 | if (touch_num > 1) { |
| 265 | − data += 1 + GOODIX_CONTACT_SIZE; | |
| 280 | + data += 1 + ts->contact_size; | |
| 266 | 281 | error = goodix_i2c_read(ts->client, |
| 267 | 282 | GOODIX_READ_COOR_ADDR + |
| 268 | − 1 + GOODIX_CONTACT_SIZE, | |
| 283 | + 1 + ts->contact_size, | |
| 269 | 284 | data, |
| 270 | − GOODIX_CONTACT_SIZE * | |
| 285 | + ts->contact_size * | |
| 271 | 286 | (touch_num - 1)); |
| 272 | 287 | if (error) |
| 273 | 288 | return error; |
| @@ -286,7 +301,7 @@ static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data) · 12 unmodified lines | ||
| 286 | 301 | return 0; |
| 287 | 302 | } |
| 288 | 303 | |
| 289 | −static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) | |
| 304 | +static void goodix_ts_report_touch_8b(struct goodix_ts_data *ts, u8 *coor_data) | |
| 290 | 305 | { |
| 291 | 306 | int id = coor_data[0] & 0x0F; |
| 292 | 307 | int input_x = get_unaligned_le16(&coor_data[1]); |
| @@ -301,6 +316,21 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) · 8 unmodified lines | ||
| 301 | 316 | input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); |
| 302 | 317 | } |
| 303 | 318 | |
| 319 | +static void goodix_ts_report_touch_9b(struct goodix_ts_data *ts, u8 *coor_data) | |
| 320 | +{ | |
| 321 | + int id = coor_data[1] & 0x0F; | |
| 322 | + int input_x = get_unaligned_le16(&coor_data[3]); | |
| 323 | + int input_y = get_unaligned_le16(&coor_data[5]); | |
| 324 | + int input_w = get_unaligned_le16(&coor_data[7]); | |
| 325 | + | |
| 326 | + input_mt_slot(ts->input_dev, id); | |
| 327 | + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, true); | |
| 328 | + touchscreen_report_pos(ts->input_dev, &ts->prop, | |
| 329 | + input_x, input_y, true); | |
| 330 | + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, input_w); | |
| 331 | + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, input_w); | |
| 332 | +} | |
| 333 | + | |
| 304 | 334 | /** |
| 305 | 335 | * goodix_process_events - Process incoming events |
| 306 | 336 | * |
| @@ -311,7 +341,7 @@ static void goodix_ts_report_touch(struct goodix_ts_data *ts, u8 *coor_data) · 4 unmodified lines | ||
| 311 | 341 | */ |
| 312 | 342 | static void goodix_process_events(struct goodix_ts_data *ts) |
| 313 | 343 | { |
| 314 | − u8 point_data[1 + GOODIX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; | |
| 344 | + u8 point_data[1 + GOODIX_MAX_CONTACT_SIZE * GOODIX_MAX_CONTACTS]; | |
| 315 | 345 | int touch_num; |
| 316 | 346 | int i; |
| 317 | 347 | |
| @@ -326,8 +356,12 @@ static void goodix_process_events(struct goodix_ts_data *ts) · 8 unmodified lines | ||
| 326 | 356 | input_report_key(ts->input_dev, KEY_LEFTMETA, point_data[0] & BIT(4)); |
| 327 | 357 | |
| 328 | 358 | for (i = 0; i < touch_num; i++) |
| 329 | − goodix_ts_report_touch(ts, | |
| 330 | − &point_data[1 + GOODIX_CONTACT_SIZE * i]); | |
| 359 | + if (ts->contact_size == 9) | |
| 360 | + goodix_ts_report_touch_9b(ts, | |
| 361 | + &point_data[1 + ts->contact_size * i]); | |
| 362 | + else | |
| 363 | + goodix_ts_report_touch_8b(ts, | |
| 364 | + &point_data[1 + ts->contact_size * i]); | |
| 331 | 365 | |
| 332 | 366 | input_mt_sync_frame(ts->input_dev); |
| 333 | 367 | input_sync(ts->input_dev); |
| @@ -730,6 +764,13 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) · 396 unmodified lines | ||
| 730 | 764 | "Applying '180 degrees rotated screen' quirk\n"); |
| 731 | 765 | } |
| 732 | 766 | |
| 767 | + if (dmi_check_system(nine_bytes_report)) { | |
| 768 | + ts->contact_size = 9; | |
| 769 | + | |
| 770 | + dev_dbg(&ts->client->dev, | |
| 771 | + "Non-standard 9-bytes report format quirk\n"); | |
| 772 | + } | |
| 773 | + | |
| 733 | 774 | error = input_mt_init_slots(ts->input_dev, ts->max_touch_num, |
| 734 | 775 | INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); |
| 735 | 776 | if (error) { |
| @@ -810,6 +851,7 @@ static int goodix_ts_probe(struct i2c_client *client, · 74 unmodified lines | ||
| 810 | 851 | ts->client = client; |
| 811 | 852 | i2c_set_clientdata(client, ts); |
| 812 | 853 | init_completion(&ts->firmware_loading_complete); |
| 854 | + ts->contact_size = GOODIX_CONTACT_SIZE; | |
| 813 | 855 | |
| 814 | 856 | error = goodix_get_gpio_config(ts); |
| 815 | 857 | if (error) |
| @@ -583,7 +583,8 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt) · 582 unmodified lines | ||
| 583 | 583 | retry: |
| 584 | 584 | type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK; |
| 585 | 585 | devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK; |
| 586 | − pasid = PPR_PASID(*(u64 *)&event[0]); | |
| 586 | + pasid = (event[0] & EVENT_DOMID_MASK_HI) | | |
| 587 | + (event[1] & EVENT_DOMID_MASK_LO); | |
| 587 | 588 | flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK; |
| 588 | 589 | address = (u64)(((u64)event[3]) << 32) | event[2]; |
| 589 | 590 | |
| @@ -616,7 +617,7 @@ retry: · 26 unmodified lines | ||
| 616 | 617 | address, flags); |
| 617 | 618 | break; |
| 618 | 619 | case EVENT_TYPE_PAGE_TAB_ERR: |
| 619 | − dev_err(dev, "Event logged [PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x domain=0x%04x address=0x%llx flags=0x%04x]\n", | |
| 620 | + dev_err(dev, "Event logged [PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x pasid=0x%04x address=0x%llx flags=0x%04x]\n", | |
| 620 | 621 | PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid), |
| 621 | 622 | pasid, address, flags); |
| 622 | 623 | break; |
| @@ -1463,6 +1464,7 @@ static void free_pagetable(struct protection_domain *domain) · 840 unmodified lines | ||
| 1463 | 1464 | * to 64 bits. |
| 1464 | 1465 | */ |
| 1465 | 1466 | static bool increase_address_space(struct protection_domain *domain, |
| 1467 | + unsigned long address, | |
| 1466 | 1468 | gfp_t gfp) |
| 1467 | 1469 | { |
| 1468 | 1470 | unsigned long flags; |
| @@ -1471,8 +1473,8 @@ static bool increase_address_space(struct protection_domain *domain, · 2 unmodified lines | ||
| 1471 | 1473 | |
| 1472 | 1474 | spin_lock_irqsave(&domain->lock, flags); |
| 1473 | 1475 | |
| 1474 | − if (WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL)) | |
| 1475 | − /* address space already 64 bit large */ | |
| 1476 | + if (address <= PM_LEVEL_SIZE(domain->mode) || | |
| 1477 | + WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL)) | |
| 1476 | 1478 | goto out; |
| 1477 | 1479 | |
| 1478 | 1480 | pte = (void *)get_zeroed_page(gfp); |
| @@ -1505,7 +1507,7 @@ static u64 *alloc_pte(struct protection_domain *domain, · 26 unmodified lines | ||
| 1505 | 1507 | BUG_ON(!is_power_of_2(page_size)); |
| 1506 | 1508 | |
| 1507 | 1509 | while (address > PM_LEVEL_SIZE(domain->mode)) |
| 1508 | − *updated = increase_address_space(domain, gfp) || *updated; | |
| 1510 | + *updated = increase_address_space(domain, address, gfp) || *updated; | |
| 1509 | 1511 | |
| 1510 | 1512 | level = domain->mode - 1; |
| 1511 | 1513 | pte = &domain->pt_root[PM_LEVEL_INDEX(level, address)]; |
| @@ -130,8 +130,8 @@ · 129 unmodified lines | ||
| 130 | 130 | #define EVENT_TYPE_INV_PPR_REQ 0x9 |
| 131 | 131 | #define EVENT_DEVID_MASK 0xffff |
| 132 | 132 | #define EVENT_DEVID_SHIFT 0 |
| 133 | −#define EVENT_DOMID_MASK 0xffff | |
| 134 | −#define EVENT_DOMID_SHIFT 0 | |
| 133 | +#define EVENT_DOMID_MASK_LO 0xffff | |
| 134 | +#define EVENT_DOMID_MASK_HI 0xf0000 | |
| 135 | 135 | #define EVENT_FLAGS_MASK 0xfff |
| 136 | 136 | #define EVENT_FLAGS_SHIFT 0x10 |
| 137 | 137 | |
| @@ -812,6 +812,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain, · 811 unmodified lines | ||
| 812 | 812 | return 0; |
| 813 | 813 | |
| 814 | 814 | out_clear_smmu: |
| 815 | + __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); | |
| 815 | 816 | smmu_domain->smmu = NULL; |
| 816 | 817 | out_unlock: |
| 817 | 818 | mutex_unlock(&smmu_domain->init_mutex); |
| @@ -166,6 +166,9 @@ · 165 unmodified lines | ||
| 166 | 166 | #define ARM_MALI_LPAE_TTBR_READ_INNER BIT(2) |
| 167 | 167 | #define ARM_MALI_LPAE_TTBR_SHARE_OUTER BIT(4) |
| 168 | 168 | |
| 169 | +#define ARM_MALI_LPAE_MEMATTR_IMP_DEF 0x88ULL | |
| 170 | +#define ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC 0x8DULL | |
| 171 | + | |
| 169 | 172 | /* IOPTE accessors */ |
| 170 | 173 | #define iopte_deref(pte,d) __va(iopte_to_paddr(pte, d)) |
| 171 | 174 | |
| @@ -1015,27 +1018,56 @@ arm_32_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie) · 843 unmodified lines | ||
| 1015 | 1018 | static struct io_pgtable * |
| 1016 | 1019 | arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie) |
| 1017 | 1020 | { |
| 1018 | − struct io_pgtable *iop; | |
| 1021 | + struct arm_lpae_io_pgtable *data; | |
| 1019 | 1022 | |
| 1020 | − if (cfg->ias != 48 || cfg->oas > 40) | |
| 1023 | + /* No quirks for Mali (hopefully) */ | |
| 1024 | + if (cfg->quirks) | |
| 1025 | + return NULL; | |
| 1026 | + | |
| 1027 | + if (cfg->ias > 48 || cfg->oas > 40) | |
| 1021 | 1028 | return NULL; |
| 1022 | 1029 | |
| 1023 | 1030 | cfg->pgsize_bitmap &= (SZ_4K | SZ_2M | SZ_1G); |
| 1024 | − iop = arm_64_lpae_alloc_pgtable_s1(cfg, cookie); | |
| 1025 | − if (iop) { | |
| 1026 | − u64 mair, ttbr; | |
| 1027 | 1031 | |
| 1028 | − /* Copy values as union fields overlap */ | |
| 1029 | − mair = cfg->arm_lpae_s1_cfg.mair[0]; | |
| 1030 | − ttbr = cfg->arm_lpae_s1_cfg.ttbr[0]; | |
| 1032 | + data = arm_lpae_alloc_pgtable(cfg); | |
| 1033 | + if (!data) | |
| 1034 | + return NULL; | |
| 1031 | 1035 | |
| 1032 | − cfg->arm_mali_lpae_cfg.memattr = mair; | |
| 1033 | − cfg->arm_mali_lpae_cfg.transtab = ttbr | | |
| 1034 | − ARM_MALI_LPAE_TTBR_READ_INNER | | |
| 1035 | − ARM_MALI_LPAE_TTBR_ADRMODE_TABLE; | |
| 1036 | + /* Mali seems to need a full 4-level table regardless of IAS */ | |
| 1037 | + if (data->levels < ARM_LPAE_MAX_LEVELS) { | |
| 1038 | + data->levels = ARM_LPAE_MAX_LEVELS; | |
| 1039 | + data->pgd_size = sizeof(arm_lpae_iopte); | |
| 1036 | 1040 | } |
| 1041 | + /* | |
| 1042 | + * MEMATTR: Mali has no actual notion of a non-cacheable type, so the | |
| 1043 | + * best we can do is mimic the out-of-tree driver and hope that the | |
| 1044 | + * "implementation-defined caching policy" is good enough. Similarly, | |
| 1045 | + * we'll use it for the sake of a valid attribute for our 'device' | |
| 1046 | + * index, although callers should never request that in practice. | |
| 1047 | + */ | |
| 1048 | + cfg->arm_mali_lpae_cfg.memattr = | |
| 1049 | + (ARM_MALI_LPAE_MEMATTR_IMP_DEF | |
| 1050 | + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_NC)) | | |
| 1051 | + (ARM_MALI_LPAE_MEMATTR_WRITE_ALLOC | |
| 1052 | + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_CACHE)) | | |
| 1053 | + (ARM_MALI_LPAE_MEMATTR_IMP_DEF | |
| 1054 | + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_DEV)); | |
| 1037 | 1055 | |
| 1038 | − return iop; | |
| 1056 | + data->pgd = __arm_lpae_alloc_pages(data->pgd_size, GFP_KERNEL, cfg); | |
| 1057 | + if (!data->pgd) | |
| 1058 | + goto out_free_data; | |
| 1059 | + | |
| 1060 | + /* Ensure the empty pgd is visible before TRANSTAB can be written */ | |
| 1061 | + wmb(); | |
| 1062 | + | |
| 1063 | + cfg->arm_mali_lpae_cfg.transtab = virt_to_phys(data->pgd) | | |
| 1064 | + ARM_MALI_LPAE_TTBR_READ_INNER | | |
| 1065 | + ARM_MALI_LPAE_TTBR_ADRMODE_TABLE; | |
| 1066 | + return &data->iop; | |
| 1067 | + | |
| 1068 | +out_free_data: | |
| 1069 | + kfree(data); | |
| 1070 | + return NULL; | |
| 1039 | 1071 | } |
| 1040 | 1072 | |
| 1041 | 1073 | struct io_pgtable_init_fns io_pgtable_arm_64_lpae_s1_init_fns = { |
| @@ -1086,8 +1086,6 @@ static int ipmmu_probe(struct platform_device *pdev) · 1085 unmodified lines | ||
| 1086 | 1086 | |
| 1087 | 1087 | mmu->num_ctx = min(IPMMU_CTX_MAX, mmu->features->number_of_contexts); |
| 1088 | 1088 | |
| 1089 | − irq = platform_get_irq(pdev, 0); | |
| 1090 | − | |
| 1091 | 1089 | /* |
| 1092 | 1090 | * Determine if this IPMMU instance is a root device by checking for |
| 1093 | 1091 | * the lack of has_cache_leaf_nodes flag or renesas,ipmmu-main property. |
| @@ -1106,6 +1104,7 @@ static int ipmmu_probe(struct platform_device *pdev) · 12 unmodified lines | ||
| 1106 | 1104 | |
| 1107 | 1105 | /* Root devices have mandatory IRQs */ |
| 1108 | 1106 | if (ipmmu_is_root(mmu)) { |
| 1107 | + irq = platform_get_irq(pdev, 0); | |
| 1109 | 1108 | if (irq < 0) { |
| 1110 | 1109 | dev_err(&pdev->dev, "no IRQ found\n"); |
| 1111 | 1110 | return irq; |
| @@ -100,6 +100,7 @@ struct rk_iommu { · 99 unmodified lines | ||
| 100 | 100 | struct device *dev; |
| 101 | 101 | void __iomem **bases; |
| 102 | 102 | int num_mmu; |
| 103 | + int num_irq; | |
| 103 | 104 | struct clk_bulk_data *clocks; |
| 104 | 105 | int num_clocks; |
| 105 | 106 | bool reset_disabled; |
| @@ -1136,7 +1137,7 @@ static int rk_iommu_probe(struct platform_device *pdev) · 1030 unmodified lines | ||
| 1136 | 1137 | struct rk_iommu *iommu; |
| 1137 | 1138 | struct resource *res; |
| 1138 | 1139 | int num_res = pdev->num_resources; |
| 1139 | − int err, i, irq; | |
| 1140 | + int err, i; | |
| 1140 | 1141 | |
| 1141 | 1142 | iommu = devm_kzalloc(dev, sizeof(*iommu), GFP_KERNEL); |
| 1142 | 1143 | if (!iommu) |
| @@ -1163,6 +1164,10 @@ static int rk_iommu_probe(struct platform_device *pdev) · 20 unmodified lines | ||
| 1163 | 1164 | if (iommu->num_mmu == 0) |
| 1164 | 1165 | return PTR_ERR(iommu->bases[0]); |
| 1165 | 1166 | |
| 1167 | + iommu->num_irq = platform_irq_count(pdev); | |
| 1168 | + if (iommu->num_irq < 0) | |
| 1169 | + return iommu->num_irq; | |
| 1170 | + | |
| 1166 | 1171 | iommu->reset_disabled = device_property_read_bool(dev, |
| 1167 | 1172 | "rockchip,disable-mmu-reset"); |
| 1168 | 1173 | |
| @@ -1219,8 +1224,9 @@ static int rk_iommu_probe(struct platform_device *pdev) · 50 unmodified lines | ||
| 1219 | 1224 | |
| 1220 | 1225 | pm_runtime_enable(dev); |
| 1221 | 1226 | |
| 1222 | − i = 0; | |
| 1223 | − while ((irq = platform_get_irq(pdev, i++)) != -ENXIO) { | |
| 1227 | + for (i = 0; i < iommu->num_irq; i++) { | |
| 1228 | + int irq = platform_get_irq(pdev, i); | |
| 1229 | + | |
| 1224 | 1230 | if (irq < 0) |
| 1225 | 1231 | return irq; |
| 1226 | 1232 | |
| @@ -1245,10 +1251,13 @@ err_unprepare_clocks: · 18 unmodified lines | ||
| 1245 | 1251 | static void rk_iommu_shutdown(struct platform_device *pdev) |
| 1246 | 1252 | { |
| 1247 | 1253 | struct rk_iommu *iommu = platform_get_drvdata(pdev); |
| 1248 | − int i = 0, irq; | |
| 1254 | + int i; | |
| 1255 | + | |
| 1256 | + for (i = 0; i < iommu->num_irq; i++) { | |
| 1257 | + int irq = platform_get_irq(pdev, i); | |
| 1249 | 1258 | |
| 1250 | − while ((irq = platform_get_irq(pdev, i++)) != -ENXIO) | |
| 1251 | 1259 | devm_free_irq(iommu->dev, irq, iommu); |
| 1260 | + } | |
| 1252 | 1261 | |
| 1253 | 1262 | pm_runtime_force_suspend(&pdev->dev); |
| 1254 | 1263 | } |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | |
| 16 | 16 | /* FIC Registers */ |
| 17 | 17 | #define AL_FIC_CAUSE 0x00 |
| 18 | +#define AL_FIC_SET_CAUSE 0x08 | |
| 18 | 19 | #define AL_FIC_MASK 0x10 |
| 19 | 20 | #define AL_FIC_CONTROL 0x28 |
| 20 | 21 | |
| @@ -126,6 +127,16 @@ static void al_fic_irq_handler(struct irq_desc *desc) · 105 unmodified lines | ||
| 126 | 127 | chained_irq_exit(irqchip, desc); |
| 127 | 128 | } |
| 128 | 129 | |
| 130 | +static int al_fic_irq_retrigger(struct irq_data *data) | |
| 131 | +{ | |
| 132 | + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); | |
| 133 | + struct al_fic *fic = gc->private; | |
| 134 | + | |
| 135 | + writel_relaxed(BIT(data->hwirq), fic->base + AL_FIC_SET_CAUSE); | |
| 136 | + | |
| 137 | + return 1; | |
| 138 | +} | |
| 139 | + | |
| 129 | 140 | static int al_fic_register(struct device_node *node, |
| 130 | 141 | struct al_fic *fic) |
| 131 | 142 | { |
| @@ -159,6 +170,7 @@ static int al_fic_register(struct device_node *node, · 27 unmodified lines | ||
| 159 | 170 | gc->chip_types->chip.irq_unmask = irq_gc_mask_clr_bit; |
| 160 | 171 | gc->chip_types->chip.irq_ack = irq_gc_ack_clr_bit; |
| 161 | 172 | gc->chip_types->chip.irq_set_type = al_fic_irq_set_type; |
| 173 | + gc->chip_types->chip.irq_retrigger = al_fic_irq_retrigger; | |
| 162 | 174 | gc->chip_types->chip.flags = IRQCHIP_SKIP_SET_WAKE; |
| 163 | 175 | gc->private = fic; |
| 164 | 176 | |
| @@ -313,6 +313,7 @@ static void __init sama5d3_aic_irq_fixup(void) · 312 unmodified lines | ||
| 313 | 313 | static const struct of_device_id aic5_irq_fixups[] __initconst = { |
| 314 | 314 | { .compatible = "atmel,sama5d3", .data = sama5d3_aic_irq_fixup }, |
| 315 | 315 | { .compatible = "atmel,sama5d4", .data = sama5d3_aic_irq_fixup }, |
| 316 | + { .compatible = "microchip,sam9x60", .data = sama5d3_aic_irq_fixup }, | |
| 316 | 317 | { /* sentinel */ }, |
| 317 | 318 | }; |
| 318 | 319 | |
| @@ -390,3 +391,12 @@ static int __init sama5d4_aic5_of_init(struct device_node *node, · 71 unmodified lines | ||
| 390 | 391 | return aic5_of_init(node, parent, NR_SAMA5D4_IRQS); |
| 391 | 392 | } |
| 392 | 393 | IRQCHIP_DECLARE(sama5d4_aic5, "atmel,sama5d4-aic", sama5d4_aic5_of_init); |
| 394 | + | |
| 395 | +#define NR_SAM9X60_IRQS 50 | |
| 396 | + | |
| 397 | +static int __init sam9x60_aic5_of_init(struct device_node *node, | |
| 398 | + struct device_node *parent) | |
| 399 | +{ | |
| 400 | + return aic5_of_init(node, parent, NR_SAM9X60_IRQS); | |
| 401 | +} | |
| 402 | +IRQCHIP_DECLARE(sam9x60_aic5, "microchip,sam9x60-aic", sam9x60_aic5_of_init); | |
| @@ -59,7 +59,7 @@ static struct gic_chip_data gic_data __read_mostly; · 58 unmodified lines | ||
| 59 | 59 | static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); |
| 60 | 60 | |
| 61 | 61 | #define GIC_ID_NR (1U << GICD_TYPER_ID_BITS(gic_data.rdists.gicd_typer)) |
| 62 | −#define GIC_LINE_NR max(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U) | |
| 62 | +#define GIC_LINE_NR min(GICD_TYPER_SPIS(gic_data.rdists.gicd_typer), 1020U) | |
| 63 | 63 | #define GIC_ESPI_NR GICD_TYPER_ESPIS(gic_data.rdists.gicd_typer) |
| 64 | 64 | |
| 65 | 65 | /* |
| @@ -97,7 +97,7 @@ static inline void plic_irq_toggle(const struct cpumask *mask, · 96 unmodified lines | ||
| 97 | 97 | } |
| 98 | 98 | } |
| 99 | 99 | |
| 100 | −static void plic_irq_enable(struct irq_data *d) | |
| 100 | +static void plic_irq_unmask(struct irq_data *d) | |
| 101 | 101 | { |
| 102 | 102 | unsigned int cpu = cpumask_any_and(irq_data_get_affinity_mask(d), |
| 103 | 103 | cpu_online_mask); |
| @@ -106,7 +106,7 @@ static void plic_irq_enable(struct irq_data *d) · 2 unmodified lines | ||
| 106 | 106 | plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | −static void plic_irq_disable(struct irq_data *d) | |
| 109 | +static void plic_irq_mask(struct irq_data *d) | |
| 110 | 110 | { |
| 111 | 111 | plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); |
| 112 | 112 | } |
| @@ -125,10 +125,8 @@ static int plic_set_affinity(struct irq_data *d, · 12 unmodified lines | ||
| 125 | 125 | if (cpu >= nr_cpu_ids) |
| 126 | 126 | return -EINVAL; |
| 127 | 127 | |
| 128 | − if (!irqd_irq_disabled(d)) { | |
| 129 | − plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); | |
| 130 | − plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); | |
| 131 | − } | |
| 128 | + plic_irq_toggle(cpu_possible_mask, d->hwirq, 0); | |
| 129 | + plic_irq_toggle(cpumask_of(cpu), d->hwirq, 1); | |
| 132 | 130 | |
| 133 | 131 | irq_data_update_effective_affinity(d, cpumask_of(cpu)); |
| 134 | 132 | |
| @@ -136,14 +134,18 @@ static int plic_set_affinity(struct irq_data *d, · 1 unmodified line | ||
| 136 | 134 | } |
| 137 | 135 | #endif |
| 138 | 136 | |
| 137 | +static void plic_irq_eoi(struct irq_data *d) | |
| 138 | +{ | |
| 139 | + struct plic_handler *handler = this_cpu_ptr(&plic_handlers); | |
| 140 | + | |
| 141 | + writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); | |
| 142 | +} | |
| 143 | + | |
| 139 | 144 | static struct irq_chip plic_chip = { |
| 140 | 145 | .name = "SiFive PLIC", |
| 141 | − /* | |
| 142 | − * There is no need to mask/unmask PLIC interrupts. They are "masked" | |
| 143 | − * by reading claim and "unmasked" when writing it back. | |
| 144 | − */ | |
| 145 | − .irq_enable = plic_irq_enable, | |
| 146 | − .irq_disable = plic_irq_disable, | |
| 146 | + .irq_mask = plic_irq_mask, | |
| 147 | + .irq_unmask = plic_irq_unmask, | |
| 148 | + .irq_eoi = plic_irq_eoi, | |
| 147 | 149 | #ifdef CONFIG_SMP |
| 148 | 150 | .irq_set_affinity = plic_set_affinity, |
| 149 | 151 | #endif |
| @@ -152,7 +154,7 @@ static struct irq_chip plic_chip = { · 2 unmodified lines | ||
| 152 | 154 | static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq, |
| 153 | 155 | irq_hw_number_t hwirq) |
| 154 | 156 | { |
| 155 | − irq_set_chip_and_handler(irq, &plic_chip, handle_simple_irq); | |
| 157 | + irq_set_chip_and_handler(irq, &plic_chip, handle_fasteoi_irq); | |
| 156 | 158 | irq_set_chip_data(irq, NULL); |
| 157 | 159 | irq_set_noprobe(irq); |
| 158 | 160 | return 0; |
| @@ -188,7 +190,6 @@ static void plic_handle_irq(struct pt_regs *regs) · 29 unmodified lines | ||
| 188 | 190 | hwirq); |
| 189 | 191 | else |
| 190 | 192 | generic_handle_irq(irq); |
| 191 | − writel(hwirq, claim); | |
| 192 | 193 | } |
| 193 | 194 | csr_set(sie, SIE_SEIE); |
| 194 | 195 | } |
| @@ -542,7 +542,7 @@ static void wake_migration_worker(struct cache *cache) · 541 unmodified lines | ||
| 542 | 542 | |
| 543 | 543 | static struct dm_bio_prison_cell_v2 *alloc_prison_cell(struct cache *cache) |
| 544 | 544 | { |
| 545 | − return dm_bio_prison_alloc_cell_v2(cache->prison, GFP_NOWAIT); | |
| 545 | + return dm_bio_prison_alloc_cell_v2(cache->prison, GFP_NOIO); | |
| 546 | 546 | } |
| 547 | 547 | |
| 548 | 548 | static void free_prison_cell(struct cache *cache, struct dm_bio_prison_cell_v2 *cell) |
| @@ -554,9 +554,7 @@ static struct dm_cache_migration *alloc_migration(struct cache *cache) · 5 unmodified lines | ||
| 554 | 554 | { |
| 555 | 555 | struct dm_cache_migration *mg; |
| 556 | 556 | |
| 557 | − mg = mempool_alloc(&cache->migration_pool, GFP_NOWAIT); | |
| 558 | − if (!mg) | |
| 559 | − return NULL; | |
| 557 | + mg = mempool_alloc(&cache->migration_pool, GFP_NOIO); | |
| 560 | 558 | |
| 561 | 559 | memset(mg, 0, sizeof(*mg)); |
| 562 | 560 | |
| @@ -664,10 +662,6 @@ static bool bio_detain_shared(struct cache *cache, dm_oblock_t oblock, struct bi · 101 unmodified lines | ||
| 664 | 662 | struct dm_bio_prison_cell_v2 *cell_prealloc, *cell; |
| 665 | 663 | |
| 666 | 664 | cell_prealloc = alloc_prison_cell(cache); /* FIXME: allow wait if calling from worker */ |
| 667 | − if (!cell_prealloc) { | |
| 668 | − defer_bio(cache, bio); | |
| 669 | − return false; | |
| 670 | − } | |
| 671 | 665 | |
| 672 | 666 | build_key(oblock, end, &key); |
| 673 | 667 | r = dm_cell_get_v2(cache->prison, &key, lock_level(bio), bio, cell_prealloc, &cell); |
| @@ -1493,11 +1487,6 @@ static int mg_lock_writes(struct dm_cache_migration *mg) · 819 unmodified lines | ||
| 1493 | 1487 | struct dm_bio_prison_cell_v2 *prealloc; |
| 1494 | 1488 | |
| 1495 | 1489 | prealloc = alloc_prison_cell(cache); |
| 1496 | − if (!prealloc) { | |
| 1497 | − DMERR_LIMIT("%s: alloc_prison_cell failed", cache_device_name(cache)); | |
| 1498 | − mg_complete(mg, false); | |
| 1499 | − return -ENOMEM; | |
| 1500 | − } | |
| 1501 | 1490 | |
| 1502 | 1491 | /* |
| 1503 | 1492 | * Prevent writes to the block, but allow reads to continue. |
| @@ -1535,11 +1524,6 @@ static int mg_start(struct cache *cache, struct policy_work *op, struct bio *bio · 31 unmodified lines | ||
| 1535 | 1524 | } |
| 1536 | 1525 | |
| 1537 | 1526 | mg = alloc_migration(cache); |
| 1538 | − if (!mg) { | |
| 1539 | − policy_complete_background_work(cache->policy, op, false); | |
| 1540 | − background_work_end(cache); | |
| 1541 | − return -ENOMEM; | |
| 1542 | − } | |
| 1543 | 1527 | |
| 1544 | 1528 | mg->op = op; |
| 1545 | 1529 | mg->overwrite_bio = bio; |
| @@ -1628,10 +1612,6 @@ static int invalidate_lock(struct dm_cache_migration *mg) · 82 unmodified lines | ||
| 1628 | 1612 | struct dm_bio_prison_cell_v2 *prealloc; |
| 1629 | 1613 | |
| 1630 | 1614 | prealloc = alloc_prison_cell(cache); |
| 1631 | − if (!prealloc) { | |
| 1632 | − invalidate_complete(mg, false); | |
| 1633 | − return -ENOMEM; | |
| 1634 | − } | |
| 1635 | 1615 | |
| 1636 | 1616 | build_key(mg->invalidate_oblock, oblock_succ(mg->invalidate_oblock), &key); |
| 1637 | 1617 | r = dm_cell_lock_v2(cache->prison, &key, |
| @@ -1669,10 +1649,6 @@ static int invalidate_start(struct cache *cache, dm_cblock_t cblock, · 31 unmodified lines | ||
| 1669 | 1649 | return -EPERM; |
| 1670 | 1650 | |
| 1671 | 1651 | mg = alloc_migration(cache); |
| 1672 | − if (!mg) { | |
| 1673 | − background_work_end(cache); | |
| 1674 | − return -ENOMEM; | |
| 1675 | − } | |
| 1676 | 1652 | |
| 1677 | 1653 | mg->overwrite_bio = bio; |
| 1678 | 1654 | mg->invalidate_cblock = cblock; |
| @@ -591,8 +591,8 @@ static struct hash_table_bucket *get_hash_table_bucket(struct clone *clone, · 590 unmodified lines | ||
| 591 | 591 | * |
| 592 | 592 | * NOTE: Must be called with the bucket lock held |
| 593 | 593 | */ |
| 594 | −struct dm_clone_region_hydration *__hash_find(struct hash_table_bucket *bucket, | |
| 595 | − unsigned long region_nr) | |
| 594 | +static struct dm_clone_region_hydration *__hash_find(struct hash_table_bucket *bucket, | |
| 595 | + unsigned long region_nr) | |
| 596 | 596 | { |
| 597 | 597 | struct dm_clone_region_hydration *hd; |
| 598 | 598 | |
| @@ -18,7 +18,6 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/vmalloc.h> |
| 19 | 19 | #include <linux/log2.h> |
| 20 | 20 | #include <linux/dm-kcopyd.h> |
| 21 | −#include <linux/semaphore.h> | |
| 22 | 21 | |
| 23 | 22 | #include "dm.h" |
| 24 | 23 | |
| @@ -107,8 +106,8 @@ struct dm_snapshot { · 82 unmodified lines | ||
| 107 | 106 | /* The on disk metadata handler */ |
| 108 | 107 | struct dm_exception_store *store; |
| 109 | 108 | |
| 110 | − /* Maximum number of in-flight COW jobs. */ | |
| 111 | − struct semaphore cow_count; | |
| 109 | + unsigned in_progress; | |
| 110 | + struct wait_queue_head in_progress_wait; | |
| 112 | 111 | |
| 113 | 112 | struct dm_kcopyd_client *kcopyd_client; |
| 114 | 113 | |
| @@ -162,8 +161,8 @@ struct dm_snapshot { · 47 unmodified lines | ||
| 162 | 161 | */ |
| 163 | 162 | #define DEFAULT_COW_THRESHOLD 2048 |
| 164 | 163 | |
| 165 | −static int cow_threshold = DEFAULT_COW_THRESHOLD; | |
| 166 | −module_param_named(snapshot_cow_threshold, cow_threshold, int, 0644); | |
| 164 | +static unsigned cow_threshold = DEFAULT_COW_THRESHOLD; | |
| 165 | +module_param_named(snapshot_cow_threshold, cow_threshold, uint, 0644); | |
| 167 | 166 | MODULE_PARM_DESC(snapshot_cow_threshold, "Maximum number of chunks being copied on write"); |
| 168 | 167 | |
| 169 | 168 | DECLARE_DM_KCOPYD_THROTTLE_WITH_MODULE_PARM(snapshot_copy_throttle, |
| @@ -1327,7 +1326,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) · 1157 unmodified lines | ||
| 1327 | 1326 | goto bad_hash_tables; |
| 1328 | 1327 | } |
| 1329 | 1328 | |
| 1330 | − sema_init(&s->cow_count, (cow_threshold > 0) ? cow_threshold : INT_MAX); | |
| 1329 | + init_waitqueue_head(&s->in_progress_wait); | |
| 1331 | 1330 | |
| 1332 | 1331 | s->kcopyd_client = dm_kcopyd_client_create(&dm_kcopyd_throttle); |
| 1333 | 1332 | if (IS_ERR(s->kcopyd_client)) { |
| @@ -1509,9 +1508,56 @@ static void snapshot_dtr(struct dm_target *ti) · 175 unmodified lines | ||
| 1509 | 1508 | |
| 1510 | 1509 | dm_put_device(ti, s->origin); |
| 1511 | 1510 | |
| 1511 | + WARN_ON(s->in_progress); | |
| 1512 | + | |
| 1512 | 1513 | kfree(s); |
| 1513 | 1514 | } |
| 1514 | 1515 | |
| 1516 | +static void account_start_copy(struct dm_snapshot *s) | |
| 1517 | +{ | |
| 1518 | + spin_lock(&s->in_progress_wait.lock); | |
| 1519 | + s->in_progress++; | |
| 1520 | + spin_unlock(&s->in_progress_wait.lock); | |
| 1521 | +} | |
| 1522 | + | |
| 1523 | +static void account_end_copy(struct dm_snapshot *s) | |
| 1524 | +{ | |
| 1525 | + spin_lock(&s->in_progress_wait.lock); | |
| 1526 | + BUG_ON(!s->in_progress); | |
| 1527 | + s->in_progress--; | |
| 1528 | + if (likely(s->in_progress <= cow_threshold) && | |
| 1529 | + unlikely(waitqueue_active(&s->in_progress_wait))) | |
| 1530 | + wake_up_locked(&s->in_progress_wait); | |
| 1531 | + spin_unlock(&s->in_progress_wait.lock); | |
| 1532 | +} | |
| 1533 | + | |
| 1534 | +static bool wait_for_in_progress(struct dm_snapshot *s, bool unlock_origins) | |
| 1535 | +{ | |
| 1536 | + if (unlikely(s->in_progress > cow_threshold)) { | |
| 1537 | + spin_lock(&s->in_progress_wait.lock); | |
| 1538 | + if (likely(s->in_progress > cow_threshold)) { | |
| 1539 | + /* | |
| 1540 | + * NOTE: this throttle doesn't account for whether | |
| 1541 | + * the caller is servicing an IO that will trigger a COW | |
| 1542 | + * so excess throttling may result for chunks not required | |
| 1543 | + * to be COW'd. But if cow_threshold was reached, extra | |
| 1544 | + * throttling is unlikely to negatively impact performance. | |
| 1545 | + */ | |
| 1546 | + DECLARE_WAITQUEUE(wait, current); | |
| 1547 | + __add_wait_queue(&s->in_progress_wait, &wait); | |
| 1548 | + __set_current_state(TASK_UNINTERRUPTIBLE); | |
| 1549 | + spin_unlock(&s->in_progress_wait.lock); | |
| 1550 | + if (unlock_origins) | |
| 1551 | + up_read(&_origins_lock); | |
| 1552 | + io_schedule(); | |
| 1553 | + remove_wait_queue(&s->in_progress_wait, &wait); | |
| 1554 | + return false; | |
| 1555 | + } | |
| 1556 | + spin_unlock(&s->in_progress_wait.lock); | |
| 1557 | + } | |
| 1558 | + return true; | |
| 1559 | +} | |
| 1560 | + | |
| 1515 | 1561 | /* |
| 1516 | 1562 | * Flush a list of buffers. |
| 1517 | 1563 | */ |
| @@ -1527,7 +1573,7 @@ static void flush_bios(struct bio *bio) · 9 unmodified lines | ||
| 1527 | 1573 | } |
| 1528 | 1574 | } |
| 1529 | 1575 | |
| 1530 | −static int do_origin(struct dm_dev *origin, struct bio *bio); | |
| 1576 | +static int do_origin(struct dm_dev *origin, struct bio *bio, bool limit); | |
| 1531 | 1577 | |
| 1532 | 1578 | /* |
| 1533 | 1579 | * Flush a list of buffers. |
| @@ -1540,7 +1586,7 @@ static void retry_origin_bios(struct dm_snapshot *s, struct bio *bio) · 6 unmodified lines | ||
| 1540 | 1586 | while (bio) { |
| 1541 | 1587 | n = bio->bi_next; |
| 1542 | 1588 | bio->bi_next = NULL; |
| 1543 | − r = do_origin(s->origin, bio); | |
| 1589 | + r = do_origin(s->origin, bio, false); | |
| 1544 | 1590 | if (r == DM_MAPIO_REMAPPED) |
| 1545 | 1591 | generic_make_request(bio); |
| 1546 | 1592 | bio = n; |
| @@ -1732,7 +1778,7 @@ static void copy_callback(int read_err, unsigned long write_err, void *context) · 185 unmodified lines | ||
| 1732 | 1778 | rb_link_node(&pe->out_of_order_node, parent, p); |
| 1733 | 1779 | rb_insert_color(&pe->out_of_order_node, &s->out_of_order_tree); |
| 1734 | 1780 | } |
| 1735 | − up(&s->cow_count); | |
| 1781 | + account_end_copy(s); | |
| 1736 | 1782 | } |
| 1737 | 1783 | |
| 1738 | 1784 | /* |
| @@ -1756,7 +1802,7 @@ static void start_copy(struct dm_snap_pending_exception *pe) · 17 unmodified lines | ||
| 1756 | 1802 | dest.count = src.count; |
| 1757 | 1803 | |
| 1758 | 1804 | /* Hand over to kcopyd */ |
| 1759 | − down(&s->cow_count); | |
| 1805 | + account_start_copy(s); | |
| 1760 | 1806 | dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, copy_callback, pe); |
| 1761 | 1807 | } |
| 1762 | 1808 | |
| @@ -1776,7 +1822,7 @@ static void start_full_bio(struct dm_snap_pending_exception *pe, · 13 unmodified lines | ||
| 1776 | 1822 | pe->full_bio = bio; |
| 1777 | 1823 | pe->full_bio_end_io = bio->bi_end_io; |
| 1778 | 1824 | |
| 1779 | − down(&s->cow_count); | |
| 1825 | + account_start_copy(s); | |
| 1780 | 1826 | callback_data = dm_kcopyd_prepare_callback(s->kcopyd_client, |
| 1781 | 1827 | copy_callback, pe); |
| 1782 | 1828 | |
| @@ -1866,7 +1912,7 @@ static void zero_callback(int read_err, unsigned long write_err, void *context) · 83 unmodified lines | ||
| 1866 | 1912 | struct bio *bio = context; |
| 1867 | 1913 | struct dm_snapshot *s = bio->bi_private; |
| 1868 | 1914 | |
| 1869 | − up(&s->cow_count); | |
| 1915 | + account_end_copy(s); | |
| 1870 | 1916 | bio->bi_status = write_err ? BLK_STS_IOERR : 0; |
| 1871 | 1917 | bio_endio(bio); |
| 1872 | 1918 | } |
| @@ -1880,7 +1926,7 @@ static void zero_exception(struct dm_snapshot *s, struct dm_exception *e, · 7 unmodified lines | ||
| 1880 | 1926 | dest.sector = bio->bi_iter.bi_sector; |
| 1881 | 1927 | dest.count = s->store->chunk_size; |
| 1882 | 1928 | |
| 1883 | − down(&s->cow_count); | |
| 1929 | + account_start_copy(s); | |
| 1884 | 1930 | WARN_ON_ONCE(bio->bi_private); |
| 1885 | 1931 | bio->bi_private = s; |
| 1886 | 1932 | dm_kcopyd_zero(s->kcopyd_client, 1, &dest, 0, zero_callback, bio); |
| @@ -1916,6 +1962,11 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio) · 29 unmodified lines | ||
| 1916 | 1962 | if (!s->valid) |
| 1917 | 1963 | return DM_MAPIO_KILL; |
| 1918 | 1964 | |
| 1965 | + if (bio_data_dir(bio) == WRITE) { | |
| 1966 | + while (unlikely(!wait_for_in_progress(s, false))) | |
| 1967 | + ; /* wait_for_in_progress() has slept */ | |
| 1968 | + } | |
| 1969 | + | |
| 1919 | 1970 | down_read(&s->lock); |
| 1920 | 1971 | dm_exception_table_lock(&lock); |
| 1921 | 1972 | |
| @@ -2112,7 +2163,7 @@ redirect_to_origin: · 190 unmodified lines | ||
| 2112 | 2163 | |
| 2113 | 2164 | if (bio_data_dir(bio) == WRITE) { |
| 2114 | 2165 | up_write(&s->lock); |
| 2115 | − return do_origin(s->origin, bio); | |
| 2166 | + return do_origin(s->origin, bio, false); | |
| 2116 | 2167 | } |
| 2117 | 2168 | |
| 2118 | 2169 | out_unlock: |
| @@ -2487,15 +2538,24 @@ next_snapshot: · 368 unmodified lines | ||
| 2487 | 2538 | /* |
| 2488 | 2539 | * Called on a write from the origin driver. |
| 2489 | 2540 | */ |
| 2490 | −static int do_origin(struct dm_dev *origin, struct bio *bio) | |
| 2541 | +static int do_origin(struct dm_dev *origin, struct bio *bio, bool limit) | |
| 2491 | 2542 | { |
| 2492 | 2543 | struct origin *o; |
| 2493 | 2544 | int r = DM_MAPIO_REMAPPED; |
| 2494 | 2545 | |
| 2546 | +again: | |
| 2495 | 2547 | down_read(&_origins_lock); |
| 2496 | 2548 | o = __lookup_origin(origin->bdev); |
| 2497 | − if (o) | |
| 2549 | + if (o) { | |
| 2550 | + if (limit) { | |
| 2551 | + struct dm_snapshot *s; | |
| 2552 | + list_for_each_entry(s, &o->snapshots, list) | |
| 2553 | + if (unlikely(!wait_for_in_progress(s, true))) | |
| 2554 | + goto again; | |
| 2555 | + } | |
| 2556 | + | |
| 2498 | 2557 | r = __origin_write(&o->snapshots, bio->bi_iter.bi_sector, bio); |
| 2558 | + } | |
| 2499 | 2559 | up_read(&_origins_lock); |
| 2500 | 2560 | |
| 2501 | 2561 | return r; |
| @@ -2608,7 +2668,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio) · 106 unmodified lines | ||
| 2608 | 2668 | dm_accept_partial_bio(bio, available_sectors); |
| 2609 | 2669 | |
| 2610 | 2670 | /* Only tell snapshots if this is a write */ |
| 2611 | − return do_origin(o->dev, bio); | |
| 2671 | + return do_origin(o->dev, bio, true); | |
| 2612 | 2672 | } |
| 2613 | 2673 | |
| 2614 | 2674 | /* |
| @@ -154,7 +154,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) · 153 unmodified lines | ||
| 154 | 154 | } else { |
| 155 | 155 | pr_err("md/raid0:%s: cannot assemble multi-zone RAID0 with default_layout setting\n", |
| 156 | 156 | mdname(mddev)); |
| 157 | − pr_err("md/raid0: please set raid.default_layout to 1 or 2\n"); | |
| 157 | + pr_err("md/raid0: please set raid0.default_layout to 1 or 2\n"); | |
| 158 | 158 | err = -ENOTSUPP; |
| 159 | 159 | goto abort; |
| 160 | 160 | } |
| @@ -643,8 +643,7 @@ static int v4l_stk_release(struct file *fp) · 642 unmodified lines | ||
| 643 | 643 | dev->owner = NULL; |
| 644 | 644 | } |
| 645 | 645 | |
| 646 | − if (is_present(dev)) | |
| 647 | − usb_autopm_put_interface(dev->interface); | |
| 646 | + usb_autopm_put_interface(dev->interface); | |
| 648 | 647 | mutex_unlock(&dev->lock); |
| 649 | 648 | return v4l2_fh_release(fp); |
| 650 | 649 | } |
| @@ -941,7 +941,7 @@ static int jmb38x_ms_probe(struct pci_dev *pdev, · 940 unmodified lines | ||
| 941 | 941 | if (!cnt) { |
| 942 | 942 | rc = -ENODEV; |
| 943 | 943 | pci_dev_busy = 1; |
| 944 | − goto err_out; | |
| 944 | + goto err_out_int; | |
| 945 | 945 | } |
| 946 | 946 | |
| 947 | 947 | jm = kzalloc(sizeof(struct jmb38x_ms) |
| @@ -527,6 +527,7 @@ static int fastrpc_dma_buf_attach(struct dma_buf *dmabuf, · 526 unmodified lines | ||
| 527 | 527 | FASTRPC_PHYS(buffer->phys), buffer->size); |
| 528 | 528 | if (ret < 0) { |
| 529 | 529 | dev_err(buffer->dev, "failed to get scatterlist from DMA API\n"); |
| 530 | + kfree(a); | |
| 530 | 531 | return -EINVAL; |
| 531 | 532 | } |
| 532 | 533 | |
| @@ -218,13 +218,21 @@ static void mei_mkhi_fix(struct mei_cl_device *cldev) · 217 unmodified lines | ||
| 218 | 218 | { |
| 219 | 219 | int ret; |
| 220 | 220 | |
| 221 | + /* No need to enable the client if nothing is needed from it */ | |
| 222 | + if (!cldev->bus->fw_f_fw_ver_supported && | |
| 223 | + !cldev->bus->hbm_f_os_supported) | |
| 224 | + return; | |
| 225 | + | |
| 221 | 226 | ret = mei_cldev_enable(cldev); |
| 222 | 227 | if (ret) |
| 223 | 228 | return; |
| 224 | 229 | |
| 225 | − ret = mei_fwver(cldev); | |
| 226 | − if (ret < 0) | |
| 227 | − dev_err(&cldev->dev, "FW version command failed %d\n", ret); | |
| 230 | + if (cldev->bus->fw_f_fw_ver_supported) { | |
| 231 | + ret = mei_fwver(cldev); | |
| 232 | + if (ret < 0) | |
| 233 | + dev_err(&cldev->dev, "FW version command failed %d\n", | |
| 234 | + ret); | |
| 235 | + } | |
| 228 | 236 | |
| 229 | 237 | if (cldev->bus->hbm_f_os_supported) { |
| 230 | 238 | ret = mei_osver(cldev); |
| @@ -79,6 +79,9 @@ · 78 unmodified lines | ||
| 79 | 79 | #define MEI_DEV_ID_CNP_H 0xA360 /* Cannon Point H */ |
| 80 | 80 | #define MEI_DEV_ID_CNP_H_4 0xA364 /* Cannon Point H 4 (iTouch) */ |
| 81 | 81 | |
| 82 | +#define MEI_DEV_ID_CMP_LP 0x02e0 /* Comet Point LP */ | |
| 83 | +#define MEI_DEV_ID_CMP_LP_3 0x02e4 /* Comet Point LP 3 (iTouch) */ | |
| 84 | + | |
| 82 | 85 | #define MEI_DEV_ID_ICP_LP 0x34E0 /* Ice Lake Point LP */ |
| 83 | 86 | |
| 84 | 87 | #define MEI_DEV_ID_TGP_LP 0xA0E0 /* Tiger Lake Point LP */ |
| @@ -1355,6 +1355,8 @@ static bool mei_me_fw_type_sps(struct pci_dev *pdev) · 1354 unmodified lines | ||
| 1355 | 1355 | #define MEI_CFG_FW_SPS \ |
| 1356 | 1356 | .quirk_probe = mei_me_fw_type_sps |
| 1357 | 1357 | |
| 1358 | +#define MEI_CFG_FW_VER_SUPP \ | |
| 1359 | + .fw_ver_supported = 1 | |
| 1358 | 1360 | |
| 1359 | 1361 | #define MEI_CFG_ICH_HFS \ |
| 1360 | 1362 | .fw_status.count = 0 |
| @@ -1392,31 +1394,41 @@ static const struct mei_cfg mei_me_ich10_cfg = { · 31 unmodified lines | ||
| 1392 | 1394 | MEI_CFG_ICH10_HFS, |
| 1393 | 1395 | }; |
| 1394 | 1396 | |
| 1395 | −/* PCH devices */ | |
| 1396 | −static const struct mei_cfg mei_me_pch_cfg = { | |
| 1397 | +/* PCH6 devices */ | |
| 1398 | +static const struct mei_cfg mei_me_pch6_cfg = { | |
| 1397 | 1399 | MEI_CFG_PCH_HFS, |
| 1398 | 1400 | }; |
| 1399 | 1401 | |
| 1402 | +/* PCH7 devices */ | |
| 1403 | +static const struct mei_cfg mei_me_pch7_cfg = { | |
| 1404 | + MEI_CFG_PCH_HFS, | |
| 1405 | + MEI_CFG_FW_VER_SUPP, | |
| 1406 | +}; | |
| 1407 | + | |
| 1400 | 1408 | /* PCH Cougar Point and Patsburg with quirk for Node Manager exclusion */ |
| 1401 | 1409 | static const struct mei_cfg mei_me_pch_cpt_pbg_cfg = { |
| 1402 | 1410 | MEI_CFG_PCH_HFS, |
| 1411 | + MEI_CFG_FW_VER_SUPP, | |
| 1403 | 1412 | MEI_CFG_FW_NM, |
| 1404 | 1413 | }; |
| 1405 | 1414 | |
| 1406 | 1415 | /* PCH8 Lynx Point and newer devices */ |
| 1407 | 1416 | static const struct mei_cfg mei_me_pch8_cfg = { |
| 1408 | 1417 | MEI_CFG_PCH8_HFS, |
| 1418 | + MEI_CFG_FW_VER_SUPP, | |
| 1409 | 1419 | }; |
| 1410 | 1420 | |
| 1411 | 1421 | /* PCH8 Lynx Point with quirk for SPS Firmware exclusion */ |
| 1412 | 1422 | static const struct mei_cfg mei_me_pch8_sps_cfg = { |
| 1413 | 1423 | MEI_CFG_PCH8_HFS, |
| 1424 | + MEI_CFG_FW_VER_SUPP, | |
| 1414 | 1425 | MEI_CFG_FW_SPS, |
| 1415 | 1426 | }; |
| 1416 | 1427 | |
| 1417 | 1428 | /* Cannon Lake and newer devices */ |
| 1418 | 1429 | static const struct mei_cfg mei_me_pch12_cfg = { |
| 1419 | 1430 | MEI_CFG_PCH8_HFS, |
| 1431 | + MEI_CFG_FW_VER_SUPP, | |
| 1420 | 1432 | MEI_CFG_DMA_128, |
| 1421 | 1433 | }; |
| 1422 | 1434 | |
| @@ -1428,7 +1440,8 @@ static const struct mei_cfg *const mei_cfg_list[] = { · 5 unmodified lines | ||
| 1428 | 1440 | [MEI_ME_UNDEF_CFG] = NULL, |
| 1429 | 1441 | [MEI_ME_ICH_CFG] = &mei_me_ich_cfg, |
| 1430 | 1442 | [MEI_ME_ICH10_CFG] = &mei_me_ich10_cfg, |
| 1431 | − [MEI_ME_PCH_CFG] = &mei_me_pch_cfg, | |
| 1443 | + [MEI_ME_PCH6_CFG] = &mei_me_pch6_cfg, | |
| 1444 | + [MEI_ME_PCH7_CFG] = &mei_me_pch7_cfg, | |
| 1432 | 1445 | [MEI_ME_PCH_CPT_PBG_CFG] = &mei_me_pch_cpt_pbg_cfg, |
| 1433 | 1446 | [MEI_ME_PCH8_CFG] = &mei_me_pch8_cfg, |
| 1434 | 1447 | [MEI_ME_PCH8_SPS_CFG] = &mei_me_pch8_sps_cfg, |
| @@ -1473,6 +1486,8 @@ struct mei_device *mei_me_dev_init(struct pci_dev *pdev, · 38 unmodified lines | ||
| 1473 | 1486 | mei_device_init(dev, &pdev->dev, &mei_me_hw_ops); |
| 1474 | 1487 | hw->cfg = cfg; |
| 1475 | 1488 | |
| 1489 | + dev->fw_f_fw_ver_supported = cfg->fw_ver_supported; | |
| 1490 | + | |
| 1476 | 1491 | return dev; |
| 1477 | 1492 | } |
| 1478 | 1493 | |
| @@ -20,11 +20,13 @@ · 19 unmodified lines | ||
| 20 | 20 | * @fw_status: FW status |
| 21 | 21 | * @quirk_probe: device exclusion quirk |
| 22 | 22 | * @dma_size: device DMA buffers size |
| 23 | + * @fw_ver_supported: is fw version retrievable from FW | |
| 23 | 24 | */ |
| 24 | 25 | struct mei_cfg { |
| 25 | 26 | const struct mei_fw_status fw_status; |
| 26 | 27 | bool (*quirk_probe)(struct pci_dev *pdev); |
| 27 | 28 | size_t dma_size[DMA_DSCR_NUM]; |
| 29 | + u32 fw_ver_supported:1; | |
| 28 | 30 | }; |
| 29 | 31 | |
| 30 | 32 | |
| @@ -62,7 +64,8 @@ struct mei_me_hw { · 31 unmodified lines | ||
| 62 | 64 | * @MEI_ME_UNDEF_CFG: Lower sentinel. |
| 63 | 65 | * @MEI_ME_ICH_CFG: I/O Controller Hub legacy devices. |
| 64 | 66 | * @MEI_ME_ICH10_CFG: I/O Controller Hub platforms Gen10 |
| 65 | − * @MEI_ME_PCH_CFG: Platform Controller Hub platforms (Up to Gen8). | |
| 67 | + * @MEI_ME_PCH6_CFG: Platform Controller Hub platforms (Gen6). | |
| 68 | + * @MEI_ME_PCH7_CFG: Platform Controller Hub platforms (Gen7). | |
| 66 | 69 | * @MEI_ME_PCH_CPT_PBG_CFG:Platform Controller Hub workstations |
| 67 | 70 | * with quirk for Node Manager exclusion. |
| 68 | 71 | * @MEI_ME_PCH8_CFG: Platform Controller Hub Gen8 and newer |
| @@ -77,7 +80,8 @@ enum mei_cfg_idx { · 8 unmodified lines | ||
| 77 | 80 | MEI_ME_UNDEF_CFG, |
| 78 | 81 | MEI_ME_ICH_CFG, |
| 79 | 82 | MEI_ME_ICH10_CFG, |
| 80 | − MEI_ME_PCH_CFG, | |
| 83 | + MEI_ME_PCH6_CFG, | |
| 84 | + MEI_ME_PCH7_CFG, | |
| 81 | 85 | MEI_ME_PCH_CPT_PBG_CFG, |
| 82 | 86 | MEI_ME_PCH8_CFG, |
| 83 | 87 | MEI_ME_PCH8_SPS_CFG, |
| @@ -426,6 +426,8 @@ struct mei_fw_version { · 425 unmodified lines | ||
| 426 | 426 | * |
| 427 | 427 | * @fw_ver : FW versions |
| 428 | 428 | * |
| 429 | + * @fw_f_fw_ver_supported : fw feature: fw version supported | |
| 430 | + * | |
| 429 | 431 | * @me_clients_rwsem: rw lock over me_clients list |
| 430 | 432 | * @me_clients : list of FW clients |
| 431 | 433 | * @me_clients_map : FW clients bit map |
| @@ -506,6 +508,8 @@ struct mei_device { · 74 unmodified lines | ||
| 506 | 508 | |
| 507 | 509 | struct mei_fw_version fw_ver[MEI_MAX_FW_VER_BLOCKS]; |
| 508 | 510 | |
| 511 | + unsigned int fw_f_fw_ver_supported:1; | |
| 512 | + | |
| 509 | 513 | struct rw_semaphore me_clients_rwsem; |
| 510 | 514 | struct list_head me_clients; |
| 511 | 515 | DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); |
| @@ -61,13 +61,13 @@ static const struct pci_device_id mei_me_pci_tbl[] = { · 60 unmodified lines | ||
| 61 | 61 | {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_3, MEI_ME_ICH10_CFG)}, |
| 62 | 62 | {MEI_PCI_DEVICE(MEI_DEV_ID_ICH10_4, MEI_ME_ICH10_CFG)}, |
| 63 | 63 | |
| 64 | − {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_1, MEI_ME_PCH_CFG)}, | |
| 65 | − {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_2, MEI_ME_PCH_CFG)}, | |
| 64 | + {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_1, MEI_ME_PCH6_CFG)}, | |
| 65 | + {MEI_PCI_DEVICE(MEI_DEV_ID_IBXPK_2, MEI_ME_PCH6_CFG)}, | |
| 66 | 66 | {MEI_PCI_DEVICE(MEI_DEV_ID_CPT_1, MEI_ME_PCH_CPT_PBG_CFG)}, |
| 67 | 67 | {MEI_PCI_DEVICE(MEI_DEV_ID_PBG_1, MEI_ME_PCH_CPT_PBG_CFG)}, |
| 68 | − {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, MEI_ME_PCH_CFG)}, | |
| 69 | − {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, MEI_ME_PCH_CFG)}, | |
| 70 | − {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, MEI_ME_PCH_CFG)}, | |
| 68 | + {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_1, MEI_ME_PCH7_CFG)}, | |
| 69 | + {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_2, MEI_ME_PCH7_CFG)}, | |
| 70 | + {MEI_PCI_DEVICE(MEI_DEV_ID_PPT_3, MEI_ME_PCH7_CFG)}, | |
| 71 | 71 | {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_H, MEI_ME_PCH8_SPS_CFG)}, |
| 72 | 72 | {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_W, MEI_ME_PCH8_SPS_CFG)}, |
| 73 | 73 | {MEI_PCI_DEVICE(MEI_DEV_ID_LPT_LP, MEI_ME_PCH8_CFG)}, |
| @@ -96,6 +96,9 @@ static const struct pci_device_id mei_me_pci_tbl[] = { · 22 unmodified lines | ||
| 96 | 96 | {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H, MEI_ME_PCH12_CFG)}, |
| 97 | 97 | {MEI_PCI_DEVICE(MEI_DEV_ID_CNP_H_4, MEI_ME_PCH8_CFG)}, |
| 98 | 98 | |
| 99 | + {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP, MEI_ME_PCH12_CFG)}, | |
| 100 | + {MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP_3, MEI_ME_PCH8_CFG)}, | |
| 101 | + | |
| 99 | 102 | {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)}, |
| 100 | 103 | |
| 101 | 104 | {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH12_CFG)}, |
| @@ -646,8 +646,8 @@ int renesas_sdhi_probe(struct platform_device *pdev, · 645 unmodified lines | ||
| 646 | 646 | struct tmio_mmc_dma *dma_priv; |
| 647 | 647 | struct tmio_mmc_host *host; |
| 648 | 648 | struct renesas_sdhi *priv; |
| 649 | + int num_irqs, irq, ret, i; | |
| 649 | 650 | struct resource *res; |
| 650 | − int irq, ret, i; | |
| 651 | 651 | u16 ver; |
| 652 | 652 | |
| 653 | 653 | of_data = of_device_get_match_data(&pdev->dev); |
| @@ -825,24 +825,31 @@ int renesas_sdhi_probe(struct platform_device *pdev, · 171 unmodified lines | ||
| 825 | 825 | host->hs400_complete = renesas_sdhi_hs400_complete; |
| 826 | 826 | } |
| 827 | 827 | |
| 828 | − i = 0; | |
| 829 | − while (1) { | |
| 828 | + num_irqs = platform_irq_count(pdev); | |
| 829 | + if (num_irqs < 0) { | |
| 830 | + ret = num_irqs; | |
| 831 | + goto eirq; | |
| 832 | + } | |
| 833 | + | |
| 834 | + /* There must be at least one IRQ source */ | |
| 835 | + if (!num_irqs) { | |
| 836 | + ret = -ENXIO; | |
| 837 | + goto eirq; | |
| 838 | + } | |
| 839 | + | |
| 840 | + for (i = 0; i < num_irqs; i++) { | |
| 830 | 841 | irq = platform_get_irq(pdev, i); |
| 831 | − if (irq < 0) | |
| 832 | − break; | |
| 833 | − i++; | |
| 842 | + if (irq < 0) { | |
| 843 | + ret = irq; | |
| 844 | + goto eirq; | |
| 845 | + } | |
| 846 | + | |
| 834 | 847 | ret = devm_request_irq(&pdev->dev, irq, tmio_mmc_irq, 0, |
| 835 | 848 | dev_name(&pdev->dev), host); |
| 836 | 849 | if (ret) |
| 837 | 850 | goto eirq; |
| 838 | 851 | } |
| 839 | 852 | |
| 840 | − /* There must be at least one IRQ source */ | |
| 841 | − if (!i) { | |
| 842 | − ret = irq; | |
| 843 | − goto eirq; | |
| 844 | − } | |
| 845 | − | |
| 846 | 853 | dev_info(&pdev->dev, "%s base at 0x%08lx max clock rate %u MHz\n", |
| 847 | 854 | mmc_hostname(host->mmc), (unsigned long) |
| 848 | 855 | (platform_get_resource(pdev, IORESOURCE_MEM, 0)->start), |
| @@ -262,6 +262,7 @@ static const struct sdhci_iproc_data bcm2835_data = { · 261 unmodified lines | ||
| 262 | 262 | }; |
| 263 | 263 | |
| 264 | 264 | static const struct sdhci_pltfm_data sdhci_bcm2711_pltfm_data = { |
| 265 | + .quirks = SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, | |
| 265 | 266 | .ops = &sdhci_iproc_32only_ops, |
| 266 | 267 | }; |
| 267 | 268 | |
| @@ -1393,11 +1393,9 @@ static int sh_mmcif_probe(struct platform_device *pdev) · 1392 unmodified lines | ||
| 1393 | 1393 | const char *name; |
| 1394 | 1394 | |
| 1395 | 1395 | irq[0] = platform_get_irq(pdev, 0); |
| 1396 | − irq[1] = platform_get_irq(pdev, 1); | |
| 1397 | − if (irq[0] < 0) { | |
| 1398 | − dev_err(dev, "Get irq error\n"); | |
| 1396 | + irq[1] = platform_get_irq_optional(pdev, 1); | |
| 1397 | + if (irq[0] < 0) | |
| 1399 | 1398 | return -ENXIO; |
| 1400 | − } | |
| 1401 | 1399 | |
| 1402 | 1400 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1403 | 1401 | reg = devm_ioremap_resource(dev, res); |
| @@ -134,16 +134,15 @@ static void au_write_buf16(struct nand_chip *this, const u_char *buf, int len) · 133 unmodified lines | ||
| 134 | 134 | |
| 135 | 135 | /** |
| 136 | 136 | * au_read_buf16 - read chip data into buffer |
| 137 | − * @mtd: MTD device structure | |
| 137 | + * @this: NAND chip object | |
| 138 | 138 | * @buf: buffer to store date |
| 139 | 139 | * @len: number of bytes to read |
| 140 | 140 | * |
| 141 | 141 | * read function for 16bit buswidth |
| 142 | 142 | */ |
| 143 | −static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | |
| 143 | +static void au_read_buf16(struct nand_chip *this, u_char *buf, int len) | |
| 144 | 144 | { |
| 145 | 145 | int i; |
| 146 | − struct nand_chip *this = mtd_to_nand(mtd); | |
| 147 | 146 | u16 *p = (u16 *) buf; |
| 148 | 147 | len >>= 1; |
| 149 | 148 | |
| @@ -487,7 +487,7 @@ static int write_sr(struct spi_nor *nor, u8 val) · 486 unmodified lines | ||
| 487 | 487 | SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR, 1), |
| 488 | 488 | SPI_MEM_OP_NO_ADDR, |
| 489 | 489 | SPI_MEM_OP_NO_DUMMY, |
| 490 | − SPI_MEM_OP_DATA_IN(1, nor->bouncebuf, 1)); | |
| 490 | + SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 1)); | |
| 491 | 491 | |
| 492 | 492 | return spi_mem_exec_op(nor->spimem, &op); |
| 493 | 493 | } |
| @@ -4039,7 +4039,7 @@ out: · 4038 unmodified lines | ||
| 4039 | 4039 | * this to-be-skipped slave to send a packet out. |
| 4040 | 4040 | */ |
| 4041 | 4041 | old_arr = rtnl_dereference(bond->slave_arr); |
| 4042 | − for (idx = 0; idx < old_arr->count; idx++) { | |
| 4042 | + for (idx = 0; old_arr != NULL && idx < old_arr->count; idx++) { | |
| 4043 | 4043 | if (skipslave == old_arr->arr[idx]) { |
| 4044 | 4044 | old_arr->arr[idx] = |
| 4045 | 4045 | old_arr->arr[old_arr->count-1]; |
| @@ -1845,7 +1845,6 @@ int b53_mirror_add(struct dsa_switch *ds, int port, · 1844 unmodified lines | ||
| 1845 | 1845 | loc = B53_EG_MIR_CTL; |
| 1846 | 1846 | |
| 1847 | 1847 | b53_read16(dev, B53_MGMT_PAGE, loc, ®); |
| 1848 | − reg &= ~MIRROR_MASK; | |
| 1849 | 1848 | reg |= BIT(port); |
| 1850 | 1849 | b53_write16(dev, B53_MGMT_PAGE, loc, reg); |
| 1851 | 1850 | |
| @@ -1224,10 +1224,6 @@ static int ksz8795_switch_init(struct ksz_device *dev) · 1223 unmodified lines | ||
| 1224 | 1224 | { |
| 1225 | 1225 | int i; |
| 1226 | 1226 | |
| 1227 | − mutex_init(&dev->stats_mutex); | |
| 1228 | − mutex_init(&dev->alu_mutex); | |
| 1229 | − mutex_init(&dev->vlan_mutex); | |
| 1230 | − | |
| 1231 | 1227 | dev->ds->ops = &ksz8795_switch_ops; |
| 1232 | 1228 | |
| 1233 | 1229 | for (i = 0; i < ARRAY_SIZE(ksz8795_switch_chips); i++) { |
| @@ -25,6 +25,7 @@ KSZ_REGMAP_TABLE(ksz8795, 16, SPI_ADDR_SHIFT, · 24 unmodified lines | ||
| 25 | 25 | |
| 26 | 26 | static int ksz8795_spi_probe(struct spi_device *spi) |
| 27 | 27 | { |
| 28 | + struct regmap_config rc; | |
| 28 | 29 | struct ksz_device *dev; |
| 29 | 30 | int i, ret; |
| 30 | 31 | |
| @@ -33,9 +34,9 @@ static int ksz8795_spi_probe(struct spi_device *spi) · 2 unmodified lines | ||
| 33 | 34 | return -ENOMEM; |
| 34 | 35 | |
| 35 | 36 | for (i = 0; i < ARRAY_SIZE(ksz8795_regmap_config); i++) { |
| 36 | − dev->regmap[i] = devm_regmap_init_spi(spi, | |
| 37 | − &ksz8795_regmap_config | |
| 38 | − [i]); | |
| 37 | + rc = ksz8795_regmap_config[i]; | |
| 38 | + rc.lock_arg = &dev->regmap_mutex; | |
| 39 | + dev->regmap[i] = devm_regmap_init_spi(spi, &rc); | |
| 39 | 40 | if (IS_ERR(dev->regmap[i])) { |
| 40 | 41 | ret = PTR_ERR(dev->regmap[i]); |
| 41 | 42 | dev_err(&spi->dev, |
| @@ -17,6 +17,7 @@ KSZ_REGMAP_TABLE(ksz9477, not_used, 16, 0, 0); · 16 unmodified lines | ||
| 17 | 17 | static int ksz9477_i2c_probe(struct i2c_client *i2c, |
| 18 | 18 | const struct i2c_device_id *i2c_id) |
| 19 | 19 | { |
| 20 | + struct regmap_config rc; | |
| 20 | 21 | struct ksz_device *dev; |
| 21 | 22 | int i, ret; |
| 22 | 23 | |
| @@ -25,8 +26,9 @@ static int ksz9477_i2c_probe(struct i2c_client *i2c, · 2 unmodified lines | ||
| 25 | 26 | return -ENOMEM; |
| 26 | 27 | |
| 27 | 28 | for (i = 0; i < ARRAY_SIZE(ksz9477_regmap_config); i++) { |
| 28 | − dev->regmap[i] = devm_regmap_init_i2c(i2c, | |
| 29 | − &ksz9477_regmap_config[i]); | |
| 29 | + rc = ksz9477_regmap_config[i]; | |
| 30 | + rc.lock_arg = &dev->regmap_mutex; | |
| 31 | + dev->regmap[i] = devm_regmap_init_i2c(i2c, &rc); | |
| 30 | 32 | if (IS_ERR(dev->regmap[i])) { |
| 31 | 33 | ret = PTR_ERR(dev->regmap[i]); |
| 32 | 34 | dev_err(&i2c->dev, |
| @@ -1,5 +1,5 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 | |
| 2 | − * | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +/* | |
| 3 | 3 | * Microchip KSZ9477 register definitions |
| 4 | 4 | * |
| 5 | 5 | * Copyright (C) 2017-2018 Microchip Technology Inc. |
| @@ -24,6 +24,7 @@ KSZ_REGMAP_TABLE(ksz9477, 32, SPI_ADDR_SHIFT, · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | static int ksz9477_spi_probe(struct spi_device *spi) |
| 26 | 26 | { |
| 27 | + struct regmap_config rc; | |
| 27 | 28 | struct ksz_device *dev; |
| 28 | 29 | int i, ret; |
| 29 | 30 | |
| @@ -32,8 +33,9 @@ static int ksz9477_spi_probe(struct spi_device *spi) · 2 unmodified lines | ||
| 32 | 33 | return -ENOMEM; |
| 33 | 34 | |
| 34 | 35 | for (i = 0; i < ARRAY_SIZE(ksz9477_regmap_config); i++) { |
| 35 | − dev->regmap[i] = devm_regmap_init_spi(spi, | |
| 36 | − &ksz9477_regmap_config[i]); | |
| 36 | + rc = ksz9477_regmap_config[i]; | |
| 37 | + rc.lock_arg = &dev->regmap_mutex; | |
| 38 | + dev->regmap[i] = devm_regmap_init_spi(spi, &rc); | |
| 37 | 39 | if (IS_ERR(dev->regmap[i])) { |
| 38 | 40 | ret = PTR_ERR(dev->regmap[i]); |
| 39 | 41 | dev_err(&spi->dev, |
| @@ -436,7 +436,7 @@ int ksz_switch_register(struct ksz_device *dev, · 435 unmodified lines | ||
| 436 | 436 | } |
| 437 | 437 | |
| 438 | 438 | mutex_init(&dev->dev_mutex); |
| 439 | − mutex_init(&dev->stats_mutex); | |
| 439 | + mutex_init(&dev->regmap_mutex); | |
| 440 | 440 | mutex_init(&dev->alu_mutex); |
| 441 | 441 | mutex_init(&dev->vlan_mutex); |
| 442 | 442 | |
| @@ -1,5 +1,5 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 | |
| 2 | − * Microchip switch driver common header | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +/* Microchip switch driver common header | |
| 3 | 3 | * |
| 4 | 4 | * Copyright (C) 2017-2019 Microchip Technology Inc. |
| 5 | 5 | */ |
| @@ -47,7 +47,7 @@ struct ksz_device { · 41 unmodified lines | ||
| 47 | 47 | const char *name; |
| 48 | 48 | |
| 49 | 49 | struct mutex dev_mutex; /* device access */ |
| 50 | − struct mutex stats_mutex; /* status access */ | |
| 50 | + struct mutex regmap_mutex; /* regmap access */ | |
| 51 | 51 | struct mutex alu_mutex; /* ALU access */ |
| 52 | 52 | struct mutex vlan_mutex; /* vlan access */ |
| 53 | 53 | const struct ksz_dev_ops *dev_ops; |
| @@ -290,6 +290,18 @@ static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset, · 236 unmodified lines | ||
| 290 | 290 | ksz_write32(dev, dev->dev_ops->get_port_addr(port, offset), data); |
| 291 | 291 | } |
| 292 | 292 | |
| 293 | +static inline void ksz_regmap_lock(void *__mtx) | |
| 294 | +{ | |
| 295 | + struct mutex *mtx = __mtx; | |
| 296 | + mutex_lock(mtx); | |
| 297 | +} | |
| 298 | + | |
| 299 | +static inline void ksz_regmap_unlock(void *__mtx) | |
| 300 | +{ | |
| 301 | + struct mutex *mtx = __mtx; | |
| 302 | + mutex_unlock(mtx); | |
| 303 | +} | |
| 304 | + | |
| 293 | 305 | /* Regmap tables generation */ |
| 294 | 306 | #define KSZ_SPI_OP_RD 3 |
| 295 | 307 | #define KSZ_SPI_OP_WR 2 |
| @@ -314,6 +326,8 @@ static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset, · 18 unmodified lines | ||
| 314 | 326 | .write_flag_mask = \ |
| 315 | 327 | KSZ_SPI_OP_FLAG_MASK(KSZ_SPI_OP_WR, swp, \ |
| 316 | 328 | regbits, regpad), \ |
| 329 | + .lock = ksz_regmap_lock, \ | |
| 330 | + .unlock = ksz_regmap_unlock, \ | |
| 317 | 331 | .reg_format_endian = REGMAP_ENDIAN_BIG, \ |
| 318 | 332 | .val_format_endian = REGMAP_ENDIAN_BIG \ |
| 319 | 333 | } |
| @@ -1,5 +1,5 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 | |
| 2 | − * Copyright (c) 2018, Sensor-Technik Wiedemann GmbH | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +/* Copyright (c) 2018, Sensor-Technik Wiedemann GmbH | |
| 3 | 3 | * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com> |
| 4 | 4 | */ |
| 5 | 5 | #ifndef _SJA1105_H |
| @@ -1,5 +1,5 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 | |
| 2 | − * Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com> | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +/* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com> | |
| 3 | 3 | */ |
| 4 | 4 | #ifndef _SJA1105_DYNAMIC_CONFIG_H |
| 5 | 5 | #define _SJA1105_DYNAMIC_CONFIG_H |
| @@ -1,5 +1,5 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 | |
| 2 | − * Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com> | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +/* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com> | |
| 3 | 3 | */ |
| 4 | 4 | #ifndef _SJA1105_PTP_H |
| 5 | 5 | #define _SJA1105_PTP_H |
| @@ -1,5 +1,5 @@ | ||
| 1 | −/* SPDX-License-Identifier: BSD-3-Clause | |
| 2 | − * Copyright (c) 2016-2018, NXP Semiconductors | |
| 1 | +/* SPDX-License-Identifier: BSD-3-Clause */ | |
| 2 | +/* Copyright (c) 2016-2018, NXP Semiconductors | |
| 3 | 3 | * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com> |
| 4 | 4 | */ |
| 5 | 5 | #ifndef _SJA1105_STATIC_CONFIG_H |
| @@ -1,5 +1,5 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 | |
| 2 | − * Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com> | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | +/* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com> | |
| 3 | 3 | */ |
| 4 | 4 | #ifndef _SJA1105_TAS_H |
| 5 | 5 | #define _SJA1105_TAS_H |
| @@ -194,9 +194,7 @@ static void aq_ndev_set_multicast_settings(struct net_device *ndev) · 193 unmodified lines | ||
| 194 | 194 | { |
| 195 | 195 | struct aq_nic_s *aq_nic = netdev_priv(ndev); |
| 196 | 196 | |
| 197 | − aq_nic_set_packet_filter(aq_nic, ndev->flags); | |
| 198 | − | |
| 199 | − aq_nic_set_multicast_list(aq_nic, ndev); | |
| 197 | + (void)aq_nic_set_multicast_list(aq_nic, ndev); | |
| 200 | 198 | } |
| 201 | 199 | |
| 202 | 200 | static int aq_ndo_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, |
| @@ -631,9 +631,12 @@ err_exit: · 630 unmodified lines | ||
| 631 | 631 | |
| 632 | 632 | int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev) |
| 633 | 633 | { |
| 634 | − unsigned int packet_filter = self->packet_filter; | |
| 634 | + const struct aq_hw_ops *hw_ops = self->aq_hw_ops; | |
| 635 | + struct aq_nic_cfg_s *cfg = &self->aq_nic_cfg; | |
| 636 | + unsigned int packet_filter = ndev->flags; | |
| 635 | 637 | struct netdev_hw_addr *ha = NULL; |
| 636 | 638 | unsigned int i = 0U; |
| 639 | + int err = 0; | |
| 637 | 640 | |
| 638 | 641 | self->mc_list.count = 0; |
| 639 | 642 | if (netdev_uc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) { |
| @@ -641,29 +644,28 @@ int aq_nic_set_multicast_list(struct aq_nic_s *self, struct net_device *ndev) · 1 unmodified line | ||
| 641 | 644 | } else { |
| 642 | 645 | netdev_for_each_uc_addr(ha, ndev) { |
| 643 | 646 | ether_addr_copy(self->mc_list.ar[i++], ha->addr); |
| 644 | − | |
| 645 | − if (i >= AQ_HW_MULTICAST_ADDRESS_MAX) | |
| 646 | − break; | |
| 647 | 647 | } |
| 648 | 648 | } |
| 649 | 649 | |
| 650 | − if (i + netdev_mc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) { | |
| 651 | − packet_filter |= IFF_ALLMULTI; | |
| 652 | − } else { | |
| 653 | − netdev_for_each_mc_addr(ha, ndev) { | |
| 654 | − ether_addr_copy(self->mc_list.ar[i++], ha->addr); | |
| 655 | − | |
| 656 | − if (i >= AQ_HW_MULTICAST_ADDRESS_MAX) | |
| 657 | − break; | |
| 650 | + cfg->is_mc_list_enabled = !!(packet_filter & IFF_MULTICAST); | |
| 651 | + if (cfg->is_mc_list_enabled) { | |
| 652 | + if (i + netdev_mc_count(ndev) > AQ_HW_MULTICAST_ADDRESS_MAX) { | |
| 653 | + packet_filter |= IFF_ALLMULTI; | |
| 654 | + } else { | |
| 655 | + netdev_for_each_mc_addr(ha, ndev) { | |
| 656 | + ether_addr_copy(self->mc_list.ar[i++], | |
| 657 | + ha->addr); | |
| 658 | + } | |
| 658 | 659 | } |
| 659 | 660 | } |
| 660 | 661 | |
| 661 | 662 | if (i > 0 && i <= AQ_HW_MULTICAST_ADDRESS_MAX) { |
| 662 | − packet_filter |= IFF_MULTICAST; | |
| 663 | 663 | self->mc_list.count = i; |
| 664 | − self->aq_hw_ops->hw_multicast_list_set(self->aq_hw, | |
| 665 | − self->mc_list.ar, | |
| 666 | − self->mc_list.count); | |
| 664 | + err = hw_ops->hw_multicast_list_set(self->aq_hw, | |
| 665 | + self->mc_list.ar, | |
| 666 | + self->mc_list.count); | |
| 667 | + if (err < 0) | |
| 668 | + return err; | |
| 667 | 669 | } |
| 668 | 670 | return aq_nic_set_packet_filter(self, packet_filter); |
| 669 | 671 | } |
| @@ -313,6 +313,7 @@ int aq_ring_rx_clean(struct aq_ring_s *self, · 312 unmodified lines | ||
| 313 | 313 | break; |
| 314 | 314 | |
| 315 | 315 | buff->is_error |= buff_->is_error; |
| 316 | + buff->is_cso_err |= buff_->is_cso_err; | |
| 316 | 317 | |
| 317 | 318 | } while (!buff_->is_eop); |
| 318 | 319 | |
| @@ -320,7 +321,7 @@ int aq_ring_rx_clean(struct aq_ring_s *self, · 1 unmodified line | ||
| 320 | 321 | err = 0; |
| 321 | 322 | goto err_exit; |
| 322 | 323 | } |
| 323 | − if (buff->is_error) { | |
| 324 | + if (buff->is_error || buff->is_cso_err) { | |
| 324 | 325 | buff_ = buff; |
| 325 | 326 | do { |
| 326 | 327 | next_ = buff_->next, |
| @@ -818,14 +818,15 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self, · 817 unmodified lines | ||
| 818 | 818 | cfg->is_vlan_force_promisc); |
| 819 | 819 | |
| 820 | 820 | hw_atl_rpfl2multicast_flr_en_set(self, |
| 821 | − IS_FILTER_ENABLED(IFF_ALLMULTI), 0); | |
| 821 | + IS_FILTER_ENABLED(IFF_ALLMULTI) && | |
| 822 | + IS_FILTER_ENABLED(IFF_MULTICAST), 0); | |
| 822 | 823 | |
| 823 | 824 | hw_atl_rpfl2_accept_all_mc_packets_set(self, |
| 824 | − IS_FILTER_ENABLED(IFF_ALLMULTI)); | |
| 825 | + IS_FILTER_ENABLED(IFF_ALLMULTI) && | |
| 826 | + IS_FILTER_ENABLED(IFF_MULTICAST)); | |
| 825 | 827 | |
| 826 | 828 | hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST)); |
| 827 | 829 | |
| 828 | − cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST); | |
| 829 | 830 | |
| 830 | 831 | for (i = HW_ATL_B0_MAC_MIN; i < HW_ATL_B0_MAC_MAX; ++i) |
| 831 | 832 | hw_atl_rpfl2_uc_flr_en_set(self, |
| @@ -968,14 +969,26 @@ static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self) · 136 unmodified lines | ||
| 968 | 969 | |
| 969 | 970 | static int hw_atl_b0_hw_stop(struct aq_hw_s *self) |
| 970 | 971 | { |
| 972 | + int err; | |
| 973 | + u32 val; | |
| 974 | + | |
| 971 | 975 | hw_atl_b0_hw_irq_disable(self, HW_ATL_B0_INT_MASK); |
| 972 | 976 | |
| 973 | 977 | /* Invalidate Descriptor Cache to prevent writing to the cached |
| 974 | 978 | * descriptors and to the data pointer of those descriptors |
| 975 | 979 | */ |
| 976 | − hw_atl_rdm_rx_dma_desc_cache_init_set(self, 1); | |
| 980 | + hw_atl_rdm_rx_dma_desc_cache_init_tgl(self); | |
| 977 | 981 | |
| 978 | − return aq_hw_err_from_flags(self); | |
| 982 | + err = aq_hw_err_from_flags(self); | |
| 983 | + | |
| 984 | + if (err) | |
| 985 | + goto err_exit; | |
| 986 | + | |
| 987 | + readx_poll_timeout_atomic(hw_atl_rdm_rx_dma_desc_cache_init_done_get, | |
| 988 | + self, val, val == 1, 1000U, 10000U); | |
| 989 | + | |
| 990 | +err_exit: | |
| 991 | + return err; | |
| 979 | 992 | } |
| 980 | 993 | |
| 981 | 994 | static int hw_atl_b0_hw_ring_tx_stop(struct aq_hw_s *self, |
| @@ -606,12 +606,25 @@ void hw_atl_rpb_rx_flow_ctl_mode_set(struct aq_hw_s *aq_hw, u32 rx_flow_ctl_mode · 605 unmodified lines | ||
| 606 | 606 | HW_ATL_RPB_RX_FC_MODE_SHIFT, rx_flow_ctl_mode); |
| 607 | 607 | } |
| 608 | 608 | |
| 609 | −void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init) | |
| 609 | +void hw_atl_rdm_rx_dma_desc_cache_init_tgl(struct aq_hw_s *aq_hw) | |
| 610 | 610 | { |
| 611 | + u32 val; | |
| 612 | + | |
| 613 | + val = aq_hw_read_reg_bit(aq_hw, HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR, | |
| 614 | + HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK, | |
| 615 | + HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT); | |
| 616 | + | |
| 611 | 617 | aq_hw_write_reg_bit(aq_hw, HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_ADR, |
| 612 | 618 | HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_MSK, |
| 613 | 619 | HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_SHIFT, |
| 614 | − init); | |
| 620 | + val ^ 1); | |
| 621 | +} | |
| 622 | + | |
| 623 | +u32 hw_atl_rdm_rx_dma_desc_cache_init_done_get(struct aq_hw_s *aq_hw) | |
| 624 | +{ | |
| 625 | + return aq_hw_read_reg_bit(aq_hw, RDM_RX_DMA_DESC_CACHE_INIT_DONE_ADR, | |
| 626 | + RDM_RX_DMA_DESC_CACHE_INIT_DONE_MSK, | |
| 627 | + RDM_RX_DMA_DESC_CACHE_INIT_DONE_SHIFT); | |
| 615 | 628 | } |
| 616 | 629 | |
| 617 | 630 | void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, |
| @@ -313,8 +313,11 @@ void hw_atl_rpb_rx_pkt_buff_size_per_tc_set(struct aq_hw_s *aq_hw, · 312 unmodified lines | ||
| 313 | 313 | u32 rx_pkt_buff_size_per_tc, |
| 314 | 314 | u32 buffer); |
| 315 | 315 | |
| 316 | −/* set rdm rx dma descriptor cache init */ | |
| 317 | −void hw_atl_rdm_rx_dma_desc_cache_init_set(struct aq_hw_s *aq_hw, u32 init); | |
| 316 | +/* toggle rdm rx dma descriptor cache init */ | |
| 317 | +void hw_atl_rdm_rx_dma_desc_cache_init_tgl(struct aq_hw_s *aq_hw); | |
| 318 | + | |
| 319 | +/* get rdm rx dma descriptor cache init done */ | |
| 320 | +u32 hw_atl_rdm_rx_dma_desc_cache_init_done_get(struct aq_hw_s *aq_hw); | |
| 318 | 321 | |
| 319 | 322 | /* set rx xoff enable (per tc) */ |
| 320 | 323 | void hw_atl_rpb_rx_xoff_en_per_tc_set(struct aq_hw_s *aq_hw, u32 rx_xoff_en_per_tc, |
| @@ -318,6 +318,25 @@ · 317 unmodified lines | ||
| 318 | 318 | /* default value of bitfield rdm_desc_init_i */ |
| 319 | 319 | #define HW_ATL_RDM_RX_DMA_DESC_CACHE_INIT_DEFAULT 0x0 |
| 320 | 320 | |
| 321 | +/* rdm_desc_init_done_i bitfield definitions | |
| 322 | + * preprocessor definitions for the bitfield rdm_desc_init_done_i. | |
| 323 | + * port="pif_rdm_desc_init_done_i" | |
| 324 | + */ | |
| 325 | + | |
| 326 | +/* register address for bitfield rdm_desc_init_done_i */ | |
| 327 | +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_ADR 0x00005a10 | |
| 328 | +/* bitmask for bitfield rdm_desc_init_done_i */ | |
| 329 | +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_MSK 0x00000001U | |
| 330 | +/* inverted bitmask for bitfield rdm_desc_init_done_i */ | |
| 331 | +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_MSKN 0xfffffffe | |
| 332 | +/* lower bit position of bitfield rdm_desc_init_done_i */ | |
| 333 | +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_SHIFT 0U | |
| 334 | +/* width of bitfield rdm_desc_init_done_i */ | |
| 335 | +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_WIDTH 1 | |
| 336 | +/* default value of bitfield rdm_desc_init_done_i */ | |
| 337 | +#define RDM_RX_DMA_DESC_CACHE_INIT_DONE_DEFAULT 0x0 | |
| 338 | + | |
| 339 | + | |
| 321 | 340 | /* rx int_desc_wrb_en bitfield definitions |
| 322 | 341 | * preprocessor definitions for the bitfield "int_desc_wrb_en". |
| 323 | 342 | * port="pif_rdm_int_desc_wrb_en_i" |
| @@ -337,7 +337,7 @@ static int aq_fw2x_get_phy_temp(struct aq_hw_s *self, int *temp) · 336 unmodified lines | ||
| 337 | 337 | /* Convert PHY temperature from 1/256 degree Celsius |
| 338 | 338 | * to 1/1000 degree Celsius. |
| 339 | 339 | */ |
| 340 | − *temp = temp_res * 1000 / 256; | |
| 340 | + *temp = (temp_res & 0xFFFF) * 1000 / 256; | |
| 341 | 341 | |
| 342 | 342 | return 0; |
| 343 | 343 | } |
| @@ -8,7 +8,6 @@ config NET_VENDOR_BROADCOM · 7 unmodified lines | ||
| 8 | 8 | default y |
| 9 | 9 | depends on (SSB_POSSIBLE && HAS_DMA) || PCI || BCM63XX || \ |
| 10 | 10 | SIBYTE_SB1xxx_SOC |
| 11 | − select DIMLIB | |
| 12 | 11 | ---help--- |
| 13 | 12 | If you have a network (Ethernet) chipset belonging to this class, |
| 14 | 13 | say Y. |
| @@ -69,6 +68,7 @@ config BCMGENET · 54 unmodified lines | ||
| 69 | 68 | select FIXED_PHY |
| 70 | 69 | select BCM7XXX_PHY |
| 71 | 70 | select MDIO_BCM_UNIMAC |
| 71 | + select DIMLIB | |
| 72 | 72 | help |
| 73 | 73 | This driver supports the built-in Ethernet MACs found in the |
| 74 | 74 | Broadcom BCM7xxx Set Top Box family chipset. |
| @@ -188,6 +188,7 @@ config SYSTEMPORT · 113 unmodified lines | ||
| 188 | 188 | select MII |
| 189 | 189 | select PHYLIB |
| 190 | 190 | select FIXED_PHY |
| 191 | + select DIMLIB | |
| 191 | 192 | help |
| 192 | 193 | This driver supports the built-in Ethernet MACs found in the |
| 193 | 194 | Broadcom BCM7xxx Set Top Box family chipset using an internal |
| @@ -200,6 +201,7 @@ config BNXT · 6 unmodified lines | ||
| 200 | 201 | select LIBCRC32C |
| 201 | 202 | select NET_DEVLINK |
| 202 | 203 | select PAGE_POOL |
| 204 | + select DIMLIB | |
| 203 | 205 | ---help--- |
| 204 | 206 | This driver supports Broadcom NetXtreme-C/E 10/25/40/50 gigabit |
| 205 | 207 | Ethernet cards. To compile this driver as a module, choose M here: |
| @@ -2018,6 +2018,8 @@ static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv) · 2017 unmodified lines | ||
| 2018 | 2018 | */ |
| 2019 | 2019 | if (priv->internal_phy) { |
| 2020 | 2020 | int0_enable |= UMAC_IRQ_LINK_EVENT; |
| 2021 | + if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv)) | |
| 2022 | + int0_enable |= UMAC_IRQ_PHY_DET_R; | |
| 2021 | 2023 | } else if (priv->ext_phy) { |
| 2022 | 2024 | int0_enable |= UMAC_IRQ_LINK_EVENT; |
| 2023 | 2025 | } else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) { |
| @@ -2611,11 +2613,14 @@ static void bcmgenet_irq_task(struct work_struct *work) · 587 unmodified lines | ||
| 2611 | 2613 | priv->irq0_stat = 0; |
| 2612 | 2614 | spin_unlock_irq(&priv->lock); |
| 2613 | 2615 | |
| 2616 | + if (status & UMAC_IRQ_PHY_DET_R && | |
| 2617 | + priv->dev->phydev->autoneg != AUTONEG_ENABLE) | |
| 2618 | + phy_init_hw(priv->dev->phydev); | |
| 2619 | + | |
| 2614 | 2620 | /* Link UP/DOWN event */ |
| 2615 | − if (status & UMAC_IRQ_LINK_EVENT) { | |
| 2616 | − priv->dev->phydev->link = !!(status & UMAC_IRQ_LINK_UP); | |
| 2621 | + if (status & UMAC_IRQ_LINK_EVENT) | |
| 2617 | 2622 | phy_mac_interrupt(priv->dev->phydev); |
| 2618 | − } | |
| 2623 | + | |
| 2619 | 2624 | } |
| 2620 | 2625 | |
| 2621 | 2626 | /* bcmgenet_isr1: handle Rx and Tx priority queues */ |
| @@ -2710,7 +2715,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id) · 88 unmodified lines | ||
| 2710 | 2715 | } |
| 2711 | 2716 | |
| 2712 | 2717 | /* all other interested interrupts handled in bottom half */ |
| 2713 | − status &= UMAC_IRQ_LINK_EVENT; | |
| 2718 | + status &= (UMAC_IRQ_LINK_EVENT | UMAC_IRQ_PHY_DET_R); | |
| 2714 | 2719 | if (status) { |
| 2715 | 2720 | /* Save irq status for bottom-half processing. */ |
| 2716 | 2721 | spin_lock_irqsave(&priv->lock, flags); |
| @@ -2874,6 +2879,12 @@ static int bcmgenet_open(struct net_device *dev) · 157 unmodified lines | ||
| 2874 | 2879 | if (priv->internal_phy) |
| 2875 | 2880 | bcmgenet_power_up(priv, GENET_POWER_PASSIVE); |
| 2876 | 2881 | |
| 2882 | + ret = bcmgenet_mii_connect(dev); | |
| 2883 | + if (ret) { | |
| 2884 | + netdev_err(dev, "failed to connect to PHY\n"); | |
| 2885 | + goto err_clk_disable; | |
| 2886 | + } | |
| 2887 | + | |
| 2877 | 2888 | /* take MAC out of reset */ |
| 2878 | 2889 | bcmgenet_umac_reset(priv); |
| 2879 | 2890 | |
| @@ -2883,6 +2894,12 @@ static int bcmgenet_open(struct net_device *dev) · 3 unmodified lines | ||
| 2883 | 2894 | reg = bcmgenet_umac_readl(priv, UMAC_CMD); |
| 2884 | 2895 | priv->crc_fwd_en = !!(reg & CMD_CRC_FWD); |
| 2885 | 2896 | |
| 2897 | + ret = bcmgenet_mii_config(dev, true); | |
| 2898 | + if (ret) { | |
| 2899 | + netdev_err(dev, "unsupported PHY\n"); | |
| 2900 | + goto err_disconnect_phy; | |
| 2901 | + } | |
| 2902 | + | |
| 2886 | 2903 | bcmgenet_set_hw_addr(priv, dev->dev_addr); |
| 2887 | 2904 | |
| 2888 | 2905 | if (priv->internal_phy) { |
| @@ -2898,7 +2915,7 @@ static int bcmgenet_open(struct net_device *dev) · 9 unmodified lines | ||
| 2898 | 2915 | ret = bcmgenet_init_dma(priv); |
| 2899 | 2916 | if (ret) { |
| 2900 | 2917 | netdev_err(dev, "failed to initialize DMA\n"); |
| 2901 | − goto err_clk_disable; | |
| 2918 | + goto err_disconnect_phy; | |
| 2902 | 2919 | } |
| 2903 | 2920 | |
| 2904 | 2921 | /* Always enable ring 16 - descriptor ring */ |
| @@ -2921,25 +2938,19 @@ static int bcmgenet_open(struct net_device *dev) · 16 unmodified lines | ||
| 2921 | 2938 | goto err_irq0; |
| 2922 | 2939 | } |
| 2923 | 2940 | |
| 2924 | − ret = bcmgenet_mii_probe(dev); | |
| 2925 | − if (ret) { | |
| 2926 | − netdev_err(dev, "failed to connect to PHY\n"); | |
| 2927 | − goto err_irq1; | |
| 2928 | − } | |
| 2929 | − | |
| 2930 | 2941 | bcmgenet_netif_start(dev); |
| 2931 | 2942 | |
| 2932 | 2943 | netif_tx_start_all_queues(dev); |
| 2933 | 2944 | |
| 2934 | 2945 | return 0; |
| 2935 | 2946 | |
| 2936 | −err_irq1: | |
| 2937 | − free_irq(priv->irq1, priv); | |
| 2938 | 2947 | err_irq0: |
| 2939 | 2948 | free_irq(priv->irq0, priv); |
| 2940 | 2949 | err_fini_dma: |
| 2941 | 2950 | bcmgenet_dma_teardown(priv); |
| 2942 | 2951 | bcmgenet_fini_dma(priv); |
| 2952 | +err_disconnect_phy: | |
| 2953 | + phy_disconnect(dev->phydev); | |
| 2943 | 2954 | err_clk_disable: |
| 2944 | 2955 | if (priv->internal_phy) |
| 2945 | 2956 | bcmgenet_power_down(priv, GENET_POWER_PASSIVE); |
| @@ -3620,6 +3631,8 @@ static int bcmgenet_resume(struct device *d) · 674 unmodified lines | ||
| 3620 | 3631 | if (priv->internal_phy) |
| 3621 | 3632 | bcmgenet_power_up(priv, GENET_POWER_PASSIVE); |
| 3622 | 3633 | |
| 3634 | + phy_init_hw(dev->phydev); | |
| 3635 | + | |
| 3623 | 3636 | bcmgenet_umac_reset(priv); |
| 3624 | 3637 | |
| 3625 | 3638 | init_umac(priv); |
| @@ -3628,8 +3641,6 @@ static int bcmgenet_resume(struct device *d) · 2 unmodified lines | ||
| 3628 | 3641 | if (priv->wolopts) |
| 3629 | 3642 | clk_disable_unprepare(priv->clk_wol); |
| 3630 | 3643 | |
| 3631 | − phy_init_hw(dev->phydev); | |
| 3632 | − | |
| 3633 | 3644 | /* Speed settings must be restored */ |
| 3634 | 3645 | bcmgenet_mii_config(priv->dev, false); |
| 3635 | 3646 | |
| @@ -366,6 +366,7 @@ struct bcmgenet_mib_counters { · 365 unmodified lines | ||
| 366 | 366 | #define EXT_PWR_DOWN_PHY_EN (1 << 20) |
| 367 | 367 | |
| 368 | 368 | #define EXT_RGMII_OOB_CTRL 0x0C |
| 369 | +#define RGMII_MODE_EN_V123 (1 << 0) | |
| 369 | 370 | #define RGMII_LINK (1 << 4) |
| 370 | 371 | #define OOB_DISABLE (1 << 5) |
| 371 | 372 | #define RGMII_MODE_EN (1 << 6) |
| @@ -719,8 +720,8 @@ GENET_IO_MACRO(rbuf, GENET_RBUF_OFF); · 347 unmodified lines | ||
| 719 | 720 | |
| 720 | 721 | /* MDIO routines */ |
| 721 | 722 | int bcmgenet_mii_init(struct net_device *dev); |
| 723 | +int bcmgenet_mii_connect(struct net_device *dev); | |
| 722 | 724 | int bcmgenet_mii_config(struct net_device *dev, bool init); |
| 723 | −int bcmgenet_mii_probe(struct net_device *dev); | |
| 724 | 725 | void bcmgenet_mii_exit(struct net_device *dev); |
| 725 | 726 | void bcmgenet_phy_power_set(struct net_device *dev, bool enable); |
| 726 | 727 | void bcmgenet_mii_setup(struct net_device *dev); |
| @@ -173,6 +173,46 @@ static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv) · 172 unmodified lines | ||
| 173 | 173 | bcmgenet_fixed_phy_link_update); |
| 174 | 174 | } |
| 175 | 175 | |
| 176 | +int bcmgenet_mii_connect(struct net_device *dev) | |
| 177 | +{ | |
| 178 | + struct bcmgenet_priv *priv = netdev_priv(dev); | |
| 179 | + struct device_node *dn = priv->pdev->dev.of_node; | |
| 180 | + struct phy_device *phydev; | |
| 181 | + u32 phy_flags = 0; | |
| 182 | + int ret; | |
| 183 | + | |
| 184 | + /* Communicate the integrated PHY revision */ | |
| 185 | + if (priv->internal_phy) | |
| 186 | + phy_flags = priv->gphy_rev; | |
| 187 | + | |
| 188 | + /* Initialize link state variables that bcmgenet_mii_setup() uses */ | |
| 189 | + priv->old_link = -1; | |
| 190 | + priv->old_speed = -1; | |
| 191 | + priv->old_duplex = -1; | |
| 192 | + priv->old_pause = -1; | |
| 193 | + | |
| 194 | + if (dn) { | |
| 195 | + phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup, | |
| 196 | + phy_flags, priv->phy_interface); | |
| 197 | + if (!phydev) { | |
| 198 | + pr_err("could not attach to PHY\n"); | |
| 199 | + return -ENODEV; | |
| 200 | + } | |
| 201 | + } else { | |
| 202 | + phydev = dev->phydev; | |
| 203 | + phydev->dev_flags = phy_flags; | |
| 204 | + | |
| 205 | + ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup, | |
| 206 | + priv->phy_interface); | |
| 207 | + if (ret) { | |
| 208 | + pr_err("could not attach to PHY\n"); | |
| 209 | + return -ENODEV; | |
| 210 | + } | |
| 211 | + } | |
| 212 | + | |
| 213 | + return 0; | |
| 214 | +} | |
| 215 | + | |
| 176 | 216 | int bcmgenet_mii_config(struct net_device *dev, bool init) |
| 177 | 217 | { |
| 178 | 218 | struct bcmgenet_priv *priv = netdev_priv(dev); |
| @@ -258,74 +298,29 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) · 79 unmodified lines | ||
| 258 | 298 | */ |
| 259 | 299 | if (priv->ext_phy) { |
| 260 | 300 | reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL); |
| 261 | − reg |= RGMII_MODE_EN | id_mode_dis; | |
| 301 | + reg |= id_mode_dis; | |
| 302 | + if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv)) | |
| 303 | + reg |= RGMII_MODE_EN_V123; | |
| 304 | + else | |
| 305 | + reg |= RGMII_MODE_EN; | |
| 262 | 306 | bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); |
| 263 | 307 | } |
| 264 | 308 | |
| 265 | − if (init) | |
| 266 | − dev_info(kdev, "configuring instance for %s\n", phy_name); | |
| 267 | − | |
| 268 | − return 0; | |
| 269 | −} | |
| 270 | − | |
| 271 | −int bcmgenet_mii_probe(struct net_device *dev) | |
| 272 | −{ | |
| 273 | − struct bcmgenet_priv *priv = netdev_priv(dev); | |
| 274 | − struct device_node *dn = priv->pdev->dev.of_node; | |
| 275 | − struct phy_device *phydev; | |
| 276 | − u32 phy_flags; | |
| 277 | − int ret; | |
| 278 | − | |
| 279 | − /* Communicate the integrated PHY revision */ | |
| 280 | − phy_flags = priv->gphy_rev; | |
| 281 | − | |
| 282 | − /* Initialize link state variables that bcmgenet_mii_setup() uses */ | |
| 283 | − priv->old_link = -1; | |
| 284 | − priv->old_speed = -1; | |
| 285 | − priv->old_duplex = -1; | |
| 286 | − priv->old_pause = -1; | |
| 287 | − | |
| 288 | − if (dn) { | |
| 289 | − phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup, | |
| 290 | − phy_flags, priv->phy_interface); | |
| 291 | − if (!phydev) { | |
| 292 | − pr_err("could not attach to PHY\n"); | |
| 293 | − return -ENODEV; | |
| 294 | − } | |
| 295 | − } else { | |
| 296 | − phydev = dev->phydev; | |
| 297 | − phydev->dev_flags = phy_flags; | |
| 309 | + if (init) { | |
| 310 | + linkmode_copy(phydev->advertising, phydev->supported); | |
| 298 | 311 | |
| 299 | − ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup, | |
| 300 | − priv->phy_interface); | |
| 301 | − if (ret) { | |
| 302 | − pr_err("could not attach to PHY\n"); | |
| 303 | − return -ENODEV; | |
| 304 | − } | |
| 305 | − } | |
| 312 | + /* The internal PHY has its link interrupts routed to the | |
| 313 | + * Ethernet MAC ISRs. On GENETv5 there is a hardware issue | |
| 314 | + * that prevents the signaling of link UP interrupts when | |
| 315 | + * the link operates at 10Mbps, so fallback to polling for | |
| 316 | + * those versions of GENET. | |
| 317 | + */ | |
| 318 | + if (priv->internal_phy && !GENET_IS_V5(priv)) | |
| 319 | + phydev->irq = PHY_IGNORE_INTERRUPT; | |
| 306 | 320 | |
| 307 | − /* Configure port multiplexer based on what the probed PHY device since | |
| 308 | − * reading the 'max-speed' property determines the maximum supported | |
| 309 | − * PHY speed which is needed for bcmgenet_mii_config() to configure | |
| 310 | − * things appropriately. | |
| 311 | − */ | |
| 312 | − ret = bcmgenet_mii_config(dev, true); | |
| 313 | − if (ret) { | |
| 314 | − phy_disconnect(dev->phydev); | |
| 315 | − return ret; | |
| 321 | + dev_info(kdev, "configuring instance for %s\n", phy_name); | |
| 316 | 322 | } |
| 317 | 323 | |
| 318 | − linkmode_copy(phydev->advertising, phydev->supported); | |
| 319 | − | |
| 320 | − /* The internal PHY has its link interrupts routed to the | |
| 321 | − * Ethernet MAC ISRs. On GENETv5 there is a hardware issue | |
| 322 | − * that prevents the signaling of link UP interrupts when | |
| 323 | − * the link operates at 10Mbps, so fallback to polling for | |
| 324 | − * those versions of GENET. | |
| 325 | − */ | |
| 326 | − if (priv->internal_phy && !GENET_IS_V5(priv)) | |
| 327 | − dev->phydev->irq = PHY_IGNORE_INTERRUPT; | |
| 328 | − | |
| 329 | 324 | return 0; |
| 330 | 325 | } |
| 331 | 326 | |
| @@ -3405,17 +3405,17 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk, · 3404 unmodified lines | ||
| 3405 | 3405 | return err; |
| 3406 | 3406 | } |
| 3407 | 3407 | |
| 3408 | − *tx_clk = devm_clk_get(&pdev->dev, "tx_clk"); | |
| 3408 | + *tx_clk = devm_clk_get_optional(&pdev->dev, "tx_clk"); | |
| 3409 | 3409 | if (IS_ERR(*tx_clk)) |
| 3410 | − *tx_clk = NULL; | |
| 3410 | + return PTR_ERR(*tx_clk); | |
| 3411 | 3411 | |
| 3412 | − *rx_clk = devm_clk_get(&pdev->dev, "rx_clk"); | |
| 3412 | + *rx_clk = devm_clk_get_optional(&pdev->dev, "rx_clk"); | |
| 3413 | 3413 | if (IS_ERR(*rx_clk)) |
| 3414 | − *rx_clk = NULL; | |
| 3414 | + return PTR_ERR(*rx_clk); | |
| 3415 | 3415 | |
| 3416 | − *tsu_clk = devm_clk_get(&pdev->dev, "tsu_clk"); | |
| 3416 | + *tsu_clk = devm_clk_get_optional(&pdev->dev, "tsu_clk"); | |
| 3417 | 3417 | if (IS_ERR(*tsu_clk)) |
| 3418 | − *tsu_clk = NULL; | |
| 3418 | + return PTR_ERR(*tsu_clk); | |
| 3419 | 3419 | |
| 3420 | 3420 | err = clk_prepare_enable(*pclk); |
| 3421 | 3421 | if (err) { |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ | |
| 2 | 2 | /* cavium_ptp.h - PTP 1588 clock on Cavium hardware |
| 3 | 3 | * Copyright (c) 2003-2015, 2017 Cavium, Inc. |
| 4 | 4 | */ |
| @@ -1235,6 +1235,8 @@ static void dpaa2_eth_set_rx_taildrop(struct dpaa2_eth_priv *priv, bool enable) · 1234 unmodified lines | ||
| 1235 | 1235 | priv->rx_td_enabled = enable; |
| 1236 | 1236 | } |
| 1237 | 1237 | |
| 1238 | +static void update_tx_fqids(struct dpaa2_eth_priv *priv); | |
| 1239 | + | |
| 1238 | 1240 | static int link_state_update(struct dpaa2_eth_priv *priv) |
| 1239 | 1241 | { |
| 1240 | 1242 | struct dpni_link_state state = {0}; |
| @@ -1261,6 +1263,7 @@ static int link_state_update(struct dpaa2_eth_priv *priv) · 20 unmodified lines | ||
| 1261 | 1263 | goto out; |
| 1262 | 1264 | |
| 1263 | 1265 | if (state.up) { |
| 1266 | + update_tx_fqids(priv); | |
| 1264 | 1267 | netif_carrier_on(priv->net_dev); |
| 1265 | 1268 | netif_tx_start_all_queues(priv->net_dev); |
| 1266 | 1269 | } else { |
| @@ -2533,6 +2536,47 @@ static int set_pause(struct dpaa2_eth_priv *priv) · 1266 unmodified lines | ||
| 2533 | 2536 | return 0; |
| 2534 | 2537 | } |
| 2535 | 2538 | |
| 2539 | +static void update_tx_fqids(struct dpaa2_eth_priv *priv) | |
| 2540 | +{ | |
| 2541 | + struct dpni_queue_id qid = {0}; | |
| 2542 | + struct dpaa2_eth_fq *fq; | |
| 2543 | + struct dpni_queue queue; | |
| 2544 | + int i, j, err; | |
| 2545 | + | |
| 2546 | + /* We only use Tx FQIDs for FQID-based enqueue, so check | |
| 2547 | + * if DPNI version supports it before updating FQIDs | |
| 2548 | + */ | |
| 2549 | + if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_ENQUEUE_FQID_VER_MAJOR, | |
| 2550 | + DPNI_ENQUEUE_FQID_VER_MINOR) < 0) | |
| 2551 | + return; | |
| 2552 | + | |
| 2553 | + for (i = 0; i < priv->num_fqs; i++) { | |
| 2554 | + fq = &priv->fq[i]; | |
| 2555 | + if (fq->type != DPAA2_TX_CONF_FQ) | |
| 2556 | + continue; | |
| 2557 | + for (j = 0; j < dpaa2_eth_tc_count(priv); j++) { | |
| 2558 | + err = dpni_get_queue(priv->mc_io, 0, priv->mc_token, | |
| 2559 | + DPNI_QUEUE_TX, j, fq->flowid, | |
| 2560 | + &queue, &qid); | |
| 2561 | + if (err) | |
| 2562 | + goto out_err; | |
| 2563 | + | |
| 2564 | + fq->tx_fqid[j] = qid.fqid; | |
| 2565 | + if (fq->tx_fqid[j] == 0) | |
| 2566 | + goto out_err; | |
| 2567 | + } | |
| 2568 | + } | |
| 2569 | + | |
| 2570 | + priv->enqueue = dpaa2_eth_enqueue_fq; | |
| 2571 | + | |
| 2572 | + return; | |
| 2573 | + | |
| 2574 | +out_err: | |
| 2575 | + netdev_info(priv->net_dev, | |
| 2576 | + "Error reading Tx FQID, fallback to QDID-based enqueue\n"); | |
| 2577 | + priv->enqueue = dpaa2_eth_enqueue_qd; | |
| 2578 | +} | |
| 2579 | + | |
| 2536 | 2580 | /* Configure the DPNI object this interface is associated with */ |
| 2537 | 2581 | static int setup_dpni(struct fsl_mc_device *ls_dev) |
| 2538 | 2582 | { |
| @@ -3306,6 +3350,9 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg) · 767 unmodified lines | ||
| 3306 | 3350 | if (status & DPNI_IRQ_EVENT_LINK_CHANGED) |
| 3307 | 3351 | link_state_update(netdev_priv(net_dev)); |
| 3308 | 3352 | |
| 3353 | + if (status & DPNI_IRQ_EVENT_ENDPOINT_CHANGED) | |
| 3354 | + set_mac_addr(netdev_priv(net_dev)); | |
| 3355 | + | |
| 3309 | 3356 | return IRQ_HANDLED; |
| 3310 | 3357 | } |
| 3311 | 3358 | |
| @@ -3331,7 +3378,8 @@ static int setup_irqs(struct fsl_mc_device *ls_dev) · 19 unmodified lines | ||
| 3331 | 3378 | } |
| 3332 | 3379 | |
| 3333 | 3380 | err = dpni_set_irq_mask(ls_dev->mc_io, 0, ls_dev->mc_handle, |
| 3334 | − DPNI_IRQ_INDEX, DPNI_IRQ_EVENT_LINK_CHANGED); | |
| 3381 | + DPNI_IRQ_INDEX, DPNI_IRQ_EVENT_LINK_CHANGED | | |
| 3382 | + DPNI_IRQ_EVENT_ENDPOINT_CHANGED); | |
| 3335 | 3383 | if (err < 0) { |
| 3336 | 3384 | dev_err(&ls_dev->dev, "dpni_set_irq_mask(): %d\n", err); |
| 3337 | 3385 | goto free_irq; |
| @@ -133,9 +133,12 @@ int dpni_reset(struct fsl_mc_io *mc_io, · 132 unmodified lines | ||
| 133 | 133 | */ |
| 134 | 134 | #define DPNI_IRQ_INDEX 0 |
| 135 | 135 | /** |
| 136 | − * IRQ event - indicates a change in link state | |
| 136 | + * IRQ events: | |
| 137 | + * indicates a change in link state | |
| 138 | + * indicates a change in endpoint | |
| 137 | 139 | */ |
| 138 | 140 | #define DPNI_IRQ_EVENT_LINK_CHANGED 0x00000001 |
| 141 | +#define DPNI_IRQ_EVENT_ENDPOINT_CHANGED 0x00000002 | |
| 139 | 142 | |
| 140 | 143 | int dpni_set_irq_enable(struct fsl_mc_io *mc_io, |
| 141 | 144 | u32 cmd_flags, |
| @@ -32,6 +32,8 @@ · 31 unmodified lines | ||
| 32 | 32 | |
| 33 | 33 | #define HNAE3_MOD_VERSION "1.0" |
| 34 | 34 | |
| 35 | +#define HNAE3_MIN_VECTOR_NUM 2 /* first one for misc, another for IO */ | |
| 36 | + | |
| 35 | 37 | /* Device IDs */ |
| 36 | 38 | #define HNAE3_DEV_ID_GE 0xA220 |
| 37 | 39 | #define HNAE3_DEV_ID_25GE 0xA221 |
| @@ -906,6 +906,9 @@ static int hclge_query_pf_resource(struct hclge_dev *hdev) · 905 unmodified lines | ||
| 906 | 906 | hnae3_get_field(__le16_to_cpu(req->pf_intr_vector_number), |
| 907 | 907 | HCLGE_PF_VEC_NUM_M, HCLGE_PF_VEC_NUM_S); |
| 908 | 908 | |
| 909 | + /* nic's msix numbers is always equals to the roce's. */ | |
| 910 | + hdev->num_nic_msi = hdev->num_roce_msi; | |
| 911 | + | |
| 909 | 912 | /* PF should have NIC vectors and Roce vectors, |
| 910 | 913 | * NIC vectors are queued before Roce vectors. |
| 911 | 914 | */ |
| @@ -915,6 +918,15 @@ static int hclge_query_pf_resource(struct hclge_dev *hdev) · 3 unmodified lines | ||
| 915 | 918 | hdev->num_msi = |
| 916 | 919 | hnae3_get_field(__le16_to_cpu(req->pf_intr_vector_number), |
| 917 | 920 | HCLGE_PF_VEC_NUM_M, HCLGE_PF_VEC_NUM_S); |
| 921 | + | |
| 922 | + hdev->num_nic_msi = hdev->num_msi; | |
| 923 | + } | |
| 924 | + | |
| 925 | + if (hdev->num_nic_msi < HNAE3_MIN_VECTOR_NUM) { | |
| 926 | + dev_err(&hdev->pdev->dev, | |
| 927 | + "Just %u msi resources, not enough for pf(min:2).\n", | |
| 928 | + hdev->num_nic_msi); | |
| 929 | + return -EINVAL; | |
| 918 | 930 | } |
| 919 | 931 | |
| 920 | 932 | return 0; |
| @@ -1507,6 +1519,10 @@ static int hclge_assign_tqp(struct hclge_vport *vport, u16 num_tqps) · 586 unmodified lines | ||
| 1507 | 1519 | kinfo->rss_size = min_t(u16, hdev->rss_size_max, |
| 1508 | 1520 | vport->alloc_tqps / hdev->tm_info.num_tc); |
| 1509 | 1521 | |
| 1522 | + /* ensure one to one mapping between irq and queue at default */ | |
| 1523 | + kinfo->rss_size = min_t(u16, kinfo->rss_size, | |
| 1524 | + (hdev->num_nic_msi - 1) / hdev->tm_info.num_tc); | |
| 1525 | + | |
| 1510 | 1526 | return 0; |
| 1511 | 1527 | } |
| 1512 | 1528 | |
| @@ -2285,7 +2301,8 @@ static int hclge_init_msi(struct hclge_dev *hdev) · 772 unmodified lines | ||
| 2285 | 2301 | int vectors; |
| 2286 | 2302 | int i; |
| 2287 | 2303 | |
| 2288 | − vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi, | |
| 2304 | + vectors = pci_alloc_irq_vectors(pdev, HNAE3_MIN_VECTOR_NUM, | |
| 2305 | + hdev->num_msi, | |
| 2289 | 2306 | PCI_IRQ_MSI | PCI_IRQ_MSIX); |
| 2290 | 2307 | if (vectors < 0) { |
| 2291 | 2308 | dev_err(&pdev->dev, |
| @@ -2300,6 +2317,7 @@ static int hclge_init_msi(struct hclge_dev *hdev) · 8 unmodified lines | ||
| 2300 | 2317 | |
| 2301 | 2318 | hdev->num_msi = vectors; |
| 2302 | 2319 | hdev->num_msi_left = vectors; |
| 2320 | + | |
| 2303 | 2321 | hdev->base_msi_vector = pdev->irq; |
| 2304 | 2322 | hdev->roce_base_vector = hdev->base_msi_vector + |
| 2305 | 2323 | hdev->roce_base_msix_offset; |
| @@ -3903,6 +3921,7 @@ static int hclge_get_vector(struct hnae3_handle *handle, u16 vector_num, · 1597 unmodified lines | ||
| 3903 | 3921 | int alloc = 0; |
| 3904 | 3922 | int i, j; |
| 3905 | 3923 | |
| 3924 | + vector_num = min_t(u16, hdev->num_nic_msi - 1, vector_num); | |
| 3906 | 3925 | vector_num = min(hdev->num_msi_left, vector_num); |
| 3907 | 3926 | |
| 3908 | 3927 | for (j = 0; j < vector_num; j++) { |
| @@ -763,6 +763,7 @@ struct hclge_dev { · 762 unmodified lines | ||
| 763 | 763 | u32 base_msi_vector; |
| 764 | 764 | u16 *vector_status; |
| 765 | 765 | int *vector_irq; |
| 766 | + u16 num_nic_msi; /* Num of nic vectors for this PF */ | |
| 766 | 767 | u16 num_roce_msi; /* Num of roce vectors for this PF */ |
| 767 | 768 | int roce_base_vector; |
| 768 | 769 | |
| @@ -537,9 +537,16 @@ static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) · 536 unmodified lines | ||
| 537 | 537 | kinfo->rss_size = kinfo->req_rss_size; |
| 538 | 538 | } else if (kinfo->rss_size > max_rss_size || |
| 539 | 539 | (!kinfo->req_rss_size && kinfo->rss_size < max_rss_size)) { |
| 540 | + /* if user not set rss, the rss_size should compare with the | |
| 541 | + * valid msi numbers to ensure one to one map between tqp and | |
| 542 | + * irq as default. | |
| 543 | + */ | |
| 544 | + if (!kinfo->req_rss_size) | |
| 545 | + max_rss_size = min_t(u16, max_rss_size, | |
| 546 | + (hdev->num_nic_msi - 1) / | |
| 547 | + kinfo->num_tc); | |
| 548 | + | |
| 540 | 549 | /* Set to the maximum specification value (max_rss_size). */ |
| 541 | − dev_info(&hdev->pdev->dev, "rss changes from %d to %d\n", | |
| 542 | − kinfo->rss_size, max_rss_size); | |
| 543 | 550 | kinfo->rss_size = max_rss_size; |
| 544 | 551 | } |
| 545 | 552 | |
| @@ -411,6 +411,13 @@ static int hclgevf_knic_setup(struct hclgevf_dev *hdev) · 410 unmodified lines | ||
| 411 | 411 | kinfo->tqp[i] = &hdev->htqp[i].q; |
| 412 | 412 | } |
| 413 | 413 | |
| 414 | + /* after init the max rss_size and tqps, adjust the default tqp numbers | |
| 415 | + * and rss size with the actual vector numbers | |
| 416 | + */ | |
| 417 | + kinfo->num_tqps = min_t(u16, hdev->num_nic_msix - 1, kinfo->num_tqps); | |
| 418 | + kinfo->rss_size = min_t(u16, kinfo->num_tqps / kinfo->num_tc, | |
| 419 | + kinfo->rss_size); | |
| 420 | + | |
| 414 | 421 | return 0; |
| 415 | 422 | } |
| 416 | 423 | |
| @@ -502,6 +509,7 @@ static int hclgevf_get_vector(struct hnae3_handle *handle, u16 vector_num, · 85 unmodified lines | ||
| 502 | 509 | int alloc = 0; |
| 503 | 510 | int i, j; |
| 504 | 511 | |
| 512 | + vector_num = min_t(u16, hdev->num_nic_msix - 1, vector_num); | |
| 505 | 513 | vector_num = min(hdev->num_msi_left, vector_num); |
| 506 | 514 | |
| 507 | 515 | for (j = 0; j < vector_num; j++) { |
| @@ -2246,13 +2254,14 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev) · 1738 unmodified lines | ||
| 2246 | 2254 | int vectors; |
| 2247 | 2255 | int i; |
| 2248 | 2256 | |
| 2249 | − if (hnae3_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_ROCE_B)) | |
| 2257 | + if (hnae3_dev_roce_supported(hdev)) | |
| 2250 | 2258 | vectors = pci_alloc_irq_vectors(pdev, |
| 2251 | 2259 | hdev->roce_base_msix_offset + 1, |
| 2252 | 2260 | hdev->num_msi, |
| 2253 | 2261 | PCI_IRQ_MSIX); |
| 2254 | 2262 | else |
| 2255 | − vectors = pci_alloc_irq_vectors(pdev, 1, hdev->num_msi, | |
| 2263 | + vectors = pci_alloc_irq_vectors(pdev, HNAE3_MIN_VECTOR_NUM, | |
| 2264 | + hdev->num_msi, | |
| 2256 | 2265 | PCI_IRQ_MSI | PCI_IRQ_MSIX); |
| 2257 | 2266 | |
| 2258 | 2267 | if (vectors < 0) { |
| @@ -2268,6 +2277,7 @@ static int hclgevf_init_msi(struct hclgevf_dev *hdev) · 9 unmodified lines | ||
| 2268 | 2277 | |
| 2269 | 2278 | hdev->num_msi = vectors; |
| 2270 | 2279 | hdev->num_msi_left = vectors; |
| 2280 | + | |
| 2271 | 2281 | hdev->base_msi_vector = pdev->irq; |
| 2272 | 2282 | hdev->roce_base_vector = pdev->irq + hdev->roce_base_msix_offset; |
| 2273 | 2283 | |
| @@ -2533,7 +2543,7 @@ static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev) · 259 unmodified lines | ||
| 2533 | 2543 | |
| 2534 | 2544 | req = (struct hclgevf_query_res_cmd *)desc.data; |
| 2535 | 2545 | |
| 2536 | − if (hnae3_get_bit(hdev->ae_dev->flag, HNAE3_DEV_SUPPORT_ROCE_B)) { | |
| 2546 | + if (hnae3_dev_roce_supported(hdev)) { | |
| 2537 | 2547 | hdev->roce_base_msix_offset = |
| 2538 | 2548 | hnae3_get_field(__le16_to_cpu(req->msixcap_localid_ba_rocee), |
| 2539 | 2549 | HCLGEVF_MSIX_OFT_ROCEE_M, |
| @@ -2542,6 +2552,9 @@ static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev) · 2 unmodified lines | ||
| 2542 | 2552 | hnae3_get_field(__le16_to_cpu(req->vf_intr_vector_number), |
| 2543 | 2553 | HCLGEVF_VEC_NUM_M, HCLGEVF_VEC_NUM_S); |
| 2544 | 2554 | |
| 2555 | + /* nic's msix numbers is always equals to the roce's. */ | |
| 2556 | + hdev->num_nic_msix = hdev->num_roce_msix; | |
| 2557 | + | |
| 2545 | 2558 | /* VF should have NIC vectors and Roce vectors, NIC vectors |
| 2546 | 2559 | * are queued before Roce vectors. The offset is fixed to 64. |
| 2547 | 2560 | */ |
| @@ -2551,6 +2564,15 @@ static int hclgevf_query_vf_resource(struct hclgevf_dev *hdev) · 3 unmodified lines | ||
| 2551 | 2564 | hdev->num_msi = |
| 2552 | 2565 | hnae3_get_field(__le16_to_cpu(req->vf_intr_vector_number), |
| 2553 | 2566 | HCLGEVF_VEC_NUM_M, HCLGEVF_VEC_NUM_S); |
| 2567 | + | |
| 2568 | + hdev->num_nic_msix = hdev->num_msi; | |
| 2569 | + } | |
| 2570 | + | |
| 2571 | + if (hdev->num_nic_msix < HNAE3_MIN_VECTOR_NUM) { | |
| 2572 | + dev_err(&hdev->pdev->dev, | |
| 2573 | + "Just %u msi resources, not enough for vf(min:2).\n", | |
| 2574 | + hdev->num_nic_msix); | |
| 2575 | + return -EINVAL; | |
| 2554 | 2576 | } |
| 2555 | 2577 | |
| 2556 | 2578 | return 0; |
| @@ -270,6 +270,7 @@ struct hclgevf_dev { · 269 unmodified lines | ||
| 270 | 270 | u16 num_msi; |
| 271 | 271 | u16 num_msi_left; |
| 272 | 272 | u16 num_msi_used; |
| 273 | + u16 num_nic_msix; /* Num of nic vectors for this VF */ | |
| 273 | 274 | u16 num_roce_msix; /* Num of roce vectors for this VF */ |
| 274 | 275 | u16 roce_base_msix_offset; |
| 275 | 276 | int roce_base_vector; |
| @@ -96,6 +96,8 @@ · 95 unmodified lines | ||
| 96 | 96 | |
| 97 | 97 | #define OPT_SWAP_PORT 0x0001 /* Need to wordswp on the MPU port */ |
| 98 | 98 | |
| 99 | +#define LIB82596_DMA_ATTR DMA_ATTR_NON_CONSISTENT | |
| 100 | + | |
| 99 | 101 | #define DMA_WBACK(ndev, addr, len) \ |
| 100 | 102 | do { dma_cache_sync((ndev)->dev.parent, (void *)addr, len, DMA_TO_DEVICE); } while (0) |
| 101 | 103 | |
| @@ -200,7 +202,7 @@ static int __exit lan_remove_chip(struct parisc_device *pdev) · 98 unmodified lines | ||
| 200 | 202 | |
| 201 | 203 | unregister_netdev (dev); |
| 202 | 204 | dma_free_attrs(&pdev->dev, sizeof(struct i596_private), lp->dma, |
| 203 | − lp->dma_addr, DMA_ATTR_NON_CONSISTENT); | |
| 205 | + lp->dma_addr, LIB82596_DMA_ATTR); | |
| 204 | 206 | free_netdev (dev); |
| 205 | 207 | return 0; |
| 206 | 208 | } |
| @@ -1065,7 +1065,7 @@ static int i82596_probe(struct net_device *dev) · 1064 unmodified lines | ||
| 1065 | 1065 | |
| 1066 | 1066 | dma = dma_alloc_attrs(dev->dev.parent, sizeof(struct i596_dma), |
| 1067 | 1067 | &lp->dma_addr, GFP_KERNEL, |
| 1068 | − DMA_ATTR_NON_CONSISTENT); | |
| 1068 | + LIB82596_DMA_ATTR); | |
| 1069 | 1069 | if (!dma) { |
| 1070 | 1070 | printk(KERN_ERR "%s: Couldn't get shared memory\n", __FILE__); |
| 1071 | 1071 | return -ENOMEM; |
| @@ -1087,7 +1087,7 @@ static int i82596_probe(struct net_device *dev) · 15 unmodified lines | ||
| 1087 | 1087 | i = register_netdev(dev); |
| 1088 | 1088 | if (i) { |
| 1089 | 1089 | dma_free_attrs(dev->dev.parent, sizeof(struct i596_dma), |
| 1090 | − dma, lp->dma_addr, DMA_ATTR_NON_CONSISTENT); | |
| 1090 | + dma, lp->dma_addr, LIB82596_DMA_ATTR); | |
| 1091 | 1091 | return i; |
| 1092 | 1092 | } |
| 1093 | 1093 | |
| @@ -24,6 +24,8 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | static const char sni_82596_string[] = "snirm_82596"; |
| 26 | 26 | |
| 27 | +#define LIB82596_DMA_ATTR 0 | |
| 28 | + | |
| 27 | 29 | #define DMA_WBACK(priv, addr, len) do { } while (0) |
| 28 | 30 | #define DMA_INV(priv, addr, len) do { } while (0) |
| 29 | 31 | #define DMA_WBACK_INV(priv, addr, len) do { } while (0) |
| @@ -152,7 +154,7 @@ static int sni_82596_driver_remove(struct platform_device *pdev) · 122 unmodified lines | ||
| 152 | 154 | |
| 153 | 155 | unregister_netdev(dev); |
| 154 | 156 | dma_free_attrs(dev->dev.parent, sizeof(struct i596_private), lp->dma, |
| 155 | − lp->dma_addr, DMA_ATTR_NON_CONSISTENT); | |
| 157 | + lp->dma_addr, LIB82596_DMA_ATTR); | |
| 156 | 158 | iounmap(lp->ca); |
| 157 | 159 | iounmap(lp->mpu_port); |
| 158 | 160 | free_netdev (dev); |
| @@ -2878,12 +2878,10 @@ static int enable_scrq_irq(struct ibmvnic_adapter *adapter, · 2877 unmodified lines | ||
| 2878 | 2878 | |
| 2879 | 2879 | if (test_bit(0, &adapter->resetting) && |
| 2880 | 2880 | adapter->reset_reason == VNIC_RESET_MOBILITY) { |
| 2881 | − u64 val = (0xff000000) | scrq->hw_irq; | |
| 2881 | + struct irq_desc *desc = irq_to_desc(scrq->irq); | |
| 2882 | + struct irq_chip *chip = irq_desc_get_chip(desc); | |
| 2882 | 2883 | |
| 2883 | − rc = plpar_hcall_norets(H_EOI, val); | |
| 2884 | − if (rc) | |
| 2885 | − dev_err(dev, "H_EOI FAILED irq 0x%llx. rc=%ld\n", | |
| 2886 | − val, rc); | |
| 2884 | + chip->irq_eoi(&desc->irq_data); | |
| 2887 | 2885 | } |
| 2888 | 2886 | |
| 2889 | 2887 | rc = plpar_hcall_norets(H_VIOCTL, adapter->vdev->unit_address, |
| @@ -261,6 +261,7 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, · 260 unmodified lines | ||
| 261 | 261 | ge_mode = 0; |
| 262 | 262 | switch (state->interface) { |
| 263 | 263 | case PHY_INTERFACE_MODE_MII: |
| 264 | + case PHY_INTERFACE_MODE_GMII: | |
| 264 | 265 | ge_mode = 1; |
| 265 | 266 | break; |
| 266 | 267 | case PHY_INTERFACE_MODE_REVMII: |
| @@ -112,17 +112,11 @@ int mlx5_core_destroy_mkey(struct mlx5_core_dev *dev, · 111 unmodified lines | ||
| 112 | 112 | u32 out[MLX5_ST_SZ_DW(destroy_mkey_out)] = {0}; |
| 113 | 113 | u32 in[MLX5_ST_SZ_DW(destroy_mkey_in)] = {0}; |
| 114 | 114 | struct xarray *mkeys = &dev->priv.mkey_table; |
| 115 | − struct mlx5_core_mkey *deleted_mkey; | |
| 116 | 115 | unsigned long flags; |
| 117 | 116 | |
| 118 | 117 | xa_lock_irqsave(mkeys, flags); |
| 119 | − deleted_mkey = __xa_erase(mkeys, mlx5_base_mkey(mkey->key)); | |
| 118 | + __xa_erase(mkeys, mlx5_base_mkey(mkey->key)); | |
| 120 | 119 | xa_unlock_irqrestore(mkeys, flags); |
| 121 | − if (!deleted_mkey) { | |
| 122 | − mlx5_core_dbg(dev, "failed xarray delete of mkey 0x%x\n", | |
| 123 | − mlx5_base_mkey(mkey->key)); | |
| 124 | − return -ENOENT; | |
| 125 | − } | |
| 126 | 120 | |
| 127 | 121 | MLX5_SET(destroy_mkey_in, in, opcode, MLX5_CMD_OP_DESTROY_MKEY); |
| 128 | 122 | MLX5_SET(destroy_mkey_in, in, mkey_index, mlx5_mkey_to_idx(mkey->key)); |
| @@ -788,12 +788,10 @@ again: · 787 unmodified lines | ||
| 788 | 788 | * it means that all the previous stes are the same, |
| 789 | 789 | * if so, this rule is duplicated. |
| 790 | 790 | */ |
| 791 | − if (mlx5dr_ste_is_last_in_rule(nic_matcher, | |
| 792 | − matched_ste->ste_chain_location)) { | |
| 793 | − mlx5dr_info(dmn, "Duplicate rule inserted, aborting!!\n"); | |
| 794 | − return NULL; | |
| 795 | − } | |
| 796 | − return matched_ste; | |
| 791 | + if (!mlx5dr_ste_is_last_in_rule(nic_matcher, ste_location)) | |
| 792 | + return matched_ste; | |
| 793 | + | |
| 794 | + mlx5dr_dbg(dmn, "Duplicate rule inserted\n"); | |
| 797 | 795 | } |
| 798 | 796 | |
| 799 | 797 | if (!skip_rehash && dr_rule_need_enlarge_hash(cur_htbl, dmn, nic_dmn)) { |
| @@ -99,6 +99,7 @@ static void mlxsw_sp_rx_drop_listener(struct sk_buff *skb, u8 local_port, · 98 unmodified lines | ||
| 99 | 99 | devlink = priv_to_devlink(mlxsw_sp->core); |
| 100 | 100 | in_devlink_port = mlxsw_core_port_devlink_port_get(mlxsw_sp->core, |
| 101 | 101 | local_port); |
| 102 | + skb_push(skb, ETH_HLEN); | |
| 102 | 103 | devlink_trap_report(devlink, skb, trap_ctx, in_devlink_port); |
| 103 | 104 | consume_skb(skb); |
| 104 | 105 | } |
| @@ -1356,9 +1356,6 @@ static int lpc_eth_drv_probe(struct platform_device *pdev) · 1355 unmodified lines | ||
| 1356 | 1356 | if (!is_valid_ether_addr(ndev->dev_addr)) |
| 1357 | 1357 | eth_hw_addr_random(ndev); |
| 1358 | 1358 | |
| 1359 | − /* Reset the ethernet controller */ | |
| 1360 | − __lpc_eth_reset(pldat); | |
| 1361 | − | |
| 1362 | 1359 | /* then shut everything down to save power */ |
| 1363 | 1360 | __lpc_eth_shutdown(pldat); |
| 1364 | 1361 | |
| @@ -182,6 +182,8 @@ struct ionic_lif { · 181 unmodified lines | ||
| 182 | 182 | |
| 183 | 183 | #define lif_to_txqcq(lif, i) ((lif)->txqcqs[i].qcq) |
| 184 | 184 | #define lif_to_rxqcq(lif, i) ((lif)->rxqcqs[i].qcq) |
| 185 | +#define lif_to_txstats(lif, i) ((lif)->txqcqs[i].stats->tx) | |
| 186 | +#define lif_to_rxstats(lif, i) ((lif)->rxqcqs[i].stats->rx) | |
| 185 | 187 | #define lif_to_txq(lif, i) (&lif_to_txqcq((lif), i)->q) |
| 186 | 188 | #define lif_to_rxq(lif, i) (&lif_to_txqcq((lif), i)->q) |
| 187 | 189 | |
| @@ -117,7 +117,8 @@ static u64 ionic_sw_stats_get_count(struct ionic_lif *lif) · 116 unmodified lines | ||
| 117 | 117 | /* rx stats */ |
| 118 | 118 | total += MAX_Q(lif) * IONIC_NUM_RX_STATS; |
| 119 | 119 | |
| 120 | − if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { | |
| 120 | + if (test_bit(IONIC_LIF_UP, lif->state) && | |
| 121 | + test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { | |
| 121 | 122 | /* tx debug stats */ |
| 122 | 123 | total += MAX_Q(lif) * (IONIC_NUM_DBG_CQ_STATS + |
| 123 | 124 | IONIC_NUM_TX_Q_STATS + |
| @@ -149,7 +150,8 @@ static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf) · 25 unmodified lines | ||
| 149 | 150 | *buf += ETH_GSTRING_LEN; |
| 150 | 151 | } |
| 151 | 152 | |
| 152 | − if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { | |
| 153 | + if (test_bit(IONIC_LIF_UP, lif->state) && | |
| 154 | + test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { | |
| 153 | 155 | for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) { |
| 154 | 156 | snprintf(*buf, ETH_GSTRING_LEN, |
| 155 | 157 | "txq_%d_%s", |
| @@ -187,7 +189,8 @@ static void ionic_sw_stats_get_strings(struct ionic_lif *lif, u8 **buf) · 31 unmodified lines | ||
| 187 | 189 | *buf += ETH_GSTRING_LEN; |
| 188 | 190 | } |
| 189 | 191 | |
| 190 | − if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { | |
| 192 | + if (test_bit(IONIC_LIF_UP, lif->state) && | |
| 193 | + test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { | |
| 191 | 194 | for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) { |
| 192 | 195 | snprintf(*buf, ETH_GSTRING_LEN, |
| 193 | 196 | "rxq_%d_cq_%s", |
| @@ -223,6 +226,8 @@ static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf) · 29 unmodified lines | ||
| 223 | 226 | { |
| 224 | 227 | struct ionic_lif_sw_stats lif_stats; |
| 225 | 228 | struct ionic_qcq *txqcq, *rxqcq; |
| 229 | + struct ionic_tx_stats *txstats; | |
| 230 | + struct ionic_rx_stats *rxstats; | |
| 226 | 231 | int i, q_num; |
| 227 | 232 | |
| 228 | 233 | ionic_get_lif_stats(lif, &lif_stats); |
| @@ -233,15 +238,17 @@ static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf) · 4 unmodified lines | ||
| 233 | 238 | } |
| 234 | 239 | |
| 235 | 240 | for (q_num = 0; q_num < MAX_Q(lif); q_num++) { |
| 236 | − txqcq = lif_to_txqcq(lif, q_num); | |
| 241 | + txstats = &lif_to_txstats(lif, q_num); | |
| 237 | 242 | |
| 238 | 243 | for (i = 0; i < IONIC_NUM_TX_STATS; i++) { |
| 239 | − **buf = IONIC_READ_STAT64(&txqcq->stats->tx, | |
| 244 | + **buf = IONIC_READ_STAT64(txstats, | |
| 240 | 245 | &ionic_tx_stats_desc[i]); |
| 241 | 246 | (*buf)++; |
| 242 | 247 | } |
| 243 | 248 | |
| 244 | − if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { | |
| 249 | + if (test_bit(IONIC_LIF_UP, lif->state) && | |
| 250 | + test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { | |
| 251 | + txqcq = lif_to_txqcq(lif, q_num); | |
| 245 | 252 | for (i = 0; i < IONIC_NUM_TX_Q_STATS; i++) { |
| 246 | 253 | **buf = IONIC_READ_STAT64(&txqcq->q, |
| 247 | 254 | &ionic_txq_stats_desc[i]); |
| @@ -258,22 +265,24 @@ static void ionic_sw_stats_get_values(struct ionic_lif *lif, u64 **buf) · 10 unmodified lines | ||
| 258 | 265 | (*buf)++; |
| 259 | 266 | } |
| 260 | 267 | for (i = 0; i < IONIC_MAX_NUM_SG_CNTR; i++) { |
| 261 | − **buf = txqcq->stats->tx.sg_cntr[i]; | |
| 268 | + **buf = txstats->sg_cntr[i]; | |
| 262 | 269 | (*buf)++; |
| 263 | 270 | } |
| 264 | 271 | } |
| 265 | 272 | } |
| 266 | 273 | |
| 267 | 274 | for (q_num = 0; q_num < MAX_Q(lif); q_num++) { |
| 268 | − rxqcq = lif_to_rxqcq(lif, q_num); | |
| 275 | + rxstats = &lif_to_rxstats(lif, q_num); | |
| 269 | 276 | |
| 270 | 277 | for (i = 0; i < IONIC_NUM_RX_STATS; i++) { |
| 271 | − **buf = IONIC_READ_STAT64(&rxqcq->stats->rx, | |
| 278 | + **buf = IONIC_READ_STAT64(rxstats, | |
| 272 | 279 | &ionic_rx_stats_desc[i]); |
| 273 | 280 | (*buf)++; |
| 274 | 281 | } |
| 275 | 282 | |
| 276 | − if (test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { | |
| 283 | + if (test_bit(IONIC_LIF_UP, lif->state) && | |
| 284 | + test_bit(IONIC_LIF_SW_DEBUG_STATS, lif->state)) { | |
| 285 | + rxqcq = lif_to_rxqcq(lif, q_num); | |
| 277 | 286 | for (i = 0; i < IONIC_NUM_DBG_CQ_STATS; i++) { |
| 278 | 287 | **buf = IONIC_READ_STAT64(&rxqcq->cq, |
| 279 | 288 | &ionic_dbg_cq_stats_desc[i]); |
| @@ -4146,6 +4146,14 @@ static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) · 4145 unmodified lines | ||
| 4146 | 4146 | rtl_lock_config_regs(tp); |
| 4147 | 4147 | } |
| 4148 | 4148 | |
| 4149 | +static void rtl_jumbo_config(struct rtl8169_private *tp, int mtu) | |
| 4150 | +{ | |
| 4151 | + if (mtu > ETH_DATA_LEN) | |
| 4152 | + rtl_hw_jumbo_enable(tp); | |
| 4153 | + else | |
| 4154 | + rtl_hw_jumbo_disable(tp); | |
| 4155 | +} | |
| 4156 | + | |
| 4149 | 4157 | DECLARE_RTL_COND(rtl_chipcmd_cond) |
| 4150 | 4158 | { |
| 4151 | 4159 | return RTL_R8(tp, ChipCmd) & CmdReset; |
| @@ -4442,11 +4450,6 @@ static void rtl8168g_set_pause_thresholds(struct rtl8169_private *tp, · 290 unmodified lines | ||
| 4442 | 4450 | static void rtl_hw_start_8168bb(struct rtl8169_private *tp) |
| 4443 | 4451 | { |
| 4444 | 4452 | RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); |
| 4445 | − | |
| 4446 | − if (tp->dev->mtu <= ETH_DATA_LEN) { | |
| 4447 | − rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B | | |
| 4448 | − PCI_EXP_DEVCTL_NOSNOOP_EN); | |
| 4449 | − } | |
| 4450 | 4453 | } |
| 4451 | 4454 | |
| 4452 | 4455 | static void rtl_hw_start_8168bef(struct rtl8169_private *tp) |
| @@ -4462,9 +4465,6 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) · 9 unmodified lines | ||
| 4462 | 4465 | |
| 4463 | 4466 | RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); |
| 4464 | 4467 | |
| 4465 | − if (tp->dev->mtu <= ETH_DATA_LEN) | |
| 4466 | − rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); | |
| 4467 | − | |
| 4468 | 4468 | rtl_disable_clock_request(tp); |
| 4469 | 4469 | } |
| 4470 | 4470 | |
| @@ -4490,9 +4490,6 @@ static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp) · 19 unmodified lines | ||
| 4490 | 4490 | rtl_set_def_aspm_entry_latency(tp); |
| 4491 | 4491 | |
| 4492 | 4492 | RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en); |
| 4493 | − | |
| 4494 | − if (tp->dev->mtu <= ETH_DATA_LEN) | |
| 4495 | − rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); | |
| 4496 | 4493 | } |
| 4497 | 4494 | |
| 4498 | 4495 | static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) |
| @@ -4503,9 +4500,6 @@ static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) · 4 unmodified lines | ||
| 4503 | 4500 | |
| 4504 | 4501 | /* Magic. */ |
| 4505 | 4502 | RTL_W8(tp, DBG_REG, 0x20); |
| 4506 | − | |
| 4507 | − if (tp->dev->mtu <= ETH_DATA_LEN) | |
| 4508 | − rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); | |
| 4509 | 4503 | } |
| 4510 | 4504 | |
| 4511 | 4505 | static void rtl_hw_start_8168c_1(struct rtl8169_private *tp) |
| @@ -4611,9 +4605,6 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp) · 99 unmodified lines | ||
| 4611 | 4605 | |
| 4612 | 4606 | rtl_ephy_init(tp, e_info_8168e_1); |
| 4613 | 4607 | |
| 4614 | − if (tp->dev->mtu <= ETH_DATA_LEN) | |
| 4615 | − rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); | |
| 4616 | − | |
| 4617 | 4608 | rtl_disable_clock_request(tp); |
| 4618 | 4609 | |
| 4619 | 4610 | /* Reset tx FIFO pointer */ |
| @@ -4636,9 +4627,6 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) · 16 unmodified lines | ||
| 4636 | 4627 | |
| 4637 | 4628 | rtl_ephy_init(tp, e_info_8168e_2); |
| 4638 | 4629 | |
| 4639 | − if (tp->dev->mtu <= ETH_DATA_LEN) | |
| 4640 | − rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B); | |
| 4641 | − | |
| 4642 | 4630 | rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000); |
| 4643 | 4631 | rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000); |
| 4644 | 4632 | rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06); |
| @@ -5485,6 +5473,8 @@ static void rtl_hw_start(struct rtl8169_private *tp) · 840 unmodified lines | ||
| 5485 | 5473 | rtl_set_rx_tx_desc_registers(tp); |
| 5486 | 5474 | rtl_lock_config_regs(tp); |
| 5487 | 5475 | |
| 5476 | + rtl_jumbo_config(tp, tp->dev->mtu); | |
| 5477 | + | |
| 5488 | 5478 | /* Initially a 10 us delay. Turned it into a PCI commit. - FR */ |
| 5489 | 5479 | RTL_R16(tp, CPlusCmd); |
| 5490 | 5480 | RTL_W8(tp, ChipCmd, CmdTxEnb | CmdRxEnb); |
| @@ -5498,10 +5488,7 @@ static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) · 7 unmodified lines | ||
| 5498 | 5488 | { |
| 5499 | 5489 | struct rtl8169_private *tp = netdev_priv(dev); |
| 5500 | 5490 | |
| 5501 | − if (new_mtu > ETH_DATA_LEN) | |
| 5502 | − rtl_hw_jumbo_enable(tp); | |
| 5503 | − else | |
| 5504 | − rtl_hw_jumbo_disable(tp); | |
| 5491 | + rtl_jumbo_config(tp, new_mtu); | |
| 5505 | 5492 | |
| 5506 | 5493 | dev->mtu = new_mtu; |
| 5507 | 5494 | netdev_update_features(dev); |
| @@ -651,7 +651,8 @@ static void sun8i_dwmac_set_filter(struct mac_device_info *hw, · 650 unmodified lines | ||
| 651 | 651 | } |
| 652 | 652 | } |
| 653 | 653 | } else { |
| 654 | − netdev_info(dev, "Too many address, switching to promiscuous\n"); | |
| 654 | + if (!(readl(ioaddr + EMAC_RX_FRM_FLT) & EMAC_FRM_FLT_RXALL)) | |
| 655 | + netdev_info(dev, "Too many address, switching to promiscuous\n"); | |
| 655 | 656 | v = EMAC_FRM_FLT_RXALL; |
| 656 | 657 | } |
| 657 | 658 | |
| @@ -448,7 +448,7 @@ static void dwmac4_set_filter(struct mac_device_info *hw, · 447 unmodified lines | ||
| 448 | 448 | value |= GMAC_PACKET_FILTER_HPF; |
| 449 | 449 | |
| 450 | 450 | /* Handle multiple unicast addresses */ |
| 451 | − if (netdev_uc_count(dev) > GMAC_MAX_PERFECT_ADDRESSES) { | |
| 451 | + if (netdev_uc_count(dev) > hw->unicast_filter_entries) { | |
| 452 | 452 | /* Switch to promiscuous mode if more than 128 addrs |
| 453 | 453 | * are required |
| 454 | 454 | */ |
| @@ -515,6 +515,7 @@ int dwmac5_flex_pps_config(void __iomem *ioaddr, int index, · 514 unmodified lines | ||
| 515 | 515 | |
| 516 | 516 | if (!enable) { |
| 517 | 517 | val |= PPSCMDx(index, 0x5); |
| 518 | + val |= PPSEN0; | |
| 518 | 519 | writel(val, ioaddr + MAC_PPS_CONTROL); |
| 519 | 520 | return 0; |
| 520 | 521 | } |
| @@ -2610,7 +2610,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) · 2609 unmodified lines | ||
| 2610 | 2610 | } |
| 2611 | 2611 | |
| 2612 | 2612 | if (priv->hw->pcs) |
| 2613 | − stmmac_pcs_ctrl_ane(priv, priv->hw, 1, priv->hw->ps, 0); | |
| 2613 | + stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0); | |
| 2614 | 2614 | |
| 2615 | 2615 | /* set TX and RX rings length */ |
| 2616 | 2616 | stmmac_set_rings_length(priv); |
| @@ -4742,8 +4742,10 @@ int stmmac_suspend(struct device *dev) · 2125 unmodified lines | ||
| 4742 | 4742 | stmmac_mac_set(priv, priv->ioaddr, false); |
| 4743 | 4743 | pinctrl_pm_select_sleep_state(priv->device); |
| 4744 | 4744 | /* Disable clock in case of PWM is off */ |
| 4745 | − clk_disable(priv->plat->pclk); | |
| 4746 | − clk_disable(priv->plat->stmmac_clk); | |
| 4745 | + if (priv->plat->clk_ptp_ref) | |
| 4746 | + clk_disable_unprepare(priv->plat->clk_ptp_ref); | |
| 4747 | + clk_disable_unprepare(priv->plat->pclk); | |
| 4748 | + clk_disable_unprepare(priv->plat->stmmac_clk); | |
| 4747 | 4749 | } |
| 4748 | 4750 | mutex_unlock(&priv->lock); |
| 4749 | 4751 | |
| @@ -4806,8 +4808,10 @@ int stmmac_resume(struct device *dev) · 56 unmodified lines | ||
| 4806 | 4808 | } else { |
| 4807 | 4809 | pinctrl_pm_select_default_state(priv->device); |
| 4808 | 4810 | /* enable the clk previously disabled */ |
| 4809 | − clk_enable(priv->plat->stmmac_clk); | |
| 4810 | − clk_enable(priv->plat->pclk); | |
| 4811 | + clk_prepare_enable(priv->plat->stmmac_clk); | |
| 4812 | + clk_prepare_enable(priv->plat->pclk); | |
| 4813 | + if (priv->plat->clk_ptp_ref) | |
| 4814 | + clk_prepare_enable(priv->plat->clk_ptp_ref); | |
| 4811 | 4815 | /* reset the phy so that it's ready */ |
| 4812 | 4816 | if (priv->mii) |
| 4813 | 4817 | stmmac_mdio_reset(priv->mii); |
| @@ -164,7 +164,7 @@ static int stmmac_enable(struct ptp_clock_info *ptp, · 163 unmodified lines | ||
| 164 | 164 | /* structure describing a PTP hardware clock */ |
| 165 | 165 | static struct ptp_clock_info stmmac_ptp_clock_ops = { |
| 166 | 166 | .owner = THIS_MODULE, |
| 167 | − .name = "stmmac_ptp_clock", | |
| 167 | + .name = "stmmac ptp", | |
| 168 | 168 | .max_adj = 62500000, |
| 169 | 169 | .n_alarm = 0, |
| 170 | 170 | .n_ext_ts = 0, |
| @@ -487,8 +487,8 @@ static int stmmac_filter_check(struct stmmac_priv *priv) · 486 unmodified lines | ||
| 487 | 487 | |
| 488 | 488 | static int stmmac_test_hfilt(struct stmmac_priv *priv) |
| 489 | 489 | { |
| 490 | − unsigned char gd_addr[ETH_ALEN] = {0x01, 0x00, 0xcc, 0xcc, 0xdd, 0xdd}; | |
| 491 | − unsigned char bd_addr[ETH_ALEN] = {0x09, 0x00, 0xaa, 0xaa, 0xbb, 0xbb}; | |
| 490 | + unsigned char gd_addr[ETH_ALEN] = {0x01, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}; | |
| 491 | + unsigned char bd_addr[ETH_ALEN] = {0x01, 0x01, 0x02, 0x03, 0x04, 0x05}; | |
| 492 | 492 | struct stmmac_packet_attrs attr = { }; |
| 493 | 493 | int ret; |
| 494 | 494 | |
| @@ -496,6 +496,9 @@ static int stmmac_test_hfilt(struct stmmac_priv *priv) · 1 unmodified line | ||
| 496 | 496 | if (ret) |
| 497 | 497 | return ret; |
| 498 | 498 | |
| 499 | + if (netdev_mc_count(priv->dev) >= priv->hw->multicast_filter_bins) | |
| 500 | + return -EOPNOTSUPP; | |
| 501 | + | |
| 499 | 502 | ret = dev_mc_add(priv->dev, gd_addr); |
| 500 | 503 | if (ret) |
| 501 | 504 | return ret; |
| @@ -573,6 +576,8 @@ static int stmmac_test_mcfilt(struct stmmac_priv *priv) · 71 unmodified lines | ||
| 573 | 576 | |
| 574 | 577 | if (stmmac_filter_check(priv)) |
| 575 | 578 | return -EOPNOTSUPP; |
| 579 | + if (!priv->hw->multicast_filter_bins) | |
| 580 | + return -EOPNOTSUPP; | |
| 576 | 581 | |
| 577 | 582 | /* Remove all MC addresses */ |
| 578 | 583 | __dev_mc_unsync(priv->dev, NULL); |
| @@ -611,6 +616,8 @@ static int stmmac_test_ucfilt(struct stmmac_priv *priv) · 32 unmodified lines | ||
| 611 | 616 | |
| 612 | 617 | if (stmmac_filter_check(priv)) |
| 613 | 618 | return -EOPNOTSUPP; |
| 619 | + if (!priv->hw->multicast_filter_bins) | |
| 620 | + return -EOPNOTSUPP; | |
| 614 | 621 | |
| 615 | 622 | /* Remove all UC addresses */ |
| 616 | 623 | __dev_uc_unsync(priv->dev, NULL); |
| @@ -510,7 +510,7 @@ static struct stmmac_flow_entry *tc_find_flow(struct stmmac_priv *priv, · 509 unmodified lines | ||
| 510 | 510 | return NULL; |
| 511 | 511 | } |
| 512 | 512 | |
| 513 | −struct { | |
| 513 | +static struct { | |
| 514 | 514 | int (*fn)(struct stmmac_priv *priv, struct flow_cls_offload *cls, |
| 515 | 515 | struct stmmac_flow_entry *entry); |
| 516 | 516 | } tc_flow_parsers[] = { |
| @@ -722,7 +722,7 @@ static void cpdma_chan_set_descs(struct cpdma_ctlr *ctlr, · 721 unmodified lines | ||
| 722 | 722 | * cpdma_chan_split_pool - Splits ctrl pool between all channels. |
| 723 | 723 | * Has to be called under ctlr lock |
| 724 | 724 | */ |
| 725 | −int cpdma_chan_split_pool(struct cpdma_ctlr *ctlr) | |
| 725 | +static int cpdma_chan_split_pool(struct cpdma_ctlr *ctlr) | |
| 726 | 726 | { |
| 727 | 727 | int tx_per_ch_desc = 0, rx_per_ch_desc = 0; |
| 728 | 728 | int free_rx_num = 0, free_tx_num = 0; |
| @@ -241,8 +241,8 @@ static struct pernet_operations nsim_fib_net_ops = { · 240 unmodified lines | ||
| 241 | 241 | |
| 242 | 242 | void nsim_fib_exit(void) |
| 243 | 243 | { |
| 244 | − unregister_pernet_subsys(&nsim_fib_net_ops); | |
| 245 | 244 | unregister_fib_notifier(&nsim_fib_nb); |
| 245 | + unregister_pernet_subsys(&nsim_fib_net_ops); | |
| 246 | 246 | } |
| 247 | 247 | |
| 248 | 248 | int nsim_fib_init(void) |
| @@ -258,6 +258,7 @@ int nsim_fib_init(void) · 9 unmodified lines | ||
| 258 | 258 | err = register_fib_notifier(&nsim_fib_nb, nsim_fib_dump_inconsistent); |
| 259 | 259 | if (err < 0) { |
| 260 | 260 | pr_err("Failed to register fib notifier\n"); |
| 261 | + unregister_pernet_subsys(&nsim_fib_net_ops); | |
| 261 | 262 | goto err_out; |
| 262 | 263 | } |
| 263 | 264 | |
| @@ -572,6 +572,7 @@ static int bcm7xxx_28nm_probe(struct phy_device *phydev) · 571 unmodified lines | ||
| 572 | 572 | .name = _name, \ |
| 573 | 573 | /* PHY_BASIC_FEATURES */ \ |
| 574 | 574 | .flags = PHY_IS_INTERNAL, \ |
| 575 | + .soft_reset = genphy_soft_reset, \ | |
| 575 | 576 | .config_init = bcm7xxx_config_init, \ |
| 576 | 577 | .suspend = bcm7xxx_suspend, \ |
| 577 | 578 | .resume = bcm7xxx_config_init, \ |
| @@ -341,6 +341,35 @@ static int ksz8041_config_aneg(struct phy_device *phydev) · 340 unmodified lines | ||
| 341 | 341 | return genphy_config_aneg(phydev); |
| 342 | 342 | } |
| 343 | 343 | |
| 344 | +static int ksz8051_ksz8795_match_phy_device(struct phy_device *phydev, | |
| 345 | + const u32 ksz_phy_id) | |
| 346 | +{ | |
| 347 | + int ret; | |
| 348 | + | |
| 349 | + if ((phydev->phy_id & MICREL_PHY_ID_MASK) != ksz_phy_id) | |
| 350 | + return 0; | |
| 351 | + | |
| 352 | + ret = phy_read(phydev, MII_BMSR); | |
| 353 | + if (ret < 0) | |
| 354 | + return ret; | |
| 355 | + | |
| 356 | + /* KSZ8051 PHY and KSZ8794/KSZ8795/KSZ8765 switch share the same | |
| 357 | + * exact PHY ID. However, they can be told apart by the extended | |
| 358 | + * capability registers presence. The KSZ8051 PHY has them while | |
| 359 | + * the switch does not. | |
| 360 | + */ | |
| 361 | + ret &= BMSR_ERCAP; | |
| 362 | + if (ksz_phy_id == PHY_ID_KSZ8051) | |
| 363 | + return ret; | |
| 364 | + else | |
| 365 | + return !ret; | |
| 366 | +} | |
| 367 | + | |
| 368 | +static int ksz8051_match_phy_device(struct phy_device *phydev) | |
| 369 | +{ | |
| 370 | + return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ8051); | |
| 371 | +} | |
| 372 | + | |
| 344 | 373 | static int ksz8081_config_init(struct phy_device *phydev) |
| 345 | 374 | { |
| 346 | 375 | /* KSZPHY_OMSO_FACTORY_TEST is set at de-assertion of the reset line |
| @@ -364,6 +393,11 @@ static int ksz8061_config_init(struct phy_device *phydev) · 17 unmodified lines | ||
| 364 | 393 | return kszphy_config_init(phydev); |
| 365 | 394 | } |
| 366 | 395 | |
| 396 | +static int ksz8795_match_phy_device(struct phy_device *phydev) | |
| 397 | +{ | |
| 398 | + return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ87XX); | |
| 399 | +} | |
| 400 | + | |
| 367 | 401 | static int ksz9021_load_values_from_of(struct phy_device *phydev, |
| 368 | 402 | const struct device_node *of_node, |
| 369 | 403 | u16 reg, |
| @@ -1017,8 +1051,6 @@ static struct phy_driver ksphy_driver[] = { · 647 unmodified lines | ||
| 1017 | 1051 | .suspend = genphy_suspend, |
| 1018 | 1052 | .resume = genphy_resume, |
| 1019 | 1053 | }, { |
| 1020 | − .phy_id = PHY_ID_KSZ8051, | |
| 1021 | − .phy_id_mask = MICREL_PHY_ID_MASK, | |
| 1022 | 1054 | .name = "Micrel KSZ8051", |
| 1023 | 1055 | /* PHY_BASIC_FEATURES */ |
| 1024 | 1056 | .driver_data = &ksz8051_type, |
| @@ -1029,6 +1061,7 @@ static struct phy_driver ksphy_driver[] = { · 4 unmodified lines | ||
| 1029 | 1061 | .get_sset_count = kszphy_get_sset_count, |
| 1030 | 1062 | .get_strings = kszphy_get_strings, |
| 1031 | 1063 | .get_stats = kszphy_get_stats, |
| 1064 | + .match_phy_device = ksz8051_match_phy_device, | |
| 1032 | 1065 | .suspend = genphy_suspend, |
| 1033 | 1066 | .resume = genphy_resume, |
| 1034 | 1067 | }, { |
| @@ -1141,13 +1174,12 @@ static struct phy_driver ksphy_driver[] = { · 106 unmodified lines | ||
| 1141 | 1174 | .suspend = genphy_suspend, |
| 1142 | 1175 | .resume = genphy_resume, |
| 1143 | 1176 | }, { |
| 1144 | − .phy_id = PHY_ID_KSZ8795, | |
| 1145 | − .phy_id_mask = MICREL_PHY_ID_MASK, | |
| 1146 | − .name = "Micrel KSZ8795", | |
| 1177 | + .name = "Micrel KSZ87XX Switch", | |
| 1147 | 1178 | /* PHY_BASIC_FEATURES */ |
| 1148 | 1179 | .config_init = kszphy_config_init, |
| 1149 | 1180 | .config_aneg = ksz8873mll_config_aneg, |
| 1150 | 1181 | .read_status = ksz8873mll_read_status, |
| 1182 | + .match_phy_device = ksz8795_match_phy_device, | |
| 1151 | 1183 | .suspend = genphy_suspend, |
| 1152 | 1184 | .resume = genphy_resume, |
| 1153 | 1185 | }, { |
| @@ -323,6 +323,8 @@ int genphy_c45_read_pma(struct phy_device *phydev) · 322 unmodified lines | ||
| 323 | 323 | { |
| 324 | 324 | int val; |
| 325 | 325 | |
| 326 | + linkmode_zero(phydev->lp_advertising); | |
| 327 | + | |
| 326 | 328 | val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_CTRL1); |
| 327 | 329 | if (val < 0) |
| 328 | 330 | return val; |
| @@ -572,9 +572,6 @@ int phy_start_aneg(struct phy_device *phydev) · 571 unmodified lines | ||
| 572 | 572 | if (AUTONEG_DISABLE == phydev->autoneg) |
| 573 | 573 | phy_sanitize_settings(phydev); |
| 574 | 574 | |
| 575 | − /* Invalidate LP advertising flags */ | |
| 576 | − linkmode_zero(phydev->lp_advertising); | |
| 577 | − | |
| 578 | 575 | err = phy_config_aneg(phydev); |
| 579 | 576 | if (err < 0) |
| 580 | 577 | goto out_unlock; |
| @@ -1787,7 +1787,14 @@ int genphy_read_lpa(struct phy_device *phydev) · 1786 unmodified lines | ||
| 1787 | 1787 | { |
| 1788 | 1788 | int lpa, lpagb; |
| 1789 | 1789 | |
| 1790 | − if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { | |
| 1790 | + if (phydev->autoneg == AUTONEG_ENABLE) { | |
| 1791 | + if (!phydev->autoneg_complete) { | |
| 1792 | + mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, | |
| 1793 | + 0); | |
| 1794 | + mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0); | |
| 1795 | + return 0; | |
| 1796 | + } | |
| 1797 | + | |
| 1791 | 1798 | if (phydev->is_gigabit_capable) { |
| 1792 | 1799 | lpagb = phy_read(phydev, MII_STAT1000); |
| 1793 | 1800 | if (lpagb < 0) |
| @@ -1815,6 +1822,8 @@ int genphy_read_lpa(struct phy_device *phydev) · 21 unmodified lines | ||
| 1815 | 1822 | return lpa; |
| 1816 | 1823 | |
| 1817 | 1824 | mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa); |
| 1825 | + } else { | |
| 1826 | + linkmode_zero(phydev->lp_advertising); | |
| 1818 | 1827 | } |
| 1819 | 1828 | |
| 1820 | 1829 | return 0; |
| @@ -576,7 +576,7 @@ static int phylink_register_sfp(struct phylink *pl, · 575 unmodified lines | ||
| 576 | 576 | |
| 577 | 577 | /** |
| 578 | 578 | * phylink_create() - create a phylink instance |
| 579 | − * @ndev: a pointer to the &struct net_device | |
| 579 | + * @config: a pointer to the target &struct phylink_config | |
| 580 | 580 | * @fwnode: a pointer to a &struct fwnode_handle describing the network |
| 581 | 581 | * interface |
| 582 | 582 | * @iface: the desired link mode defined by &typedef phy_interface_t |
| @@ -526,8 +526,8 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash, · 525 unmodified lines | ||
| 526 | 526 | e = tun_flow_find(head, rxhash); |
| 527 | 527 | if (likely(e)) { |
| 528 | 528 | /* TODO: keep queueing to old queue until it's empty? */ |
| 529 | − if (e->queue_index != queue_index) | |
| 530 | − e->queue_index = queue_index; | |
| 529 | + if (READ_ONCE(e->queue_index) != queue_index) | |
| 530 | + WRITE_ONCE(e->queue_index, queue_index); | |
| 531 | 531 | if (e->updated != jiffies) |
| 532 | 532 | e->updated = jiffies; |
| 533 | 533 | sock_rps_record_flow_hash(e->rps_rxhash); |
| @@ -186,7 +186,7 @@ struct hso_tiocmget { · 185 unmodified lines | ||
| 186 | 186 | int intr_completed; |
| 187 | 187 | struct usb_endpoint_descriptor *endp; |
| 188 | 188 | struct urb *urb; |
| 189 | − struct hso_serial_state_notification serial_state_notification; | |
| 189 | + struct hso_serial_state_notification *serial_state_notification; | |
| 190 | 190 | u16 prev_UART_state_bitmap; |
| 191 | 191 | struct uart_icount icount; |
| 192 | 192 | }; |
| @@ -1432,7 +1432,7 @@ static int tiocmget_submit_urb(struct hso_serial *serial, · 1239 unmodified lines | ||
| 1432 | 1432 | usb_rcvintpipe(usb, |
| 1433 | 1433 | tiocmget->endp-> |
| 1434 | 1434 | bEndpointAddress & 0x7F), |
| 1435 | − &tiocmget->serial_state_notification, | |
| 1435 | + tiocmget->serial_state_notification, | |
| 1436 | 1436 | sizeof(struct hso_serial_state_notification), |
| 1437 | 1437 | tiocmget_intr_callback, serial, |
| 1438 | 1438 | tiocmget->endp->bInterval); |
| @@ -1479,7 +1479,7 @@ static void tiocmget_intr_callback(struct urb *urb) · 40 unmodified lines | ||
| 1479 | 1479 | /* wIndex should be the USB interface number of the port to which the |
| 1480 | 1480 | * notification applies, which should always be the Modem port. |
| 1481 | 1481 | */ |
| 1482 | − serial_state_notification = &tiocmget->serial_state_notification; | |
| 1482 | + serial_state_notification = tiocmget->serial_state_notification; | |
| 1483 | 1483 | if (serial_state_notification->bmRequestType != BM_REQUEST_TYPE || |
| 1484 | 1484 | serial_state_notification->bNotification != B_NOTIFICATION || |
| 1485 | 1485 | le16_to_cpu(serial_state_notification->wValue) != W_VALUE || |
| @@ -2565,6 +2565,8 @@ static void hso_free_tiomget(struct hso_serial *serial) · 1079 unmodified lines | ||
| 2565 | 2565 | usb_free_urb(tiocmget->urb); |
| 2566 | 2566 | tiocmget->urb = NULL; |
| 2567 | 2567 | serial->tiocmget = NULL; |
| 2568 | + kfree(tiocmget->serial_state_notification); | |
| 2569 | + tiocmget->serial_state_notification = NULL; | |
| 2568 | 2570 | kfree(tiocmget); |
| 2569 | 2571 | } |
| 2570 | 2572 | } |
| @@ -2615,10 +2617,13 @@ static struct hso_device *hso_create_bulk_serial_device( · 44 unmodified lines | ||
| 2615 | 2617 | num_urbs = 2; |
| 2616 | 2618 | serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget), |
| 2617 | 2619 | GFP_KERNEL); |
| 2620 | + serial->tiocmget->serial_state_notification | |
| 2621 | + = kzalloc(sizeof(struct hso_serial_state_notification), | |
| 2622 | + GFP_KERNEL); | |
| 2618 | 2623 | /* it isn't going to break our heart if serial->tiocmget |
| 2619 | 2624 | * allocation fails don't bother checking this. |
| 2620 | 2625 | */ |
| 2621 | − if (serial->tiocmget) { | |
| 2626 | + if (serial->tiocmget && serial->tiocmget->serial_state_notification) { | |
| 2622 | 2627 | tiocmget = serial->tiocmget; |
| 2623 | 2628 | tiocmget->endp = hso_get_ep(interface, |
| 2624 | 2629 | USB_ENDPOINT_XFER_INT, |
| @@ -3782,10 +3782,14 @@ static int lan78xx_probe(struct usb_interface *intf, · 3781 unmodified lines | ||
| 3782 | 3782 | /* driver requires remote-wakeup capability during autosuspend. */ |
| 3783 | 3783 | intf->needs_remote_wakeup = 1; |
| 3784 | 3784 | |
| 3785 | + ret = lan78xx_phy_init(dev); | |
| 3786 | + if (ret < 0) | |
| 3787 | + goto out4; | |
| 3788 | + | |
| 3785 | 3789 | ret = register_netdev(netdev); |
| 3786 | 3790 | if (ret != 0) { |
| 3787 | 3791 | netif_err(dev, probe, netdev, "couldn't register the device\n"); |
| 3788 | − goto out4; | |
| 3792 | + goto out5; | |
| 3789 | 3793 | } |
| 3790 | 3794 | |
| 3791 | 3795 | usb_set_intfdata(intf, dev); |
| @@ -3798,14 +3802,10 @@ static int lan78xx_probe(struct usb_interface *intf, · 6 unmodified lines | ||
| 3798 | 3802 | pm_runtime_set_autosuspend_delay(&udev->dev, |
| 3799 | 3803 | DEFAULT_AUTOSUSPEND_DELAY); |
| 3800 | 3804 | |
| 3801 | − ret = lan78xx_phy_init(dev); | |
| 3802 | − if (ret < 0) | |
| 3803 | − goto out5; | |
| 3804 | − | |
| 3805 | 3805 | return 0; |
| 3806 | 3806 | |
| 3807 | 3807 | out5: |
| 3808 | − unregister_netdev(netdev); | |
| 3808 | + phy_disconnect(netdev->phydev); | |
| 3809 | 3809 | out4: |
| 3810 | 3810 | usb_free_urb(dev->urb_intr); |
| 3811 | 3811 | out3: |
| @@ -1327,6 +1327,7 @@ static const struct usb_device_id products[] = { · 1326 unmodified lines | ||
| 1327 | 1327 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
| 1328 | 1328 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
| 1329 | 1329 | {QMI_QUIRK_SET_DTR(0x1bc7, 0x1040, 2)}, /* Telit LE922A */ |
| 1330 | + {QMI_QUIRK_SET_DTR(0x1bc7, 0x1050, 2)}, /* Telit FN980 */ | |
| 1330 | 1331 | {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */ |
| 1331 | 1332 | {QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */ |
| 1332 | 1333 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ |
| @@ -335,7 +335,7 @@ static void sr_set_multicast(struct net_device *net) · 334 unmodified lines | ||
| 335 | 335 | static int sr_mdio_read(struct net_device *net, int phy_id, int loc) |
| 336 | 336 | { |
| 337 | 337 | struct usbnet *dev = netdev_priv(net); |
| 338 | − __le16 res; | |
| 338 | + __le16 res = 0; | |
| 339 | 339 | |
| 340 | 340 | mutex_lock(&dev->phy_mutex); |
| 341 | 341 | sr_set_sw_mii(dev); |
| @@ -2118,12 +2118,15 @@ static int ath10k_init_uart(struct ath10k *ar) · 2117 unmodified lines | ||
| 2118 | 2118 | return ret; |
| 2119 | 2119 | } |
| 2120 | 2120 | |
| 2121 | − if (!uart_print && ar->hw_params.uart_pin_workaround) { | |
| 2122 | − ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, | |
| 2123 | − ar->hw_params.uart_pin); | |
| 2124 | − if (ret) { | |
| 2125 | − ath10k_warn(ar, "failed to set UART TX pin: %d", ret); | |
| 2126 | − return ret; | |
| 2121 | + if (!uart_print) { | |
| 2122 | + if (ar->hw_params.uart_pin_workaround) { | |
| 2123 | + ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, | |
| 2124 | + ar->hw_params.uart_pin); | |
| 2125 | + if (ret) { | |
| 2126 | + ath10k_warn(ar, "failed to set UART TX pin: %d", | |
| 2127 | + ret); | |
| 2128 | + return ret; | |
| 2129 | + } | |
| 2127 | 2130 | } |
| 2128 | 2131 | |
| 2129 | 2132 | return 0; |
| @@ -162,12 +162,13 @@ int iwl_acpi_get_mcc(struct device *dev, char *mcc) · 161 unmodified lines | ||
| 162 | 162 | |
| 163 | 163 | wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_WRDD_WIFI_DATA_SIZE, |
| 164 | 164 | &tbl_rev); |
| 165 | − if (IS_ERR(wifi_pkg) || tbl_rev != 0) { | |
| 165 | + if (IS_ERR(wifi_pkg)) { | |
| 166 | 166 | ret = PTR_ERR(wifi_pkg); |
| 167 | 167 | goto out_free; |
| 168 | 168 | } |
| 169 | 169 | |
| 170 | − if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) { | |
| 170 | + if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER || | |
| 171 | + tbl_rev != 0) { | |
| 171 | 172 | ret = -EINVAL; |
| 172 | 173 | goto out_free; |
| 173 | 174 | } |
| @@ -224,12 +225,13 @@ int iwl_acpi_get_eckv(struct device *dev, u32 *extl_clk) · 50 unmodified lines | ||
| 224 | 225 | |
| 225 | 226 | wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_ECKV_WIFI_DATA_SIZE, |
| 226 | 227 | &tbl_rev); |
| 227 | − if (IS_ERR(wifi_pkg) || tbl_rev != 0) { | |
| 228 | + if (IS_ERR(wifi_pkg)) { | |
| 228 | 229 | ret = PTR_ERR(wifi_pkg); |
| 229 | 230 | goto out_free; |
| 230 | 231 | } |
| 231 | 232 | |
| 232 | − if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) { | |
| 233 | + if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER || | |
| 234 | + tbl_rev != 0) { | |
| 233 | 235 | ret = -EINVAL; |
| 234 | 236 | goto out_free; |
| 235 | 237 | } |
| @@ -646,6 +646,7 @@ static struct scatterlist *alloc_sgtable(int size) · 645 unmodified lines | ||
| 646 | 646 | if (new_page) |
| 647 | 647 | __free_page(new_page); |
| 648 | 648 | } |
| 649 | + kfree(table); | |
| 649 | 650 | return NULL; |
| 650 | 651 | } |
| 651 | 652 | alloc_size = min_t(int, size, PAGE_SIZE); |
| @@ -112,38 +112,38 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf); · 111 unmodified lines | ||
| 112 | 112 | */ |
| 113 | 113 | static inline u32 iwl_umac_prph(struct iwl_trans *trans, u32 ofs) |
| 114 | 114 | { |
| 115 | − return ofs + trans->cfg->trans.umac_prph_offset; | |
| 115 | + return ofs + trans->trans_cfg->umac_prph_offset; | |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | 118 | static inline u32 iwl_read_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs) |
| 119 | 119 | { |
| 120 | 120 | return iwl_read_prph_no_grab(trans, ofs + |
| 121 | − trans->cfg->trans.umac_prph_offset); | |
| 121 | + trans->trans_cfg->umac_prph_offset); | |
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | static inline u32 iwl_read_umac_prph(struct iwl_trans *trans, u32 ofs) |
| 125 | 125 | { |
| 126 | − return iwl_read_prph(trans, ofs + trans->cfg->trans.umac_prph_offset); | |
| 126 | + return iwl_read_prph(trans, ofs + trans->trans_cfg->umac_prph_offset); | |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | 129 | static inline void iwl_write_umac_prph_no_grab(struct iwl_trans *trans, u32 ofs, |
| 130 | 130 | u32 val) |
| 131 | 131 | { |
| 132 | − iwl_write_prph_no_grab(trans, ofs + trans->cfg->trans.umac_prph_offset, | |
| 132 | + iwl_write_prph_no_grab(trans, ofs + trans->trans_cfg->umac_prph_offset, | |
| 133 | 133 | val); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | 136 | static inline void iwl_write_umac_prph(struct iwl_trans *trans, u32 ofs, |
| 137 | 137 | u32 val) |
| 138 | 138 | { |
| 139 | − iwl_write_prph(trans, ofs + trans->cfg->trans.umac_prph_offset, val); | |
| 139 | + iwl_write_prph(trans, ofs + trans->trans_cfg->umac_prph_offset, val); | |
| 140 | 140 | } |
| 141 | 141 | |
| 142 | 142 | static inline int iwl_poll_umac_prph_bit(struct iwl_trans *trans, u32 addr, |
| 143 | 143 | u32 bits, u32 mask, int timeout) |
| 144 | 144 | { |
| 145 | 145 | return iwl_poll_prph_bit(trans, addr + |
| 146 | − trans->cfg->trans.umac_prph_offset, | |
| 146 | + trans->trans_cfg->umac_prph_offset, | |
| 147 | 147 | bits, mask, timeout); |
| 148 | 148 | } |
| 149 | 149 | |
| @@ -420,6 +420,9 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) · 419 unmodified lines | ||
| 420 | 420 | }; |
| 421 | 421 | int ret; |
| 422 | 422 | |
| 423 | + if (mvm->trans->cfg->tx_with_siso_diversity) | |
| 424 | + init_cfg.init_flags |= cpu_to_le32(BIT(IWL_INIT_PHY)); | |
| 425 | + | |
| 423 | 426 | lockdep_assert_held(&mvm->mutex); |
| 424 | 427 | |
| 425 | 428 | mvm->rfkill_safe_init_done = false; |
| @@ -694,12 +697,13 @@ static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm) · 268 unmodified lines | ||
| 694 | 697 | |
| 695 | 698 | wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, |
| 696 | 699 | ACPI_WRDS_WIFI_DATA_SIZE, &tbl_rev); |
| 697 | − if (IS_ERR(wifi_pkg) || tbl_rev != 0) { | |
| 700 | + if (IS_ERR(wifi_pkg)) { | |
| 698 | 701 | ret = PTR_ERR(wifi_pkg); |
| 699 | 702 | goto out_free; |
| 700 | 703 | } |
| 701 | 704 | |
| 702 | − if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) { | |
| 705 | + if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER || | |
| 706 | + tbl_rev != 0) { | |
| 703 | 707 | ret = -EINVAL; |
| 704 | 708 | goto out_free; |
| 705 | 709 | } |
| @@ -731,13 +735,14 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm) · 25 unmodified lines | ||
| 731 | 735 | |
| 732 | 736 | wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, |
| 733 | 737 | ACPI_EWRD_WIFI_DATA_SIZE, &tbl_rev); |
| 734 | − if (IS_ERR(wifi_pkg) || tbl_rev != 0) { | |
| 738 | + if (IS_ERR(wifi_pkg)) { | |
| 735 | 739 | ret = PTR_ERR(wifi_pkg); |
| 736 | 740 | goto out_free; |
| 737 | 741 | } |
| 738 | 742 | |
| 739 | 743 | if ((wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) || |
| 740 | − (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER)) { | |
| 744 | + (wifi_pkg->package.elements[2].type != ACPI_TYPE_INTEGER) || | |
| 745 | + tbl_rev != 0) { | |
| 741 | 746 | ret = -EINVAL; |
| 742 | 747 | goto out_free; |
| 743 | 748 | } |
| @@ -791,11 +796,16 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm) · 47 unmodified lines | ||
| 791 | 796 | |
| 792 | 797 | wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, |
| 793 | 798 | ACPI_WGDS_WIFI_DATA_SIZE, &tbl_rev); |
| 794 | − if (IS_ERR(wifi_pkg) || tbl_rev > 1) { | |
| 799 | + if (IS_ERR(wifi_pkg)) { | |
| 795 | 800 | ret = PTR_ERR(wifi_pkg); |
| 796 | 801 | goto out_free; |
| 797 | 802 | } |
| 798 | 803 | |
| 804 | + if (tbl_rev != 0) { | |
| 805 | + ret = -EINVAL; | |
| 806 | + goto out_free; | |
| 807 | + } | |
| 808 | + | |
| 799 | 809 | mvm->geo_rev = tbl_rev; |
| 800 | 810 | for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) { |
| 801 | 811 | for (j = 0; j < ACPI_GEO_TABLE_SIZE; j++) { |
| @@ -889,15 +899,17 @@ static bool iwl_mvm_sar_geo_support(struct iwl_mvm *mvm) · 87 unmodified lines | ||
| 889 | 899 | * firmware versions. Unfortunately, we don't have a TLV API |
| 890 | 900 | * flag to rely on, so rely on the major version which is in |
| 891 | 901 | * the first byte of ucode_ver. This was implemented |
| 892 | − * initially on version 38 and then backported to29 and 17. | |
| 893 | − * The intention was to have it in 36 as well, but not all | |
| 894 | − * 8000 family got this feature enabled. The 8000 family is | |
| 895 | − * the only one using version 36, so skip this version | |
| 896 | − * entirely. | |
| 902 | + * initially on version 38 and then backported to 17. It was | |
| 903 | + * also backported to 29, but only for 7265D devices. The | |
| 904 | + * intention was to have it in 36 as well, but not all 8000 | |
| 905 | + * family got this feature enabled. The 8000 family is the | |
| 906 | + * only one using version 36, so skip this version entirely. | |
| 897 | 907 | */ |
| 898 | 908 | return IWL_UCODE_SERIAL(mvm->fw->ucode_ver) >= 38 || |
| 899 | − IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 29 || | |
| 900 | − IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 17; | |
| 909 | + IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 17 || | |
| 910 | + (IWL_UCODE_SERIAL(mvm->fw->ucode_ver) == 29 && | |
| 911 | + ((mvm->trans->hw_rev & CSR_HW_REV_TYPE_MSK) == | |
| 912 | + CSR_HW_REV_TYPE_7265D)); | |
| 901 | 913 | } |
| 902 | 914 | |
| 903 | 915 | int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm) |
| @@ -1020,11 +1032,16 @@ static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm) · 116 unmodified lines | ||
| 1020 | 1032 | wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data, |
| 1021 | 1033 | ACPI_PPAG_WIFI_DATA_SIZE, &tbl_rev); |
| 1022 | 1034 | |
| 1023 | − if (IS_ERR(wifi_pkg) || tbl_rev != 0) { | |
| 1035 | + if (IS_ERR(wifi_pkg)) { | |
| 1024 | 1036 | ret = PTR_ERR(wifi_pkg); |
| 1025 | 1037 | goto out_free; |
| 1026 | 1038 | } |
| 1027 | 1039 | |
| 1040 | + if (tbl_rev != 0) { | |
| 1041 | + ret = -EINVAL; | |
| 1042 | + goto out_free; | |
| 1043 | + } | |
| 1044 | + | |
| 1028 | 1045 | enabled = &wifi_pkg->package.elements[1]; |
| 1029 | 1046 | if (enabled->type != ACPI_TYPE_INTEGER || |
| 1030 | 1047 | (enabled->integer.value != 0 && enabled->integer.value != 1)) { |
| @@ -4881,11 +4881,11 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, · 4880 unmodified lines | ||
| 4881 | 4881 | if (!iwl_mvm_has_new_rx_api(mvm)) |
| 4882 | 4882 | return; |
| 4883 | 4883 | |
| 4884 | − notif->cookie = mvm->queue_sync_cookie; | |
| 4885 | − | |
| 4886 | − if (notif->sync) | |
| 4884 | + if (notif->sync) { | |
| 4885 | + notif->cookie = mvm->queue_sync_cookie; | |
| 4887 | 4886 | atomic_set(&mvm->queue_sync_counter, |
| 4888 | 4887 | mvm->trans->num_rx_queues); |
| 4888 | + } | |
| 4889 | 4889 | |
| 4890 | 4890 | ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif, |
| 4891 | 4891 | size, !notif->sync); |
| @@ -4905,7 +4905,8 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm, · 13 unmodified lines | ||
| 4905 | 4905 | |
| 4906 | 4906 | out: |
| 4907 | 4907 | atomic_set(&mvm->queue_sync_counter, 0); |
| 4908 | − mvm->queue_sync_cookie++; | |
| 4908 | + if (notif->sync) | |
| 4909 | + mvm->queue_sync_cookie++; | |
| 4909 | 4910 | } |
| 4910 | 4911 | |
| 4911 | 4912 | static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw) |
| @@ -107,13 +107,9 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, · 106 unmodified lines | ||
| 107 | 107 | |
| 108 | 108 | /* allocate ucode sections in dram and set addresses */ |
| 109 | 109 | ret = iwl_pcie_init_fw_sec(trans, fw, &prph_scratch->dram); |
| 110 | − if (ret) { | |
| 111 | − dma_free_coherent(trans->dev, | |
| 112 | − sizeof(*prph_scratch), | |
| 113 | − prph_scratch, | |
| 114 | − trans_pcie->prph_scratch_dma_addr); | |
| 115 | − return ret; | |
| 116 | − } | |
| 110 | + if (ret) | |
| 111 | + goto err_free_prph_scratch; | |
| 112 | + | |
| 117 | 113 | |
| 118 | 114 | /* Allocate prph information |
| 119 | 115 | * currently we don't assign to the prph info anything, but it would get |
| @@ -121,16 +117,20 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, · 1 unmodified line | ||
| 121 | 117 | prph_info = dma_alloc_coherent(trans->dev, sizeof(*prph_info), |
| 122 | 118 | &trans_pcie->prph_info_dma_addr, |
| 123 | 119 | GFP_KERNEL); |
| 124 | − if (!prph_info) | |
| 125 | − return -ENOMEM; | |
| 120 | + if (!prph_info) { | |
| 121 | + ret = -ENOMEM; | |
| 122 | + goto err_free_prph_scratch; | |
| 123 | + } | |
| 126 | 124 | |
| 127 | 125 | /* Allocate context info */ |
| 128 | 126 | ctxt_info_gen3 = dma_alloc_coherent(trans->dev, |
| 129 | 127 | sizeof(*ctxt_info_gen3), |
| 130 | 128 | &trans_pcie->ctxt_info_dma_addr, |
| 131 | 129 | GFP_KERNEL); |
| 132 | − if (!ctxt_info_gen3) | |
| 133 | − return -ENOMEM; | |
| 130 | + if (!ctxt_info_gen3) { | |
| 131 | + ret = -ENOMEM; | |
| 132 | + goto err_free_prph_info; | |
| 133 | + } | |
| 134 | 134 | |
| 135 | 135 | ctxt_info_gen3->prph_info_base_addr = |
| 136 | 136 | cpu_to_le64(trans_pcie->prph_info_dma_addr); |
| @@ -186,6 +186,20 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, · 49 unmodified lines | ||
| 186 | 186 | iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT); |
| 187 | 187 | |
| 188 | 188 | return 0; |
| 189 | + | |
| 190 | +err_free_prph_info: | |
| 191 | + dma_free_coherent(trans->dev, | |
| 192 | + sizeof(*prph_info), | |
| 193 | + prph_info, | |
| 194 | + trans_pcie->prph_info_dma_addr); | |
| 195 | + | |
| 196 | +err_free_prph_scratch: | |
| 197 | + dma_free_coherent(trans->dev, | |
| 198 | + sizeof(*prph_scratch), | |
| 199 | + prph_scratch, | |
| 200 | + trans_pcie->prph_scratch_dma_addr); | |
| 201 | + return ret; | |
| 202 | + | |
| 189 | 203 | } |
| 190 | 204 | |
| 191 | 205 | void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans) |
| @@ -513,31 +513,33 @@ static const struct pci_device_id iwl_hw_card_ids[] = { · 512 unmodified lines | ||
| 513 | 513 | {IWL_PCI_DEVICE(0x24FD, 0x9074, iwl8265_2ac_cfg)}, |
| 514 | 514 | |
| 515 | 515 | /* 9000 Series */ |
| 516 | − {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, | |
| 517 | − {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 518 | − {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, | |
| 519 | − {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, | |
| 520 | − {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 521 | − {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 522 | − {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 523 | − {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 524 | − {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 525 | − {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 526 | − {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 527 | − {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 528 | − {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 529 | − {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 530 | − {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 531 | − {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 532 | − {IWL_PCI_DEVICE(0x02F0, 0x1551, iwl9560_killer_s_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 533 | − {IWL_PCI_DEVICE(0x02F0, 0x1552, iwl9560_killer_i_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 534 | − {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, | |
| 535 | − {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, | |
| 536 | − {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, | |
| 537 | − {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, | |
| 538 | − {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 539 | − {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 540 | − {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_quz_a0_jf_b0_soc)}, | |
| 516 | + {IWL_PCI_DEVICE(0x02F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 517 | + {IWL_PCI_DEVICE(0x02F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 518 | + {IWL_PCI_DEVICE(0x02F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 519 | + {IWL_PCI_DEVICE(0x02F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 520 | + {IWL_PCI_DEVICE(0x02F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 521 | + {IWL_PCI_DEVICE(0x02F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 522 | + {IWL_PCI_DEVICE(0x02F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 523 | + {IWL_PCI_DEVICE(0x02F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 524 | + {IWL_PCI_DEVICE(0x02F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 525 | + {IWL_PCI_DEVICE(0x02F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 526 | + {IWL_PCI_DEVICE(0x02F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 527 | + {IWL_PCI_DEVICE(0x02F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 528 | + {IWL_PCI_DEVICE(0x02F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 529 | + {IWL_PCI_DEVICE(0x02F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 530 | + {IWL_PCI_DEVICE(0x02F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 531 | + {IWL_PCI_DEVICE(0x02F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 532 | + {IWL_PCI_DEVICE(0x02F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 533 | + {IWL_PCI_DEVICE(0x02F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, | |
| 534 | + {IWL_PCI_DEVICE(0x02F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, | |
| 535 | + {IWL_PCI_DEVICE(0x02F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 536 | + {IWL_PCI_DEVICE(0x02F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 537 | + {IWL_PCI_DEVICE(0x02F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 538 | + {IWL_PCI_DEVICE(0x02F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 539 | + {IWL_PCI_DEVICE(0x02F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 540 | + {IWL_PCI_DEVICE(0x02F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 541 | + {IWL_PCI_DEVICE(0x02F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 542 | + | |
| 541 | 543 | {IWL_PCI_DEVICE(0x06F0, 0x0030, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, |
| 542 | 544 | {IWL_PCI_DEVICE(0x06F0, 0x0034, iwl9560_2ac_cfg_quz_a0_jf_b0_soc)}, |
| 543 | 545 | {IWL_PCI_DEVICE(0x06F0, 0x0038, iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc)}, |
| @@ -643,34 +645,34 @@ static const struct pci_device_id iwl_hw_card_ids[] = { · 99 unmodified lines | ||
| 643 | 645 | {IWL_PCI_DEVICE(0x2720, 0x40A4, iwl9462_2ac_cfg_soc)}, |
| 644 | 646 | {IWL_PCI_DEVICE(0x2720, 0x4234, iwl9560_2ac_cfg_soc)}, |
| 645 | 647 | {IWL_PCI_DEVICE(0x2720, 0x42A4, iwl9462_2ac_cfg_soc)}, |
| 646 | − {IWL_PCI_DEVICE(0x30DC, 0x0030, iwl9560_2ac_160_cfg_soc)}, | |
| 647 | − {IWL_PCI_DEVICE(0x30DC, 0x0034, iwl9560_2ac_cfg_soc)}, | |
| 648 | − {IWL_PCI_DEVICE(0x30DC, 0x0038, iwl9560_2ac_160_cfg_soc)}, | |
| 649 | − {IWL_PCI_DEVICE(0x30DC, 0x003C, iwl9560_2ac_160_cfg_soc)}, | |
| 650 | − {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9460_2ac_cfg_soc)}, | |
| 651 | − {IWL_PCI_DEVICE(0x30DC, 0x0064, iwl9461_2ac_cfg_soc)}, | |
| 652 | − {IWL_PCI_DEVICE(0x30DC, 0x00A0, iwl9462_2ac_cfg_soc)}, | |
| 653 | − {IWL_PCI_DEVICE(0x30DC, 0x00A4, iwl9462_2ac_cfg_soc)}, | |
| 654 | − {IWL_PCI_DEVICE(0x30DC, 0x0230, iwl9560_2ac_cfg_soc)}, | |
| 655 | − {IWL_PCI_DEVICE(0x30DC, 0x0234, iwl9560_2ac_cfg_soc)}, | |
| 656 | − {IWL_PCI_DEVICE(0x30DC, 0x0238, iwl9560_2ac_cfg_soc)}, | |
| 657 | − {IWL_PCI_DEVICE(0x30DC, 0x023C, iwl9560_2ac_cfg_soc)}, | |
| 658 | − {IWL_PCI_DEVICE(0x30DC, 0x0260, iwl9461_2ac_cfg_soc)}, | |
| 659 | − {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_soc)}, | |
| 660 | − {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_soc)}, | |
| 661 | − {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_soc)}, | |
| 662 | − {IWL_PCI_DEVICE(0x30DC, 0x1010, iwl9260_2ac_cfg)}, | |
| 663 | − {IWL_PCI_DEVICE(0x30DC, 0x1030, iwl9560_2ac_cfg_soc)}, | |
| 664 | − {IWL_PCI_DEVICE(0x30DC, 0x1210, iwl9260_2ac_cfg)}, | |
| 665 | − {IWL_PCI_DEVICE(0x30DC, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, | |
| 666 | − {IWL_PCI_DEVICE(0x30DC, 0x1552, iwl9560_killer_2ac_cfg_soc)}, | |
| 667 | − {IWL_PCI_DEVICE(0x30DC, 0x2030, iwl9560_2ac_160_cfg_soc)}, | |
| 668 | − {IWL_PCI_DEVICE(0x30DC, 0x2034, iwl9560_2ac_160_cfg_soc)}, | |
| 669 | − {IWL_PCI_DEVICE(0x30DC, 0x4030, iwl9560_2ac_160_cfg_soc)}, | |
| 670 | − {IWL_PCI_DEVICE(0x30DC, 0x4034, iwl9560_2ac_160_cfg_soc)}, | |
| 671 | − {IWL_PCI_DEVICE(0x30DC, 0x40A4, iwl9462_2ac_cfg_soc)}, | |
| 672 | − {IWL_PCI_DEVICE(0x30DC, 0x4234, iwl9560_2ac_cfg_soc)}, | |
| 673 | − {IWL_PCI_DEVICE(0x30DC, 0x42A4, iwl9462_2ac_cfg_soc)}, | |
| 648 | + | |
| 649 | + {IWL_PCI_DEVICE(0x30DC, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 650 | + {IWL_PCI_DEVICE(0x30DC, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 651 | + {IWL_PCI_DEVICE(0x30DC, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 652 | + {IWL_PCI_DEVICE(0x30DC, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 653 | + {IWL_PCI_DEVICE(0x30DC, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 654 | + {IWL_PCI_DEVICE(0x30DC, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 655 | + {IWL_PCI_DEVICE(0x30DC, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 656 | + {IWL_PCI_DEVICE(0x30DC, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 657 | + {IWL_PCI_DEVICE(0x30DC, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 658 | + {IWL_PCI_DEVICE(0x30DC, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 659 | + {IWL_PCI_DEVICE(0x30DC, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 660 | + {IWL_PCI_DEVICE(0x30DC, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 661 | + {IWL_PCI_DEVICE(0x30DC, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 662 | + {IWL_PCI_DEVICE(0x30DC, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 663 | + {IWL_PCI_DEVICE(0x30DC, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 664 | + {IWL_PCI_DEVICE(0x30DC, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 665 | + {IWL_PCI_DEVICE(0x30DC, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 666 | + {IWL_PCI_DEVICE(0x30DC, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, | |
| 667 | + {IWL_PCI_DEVICE(0x30DC, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, | |
| 668 | + {IWL_PCI_DEVICE(0x30DC, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 669 | + {IWL_PCI_DEVICE(0x30DC, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 670 | + {IWL_PCI_DEVICE(0x30DC, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 671 | + {IWL_PCI_DEVICE(0x30DC, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 672 | + {IWL_PCI_DEVICE(0x30DC, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 673 | + {IWL_PCI_DEVICE(0x30DC, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 674 | + {IWL_PCI_DEVICE(0x30DC, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 675 | + | |
| 674 | 676 | {IWL_PCI_DEVICE(0x31DC, 0x0030, iwl9560_2ac_160_cfg_shared_clk)}, |
| 675 | 677 | {IWL_PCI_DEVICE(0x31DC, 0x0034, iwl9560_2ac_cfg_shared_clk)}, |
| 676 | 678 | {IWL_PCI_DEVICE(0x31DC, 0x0038, iwl9560_2ac_160_cfg_shared_clk)}, |
| @@ -726,62 +728,60 @@ static const struct pci_device_id iwl_hw_card_ids[] = { · 49 unmodified lines | ||
| 726 | 728 | {IWL_PCI_DEVICE(0x34F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, |
| 727 | 729 | {IWL_PCI_DEVICE(0x34F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, |
| 728 | 730 | |
| 729 | − {IWL_PCI_DEVICE(0x3DF0, 0x0030, iwl9560_2ac_160_cfg_soc)}, | |
| 730 | − {IWL_PCI_DEVICE(0x3DF0, 0x0034, iwl9560_2ac_cfg_soc)}, | |
| 731 | − {IWL_PCI_DEVICE(0x3DF0, 0x0038, iwl9560_2ac_160_cfg_soc)}, | |
| 732 | − {IWL_PCI_DEVICE(0x3DF0, 0x003C, iwl9560_2ac_160_cfg_soc)}, | |
| 733 | − {IWL_PCI_DEVICE(0x3DF0, 0x0060, iwl9461_2ac_cfg_soc)}, | |
| 734 | − {IWL_PCI_DEVICE(0x3DF0, 0x0064, iwl9461_2ac_cfg_soc)}, | |
| 735 | − {IWL_PCI_DEVICE(0x3DF0, 0x00A0, iwl9462_2ac_cfg_soc)}, | |
| 736 | − {IWL_PCI_DEVICE(0x3DF0, 0x00A4, iwl9462_2ac_cfg_soc)}, | |
| 737 | − {IWL_PCI_DEVICE(0x3DF0, 0x0230, iwl9560_2ac_cfg_soc)}, | |
| 738 | − {IWL_PCI_DEVICE(0x3DF0, 0x0234, iwl9560_2ac_cfg_soc)}, | |
| 739 | − {IWL_PCI_DEVICE(0x3DF0, 0x0238, iwl9560_2ac_cfg_soc)}, | |
| 740 | − {IWL_PCI_DEVICE(0x3DF0, 0x023C, iwl9560_2ac_cfg_soc)}, | |
| 741 | − {IWL_PCI_DEVICE(0x3DF0, 0x0260, iwl9461_2ac_cfg_soc)}, | |
| 742 | − {IWL_PCI_DEVICE(0x3DF0, 0x0264, iwl9461_2ac_cfg_soc)}, | |
| 743 | − {IWL_PCI_DEVICE(0x3DF0, 0x02A0, iwl9462_2ac_cfg_soc)}, | |
| 744 | − {IWL_PCI_DEVICE(0x3DF0, 0x02A4, iwl9462_2ac_cfg_soc)}, | |
| 745 | − {IWL_PCI_DEVICE(0x3DF0, 0x1010, iwl9260_2ac_cfg)}, | |
| 746 | − {IWL_PCI_DEVICE(0x3DF0, 0x1030, iwl9560_2ac_cfg_soc)}, | |
| 747 | − {IWL_PCI_DEVICE(0x3DF0, 0x1210, iwl9260_2ac_cfg)}, | |
| 748 | − {IWL_PCI_DEVICE(0x3DF0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, | |
| 749 | − {IWL_PCI_DEVICE(0x3DF0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, | |
| 750 | − {IWL_PCI_DEVICE(0x3DF0, 0x2030, iwl9560_2ac_160_cfg_soc)}, | |
| 751 | − {IWL_PCI_DEVICE(0x3DF0, 0x2034, iwl9560_2ac_160_cfg_soc)}, | |
| 752 | − {IWL_PCI_DEVICE(0x3DF0, 0x4030, iwl9560_2ac_160_cfg_soc)}, | |
| 753 | − {IWL_PCI_DEVICE(0x3DF0, 0x4034, iwl9560_2ac_160_cfg_soc)}, | |
| 754 | − {IWL_PCI_DEVICE(0x3DF0, 0x40A4, iwl9462_2ac_cfg_soc)}, | |
| 755 | − {IWL_PCI_DEVICE(0x3DF0, 0x4234, iwl9560_2ac_cfg_soc)}, | |
| 756 | − {IWL_PCI_DEVICE(0x3DF0, 0x42A4, iwl9462_2ac_cfg_soc)}, | |
| 757 | − {IWL_PCI_DEVICE(0x43F0, 0x0030, iwl9560_2ac_160_cfg_soc)}, | |
| 758 | − {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_soc)}, | |
| 759 | − {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, | |
| 760 | − {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, | |
| 761 | − {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_soc)}, | |
| 762 | − {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_soc)}, | |
| 763 | − {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_soc)}, | |
| 764 | − {IWL_PCI_DEVICE(0x43F0, 0x00A4, iwl9462_2ac_cfg_soc)}, | |
| 765 | − {IWL_PCI_DEVICE(0x43F0, 0x0230, iwl9560_2ac_cfg_soc)}, | |
| 766 | − {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_soc)}, | |
| 767 | − {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_soc)}, | |
| 768 | − {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_soc)}, | |
| 769 | − {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_soc)}, | |
| 770 | − {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_soc)}, | |
| 771 | − {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_soc)}, | |
| 772 | − {IWL_PCI_DEVICE(0x43F0, 0x02A4, iwl9462_2ac_cfg_soc)}, | |
| 773 | − {IWL_PCI_DEVICE(0x43F0, 0x1010, iwl9260_2ac_cfg)}, | |
| 774 | − {IWL_PCI_DEVICE(0x43F0, 0x1030, iwl9560_2ac_cfg_soc)}, | |
| 775 | − {IWL_PCI_DEVICE(0x43F0, 0x1210, iwl9260_2ac_cfg)}, | |
| 776 | − {IWL_PCI_DEVICE(0x43F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, | |
| 777 | − {IWL_PCI_DEVICE(0x43F0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, | |
| 778 | − {IWL_PCI_DEVICE(0x43F0, 0x2030, iwl9560_2ac_160_cfg_soc)}, | |
| 779 | − {IWL_PCI_DEVICE(0x43F0, 0x2034, iwl9560_2ac_160_cfg_soc)}, | |
| 780 | − {IWL_PCI_DEVICE(0x43F0, 0x4030, iwl9560_2ac_160_cfg_soc)}, | |
| 781 | − {IWL_PCI_DEVICE(0x43F0, 0x4034, iwl9560_2ac_160_cfg_soc)}, | |
| 782 | − {IWL_PCI_DEVICE(0x43F0, 0x40A4, iwl9462_2ac_cfg_soc)}, | |
| 783 | − {IWL_PCI_DEVICE(0x43F0, 0x4234, iwl9560_2ac_cfg_soc)}, | |
| 784 | − {IWL_PCI_DEVICE(0x43F0, 0x42A4, iwl9462_2ac_cfg_soc)}, | |
| 731 | + {IWL_PCI_DEVICE(0x3DF0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 732 | + {IWL_PCI_DEVICE(0x3DF0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 733 | + {IWL_PCI_DEVICE(0x3DF0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 734 | + {IWL_PCI_DEVICE(0x3DF0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 735 | + {IWL_PCI_DEVICE(0x3DF0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 736 | + {IWL_PCI_DEVICE(0x3DF0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 737 | + {IWL_PCI_DEVICE(0x3DF0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 738 | + {IWL_PCI_DEVICE(0x3DF0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 739 | + {IWL_PCI_DEVICE(0x3DF0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 740 | + {IWL_PCI_DEVICE(0x3DF0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 741 | + {IWL_PCI_DEVICE(0x3DF0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 742 | + {IWL_PCI_DEVICE(0x3DF0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 743 | + {IWL_PCI_DEVICE(0x3DF0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 744 | + {IWL_PCI_DEVICE(0x3DF0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 745 | + {IWL_PCI_DEVICE(0x3DF0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 746 | + {IWL_PCI_DEVICE(0x3DF0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 747 | + {IWL_PCI_DEVICE(0x3DF0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 748 | + {IWL_PCI_DEVICE(0x3DF0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, | |
| 749 | + {IWL_PCI_DEVICE(0x3DF0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, | |
| 750 | + {IWL_PCI_DEVICE(0x3DF0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 751 | + {IWL_PCI_DEVICE(0x3DF0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 752 | + {IWL_PCI_DEVICE(0x3DF0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 753 | + {IWL_PCI_DEVICE(0x3DF0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 754 | + {IWL_PCI_DEVICE(0x3DF0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 755 | + {IWL_PCI_DEVICE(0x3DF0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 756 | + {IWL_PCI_DEVICE(0x3DF0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 757 | + | |
| 758 | + {IWL_PCI_DEVICE(0x43F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 759 | + {IWL_PCI_DEVICE(0x43F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 760 | + {IWL_PCI_DEVICE(0x43F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 761 | + {IWL_PCI_DEVICE(0x43F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 762 | + {IWL_PCI_DEVICE(0x43F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 763 | + {IWL_PCI_DEVICE(0x43F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 764 | + {IWL_PCI_DEVICE(0x43F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 765 | + {IWL_PCI_DEVICE(0x43F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 766 | + {IWL_PCI_DEVICE(0x43F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 767 | + {IWL_PCI_DEVICE(0x43F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 768 | + {IWL_PCI_DEVICE(0x43F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 769 | + {IWL_PCI_DEVICE(0x43F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 770 | + {IWL_PCI_DEVICE(0x43F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 771 | + {IWL_PCI_DEVICE(0x43F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 772 | + {IWL_PCI_DEVICE(0x43F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 773 | + {IWL_PCI_DEVICE(0x43F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 774 | + {IWL_PCI_DEVICE(0x43F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 775 | + {IWL_PCI_DEVICE(0x43F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, | |
| 776 | + {IWL_PCI_DEVICE(0x43F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, | |
| 777 | + {IWL_PCI_DEVICE(0x43F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 778 | + {IWL_PCI_DEVICE(0x43F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 779 | + {IWL_PCI_DEVICE(0x43F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 780 | + {IWL_PCI_DEVICE(0x43F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 781 | + {IWL_PCI_DEVICE(0x43F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 782 | + {IWL_PCI_DEVICE(0x43F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 783 | + {IWL_PCI_DEVICE(0x43F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 784 | + | |
| 785 | 785 | {IWL_PCI_DEVICE(0x9DF0, 0x0000, iwl9460_2ac_cfg_soc)}, |
| 786 | 786 | {IWL_PCI_DEVICE(0x9DF0, 0x0010, iwl9460_2ac_cfg_soc)}, |
| 787 | 787 | {IWL_PCI_DEVICE(0x9DF0, 0x0030, iwl9560_2ac_160_cfg_soc)}, |
| @@ -821,34 +821,34 @@ static const struct pci_device_id iwl_hw_card_ids[] = { · 33 unmodified lines | ||
| 821 | 821 | {IWL_PCI_DEVICE(0x9DF0, 0x40A4, iwl9462_2ac_cfg_soc)}, |
| 822 | 822 | {IWL_PCI_DEVICE(0x9DF0, 0x4234, iwl9560_2ac_cfg_soc)}, |
| 823 | 823 | {IWL_PCI_DEVICE(0x9DF0, 0x42A4, iwl9462_2ac_cfg_soc)}, |
| 824 | − {IWL_PCI_DEVICE(0xA0F0, 0x0030, iwl9560_2ac_160_cfg_soc)}, | |
| 825 | − {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_soc)}, | |
| 826 | − {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_soc)}, | |
| 827 | − {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_soc)}, | |
| 828 | − {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_soc)}, | |
| 829 | − {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_soc)}, | |
| 830 | − {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_soc)}, | |
| 831 | − {IWL_PCI_DEVICE(0xA0F0, 0x00A4, iwl9462_2ac_cfg_soc)}, | |
| 832 | − {IWL_PCI_DEVICE(0xA0F0, 0x0230, iwl9560_2ac_cfg_soc)}, | |
| 833 | − {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_soc)}, | |
| 834 | − {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_soc)}, | |
| 835 | − {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_soc)}, | |
| 836 | − {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_soc)}, | |
| 837 | − {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_soc)}, | |
| 838 | − {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_soc)}, | |
| 839 | − {IWL_PCI_DEVICE(0xA0F0, 0x02A4, iwl9462_2ac_cfg_soc)}, | |
| 840 | − {IWL_PCI_DEVICE(0xA0F0, 0x1010, iwl9260_2ac_cfg)}, | |
| 841 | − {IWL_PCI_DEVICE(0xA0F0, 0x1030, iwl9560_2ac_cfg_soc)}, | |
| 842 | − {IWL_PCI_DEVICE(0xA0F0, 0x1210, iwl9260_2ac_cfg)}, | |
| 843 | − {IWL_PCI_DEVICE(0xA0F0, 0x1551, iwl9560_killer_s_2ac_cfg_soc)}, | |
| 844 | − {IWL_PCI_DEVICE(0xA0F0, 0x1552, iwl9560_killer_2ac_cfg_soc)}, | |
| 845 | − {IWL_PCI_DEVICE(0xA0F0, 0x2030, iwl9560_2ac_160_cfg_soc)}, | |
| 846 | − {IWL_PCI_DEVICE(0xA0F0, 0x2034, iwl9560_2ac_160_cfg_soc)}, | |
| 847 | − {IWL_PCI_DEVICE(0xA0F0, 0x4030, iwl9560_2ac_160_cfg_soc)}, | |
| 848 | − {IWL_PCI_DEVICE(0xA0F0, 0x4034, iwl9560_2ac_160_cfg_soc)}, | |
| 849 | − {IWL_PCI_DEVICE(0xA0F0, 0x40A4, iwl9462_2ac_cfg_soc)}, | |
| 850 | − {IWL_PCI_DEVICE(0xA0F0, 0x4234, iwl9560_2ac_cfg_soc)}, | |
| 851 | − {IWL_PCI_DEVICE(0xA0F0, 0x42A4, iwl9462_2ac_cfg_soc)}, | |
| 824 | + | |
| 825 | + {IWL_PCI_DEVICE(0xA0F0, 0x0030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 826 | + {IWL_PCI_DEVICE(0xA0F0, 0x0034, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 827 | + {IWL_PCI_DEVICE(0xA0F0, 0x0038, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 828 | + {IWL_PCI_DEVICE(0xA0F0, 0x003C, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 829 | + {IWL_PCI_DEVICE(0xA0F0, 0x0060, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 830 | + {IWL_PCI_DEVICE(0xA0F0, 0x0064, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 831 | + {IWL_PCI_DEVICE(0xA0F0, 0x00A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 832 | + {IWL_PCI_DEVICE(0xA0F0, 0x00A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 833 | + {IWL_PCI_DEVICE(0xA0F0, 0x0230, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 834 | + {IWL_PCI_DEVICE(0xA0F0, 0x0234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 835 | + {IWL_PCI_DEVICE(0xA0F0, 0x0238, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 836 | + {IWL_PCI_DEVICE(0xA0F0, 0x023C, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 837 | + {IWL_PCI_DEVICE(0xA0F0, 0x0260, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 838 | + {IWL_PCI_DEVICE(0xA0F0, 0x0264, iwl9461_2ac_cfg_qu_b0_jf_b0)}, | |
| 839 | + {IWL_PCI_DEVICE(0xA0F0, 0x02A0, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 840 | + {IWL_PCI_DEVICE(0xA0F0, 0x02A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 841 | + {IWL_PCI_DEVICE(0xA0F0, 0x1030, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 842 | + {IWL_PCI_DEVICE(0xA0F0, 0x1551, killer1550s_2ac_cfg_qu_b0_jf_b0)}, | |
| 843 | + {IWL_PCI_DEVICE(0xA0F0, 0x1552, killer1550i_2ac_cfg_qu_b0_jf_b0)}, | |
| 844 | + {IWL_PCI_DEVICE(0xA0F0, 0x2030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 845 | + {IWL_PCI_DEVICE(0xA0F0, 0x2034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 846 | + {IWL_PCI_DEVICE(0xA0F0, 0x4030, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 847 | + {IWL_PCI_DEVICE(0xA0F0, 0x4034, iwl9560_2ac_160_cfg_qu_b0_jf_b0)}, | |
| 848 | + {IWL_PCI_DEVICE(0xA0F0, 0x40A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 849 | + {IWL_PCI_DEVICE(0xA0F0, 0x4234, iwl9560_2ac_cfg_qu_b0_jf_b0)}, | |
| 850 | + {IWL_PCI_DEVICE(0xA0F0, 0x42A4, iwl9462_2ac_cfg_qu_b0_jf_b0)}, | |
| 851 | + | |
| 852 | 852 | {IWL_PCI_DEVICE(0xA370, 0x0030, iwl9560_2ac_160_cfg_soc)}, |
| 853 | 853 | {IWL_PCI_DEVICE(0xA370, 0x0034, iwl9560_2ac_cfg_soc)}, |
| 854 | 854 | {IWL_PCI_DEVICE(0xA370, 0x0038, iwl9560_2ac_160_cfg_soc)}, |
| @@ -3272,11 +3272,17 @@ static struct iwl_trans_dump_data · 3271 unmodified lines | ||
| 3272 | 3272 | ptr = cmdq->write_ptr; |
| 3273 | 3273 | for (i = 0; i < cmdq->n_window; i++) { |
| 3274 | 3274 | u8 idx = iwl_pcie_get_cmd_index(cmdq, ptr); |
| 3275 | + u8 tfdidx; | |
| 3275 | 3276 | u32 caplen, cmdlen; |
| 3276 | 3277 | |
| 3278 | + if (trans->trans_cfg->use_tfh) | |
| 3279 | + tfdidx = idx; | |
| 3280 | + else | |
| 3281 | + tfdidx = ptr; | |
| 3282 | + | |
| 3277 | 3283 | cmdlen = iwl_trans_pcie_get_cmdlen(trans, |
| 3278 | − cmdq->tfds + | |
| 3279 | − tfd_size * ptr); | |
| 3284 | + (u8 *)cmdq->tfds + | |
| 3285 | + tfd_size * tfdidx); | |
| 3280 | 3286 | caplen = min_t(u32, TFD_MAX_PAYLOAD_SIZE, cmdlen); |
| 3281 | 3287 | |
| 3282 | 3288 | if (cmdlen) { |
| @@ -3450,6 +3456,15 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, · 167 unmodified lines | ||
| 3450 | 3456 | spin_lock_init(&trans_pcie->reg_lock); |
| 3451 | 3457 | mutex_init(&trans_pcie->mutex); |
| 3452 | 3458 | init_waitqueue_head(&trans_pcie->ucode_write_waitq); |
| 3459 | + | |
| 3460 | + trans_pcie->rba.alloc_wq = alloc_workqueue("rb_allocator", | |
| 3461 | + WQ_HIGHPRI | WQ_UNBOUND, 1); | |
| 3462 | + if (!trans_pcie->rba.alloc_wq) { | |
| 3463 | + ret = -ENOMEM; | |
| 3464 | + goto out_free_trans; | |
| 3465 | + } | |
| 3466 | + INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work); | |
| 3467 | + | |
| 3453 | 3468 | trans_pcie->tso_hdr_page = alloc_percpu(struct iwl_tso_hdr_page); |
| 3454 | 3469 | if (!trans_pcie->tso_hdr_page) { |
| 3455 | 3470 | ret = -ENOMEM; |
| @@ -3584,10 +3599,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, · 128 unmodified lines | ||
| 3584 | 3599 | trans_pcie->inta_mask = CSR_INI_SET_MASK; |
| 3585 | 3600 | } |
| 3586 | 3601 | |
| 3587 | − trans_pcie->rba.alloc_wq = alloc_workqueue("rb_allocator", | |
| 3588 | − WQ_HIGHPRI | WQ_UNBOUND, 1); | |
| 3589 | − INIT_WORK(&trans_pcie->rba.rx_alloc, iwl_pcie_rx_allocator_work); | |
| 3590 | − | |
| 3591 | 3602 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 3592 | 3603 | trans_pcie->fw_mon_data.state = IWL_FW_MON_DBGFS_STATE_CLOSED; |
| 3593 | 3604 | mutex_init(&trans_pcie->fw_mon_data.mutex); |
| @@ -3599,6 +3610,8 @@ out_free_ict: · 5 unmodified lines | ||
| 3599 | 3610 | iwl_pcie_free_ict(trans); |
| 3600 | 3611 | out_no_pci: |
| 3601 | 3612 | free_percpu(trans_pcie->tso_hdr_page); |
| 3613 | + destroy_workqueue(trans_pcie->rba.alloc_wq); | |
| 3614 | +out_free_trans: | |
| 3602 | 3615 | iwl_trans_free(trans); |
| 3603 | 3616 | return ERR_PTR(ret); |
| 3604 | 3617 | } |
| @@ -4026,7 +4026,7 @@ static int __init init_mac80211_hwsim(void) · 4025 unmodified lines | ||
| 4026 | 4026 | err = dev_alloc_name(hwsim_mon, hwsim_mon->name); |
| 4027 | 4027 | if (err < 0) { |
| 4028 | 4028 | rtnl_unlock(); |
| 4029 | − goto out_free_radios; | |
| 4029 | + goto out_free_mon; | |
| 4030 | 4030 | } |
| 4031 | 4031 | |
| 4032 | 4032 | err = register_netdevice(hwsim_mon); |
| @@ -23,7 +23,6 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/leds.h> |
| 24 | 24 | #include <linux/mutex.h> |
| 25 | 25 | #include <linux/etherdevice.h> |
| 26 | −#include <linux/input-polldev.h> | |
| 27 | 26 | #include <linux/kfifo.h> |
| 28 | 27 | #include <linux/hrtimer.h> |
| 29 | 28 | #include <linux/average.h> |
| @@ -555,7 +555,7 @@ static ssize_t rt2x00debug_write_restart_hw(struct file *file, · 554 unmodified lines | ||
| 555 | 555 | { |
| 556 | 556 | struct rt2x00debug_intf *intf = file->private_data; |
| 557 | 557 | struct rt2x00_dev *rt2x00dev = intf->rt2x00dev; |
| 558 | − static unsigned long last_reset; | |
| 558 | + static unsigned long last_reset = INITIAL_JIFFIES; | |
| 559 | 559 | |
| 560 | 560 | if (!rt2x00_has_cap_restart_hw(rt2x00dev)) |
| 561 | 561 | return -EOPNOTSUPP; |
| @@ -719,7 +719,6 @@ err_unmap: · 718 unmodified lines | ||
| 719 | 719 | xenvif_unmap_frontend_data_rings(queue); |
| 720 | 720 | netif_napi_del(&queue->napi); |
| 721 | 721 | err: |
| 722 | − module_put(THIS_MODULE); | |
| 723 | 722 | return err; |
| 724 | 723 | } |
| 725 | 724 | |
| @@ -547,18 +547,25 @@ static int pn533_usb_probe(struct usb_interface *interface, · 546 unmodified lines | ||
| 547 | 547 | |
| 548 | 548 | rc = pn533_finalize_setup(priv); |
| 549 | 549 | if (rc) |
| 550 | − goto error; | |
| 550 | + goto err_deregister; | |
| 551 | 551 | |
| 552 | 552 | usb_set_intfdata(interface, phy); |
| 553 | 553 | |
| 554 | 554 | return 0; |
| 555 | 555 | |
| 556 | +err_deregister: | |
| 557 | + pn533_unregister_device(phy->priv); | |
| 556 | 558 | error: |
| 559 | + usb_kill_urb(phy->in_urb); | |
| 560 | + usb_kill_urb(phy->out_urb); | |
| 561 | + usb_kill_urb(phy->ack_urb); | |
| 562 | + | |
| 557 | 563 | usb_free_urb(phy->in_urb); |
| 558 | 564 | usb_free_urb(phy->out_urb); |
| 559 | 565 | usb_free_urb(phy->ack_urb); |
| 560 | 566 | usb_put_dev(phy->udev); |
| 561 | 567 | kfree(in_buf); |
| 568 | + kfree(phy->ack_buffer); | |
| 562 | 569 | |
| 563 | 570 | return rc; |
| 564 | 571 | } |
| @@ -116,10 +116,26 @@ static void nvme_queue_scan(struct nvme_ctrl *ctrl) · 115 unmodified lines | ||
| 116 | 116 | /* |
| 117 | 117 | * Only new queue scan work when admin and IO queues are both alive |
| 118 | 118 | */ |
| 119 | − if (ctrl->state == NVME_CTRL_LIVE) | |
| 119 | + if (ctrl->state == NVME_CTRL_LIVE && ctrl->tagset) | |
| 120 | 120 | queue_work(nvme_wq, &ctrl->scan_work); |
| 121 | 121 | } |
| 122 | 122 | |
| 123 | +/* | |
| 124 | + * Use this function to proceed with scheduling reset_work for a controller | |
| 125 | + * that had previously been set to the resetting state. This is intended for | |
| 126 | + * code paths that can't be interrupted by other reset attempts. A hot removal | |
| 127 | + * may prevent this from succeeding. | |
| 128 | + */ | |
| 129 | +int nvme_try_sched_reset(struct nvme_ctrl *ctrl) | |
| 130 | +{ | |
| 131 | + if (ctrl->state != NVME_CTRL_RESETTING) | |
| 132 | + return -EBUSY; | |
| 133 | + if (!queue_work(nvme_reset_wq, &ctrl->reset_work)) | |
| 134 | + return -EBUSY; | |
| 135 | + return 0; | |
| 136 | +} | |
| 137 | +EXPORT_SYMBOL_GPL(nvme_try_sched_reset); | |
| 138 | + | |
| 123 | 139 | int nvme_reset_ctrl(struct nvme_ctrl *ctrl) |
| 124 | 140 | { |
| 125 | 141 | if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) |
| @@ -137,8 +153,7 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl) · 11 unmodified lines | ||
| 137 | 153 | ret = nvme_reset_ctrl(ctrl); |
| 138 | 154 | if (!ret) { |
| 139 | 155 | flush_work(&ctrl->reset_work); |
| 140 | − if (ctrl->state != NVME_CTRL_LIVE && | |
| 141 | − ctrl->state != NVME_CTRL_ADMIN_ONLY) | |
| 156 | + if (ctrl->state != NVME_CTRL_LIVE) | |
| 142 | 157 | ret = -ENETRESET; |
| 143 | 158 | } |
| 144 | 159 | |
| @@ -315,15 +330,6 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, · 170 unmodified lines | ||
| 315 | 330 | |
| 316 | 331 | old_state = ctrl->state; |
| 317 | 332 | switch (new_state) { |
| 318 | − case NVME_CTRL_ADMIN_ONLY: | |
| 319 | − switch (old_state) { | |
| 320 | − case NVME_CTRL_CONNECTING: | |
| 321 | − changed = true; | |
| 322 | − /* FALLTHRU */ | |
| 323 | − default: | |
| 324 | − break; | |
| 325 | − } | |
| 326 | − break; | |
| 327 | 333 | case NVME_CTRL_LIVE: |
| 328 | 334 | switch (old_state) { |
| 329 | 335 | case NVME_CTRL_NEW: |
| @@ -339,7 +345,6 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, · 9 unmodified lines | ||
| 339 | 345 | switch (old_state) { |
| 340 | 346 | case NVME_CTRL_NEW: |
| 341 | 347 | case NVME_CTRL_LIVE: |
| 342 | − case NVME_CTRL_ADMIN_ONLY: | |
| 343 | 348 | changed = true; |
| 344 | 349 | /* FALLTHRU */ |
| 345 | 350 | default: |
| @@ -359,7 +364,6 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, · 13 unmodified lines | ||
| 359 | 364 | case NVME_CTRL_DELETING: |
| 360 | 365 | switch (old_state) { |
| 361 | 366 | case NVME_CTRL_LIVE: |
| 362 | − case NVME_CTRL_ADMIN_ONLY: | |
| 363 | 367 | case NVME_CTRL_RESETTING: |
| 364 | 368 | case NVME_CTRL_CONNECTING: |
| 365 | 369 | changed = true; |
| @@ -381,8 +385,10 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, · 15 unmodified lines | ||
| 381 | 385 | break; |
| 382 | 386 | } |
| 383 | 387 | |
| 384 | − if (changed) | |
| 388 | + if (changed) { | |
| 385 | 389 | ctrl->state = new_state; |
| 390 | + wake_up_all(&ctrl->state_wq); | |
| 391 | + } | |
| 386 | 392 | |
| 387 | 393 | spin_unlock_irqrestore(&ctrl->lock, flags); |
| 388 | 394 | if (changed && ctrl->state == NVME_CTRL_LIVE) |
| @@ -391,6 +397,39 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, · 2 unmodified lines | ||
| 391 | 397 | } |
| 392 | 398 | EXPORT_SYMBOL_GPL(nvme_change_ctrl_state); |
| 393 | 399 | |
| 400 | +/* | |
| 401 | + * Returns true for sink states that can't ever transition back to live. | |
| 402 | + */ | |
| 403 | +static bool nvme_state_terminal(struct nvme_ctrl *ctrl) | |
| 404 | +{ | |
| 405 | + switch (ctrl->state) { | |
| 406 | + case NVME_CTRL_NEW: | |
| 407 | + case NVME_CTRL_LIVE: | |
| 408 | + case NVME_CTRL_RESETTING: | |
| 409 | + case NVME_CTRL_CONNECTING: | |
| 410 | + return false; | |
| 411 | + case NVME_CTRL_DELETING: | |
| 412 | + case NVME_CTRL_DEAD: | |
| 413 | + return true; | |
| 414 | + default: | |
| 415 | + WARN_ONCE(1, "Unhandled ctrl state:%d", ctrl->state); | |
| 416 | + return true; | |
| 417 | + } | |
| 418 | +} | |
| 419 | + | |
| 420 | +/* | |
| 421 | + * Waits for the controller state to be resetting, or returns false if it is | |
| 422 | + * not possible to ever transition to that state. | |
| 423 | + */ | |
| 424 | +bool nvme_wait_reset(struct nvme_ctrl *ctrl) | |
| 425 | +{ | |
| 426 | + wait_event(ctrl->state_wq, | |
| 427 | + nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING) || | |
| 428 | + nvme_state_terminal(ctrl)); | |
| 429 | + return ctrl->state == NVME_CTRL_RESETTING; | |
| 430 | +} | |
| 431 | +EXPORT_SYMBOL_GPL(nvme_wait_reset); | |
| 432 | + | |
| 394 | 433 | static void nvme_free_ns_head(struct kref *ref) |
| 395 | 434 | { |
| 396 | 435 | struct nvme_ns_head *head = |
| @@ -1306,8 +1345,6 @@ static void nvme_update_formats(struct nvme_ctrl *ctrl) · 909 unmodified lines | ||
| 1306 | 1345 | if (ns->disk && nvme_revalidate_disk(ns->disk)) |
| 1307 | 1346 | nvme_set_queue_dying(ns); |
| 1308 | 1347 | up_read(&ctrl->namespaces_rwsem); |
| 1309 | − | |
| 1310 | − nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL); | |
| 1311 | 1348 | } |
| 1312 | 1349 | |
| 1313 | 1350 | static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects) |
| @@ -1323,6 +1360,7 @@ static void nvme_passthru_end(struct nvme_ctrl *ctrl, u32 effects) · 9 unmodified lines | ||
| 1323 | 1360 | nvme_unfreeze(ctrl); |
| 1324 | 1361 | nvme_mpath_unfreeze(ctrl->subsys); |
| 1325 | 1362 | mutex_unlock(&ctrl->subsys->lock); |
| 1363 | + nvme_remove_invalid_namespaces(ctrl, NVME_NSID_ALL); | |
| 1326 | 1364 | mutex_unlock(&ctrl->scan_lock); |
| 1327 | 1365 | } |
| 1328 | 1366 | if (effects & NVME_CMD_EFFECTS_CCC) |
| @@ -2874,7 +2912,6 @@ static int nvme_dev_open(struct inode *inode, struct file *file) · 1545 unmodified lines | ||
| 2874 | 2912 | |
| 2875 | 2913 | switch (ctrl->state) { |
| 2876 | 2914 | case NVME_CTRL_LIVE: |
| 2877 | − case NVME_CTRL_ADMIN_ONLY: | |
| 2878 | 2915 | break; |
| 2879 | 2916 | default: |
| 2880 | 2917 | return -EWOULDBLOCK; |
| @@ -3168,7 +3205,6 @@ static ssize_t nvme_sysfs_show_state(struct device *dev, · 287 unmodified lines | ||
| 3168 | 3205 | static const char *const state_name[] = { |
| 3169 | 3206 | [NVME_CTRL_NEW] = "new", |
| 3170 | 3207 | [NVME_CTRL_LIVE] = "live", |
| 3171 | − [NVME_CTRL_ADMIN_ONLY] = "only-admin", | |
| 3172 | 3208 | [NVME_CTRL_RESETTING] = "resetting", |
| 3173 | 3209 | [NVME_CTRL_CONNECTING] = "connecting", |
| 3174 | 3210 | [NVME_CTRL_DELETING] = "deleting", |
| @@ -3679,11 +3715,10 @@ static void nvme_scan_work(struct work_struct *work) · 504 unmodified lines | ||
| 3679 | 3715 | struct nvme_id_ctrl *id; |
| 3680 | 3716 | unsigned nn; |
| 3681 | 3717 | |
| 3682 | − if (ctrl->state != NVME_CTRL_LIVE) | |
| 3718 | + /* No tagset on a live ctrl means IO queues could not created */ | |
| 3719 | + if (ctrl->state != NVME_CTRL_LIVE || !ctrl->tagset) | |
| 3683 | 3720 | return; |
| 3684 | 3721 | |
| 3685 | − WARN_ON_ONCE(!ctrl->tagset); | |
| 3686 | − | |
| 3687 | 3722 | if (test_and_clear_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events)) { |
| 3688 | 3723 | dev_info(ctrl->device, "rescanning namespaces.\n"); |
| 3689 | 3724 | nvme_clear_changed_ns_log(ctrl); |
| @@ -3844,13 +3879,13 @@ static void nvme_fw_act_work(struct work_struct *work) · 154 unmodified lines | ||
| 3844 | 3879 | if (time_after(jiffies, fw_act_timeout)) { |
| 3845 | 3880 | dev_warn(ctrl->device, |
| 3846 | 3881 | "Fw activation timeout, reset controller\n"); |
| 3847 | − nvme_reset_ctrl(ctrl); | |
| 3848 | − break; | |
| 3882 | + nvme_try_sched_reset(ctrl); | |
| 3883 | + return; | |
| 3849 | 3884 | } |
| 3850 | 3885 | msleep(100); |
| 3851 | 3886 | } |
| 3852 | 3887 | |
| 3853 | − if (ctrl->state != NVME_CTRL_LIVE) | |
| 3888 | + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_LIVE)) | |
| 3854 | 3889 | return; |
| 3855 | 3890 | |
| 3856 | 3891 | nvme_start_queues(ctrl); |
| @@ -3870,7 +3905,13 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) · 13 unmodified lines | ||
| 3870 | 3905 | nvme_queue_scan(ctrl); |
| 3871 | 3906 | break; |
| 3872 | 3907 | case NVME_AER_NOTICE_FW_ACT_STARTING: |
| 3873 | − queue_work(nvme_wq, &ctrl->fw_act_work); | |
| 3908 | + /* | |
| 3909 | + * We are (ab)using the RESETTING state to prevent subsequent | |
| 3910 | + * recovery actions from interfering with the controller's | |
| 3911 | + * firmware activation. | |
| 3912 | + */ | |
| 3913 | + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) | |
| 3914 | + queue_work(nvme_wq, &ctrl->fw_act_work); | |
| 3874 | 3915 | break; |
| 3875 | 3916 | #ifdef CONFIG_NVME_MULTIPATH |
| 3876 | 3917 | case NVME_AER_NOTICE_ANA: |
| @@ -3993,6 +4034,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev, · 116 unmodified lines | ||
| 3993 | 4034 | INIT_WORK(&ctrl->async_event_work, nvme_async_event_work); |
| 3994 | 4035 | INIT_WORK(&ctrl->fw_act_work, nvme_fw_act_work); |
| 3995 | 4036 | INIT_WORK(&ctrl->delete_work, nvme_delete_ctrl_work); |
| 4037 | + init_waitqueue_head(&ctrl->state_wq); | |
| 3996 | 4038 | |
| 3997 | 4039 | INIT_DELAYED_WORK(&ctrl->ka_work, nvme_keep_alive_work); |
| 3998 | 4040 | memset(&ctrl->ka_cmd, 0, sizeof(ctrl->ka_cmd)); |
| @@ -182,8 +182,7 @@ bool nvmf_ip_options_match(struct nvme_ctrl *ctrl, · 181 unmodified lines | ||
| 182 | 182 | static inline bool nvmf_check_ready(struct nvme_ctrl *ctrl, struct request *rq, |
| 183 | 183 | bool queue_live) |
| 184 | 184 | { |
| 185 | − if (likely(ctrl->state == NVME_CTRL_LIVE || | |
| 186 | − ctrl->state == NVME_CTRL_ADMIN_ONLY)) | |
| 185 | + if (likely(ctrl->state == NVME_CTRL_LIVE)) | |
| 187 | 186 | return true; |
| 188 | 187 | return __nvmf_check_ready(ctrl, rq, queue_live); |
| 189 | 188 | } |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/sed-opal.h> |
| 16 | 16 | #include <linux/fault-inject.h> |
| 17 | 17 | #include <linux/rcupdate.h> |
| 18 | +#include <linux/wait.h> | |
| 18 | 19 | |
| 19 | 20 | #include <trace/events/block.h> |
| 20 | 21 | |
| @@ -161,7 +162,6 @@ static inline u16 nvme_req_qid(struct request *req) · 140 unmodified lines | ||
| 161 | 162 | enum nvme_ctrl_state { |
| 162 | 163 | NVME_CTRL_NEW, |
| 163 | 164 | NVME_CTRL_LIVE, |
| 164 | − NVME_CTRL_ADMIN_ONLY, /* Only admin queue live */ | |
| 165 | 165 | NVME_CTRL_RESETTING, |
| 166 | 166 | NVME_CTRL_CONNECTING, |
| 167 | 167 | NVME_CTRL_DELETING, |
| @@ -199,6 +199,7 @@ struct nvme_ctrl { · 31 unmodified lines | ||
| 199 | 199 | struct cdev cdev; |
| 200 | 200 | struct work_struct reset_work; |
| 201 | 201 | struct work_struct delete_work; |
| 202 | + wait_queue_head_t state_wq; | |
| 202 | 203 | |
| 203 | 204 | struct nvme_subsystem *subsys; |
| 204 | 205 | struct list_head subsys_entry; |
| @@ -449,6 +450,7 @@ void nvme_complete_rq(struct request *req); · 244 unmodified lines | ||
| 449 | 450 | bool nvme_cancel_request(struct request *req, void *data, bool reserved); |
| 450 | 451 | bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, |
| 451 | 452 | enum nvme_ctrl_state new_state); |
| 453 | +bool nvme_wait_reset(struct nvme_ctrl *ctrl); | |
| 452 | 454 | int nvme_disable_ctrl(struct nvme_ctrl *ctrl); |
| 453 | 455 | int nvme_enable_ctrl(struct nvme_ctrl *ctrl); |
| 454 | 456 | int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl); |
| @@ -499,6 +501,7 @@ int nvme_set_queue_count(struct nvme_ctrl *ctrl, int *count); · 44 unmodified lines | ||
| 499 | 501 | void nvme_stop_keep_alive(struct nvme_ctrl *ctrl); |
| 500 | 502 | int nvme_reset_ctrl(struct nvme_ctrl *ctrl); |
| 501 | 503 | int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl); |
| 504 | +int nvme_try_sched_reset(struct nvme_ctrl *ctrl); | |
| 502 | 505 | int nvme_delete_ctrl(struct nvme_ctrl *ctrl); |
| 503 | 506 | |
| 504 | 507 | int nvme_get_log(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page, u8 lsp, |
| @@ -773,7 +773,8 @@ static blk_status_t nvme_setup_prp_simple(struct nvme_dev *dev, · 772 unmodified lines | ||
| 773 | 773 | struct bio_vec *bv) |
| 774 | 774 | { |
| 775 | 775 | struct nvme_iod *iod = blk_mq_rq_to_pdu(req); |
| 776 | − unsigned int first_prp_len = dev->ctrl.page_size - bv->bv_offset; | |
| 776 | + unsigned int offset = bv->bv_offset & (dev->ctrl.page_size - 1); | |
| 777 | + unsigned int first_prp_len = dev->ctrl.page_size - offset; | |
| 777 | 778 | |
| 778 | 779 | iod->first_dma = dma_map_bvec(dev->dev, bv, rq_dma_dir(req), 0); |
| 779 | 780 | if (dma_mapping_error(dev->dev, iod->first_dma)) |
| @@ -2263,10 +2264,7 @@ static bool __nvme_disable_io_queues(struct nvme_dev *dev, u8 opcode) · 1483 unmodified lines | ||
| 2263 | 2264 | return true; |
| 2264 | 2265 | } |
| 2265 | 2266 | |
| 2266 | −/* | |
| 2267 | − * return error value only when tagset allocation failed | |
| 2268 | − */ | |
| 2269 | −static int nvme_dev_add(struct nvme_dev *dev) | |
| 2267 | +static void nvme_dev_add(struct nvme_dev *dev) | |
| 2270 | 2268 | { |
| 2271 | 2269 | int ret; |
| 2272 | 2270 | |
| @@ -2296,7 +2294,7 @@ static int nvme_dev_add(struct nvme_dev *dev) · 23 unmodified lines | ||
| 2296 | 2294 | if (ret) { |
| 2297 | 2295 | dev_warn(dev->ctrl.device, |
| 2298 | 2296 | "IO queues tagset allocation failed %d\n", ret); |
| 2299 | − return ret; | |
| 2297 | + return; | |
| 2300 | 2298 | } |
| 2301 | 2299 | dev->ctrl.tagset = &dev->tagset; |
| 2302 | 2300 | } else { |
| @@ -2307,7 +2305,6 @@ static int nvme_dev_add(struct nvme_dev *dev) · 4 unmodified lines | ||
| 2307 | 2305 | } |
| 2308 | 2306 | |
| 2309 | 2307 | nvme_dbbuf_set(dev); |
| 2310 | − return 0; | |
| 2311 | 2308 | } |
| 2312 | 2309 | |
| 2313 | 2310 | static int nvme_pci_enable(struct nvme_dev *dev) |
| @@ -2467,6 +2464,14 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) · 153 unmodified lines | ||
| 2467 | 2464 | mutex_unlock(&dev->shutdown_lock); |
| 2468 | 2465 | } |
| 2469 | 2466 | |
| 2467 | +static int nvme_disable_prepare_reset(struct nvme_dev *dev, bool shutdown) | |
| 2468 | +{ | |
| 2469 | + if (!nvme_wait_reset(&dev->ctrl)) | |
| 2470 | + return -EBUSY; | |
| 2471 | + nvme_dev_disable(dev, shutdown); | |
| 2472 | + return 0; | |
| 2473 | +} | |
| 2474 | + | |
| 2470 | 2475 | static int nvme_setup_prp_pools(struct nvme_dev *dev) |
| 2471 | 2476 | { |
| 2472 | 2477 | dev->prp_page_pool = dma_pool_create("prp list page", dev->dev, |
| @@ -2490,14 +2495,20 @@ static void nvme_release_prp_pools(struct nvme_dev *dev) · 17 unmodified lines | ||
| 2490 | 2495 | dma_pool_destroy(dev->prp_small_pool); |
| 2491 | 2496 | } |
| 2492 | 2497 | |
| 2498 | +static void nvme_free_tagset(struct nvme_dev *dev) | |
| 2499 | +{ | |
| 2500 | + if (dev->tagset.tags) | |
| 2501 | + blk_mq_free_tag_set(&dev->tagset); | |
| 2502 | + dev->ctrl.tagset = NULL; | |
| 2503 | +} | |
| 2504 | + | |
| 2493 | 2505 | static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl) |
| 2494 | 2506 | { |
| 2495 | 2507 | struct nvme_dev *dev = to_nvme_dev(ctrl); |
| 2496 | 2508 | |
| 2497 | 2509 | nvme_dbbuf_dma_free(dev); |
| 2498 | 2510 | put_device(dev->dev); |
| 2499 | − if (dev->tagset.tags) | |
| 2500 | − blk_mq_free_tag_set(&dev->tagset); | |
| 2511 | + nvme_free_tagset(dev); | |
| 2501 | 2512 | if (dev->ctrl.admin_q) |
| 2502 | 2513 | blk_put_queue(dev->ctrl.admin_q); |
| 2503 | 2514 | kfree(dev->queues); |
| @@ -2508,6 +2519,11 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl) · 4 unmodified lines | ||
| 2508 | 2519 | |
| 2509 | 2520 | static void nvme_remove_dead_ctrl(struct nvme_dev *dev) |
| 2510 | 2521 | { |
| 2522 | + /* | |
| 2523 | + * Set state to deleting now to avoid blocking nvme_wait_reset(), which | |
| 2524 | + * may be holding this pci_dev's device lock. | |
| 2525 | + */ | |
| 2526 | + nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING); | |
| 2511 | 2527 | nvme_get_ctrl(&dev->ctrl); |
| 2512 | 2528 | nvme_dev_disable(dev, false); |
| 2513 | 2529 | nvme_kill_queues(&dev->ctrl); |
| @@ -2521,7 +2537,6 @@ static void nvme_reset_work(struct work_struct *work) · 7 unmodified lines | ||
| 2521 | 2537 | container_of(work, struct nvme_dev, ctrl.reset_work); |
| 2522 | 2538 | bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL); |
| 2523 | 2539 | int result; |
| 2524 | − enum nvme_ctrl_state new_state = NVME_CTRL_LIVE; | |
| 2525 | 2540 | |
| 2526 | 2541 | if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING)) { |
| 2527 | 2542 | result = -ENODEV; |
| @@ -2615,13 +2630,11 @@ static void nvme_reset_work(struct work_struct *work) · 87 unmodified lines | ||
| 2615 | 2630 | dev_warn(dev->ctrl.device, "IO queues not created\n"); |
| 2616 | 2631 | nvme_kill_queues(&dev->ctrl); |
| 2617 | 2632 | nvme_remove_namespaces(&dev->ctrl); |
| 2618 | − new_state = NVME_CTRL_ADMIN_ONLY; | |
| 2633 | + nvme_free_tagset(dev); | |
| 2619 | 2634 | } else { |
| 2620 | 2635 | nvme_start_queues(&dev->ctrl); |
| 2621 | 2636 | nvme_wait_freeze(&dev->ctrl); |
| 2622 | − /* hit this only when allocate tagset fails */ | |
| 2623 | − if (nvme_dev_add(dev)) | |
| 2624 | − new_state = NVME_CTRL_ADMIN_ONLY; | |
| 2637 | + nvme_dev_add(dev); | |
| 2625 | 2638 | nvme_unfreeze(&dev->ctrl); |
| 2626 | 2639 | } |
| 2627 | 2640 | |
| @@ -2629,9 +2642,9 @@ static void nvme_reset_work(struct work_struct *work) · 1 unmodified line | ||
| 2629 | 2642 | * If only admin queue live, keep it to do further investigation or |
| 2630 | 2643 | * recovery. |
| 2631 | 2644 | */ |
| 2632 | − if (!nvme_change_ctrl_state(&dev->ctrl, new_state)) { | |
| 2645 | + if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_LIVE)) { | |
| 2633 | 2646 | dev_warn(dev->ctrl.device, |
| 2634 | − "failed to mark controller state %d\n", new_state); | |
| 2647 | + "failed to mark controller live state\n"); | |
| 2635 | 2648 | result = -ENODEV; |
| 2636 | 2649 | goto out; |
| 2637 | 2650 | } |
| @@ -2672,7 +2685,7 @@ static int nvme_pci_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val) · 34 unmodified lines | ||
| 2672 | 2685 | |
| 2673 | 2686 | static int nvme_pci_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val) |
| 2674 | 2687 | { |
| 2675 | − *val = readq(to_nvme_dev(ctrl)->bar + off); | |
| 2688 | + *val = lo_hi_readq(to_nvme_dev(ctrl)->bar + off); | |
| 2676 | 2689 | return 0; |
| 2677 | 2690 | } |
| 2678 | 2691 | |
| @@ -2836,19 +2849,28 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) · 157 unmodified lines | ||
| 2836 | 2849 | static void nvme_reset_prepare(struct pci_dev *pdev) |
| 2837 | 2850 | { |
| 2838 | 2851 | struct nvme_dev *dev = pci_get_drvdata(pdev); |
| 2839 | − nvme_dev_disable(dev, false); | |
| 2852 | + | |
| 2853 | + /* | |
| 2854 | + * We don't need to check the return value from waiting for the reset | |
| 2855 | + * state as pci_dev device lock is held, making it impossible to race | |
| 2856 | + * with ->remove(). | |
| 2857 | + */ | |
| 2858 | + nvme_disable_prepare_reset(dev, false); | |
| 2859 | + nvme_sync_queues(&dev->ctrl); | |
| 2840 | 2860 | } |
| 2841 | 2861 | |
| 2842 | 2862 | static void nvme_reset_done(struct pci_dev *pdev) |
| 2843 | 2863 | { |
| 2844 | 2864 | struct nvme_dev *dev = pci_get_drvdata(pdev); |
| 2845 | − nvme_reset_ctrl_sync(&dev->ctrl); | |
| 2865 | + | |
| 2866 | + if (!nvme_try_sched_reset(&dev->ctrl)) | |
| 2867 | + flush_work(&dev->ctrl.reset_work); | |
| 2846 | 2868 | } |
| 2847 | 2869 | |
| 2848 | 2870 | static void nvme_shutdown(struct pci_dev *pdev) |
| 2849 | 2871 | { |
| 2850 | 2872 | struct nvme_dev *dev = pci_get_drvdata(pdev); |
| 2851 | − nvme_dev_disable(dev, true); | |
| 2873 | + nvme_disable_prepare_reset(dev, true); | |
| 2852 | 2874 | } |
| 2853 | 2875 | |
| 2854 | 2876 | /* |
| @@ -2901,7 +2923,7 @@ static int nvme_resume(struct device *dev) · 46 unmodified lines | ||
| 2901 | 2923 | |
| 2902 | 2924 | if (ndev->last_ps == U32_MAX || |
| 2903 | 2925 | nvme_set_power_state(ctrl, ndev->last_ps) != 0) |
| 2904 | − nvme_reset_ctrl(ctrl); | |
| 2926 | + return nvme_try_sched_reset(&ndev->ctrl); | |
| 2905 | 2927 | return 0; |
| 2906 | 2928 | } |
| 2907 | 2929 | |
| @@ -2929,17 +2951,14 @@ static int nvme_suspend(struct device *dev) · 21 unmodified lines | ||
| 2929 | 2951 | */ |
| 2930 | 2952 | if (pm_suspend_via_firmware() || !ctrl->npss || |
| 2931 | 2953 | !pcie_aspm_enabled(pdev) || |
| 2932 | − (ndev->ctrl.quirks & NVME_QUIRK_SIMPLE_SUSPEND)) { | |
| 2933 | − nvme_dev_disable(ndev, true); | |
| 2934 | − return 0; | |
| 2935 | − } | |
| 2954 | + (ndev->ctrl.quirks & NVME_QUIRK_SIMPLE_SUSPEND)) | |
| 2955 | + return nvme_disable_prepare_reset(ndev, true); | |
| 2936 | 2956 | |
| 2937 | 2957 | nvme_start_freeze(ctrl); |
| 2938 | 2958 | nvme_wait_freeze(ctrl); |
| 2939 | 2959 | nvme_sync_queues(ctrl); |
| 2940 | 2960 | |
| 2941 | − if (ctrl->state != NVME_CTRL_LIVE && | |
| 2942 | − ctrl->state != NVME_CTRL_ADMIN_ONLY) | |
| 2961 | + if (ctrl->state != NVME_CTRL_LIVE) | |
| 2943 | 2962 | goto unfreeze; |
| 2944 | 2963 | |
| 2945 | 2964 | ret = nvme_get_power_state(ctrl, &ndev->last_ps); |
| @@ -2965,9 +2984,8 @@ static int nvme_suspend(struct device *dev) · 19 unmodified lines | ||
| 2965 | 2984 | * Clearing npss forces a controller reset on resume. The |
| 2966 | 2985 | * correct value will be resdicovered then. |
| 2967 | 2986 | */ |
| 2968 | − nvme_dev_disable(ndev, true); | |
| 2987 | + ret = nvme_disable_prepare_reset(ndev, true); | |
| 2969 | 2988 | ctrl->npss = 0; |
| 2970 | − ret = 0; | |
| 2971 | 2989 | } |
| 2972 | 2990 | unfreeze: |
| 2973 | 2991 | nvme_unfreeze(ctrl); |
| @@ -2977,9 +2995,7 @@ unfreeze: · 3 unmodified lines | ||
| 2977 | 2995 | static int nvme_simple_suspend(struct device *dev) |
| 2978 | 2996 | { |
| 2979 | 2997 | struct nvme_dev *ndev = pci_get_drvdata(to_pci_dev(dev)); |
| 2980 | − | |
| 2981 | − nvme_dev_disable(ndev, true); | |
| 2982 | − return 0; | |
| 2998 | + return nvme_disable_prepare_reset(ndev, true); | |
| 2983 | 2999 | } |
| 2984 | 3000 | |
| 2985 | 3001 | static int nvme_simple_resume(struct device *dev) |
| @@ -2987,8 +3003,7 @@ static int nvme_simple_resume(struct device *dev) · 1 unmodified line | ||
| 2987 | 3003 | struct pci_dev *pdev = to_pci_dev(dev); |
| 2988 | 3004 | struct nvme_dev *ndev = pci_get_drvdata(pdev); |
| 2989 | 3005 | |
| 2990 | − nvme_reset_ctrl(&ndev->ctrl); | |
| 2991 | − return 0; | |
| 3006 | + return nvme_try_sched_reset(&ndev->ctrl); | |
| 2992 | 3007 | } |
| 2993 | 3008 | |
| 2994 | 3009 | static const struct dev_pm_ops nvme_dev_pm_ops = { |
| @@ -1701,6 +1701,14 @@ nvme_rdma_timeout(struct request *rq, bool reserved) · 1700 unmodified lines | ||
| 1701 | 1701 | dev_warn(ctrl->ctrl.device, "I/O %d QID %d timeout\n", |
| 1702 | 1702 | rq->tag, nvme_rdma_queue_idx(queue)); |
| 1703 | 1703 | |
| 1704 | + /* | |
| 1705 | + * Restart the timer if a controller reset is already scheduled. Any | |
| 1706 | + * timed out commands would be handled before entering the connecting | |
| 1707 | + * state. | |
| 1708 | + */ | |
| 1709 | + if (ctrl->ctrl.state == NVME_CTRL_RESETTING) | |
| 1710 | + return BLK_EH_RESET_TIMER; | |
| 1711 | + | |
| 1704 | 1712 | if (ctrl->ctrl.state != NVME_CTRL_LIVE) { |
| 1705 | 1713 | /* |
| 1706 | 1714 | * Teardown immediately if controller times out while starting |
| @@ -1386,7 +1386,9 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, · 1385 unmodified lines | ||
| 1386 | 1386 | queue->sock->sk->sk_data_ready = nvme_tcp_data_ready; |
| 1387 | 1387 | queue->sock->sk->sk_state_change = nvme_tcp_state_change; |
| 1388 | 1388 | queue->sock->sk->sk_write_space = nvme_tcp_write_space; |
| 1389 | +#ifdef CONFIG_NET_RX_BUSY_POLL | |
| 1389 | 1390 | queue->sock->sk->sk_ll_usec = 1; |
| 1391 | +#endif | |
| 1390 | 1392 | write_unlock_bh(&queue->sock->sk->sk_callback_lock); |
| 1391 | 1393 | |
| 1392 | 1394 | return 0; |
| @@ -2044,6 +2046,14 @@ nvme_tcp_timeout(struct request *rq, bool reserved) · 651 unmodified lines | ||
| 2044 | 2046 | struct nvme_tcp_ctrl *ctrl = req->queue->ctrl; |
| 2045 | 2047 | struct nvme_tcp_cmd_pdu *pdu = req->pdu; |
| 2046 | 2048 | |
| 2049 | + /* | |
| 2050 | + * Restart the timer if a controller reset is already scheduled. Any | |
| 2051 | + * timed out commands would be handled before entering the connecting | |
| 2052 | + * state. | |
| 2053 | + */ | |
| 2054 | + if (ctrl->ctrl.state == NVME_CTRL_RESETTING) | |
| 2055 | + return BLK_EH_RESET_TIMER; | |
| 2056 | + | |
| 2047 | 2057 | dev_warn(ctrl->ctrl.device, |
| 2048 | 2058 | "queue %d: timeout request %#x type %d\n", |
| 2049 | 2059 | nvme_tcp_queue_id(req->queue), rq->tag, pdu->hdr.type); |
| @@ -2126,6 +2136,7 @@ static blk_status_t nvme_tcp_setup_cmd_pdu(struct nvme_ns *ns, · 76 unmodified lines | ||
| 2126 | 2136 | |
| 2127 | 2137 | ret = nvme_tcp_map_data(queue, rq); |
| 2128 | 2138 | if (unlikely(ret)) { |
| 2139 | + nvme_cleanup_cmd(rq); | |
| 2129 | 2140 | dev_err(queue->ctrl->ctrl.device, |
| 2130 | 2141 | "Failed to map data (%d)\n", ret); |
| 2131 | 2142 | return ret; |
| @@ -157,8 +157,10 @@ static blk_status_t nvme_loop_queue_rq(struct blk_mq_hw_ctx *hctx, · 156 unmodified lines | ||
| 157 | 157 | iod->sg_table.sgl = iod->first_sgl; |
| 158 | 158 | if (sg_alloc_table_chained(&iod->sg_table, |
| 159 | 159 | blk_rq_nr_phys_segments(req), |
| 160 | − iod->sg_table.sgl, SG_CHUNK_SIZE)) | |
| 160 | + iod->sg_table.sgl, SG_CHUNK_SIZE)) { | |
| 161 | + nvme_cleanup_cmd(req); | |
| 161 | 162 | return BLK_STS_RESOURCE; |
| 163 | + } | |
| 162 | 164 | |
| 163 | 165 | iod->req.sg = iod->sg_table.sgl; |
| 164 | 166 | iod->req.sg_cnt = blk_rq_map_sg(req->q, req, iod->sg_table.sgl); |
| @@ -678,14 +678,6 @@ static int sba_dma_supported( struct device *dev, u64 mask) · 677 unmodified lines | ||
| 678 | 678 | return(0); |
| 679 | 679 | } |
| 680 | 680 | |
| 681 | − /* Documentation/DMA-API-HOWTO.txt tells drivers to try 64-bit | |
| 682 | − * first, then fall back to 32-bit if that fails. | |
| 683 | − * We are just "encouraging" 32-bit DMA masks here since we can | |
| 684 | − * never allow IOMMU bypass unless we add special support for ZX1. | |
| 685 | − */ | |
| 686 | − if (mask > ~0U) | |
| 687 | − return 0; | |
| 688 | − | |
| 689 | 681 | ioc = GET_IOC(dev); |
| 690 | 682 | if (!ioc) |
| 691 | 683 | return 0; |
| @@ -958,19 +958,6 @@ void pci_refresh_power_state(struct pci_dev *dev) · 957 unmodified lines | ||
| 958 | 958 | pci_update_current_state(dev, dev->current_state); |
| 959 | 959 | } |
| 960 | 960 | |
| 961 | −/** | |
| 962 | − * pci_power_up - Put the given device into D0 forcibly | |
| 963 | − * @dev: PCI device to power up | |
| 964 | − */ | |
| 965 | −void pci_power_up(struct pci_dev *dev) | |
| 966 | −{ | |
| 967 | − if (platform_pci_power_manageable(dev)) | |
| 968 | − platform_pci_set_power_state(dev, PCI_D0); | |
| 969 | − | |
| 970 | − pci_raw_set_power_state(dev, PCI_D0); | |
| 971 | − pci_update_current_state(dev, PCI_D0); | |
| 972 | −} | |
| 973 | − | |
| 974 | 961 | /** |
| 975 | 962 | * pci_platform_power_transition - Use platform to change device power state |
| 976 | 963 | * @dev: PCI device to handle. |
| @@ -1153,6 +1140,17 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) · 176 unmodified lines | ||
| 1153 | 1140 | } |
| 1154 | 1141 | EXPORT_SYMBOL(pci_set_power_state); |
| 1155 | 1142 | |
| 1143 | +/** | |
| 1144 | + * pci_power_up - Put the given device into D0 forcibly | |
| 1145 | + * @dev: PCI device to power up | |
| 1146 | + */ | |
| 1147 | +void pci_power_up(struct pci_dev *dev) | |
| 1148 | +{ | |
| 1149 | + __pci_start_power_transition(dev, PCI_D0); | |
| 1150 | + pci_raw_set_power_state(dev, PCI_D0); | |
| 1151 | + pci_update_current_state(dev, PCI_D0); | |
| 1152 | +} | |
| 1153 | + | |
| 1156 | 1154 | /** |
| 1157 | 1155 | * pci_choose_state - Choose the power state of a PCI device |
| 1158 | 1156 | * @dev: PCI device to be suspended |
| @@ -420,12 +420,6 @@ failed_sensitivity: · 419 unmodified lines | ||
| 420 | 420 | |
| 421 | 421 | static int cmpc_accel_remove_v4(struct acpi_device *acpi) |
| 422 | 422 | { |
| 423 | − struct input_dev *inputdev; | |
| 424 | − struct cmpc_accel *accel; | |
| 425 | − | |
| 426 | − inputdev = dev_get_drvdata(&acpi->dev); | |
| 427 | − accel = dev_get_drvdata(&inputdev->dev); | |
| 428 | − | |
| 429 | 423 | device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr_v4); |
| 430 | 424 | device_remove_file(&acpi->dev, &cmpc_accel_g_select_attr_v4); |
| 431 | 425 | return cmpc_remove_acpi_notify_device(acpi); |
| @@ -656,12 +650,6 @@ failed_file: · 224 unmodified lines | ||
| 656 | 650 | |
| 657 | 651 | static int cmpc_accel_remove(struct acpi_device *acpi) |
| 658 | 652 | { |
| 659 | − struct input_dev *inputdev; | |
| 660 | − struct cmpc_accel *accel; | |
| 661 | − | |
| 662 | − inputdev = dev_get_drvdata(&acpi->dev); | |
| 663 | − accel = dev_get_drvdata(&inputdev->dev); | |
| 664 | − | |
| 665 | 653 | device_remove_file(&acpi->dev, &cmpc_accel_sensitivity_attr); |
| 666 | 654 | return cmpc_remove_acpi_notify_device(acpi); |
| 667 | 655 | } |
| @@ -108,6 +108,7 @@ static int i2c_multi_inst_probe(struct platform_device *pdev) · 107 unmodified lines | ||
| 108 | 108 | if (ret < 0) { |
| 109 | 109 | dev_dbg(dev, "Error requesting irq at index %d: %d\n", |
| 110 | 110 | inst_data[i].irq_idx, ret); |
| 111 | + goto error; | |
| 111 | 112 | } |
| 112 | 113 | board_info.irq = ret; |
| 113 | 114 | break; |
| @@ -293,9 +293,8 @@ static int intel_punit_ipc_probe(struct platform_device *pdev) · 292 unmodified lines | ||
| 293 | 293 | |
| 294 | 294 | platform_set_drvdata(pdev, punit_ipcdev); |
| 295 | 295 | |
| 296 | − irq = platform_get_irq(pdev, 0); | |
| 296 | + irq = platform_get_irq_optional(pdev, 0); | |
| 297 | 297 | if (irq < 0) { |
| 298 | − punit_ipcdev->irq = 0; | |
| 299 | 298 | dev_warn(&pdev->dev, "Invalid IRQ, using polling mode\n"); |
| 300 | 299 | } else { |
| 301 | 300 | ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc, |
| @@ -97,8 +97,8 @@ config PTP_1588_CLOCK_PCH · 96 unmodified lines | ||
| 97 | 97 | help |
| 98 | 98 | This driver adds support for using the PCH EG20T as a PTP |
| 99 | 99 | clock. The hardware supports time stamping of PTP packets |
| 100 | − when using the end-to-end delay (E2E) mechansim. The peer | |
| 101 | − delay mechansim (P2P) is not supported. | |
| 100 | + when using the end-to-end delay (E2E) mechanism. The peer | |
| 101 | + delay mechanism (P2P) is not supported. | |
| 102 | 102 | |
| 103 | 103 | This clock is only useful if your PTP programs are getting |
| 104 | 104 | hardware time stamps on the PTP Ethernet packets using the |
| @@ -113,6 +113,7 @@ struct subchannel { · 112 unmodified lines | ||
| 113 | 113 | enum sch_todo todo; |
| 114 | 114 | struct work_struct todo_work; |
| 115 | 115 | struct schib_config config; |
| 116 | + u64 dma_mask; | |
| 116 | 117 | char *driver_override; /* Driver name to force a match */ |
| 117 | 118 | } __attribute__ ((aligned(8))); |
| 118 | 119 | |
| @@ -232,7 +232,12 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid, · 231 unmodified lines | ||
| 232 | 232 | * belong to a subchannel need to fit 31 bit width (e.g. ccw). |
| 233 | 233 | */ |
| 234 | 234 | sch->dev.coherent_dma_mask = DMA_BIT_MASK(31); |
| 235 | − sch->dev.dma_mask = &sch->dev.coherent_dma_mask; | |
| 235 | + /* | |
| 236 | + * But we don't have such restrictions imposed on the stuff that | |
| 237 | + * is handled by the streaming API. | |
| 238 | + */ | |
| 239 | + sch->dma_mask = DMA_BIT_MASK(64); | |
| 240 | + sch->dev.dma_mask = &sch->dma_mask; | |
| 236 | 241 | return sch; |
| 237 | 242 | |
| 238 | 243 | err: |
| @@ -710,7 +710,7 @@ static struct ccw_device * io_subchannel_allocate_dev(struct subchannel *sch) · 709 unmodified lines | ||
| 710 | 710 | if (!cdev->private) |
| 711 | 711 | goto err_priv; |
| 712 | 712 | cdev->dev.coherent_dma_mask = sch->dev.coherent_dma_mask; |
| 713 | − cdev->dev.dma_mask = &cdev->dev.coherent_dma_mask; | |
| 713 | + cdev->dev.dma_mask = sch->dev.dma_mask; | |
| 714 | 714 | dma_pool = cio_gp_dma_create(&cdev->dev, 1); |
| 715 | 715 | if (!dma_pool) |
| 716 | 716 | goto err_dma_pool; |
| @@ -2021,10 +2021,10 @@ static bool qeth_l2_vnicc_recover_char(struct qeth_card *card, u32 vnicc, · 2020 unmodified lines | ||
| 2021 | 2021 | static void qeth_l2_vnicc_init(struct qeth_card *card) |
| 2022 | 2022 | { |
| 2023 | 2023 | u32 *timeout = &card->options.vnicc.learning_timeout; |
| 2024 | + bool enable, error = false; | |
| 2024 | 2025 | unsigned int chars_len, i; |
| 2025 | 2026 | unsigned long chars_tmp; |
| 2026 | 2027 | u32 sup_cmds, vnicc; |
| 2027 | − bool enable, error; | |
| 2028 | 2028 | |
| 2029 | 2029 | QETH_CARD_TEXT(card, 2, "vniccini"); |
| 2030 | 2030 | /* reset rx_bcast */ |
| @@ -2045,17 +2045,24 @@ static void qeth_l2_vnicc_init(struct qeth_card *card) · 14 unmodified lines | ||
| 2045 | 2045 | chars_len = sizeof(card->options.vnicc.sup_chars) * BITS_PER_BYTE; |
| 2046 | 2046 | for_each_set_bit(i, &chars_tmp, chars_len) { |
| 2047 | 2047 | vnicc = BIT(i); |
| 2048 | − qeth_l2_vnicc_query_cmds(card, vnicc, &sup_cmds); | |
| 2049 | − if (!(sup_cmds & IPA_VNICC_SET_TIMEOUT) || | |
| 2050 | − !(sup_cmds & IPA_VNICC_GET_TIMEOUT)) | |
| 2048 | + if (qeth_l2_vnicc_query_cmds(card, vnicc, &sup_cmds)) { | |
| 2049 | + sup_cmds = 0; | |
| 2050 | + error = true; | |
| 2051 | + } | |
| 2052 | + if ((sup_cmds & IPA_VNICC_SET_TIMEOUT) && | |
| 2053 | + (sup_cmds & IPA_VNICC_GET_TIMEOUT)) | |
| 2054 | + card->options.vnicc.getset_timeout_sup |= vnicc; | |
| 2055 | + else | |
| 2051 | 2056 | card->options.vnicc.getset_timeout_sup &= ~vnicc; |
| 2052 | − if (!(sup_cmds & IPA_VNICC_ENABLE) || | |
| 2053 | − !(sup_cmds & IPA_VNICC_DISABLE)) | |
| 2057 | + if ((sup_cmds & IPA_VNICC_ENABLE) && | |
| 2058 | + (sup_cmds & IPA_VNICC_DISABLE)) | |
| 2059 | + card->options.vnicc.set_char_sup |= vnicc; | |
| 2060 | + else | |
| 2054 | 2061 | card->options.vnicc.set_char_sup &= ~vnicc; |
| 2055 | 2062 | } |
| 2056 | 2063 | /* enforce assumed default values and recover settings, if changed */ |
| 2057 | − error = qeth_l2_vnicc_recover_timeout(card, QETH_VNICC_LEARNING, | |
| 2058 | − timeout); | |
| 2064 | + error |= qeth_l2_vnicc_recover_timeout(card, QETH_VNICC_LEARNING, | |
| 2065 | + timeout); | |
| 2059 | 2066 | chars_tmp = card->options.vnicc.wanted_chars ^ QETH_VNICC_DEFAULT; |
| 2060 | 2067 | chars_tmp |= QETH_VNICC_BRIDGE_INVISIBLE; |
| 2061 | 2068 | chars_len = sizeof(card->options.vnicc.wanted_chars) * BITS_PER_BYTE; |
| @@ -27,6 +27,11 @@ · 26 unmodified lines | ||
| 27 | 27 | |
| 28 | 28 | struct kmem_cache *zfcp_fsf_qtcb_cache; |
| 29 | 29 | |
| 30 | +static bool ber_stop = true; | |
| 31 | +module_param(ber_stop, bool, 0600); | |
| 32 | +MODULE_PARM_DESC(ber_stop, | |
| 33 | + "Shuts down FCP devices for FCP channels that report a bit-error count in excess of its threshold (default on)"); | |
| 34 | + | |
| 30 | 35 | static void zfcp_fsf_request_timeout_handler(struct timer_list *t) |
| 31 | 36 | { |
| 32 | 37 | struct zfcp_fsf_req *fsf_req = from_timer(fsf_req, t, timer); |
| @@ -236,10 +241,15 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) · 203 unmodified lines | ||
| 236 | 241 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: |
| 237 | 242 | break; |
| 238 | 243 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: |
| 239 | − dev_warn(&adapter->ccw_device->dev, | |
| 240 | − "The error threshold for checksum statistics " | |
| 241 | − "has been exceeded\n"); | |
| 242 | 244 | zfcp_dbf_hba_bit_err("fssrh_3", req); |
| 245 | + if (ber_stop) { | |
| 246 | + dev_warn(&adapter->ccw_device->dev, | |
| 247 | + "All paths over this FCP device are disused because of excessive bit errors\n"); | |
| 248 | + zfcp_erp_adapter_shutdown(adapter, 0, "fssrh_b"); | |
| 249 | + } else { | |
| 250 | + dev_warn(&adapter->ccw_device->dev, | |
| 251 | + "The error threshold for checksum statistics has been exceeded\n"); | |
| 252 | + } | |
| 243 | 253 | break; |
| 244 | 254 | case FSF_STATUS_READ_LINK_DOWN: |
| 245 | 255 | zfcp_fsf_status_read_link_down(req); |
| @@ -2837,8 +2837,6 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) · 2836 unmodified lines | ||
| 2837 | 2837 | if (sense_len == 0) { |
| 2838 | 2838 | rsp->status_srb = NULL; |
| 2839 | 2839 | sp->done(sp, cp->result); |
| 2840 | − } else { | |
| 2841 | − WARN_ON_ONCE(true); | |
| 2842 | 2840 | } |
| 2843 | 2841 | } |
| 2844 | 2842 | |
| @@ -967,6 +967,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, · 966 unmodified lines | ||
| 967 | 967 | ses->data_direction = scmd->sc_data_direction; |
| 968 | 968 | ses->sdb = scmd->sdb; |
| 969 | 969 | ses->result = scmd->result; |
| 970 | + ses->resid_len = scmd->req.resid_len; | |
| 970 | 971 | ses->underflow = scmd->underflow; |
| 971 | 972 | ses->prot_op = scmd->prot_op; |
| 972 | 973 | ses->eh_eflags = scmd->eh_eflags; |
| @@ -977,6 +978,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, · 4 unmodified lines | ||
| 977 | 978 | memset(scmd->cmnd, 0, BLK_MAX_CDB); |
| 978 | 979 | memset(&scmd->sdb, 0, sizeof(scmd->sdb)); |
| 979 | 980 | scmd->result = 0; |
| 981 | + scmd->req.resid_len = 0; | |
| 980 | 982 | |
| 981 | 983 | if (sense_bytes) { |
| 982 | 984 | scmd->sdb.length = min_t(unsigned, SCSI_SENSE_BUFFERSIZE, |
| @@ -1029,6 +1031,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) · 46 unmodified lines | ||
| 1029 | 1031 | scmd->sc_data_direction = ses->data_direction; |
| 1030 | 1032 | scmd->sdb = ses->sdb; |
| 1031 | 1033 | scmd->result = ses->result; |
| 1034 | + scmd->req.resid_len = ses->resid_len; | |
| 1032 | 1035 | scmd->underflow = ses->underflow; |
| 1033 | 1036 | scmd->prot_op = ses->prot_op; |
| 1034 | 1037 | scmd->eh_eflags = ses->eh_eflags; |
| @@ -1834,6 +1834,7 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = { · 1833 unmodified lines | ||
| 1834 | 1834 | .init_request = scsi_mq_init_request, |
| 1835 | 1835 | .exit_request = scsi_mq_exit_request, |
| 1836 | 1836 | .initialize_rq_fn = scsi_initialize_rq, |
| 1837 | + .cleanup_rq = scsi_cleanup_rq, | |
| 1837 | 1838 | .busy = scsi_mq_lld_busy, |
| 1838 | 1839 | .map_queues = scsi_map_queues, |
| 1839 | 1840 | }; |
| @@ -1921,7 +1922,8 @@ struct scsi_device *scsi_device_from_queue(struct request_queue *q) · 81 unmodified lines | ||
| 1921 | 1922 | { |
| 1922 | 1923 | struct scsi_device *sdev = NULL; |
| 1923 | 1924 | |
| 1924 | − if (q->mq_ops == &scsi_mq_ops) | |
| 1925 | + if (q->mq_ops == &scsi_mq_ops_no_commit || | |
| 1926 | + q->mq_ops == &scsi_mq_ops) | |
| 1925 | 1927 | sdev = q->queuedata; |
| 1926 | 1928 | if (!sdev || !get_device(&sdev->sdev_gendev)) |
| 1927 | 1929 | sdev = NULL; |
| @@ -1654,7 +1654,8 @@ static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr) · 1653 unmodified lines | ||
| 1654 | 1654 | /* we need to evaluate the error return */ |
| 1655 | 1655 | if (scsi_sense_valid(sshdr) && |
| 1656 | 1656 | (sshdr->asc == 0x3a || /* medium not present */ |
| 1657 | − sshdr->asc == 0x20)) /* invalid command */ | |
| 1657 | + sshdr->asc == 0x20 || /* invalid command */ | |
| 1658 | + (sshdr->asc == 0x74 && sshdr->ascq == 0x71))) /* drive is password locked */ | |
| 1658 | 1659 | /* this is no error here */ |
| 1659 | 1660 | return 0; |
| 1660 | 1661 | |
| @@ -1,3 +1,4 @@ | ||
| 1 | +# SPDX-License-Identifier: GPL-2.0 | |
| 1 | 2 | config EXFAT_FS |
| 2 | 3 | tristate "exFAT fs support" |
| 3 | 4 | depends on BLOCK |
| @@ -6,7 +7,7 @@ config EXFAT_FS · 2 unmodified lines | ||
| 6 | 7 | This adds support for the exFAT file system. |
| 7 | 8 | |
| 8 | 9 | config EXFAT_DONT_MOUNT_VFAT |
| 9 | − bool "Prohibit mounting of fat/vfat filesysems by exFAT" | |
| 10 | + bool "Prohibit mounting of fat/vfat filesystems by exFAT" | |
| 10 | 11 | depends on EXFAT_FS |
| 11 | 12 | default y |
| 12 | 13 | help |
| @@ -1,4 +1,4 @@ | ||
| 1 | −# SPDX-License-Identifier: GPL-2.0 | |
| 1 | +# SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | 2 | |
| 3 | 3 | obj-$(CONFIG_EXFAT_FS) += exfat.o |
| 4 | 4 | |
| @@ -1,4 +1,4 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 */ | |
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ | |
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. |
| 4 | 4 | */ |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. |
| 4 | 4 | */ |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. |
| 4 | 4 | */ |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. |
| 4 | 4 | */ |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. |
| 4 | 4 | */ |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. |
| 4 | 4 | */ |
| @@ -7,6 +7,7 @@ · 2 unmodified lines | ||
| 7 | 7 | #include <linux/init.h> |
| 8 | 8 | #include <linux/time.h> |
| 9 | 9 | #include <linux/slab.h> |
| 10 | +#include <linux/mm.h> | |
| 10 | 11 | #include <linux/seq_file.h> |
| 11 | 12 | #include <linux/pagemap.h> |
| 12 | 13 | #include <linux/mpage.h> |
| @@ -3450,7 +3451,7 @@ static void exfat_free_super(struct exfat_sb_info *sbi) · 3437 unmodified lines | ||
| 3450 | 3451 | kfree(sbi->options.iocharset); |
| 3451 | 3452 | /* mutex_init is in exfat_fill_super function. only for 3.7+ */ |
| 3452 | 3453 | mutex_destroy(&sbi->s_lock); |
| 3453 | − kfree(sbi); | |
| 3454 | + kvfree(sbi); | |
| 3454 | 3455 | } |
| 3455 | 3456 | |
| 3456 | 3457 | static void exfat_put_super(struct super_block *sb) |
| @@ -3845,7 +3846,7 @@ static int exfat_fill_super(struct super_block *sb, void *data, int silent) · 388 unmodified lines | ||
| 3845 | 3846 | * the filesystem, since we're only just about to mount |
| 3846 | 3847 | * it and have no inodes etc active! |
| 3847 | 3848 | */ |
| 3848 | − sbi = kzalloc(sizeof(struct exfat_sb_info), GFP_KERNEL); | |
| 3849 | + sbi = kvzalloc(sizeof(*sbi), GFP_KERNEL); | |
| 3849 | 3850 | if (!sbi) |
| 3850 | 3851 | return -ENOMEM; |
| 3851 | 3852 | mutex_init(&sbi->s_lock); |
| @@ -1,4 +1,4 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0 | |
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later | |
| 2 | 2 | /* |
| 3 | 3 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. |
| 4 | 4 | */ |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | menuconfig FB_TFT |
| 3 | 3 | tristate "Support for small TFT LCD display modules" |
| 4 | − depends on FB && SPI | |
| 4 | + depends on FB && SPI && OF | |
| 5 | 5 | depends on GPIOLIB || COMPILE_TEST |
| 6 | 6 | select FB_SYS_FILLRECT |
| 7 | 7 | select FB_SYS_COPYAREA |
| @@ -199,13 +199,3 @@ config FB_TFT_WATTEROTT · 191 unmodified lines | ||
| 199 | 199 | depends on FB_TFT |
| 200 | 200 | help |
| 201 | 201 | Generic Framebuffer support for WATTEROTT |
| 202 | − | |
| 203 | −config FB_FLEX | |
| 204 | − tristate "Generic FB driver for TFT LCD displays" | |
| 205 | − depends on FB_TFT | |
| 206 | − help | |
| 207 | − Generic Framebuffer support for TFT LCD displays. | |
| 208 | − | |
| 209 | −config FB_TFT_FBTFT_DEVICE | |
| 210 | − tristate "Module to for adding FBTFT devices" | |
| 211 | − depends on FB_TFT | |
| @@ -36,7 +36,3 @@ obj-$(CONFIG_FB_TFT_UC1611) += fb_uc1611.o · 35 unmodified lines | ||
| 36 | 36 | obj-$(CONFIG_FB_TFT_UC1701) += fb_uc1701.o |
| 37 | 37 | obj-$(CONFIG_FB_TFT_UPD161704) += fb_upd161704.o |
| 38 | 38 | obj-$(CONFIG_FB_TFT_WATTEROTT) += fb_watterott.o |
| 39 | −obj-$(CONFIG_FB_FLEX) += flexfb.o | |
| 40 | − | |
| 41 | −# Device modules | |
| 42 | −obj-$(CONFIG_FB_TFT_FBTFT_DEVICE) += fbtft_device.o | |
| @@ -714,7 +714,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, · 713 unmodified lines | ||
| 714 | 714 | if (par->gamma.curves && gamma) { |
| 715 | 715 | if (fbtft_gamma_parse_str(par, par->gamma.curves, gamma, |
| 716 | 716 | strlen(gamma))) |
| 717 | − goto alloc_fail; | |
| 717 | + goto release_framebuf; | |
| 718 | 718 | } |
| 719 | 719 | |
| 720 | 720 | /* Transmit buffer */ |
| @@ -731,7 +731,7 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, · 10 unmodified lines | ||
| 731 | 731 | if (txbuflen > 0) { |
| 732 | 732 | txbuf = devm_kzalloc(par->info->device, txbuflen, GFP_KERNEL); |
| 733 | 733 | if (!txbuf) |
| 734 | − goto alloc_fail; | |
| 734 | + goto release_framebuf; | |
| 735 | 735 | par->txbuf.buf = txbuf; |
| 736 | 736 | par->txbuf.len = txbuflen; |
| 737 | 737 | } |
| @@ -753,6 +753,9 @@ struct fb_info *fbtft_framebuffer_alloc(struct fbtft_display *display, · 15 unmodified lines | ||
| 753 | 753 | |
| 754 | 754 | return info; |
| 755 | 755 | |
| 756 | +release_framebuf: | |
| 757 | + framebuffer_release(info); | |
| 758 | + | |
| 756 | 759 | alloc_fail: |
| 757 | 760 | vfree(vmem); |
| 758 | 761 | |
| @@ -1,1261 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0+ | |
| 2 | −/* | |
| 3 | − * | |
| 4 | − * Copyright (C) 2013, Noralf Tronnes | |
| 5 | − */ | |
| 6 | − | |
| 7 | −#define pr_fmt(fmt) "fbtft_device: " fmt | |
| 8 | −#include <linux/module.h> | |
| 9 | −#include <linux/kernel.h> | |
| 10 | −#include <linux/init.h> | |
| 11 | −#include <linux/gpio/consumer.h> | |
| 12 | −#include <linux/spi/spi.h> | |
| 13 | −#include <video/mipi_display.h> | |
| 14 | − | |
| 15 | −#include "fbtft.h" | |
| 16 | − | |
| 17 | −#define MAX_GPIOS 32 | |
| 18 | − | |
| 19 | −static struct spi_device *spi_device; | |
| 20 | −static struct platform_device *p_device; | |
| 21 | − | |
| 22 | −static char *name; | |
| 23 | −module_param(name, charp, 0000); | |
| 24 | −MODULE_PARM_DESC(name, | |
| 25 | − "Devicename (required). name=list => list all supported devices."); | |
| 26 | − | |
| 27 | −static unsigned int rotate; | |
| 28 | −module_param(rotate, uint, 0000); | |
| 29 | −MODULE_PARM_DESC(rotate, | |
| 30 | − "Angle to rotate display counter clockwise: 0, 90, 180, 270"); | |
| 31 | − | |
| 32 | −static unsigned int busnum; | |
| 33 | −module_param(busnum, uint, 0000); | |
| 34 | −MODULE_PARM_DESC(busnum, "SPI bus number (default=0)"); | |
| 35 | − | |
| 36 | −static unsigned int cs; | |
| 37 | −module_param(cs, uint, 0000); | |
| 38 | −MODULE_PARM_DESC(cs, "SPI chip select (default=0)"); | |
| 39 | − | |
| 40 | −static unsigned int speed; | |
| 41 | −module_param(speed, uint, 0000); | |
| 42 | −MODULE_PARM_DESC(speed, "SPI speed (override device default)"); | |
| 43 | − | |
| 44 | −static int mode = -1; | |
| 45 | −module_param(mode, int, 0000); | |
| 46 | −MODULE_PARM_DESC(mode, "SPI mode (override device default)"); | |
| 47 | − | |
| 48 | −static unsigned int fps; | |
| 49 | −module_param(fps, uint, 0000); | |
| 50 | −MODULE_PARM_DESC(fps, "Frames per second (override driver default)"); | |
| 51 | − | |
| 52 | −static char *gamma; | |
| 53 | −module_param(gamma, charp, 0000); | |
| 54 | −MODULE_PARM_DESC(gamma, | |
| 55 | − "String representation of Gamma Curve(s). Driver specific."); | |
| 56 | − | |
| 57 | −static int txbuflen; | |
| 58 | −module_param(txbuflen, int, 0000); | |
| 59 | −MODULE_PARM_DESC(txbuflen, "txbuflen (override driver default)"); | |
| 60 | − | |
| 61 | −static int bgr = -1; | |
| 62 | −module_param(bgr, int, 0000); | |
| 63 | −MODULE_PARM_DESC(bgr, | |
| 64 | − "BGR bit (supported by some drivers)."); | |
| 65 | − | |
| 66 | −static unsigned int startbyte; | |
| 67 | −module_param(startbyte, uint, 0000); | |
| 68 | −MODULE_PARM_DESC(startbyte, "Sets the Start byte used by some SPI displays."); | |
| 69 | − | |
| 70 | −static bool custom; | |
| 71 | −module_param(custom, bool, 0000); | |
| 72 | −MODULE_PARM_DESC(custom, "Add a custom display device. Use speed= argument to make it a SPI device, else platform_device"); | |
| 73 | − | |
| 74 | −static unsigned int width; | |
| 75 | −module_param(width, uint, 0000); | |
| 76 | −MODULE_PARM_DESC(width, "Display width, used with the custom argument"); | |
| 77 | − | |
| 78 | −static unsigned int height; | |
| 79 | −module_param(height, uint, 0000); | |
| 80 | −MODULE_PARM_DESC(height, "Display height, used with the custom argument"); | |
| 81 | − | |
| 82 | −static unsigned int buswidth = 8; | |
| 83 | −module_param(buswidth, uint, 0000); | |
| 84 | −MODULE_PARM_DESC(buswidth, "Display bus width, used with the custom argument"); | |
| 85 | − | |
| 86 | −static s16 init[FBTFT_MAX_INIT_SEQUENCE]; | |
| 87 | −static int init_num; | |
| 88 | −module_param_array(init, short, &init_num, 0000); | |
| 89 | −MODULE_PARM_DESC(init, "Init sequence, used with the custom argument"); | |
| 90 | − | |
| 91 | −static unsigned long debug; | |
| 92 | −module_param(debug, ulong, 0000); | |
| 93 | −MODULE_PARM_DESC(debug, | |
| 94 | − "level: 0-7 (the remaining 29 bits is for advanced usage)"); | |
| 95 | − | |
| 96 | −static unsigned int verbose = 3; | |
| 97 | −module_param(verbose, uint, 0000); | |
| 98 | −MODULE_PARM_DESC(verbose, | |
| 99 | − "0 silent, >1 show devices, >2 show devices before (default=3)"); | |
| 100 | − | |
| 101 | −struct fbtft_device_display { | |
| 102 | − char *name; | |
| 103 | − struct spi_board_info *spi; | |
| 104 | − struct platform_device *pdev; | |
| 105 | −}; | |
| 106 | − | |
| 107 | −static void fbtft_device_pdev_release(struct device *dev); | |
| 108 | − | |
| 109 | −static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len); | |
| 110 | −static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par, | |
| 111 | − int xs, int ys, int xe, int ye); | |
| 112 | − | |
| 113 | −#define ADAFRUIT18_GAMMA \ | |
| 114 | − "02 1c 07 12 37 32 29 2d 29 25 2B 39 00 01 03 10\n" \ | |
| 115 | − "03 1d 07 06 2E 2C 29 2D 2E 2E 37 3F 00 00 02 10" | |
| 116 | − | |
| 117 | −#define CBERRY28_GAMMA \ | |
| 118 | − "D0 00 14 15 13 2C 42 43 4E 09 16 14 18 21\n" \ | |
| 119 | − "D0 00 14 15 13 0B 43 55 53 0C 17 14 23 20" | |
| 120 | − | |
| 121 | −static const s16 cberry28_init_sequence[] = { | |
| 122 | − /* turn off sleep mode */ | |
| 123 | − -1, MIPI_DCS_EXIT_SLEEP_MODE, | |
| 124 | − -2, 120, | |
| 125 | − | |
| 126 | − /* set pixel format to RGB-565 */ | |
| 127 | − -1, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT, | |
| 128 | − | |
| 129 | − -1, 0xB2, 0x0C, 0x0C, 0x00, 0x33, 0x33, | |
| 130 | − | |
| 131 | − /* | |
| 132 | − * VGH = 13.26V | |
| 133 | − * VGL = -10.43V | |
| 134 | − */ | |
| 135 | − -1, 0xB7, 0x35, | |
| 136 | − | |
| 137 | − /* | |
| 138 | − * VDV and VRH register values come from command write | |
| 139 | − * (instead of NVM) | |
| 140 | − */ | |
| 141 | − -1, 0xC2, 0x01, 0xFF, | |
| 142 | − | |
| 143 | − /* | |
| 144 | − * VAP = 4.7V + (VCOM + VCOM offset + 0.5 * VDV) | |
| 145 | − * VAN = -4.7V + (VCOM + VCOM offset + 0.5 * VDV) | |
| 146 | − */ | |
| 147 | − -1, 0xC3, 0x17, | |
| 148 | − | |
| 149 | − /* VDV = 0V */ | |
| 150 | − -1, 0xC4, 0x20, | |
| 151 | − | |
| 152 | − /* VCOM = 0.675V */ | |
| 153 | − -1, 0xBB, 0x17, | |
| 154 | − | |
| 155 | − /* VCOM offset = 0V */ | |
| 156 | − -1, 0xC5, 0x20, | |
| 157 | − | |
| 158 | − /* | |
| 159 | − * AVDD = 6.8V | |
| 160 | − * AVCL = -4.8V | |
| 161 | − * VDS = 2.3V | |
| 162 | − */ | |
| 163 | − -1, 0xD0, 0xA4, 0xA1, | |
| 164 | − | |
| 165 | − -1, MIPI_DCS_SET_DISPLAY_ON, | |
| 166 | − | |
| 167 | − -3, | |
| 168 | −}; | |
| 169 | − | |
| 170 | −static const s16 hy28b_init_sequence[] = { | |
| 171 | − -1, 0x00e7, 0x0010, -1, 0x0000, 0x0001, | |
| 172 | − -1, 0x0001, 0x0100, -1, 0x0002, 0x0700, | |
| 173 | − -1, 0x0003, 0x1030, -1, 0x0004, 0x0000, | |
| 174 | − -1, 0x0008, 0x0207, -1, 0x0009, 0x0000, | |
| 175 | − -1, 0x000a, 0x0000, -1, 0x000c, 0x0001, | |
| 176 | − -1, 0x000d, 0x0000, -1, 0x000f, 0x0000, | |
| 177 | − -1, 0x0010, 0x0000, -1, 0x0011, 0x0007, | |
| 178 | − -1, 0x0012, 0x0000, -1, 0x0013, 0x0000, | |
| 179 | − -2, 50, -1, 0x0010, 0x1590, -1, 0x0011, | |
| 180 | − 0x0227, -2, 50, -1, 0x0012, 0x009c, -2, 50, | |
| 181 | − -1, 0x0013, 0x1900, -1, 0x0029, 0x0023, | |
| 182 | − -1, 0x002b, 0x000e, -2, 50, | |
| 183 | − -1, 0x0020, 0x0000, -1, 0x0021, 0x0000, | |
| 184 | − -2, 50, -1, 0x0050, 0x0000, | |
| 185 | − -1, 0x0051, 0x00ef, -1, 0x0052, 0x0000, | |
| 186 | − -1, 0x0053, 0x013f, -1, 0x0060, 0xa700, | |
| 187 | − -1, 0x0061, 0x0001, -1, 0x006a, 0x0000, | |
| 188 | − -1, 0x0080, 0x0000, -1, 0x0081, 0x0000, | |
| 189 | − -1, 0x0082, 0x0000, -1, 0x0083, 0x0000, | |
| 190 | − -1, 0x0084, 0x0000, -1, 0x0085, 0x0000, | |
| 191 | − -1, 0x0090, 0x0010, -1, 0x0092, 0x0000, | |
| 192 | − -1, 0x0093, 0x0003, -1, 0x0095, 0x0110, | |
| 193 | − -1, 0x0097, 0x0000, -1, 0x0098, 0x0000, | |
| 194 | − -1, 0x0007, 0x0133, -1, 0x0020, 0x0000, | |
| 195 | − -1, 0x0021, 0x0000, -2, 100, -3 }; | |
| 196 | − | |
| 197 | −#define HY28B_GAMMA \ | |
| 198 | − "04 1F 4 7 7 0 7 7 6 0\n" \ | |
| 199 | − "0F 00 1 7 4 0 0 0 6 7" | |
| 200 | − | |
| 201 | −static const s16 pitft_init_sequence[] = { | |
| 202 | − -1, MIPI_DCS_SOFT_RESET, | |
| 203 | − -2, 5, | |
| 204 | − -1, MIPI_DCS_SET_DISPLAY_OFF, | |
| 205 | − -1, 0xEF, 0x03, 0x80, 0x02, | |
| 206 | − -1, 0xCF, 0x00, 0xC1, 0x30, | |
| 207 | − -1, 0xED, 0x64, 0x03, 0x12, 0x81, | |
| 208 | − -1, 0xE8, 0x85, 0x00, 0x78, | |
| 209 | − -1, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02, | |
| 210 | − -1, 0xF7, 0x20, | |
| 211 | − -1, 0xEA, 0x00, 0x00, | |
| 212 | − -1, 0xC0, 0x23, | |
| 213 | − -1, 0xC1, 0x10, | |
| 214 | − -1, 0xC5, 0x3E, 0x28, | |
| 215 | − -1, 0xC7, 0x86, | |
| 216 | − -1, MIPI_DCS_SET_PIXEL_FORMAT, 0x55, | |
| 217 | − -1, 0xB1, 0x00, 0x18, | |
| 218 | − -1, 0xB6, 0x08, 0x82, 0x27, | |
| 219 | − -1, 0xF2, 0x00, | |
| 220 | − -1, MIPI_DCS_SET_GAMMA_CURVE, 0x01, | |
| 221 | − -1, 0xE0, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, | |
| 222 | − 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, | |
| 223 | − -1, 0xE1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, | |
| 224 | − 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, | |
| 225 | − -1, MIPI_DCS_EXIT_SLEEP_MODE, | |
| 226 | − -2, 100, | |
| 227 | − -1, MIPI_DCS_SET_DISPLAY_ON, | |
| 228 | − -2, 20, | |
| 229 | − -3 | |
| 230 | −}; | |
| 231 | − | |
| 232 | −static const s16 waveshare32b_init_sequence[] = { | |
| 233 | − -1, 0xCB, 0x39, 0x2C, 0x00, 0x34, 0x02, | |
| 234 | − -1, 0xCF, 0x00, 0xC1, 0x30, | |
| 235 | − -1, 0xE8, 0x85, 0x00, 0x78, | |
| 236 | − -1, 0xEA, 0x00, 0x00, | |
| 237 | − -1, 0xED, 0x64, 0x03, 0x12, 0x81, | |
| 238 | − -1, 0xF7, 0x20, | |
| 239 | − -1, 0xC0, 0x23, | |
| 240 | − -1, 0xC1, 0x10, | |
| 241 | − -1, 0xC5, 0x3E, 0x28, | |
| 242 | − -1, 0xC7, 0x86, | |
| 243 | − -1, MIPI_DCS_SET_ADDRESS_MODE, 0x28, | |
| 244 | − -1, MIPI_DCS_SET_PIXEL_FORMAT, 0x55, | |
| 245 | − -1, 0xB1, 0x00, 0x18, | |
| 246 | − -1, 0xB6, 0x08, 0x82, 0x27, | |
| 247 | − -1, 0xF2, 0x00, | |
| 248 | − -1, MIPI_DCS_SET_GAMMA_CURVE, 0x01, | |
| 249 | − -1, 0xE0, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, | |
| 250 | − 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, | |
| 251 | − -1, 0xE1, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, | |
| 252 | − 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, | |
| 253 | − -1, MIPI_DCS_EXIT_SLEEP_MODE, | |
| 254 | − -2, 120, | |
| 255 | − -1, MIPI_DCS_SET_DISPLAY_ON, | |
| 256 | − -1, MIPI_DCS_WRITE_MEMORY_START, | |
| 257 | − -3 | |
| 258 | −}; | |
| 259 | − | |
| 260 | −#define PIOLED_GAMMA "0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 " \ | |
| 261 | − "2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 " \ | |
| 262 | − "3 3 3 4 4 4 4 4 4 4 4 4 4 4 4" | |
| 263 | − | |
| 264 | −/* Supported displays in alphabetical order */ | |
| 265 | −static struct fbtft_device_display displays[] = { | |
| 266 | − { | |
| 267 | − .name = "adafruit18", | |
| 268 | − .spi = &(struct spi_board_info) { | |
| 269 | − .modalias = "fb_st7735r", | |
| 270 | − .max_speed_hz = 32000000, | |
| 271 | − .mode = SPI_MODE_0, | |
| 272 | − .platform_data = &(struct fbtft_platform_data) { | |
| 273 | − .display = { | |
| 274 | − .buswidth = 8, | |
| 275 | − .backlight = 1, | |
| 276 | − }, | |
| 277 | − .gamma = ADAFRUIT18_GAMMA, | |
| 278 | − } | |
| 279 | − } | |
| 280 | − }, { | |
| 281 | − .name = "adafruit18_green", | |
| 282 | − .spi = &(struct spi_board_info) { | |
| 283 | − .modalias = "fb_st7735r", | |
| 284 | − .max_speed_hz = 4000000, | |
| 285 | − .mode = SPI_MODE_0, | |
| 286 | − .platform_data = &(struct fbtft_platform_data) { | |
| 287 | − .display = { | |
| 288 | − .buswidth = 8, | |
| 289 | − .backlight = 1, | |
| 290 | − .fbtftops.set_addr_win = | |
| 291 | − adafruit18_green_tab_set_addr_win, | |
| 292 | − }, | |
| 293 | − .bgr = true, | |
| 294 | − .gamma = ADAFRUIT18_GAMMA, | |
| 295 | − } | |
| 296 | − } | |
| 297 | − }, { | |
| 298 | − .name = "adafruit22", | |
| 299 | − .spi = &(struct spi_board_info) { | |
| 300 | − .modalias = "fb_hx8340bn", | |
| 301 | − .max_speed_hz = 32000000, | |
| 302 | − .mode = SPI_MODE_0, | |
| 303 | − .platform_data = &(struct fbtft_platform_data) { | |
| 304 | − .display = { | |
| 305 | − .buswidth = 9, | |
| 306 | − .backlight = 1, | |
| 307 | − }, | |
| 308 | − .bgr = true, | |
| 309 | − } | |
| 310 | − } | |
| 311 | − }, { | |
| 312 | − .name = "adafruit22a", | |
| 313 | − .spi = &(struct spi_board_info) { | |
| 314 | − .modalias = "fb_ili9340", | |
| 315 | − .max_speed_hz = 32000000, | |
| 316 | − .mode = SPI_MODE_0, | |
| 317 | − .platform_data = &(struct fbtft_platform_data) { | |
| 318 | − .display = { | |
| 319 | − .buswidth = 8, | |
| 320 | − .backlight = 1, | |
| 321 | − }, | |
| 322 | − .bgr = true, | |
| 323 | − } | |
| 324 | − } | |
| 325 | − }, { | |
| 326 | − .name = "adafruit28", | |
| 327 | − .spi = &(struct spi_board_info) { | |
| 328 | − .modalias = "fb_ili9341", | |
| 329 | − .max_speed_hz = 32000000, | |
| 330 | − .mode = SPI_MODE_0, | |
| 331 | − .platform_data = &(struct fbtft_platform_data) { | |
| 332 | − .display = { | |
| 333 | − .buswidth = 8, | |
| 334 | − .backlight = 1, | |
| 335 | − }, | |
| 336 | − .bgr = true, | |
| 337 | − } | |
| 338 | − } | |
| 339 | − }, { | |
| 340 | − .name = "adafruit13m", | |
| 341 | − .spi = &(struct spi_board_info) { | |
| 342 | − .modalias = "fb_ssd1306", | |
| 343 | − .max_speed_hz = 16000000, | |
| 344 | − .mode = SPI_MODE_0, | |
| 345 | − .platform_data = &(struct fbtft_platform_data) { | |
| 346 | − .display = { | |
| 347 | − .buswidth = 8, | |
| 348 | − }, | |
| 349 | − } | |
| 350 | − } | |
| 351 | − }, { | |
| 352 | − .name = "admatec_c-berry28", | |
| 353 | − .spi = &(struct spi_board_info) { | |
| 354 | − .modalias = "fb_st7789v", | |
| 355 | − .max_speed_hz = 48000000, | |
| 356 | − .mode = SPI_MODE_0, | |
| 357 | − .platform_data = &(struct fbtft_platform_data) { | |
| 358 | − .display = { | |
| 359 | − .buswidth = 8, | |
| 360 | − .backlight = 1, | |
| 361 | − .init_sequence = cberry28_init_sequence, | |
| 362 | − }, | |
| 363 | − .gamma = CBERRY28_GAMMA, | |
| 364 | − } | |
| 365 | − } | |
| 366 | − }, { | |
| 367 | − .name = "agm1264k-fl", | |
| 368 | − .pdev = &(struct platform_device) { | |
| 369 | − .name = "fb_agm1264k-fl", | |
| 370 | − .id = 0, | |
| 371 | − .dev = { | |
| 372 | − .release = fbtft_device_pdev_release, | |
| 373 | − .platform_data = &(struct fbtft_platform_data) { | |
| 374 | − .display = { | |
| 375 | − .buswidth = 8, | |
| 376 | − .backlight = FBTFT_ONBOARD_BACKLIGHT, | |
| 377 | − }, | |
| 378 | − }, | |
| 379 | − } | |
| 380 | − } | |
| 381 | − }, { | |
| 382 | − .name = "dogs102", | |
| 383 | − .spi = &(struct spi_board_info) { | |
| 384 | − .modalias = "fb_uc1701", | |
| 385 | − .max_speed_hz = 8000000, | |
| 386 | − .mode = SPI_MODE_0, | |
| 387 | − .platform_data = &(struct fbtft_platform_data) { | |
| 388 | − .display = { | |
| 389 | − .buswidth = 8, | |
| 390 | − }, | |
| 391 | − .bgr = true, | |
| 392 | − } | |
| 393 | − } | |
| 394 | − }, { | |
| 395 | − .name = "er_tftm050_2", | |
| 396 | − .spi = &(struct spi_board_info) { | |
| 397 | − .modalias = "fb_ra8875", | |
| 398 | − .max_speed_hz = 5000000, | |
| 399 | − .mode = SPI_MODE_3, | |
| 400 | − .platform_data = &(struct fbtft_platform_data) { | |
| 401 | − .display = { | |
| 402 | − .buswidth = 8, | |
| 403 | − .backlight = 1, | |
| 404 | − .width = 480, | |
| 405 | − .height = 272, | |
| 406 | − }, | |
| 407 | − .bgr = true, | |
| 408 | − } | |
| 409 | − } | |
| 410 | − }, { | |
| 411 | − .name = "er_tftm070_5", | |
| 412 | − .spi = &(struct spi_board_info) { | |
| 413 | − .modalias = "fb_ra8875", | |
| 414 | − .max_speed_hz = 5000000, | |
| 415 | − .mode = SPI_MODE_3, | |
| 416 | − .platform_data = &(struct fbtft_platform_data) { | |
| 417 | − .display = { | |
| 418 | − .buswidth = 8, | |
| 419 | − .backlight = 1, | |
| 420 | − .width = 800, | |
| 421 | − .height = 480, | |
| 422 | − }, | |
| 423 | − .bgr = true, | |
| 424 | − } | |
| 425 | − } | |
| 426 | − }, { | |
| 427 | − .name = "ew24ha0", | |
| 428 | − .spi = &(struct spi_board_info) { | |
| 429 | − .modalias = "fb_uc1611", | |
| 430 | − .max_speed_hz = 32000000, | |
| 431 | − .mode = SPI_MODE_3, | |
| 432 | − .platform_data = &(struct fbtft_platform_data) { | |
| 433 | − .display = { | |
| 434 | − .buswidth = 8, | |
| 435 | − }, | |
| 436 | − } | |
| 437 | − } | |
| 438 | − }, { | |
| 439 | − .name = "ew24ha0_9bit", | |
| 440 | − .spi = &(struct spi_board_info) { | |
| 441 | − .modalias = "fb_uc1611", | |
| 442 | − .max_speed_hz = 32000000, | |
| 443 | − .mode = SPI_MODE_3, | |
| 444 | − .platform_data = &(struct fbtft_platform_data) { | |
| 445 | − .display = { | |
| 446 | − .buswidth = 9, | |
| 447 | − }, | |
| 448 | − } | |
| 449 | − } | |
| 450 | − }, { | |
| 451 | − .name = "flexfb", | |
| 452 | − .spi = &(struct spi_board_info) { | |
| 453 | − .modalias = "flexfb", | |
| 454 | − .max_speed_hz = 32000000, | |
| 455 | − .mode = SPI_MODE_0, | |
| 456 | − } | |
| 457 | − }, { | |
| 458 | − .name = "flexpfb", | |
| 459 | − .pdev = &(struct platform_device) { | |
| 460 | − .name = "flexpfb", | |
| 461 | − .id = 0, | |
| 462 | − .dev = { | |
| 463 | − .release = fbtft_device_pdev_release, | |
| 464 | − } | |
| 465 | − } | |
| 466 | − }, { | |
| 467 | − .name = "freetronicsoled128", | |
| 468 | − .spi = &(struct spi_board_info) { | |
| 469 | − .modalias = "fb_ssd1351", | |
| 470 | − .max_speed_hz = 20000000, | |
| 471 | − .mode = SPI_MODE_0, | |
| 472 | − .platform_data = &(struct fbtft_platform_data) { | |
| 473 | − .display = { | |
| 474 | − .buswidth = 8, | |
| 475 | − .backlight = FBTFT_ONBOARD_BACKLIGHT, | |
| 476 | − }, | |
| 477 | − .bgr = true, | |
| 478 | − } | |
| 479 | − } | |
| 480 | − }, { | |
| 481 | − .name = "hx8353d", | |
| 482 | − .spi = &(struct spi_board_info) { | |
| 483 | − .modalias = "fb_hx8353d", | |
| 484 | − .max_speed_hz = 16000000, | |
| 485 | − .mode = SPI_MODE_0, | |
| 486 | − .platform_data = &(struct fbtft_platform_data) { | |
| 487 | − .display = { | |
| 488 | − .buswidth = 8, | |
| 489 | − .backlight = 1, | |
| 490 | − }, | |
| 491 | − } | |
| 492 | − } | |
| 493 | − }, { | |
| 494 | − .name = "hy28a", | |
| 495 | − .spi = &(struct spi_board_info) { | |
| 496 | − .modalias = "fb_ili9320", | |
| 497 | − .max_speed_hz = 32000000, | |
| 498 | − .mode = SPI_MODE_3, | |
| 499 | − .platform_data = &(struct fbtft_platform_data) { | |
| 500 | − .display = { | |
| 501 | − .buswidth = 8, | |
| 502 | − .backlight = 1, | |
| 503 | − }, | |
| 504 | − .startbyte = 0x70, | |
| 505 | − .bgr = true, | |
| 506 | − } | |
| 507 | − } | |
| 508 | − }, { | |
| 509 | − .name = "hy28b", | |
| 510 | − .spi = &(struct spi_board_info) { | |
| 511 | − .modalias = "fb_ili9325", | |
| 512 | − .max_speed_hz = 48000000, | |
| 513 | − .mode = SPI_MODE_3, | |
| 514 | − .platform_data = &(struct fbtft_platform_data) { | |
| 515 | − .display = { | |
| 516 | − .buswidth = 8, | |
| 517 | − .backlight = 1, | |
| 518 | − .init_sequence = hy28b_init_sequence, | |
| 519 | − }, | |
| 520 | − .startbyte = 0x70, | |
| 521 | − .bgr = true, | |
| 522 | − .fps = 50, | |
| 523 | − .gamma = HY28B_GAMMA, | |
| 524 | − } | |
| 525 | − } | |
| 526 | − }, { | |
| 527 | − .name = "ili9481", | |
| 528 | − .spi = &(struct spi_board_info) { | |
| 529 | − .modalias = "fb_ili9481", | |
| 530 | − .max_speed_hz = 32000000, | |
| 531 | − .mode = SPI_MODE_0, | |
| 532 | − .platform_data = &(struct fbtft_platform_data) { | |
| 533 | − .display = { | |
| 534 | − .regwidth = 16, | |
| 535 | − .buswidth = 8, | |
| 536 | − .backlight = 1, | |
| 537 | − }, | |
| 538 | − .bgr = true, | |
| 539 | − } | |
| 540 | − } | |
| 541 | − }, { | |
| 542 | − .name = "itdb24", | |
| 543 | − .pdev = &(struct platform_device) { | |
| 544 | − .name = "fb_s6d1121", | |
| 545 | − .id = 0, | |
| 546 | − .dev = { | |
| 547 | − .release = fbtft_device_pdev_release, | |
| 548 | − .platform_data = &(struct fbtft_platform_data) { | |
| 549 | − .display = { | |
| 550 | − .buswidth = 8, | |
| 551 | − .backlight = 1, | |
| 552 | − }, | |
| 553 | − .bgr = false, | |
| 554 | − }, | |
| 555 | − } | |
| 556 | − } | |
| 557 | − }, { | |
| 558 | − .name = "itdb28", | |
| 559 | − .pdev = &(struct platform_device) { | |
| 560 | − .name = "fb_ili9325", | |
| 561 | − .id = 0, | |
| 562 | − .dev = { | |
| 563 | − .release = fbtft_device_pdev_release, | |
| 564 | − .platform_data = &(struct fbtft_platform_data) { | |
| 565 | − .display = { | |
| 566 | − .buswidth = 8, | |
| 567 | − .backlight = 1, | |
| 568 | − }, | |
| 569 | − .bgr = true, | |
| 570 | − }, | |
| 571 | − } | |
| 572 | − } | |
| 573 | − }, { | |
| 574 | − .name = "itdb28_spi", | |
| 575 | − .spi = &(struct spi_board_info) { | |
| 576 | − .modalias = "fb_ili9325", | |
| 577 | − .max_speed_hz = 32000000, | |
| 578 | − .mode = SPI_MODE_0, | |
| 579 | − .platform_data = &(struct fbtft_platform_data) { | |
| 580 | − .display = { | |
| 581 | − .buswidth = 8, | |
| 582 | − .backlight = 1, | |
| 583 | − }, | |
| 584 | − .bgr = true, | |
| 585 | − } | |
| 586 | − } | |
| 587 | − }, { | |
| 588 | − .name = "mi0283qt-2", | |
| 589 | − .spi = &(struct spi_board_info) { | |
| 590 | − .modalias = "fb_hx8347d", | |
| 591 | − .max_speed_hz = 32000000, | |
| 592 | − .mode = SPI_MODE_0, | |
| 593 | − .platform_data = &(struct fbtft_platform_data) { | |
| 594 | − .display = { | |
| 595 | − .buswidth = 8, | |
| 596 | − .backlight = 1, | |
| 597 | − }, | |
| 598 | − .startbyte = 0x70, | |
| 599 | − .bgr = true, | |
| 600 | − } | |
| 601 | − } | |
| 602 | − }, { | |
| 603 | − .name = "mi0283qt-9a", | |
| 604 | − .spi = &(struct spi_board_info) { | |
| 605 | − .modalias = "fb_ili9341", | |
| 606 | − .max_speed_hz = 32000000, | |
| 607 | − .mode = SPI_MODE_0, | |
| 608 | − .platform_data = &(struct fbtft_platform_data) { | |
| 609 | − .display = { | |
| 610 | − .buswidth = 9, | |
| 611 | − .backlight = 1, | |
| 612 | − }, | |
| 613 | − .bgr = true, | |
| 614 | − } | |
| 615 | − } | |
| 616 | − }, { | |
| 617 | − .name = "mi0283qt-v2", | |
| 618 | − .spi = &(struct spi_board_info) { | |
| 619 | − .modalias = "fb_watterott", | |
| 620 | − .max_speed_hz = 4000000, | |
| 621 | − .mode = SPI_MODE_3, | |
| 622 | − .platform_data = &(struct fbtft_platform_data) { | |
| 623 | − } | |
| 624 | − } | |
| 625 | − }, { | |
| 626 | − .name = "nokia3310", | |
| 627 | − .spi = &(struct spi_board_info) { | |
| 628 | − .modalias = "fb_pcd8544", | |
| 629 | − .max_speed_hz = 400000, | |
| 630 | − .mode = SPI_MODE_0, | |
| 631 | − .platform_data = &(struct fbtft_platform_data) { | |
| 632 | − .display = { | |
| 633 | − .buswidth = 8, | |
| 634 | − }, | |
| 635 | − } | |
| 636 | − } | |
| 637 | − }, { | |
| 638 | − .name = "nokia3310a", | |
| 639 | − .spi = &(struct spi_board_info) { | |
| 640 | − .modalias = "fb_tls8204", | |
| 641 | − .max_speed_hz = 1000000, | |
| 642 | − .mode = SPI_MODE_0, | |
| 643 | − .platform_data = &(struct fbtft_platform_data) { | |
| 644 | − .display = { | |
| 645 | − .buswidth = 8, | |
| 646 | − }, | |
| 647 | − } | |
| 648 | − } | |
| 649 | − }, { | |
| 650 | − .name = "nokia5110", | |
| 651 | − .spi = &(struct spi_board_info) { | |
| 652 | − .modalias = "fb_ili9163", | |
| 653 | − .max_speed_hz = 12000000, | |
| 654 | − .mode = SPI_MODE_0, | |
| 655 | − .platform_data = &(struct fbtft_platform_data) { | |
| 656 | − .display = { | |
| 657 | − .buswidth = 8, | |
| 658 | − .backlight = 1, | |
| 659 | − }, | |
| 660 | − .bgr = true, | |
| 661 | − } | |
| 662 | − } | |
| 663 | − }, { | |
| 664 | − .name = "piscreen", | |
| 665 | − .spi = &(struct spi_board_info) { | |
| 666 | − .modalias = "fb_ili9486", | |
| 667 | − .max_speed_hz = 32000000, | |
| 668 | − .mode = SPI_MODE_0, | |
| 669 | − .platform_data = &(struct fbtft_platform_data) { | |
| 670 | − .display = { | |
| 671 | − .regwidth = 16, | |
| 672 | − .buswidth = 8, | |
| 673 | − .backlight = 1, | |
| 674 | − }, | |
| 675 | − .bgr = true, | |
| 676 | − } | |
| 677 | − } | |
| 678 | − }, { | |
| 679 | − .name = "pitft", | |
| 680 | − .spi = &(struct spi_board_info) { | |
| 681 | − .modalias = "fb_ili9340", | |
| 682 | − .max_speed_hz = 32000000, | |
| 683 | − .mode = SPI_MODE_0, | |
| 684 | − .chip_select = 0, | |
| 685 | − .platform_data = &(struct fbtft_platform_data) { | |
| 686 | − .display = { | |
| 687 | − .buswidth = 8, | |
| 688 | − .backlight = 1, | |
| 689 | − .init_sequence = pitft_init_sequence, | |
| 690 | − }, | |
| 691 | − .bgr = true, | |
| 692 | − } | |
| 693 | − } | |
| 694 | − }, { | |
| 695 | − .name = "pioled", | |
| 696 | − .spi = &(struct spi_board_info) { | |
| 697 | − .modalias = "fb_ssd1351", | |
| 698 | − .max_speed_hz = 20000000, | |
| 699 | − .mode = SPI_MODE_0, | |
| 700 | − .platform_data = &(struct fbtft_platform_data) { | |
| 701 | − .display = { | |
| 702 | − .buswidth = 8, | |
| 703 | − }, | |
| 704 | − .bgr = true, | |
| 705 | − .gamma = PIOLED_GAMMA | |
| 706 | − } | |
| 707 | − } | |
| 708 | − }, { | |
| 709 | − .name = "rpi-display", | |
| 710 | − .spi = &(struct spi_board_info) { | |
| 711 | − .modalias = "fb_ili9341", | |
| 712 | − .max_speed_hz = 32000000, | |
| 713 | − .mode = SPI_MODE_0, | |
| 714 | − .platform_data = &(struct fbtft_platform_data) { | |
| 715 | − .display = { | |
| 716 | − .buswidth = 8, | |
| 717 | − .backlight = 1, | |
| 718 | − }, | |
| 719 | − .bgr = true, | |
| 720 | − } | |
| 721 | − } | |
| 722 | − }, { | |
| 723 | − .name = "s6d02a1", | |
| 724 | − .spi = &(struct spi_board_info) { | |
| 725 | − .modalias = "fb_s6d02a1", | |
| 726 | − .max_speed_hz = 32000000, | |
| 727 | − .mode = SPI_MODE_0, | |
| 728 | − .platform_data = &(struct fbtft_platform_data) { | |
| 729 | − .display = { | |
| 730 | − .buswidth = 8, | |
| 731 | − .backlight = 1, | |
| 732 | − }, | |
| 733 | − .bgr = true, | |
| 734 | − } | |
| 735 | − } | |
| 736 | − }, { | |
| 737 | − .name = "sainsmart18", | |
| 738 | − .spi = &(struct spi_board_info) { | |
| 739 | − .modalias = "fb_st7735r", | |
| 740 | − .max_speed_hz = 32000000, | |
| 741 | − .mode = SPI_MODE_0, | |
| 742 | − .platform_data = &(struct fbtft_platform_data) { | |
| 743 | − .display = { | |
| 744 | − .buswidth = 8, | |
| 745 | − }, | |
| 746 | − } | |
| 747 | − } | |
| 748 | − }, { | |
| 749 | − .name = "sainsmart32", | |
| 750 | − .pdev = &(struct platform_device) { | |
| 751 | − .name = "fb_ssd1289", | |
| 752 | − .id = 0, | |
| 753 | − .dev = { | |
| 754 | − .release = fbtft_device_pdev_release, | |
| 755 | − .platform_data = &(struct fbtft_platform_data) { | |
| 756 | − .display = { | |
| 757 | − .buswidth = 16, | |
| 758 | − .txbuflen = -2, /* disable buffer */ | |
| 759 | − .backlight = 1, | |
| 760 | − .fbtftops.write = write_gpio16_wr_slow, | |
| 761 | − }, | |
| 762 | − .bgr = true, | |
| 763 | − }, | |
| 764 | − }, | |
| 765 | − } | |
| 766 | − }, { | |
| 767 | − .name = "sainsmart32_fast", | |
| 768 | − .pdev = &(struct platform_device) { | |
| 769 | − .name = "fb_ssd1289", | |
| 770 | − .id = 0, | |
| 771 | − .dev = { | |
| 772 | − .release = fbtft_device_pdev_release, | |
| 773 | − .platform_data = &(struct fbtft_platform_data) { | |
| 774 | − .display = { | |
| 775 | − .buswidth = 16, | |
| 776 | − .txbuflen = -2, /* disable buffer */ | |
| 777 | − .backlight = 1, | |
| 778 | − }, | |
| 779 | − .bgr = true, | |
| 780 | − }, | |
| 781 | − }, | |
| 782 | − } | |
| 783 | − }, { | |
| 784 | − .name = "sainsmart32_latched", | |
| 785 | − .pdev = &(struct platform_device) { | |
| 786 | − .name = "fb_ssd1289", | |
| 787 | − .id = 0, | |
| 788 | − .dev = { | |
| 789 | − .release = fbtft_device_pdev_release, | |
| 790 | − .platform_data = &(struct fbtft_platform_data) { | |
| 791 | − .display = { | |
| 792 | − .buswidth = 16, | |
| 793 | − .txbuflen = -2, /* disable buffer */ | |
| 794 | − .backlight = 1, | |
| 795 | − .fbtftops.write = | |
| 796 | − fbtft_write_gpio16_wr_latched, | |
| 797 | − }, | |
| 798 | − .bgr = true, | |
| 799 | − }, | |
| 800 | − }, | |
| 801 | − } | |
| 802 | − }, { | |
| 803 | − .name = "sainsmart32_spi", | |
| 804 | − .spi = &(struct spi_board_info) { | |
| 805 | − .modalias = "fb_ssd1289", | |
| 806 | − .max_speed_hz = 16000000, | |
| 807 | − .mode = SPI_MODE_0, | |
| 808 | − .platform_data = &(struct fbtft_platform_data) { | |
| 809 | − .display = { | |
| 810 | − .buswidth = 8, | |
| 811 | − .backlight = 1, | |
| 812 | − }, | |
| 813 | − .bgr = true, | |
| 814 | − } | |
| 815 | − } | |
| 816 | − }, { | |
| 817 | − .name = "spidev", | |
| 818 | − .spi = &(struct spi_board_info) { | |
| 819 | − .modalias = "spidev", | |
| 820 | − .max_speed_hz = 500000, | |
| 821 | − .bus_num = 0, | |
| 822 | − .chip_select = 0, | |
| 823 | − .mode = SPI_MODE_0, | |
| 824 | − .platform_data = &(struct fbtft_platform_data) { | |
| 825 | − } | |
| 826 | − } | |
| 827 | − }, { | |
| 828 | − .name = "ssd1331", | |
| 829 | − .spi = &(struct spi_board_info) { | |
| 830 | − .modalias = "fb_ssd1331", | |
| 831 | − .max_speed_hz = 20000000, | |
| 832 | − .mode = SPI_MODE_3, | |
| 833 | − .platform_data = &(struct fbtft_platform_data) { | |
| 834 | − .display = { | |
| 835 | − .buswidth = 8, | |
| 836 | − }, | |
| 837 | − } | |
| 838 | − } | |
| 839 | − }, { | |
| 840 | − .name = "tinylcd35", | |
| 841 | − .spi = &(struct spi_board_info) { | |
| 842 | − .modalias = "fb_tinylcd", | |
| 843 | − .max_speed_hz = 32000000, | |
| 844 | − .mode = SPI_MODE_0, | |
| 845 | − .platform_data = &(struct fbtft_platform_data) { | |
| 846 | − .display = { | |
| 847 | − .buswidth = 8, | |
| 848 | − .backlight = 1, | |
| 849 | − }, | |
| 850 | − .bgr = true, | |
| 851 | − } | |
| 852 | − } | |
| 853 | − }, { | |
| 854 | − .name = "tm022hdh26", | |
| 855 | − .spi = &(struct spi_board_info) { | |
| 856 | − .modalias = "fb_ili9341", | |
| 857 | − .max_speed_hz = 32000000, | |
| 858 | − .mode = SPI_MODE_0, | |
| 859 | − .platform_data = &(struct fbtft_platform_data) { | |
| 860 | − .display = { | |
| 861 | − .buswidth = 8, | |
| 862 | − .backlight = 1, | |
| 863 | − }, | |
| 864 | − .bgr = true, | |
| 865 | − } | |
| 866 | − } | |
| 867 | − }, { | |
| 868 | − .name = "tontec35_9481", /* boards before 02 July 2014 */ | |
| 869 | − .spi = &(struct spi_board_info) { | |
| 870 | − .modalias = "fb_ili9481", | |
| 871 | − .max_speed_hz = 128000000, | |
| 872 | − .mode = SPI_MODE_3, | |
| 873 | − .platform_data = &(struct fbtft_platform_data) { | |
| 874 | − .display = { | |
| 875 | − .buswidth = 8, | |
| 876 | − .backlight = 1, | |
| 877 | − }, | |
| 878 | − .bgr = true, | |
| 879 | − } | |
| 880 | − } | |
| 881 | − }, { | |
| 882 | − .name = "tontec35_9486", /* boards after 02 July 2014 */ | |
| 883 | − .spi = &(struct spi_board_info) { | |
| 884 | − .modalias = "fb_ili9486", | |
| 885 | − .max_speed_hz = 128000000, | |
| 886 | − .mode = SPI_MODE_3, | |
| 887 | − .platform_data = &(struct fbtft_platform_data) { | |
| 888 | − .display = { | |
| 889 | − .buswidth = 8, | |
| 890 | − .backlight = 1, | |
| 891 | − }, | |
| 892 | − .bgr = true, | |
| 893 | − } | |
| 894 | − } | |
| 895 | − }, { | |
| 896 | − .name = "upd161704", | |
| 897 | − .spi = &(struct spi_board_info) { | |
| 898 | − .modalias = "fb_upd161704", | |
| 899 | − .max_speed_hz = 32000000, | |
| 900 | − .mode = SPI_MODE_0, | |
| 901 | − .platform_data = &(struct fbtft_platform_data) { | |
| 902 | − .display = { | |
| 903 | − .buswidth = 8, | |
| 904 | − }, | |
| 905 | − } | |
| 906 | − } | |
| 907 | − }, { | |
| 908 | − .name = "waveshare32b", | |
| 909 | − .spi = &(struct spi_board_info) { | |
| 910 | − .modalias = "fb_ili9340", | |
| 911 | − .max_speed_hz = 48000000, | |
| 912 | − .mode = SPI_MODE_0, | |
| 913 | − .platform_data = &(struct fbtft_platform_data) { | |
| 914 | − .display = { | |
| 915 | − .buswidth = 8, | |
| 916 | − .backlight = 1, | |
| 917 | − .init_sequence = | |
| 918 | − waveshare32b_init_sequence, | |
| 919 | − }, | |
| 920 | − .bgr = true, | |
| 921 | − } | |
| 922 | − } | |
| 923 | − }, { | |
| 924 | − .name = "waveshare22", | |
| 925 | − .spi = &(struct spi_board_info) { | |
| 926 | − .modalias = "fb_bd663474", | |
| 927 | − .max_speed_hz = 32000000, | |
| 928 | − .mode = SPI_MODE_3, | |
| 929 | − .platform_data = &(struct fbtft_platform_data) { | |
| 930 | − .display = { | |
| 931 | − .buswidth = 8, | |
| 932 | − }, | |
| 933 | − } | |
| 934 | − } | |
| 935 | − }, { | |
| 936 | − /* This should be the last item. | |
| 937 | − * Used with the custom argument | |
| 938 | − */ | |
| 939 | − .name = "", | |
| 940 | − .spi = &(struct spi_board_info) { | |
| 941 | − .modalias = "", | |
| 942 | − .max_speed_hz = 0, | |
| 943 | − .mode = SPI_MODE_0, | |
| 944 | − .platform_data = &(struct fbtft_platform_data) { | |
| 945 | − } | |
| 946 | − }, | |
| 947 | − .pdev = &(struct platform_device) { | |
| 948 | − .name = "", | |
| 949 | − .id = 0, | |
| 950 | − .dev = { | |
| 951 | − .release = fbtft_device_pdev_release, | |
| 952 | − .platform_data = &(struct fbtft_platform_data) { | |
| 953 | − }, | |
| 954 | − }, | |
| 955 | − }, | |
| 956 | − } | |
| 957 | −}; | |
| 958 | − | |
| 959 | −static int write_gpio16_wr_slow(struct fbtft_par *par, void *buf, size_t len) | |
| 960 | −{ | |
| 961 | − u16 data; | |
| 962 | − int i; | |
| 963 | −#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO | |
| 964 | − static u16 prev_data; | |
| 965 | −#endif | |
| 966 | − | |
| 967 | − fbtft_par_dbg_hex(DEBUG_WRITE, par, par->info->device, u8, buf, len, | |
| 968 | − "%s(len=%zu): ", __func__, len); | |
| 969 | − | |
| 970 | − while (len) { | |
| 971 | − data = *(u16 *)buf; | |
| 972 | − | |
| 973 | − /* Start writing by pulling down /WR */ | |
| 974 | − gpiod_set_value(par->gpio.wr, 0); | |
| 975 | − | |
| 976 | − /* Set data */ | |
| 977 | −#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO | |
| 978 | − if (data == prev_data) { | |
| 979 | − gpiod_set_value(par->gpio.wr, 0); /* used as delay */ | |
| 980 | − } else { | |
| 981 | − for (i = 0; i < 16; i++) { | |
| 982 | − if ((data & 1) != (prev_data & 1)) | |
| 983 | − gpiod_set_value(par->gpio.db[i], | |
| 984 | − data & 1); | |
| 985 | − data >>= 1; | |
| 986 | − prev_data >>= 1; | |
| 987 | − } | |
| 988 | − } | |
| 989 | −#else | |
| 990 | − for (i = 0; i < 16; i++) { | |
| 991 | − gpiod_set_value(par->gpio.db[i], data & 1); | |
| 992 | − data >>= 1; | |
| 993 | − } | |
| 994 | −#endif | |
| 995 | − | |
| 996 | − /* Pullup /WR */ | |
| 997 | − gpiod_set_value(par->gpio.wr, 1); | |
| 998 | − | |
| 999 | −#ifndef DO_NOT_OPTIMIZE_FBTFT_WRITE_GPIO | |
| 1000 | − prev_data = *(u16 *)buf; | |
| 1001 | −#endif | |
| 1002 | − buf += 2; | |
| 1003 | − len -= 2; | |
| 1004 | − } | |
| 1005 | − | |
| 1006 | − return 0; | |
| 1007 | −} | |
| 1008 | − | |
| 1009 | −static void adafruit18_green_tab_set_addr_win(struct fbtft_par *par, | |
| 1010 | − int xs, int ys, int xe, int ye) | |
| 1011 | −{ | |
| 1012 | − write_reg(par, 0x2A, 0, xs + 2, 0, xe + 2); | |
| 1013 | − write_reg(par, 0x2B, 0, ys + 1, 0, ye + 1); | |
| 1014 | − write_reg(par, 0x2C); | |
| 1015 | −} | |
| 1016 | − | |
| 1017 | −static void fbtft_device_pdev_release(struct device *dev) | |
| 1018 | −{ | |
| 1019 | −/* Needed to silence this message: | |
| 1020 | − * Device 'xxx' does not have a release() function, | |
| 1021 | − * it is broken and must be fixed | |
| 1022 | − */ | |
| 1023 | −} | |
| 1024 | − | |
| 1025 | −static int spi_device_found(struct device *dev, void *data) | |
| 1026 | −{ | |
| 1027 | − struct spi_device *spi = to_spi_device(dev); | |
| 1028 | − | |
| 1029 | − dev_info(dev, "%s %s %dkHz %d bits mode=0x%02X\n", spi->modalias, | |
| 1030 | − dev_name(dev), spi->max_speed_hz / 1000, spi->bits_per_word, | |
| 1031 | − spi->mode); | |
| 1032 | − | |
| 1033 | − return 0; | |
| 1034 | −} | |
| 1035 | − | |
| 1036 | −static void pr_spi_devices(void) | |
| 1037 | −{ | |
| 1038 | − pr_debug("SPI devices registered:\n"); | |
| 1039 | − bus_for_each_dev(&spi_bus_type, NULL, NULL, spi_device_found); | |
| 1040 | −} | |
| 1041 | − | |
| 1042 | −static int p_device_found(struct device *dev, void *data) | |
| 1043 | −{ | |
| 1044 | − struct platform_device | |
| 1045 | − *pdev = to_platform_device(dev); | |
| 1046 | − | |
| 1047 | − if (strstr(pdev->name, "fb")) | |
| 1048 | − dev_info(dev, "%s id=%d pdata? %s\n", pdev->name, pdev->id, | |
| 1049 | − pdev->dev.platform_data ? "yes" : "no"); | |
| 1050 | − | |
| 1051 | − return 0; | |
| 1052 | −} | |
| 1053 | − | |
| 1054 | −static void pr_p_devices(void) | |
| 1055 | −{ | |
| 1056 | − pr_debug("'fb' Platform devices registered:\n"); | |
| 1057 | − bus_for_each_dev(&platform_bus_type, NULL, NULL, p_device_found); | |
| 1058 | −} | |
| 1059 | − | |
| 1060 | −#ifdef MODULE | |
| 1061 | −static void fbtft_device_spi_delete(struct spi_master *master, unsigned int cs) | |
| 1062 | −{ | |
| 1063 | − struct device *dev; | |
| 1064 | − char str[32]; | |
| 1065 | − | |
| 1066 | − snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), cs); | |
| 1067 | − | |
| 1068 | − dev = bus_find_device_by_name(&spi_bus_type, NULL, str); | |
| 1069 | − if (dev) { | |
| 1070 | − if (verbose) | |
| 1071 | − dev_info(dev, "Deleting %s\n", str); | |
| 1072 | − device_del(dev); | |
| 1073 | − } | |
| 1074 | −} | |
| 1075 | − | |
| 1076 | −static int fbtft_device_spi_device_register(struct spi_board_info *spi) | |
| 1077 | −{ | |
| 1078 | − struct spi_master *master; | |
| 1079 | − | |
| 1080 | − master = spi_busnum_to_master(spi->bus_num); | |
| 1081 | − if (!master) { | |
| 1082 | − pr_err("spi_busnum_to_master(%d) returned NULL\n", | |
| 1083 | − spi->bus_num); | |
| 1084 | − return -EINVAL; | |
| 1085 | − } | |
| 1086 | − /* make sure it's available */ | |
| 1087 | − fbtft_device_spi_delete(master, spi->chip_select); | |
| 1088 | − spi_device = spi_new_device(master, spi); | |
| 1089 | − put_device(&master->dev); | |
| 1090 | − if (!spi_device) { | |
| 1091 | − dev_err(&master->dev, "spi_new_device() returned NULL\n"); | |
| 1092 | − return -EPERM; | |
| 1093 | − } | |
| 1094 | − return 0; | |
| 1095 | −} | |
| 1096 | −#else | |
| 1097 | −static int fbtft_device_spi_device_register(struct spi_board_info *spi) | |
| 1098 | −{ | |
| 1099 | − return spi_register_board_info(spi, 1); | |
| 1100 | −} | |
| 1101 | −#endif | |
| 1102 | − | |
| 1103 | −static int __init fbtft_device_init(void) | |
| 1104 | −{ | |
| 1105 | − struct spi_board_info *spi = NULL; | |
| 1106 | − struct fbtft_platform_data *pdata; | |
| 1107 | − bool found = false; | |
| 1108 | − int i = 0; | |
| 1109 | − int ret = 0; | |
| 1110 | − | |
| 1111 | − if (!name) { | |
| 1112 | −#ifdef MODULE | |
| 1113 | − pr_err("missing module parameter: 'name'\n"); | |
| 1114 | − return -EINVAL; | |
| 1115 | −#else | |
| 1116 | − return 0; | |
| 1117 | −#endif | |
| 1118 | − } | |
| 1119 | − | |
| 1120 | − if (init_num > FBTFT_MAX_INIT_SEQUENCE) { | |
| 1121 | − pr_err("init parameter: exceeded max array size: %d\n", | |
| 1122 | − FBTFT_MAX_INIT_SEQUENCE); | |
| 1123 | − return -EINVAL; | |
| 1124 | − } | |
| 1125 | − | |
| 1126 | − if (verbose > 2) { | |
| 1127 | − pr_spi_devices(); /* print list of registered SPI devices */ | |
| 1128 | − pr_p_devices(); /* print list of 'fb' platform devices */ | |
| 1129 | − } | |
| 1130 | − | |
| 1131 | − pr_debug("name='%s', busnum=%d, cs=%d\n", name, busnum, cs); | |
| 1132 | − | |
| 1133 | − if (rotate > 0 && rotate < 4) { | |
| 1134 | − rotate = (4 - rotate) * 90; | |
| 1135 | − pr_warn("argument 'rotate' should be an angle. Values 1-3 is deprecated. Setting it to %d.\n", | |
| 1136 | − rotate); | |
| 1137 | − } | |
| 1138 | − if (rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) { | |
| 1139 | − pr_warn("argument 'rotate' illegal value: %d. Setting it to 0.\n", | |
| 1140 | − rotate); | |
| 1141 | − rotate = 0; | |
| 1142 | − } | |
| 1143 | − | |
| 1144 | − /* name=list lists all supported displays */ | |
| 1145 | − if (strcmp(name, "list") == 0) { | |
| 1146 | − pr_info("Supported displays:\n"); | |
| 1147 | − | |
| 1148 | − for (i = 0; i < ARRAY_SIZE(displays); i++) | |
| 1149 | − pr_info("%s\n", displays[i].name); | |
| 1150 | − return -ECANCELED; | |
| 1151 | − } | |
| 1152 | − | |
| 1153 | − if (custom) { | |
| 1154 | − i = ARRAY_SIZE(displays) - 1; | |
| 1155 | − displays[i].name = name; | |
| 1156 | − if (speed == 0) { | |
| 1157 | − displays[i].pdev->name = name; | |
| 1158 | − displays[i].spi = NULL; | |
| 1159 | − } else { | |
| 1160 | − size_t len; | |
| 1161 | − | |
| 1162 | − len = strlcpy(displays[i].spi->modalias, name, | |
| 1163 | − SPI_NAME_SIZE); | |
| 1164 | − if (len >= SPI_NAME_SIZE) | |
| 1165 | − pr_warn("modalias (name) truncated to: %s\n", | |
| 1166 | − displays[i].spi->modalias); | |
| 1167 | − displays[i].pdev = NULL; | |
| 1168 | − } | |
| 1169 | − } | |
| 1170 | − | |
| 1171 | − for (i = 0; i < ARRAY_SIZE(displays); i++) { | |
| 1172 | − if (strncmp(name, displays[i].name, SPI_NAME_SIZE) == 0) { | |
| 1173 | − if (displays[i].spi) { | |
| 1174 | − spi = displays[i].spi; | |
| 1175 | − spi->chip_select = cs; | |
| 1176 | − spi->bus_num = busnum; | |
| 1177 | − if (speed) | |
| 1178 | − spi->max_speed_hz = speed; | |
| 1179 | − if (mode != -1) | |
| 1180 | − spi->mode = mode; | |
| 1181 | − pdata = (void *)spi->platform_data; | |
| 1182 | − } else if (displays[i].pdev) { | |
| 1183 | − p_device = displays[i].pdev; | |
| 1184 | − pdata = p_device->dev.platform_data; | |
| 1185 | − } else { | |
| 1186 | − pr_err("broken displays array\n"); | |
| 1187 | − return -EINVAL; | |
| 1188 | − } | |
| 1189 | − | |
| 1190 | − pdata->rotate = rotate; | |
| 1191 | − if (bgr == 0) | |
| 1192 | − pdata->bgr = false; | |
| 1193 | − else if (bgr == 1) | |
| 1194 | − pdata->bgr = true; | |
| 1195 | − if (startbyte) | |
| 1196 | − pdata->startbyte = startbyte; | |
| 1197 | − if (gamma) | |
| 1198 | − pdata->gamma = gamma; | |
| 1199 | − pdata->display.debug = debug; | |
| 1200 | − if (fps) | |
| 1201 | − pdata->fps = fps; | |
| 1202 | − if (txbuflen) | |
| 1203 | − pdata->txbuflen = txbuflen; | |
| 1204 | − if (init_num) | |
| 1205 | − pdata->display.init_sequence = init; | |
| 1206 | − if (custom) { | |
| 1207 | − pdata->display.width = width; | |
| 1208 | − pdata->display.height = height; | |
| 1209 | − pdata->display.buswidth = buswidth; | |
| 1210 | − pdata->display.backlight = 1; | |
| 1211 | − } | |
| 1212 | − | |
| 1213 | − if (displays[i].spi) { | |
| 1214 | − ret = fbtft_device_spi_device_register(spi); | |
| 1215 | − if (ret) { | |
| 1216 | − pr_err("failed to register SPI device\n"); | |
| 1217 | − return ret; | |
| 1218 | − } | |
| 1219 | − } else { | |
| 1220 | − ret = platform_device_register(p_device); | |
| 1221 | − if (ret < 0) { | |
| 1222 | − pr_err("platform_device_register() returned %d\n", | |
| 1223 | − ret); | |
| 1224 | − return ret; | |
| 1225 | − } | |
| 1226 | − } | |
| 1227 | − found = true; | |
| 1228 | − break; | |
| 1229 | − } | |
| 1230 | − } | |
| 1231 | − | |
| 1232 | − if (!found) { | |
| 1233 | − pr_err("display not supported: '%s'\n", name); | |
| 1234 | − return -EINVAL; | |
| 1235 | − } | |
| 1236 | − | |
| 1237 | − if (spi_device && (verbose > 1)) | |
| 1238 | − pr_spi_devices(); | |
| 1239 | − if (p_device && (verbose > 1)) | |
| 1240 | − pr_p_devices(); | |
| 1241 | − | |
| 1242 | − return 0; | |
| 1243 | −} | |
| 1244 | − | |
| 1245 | −static void __exit fbtft_device_exit(void) | |
| 1246 | −{ | |
| 1247 | − if (spi_device) { | |
| 1248 | − device_del(&spi_device->dev); | |
| 1249 | − kfree(spi_device); | |
| 1250 | − } | |
| 1251 | − | |
| 1252 | − if (p_device) | |
| 1253 | − platform_device_unregister(p_device); | |
| 1254 | −} | |
| 1255 | − | |
| 1256 | −arch_initcall(fbtft_device_init); | |
| 1257 | −module_exit(fbtft_device_exit); | |
| 1258 | − | |
| 1259 | −MODULE_DESCRIPTION("Add a FBTFT device."); | |
| 1260 | −MODULE_AUTHOR("Noralf Tronnes"); | |
| 1261 | −MODULE_LICENSE("GPL"); | |
| @@ -1,851 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0+ | |
| 2 | −/* | |
| 3 | − * Generic FB driver for TFT LCD displays | |
| 4 | − * | |
| 5 | − * Copyright (C) 2013 Noralf Tronnes | |
| 6 | − */ | |
| 7 | − | |
| 8 | −#include <linux/module.h> | |
| 9 | −#include <linux/kernel.h> | |
| 10 | −#include <linux/init.h> | |
| 11 | −#include <linux/vmalloc.h> | |
| 12 | −#include <linux/gpio/consumer.h> | |
| 13 | −#include <linux/spi/spi.h> | |
| 14 | −#include <linux/delay.h> | |
| 15 | − | |
| 16 | −#include "fbtft.h" | |
| 17 | − | |
| 18 | −#define DRVNAME "flexfb" | |
| 19 | − | |
| 20 | −static char *chip; | |
| 21 | −module_param(chip, charp, 0000); | |
| 22 | −MODULE_PARM_DESC(chip, "LCD controller"); | |
| 23 | − | |
| 24 | −static unsigned int width; | |
| 25 | −module_param(width, uint, 0000); | |
| 26 | −MODULE_PARM_DESC(width, "Display width"); | |
| 27 | − | |
| 28 | −static unsigned int height; | |
| 29 | −module_param(height, uint, 0000); | |
| 30 | −MODULE_PARM_DESC(height, "Display height"); | |
| 31 | − | |
| 32 | −static s16 init[512]; | |
| 33 | −static int init_num; | |
| 34 | −module_param_array(init, short, &init_num, 0000); | |
| 35 | −MODULE_PARM_DESC(init, "Init sequence"); | |
| 36 | − | |
| 37 | −static unsigned int setaddrwin; | |
| 38 | −module_param(setaddrwin, uint, 0000); | |
| 39 | −MODULE_PARM_DESC(setaddrwin, "Which set_addr_win() implementation to use"); | |
| 40 | − | |
| 41 | −static unsigned int buswidth = 8; | |
| 42 | −module_param(buswidth, uint, 0000); | |
| 43 | −MODULE_PARM_DESC(buswidth, "Width of databus (default: 8)"); | |
| 44 | − | |
| 45 | −static unsigned int regwidth = 8; | |
| 46 | −module_param(regwidth, uint, 0000); | |
| 47 | −MODULE_PARM_DESC(regwidth, "Width of controller register (default: 8)"); | |
| 48 | − | |
| 49 | −static bool nobacklight; | |
| 50 | −module_param(nobacklight, bool, 0000); | |
| 51 | −MODULE_PARM_DESC(nobacklight, "Turn off backlight functionality."); | |
| 52 | − | |
| 53 | −static bool latched; | |
| 54 | −module_param(latched, bool, 0000); | |
| 55 | −MODULE_PARM_DESC(latched, "Use with latched 16-bit databus"); | |
| 56 | − | |
| 57 | −static const s16 *initp; | |
| 58 | −static int initp_num; | |
| 59 | − | |
| 60 | −/* default init sequences */ | |
| 61 | −static const s16 st7735r_init[] = { | |
| 62 | − -1, 0x01, | |
| 63 | − -2, 150, | |
| 64 | − -1, 0x11, | |
| 65 | − -2, 500, | |
| 66 | − -1, 0xB1, 0x01, 0x2C, 0x2D, | |
| 67 | − -1, 0xB2, 0x01, 0x2C, 0x2D, | |
| 68 | − -1, 0xB3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, | |
| 69 | − -1, 0xB4, 0x07, | |
| 70 | − -1, 0xC0, 0xA2, 0x02, 0x84, | |
| 71 | − -1, 0xC1, 0xC5, | |
| 72 | − -1, 0xC2, 0x0A, 0x00, | |
| 73 | − -1, 0xC3, 0x8A, 0x2A, | |
| 74 | − -1, 0xC4, 0x8A, 0xEE, | |
| 75 | − -1, 0xC5, 0x0E, | |
| 76 | − -1, 0x20, | |
| 77 | − -1, 0x36, 0xC0, | |
| 78 | − -1, 0x3A, 0x05, | |
| 79 | − -1, 0xE0, 0x0f, 0x1a, 0x0f, 0x18, 0x2f, 0x28, 0x20, 0x22, | |
| 80 | − 0x1f, 0x1b, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10, | |
| 81 | − -1, 0xE1, 0x0f, 0x1b, 0x0f, 0x17, 0x33, 0x2c, 0x29, 0x2e, | |
| 82 | − 0x30, 0x30, 0x39, 0x3f, 0x00, 0x07, 0x03, 0x10, | |
| 83 | − -1, 0x29, | |
| 84 | − -2, 100, | |
| 85 | − -1, 0x13, | |
| 86 | − -2, 10, | |
| 87 | − -3 | |
| 88 | −}; | |
| 89 | − | |
| 90 | −static const s16 ssd1289_init[] = { | |
| 91 | − -1, 0x00, 0x0001, | |
| 92 | − -1, 0x03, 0xA8A4, | |
| 93 | − -1, 0x0C, 0x0000, | |
| 94 | − -1, 0x0D, 0x080C, | |
| 95 | − -1, 0x0E, 0x2B00, | |
| 96 | − -1, 0x1E, 0x00B7, | |
| 97 | − -1, 0x01, 0x2B3F, | |
| 98 | − -1, 0x02, 0x0600, | |
| 99 | − -1, 0x10, 0x0000, | |
| 100 | − -1, 0x11, 0x6070, | |
| 101 | − -1, 0x05, 0x0000, | |
| 102 | − -1, 0x06, 0x0000, | |
| 103 | − -1, 0x16, 0xEF1C, | |
| 104 | − -1, 0x17, 0x0003, | |
| 105 | − -1, 0x07, 0x0233, | |
| 106 | − -1, 0x0B, 0x0000, | |
| 107 | − -1, 0x0F, 0x0000, | |
| 108 | − -1, 0x41, 0x0000, | |
| 109 | − -1, 0x42, 0x0000, | |
| 110 | − -1, 0x48, 0x0000, | |
| 111 | − -1, 0x49, 0x013F, | |
| 112 | − -1, 0x4A, 0x0000, | |
| 113 | − -1, 0x4B, 0x0000, | |
| 114 | − -1, 0x44, 0xEF00, | |
| 115 | − -1, 0x45, 0x0000, | |
| 116 | − -1, 0x46, 0x013F, | |
| 117 | − -1, 0x30, 0x0707, | |
| 118 | − -1, 0x31, 0x0204, | |
| 119 | − -1, 0x32, 0x0204, | |
| 120 | − -1, 0x33, 0x0502, | |
| 121 | − -1, 0x34, 0x0507, | |
| 122 | − -1, 0x35, 0x0204, | |
| 123 | − -1, 0x36, 0x0204, | |
| 124 | − -1, 0x37, 0x0502, | |
| 125 | − -1, 0x3A, 0x0302, | |
| 126 | − -1, 0x3B, 0x0302, | |
| 127 | − -1, 0x23, 0x0000, | |
| 128 | − -1, 0x24, 0x0000, | |
| 129 | − -1, 0x25, 0x8000, | |
| 130 | − -1, 0x4f, 0x0000, | |
| 131 | − -1, 0x4e, 0x0000, | |
| 132 | − -1, 0x22, | |
| 133 | − -3 | |
| 134 | −}; | |
| 135 | − | |
| 136 | −static const s16 hx8340bn_init[] = { | |
| 137 | − -1, 0xC1, 0xFF, 0x83, 0x40, | |
| 138 | − -1, 0x11, | |
| 139 | − -2, 150, | |
| 140 | − -1, 0xCA, 0x70, 0x00, 0xD9, | |
| 141 | − -1, 0xB0, 0x01, 0x11, | |
| 142 | − -1, 0xC9, 0x90, 0x49, 0x10, 0x28, 0x28, 0x10, 0x00, 0x06, | |
| 143 | − -2, 20, | |
| 144 | − -1, 0xC2, 0x60, 0x71, 0x01, 0x0E, 0x05, 0x02, 0x09, 0x31, 0x0A, | |
| 145 | − -1, 0xC3, 0x67, 0x30, 0x61, 0x17, 0x48, 0x07, 0x05, 0x33, | |
| 146 | − -2, 10, | |
| 147 | − -1, 0xB5, 0x35, 0x20, 0x45, | |
| 148 | − -1, 0xB4, 0x33, 0x25, 0x4C, | |
| 149 | − -2, 10, | |
| 150 | − -1, 0x3A, 0x05, | |
| 151 | − -1, 0x29, | |
| 152 | − -2, 10, | |
| 153 | − -3 | |
| 154 | −}; | |
| 155 | − | |
| 156 | −static const s16 ili9225_init[] = { | |
| 157 | − -1, 0x0001, 0x011C, | |
| 158 | − -1, 0x0002, 0x0100, | |
| 159 | − -1, 0x0003, 0x1030, | |
| 160 | − -1, 0x0008, 0x0808, | |
| 161 | − -1, 0x000C, 0x0000, | |
| 162 | − -1, 0x000F, 0x0A01, | |
| 163 | − -1, 0x0020, 0x0000, | |
| 164 | − -1, 0x0021, 0x0000, | |
| 165 | − -2, 50, | |
| 166 | − -1, 0x0010, 0x0A00, | |
| 167 | − -1, 0x0011, 0x1038, | |
| 168 | − -2, 50, | |
| 169 | − -1, 0x0012, 0x1121, | |
| 170 | − -1, 0x0013, 0x004E, | |
| 171 | − -1, 0x0014, 0x676F, | |
| 172 | − -1, 0x0030, 0x0000, | |
| 173 | − -1, 0x0031, 0x00DB, | |
| 174 | − -1, 0x0032, 0x0000, | |
| 175 | − -1, 0x0033, 0x0000, | |
| 176 | − -1, 0x0034, 0x00DB, | |
| 177 | − -1, 0x0035, 0x0000, | |
| 178 | − -1, 0x0036, 0x00AF, | |
| 179 | − -1, 0x0037, 0x0000, | |
| 180 | − -1, 0x0038, 0x00DB, | |
| 181 | − -1, 0x0039, 0x0000, | |
| 182 | − -1, 0x0050, 0x0000, | |
| 183 | − -1, 0x0051, 0x060A, | |
| 184 | − -1, 0x0052, 0x0D0A, | |
| 185 | − -1, 0x0053, 0x0303, | |
| 186 | − -1, 0x0054, 0x0A0D, | |
| 187 | − -1, 0x0055, 0x0A06, | |
| 188 | − -1, 0x0056, 0x0000, | |
| 189 | − -1, 0x0057, 0x0303, | |
| 190 | − -1, 0x0058, 0x0000, | |
| 191 | − -1, 0x0059, 0x0000, | |
| 192 | − -2, 50, | |
| 193 | − -1, 0x0007, 0x1017, | |
| 194 | − -2, 50, | |
| 195 | − -3 | |
| 196 | −}; | |
| 197 | − | |
| 198 | −static const s16 ili9320_init[] = { | |
| 199 | − -1, 0x00E5, 0x8000, | |
| 200 | − -1, 0x0000, 0x0001, | |
| 201 | − -1, 0x0001, 0x0100, | |
| 202 | − -1, 0x0002, 0x0700, | |
| 203 | − -1, 0x0003, 0x1030, | |
| 204 | − -1, 0x0004, 0x0000, | |
| 205 | − -1, 0x0008, 0x0202, | |
| 206 | − -1, 0x0009, 0x0000, | |
| 207 | − -1, 0x000A, 0x0000, | |
| 208 | − -1, 0x000C, 0x0000, | |
| 209 | − -1, 0x000D, 0x0000, | |
| 210 | − -1, 0x000F, 0x0000, | |
| 211 | − -1, 0x0010, 0x0000, | |
| 212 | − -1, 0x0011, 0x0007, | |
| 213 | − -1, 0x0012, 0x0000, | |
| 214 | − -1, 0x0013, 0x0000, | |
| 215 | − -2, 200, | |
| 216 | − -1, 0x0010, 0x17B0, | |
| 217 | − -1, 0x0011, 0x0031, | |
| 218 | − -2, 50, | |
| 219 | − -1, 0x0012, 0x0138, | |
| 220 | − -2, 50, | |
| 221 | − -1, 0x0013, 0x1800, | |
| 222 | − -1, 0x0029, 0x0008, | |
| 223 | − -2, 50, | |
| 224 | − -1, 0x0020, 0x0000, | |
| 225 | − -1, 0x0021, 0x0000, | |
| 226 | − -1, 0x0030, 0x0000, | |
| 227 | − -1, 0x0031, 0x0505, | |
| 228 | − -1, 0x0032, 0x0004, | |
| 229 | − -1, 0x0035, 0x0006, | |
| 230 | − -1, 0x0036, 0x0707, | |
| 231 | − -1, 0x0037, 0x0105, | |
| 232 | − -1, 0x0038, 0x0002, | |
| 233 | − -1, 0x0039, 0x0707, | |
| 234 | − -1, 0x003C, 0x0704, | |
| 235 | − -1, 0x003D, 0x0807, | |
| 236 | − -1, 0x0050, 0x0000, | |
| 237 | − -1, 0x0051, 0x00EF, | |
| 238 | − -1, 0x0052, 0x0000, | |
| 239 | − -1, 0x0053, 0x013F, | |
| 240 | − -1, 0x0060, 0x2700, | |
| 241 | − -1, 0x0061, 0x0001, | |
| 242 | − -1, 0x006A, 0x0000, | |
| 243 | − -1, 0x0080, 0x0000, | |
| 244 | − -1, 0x0081, 0x0000, | |
| 245 | − -1, 0x0082, 0x0000, | |
| 246 | − -1, 0x0083, 0x0000, | |
| 247 | − -1, 0x0084, 0x0000, | |
| 248 | − -1, 0x0085, 0x0000, | |
| 249 | − -1, 0x0090, 0x0010, | |
| 250 | − -1, 0x0092, 0x0000, | |
| 251 | − -1, 0x0093, 0x0003, | |
| 252 | − -1, 0x0095, 0x0110, | |
| 253 | − -1, 0x0097, 0x0000, | |
| 254 | − -1, 0x0098, 0x0000, | |
| 255 | − -1, 0x0007, 0x0173, | |
| 256 | − -3 | |
| 257 | −}; | |
| 258 | − | |
| 259 | −static const s16 ili9325_init[] = { | |
| 260 | − -1, 0x00E3, 0x3008, | |
| 261 | − -1, 0x00E7, 0x0012, | |
| 262 | − -1, 0x00EF, 0x1231, | |
| 263 | − -1, 0x0001, 0x0100, | |
| 264 | − -1, 0x0002, 0x0700, | |
| 265 | − -1, 0x0003, 0x1030, | |
| 266 | − -1, 0x0004, 0x0000, | |
| 267 | − -1, 0x0008, 0x0207, | |
| 268 | − -1, 0x0009, 0x0000, | |
| 269 | − -1, 0x000A, 0x0000, | |
| 270 | − -1, 0x000C, 0x0000, | |
| 271 | − -1, 0x000D, 0x0000, | |
| 272 | − -1, 0x000F, 0x0000, | |
| 273 | − -1, 0x0010, 0x0000, | |
| 274 | − -1, 0x0011, 0x0007, | |
| 275 | − -1, 0x0012, 0x0000, | |
| 276 | − -1, 0x0013, 0x0000, | |
| 277 | − -2, 200, | |
| 278 | − -1, 0x0010, 0x1690, | |
| 279 | − -1, 0x0011, 0x0223, | |
| 280 | − -2, 50, | |
| 281 | − -1, 0x0012, 0x000D, | |
| 282 | − -2, 50, | |
| 283 | − -1, 0x0013, 0x1200, | |
| 284 | − -1, 0x0029, 0x000A, | |
| 285 | − -1, 0x002B, 0x000C, | |
| 286 | − -2, 50, | |
| 287 | − -1, 0x0020, 0x0000, | |
| 288 | − -1, 0x0021, 0x0000, | |
| 289 | − -1, 0x0030, 0x0000, | |
| 290 | − -1, 0x0031, 0x0506, | |
| 291 | − -1, 0x0032, 0x0104, | |
| 292 | − -1, 0x0035, 0x0207, | |
| 293 | − -1, 0x0036, 0x000F, | |
| 294 | − -1, 0x0037, 0x0306, | |
| 295 | − -1, 0x0038, 0x0102, | |
| 296 | − -1, 0x0039, 0x0707, | |
| 297 | − -1, 0x003C, 0x0702, | |
| 298 | − -1, 0x003D, 0x1604, | |
| 299 | − -1, 0x0050, 0x0000, | |
| 300 | − -1, 0x0051, 0x00EF, | |
| 301 | − -1, 0x0052, 0x0000, | |
| 302 | − -1, 0x0053, 0x013F, | |
| 303 | − -1, 0x0060, 0xA700, | |
| 304 | − -1, 0x0061, 0x0001, | |
| 305 | − -1, 0x006A, 0x0000, | |
| 306 | − -1, 0x0080, 0x0000, | |
| 307 | − -1, 0x0081, 0x0000, | |
| 308 | − -1, 0x0082, 0x0000, | |
| 309 | − -1, 0x0083, 0x0000, | |
| 310 | − -1, 0x0084, 0x0000, | |
| 311 | − -1, 0x0085, 0x0000, | |
| 312 | − -1, 0x0090, 0x0010, | |
| 313 | − -1, 0x0092, 0x0600, | |
| 314 | − -1, 0x0007, 0x0133, | |
| 315 | − -3 | |
| 316 | −}; | |
| 317 | − | |
| 318 | −static const s16 ili9341_init[] = { | |
| 319 | − -1, 0x28, | |
| 320 | − -2, 20, | |
| 321 | − -1, 0xCF, 0x00, 0x83, 0x30, | |
| 322 | − -1, 0xED, 0x64, 0x03, 0x12, 0x81, | |
| 323 | − -1, 0xE8, 0x85, 0x01, 0x79, | |
| 324 | − -1, 0xCB, 0x39, 0x2c, 0x00, 0x34, 0x02, | |
| 325 | − -1, 0xF7, 0x20, | |
| 326 | − -1, 0xEA, 0x00, 0x00, | |
| 327 | − -1, 0xC0, 0x26, | |
| 328 | − -1, 0xC1, 0x11, | |
| 329 | − -1, 0xC5, 0x35, 0x3E, | |
| 330 | − -1, 0xC7, 0xBE, | |
| 331 | − -1, 0xB1, 0x00, 0x1B, | |
| 332 | − -1, 0xB6, 0x0a, 0x82, 0x27, 0x00, | |
| 333 | − -1, 0xB7, 0x07, | |
| 334 | − -1, 0x3A, 0x55, | |
| 335 | − -1, 0x36, 0x48, | |
| 336 | − -1, 0x11, | |
| 337 | − -2, 120, | |
| 338 | − -1, 0x29, | |
| 339 | − -2, 20, | |
| 340 | − -3 | |
| 341 | −}; | |
| 342 | − | |
| 343 | −static const s16 ssd1351_init[] = { | |
| 344 | − -1, 0xfd, 0x12, | |
| 345 | − -1, 0xfd, 0xb1, | |
| 346 | − -1, 0xae, | |
| 347 | − -1, 0xb3, 0xf1, | |
| 348 | − -1, 0xca, 0x7f, | |
| 349 | − -1, 0xa0, 0x74, | |
| 350 | − -1, 0x15, 0x00, 0x7f, | |
| 351 | − -1, 0x75, 0x00, 0x7f, | |
| 352 | − -1, 0xa1, 0x00, | |
| 353 | − -1, 0xa2, 0x00, | |
| 354 | − -1, 0xb5, 0x00, | |
| 355 | − -1, 0xab, 0x01, | |
| 356 | − -1, 0xb1, 0x32, | |
| 357 | − -1, 0xb4, 0xa0, 0xb5, 0x55, | |
| 358 | − -1, 0xbb, 0x17, | |
| 359 | − -1, 0xbe, 0x05, | |
| 360 | − -1, 0xc1, 0xc8, 0x80, 0xc8, | |
| 361 | − -1, 0xc7, 0x0f, | |
| 362 | − -1, 0xb6, 0x01, | |
| 363 | − -1, 0xa6, | |
| 364 | − -1, 0xaf, | |
| 365 | − -3 | |
| 366 | −}; | |
| 367 | − | |
| 368 | −/** | |
| 369 | − * struct flexfb_lcd_controller - Describes the LCD controller properties | |
| 370 | − * @name: Model name of the chip | |
| 371 | − * @width: Width of display in pixels | |
| 372 | − * @height: Height of display in pixels | |
| 373 | − * @setaddrwin: Which set_addr_win() implementation to use | |
| 374 | − * @regwidth: LCD Controller Register width in bits | |
| 375 | − * @init_seq: LCD initialization sequence | |
| 376 | − * @init_seq_sz: Size of LCD initialization sequence | |
| 377 | − */ | |
| 378 | −struct flexfb_lcd_controller { | |
| 379 | − const char *name; | |
| 380 | − unsigned int width; | |
| 381 | − unsigned int height; | |
| 382 | − unsigned int setaddrwin; | |
| 383 | − unsigned int regwidth; | |
| 384 | − const s16 *init_seq; | |
| 385 | − int init_seq_sz; | |
| 386 | −}; | |
| 387 | − | |
| 388 | −static const struct flexfb_lcd_controller flexfb_chip_table[] = { | |
| 389 | − { | |
| 390 | − .name = "st7735r", | |
| 391 | − .width = 120, | |
| 392 | − .height = 160, | |
| 393 | − .init_seq = st7735r_init, | |
| 394 | − .init_seq_sz = ARRAY_SIZE(st7735r_init), | |
| 395 | − }, | |
| 396 | − { | |
| 397 | − .name = "hx8340bn", | |
| 398 | − .width = 176, | |
| 399 | − .height = 220, | |
| 400 | − .init_seq = hx8340bn_init, | |
| 401 | − .init_seq_sz = ARRAY_SIZE(hx8340bn_init), | |
| 402 | − }, | |
| 403 | − { | |
| 404 | − .name = "ili9225", | |
| 405 | − .width = 176, | |
| 406 | − .height = 220, | |
| 407 | − .regwidth = 16, | |
| 408 | − .init_seq = ili9225_init, | |
| 409 | − .init_seq_sz = ARRAY_SIZE(ili9225_init), | |
| 410 | − }, | |
| 411 | − { | |
| 412 | − .name = "ili9320", | |
| 413 | − .width = 240, | |
| 414 | − .height = 320, | |
| 415 | − .setaddrwin = 1, | |
| 416 | − .regwidth = 16, | |
| 417 | − .init_seq = ili9320_init, | |
| 418 | − .init_seq_sz = ARRAY_SIZE(ili9320_init), | |
| 419 | − }, | |
| 420 | − { | |
| 421 | − .name = "ili9325", | |
| 422 | − .width = 240, | |
| 423 | − .height = 320, | |
| 424 | − .setaddrwin = 1, | |
| 425 | − .regwidth = 16, | |
| 426 | − .init_seq = ili9325_init, | |
| 427 | − .init_seq_sz = ARRAY_SIZE(ili9325_init), | |
| 428 | − }, | |
| 429 | − { | |
| 430 | − .name = "ili9341", | |
| 431 | − .width = 240, | |
| 432 | − .height = 320, | |
| 433 | − .init_seq = ili9341_init, | |
| 434 | − .init_seq_sz = ARRAY_SIZE(ili9341_init), | |
| 435 | − }, | |
| 436 | − { | |
| 437 | − .name = "ssd1289", | |
| 438 | − .width = 240, | |
| 439 | − .height = 320, | |
| 440 | − .setaddrwin = 2, | |
| 441 | − .regwidth = 16, | |
| 442 | − .init_seq = ssd1289_init, | |
| 443 | − .init_seq_sz = ARRAY_SIZE(ssd1289_init), | |
| 444 | − }, | |
| 445 | − { | |
| 446 | − .name = "ssd1351", | |
| 447 | − .width = 128, | |
| 448 | − .height = 128, | |
| 449 | − .setaddrwin = 3, | |
| 450 | − .init_seq = ssd1351_init, | |
| 451 | − .init_seq_sz = ARRAY_SIZE(ssd1351_init), | |
| 452 | − }, | |
| 453 | −}; | |
| 454 | − | |
| 455 | −/* ili9320, ili9325 */ | |
| 456 | −static void flexfb_set_addr_win_1(struct fbtft_par *par, | |
| 457 | − int xs, int ys, int xe, int ye) | |
| 458 | −{ | |
| 459 | − switch (par->info->var.rotate) { | |
| 460 | − /* R20h = Horizontal GRAM Start Address */ | |
| 461 | − /* R21h = Vertical GRAM Start Address */ | |
| 462 | − case 0: | |
| 463 | − write_reg(par, 0x0020, xs); | |
| 464 | − write_reg(par, 0x0021, ys); | |
| 465 | − break; | |
| 466 | − case 180: | |
| 467 | − write_reg(par, 0x0020, width - 1 - xs); | |
| 468 | − write_reg(par, 0x0021, height - 1 - ys); | |
| 469 | − break; | |
| 470 | − case 270: | |
| 471 | − write_reg(par, 0x0020, width - 1 - ys); | |
| 472 | − write_reg(par, 0x0021, xs); | |
| 473 | − break; | |
| 474 | − case 90: | |
| 475 | − write_reg(par, 0x0020, ys); | |
| 476 | − write_reg(par, 0x0021, height - 1 - xs); | |
| 477 | − break; | |
| 478 | − } | |
| 479 | − write_reg(par, 0x0022); /* Write Data to GRAM */ | |
| 480 | −} | |
| 481 | − | |
| 482 | −/* ssd1289 */ | |
| 483 | −static void flexfb_set_addr_win_2(struct fbtft_par *par, | |
| 484 | − int xs, int ys, int xe, int ye) | |
| 485 | −{ | |
| 486 | − switch (par->info->var.rotate) { | |
| 487 | − /* R4Eh - Set GDDRAM X address counter */ | |
| 488 | − /* R4Fh - Set GDDRAM Y address counter */ | |
| 489 | − case 0: | |
| 490 | − write_reg(par, 0x4e, xs); | |
| 491 | − write_reg(par, 0x4f, ys); | |
| 492 | − break; | |
| 493 | − case 180: | |
| 494 | − write_reg(par, 0x4e, par->info->var.xres - 1 - xs); | |
| 495 | − write_reg(par, 0x4f, par->info->var.yres - 1 - ys); | |
| 496 | − break; | |
| 497 | − case 270: | |
| 498 | − write_reg(par, 0x4e, par->info->var.yres - 1 - ys); | |
| 499 | − write_reg(par, 0x4f, xs); | |
| 500 | − break; | |
| 501 | − case 90: | |
| 502 | − write_reg(par, 0x4e, ys); | |
| 503 | − write_reg(par, 0x4f, par->info->var.xres - 1 - xs); | |
| 504 | − break; | |
| 505 | − } | |
| 506 | − | |
| 507 | − /* R22h - RAM data write */ | |
| 508 | − write_reg(par, 0x22, 0); | |
| 509 | −} | |
| 510 | − | |
| 511 | −/* ssd1351 */ | |
| 512 | −static void set_addr_win_3(struct fbtft_par *par, | |
| 513 | − int xs, int ys, int xe, int ye) | |
| 514 | −{ | |
| 515 | − write_reg(par, 0x15, xs, xe); | |
| 516 | − write_reg(par, 0x75, ys, ye); | |
| 517 | − write_reg(par, 0x5C); | |
| 518 | −} | |
| 519 | − | |
| 520 | −static int flexfb_verify_gpios_dc(struct fbtft_par *par) | |
| 521 | −{ | |
| 522 | − fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); | |
| 523 | − | |
| 524 | − if (!par->gpio.dc) { | |
| 525 | − dev_err(par->info->device, | |
| 526 | − "Missing info about 'dc' gpio. Aborting.\n"); | |
| 527 | − return -EINVAL; | |
| 528 | − } | |
| 529 | − | |
| 530 | − return 0; | |
| 531 | −} | |
| 532 | − | |
| 533 | −static int flexfb_verify_gpios_db(struct fbtft_par *par) | |
| 534 | −{ | |
| 535 | − int i; | |
| 536 | − int num_db = buswidth; | |
| 537 | − | |
| 538 | − fbtft_par_dbg(DEBUG_VERIFY_GPIOS, par, "%s()\n", __func__); | |
| 539 | − | |
| 540 | − if (!par->gpio.dc) { | |
| 541 | − dev_err(par->info->device, "Missing info about 'dc' gpio. Aborting.\n"); | |
| 542 | − return -EINVAL; | |
| 543 | − } | |
| 544 | − if (!par->gpio.wr) { | |
| 545 | − dev_err(par->info->device, "Missing info about 'wr' gpio. Aborting.\n"); | |
| 546 | − return -EINVAL; | |
| 547 | − } | |
| 548 | − if (latched && !par->gpio.latch) { | |
| 549 | − dev_err(par->info->device, "Missing info about 'latch' gpio. Aborting.\n"); | |
| 550 | − return -EINVAL; | |
| 551 | − } | |
| 552 | − if (latched) | |
| 553 | − num_db = buswidth / 2; | |
| 554 | − for (i = 0; i < num_db; i++) { | |
| 555 | − if (!par->gpio.db[i]) { | |
| 556 | − dev_err(par->info->device, | |
| 557 | − "Missing info about 'db%02d' gpio. Aborting.\n", | |
| 558 | − i); | |
| 559 | − return -EINVAL; | |
| 560 | − } | |
| 561 | − } | |
| 562 | − | |
| 563 | − return 0; | |
| 564 | −} | |
| 565 | − | |
| 566 | −static void flexfb_chip_load_param(const struct flexfb_lcd_controller *chip) | |
| 567 | −{ | |
| 568 | − if (!width) | |
| 569 | − width = chip->width; | |
| 570 | − if (!height) | |
| 571 | − height = chip->height; | |
| 572 | − setaddrwin = chip->setaddrwin; | |
| 573 | − if (chip->regwidth) | |
| 574 | − regwidth = chip->regwidth; | |
| 575 | − if (!init_num) { | |
| 576 | − initp = chip->init_seq; | |
| 577 | − initp_num = chip->init_seq_sz; | |
| 578 | − } | |
| 579 | −} | |
| 580 | − | |
| 581 | −static struct fbtft_display flex_display = { }; | |
| 582 | − | |
| 583 | −static int flexfb_chip_init(const struct device *dev) | |
| 584 | −{ | |
| 585 | − int i; | |
| 586 | − | |
| 587 | − for (i = 0; i < ARRAY_SIZE(flexfb_chip_table); i++) | |
| 588 | − if (!strcmp(chip, flexfb_chip_table[i].name)) { | |
| 589 | − flexfb_chip_load_param(&flexfb_chip_table[i]); | |
| 590 | − return 0; | |
| 591 | − } | |
| 592 | − | |
| 593 | − dev_err(dev, "chip=%s is not supported\n", chip); | |
| 594 | − | |
| 595 | − return -EINVAL; | |
| 596 | −} | |
| 597 | − | |
| 598 | −static int flexfb_probe_common(struct spi_device *sdev, | |
| 599 | − struct platform_device *pdev) | |
| 600 | −{ | |
| 601 | − struct device *dev; | |
| 602 | − struct fb_info *info; | |
| 603 | − struct fbtft_par *par; | |
| 604 | − int ret; | |
| 605 | − | |
| 606 | − initp = init; | |
| 607 | − initp_num = init_num; | |
| 608 | − | |
| 609 | − if (sdev) | |
| 610 | − dev = &sdev->dev; | |
| 611 | − else | |
| 612 | − dev = &pdev->dev; | |
| 613 | − | |
| 614 | − fbtft_init_dbg(dev, "%s(%s)\n", __func__, | |
| 615 | − sdev ? "'SPI device'" : "'Platform device'"); | |
| 616 | − | |
| 617 | − if (chip) { | |
| 618 | − ret = flexfb_chip_init(dev); | |
| 619 | − if (ret) | |
| 620 | − return ret; | |
| 621 | − } | |
| 622 | − | |
| 623 | − if (width == 0 || height == 0) { | |
| 624 | − dev_err(dev, "argument(s) missing: width and height has to be set.\n"); | |
| 625 | − return -EINVAL; | |
| 626 | − } | |
| 627 | − flex_display.width = width; | |
| 628 | − flex_display.height = height; | |
| 629 | − fbtft_init_dbg(dev, "Display resolution: %dx%d\n", width, height); | |
| 630 | − fbtft_init_dbg(dev, "chip = %s\n", chip ? chip : "not set"); | |
| 631 | − fbtft_init_dbg(dev, "setaddrwin = %d\n", setaddrwin); | |
| 632 | − fbtft_init_dbg(dev, "regwidth = %d\n", regwidth); | |
| 633 | − fbtft_init_dbg(dev, "buswidth = %d\n", buswidth); | |
| 634 | − | |
| 635 | − info = fbtft_framebuffer_alloc(&flex_display, dev, dev->platform_data); | |
| 636 | − if (!info) | |
| 637 | − return -ENOMEM; | |
| 638 | − | |
| 639 | − par = info->par; | |
| 640 | − if (sdev) | |
| 641 | − par->spi = sdev; | |
| 642 | − else | |
| 643 | − par->pdev = pdev; | |
| 644 | − if (!par->init_sequence) | |
| 645 | − par->init_sequence = initp; | |
| 646 | − par->fbtftops.init_display = fbtft_init_display; | |
| 647 | − | |
| 648 | − /* registerwrite functions */ | |
| 649 | − switch (regwidth) { | |
| 650 | − case 8: | |
| 651 | − par->fbtftops.write_register = fbtft_write_reg8_bus8; | |
| 652 | − break; | |
| 653 | − case 16: | |
| 654 | − par->fbtftops.write_register = fbtft_write_reg16_bus8; | |
| 655 | − break; | |
| 656 | − default: | |
| 657 | − dev_err(dev, | |
| 658 | − "argument 'regwidth': %d is not supported.\n", | |
| 659 | − regwidth); | |
| 660 | − return -EINVAL; | |
| 661 | − } | |
| 662 | − | |
| 663 | − /* bus functions */ | |
| 664 | − if (sdev) { | |
| 665 | − par->fbtftops.write = fbtft_write_spi; | |
| 666 | − switch (buswidth) { | |
| 667 | − case 8: | |
| 668 | − par->fbtftops.write_vmem = fbtft_write_vmem16_bus8; | |
| 669 | − if (!par->startbyte) | |
| 670 | − par->fbtftops.verify_gpios = flexfb_verify_gpios_dc; | |
| 671 | − break; | |
| 672 | − case 9: | |
| 673 | − if (regwidth == 16) { | |
| 674 | − dev_err(dev, "argument 'regwidth': %d is not supported with buswidth=%d and SPI.\n", | |
| 675 | − regwidth, buswidth); | |
| 676 | − return -EINVAL; | |
| 677 | − } | |
| 678 | − par->fbtftops.write_register = fbtft_write_reg8_bus9; | |
| 679 | − par->fbtftops.write_vmem = fbtft_write_vmem16_bus9; | |
| 680 | − if (par->spi->master->bits_per_word_mask | |
| 681 | − & SPI_BPW_MASK(9)) { | |
| 682 | − par->spi->bits_per_word = 9; | |
| 683 | − break; | |
| 684 | − } | |
| 685 | − | |
| 686 | − dev_warn(dev, | |
| 687 | − "9-bit SPI not available, emulating using 8-bit.\n"); | |
| 688 | − /* allocate buffer with room for dc bits */ | |
| 689 | − par->extra = devm_kzalloc(par->info->device, | |
| 690 | − par->txbuf.len | |
| 691 | − + (par->txbuf.len / 8) + 8, | |
| 692 | − GFP_KERNEL); | |
| 693 | − if (!par->extra) { | |
| 694 | − ret = -ENOMEM; | |
| 695 | − goto out_release; | |
| 696 | − } | |
| 697 | − par->fbtftops.write = fbtft_write_spi_emulate_9; | |
| 698 | − | |
| 699 | − break; | |
| 700 | − default: | |
| 701 | − dev_err(dev, | |
| 702 | − "argument 'buswidth': %d is not supported with SPI.\n", | |
| 703 | − buswidth); | |
| 704 | − return -EINVAL; | |
| 705 | − } | |
| 706 | − } else { | |
| 707 | − par->fbtftops.verify_gpios = flexfb_verify_gpios_db; | |
| 708 | − switch (buswidth) { | |
| 709 | − case 8: | |
| 710 | − par->fbtftops.write = fbtft_write_gpio8_wr; | |
| 711 | − par->fbtftops.write_vmem = fbtft_write_vmem16_bus8; | |
| 712 | − break; | |
| 713 | − case 16: | |
| 714 | − par->fbtftops.write_register = fbtft_write_reg16_bus16; | |
| 715 | − if (latched) | |
| 716 | − par->fbtftops.write = fbtft_write_gpio16_wr_latched; | |
| 717 | − else | |
| 718 | − par->fbtftops.write = fbtft_write_gpio16_wr; | |
| 719 | − par->fbtftops.write_vmem = fbtft_write_vmem16_bus16; | |
| 720 | − break; | |
| 721 | − default: | |
| 722 | − dev_err(dev, | |
| 723 | − "argument 'buswidth': %d is not supported with parallel.\n", | |
| 724 | − buswidth); | |
| 725 | − return -EINVAL; | |
| 726 | − } | |
| 727 | − } | |
| 728 | − | |
| 729 | − /* set_addr_win function */ | |
| 730 | − switch (setaddrwin) { | |
| 731 | − case 0: | |
| 732 | − /* use default */ | |
| 733 | − break; | |
| 734 | − case 1: | |
| 735 | − par->fbtftops.set_addr_win = flexfb_set_addr_win_1; | |
| 736 | − break; | |
| 737 | − case 2: | |
| 738 | − par->fbtftops.set_addr_win = flexfb_set_addr_win_2; | |
| 739 | − break; | |
| 740 | − case 3: | |
| 741 | − par->fbtftops.set_addr_win = set_addr_win_3; | |
| 742 | − break; | |
| 743 | − default: | |
| 744 | − dev_err(dev, "argument 'setaddrwin': unknown value %d.\n", | |
| 745 | − setaddrwin); | |
| 746 | − return -EINVAL; | |
| 747 | − } | |
| 748 | − | |
| 749 | − if (!nobacklight) | |
| 750 | − par->fbtftops.register_backlight = fbtft_register_backlight; | |
| 751 | − | |
| 752 | − ret = fbtft_register_framebuffer(info); | |
| 753 | − if (ret < 0) | |
| 754 | − goto out_release; | |
| 755 | − | |
| 756 | − return 0; | |
| 757 | − | |
| 758 | −out_release: | |
| 759 | − fbtft_framebuffer_release(info); | |
| 760 | − | |
| 761 | − return ret; | |
| 762 | −} | |
| 763 | − | |
| 764 | −static int flexfb_remove_common(struct device *dev, struct fb_info *info) | |
| 765 | −{ | |
| 766 | − struct fbtft_par *par; | |
| 767 | − | |
| 768 | − if (!info) | |
| 769 | − return -EINVAL; | |
| 770 | − par = info->par; | |
| 771 | − if (par) | |
| 772 | − fbtft_par_dbg(DEBUG_DRIVER_INIT_FUNCTIONS, par, "%s()\n", | |
| 773 | − __func__); | |
| 774 | − fbtft_unregister_framebuffer(info); | |
| 775 | − fbtft_framebuffer_release(info); | |
| 776 | − | |
| 777 | − return 0; | |
| 778 | −} | |
| 779 | − | |
| 780 | −static int flexfb_probe_spi(struct spi_device *spi) | |
| 781 | −{ | |
| 782 | − return flexfb_probe_common(spi, NULL); | |
| 783 | −} | |
| 784 | − | |
| 785 | −static int flexfb_remove_spi(struct spi_device *spi) | |
| 786 | −{ | |
| 787 | − struct fb_info *info = spi_get_drvdata(spi); | |
| 788 | − | |
| 789 | − return flexfb_remove_common(&spi->dev, info); | |
| 790 | −} | |
| 791 | − | |
| 792 | −static int flexfb_probe_pdev(struct platform_device *pdev) | |
| 793 | −{ | |
| 794 | − return flexfb_probe_common(NULL, pdev); | |
| 795 | −} | |
| 796 | − | |
| 797 | −static int flexfb_remove_pdev(struct platform_device *pdev) | |
| 798 | −{ | |
| 799 | − struct fb_info *info = platform_get_drvdata(pdev); | |
| 800 | − | |
| 801 | − return flexfb_remove_common(&pdev->dev, info); | |
| 802 | −} | |
| 803 | − | |
| 804 | −static struct spi_driver flexfb_spi_driver = { | |
| 805 | − .driver = { | |
| 806 | − .name = DRVNAME, | |
| 807 | − }, | |
| 808 | − .probe = flexfb_probe_spi, | |
| 809 | − .remove = flexfb_remove_spi, | |
| 810 | −}; | |
| 811 | − | |
| 812 | −static const struct platform_device_id flexfb_platform_ids[] = { | |
| 813 | − { "flexpfb", 0 }, | |
| 814 | − { }, | |
| 815 | −}; | |
| 816 | −MODULE_DEVICE_TABLE(platform, flexfb_platform_ids); | |
| 817 | − | |
| 818 | −static struct platform_driver flexfb_platform_driver = { | |
| 819 | − .driver = { | |
| 820 | − .name = DRVNAME, | |
| 821 | − }, | |
| 822 | − .id_table = flexfb_platform_ids, | |
| 823 | − .probe = flexfb_probe_pdev, | |
| 824 | − .remove = flexfb_remove_pdev, | |
| 825 | −}; | |
| 826 | − | |
| 827 | −static int __init flexfb_init(void) | |
| 828 | −{ | |
| 829 | − int ret, ret2; | |
| 830 | − | |
| 831 | − ret = spi_register_driver(&flexfb_spi_driver); | |
| 832 | − ret2 = platform_driver_register(&flexfb_platform_driver); | |
| 833 | − if (ret < 0) | |
| 834 | − return ret; | |
| 835 | − return ret2; | |
| 836 | −} | |
| 837 | − | |
| 838 | −static void __exit flexfb_exit(void) | |
| 839 | −{ | |
| 840 | − spi_unregister_driver(&flexfb_spi_driver); | |
| 841 | − platform_driver_unregister(&flexfb_platform_driver); | |
| 842 | −} | |
| 843 | − | |
| 844 | −/* ------------------------------------------------------------------------- */ | |
| 845 | − | |
| 846 | −module_init(flexfb_init); | |
| 847 | −module_exit(flexfb_exit); | |
| 848 | − | |
| 849 | −MODULE_DESCRIPTION("Generic FB driver for TFT LCD displays"); | |
| 850 | −MODULE_AUTHOR("Noralf Tronnes"); | |
| 851 | −MODULE_LICENSE("GPL"); | |
| @@ -261,11 +261,11 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) · 260 unmodified lines | ||
| 261 | 261 | /* Build the PKO buffer pointer */ |
| 262 | 262 | hw_buffer.u64 = 0; |
| 263 | 263 | if (skb_shinfo(skb)->nr_frags == 0) { |
| 264 | − hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)skb->data); | |
| 264 | + hw_buffer.s.addr = XKPHYS_TO_PHYS((uintptr_t)skb->data); | |
| 265 | 265 | hw_buffer.s.pool = 0; |
| 266 | 266 | hw_buffer.s.size = skb->len; |
| 267 | 267 | } else { |
| 268 | − hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)skb->data); | |
| 268 | + hw_buffer.s.addr = XKPHYS_TO_PHYS((uintptr_t)skb->data); | |
| 269 | 269 | hw_buffer.s.pool = 0; |
| 270 | 270 | hw_buffer.s.size = skb_headlen(skb); |
| 271 | 271 | CVM_OCT_SKB_CB(skb)[0] = hw_buffer.u64; |
| @@ -273,11 +273,12 @@ int cvm_oct_xmit(struct sk_buff *skb, struct net_device *dev) · 1 unmodified line | ||
| 273 | 273 | skb_frag_t *fs = skb_shinfo(skb)->frags + i; |
| 274 | 274 | |
| 275 | 275 | hw_buffer.s.addr = |
| 276 | − XKPHYS_TO_PHYS((u64)skb_frag_address(fs)); | |
| 276 | + XKPHYS_TO_PHYS((uintptr_t)skb_frag_address(fs)); | |
| 277 | 277 | hw_buffer.s.size = skb_frag_size(fs); |
| 278 | 278 | CVM_OCT_SKB_CB(skb)[i + 1] = hw_buffer.u64; |
| 279 | 279 | } |
| 280 | − hw_buffer.s.addr = XKPHYS_TO_PHYS((u64)CVM_OCT_SKB_CB(skb)); | |
| 280 | + hw_buffer.s.addr = | |
| 281 | + XKPHYS_TO_PHYS((uintptr_t)CVM_OCT_SKB_CB(skb)); | |
| 281 | 282 | hw_buffer.s.size = skb_shinfo(skb)->nr_frags + 1; |
| 282 | 283 | pko_command.s.segs = skb_shinfo(skb)->nr_frags + 1; |
| 283 | 284 | pko_command.s.gather = 1; |
| @@ -1202,7 +1202,7 @@ static inline int cvmx_wqe_get_grp(cvmx_wqe_t *work) · 1201 unmodified lines | ||
| 1202 | 1202 | |
| 1203 | 1203 | static inline void *cvmx_phys_to_ptr(uint64_t physical_address) |
| 1204 | 1204 | { |
| 1205 | − return (void *)(physical_address); | |
| 1205 | + return (void *)(uintptr_t)(physical_address); | |
| 1206 | 1206 | } |
| 1207 | 1207 | |
| 1208 | 1208 | static inline uint64_t cvmx_ptr_to_phys(void *ptr) |
| @@ -409,7 +409,7 @@ static int odm_ARFBRefresh_8188E(struct odm_dm_struct *dm_odm, struct odm_ra_inf · 408 unmodified lines | ||
| 409 | 409 | pRaInfo->PTModeSS = 3; |
| 410 | 410 | else if (pRaInfo->HighestRate > 0x0b) |
| 411 | 411 | pRaInfo->PTModeSS = 2; |
| 412 | − else if (pRaInfo->HighestRate > 0x0b) | |
| 412 | + else if (pRaInfo->HighestRate > 0x03) | |
| 413 | 413 | pRaInfo->PTModeSS = 1; |
| 414 | 414 | else |
| 415 | 415 | pRaInfo->PTModeSS = 0; |
| @@ -348,8 +348,10 @@ static struct adapter *rtw_usb_if1_init(struct dvobj_priv *dvobj, · 347 unmodified lines | ||
| 348 | 348 | } |
| 349 | 349 | |
| 350 | 350 | padapter->HalData = kzalloc(sizeof(struct hal_data_8188e), GFP_KERNEL); |
| 351 | − if (!padapter->HalData) | |
| 352 | − DBG_88E("cant not alloc memory for HAL DATA\n"); | |
| 351 | + if (!padapter->HalData) { | |
| 352 | + DBG_88E("Failed to allocate memory for HAL data\n"); | |
| 353 | + goto free_adapter; | |
| 354 | + } | |
| 353 | 355 | |
| 354 | 356 | /* step read_chip_version */ |
| 355 | 357 | rtw_hal_read_chip_version(padapter); |
| @@ -0,0 +1,369 @@ | ||
| 1 | +What: /sys/accessibility/speakup/attrib_bleep | |
| 2 | +KernelVersion: 2.6 | |
| 3 | +Contact: speakup@linux-speakup.org | |
| 4 | +Description: Beeps the PC speaker when there is an attribute change such as | |
| 5 | + foreground or background color when using speakup review | |
| 6 | + commands. One = on, zero = off. | |
| 7 | + | |
| 8 | +What: /sys/accessibility/speakup/bell_pos | |
| 9 | +KernelVersion: 2.6 | |
| 10 | +Contact: speakup@linux-speakup.org | |
| 11 | +Description: This works much like a typewriter bell. If for example 72 is | |
| 12 | + echoed to bell_pos, it will beep the PC speaker when typing on | |
| 13 | + a line past character 72. | |
| 14 | + | |
| 15 | +What: /sys/accessibility/speakup/bleeps | |
| 16 | +KernelVersion: 2.6 | |
| 17 | +Contact: speakup@linux-speakup.org | |
| 18 | +Description: This controls whether one hears beeps through the PC speaker | |
| 19 | + when using speakup's review commands. | |
| 20 | + TODO: what values does it accept? | |
| 21 | + | |
| 22 | +What: /sys/accessibility/speakup/bleep_time | |
| 23 | +KernelVersion: 2.6 | |
| 24 | +Contact: speakup@linux-speakup.org | |
| 25 | +Description: This controls the duration of the PC speaker beeps speakup | |
| 26 | + produces. | |
| 27 | + TODO: What are the units? Jiffies? | |
| 28 | + | |
| 29 | +What: /sys/accessibility/speakup/cursor_time | |
| 30 | +KernelVersion: 2.6 | |
| 31 | +Contact: speakup@linux-speakup.org | |
| 32 | +Description: This controls cursor delay when using arrow keys. When a | |
| 33 | + connection is very slow, with the default setting, when moving | |
| 34 | + with the arrows, or backspacing etc. speakup says the incorrect | |
| 35 | + characters. Set this to a higher value to adjust for the delay | |
| 36 | + and better synchronisation between cursor position and speech. | |
| 37 | + | |
| 38 | +What: /sys/accessibility/speakup/delimiters | |
| 39 | +KernelVersion: 2.6 | |
| 40 | +Contact: speakup@linux-speakup.org | |
| 41 | +Description: Delimit a word from speakup. | |
| 42 | + TODO: add more info | |
| 43 | + | |
| 44 | +What: /sys/accessibility/speakup/ex_num | |
| 45 | +KernelVersion: 2.6 | |
| 46 | +Contact: speakup@linux-speakup.org | |
| 47 | +Description: TODO: | |
| 48 | + | |
| 49 | +What: /sys/accessibility/speakup/key_echo | |
| 50 | +KernelVersion: 2.6 | |
| 51 | +Contact: speakup@linux-speakup.org | |
| 52 | +Description: Controls if speakup speaks keys when they are typed. One = on, | |
| 53 | + zero = off or don't echo keys. | |
| 54 | + | |
| 55 | +What: /sys/accessibility/speakup/keymap | |
| 56 | +KernelVersion: 2.6 | |
| 57 | +Contact: speakup@linux-speakup.org | |
| 58 | +Description: Speakup keymap remaps keys to Speakup functions. | |
| 59 | + It uses a binary | |
| 60 | + format. A special program called genmap is needed to compile a | |
| 61 | + textual keymap into the binary format which is then loaded into | |
| 62 | + /sys/accessibility/speakup/keymap. | |
| 63 | + | |
| 64 | +What: /sys/accessibility/speakup/no_interrupt | |
| 65 | +KernelVersion: 2.6 | |
| 66 | +Contact: speakup@linux-speakup.org | |
| 67 | +Description: Controls if typing interrupts output from speakup. With | |
| 68 | + no_interrupt set to zero, typing on the keyboard will interrupt | |
| 69 | + speakup if for example | |
| 70 | + the say screen command is used before the | |
| 71 | + entire screen is read. | |
| 72 | + With no_interrupt set to one, if the say | |
| 73 | + screen command is used, and one then types on the keyboard, | |
| 74 | + speakup will continue to say the whole screen regardless until | |
| 75 | + it finishes. | |
| 76 | + | |
| 77 | +What: /sys/accessibility/speakup/punc_all | |
| 78 | +KernelVersion: 2.6 | |
| 79 | +Contact: speakup@linux-speakup.org | |
| 80 | +Description: This is a list of all the punctuation speakup should speak when | |
| 81 | + punc_level is set to four. | |
| 82 | + | |
| 83 | +What: /sys/accessibility/speakup/punc_level | |
| 84 | +KernelVersion: 2.6 | |
| 85 | +Contact: speakup@linux-speakup.org | |
| 86 | +Description: Controls the level of punctuation spoken as the screen is | |
| 87 | + displayed, not reviewed. Levels range from zero no punctuation, | |
| 88 | + to four, all punctuation. One corresponds to punc_some, two | |
| 89 | + corresponds to punc_most, and three as well as four both | |
| 90 | + correspond to punc_all. Some hardware synthesizers may have | |
| 91 | + different levels each corresponding to three and four for | |
| 92 | + punc_level. Also note that if punc_level is set to zero, and | |
| 93 | + key_echo is set to one, typed punctuation is still spoken as it | |
| 94 | + is typed. | |
| 95 | + | |
| 96 | +What: /sys/accessibility/speakup/punc_most | |
| 97 | +KernelVersion: 2.6 | |
| 98 | +Contact: speakup@linux-speakup.org | |
| 99 | +Description: This is a list of all the punctuation speakup should speak when | |
| 100 | + punc_level is set to two. | |
| 101 | + | |
| 102 | +What: /sys/accessibility/speakup/punc_some | |
| 103 | +KernelVersion: 2.6 | |
| 104 | +Contact: speakup@linux-speakup.org | |
| 105 | +Description: This is a list of all the punctuation speakup should speak when | |
| 106 | + punc_level is set to one. | |
| 107 | + | |
| 108 | +What: /sys/accessibility/speakup/reading_punc | |
| 109 | +KernelVersion: 2.6 | |
| 110 | +Contact: speakup@linux-speakup.org | |
| 111 | +Description: Almost the same as punc_level, the differences being that | |
| 112 | + reading_punc controls the level of punctuation when reviewing | |
| 113 | + the screen with speakup's screen review commands. The other | |
| 114 | + difference is that reading_punc set to three speaks punc_all, | |
| 115 | + and reading_punc set to four speaks all punctuation, including | |
| 116 | + spaces. | |
| 117 | + | |
| 118 | +What: /sys/accessibility/speakup/repeats | |
| 119 | +KernelVersion: 2.6 | |
| 120 | +Contact: speakup@linux-speakup.org | |
| 121 | +Description: A list of characters speakup repeats. Normally, when there are | |
| 122 | + more than three characters in a row, speakup | |
| 123 | + just reads three of | |
| 124 | + those characters. For example, "......" would be read as dot, | |
| 125 | + dot, dot. If a . is added to the list of characters in repeats, | |
| 126 | + "......" would be read as dot, dot, dot, times six. | |
| 127 | + | |
| 128 | +What: /sys/accessibility/speakup/say_control | |
| 129 | +KernelVersion: 2.6 | |
| 130 | +Contact: speakup@linux-speakup.org | |
| 131 | +Description: If set to one, speakup speaks shift, alt and control when those | |
| 132 | + keys are pressed. If say_control is set to zero, shift, ctrl, | |
| 133 | + and alt are not spoken when they are pressed. | |
| 134 | + | |
| 135 | +What: /sys/accessibility/speakup/say_word_ctl | |
| 136 | +KernelVersion: 2.6 | |
| 137 | +Contact: speakup@linux-speakup.org | |
| 138 | +Description: TODO: | |
| 139 | + | |
| 140 | +What: /sys/accessibility/speakup/silent | |
| 141 | +KernelVersion: 2.6 | |
| 142 | +Contact: speakup@linux-speakup.org | |
| 143 | +Description: TODO: | |
| 144 | + | |
| 145 | +What: /sys/accessibility/speakup/spell_delay | |
| 146 | +KernelVersion: 2.6 | |
| 147 | +Contact: speakup@linux-speakup.org | |
| 148 | +Description: This controls how fast a word is spelled | |
| 149 | + when speakup's say word | |
| 150 | + review command is pressed twice quickly to speak the current | |
| 151 | + word being reviewed. Zero just speaks the letters one after | |
| 152 | + another, while values one through four | |
| 153 | + seem to introduce more of | |
| 154 | + a pause between the spelling of each letter by speakup. | |
| 155 | + | |
| 156 | +What: /sys/accessibility/speakup/synth | |
| 157 | +KernelVersion: 2.6 | |
| 158 | +Contact: speakup@linux-speakup.org | |
| 159 | +Description: Gets or sets the synthesizer driver currently in use. Reading | |
| 160 | + synth returns the synthesizer driver currently in use. Writing | |
| 161 | + synth switches to the given synthesizer driver, provided it is | |
| 162 | + either built into the kernel, or already loaded as a module. | |
| 163 | + | |
| 164 | +What: /sys/accessibility/speakup/synth_direct | |
| 165 | +KernelVersion: 2.6 | |
| 166 | +Contact: speakup@linux-speakup.org | |
| 167 | +Description: Sends whatever is written to synth_direct | |
| 168 | + directly to the speech synthesizer in use, bypassing speakup. | |
| 169 | + This could be used to make the synthesizer speak | |
| 170 | + a string, or to | |
| 171 | + send control sequences to the synthesizer to change how the | |
| 172 | + synthesizer behaves. | |
| 173 | + | |
| 174 | +What: /sys/accessibility/speakup/version | |
| 175 | +KernelVersion: 2.6 | |
| 176 | +Contact: speakup@linux-speakup.org | |
| 177 | +Description: Reading version returns the version of speakup, and the version | |
| 178 | + of the synthesizer driver currently in use. | |
| 179 | + | |
| 180 | +What: /sys/accessibility/speakup/i18n/announcements | |
| 181 | +KernelVersion: 2.6 | |
| 182 | +Contact: speakup@linux-speakup.org | |
| 183 | +Description: This file contains various general announcements, most of which | |
| 184 | + cannot be categorized. You will find messages such as "You | |
| 185 | + killed Speakup", "I'm alive", "leaving help", "parked", | |
| 186 | + "unparked", and others. You will also find the names of the | |
| 187 | + screen edges and cursor tracking modes here. | |
| 188 | + | |
| 189 | +What: /sys/accessibility/speakup/i18n/chartab | |
| 190 | +KernelVersion: 2.6 | |
| 191 | +Contact: speakup@linux-speakup.org | |
| 192 | +Description: TODO | |
| 193 | + | |
| 194 | +What: /sys/accessibility/speakup/i18n/ctl_keys | |
| 195 | +KernelVersion: 2.6 | |
| 196 | +Contact: speakup@linux-speakup.org | |
| 197 | +Description: Here, you will find names of control keys. These are used with | |
| 198 | + Speakup's say_control feature. | |
| 199 | + | |
| 200 | +What: /sys/accessibility/speakup/i18n/function_names | |
| 201 | +KernelVersion: 2.6 | |
| 202 | +Contact: speakup@linux-speakup.org | |
| 203 | +Description: Here, you will find a list of names for Speakup functions. | |
| 204 | + These are used by the help system. For example, suppose that | |
| 205 | + you have activated help mode, and you pressed | |
| 206 | + keypad 3. Speakup | |
| 207 | + says: "keypad 3 is character, say next." | |
| 208 | + The message "character, say next" names a Speakup function, and | |
| 209 | + it comes from this function_names file. | |
| 210 | + | |
| 211 | +What: /sys/accessibility/speakup/i18n/states | |
| 212 | +KernelVersion: 2.6 | |
| 213 | +Contact: speakup@linux-speakup.org | |
| 214 | +Description: This file contains names for key states. | |
| 215 | + Again, these are part of the help system. For instance, if you | |
| 216 | + had pressed speakup + keypad 3, you would hear: | |
| 217 | + "speakup keypad 3 is go to bottom edge." | |
| 218 | + The speakup key is depressed, so the name of the key state is | |
| 219 | + speakup. | |
| 220 | + This part of the message comes from the states collection. | |
| 221 | + | |
| 222 | +What: /sys/accessibility/speakup/i18n/characters | |
| 223 | +KernelVersion: 2.6 | |
| 224 | +Contact: speakup@linux-speakup.org | |
| 225 | +Description: Through this sys entry, Speakup gives you the ability to change | |
| 226 | + how Speakup pronounces a given character. You could, for | |
| 227 | + example, change how some punctuation characters are spoken. You | |
| 228 | + can even change how Speakup will pronounce certain letters. For | |
| 229 | + further details see '12. Changing the Pronunciation of | |
| 230 | + Characters' in Speakup User's Guide (file spkguide.txt in | |
| 231 | + source). | |
| 232 | + | |
| 233 | +What: /sys/accessibility/speakup/i18n/colors | |
| 234 | +KernelVersion: 2.6 | |
| 235 | +Contact: speakup@linux-speakup.org | |
| 236 | +Description: When you use the "say attributes" function, Speakup says the | |
| 237 | + name of the foreground and background colors. These names come | |
| 238 | + from the i18n/colors file. | |
| 239 | + | |
| 240 | +What: /sys/accessibility/speakup/i18n/formatted | |
| 241 | +KernelVersion: 2.6 | |
| 242 | +Contact: speakup@linux-speakup.org | |
| 243 | +Description: This group of messages contains embedded formatting codes, to | |
| 244 | + specify the type and width of displayed data. If you change | |
| 245 | + these, you must preserve all of the formatting codes, and they | |
| 246 | + must appear in the order used by the default messages. | |
| 247 | + | |
| 248 | +What: /sys/accessibility/speakup/i18n/key_names | |
| 249 | +KernelVersion: 2.6 | |
| 250 | +Contact: speakup@linux-speakup.org | |
| 251 | +Description: Again, key_names is used by Speakup's help system. In the | |
| 252 | + previous example, Speakup said that you pressed "keypad 3." | |
| 253 | + This name came from the key_names file. | |
| 254 | + | |
| 255 | +What: /sys/accessibility/speakup/<synth-name>/ | |
| 256 | +KernelVersion: 2.6 | |
| 257 | +Contact: speakup@linux-speakup.org | |
| 258 | +Description: In `/sys/accessibility/speakup` is a directory corresponding to | |
| 259 | + the synthesizer driver currently in use (E.G) `soft` for the | |
| 260 | + soft driver. This directory contains files which control the | |
| 261 | + speech synthesizer itself, | |
| 262 | + as opposed to controlling the speakup | |
| 263 | + screen reader. The parameters in this directory have the same | |
| 264 | + names and functions across all | |
| 265 | + supported synthesizers. The range | |
| 266 | + of values for freq, pitch, rate, and vol is the same for all | |
| 267 | + supported synthesizers, with the given range being internally | |
| 268 | + mapped by the driver to more or less fit the range of values | |
| 269 | + supported for a given parameter by the individual synthesizer. | |
| 270 | + Below is a description of values and parameters for soft | |
| 271 | + synthesizer, which is currently the most commonly used. | |
| 272 | + | |
| 273 | +What: /sys/accessibility/speakup/soft/caps_start | |
| 274 | +KernelVersion: 2.6 | |
| 275 | +Contact: speakup@linux-speakup.org | |
| 276 | +Description: This is the string that is sent to the synthesizer to cause it | |
| 277 | + to start speaking uppercase letters. For the soft synthesizer | |
| 278 | + and most others, this causes the pitch of the voice to rise | |
| 279 | + above the currently set pitch. | |
| 280 | + | |
| 281 | +What: /sys/accessibility/speakup/soft/caps_stop | |
| 282 | +KernelVersion: 2.6 | |
| 283 | +Contact: speakup@linux-speakup.org | |
| 284 | +Description: This is the string sent to the synthesizer to cause it to stop | |
| 285 | + speaking uppercase letters. In the case of the soft synthesizer | |
| 286 | + and most others, this returns the pitch of the voice | |
| 287 | + down to the | |
| 288 | + currently set pitch. | |
| 289 | + | |
| 290 | +What: /sys/accessibility/speakup/soft/delay_time | |
| 291 | +KernelVersion: 2.6 | |
| 292 | +Contact: speakup@linux-speakup.org | |
| 293 | +Description: TODO: | |
| 294 | + | |
| 295 | +What: /sys/accessibility/speakup/soft/direct | |
| 296 | +KernelVersion: 2.6 | |
| 297 | +Contact: speakup@linux-speakup.org | |
| 298 | +Description: Controls if punctuation is spoken by speakup, or by the | |
| 299 | + synthesizer. | |
| 300 | + For example, speakup speaks ">" as "greater", while | |
| 301 | + the espeak synthesizer used by the soft driver speaks "greater | |
| 302 | + than". Zero lets speakup speak the punctuation. One lets the | |
| 303 | + synthesizer itself speak punctuation. | |
| 304 | + | |
| 305 | +What: /sys/accessibility/speakup/soft/freq | |
| 306 | +KernelVersion: 2.6 | |
| 307 | +Contact: speakup@linux-speakup.org | |
| 308 | +Description: Gets or sets the frequency of the speech synthesizer. Range is | |
| 309 | + 0-9. | |
| 310 | + | |
| 311 | +What: /sys/accessibility/speakup/soft/full_time | |
| 312 | +KernelVersion: 2.6 | |
| 313 | +Contact: speakup@linux-speakup.org | |
| 314 | +Description: TODO: | |
| 315 | + | |
| 316 | +What: /sys/accessibility/speakup/soft/jiffy_delta | |
| 317 | +KernelVersion: 2.6 | |
| 318 | +Contact: speakup@linux-speakup.org | |
| 319 | +Description: This controls how many jiffys the kernel gives to the | |
| 320 | + synthesizer. Setting this too high can make a system unstable, | |
| 321 | + or even crash it. | |
| 322 | + | |
| 323 | +What: /sys/accessibility/speakup/soft/pitch | |
| 324 | +KernelVersion: 2.6 | |
| 325 | +Contact: speakup@linux-speakup.org | |
| 326 | +Description: Gets or sets the pitch of the synthesizer. The range is 0-9. | |
| 327 | + | |
| 328 | +What: /sys/accessibility/speakup/soft/punct | |
| 329 | +KernelVersion: 2.6 | |
| 330 | +Contact: speakup@linux-speakup.org | |
| 331 | +Description: Gets or sets the amount of punctuation spoken by the | |
| 332 | + synthesizer. The range for the soft driver seems to be 0-2. | |
| 333 | + TODO: How is this related to speakup's punc_level, or | |
| 334 | + reading_punc. | |
| 335 | + | |
| 336 | +What: /sys/accessibility/speakup/soft/rate | |
| 337 | +KernelVersion: 2.6 | |
| 338 | +Contact: speakup@linux-speakup.org | |
| 339 | +Description: Gets or sets the rate of the synthesizer. Range is from zero | |
| 340 | + slowest, to nine fastest. | |
| 341 | + | |
| 342 | +What: /sys/accessibility/speakup/soft/tone | |
| 343 | +KernelVersion: 2.6 | |
| 344 | +Contact: speakup@linux-speakup.org | |
| 345 | +Description: Gets or sets the tone of the speech synthesizer. The range for | |
| 346 | + the soft driver seems to be 0-2. This seems to make no | |
| 347 | + difference if using espeak and the espeakup connector. | |
| 348 | + TODO: does espeakup support different tonalities? | |
| 349 | + | |
| 350 | +What: /sys/accessibility/speakup/soft/trigger_time | |
| 351 | +KernelVersion: 2.6 | |
| 352 | +Contact: speakup@linux-speakup.org | |
| 353 | +Description: TODO: | |
| 354 | + | |
| 355 | +What: /sys/accessibility/speakup/soft/voice | |
| 356 | +KernelVersion: 2.6 | |
| 357 | +Contact: speakup@linux-speakup.org | |
| 358 | +Description: Gets or sets the voice used by the synthesizer if the | |
| 359 | + synthesizer can speak in more than one voice. The range for the | |
| 360 | + soft driver is 0-7. Note that while espeak supports multiple | |
| 361 | + voices, this parameter will not set the voice when the espeakup | |
| 362 | + connector is used between speakup and espeak. | |
| 363 | + | |
| 364 | +What: /sys/accessibility/speakup/soft/vol | |
| 365 | +KernelVersion: 2.6 | |
| 366 | +Contact: speakup@linux-speakup.org | |
| 367 | +Description: Gets or sets the volume of the speech synthesizer. Range is 0-9, | |
| 368 | + with zero being the softest, and nine being the loudest. | |
| 369 | + | |
| @@ -12,7 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { |
| 13 | 13 | .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 14 | 14 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | |
| 15 | − SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), | |
| 15 | + SNDRV_PCM_INFO_SYNC_APPLPTR), | |
| 16 | 16 | .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, |
| 17 | 17 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, |
| 18 | 18 | .rate_min = 8000, |
| @@ -29,7 +29,7 @@ static const struct snd_pcm_hardware snd_bcm2835_playback_hw = { · 10 unmodified lines | ||
| 29 | 29 | static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { |
| 30 | 30 | .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
| 31 | 31 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | |
| 32 | − SNDRV_PCM_INFO_DRAIN_TRIGGER | SNDRV_PCM_INFO_SYNC_APPLPTR), | |
| 32 | + SNDRV_PCM_INFO_SYNC_APPLPTR), | |
| 33 | 33 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
| 34 | 34 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | |
| 35 | 35 | SNDRV_PCM_RATE_48000, |
| @@ -289,6 +289,7 @@ int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream) · 288 unmodified lines | ||
| 289 | 289 | VC_AUDIO_MSG_TYPE_STOP, false); |
| 290 | 290 | } |
| 291 | 291 | |
| 292 | +/* FIXME: this doesn't seem working as expected for "draining" */ | |
| 292 | 293 | int bcm2835_audio_drain(struct bcm2835_alsa_stream *alsa_stream) |
| 293 | 294 | { |
| 294 | 295 | struct vc_audio_msg m = { |
| @@ -1748,8 +1748,10 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) · 1747 unmodified lines | ||
| 1748 | 1748 | |
| 1749 | 1749 | priv->hw->max_signal = 100; |
| 1750 | 1750 | |
| 1751 | − if (vnt_init(priv)) | |
| 1751 | + if (vnt_init(priv)) { | |
| 1752 | + device_free_info(priv); | |
| 1752 | 1753 | return -ENODEV; |
| 1754 | + } | |
| 1753 | 1755 | |
| 1754 | 1756 | device_print_info(priv); |
| 1755 | 1757 | pci_set_drvdata(pcid, priv); |
| @@ -968,6 +968,11 @@ static int __init n_hdlc_init(void) · 967 unmodified lines | ||
| 968 | 968 | |
| 969 | 969 | } /* end of init_module() */ |
| 970 | 970 | |
| 971 | +#ifdef CONFIG_SPARC | |
| 972 | +#undef __exitdata | |
| 973 | +#define __exitdata | |
| 974 | +#endif | |
| 975 | + | |
| 971 | 976 | static const char hdlc_unregister_ok[] __exitdata = |
| 972 | 977 | KERN_INFO "N_HDLC: line discipline unregistered\n"; |
| 973 | 978 | static const char hdlc_unregister_fail[] __exitdata = |
| @@ -141,7 +141,7 @@ static void omap8250_set_mctrl(struct uart_port *port, unsigned int mctrl) · 140 unmodified lines | ||
| 141 | 141 | |
| 142 | 142 | serial8250_do_set_mctrl(port, mctrl); |
| 143 | 143 | |
| 144 | − if (!up->gpios) { | |
| 144 | + if (!mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS)) { | |
| 145 | 145 | /* |
| 146 | 146 | * Turn off autoRTS if RTS is lowered and restore autoRTS |
| 147 | 147 | * setting if RTS is raised |
| @@ -456,7 +456,8 @@ static void omap_8250_set_termios(struct uart_port *port, · 308 unmodified lines | ||
| 456 | 456 | up->port.status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS | UPSTAT_AUTOXOFF); |
| 457 | 457 | |
| 458 | 458 | if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW && |
| 459 | − !up->gpios) { | |
| 459 | + !mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_RTS) && | |
| 460 | + !mctrl_gpio_to_gpiod(up->gpios, UART_GPIO_CTS)) { | |
| 460 | 461 | /* Enable AUTOCTS (autoRTS is enabled when RTS is raised) */ |
| 461 | 462 | up->port.status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS; |
| 462 | 463 | priv->efr |= UART_EFR_CTS; |
| @@ -1032,6 +1032,7 @@ config SERIAL_SIFIVE_CONSOLE · 1031 unmodified lines | ||
| 1032 | 1032 | bool "Console on SiFive UART" |
| 1033 | 1033 | depends on SERIAL_SIFIVE=y |
| 1034 | 1034 | select SERIAL_CORE_CONSOLE |
| 1035 | + select SERIAL_EARLYCON | |
| 1035 | 1036 | help |
| 1036 | 1037 | Select this option if you would like to use a SiFive UART as the |
| 1037 | 1038 | system console. |
| @@ -3,7 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | * Freescale linflexuart serial port driver |
| 4 | 4 | * |
| 5 | 5 | * Copyright 2012-2016 Freescale Semiconductor, Inc. |
| 6 | − * Copyright 2017-2018 NXP | |
| 6 | + * Copyright 2017-2019 NXP | |
| 7 | 7 | */ |
| 8 | 8 | |
| 9 | 9 | #if defined(CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE) && \ |
| @@ -246,12 +246,14 @@ static irqreturn_t linflex_rxint(int irq, void *dev_id) · 236 unmodified lines | ||
| 246 | 246 | struct tty_port *port = &sport->state->port; |
| 247 | 247 | unsigned long flags, status; |
| 248 | 248 | unsigned char rx; |
| 249 | + bool brk; | |
| 249 | 250 | |
| 250 | 251 | spin_lock_irqsave(&sport->lock, flags); |
| 251 | 252 | |
| 252 | 253 | status = readl(sport->membase + UARTSR); |
| 253 | 254 | while (status & LINFLEXD_UARTSR_RMB) { |
| 254 | 255 | rx = readb(sport->membase + BDRM); |
| 256 | + brk = false; | |
| 255 | 257 | flg = TTY_NORMAL; |
| 256 | 258 | sport->icount.rx++; |
| 257 | 259 | |
| @@ -261,8 +263,11 @@ static irqreturn_t linflex_rxint(int irq, void *dev_id) · 3 unmodified lines | ||
| 261 | 263 | status |= LINFLEXD_UARTSR_SZF; |
| 262 | 264 | if (status & LINFLEXD_UARTSR_BOF) |
| 263 | 265 | status |= LINFLEXD_UARTSR_BOF; |
| 264 | − if (status & LINFLEXD_UARTSR_FEF) | |
| 266 | + if (status & LINFLEXD_UARTSR_FEF) { | |
| 267 | + if (!rx) | |
| 268 | + brk = true; | |
| 265 | 269 | status |= LINFLEXD_UARTSR_FEF; |
| 270 | + } | |
| 266 | 271 | if (status & LINFLEXD_UARTSR_PE) |
| 267 | 272 | status |= LINFLEXD_UARTSR_PE; |
| 268 | 273 | } |
| @@ -271,13 +276,15 @@ static irqreturn_t linflex_rxint(int irq, void *dev_id) · 2 unmodified lines | ||
| 271 | 276 | sport->membase + UARTSR); |
| 272 | 277 | status = readl(sport->membase + UARTSR); |
| 273 | 278 | |
| 274 | − if (uart_handle_sysrq_char(sport, (unsigned char)rx)) | |
| 275 | − continue; | |
| 276 | − | |
| 279 | + if (brk) { | |
| 280 | + uart_handle_break(sport); | |
| 281 | + } else { | |
| 277 | 282 | #ifdef SUPPORT_SYSRQ |
| 278 | − sport->sysrq = 0; | |
| 283 | + if (uart_handle_sysrq_char(sport, (unsigned char)rx)) | |
| 284 | + continue; | |
| 279 | 285 | #endif |
| 280 | − tty_insert_flip_char(port, rx, flg); | |
| 286 | + tty_insert_flip_char(port, rx, flg); | |
| 287 | + } | |
| 281 | 288 | } |
| 282 | 289 | |
| 283 | 290 | spin_unlock_irqrestore(&sport->lock, flags); |
| @@ -548,7 +548,7 @@ static void lpuart_flush_buffer(struct uart_port *port) · 547 unmodified lines | ||
| 548 | 548 | val |= UARTFIFO_TXFLUSH | UARTFIFO_RXFLUSH; |
| 549 | 549 | lpuart32_write(&sport->port, val, UARTFIFO); |
| 550 | 550 | } else { |
| 551 | − val = readb(sport->port.membase + UARTPFIFO); | |
| 551 | + val = readb(sport->port.membase + UARTCFIFO); | |
| 552 | 552 | val |= UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH; |
| 553 | 553 | writeb(val, sport->port.membase + UARTCFIFO); |
| 554 | 554 | } |
| @@ -2222,8 +2222,8 @@ static int imx_uart_probe(struct platform_device *pdev) · 2221 unmodified lines | ||
| 2222 | 2222 | return PTR_ERR(base); |
| 2223 | 2223 | |
| 2224 | 2224 | rxirq = platform_get_irq(pdev, 0); |
| 2225 | − txirq = platform_get_irq(pdev, 1); | |
| 2226 | − rtsirq = platform_get_irq(pdev, 2); | |
| 2225 | + txirq = platform_get_irq_optional(pdev, 1); | |
| 2226 | + rtsirq = platform_get_irq_optional(pdev, 2); | |
| 2227 | 2227 | |
| 2228 | 2228 | sport->port.dev = &pdev->dev; |
| 2229 | 2229 | sport->port.mapbase = res->start; |
| @@ -740,7 +740,7 @@ static int __init owl_uart_init(void) · 739 unmodified lines | ||
| 740 | 740 | return ret; |
| 741 | 741 | } |
| 742 | 742 | |
| 743 | −static void __init owl_uart_exit(void) | |
| 743 | +static void __exit owl_uart_exit(void) | |
| 744 | 744 | { |
| 745 | 745 | platform_driver_unregister(&owl_uart_platform_driver); |
| 746 | 746 | uart_unregister_driver(&owl_uart_driver); |
| @@ -815,7 +815,7 @@ static int __init rda_uart_init(void) · 814 unmodified lines | ||
| 815 | 815 | return ret; |
| 816 | 816 | } |
| 817 | 817 | |
| 818 | −static void __init rda_uart_exit(void) | |
| 818 | +static void __exit rda_uart_exit(void) | |
| 819 | 819 | { |
| 820 | 820 | platform_driver_unregister(&rda_uart_platform_driver); |
| 821 | 821 | uart_unregister_driver(&rda_uart_driver); |
| @@ -1964,8 +1964,10 @@ uart_get_console(struct uart_port *ports, int nr, struct console *co) · 1963 unmodified lines | ||
| 1964 | 1964 | * console=<name>,io|mmio|mmio16|mmio32|mmio32be|mmio32native,<addr>,<options> |
| 1965 | 1965 | * |
| 1966 | 1966 | * The optional form |
| 1967 | + * | |
| 1967 | 1968 | * earlycon=<name>,0x<addr>,<options> |
| 1968 | 1969 | * console=<name>,0x<addr>,<options> |
| 1970 | + * | |
| 1969 | 1971 | * is also accepted; the returned @iotype will be UPIO_MEM. |
| 1970 | 1972 | * |
| 1971 | 1973 | * Returns 0 on success or -EINVAL on failure |
| @@ -66,6 +66,9 @@ EXPORT_SYMBOL_GPL(mctrl_gpio_set); · 65 unmodified lines | ||
| 66 | 66 | struct gpio_desc *mctrl_gpio_to_gpiod(struct mctrl_gpios *gpios, |
| 67 | 67 | enum mctrl_gpio_idx gidx) |
| 68 | 68 | { |
| 69 | + if (gpios == NULL) | |
| 70 | + return NULL; | |
| 71 | + | |
| 69 | 72 | return gpios->gpio[gidx]; |
| 70 | 73 | } |
| 71 | 74 | EXPORT_SYMBOL_GPL(mctrl_gpio_to_gpiod); |
| @@ -2894,8 +2894,12 @@ static int sci_init_single(struct platform_device *dev, · 2893 unmodified lines | ||
| 2894 | 2894 | port->mapbase = res->start; |
| 2895 | 2895 | sci_port->reg_size = resource_size(res); |
| 2896 | 2896 | |
| 2897 | − for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) | |
| 2898 | − sci_port->irqs[i] = platform_get_irq(dev, i); | |
| 2897 | + for (i = 0; i < ARRAY_SIZE(sci_port->irqs); ++i) { | |
| 2898 | + if (i) | |
| 2899 | + sci_port->irqs[i] = platform_get_irq_optional(dev, i); | |
| 2900 | + else | |
| 2901 | + sci_port->irqs[i] = platform_get_irq(dev, i); | |
| 2902 | + } | |
| 2899 | 2903 | |
| 2900 | 2904 | /* The SCI generates several interrupts. They can be muxed together or |
| 2901 | 2905 | * connected to different interrupt lines. In the muxed case only one |
| @@ -897,7 +897,8 @@ static int __init ulite_init(void) · 896 unmodified lines | ||
| 897 | 897 | static void __exit ulite_exit(void) |
| 898 | 898 | { |
| 899 | 899 | platform_driver_unregister(&ulite_platform_driver); |
| 900 | − uart_unregister_driver(&ulite_uart_driver); | |
| 900 | + if (ulite_uart_driver.state) | |
| 901 | + uart_unregister_driver(&ulite_uart_driver); | |
| 901 | 902 | } |
| 902 | 903 | |
| 903 | 904 | module_init(ulite_init); |
| @@ -1550,7 +1550,6 @@ static int cdns_uart_probe(struct platform_device *pdev) · 1549 unmodified lines | ||
| 1550 | 1550 | goto err_out_id; |
| 1551 | 1551 | } |
| 1552 | 1552 | |
| 1553 | − uartps_major = cdns_uart_uart_driver->tty_driver->major; | |
| 1554 | 1553 | cdns_uart_data->cdns_uart_driver = cdns_uart_uart_driver; |
| 1555 | 1554 | |
| 1556 | 1555 | /* |
| @@ -1680,6 +1679,7 @@ static int cdns_uart_probe(struct platform_device *pdev) · 123 unmodified lines | ||
| 1680 | 1679 | console_port = NULL; |
| 1681 | 1680 | #endif |
| 1682 | 1681 | |
| 1682 | + uartps_major = cdns_uart_uart_driver->tty_driver->major; | |
| 1683 | 1683 | cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node, |
| 1684 | 1684 | "cts-override"); |
| 1685 | 1685 | return 0; |
| @@ -1741,6 +1741,12 @@ static int cdns_uart_remove(struct platform_device *pdev) · 55 unmodified lines | ||
| 1741 | 1741 | console_port = NULL; |
| 1742 | 1742 | #endif |
| 1743 | 1743 | |
| 1744 | + /* If this is last instance major number should be initialized */ | |
| 1745 | + mutex_lock(&bitmap_lock); | |
| 1746 | + if (bitmap_empty(bitmap, MAX_UART_INSTANCES)) | |
| 1747 | + uartps_major = 0; | |
| 1748 | + mutex_unlock(&bitmap_lock); | |
| 1749 | + | |
| 1744 | 1750 | uart_unregister_driver(cdns_uart_data->cdns_uart_driver); |
| 1745 | 1751 | return rc; |
| 1746 | 1752 | } |
| @@ -159,8 +159,9 @@ static int cdns3_pci_probe(struct pci_dev *pdev, · 158 unmodified lines | ||
| 159 | 159 | wrap->plat_dev = platform_device_register_full(&plat_info); |
| 160 | 160 | if (IS_ERR(wrap->plat_dev)) { |
| 161 | 161 | pci_disable_device(pdev); |
| 162 | + err = PTR_ERR(wrap->plat_dev); | |
| 162 | 163 | kfree(wrap); |
| 163 | − return PTR_ERR(wrap->plat_dev); | |
| 164 | + return err; | |
| 164 | 165 | } |
| 165 | 166 | } |
| 166 | 167 | |
| @@ -160,10 +160,28 @@ static int cdns3_core_init_role(struct cdns3 *cdns) · 159 unmodified lines | ||
| 160 | 160 | if (ret) |
| 161 | 161 | goto err; |
| 162 | 162 | |
| 163 | − if (cdns->dr_mode != USB_DR_MODE_OTG) { | |
| 163 | + /* Initialize idle role to start with */ | |
| 164 | + ret = cdns3_role_start(cdns, USB_ROLE_NONE); | |
| 165 | + if (ret) | |
| 166 | + goto err; | |
| 167 | + | |
| 168 | + switch (cdns->dr_mode) { | |
| 169 | + case USB_DR_MODE_UNKNOWN: | |
| 170 | + case USB_DR_MODE_OTG: | |
| 164 | 171 | ret = cdns3_hw_role_switch(cdns); |
| 165 | 172 | if (ret) |
| 166 | 173 | goto err; |
| 174 | + break; | |
| 175 | + case USB_DR_MODE_PERIPHERAL: | |
| 176 | + ret = cdns3_role_start(cdns, USB_ROLE_DEVICE); | |
| 177 | + if (ret) | |
| 178 | + goto err; | |
| 179 | + break; | |
| 180 | + case USB_DR_MODE_HOST: | |
| 181 | + ret = cdns3_role_start(cdns, USB_ROLE_HOST); | |
| 182 | + if (ret) | |
| 183 | + goto err; | |
| 184 | + break; | |
| 167 | 185 | } |
| 168 | 186 | |
| 169 | 187 | return ret; |
| @@ -234,9 +234,11 @@ static int cdns3_req_ep0_set_address(struct cdns3_device *priv_dev, · 233 unmodified lines | ||
| 234 | 234 | static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev, |
| 235 | 235 | struct usb_ctrlrequest *ctrl) |
| 236 | 236 | { |
| 237 | + struct cdns3_endpoint *priv_ep; | |
| 237 | 238 | __le16 *response_pkt; |
| 238 | 239 | u16 usb_status = 0; |
| 239 | 240 | u32 recip; |
| 241 | + u8 index; | |
| 240 | 242 | |
| 241 | 243 | recip = ctrl->bRequestType & USB_RECIP_MASK; |
| 242 | 244 | |
| @@ -262,9 +264,13 @@ static int cdns3_req_ep0_get_status(struct cdns3_device *priv_dev, · 19 unmodified lines | ||
| 262 | 264 | case USB_RECIP_INTERFACE: |
| 263 | 265 | return cdns3_ep0_delegate_req(priv_dev, ctrl); |
| 264 | 266 | case USB_RECIP_ENDPOINT: |
| 265 | − /* check if endpoint is stalled */ | |
| 267 | + index = cdns3_ep_addr_to_index(ctrl->wIndex); | |
| 268 | + priv_ep = priv_dev->eps[index]; | |
| 269 | + | |
| 270 | + /* check if endpoint is stalled or stall is pending */ | |
| 266 | 271 | cdns3_select_ep(priv_dev, ctrl->wIndex); |
| 267 | − if (EP_STS_STALL(readl(&priv_dev->regs->ep_sts))) | |
| 272 | + if (EP_STS_STALL(readl(&priv_dev->regs->ep_sts)) || | |
| 273 | + (priv_ep->flags & EP_STALL_PENDING)) | |
| 268 | 274 | usb_status = BIT(USB_ENDPOINT_HALT); |
| 269 | 275 | break; |
| 270 | 276 | default: |
| @@ -332,7 +338,7 @@ static int cdns3_ep0_feature_handle_device(struct cdns3_device *priv_dev, · 61 unmodified lines | ||
| 332 | 338 | * for sending status stage. |
| 333 | 339 | * This time should be less then 3ms. |
| 334 | 340 | */ |
| 335 | − usleep_range(1000, 2000); | |
| 341 | + mdelay(1); | |
| 336 | 342 | cdns3_set_register_bit(&priv_dev->regs->usb_cmd, |
| 337 | 343 | USB_CMD_STMODE | |
| 338 | 344 | USB_STS_TMODE_SEL(tmode - 1)); |
| @@ -2571,6 +2571,7 @@ static int cdns3_gadget_start(struct cdns3 *cdns) · 2570 unmodified lines | ||
| 2571 | 2571 | switch (max_speed) { |
| 2572 | 2572 | case USB_SPEED_FULL: |
| 2573 | 2573 | writel(USB_CONF_SFORCE_FS, &priv_dev->regs->usb_conf); |
| 2574 | + writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); | |
| 2574 | 2575 | break; |
| 2575 | 2576 | case USB_SPEED_HIGH: |
| 2576 | 2577 | writel(USB_CONF_USB3DIS, &priv_dev->regs->usb_conf); |
| @@ -2662,6 +2663,13 @@ static int __cdns3_gadget_init(struct cdns3 *cdns) · 85 unmodified lines | ||
| 2662 | 2663 | { |
| 2663 | 2664 | int ret = 0; |
| 2664 | 2665 | |
| 2666 | + /* Ensure 32-bit DMA Mask in case we switched back from Host mode */ | |
| 2667 | + ret = dma_set_mask_and_coherent(cdns->dev, DMA_BIT_MASK(32)); | |
| 2668 | + if (ret) { | |
| 2669 | + dev_err(cdns->dev, "Failed to set dma mask: %d\n", ret); | |
| 2670 | + return ret; | |
| 2671 | + } | |
| 2672 | + | |
| 2665 | 2673 | cdns3_drd_switch_gadget(cdns, 1); |
| 2666 | 2674 | pm_runtime_get_sync(cdns->dev); |
| 2667 | 2675 | |
| @@ -461,10 +461,12 @@ static int usblp_release(struct inode *inode, struct file *file) · 460 unmodified lines | ||
| 461 | 461 | |
| 462 | 462 | mutex_lock(&usblp_mutex); |
| 463 | 463 | usblp->used = 0; |
| 464 | − if (usblp->present) { | |
| 464 | + if (usblp->present) | |
| 465 | 465 | usblp_unlink_urbs(usblp); |
| 466 | − usb_autopm_put_interface(usblp->intf); | |
| 467 | − } else /* finish cleanup from disconnect */ | |
| 466 | + | |
| 467 | + usb_autopm_put_interface(usblp->intf); | |
| 468 | + | |
| 469 | + if (!usblp->present) /* finish cleanup from disconnect */ | |
| 468 | 470 | usblp_cleanup(usblp); |
| 469 | 471 | mutex_unlock(&usblp_mutex); |
| 470 | 472 | return 0; |
| @@ -139,14 +139,14 @@ static int dwc3_otg_get_irq(struct dwc3 *dwc) · 138 unmodified lines | ||
| 139 | 139 | struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); |
| 140 | 140 | int irq; |
| 141 | 141 | |
| 142 | − irq = platform_get_irq_byname(dwc3_pdev, "otg"); | |
| 142 | + irq = platform_get_irq_byname_optional(dwc3_pdev, "otg"); | |
| 143 | 143 | if (irq > 0) |
| 144 | 144 | goto out; |
| 145 | 145 | |
| 146 | 146 | if (irq == -EPROBE_DEFER) |
| 147 | 147 | goto out; |
| 148 | 148 | |
| 149 | − irq = platform_get_irq_byname(dwc3_pdev, "dwc_usb3"); | |
| 149 | + irq = platform_get_irq_byname_optional(dwc3_pdev, "dwc_usb3"); | |
| 150 | 150 | if (irq > 0) |
| 151 | 151 | goto out; |
| 152 | 152 | |
| @@ -157,9 +157,6 @@ static int dwc3_otg_get_irq(struct dwc3 *dwc) · 4 unmodified lines | ||
| 157 | 157 | if (irq > 0) |
| 158 | 158 | goto out; |
| 159 | 159 | |
| 160 | − if (irq != -EPROBE_DEFER) | |
| 161 | − dev_err(dwc->dev, "missing OTG IRQ\n"); | |
| 162 | − | |
| 163 | 160 | if (!irq) |
| 164 | 161 | irq = -EINVAL; |
| 165 | 162 | |
| @@ -3264,14 +3264,14 @@ static int dwc3_gadget_get_irq(struct dwc3 *dwc) · 3263 unmodified lines | ||
| 3264 | 3264 | struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); |
| 3265 | 3265 | int irq; |
| 3266 | 3266 | |
| 3267 | − irq = platform_get_irq_byname(dwc3_pdev, "peripheral"); | |
| 3267 | + irq = platform_get_irq_byname_optional(dwc3_pdev, "peripheral"); | |
| 3268 | 3268 | if (irq > 0) |
| 3269 | 3269 | goto out; |
| 3270 | 3270 | |
| 3271 | 3271 | if (irq == -EPROBE_DEFER) |
| 3272 | 3272 | goto out; |
| 3273 | 3273 | |
| 3274 | − irq = platform_get_irq_byname(dwc3_pdev, "dwc_usb3"); | |
| 3274 | + irq = platform_get_irq_byname_optional(dwc3_pdev, "dwc_usb3"); | |
| 3275 | 3275 | if (irq > 0) |
| 3276 | 3276 | goto out; |
| 3277 | 3277 | |
| @@ -3282,9 +3282,6 @@ static int dwc3_gadget_get_irq(struct dwc3 *dwc) · 4 unmodified lines | ||
| 3282 | 3282 | if (irq > 0) |
| 3283 | 3283 | goto out; |
| 3284 | 3284 | |
| 3285 | − if (irq != -EPROBE_DEFER) | |
| 3286 | − dev_err(dwc->dev, "missing peripheral IRQ\n"); | |
| 3287 | − | |
| 3288 | 3285 | if (!irq) |
| 3289 | 3286 | irq = -EINVAL; |
| 3290 | 3287 | |
| @@ -16,14 +16,14 @@ static int dwc3_host_get_irq(struct dwc3 *dwc) · 15 unmodified lines | ||
| 16 | 16 | struct platform_device *dwc3_pdev = to_platform_device(dwc->dev); |
| 17 | 17 | int irq; |
| 18 | 18 | |
| 19 | − irq = platform_get_irq_byname(dwc3_pdev, "host"); | |
| 19 | + irq = platform_get_irq_byname_optional(dwc3_pdev, "host"); | |
| 20 | 20 | if (irq > 0) |
| 21 | 21 | goto out; |
| 22 | 22 | |
| 23 | 23 | if (irq == -EPROBE_DEFER) |
| 24 | 24 | goto out; |
| 25 | 25 | |
| 26 | − irq = platform_get_irq_byname(dwc3_pdev, "dwc_usb3"); | |
| 26 | + irq = platform_get_irq_byname_optional(dwc3_pdev, "dwc_usb3"); | |
| 27 | 27 | if (irq > 0) |
| 28 | 28 | goto out; |
| 29 | 29 | |
| @@ -34,9 +34,6 @@ static int dwc3_host_get_irq(struct dwc3 *dwc) · 4 unmodified lines | ||
| 34 | 34 | if (irq > 0) |
| 35 | 35 | goto out; |
| 36 | 36 | |
| 37 | − if (irq != -EPROBE_DEFER) | |
| 38 | − dev_err(dwc->dev, "missing host IRQ\n"); | |
| 39 | − | |
| 40 | 37 | if (!irq) |
| 41 | 38 | irq = -EINVAL; |
| 42 | 39 | |
| @@ -45,7 +45,7 @@ config USB_AT91 · 44 unmodified lines | ||
| 45 | 45 | |
| 46 | 46 | config USB_LPC32XX |
| 47 | 47 | tristate "LPC32XX USB Peripheral Controller" |
| 48 | − depends on ARCH_LPC32XX | |
| 48 | + depends on ARCH_LPC32XX || COMPILE_TEST | |
| 49 | 49 | depends on I2C |
| 50 | 50 | select USB_ISP1301 |
| 51 | 51 | help |
| @@ -48,6 +48,7 @@ · 47 unmodified lines | ||
| 48 | 48 | #define DRIVER_VERSION "02 May 2005" |
| 49 | 49 | |
| 50 | 50 | #define POWER_BUDGET 500 /* in mA; use 8 for low-power port testing */ |
| 51 | +#define POWER_BUDGET_3 900 /* in mA */ | |
| 51 | 52 | |
| 52 | 53 | static const char driver_name[] = "dummy_hcd"; |
| 53 | 54 | static const char driver_desc[] = "USB Host+Gadget Emulator"; |
| @@ -2432,7 +2433,7 @@ static int dummy_start_ss(struct dummy_hcd *dum_hcd) · 2378 unmodified lines | ||
| 2432 | 2433 | dum_hcd->rh_state = DUMMY_RH_RUNNING; |
| 2433 | 2434 | dum_hcd->stream_en_ep = 0; |
| 2434 | 2435 | INIT_LIST_HEAD(&dum_hcd->urbp_list); |
| 2435 | − dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET; | |
| 2436 | + dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET_3; | |
| 2436 | 2437 | dummy_hcd_to_hcd(dum_hcd)->state = HC_STATE_RUNNING; |
| 2437 | 2438 | dummy_hcd_to_hcd(dum_hcd)->uses_new_polling = 1; |
| 2438 | 2439 | #ifdef CONFIG_USB_OTG |
| @@ -1151,7 +1151,7 @@ static void udc_pop_fifo(struct lpc32xx_udc *udc, u8 *data, u32 bytes) · 1150 unmodified lines | ||
| 1151 | 1151 | u32 *p32, tmp, cbytes; |
| 1152 | 1152 | |
| 1153 | 1153 | /* Use optimal data transfer method based on source address and size */ |
| 1154 | − switch (((u32) data) & 0x3) { | |
| 1154 | + switch (((uintptr_t) data) & 0x3) { | |
| 1155 | 1155 | case 0: /* 32-bit aligned */ |
| 1156 | 1156 | p32 = (u32 *) data; |
| 1157 | 1157 | cbytes = (bytes & ~0x3); |
| @@ -1252,7 +1252,7 @@ static void udc_stuff_fifo(struct lpc32xx_udc *udc, u8 *data, u32 bytes) · 94 unmodified lines | ||
| 1252 | 1252 | u32 *p32, tmp, cbytes; |
| 1253 | 1253 | |
| 1254 | 1254 | /* Use optimal data transfer method based on source address and size */ |
| 1255 | − switch (((u32) data) & 0x3) { | |
| 1255 | + switch (((uintptr_t) data) & 0x3) { | |
| 1256 | 1256 | case 0: /* 32-bit aligned */ |
| 1257 | 1257 | p32 = (u32 *) data; |
| 1258 | 1258 | cbytes = (bytes & ~0x3); |
| @@ -57,6 +57,7 @@ static int xhci_create_intel_xhci_sw_pdev(struct xhci_hcd *xhci, u32 cap_offset) · 56 unmodified lines | ||
| 57 | 57 | ret = platform_device_add_properties(pdev, role_switch_props); |
| 58 | 58 | if (ret) { |
| 59 | 59 | dev_err(dev, "failed to register device properties\n"); |
| 60 | + platform_device_put(pdev); | |
| 60 | 61 | return ret; |
| 61 | 62 | } |
| 62 | 63 | } |
| @@ -3202,10 +3202,10 @@ static int xhci_align_td(struct xhci_hcd *xhci, struct urb *urb, u32 enqd_len, · 3201 unmodified lines | ||
| 3202 | 3202 | if (usb_urb_dir_out(urb)) { |
| 3203 | 3203 | len = sg_pcopy_to_buffer(urb->sg, urb->num_sgs, |
| 3204 | 3204 | seg->bounce_buf, new_buff_len, enqd_len); |
| 3205 | − if (len != seg->bounce_len) | |
| 3205 | + if (len != new_buff_len) | |
| 3206 | 3206 | xhci_warn(xhci, |
| 3207 | 3207 | "WARN Wrong bounce buffer write length: %zu != %d\n", |
| 3208 | − len, seg->bounce_len); | |
| 3208 | + len, new_buff_len); | |
| 3209 | 3209 | seg->bounce_dma = dma_map_single(dev, seg->bounce_buf, |
| 3210 | 3210 | max_pkt, DMA_TO_DEVICE); |
| 3211 | 3211 | } else { |
| @@ -1032,7 +1032,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) · 1031 unmodified lines | ||
| 1032 | 1032 | writel(command, &xhci->op_regs->command); |
| 1033 | 1033 | xhci->broken_suspend = 0; |
| 1034 | 1034 | if (xhci_handshake(&xhci->op_regs->status, |
| 1035 | − STS_SAVE, 0, 10 * 1000)) { | |
| 1035 | + STS_SAVE, 0, 20 * 1000)) { | |
| 1036 | 1036 | /* |
| 1037 | 1037 | * AMD SNPS xHC 3.0 occasionally does not clear the |
| 1038 | 1038 | * SSS bit of USBSTS and when driver tries to poll |
| @@ -1108,6 +1108,18 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) · 69 unmodified lines | ||
| 1108 | 1108 | hibernated = true; |
| 1109 | 1109 | |
| 1110 | 1110 | if (!hibernated) { |
| 1111 | + /* | |
| 1112 | + * Some controllers might lose power during suspend, so wait | |
| 1113 | + * for controller not ready bit to clear, just as in xHC init. | |
| 1114 | + */ | |
| 1115 | + retval = xhci_handshake(&xhci->op_regs->status, | |
| 1116 | + STS_CNR, 0, 10 * 1000 * 1000); | |
| 1117 | + if (retval) { | |
| 1118 | + xhci_warn(xhci, "Controller not ready at resume %d\n", | |
| 1119 | + retval); | |
| 1120 | + spin_unlock_irq(&xhci->lock); | |
| 1121 | + return retval; | |
| 1122 | + } | |
| 1111 | 1123 | /* step 1: restore register */ |
| 1112 | 1124 | xhci_restore_registers(xhci); |
| 1113 | 1125 | /* step 2: initialize command ring buffer */ |
| @@ -3083,6 +3095,7 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd, · 1969 unmodified lines | ||
| 3083 | 3095 | unsigned int ep_index; |
| 3084 | 3096 | unsigned long flags; |
| 3085 | 3097 | u32 ep_flag; |
| 3098 | + int err; | |
| 3086 | 3099 | |
| 3087 | 3100 | xhci = hcd_to_xhci(hcd); |
| 3088 | 3101 | if (!host_ep->hcpriv) |
| @@ -3142,7 +3155,17 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd, · 53 unmodified lines | ||
| 3142 | 3155 | xhci_free_command(xhci, cfg_cmd); |
| 3143 | 3156 | goto cleanup; |
| 3144 | 3157 | } |
| 3145 | − xhci_queue_stop_endpoint(xhci, stop_cmd, udev->slot_id, ep_index, 0); | |
| 3158 | + | |
| 3159 | + err = xhci_queue_stop_endpoint(xhci, stop_cmd, udev->slot_id, | |
| 3160 | + ep_index, 0); | |
| 3161 | + if (err < 0) { | |
| 3162 | + spin_unlock_irqrestore(&xhci->lock, flags); | |
| 3163 | + xhci_free_command(xhci, cfg_cmd); | |
| 3164 | + xhci_dbg(xhci, "%s: Failed to queue stop ep command, %d ", | |
| 3165 | + __func__, err); | |
| 3166 | + goto cleanup; | |
| 3167 | + } | |
| 3168 | + | |
| 3146 | 3169 | xhci_ring_cmd_db(xhci); |
| 3147 | 3170 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 3148 | 3171 | |
| @@ -3156,8 +3179,16 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd, · 7 unmodified lines | ||
| 3156 | 3179 | ctrl_ctx, ep_flag, ep_flag); |
| 3157 | 3180 | xhci_endpoint_copy(xhci, cfg_cmd->in_ctx, vdev->out_ctx, ep_index); |
| 3158 | 3181 | |
| 3159 | − xhci_queue_configure_endpoint(xhci, cfg_cmd, cfg_cmd->in_ctx->dma, | |
| 3182 | + err = xhci_queue_configure_endpoint(xhci, cfg_cmd, cfg_cmd->in_ctx->dma, | |
| 3160 | 3183 | udev->slot_id, false); |
| 3184 | + if (err < 0) { | |
| 3185 | + spin_unlock_irqrestore(&xhci->lock, flags); | |
| 3186 | + xhci_free_command(xhci, cfg_cmd); | |
| 3187 | + xhci_dbg(xhci, "%s: Failed to queue config ep command, %d ", | |
| 3188 | + __func__, err); | |
| 3189 | + goto cleanup; | |
| 3190 | + } | |
| 3191 | + | |
| 3161 | 3192 | xhci_ring_cmd_db(xhci); |
| 3162 | 3193 | spin_unlock_irqrestore(&xhci->lock, flags); |
| 3163 | 3194 | |
| @@ -4674,12 +4705,12 @@ static int xhci_update_timeout_for_endpoint(struct xhci_hcd *xhci, · 1510 unmodified lines | ||
| 4674 | 4705 | alt_timeout = xhci_call_host_update_timeout_for_endpoint(xhci, udev, |
| 4675 | 4706 | desc, state, timeout); |
| 4676 | 4707 | |
| 4677 | − /* If we found we can't enable hub-initiated LPM, or | |
| 4708 | + /* If we found we can't enable hub-initiated LPM, and | |
| 4678 | 4709 | * the U1 or U2 exit latency was too high to allow |
| 4679 | − * device-initiated LPM as well, just stop searching. | |
| 4710 | + * device-initiated LPM as well, then we will disable LPM | |
| 4711 | + * for this device, so stop searching any further. | |
| 4680 | 4712 | */ |
| 4681 | − if (alt_timeout == USB3_LPM_DISABLED || | |
| 4682 | − alt_timeout == USB3_LPM_DEVICE_INITIATED) { | |
| 4713 | + if (alt_timeout == USB3_LPM_DISABLED) { | |
| 4683 | 4714 | *timeout = alt_timeout; |
| 4684 | 4715 | return -E2BIG; |
| 4685 | 4716 | } |
| @@ -4790,10 +4821,12 @@ static u16 xhci_calculate_lpm_timeout(struct usb_hcd *hcd, · 104 unmodified lines | ||
| 4790 | 4821 | if (intf->dev.driver) { |
| 4791 | 4822 | driver = to_usb_driver(intf->dev.driver); |
| 4792 | 4823 | if (driver && driver->disable_hub_initiated_lpm) { |
| 4793 | − dev_dbg(&udev->dev, "Hub-initiated %s disabled " | |
| 4794 | − "at request of driver %s\n", | |
| 4795 | − state_name, driver->name); | |
| 4796 | − return xhci_get_timeout_no_hub_lpm(udev, state); | |
| 4824 | + dev_dbg(&udev->dev, "Hub-initiated %s disabled at request of driver %s\n", | |
| 4825 | + state_name, driver->name); | |
| 4826 | + timeout = xhci_get_timeout_no_hub_lpm(udev, | |
| 4827 | + state); | |
| 4828 | + if (timeout == USB3_LPM_DISABLED) | |
| 4829 | + return timeout; | |
| 4797 | 4830 | } |
| 4798 | 4831 | } |
| 4799 | 4832 | |
| @@ -5077,11 +5110,18 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) · 277 unmodified lines | ||
| 5077 | 5110 | hcd->has_tt = 1; |
| 5078 | 5111 | } else { |
| 5079 | 5112 | /* |
| 5080 | − * Some 3.1 hosts return sbrn 0x30, use xhci supported protocol | |
| 5081 | − * minor revision instead of sbrn. Minor revision is a two digit | |
| 5082 | − * BCD containing minor and sub-minor numbers, only show minor. | |
| 5113 | + * Early xHCI 1.1 spec did not mention USB 3.1 capable hosts | |
| 5114 | + * should return 0x31 for sbrn, or that the minor revision | |
| 5115 | + * is a two digit BCD containig minor and sub-minor numbers. | |
| 5116 | + * This was later clarified in xHCI 1.2. | |
| 5117 | + * | |
| 5118 | + * Some USB 3.1 capable hosts therefore have sbrn 0x30, and | |
| 5119 | + * minor revision set to 0x1 instead of 0x10. | |
| 5083 | 5120 | */ |
| 5084 | − minor_rev = xhci->usb3_rhub.min_rev / 0x10; | |
| 5121 | + if (xhci->usb3_rhub.min_rev == 0x1) | |
| 5122 | + minor_rev = 1; | |
| 5123 | + else | |
| 5124 | + minor_rev = xhci->usb3_rhub.min_rev / 0x10; | |
| 5085 | 5125 | |
| 5086 | 5126 | switch (minor_rev) { |
| 5087 | 5127 | case 2: |
| @@ -5198,8 +5238,16 @@ static void xhci_clear_tt_buffer_complete(struct usb_hcd *hcd, · 110 unmodified lines | ||
| 5198 | 5238 | unsigned int ep_index; |
| 5199 | 5239 | unsigned long flags; |
| 5200 | 5240 | |
| 5241 | + /* | |
| 5242 | + * udev might be NULL if tt buffer is cleared during a failed device | |
| 5243 | + * enumeration due to a halted control endpoint. Usb core might | |
| 5244 | + * have allocated a new udev for the next enumeration attempt. | |
| 5245 | + */ | |
| 5246 | + | |
| 5201 | 5247 | xhci = hcd_to_xhci(hcd); |
| 5202 | 5248 | udev = (struct usb_device *)ep->hcpriv; |
| 5249 | + if (!udev) | |
| 5250 | + return; | |
| 5203 | 5251 | slot_id = udev->slot_id; |
| 5204 | 5252 | ep_index = xhci_get_endpoint_index(&ep->desc); |
| 5205 | 5253 | |
| @@ -716,6 +716,10 @@ static int mts_usb_probe(struct usb_interface *intf, · 715 unmodified lines | ||
| 716 | 716 | |
| 717 | 717 | } |
| 718 | 718 | |
| 719 | + if (ep_in_current != &ep_in_set[2]) { | |
| 720 | + MTS_WARNING("couldn't find two input bulk endpoints. Bailing out.\n"); | |
| 721 | + return -ENODEV; | |
| 722 | + } | |
| 719 | 723 | |
| 720 | 724 | if ( ep_out == -1 ) { |
| 721 | 725 | MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" ); |
| @@ -47,16 +47,6 @@ config USB_SEVSEG · 46 unmodified lines | ||
| 47 | 47 | To compile this driver as a module, choose M here: the |
| 48 | 48 | module will be called usbsevseg. |
| 49 | 49 | |
| 50 | −config USB_RIO500 | |
| 51 | − tristate "USB Diamond Rio500 support" | |
| 52 | − help | |
| 53 | − Say Y here if you want to connect a USB Rio500 mp3 player to your | |
| 54 | − computer's USB port. Please read <file:Documentation/usb/rio.rst> | |
| 55 | − for more information. | |
| 56 | − | |
| 57 | − To compile this driver as a module, choose M here: the | |
| 58 | − module will be called rio500. | |
| 59 | − | |
| 60 | 50 | config USB_LEGOTOWER |
| 61 | 51 | tristate "USB Lego Infrared Tower support" |
| 62 | 52 | help |
| @@ -17,7 +17,6 @@ obj-$(CONFIG_USB_ISIGHTFW) += isight_firmware.o · 16 unmodified lines | ||
| 17 | 17 | obj-$(CONFIG_USB_LCD) += usblcd.o |
| 18 | 18 | obj-$(CONFIG_USB_LD) += ldusb.o |
| 19 | 19 | obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o |
| 20 | −obj-$(CONFIG_USB_RIO500) += rio500.o | |
| 21 | 20 | obj-$(CONFIG_USB_TEST) += usbtest.o |
| 22 | 21 | obj-$(CONFIG_USB_EHSET_TEST_FIXTURE) += ehset.o |
| 23 | 22 | obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o |
| @@ -75,6 +75,7 @@ struct adu_device { · 74 unmodified lines | ||
| 75 | 75 | char serial_number[8]; |
| 76 | 76 | |
| 77 | 77 | int open_count; /* number of times this port has been opened */ |
| 78 | + unsigned long disconnected:1; | |
| 78 | 79 | |
| 79 | 80 | char *read_buffer_primary; |
| 80 | 81 | int read_buffer_length; |
| @@ -116,7 +117,7 @@ static void adu_abort_transfers(struct adu_device *dev) · 35 unmodified lines | ||
| 116 | 117 | { |
| 117 | 118 | unsigned long flags; |
| 118 | 119 | |
| 119 | − if (dev->udev == NULL) | |
| 120 | + if (dev->disconnected) | |
| 120 | 121 | return; |
| 121 | 122 | |
| 122 | 123 | /* shutdown transfer */ |
| @@ -148,6 +149,7 @@ static void adu_delete(struct adu_device *dev) · 25 unmodified lines | ||
| 148 | 149 | kfree(dev->read_buffer_secondary); |
| 149 | 150 | kfree(dev->interrupt_in_buffer); |
| 150 | 151 | kfree(dev->interrupt_out_buffer); |
| 152 | + usb_put_dev(dev->udev); | |
| 151 | 153 | kfree(dev); |
| 152 | 154 | } |
| 153 | 155 | |
| @@ -243,7 +245,7 @@ static int adu_open(struct inode *inode, struct file *file) · 89 unmodified lines | ||
| 243 | 245 | } |
| 244 | 246 | |
| 245 | 247 | dev = usb_get_intfdata(interface); |
| 246 | − if (!dev || !dev->udev) { | |
| 248 | + if (!dev) { | |
| 247 | 249 | retval = -ENODEV; |
| 248 | 250 | goto exit_no_device; |
| 249 | 251 | } |
| @@ -326,7 +328,7 @@ static int adu_release(struct inode *inode, struct file *file) · 76 unmodified lines | ||
| 326 | 328 | } |
| 327 | 329 | |
| 328 | 330 | adu_release_internal(dev); |
| 329 | − if (dev->udev == NULL) { | |
| 331 | + if (dev->disconnected) { | |
| 330 | 332 | /* the device was unplugged before the file was released */ |
| 331 | 333 | if (!dev->open_count) /* ... and we're the last user */ |
| 332 | 334 | adu_delete(dev); |
| @@ -354,7 +356,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, · 21 unmodified lines | ||
| 354 | 356 | return -ERESTARTSYS; |
| 355 | 357 | |
| 356 | 358 | /* verify that the device wasn't unplugged */ |
| 357 | − if (dev->udev == NULL) { | |
| 359 | + if (dev->disconnected) { | |
| 358 | 360 | retval = -ENODEV; |
| 359 | 361 | pr_err("No device or device unplugged %d\n", retval); |
| 360 | 362 | goto exit; |
| @@ -518,7 +520,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, · 157 unmodified lines | ||
| 518 | 520 | goto exit_nolock; |
| 519 | 521 | |
| 520 | 522 | /* verify that the device wasn't unplugged */ |
| 521 | − if (dev->udev == NULL) { | |
| 523 | + if (dev->disconnected) { | |
| 522 | 524 | retval = -ENODEV; |
| 523 | 525 | pr_err("No device or device unplugged %d\n", retval); |
| 524 | 526 | goto exit; |
| @@ -663,7 +665,7 @@ static int adu_probe(struct usb_interface *interface, · 138 unmodified lines | ||
| 663 | 665 | |
| 664 | 666 | mutex_init(&dev->mtx); |
| 665 | 667 | spin_lock_init(&dev->buflock); |
| 666 | − dev->udev = udev; | |
| 668 | + dev->udev = usb_get_dev(udev); | |
| 667 | 669 | init_waitqueue_head(&dev->read_wait); |
| 668 | 670 | init_waitqueue_head(&dev->write_wait); |
| 669 | 671 | |
| @@ -762,14 +764,18 @@ static void adu_disconnect(struct usb_interface *interface) · 92 unmodified lines | ||
| 762 | 764 | |
| 763 | 765 | dev = usb_get_intfdata(interface); |
| 764 | 766 | |
| 765 | − mutex_lock(&dev->mtx); /* not interruptible */ | |
| 766 | − dev->udev = NULL; /* poison */ | |
| 767 | 767 | usb_deregister_dev(interface, &adu_class); |
| 768 | − mutex_unlock(&dev->mtx); | |
| 768 | + | |
| 769 | + usb_poison_urb(dev->interrupt_in_urb); | |
| 770 | + usb_poison_urb(dev->interrupt_out_urb); | |
| 769 | 771 | |
| 770 | 772 | mutex_lock(&adutux_mutex); |
| 771 | 773 | usb_set_intfdata(interface, NULL); |
| 772 | 774 | |
| 775 | + mutex_lock(&dev->mtx); /* not interruptible */ | |
| 776 | + dev->disconnected = 1; | |
| 777 | + mutex_unlock(&dev->mtx); | |
| 778 | + | |
| 773 | 779 | /* if the device is not opened, then we clean up right now */ |
| 774 | 780 | if (!dev->open_count) |
| 775 | 781 | adu_delete(dev); |
| @@ -98,6 +98,7 @@ static void chaoskey_free(struct chaoskey *dev) · 97 unmodified lines | ||
| 98 | 98 | usb_free_urb(dev->urb); |
| 99 | 99 | kfree(dev->name); |
| 100 | 100 | kfree(dev->buf); |
| 101 | + usb_put_intf(dev->interface); | |
| 101 | 102 | kfree(dev); |
| 102 | 103 | } |
| 103 | 104 | } |
| @@ -145,6 +146,8 @@ static int chaoskey_probe(struct usb_interface *interface, · 41 unmodified lines | ||
| 145 | 146 | if (dev == NULL) |
| 146 | 147 | goto out; |
| 147 | 148 | |
| 149 | + dev->interface = usb_get_intf(interface); | |
| 150 | + | |
| 148 | 151 | dev->buf = kmalloc(size, GFP_KERNEL); |
| 149 | 152 | |
| 150 | 153 | if (dev->buf == NULL) |
| @@ -174,8 +177,6 @@ static int chaoskey_probe(struct usb_interface *interface, · 23 unmodified lines | ||
| 174 | 177 | goto out; |
| 175 | 178 | } |
| 176 | 179 | |
| 177 | − dev->interface = interface; | |
| 178 | − | |
| 179 | 180 | dev->in_ep = in_ep; |
| 180 | 181 | |
| 181 | 182 | if (le16_to_cpu(udev->descriptor.idVendor) != ALEA_VENDOR_ID) |
| @@ -54,11 +54,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR); · 53 unmodified lines | ||
| 54 | 54 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 55 | 55 | MODULE_LICENSE("GPL"); |
| 56 | 56 | |
| 57 | −/* Module parameters */ | |
| 58 | −static DEFINE_MUTEX(iowarrior_mutex); | |
| 59 | − | |
| 60 | 57 | static struct usb_driver iowarrior_driver; |
| 61 | −static DEFINE_MUTEX(iowarrior_open_disc_lock); | |
| 62 | 58 | |
| 63 | 59 | /*--------------*/ |
| 64 | 60 | /* data */ |
| @@ -87,6 +83,7 @@ struct iowarrior { · 22 unmodified lines | ||
| 87 | 83 | char chip_serial[9]; /* the serial number string of the chip connected */ |
| 88 | 84 | int report_size; /* number of bytes in a report */ |
| 89 | 85 | u16 product_id; |
| 86 | + struct usb_anchor submitted; | |
| 90 | 87 | }; |
| 91 | 88 | |
| 92 | 89 | /*--------------*/ |
| @@ -243,6 +240,7 @@ static inline void iowarrior_delete(struct iowarrior *dev) · 150 unmodified lines | ||
| 243 | 240 | kfree(dev->int_in_buffer); |
| 244 | 241 | usb_free_urb(dev->int_in_urb); |
| 245 | 242 | kfree(dev->read_queue); |
| 243 | + usb_put_intf(dev->interface); | |
| 246 | 244 | kfree(dev); |
| 247 | 245 | } |
| 248 | 246 | |
| @@ -424,11 +422,13 @@ static ssize_t iowarrior_write(struct file *file, · 175 unmodified lines | ||
| 424 | 422 | retval = -EFAULT; |
| 425 | 423 | goto error; |
| 426 | 424 | } |
| 425 | + usb_anchor_urb(int_out_urb, &dev->submitted); | |
| 427 | 426 | retval = usb_submit_urb(int_out_urb, GFP_KERNEL); |
| 428 | 427 | if (retval) { |
| 429 | 428 | dev_dbg(&dev->interface->dev, |
| 430 | 429 | "submit error %d for urb nr.%d\n", |
| 431 | 430 | retval, atomic_read(&dev->write_busy)); |
| 431 | + usb_unanchor_urb(int_out_urb); | |
| 432 | 432 | goto error; |
| 433 | 433 | } |
| 434 | 434 | /* submit was ok */ |
| @@ -477,8 +477,6 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, · 42 unmodified lines | ||
| 477 | 477 | if (!buffer) |
| 478 | 478 | return -ENOMEM; |
| 479 | 479 | |
| 480 | − /* lock this object */ | |
| 481 | − mutex_lock(&iowarrior_mutex); | |
| 482 | 480 | mutex_lock(&dev->mutex); |
| 483 | 481 | |
| 484 | 482 | /* verify that the device wasn't unplugged */ |
| @@ -571,7 +569,6 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, · 86 unmodified lines | ||
| 571 | 569 | error_out: |
| 572 | 570 | /* unlock the device */ |
| 573 | 571 | mutex_unlock(&dev->mutex); |
| 574 | − mutex_unlock(&iowarrior_mutex); | |
| 575 | 572 | kfree(buffer); |
| 576 | 573 | return retval; |
| 577 | 574 | } |
| @@ -586,27 +583,20 @@ static int iowarrior_open(struct inode *inode, struct file *file) · 8 unmodified lines | ||
| 586 | 583 | int subminor; |
| 587 | 584 | int retval = 0; |
| 588 | 585 | |
| 589 | − mutex_lock(&iowarrior_mutex); | |
| 590 | 586 | subminor = iminor(inode); |
| 591 | 587 | |
| 592 | 588 | interface = usb_find_interface(&iowarrior_driver, subminor); |
| 593 | 589 | if (!interface) { |
| 594 | − mutex_unlock(&iowarrior_mutex); | |
| 595 | − printk(KERN_ERR "%s - error, can't find device for minor %d\n", | |
| 590 | + pr_err("%s - error, can't find device for minor %d\n", | |
| 596 | 591 | __func__, subminor); |
| 597 | 592 | return -ENODEV; |
| 598 | 593 | } |
| 599 | 594 | |
| 600 | − mutex_lock(&iowarrior_open_disc_lock); | |
| 601 | 595 | dev = usb_get_intfdata(interface); |
| 602 | − if (!dev) { | |
| 603 | − mutex_unlock(&iowarrior_open_disc_lock); | |
| 604 | − mutex_unlock(&iowarrior_mutex); | |
| 596 | + if (!dev) | |
| 605 | 597 | return -ENODEV; |
| 606 | − } | |
| 607 | 598 | |
| 608 | 599 | mutex_lock(&dev->mutex); |
| 609 | − mutex_unlock(&iowarrior_open_disc_lock); | |
| 610 | 600 | |
| 611 | 601 | /* Only one process can open each device, no sharing. */ |
| 612 | 602 | if (dev->opened) { |
| @@ -628,7 +618,6 @@ static int iowarrior_open(struct inode *inode, struct file *file) · 15 unmodified lines | ||
| 628 | 618 | |
| 629 | 619 | out: |
| 630 | 620 | mutex_unlock(&dev->mutex); |
| 631 | − mutex_unlock(&iowarrior_mutex); | |
| 632 | 621 | return retval; |
| 633 | 622 | } |
| 634 | 623 | |
| @@ -764,11 +753,13 @@ static int iowarrior_probe(struct usb_interface *interface, · 129 unmodified lines | ||
| 764 | 753 | init_waitqueue_head(&dev->write_wait); |
| 765 | 754 | |
| 766 | 755 | dev->udev = udev; |
| 767 | − dev->interface = interface; | |
| 756 | + dev->interface = usb_get_intf(interface); | |
| 768 | 757 | |
| 769 | 758 | iface_desc = interface->cur_altsetting; |
| 770 | 759 | dev->product_id = le16_to_cpu(udev->descriptor.idProduct); |
| 771 | 760 | |
| 761 | + init_usb_anchor(&dev->submitted); | |
| 762 | + | |
| 772 | 763 | res = usb_find_last_int_in_endpoint(iface_desc, &dev->int_in_endpoint); |
| 773 | 764 | if (res) { |
| 774 | 765 | dev_err(&interface->dev, "no interrupt-in endpoint found\n"); |
| @@ -836,7 +827,6 @@ static int iowarrior_probe(struct usb_interface *interface, · 61 unmodified lines | ||
| 836 | 827 | if (retval) { |
| 837 | 828 | /* something prevented us from registering this driver */ |
| 838 | 829 | dev_err(&interface->dev, "Not able to get a minor for this device.\n"); |
| 839 | − usb_set_intfdata(interface, NULL); | |
| 840 | 830 | goto error; |
| 841 | 831 | } |
| 842 | 832 | |
| @@ -860,26 +850,15 @@ error: · 17 unmodified lines | ||
| 860 | 850 | */ |
| 861 | 851 | static void iowarrior_disconnect(struct usb_interface *interface) |
| 862 | 852 | { |
| 863 | − struct iowarrior *dev; | |
| 864 | − int minor; | |
| 865 | − | |
| 866 | − dev = usb_get_intfdata(interface); | |
| 867 | − mutex_lock(&iowarrior_open_disc_lock); | |
| 868 | − usb_set_intfdata(interface, NULL); | |
| 869 | − /* prevent device read, write and ioctl */ | |
| 870 | − dev->present = 0; | |
| 871 | − | |
| 872 | − minor = dev->minor; | |
| 873 | − mutex_unlock(&iowarrior_open_disc_lock); | |
| 874 | − /* give back our minor - this will call close() locks need to be dropped at this point*/ | |
| 853 | + struct iowarrior *dev = usb_get_intfdata(interface); | |
| 854 | + int minor = dev->minor; | |
| 875 | 855 | |
| 876 | 856 | usb_deregister_dev(interface, &iowarrior_class); |
| 877 | 857 | |
| 878 | 858 | mutex_lock(&dev->mutex); |
| 879 | 859 | |
| 880 | 860 | /* prevent device read, write and ioctl */ |
| 881 | − | |
| 882 | − mutex_unlock(&dev->mutex); | |
| 861 | + dev->present = 0; | |
| 883 | 862 | |
| 884 | 863 | if (dev->opened) { |
| 885 | 864 | /* There is a process that holds a filedescriptor to the device , |
| @@ -887,10 +866,13 @@ static void iowarrior_disconnect(struct usb_interface *interface) · 1 unmodified line | ||
| 887 | 866 | Deleting the device is postponed until close() was called. |
| 888 | 867 | */ |
| 889 | 868 | usb_kill_urb(dev->int_in_urb); |
| 869 | + usb_kill_anchored_urbs(&dev->submitted); | |
| 890 | 870 | wake_up_interruptible(&dev->read_wait); |
| 891 | 871 | wake_up_interruptible(&dev->write_wait); |
| 872 | + mutex_unlock(&dev->mutex); | |
| 892 | 873 | } else { |
| 893 | 874 | /* no process is using the device, cleanup now */ |
| 875 | + mutex_unlock(&dev->mutex); | |
| 894 | 876 | iowarrior_delete(dev); |
| 895 | 877 | } |
| 896 | 878 | |
| @@ -153,6 +153,7 @@ MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in · 152 unmodified lines | ||
| 153 | 153 | struct ld_usb { |
| 154 | 154 | struct mutex mutex; /* locks this structure */ |
| 155 | 155 | struct usb_interface *intf; /* save off the usb interface pointer */ |
| 156 | + unsigned long disconnected:1; | |
| 156 | 157 | |
| 157 | 158 | int open_count; /* number of times this port has been opened */ |
| 158 | 159 | |
| @@ -192,12 +193,10 @@ static void ld_usb_abort_transfers(struct ld_usb *dev) · 33 unmodified lines | ||
| 192 | 193 | /* shutdown transfer */ |
| 193 | 194 | if (dev->interrupt_in_running) { |
| 194 | 195 | dev->interrupt_in_running = 0; |
| 195 | − if (dev->intf) | |
| 196 | − usb_kill_urb(dev->interrupt_in_urb); | |
| 196 | + usb_kill_urb(dev->interrupt_in_urb); | |
| 197 | 197 | } |
| 198 | 198 | if (dev->interrupt_out_busy) |
| 199 | − if (dev->intf) | |
| 200 | − usb_kill_urb(dev->interrupt_out_urb); | |
| 199 | + usb_kill_urb(dev->interrupt_out_urb); | |
| 201 | 200 | } |
| 202 | 201 | |
| 203 | 202 | /** |
| @@ -205,8 +204,6 @@ static void ld_usb_abort_transfers(struct ld_usb *dev) · 1 unmodified line | ||
| 205 | 204 | */ |
| 206 | 205 | static void ld_usb_delete(struct ld_usb *dev) |
| 207 | 206 | { |
| 208 | − ld_usb_abort_transfers(dev); | |
| 209 | − | |
| 210 | 207 | /* free data structures */ |
| 211 | 208 | usb_free_urb(dev->interrupt_in_urb); |
| 212 | 209 | usb_free_urb(dev->interrupt_out_urb); |
| @@ -263,7 +260,7 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) · 50 unmodified lines | ||
| 263 | 260 | |
| 264 | 261 | resubmit: |
| 265 | 262 | /* resubmit if we're still running */ |
| 266 | − if (dev->interrupt_in_running && !dev->buffer_overflow && dev->intf) { | |
| 263 | + if (dev->interrupt_in_running && !dev->buffer_overflow) { | |
| 267 | 264 | retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); |
| 268 | 265 | if (retval) { |
| 269 | 266 | dev_err(&dev->intf->dev, |
| @@ -392,7 +389,7 @@ static int ld_usb_release(struct inode *inode, struct file *file) · 122 unmodified lines | ||
| 392 | 389 | retval = -ENODEV; |
| 393 | 390 | goto unlock_exit; |
| 394 | 391 | } |
| 395 | − if (dev->intf == NULL) { | |
| 392 | + if (dev->disconnected) { | |
| 396 | 393 | /* the device was unplugged before the file was released */ |
| 397 | 394 | mutex_unlock(&dev->mutex); |
| 398 | 395 | /* unlock here as ld_usb_delete frees dev */ |
| @@ -423,7 +420,7 @@ static __poll_t ld_usb_poll(struct file *file, poll_table *wait) · 24 unmodified lines | ||
| 423 | 420 | |
| 424 | 421 | dev = file->private_data; |
| 425 | 422 | |
| 426 | − if (!dev->intf) | |
| 423 | + if (dev->disconnected) | |
| 427 | 424 | return EPOLLERR | EPOLLHUP; |
| 428 | 425 | |
| 429 | 426 | poll_wait(file, &dev->read_wait, wait); |
| @@ -462,7 +459,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, · 32 unmodified lines | ||
| 462 | 459 | } |
| 463 | 460 | |
| 464 | 461 | /* verify that the device wasn't unplugged */ |
| 465 | − if (dev->intf == NULL) { | |
| 462 | + if (dev->disconnected) { | |
| 466 | 463 | retval = -ENODEV; |
| 467 | 464 | printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval); |
| 468 | 465 | goto unlock_exit; |
| @@ -542,7 +539,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer, · 73 unmodified lines | ||
| 542 | 539 | } |
| 543 | 540 | |
| 544 | 541 | /* verify that the device wasn't unplugged */ |
| 545 | − if (dev->intf == NULL) { | |
| 542 | + if (dev->disconnected) { | |
| 546 | 543 | retval = -ENODEV; |
| 547 | 544 | printk(KERN_ERR "ldusb: No device or device unplugged %d\n", retval); |
| 548 | 545 | goto unlock_exit; |
| @@ -764,6 +761,9 @@ static void ld_usb_disconnect(struct usb_interface *intf) · 215 unmodified lines | ||
| 764 | 761 | /* give back our minor */ |
| 765 | 762 | usb_deregister_dev(intf, &ld_usb_class); |
| 766 | 763 | |
| 764 | + usb_poison_urb(dev->interrupt_in_urb); | |
| 765 | + usb_poison_urb(dev->interrupt_out_urb); | |
| 766 | + | |
| 767 | 767 | mutex_lock(&dev->mutex); |
| 768 | 768 | |
| 769 | 769 | /* if the device is not opened, then we clean up right now */ |
| @@ -771,7 +771,7 @@ static void ld_usb_disconnect(struct usb_interface *intf) · 1 unmodified line | ||
| 771 | 771 | mutex_unlock(&dev->mutex); |
| 772 | 772 | ld_usb_delete(dev); |
| 773 | 773 | } else { |
| 774 | − dev->intf = NULL; | |
| 774 | + dev->disconnected = 1; | |
| 775 | 775 | /* wake up pollers */ |
| 776 | 776 | wake_up_interruptible_all(&dev->read_wait); |
| 777 | 777 | wake_up_interruptible_all(&dev->write_wait); |
| @@ -179,7 +179,6 @@ static const struct usb_device_id tower_table[] = { · 178 unmodified lines | ||
| 179 | 179 | }; |
| 180 | 180 | |
| 181 | 181 | MODULE_DEVICE_TABLE (usb, tower_table); |
| 182 | −static DEFINE_MUTEX(open_disc_mutex); | |
| 183 | 182 | |
| 184 | 183 | #define LEGO_USB_TOWER_MINOR_BASE 160 |
| 185 | 184 | |
| @@ -191,6 +190,7 @@ struct lego_usb_tower { · 5 unmodified lines | ||
| 191 | 190 | unsigned char minor; /* the starting minor number for this device */ |
| 192 | 191 | |
| 193 | 192 | int open_count; /* number of times this port has been opened */ |
| 193 | + unsigned long disconnected:1; | |
| 194 | 194 | |
| 195 | 195 | char* read_buffer; |
| 196 | 196 | size_t read_buffer_length; /* this much came in */ |
| @@ -290,14 +290,13 @@ static inline void lego_usb_tower_debug_data(struct device *dev, · 93 unmodified lines | ||
| 290 | 290 | */ |
| 291 | 291 | static inline void tower_delete (struct lego_usb_tower *dev) |
| 292 | 292 | { |
| 293 | − tower_abort_transfers (dev); | |
| 294 | − | |
| 295 | 293 | /* free data structures */ |
| 296 | 294 | usb_free_urb(dev->interrupt_in_urb); |
| 297 | 295 | usb_free_urb(dev->interrupt_out_urb); |
| 298 | 296 | kfree (dev->read_buffer); |
| 299 | 297 | kfree (dev->interrupt_in_buffer); |
| 300 | 298 | kfree (dev->interrupt_out_buffer); |
| 299 | + usb_put_dev(dev->udev); | |
| 301 | 300 | kfree (dev); |
| 302 | 301 | } |
| 303 | 302 | |
| @@ -332,18 +331,14 @@ static int tower_open (struct inode *inode, struct file *file) · 28 unmodified lines | ||
| 332 | 331 | goto exit; |
| 333 | 332 | } |
| 334 | 333 | |
| 335 | − mutex_lock(&open_disc_mutex); | |
| 336 | 334 | dev = usb_get_intfdata(interface); |
| 337 | − | |
| 338 | 335 | if (!dev) { |
| 339 | − mutex_unlock(&open_disc_mutex); | |
| 340 | 336 | retval = -ENODEV; |
| 341 | 337 | goto exit; |
| 342 | 338 | } |
| 343 | 339 | |
| 344 | 340 | /* lock this device */ |
| 345 | 341 | if (mutex_lock_interruptible(&dev->lock)) { |
| 346 | − mutex_unlock(&open_disc_mutex); | |
| 347 | 342 | retval = -ERESTARTSYS; |
| 348 | 343 | goto exit; |
| 349 | 344 | } |
| @@ -351,12 +346,9 @@ static int tower_open (struct inode *inode, struct file *file) · 1 unmodified line | ||
| 351 | 346 | |
| 352 | 347 | /* allow opening only once */ |
| 353 | 348 | if (dev->open_count) { |
| 354 | − mutex_unlock(&open_disc_mutex); | |
| 355 | 349 | retval = -EBUSY; |
| 356 | 350 | goto unlock_exit; |
| 357 | 351 | } |
| 358 | − dev->open_count = 1; | |
| 359 | − mutex_unlock(&open_disc_mutex); | |
| 360 | 352 | |
| 361 | 353 | /* reset the tower */ |
| 362 | 354 | result = usb_control_msg (dev->udev, |
| @@ -396,13 +388,14 @@ static int tower_open (struct inode *inode, struct file *file) · 33 unmodified lines | ||
| 396 | 388 | dev_err(&dev->udev->dev, |
| 397 | 389 | "Couldn't submit interrupt_in_urb %d\n", retval); |
| 398 | 390 | dev->interrupt_in_running = 0; |
| 399 | − dev->open_count = 0; | |
| 400 | 391 | goto unlock_exit; |
| 401 | 392 | } |
| 402 | 393 | |
| 403 | 394 | /* save device in the file's private structure */ |
| 404 | 395 | file->private_data = dev; |
| 405 | 396 | |
| 397 | + dev->open_count = 1; | |
| 398 | + | |
| 406 | 399 | unlock_exit: |
| 407 | 400 | mutex_unlock(&dev->lock); |
| 408 | 401 | |
| @@ -423,10 +416,9 @@ static int tower_release (struct inode *inode, struct file *file) · 14 unmodified lines | ||
| 423 | 416 | |
| 424 | 417 | if (dev == NULL) { |
| 425 | 418 | retval = -ENODEV; |
| 426 | − goto exit_nolock; | |
| 419 | + goto exit; | |
| 427 | 420 | } |
| 428 | 421 | |
| 429 | − mutex_lock(&open_disc_mutex); | |
| 430 | 422 | if (mutex_lock_interruptible(&dev->lock)) { |
| 431 | 423 | retval = -ERESTARTSYS; |
| 432 | 424 | goto exit; |
| @@ -438,7 +430,8 @@ static int tower_release (struct inode *inode, struct file *file) · 5 unmodified lines | ||
| 438 | 430 | retval = -ENODEV; |
| 439 | 431 | goto unlock_exit; |
| 440 | 432 | } |
| 441 | − if (dev->udev == NULL) { | |
| 433 | + | |
| 434 | + if (dev->disconnected) { | |
| 442 | 435 | /* the device was unplugged before the file was released */ |
| 443 | 436 | |
| 444 | 437 | /* unlock here as tower_delete frees dev */ |
| @@ -456,10 +449,7 @@ static int tower_release (struct inode *inode, struct file *file) · 11 unmodified lines | ||
| 456 | 449 | |
| 457 | 450 | unlock_exit: |
| 458 | 451 | mutex_unlock(&dev->lock); |
| 459 | − | |
| 460 | 452 | exit: |
| 461 | − mutex_unlock(&open_disc_mutex); | |
| 462 | −exit_nolock: | |
| 463 | 453 | return retval; |
| 464 | 454 | } |
| 465 | 455 | |
| @@ -477,10 +467,9 @@ static void tower_abort_transfers (struct lego_usb_tower *dev) · 11 unmodified lines | ||
| 477 | 467 | if (dev->interrupt_in_running) { |
| 478 | 468 | dev->interrupt_in_running = 0; |
| 479 | 469 | mb(); |
| 480 | − if (dev->udev) | |
| 481 | − usb_kill_urb (dev->interrupt_in_urb); | |
| 470 | + usb_kill_urb(dev->interrupt_in_urb); | |
| 482 | 471 | } |
| 483 | − if (dev->interrupt_out_busy && dev->udev) | |
| 472 | + if (dev->interrupt_out_busy) | |
| 484 | 473 | usb_kill_urb(dev->interrupt_out_urb); |
| 485 | 474 | } |
| 486 | 475 | |
| @@ -516,7 +505,7 @@ static __poll_t tower_poll (struct file *file, poll_table *wait) · 29 unmodified lines | ||
| 516 | 505 | |
| 517 | 506 | dev = file->private_data; |
| 518 | 507 | |
| 519 | − if (!dev->udev) | |
| 508 | + if (dev->disconnected) | |
| 520 | 509 | return EPOLLERR | EPOLLHUP; |
| 521 | 510 | |
| 522 | 511 | poll_wait(file, &dev->read_wait, wait); |
| @@ -563,7 +552,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, · 40 unmodified lines | ||
| 563 | 552 | } |
| 564 | 553 | |
| 565 | 554 | /* verify that the device wasn't unplugged */ |
| 566 | − if (dev->udev == NULL) { | |
| 555 | + if (dev->disconnected) { | |
| 567 | 556 | retval = -ENODEV; |
| 568 | 557 | pr_err("No device or device unplugged %d\n", retval); |
| 569 | 558 | goto unlock_exit; |
| @@ -649,7 +638,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t · 79 unmodified lines | ||
| 649 | 638 | } |
| 650 | 639 | |
| 651 | 640 | /* verify that the device wasn't unplugged */ |
| 652 | − if (dev->udev == NULL) { | |
| 641 | + if (dev->disconnected) { | |
| 653 | 642 | retval = -ENODEV; |
| 654 | 643 | pr_err("No device or device unplugged %d\n", retval); |
| 655 | 644 | goto unlock_exit; |
| @@ -759,7 +748,7 @@ static void tower_interrupt_in_callback (struct urb *urb) · 103 unmodified lines | ||
| 759 | 748 | |
| 760 | 749 | resubmit: |
| 761 | 750 | /* resubmit if we're still running */ |
| 762 | − if (dev->interrupt_in_running && dev->udev) { | |
| 751 | + if (dev->interrupt_in_running) { | |
| 763 | 752 | retval = usb_submit_urb (dev->interrupt_in_urb, GFP_ATOMIC); |
| 764 | 753 | if (retval) |
| 765 | 754 | dev_err(&dev->udev->dev, |
| @@ -822,8 +811,9 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device · 56 unmodified lines | ||
| 822 | 811 | |
| 823 | 812 | mutex_init(&dev->lock); |
| 824 | 813 | |
| 825 | − dev->udev = udev; | |
| 814 | + dev->udev = usb_get_dev(udev); | |
| 826 | 815 | dev->open_count = 0; |
| 816 | + dev->disconnected = 0; | |
| 827 | 817 | |
| 828 | 818 | dev->read_buffer = NULL; |
| 829 | 819 | dev->read_buffer_length = 0; |
| @@ -891,8 +881,10 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device · 61 unmodified lines | ||
| 891 | 881 | get_version_reply, |
| 892 | 882 | sizeof(*get_version_reply), |
| 893 | 883 | 1000); |
| 894 | − if (result < 0) { | |
| 895 | − dev_err(idev, "LEGO USB Tower get version control request failed\n"); | |
| 884 | + if (result < sizeof(*get_version_reply)) { | |
| 885 | + if (result >= 0) | |
| 886 | + result = -EIO; | |
| 887 | + dev_err(idev, "get version request failed: %d\n", result); | |
| 896 | 888 | retval = result; |
| 897 | 889 | goto error; |
| 898 | 890 | } |
| @@ -910,7 +902,6 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device · 11 unmodified lines | ||
| 910 | 902 | if (retval) { |
| 911 | 903 | /* something prevented us from registering this driver */ |
| 912 | 904 | dev_err(idev, "Not able to get a minor for this device.\n"); |
| 913 | − usb_set_intfdata (interface, NULL); | |
| 914 | 905 | goto error; |
| 915 | 906 | } |
| 916 | 907 | dev->minor = interface->minor; |
| @@ -942,23 +933,24 @@ static void tower_disconnect (struct usb_interface *interface) · 25 unmodified lines | ||
| 942 | 933 | int minor; |
| 943 | 934 | |
| 944 | 935 | dev = usb_get_intfdata (interface); |
| 945 | − mutex_lock(&open_disc_mutex); | |
| 946 | − usb_set_intfdata (interface, NULL); | |
| 947 | 936 | |
| 948 | 937 | minor = dev->minor; |
| 949 | 938 | |
| 950 | − /* give back our minor */ | |
| 939 | + /* give back our minor and prevent further open() */ | |
| 951 | 940 | usb_deregister_dev (interface, &tower_class); |
| 952 | 941 | |
| 942 | + /* stop I/O */ | |
| 943 | + usb_poison_urb(dev->interrupt_in_urb); | |
| 944 | + usb_poison_urb(dev->interrupt_out_urb); | |
| 945 | + | |
| 953 | 946 | mutex_lock(&dev->lock); |
| 954 | − mutex_unlock(&open_disc_mutex); | |
| 955 | 947 | |
| 956 | 948 | /* if the device is not opened, then we clean up right now */ |
| 957 | 949 | if (!dev->open_count) { |
| 958 | 950 | mutex_unlock(&dev->lock); |
| 959 | 951 | tower_delete (dev); |
| 960 | 952 | } else { |
| 961 | − dev->udev = NULL; | |
| 953 | + dev->disconnected = 1; | |
| 962 | 954 | /* wake up pollers */ |
| 963 | 955 | wake_up_interruptible_all(&dev->read_wait); |
| 964 | 956 | wake_up_interruptible_all(&dev->write_wait); |
| @@ -1,554 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0+ | |
| 2 | −/* -*- linux-c -*- */ | |
| 3 | − | |
| 4 | −/* | |
| 5 | − * Driver for USB Rio 500 | |
| 6 | − * | |
| 7 | − * Cesar Miquel (miquel@df.uba.ar) | |
| 8 | − * | |
| 9 | − * based on hp_scanner.c by David E. Nelson (dnelson@jump.net) | |
| 10 | − * | |
| 11 | − * Based upon mouse.c (Brad Keryan) and printer.c (Michael Gee). | |
| 12 | − * | |
| 13 | − * Changelog: | |
| 14 | − * 30/05/2003 replaced lock/unlock kernel with up/down | |
| 15 | − * Daniele Bellucci bellucda@tiscali.it | |
| 16 | − * */ | |
| 17 | − | |
| 18 | −#include <linux/module.h> | |
| 19 | −#include <linux/kernel.h> | |
| 20 | −#include <linux/signal.h> | |
| 21 | −#include <linux/sched/signal.h> | |
| 22 | −#include <linux/mutex.h> | |
| 23 | −#include <linux/errno.h> | |
| 24 | −#include <linux/random.h> | |
| 25 | −#include <linux/poll.h> | |
| 26 | −#include <linux/slab.h> | |
| 27 | −#include <linux/spinlock.h> | |
| 28 | −#include <linux/usb.h> | |
| 29 | −#include <linux/wait.h> | |
| 30 | − | |
| 31 | −#include "rio500_usb.h" | |
| 32 | − | |
| 33 | −#define DRIVER_AUTHOR "Cesar Miquel <miquel@df.uba.ar>" | |
| 34 | −#define DRIVER_DESC "USB Rio 500 driver" | |
| 35 | − | |
| 36 | −#define RIO_MINOR 64 | |
| 37 | − | |
| 38 | −/* stall/wait timeout for rio */ | |
| 39 | −#define NAK_TIMEOUT (HZ) | |
| 40 | − | |
| 41 | −#define IBUF_SIZE 0x1000 | |
| 42 | − | |
| 43 | −/* Size of the rio buffer */ | |
| 44 | −#define OBUF_SIZE 0x10000 | |
| 45 | − | |
| 46 | −struct rio_usb_data { | |
| 47 | − struct usb_device *rio_dev; /* init: probe_rio */ | |
| 48 | − unsigned int ifnum; /* Interface number of the USB device */ | |
| 49 | − int isopen; /* nz if open */ | |
| 50 | − int present; /* Device is present on the bus */ | |
| 51 | − char *obuf, *ibuf; /* transfer buffers */ | |
| 52 | − char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ | |
| 53 | − wait_queue_head_t wait_q; /* for timeouts */ | |
| 54 | −}; | |
| 55 | − | |
| 56 | −static DEFINE_MUTEX(rio500_mutex); | |
| 57 | −static struct rio_usb_data rio_instance; | |
| 58 | − | |
| 59 | −static int open_rio(struct inode *inode, struct file *file) | |
| 60 | −{ | |
| 61 | − struct rio_usb_data *rio = &rio_instance; | |
| 62 | − | |
| 63 | − /* against disconnect() */ | |
| 64 | − mutex_lock(&rio500_mutex); | |
| 65 | − | |
| 66 | − if (rio->isopen || !rio->present) { | |
| 67 | − mutex_unlock(&rio500_mutex); | |
| 68 | − return -EBUSY; | |
| 69 | − } | |
| 70 | − rio->isopen = 1; | |
| 71 | − | |
| 72 | − init_waitqueue_head(&rio->wait_q); | |
| 73 | − | |
| 74 | − | |
| 75 | − dev_info(&rio->rio_dev->dev, "Rio opened.\n"); | |
| 76 | − mutex_unlock(&rio500_mutex); | |
| 77 | − | |
| 78 | − return 0; | |
| 79 | −} | |
| 80 | − | |
| 81 | −static int close_rio(struct inode *inode, struct file *file) | |
| 82 | −{ | |
| 83 | − struct rio_usb_data *rio = &rio_instance; | |
| 84 | − | |
| 85 | − /* against disconnect() */ | |
| 86 | − mutex_lock(&rio500_mutex); | |
| 87 | − | |
| 88 | − rio->isopen = 0; | |
| 89 | − if (!rio->present) { | |
| 90 | − /* cleanup has been delayed */ | |
| 91 | − kfree(rio->ibuf); | |
| 92 | − kfree(rio->obuf); | |
| 93 | − rio->ibuf = NULL; | |
| 94 | − rio->obuf = NULL; | |
| 95 | − } else { | |
| 96 | − dev_info(&rio->rio_dev->dev, "Rio closed.\n"); | |
| 97 | − } | |
| 98 | − mutex_unlock(&rio500_mutex); | |
| 99 | − return 0; | |
| 100 | −} | |
| 101 | − | |
| 102 | −static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg) | |
| 103 | −{ | |
| 104 | − struct RioCommand rio_cmd; | |
| 105 | − struct rio_usb_data *rio = &rio_instance; | |
| 106 | − void __user *data; | |
| 107 | − unsigned char *buffer; | |
| 108 | − int result, requesttype; | |
| 109 | − int retries; | |
| 110 | − int retval=0; | |
| 111 | − | |
| 112 | − mutex_lock(&rio500_mutex); | |
| 113 | − /* Sanity check to make sure rio is connected, powered, etc */ | |
| 114 | − if (rio->present == 0 || rio->rio_dev == NULL) { | |
| 115 | − retval = -ENODEV; | |
| 116 | − goto err_out; | |
| 117 | − } | |
| 118 | − | |
| 119 | − switch (cmd) { | |
| 120 | − case RIO_RECV_COMMAND: | |
| 121 | − data = (void __user *) arg; | |
| 122 | − if (data == NULL) | |
| 123 | − break; | |
| 124 | − if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { | |
| 125 | − retval = -EFAULT; | |
| 126 | − goto err_out; | |
| 127 | − } | |
| 128 | − if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) { | |
| 129 | − retval = -EINVAL; | |
| 130 | − goto err_out; | |
| 131 | − } | |
| 132 | − buffer = (unsigned char *) __get_free_page(GFP_KERNEL); | |
| 133 | − if (buffer == NULL) { | |
| 134 | − retval = -ENOMEM; | |
| 135 | − goto err_out; | |
| 136 | − } | |
| 137 | − if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) { | |
| 138 | − retval = -EFAULT; | |
| 139 | − free_page((unsigned long) buffer); | |
| 140 | − goto err_out; | |
| 141 | − } | |
| 142 | − | |
| 143 | − requesttype = rio_cmd.requesttype | USB_DIR_IN | | |
| 144 | − USB_TYPE_VENDOR | USB_RECIP_DEVICE; | |
| 145 | − dev_dbg(&rio->rio_dev->dev, | |
| 146 | − "sending command:reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n", | |
| 147 | − requesttype, rio_cmd.request, rio_cmd.value, | |
| 148 | − rio_cmd.index, rio_cmd.length); | |
| 149 | − /* Send rio control message */ | |
| 150 | − retries = 3; | |
| 151 | − while (retries) { | |
| 152 | − result = usb_control_msg(rio->rio_dev, | |
| 153 | − usb_rcvctrlpipe(rio-> rio_dev, 0), | |
| 154 | − rio_cmd.request, | |
| 155 | − requesttype, | |
| 156 | − rio_cmd.value, | |
| 157 | − rio_cmd.index, buffer, | |
| 158 | − rio_cmd.length, | |
| 159 | − jiffies_to_msecs(rio_cmd.timeout)); | |
| 160 | − if (result == -ETIMEDOUT) | |
| 161 | − retries--; | |
| 162 | − else if (result < 0) { | |
| 163 | − dev_err(&rio->rio_dev->dev, | |
| 164 | − "Error executing ioctrl. code = %d\n", | |
| 165 | − result); | |
| 166 | − retries = 0; | |
| 167 | − } else { | |
| 168 | − dev_dbg(&rio->rio_dev->dev, | |
| 169 | − "Executed ioctl. Result = %d (data=%02x)\n", | |
| 170 | − result, buffer[0]); | |
| 171 | − if (copy_to_user(rio_cmd.buffer, buffer, | |
| 172 | − rio_cmd.length)) { | |
| 173 | − free_page((unsigned long) buffer); | |
| 174 | − retval = -EFAULT; | |
| 175 | − goto err_out; | |
| 176 | − } | |
| 177 | − retries = 0; | |
| 178 | − } | |
| 179 | − | |
| 180 | − /* rio_cmd.buffer contains a raw stream of single byte | |
| 181 | − data which has been returned from rio. Data is | |
| 182 | − interpreted at application level. For data that | |
| 183 | − will be cast to data types longer than 1 byte, data | |
| 184 | − will be little_endian and will potentially need to | |
| 185 | − be swapped at the app level */ | |
| 186 | − | |
| 187 | − } | |
| 188 | − free_page((unsigned long) buffer); | |
| 189 | − break; | |
| 190 | − | |
| 191 | − case RIO_SEND_COMMAND: | |
| 192 | − data = (void __user *) arg; | |
| 193 | − if (data == NULL) | |
| 194 | − break; | |
| 195 | − if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) { | |
| 196 | − retval = -EFAULT; | |
| 197 | − goto err_out; | |
| 198 | − } | |
| 199 | − if (rio_cmd.length < 0 || rio_cmd.length > PAGE_SIZE) { | |
| 200 | − retval = -EINVAL; | |
| 201 | − goto err_out; | |
| 202 | − } | |
| 203 | − buffer = (unsigned char *) __get_free_page(GFP_KERNEL); | |
| 204 | − if (buffer == NULL) { | |
| 205 | − retval = -ENOMEM; | |
| 206 | − goto err_out; | |
| 207 | − } | |
| 208 | − if (copy_from_user(buffer, rio_cmd.buffer, rio_cmd.length)) { | |
| 209 | − free_page((unsigned long)buffer); | |
| 210 | − retval = -EFAULT; | |
| 211 | − goto err_out; | |
| 212 | − } | |
| 213 | − | |
| 214 | − requesttype = rio_cmd.requesttype | USB_DIR_OUT | | |
| 215 | − USB_TYPE_VENDOR | USB_RECIP_DEVICE; | |
| 216 | − dev_dbg(&rio->rio_dev->dev, | |
| 217 | − "sending command: reqtype=%0x req=%0x value=%0x index=%0x len=%0x\n", | |
| 218 | − requesttype, rio_cmd.request, rio_cmd.value, | |
| 219 | − rio_cmd.index, rio_cmd.length); | |
| 220 | − /* Send rio control message */ | |
| 221 | − retries = 3; | |
| 222 | − while (retries) { | |
| 223 | − result = usb_control_msg(rio->rio_dev, | |
| 224 | − usb_sndctrlpipe(rio-> rio_dev, 0), | |
| 225 | − rio_cmd.request, | |
| 226 | − requesttype, | |
| 227 | − rio_cmd.value, | |
| 228 | − rio_cmd.index, buffer, | |
| 229 | − rio_cmd.length, | |
| 230 | − jiffies_to_msecs(rio_cmd.timeout)); | |
| 231 | − if (result == -ETIMEDOUT) | |
| 232 | − retries--; | |
| 233 | − else if (result < 0) { | |
| 234 | − dev_err(&rio->rio_dev->dev, | |
| 235 | − "Error executing ioctrl. code = %d\n", | |
| 236 | − result); | |
| 237 | − retries = 0; | |
| 238 | − } else { | |
| 239 | − dev_dbg(&rio->rio_dev->dev, | |
| 240 | − "Executed ioctl. Result = %d\n", result); | |
| 241 | − retries = 0; | |
| 242 | − | |
| 243 | − } | |
| 244 | − | |
| 245 | − } | |
| 246 | − free_page((unsigned long) buffer); | |
| 247 | − break; | |
| 248 | − | |
| 249 | − default: | |
| 250 | − retval = -ENOTTY; | |
| 251 | − break; | |
| 252 | − } | |
| 253 | − | |
| 254 | − | |
| 255 | −err_out: | |
| 256 | − mutex_unlock(&rio500_mutex); | |
| 257 | − return retval; | |
| 258 | −} | |
| 259 | − | |
| 260 | −static ssize_t | |
| 261 | −write_rio(struct file *file, const char __user *buffer, | |
| 262 | − size_t count, loff_t * ppos) | |
| 263 | −{ | |
| 264 | − DEFINE_WAIT(wait); | |
| 265 | − struct rio_usb_data *rio = &rio_instance; | |
| 266 | − | |
| 267 | − unsigned long copy_size; | |
| 268 | − unsigned long bytes_written = 0; | |
| 269 | − unsigned int partial; | |
| 270 | − | |
| 271 | − int result = 0; | |
| 272 | − int maxretry; | |
| 273 | − int errn = 0; | |
| 274 | − int intr; | |
| 275 | − | |
| 276 | − intr = mutex_lock_interruptible(&rio500_mutex); | |
| 277 | − if (intr) | |
| 278 | − return -EINTR; | |
| 279 | − /* Sanity check to make sure rio is connected, powered, etc */ | |
| 280 | − if (rio->present == 0 || rio->rio_dev == NULL) { | |
| 281 | − mutex_unlock(&rio500_mutex); | |
| 282 | − return -ENODEV; | |
| 283 | − } | |
| 284 | − | |
| 285 | − | |
| 286 | − | |
| 287 | − do { | |
| 288 | − unsigned long thistime; | |
| 289 | − char *obuf = rio->obuf; | |
| 290 | − | |
| 291 | − thistime = copy_size = | |
| 292 | − (count >= OBUF_SIZE) ? OBUF_SIZE : count; | |
| 293 | − if (copy_from_user(rio->obuf, buffer, copy_size)) { | |
| 294 | − errn = -EFAULT; | |
| 295 | − goto error; | |
| 296 | − } | |
| 297 | − maxretry = 5; | |
| 298 | − while (thistime) { | |
| 299 | − if (!rio->rio_dev) { | |
| 300 | − errn = -ENODEV; | |
| 301 | − goto error; | |
| 302 | − } | |
| 303 | − if (signal_pending(current)) { | |
| 304 | − mutex_unlock(&rio500_mutex); | |
| 305 | − return bytes_written ? bytes_written : -EINTR; | |
| 306 | − } | |
| 307 | − | |
| 308 | − result = usb_bulk_msg(rio->rio_dev, | |
| 309 | − usb_sndbulkpipe(rio->rio_dev, 2), | |
| 310 | − obuf, thistime, &partial, 5000); | |
| 311 | − | |
| 312 | − dev_dbg(&rio->rio_dev->dev, | |
| 313 | − "write stats: result:%d thistime:%lu partial:%u\n", | |
| 314 | − result, thistime, partial); | |
| 315 | − | |
| 316 | − if (result == -ETIMEDOUT) { /* NAK - so hold for a while */ | |
| 317 | − if (!maxretry--) { | |
| 318 | − errn = -ETIME; | |
| 319 | − goto error; | |
| 320 | − } | |
| 321 | − prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE); | |
| 322 | − schedule_timeout(NAK_TIMEOUT); | |
| 323 | − finish_wait(&rio->wait_q, &wait); | |
| 324 | − continue; | |
| 325 | − } else if (!result && partial) { | |
| 326 | − obuf += partial; | |
| 327 | − thistime -= partial; | |
| 328 | − } else | |
| 329 | − break; | |
| 330 | − } | |
| 331 | − if (result) { | |
| 332 | − dev_err(&rio->rio_dev->dev, "Write Whoops - %x\n", | |
| 333 | − result); | |
| 334 | − errn = -EIO; | |
| 335 | − goto error; | |
| 336 | − } | |
| 337 | − bytes_written += copy_size; | |
| 338 | − count -= copy_size; | |
| 339 | − buffer += copy_size; | |
| 340 | − } while (count > 0); | |
| 341 | − | |
| 342 | − mutex_unlock(&rio500_mutex); | |
| 343 | − | |
| 344 | − return bytes_written ? bytes_written : -EIO; | |
| 345 | − | |
| 346 | −error: | |
| 347 | − mutex_unlock(&rio500_mutex); | |
| 348 | − return errn; | |
| 349 | −} | |
| 350 | − | |
| 351 | −static ssize_t | |
| 352 | −read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |
| 353 | −{ | |
| 354 | − DEFINE_WAIT(wait); | |
| 355 | − struct rio_usb_data *rio = &rio_instance; | |
| 356 | − ssize_t read_count; | |
| 357 | − unsigned int partial; | |
| 358 | − int this_read; | |
| 359 | − int result; | |
| 360 | − int maxretry = 10; | |
| 361 | − char *ibuf; | |
| 362 | − int intr; | |
| 363 | − | |
| 364 | − intr = mutex_lock_interruptible(&rio500_mutex); | |
| 365 | − if (intr) | |
| 366 | − return -EINTR; | |
| 367 | − /* Sanity check to make sure rio is connected, powered, etc */ | |
| 368 | − if (rio->present == 0 || rio->rio_dev == NULL) { | |
| 369 | − mutex_unlock(&rio500_mutex); | |
| 370 | − return -ENODEV; | |
| 371 | − } | |
| 372 | − | |
| 373 | − ibuf = rio->ibuf; | |
| 374 | − | |
| 375 | − read_count = 0; | |
| 376 | − | |
| 377 | − | |
| 378 | − while (count > 0) { | |
| 379 | − if (signal_pending(current)) { | |
| 380 | − mutex_unlock(&rio500_mutex); | |
| 381 | − return read_count ? read_count : -EINTR; | |
| 382 | − } | |
| 383 | − if (!rio->rio_dev) { | |
| 384 | − mutex_unlock(&rio500_mutex); | |
| 385 | − return -ENODEV; | |
| 386 | − } | |
| 387 | − this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; | |
| 388 | − | |
| 389 | − result = usb_bulk_msg(rio->rio_dev, | |
| 390 | − usb_rcvbulkpipe(rio->rio_dev, 1), | |
| 391 | − ibuf, this_read, &partial, | |
| 392 | − 8000); | |
| 393 | − | |
| 394 | − dev_dbg(&rio->rio_dev->dev, | |
| 395 | − "read stats: result:%d this_read:%u partial:%u\n", | |
| 396 | − result, this_read, partial); | |
| 397 | − | |
| 398 | − if (partial) { | |
| 399 | − count = this_read = partial; | |
| 400 | − } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ | |
| 401 | − if (!maxretry--) { | |
| 402 | − mutex_unlock(&rio500_mutex); | |
| 403 | − dev_err(&rio->rio_dev->dev, | |
| 404 | − "read_rio: maxretry timeout\n"); | |
| 405 | − return -ETIME; | |
| 406 | − } | |
| 407 | − prepare_to_wait(&rio->wait_q, &wait, TASK_INTERRUPTIBLE); | |
| 408 | − schedule_timeout(NAK_TIMEOUT); | |
| 409 | − finish_wait(&rio->wait_q, &wait); | |
| 410 | − continue; | |
| 411 | − } else if (result != -EREMOTEIO) { | |
| 412 | − mutex_unlock(&rio500_mutex); | |
| 413 | − dev_err(&rio->rio_dev->dev, | |
| 414 | − "Read Whoops - result:%d partial:%u this_read:%u\n", | |
| 415 | − result, partial, this_read); | |
| 416 | − return -EIO; | |
| 417 | − } else { | |
| 418 | − mutex_unlock(&rio500_mutex); | |
| 419 | − return (0); | |
| 420 | − } | |
| 421 | − | |
| 422 | − if (this_read) { | |
| 423 | − if (copy_to_user(buffer, ibuf, this_read)) { | |
| 424 | − mutex_unlock(&rio500_mutex); | |
| 425 | − return -EFAULT; | |
| 426 | − } | |
| 427 | − count -= this_read; | |
| 428 | − read_count += this_read; | |
| 429 | − buffer += this_read; | |
| 430 | − } | |
| 431 | − } | |
| 432 | − mutex_unlock(&rio500_mutex); | |
| 433 | − return read_count; | |
| 434 | −} | |
| 435 | − | |
| 436 | −static const struct file_operations usb_rio_fops = { | |
| 437 | − .owner = THIS_MODULE, | |
| 438 | − .read = read_rio, | |
| 439 | − .write = write_rio, | |
| 440 | − .unlocked_ioctl = ioctl_rio, | |
| 441 | − .open = open_rio, | |
| 442 | − .release = close_rio, | |
| 443 | − .llseek = noop_llseek, | |
| 444 | −}; | |
| 445 | − | |
| 446 | −static struct usb_class_driver usb_rio_class = { | |
| 447 | − .name = "rio500%d", | |
| 448 | − .fops = &usb_rio_fops, | |
| 449 | − .minor_base = RIO_MINOR, | |
| 450 | −}; | |
| 451 | − | |
| 452 | −static int probe_rio(struct usb_interface *intf, | |
| 453 | − const struct usb_device_id *id) | |
| 454 | −{ | |
| 455 | − struct usb_device *dev = interface_to_usbdev(intf); | |
| 456 | − struct rio_usb_data *rio = &rio_instance; | |
| 457 | − int retval = -ENOMEM; | |
| 458 | − char *ibuf, *obuf; | |
| 459 | − | |
| 460 | − if (rio->present) { | |
| 461 | − dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum); | |
| 462 | − return -EBUSY; | |
| 463 | − } | |
| 464 | − dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum); | |
| 465 | − | |
| 466 | − obuf = kmalloc(OBUF_SIZE, GFP_KERNEL); | |
| 467 | − if (!obuf) { | |
| 468 | − dev_err(&dev->dev, | |
| 469 | − "probe_rio: Not enough memory for the output buffer\n"); | |
| 470 | − goto err_obuf; | |
| 471 | − } | |
| 472 | − dev_dbg(&intf->dev, "obuf address: %p\n", obuf); | |
| 473 | − | |
| 474 | − ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL); | |
| 475 | − if (!ibuf) { | |
| 476 | − dev_err(&dev->dev, | |
| 477 | − "probe_rio: Not enough memory for the input buffer\n"); | |
| 478 | − goto err_ibuf; | |
| 479 | − } | |
| 480 | − dev_dbg(&intf->dev, "ibuf address: %p\n", ibuf); | |
| 481 | − | |
| 482 | − mutex_lock(&rio500_mutex); | |
| 483 | − rio->rio_dev = dev; | |
| 484 | − rio->ibuf = ibuf; | |
| 485 | − rio->obuf = obuf; | |
| 486 | − rio->present = 1; | |
| 487 | − mutex_unlock(&rio500_mutex); | |
| 488 | − | |
| 489 | − retval = usb_register_dev(intf, &usb_rio_class); | |
| 490 | − if (retval) { | |
| 491 | − dev_err(&dev->dev, | |
| 492 | − "Not able to get a minor for this device.\n"); | |
| 493 | − goto err_register; | |
| 494 | − } | |
| 495 | − | |
| 496 | − usb_set_intfdata(intf, rio); | |
| 497 | − return retval; | |
| 498 | − | |
| 499 | − err_register: | |
| 500 | − mutex_lock(&rio500_mutex); | |
| 501 | − rio->present = 0; | |
| 502 | − mutex_unlock(&rio500_mutex); | |
| 503 | − err_ibuf: | |
| 504 | − kfree(obuf); | |
| 505 | − err_obuf: | |
| 506 | − return retval; | |
| 507 | −} | |
| 508 | − | |
| 509 | −static void disconnect_rio(struct usb_interface *intf) | |
| 510 | −{ | |
| 511 | − struct rio_usb_data *rio = usb_get_intfdata (intf); | |
| 512 | − | |
| 513 | − usb_set_intfdata (intf, NULL); | |
| 514 | − if (rio) { | |
| 515 | − usb_deregister_dev(intf, &usb_rio_class); | |
| 516 | − | |
| 517 | − mutex_lock(&rio500_mutex); | |
| 518 | − if (rio->isopen) { | |
| 519 | − rio->isopen = 0; | |
| 520 | − /* better let it finish - the release will do whats needed */ | |
| 521 | − rio->rio_dev = NULL; | |
| 522 | − mutex_unlock(&rio500_mutex); | |
| 523 | − return; | |
| 524 | − } | |
| 525 | − kfree(rio->ibuf); | |
| 526 | − kfree(rio->obuf); | |
| 527 | − | |
| 528 | − dev_info(&intf->dev, "USB Rio disconnected.\n"); | |
| 529 | − | |
| 530 | − rio->present = 0; | |
| 531 | − mutex_unlock(&rio500_mutex); | |
| 532 | − } | |
| 533 | −} | |
| 534 | − | |
| 535 | −static const struct usb_device_id rio_table[] = { | |
| 536 | − { USB_DEVICE(0x0841, 1) }, /* Rio 500 */ | |
| 537 | − { } /* Terminating entry */ | |
| 538 | −}; | |
| 539 | − | |
| 540 | −MODULE_DEVICE_TABLE (usb, rio_table); | |
| 541 | − | |
| 542 | −static struct usb_driver rio_driver = { | |
| 543 | − .name = "rio500", | |
| 544 | − .probe = probe_rio, | |
| 545 | − .disconnect = disconnect_rio, | |
| 546 | − .id_table = rio_table, | |
| 547 | −}; | |
| 548 | − | |
| 549 | −module_usb_driver(rio_driver); | |
| 550 | − | |
| 551 | −MODULE_AUTHOR( DRIVER_AUTHOR ); | |
| 552 | −MODULE_DESCRIPTION( DRIVER_DESC ); | |
| 553 | −MODULE_LICENSE("GPL"); | |
| 554 | − | |
| @@ -1,20 +0,0 @@ | ||
| 1 | −// SPDX-License-Identifier: GPL-2.0+ | |
| 2 | −/* ---------------------------------------------------------------------- | |
| 3 | − Copyright (C) 2000 Cesar Miquel (miquel@df.uba.ar) | |
| 4 | − ---------------------------------------------------------------------- */ | |
| 5 | − | |
| 6 | −#define RIO_SEND_COMMAND 0x1 | |
| 7 | −#define RIO_RECV_COMMAND 0x2 | |
| 8 | − | |
| 9 | −#define RIO_DIR_OUT 0x0 | |
| 10 | −#define RIO_DIR_IN 0x1 | |
| 11 | − | |
| 12 | −struct RioCommand { | |
| 13 | − short length; | |
| 14 | − int request; | |
| 15 | − int requesttype; | |
| 16 | − int value; | |
| 17 | − int index; | |
| 18 | − void __user *buffer; | |
| 19 | − int timeout; | |
| 20 | −}; | |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/slab.h> |
| 19 | 19 | #include <linux/errno.h> |
| 20 | 20 | #include <linux/mutex.h> |
| 21 | +#include <linux/rwsem.h> | |
| 21 | 22 | #include <linux/uaccess.h> |
| 22 | 23 | #include <linux/usb.h> |
| 23 | 24 | |
| @@ -29,16 +30,12 @@ · 5 unmodified lines | ||
| 29 | 30 | #define IOCTL_GET_DRV_VERSION 2 |
| 30 | 31 | |
| 31 | 32 | |
| 32 | −static DEFINE_MUTEX(lcd_mutex); | |
| 33 | 33 | static const struct usb_device_id id_table[] = { |
| 34 | 34 | { .idVendor = 0x10D2, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, }, |
| 35 | 35 | { }, |
| 36 | 36 | }; |
| 37 | 37 | MODULE_DEVICE_TABLE(usb, id_table); |
| 38 | 38 | |
| 39 | −static DEFINE_MUTEX(open_disc_mutex); | |
| 40 | − | |
| 41 | − | |
| 42 | 39 | struct usb_lcd { |
| 43 | 40 | struct usb_device *udev; /* init: probe_lcd */ |
| 44 | 41 | struct usb_interface *interface; /* the interface for |
| @@ -57,6 +54,8 @@ struct usb_lcd { · 12 unmodified lines | ||
| 57 | 54 | using up all RAM */ |
| 58 | 55 | struct usb_anchor submitted; /* URBs to wait for |
| 59 | 56 | before suspend */ |
| 57 | + struct rw_semaphore io_rwsem; | |
| 58 | + unsigned long disconnected:1; | |
| 60 | 59 | }; |
| 61 | 60 | #define to_lcd_dev(d) container_of(d, struct usb_lcd, kref) |
| 62 | 61 | |
| @@ -81,40 +80,29 @@ static int lcd_open(struct inode *inode, struct file *file) · 18 unmodified lines | ||
| 81 | 80 | struct usb_interface *interface; |
| 82 | 81 | int subminor, r; |
| 83 | 82 | |
| 84 | − mutex_lock(&lcd_mutex); | |
| 85 | 83 | subminor = iminor(inode); |
| 86 | 84 | |
| 87 | 85 | interface = usb_find_interface(&lcd_driver, subminor); |
| 88 | 86 | if (!interface) { |
| 89 | − mutex_unlock(&lcd_mutex); | |
| 90 | − printk(KERN_ERR "USBLCD: %s - error, can't find device for minor %d\n", | |
| 87 | + pr_err("USBLCD: %s - error, can't find device for minor %d\n", | |
| 91 | 88 | __func__, subminor); |
| 92 | 89 | return -ENODEV; |
| 93 | 90 | } |
| 94 | 91 | |
| 95 | − mutex_lock(&open_disc_mutex); | |
| 96 | 92 | dev = usb_get_intfdata(interface); |
| 97 | − if (!dev) { | |
| 98 | − mutex_unlock(&open_disc_mutex); | |
| 99 | − mutex_unlock(&lcd_mutex); | |
| 100 | − return -ENODEV; | |
| 101 | − } | |
| 102 | 93 | |
| 103 | 94 | /* increment our usage count for the device */ |
| 104 | 95 | kref_get(&dev->kref); |
| 105 | − mutex_unlock(&open_disc_mutex); | |
| 106 | 96 | |
| 107 | 97 | /* grab a power reference */ |
| 108 | 98 | r = usb_autopm_get_interface(interface); |
| 109 | 99 | if (r < 0) { |
| 110 | 100 | kref_put(&dev->kref, lcd_delete); |
| 111 | − mutex_unlock(&lcd_mutex); | |
| 112 | 101 | return r; |
| 113 | 102 | } |
| 114 | 103 | |
| 115 | 104 | /* save our object in the file's private structure */ |
| 116 | 105 | file->private_data = dev; |
| 117 | − mutex_unlock(&lcd_mutex); | |
| 118 | 106 | |
| 119 | 107 | return 0; |
| 120 | 108 | } |
| @@ -142,6 +130,13 @@ static ssize_t lcd_read(struct file *file, char __user * buffer, · 21 unmodified lines | ||
| 142 | 130 | |
| 143 | 131 | dev = file->private_data; |
| 144 | 132 | |
| 133 | + down_read(&dev->io_rwsem); | |
| 134 | + | |
| 135 | + if (dev->disconnected) { | |
| 136 | + retval = -ENODEV; | |
| 137 | + goto out_up_io; | |
| 138 | + } | |
| 139 | + | |
| 145 | 140 | /* do a blocking bulk read to get data from the device */ |
| 146 | 141 | retval = usb_bulk_msg(dev->udev, |
| 147 | 142 | usb_rcvbulkpipe(dev->udev, |
| @@ -158,6 +153,9 @@ static ssize_t lcd_read(struct file *file, char __user * buffer, · 10 unmodified lines | ||
| 158 | 153 | retval = bytes_read; |
| 159 | 154 | } |
| 160 | 155 | |
| 156 | +out_up_io: | |
| 157 | + up_read(&dev->io_rwsem); | |
| 158 | + | |
| 161 | 159 | return retval; |
| 162 | 160 | } |
| 163 | 161 | |
| @@ -173,14 +171,12 @@ static long lcd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) · 9 unmodified lines | ||
| 173 | 171 | |
| 174 | 172 | switch (cmd) { |
| 175 | 173 | case IOCTL_GET_HARD_VERSION: |
| 176 | − mutex_lock(&lcd_mutex); | |
| 177 | 174 | bcdDevice = le16_to_cpu((dev->udev)->descriptor.bcdDevice); |
| 178 | 175 | sprintf(buf, "%1d%1d.%1d%1d", |
| 179 | 176 | (bcdDevice & 0xF000)>>12, |
| 180 | 177 | (bcdDevice & 0xF00)>>8, |
| 181 | 178 | (bcdDevice & 0xF0)>>4, |
| 182 | 179 | (bcdDevice & 0xF)); |
| 183 | − mutex_unlock(&lcd_mutex); | |
| 184 | 180 | if (copy_to_user((void __user *)arg, buf, strlen(buf)) != 0) |
| 185 | 181 | return -EFAULT; |
| 186 | 182 | break; |
| @@ -237,11 +233,18 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, · 50 unmodified lines | ||
| 237 | 233 | if (r < 0) |
| 238 | 234 | return -EINTR; |
| 239 | 235 | |
| 236 | + down_read(&dev->io_rwsem); | |
| 237 | + | |
| 238 | + if (dev->disconnected) { | |
| 239 | + retval = -ENODEV; | |
| 240 | + goto err_up_io; | |
| 241 | + } | |
| 242 | + | |
| 240 | 243 | /* create a urb, and a buffer for it, and copy the data to the urb */ |
| 241 | 244 | urb = usb_alloc_urb(0, GFP_KERNEL); |
| 242 | 245 | if (!urb) { |
| 243 | 246 | retval = -ENOMEM; |
| 244 | − goto err_no_buf; | |
| 247 | + goto err_up_io; | |
| 245 | 248 | } |
| 246 | 249 | |
| 247 | 250 | buf = usb_alloc_coherent(dev->udev, count, GFP_KERNEL, |
| @@ -278,6 +281,7 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, · 30 unmodified lines | ||
| 278 | 281 | the USB core will eventually free it entirely */ |
| 279 | 282 | usb_free_urb(urb); |
| 280 | 283 | |
| 284 | + up_read(&dev->io_rwsem); | |
| 281 | 285 | exit: |
| 282 | 286 | return count; |
| 283 | 287 | error_unanchor: |
| @@ -285,7 +289,8 @@ error_unanchor: · 1 unmodified line | ||
| 285 | 289 | error: |
| 286 | 290 | usb_free_coherent(dev->udev, count, buf, urb->transfer_dma); |
| 287 | 291 | usb_free_urb(urb); |
| 288 | −err_no_buf: | |
| 292 | +err_up_io: | |
| 293 | + up_read(&dev->io_rwsem); | |
| 289 | 294 | up(&dev->limit_sem); |
| 290 | 295 | return retval; |
| 291 | 296 | } |
| @@ -325,6 +330,7 @@ static int lcd_probe(struct usb_interface *interface, · 33 unmodified lines | ||
| 325 | 330 | |
| 326 | 331 | kref_init(&dev->kref); |
| 327 | 332 | sema_init(&dev->limit_sem, USB_LCD_CONCURRENT_WRITES); |
| 333 | + init_rwsem(&dev->io_rwsem); | |
| 328 | 334 | init_usb_anchor(&dev->submitted); |
| 329 | 335 | |
| 330 | 336 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
| @@ -365,7 +371,6 @@ static int lcd_probe(struct usb_interface *interface, · 34 unmodified lines | ||
| 365 | 371 | /* something prevented us from registering this driver */ |
| 366 | 372 | dev_err(&interface->dev, |
| 367 | 373 | "Not able to get a minor for this device.\n"); |
| 368 | − usb_set_intfdata(interface, NULL); | |
| 369 | 374 | goto error; |
| 370 | 375 | } |
| 371 | 376 | |
| @@ -411,17 +416,18 @@ static int lcd_resume(struct usb_interface *intf) · 39 unmodified lines | ||
| 411 | 416 | |
| 412 | 417 | static void lcd_disconnect(struct usb_interface *interface) |
| 413 | 418 | { |
| 414 | − struct usb_lcd *dev; | |
| 419 | + struct usb_lcd *dev = usb_get_intfdata(interface); | |
| 415 | 420 | int minor = interface->minor; |
| 416 | 421 | |
| 417 | − mutex_lock(&open_disc_mutex); | |
| 418 | − dev = usb_get_intfdata(interface); | |
| 419 | − usb_set_intfdata(interface, NULL); | |
| 420 | − mutex_unlock(&open_disc_mutex); | |
| 421 | − | |
| 422 | 422 | /* give back our minor */ |
| 423 | 423 | usb_deregister_dev(interface, &lcd_class); |
| 424 | 424 | |
| 425 | + down_write(&dev->io_rwsem); | |
| 426 | + dev->disconnected = 1; | |
| 427 | + up_write(&dev->io_rwsem); | |
| 428 | + | |
| 429 | + usb_kill_anchored_urbs(&dev->submitted); | |
| 430 | + | |
| 425 | 431 | /* decrement our usage count */ |
| 426 | 432 | kref_put(&dev->kref, lcd_delete); |
| 427 | 433 | |
| @@ -60,6 +60,7 @@ struct usb_yurex { · 59 unmodified lines | ||
| 60 | 60 | |
| 61 | 61 | struct kref kref; |
| 62 | 62 | struct mutex io_mutex; |
| 63 | + unsigned long disconnected:1; | |
| 63 | 64 | struct fasync_struct *async_queue; |
| 64 | 65 | wait_queue_head_t waitq; |
| 65 | 66 | |
| @@ -107,6 +108,7 @@ static void yurex_delete(struct kref *kref) · 41 unmodified lines | ||
| 107 | 108 | dev->int_buffer, dev->urb->transfer_dma); |
| 108 | 109 | usb_free_urb(dev->urb); |
| 109 | 110 | } |
| 111 | + usb_put_intf(dev->interface); | |
| 110 | 112 | usb_put_dev(dev->udev); |
| 111 | 113 | kfree(dev); |
| 112 | 114 | } |
| @@ -132,6 +134,7 @@ static void yurex_interrupt(struct urb *urb) · 19 unmodified lines | ||
| 132 | 134 | switch (status) { |
| 133 | 135 | case 0: /*success*/ |
| 134 | 136 | break; |
| 137 | + /* The device is terminated or messed up, give up */ | |
| 135 | 138 | case -EOVERFLOW: |
| 136 | 139 | dev_err(&dev->interface->dev, |
| 137 | 140 | "%s - overflow with length %d, actual length is %d\n", |
| @@ -140,12 +143,13 @@ static void yurex_interrupt(struct urb *urb) · 2 unmodified lines | ||
| 140 | 143 | case -ENOENT: |
| 141 | 144 | case -ESHUTDOWN: |
| 142 | 145 | case -EILSEQ: |
| 143 | − /* The device is terminated, clean up */ | |
| 146 | + case -EPROTO: | |
| 147 | + case -ETIME: | |
| 144 | 148 | return; |
| 145 | 149 | default: |
| 146 | 150 | dev_err(&dev->interface->dev, |
| 147 | 151 | "%s - unknown status received: %d\n", __func__, status); |
| 148 | − goto exit; | |
| 152 | + return; | |
| 149 | 153 | } |
| 150 | 154 | |
| 151 | 155 | /* handle received message */ |
| @@ -177,7 +181,6 @@ static void yurex_interrupt(struct urb *urb) · 25 unmodified lines | ||
| 177 | 181 | break; |
| 178 | 182 | } |
| 179 | 183 | |
| 180 | −exit: | |
| 181 | 184 | retval = usb_submit_urb(dev->urb, GFP_ATOMIC); |
| 182 | 185 | if (retval) { |
| 183 | 186 | dev_err(&dev->interface->dev, "%s - usb_submit_urb failed: %d\n", |
| @@ -204,7 +207,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ · 20 unmodified lines | ||
| 204 | 207 | init_waitqueue_head(&dev->waitq); |
| 205 | 208 | |
| 206 | 209 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
| 207 | − dev->interface = interface; | |
| 210 | + dev->interface = usb_get_intf(interface); | |
| 208 | 211 | |
| 209 | 212 | /* set up the endpoint information */ |
| 210 | 213 | iface_desc = interface->cur_altsetting; |
| @@ -315,8 +318,9 @@ static void yurex_disconnect(struct usb_interface *interface) · 104 unmodified lines | ||
| 315 | 318 | |
| 316 | 319 | /* prevent more I/O from starting */ |
| 317 | 320 | usb_poison_urb(dev->urb); |
| 321 | + usb_poison_urb(dev->cntl_urb); | |
| 318 | 322 | mutex_lock(&dev->io_mutex); |
| 319 | − dev->interface = NULL; | |
| 323 | + dev->disconnected = 1; | |
| 320 | 324 | mutex_unlock(&dev->io_mutex); |
| 321 | 325 | |
| 322 | 326 | /* wakeup waiters */ |
| @@ -404,7 +408,7 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count, · 81 unmodified lines | ||
| 404 | 408 | dev = file->private_data; |
| 405 | 409 | |
| 406 | 410 | mutex_lock(&dev->io_mutex); |
| 407 | − if (!dev->interface) { /* already disconnected */ | |
| 411 | + if (dev->disconnected) { /* already disconnected */ | |
| 408 | 412 | mutex_unlock(&dev->io_mutex); |
| 409 | 413 | return -ENODEV; |
| 410 | 414 | } |
| @@ -439,7 +443,7 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, · 28 unmodified lines | ||
| 439 | 443 | goto error; |
| 440 | 444 | |
| 441 | 445 | mutex_lock(&dev->io_mutex); |
| 442 | − if (!dev->interface) { /* already disconnected */ | |
| 446 | + if (dev->disconnected) { /* already disconnected */ | |
| 443 | 447 | mutex_unlock(&dev->io_mutex); |
| 444 | 448 | retval = -ENODEV; |
| 445 | 449 | goto error; |
| @@ -211,6 +211,7 @@ struct usbhs_priv; · 210 unmodified lines | ||
| 211 | 211 | /* DCPCTR */ |
| 212 | 212 | #define BSTS (1 << 15) /* Buffer Status */ |
| 213 | 213 | #define SUREQ (1 << 14) /* Sending SETUP Token */ |
| 214 | +#define INBUFM (1 << 14) /* (PIPEnCTR) Transfer Buffer Monitor */ | |
| 214 | 215 | #define CSSTS (1 << 12) /* CSSTS Status */ |
| 215 | 216 | #define ACLRM (1 << 9) /* Buffer Auto-Clear Mode */ |
| 216 | 217 | #define SQCLR (1 << 8) /* Toggle Bit Clear */ |
| @@ -89,7 +89,7 @@ static void __usbhsf_pkt_del(struct usbhs_pkt *pkt) · 88 unmodified lines | ||
| 89 | 89 | list_del_init(&pkt->node); |
| 90 | 90 | } |
| 91 | 91 | |
| 92 | −static struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe) | |
| 92 | +struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe) | |
| 93 | 93 | { |
| 94 | 94 | return list_first_entry_or_null(&pipe->list, struct usbhs_pkt, node); |
| 95 | 95 | } |
| @@ -97,5 +97,6 @@ void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, · 96 unmodified lines | ||
| 97 | 97 | void *buf, int len, int zero, int sequence); |
| 98 | 98 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt); |
| 99 | 99 | void usbhs_pkt_start(struct usbhs_pipe *pipe); |
| 100 | +struct usbhs_pkt *__usbhsf_pkt_get(struct usbhs_pipe *pipe); | |
| 100 | 101 | |
| 101 | 102 | #endif /* RENESAS_USB_FIFO_H */ |
| @@ -722,8 +722,7 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) · 721 unmodified lines | ||
| 722 | 722 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); |
| 723 | 723 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); |
| 724 | 724 | unsigned long flags; |
| 725 | − | |
| 726 | − usbhsg_pipe_disable(uep); | |
| 725 | + int ret = 0; | |
| 727 | 726 | |
| 728 | 727 | dev_dbg(dev, "set halt %d (pipe %d)\n", |
| 729 | 728 | halt, usbhs_pipe_number(pipe)); |
| @@ -731,6 +730,18 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) · 1 unmodified line | ||
| 731 | 730 | /******************** spin lock ********************/ |
| 732 | 731 | usbhs_lock(priv, flags); |
| 733 | 732 | |
| 733 | + /* | |
| 734 | + * According to usb_ep_set_halt()'s description, this function should | |
| 735 | + * return -EAGAIN if the IN endpoint has any queue or data. Note | |
| 736 | + * that the usbhs_pipe_is_dir_in() returns false if the pipe is an | |
| 737 | + * IN endpoint in the gadget mode. | |
| 738 | + */ | |
| 739 | + if (!usbhs_pipe_is_dir_in(pipe) && (__usbhsf_pkt_get(pipe) || | |
| 740 | + usbhs_pipe_contains_transmittable_data(pipe))) { | |
| 741 | + ret = -EAGAIN; | |
| 742 | + goto out; | |
| 743 | + } | |
| 744 | + | |
| 734 | 745 | if (halt) |
| 735 | 746 | usbhs_pipe_stall(pipe); |
| 736 | 747 | else |
| @@ -741,10 +752,11 @@ static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) · 4 unmodified lines | ||
| 741 | 752 | else |
| 742 | 753 | usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); |
| 743 | 754 | |
| 755 | +out: | |
| 744 | 756 | usbhs_unlock(priv, flags); |
| 745 | 757 | /******************** spin unlock ******************/ |
| 746 | 758 | |
| 747 | − return 0; | |
| 759 | + return ret; | |
| 748 | 760 | } |
| 749 | 761 | |
| 750 | 762 | static int usbhsg_ep_set_halt(struct usb_ep *ep, int value) |
| @@ -277,6 +277,21 @@ int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe) · 276 unmodified lines | ||
| 277 | 277 | return -EBUSY; |
| 278 | 278 | } |
| 279 | 279 | |
| 280 | +bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe) | |
| 281 | +{ | |
| 282 | + u16 val; | |
| 283 | + | |
| 284 | + /* Do not support for DCP pipe */ | |
| 285 | + if (usbhs_pipe_is_dcp(pipe)) | |
| 286 | + return false; | |
| 287 | + | |
| 288 | + val = usbhsp_pipectrl_get(pipe); | |
| 289 | + if (val & INBUFM) | |
| 290 | + return true; | |
| 291 | + | |
| 292 | + return false; | |
| 293 | +} | |
| 294 | + | |
| 280 | 295 | /* |
| 281 | 296 | * PID ctrl |
| 282 | 297 | */ |
| @@ -83,6 +83,7 @@ void usbhs_pipe_clear(struct usbhs_pipe *pipe); · 82 unmodified lines | ||
| 83 | 83 | void usbhs_pipe_clear_without_sequence(struct usbhs_pipe *pipe, |
| 84 | 84 | int needs_bfre, int bfre_enable); |
| 85 | 85 | int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe); |
| 86 | +bool usbhs_pipe_contains_transmittable_data(struct usbhs_pipe *pipe); | |
| 86 | 87 | void usbhs_pipe_enable(struct usbhs_pipe *pipe); |
| 87 | 88 | void usbhs_pipe_disable(struct usbhs_pipe *pipe); |
| 88 | 89 | void usbhs_pipe_stall(struct usbhs_pipe *pipe); |
| @@ -1030,6 +1030,9 @@ static const struct usb_device_id id_table_combined[] = { · 1029 unmodified lines | ||
| 1030 | 1030 | /* EZPrototypes devices */ |
| 1031 | 1031 | { USB_DEVICE(EZPROTOTYPES_VID, HJELMSLUND_USB485_ISO_PID) }, |
| 1032 | 1032 | { USB_DEVICE_INTERFACE_NUMBER(UNJO_VID, UNJO_ISODEBUG_V1_PID, 1) }, |
| 1033 | + /* Sienna devices */ | |
| 1034 | + { USB_DEVICE(FTDI_VID, FTDI_SIENNA_PID) }, | |
| 1035 | + { USB_DEVICE(ECHELON_VID, ECHELON_U20_PID) }, | |
| 1033 | 1036 | { } /* Terminating entry */ |
| 1034 | 1037 | }; |
| 1035 | 1038 | |
| @@ -39,6 +39,9 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #define FTDI_LUMEL_PD12_PID 0x6002 |
| 41 | 41 | |
| 42 | +/* Sienna Serial Interface by Secyourit GmbH */ | |
| 43 | +#define FTDI_SIENNA_PID 0x8348 | |
| 44 | + | |
| 42 | 45 | /* Cyber Cortex AV by Fabulous Silicon (http://fabuloussilicon.com) */ |
| 43 | 46 | #define CYBER_CORTEX_AV_PID 0x8698 |
| 44 | 47 | |
| @@ -688,6 +691,12 @@ · 643 unmodified lines | ||
| 688 | 691 | #define BANDB_TTL3USB9M_PID 0xAC50 |
| 689 | 692 | #define BANDB_ZZ_PROG1_USB_PID 0xBA02 |
| 690 | 693 | |
| 694 | +/* | |
| 695 | + * Echelon USB Serial Interface | |
| 696 | + */ | |
| 697 | +#define ECHELON_VID 0x0920 | |
| 698 | +#define ECHELON_U20_PID 0x7500 | |
| 699 | + | |
| 691 | 700 | /* |
| 692 | 701 | * Intrepid Control Systems (http://www.intrepidcs.com/) ValueCAN and NeoVI |
| 693 | 702 | */ |
| @@ -1741,8 +1741,8 @@ static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint, · 1740 unmodified lines | ||
| 1741 | 1741 | |
| 1742 | 1742 | ep_desc = find_ep(serial, endpoint); |
| 1743 | 1743 | if (!ep_desc) { |
| 1744 | − /* leak the urb, something's wrong and the callers don't care */ | |
| 1745 | − return urb; | |
| 1744 | + usb_free_urb(urb); | |
| 1745 | + return NULL; | |
| 1746 | 1746 | } |
| 1747 | 1747 | if (usb_endpoint_xfer_int(ep_desc)) { |
| 1748 | 1748 | ep_type_name = "INT"; |
| @@ -419,6 +419,7 @@ static void option_instat_callback(struct urb *urb); · 418 unmodified lines | ||
| 419 | 419 | #define CINTERION_PRODUCT_PH8_AUDIO 0x0083 |
| 420 | 420 | #define CINTERION_PRODUCT_AHXX_2RMNET 0x0084 |
| 421 | 421 | #define CINTERION_PRODUCT_AHXX_AUDIO 0x0085 |
| 422 | +#define CINTERION_PRODUCT_CLS8 0x00b0 | |
| 422 | 423 | |
| 423 | 424 | /* Olivetti products */ |
| 424 | 425 | #define OLIVETTI_VENDOR_ID 0x0b3c |
| @@ -1154,6 +1155,14 @@ static const struct usb_device_id option_ids[] = { · 729 unmodified lines | ||
| 1154 | 1155 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, |
| 1155 | 1156 | { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff), |
| 1156 | 1157 | .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, |
| 1158 | + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1050, 0xff), /* Telit FN980 (rmnet) */ | |
| 1159 | + .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, | |
| 1160 | + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1051, 0xff), /* Telit FN980 (MBIM) */ | |
| 1161 | + .driver_info = NCTRL(0) | RSVD(1) }, | |
| 1162 | + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1052, 0xff), /* Telit FN980 (RNDIS) */ | |
| 1163 | + .driver_info = NCTRL(2) | RSVD(3) }, | |
| 1164 | + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1053, 0xff), /* Telit FN980 (ECM) */ | |
| 1165 | + .driver_info = NCTRL(0) | RSVD(1) }, | |
| 1157 | 1166 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), |
| 1158 | 1167 | .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, |
| 1159 | 1168 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), |
| @@ -1847,6 +1856,8 @@ static const struct usb_device_id option_ids[] = { · 687 unmodified lines | ||
| 1847 | 1856 | .driver_info = RSVD(4) }, |
| 1848 | 1857 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) }, |
| 1849 | 1858 | { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) }, |
| 1859 | + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_CLS8, 0xff), | |
| 1860 | + .driver_info = RSVD(0) | RSVD(4) }, | |
| 1850 | 1861 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, |
| 1851 | 1862 | { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, |
| 1852 | 1863 | { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, |
| @@ -314,10 +314,7 @@ static void serial_cleanup(struct tty_struct *tty) · 313 unmodified lines | ||
| 314 | 314 | serial = port->serial; |
| 315 | 315 | owner = serial->type->driver.owner; |
| 316 | 316 | |
| 317 | − mutex_lock(&serial->disc_mutex); | |
| 318 | − if (!serial->disconnected) | |
| 319 | − usb_autopm_put_interface(serial->interface); | |
| 320 | − mutex_unlock(&serial->disc_mutex); | |
| 317 | + usb_autopm_put_interface(serial->interface); | |
| 321 | 318 | |
| 322 | 319 | usb_serial_put(serial); |
| 323 | 320 | module_put(owner); |
| @@ -4409,18 +4409,20 @@ static int tcpm_fw_get_caps(struct tcpm_port *port, · 4408 unmodified lines | ||
| 4409 | 4409 | /* USB data support is optional */ |
| 4410 | 4410 | ret = fwnode_property_read_string(fwnode, "data-role", &cap_str); |
| 4411 | 4411 | if (ret == 0) { |
| 4412 | − port->typec_caps.data = typec_find_port_data_role(cap_str); | |
| 4413 | − if (port->typec_caps.data < 0) | |
| 4414 | − return -EINVAL; | |
| 4412 | + ret = typec_find_port_data_role(cap_str); | |
| 4413 | + if (ret < 0) | |
| 4414 | + return ret; | |
| 4415 | + port->typec_caps.data = ret; | |
| 4415 | 4416 | } |
| 4416 | 4417 | |
| 4417 | 4418 | ret = fwnode_property_read_string(fwnode, "power-role", &cap_str); |
| 4418 | 4419 | if (ret < 0) |
| 4419 | 4420 | return ret; |
| 4420 | 4421 | |
| 4421 | − port->typec_caps.type = typec_find_port_power_role(cap_str); | |
| 4422 | − if (port->typec_caps.type < 0) | |
| 4423 | − return -EINVAL; | |
| 4422 | + ret = typec_find_port_power_role(cap_str); | |
| 4423 | + if (ret < 0) | |
| 4424 | + return ret; | |
| 4425 | + port->typec_caps.type = ret; | |
| 4424 | 4426 | port->port_type = port->typec_caps.type; |
| 4425 | 4427 | |
| 4426 | 4428 | if (port->port_type == TYPEC_PORT_SNK) |
| @@ -75,6 +75,8 @@ static int ucsi_displayport_enter(struct typec_altmode *alt) · 74 unmodified lines | ||
| 75 | 75 | |
| 76 | 76 | if (cur != 0xff) { |
| 77 | 77 | mutex_unlock(&dp->con->lock); |
| 78 | + if (dp->con->port_altmode[cur] == alt) | |
| 79 | + return 0; | |
| 78 | 80 | return -EBUSY; |
| 79 | 81 | } |
| 80 | 82 | |
| @@ -195,7 +195,6 @@ struct ucsi_ccg { · 194 unmodified lines | ||
| 195 | 195 | |
| 196 | 196 | /* fw build with vendor information */ |
| 197 | 197 | u16 fw_build; |
| 198 | − bool run_isr; /* flag to call ISR routine during resume */ | |
| 199 | 198 | struct work_struct pm_work; |
| 200 | 199 | }; |
| 201 | 200 | |
| @@ -224,18 +223,6 @@ static int ccg_read(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len) · 22 unmodified lines | ||
| 224 | 223 | if (quirks && quirks->max_read_len) |
| 225 | 224 | max_read_len = quirks->max_read_len; |
| 226 | 225 | |
| 227 | − if (uc->fw_build == CCG_FW_BUILD_NVIDIA && | |
| 228 | − uc->fw_version <= CCG_OLD_FW_VERSION) { | |
| 229 | − mutex_lock(&uc->lock); | |
| 230 | − /* | |
| 231 | − * Do not schedule pm_work to run ISR in | |
| 232 | − * ucsi_ccg_runtime_resume() after pm_runtime_get_sync() | |
| 233 | − * since we are already in ISR path. | |
| 234 | − */ | |
| 235 | − uc->run_isr = false; | |
| 236 | − mutex_unlock(&uc->lock); | |
| 237 | − } | |
| 238 | − | |
| 239 | 226 | pm_runtime_get_sync(uc->dev); |
| 240 | 227 | while (rem_len > 0) { |
| 241 | 228 | msgs[1].buf = &data[len - rem_len]; |
| @@ -278,18 +265,6 @@ static int ccg_write(struct ucsi_ccg *uc, u16 rab, u8 *data, u32 len) · 36 unmodified lines | ||
| 278 | 265 | msgs[0].len = len + sizeof(rab); |
| 279 | 266 | msgs[0].buf = buf; |
| 280 | 267 | |
| 281 | − if (uc->fw_build == CCG_FW_BUILD_NVIDIA && | |
| 282 | − uc->fw_version <= CCG_OLD_FW_VERSION) { | |
| 283 | − mutex_lock(&uc->lock); | |
| 284 | − /* | |
| 285 | − * Do not schedule pm_work to run ISR in | |
| 286 | − * ucsi_ccg_runtime_resume() after pm_runtime_get_sync() | |
| 287 | − * since we are already in ISR path. | |
| 288 | − */ | |
| 289 | − uc->run_isr = false; | |
| 290 | − mutex_unlock(&uc->lock); | |
| 291 | − } | |
| 292 | − | |
| 293 | 268 | pm_runtime_get_sync(uc->dev); |
| 294 | 269 | status = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); |
| 295 | 270 | if (status < 0) { |
| @@ -1130,7 +1105,6 @@ static int ucsi_ccg_probe(struct i2c_client *client, · 834 unmodified lines | ||
| 1130 | 1105 | uc->ppm.sync = ucsi_ccg_sync; |
| 1131 | 1106 | uc->dev = dev; |
| 1132 | 1107 | uc->client = client; |
| 1133 | − uc->run_isr = true; | |
| 1134 | 1108 | mutex_init(&uc->lock); |
| 1135 | 1109 | INIT_WORK(&uc->work, ccg_update_firmware); |
| 1136 | 1110 | INIT_WORK(&uc->pm_work, ccg_pm_workaround_work); |
| @@ -1188,6 +1162,8 @@ static int ucsi_ccg_probe(struct i2c_client *client, · 51 unmodified lines | ||
| 1188 | 1162 | |
| 1189 | 1163 | pm_runtime_set_active(uc->dev); |
| 1190 | 1164 | pm_runtime_enable(uc->dev); |
| 1165 | + pm_runtime_use_autosuspend(uc->dev); | |
| 1166 | + pm_runtime_set_autosuspend_delay(uc->dev, 5000); | |
| 1191 | 1167 | pm_runtime_idle(uc->dev); |
| 1192 | 1168 | |
| 1193 | 1169 | return 0; |
| @@ -1229,7 +1205,6 @@ static int ucsi_ccg_runtime_resume(struct device *dev) · 35 unmodified lines | ||
| 1229 | 1205 | { |
| 1230 | 1206 | struct i2c_client *client = to_i2c_client(dev); |
| 1231 | 1207 | struct ucsi_ccg *uc = i2c_get_clientdata(client); |
| 1232 | − bool schedule = true; | |
| 1233 | 1208 | |
| 1234 | 1209 | /* |
| 1235 | 1210 | * Firmware version 3.1.10 or earlier, built for NVIDIA has known issue |
| @@ -1237,17 +1212,8 @@ static int ucsi_ccg_runtime_resume(struct device *dev) · 1 unmodified line | ||
| 1237 | 1212 | * Schedule a work to call ISR as a workaround. |
| 1238 | 1213 | */ |
| 1239 | 1214 | if (uc->fw_build == CCG_FW_BUILD_NVIDIA && |
| 1240 | − uc->fw_version <= CCG_OLD_FW_VERSION) { | |
| 1241 | − mutex_lock(&uc->lock); | |
| 1242 | − if (!uc->run_isr) { | |
| 1243 | − uc->run_isr = true; | |
| 1244 | − schedule = false; | |
| 1245 | − } | |
| 1246 | − mutex_unlock(&uc->lock); | |
| 1247 | − | |
| 1248 | − if (schedule) | |
| 1249 | − schedule_work(&uc->pm_work); | |
| 1250 | − } | |
| 1215 | + uc->fw_version <= CCG_OLD_FW_VERSION) | |
| 1216 | + schedule_work(&uc->pm_work); | |
| 1251 | 1217 | |
| 1252 | 1218 | return 0; |
| 1253 | 1219 | } |
| @@ -61,6 +61,7 @@ struct usb_skel { · 60 unmodified lines | ||
| 61 | 61 | spinlock_t err_lock; /* lock for errors */ |
| 62 | 62 | struct kref kref; |
| 63 | 63 | struct mutex io_mutex; /* synchronize I/O with disconnect */ |
| 64 | + unsigned long disconnected:1; | |
| 64 | 65 | wait_queue_head_t bulk_in_wait; /* to wait for an ongoing read */ |
| 65 | 66 | }; |
| 66 | 67 | #define to_skel_dev(d) container_of(d, struct usb_skel, kref) |
| @@ -73,6 +74,7 @@ static void skel_delete(struct kref *kref) · 6 unmodified lines | ||
| 73 | 74 | struct usb_skel *dev = to_skel_dev(kref); |
| 74 | 75 | |
| 75 | 76 | usb_free_urb(dev->bulk_in_urb); |
| 77 | + usb_put_intf(dev->interface); | |
| 76 | 78 | usb_put_dev(dev->udev); |
| 77 | 79 | kfree(dev->bulk_in_buffer); |
| 78 | 80 | kfree(dev); |
| @@ -124,10 +126,7 @@ static int skel_release(struct inode *inode, struct file *file) · 45 unmodified lines | ||
| 124 | 126 | return -ENODEV; |
| 125 | 127 | |
| 126 | 128 | /* allow the device to be autosuspended */ |
| 127 | − mutex_lock(&dev->io_mutex); | |
| 128 | − if (dev->interface) | |
| 129 | − usb_autopm_put_interface(dev->interface); | |
| 130 | − mutex_unlock(&dev->io_mutex); | |
| 129 | + usb_autopm_put_interface(dev->interface); | |
| 131 | 130 | |
| 132 | 131 | /* decrement the count on our device */ |
| 133 | 132 | kref_put(&dev->kref, skel_delete); |
| @@ -231,8 +230,7 @@ static ssize_t skel_read(struct file *file, char *buffer, size_t count, · 97 unmodified lines | ||
| 231 | 230 | |
| 232 | 231 | dev = file->private_data; |
| 233 | 232 | |
| 234 | − /* if we cannot read at all, return EOF */ | |
| 235 | − if (!dev->bulk_in_urb || !count) | |
| 233 | + if (!count) | |
| 236 | 234 | return 0; |
| 237 | 235 | |
| 238 | 236 | /* no concurrent readers */ |
| @@ -240,7 +238,7 @@ static ssize_t skel_read(struct file *file, char *buffer, size_t count, · 1 unmodified line | ||
| 240 | 238 | if (rv < 0) |
| 241 | 239 | return rv; |
| 242 | 240 | |
| 243 | − if (!dev->interface) { /* disconnect() was called */ | |
| 241 | + if (dev->disconnected) { /* disconnect() was called */ | |
| 244 | 242 | rv = -ENODEV; |
| 245 | 243 | goto exit; |
| 246 | 244 | } |
| @@ -422,7 +420,7 @@ static ssize_t skel_write(struct file *file, const char *user_buffer, · 175 unmodified lines | ||
| 422 | 420 | |
| 423 | 421 | /* this lock makes sure we don't submit URBs to gone devices */ |
| 424 | 422 | mutex_lock(&dev->io_mutex); |
| 425 | − if (!dev->interface) { /* disconnect() was called */ | |
| 423 | + if (dev->disconnected) { /* disconnect() was called */ | |
| 426 | 424 | mutex_unlock(&dev->io_mutex); |
| 427 | 425 | retval = -ENODEV; |
| 428 | 426 | goto error; |
| @@ -507,7 +505,7 @@ static int skel_probe(struct usb_interface *interface, · 78 unmodified lines | ||
| 507 | 505 | init_waitqueue_head(&dev->bulk_in_wait); |
| 508 | 506 | |
| 509 | 507 | dev->udev = usb_get_dev(interface_to_usbdev(interface)); |
| 510 | − dev->interface = interface; | |
| 508 | + dev->interface = usb_get_intf(interface); | |
| 511 | 509 | |
| 512 | 510 | /* set up the endpoint information */ |
| 513 | 511 | /* use only the first bulk-in and bulk-out endpoints */ |
| @@ -573,9 +571,10 @@ static void skel_disconnect(struct usb_interface *interface) · 59 unmodified lines | ||
| 573 | 571 | |
| 574 | 572 | /* prevent more I/O from starting */ |
| 575 | 573 | mutex_lock(&dev->io_mutex); |
| 576 | − dev->interface = NULL; | |
| 574 | + dev->disconnected = 1; | |
| 577 | 575 | mutex_unlock(&dev->io_mutex); |
| 578 | 576 | |
| 577 | + usb_kill_urb(dev->bulk_in_urb); | |
| 579 | 578 | usb_kill_anchored_urbs(&dev->submitted); |
| 580 | 579 | |
| 581 | 580 | /* decrement our usage count */ |
| @@ -1195,12 +1195,12 @@ static int vhci_start(struct usb_hcd *hcd) · 1194 unmodified lines | ||
| 1195 | 1195 | if (id == 0 && usb_hcd_is_primary_hcd(hcd)) { |
| 1196 | 1196 | err = vhci_init_attr_group(); |
| 1197 | 1197 | if (err) { |
| 1198 | − pr_err("init attr group\n"); | |
| 1198 | + dev_err(hcd_dev(hcd), "init attr group failed, err = %d\n", err); | |
| 1199 | 1199 | return err; |
| 1200 | 1200 | } |
| 1201 | 1201 | err = sysfs_create_group(&hcd_dev(hcd)->kobj, &vhci_attr_group); |
| 1202 | 1202 | if (err) { |
| 1203 | − pr_err("create sysfs files\n"); | |
| 1203 | + dev_err(hcd_dev(hcd), "create sysfs files failed, err = %d\n", err); | |
| 1204 | 1204 | vhci_finish_attr_group(); |
| 1205 | 1205 | return err; |
| 1206 | 1206 | } |
| @@ -161,6 +161,7 @@ static int vhost_test_release(struct inode *inode, struct file *f) · 160 unmodified lines | ||
| 161 | 161 | |
| 162 | 162 | vhost_test_stop(n, &private); |
| 163 | 163 | vhost_test_flush(n); |
| 164 | + vhost_dev_stop(&n->dev); | |
| 164 | 165 | vhost_dev_cleanup(&n->dev); |
| 165 | 166 | /* We do an extra flush before freeing memory, |
| 166 | 167 | * since jobs can re-queue themselves. */ |
| @@ -237,6 +238,7 @@ static long vhost_test_reset_owner(struct vhost_test *n) · 70 unmodified lines | ||
| 237 | 238 | } |
| 238 | 239 | vhost_test_stop(n, &priv); |
| 239 | 240 | vhost_test_flush(n); |
| 241 | + vhost_dev_stop(&n->dev); | |
| 240 | 242 | vhost_dev_reset_owner(&n->dev, umem); |
| 241 | 243 | done: |
| 242 | 244 | mutex_unlock(&n->dev.mutex); |
| @@ -220,6 +220,8 @@ static int hgcm_call_preprocess_linaddr( · 219 unmodified lines | ||
| 220 | 220 | if (!bounce_buf) |
| 221 | 221 | return -ENOMEM; |
| 222 | 222 | |
| 223 | + *bounce_buf_ret = bounce_buf; | |
| 224 | + | |
| 223 | 225 | if (copy_in) { |
| 224 | 226 | ret = copy_from_user(bounce_buf, (void __user *)buf, len); |
| 225 | 227 | if (ret) |
| @@ -228,7 +230,6 @@ static int hgcm_call_preprocess_linaddr( · 2 unmodified lines | ||
| 228 | 230 | memset(bounce_buf, 0, len); |
| 229 | 231 | } |
| 230 | 232 | |
| 231 | − *bounce_buf_ret = bounce_buf; | |
| 232 | 233 | hgcm_call_add_pagelist_size(bounce_buf, len, extra); |
| 233 | 234 | return 0; |
| 234 | 235 | } |
| @@ -103,6 +103,7 @@ config W1_SLAVE_DS2438 · 102 unmodified lines | ||
| 103 | 103 | |
| 104 | 104 | config W1_SLAVE_DS250X |
| 105 | 105 | tristate "512b/1kb/16kb EPROM family support" |
| 106 | + select CRC16 | |
| 106 | 107 | help |
| 107 | 108 | Say Y here if you want to use a 1-wire |
| 108 | 109 | 512b/1kb/16kb EPROM family device (DS250x). |
| @@ -22,6 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | |
| 23 | 23 | #define pr_fmt(fmt) "xen:" KBUILD_MODNAME ": " fmt |
| 24 | 24 | |
| 25 | +#include <linux/dma-mapping.h> | |
| 25 | 26 | #include <linux/module.h> |
| 26 | 27 | #include <linux/kernel.h> |
| 27 | 28 | #include <linux/init.h> |
| @@ -34,9 +35,6 @@ · 6 unmodified lines | ||
| 34 | 35 | #include <linux/slab.h> |
| 35 | 36 | #include <linux/highmem.h> |
| 36 | 37 | #include <linux/refcount.h> |
| 37 | −#ifdef CONFIG_XEN_GRANT_DMA_ALLOC | |
| 38 | −#include <linux/of_device.h> | |
| 39 | −#endif | |
| 40 | 38 | |
| 41 | 39 | #include <xen/xen.h> |
| 42 | 40 | #include <xen/grant_table.h> |
| @@ -625,14 +623,7 @@ static int gntdev_open(struct inode *inode, struct file *flip) · 582 unmodified lines | ||
| 625 | 623 | flip->private_data = priv; |
| 626 | 624 | #ifdef CONFIG_XEN_GRANT_DMA_ALLOC |
| 627 | 625 | priv->dma_dev = gntdev_miscdev.this_device; |
| 628 | − | |
| 629 | − /* | |
| 630 | − * The device is not spawn from a device tree, so arch_setup_dma_ops | |
| 631 | − * is not called, thus leaving the device with dummy DMA ops. | |
| 632 | − * Fix this by calling of_dma_configure() with a NULL node to set | |
| 633 | − * default DMA ops. | |
| 634 | − */ | |
| 635 | − of_dma_configure(priv->dma_dev, NULL, true); | |
| 626 | + dma_coerce_mask_and_coherent(priv->dma_dev, DMA_BIT_MASK(64)); | |
| 636 | 627 | #endif |
| 637 | 628 | pr_debug("priv %p\n", priv); |
| 638 | 629 | |
| @@ -1363,8 +1363,7 @@ static int gnttab_setup(void) · 1362 unmodified lines | ||
| 1363 | 1363 | if (xen_feature(XENFEAT_auto_translated_physmap) && gnttab_shared.addr == NULL) { |
| 1364 | 1364 | gnttab_shared.addr = xen_auto_xlat_grant_frames.vaddr; |
| 1365 | 1365 | if (gnttab_shared.addr == NULL) { |
| 1366 | − pr_warn("gnttab share frames (addr=0x%08lx) is not mapped!\n", | |
| 1367 | − (unsigned long)xen_auto_xlat_grant_frames.vaddr); | |
| 1366 | + pr_warn("gnttab share frames is not mapped!\n"); | |
| 1368 | 1367 | return -ENOMEM; |
| 1369 | 1368 | } |
| 1370 | 1369 | } |
| @@ -775,7 +775,7 @@ static int pvcalls_back_poll(struct xenbus_device *dev, · 774 unmodified lines | ||
| 775 | 775 | mappass->reqcopy = *req; |
| 776 | 776 | icsk = inet_csk(mappass->sock->sk); |
| 777 | 777 | queue = &icsk->icsk_accept_queue; |
| 778 | − data = queue->rskq_accept_head != NULL; | |
| 778 | + data = READ_ONCE(queue->rskq_accept_head) != NULL; | |
| 779 | 779 | if (data) { |
| 780 | 780 | mappass->reqcopy.cmd = 0; |
| 781 | 781 | ret = 0; |
| @@ -1591,7 +1591,6 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, · 1590 unmodified lines | ||
| 1591 | 1591 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
| 1592 | 1592 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 1593 | 1593 | struct page **pages = NULL; |
| 1594 | − struct extent_state *cached_state = NULL; | |
| 1595 | 1594 | struct extent_changeset *data_reserved = NULL; |
| 1596 | 1595 | u64 release_bytes = 0; |
| 1597 | 1596 | u64 lockstart; |
| @@ -1611,6 +1610,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, · 13 unmodified lines | ||
| 1611 | 1610 | return -ENOMEM; |
| 1612 | 1611 | |
| 1613 | 1612 | while (iov_iter_count(i) > 0) { |
| 1613 | + struct extent_state *cached_state = NULL; | |
| 1614 | 1614 | size_t offset = offset_in_page(pos); |
| 1615 | 1615 | size_t sector_offset; |
| 1616 | 1616 | size_t write_bytes = min(iov_iter_count(i), |
| @@ -1758,9 +1758,20 @@ again: · 141 unmodified lines | ||
| 1758 | 1758 | if (copied > 0) |
| 1759 | 1759 | ret = btrfs_dirty_pages(inode, pages, dirty_pages, |
| 1760 | 1760 | pos, copied, &cached_state); |
| 1761 | + | |
| 1762 | + /* | |
| 1763 | + * If we have not locked the extent range, because the range's | |
| 1764 | + * start offset is >= i_size, we might still have a non-NULL | |
| 1765 | + * cached extent state, acquired while marking the extent range | |
| 1766 | + * as delalloc through btrfs_dirty_pages(). Therefore free any | |
| 1767 | + * possible cached extent state to avoid a memory leak. | |
| 1768 | + */ | |
| 1761 | 1769 | if (extents_locked) |
| 1762 | 1770 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, |
| 1763 | 1771 | lockstart, lockend, &cached_state); |
| 1772 | + else | |
| 1773 | + free_extent_state(cached_state); | |
| 1774 | + | |
| 1764 | 1775 | btrfs_delalloc_release_extents(BTRFS_I(inode), reserve_bytes, |
| 1765 | 1776 | true); |
| 1766 | 1777 | if (ret) { |
| @@ -6305,13 +6305,16 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, · 6304 unmodified lines | ||
| 6305 | 6305 | u32 sizes[2]; |
| 6306 | 6306 | int nitems = name ? 2 : 1; |
| 6307 | 6307 | unsigned long ptr; |
| 6308 | + unsigned int nofs_flag; | |
| 6308 | 6309 | int ret; |
| 6309 | 6310 | |
| 6310 | 6311 | path = btrfs_alloc_path(); |
| 6311 | 6312 | if (!path) |
| 6312 | 6313 | return ERR_PTR(-ENOMEM); |
| 6313 | 6314 | |
| 6315 | + nofs_flag = memalloc_nofs_save(); | |
| 6314 | 6316 | inode = new_inode(fs_info->sb); |
| 6317 | + memalloc_nofs_restore(nofs_flag); | |
| 6315 | 6318 | if (!inode) { |
| 6316 | 6319 | btrfs_free_path(path); |
| 6317 | 6320 | return ERR_PTR(-ENOMEM); |
| @@ -500,7 +500,7 @@ static int process_leaf(struct btrfs_root *root, · 499 unmodified lines | ||
| 500 | 500 | struct btrfs_extent_data_ref *dref; |
| 501 | 501 | struct btrfs_shared_data_ref *sref; |
| 502 | 502 | u32 count; |
| 503 | − int i = 0, tree_block_level = 0, ret; | |
| 503 | + int i = 0, tree_block_level = 0, ret = 0; | |
| 504 | 504 | struct btrfs_key key; |
| 505 | 505 | int nritems = btrfs_header_nritems(leaf); |
| 506 | 506 | |
| @@ -5085,7 +5085,7 @@ static int clone_range(struct send_ctx *sctx, · 5084 unmodified lines | ||
| 5085 | 5085 | struct btrfs_path *path; |
| 5086 | 5086 | struct btrfs_key key; |
| 5087 | 5087 | int ret; |
| 5088 | − u64 clone_src_i_size; | |
| 5088 | + u64 clone_src_i_size = 0; | |
| 5089 | 5089 | |
| 5090 | 5090 | /* |
| 5091 | 5091 | * Prevent cloning from a zero offset with a length matching the sector |
| @@ -2932,7 +2932,8 @@ out: · 2931 unmodified lines | ||
| 2932 | 2932 | * in the tree of log roots |
| 2933 | 2933 | */ |
| 2934 | 2934 | static int update_log_root(struct btrfs_trans_handle *trans, |
| 2935 | − struct btrfs_root *log) | |
| 2935 | + struct btrfs_root *log, | |
| 2936 | + struct btrfs_root_item *root_item) | |
| 2936 | 2937 | { |
| 2937 | 2938 | struct btrfs_fs_info *fs_info = log->fs_info; |
| 2938 | 2939 | int ret; |
| @@ -2940,10 +2941,10 @@ static int update_log_root(struct btrfs_trans_handle *trans, · 1 unmodified line | ||
| 2940 | 2941 | if (log->log_transid == 1) { |
| 2941 | 2942 | /* insert root item on the first sync */ |
| 2942 | 2943 | ret = btrfs_insert_root(trans, fs_info->log_root_tree, |
| 2943 | − &log->root_key, &log->root_item); | |
| 2944 | + &log->root_key, root_item); | |
| 2944 | 2945 | } else { |
| 2945 | 2946 | ret = btrfs_update_root(trans, fs_info->log_root_tree, |
| 2946 | − &log->root_key, &log->root_item); | |
| 2947 | + &log->root_key, root_item); | |
| 2947 | 2948 | } |
| 2948 | 2949 | return ret; |
| 2949 | 2950 | } |
| @@ -3041,6 +3042,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, · 91 unmodified lines | ||
| 3041 | 3042 | struct btrfs_fs_info *fs_info = root->fs_info; |
| 3042 | 3043 | struct btrfs_root *log = root->log_root; |
| 3043 | 3044 | struct btrfs_root *log_root_tree = fs_info->log_root_tree; |
| 3045 | + struct btrfs_root_item new_root_item; | |
| 3044 | 3046 | int log_transid = 0; |
| 3045 | 3047 | struct btrfs_log_ctx root_log_ctx; |
| 3046 | 3048 | struct blk_plug plug; |
| @@ -3104,17 +3106,25 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, · 57 unmodified lines | ||
| 3104 | 3106 | goto out; |
| 3105 | 3107 | } |
| 3106 | 3108 | |
| 3109 | + /* | |
| 3110 | + * We _must_ update under the root->log_mutex in order to make sure we | |
| 3111 | + * have a consistent view of the log root we are trying to commit at | |
| 3112 | + * this moment. | |
| 3113 | + * | |
| 3114 | + * We _must_ copy this into a local copy, because we are not holding the | |
| 3115 | + * log_root_tree->log_mutex yet. This is important because when we | |
| 3116 | + * commit the log_root_tree we must have a consistent view of the | |
| 3117 | + * log_root_tree when we update the super block to point at the | |
| 3118 | + * log_root_tree bytenr. If we update the log_root_tree here we'll race | |
| 3119 | + * with the commit and possibly point at the new block which we may not | |
| 3120 | + * have written out. | |
| 3121 | + */ | |
| 3107 | 3122 | btrfs_set_root_node(&log->root_item, log->node); |
| 3123 | + memcpy(&new_root_item, &log->root_item, sizeof(new_root_item)); | |
| 3108 | 3124 | |
| 3109 | 3125 | root->log_transid++; |
| 3110 | 3126 | log->log_transid = root->log_transid; |
| 3111 | 3127 | root->log_start_pid = 0; |
| 3112 | − /* | |
| 3113 | − * Update or create log root item under the root's log_mutex to prevent | |
| 3114 | − * races with concurrent log syncs that can lead to failure to update | |
| 3115 | − * log root item because it was not created yet. | |
| 3116 | − */ | |
| 3117 | − ret = update_log_root(trans, log); | |
| 3118 | 3128 | /* |
| 3119 | 3129 | * IO has been started, blocks of the log tree have WRITTEN flag set |
| 3120 | 3130 | * in their headers. new modifications of the log will be written to |
| @@ -3135,6 +3145,14 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, · 14 unmodified lines | ||
| 3135 | 3145 | mutex_unlock(&log_root_tree->log_mutex); |
| 3136 | 3146 | |
| 3137 | 3147 | mutex_lock(&log_root_tree->log_mutex); |
| 3148 | + | |
| 3149 | + /* | |
| 3150 | + * Now we are safe to update the log_root_tree because we're under the | |
| 3151 | + * log_mutex, and we're a current writer so we're holding the commit | |
| 3152 | + * open until we drop the log_mutex. | |
| 3153 | + */ | |
| 3154 | + ret = update_log_root(trans, log, &new_root_item); | |
| 3155 | + | |
| 3138 | 3156 | if (atomic_dec_and_test(&log_root_tree->log_writers)) { |
| 3139 | 3157 | /* atomic_dec_and_test implies a barrier */ |
| 3140 | 3158 | cond_wake_up_nomb(&log_root_tree->log_writer_wait); |
| @@ -3845,7 +3845,11 @@ static int alloc_profile_is_valid(u64 flags, int extended) · 3844 unmodified lines | ||
| 3845 | 3845 | return !extended; /* "0" is valid for usual profiles */ |
| 3846 | 3846 | |
| 3847 | 3847 | /* true if exactly one bit set */ |
| 3848 | − return is_power_of_2(flags); | |
| 3848 | + /* | |
| 3849 | + * Don't use is_power_of_2(unsigned long) because it won't work | |
| 3850 | + * for the single profile (1ULL << 48) on 32-bit CPUs. | |
| 3851 | + */ | |
| 3852 | + return flags != 0 && (flags & (flags - 1)) == 0; | |
| 3849 | 3853 | } |
| 3850 | 3854 | |
| 3851 | 3855 | static inline int balance_need_close(struct btrfs_fs_info *fs_info) |
| @@ -384,8 +384,8 @@ static int parse_reply_info_readdir(void **p, void *end, · 383 unmodified lines | ||
| 384 | 384 | } |
| 385 | 385 | |
| 386 | 386 | done: |
| 387 | − if (*p != end) | |
| 388 | − goto bad; | |
| 387 | + /* Skip over any unrecognized fields */ | |
| 388 | + *p = end; | |
| 389 | 389 | return 0; |
| 390 | 390 | |
| 391 | 391 | bad: |
| @@ -406,12 +406,10 @@ static int parse_reply_info_filelock(void **p, void *end, · 14 unmodified lines | ||
| 406 | 406 | goto bad; |
| 407 | 407 | |
| 408 | 408 | info->filelock_reply = *p; |
| 409 | − *p += sizeof(*info->filelock_reply); | |
| 410 | 409 | |
| 411 | − if (unlikely(*p != end)) | |
| 412 | − goto bad; | |
| 410 | + /* Skip over any unrecognized fields */ | |
| 411 | + *p = end; | |
| 413 | 412 | return 0; |
| 414 | − | |
| 415 | 413 | bad: |
| 416 | 414 | return -EIO; |
| 417 | 415 | } |
| @@ -425,18 +423,21 @@ static int parse_reply_info_create(void **p, void *end, · 7 unmodified lines | ||
| 425 | 423 | { |
| 426 | 424 | if (features == (u64)-1 || |
| 427 | 425 | (features & CEPH_FEATURE_REPLY_CREATE_INODE)) { |
| 426 | + /* Malformed reply? */ | |
| 428 | 427 | if (*p == end) { |
| 429 | 428 | info->has_create_ino = false; |
| 430 | 429 | } else { |
| 431 | 430 | info->has_create_ino = true; |
| 432 | − info->ino = ceph_decode_64(p); | |
| 431 | + ceph_decode_64_safe(p, end, info->ino, bad); | |
| 433 | 432 | } |
| 433 | + } else { | |
| 434 | + if (*p != end) | |
| 435 | + goto bad; | |
| 434 | 436 | } |
| 435 | 437 | |
| 436 | − if (unlikely(*p != end)) | |
| 437 | − goto bad; | |
| 438 | + /* Skip over any unrecognized fields */ | |
| 439 | + *p = end; | |
| 438 | 440 | return 0; |
| 439 | − | |
| 440 | 441 | bad: |
| 441 | 442 | return -EIO; |
| 442 | 443 | } |
| @@ -169,18 +169,26 @@ cifs_read_super(struct super_block *sb) · 168 unmodified lines | ||
| 169 | 169 | else |
| 170 | 170 | sb->s_maxbytes = MAX_NON_LFS; |
| 171 | 171 | |
| 172 | − /* BB FIXME fix time_gran to be larger for LANMAN sessions */ | |
| 173 | − sb->s_time_gran = 100; | |
| 174 | − | |
| 175 | − if (tcon->unix_ext) { | |
| 176 | − ts = cifs_NTtimeToUnix(0); | |
| 172 | + /* Some very old servers like DOS and OS/2 used 2 second granularity */ | |
| 173 | + if ((tcon->ses->server->vals->protocol_id == SMB10_PROT_ID) && | |
| 174 | + ((tcon->ses->capabilities & | |
| 175 | + tcon->ses->server->vals->cap_nt_find) == 0) && | |
| 176 | + !tcon->unix_ext) { | |
| 177 | + sb->s_time_gran = 1000000000; /* 1 second is max allowed gran */ | |
| 178 | + ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MIN), 0, 0); | |
| 177 | 179 | sb->s_time_min = ts.tv_sec; |
| 178 | − ts = cifs_NTtimeToUnix(cpu_to_le64(S64_MAX)); | |
| 180 | + ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MAX), | |
| 181 | + cpu_to_le16(SMB_TIME_MAX), 0); | |
| 179 | 182 | sb->s_time_max = ts.tv_sec; |
| 180 | 183 | } else { |
| 181 | − ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MIN), 0, 0); | |
| 184 | + /* | |
| 185 | + * Almost every server, including all SMB2+, uses DCE TIME | |
| 186 | + * ie 100 nanosecond units, since 1601. See MS-DTYP and MS-FSCC | |
| 187 | + */ | |
| 188 | + sb->s_time_gran = 100; | |
| 189 | + ts = cifs_NTtimeToUnix(0); | |
| 182 | 190 | sb->s_time_min = ts.tv_sec; |
| 183 | − ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MAX), cpu_to_le16(SMB_TIME_MAX), 0); | |
| 191 | + ts = cifs_NTtimeToUnix(cpu_to_le64(S64_MAX)); | |
| 184 | 192 | sb->s_time_max = ts.tv_sec; |
| 185 | 193 | } |
| 186 | 194 | |
| @@ -1210,7 +1210,7 @@ struct cifs_search_info { · 1209 unmodified lines | ||
| 1210 | 1210 | bool smallBuf:1; /* so we know which buf_release function to call */ |
| 1211 | 1211 | }; |
| 1212 | 1212 | |
| 1213 | −#define ACL_NO_MODE -1 | |
| 1213 | +#define ACL_NO_MODE ((umode_t)(-1)) | |
| 1214 | 1214 | struct cifs_open_parms { |
| 1215 | 1215 | struct cifs_tcon *tcon; |
| 1216 | 1216 | struct cifs_sb_info *cifs_sb; |
| @@ -4264,7 +4264,7 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, · 4263 unmodified lines | ||
| 4264 | 4264 | server->ops->qfs_tcon(*xid, tcon); |
| 4265 | 4265 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) { |
| 4266 | 4266 | if (tcon->fsDevInfo.DeviceCharacteristics & |
| 4267 | − FILE_READ_ONLY_DEVICE) | |
| 4267 | + cpu_to_le32(FILE_READ_ONLY_DEVICE)) | |
| 4268 | 4268 | cifs_dbg(VFS, "mounted to read only share\n"); |
| 4269 | 4269 | else if ((cifs_sb->mnt_cifs_flags & |
| 4270 | 4270 | CIFS_MOUNT_RW_CACHE) == 0) |
| @@ -4445,7 +4445,7 @@ static int setup_dfs_tgt_conn(const char *path, · 174 unmodified lines | ||
| 4445 | 4445 | int rc; |
| 4446 | 4446 | struct dfs_info3_param ref = {0}; |
| 4447 | 4447 | char *mdata = NULL, *fake_devname = NULL; |
| 4448 | − struct smb_vol fake_vol = {0}; | |
| 4448 | + struct smb_vol fake_vol = {NULL}; | |
| 4449 | 4449 | |
| 4450 | 4450 | cifs_dbg(FYI, "%s: dfs path: %s\n", __func__, path); |
| 4451 | 4451 | |
| @@ -738,10 +738,16 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, · 737 unmodified lines | ||
| 738 | 738 | static int |
| 739 | 739 | cifs_d_revalidate(struct dentry *direntry, unsigned int flags) |
| 740 | 740 | { |
| 741 | + struct inode *inode; | |
| 742 | + | |
| 741 | 743 | if (flags & LOOKUP_RCU) |
| 742 | 744 | return -ECHILD; |
| 743 | 745 | |
| 744 | 746 | if (d_really_is_positive(direntry)) { |
| 747 | + inode = d_inode(direntry); | |
| 748 | + if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode))) | |
| 749 | + CIFS_I(inode)->time = 0; /* force reval */ | |
| 750 | + | |
| 745 | 751 | if (cifs_revalidate_dentry(direntry)) |
| 746 | 752 | return 0; |
| 747 | 753 | else { |
| @@ -752,7 +758,7 @@ cifs_d_revalidate(struct dentry *direntry, unsigned int flags) · 4 unmodified lines | ||
| 752 | 758 | * attributes will have been updated by |
| 753 | 759 | * cifs_revalidate_dentry(). |
| 754 | 760 | */ |
| 755 | − if (IS_AUTOMOUNT(d_inode(direntry)) && | |
| 761 | + if (IS_AUTOMOUNT(inode) && | |
| 756 | 762 | !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) { |
| 757 | 763 | spin_lock(&direntry->d_lock); |
| 758 | 764 | direntry->d_flags |= DCACHE_NEED_AUTOMOUNT; |
| @@ -253,6 +253,12 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, · 252 unmodified lines | ||
| 253 | 253 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, |
| 254 | 254 | xid, fid); |
| 255 | 255 | |
| 256 | + if (rc) { | |
| 257 | + server->ops->close(xid, tcon, fid); | |
| 258 | + if (rc == -ESTALE) | |
| 259 | + rc = -EOPENSTALE; | |
| 260 | + } | |
| 261 | + | |
| 256 | 262 | out: |
| 257 | 263 | kfree(buf); |
| 258 | 264 | return rc; |
| @@ -1840,13 +1846,12 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, · 1581 unmodified lines | ||
| 1840 | 1846 | { |
| 1841 | 1847 | struct cifsFileInfo *open_file = NULL; |
| 1842 | 1848 | struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); |
| 1843 | − struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); | |
| 1844 | 1849 | |
| 1845 | 1850 | /* only filter by fsuid on multiuser mounts */ |
| 1846 | 1851 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
| 1847 | 1852 | fsuid_only = false; |
| 1848 | 1853 | |
| 1849 | − spin_lock(&tcon->open_file_lock); | |
| 1854 | + spin_lock(&cifs_inode->open_file_lock); | |
| 1850 | 1855 | /* we could simply get the first_list_entry since write-only entries |
| 1851 | 1856 | are always at the end of the list but since the first entry might |
| 1852 | 1857 | have a close pending, we go through the whole list */ |
| @@ -1858,7 +1863,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, · 5 unmodified lines | ||
| 1858 | 1863 | /* found a good file */ |
| 1859 | 1864 | /* lock it so it will not be closed on us */ |
| 1860 | 1865 | cifsFileInfo_get(open_file); |
| 1861 | − spin_unlock(&tcon->open_file_lock); | |
| 1866 | + spin_unlock(&cifs_inode->open_file_lock); | |
| 1862 | 1867 | return open_file; |
| 1863 | 1868 | } /* else might as well continue, and look for |
| 1864 | 1869 | another, or simply have the caller reopen it |
| @@ -1866,7 +1871,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, · 1 unmodified line | ||
| 1866 | 1871 | } else /* write only file */ |
| 1867 | 1872 | break; /* write only files are last so must be done */ |
| 1868 | 1873 | } |
| 1869 | − spin_unlock(&tcon->open_file_lock); | |
| 1874 | + spin_unlock(&cifs_inode->open_file_lock); | |
| 1870 | 1875 | return NULL; |
| 1871 | 1876 | } |
| 1872 | 1877 | |
| @@ -1877,7 +1882,6 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only, · 4 unmodified lines | ||
| 1877 | 1882 | { |
| 1878 | 1883 | struct cifsFileInfo *open_file, *inv_file = NULL; |
| 1879 | 1884 | struct cifs_sb_info *cifs_sb; |
| 1880 | − struct cifs_tcon *tcon; | |
| 1881 | 1885 | bool any_available = false; |
| 1882 | 1886 | int rc = -EBADF; |
| 1883 | 1887 | unsigned int refind = 0; |
| @@ -1897,16 +1901,15 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only, · 13 unmodified lines | ||
| 1897 | 1901 | } |
| 1898 | 1902 | |
| 1899 | 1903 | cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); |
| 1900 | − tcon = cifs_sb_master_tcon(cifs_sb); | |
| 1901 | 1904 | |
| 1902 | 1905 | /* only filter by fsuid on multiuser mounts */ |
| 1903 | 1906 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
| 1904 | 1907 | fsuid_only = false; |
| 1905 | 1908 | |
| 1906 | − spin_lock(&tcon->open_file_lock); | |
| 1909 | + spin_lock(&cifs_inode->open_file_lock); | |
| 1907 | 1910 | refind_writable: |
| 1908 | 1911 | if (refind > MAX_REOPEN_ATT) { |
| 1909 | − spin_unlock(&tcon->open_file_lock); | |
| 1912 | + spin_unlock(&cifs_inode->open_file_lock); | |
| 1910 | 1913 | return rc; |
| 1911 | 1914 | } |
| 1912 | 1915 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { |
| @@ -1918,7 +1921,7 @@ refind_writable: · 5 unmodified lines | ||
| 1918 | 1921 | if (!open_file->invalidHandle) { |
| 1919 | 1922 | /* found a good writable file */ |
| 1920 | 1923 | cifsFileInfo_get(open_file); |
| 1921 | − spin_unlock(&tcon->open_file_lock); | |
| 1924 | + spin_unlock(&cifs_inode->open_file_lock); | |
| 1922 | 1925 | *ret_file = open_file; |
| 1923 | 1926 | return 0; |
| 1924 | 1927 | } else { |
| @@ -1938,7 +1941,7 @@ refind_writable: · 13 unmodified lines | ||
| 1938 | 1941 | cifsFileInfo_get(inv_file); |
| 1939 | 1942 | } |
| 1940 | 1943 | |
| 1941 | − spin_unlock(&tcon->open_file_lock); | |
| 1944 | + spin_unlock(&cifs_inode->open_file_lock); | |
| 1942 | 1945 | |
| 1943 | 1946 | if (inv_file) { |
| 1944 | 1947 | rc = cifs_reopen_file(inv_file, false); |
| @@ -1953,7 +1956,7 @@ refind_writable: · 8 unmodified lines | ||
| 1953 | 1956 | cifsFileInfo_put(inv_file); |
| 1954 | 1957 | ++refind; |
| 1955 | 1958 | inv_file = NULL; |
| 1956 | − spin_lock(&tcon->open_file_lock); | |
| 1959 | + spin_lock(&cifs_inode->open_file_lock); | |
| 1957 | 1960 | goto refind_writable; |
| 1958 | 1961 | } |
| 1959 | 1962 | |
| @@ -4461,17 +4464,15 @@ static int cifs_readpage(struct file *file, struct page *page) · 2501 unmodified lines | ||
| 4461 | 4464 | static int is_inode_writable(struct cifsInodeInfo *cifs_inode) |
| 4462 | 4465 | { |
| 4463 | 4466 | struct cifsFileInfo *open_file; |
| 4464 | − struct cifs_tcon *tcon = | |
| 4465 | − cifs_sb_master_tcon(CIFS_SB(cifs_inode->vfs_inode.i_sb)); | |
| 4466 | 4467 | |
| 4467 | − spin_lock(&tcon->open_file_lock); | |
| 4468 | + spin_lock(&cifs_inode->open_file_lock); | |
| 4468 | 4469 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { |
| 4469 | 4470 | if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { |
| 4470 | − spin_unlock(&tcon->open_file_lock); | |
| 4471 | + spin_unlock(&cifs_inode->open_file_lock); | |
| 4471 | 4472 | return 1; |
| 4472 | 4473 | } |
| 4473 | 4474 | } |
| 4474 | − spin_unlock(&tcon->open_file_lock); | |
| 4475 | + spin_unlock(&cifs_inode->open_file_lock); | |
| 4475 | 4476 | return 0; |
| 4476 | 4477 | } |
| 4477 | 4478 | |
| @@ -414,6 +414,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, · 413 unmodified lines | ||
| 414 | 414 | /* if uniqueid is different, return error */ |
| 415 | 415 | if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && |
| 416 | 416 | CIFS_I(*pinode)->uniqueid != fattr.cf_uniqueid)) { |
| 417 | + CIFS_I(*pinode)->time = 0; /* force reval */ | |
| 417 | 418 | rc = -ESTALE; |
| 418 | 419 | goto cgiiu_exit; |
| 419 | 420 | } |
| @@ -421,6 +422,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, · 1 unmodified line | ||
| 421 | 422 | /* if filetype is different, return error */ |
| 422 | 423 | if (unlikely(((*pinode)->i_mode & S_IFMT) != |
| 423 | 424 | (fattr.cf_mode & S_IFMT))) { |
| 425 | + CIFS_I(*pinode)->time = 0; /* force reval */ | |
| 424 | 426 | rc = -ESTALE; |
| 425 | 427 | goto cgiiu_exit; |
| 426 | 428 | } |
| @@ -933,6 +935,7 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, · 506 unmodified lines | ||
| 933 | 935 | /* if uniqueid is different, return error */ |
| 934 | 936 | if (unlikely(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM && |
| 935 | 937 | CIFS_I(*inode)->uniqueid != fattr.cf_uniqueid)) { |
| 938 | + CIFS_I(*inode)->time = 0; /* force reval */ | |
| 936 | 939 | rc = -ESTALE; |
| 937 | 940 | goto cgii_exit; |
| 938 | 941 | } |
| @@ -940,6 +943,7 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, · 1 unmodified line | ||
| 940 | 943 | /* if filetype is different, return error */ |
| 941 | 944 | if (unlikely(((*inode)->i_mode & S_IFMT) != |
| 942 | 945 | (fattr.cf_mode & S_IFMT))) { |
| 946 | + CIFS_I(*inode)->time = 0; /* force reval */ | |
| 943 | 947 | rc = -ESTALE; |
| 944 | 948 | goto cgii_exit; |
| 945 | 949 | } |
| @@ -117,10 +117,6 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = { · 116 unmodified lines | ||
| 117 | 117 | {0, 0} |
| 118 | 118 | }; |
| 119 | 119 | |
| 120 | −static const struct smb_to_posix_error mapping_table_ERRHRD[] = { | |
| 121 | − {0, 0} | |
| 122 | −}; | |
| 123 | − | |
| 124 | 120 | /* |
| 125 | 121 | * Convert a string containing text IPv4 or IPv6 address to binary form. |
| 126 | 122 | * |
| @@ -751,8 +751,8 @@ add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode) · 750 unmodified lines | ||
| 751 | 751 | unsigned int num = *num_iovec; |
| 752 | 752 | |
| 753 | 753 | iov[num].iov_base = create_posix_buf(mode); |
| 754 | − if (mode == -1) | |
| 755 | − cifs_dbg(VFS, "illegal mode\n"); /* BB REMOVEME */ | |
| 754 | + if (mode == ACL_NO_MODE) | |
| 755 | + cifs_dbg(FYI, "illegal mode\n"); | |
| 756 | 756 | if (iov[num].iov_base == NULL) |
| 757 | 757 | return -ENOMEM; |
| 758 | 758 | iov[num].iov_len = sizeof(struct create_posix); |
| @@ -2521,11 +2521,8 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock, · 1762 unmodified lines | ||
| 2521 | 2521 | return rc; |
| 2522 | 2522 | } |
| 2523 | 2523 | |
| 2524 | − /* TODO: add handling for the mode on create */ | |
| 2525 | − if (oparms->disposition == FILE_CREATE) | |
| 2526 | − cifs_dbg(VFS, "mode is 0x%x\n", oparms->mode); /* BB REMOVEME */ | |
| 2527 | − | |
| 2528 | − if ((oparms->disposition == FILE_CREATE) && (oparms->mode != -1)) { | |
| 2524 | + if ((oparms->disposition == FILE_CREATE) && | |
| 2525 | + (oparms->mode != ACL_NO_MODE)) { | |
| 2529 | 2526 | if (n_iov > 2) { |
| 2530 | 2527 | struct create_context *ccontext = |
| 2531 | 2528 | (struct create_context *)iov[n_iov-1].iov_base; |
| @@ -3217,7 +3214,8 @@ SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst, · 685 unmodified lines | ||
| 3217 | 3214 | |
| 3218 | 3215 | req->PersistentFileId = persistent_fid; |
| 3219 | 3216 | req->VolatileFileId = volatile_fid; |
| 3220 | − req->OutputBufferLength = SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE; | |
| 3217 | + req->OutputBufferLength = | |
| 3218 | + cpu_to_le32(SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE); | |
| 3221 | 3219 | req->CompletionFilter = cpu_to_le32(completion_filter); |
| 3222 | 3220 | if (watch_tree) |
| 3223 | 3221 | req->Flags = cpu_to_le16(SMB2_WATCH_TREE); |
| @@ -150,6 +150,10 @@ extern int SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, · 149 unmodified lines | ||
| 150 | 150 | bool is_fsctl, char *in_data, u32 indatalen, |
| 151 | 151 | __u32 max_response_size); |
| 152 | 152 | extern void SMB2_ioctl_free(struct smb_rqst *rqst); |
| 153 | +extern int SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, | |
| 154 | + u64 persistent_fid, u64 volatile_fid, bool watch_tree, | |
| 155 | + u32 completion_filter); | |
| 156 | + | |
| 153 | 157 | extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon, |
| 154 | 158 | u64 persistent_file_id, u64 volatile_file_id); |
| 155 | 159 | extern int SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon, |
| @@ -241,9 +241,8 @@ void dio_warn_stale_pagecache(struct file *filp) · 240 unmodified lines | ||
| 241 | 241 | } |
| 242 | 242 | } |
| 243 | 243 | |
| 244 | −/** | |
| 244 | +/* | |
| 245 | 245 | * dio_complete() - called when all DIO BIO I/O has been completed |
| 246 | − * @offset: the byte offset in the file of the completed operation | |
| 247 | 246 | * |
| 248 | 247 | * This drops i_dio_count, lets interested parties know that a DIO operation |
| 249 | 248 | * has completed, and calculates the resulting return code for the operation. |
| @@ -164,8 +164,13 @@ static void finish_writeback_work(struct bdi_writeback *wb, · 163 unmodified lines | ||
| 164 | 164 | |
| 165 | 165 | if (work->auto_free) |
| 166 | 166 | kfree(work); |
| 167 | − if (done && atomic_dec_and_test(&done->cnt)) | |
| 168 | − wake_up_all(done->waitq); | |
| 167 | + if (done) { | |
| 168 | + wait_queue_head_t *waitq = done->waitq; | |
| 169 | + | |
| 170 | + /* @done can't be accessed after the following dec */ | |
| 171 | + if (atomic_dec_and_test(&done->cnt)) | |
| 172 | + wake_up_all(waitq); | |
| 173 | + } | |
| 169 | 174 | } |
| 170 | 175 | |
| 171 | 176 | static void wb_queue_work(struct bdi_writeback *wb, |
| @@ -900,7 +905,7 @@ restart: · 728 unmodified lines | ||
| 900 | 905 | * cgroup_writeback_by_id - initiate cgroup writeback from bdi and memcg IDs |
| 901 | 906 | * @bdi_id: target bdi id |
| 902 | 907 | * @memcg_id: target memcg css id |
| 903 | − * @nr_pages: number of pages to write, 0 for best-effort dirty flushing | |
| 908 | + * @nr: number of pages to write, 0 for best-effort dirty flushing | |
| 904 | 909 | * @reason: reason why some writeback work initiated |
| 905 | 910 | * @done: target wb_completion |
| 906 | 911 | * |
| @@ -322,6 +322,8 @@ struct io_kiocb { · 321 unmodified lines | ||
| 322 | 322 | #define REQ_F_FAIL_LINK 256 /* fail rest of links */ |
| 323 | 323 | #define REQ_F_SHADOW_DRAIN 512 /* link-drain shadow req */ |
| 324 | 324 | #define REQ_F_TIMEOUT 1024 /* timeout request */ |
| 325 | +#define REQ_F_ISREG 2048 /* regular file */ | |
| 326 | +#define REQ_F_MUST_PUNT 4096 /* must be punted even for NONBLOCK */ | |
| 325 | 327 | u64 user_data; |
| 326 | 328 | u32 result; |
| 327 | 329 | u32 sequence; |
| @@ -415,27 +417,27 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) · 87 unmodified lines | ||
| 415 | 417 | return ctx; |
| 416 | 418 | } |
| 417 | 419 | |
| 420 | +static inline bool __io_sequence_defer(struct io_ring_ctx *ctx, | |
| 421 | + struct io_kiocb *req) | |
| 422 | +{ | |
| 423 | + return req->sequence != ctx->cached_cq_tail + ctx->rings->sq_dropped; | |
| 424 | +} | |
| 425 | + | |
| 418 | 426 | static inline bool io_sequence_defer(struct io_ring_ctx *ctx, |
| 419 | 427 | struct io_kiocb *req) |
| 420 | 428 | { |
| 421 | − /* timeout requests always honor sequence */ | |
| 422 | − if (!(req->flags & REQ_F_TIMEOUT) && | |
| 423 | − (req->flags & (REQ_F_IO_DRAIN|REQ_F_IO_DRAINED)) != REQ_F_IO_DRAIN) | |
| 429 | + if ((req->flags & (REQ_F_IO_DRAIN|REQ_F_IO_DRAINED)) != REQ_F_IO_DRAIN) | |
| 424 | 430 | return false; |
| 425 | 431 | |
| 426 | − return req->sequence != ctx->cached_cq_tail + ctx->rings->sq_dropped; | |
| 432 | + return __io_sequence_defer(ctx, req); | |
| 427 | 433 | } |
| 428 | 434 | |
| 429 | −static struct io_kiocb *__io_get_deferred_req(struct io_ring_ctx *ctx, | |
| 430 | − struct list_head *list) | |
| 435 | +static struct io_kiocb *io_get_deferred_req(struct io_ring_ctx *ctx) | |
| 431 | 436 | { |
| 432 | 437 | struct io_kiocb *req; |
| 433 | 438 | |
| 434 | − if (list_empty(list)) | |
| 435 | − return NULL; | |
| 436 | − | |
| 437 | − req = list_first_entry(list, struct io_kiocb, list); | |
| 438 | − if (!io_sequence_defer(ctx, req)) { | |
| 439 | + req = list_first_entry_or_null(&ctx->defer_list, struct io_kiocb, list); | |
| 440 | + if (req && !io_sequence_defer(ctx, req)) { | |
| 439 | 441 | list_del_init(&req->list); |
| 440 | 442 | return req; |
| 441 | 443 | } |
| @@ -443,14 +445,17 @@ static struct io_kiocb *__io_get_deferred_req(struct io_ring_ctx *ctx, · 1 unmodified line | ||
| 443 | 445 | return NULL; |
| 444 | 446 | } |
| 445 | 447 | |
| 446 | −static struct io_kiocb *io_get_deferred_req(struct io_ring_ctx *ctx) | |
| 447 | −{ | |
| 448 | − return __io_get_deferred_req(ctx, &ctx->defer_list); | |
| 449 | −} | |
| 450 | − | |
| 451 | 448 | static struct io_kiocb *io_get_timeout_req(struct io_ring_ctx *ctx) |
| 452 | 449 | { |
| 453 | − return __io_get_deferred_req(ctx, &ctx->timeout_list); | |
| 450 | + struct io_kiocb *req; | |
| 451 | + | |
| 452 | + req = list_first_entry_or_null(&ctx->timeout_list, struct io_kiocb, list); | |
| 453 | + if (req && !__io_sequence_defer(ctx, req)) { | |
| 454 | + list_del_init(&req->list); | |
| 455 | + return req; | |
| 456 | + } | |
| 457 | + | |
| 458 | + return NULL; | |
| 454 | 459 | } |
| 455 | 460 | |
| 456 | 461 | static void __io_commit_cqring(struct io_ring_ctx *ctx) |
| @@ -591,14 +596,6 @@ static void io_cqring_add_event(struct io_ring_ctx *ctx, u64 user_data, · 134 unmodified lines | ||
| 591 | 596 | io_cqring_ev_posted(ctx); |
| 592 | 597 | } |
| 593 | 598 | |
| 594 | −static void io_ring_drop_ctx_refs(struct io_ring_ctx *ctx, unsigned refs) | |
| 595 | −{ | |
| 596 | − percpu_ref_put_many(&ctx->refs, refs); | |
| 597 | − | |
| 598 | − if (waitqueue_active(&ctx->wait)) | |
| 599 | − wake_up(&ctx->wait); | |
| 600 | −} | |
| 601 | − | |
| 602 | 599 | static struct io_kiocb *io_get_req(struct io_ring_ctx *ctx, |
| 603 | 600 | struct io_submit_state *state) |
| 604 | 601 | { |
| @@ -646,7 +643,7 @@ static struct io_kiocb *io_get_req(struct io_ring_ctx *ctx, · 41 unmodified lines | ||
| 646 | 643 | req->result = 0; |
| 647 | 644 | return req; |
| 648 | 645 | out: |
| 649 | − io_ring_drop_ctx_refs(ctx, 1); | |
| 646 | + percpu_ref_put(&ctx->refs); | |
| 650 | 647 | return NULL; |
| 651 | 648 | } |
| 652 | 649 | |
| @@ -654,7 +651,7 @@ static void io_free_req_many(struct io_ring_ctx *ctx, void **reqs, int *nr) · 1 unmodified line | ||
| 654 | 651 | { |
| 655 | 652 | if (*nr) { |
| 656 | 653 | kmem_cache_free_bulk(req_cachep, *nr, reqs); |
| 657 | − io_ring_drop_ctx_refs(ctx, *nr); | |
| 654 | + percpu_ref_put_many(&ctx->refs, *nr); | |
| 658 | 655 | *nr = 0; |
| 659 | 656 | } |
| 660 | 657 | } |
| @@ -663,7 +660,7 @@ static void __io_free_req(struct io_kiocb *req) · 2 unmodified lines | ||
| 663 | 660 | { |
| 664 | 661 | if (req->file && !(req->flags & REQ_F_FIXED_FILE)) |
| 665 | 662 | fput(req->file); |
| 666 | − io_ring_drop_ctx_refs(req->ctx, 1); | |
| 663 | + percpu_ref_put(&req->ctx->refs); | |
| 667 | 664 | kmem_cache_free(req_cachep, req); |
| 668 | 665 | } |
| 669 | 666 | |
| @@ -919,26 +916,26 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, unsigned *nr_events, · 249 unmodified lines | ||
| 919 | 916 | return ret; |
| 920 | 917 | } |
| 921 | 918 | |
| 922 | −static void kiocb_end_write(struct kiocb *kiocb) | |
| 919 | +static void kiocb_end_write(struct io_kiocb *req) | |
| 923 | 920 | { |
| 924 | − if (kiocb->ki_flags & IOCB_WRITE) { | |
| 925 | − struct inode *inode = file_inode(kiocb->ki_filp); | |
| 921 | + /* | |
| 922 | + * Tell lockdep we inherited freeze protection from submission | |
| 923 | + * thread. | |
| 924 | + */ | |
| 925 | + if (req->flags & REQ_F_ISREG) { | |
| 926 | + struct inode *inode = file_inode(req->file); | |
| 926 | 927 | |
| 927 | − /* | |
| 928 | − * Tell lockdep we inherited freeze protection from submission | |
| 929 | − * thread. | |
| 930 | − */ | |
| 931 | − if (S_ISREG(inode->i_mode)) | |
| 932 | − __sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE); | |
| 933 | − file_end_write(kiocb->ki_filp); | |
| 928 | + __sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE); | |
| 934 | 929 | } |
| 930 | + file_end_write(req->file); | |
| 935 | 931 | } |
| 936 | 932 | |
| 937 | 933 | static void io_complete_rw(struct kiocb *kiocb, long res, long res2) |
| 938 | 934 | { |
| 939 | 935 | struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw); |
| 940 | 936 | |
| 941 | − kiocb_end_write(kiocb); | |
| 937 | + if (kiocb->ki_flags & IOCB_WRITE) | |
| 938 | + kiocb_end_write(req); | |
| 942 | 939 | |
| 943 | 940 | if ((req->flags & REQ_F_LINK) && res != req->result) |
| 944 | 941 | req->flags |= REQ_F_FAIL_LINK; |
| @@ -950,7 +947,8 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2) · 5 unmodified lines | ||
| 950 | 947 | { |
| 951 | 948 | struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw); |
| 952 | 949 | |
| 953 | − kiocb_end_write(kiocb); | |
| 950 | + if (kiocb->ki_flags & IOCB_WRITE) | |
| 951 | + kiocb_end_write(req); | |
| 954 | 952 | |
| 955 | 953 | if ((req->flags & REQ_F_LINK) && res != req->result) |
| 956 | 954 | req->flags |= REQ_F_FAIL_LINK; |
| @@ -1064,8 +1062,17 @@ static int io_prep_rw(struct io_kiocb *req, const struct sqe_submit *s, · 107 unmodified lines | ||
| 1064 | 1062 | if (!req->file) |
| 1065 | 1063 | return -EBADF; |
| 1066 | 1064 | |
| 1067 | − if (force_nonblock && !io_file_supports_async(req->file)) | |
| 1068 | − force_nonblock = false; | |
| 1065 | + if (S_ISREG(file_inode(req->file)->i_mode)) | |
| 1066 | + req->flags |= REQ_F_ISREG; | |
| 1067 | + | |
| 1068 | + /* | |
| 1069 | + * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so | |
| 1070 | + * we know to async punt it even if it was opened O_NONBLOCK | |
| 1071 | + */ | |
| 1072 | + if (force_nonblock && !io_file_supports_async(req->file)) { | |
| 1073 | + req->flags |= REQ_F_MUST_PUNT; | |
| 1074 | + return -EAGAIN; | |
| 1075 | + } | |
| 1069 | 1076 | |
| 1070 | 1077 | kiocb->ki_pos = READ_ONCE(sqe->off); |
| 1071 | 1078 | kiocb->ki_flags = iocb_flags(kiocb->ki_filp); |
| @@ -1086,7 +1093,8 @@ static int io_prep_rw(struct io_kiocb *req, const struct sqe_submit *s, · 14 unmodified lines | ||
| 1086 | 1093 | return ret; |
| 1087 | 1094 | |
| 1088 | 1095 | /* don't allow async punt if RWF_NOWAIT was requested */ |
| 1089 | − if (kiocb->ki_flags & IOCB_NOWAIT) | |
| 1096 | + if ((kiocb->ki_flags & IOCB_NOWAIT) || | |
| 1097 | + (req->file->f_flags & O_NONBLOCK)) | |
| 1090 | 1098 | req->flags |= REQ_F_NOWAIT; |
| 1091 | 1099 | |
| 1092 | 1100 | if (force_nonblock) |
| @@ -1387,7 +1395,9 @@ static int io_read(struct io_kiocb *req, const struct sqe_submit *s, · 294 unmodified lines | ||
| 1387 | 1395 | * need async punt anyway, so it's more efficient to do it |
| 1388 | 1396 | * here. |
| 1389 | 1397 | */ |
| 1390 | − if (force_nonblock && ret2 > 0 && ret2 < read_size) | |
| 1398 | + if (force_nonblock && !(req->flags & REQ_F_NOWAIT) && | |
| 1399 | + (req->flags & REQ_F_ISREG) && | |
| 1400 | + ret2 > 0 && ret2 < read_size) | |
| 1391 | 1401 | ret2 = -EAGAIN; |
| 1392 | 1402 | /* Catch -EAGAIN return for forced non-blocking submission */ |
| 1393 | 1403 | if (!force_nonblock || ret2 != -EAGAIN) { |
| @@ -1452,7 +1462,7 @@ static int io_write(struct io_kiocb *req, const struct sqe_submit *s, · 58 unmodified lines | ||
| 1452 | 1462 | * released so that it doesn't complain about the held lock when |
| 1453 | 1463 | * we return to userspace. |
| 1454 | 1464 | */ |
| 1455 | − if (S_ISREG(file_inode(file)->i_mode)) { | |
| 1465 | + if (req->flags & REQ_F_ISREG) { | |
| 1456 | 1466 | __sb_start_write(file_inode(file)->i_sb, |
| 1457 | 1467 | SB_FREEZE_WRITE, true); |
| 1458 | 1468 | __sb_writers_release(file_inode(file)->i_sb, |
| @@ -1889,7 +1899,7 @@ static enum hrtimer_restart io_timeout_fn(struct hrtimer *timer) · 430 unmodified lines | ||
| 1889 | 1899 | |
| 1890 | 1900 | static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe) |
| 1891 | 1901 | { |
| 1892 | − unsigned count, req_dist, tail_index; | |
| 1902 | + unsigned count; | |
| 1893 | 1903 | struct io_ring_ctx *ctx = req->ctx; |
| 1894 | 1904 | struct list_head *entry; |
| 1895 | 1905 | struct timespec64 ts; |
| @@ -1912,21 +1922,36 @@ static int io_timeout(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 16 unmodified lines | ||
| 1912 | 1922 | count = 1; |
| 1913 | 1923 | |
| 1914 | 1924 | req->sequence = ctx->cached_sq_head + count - 1; |
| 1925 | + /* reuse it to store the count */ | |
| 1926 | + req->submit.sequence = count; | |
| 1915 | 1927 | req->flags |= REQ_F_TIMEOUT; |
| 1916 | 1928 | |
| 1917 | 1929 | /* |
| 1918 | 1930 | * Insertion sort, ensuring the first entry in the list is always |
| 1919 | 1931 | * the one we need first. |
| 1920 | 1932 | */ |
| 1921 | − tail_index = ctx->cached_cq_tail - ctx->rings->sq_dropped; | |
| 1922 | − req_dist = req->sequence - tail_index; | |
| 1923 | 1933 | spin_lock_irq(&ctx->completion_lock); |
| 1924 | 1934 | list_for_each_prev(entry, &ctx->timeout_list) { |
| 1925 | 1935 | struct io_kiocb *nxt = list_entry(entry, struct io_kiocb, list); |
| 1926 | − unsigned dist; | |
| 1936 | + unsigned nxt_sq_head; | |
| 1937 | + long long tmp, tmp_nxt; | |
| 1927 | 1938 | |
| 1928 | − dist = nxt->sequence - tail_index; | |
| 1929 | − if (req_dist >= dist) | |
| 1939 | + /* | |
| 1940 | + * Since cached_sq_head + count - 1 can overflow, use type long | |
| 1941 | + * long to store it. | |
| 1942 | + */ | |
| 1943 | + tmp = (long long)ctx->cached_sq_head + count - 1; | |
| 1944 | + nxt_sq_head = nxt->sequence - nxt->submit.sequence + 1; | |
| 1945 | + tmp_nxt = (long long)nxt_sq_head + nxt->submit.sequence - 1; | |
| 1946 | + | |
| 1947 | + /* | |
| 1948 | + * cached_sq_head may overflow, and it will never overflow twice | |
| 1949 | + * once there is some timeout req still be valid. | |
| 1950 | + */ | |
| 1951 | + if (ctx->cached_sq_head < nxt_sq_head) | |
| 1952 | + tmp += UINT_MAX; | |
| 1953 | + | |
| 1954 | + if (tmp >= tmp_nxt) | |
| 1930 | 1955 | break; |
| 1931 | 1956 | } |
| 1932 | 1957 | list_add(&req->list, entry); |
| @@ -2272,7 +2297,13 @@ static int __io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, · 339 unmodified lines | ||
| 2272 | 2297 | int ret; |
| 2273 | 2298 | |
| 2274 | 2299 | ret = __io_submit_sqe(ctx, req, s, force_nonblock); |
| 2275 | − if (ret == -EAGAIN && !(req->flags & REQ_F_NOWAIT)) { | |
| 2300 | + | |
| 2301 | + /* | |
| 2302 | + * We async punt it if the file wasn't marked NOWAIT, or if the file | |
| 2303 | + * doesn't support non-blocking read/write attempts | |
| 2304 | + */ | |
| 2305 | + if (ret == -EAGAIN && (!(req->flags & REQ_F_NOWAIT) || | |
| 2306 | + (req->flags & REQ_F_MUST_PUNT))) { | |
| 2276 | 2307 | struct io_uring_sqe *sqe_copy; |
| 2277 | 2308 | |
| 2278 | 2309 | sqe_copy = kmemdup(s->sqe, sizeof(*sqe_copy), GFP_KERNEL); |
| @@ -2761,7 +2792,7 @@ out: · 482 unmodified lines | ||
| 2761 | 2792 | |
| 2762 | 2793 | if (link) |
| 2763 | 2794 | io_queue_link_head(ctx, link, &link->submit, shadow_req, |
| 2764 | − block_for_last); | |
| 2795 | + !block_for_last); | |
| 2765 | 2796 | if (statep) |
| 2766 | 2797 | io_submit_state_end(statep); |
| 2767 | 2798 | |
| @@ -2920,8 +2951,12 @@ static void io_finish_async(struct io_ring_ctx *ctx) · 152 unmodified lines | ||
| 2920 | 2951 | static void io_destruct_skb(struct sk_buff *skb) |
| 2921 | 2952 | { |
| 2922 | 2953 | struct io_ring_ctx *ctx = skb->sk->sk_user_data; |
| 2954 | + int i; | |
| 2955 | + | |
| 2956 | + for (i = 0; i < ARRAY_SIZE(ctx->sqo_wq); i++) | |
| 2957 | + if (ctx->sqo_wq[i]) | |
| 2958 | + flush_workqueue(ctx->sqo_wq[i]); | |
| 2923 | 2959 | |
| 2924 | − io_finish_async(ctx); | |
| 2925 | 2960 | unix_destruct_scm(skb); |
| 2926 | 2961 | } |
| 2927 | 2962 | |
| @@ -3630,7 +3665,7 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit, · 702 unmodified lines | ||
| 3630 | 3665 | } |
| 3631 | 3666 | } |
| 3632 | 3667 | |
| 3633 | − io_ring_drop_ctx_refs(ctx, 1); | |
| 3668 | + percpu_ref_put(&ctx->refs); | |
| 3634 | 3669 | out_fput: |
| 3635 | 3670 | fdput(f); |
| 3636 | 3671 | return submitted ? submitted : ret; |
| @@ -89,58 +89,45 @@ int dcache_dir_close(struct inode *inode, struct file *file) · 88 unmodified lines | ||
| 89 | 89 | EXPORT_SYMBOL(dcache_dir_close); |
| 90 | 90 | |
| 91 | 91 | /* parent is locked at least shared */ |
| 92 | −static struct dentry *next_positive(struct dentry *parent, | |
| 93 | − struct list_head *from, | |
| 94 | − int count) | |
| 92 | +/* | |
| 93 | + * Returns an element of siblings' list. | |
| 94 | + * We are looking for <count>th positive after <p>; if | |
| 95 | + * found, dentry is grabbed and returned to caller. | |
| 96 | + * If no such element exists, NULL is returned. | |
| 97 | + */ | |
| 98 | +static struct dentry *scan_positives(struct dentry *cursor, | |
| 99 | + struct list_head *p, | |
| 100 | + loff_t count, | |
| 101 | + struct dentry *last) | |
| 95 | 102 | { |
| 96 | − unsigned *seq = &parent->d_inode->i_dir_seq, n; | |
| 97 | − struct dentry *res; | |
| 98 | − struct list_head *p; | |
| 99 | − bool skipped; | |
| 100 | − int i; | |
| 103 | + struct dentry *dentry = cursor->d_parent, *found = NULL; | |
| 101 | 104 | |
| 102 | −retry: | |
| 103 | − i = count; | |
| 104 | − skipped = false; | |
| 105 | − n = smp_load_acquire(seq) & ~1; | |
| 106 | − res = NULL; | |
| 107 | − rcu_read_lock(); | |
| 108 | − for (p = from->next; p != &parent->d_subdirs; p = p->next) { | |
| 105 | + spin_lock(&dentry->d_lock); | |
| 106 | + while ((p = p->next) != &dentry->d_subdirs) { | |
| 109 | 107 | struct dentry *d = list_entry(p, struct dentry, d_child); |
| 110 | − if (!simple_positive(d)) { | |
| 111 | − skipped = true; | |
| 112 | − } else if (!--i) { | |
| 113 | − res = d; | |
| 114 | − break; | |
| 108 | + // we must at least skip cursors, to avoid livelocks | |
| 109 | + if (d->d_flags & DCACHE_DENTRY_CURSOR) | |
| 110 | + continue; | |
| 111 | + if (simple_positive(d) && !--count) { | |
| 112 | + spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); | |
| 113 | + if (simple_positive(d)) | |
| 114 | + found = dget_dlock(d); | |
| 115 | + spin_unlock(&d->d_lock); | |
| 116 | + if (likely(found)) | |
| 117 | + break; | |
| 118 | + count = 1; | |
| 119 | + } | |
| 120 | + if (need_resched()) { | |
| 121 | + list_move(&cursor->d_child, p); | |
| 122 | + p = &cursor->d_child; | |
| 123 | + spin_unlock(&dentry->d_lock); | |
| 124 | + cond_resched(); | |
| 125 | + spin_lock(&dentry->d_lock); | |
| 115 | 126 | } |
| 116 | 127 | } |
| 117 | − rcu_read_unlock(); | |
| 118 | − if (skipped) { | |
| 119 | − smp_rmb(); | |
| 120 | − if (unlikely(*seq != n)) | |
| 121 | − goto retry; | |
| 122 | − } | |
| 123 | − return res; | |
| 124 | −} | |
| 125 | − | |
| 126 | −static void move_cursor(struct dentry *cursor, struct list_head *after) | |
| 127 | −{ | |
| 128 | − struct dentry *parent = cursor->d_parent; | |
| 129 | − unsigned n, *seq = &parent->d_inode->i_dir_seq; | |
| 130 | − spin_lock(&parent->d_lock); | |
| 131 | − for (;;) { | |
| 132 | − n = *seq; | |
| 133 | − if (!(n & 1) && cmpxchg(seq, n, n + 1) == n) | |
| 134 | − break; | |
| 135 | − cpu_relax(); | |
| 136 | − } | |
| 137 | − __list_del(cursor->d_child.prev, cursor->d_child.next); | |
| 138 | − if (after) | |
| 139 | − list_add(&cursor->d_child, after); | |
| 140 | − else | |
| 141 | − list_add_tail(&cursor->d_child, &parent->d_subdirs); | |
| 142 | − smp_store_release(seq, n + 2); | |
| 143 | − spin_unlock(&parent->d_lock); | |
| 128 | + spin_unlock(&dentry->d_lock); | |
| 129 | + dput(last); | |
| 130 | + return found; | |
| 144 | 131 | } |
| 145 | 132 | |
| 146 | 133 | loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence) |
| @@ -158,17 +145,25 @@ loff_t dcache_dir_lseek(struct file *file, loff_t offset, int whence) · 11 unmodified lines | ||
| 158 | 145 | return -EINVAL; |
| 159 | 146 | } |
| 160 | 147 | if (offset != file->f_pos) { |
| 148 | + struct dentry *cursor = file->private_data; | |
| 149 | + struct dentry *to = NULL; | |
| 150 | + | |
| 151 | + inode_lock_shared(dentry->d_inode); | |
| 152 | + | |
| 153 | + if (offset > 2) | |
| 154 | + to = scan_positives(cursor, &dentry->d_subdirs, | |
| 155 | + offset - 2, NULL); | |
| 156 | + spin_lock(&dentry->d_lock); | |
| 157 | + if (to) | |
| 158 | + list_move(&cursor->d_child, &to->d_child); | |
| 159 | + else | |
| 160 | + list_del_init(&cursor->d_child); | |
| 161 | + spin_unlock(&dentry->d_lock); | |
| 162 | + dput(to); | |
| 163 | + | |
| 161 | 164 | file->f_pos = offset; |
| 162 | − if (file->f_pos >= 2) { | |
| 163 | − struct dentry *cursor = file->private_data; | |
| 164 | − struct dentry *to; | |
| 165 | − loff_t n = file->f_pos - 2; | |
| 166 | − | |
| 167 | − inode_lock_shared(dentry->d_inode); | |
| 168 | − to = next_positive(dentry, &dentry->d_subdirs, n); | |
| 169 | − move_cursor(cursor, to ? &to->d_child : NULL); | |
| 170 | − inode_unlock_shared(dentry->d_inode); | |
| 171 | − } | |
| 165 | + | |
| 166 | + inode_unlock_shared(dentry->d_inode); | |
| 172 | 167 | } |
| 173 | 168 | return offset; |
| 174 | 169 | } |
| @@ -190,25 +185,35 @@ int dcache_readdir(struct file *file, struct dir_context *ctx) · 15 unmodified lines | ||
| 190 | 185 | { |
| 191 | 186 | struct dentry *dentry = file->f_path.dentry; |
| 192 | 187 | struct dentry *cursor = file->private_data; |
| 193 | − struct list_head *p = &cursor->d_child; | |
| 194 | − struct dentry *next; | |
| 195 | − bool moved = false; | |
| 188 | + struct list_head *anchor = &dentry->d_subdirs; | |
| 189 | + struct dentry *next = NULL; | |
| 190 | + struct list_head *p; | |
| 196 | 191 | |
| 197 | 192 | if (!dir_emit_dots(file, ctx)) |
| 198 | 193 | return 0; |
| 199 | 194 | |
| 200 | 195 | if (ctx->pos == 2) |
| 201 | − p = &dentry->d_subdirs; | |
| 202 | − while ((next = next_positive(dentry, p, 1)) != NULL) { | |
| 196 | + p = anchor; | |
| 197 | + else if (!list_empty(&cursor->d_child)) | |
| 198 | + p = &cursor->d_child; | |
| 199 | + else | |
| 200 | + return 0; | |
| 201 | + | |
| 202 | + while ((next = scan_positives(cursor, p, 1, next)) != NULL) { | |
| 203 | 203 | if (!dir_emit(ctx, next->d_name.name, next->d_name.len, |
| 204 | 204 | d_inode(next)->i_ino, dt_type(d_inode(next)))) |
| 205 | 205 | break; |
| 206 | − moved = true; | |
| 207 | − p = &next->d_child; | |
| 208 | 206 | ctx->pos++; |
| 207 | + p = &next->d_child; | |
| 209 | 208 | } |
| 210 | − if (moved) | |
| 211 | − move_cursor(cursor, p); | |
| 209 | + spin_lock(&dentry->d_lock); | |
| 210 | + if (next) | |
| 211 | + list_move_tail(&cursor->d_child, &next->d_child); | |
| 212 | + else | |
| 213 | + list_del_init(&cursor->d_child); | |
| 214 | + spin_unlock(&dentry->d_lock); | |
| 215 | + dput(next); | |
| 216 | + | |
| 212 | 217 | return 0; |
| 213 | 218 | } |
| 214 | 219 | EXPORT_SYMBOL(dcache_readdir); |
| @@ -468,8 +473,7 @@ EXPORT_SYMBOL(simple_write_begin); · 253 unmodified lines | ||
| 468 | 473 | |
| 469 | 474 | /** |
| 470 | 475 | * simple_write_end - .write_end helper for non-block-device FSes |
| 471 | − * @available: See .write_end of address_space_operations | |
| 472 | − * @file: " | |
| 476 | + * @file: See .write_end of address_space_operations | |
| 473 | 477 | * @mapping: " |
| 474 | 478 | * @pos: " |
| 475 | 479 | * @len: " |
| @@ -64,13 +64,6 @@ · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | static struct kmem_cache *nfs_direct_cachep; |
| 66 | 66 | |
| 67 | −/* | |
| 68 | − * This represents a set of asynchronous requests that we're waiting on | |
| 69 | − */ | |
| 70 | −struct nfs_direct_mirror { | |
| 71 | − ssize_t count; | |
| 72 | −}; | |
| 73 | − | |
| 74 | 67 | struct nfs_direct_req { |
| 75 | 68 | struct kref kref; /* release manager */ |
| 76 | 69 | |
| @@ -84,9 +77,6 @@ struct nfs_direct_req { · 7 unmodified lines | ||
| 84 | 77 | atomic_t io_count; /* i/os we're waiting for */ |
| 85 | 78 | spinlock_t lock; /* protect completion state */ |
| 86 | 79 | |
| 87 | − struct nfs_direct_mirror mirrors[NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX]; | |
| 88 | − int mirror_count; | |
| 89 | − | |
| 90 | 80 | loff_t io_start; /* Start offset for I/O */ |
| 91 | 81 | ssize_t count, /* bytes actually processed */ |
| 92 | 82 | max_count, /* max expected count */ |
| @@ -123,32 +113,42 @@ static inline int put_dreq(struct nfs_direct_req *dreq) · 30 unmodified lines | ||
| 123 | 113 | } |
| 124 | 114 | |
| 125 | 115 | static void |
| 126 | −nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr) | |
| 116 | +nfs_direct_handle_truncated(struct nfs_direct_req *dreq, | |
| 117 | + const struct nfs_pgio_header *hdr, | |
| 118 | + ssize_t dreq_len) | |
| 127 | 119 | { |
| 128 | − int i; | |
| 129 | − ssize_t count; | |
| 120 | + if (!(test_bit(NFS_IOHDR_ERROR, &hdr->flags) || | |
| 121 | + test_bit(NFS_IOHDR_EOF, &hdr->flags))) | |
| 122 | + return; | |
| 123 | + if (dreq->max_count >= dreq_len) { | |
| 124 | + dreq->max_count = dreq_len; | |
| 125 | + if (dreq->count > dreq_len) | |
| 126 | + dreq->count = dreq_len; | |
| 127 | + | |
| 128 | + if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) | |
| 129 | + dreq->error = hdr->error; | |
| 130 | + else /* Clear outstanding error if this is EOF */ | |
| 131 | + dreq->error = 0; | |
| 132 | + } | |
| 133 | +} | |
| 130 | 134 | |
| 131 | − WARN_ON_ONCE(dreq->count >= dreq->max_count); | |
| 135 | +static void | |
| 136 | +nfs_direct_count_bytes(struct nfs_direct_req *dreq, | |
| 137 | + const struct nfs_pgio_header *hdr) | |
| 138 | +{ | |
| 139 | + loff_t hdr_end = hdr->io_start + hdr->good_bytes; | |
| 140 | + ssize_t dreq_len = 0; | |
| 132 | 141 | |
| 133 | − if (dreq->mirror_count == 1) { | |
| 134 | − dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes; | |
| 135 | − dreq->count += hdr->good_bytes; | |
| 136 | − } else { | |
| 137 | − /* mirrored writes */ | |
| 138 | − count = dreq->mirrors[hdr->pgio_mirror_idx].count; | |
| 139 | − if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) { | |
| 140 | − count = hdr->io_start + hdr->good_bytes - dreq->io_start; | |
| 141 | − dreq->mirrors[hdr->pgio_mirror_idx].count = count; | |
| 142 | − } | |
| 143 | − /* update the dreq->count by finding the minimum agreed count from all | |
| 144 | − * mirrors */ | |
| 145 | − count = dreq->mirrors[0].count; | |
| 142 | + if (hdr_end > dreq->io_start) | |
| 143 | + dreq_len = hdr_end - dreq->io_start; | |
| 146 | 144 | |
| 147 | − for (i = 1; i < dreq->mirror_count; i++) | |
| 148 | − count = min(count, dreq->mirrors[i].count); | |
| 145 | + nfs_direct_handle_truncated(dreq, hdr, dreq_len); | |
| 149 | 146 | |
| 150 | − dreq->count = count; | |
| 151 | − } | |
| 147 | + if (dreq_len > dreq->max_count) | |
| 148 | + dreq_len = dreq->max_count; | |
| 149 | + | |
| 150 | + if (dreq->count < dreq_len) | |
| 151 | + dreq->count = dreq_len; | |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | 154 | /* |
| @@ -293,18 +293,6 @@ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, · 138 unmodified lines | ||
| 293 | 293 | cinfo->completion_ops = &nfs_direct_commit_completion_ops; |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | −static inline void nfs_direct_setup_mirroring(struct nfs_direct_req *dreq, | |
| 297 | − struct nfs_pageio_descriptor *pgio, | |
| 298 | − struct nfs_page *req) | |
| 299 | −{ | |
| 300 | − int mirror_count = 1; | |
| 301 | − | |
| 302 | − if (pgio->pg_ops->pg_get_mirror_count) | |
| 303 | − mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req); | |
| 304 | − | |
| 305 | − dreq->mirror_count = mirror_count; | |
| 306 | −} | |
| 307 | − | |
| 308 | 296 | static inline struct nfs_direct_req *nfs_direct_req_alloc(void) |
| 309 | 297 | { |
| 310 | 298 | struct nfs_direct_req *dreq; |
| @@ -319,7 +307,6 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void) · 8 unmodified lines | ||
| 319 | 307 | INIT_LIST_HEAD(&dreq->mds_cinfo.list); |
| 320 | 308 | dreq->verf.committed = NFS_INVALID_STABLE_HOW; /* not set yet */ |
| 321 | 309 | INIT_WORK(&dreq->work, nfs_direct_write_schedule_work); |
| 322 | − dreq->mirror_count = 1; | |
| 323 | 310 | spin_lock_init(&dreq->lock); |
| 324 | 311 | |
| 325 | 312 | return dreq; |
| @@ -402,20 +389,12 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr) · 76 unmodified lines | ||
| 402 | 389 | struct nfs_direct_req *dreq = hdr->dreq; |
| 403 | 390 | |
| 404 | 391 | spin_lock(&dreq->lock); |
| 405 | − if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) | |
| 406 | − dreq->error = hdr->error; | |
| 407 | − | |
| 408 | 392 | if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) { |
| 409 | 393 | spin_unlock(&dreq->lock); |
| 410 | 394 | goto out_put; |
| 411 | 395 | } |
| 412 | 396 | |
| 413 | − if (hdr->good_bytes != 0) | |
| 414 | − nfs_direct_good_bytes(dreq, hdr); | |
| 415 | − | |
| 416 | − if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) | |
| 417 | − dreq->error = 0; | |
| 418 | − | |
| 397 | + nfs_direct_count_bytes(dreq, hdr); | |
| 419 | 398 | spin_unlock(&dreq->lock); |
| 420 | 399 | |
| 421 | 400 | while (!list_empty(&hdr->pages)) { |
| @@ -646,29 +625,22 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) · 224 unmodified lines | ||
| 646 | 625 | LIST_HEAD(reqs); |
| 647 | 626 | struct nfs_commit_info cinfo; |
| 648 | 627 | LIST_HEAD(failed); |
| 649 | − int i; | |
| 650 | 628 | |
| 651 | 629 | nfs_init_cinfo_from_dreq(&cinfo, dreq); |
| 652 | 630 | nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); |
| 653 | 631 | |
| 654 | 632 | dreq->count = 0; |
| 633 | + dreq->max_count = 0; | |
| 634 | + list_for_each_entry(req, &reqs, wb_list) | |
| 635 | + dreq->max_count += req->wb_bytes; | |
| 655 | 636 | dreq->verf.committed = NFS_INVALID_STABLE_HOW; |
| 656 | 637 | nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo); |
| 657 | − for (i = 0; i < dreq->mirror_count; i++) | |
| 658 | − dreq->mirrors[i].count = 0; | |
| 659 | 638 | get_dreq(dreq); |
| 660 | 639 | |
| 661 | 640 | nfs_pageio_init_write(&desc, dreq->inode, FLUSH_STABLE, false, |
| 662 | 641 | &nfs_direct_write_completion_ops); |
| 663 | 642 | desc.pg_dreq = dreq; |
| 664 | 643 | |
| 665 | − req = nfs_list_entry(reqs.next); | |
| 666 | − nfs_direct_setup_mirroring(dreq, &desc, req); | |
| 667 | − if (desc.pg_error < 0) { | |
| 668 | − list_splice_init(&reqs, &failed); | |
| 669 | − goto out_failed; | |
| 670 | − } | |
| 671 | − | |
| 672 | 644 | list_for_each_entry_safe(req, tmp, &reqs, wb_list) { |
| 673 | 645 | /* Bump the transmission count */ |
| 674 | 646 | req->wb_nio++; |
| @@ -686,7 +658,6 @@ static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) · 11 unmodified lines | ||
| 686 | 658 | } |
| 687 | 659 | nfs_pageio_complete(&desc); |
| 688 | 660 | |
| 689 | −out_failed: | |
| 690 | 661 | while (!list_empty(&failed)) { |
| 691 | 662 | req = nfs_list_entry(failed.next); |
| 692 | 663 | nfs_list_remove_request(req); |
| @@ -791,17 +762,13 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr) · 98 unmodified lines | ||
| 791 | 762 | nfs_init_cinfo_from_dreq(&cinfo, dreq); |
| 792 | 763 | |
| 793 | 764 | spin_lock(&dreq->lock); |
| 794 | − | |
| 795 | − if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) | |
| 796 | − dreq->error = hdr->error; | |
| 797 | − | |
| 798 | 765 | if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) { |
| 799 | 766 | spin_unlock(&dreq->lock); |
| 800 | 767 | goto out_put; |
| 801 | 768 | } |
| 802 | 769 | |
| 770 | + nfs_direct_count_bytes(dreq, hdr); | |
| 803 | 771 | if (hdr->good_bytes != 0) { |
| 804 | − nfs_direct_good_bytes(dreq, hdr); | |
| 805 | 772 | if (nfs_write_need_commit(hdr)) { |
| 806 | 773 | if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) |
| 807 | 774 | request_commit = true; |
| @@ -923,7 +890,6 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, · 115 unmodified lines | ||
| 923 | 890 | break; |
| 924 | 891 | } |
| 925 | 892 | |
| 926 | − nfs_direct_setup_mirroring(dreq, &desc, req); | |
| 927 | 893 | if (desc.pg_error < 0) { |
| 928 | 894 | nfs_free_request(req); |
| 929 | 895 | result = desc.pg_error; |
| @@ -6106,6 +6106,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, · 6105 unmodified lines | ||
| 6106 | 6106 | |
| 6107 | 6107 | status = nfs4_call_sync_custom(&task_setup_data); |
| 6108 | 6108 | if (setclientid.sc_cred) { |
| 6109 | + kfree(clp->cl_acceptor); | |
| 6109 | 6110 | clp->cl_acceptor = rpcauth_stringify_acceptor(setclientid.sc_cred); |
| 6110 | 6111 | put_rpccred(setclientid.sc_cred); |
| 6111 | 6112 | } |
| @@ -786,7 +786,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) · 785 unmodified lines | ||
| 786 | 786 | struct nfs_inode *nfsi = NFS_I(inode); |
| 787 | 787 | struct nfs_page *head; |
| 788 | 788 | |
| 789 | − atomic_long_dec(&nfsi->nrequests); | |
| 790 | 789 | if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) { |
| 791 | 790 | head = req->wb_head; |
| 792 | 791 | |
| @@ -799,8 +798,10 @@ static void nfs_inode_remove_request(struct nfs_page *req) · 6 unmodified lines | ||
| 799 | 798 | spin_unlock(&mapping->private_lock); |
| 800 | 799 | } |
| 801 | 800 | |
| 802 | − if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) | |
| 801 | + if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) { | |
| 803 | 802 | nfs_release_request(req); |
| 803 | + atomic_long_dec(&nfsi->nrequests); | |
| 804 | + } | |
| 804 | 805 | } |
| 805 | 806 | |
| 806 | 807 | static void |
| @@ -2049,7 +2049,8 @@ out_write_size: · 2048 unmodified lines | ||
| 2049 | 2049 | inode->i_mtime = inode->i_ctime = current_time(inode); |
| 2050 | 2050 | di->i_mtime = di->i_ctime = cpu_to_le64(inode->i_mtime.tv_sec); |
| 2051 | 2051 | di->i_mtime_nsec = di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); |
| 2052 | − ocfs2_update_inode_fsync_trans(handle, inode, 1); | |
| 2052 | + if (handle) | |
| 2053 | + ocfs2_update_inode_fsync_trans(handle, inode, 1); | |
| 2053 | 2054 | } |
| 2054 | 2055 | if (handle) |
| 2055 | 2056 | ocfs2_journal_dirty(handle, wc->w_di_bh); |
| @@ -2146,13 +2147,30 @@ static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock, · 90 unmodified lines | ||
| 2146 | 2147 | struct ocfs2_dio_write_ctxt *dwc = NULL; |
| 2147 | 2148 | struct buffer_head *di_bh = NULL; |
| 2148 | 2149 | u64 p_blkno; |
| 2149 | − loff_t pos = iblock << inode->i_sb->s_blocksize_bits; | |
| 2150 | + unsigned int i_blkbits = inode->i_sb->s_blocksize_bits; | |
| 2151 | + loff_t pos = iblock << i_blkbits; | |
| 2152 | + sector_t endblk = (i_size_read(inode) - 1) >> i_blkbits; | |
| 2150 | 2153 | unsigned len, total_len = bh_result->b_size; |
| 2151 | 2154 | int ret = 0, first_get_block = 0; |
| 2152 | 2155 | |
| 2153 | 2156 | len = osb->s_clustersize - (pos & (osb->s_clustersize - 1)); |
| 2154 | 2157 | len = min(total_len, len); |
| 2155 | 2158 | |
| 2159 | + /* | |
| 2160 | + * bh_result->b_size is count in get_more_blocks according to write | |
| 2161 | + * "pos" and "end", we need map twice to return different buffer state: | |
| 2162 | + * 1. area in file size, not set NEW; | |
| 2163 | + * 2. area out file size, set NEW. | |
| 2164 | + * | |
| 2165 | + * iblock endblk | |
| 2166 | + * |--------|---------|---------|--------- | |
| 2167 | + * |<-------area in file------->| | |
| 2168 | + */ | |
| 2169 | + | |
| 2170 | + if ((iblock <= endblk) && | |
| 2171 | + ((iblock + ((len - 1) >> i_blkbits)) > endblk)) | |
| 2172 | + len = (endblk - iblock + 1) << i_blkbits; | |
| 2173 | + | |
| 2156 | 2174 | mlog(0, "get block of %lu at %llu:%u req %u\n", |
| 2157 | 2175 | inode->i_ino, pos, len, total_len); |
| 2158 | 2176 | |
| @@ -2236,6 +2254,9 @@ static int ocfs2_dio_wr_get_block(struct inode *inode, sector_t iblock, · 77 unmodified lines | ||
| 2236 | 2254 | if (desc->c_needs_zero) |
| 2237 | 2255 | set_buffer_new(bh_result); |
| 2238 | 2256 | |
| 2257 | + if (iblock > endblk) | |
| 2258 | + set_buffer_new(bh_result); | |
| 2259 | + | |
| 2239 | 2260 | /* May sleep in end_io. It should not happen in a irq context. So defer |
| 2240 | 2261 | * it to dio work queue. */ |
| 2241 | 2262 | set_buffer_defer_completion(bh_result); |
| @@ -1230,6 +1230,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) · 1229 unmodified lines | ||
| 1230 | 1230 | transfer_to[USRQUOTA] = dqget(sb, make_kqid_uid(attr->ia_uid)); |
| 1231 | 1231 | if (IS_ERR(transfer_to[USRQUOTA])) { |
| 1232 | 1232 | status = PTR_ERR(transfer_to[USRQUOTA]); |
| 1233 | + transfer_to[USRQUOTA] = NULL; | |
| 1233 | 1234 | goto bail_unlock; |
| 1234 | 1235 | } |
| 1235 | 1236 | } |
| @@ -1239,6 +1240,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) · 3 unmodified lines | ||
| 1239 | 1240 | transfer_to[GRPQUOTA] = dqget(sb, make_kqid_gid(attr->ia_gid)); |
| 1240 | 1241 | if (IS_ERR(transfer_to[GRPQUOTA])) { |
| 1241 | 1242 | status = PTR_ERR(transfer_to[GRPQUOTA]); |
| 1243 | + transfer_to[GRPQUOTA] = NULL; | |
| 1242 | 1244 | goto bail_unlock; |
| 1243 | 1245 | } |
| 1244 | 1246 | } |
| @@ -283,7 +283,7 @@ static int ocfs2_info_scan_inode_alloc(struct ocfs2_super *osb, · 282 unmodified lines | ||
| 283 | 283 | if (inode_alloc) |
| 284 | 284 | inode_lock(inode_alloc); |
| 285 | 285 | |
| 286 | − if (o2info_coherent(&fi->ifi_req)) { | |
| 286 | + if (inode_alloc && o2info_coherent(&fi->ifi_req)) { | |
| 287 | 287 | status = ocfs2_inode_lock(inode_alloc, &bh, 0); |
| 288 | 288 | if (status < 0) { |
| 289 | 289 | mlog_errno(status); |
| @@ -217,7 +217,8 @@ void ocfs2_recovery_exit(struct ocfs2_super *osb) · 216 unmodified lines | ||
| 217 | 217 | /* At this point, we know that no more recovery threads can be |
| 218 | 218 | * launched, so wait for any recovery completion work to |
| 219 | 219 | * complete. */ |
| 220 | − flush_workqueue(osb->ocfs2_wq); | |
| 220 | + if (osb->ocfs2_wq) | |
| 221 | + flush_workqueue(osb->ocfs2_wq); | |
| 221 | 222 | |
| 222 | 223 | /* |
| 223 | 224 | * Now that recovery is shut down, and the osb is about to be |
| @@ -377,7 +377,8 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) · 376 unmodified lines | ||
| 377 | 377 | struct ocfs2_dinode *alloc = NULL; |
| 378 | 378 | |
| 379 | 379 | cancel_delayed_work(&osb->la_enable_wq); |
| 380 | − flush_workqueue(osb->ocfs2_wq); | |
| 380 | + if (osb->ocfs2_wq) | |
| 381 | + flush_workqueue(osb->ocfs2_wq); | |
| 381 | 382 | |
| 382 | 383 | if (osb->local_alloc_state == OCFS2_LA_UNUSED) |
| 383 | 384 | goto out; |
| @@ -1490,18 +1490,6 @@ static int ocfs2_xa_check_space(struct ocfs2_xa_loc *loc, · 1489 unmodified lines | ||
| 1490 | 1490 | return loc->xl_ops->xlo_check_space(loc, xi); |
| 1491 | 1491 | } |
| 1492 | 1492 | |
| 1493 | −static void ocfs2_xa_add_entry(struct ocfs2_xa_loc *loc, u32 name_hash) | |
| 1494 | −{ | |
| 1495 | − loc->xl_ops->xlo_add_entry(loc, name_hash); | |
| 1496 | − loc->xl_entry->xe_name_hash = cpu_to_le32(name_hash); | |
| 1497 | − /* | |
| 1498 | − * We can't leave the new entry's xe_name_offset at zero or | |
| 1499 | − * add_namevalue() will go nuts. We set it to the size of our | |
| 1500 | − * storage so that it can never be less than any other entry. | |
| 1501 | − */ | |
| 1502 | − loc->xl_entry->xe_name_offset = cpu_to_le16(loc->xl_size); | |
| 1503 | −} | |
| 1504 | − | |
| 1505 | 1493 | static void ocfs2_xa_add_namevalue(struct ocfs2_xa_loc *loc, |
| 1506 | 1494 | struct ocfs2_xattr_info *xi) |
| 1507 | 1495 | { |
| @@ -2133,29 +2121,31 @@ static int ocfs2_xa_prepare_entry(struct ocfs2_xa_loc *loc, · 625 unmodified lines | ||
| 2133 | 2121 | if (rc) |
| 2134 | 2122 | goto out; |
| 2135 | 2123 | |
| 2136 | − if (loc->xl_entry) { | |
| 2137 | − if (ocfs2_xa_can_reuse_entry(loc, xi)) { | |
| 2138 | − orig_value_size = loc->xl_entry->xe_value_size; | |
| 2139 | − rc = ocfs2_xa_reuse_entry(loc, xi, ctxt); | |
| 2140 | − if (rc) | |
| 2141 | − goto out; | |
| 2142 | − goto alloc_value; | |
| 2143 | − } | |
| 2124 | + if (!loc->xl_entry) { | |
| 2125 | + rc = -EINVAL; | |
| 2126 | + goto out; | |
| 2127 | + } | |
| 2144 | 2128 | |
| 2145 | − if (!ocfs2_xattr_is_local(loc->xl_entry)) { | |
| 2146 | − orig_clusters = ocfs2_xa_value_clusters(loc); | |
| 2147 | − rc = ocfs2_xa_value_truncate(loc, 0, ctxt); | |
| 2148 | − if (rc) { | |
| 2149 | − mlog_errno(rc); | |
| 2150 | − ocfs2_xa_cleanup_value_truncate(loc, | |
| 2151 | − "overwriting", | |
| 2152 | − orig_clusters); | |
| 2153 | − goto out; | |
| 2154 | − } | |
| 2129 | + if (ocfs2_xa_can_reuse_entry(loc, xi)) { | |
| 2130 | + orig_value_size = loc->xl_entry->xe_value_size; | |
| 2131 | + rc = ocfs2_xa_reuse_entry(loc, xi, ctxt); | |
| 2132 | + if (rc) | |
| 2133 | + goto out; | |
| 2134 | + goto alloc_value; | |
| 2135 | + } | |
| 2136 | + | |
| 2137 | + if (!ocfs2_xattr_is_local(loc->xl_entry)) { | |
| 2138 | + orig_clusters = ocfs2_xa_value_clusters(loc); | |
| 2139 | + rc = ocfs2_xa_value_truncate(loc, 0, ctxt); | |
| 2140 | + if (rc) { | |
| 2141 | + mlog_errno(rc); | |
| 2142 | + ocfs2_xa_cleanup_value_truncate(loc, | |
| 2143 | + "overwriting", | |
| 2144 | + orig_clusters); | |
| 2145 | + goto out; | |
| 2155 | 2146 | } |
| 2156 | − ocfs2_xa_wipe_namevalue(loc); | |
| 2157 | − } else | |
| 2158 | − ocfs2_xa_add_entry(loc, name_hash); | |
| 2147 | + } | |
| 2148 | + ocfs2_xa_wipe_namevalue(loc); | |
| 2159 | 2149 | |
| 2160 | 2150 | /* |
| 2161 | 2151 | * If we get here, we have a blank entry. Fill it. We grow our |
| @@ -132,9 +132,9 @@ static int meminfo_proc_show(struct seq_file *m, void *v) · 131 unmodified lines | ||
| 132 | 132 | global_node_page_state(NR_SHMEM_THPS) * HPAGE_PMD_NR); |
| 133 | 133 | show_val_kb(m, "ShmemPmdMapped: ", |
| 134 | 134 | global_node_page_state(NR_SHMEM_PMDMAPPED) * HPAGE_PMD_NR); |
| 135 | − show_val_kb(m, "FileHugePages: ", | |
| 135 | + show_val_kb(m, "FileHugePages: ", | |
| 136 | 136 | global_node_page_state(NR_FILE_THPS) * HPAGE_PMD_NR); |
| 137 | − show_val_kb(m, "FilePmdMapped: ", | |
| 137 | + show_val_kb(m, "FilePmdMapped: ", | |
| 138 | 138 | global_node_page_state(NR_FILE_PMDMAPPED) * HPAGE_PMD_NR); |
| 139 | 139 | #endif |
| 140 | 140 | |
| @@ -42,10 +42,12 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf, · 41 unmodified lines | ||
| 42 | 42 | return -EINVAL; |
| 43 | 43 | |
| 44 | 44 | while (count > 0) { |
| 45 | − if (pfn_valid(pfn)) | |
| 46 | − ppage = pfn_to_page(pfn); | |
| 47 | − else | |
| 48 | − ppage = NULL; | |
| 45 | + /* | |
| 46 | + * TODO: ZONE_DEVICE support requires to identify | |
| 47 | + * memmaps that were actually initialized. | |
| 48 | + */ | |
| 49 | + ppage = pfn_to_online_page(pfn); | |
| 50 | + | |
| 49 | 51 | if (!ppage || PageSlab(ppage) || page_has_type(ppage)) |
| 50 | 52 | pcount = 0; |
| 51 | 53 | else |
| @@ -216,10 +218,11 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf, · 164 unmodified lines | ||
| 216 | 218 | return -EINVAL; |
| 217 | 219 | |
| 218 | 220 | while (count > 0) { |
| 219 | − if (pfn_valid(pfn)) | |
| 220 | − ppage = pfn_to_page(pfn); | |
| 221 | − else | |
| 222 | − ppage = NULL; | |
| 221 | + /* | |
| 222 | + * TODO: ZONE_DEVICE support requires to identify | |
| 223 | + * memmaps that were actually initialized. | |
| 224 | + */ | |
| 225 | + ppage = pfn_to_online_page(pfn); | |
| 223 | 226 | |
| 224 | 227 | if (put_user(stable_page_flags(ppage), out)) { |
| 225 | 228 | ret = -EFAULT; |
| @@ -261,10 +264,11 @@ static ssize_t kpagecgroup_read(struct file *file, char __user *buf, · 35 unmodified lines | ||
| 261 | 264 | return -EINVAL; |
| 262 | 265 | |
| 263 | 266 | while (count > 0) { |
| 264 | − if (pfn_valid(pfn)) | |
| 265 | − ppage = pfn_to_page(pfn); | |
| 266 | − else | |
| 267 | − ppage = NULL; | |
| 267 | + /* | |
| 268 | + * TODO: ZONE_DEVICE support requires to identify | |
| 269 | + * memmaps that were actually initialized. | |
| 270 | + */ | |
| 271 | + ppage = pfn_to_online_page(pfn); | |
| 268 | 272 | |
| 269 | 273 | if (ppage) |
| 270 | 274 | ino = page_cgroup_ino(ppage); |
| @@ -27,53 +27,13 @@ · 26 unmodified lines | ||
| 27 | 27 | /* |
| 28 | 28 | * Note the "unsafe_put_user() semantics: we goto a |
| 29 | 29 | * label for errors. |
| 30 | − * | |
| 31 | − * Also note how we use a "while()" loop here, even though | |
| 32 | − * only the biggest size needs to loop. The compiler (well, | |
| 33 | − * at least gcc) is smart enough to turn the smaller sizes | |
| 34 | − * into just if-statements, and this way we don't need to | |
| 35 | − * care whether 'u64' or 'u32' is the biggest size. | |
| 36 | − */ | |
| 37 | −#define unsafe_copy_loop(dst, src, len, type, label) \ | |
| 38 | − while (len >= sizeof(type)) { \ | |
| 39 | − unsafe_put_user(get_unaligned((type *)src), \ | |
| 40 | − (type __user *)dst, label); \ | |
| 41 | − dst += sizeof(type); \ | |
| 42 | − src += sizeof(type); \ | |
| 43 | − len -= sizeof(type); \ | |
| 44 | − } | |
| 45 | − | |
| 46 | −/* | |
| 47 | − * We avoid doing 64-bit copies on 32-bit architectures. They | |
| 48 | − * might be better, but the component names are mostly small, | |
| 49 | − * and the 64-bit cases can end up being much more complex and | |
| 50 | − * put much more register pressure on the code, so it's likely | |
| 51 | − * not worth the pain of unaligned accesses etc. | |
| 52 | − * | |
| 53 | − * So limit the copies to "unsigned long" size. I did verify | |
| 54 | − * that at least the x86-32 case is ok without this limiting, | |
| 55 | − * but I worry about random other legacy 32-bit cases that | |
| 56 | − * might not do as well. | |
| 57 | − */ | |
| 58 | −#define unsafe_copy_type(dst, src, len, type, label) do { \ | |
| 59 | − if (sizeof(type) <= sizeof(unsigned long)) \ | |
| 60 | − unsafe_copy_loop(dst, src, len, type, label); \ | |
| 61 | −} while (0) | |
| 62 | − | |
| 63 | −/* | |
| 64 | − * Copy the dirent name to user space, and NUL-terminate | |
| 65 | − * it. This should not be a function call, since we're doing | |
| 66 | − * the copy inside a "user_access_begin/end()" section. | |
| 67 | 30 | */ |
| 68 | 31 | #define unsafe_copy_dirent_name(_dst, _src, _len, label) do { \ |
| 69 | 32 | char __user *dst = (_dst); \ |
| 70 | 33 | const char *src = (_src); \ |
| 71 | 34 | size_t len = (_len); \ |
| 72 | − unsafe_copy_type(dst, src, len, u64, label); \ | |
| 73 | − unsafe_copy_type(dst, src, len, u32, label); \ | |
| 74 | − unsafe_copy_type(dst, src, len, u16, label); \ | |
| 75 | − unsafe_copy_type(dst, src, len, u8, label); \ | |
| 76 | − unsafe_put_user(0, dst, label); \ | |
| 35 | + unsafe_put_user(0, dst+len, label); \ | |
| 36 | + unsafe_copy_to_user(dst, src, len, label); \ | |
| 77 | 37 | } while (0) |
| 78 | 38 | |
| 79 | 39 | |
| @@ -145,9 +105,9 @@ EXPORT_SYMBOL(iterate_dir); · 65 unmodified lines | ||
| 145 | 105 | */ |
| 146 | 106 | static int verify_dirent_name(const char *name, int len) |
| 147 | 107 | { |
| 148 | − if (WARN_ON_ONCE(!len)) | |
| 108 | + if (!len) | |
| 149 | 109 | return -EIO; |
| 150 | − if (WARN_ON_ONCE(memchr(name, '/', len))) | |
| 110 | + if (memchr(name, '/', len)) | |
| 151 | 111 | return -EIO; |
| 152 | 112 | return 0; |
| 153 | 113 | } |
| @@ -1300,6 +1300,7 @@ int get_tree_bdev(struct fs_context *fc, · 1299 unmodified lines | ||
| 1300 | 1300 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
| 1301 | 1301 | if (bdev->bd_fsfreeze_count > 0) { |
| 1302 | 1302 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
| 1303 | + blkdev_put(bdev, mode); | |
| 1303 | 1304 | warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev); |
| 1304 | 1305 | return -EBUSY; |
| 1305 | 1306 | } |
| @@ -1308,8 +1309,10 @@ int get_tree_bdev(struct fs_context *fc, · 2 unmodified lines | ||
| 1308 | 1309 | fc->sget_key = bdev; |
| 1309 | 1310 | s = sget_fc(fc, test_bdev_super_fc, set_bdev_super_fc); |
| 1310 | 1311 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
| 1311 | − if (IS_ERR(s)) | |
| 1312 | + if (IS_ERR(s)) { | |
| 1313 | + blkdev_put(bdev, mode); | |
| 1312 | 1314 | return PTR_ERR(s); |
| 1315 | + } | |
| 1313 | 1316 | |
| 1314 | 1317 | if (s->s_root) { |
| 1315 | 1318 | /* Don't summarily change the RO/RW state. */ |
| @@ -16,11 +16,11 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <linux/namei.h> |
| 17 | 17 | #include <linux/tracefs.h> |
| 18 | 18 | #include <linux/fsnotify.h> |
| 19 | +#include <linux/security.h> | |
| 19 | 20 | #include <linux/seq_file.h> |
| 20 | 21 | #include <linux/parser.h> |
| 21 | 22 | #include <linux/magic.h> |
| 22 | 23 | #include <linux/slab.h> |
| 23 | −#include <linux/security.h> | |
| 24 | 24 | |
| 25 | 25 | #define TRACEFS_DEFAULT_MODE 0700 |
| 26 | 26 | |
| @@ -28,25 +28,6 @@ static struct vfsmount *tracefs_mount; · 1 unmodified line | ||
| 28 | 28 | static int tracefs_mount_count; |
| 29 | 29 | static bool tracefs_registered; |
| 30 | 30 | |
| 31 | −static int default_open_file(struct inode *inode, struct file *filp) | |
| 32 | −{ | |
| 33 | − struct dentry *dentry = filp->f_path.dentry; | |
| 34 | − struct file_operations *real_fops; | |
| 35 | − int ret; | |
| 36 | − | |
| 37 | − if (!dentry) | |
| 38 | − return -EINVAL; | |
| 39 | − | |
| 40 | − ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 41 | − if (ret) | |
| 42 | − return ret; | |
| 43 | − | |
| 44 | − real_fops = dentry->d_fsdata; | |
| 45 | − if (!real_fops->open) | |
| 46 | − return 0; | |
| 47 | − return real_fops->open(inode, filp); | |
| 48 | −} | |
| 49 | − | |
| 50 | 31 | static ssize_t default_read_file(struct file *file, char __user *buf, |
| 51 | 32 | size_t count, loff_t *ppos) |
| 52 | 33 | { |
| @@ -241,12 +222,6 @@ static int tracefs_apply_options(struct super_block *sb) · 188 unmodified lines | ||
| 241 | 222 | return 0; |
| 242 | 223 | } |
| 243 | 224 | |
| 244 | −static void tracefs_destroy_inode(struct inode *inode) | |
| 245 | −{ | |
| 246 | − if (S_ISREG(inode->i_mode)) | |
| 247 | − kfree(inode->i_fop); | |
| 248 | −} | |
| 249 | − | |
| 250 | 225 | static int tracefs_remount(struct super_block *sb, int *flags, char *data) |
| 251 | 226 | { |
| 252 | 227 | int err; |
| @@ -283,7 +258,6 @@ static int tracefs_show_options(struct seq_file *m, struct dentry *root) · 30 unmodified lines | ||
| 283 | 258 | static const struct super_operations tracefs_super_operations = { |
| 284 | 259 | .statfs = simple_statfs, |
| 285 | 260 | .remount_fs = tracefs_remount, |
| 286 | − .destroy_inode = tracefs_destroy_inode, | |
| 287 | 261 | .show_options = tracefs_show_options, |
| 288 | 262 | }; |
| 289 | 263 | |
| @@ -414,10 +388,12 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode, · 124 unmodified lines | ||
| 414 | 388 | struct dentry *parent, void *data, |
| 415 | 389 | const struct file_operations *fops) |
| 416 | 390 | { |
| 417 | − struct file_operations *proxy_fops; | |
| 418 | 391 | struct dentry *dentry; |
| 419 | 392 | struct inode *inode; |
| 420 | 393 | |
| 394 | + if (security_locked_down(LOCKDOWN_TRACEFS)) | |
| 395 | + return NULL; | |
| 396 | + | |
| 421 | 397 | if (!(mode & S_IFMT)) |
| 422 | 398 | mode |= S_IFREG; |
| 423 | 399 | BUG_ON(!S_ISREG(mode)); |
| @@ -430,20 +406,8 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode, · 6 unmodified lines | ||
| 430 | 406 | if (unlikely(!inode)) |
| 431 | 407 | return failed_creating(dentry); |
| 432 | 408 | |
| 433 | − proxy_fops = kzalloc(sizeof(struct file_operations), GFP_KERNEL); | |
| 434 | − if (unlikely(!proxy_fops)) { | |
| 435 | − iput(inode); | |
| 436 | − return failed_creating(dentry); | |
| 437 | − } | |
| 438 | − | |
| 439 | − if (!fops) | |
| 440 | − fops = &tracefs_file_operations; | |
| 441 | − | |
| 442 | − dentry->d_fsdata = (void *)fops; | |
| 443 | − memcpy(proxy_fops, fops, sizeof(*proxy_fops)); | |
| 444 | − proxy_fops->open = default_open_file; | |
| 445 | 409 | inode->i_mode = mode; |
| 446 | − inode->i_fop = proxy_fops; | |
| 410 | + inode->i_fop = fops ? fops : &tracefs_file_operations; | |
| 447 | 411 | inode->i_private = data; |
| 448 | 412 | d_instantiate(dentry, inode); |
| 449 | 413 | fsnotify_create(dentry->d_parent->d_inode, dentry); |
| @@ -28,12 +28,11 @@ xfs_get_aghdr_buf( · 27 unmodified lines | ||
| 28 | 28 | struct xfs_mount *mp, |
| 29 | 29 | xfs_daddr_t blkno, |
| 30 | 30 | size_t numblks, |
| 31 | − int flags, | |
| 32 | 31 | const struct xfs_buf_ops *ops) |
| 33 | 32 | { |
| 34 | 33 | struct xfs_buf *bp; |
| 35 | 34 | |
| 36 | − bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, flags); | |
| 35 | + bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, 0); | |
| 37 | 36 | if (!bp) |
| 38 | 37 | return NULL; |
| 39 | 38 | |
| @@ -345,7 +344,7 @@ xfs_ag_init_hdr( · 305 unmodified lines | ||
| 345 | 344 | { |
| 346 | 345 | struct xfs_buf *bp; |
| 347 | 346 | |
| 348 | − bp = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, 0, ops); | |
| 347 | + bp = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, ops); | |
| 349 | 348 | if (!bp) |
| 350 | 349 | return -ENOMEM; |
| 351 | 350 | |
| @@ -826,32 +826,17 @@ xfs_attr_shortform_to_leaf( · 825 unmodified lines | ||
| 826 | 826 | sf = (xfs_attr_shortform_t *)tmpbuffer; |
| 827 | 827 | |
| 828 | 828 | xfs_idata_realloc(dp, -size, XFS_ATTR_FORK); |
| 829 | − xfs_bmap_local_to_extents_empty(dp, XFS_ATTR_FORK); | |
| 829 | + xfs_bmap_local_to_extents_empty(args->trans, dp, XFS_ATTR_FORK); | |
| 830 | 830 | |
| 831 | 831 | bp = NULL; |
| 832 | 832 | error = xfs_da_grow_inode(args, &blkno); |
| 833 | − if (error) { | |
| 834 | − /* | |
| 835 | − * If we hit an IO error middle of the transaction inside | |
| 836 | − * grow_inode(), we may have inconsistent data. Bail out. | |
| 837 | − */ | |
| 838 | − if (error == -EIO) | |
| 839 | − goto out; | |
| 840 | − xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */ | |
| 841 | − memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */ | |
| 833 | + if (error) | |
| 842 | 834 | goto out; |
| 843 | − } | |
| 844 | 835 | |
| 845 | 836 | ASSERT(blkno == 0); |
| 846 | 837 | error = xfs_attr3_leaf_create(args, blkno, &bp); |
| 847 | − if (error) { | |
| 848 | − /* xfs_attr3_leaf_create may not have instantiated a block */ | |
| 849 | − if (bp && (xfs_da_shrink_inode(args, 0, bp) != 0)) | |
| 850 | − goto out; | |
| 851 | − xfs_idata_realloc(dp, size, XFS_ATTR_FORK); /* try to put */ | |
| 852 | − memcpy(ifp->if_u1.if_data, tmpbuffer, size); /* it back */ | |
| 838 | + if (error) | |
| 853 | 839 | goto out; |
| 854 | − } | |
| 855 | 840 | |
| 856 | 841 | memset((char *)&nargs, 0, sizeof(nargs)); |
| 857 | 842 | nargs.dp = dp; |
| @@ -792,6 +792,7 @@ out_root_realloc: · 791 unmodified lines | ||
| 792 | 792 | */ |
| 793 | 793 | void |
| 794 | 794 | xfs_bmap_local_to_extents_empty( |
| 795 | + struct xfs_trans *tp, | |
| 795 | 796 | struct xfs_inode *ip, |
| 796 | 797 | int whichfork) |
| 797 | 798 | { |
| @@ -808,6 +809,7 @@ xfs_bmap_local_to_extents_empty( · 10 unmodified lines | ||
| 808 | 809 | ifp->if_u1.if_root = NULL; |
| 809 | 810 | ifp->if_height = 0; |
| 810 | 811 | XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); |
| 812 | + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | |
| 811 | 813 | } |
| 812 | 814 | |
| 813 | 815 | |
| @@ -840,7 +842,7 @@ xfs_bmap_local_to_extents( · 26 unmodified lines | ||
| 840 | 842 | ASSERT(XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_LOCAL); |
| 841 | 843 | |
| 842 | 844 | if (!ifp->if_bytes) { |
| 843 | − xfs_bmap_local_to_extents_empty(ip, whichfork); | |
| 845 | + xfs_bmap_local_to_extents_empty(tp, ip, whichfork); | |
| 844 | 846 | flags = XFS_ILOG_CORE; |
| 845 | 847 | goto done; |
| 846 | 848 | } |
| @@ -887,7 +889,7 @@ xfs_bmap_local_to_extents( · 40 unmodified lines | ||
| 887 | 889 | |
| 888 | 890 | /* account for the change in fork size */ |
| 889 | 891 | xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); |
| 890 | − xfs_bmap_local_to_extents_empty(ip, whichfork); | |
| 892 | + xfs_bmap_local_to_extents_empty(tp, ip, whichfork); | |
| 891 | 893 | flags |= XFS_ILOG_CORE; |
| 892 | 894 | |
| 893 | 895 | ifp->if_u1.if_root = NULL; |
| @@ -182,7 +182,8 @@ void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno, · 181 unmodified lines | ||
| 182 | 182 | xfs_filblks_t len); |
| 183 | 183 | int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); |
| 184 | 184 | int xfs_bmap_set_attrforkoff(struct xfs_inode *ip, int size, int *version); |
| 185 | −void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); | |
| 185 | +void xfs_bmap_local_to_extents_empty(struct xfs_trans *tp, | |
| 186 | + struct xfs_inode *ip, int whichfork); | |
| 186 | 187 | void __xfs_bmap_add_free(struct xfs_trans *tp, xfs_fsblock_t bno, |
| 187 | 188 | xfs_filblks_t len, const struct xfs_owner_info *oinfo, |
| 188 | 189 | bool skip_discard); |
| @@ -1096,7 +1096,7 @@ xfs_dir2_sf_to_block( · 1095 unmodified lines | ||
| 1096 | 1096 | memcpy(sfp, oldsfp, ifp->if_bytes); |
| 1097 | 1097 | |
| 1098 | 1098 | xfs_idata_realloc(dp, -ifp->if_bytes, XFS_DATA_FORK); |
| 1099 | − xfs_bmap_local_to_extents_empty(dp, XFS_DATA_FORK); | |
| 1099 | + xfs_bmap_local_to_extents_empty(tp, dp, XFS_DATA_FORK); | |
| 1100 | 1100 | dp->i_d.di_size = 0; |
| 1101 | 1101 | |
| 1102 | 1102 | /* |
| @@ -366,11 +366,11 @@ struct xfs_bulkstat { · 365 unmodified lines | ||
| 366 | 366 | uint64_t bs_blocks; /* number of blocks */ |
| 367 | 367 | uint64_t bs_xflags; /* extended flags */ |
| 368 | 368 | |
| 369 | − uint64_t bs_atime; /* access time, seconds */ | |
| 370 | − uint64_t bs_mtime; /* modify time, seconds */ | |
| 369 | + int64_t bs_atime; /* access time, seconds */ | |
| 370 | + int64_t bs_mtime; /* modify time, seconds */ | |
| 371 | 371 | |
| 372 | − uint64_t bs_ctime; /* inode change time, seconds */ | |
| 373 | − uint64_t bs_btime; /* creation time, seconds */ | |
| 372 | + int64_t bs_ctime; /* inode change time, seconds */ | |
| 373 | + int64_t bs_btime; /* creation time, seconds */ | |
| 374 | 374 | |
| 375 | 375 | uint32_t bs_gen; /* generation count */ |
| 376 | 376 | uint32_t bs_uid; /* user id */ |
| @@ -341,7 +341,6 @@ xchk_refcountbt_rec( · 340 unmodified lines | ||
| 341 | 341 | xfs_extlen_t len; |
| 342 | 342 | xfs_nlink_t refcount; |
| 343 | 343 | bool has_cowflag; |
| 344 | − int error = 0; | |
| 345 | 344 | |
| 346 | 345 | bno = be32_to_cpu(rec->refc.rc_startblock); |
| 347 | 346 | len = be32_to_cpu(rec->refc.rc_blockcount); |
| @@ -366,7 +365,7 @@ xchk_refcountbt_rec( · 18 unmodified lines | ||
| 366 | 365 | |
| 367 | 366 | xchk_refcountbt_xref(bs->sc, bno, len, refcount); |
| 368 | 367 | |
| 369 | − return error; | |
| 368 | + return 0; | |
| 370 | 369 | } |
| 371 | 370 | |
| 372 | 371 | /* Make sure we have as many refc blocks as the rmap says. */ |
| @@ -864,6 +864,7 @@ xfs_alloc_file_space( · 863 unmodified lines | ||
| 864 | 864 | xfs_filblks_t allocatesize_fsb; |
| 865 | 865 | xfs_extlen_t extsz, temp; |
| 866 | 866 | xfs_fileoff_t startoffset_fsb; |
| 867 | + xfs_fileoff_t endoffset_fsb; | |
| 867 | 868 | int nimaps; |
| 868 | 869 | int quota_flag; |
| 869 | 870 | int rt; |
| @@ -891,7 +892,8 @@ xfs_alloc_file_space( · 21 unmodified lines | ||
| 891 | 892 | imapp = &imaps[0]; |
| 892 | 893 | nimaps = 1; |
| 893 | 894 | startoffset_fsb = XFS_B_TO_FSBT(mp, offset); |
| 894 | − allocatesize_fsb = XFS_B_TO_FSB(mp, count); | |
| 895 | + endoffset_fsb = XFS_B_TO_FSB(mp, offset + count); | |
| 896 | + allocatesize_fsb = endoffset_fsb - startoffset_fsb; | |
| 895 | 897 | |
| 896 | 898 | /* |
| 897 | 899 | * Allocate file space until done or until there is an error |
| @@ -345,6 +345,15 @@ xfs_buf_allocate_memory( · 344 unmodified lines | ||
| 345 | 345 | unsigned short page_count, i; |
| 346 | 346 | xfs_off_t start, end; |
| 347 | 347 | int error; |
| 348 | + xfs_km_flags_t kmflag_mask = 0; | |
| 349 | + | |
| 350 | + /* | |
| 351 | + * assure zeroed buffer for non-read cases. | |
| 352 | + */ | |
| 353 | + if (!(flags & XBF_READ)) { | |
| 354 | + kmflag_mask |= KM_ZERO; | |
| 355 | + gfp_mask |= __GFP_ZERO; | |
| 356 | + } | |
| 348 | 357 | |
| 349 | 358 | /* |
| 350 | 359 | * for buffers that are contained within a single page, just allocate |
| @@ -354,7 +363,8 @@ xfs_buf_allocate_memory( · 3 unmodified lines | ||
| 354 | 363 | size = BBTOB(bp->b_length); |
| 355 | 364 | if (size < PAGE_SIZE) { |
| 356 | 365 | int align_mask = xfs_buftarg_dma_alignment(bp->b_target); |
| 357 | − bp->b_addr = kmem_alloc_io(size, align_mask, KM_NOFS); | |
| 366 | + bp->b_addr = kmem_alloc_io(size, align_mask, | |
| 367 | + KM_NOFS | kmflag_mask); | |
| 358 | 368 | if (!bp->b_addr) { |
| 359 | 369 | /* low memory - use alloc_page loop instead */ |
| 360 | 370 | goto use_alloc_page; |
| @@ -1443,7 +1443,7 @@ xlog_alloc_log( · 1442 unmodified lines | ||
| 1443 | 1443 | prev_iclog = iclog; |
| 1444 | 1444 | |
| 1445 | 1445 | iclog->ic_data = kmem_alloc_io(log->l_iclog_size, align_mask, |
| 1446 | − KM_MAYFAIL); | |
| 1446 | + KM_MAYFAIL | KM_ZERO); | |
| 1447 | 1447 | if (!iclog->ic_data) |
| 1448 | 1448 | goto out_free_iclog; |
| 1449 | 1449 | #ifdef DEBUG |
| @@ -127,7 +127,7 @@ xlog_alloc_buffer( · 126 unmodified lines | ||
| 127 | 127 | if (nbblks > 1 && log->l_sectBBsize > 1) |
| 128 | 128 | nbblks += log->l_sectBBsize; |
| 129 | 129 | nbblks = round_up(nbblks, log->l_sectBBsize); |
| 130 | − return kmem_alloc_io(BBTOB(nbblks), align_mask, KM_MAYFAIL); | |
| 130 | + return kmem_alloc_io(BBTOB(nbblks), align_mask, KM_MAYFAIL | KM_ZERO); | |
| 131 | 131 | } |
| 132 | 132 | |
| 133 | 133 | /* |
| @@ -326,10 +326,11 @@ static inline int bitmap_equal(const unsigned long *src1, · 325 unmodified lines | ||
| 326 | 326 | } |
| 327 | 327 | |
| 328 | 328 | /** |
| 329 | − * bitmap_or_equal - Check whether the or of two bitnaps is equal to a third | |
| 329 | + * bitmap_or_equal - Check whether the or of two bitmaps is equal to a third | |
| 330 | 330 | * @src1: Pointer to bitmap 1 |
| 331 | 331 | * @src2: Pointer to bitmap 2 will be or'ed with bitmap 1 |
| 332 | 332 | * @src3: Pointer to bitmap 3. Compare to the result of *@src1 | *@src2 |
| 333 | + * @nbits: number of bits in each of these bitmaps | |
| 333 | 334 | * |
| 334 | 335 | * Returns: True if (*@src1 | *@src2) == *@src3, false otherwise |
| 335 | 336 | */ |
| @@ -40,6 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | # define __GCC4_has_attribute___noclone__ 1 |
| 41 | 41 | # define __GCC4_has_attribute___nonstring__ 0 |
| 42 | 42 | # define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8) |
| 43 | +# define __GCC4_has_attribute___fallthrough__ 0 | |
| 43 | 44 | #endif |
| 44 | 45 | |
| 45 | 46 | /* |
| @@ -185,6 +186,22 @@ · 139 unmodified lines | ||
| 185 | 186 | # define __noclone |
| 186 | 187 | #endif |
| 187 | 188 | |
| 189 | +/* | |
| 190 | + * Add the pseudo keyword 'fallthrough' so case statement blocks | |
| 191 | + * must end with any of these keywords: | |
| 192 | + * break; | |
| 193 | + * fallthrough; | |
| 194 | + * goto <label>; | |
| 195 | + * return [expression]; | |
| 196 | + * | |
| 197 | + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes | |
| 198 | + */ | |
| 199 | +#if __has_attribute(__fallthrough__) | |
| 200 | +# define fallthrough __attribute__((__fallthrough__)) | |
| 201 | +#else | |
| 202 | +# define fallthrough do {} while (0) /* fallthrough */ | |
| 203 | +#endif | |
| 204 | + | |
| 188 | 205 | /* |
| 189 | 206 | * Note the missing underscores. |
| 190 | 207 | * |
| @@ -52,10 +52,10 @@ extern struct module __this_module; · 51 unmodified lines | ||
| 52 | 52 | __ADDRESSABLE(sym) \ |
| 53 | 53 | asm(" .section \"___ksymtab" sec "+" #sym "\", \"a\" \n" \ |
| 54 | 54 | " .balign 4 \n" \ |
| 55 | − "__ksymtab_" #sym NS_SEPARATOR #ns ": \n" \ | |
| 55 | + "__ksymtab_" #ns NS_SEPARATOR #sym ": \n" \ | |
| 56 | 56 | " .long " #sym "- . \n" \ |
| 57 | 57 | " .long __kstrtab_" #sym "- . \n" \ |
| 58 | − " .long __kstrtab_ns_" #sym "- . \n" \ | |
| 58 | + " .long __kstrtabns_" #sym "- . \n" \ | |
| 59 | 59 | " .previous \n") |
| 60 | 60 | |
| 61 | 61 | #define __KSYMTAB_ENTRY(sym, sec) \ |
| @@ -76,10 +76,10 @@ struct kernel_symbol { · 14 unmodified lines | ||
| 76 | 76 | #else |
| 77 | 77 | #define __KSYMTAB_ENTRY_NS(sym, sec, ns) \ |
| 78 | 78 | static const struct kernel_symbol __ksymtab_##sym##__##ns \ |
| 79 | − asm("__ksymtab_" #sym NS_SEPARATOR #ns) \ | |
| 79 | + asm("__ksymtab_" #ns NS_SEPARATOR #sym) \ | |
| 80 | 80 | __attribute__((section("___ksymtab" sec "+" #sym), used)) \ |
| 81 | 81 | __aligned(sizeof(void *)) \ |
| 82 | − = { (unsigned long)&sym, __kstrtab_##sym, __kstrtab_ns_##sym } | |
| 82 | + = { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym } | |
| 83 | 83 | |
| 84 | 84 | #define __KSYMTAB_ENTRY(sym, sec) \ |
| 85 | 85 | static const struct kernel_symbol __ksymtab_##sym \ |
| @@ -112,7 +112,7 @@ struct kernel_symbol { · 26 unmodified lines | ||
| 112 | 112 | /* For every exported symbol, place a struct in the __ksymtab section */ |
| 113 | 113 | #define ___EXPORT_SYMBOL_NS(sym, sec, ns) \ |
| 114 | 114 | ___export_symbol_common(sym, sec); \ |
| 115 | − static const char __kstrtab_ns_##sym[] \ | |
| 115 | + static const char __kstrtabns_##sym[] \ | |
| 116 | 116 | __attribute__((section("__ksymtab_strings"), used, aligned(1))) \ |
| 117 | 117 | = #ns; \ |
| 118 | 118 | __KSYMTAB_ENTRY_NS(sym, sec, ns) |
| @@ -201,6 +201,14 @@ struct gpio_irq_chip { · 200 unmodified lines | ||
| 201 | 201 | */ |
| 202 | 202 | bool threaded; |
| 203 | 203 | |
| 204 | + /** | |
| 205 | + * @init_hw: optional routine to initialize hardware before | |
| 206 | + * an IRQ chip will be added. This is quite useful when | |
| 207 | + * a particular driver wants to clear IRQ related registers | |
| 208 | + * in order to avoid undesired events. | |
| 209 | + */ | |
| 210 | + int (*init_hw)(struct gpio_chip *chip); | |
| 211 | + | |
| 204 | 212 | /** |
| 205 | 213 | * @init_valid_mask: optional routine to initialize @valid_mask, to be |
| 206 | 214 | * used if not all GPIO lines are valid interrupts. Sometimes some |
| @@ -235,7 +235,7 @@ enum hwmon_power_attributes { · 234 unmodified lines | ||
| 235 | 235 | #define HWMON_P_LABEL BIT(hwmon_power_label) |
| 236 | 236 | #define HWMON_P_ALARM BIT(hwmon_power_alarm) |
| 237 | 237 | #define HWMON_P_CAP_ALARM BIT(hwmon_power_cap_alarm) |
| 238 | −#define HWMON_P_MIN_ALARM BIT(hwmon_power_max_alarm) | |
| 238 | +#define HWMON_P_MIN_ALARM BIT(hwmon_power_min_alarm) | |
| 239 | 239 | #define HWMON_P_MAX_ALARM BIT(hwmon_power_max_alarm) |
| 240 | 240 | #define HWMON_P_LCRIT_ALARM BIT(hwmon_power_lcrit_alarm) |
| 241 | 241 | #define HWMON_P_CRIT_ALARM BIT(hwmon_power_crit_alarm) |
| @@ -247,7 +247,7 @@ extern void led_set_brightness(struct led_classdev *led_cdev, · 246 unmodified lines | ||
| 247 | 247 | /** |
| 248 | 248 | * led_set_brightness_sync - set LED brightness synchronously |
| 249 | 249 | * @led_cdev: the LED to set |
| 250 | − * @brightness: the brightness to set it to | |
| 250 | + * @value: the brightness to set it to | |
| 251 | 251 | * |
| 252 | 252 | * Set an LED's brightness immediately. This function will block |
| 253 | 253 | * the caller for the time required for accessing device registers, |
| @@ -301,8 +301,7 @@ extern void led_sysfs_enable(struct led_classdev *led_cdev); · 47 unmodified lines | ||
| 301 | 301 | /** |
| 302 | 302 | * led_compose_name - compose LED class device name |
| 303 | 303 | * @dev: LED controller device object |
| 304 | − * @child: child fwnode_handle describing a LED or a group of synchronized LEDs; | |
| 305 | − * it must be provided only for fwnode based LEDs | |
| 304 | + * @init_data: the LED class device initialization data | |
| 306 | 305 | * @led_classdev_name: composed LED class device name |
| 307 | 306 | * |
| 308 | 307 | * Create LED class device name basing on the provided init_data argument. |
| @@ -356,6 +356,19 @@ static inline bool mem_cgroup_disabled(void) · 355 unmodified lines | ||
| 356 | 356 | return !cgroup_subsys_enabled(memory_cgrp_subsys); |
| 357 | 357 | } |
| 358 | 358 | |
| 359 | +static inline unsigned long mem_cgroup_protection(struct mem_cgroup *memcg, | |
| 360 | + bool in_low_reclaim) | |
| 361 | +{ | |
| 362 | + if (mem_cgroup_disabled()) | |
| 363 | + return 0; | |
| 364 | + | |
| 365 | + if (in_low_reclaim) | |
| 366 | + return READ_ONCE(memcg->memory.emin); | |
| 367 | + | |
| 368 | + return max(READ_ONCE(memcg->memory.emin), | |
| 369 | + READ_ONCE(memcg->memory.elow)); | |
| 370 | +} | |
| 371 | + | |
| 359 | 372 | enum mem_cgroup_protection mem_cgroup_protected(struct mem_cgroup *root, |
| 360 | 373 | struct mem_cgroup *memcg); |
| 361 | 374 | |
| @@ -537,6 +550,8 @@ void mem_cgroup_handle_over_high(void); · 175 unmodified lines | ||
| 537 | 550 | |
| 538 | 551 | unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg); |
| 539 | 552 | |
| 553 | +unsigned long mem_cgroup_size(struct mem_cgroup *memcg); | |
| 554 | + | |
| 540 | 555 | void mem_cgroup_print_oom_context(struct mem_cgroup *memcg, |
| 541 | 556 | struct task_struct *p); |
| 542 | 557 | |
| @@ -829,6 +844,12 @@ static inline void memcg_memory_event_mm(struct mm_struct *mm, · 286 unmodified lines | ||
| 829 | 844 | { |
| 830 | 845 | } |
| 831 | 846 | |
| 847 | +static inline unsigned long mem_cgroup_protection(struct mem_cgroup *memcg, | |
| 848 | + bool in_low_reclaim) | |
| 849 | +{ | |
| 850 | + return 0; | |
| 851 | +} | |
| 852 | + | |
| 832 | 853 | static inline enum mem_cgroup_protection mem_cgroup_protected( |
| 833 | 854 | struct mem_cgroup *root, struct mem_cgroup *memcg) |
| 834 | 855 | { |
| @@ -968,6 +989,11 @@ static inline unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg) · 133 unmodified lines | ||
| 968 | 989 | return 0; |
| 969 | 990 | } |
| 970 | 991 | |
| 992 | +static inline unsigned long mem_cgroup_size(struct mem_cgroup *memcg) | |
| 993 | +{ | |
| 994 | + return 0; | |
| 995 | +} | |
| 996 | + | |
| 971 | 997 | static inline void |
| 972 | 998 | mem_cgroup_print_oom_context(struct mem_cgroup *memcg, struct task_struct *p) |
| 973 | 999 | { |
| @@ -1264,6 +1290,9 @@ void mem_cgroup_track_foreign_dirty_slowpath(struct page *page, · 290 unmodified lines | ||
| 1264 | 1290 | static inline void mem_cgroup_track_foreign_dirty(struct page *page, |
| 1265 | 1291 | struct bdi_writeback *wb) |
| 1266 | 1292 | { |
| 1293 | + if (mem_cgroup_disabled()) | |
| 1294 | + return; | |
| 1295 | + | |
| 1267 | 1296 | if (unlikely(&page->mem_cgroup->css != wb->memcg_css)) |
| 1268 | 1297 | mem_cgroup_track_foreign_dirty_slowpath(page, wb); |
| 1269 | 1298 | } |
| @@ -31,7 +31,7 @@ · 30 unmodified lines | ||
| 31 | 31 | #define PHY_ID_KSZ886X 0x00221430 |
| 32 | 32 | #define PHY_ID_KSZ8863 0x00221435 |
| 33 | 33 | |
| 34 | −#define PHY_ID_KSZ8795 0x00221550 | |
| 34 | +#define PHY_ID_KSZ87XX 0x00221550 | |
| 35 | 35 | |
| 36 | 36 | #define PHY_ID_KSZ9477 0x00221631 |
| 37 | 37 | |
| @@ -18,7 +18,7 @@ struct page_ext_operations { · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | enum page_ext_flags { |
| 20 | 20 | PAGE_EXT_OWNER, |
| 21 | − PAGE_EXT_OWNER_ACTIVE, | |
| 21 | + PAGE_EXT_OWNER_ALLOCATED, | |
| 22 | 22 | #if defined(CONFIG_IDLE_PAGE_TRACKING) && !defined(CONFIG_64BIT) |
| 23 | 23 | PAGE_EXT_YOUNG, |
| 24 | 24 | PAGE_EXT_IDLE, |
| @@ -36,6 +36,7 @@ struct page_ext { · 11 unmodified lines | ||
| 36 | 36 | unsigned long flags; |
| 37 | 37 | }; |
| 38 | 38 | |
| 39 | +extern unsigned long page_ext_size; | |
| 39 | 40 | extern void pgdat_page_ext_init(struct pglist_data *pgdat); |
| 40 | 41 | |
| 41 | 42 | #ifdef CONFIG_SPARSEMEM |
| @@ -52,6 +53,13 @@ static inline void page_ext_init(void) · 10 unmodified lines | ||
| 52 | 53 | |
| 53 | 54 | struct page_ext *lookup_page_ext(const struct page *page); |
| 54 | 55 | |
| 56 | +static inline struct page_ext *page_ext_next(struct page_ext *curr) | |
| 57 | +{ | |
| 58 | + void *next = curr; | |
| 59 | + next += page_ext_size; | |
| 60 | + return next; | |
| 61 | +} | |
| 62 | + | |
| 55 | 63 | #else /* !CONFIG_PAGE_EXTENSION */ |
| 56 | 64 | struct page_ext; |
| 57 | 65 | |
| @@ -64,6 +64,8 @@ extern struct resource *platform_get_resource_byname(struct platform_device *, · 63 unmodified lines | ||
| 64 | 64 | unsigned int, |
| 65 | 65 | const char *); |
| 66 | 66 | extern int platform_get_irq_byname(struct platform_device *, const char *); |
| 67 | +extern int platform_get_irq_byname_optional(struct platform_device *dev, | |
| 68 | + const char *name); | |
| 67 | 69 | extern int platform_add_devices(struct platform_device **, int); |
| 68 | 70 | |
| 69 | 71 | struct platform_device_info { |
| @@ -223,6 +223,7 @@ extern long schedule_timeout_uninterruptible(long timeout); · 222 unmodified lines | ||
| 223 | 223 | extern long schedule_timeout_idle(long timeout); |
| 224 | 224 | asmlinkage void schedule(void); |
| 225 | 225 | extern void schedule_preempt_disabled(void); |
| 226 | +asmlinkage void preempt_schedule_irq(void); | |
| 226 | 227 | |
| 227 | 228 | extern int __must_check io_schedule_prepare(void); |
| 228 | 229 | extern void io_schedule_finish(int token); |
| @@ -3510,8 +3510,9 @@ int skb_ensure_writable(struct sk_buff *skb, int write_len); · 3509 unmodified lines | ||
| 3510 | 3510 | int __skb_vlan_pop(struct sk_buff *skb, u16 *vlan_tci); |
| 3511 | 3511 | int skb_vlan_pop(struct sk_buff *skb); |
| 3512 | 3512 | int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci); |
| 3513 | −int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto); | |
| 3514 | −int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto); | |
| 3513 | +int skb_mpls_push(struct sk_buff *skb, __be32 mpls_lse, __be16 mpls_proto, | |
| 3514 | + int mac_len); | |
| 3515 | +int skb_mpls_pop(struct sk_buff *skb, __be16 next_proto, int mac_len); | |
| 3515 | 3516 | int skb_mpls_update_lse(struct sk_buff *skb, __be32 mpls_lse); |
| 3516 | 3517 | int skb_mpls_dec_ttl(struct sk_buff *skb); |
| 3517 | 3518 | struct sk_buff *pskb_extract(struct sk_buff *skb, int off, int to_copy, |
| @@ -493,6 +493,10 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags) · 492 unmodified lines | ||
| 493 | 493 | * kmalloc is the normal method of allocating memory |
| 494 | 494 | * for objects smaller than page size in the kernel. |
| 495 | 495 | * |
| 496 | + * The allocated object address is aligned to at least ARCH_KMALLOC_MINALIGN | |
| 497 | + * bytes. For @size of power of two bytes, the alignment is also guaranteed | |
| 498 | + * to be at least to the size. | |
| 499 | + * | |
| 496 | 500 | * The @flags argument may be one of the GFP flags defined at |
| 497 | 501 | * include/linux/gfp.h and described at |
| 498 | 502 | * :ref:`Documentation/core-api/mm-api.rst <mm-api-gfp-flags>` |
| @@ -227,7 +227,26 @@ static inline bool strstarts(const char *str, const char *prefix) · 226 unmodified lines | ||
| 227 | 227 | } |
| 228 | 228 | |
| 229 | 229 | size_t memweight(const void *ptr, size_t bytes); |
| 230 | −void memzero_explicit(void *s, size_t count); | |
| 230 | + | |
| 231 | +/** | |
| 232 | + * memzero_explicit - Fill a region of memory (e.g. sensitive | |
| 233 | + * keying data) with 0s. | |
| 234 | + * @s: Pointer to the start of the area. | |
| 235 | + * @count: The size of the area. | |
| 236 | + * | |
| 237 | + * Note: usually using memset() is just fine (!), but in cases | |
| 238 | + * where clearing out _local_ data at the end of a scope is | |
| 239 | + * necessary, memzero_explicit() should be used instead in | |
| 240 | + * order to prevent the compiler from optimising away zeroing. | |
| 241 | + * | |
| 242 | + * memzero_explicit() doesn't need an arch-specific version as | |
| 243 | + * it just invokes the one of memset() implicitly. | |
| 244 | + */ | |
| 245 | +static inline void memzero_explicit(void *s, size_t count) | |
| 246 | +{ | |
| 247 | + memset(s, 0, count); | |
| 248 | + barrier_data(s); | |
| 249 | +} | |
| 231 | 250 | |
| 232 | 251 | /** |
| 233 | 252 | * kbasename - return the last part of a pathname. |
| @@ -61,6 +61,7 @@ struct sock_xprt { · 60 unmodified lines | ||
| 61 | 61 | struct mutex recv_mutex; |
| 62 | 62 | struct sockaddr_storage srcaddr; |
| 63 | 63 | unsigned short srcport; |
| 64 | + int xprt_err; | |
| 64 | 65 | |
| 65 | 66 | /* |
| 66 | 67 | * UDP socket buffer size parameters |
| @@ -393,7 +393,7 @@ struct tcp_sock { · 392 unmodified lines | ||
| 393 | 393 | /* fastopen_rsk points to request_sock that resulted in this big |
| 394 | 394 | * socket. Used to retransmit SYNACKs etc. |
| 395 | 395 | */ |
| 396 | − struct request_sock *fastopen_rsk; | |
| 396 | + struct request_sock __rcu *fastopen_rsk; | |
| 397 | 397 | u32 *saved_syn; |
| 398 | 398 | }; |
| 399 | 399 | |
| @@ -447,8 +447,8 @@ static inline struct tcp_timewait_sock *tcp_twsk(const struct sock *sk) · 47 unmodified lines | ||
| 447 | 447 | |
| 448 | 448 | static inline bool tcp_passive_fastopen(const struct sock *sk) |
| 449 | 449 | { |
| 450 | − return (sk->sk_state == TCP_SYN_RECV && | |
| 451 | − tcp_sk(sk)->fastopen_rsk != NULL); | |
| 450 | + return sk->sk_state == TCP_SYN_RECV && | |
| 451 | + rcu_access_pointer(tcp_sk(sk)->fastopen_rsk) != NULL; | |
| 452 | 452 | } |
| 453 | 453 | |
| 454 | 454 | static inline void fastopen_queue_tune(struct sock *sk, int backlog) |
| @@ -152,7 +152,7 @@ struct tcg_algorithm_info { · 151 unmodified lines | ||
| 152 | 152 | * total. Once we've done this we know the offset of the data length field, |
| 153 | 153 | * and can calculate the total size of the event. |
| 154 | 154 | * |
| 155 | − * Return: size of the event on success, <0 on failure | |
| 155 | + * Return: size of the event on success, 0 on failure | |
| 156 | 156 | */ |
| 157 | 157 | |
| 158 | 158 | static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, |
| @@ -170,6 +170,7 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, · 11 unmodified lines | ||
| 170 | 170 | u16 halg; |
| 171 | 171 | int i; |
| 172 | 172 | int j; |
| 173 | + u32 count, event_type; | |
| 173 | 174 | |
| 174 | 175 | marker = event; |
| 175 | 176 | marker_start = marker; |
| @@ -190,16 +191,22 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, · 14 unmodified lines | ||
| 190 | 191 | } |
| 191 | 192 | |
| 192 | 193 | event = (struct tcg_pcr_event2_head *)mapping; |
| 194 | + /* | |
| 195 | + * The loop below will unmap these fields if the log is larger than | |
| 196 | + * one page, so save them here for reference: | |
| 197 | + */ | |
| 198 | + count = READ_ONCE(event->count); | |
| 199 | + event_type = READ_ONCE(event->event_type); | |
| 193 | 200 | |
| 194 | 201 | efispecid = (struct tcg_efi_specid_event_head *)event_header->event; |
| 195 | 202 | |
| 196 | 203 | /* Check if event is malformed. */ |
| 197 | − if (event->count > efispecid->num_algs) { | |
| 204 | + if (count > efispecid->num_algs) { | |
| 198 | 205 | size = 0; |
| 199 | 206 | goto out; |
| 200 | 207 | } |
| 201 | 208 | |
| 202 | − for (i = 0; i < event->count; i++) { | |
| 209 | + for (i = 0; i < count; i++) { | |
| 203 | 210 | halg_size = sizeof(event->digests[i].alg_id); |
| 204 | 211 | |
| 205 | 212 | /* Map the digest's algorithm identifier */ |
| @@ -256,8 +263,9 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event, · 50 unmodified lines | ||
| 256 | 263 | + event_field->event_size; |
| 257 | 264 | size = marker - marker_start; |
| 258 | 265 | |
| 259 | − if ((event->event_type == 0) && (event_field->event_size == 0)) | |
| 266 | + if (event_type == 0 && event_field->event_size == 0) | |
| 260 | 267 | size = 0; |
| 268 | + | |
| 261 | 269 | out: |
| 262 | 270 | if (do_mapping) |
| 263 | 271 | TPM_MEMUNMAP(mapping, mapping_size); |
| @@ -355,8 +355,10 @@ extern long strnlen_unsafe_user(const void __user *unsafe_addr, long count); · 354 unmodified lines | ||
| 355 | 355 | #ifndef user_access_begin |
| 356 | 356 | #define user_access_begin(ptr,len) access_ok(ptr, len) |
| 357 | 357 | #define user_access_end() do { } while (0) |
| 358 | −#define unsafe_get_user(x, ptr, err) do { if (unlikely(__get_user(x, ptr))) goto err; } while (0) | |
| 359 | −#define unsafe_put_user(x, ptr, err) do { if (unlikely(__put_user(x, ptr))) goto err; } while (0) | |
| 358 | +#define unsafe_op_wrap(op, err) do { if (unlikely(op)) goto err; } while (0) | |
| 359 | +#define unsafe_get_user(x,p,e) unsafe_op_wrap(__get_user(x,p),e) | |
| 360 | +#define unsafe_put_user(x,p,e) unsafe_op_wrap(__put_user(x,p),e) | |
| 361 | +#define unsafe_copy_to_user(d,s,l,e) unsafe_op_wrap(__copy_to_user(d,s,l),e) | |
| 360 | 362 | static inline unsigned long user_access_save(void) { return 0UL; } |
| 361 | 363 | static inline void user_access_restore(unsigned long flags) { } |
| 362 | 364 | #endif |
| @@ -230,8 +230,8 @@ static inline int xa_err(void *entry) · 229 unmodified lines | ||
| 230 | 230 | * This structure is used either directly or via the XA_LIMIT() macro |
| 231 | 231 | * to communicate the range of IDs that are valid for allocation. |
| 232 | 232 | * Two common ranges are predefined for you: |
| 233 | − * * xa_limit_32b - [0 - UINT_MAX] | |
| 234 | − * * xa_limit_31b - [0 - INT_MAX] | |
| 233 | + * * xa_limit_32b - [0 - UINT_MAX] | |
| 234 | + * * xa_limit_31b - [0 - INT_MAX] | |
| 235 | 235 | */ |
| 236 | 236 | struct xa_limit { |
| 237 | 237 | u32 max; |
| @@ -5549,6 +5549,14 @@ const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, · 5548 unmodified lines | ||
| 5549 | 5549 | */ |
| 5550 | 5550 | const char *reg_initiator_name(enum nl80211_reg_initiator initiator); |
| 5551 | 5551 | |
| 5552 | +/** | |
| 5553 | + * regulatory_pre_cac_allowed - check if pre-CAC allowed in the current regdom | |
| 5554 | + * @wiphy: wiphy for which pre-CAC capability is checked. | |
| 5555 | + * | |
| 5556 | + * Pre-CAC is allowed only in some regdomains (notable ETSI). | |
| 5557 | + */ | |
| 5558 | +bool regulatory_pre_cac_allowed(struct wiphy *wiphy); | |
| 5559 | + | |
| 5552 | 5560 | /** |
| 5553 | 5561 | * DOC: Internal regulatory db functions |
| 5554 | 5562 | * |
| @@ -104,7 +104,7 @@ void llc_sk_reset(struct sock *sk); · 103 unmodified lines | ||
| 104 | 104 | |
| 105 | 105 | /* Access to a connection */ |
| 106 | 106 | int llc_conn_state_process(struct sock *sk, struct sk_buff *skb); |
| 107 | −int llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb); | |
| 107 | +void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb); | |
| 108 | 108 | void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb); |
| 109 | 109 | void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit); |
| 110 | 110 | void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit); |
| @@ -52,6 +52,9 @@ struct bpf_prog; · 51 unmodified lines | ||
| 52 | 52 | #define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS) |
| 53 | 53 | |
| 54 | 54 | struct net { |
| 55 | + /* First cache line can be often dirtied. | |
| 56 | + * Do not place here read-mostly fields. | |
| 57 | + */ | |
| 55 | 58 | refcount_t passive; /* To decide when the network |
| 56 | 59 | * namespace should be freed. |
| 57 | 60 | */ |
| @@ -60,7 +63,13 @@ struct net { · 2 unmodified lines | ||
| 60 | 63 | */ |
| 61 | 64 | spinlock_t rules_mod_lock; |
| 62 | 65 | |
| 63 | − u32 hash_mix; | |
| 66 | + unsigned int dev_unreg_count; | |
| 67 | + | |
| 68 | + unsigned int dev_base_seq; /* protected by rtnl_mutex */ | |
| 69 | + int ifindex; | |
| 70 | + | |
| 71 | + spinlock_t nsid_lock; | |
| 72 | + atomic_t fnhe_genid; | |
| 64 | 73 | |
| 65 | 74 | struct list_head list; /* list of network namespaces */ |
| 66 | 75 | struct list_head exit_list; /* To linked to call pernet exit |
| @@ -76,11 +85,11 @@ struct net { · 9 unmodified lines | ||
| 76 | 85 | #endif |
| 77 | 86 | struct user_namespace *user_ns; /* Owning user namespace */ |
| 78 | 87 | struct ucounts *ucounts; |
| 79 | − spinlock_t nsid_lock; | |
| 80 | 88 | struct idr netns_ids; |
| 81 | 89 | |
| 82 | 90 | struct ns_common ns; |
| 83 | 91 | |
| 92 | + struct list_head dev_base_head; | |
| 84 | 93 | struct proc_dir_entry *proc_net; |
| 85 | 94 | struct proc_dir_entry *proc_net_stat; |
| 86 | 95 | |
| @@ -93,17 +102,18 @@ struct net { · 6 unmodified lines | ||
| 93 | 102 | |
| 94 | 103 | struct uevent_sock *uevent_sock; /* uevent socket */ |
| 95 | 104 | |
| 96 | − struct list_head dev_base_head; | |
| 97 | 105 | struct hlist_head *dev_name_head; |
| 98 | 106 | struct hlist_head *dev_index_head; |
| 99 | − unsigned int dev_base_seq; /* protected by rtnl_mutex */ | |
| 100 | − int ifindex; | |
| 101 | − unsigned int dev_unreg_count; | |
| 107 | + /* Note that @hash_mix can be read millions times per second, | |
| 108 | + * it is critical that it is on a read_mostly cache line. | |
| 109 | + */ | |
| 110 | + u32 hash_mix; | |
| 111 | + | |
| 112 | + struct net_device *loopback_dev; /* The loopback */ | |
| 102 | 113 | |
| 103 | 114 | /* core fib_rules */ |
| 104 | 115 | struct list_head rules_ops; |
| 105 | 116 | |
| 106 | − struct net_device *loopback_dev; /* The loopback */ | |
| 107 | 117 | struct netns_core core; |
| 108 | 118 | struct netns_mib mib; |
| 109 | 119 | struct netns_packet packet; |
| @@ -171,7 +181,6 @@ struct net { · 61 unmodified lines | ||
| 171 | 181 | struct sock *crypto_nlsk; |
| 172 | 182 | #endif |
| 173 | 183 | struct sock *diag_nlsk; |
| 174 | − atomic_t fnhe_genid; | |
| 175 | 184 | } __randomize_layout; |
| 176 | 185 | |
| 177 | 186 | #include <linux/seq_file_net.h> |
| @@ -185,7 +185,7 @@ void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req, · 184 unmodified lines | ||
| 185 | 185 | |
| 186 | 186 | static inline bool reqsk_queue_empty(const struct request_sock_queue *queue) |
| 187 | 187 | { |
| 188 | − return queue->rskq_accept_head == NULL; | |
| 188 | + return READ_ONCE(queue->rskq_accept_head) == NULL; | |
| 189 | 189 | } |
| 190 | 190 | |
| 191 | 191 | static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue *queue, |
| @@ -197,7 +197,7 @@ static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue · 5 unmodified lines | ||
| 197 | 197 | req = queue->rskq_accept_head; |
| 198 | 198 | if (req) { |
| 199 | 199 | sk_acceptq_removed(parent); |
| 200 | − queue->rskq_accept_head = req->dl_next; | |
| 200 | + WRITE_ONCE(queue->rskq_accept_head, req->dl_next); | |
| 201 | 201 | if (queue->rskq_accept_head == NULL) |
| 202 | 202 | queue->rskq_accept_tail = NULL; |
| 203 | 203 | } |
| @@ -610,4 +610,9 @@ static inline __u32 sctp_min_frag_point(struct sctp_sock *sp, __u16 datasize) · 609 unmodified lines | ||
| 610 | 610 | return sctp_mtu_payload(sp, SCTP_DEFAULT_MINSEGMENT, datasize); |
| 611 | 611 | } |
| 612 | 612 | |
| 613 | +static inline bool sctp_newsk_ready(const struct sock *sk) | |
| 614 | +{ | |
| 615 | + return sock_flag(sk, SOCK_DEAD) || sk->sk_socket; | |
| 616 | +} | |
| 617 | + | |
| 613 | 618 | #endif /* __net_sctp_h__ */ |
| @@ -878,12 +878,17 @@ static inline bool sk_acceptq_is_full(const struct sock *sk) · 877 unmodified lines | ||
| 878 | 878 | */ |
| 879 | 879 | static inline int sk_stream_min_wspace(const struct sock *sk) |
| 880 | 880 | { |
| 881 | − return sk->sk_wmem_queued >> 1; | |
| 881 | + return READ_ONCE(sk->sk_wmem_queued) >> 1; | |
| 882 | 882 | } |
| 883 | 883 | |
| 884 | 884 | static inline int sk_stream_wspace(const struct sock *sk) |
| 885 | 885 | { |
| 886 | − return sk->sk_sndbuf - sk->sk_wmem_queued; | |
| 886 | + return READ_ONCE(sk->sk_sndbuf) - READ_ONCE(sk->sk_wmem_queued); | |
| 887 | +} | |
| 888 | + | |
| 889 | +static inline void sk_wmem_queued_add(struct sock *sk, int val) | |
| 890 | +{ | |
| 891 | + WRITE_ONCE(sk->sk_wmem_queued, sk->sk_wmem_queued + val); | |
| 887 | 892 | } |
| 888 | 893 | |
| 889 | 894 | void sk_stream_write_space(struct sock *sk); |
| @@ -1207,7 +1212,7 @@ static inline void sk_refcnt_debug_release(const struct sock *sk) · 317 unmodified lines | ||
| 1207 | 1212 | |
| 1208 | 1213 | static inline bool __sk_stream_memory_free(const struct sock *sk, int wake) |
| 1209 | 1214 | { |
| 1210 | − if (sk->sk_wmem_queued >= sk->sk_sndbuf) | |
| 1215 | + if (READ_ONCE(sk->sk_wmem_queued) >= READ_ONCE(sk->sk_sndbuf)) | |
| 1211 | 1216 | return false; |
| 1212 | 1217 | |
| 1213 | 1218 | return sk->sk_prot->stream_memory_free ? |
| @@ -1467,7 +1472,7 @@ DECLARE_STATIC_KEY_FALSE(tcp_tx_skb_cache_key); · 253 unmodified lines | ||
| 1467 | 1472 | static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb) |
| 1468 | 1473 | { |
| 1469 | 1474 | sock_set_flag(sk, SOCK_QUEUE_SHRUNK); |
| 1470 | − sk->sk_wmem_queued -= skb->truesize; | |
| 1475 | + sk_wmem_queued_add(sk, -skb->truesize); | |
| 1471 | 1476 | sk_mem_uncharge(sk, skb->truesize); |
| 1472 | 1477 | if (static_branch_unlikely(&tcp_tx_skb_cache_key) && |
| 1473 | 1478 | !sk->sk_tx_skb_cache && !skb_cloned(skb)) { |
| @@ -2014,7 +2019,7 @@ static inline int skb_copy_to_page_nocache(struct sock *sk, struct iov_iter *fro · 540 unmodified lines | ||
| 2014 | 2019 | skb->len += copy; |
| 2015 | 2020 | skb->data_len += copy; |
| 2016 | 2021 | skb->truesize += copy; |
| 2017 | − sk->sk_wmem_queued += copy; | |
| 2022 | + sk_wmem_queued_add(sk, copy); | |
| 2018 | 2023 | sk_mem_charge(sk, copy); |
| 2019 | 2024 | return 0; |
| 2020 | 2025 | } |
| @@ -2220,10 +2225,14 @@ static inline void sk_wake_async(const struct sock *sk, int how, int band) · 199 unmodified lines | ||
| 2220 | 2225 | |
| 2221 | 2226 | static inline void sk_stream_moderate_sndbuf(struct sock *sk) |
| 2222 | 2227 | { |
| 2223 | − if (!(sk->sk_userlocks & SOCK_SNDBUF_LOCK)) { | |
| 2224 | − sk->sk_sndbuf = min(sk->sk_sndbuf, sk->sk_wmem_queued >> 1); | |
| 2225 | − sk->sk_sndbuf = max_t(u32, sk->sk_sndbuf, SOCK_MIN_SNDBUF); | |
| 2226 | − } | |
| 2228 | + u32 val; | |
| 2229 | + | |
| 2230 | + if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) | |
| 2231 | + return; | |
| 2232 | + | |
| 2233 | + val = min(sk->sk_sndbuf, sk->sk_wmem_queued >> 1); | |
| 2234 | + | |
| 2235 | + WRITE_ONCE(sk->sk_sndbuf, max_t(u32, val, SOCK_MIN_SNDBUF)); | |
| 2227 | 2236 | } |
| 2228 | 2237 | |
| 2229 | 2238 | struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp, |
| @@ -2251,7 +2260,7 @@ bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag); · 21 unmodified lines | ||
| 2251 | 2260 | */ |
| 2252 | 2261 | static inline bool sock_writeable(const struct sock *sk) |
| 2253 | 2262 | { |
| 2254 | − return refcount_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf >> 1); | |
| 2263 | + return refcount_read(&sk->sk_wmem_alloc) < (READ_ONCE(sk->sk_sndbuf) >> 1); | |
| 2255 | 2264 | } |
| 2256 | 2265 | |
| 2257 | 2266 | static inline gfp_t gfp_any(void) |
| @@ -2271,7 +2280,9 @@ static inline long sock_sndtimeo(const struct sock *sk, bool noblock) · 13 unmodified lines | ||
| 2271 | 2280 | |
| 2272 | 2281 | static inline int sock_rcvlowat(const struct sock *sk, int waitall, int len) |
| 2273 | 2282 | { |
| 2274 | − return (waitall ? len : min_t(int, sk->sk_rcvlowat, len)) ? : 1; | |
| 2283 | + int v = waitall ? len : min_t(int, READ_ONCE(sk->sk_rcvlowat), len); | |
| 2284 | + | |
| 2285 | + return v ?: 1; | |
| 2275 | 2286 | } |
| 2276 | 2287 | |
| 2277 | 2288 | /* Alas, with timeout socket operations are not restartable. |
| @@ -258,7 +258,7 @@ static inline bool tcp_under_memory_pressure(const struct sock *sk) · 257 unmodified lines | ||
| 258 | 258 | mem_cgroup_under_socket_pressure(sk->sk_memcg)) |
| 259 | 259 | return true; |
| 260 | 260 | |
| 261 | − return tcp_memory_pressure; | |
| 261 | + return READ_ONCE(tcp_memory_pressure); | |
| 262 | 262 | } |
| 263 | 263 | /* |
| 264 | 264 | * The next routines deal with comparing 32 bit unsigned ints |
| @@ -1380,13 +1380,14 @@ static inline int tcp_win_from_space(const struct sock *sk, int space) · 1115 unmodified lines | ||
| 1380 | 1380 | /* Note: caller must be prepared to deal with negative returns */ |
| 1381 | 1381 | static inline int tcp_space(const struct sock *sk) |
| 1382 | 1382 | { |
| 1383 | − return tcp_win_from_space(sk, sk->sk_rcvbuf - sk->sk_backlog.len - | |
| 1383 | + return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf) - | |
| 1384 | + READ_ONCE(sk->sk_backlog.len) - | |
| 1384 | 1385 | atomic_read(&sk->sk_rmem_alloc)); |
| 1385 | 1386 | } |
| 1386 | 1387 | |
| 1387 | 1388 | static inline int tcp_full_space(const struct sock *sk) |
| 1388 | 1389 | { |
| 1389 | − return tcp_win_from_space(sk, sk->sk_rcvbuf); | |
| 1390 | + return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf)); | |
| 1390 | 1391 | } |
| 1391 | 1392 | |
| 1392 | 1393 | extern void tcp_openreq_init_rwin(struct request_sock *req, |
| @@ -1916,7 +1917,8 @@ static inline u32 tcp_notsent_lowat(const struct tcp_sock *tp) · 523 unmodified lines | ||
| 1916 | 1917 | static inline bool tcp_stream_memory_free(const struct sock *sk, int wake) |
| 1917 | 1918 | { |
| 1918 | 1919 | const struct tcp_sock *tp = tcp_sk(sk); |
| 1919 | − u32 notsent_bytes = tp->write_seq - tp->snd_nxt; | |
| 1920 | + u32 notsent_bytes = READ_ONCE(tp->write_seq) - | |
| 1921 | + READ_ONCE(tp->snd_nxt); | |
| 1920 | 1922 | |
| 1921 | 1923 | return (notsent_bytes << wake) < tcp_notsent_lowat(tp); |
| 1922 | 1924 | } |
| @@ -32,6 +32,7 @@ extern int scsi_ioctl_reset(struct scsi_device *, int __user *); · 31 unmodified lines | ||
| 32 | 32 | struct scsi_eh_save { |
| 33 | 33 | /* saved state */ |
| 34 | 34 | int result; |
| 35 | + unsigned int resid_len; | |
| 35 | 36 | int eh_eflags; |
| 36 | 37 | enum dma_data_direction data_direction; |
| 37 | 38 | unsigned underflow; |
| @@ -264,6 +264,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; · 263 unmodified lines | ||
| 264 | 264 | #define AZX_REG_ML_LOUTPAY 0x20 |
| 265 | 265 | #define AZX_REG_ML_LINPAY 0x30 |
| 266 | 266 | |
| 267 | +/* bit0 is reserved, with BIT(1) mapping to stream1 */ | |
| 268 | +#define ML_LOSIDV_STREAM_MASK 0xFFFE | |
| 269 | + | |
| 267 | 270 | #define ML_LCTL_SCF_MASK 0xF |
| 268 | 271 | #define AZX_MLCTL_SPA (0x1 << 16) |
| 269 | 272 | #define AZX_MLCTL_CPA (0x1 << 23) |
| @@ -519,10 +519,10 @@ TRACE_EVENT(rxrpc_local, · 518 unmodified lines | ||
| 519 | 519 | ); |
| 520 | 520 | |
| 521 | 521 | TRACE_EVENT(rxrpc_peer, |
| 522 | − TP_PROTO(struct rxrpc_peer *peer, enum rxrpc_peer_trace op, | |
| 522 | + TP_PROTO(unsigned int peer_debug_id, enum rxrpc_peer_trace op, | |
| 523 | 523 | int usage, const void *where), |
| 524 | 524 | |
| 525 | − TP_ARGS(peer, op, usage, where), | |
| 525 | + TP_ARGS(peer_debug_id, op, usage, where), | |
| 526 | 526 | |
| 527 | 527 | TP_STRUCT__entry( |
| 528 | 528 | __field(unsigned int, peer ) |
| @@ -532,7 +532,7 @@ TRACE_EVENT(rxrpc_peer, · 3 unmodified lines | ||
| 532 | 532 | ), |
| 533 | 533 | |
| 534 | 534 | TP_fast_assign( |
| 535 | − __entry->peer = peer->debug_id; | |
| 535 | + __entry->peer = peer_debug_id; | |
| 536 | 536 | __entry->op = op; |
| 537 | 537 | __entry->usage = usage; |
| 538 | 538 | __entry->where = where; |
| @@ -546,10 +546,10 @@ TRACE_EVENT(rxrpc_peer, · 7 unmodified lines | ||
| 546 | 546 | ); |
| 547 | 547 | |
| 548 | 548 | TRACE_EVENT(rxrpc_conn, |
| 549 | − TP_PROTO(struct rxrpc_connection *conn, enum rxrpc_conn_trace op, | |
| 549 | + TP_PROTO(unsigned int conn_debug_id, enum rxrpc_conn_trace op, | |
| 550 | 550 | int usage, const void *where), |
| 551 | 551 | |
| 552 | − TP_ARGS(conn, op, usage, where), | |
| 552 | + TP_ARGS(conn_debug_id, op, usage, where), | |
| 553 | 553 | |
| 554 | 554 | TP_STRUCT__entry( |
| 555 | 555 | __field(unsigned int, conn ) |
| @@ -559,7 +559,7 @@ TRACE_EVENT(rxrpc_conn, · 3 unmodified lines | ||
| 559 | 559 | ), |
| 560 | 560 | |
| 561 | 561 | TP_fast_assign( |
| 562 | − __entry->conn = conn->debug_id; | |
| 562 | + __entry->conn = conn_debug_id; | |
| 563 | 563 | __entry->op = op; |
| 564 | 564 | __entry->usage = usage; |
| 565 | 565 | __entry->where = where; |
| @@ -606,10 +606,10 @@ TRACE_EVENT(rxrpc_client, · 40 unmodified lines | ||
| 606 | 606 | ); |
| 607 | 607 | |
| 608 | 608 | TRACE_EVENT(rxrpc_call, |
| 609 | − TP_PROTO(struct rxrpc_call *call, enum rxrpc_call_trace op, | |
| 609 | + TP_PROTO(unsigned int call_debug_id, enum rxrpc_call_trace op, | |
| 610 | 610 | int usage, const void *where, const void *aux), |
| 611 | 611 | |
| 612 | − TP_ARGS(call, op, usage, where, aux), | |
| 612 | + TP_ARGS(call_debug_id, op, usage, where, aux), | |
| 613 | 613 | |
| 614 | 614 | TP_STRUCT__entry( |
| 615 | 615 | __field(unsigned int, call ) |
| @@ -620,7 +620,7 @@ TRACE_EVENT(rxrpc_call, · 4 unmodified lines | ||
| 620 | 620 | ), |
| 621 | 621 | |
| 622 | 622 | TP_fast_assign( |
| 623 | − __entry->call = call->debug_id; | |
| 623 | + __entry->call = call_debug_id; | |
| 624 | 624 | __entry->op = op; |
| 625 | 625 | __entry->usage = usage; |
| 626 | 626 | __entry->where = where; |
| @@ -82,7 +82,7 @@ TRACE_EVENT(sock_rcvqueue_full, · 81 unmodified lines | ||
| 82 | 82 | TP_fast_assign( |
| 83 | 83 | __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); |
| 84 | 84 | __entry->truesize = skb->truesize; |
| 85 | − __entry->sk_rcvbuf = sk->sk_rcvbuf; | |
| 85 | + __entry->sk_rcvbuf = READ_ONCE(sk->sk_rcvbuf); | |
| 86 | 86 | ), |
| 87 | 87 | |
| 88 | 88 | TP_printk("rmem_alloc=%d truesize=%u sk_rcvbuf=%d", |
| @@ -115,7 +115,7 @@ TRACE_EVENT(sock_exceed_buf_limit, · 26 unmodified lines | ||
| 115 | 115 | __entry->rmem_alloc = atomic_read(&sk->sk_rmem_alloc); |
| 116 | 116 | __entry->sysctl_wmem = sk_get_wmem0(sk, prot); |
| 117 | 117 | __entry->wmem_alloc = refcount_read(&sk->sk_wmem_alloc); |
| 118 | − __entry->wmem_queued = sk->sk_wmem_queued; | |
| 118 | + __entry->wmem_queued = READ_ONCE(sk->sk_wmem_queued); | |
| 119 | 119 | __entry->kind = kind; |
| 120 | 120 | ), |
| 121 | 121 | |
| @@ -291,6 +291,6 @@ · 290 unmodified lines | ||
| 291 | 291 | #define PORT_SUNIX 121 |
| 292 | 292 | |
| 293 | 293 | /* Freescale Linflex UART */ |
| 294 | −#define PORT_LINFLEXUART 121 | |
| 294 | +#define PORT_LINFLEXUART 122 | |
| 295 | 295 | |
| 296 | 296 | #endif /* _UAPILINUX_SERIAL_CORE_H */ |
| @@ -3779,11 +3779,23 @@ static void rotate_ctx(struct perf_event_context *ctx, struct perf_event *event) · 3778 unmodified lines | ||
| 3779 | 3779 | perf_event_groups_insert(&ctx->flexible_groups, event); |
| 3780 | 3780 | } |
| 3781 | 3781 | |
| 3782 | +/* pick an event from the flexible_groups to rotate */ | |
| 3782 | 3783 | static inline struct perf_event * |
| 3783 | −ctx_first_active(struct perf_event_context *ctx) | |
| 3784 | +ctx_event_to_rotate(struct perf_event_context *ctx) | |
| 3784 | 3785 | { |
| 3785 | − return list_first_entry_or_null(&ctx->flexible_active, | |
| 3786 | − struct perf_event, active_list); | |
| 3786 | + struct perf_event *event; | |
| 3787 | + | |
| 3788 | + /* pick the first active flexible event */ | |
| 3789 | + event = list_first_entry_or_null(&ctx->flexible_active, | |
| 3790 | + struct perf_event, active_list); | |
| 3791 | + | |
| 3792 | + /* if no active flexible event, pick the first event */ | |
| 3793 | + if (!event) { | |
| 3794 | + event = rb_entry_safe(rb_first(&ctx->flexible_groups.tree), | |
| 3795 | + typeof(*event), group_node); | |
| 3796 | + } | |
| 3797 | + | |
| 3798 | + return event; | |
| 3787 | 3799 | } |
| 3788 | 3800 | |
| 3789 | 3801 | static bool perf_rotate_context(struct perf_cpu_context *cpuctx) |
| @@ -3808,9 +3820,9 @@ static bool perf_rotate_context(struct perf_cpu_context *cpuctx) · 18 unmodified lines | ||
| 3808 | 3820 | perf_pmu_disable(cpuctx->ctx.pmu); |
| 3809 | 3821 | |
| 3810 | 3822 | if (task_rotate) |
| 3811 | − task_event = ctx_first_active(task_ctx); | |
| 3823 | + task_event = ctx_event_to_rotate(task_ctx); | |
| 3812 | 3824 | if (cpu_rotate) |
| 3813 | − cpu_event = ctx_first_active(&cpuctx->ctx); | |
| 3825 | + cpu_event = ctx_event_to_rotate(&cpuctx->ctx); | |
| 3814 | 3826 | |
| 3815 | 3827 | /* |
| 3816 | 3828 | * As per the order given at ctx_resched() first 'pop' task flexible |
| @@ -5668,7 +5680,8 @@ again: · 1851 unmodified lines | ||
| 5668 | 5680 | * undo the VM accounting. |
| 5669 | 5681 | */ |
| 5670 | 5682 | |
| 5671 | − atomic_long_sub((size >> PAGE_SHIFT) + 1, &mmap_user->locked_vm); | |
| 5683 | + atomic_long_sub((size >> PAGE_SHIFT) + 1 - mmap_locked, | |
| 5684 | + &mmap_user->locked_vm); | |
| 5672 | 5685 | atomic64_sub(mmap_locked, &vma->vm_mm->pinned_vm); |
| 5673 | 5686 | free_uid(mmap_user); |
| 5674 | 5687 | |
| @@ -5812,8 +5825,20 @@ accounting: · 137 unmodified lines | ||
| 5812 | 5825 | |
| 5813 | 5826 | user_locked = atomic_long_read(&user->locked_vm) + user_extra; |
| 5814 | 5827 | |
| 5815 | − if (user_locked > user_lock_limit) | |
| 5828 | + if (user_locked <= user_lock_limit) { | |
| 5829 | + /* charge all to locked_vm */ | |
| 5830 | + } else if (atomic_long_read(&user->locked_vm) >= user_lock_limit) { | |
| 5831 | + /* charge all to pinned_vm */ | |
| 5832 | + extra = user_extra; | |
| 5833 | + user_extra = 0; | |
| 5834 | + } else { | |
| 5835 | + /* | |
| 5836 | + * charge locked_vm until it hits user_lock_limit; | |
| 5837 | + * charge the rest from pinned_vm | |
| 5838 | + */ | |
| 5816 | 5839 | extra = user_locked - user_lock_limit; |
| 5840 | + user_extra -= extra; | |
| 5841 | + } | |
| 5817 | 5842 | |
| 5818 | 5843 | lock_limit = rlimit(RLIMIT_MEMLOCK); |
| 5819 | 5844 | lock_limit >>= PAGE_SHIFT; |
| @@ -11862,6 +11887,10 @@ static int inherit_group(struct perf_event *parent_event, · 6042 unmodified lines | ||
| 11862 | 11887 | child, leader, child_ctx); |
| 11863 | 11888 | if (IS_ERR(child_ctr)) |
| 11864 | 11889 | return PTR_ERR(child_ctr); |
| 11890 | + | |
| 11891 | + if (sub->aux_event == parent_event && | |
| 11892 | + !perf_get_aux_event(child_ctr, leader)) | |
| 11893 | + return -EINVAL; | |
| 11865 | 11894 | } |
| 11866 | 11895 | return 0; |
| 11867 | 11896 | } |
| @@ -474,14 +474,17 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, · 473 unmodified lines | ||
| 474 | 474 | struct vm_area_struct *vma; |
| 475 | 475 | int ret, is_register, ref_ctr_updated = 0; |
| 476 | 476 | bool orig_page_huge = false; |
| 477 | + unsigned int gup_flags = FOLL_FORCE; | |
| 477 | 478 | |
| 478 | 479 | is_register = is_swbp_insn(&opcode); |
| 479 | 480 | uprobe = container_of(auprobe, struct uprobe, arch); |
| 480 | 481 | |
| 481 | 482 | retry: |
| 483 | + if (is_register) | |
| 484 | + gup_flags |= FOLL_SPLIT_PMD; | |
| 482 | 485 | /* Read the page with vaddr into memory */ |
| 483 | − ret = get_user_pages_remote(NULL, mm, vaddr, 1, | |
| 484 | − FOLL_FORCE | FOLL_SPLIT_PMD, &old_page, &vma, NULL); | |
| 486 | + ret = get_user_pages_remote(NULL, mm, vaddr, 1, gup_flags, | |
| 487 | + &old_page, &vma, NULL); | |
| 485 | 488 | if (ret <= 0) |
| 486 | 489 | return ret; |
| 487 | 490 | |
| @@ -489,6 +492,12 @@ retry: · 1 unmodified line | ||
| 489 | 492 | if (ret <= 0) |
| 490 | 493 | goto put_old; |
| 491 | 494 | |
| 495 | + if (WARN(!is_register && PageCompound(old_page), | |
| 496 | + "uprobe unregister should never work on compound page\n")) { | |
| 497 | + ret = -EINVAL; | |
| 498 | + goto put_old; | |
| 499 | + } | |
| 500 | + | |
| 492 | 501 | /* We are going to replace instruction, update ref_ctr. */ |
| 493 | 502 | if (!ref_ctr_updated && uprobe->ref_ctr_offset) { |
| 494 | 503 | ret = update_ref_ctr(uprobe, mm, is_register ? 1 : -1); |
| @@ -2925,7 +2925,7 @@ int sysctl_max_threads(struct ctl_table *table, int write, · 2924 unmodified lines | ||
| 2925 | 2925 | struct ctl_table t; |
| 2926 | 2926 | int ret; |
| 2927 | 2927 | int threads = max_threads; |
| 2928 | − int min = MIN_THREADS; | |
| 2928 | + int min = 1; | |
| 2929 | 2929 | int max = MAX_THREADS; |
| 2930 | 2930 | |
| 2931 | 2931 | t = *table; |
| @@ -2937,7 +2937,7 @@ int sysctl_max_threads(struct ctl_table *table, int write, · 5 unmodified lines | ||
| 2937 | 2937 | if (ret || !write) |
| 2938 | 2938 | return ret; |
| 2939 | 2939 | |
| 2940 | − set_max_threads(threads); | |
| 2940 | + max_threads = threads; | |
| 2941 | 2941 | |
| 2942 | 2942 | return 0; |
| 2943 | 2943 | } |
| @@ -22,12 +22,6 @@ EXPORT_SYMBOL(system_freezing_cnt); · 21 unmodified lines | ||
| 22 | 22 | bool pm_freezing; |
| 23 | 23 | bool pm_nosig_freezing; |
| 24 | 24 | |
| 25 | −/* | |
| 26 | − * Temporary export for the deadlock workaround in ata_scsi_hotplug(). | |
| 27 | − * Remove once the hack becomes unnecessary. | |
| 28 | − */ | |
| 29 | −EXPORT_SYMBOL_GPL(pm_freezing); | |
| 30 | − | |
| 31 | 25 | /* protects freezing and frozen transitions */ |
| 32 | 26 | static DEFINE_SPINLOCK(freezer_lock); |
| 33 | 27 | |
| @@ -71,10 +71,13 @@ done | cpio --quiet -pd $cpio_dir >/dev/null 2>&1 · 70 unmodified lines | ||
| 71 | 71 | find $cpio_dir -type f -print0 | |
| 72 | 72 | xargs -0 -P8 -n1 perl -pi -e 'BEGIN {undef $/;}; s/\/\*((?!SPDX).)*?\*\///smg;' |
| 73 | 73 | |
| 74 | −# Create archive and try to normalize metadata for reproducibility | |
| 75 | −tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ | |
| 76 | − --owner=0 --group=0 --sort=name --numeric-owner \ | |
| 77 | − -Jcf $tarfile -C $cpio_dir/ . > /dev/null | |
| 74 | +# Create archive and try to normalize metadata for reproducibility. | |
| 75 | +# For compatibility with older versions of tar, files are fed to tar | |
| 76 | +# pre-sorted, as --sort=name might not be available. | |
| 77 | +find $cpio_dir -printf "./%P\n" | LC_ALL=C sort | \ | |
| 78 | + tar "${KBUILD_BUILD_TIMESTAMP:+--mtime=$KBUILD_BUILD_TIMESTAMP}" \ | |
| 79 | + --owner=0 --group=0 --numeric-owner --no-recursion \ | |
| 80 | + -Jcf $tarfile -C $cpio_dir/ -T - > /dev/null | |
| 78 | 81 | |
| 79 | 82 | echo "$src_files_md5" > kernel/kheaders.md5 |
| 80 | 83 | echo "$obj_files_md5" >> kernel/kheaders.md5 |
| @@ -866,9 +866,9 @@ void kthread_delayed_work_timer_fn(struct timer_list *t) · 865 unmodified lines | ||
| 866 | 866 | } |
| 867 | 867 | EXPORT_SYMBOL(kthread_delayed_work_timer_fn); |
| 868 | 868 | |
| 869 | −void __kthread_queue_delayed_work(struct kthread_worker *worker, | |
| 870 | − struct kthread_delayed_work *dwork, | |
| 871 | − unsigned long delay) | |
| 869 | +static void __kthread_queue_delayed_work(struct kthread_worker *worker, | |
| 870 | + struct kthread_delayed_work *dwork, | |
| 871 | + unsigned long delay) | |
| 872 | 872 | { |
| 873 | 873 | struct timer_list *timer = &dwork->timer; |
| 874 | 874 | struct kthread_work *work = &dwork->work; |
| @@ -180,6 +180,7 @@ void panic(const char *fmt, ...) · 179 unmodified lines | ||
| 180 | 180 | * after setting panic_cpu) from invoking panic() again. |
| 181 | 181 | */ |
| 182 | 182 | local_irq_disable(); |
| 183 | + preempt_disable_notrace(); | |
| 183 | 184 | |
| 184 | 185 | /* |
| 185 | 186 | * It's possible to come here directly from a panic-assertion and |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/seq_file.h> |
| 16 | 16 | #include <linux/suspend.h> |
| 17 | 17 | #include <linux/syscalls.h> |
| 18 | +#include <linux/pm_runtime.h> | |
| 18 | 19 | |
| 19 | 20 | #include "power.h" |
| 20 | 21 | |
| @@ -740,7 +740,7 @@ void vtime_account_system(struct task_struct *tsk) · 739 unmodified lines | ||
| 740 | 740 | |
| 741 | 741 | write_seqcount_begin(&vtime->seqcount); |
| 742 | 742 | /* We might have scheduled out from guest path */ |
| 743 | − if (current->flags & PF_VCPU) | |
| 743 | + if (tsk->flags & PF_VCPU) | |
| 744 | 744 | vtime_account_guest(tsk, vtime); |
| 745 | 745 | else |
| 746 | 746 | __vtime_account_system(tsk, vtime); |
| @@ -783,7 +783,7 @@ void vtime_guest_enter(struct task_struct *tsk) · 36 unmodified lines | ||
| 783 | 783 | */ |
| 784 | 784 | write_seqcount_begin(&vtime->seqcount); |
| 785 | 785 | __vtime_account_system(tsk, vtime); |
| 786 | − current->flags |= PF_VCPU; | |
| 786 | + tsk->flags |= PF_VCPU; | |
| 787 | 787 | write_seqcount_end(&vtime->seqcount); |
| 788 | 788 | } |
| 789 | 789 | EXPORT_SYMBOL_GPL(vtime_guest_enter); |
| @@ -794,7 +794,7 @@ void vtime_guest_exit(struct task_struct *tsk) · 4 unmodified lines | ||
| 794 | 794 | |
| 795 | 795 | write_seqcount_begin(&vtime->seqcount); |
| 796 | 796 | vtime_account_guest(tsk, vtime); |
| 797 | − current->flags &= ~PF_VCPU; | |
| 797 | + tsk->flags &= ~PF_VCPU; | |
| 798 | 798 | write_seqcount_end(&vtime->seqcount); |
| 799 | 799 | } |
| 800 | 800 | EXPORT_SYMBOL_GPL(vtime_guest_exit); |
| @@ -4926,20 +4926,28 @@ static enum hrtimer_restart sched_cfs_period_timer(struct hrtimer *timer) · 4925 unmodified lines | ||
| 4926 | 4926 | if (++count > 3) { |
| 4927 | 4927 | u64 new, old = ktime_to_ns(cfs_b->period); |
| 4928 | 4928 | |
| 4929 | − new = (old * 147) / 128; /* ~115% */ | |
| 4930 | − new = min(new, max_cfs_quota_period); | |
| 4931 | − | |
| 4932 | − cfs_b->period = ns_to_ktime(new); | |
| 4933 | − | |
| 4934 | − /* since max is 1s, this is limited to 1e9^2, which fits in u64 */ | |
| 4935 | − cfs_b->quota *= new; | |
| 4936 | − cfs_b->quota = div64_u64(cfs_b->quota, old); | |
| 4937 | − | |
| 4938 | − pr_warn_ratelimited( | |
| 4939 | − "cfs_period_timer[cpu%d]: period too short, scaling up (new cfs_period_us %lld, cfs_quota_us = %lld)\n", | |
| 4940 | − smp_processor_id(), | |
| 4941 | − div_u64(new, NSEC_PER_USEC), | |
| 4942 | − div_u64(cfs_b->quota, NSEC_PER_USEC)); | |
| 4929 | + /* | |
| 4930 | + * Grow period by a factor of 2 to avoid losing precision. | |
| 4931 | + * Precision loss in the quota/period ratio can cause __cfs_schedulable | |
| 4932 | + * to fail. | |
| 4933 | + */ | |
| 4934 | + new = old * 2; | |
| 4935 | + if (new < max_cfs_quota_period) { | |
| 4936 | + cfs_b->period = ns_to_ktime(new); | |
| 4937 | + cfs_b->quota *= 2; | |
| 4938 | + | |
| 4939 | + pr_warn_ratelimited( | |
| 4940 | + "cfs_period_timer[cpu%d]: period too short, scaling up (new cfs_period_us = %lld, cfs_quota_us = %lld)\n", | |
| 4941 | + smp_processor_id(), | |
| 4942 | + div_u64(new, NSEC_PER_USEC), | |
| 4943 | + div_u64(cfs_b->quota, NSEC_PER_USEC)); | |
| 4944 | + } else { | |
| 4945 | + pr_warn_ratelimited( | |
| 4946 | + "cfs_period_timer[cpu%d]: period too short, but cannot scale up without losing precision (cfs_period_us = %lld, cfs_quota_us = %lld)\n", | |
| 4947 | + smp_processor_id(), | |
| 4948 | + div_u64(old, NSEC_PER_USEC), | |
| 4949 | + div_u64(cfs_b->quota, NSEC_PER_USEC)); | |
| 4950 | + } | |
| 4943 | 4951 | |
| 4944 | 4952 | /* reset count so we don't come right back in here */ |
| 4945 | 4953 | count = 0; |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * Copyright (C) 2010 SUSE Linux Products GmbH |
| 8 | 8 | * Copyright (C) 2010 Tejun Heo <tj@kernel.org> |
| 9 | 9 | */ |
| 10 | +#include <linux/compiler.h> | |
| 10 | 11 | #include <linux/completion.h> |
| 11 | 12 | #include <linux/cpu.h> |
| 12 | 13 | #include <linux/init.h> |
| @@ -167,7 +168,7 @@ static void set_state(struct multi_stop_data *msdata, · 154 unmodified lines | ||
| 167 | 168 | /* Reset ack counter. */ |
| 168 | 169 | atomic_set(&msdata->thread_ack, msdata->num_threads); |
| 169 | 170 | smp_wmb(); |
| 170 | − msdata->state = newstate; | |
| 171 | + WRITE_ONCE(msdata->state, newstate); | |
| 171 | 172 | } |
| 172 | 173 | |
| 173 | 174 | /* Last one to ack a state moves to the next state. */ |
| @@ -186,7 +187,7 @@ void __weak stop_machine_yield(const struct cpumask *cpumask) · 12 unmodified lines | ||
| 186 | 187 | static int multi_cpu_stop(void *data) |
| 187 | 188 | { |
| 188 | 189 | struct multi_stop_data *msdata = data; |
| 189 | − enum multi_stop_state curstate = MULTI_STOP_NONE; | |
| 190 | + enum multi_stop_state newstate, curstate = MULTI_STOP_NONE; | |
| 190 | 191 | int cpu = smp_processor_id(), err = 0; |
| 191 | 192 | const struct cpumask *cpumask; |
| 192 | 193 | unsigned long flags; |
| @@ -210,8 +211,9 @@ static int multi_cpu_stop(void *data) · 17 unmodified lines | ||
| 210 | 211 | do { |
| 211 | 212 | /* Chill out and ensure we re-read multi_stop_state. */ |
| 212 | 213 | stop_machine_yield(cpumask); |
| 213 | − if (msdata->state != curstate) { | |
| 214 | − curstate = msdata->state; | |
| 214 | + newstate = READ_ONCE(msdata->state); | |
| 215 | + if (newstate != curstate) { | |
| 216 | + curstate = newstate; | |
| 215 | 217 | switch (curstate) { |
| 216 | 218 | case MULTI_STOP_DISABLE_IRQ: |
| 217 | 219 | local_irq_disable(); |
| @@ -163,7 +163,7 @@ static unsigned long hung_task_timeout_max = (LONG_MAX/HZ); · 162 unmodified lines | ||
| 163 | 163 | #ifdef CONFIG_SPARC |
| 164 | 164 | #endif |
| 165 | 165 | |
| 166 | −#ifdef __hppa__ | |
| 166 | +#ifdef CONFIG_PARISC | |
| 167 | 167 | extern int pwrsw_enabled; |
| 168 | 168 | #endif |
| 169 | 169 | |
| @@ -620,7 +620,7 @@ static struct ctl_table kern_table[] = { · 450 unmodified lines | ||
| 620 | 620 | .proc_handler = proc_dointvec, |
| 621 | 621 | }, |
| 622 | 622 | #endif |
| 623 | −#ifdef __hppa__ | |
| 623 | +#ifdef CONFIG_PARISC | |
| 624 | 624 | { |
| 625 | 625 | .procname = "soft-power", |
| 626 | 626 | .data = &pwrsw_enabled, |
| @@ -164,7 +164,7 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer, · 163 unmodified lines | ||
| 164 | 164 | struct hrtimer_clock_base *base; |
| 165 | 165 | |
| 166 | 166 | for (;;) { |
| 167 | − base = timer->base; | |
| 167 | + base = READ_ONCE(timer->base); | |
| 168 | 168 | if (likely(base != &migration_base)) { |
| 169 | 169 | raw_spin_lock_irqsave(&base->cpu_base->lock, *flags); |
| 170 | 170 | if (likely(base == timer->base)) |
| @@ -244,7 +244,7 @@ again: · 73 unmodified lines | ||
| 244 | 244 | return base; |
| 245 | 245 | |
| 246 | 246 | /* See the comment in lock_hrtimer_base() */ |
| 247 | − timer->base = &migration_base; | |
| 247 | + WRITE_ONCE(timer->base, &migration_base); | |
| 248 | 248 | raw_spin_unlock(&base->cpu_base->lock); |
| 249 | 249 | raw_spin_lock(&new_base->cpu_base->lock); |
| 250 | 250 | |
| @@ -253,10 +253,10 @@ again: · 2 unmodified lines | ||
| 253 | 253 | raw_spin_unlock(&new_base->cpu_base->lock); |
| 254 | 254 | raw_spin_lock(&base->cpu_base->lock); |
| 255 | 255 | new_cpu_base = this_cpu_base; |
| 256 | − timer->base = base; | |
| 256 | + WRITE_ONCE(timer->base, base); | |
| 257 | 257 | goto again; |
| 258 | 258 | } |
| 259 | − timer->base = new_base; | |
| 259 | + WRITE_ONCE(timer->base, new_base); | |
| 260 | 260 | } else { |
| 261 | 261 | if (new_cpu_base != this_cpu_base && |
| 262 | 262 | hrtimer_check_target(timer, new_base)) { |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #include <linux/clocksource.h> |
| 19 | 19 | #include <linux/sched/task.h> |
| 20 | 20 | #include <linux/kallsyms.h> |
| 21 | +#include <linux/security.h> | |
| 21 | 22 | #include <linux/seq_file.h> |
| 22 | 23 | #include <linux/tracefs.h> |
| 23 | 24 | #include <linux/hardirq.h> |
| @@ -3486,6 +3487,11 @@ static int · 3462 unmodified lines | ||
| 3486 | 3487 | ftrace_avail_open(struct inode *inode, struct file *file) |
| 3487 | 3488 | { |
| 3488 | 3489 | struct ftrace_iterator *iter; |
| 3490 | + int ret; | |
| 3491 | + | |
| 3492 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 3493 | + if (ret) | |
| 3494 | + return ret; | |
| 3489 | 3495 | |
| 3490 | 3496 | if (unlikely(ftrace_disabled)) |
| 3491 | 3497 | return -ENODEV; |
| @@ -3505,6 +3511,15 @@ ftrace_enabled_open(struct inode *inode, struct file *file) · 13 unmodified lines | ||
| 3505 | 3511 | { |
| 3506 | 3512 | struct ftrace_iterator *iter; |
| 3507 | 3513 | |
| 3514 | + /* | |
| 3515 | + * This shows us what functions are currently being | |
| 3516 | + * traced and by what. Not sure if we want lockdown | |
| 3517 | + * to hide such critical information for an admin. | |
| 3518 | + * Although, perhaps it can show information we don't | |
| 3519 | + * want people to see, but if something is tracing | |
| 3520 | + * something, we probably want to know about it. | |
| 3521 | + */ | |
| 3522 | + | |
| 3508 | 3523 | iter = __seq_open_private(file, &show_ftrace_seq_ops, sizeof(*iter)); |
| 3509 | 3524 | if (!iter) |
| 3510 | 3525 | return -ENOMEM; |
| @@ -3540,21 +3555,22 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, · 29 unmodified lines | ||
| 3540 | 3555 | struct ftrace_hash *hash; |
| 3541 | 3556 | struct list_head *mod_head; |
| 3542 | 3557 | struct trace_array *tr = ops->private; |
| 3543 | − int ret = 0; | |
| 3558 | + int ret = -ENOMEM; | |
| 3544 | 3559 | |
| 3545 | 3560 | ftrace_ops_init(ops); |
| 3546 | 3561 | |
| 3547 | 3562 | if (unlikely(ftrace_disabled)) |
| 3548 | 3563 | return -ENODEV; |
| 3549 | 3564 | |
| 3565 | + if (tracing_check_open_get_tr(tr)) | |
| 3566 | + return -ENODEV; | |
| 3567 | + | |
| 3550 | 3568 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
| 3551 | 3569 | if (!iter) |
| 3552 | − return -ENOMEM; | |
| 3570 | + goto out; | |
| 3553 | 3571 | |
| 3554 | − if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) { | |
| 3555 | − kfree(iter); | |
| 3556 | − return -ENOMEM; | |
| 3557 | − } | |
| 3572 | + if (trace_parser_get_init(&iter->parser, FTRACE_BUFF_MAX)) | |
| 3573 | + goto out; | |
| 3558 | 3574 | |
| 3559 | 3575 | iter->ops = ops; |
| 3560 | 3576 | iter->flags = flag; |
| @@ -3584,13 +3600,13 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, · 23 unmodified lines | ||
| 3584 | 3600 | |
| 3585 | 3601 | if (!iter->hash) { |
| 3586 | 3602 | trace_parser_put(&iter->parser); |
| 3587 | − kfree(iter); | |
| 3588 | − ret = -ENOMEM; | |
| 3589 | 3603 | goto out_unlock; |
| 3590 | 3604 | } |
| 3591 | 3605 | } else |
| 3592 | 3606 | iter->hash = hash; |
| 3593 | 3607 | |
| 3608 | + ret = 0; | |
| 3609 | + | |
| 3594 | 3610 | if (file->f_mode & FMODE_READ) { |
| 3595 | 3611 | iter->pg = ftrace_pages_start; |
| 3596 | 3612 | |
| @@ -3602,7 +3618,6 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, · 5 unmodified lines | ||
| 3602 | 3618 | /* Failed */ |
| 3603 | 3619 | free_ftrace_hash(iter->hash); |
| 3604 | 3620 | trace_parser_put(&iter->parser); |
| 3605 | − kfree(iter); | |
| 3606 | 3621 | } |
| 3607 | 3622 | } else |
| 3608 | 3623 | file->private_data = iter; |
| @@ -3610,6 +3625,13 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, · 1 unmodified line | ||
| 3610 | 3625 | out_unlock: |
| 3611 | 3626 | mutex_unlock(&ops->func_hash->regex_lock); |
| 3612 | 3627 | |
| 3628 | + out: | |
| 3629 | + if (ret) { | |
| 3630 | + kfree(iter); | |
| 3631 | + if (tr) | |
| 3632 | + trace_array_put(tr); | |
| 3633 | + } | |
| 3634 | + | |
| 3613 | 3635 | return ret; |
| 3614 | 3636 | } |
| 3615 | 3637 | |
| @@ -3618,6 +3640,7 @@ ftrace_filter_open(struct inode *inode, struct file *file) · 2 unmodified lines | ||
| 3618 | 3640 | { |
| 3619 | 3641 | struct ftrace_ops *ops = inode->i_private; |
| 3620 | 3642 | |
| 3643 | + /* Checks for tracefs lockdown */ | |
| 3621 | 3644 | return ftrace_regex_open(ops, |
| 3622 | 3645 | FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES, |
| 3623 | 3646 | inode, file); |
| @@ -3628,6 +3651,7 @@ ftrace_notrace_open(struct inode *inode, struct file *file) · 4 unmodified lines | ||
| 3628 | 3651 | { |
| 3629 | 3652 | struct ftrace_ops *ops = inode->i_private; |
| 3630 | 3653 | |
| 3654 | + /* Checks for tracefs lockdown */ | |
| 3631 | 3655 | return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE, |
| 3632 | 3656 | inode, file); |
| 3633 | 3657 | } |
| @@ -5037,6 +5061,8 @@ int ftrace_regex_release(struct inode *inode, struct file *file) · 1403 unmodified lines | ||
| 5037 | 5061 | |
| 5038 | 5062 | mutex_unlock(&iter->ops->func_hash->regex_lock); |
| 5039 | 5063 | free_ftrace_hash(iter->hash); |
| 5064 | + if (iter->tr) | |
| 5065 | + trace_array_put(iter->tr); | |
| 5040 | 5066 | kfree(iter); |
| 5041 | 5067 | |
| 5042 | 5068 | return 0; |
| @@ -5194,9 +5220,13 @@ static int · 151 unmodified lines | ||
| 5194 | 5220 | __ftrace_graph_open(struct inode *inode, struct file *file, |
| 5195 | 5221 | struct ftrace_graph_data *fgd) |
| 5196 | 5222 | { |
| 5197 | − int ret = 0; | |
| 5223 | + int ret; | |
| 5198 | 5224 | struct ftrace_hash *new_hash = NULL; |
| 5199 | 5225 | |
| 5226 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 5227 | + if (ret) | |
| 5228 | + return ret; | |
| 5229 | + | |
| 5200 | 5230 | if (file->f_mode & FMODE_WRITE) { |
| 5201 | 5231 | const int size_bits = FTRACE_HASH_DEFAULT_BITS; |
| 5202 | 5232 | |
| @@ -6537,8 +6567,9 @@ ftrace_pid_open(struct inode *inode, struct file *file) · 1334 unmodified lines | ||
| 6537 | 6567 | struct seq_file *m; |
| 6538 | 6568 | int ret = 0; |
| 6539 | 6569 | |
| 6540 | − if (trace_array_get(tr) < 0) | |
| 6541 | − return -ENODEV; | |
| 6570 | + ret = tracing_check_open_get_tr(tr); | |
| 6571 | + if (ret) | |
| 6572 | + return ret; | |
| 6542 | 6573 | |
| 6543 | 6574 | if ((file->f_mode & FMODE_WRITE) && |
| 6544 | 6575 | (file->f_flags & O_TRUNC)) |
| @@ -17,6 +17,7 @@ · 16 unmodified lines | ||
| 17 | 17 | #include <linux/stacktrace.h> |
| 18 | 18 | #include <linux/writeback.h> |
| 19 | 19 | #include <linux/kallsyms.h> |
| 20 | +#include <linux/security.h> | |
| 20 | 21 | #include <linux/seq_file.h> |
| 21 | 22 | #include <linux/notifier.h> |
| 22 | 23 | #include <linux/irqflags.h> |
| @@ -304,6 +305,23 @@ void trace_array_put(struct trace_array *this_tr) · 281 unmodified lines | ||
| 304 | 305 | mutex_unlock(&trace_types_lock); |
| 305 | 306 | } |
| 306 | 307 | |
| 308 | +int tracing_check_open_get_tr(struct trace_array *tr) | |
| 309 | +{ | |
| 310 | + int ret; | |
| 311 | + | |
| 312 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 313 | + if (ret) | |
| 314 | + return ret; | |
| 315 | + | |
| 316 | + if (tracing_disabled) | |
| 317 | + return -ENODEV; | |
| 318 | + | |
| 319 | + if (tr && trace_array_get(tr) < 0) | |
| 320 | + return -ENODEV; | |
| 321 | + | |
| 322 | + return 0; | |
| 323 | +} | |
| 324 | + | |
| 307 | 325 | int call_filter_check_discard(struct trace_event_call *call, void *rec, |
| 308 | 326 | struct ring_buffer *buffer, |
| 309 | 327 | struct ring_buffer_event *event) |
| @@ -4140,8 +4158,11 @@ release: · 3830 unmodified lines | ||
| 4140 | 4158 | |
| 4141 | 4159 | int tracing_open_generic(struct inode *inode, struct file *filp) |
| 4142 | 4160 | { |
| 4143 | − if (tracing_disabled) | |
| 4144 | − return -ENODEV; | |
| 4161 | + int ret; | |
| 4162 | + | |
| 4163 | + ret = tracing_check_open_get_tr(NULL); | |
| 4164 | + if (ret) | |
| 4165 | + return ret; | |
| 4145 | 4166 | |
| 4146 | 4167 | filp->private_data = inode->i_private; |
| 4147 | 4168 | return 0; |
| @@ -4156,15 +4177,14 @@ bool tracing_is_disabled(void) · 8 unmodified lines | ||
| 4156 | 4177 | * Open and update trace_array ref count. |
| 4157 | 4178 | * Must have the current trace_array passed to it. |
| 4158 | 4179 | */ |
| 4159 | −static int tracing_open_generic_tr(struct inode *inode, struct file *filp) | |
| 4180 | +int tracing_open_generic_tr(struct inode *inode, struct file *filp) | |
| 4160 | 4181 | { |
| 4161 | 4182 | struct trace_array *tr = inode->i_private; |
| 4183 | + int ret; | |
| 4162 | 4184 | |
| 4163 | − if (tracing_disabled) | |
| 4164 | − return -ENODEV; | |
| 4165 | − | |
| 4166 | − if (trace_array_get(tr) < 0) | |
| 4167 | − return -ENODEV; | |
| 4185 | + ret = tracing_check_open_get_tr(tr); | |
| 4186 | + if (ret) | |
| 4187 | + return ret; | |
| 4168 | 4188 | |
| 4169 | 4189 | filp->private_data = inode->i_private; |
| 4170 | 4190 | |
| @@ -4233,10 +4253,11 @@ static int tracing_open(struct inode *inode, struct file *file) · 62 unmodified lines | ||
| 4233 | 4253 | { |
| 4234 | 4254 | struct trace_array *tr = inode->i_private; |
| 4235 | 4255 | struct trace_iterator *iter; |
| 4236 | − int ret = 0; | |
| 4256 | + int ret; | |
| 4237 | 4257 | |
| 4238 | − if (trace_array_get(tr) < 0) | |
| 4239 | − return -ENODEV; | |
| 4258 | + ret = tracing_check_open_get_tr(tr); | |
| 4259 | + if (ret) | |
| 4260 | + return ret; | |
| 4240 | 4261 | |
| 4241 | 4262 | /* If this file was open for write, then erase contents */ |
| 4242 | 4263 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { |
| @@ -4352,12 +4373,15 @@ static int show_traces_open(struct inode *inode, struct file *file) · 109 unmodified lines | ||
| 4352 | 4373 | struct seq_file *m; |
| 4353 | 4374 | int ret; |
| 4354 | 4375 | |
| 4355 | − if (tracing_disabled) | |
| 4356 | − return -ENODEV; | |
| 4376 | + ret = tracing_check_open_get_tr(tr); | |
| 4377 | + if (ret) | |
| 4378 | + return ret; | |
| 4357 | 4379 | |
| 4358 | 4380 | ret = seq_open(file, &show_traces_seq_ops); |
| 4359 | − if (ret) | |
| 4381 | + if (ret) { | |
| 4382 | + trace_array_put(tr); | |
| 4360 | 4383 | return ret; |
| 4384 | + } | |
| 4361 | 4385 | |
| 4362 | 4386 | m = file->private_data; |
| 4363 | 4387 | m->private = tr; |
| @@ -4365,6 +4389,14 @@ static int show_traces_open(struct inode *inode, struct file *file) · 1 unmodified line | ||
| 4365 | 4389 | return 0; |
| 4366 | 4390 | } |
| 4367 | 4391 | |
| 4392 | +static int show_traces_release(struct inode *inode, struct file *file) | |
| 4393 | +{ | |
| 4394 | + struct trace_array *tr = inode->i_private; | |
| 4395 | + | |
| 4396 | + trace_array_put(tr); | |
| 4397 | + return seq_release(inode, file); | |
| 4398 | +} | |
| 4399 | + | |
| 4368 | 4400 | static ssize_t |
| 4369 | 4401 | tracing_write_stub(struct file *filp, const char __user *ubuf, |
| 4370 | 4402 | size_t count, loff_t *ppos) |
| @@ -4395,8 +4427,8 @@ static const struct file_operations tracing_fops = { · 24 unmodified lines | ||
| 4395 | 4427 | static const struct file_operations show_traces_fops = { |
| 4396 | 4428 | .open = show_traces_open, |
| 4397 | 4429 | .read = seq_read, |
| 4398 | − .release = seq_release, | |
| 4399 | 4430 | .llseek = seq_lseek, |
| 4431 | + .release = show_traces_release, | |
| 4400 | 4432 | }; |
| 4401 | 4433 | |
| 4402 | 4434 | static ssize_t |
| @@ -4697,11 +4729,9 @@ static int tracing_trace_options_open(struct inode *inode, struct file *file) · 294 unmodified lines | ||
| 4697 | 4729 | struct trace_array *tr = inode->i_private; |
| 4698 | 4730 | int ret; |
| 4699 | 4731 | |
| 4700 | − if (tracing_disabled) | |
| 4701 | − return -ENODEV; | |
| 4702 | − | |
| 4703 | − if (trace_array_get(tr) < 0) | |
| 4704 | − return -ENODEV; | |
| 4732 | + ret = tracing_check_open_get_tr(tr); | |
| 4733 | + if (ret) | |
| 4734 | + return ret; | |
| 4705 | 4735 | |
| 4706 | 4736 | ret = single_open(file, tracing_trace_options_show, inode->i_private); |
| 4707 | 4737 | if (ret < 0) |
| @@ -5038,8 +5068,11 @@ static const struct seq_operations tracing_saved_tgids_seq_ops = { · 330 unmodified lines | ||
| 5038 | 5068 | |
| 5039 | 5069 | static int tracing_saved_tgids_open(struct inode *inode, struct file *filp) |
| 5040 | 5070 | { |
| 5041 | − if (tracing_disabled) | |
| 5042 | − return -ENODEV; | |
| 5071 | + int ret; | |
| 5072 | + | |
| 5073 | + ret = tracing_check_open_get_tr(NULL); | |
| 5074 | + if (ret) | |
| 5075 | + return ret; | |
| 5043 | 5076 | |
| 5044 | 5077 | return seq_open(filp, &tracing_saved_tgids_seq_ops); |
| 5045 | 5078 | } |
| @@ -5115,8 +5148,11 @@ static const struct seq_operations tracing_saved_cmdlines_seq_ops = { · 69 unmodified lines | ||
| 5115 | 5148 | |
| 5116 | 5149 | static int tracing_saved_cmdlines_open(struct inode *inode, struct file *filp) |
| 5117 | 5150 | { |
| 5118 | − if (tracing_disabled) | |
| 5119 | − return -ENODEV; | |
| 5151 | + int ret; | |
| 5152 | + | |
| 5153 | + ret = tracing_check_open_get_tr(NULL); | |
| 5154 | + if (ret) | |
| 5155 | + return ret; | |
| 5120 | 5156 | |
| 5121 | 5157 | return seq_open(filp, &tracing_saved_cmdlines_seq_ops); |
| 5122 | 5158 | } |
| @@ -5280,8 +5316,11 @@ static const struct seq_operations tracing_eval_map_seq_ops = { · 157 unmodified lines | ||
| 5280 | 5316 | |
| 5281 | 5317 | static int tracing_eval_map_open(struct inode *inode, struct file *filp) |
| 5282 | 5318 | { |
| 5283 | − if (tracing_disabled) | |
| 5284 | − return -ENODEV; | |
| 5319 | + int ret; | |
| 5320 | + | |
| 5321 | + ret = tracing_check_open_get_tr(NULL); | |
| 5322 | + if (ret) | |
| 5323 | + return ret; | |
| 5285 | 5324 | |
| 5286 | 5325 | return seq_open(filp, &tracing_eval_map_seq_ops); |
| 5287 | 5326 | } |
| @@ -5804,13 +5843,11 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) · 516 unmodified lines | ||
| 5804 | 5843 | { |
| 5805 | 5844 | struct trace_array *tr = inode->i_private; |
| 5806 | 5845 | struct trace_iterator *iter; |
| 5807 | − int ret = 0; | |
| 5808 | − | |
| 5809 | − if (tracing_disabled) | |
| 5810 | − return -ENODEV; | |
| 5846 | + int ret; | |
| 5811 | 5847 | |
| 5812 | − if (trace_array_get(tr) < 0) | |
| 5813 | − return -ENODEV; | |
| 5848 | + ret = tracing_check_open_get_tr(tr); | |
| 5849 | + if (ret) | |
| 5850 | + return ret; | |
| 5814 | 5851 | |
| 5815 | 5852 | mutex_lock(&trace_types_lock); |
| 5816 | 5853 | |
| @@ -5999,6 +6036,7 @@ waitagain: · 182 unmodified lines | ||
| 5999 | 6036 | sizeof(struct trace_iterator) - |
| 6000 | 6037 | offsetof(struct trace_iterator, seq)); |
| 6001 | 6038 | cpumask_clear(iter->started); |
| 6039 | + trace_seq_init(&iter->seq); | |
| 6002 | 6040 | iter->pos = -1; |
| 6003 | 6041 | |
| 6004 | 6042 | trace_event_read_lock(); |
| @@ -6547,11 +6585,9 @@ static int tracing_clock_open(struct inode *inode, struct file *file) · 542 unmodified lines | ||
| 6547 | 6585 | struct trace_array *tr = inode->i_private; |
| 6548 | 6586 | int ret; |
| 6549 | 6587 | |
| 6550 | − if (tracing_disabled) | |
| 6551 | − return -ENODEV; | |
| 6552 | − | |
| 6553 | − if (trace_array_get(tr)) | |
| 6554 | − return -ENODEV; | |
| 6588 | + ret = tracing_check_open_get_tr(tr); | |
| 6589 | + if (ret) | |
| 6590 | + return ret; | |
| 6555 | 6591 | |
| 6556 | 6592 | ret = single_open(file, tracing_clock_show, inode->i_private); |
| 6557 | 6593 | if (ret < 0) |
| @@ -6581,11 +6617,9 @@ static int tracing_time_stamp_mode_open(struct inode *inode, struct file *file) · 23 unmodified lines | ||
| 6581 | 6617 | struct trace_array *tr = inode->i_private; |
| 6582 | 6618 | int ret; |
| 6583 | 6619 | |
| 6584 | − if (tracing_disabled) | |
| 6585 | − return -ENODEV; | |
| 6586 | − | |
| 6587 | − if (trace_array_get(tr)) | |
| 6588 | − return -ENODEV; | |
| 6620 | + ret = tracing_check_open_get_tr(tr); | |
| 6621 | + if (ret) | |
| 6622 | + return ret; | |
| 6589 | 6623 | |
| 6590 | 6624 | ret = single_open(file, tracing_time_stamp_mode_show, inode->i_private); |
| 6591 | 6625 | if (ret < 0) |
| @@ -6638,10 +6672,11 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file) · 46 unmodified lines | ||
| 6638 | 6672 | struct trace_array *tr = inode->i_private; |
| 6639 | 6673 | struct trace_iterator *iter; |
| 6640 | 6674 | struct seq_file *m; |
| 6641 | − int ret = 0; | |
| 6675 | + int ret; | |
| 6642 | 6676 | |
| 6643 | − if (trace_array_get(tr) < 0) | |
| 6644 | − return -ENODEV; | |
| 6677 | + ret = tracing_check_open_get_tr(tr); | |
| 6678 | + if (ret) | |
| 6679 | + return ret; | |
| 6645 | 6680 | |
| 6646 | 6681 | if (file->f_mode & FMODE_READ) { |
| 6647 | 6682 | iter = __tracing_open(inode, file, true); |
| @@ -6786,6 +6821,7 @@ static int snapshot_raw_open(struct inode *inode, struct file *filp) · 138 unmodified lines | ||
| 6786 | 6821 | struct ftrace_buffer_info *info; |
| 6787 | 6822 | int ret; |
| 6788 | 6823 | |
| 6824 | + /* The following checks for tracefs lockdown */ | |
| 6789 | 6825 | ret = tracing_buffers_open(inode, filp); |
| 6790 | 6826 | if (ret < 0) |
| 6791 | 6827 | return ret; |
| @@ -7105,8 +7141,9 @@ static int tracing_err_log_open(struct inode *inode, struct file *file) · 313 unmodified lines | ||
| 7105 | 7141 | struct trace_array *tr = inode->i_private; |
| 7106 | 7142 | int ret = 0; |
| 7107 | 7143 | |
| 7108 | − if (trace_array_get(tr) < 0) | |
| 7109 | − return -ENODEV; | |
| 7144 | + ret = tracing_check_open_get_tr(tr); | |
| 7145 | + if (ret) | |
| 7146 | + return ret; | |
| 7110 | 7147 | |
| 7111 | 7148 | /* If this file was opened for write, then erase contents */ |
| 7112 | 7149 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) |
| @@ -7157,11 +7194,9 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp) · 44 unmodified lines | ||
| 7157 | 7194 | struct ftrace_buffer_info *info; |
| 7158 | 7195 | int ret; |
| 7159 | 7196 | |
| 7160 | − if (tracing_disabled) | |
| 7161 | − return -ENODEV; | |
| 7162 | − | |
| 7163 | − if (trace_array_get(tr) < 0) | |
| 7164 | − return -ENODEV; | |
| 7197 | + ret = tracing_check_open_get_tr(tr); | |
| 7198 | + if (ret) | |
| 7199 | + return ret; | |
| 7165 | 7200 | |
| 7166 | 7201 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
| 7167 | 7202 | if (!info) { |
| @@ -338,6 +338,7 @@ extern struct mutex trace_types_lock; · 337 unmodified lines | ||
| 338 | 338 | |
| 339 | 339 | extern int trace_array_get(struct trace_array *tr); |
| 340 | 340 | extern void trace_array_put(struct trace_array *tr); |
| 341 | +extern int tracing_check_open_get_tr(struct trace_array *tr); | |
| 341 | 342 | |
| 342 | 343 | extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs); |
| 343 | 344 | extern int tracing_set_clock(struct trace_array *tr, const char *clockstr); |
| @@ -681,6 +682,7 @@ void tracing_reset_online_cpus(struct trace_buffer *buf); · 337 unmodified lines | ||
| 681 | 682 | void tracing_reset_current(int cpu); |
| 682 | 683 | void tracing_reset_all_online_cpus(void); |
| 683 | 684 | int tracing_open_generic(struct inode *inode, struct file *filp); |
| 685 | +int tracing_open_generic_tr(struct inode *inode, struct file *filp); | |
| 684 | 686 | bool tracing_is_disabled(void); |
| 685 | 687 | bool tracer_tracing_is_on(struct trace_array *tr); |
| 686 | 688 | void tracer_tracing_on(struct trace_array *tr); |
| @@ -174,6 +174,10 @@ static int dyn_event_open(struct inode *inode, struct file *file) · 173 unmodified lines | ||
| 174 | 174 | { |
| 175 | 175 | int ret; |
| 176 | 176 | |
| 177 | + ret = tracing_check_open_get_tr(NULL); | |
| 178 | + if (ret) | |
| 179 | + return ret; | |
| 180 | + | |
| 177 | 181 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { |
| 178 | 182 | ret = dyn_events_release_all(NULL); |
| 179 | 183 | if (ret < 0) |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | #define pr_fmt(fmt) fmt |
| 13 | 13 | |
| 14 | 14 | #include <linux/workqueue.h> |
| 15 | +#include <linux/security.h> | |
| 15 | 16 | #include <linux/spinlock.h> |
| 16 | 17 | #include <linux/kthread.h> |
| 17 | 18 | #include <linux/tracefs.h> |
| @@ -1294,6 +1295,8 @@ static int trace_format_open(struct inode *inode, struct file *file) · 1276 unmodified lines | ||
| 1294 | 1295 | struct seq_file *m; |
| 1295 | 1296 | int ret; |
| 1296 | 1297 | |
| 1298 | + /* Do we want to hide event format files on tracefs lockdown? */ | |
| 1299 | + | |
| 1297 | 1300 | ret = seq_open(file, &trace_format_seq_ops); |
| 1298 | 1301 | if (ret < 0) |
| 1299 | 1302 | return ret; |
| @@ -1440,28 +1443,17 @@ static int system_tr_open(struct inode *inode, struct file *filp) · 140 unmodified lines | ||
| 1440 | 1443 | struct trace_array *tr = inode->i_private; |
| 1441 | 1444 | int ret; |
| 1442 | 1445 | |
| 1443 | − if (tracing_is_disabled()) | |
| 1444 | − return -ENODEV; | |
| 1445 | − | |
| 1446 | − if (trace_array_get(tr) < 0) | |
| 1447 | − return -ENODEV; | |
| 1448 | − | |
| 1449 | 1446 | /* Make a temporary dir that has no system but points to tr */ |
| 1450 | 1447 | dir = kzalloc(sizeof(*dir), GFP_KERNEL); |
| 1451 | − if (!dir) { | |
| 1452 | − trace_array_put(tr); | |
| 1448 | + if (!dir) | |
| 1453 | 1449 | return -ENOMEM; |
| 1454 | − } | |
| 1455 | 1450 | |
| 1456 | − dir->tr = tr; | |
| 1457 | − | |
| 1458 | − ret = tracing_open_generic(inode, filp); | |
| 1451 | + ret = tracing_open_generic_tr(inode, filp); | |
| 1459 | 1452 | if (ret < 0) { |
| 1460 | − trace_array_put(tr); | |
| 1461 | 1453 | kfree(dir); |
| 1462 | 1454 | return ret; |
| 1463 | 1455 | } |
| 1464 | − | |
| 1456 | + dir->tr = tr; | |
| 1465 | 1457 | filp->private_data = dir; |
| 1466 | 1458 | |
| 1467 | 1459 | return 0; |
| @@ -1771,6 +1763,10 @@ ftrace_event_open(struct inode *inode, struct file *file, · 303 unmodified lines | ||
| 1771 | 1763 | struct seq_file *m; |
| 1772 | 1764 | int ret; |
| 1773 | 1765 | |
| 1766 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 1767 | + if (ret) | |
| 1768 | + return ret; | |
| 1769 | + | |
| 1774 | 1770 | ret = seq_open(file, seq_ops); |
| 1775 | 1771 | if (ret < 0) |
| 1776 | 1772 | return ret; |
| @@ -1795,6 +1791,7 @@ ftrace_event_avail_open(struct inode *inode, struct file *file) · 18 unmodified lines | ||
| 1795 | 1791 | { |
| 1796 | 1792 | const struct seq_operations *seq_ops = &show_event_seq_ops; |
| 1797 | 1793 | |
| 1794 | + /* Checks for tracefs lockdown */ | |
| 1798 | 1795 | return ftrace_event_open(inode, file, seq_ops); |
| 1799 | 1796 | } |
| 1800 | 1797 | |
| @@ -1805,8 +1802,9 @@ ftrace_event_set_open(struct inode *inode, struct file *file) · 4 unmodified lines | ||
| 1805 | 1802 | struct trace_array *tr = inode->i_private; |
| 1806 | 1803 | int ret; |
| 1807 | 1804 | |
| 1808 | − if (trace_array_get(tr) < 0) | |
| 1809 | − return -ENODEV; | |
| 1805 | + ret = tracing_check_open_get_tr(tr); | |
| 1806 | + if (ret) | |
| 1807 | + return ret; | |
| 1810 | 1808 | |
| 1811 | 1809 | if ((file->f_mode & FMODE_WRITE) && |
| 1812 | 1810 | (file->f_flags & O_TRUNC)) |
| @@ -1825,8 +1823,9 @@ ftrace_event_set_pid_open(struct inode *inode, struct file *file) · 12 unmodified lines | ||
| 1825 | 1823 | struct trace_array *tr = inode->i_private; |
| 1826 | 1824 | int ret; |
| 1827 | 1825 | |
| 1828 | − if (trace_array_get(tr) < 0) | |
| 1829 | − return -ENODEV; | |
| 1826 | + ret = tracing_check_open_get_tr(tr); | |
| 1827 | + if (ret) | |
| 1828 | + return ret; | |
| 1830 | 1829 | |
| 1831 | 1830 | if ((file->f_mode & FMODE_WRITE) && |
| 1832 | 1831 | (file->f_flags & O_TRUNC)) |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include <linux/module.h> |
| 9 | 9 | #include <linux/kallsyms.h> |
| 10 | +#include <linux/security.h> | |
| 10 | 11 | #include <linux/mutex.h> |
| 11 | 12 | #include <linux/slab.h> |
| 12 | 13 | #include <linux/stacktrace.h> |
| @@ -1448,6 +1449,10 @@ static int synth_events_open(struct inode *inode, struct file *file) · 1435 unmodified lines | ||
| 1448 | 1449 | { |
| 1449 | 1450 | int ret; |
| 1450 | 1451 | |
| 1452 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 1453 | + if (ret) | |
| 1454 | + return ret; | |
| 1455 | + | |
| 1451 | 1456 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { |
| 1452 | 1457 | ret = dyn_events_release_all(&synth_event_ops); |
| 1453 | 1458 | if (ret < 0) |
| @@ -1680,7 +1685,7 @@ static int save_hist_vars(struct hist_trigger_data *hist_data) · 226 unmodified lines | ||
| 1680 | 1685 | if (var_data) |
| 1681 | 1686 | return 0; |
| 1682 | 1687 | |
| 1683 | − if (trace_array_get(tr) < 0) | |
| 1688 | + if (tracing_check_open_get_tr(tr)) | |
| 1684 | 1689 | return -ENODEV; |
| 1685 | 1690 | |
| 1686 | 1691 | var_data = kzalloc(sizeof(*var_data), GFP_KERNEL); |
| @@ -5515,6 +5520,12 @@ static int hist_show(struct seq_file *m, void *v) · 3828 unmodified lines | ||
| 5515 | 5520 | |
| 5516 | 5521 | static int event_hist_open(struct inode *inode, struct file *file) |
| 5517 | 5522 | { |
| 5523 | + int ret; | |
| 5524 | + | |
| 5525 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 5526 | + if (ret) | |
| 5527 | + return ret; | |
| 5528 | + | |
| 5518 | 5529 | return single_open(file, hist_show, file); |
| 5519 | 5530 | } |
| 5520 | 5531 | |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * Copyright (C) 2013 Tom Zanussi <tom.zanussi@linux.intel.com> |
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | +#include <linux/security.h> | |
| 8 | 9 | #include <linux/module.h> |
| 9 | 10 | #include <linux/ctype.h> |
| 10 | 11 | #include <linux/mutex.h> |
| @@ -173,7 +174,11 @@ static const struct seq_operations event_triggers_seq_ops = { · 162 unmodified lines | ||
| 173 | 174 | |
| 174 | 175 | static int event_trigger_regex_open(struct inode *inode, struct file *file) |
| 175 | 176 | { |
| 176 | − int ret = 0; | |
| 177 | + int ret; | |
| 178 | + | |
| 179 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 180 | + if (ret) | |
| 181 | + return ret; | |
| 177 | 182 | |
| 178 | 183 | mutex_lock(&event_mutex); |
| 179 | 184 | |
| @@ -292,6 +297,7 @@ event_trigger_write(struct file *filp, const char __user *ubuf, · 112 unmodified lines | ||
| 292 | 297 | static int |
| 293 | 298 | event_trigger_open(struct inode *inode, struct file *filp) |
| 294 | 299 | { |
| 300 | + /* Checks for tracefs lockdown */ | |
| 295 | 301 | return event_trigger_regex_open(inode, filp); |
| 296 | 302 | } |
| 297 | 303 | |
| @@ -150,7 +150,7 @@ void trace_hwlat_callback(bool enter) · 149 unmodified lines | ||
| 150 | 150 | if (enter) |
| 151 | 151 | nmi_ts_start = time_get(); |
| 152 | 152 | else |
| 153 | − nmi_total_ts = time_get() - nmi_ts_start; | |
| 153 | + nmi_total_ts += time_get() - nmi_ts_start; | |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | 156 | if (enter) |
| @@ -256,6 +256,8 @@ static int get_sample(void) · 99 unmodified lines | ||
| 256 | 256 | /* Keep a running maximum ever recorded hardware latency */ |
| 257 | 257 | if (sample > tr->max_latency) |
| 258 | 258 | tr->max_latency = sample; |
| 259 | + if (outer_sample > tr->max_latency) | |
| 260 | + tr->max_latency = outer_sample; | |
| 259 | 261 | } |
| 260 | 262 | |
| 261 | 263 | out: |
| @@ -7,11 +7,11 @@ · 6 unmodified lines | ||
| 7 | 7 | */ |
| 8 | 8 | #define pr_fmt(fmt) "trace_kprobe: " fmt |
| 9 | 9 | |
| 10 | +#include <linux/security.h> | |
| 10 | 11 | #include <linux/module.h> |
| 11 | 12 | #include <linux/uaccess.h> |
| 12 | 13 | #include <linux/rculist.h> |
| 13 | 14 | #include <linux/error-injection.h> |
| 14 | −#include <linux/security.h> | |
| 15 | 15 | |
| 16 | 16 | #include <asm/setup.h> /* for COMMAND_LINE_SIZE */ |
| 17 | 17 | |
| @@ -936,6 +936,10 @@ static int probes_open(struct inode *inode, struct file *file) · 918 unmodified lines | ||
| 936 | 936 | { |
| 937 | 937 | int ret; |
| 938 | 938 | |
| 939 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 940 | + if (ret) | |
| 941 | + return ret; | |
| 942 | + | |
| 939 | 943 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { |
| 940 | 944 | ret = dyn_events_release_all(&trace_kprobe_ops); |
| 941 | 945 | if (ret < 0) |
| @@ -988,6 +992,12 @@ static const struct seq_operations profile_seq_op = { · 46 unmodified lines | ||
| 988 | 992 | |
| 989 | 993 | static int profile_open(struct inode *inode, struct file *file) |
| 990 | 994 | { |
| 995 | + int ret; | |
| 996 | + | |
| 997 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 998 | + if (ret) | |
| 999 | + return ret; | |
| 1000 | + | |
| 991 | 1001 | return seq_open(file, &profile_seq_op); |
| 992 | 1002 | } |
| 993 | 1003 | |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | * |
| 7 | 7 | */ |
| 8 | 8 | #include <linux/seq_file.h> |
| 9 | +#include <linux/security.h> | |
| 9 | 10 | #include <linux/uaccess.h> |
| 10 | 11 | #include <linux/kernel.h> |
| 11 | 12 | #include <linux/ftrace.h> |
| @@ -348,6 +349,12 @@ static const struct seq_operations show_format_seq_ops = { · 336 unmodified lines | ||
| 348 | 349 | static int |
| 349 | 350 | ftrace_formats_open(struct inode *inode, struct file *file) |
| 350 | 351 | { |
| 352 | + int ret; | |
| 353 | + | |
| 354 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 355 | + if (ret) | |
| 356 | + return ret; | |
| 357 | + | |
| 351 | 358 | return seq_open(file, &show_format_seq_ops); |
| 352 | 359 | } |
| 353 | 360 | |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | */ |
| 6 | 6 | #include <linux/sched/task_stack.h> |
| 7 | 7 | #include <linux/stacktrace.h> |
| 8 | +#include <linux/security.h> | |
| 8 | 9 | #include <linux/kallsyms.h> |
| 9 | 10 | #include <linux/seq_file.h> |
| 10 | 11 | #include <linux/spinlock.h> |
| @@ -470,6 +471,12 @@ static const struct seq_operations stack_trace_seq_ops = { · 459 unmodified lines | ||
| 470 | 471 | |
| 471 | 472 | static int stack_trace_open(struct inode *inode, struct file *file) |
| 472 | 473 | { |
| 474 | + int ret; | |
| 475 | + | |
| 476 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 477 | + if (ret) | |
| 478 | + return ret; | |
| 479 | + | |
| 473 | 480 | return seq_open(file, &stack_trace_seq_ops); |
| 474 | 481 | } |
| 475 | 482 | |
| @@ -487,6 +494,7 @@ stack_trace_filter_open(struct inode *inode, struct file *file) · 11 unmodified lines | ||
| 487 | 494 | { |
| 488 | 495 | struct ftrace_ops *ops = inode->i_private; |
| 489 | 496 | |
| 497 | + /* Checks for tracefs lockdown */ | |
| 490 | 498 | return ftrace_regex_open(ops, FTRACE_ITER_FILTER, |
| 491 | 499 | inode, file); |
| 492 | 500 | } |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | * |
| 10 | 10 | */ |
| 11 | 11 | |
| 12 | − | |
| 12 | +#include <linux/security.h> | |
| 13 | 13 | #include <linux/list.h> |
| 14 | 14 | #include <linux/slab.h> |
| 15 | 15 | #include <linux/rbtree.h> |
| @@ -238,6 +238,10 @@ static int tracing_stat_open(struct inode *inode, struct file *file) · 222 unmodified lines | ||
| 238 | 238 | struct seq_file *m; |
| 239 | 239 | struct stat_session *session = inode->i_private; |
| 240 | 240 | |
| 241 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 242 | + if (ret) | |
| 243 | + return ret; | |
| 244 | + | |
| 241 | 245 | ret = stat_seq_init(session); |
| 242 | 246 | if (ret) |
| 243 | 247 | return ret; |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | */ |
| 8 | 8 | #define pr_fmt(fmt) "trace_uprobe: " fmt |
| 9 | 9 | |
| 10 | +#include <linux/security.h> | |
| 10 | 11 | #include <linux/ctype.h> |
| 11 | 12 | #include <linux/module.h> |
| 12 | 13 | #include <linux/uaccess.h> |
| @@ -769,6 +770,10 @@ static int probes_open(struct inode *inode, struct file *file) · 756 unmodified lines | ||
| 769 | 770 | { |
| 770 | 771 | int ret; |
| 771 | 772 | |
| 773 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 774 | + if (ret) | |
| 775 | + return ret; | |
| 776 | + | |
| 772 | 777 | if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { |
| 773 | 778 | ret = dyn_events_release_all(&trace_uprobe_ops); |
| 774 | 779 | if (ret) |
| @@ -818,6 +823,12 @@ static const struct seq_operations profile_seq_op = { · 43 unmodified lines | ||
| 818 | 823 | |
| 819 | 824 | static int profile_open(struct inode *inode, struct file *file) |
| 820 | 825 | { |
| 826 | + int ret; | |
| 827 | + | |
| 828 | + ret = security_locked_down(LOCKDOWN_TRACEFS); | |
| 829 | + if (ret) | |
| 830 | + return ret; | |
| 831 | + | |
| 821 | 832 | return seq_open(file, &profile_seq_op); |
| 822 | 833 | } |
| 823 | 834 | |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #include <linux/export.h> |
| 3 | 3 | #include <linux/generic-radix-tree.h> |
| 4 | 4 | #include <linux/gfp.h> |
| 5 | +#include <linux/kmemleak.h> | |
| 5 | 6 | |
| 6 | 7 | #define GENRADIX_ARY (PAGE_SIZE / sizeof(struct genradix_node *)) |
| 7 | 8 | #define GENRADIX_ARY_SHIFT ilog2(GENRADIX_ARY) |
| @@ -75,6 +76,27 @@ void *__genradix_ptr(struct __genradix *radix, size_t offset) · 67 unmodified lines | ||
| 75 | 76 | } |
| 76 | 77 | EXPORT_SYMBOL(__genradix_ptr); |
| 77 | 78 | |
| 79 | +static inline struct genradix_node *genradix_alloc_node(gfp_t gfp_mask) | |
| 80 | +{ | |
| 81 | + struct genradix_node *node; | |
| 82 | + | |
| 83 | + node = (struct genradix_node *)__get_free_page(gfp_mask|__GFP_ZERO); | |
| 84 | + | |
| 85 | + /* | |
| 86 | + * We're using pages (not slab allocations) directly for kernel data | |
| 87 | + * structures, so we need to explicitly inform kmemleak of them in order | |
| 88 | + * to avoid false positive memory leak reports. | |
| 89 | + */ | |
| 90 | + kmemleak_alloc(node, PAGE_SIZE, 1, gfp_mask); | |
| 91 | + return node; | |
| 92 | +} | |
| 93 | + | |
| 94 | +static inline void genradix_free_node(struct genradix_node *node) | |
| 95 | +{ | |
| 96 | + kmemleak_free(node); | |
| 97 | + free_page((unsigned long)node); | |
| 98 | +} | |
| 99 | + | |
| 78 | 100 | /* |
| 79 | 101 | * Returns pointer to the specified byte @offset within @radix, allocating it if |
| 80 | 102 | * necessary - newly allocated slots are always zeroed out: |
| @@ -97,8 +119,7 @@ void *__genradix_ptr_alloc(struct __genradix *radix, size_t offset, · 16 unmodified lines | ||
| 97 | 119 | break; |
| 98 | 120 | |
| 99 | 121 | if (!new_node) { |
| 100 | − new_node = (void *) | |
| 101 | − __get_free_page(gfp_mask|__GFP_ZERO); | |
| 122 | + new_node = genradix_alloc_node(gfp_mask); | |
| 102 | 123 | if (!new_node) |
| 103 | 124 | return NULL; |
| 104 | 125 | } |
| @@ -121,8 +142,7 @@ void *__genradix_ptr_alloc(struct __genradix *radix, size_t offset, · 16 unmodified lines | ||
| 121 | 142 | n = READ_ONCE(*p); |
| 122 | 143 | if (!n) { |
| 123 | 144 | if (!new_node) { |
| 124 | − new_node = (void *) | |
| 125 | − __get_free_page(gfp_mask|__GFP_ZERO); | |
| 145 | + new_node = genradix_alloc_node(gfp_mask); | |
| 126 | 146 | if (!new_node) |
| 127 | 147 | return NULL; |
| 128 | 148 | } |
| @@ -133,7 +153,7 @@ void *__genradix_ptr_alloc(struct __genradix *radix, size_t offset, · 4 unmodified lines | ||
| 133 | 153 | } |
| 134 | 154 | |
| 135 | 155 | if (new_node) |
| 136 | − free_page((unsigned long) new_node); | |
| 156 | + genradix_free_node(new_node); | |
| 137 | 157 | |
| 138 | 158 | return &n->data[offset]; |
| 139 | 159 | } |
| @@ -191,7 +211,7 @@ static void genradix_free_recurse(struct genradix_node *n, unsigned level) · 51 unmodified lines | ||
| 191 | 211 | genradix_free_recurse(n->children[i], level - 1); |
| 192 | 212 | } |
| 193 | 213 | |
| 194 | − free_page((unsigned long) n); | |
| 214 | + genradix_free_node(n); | |
| 195 | 215 | } |
| 196 | 216 | |
| 197 | 217 | int __genradix_prealloc(struct __genradix *radix, size_t size, |
| @@ -748,27 +748,6 @@ void *memset(void *s, int c, size_t count) · 747 unmodified lines | ||
| 748 | 748 | EXPORT_SYMBOL(memset); |
| 749 | 749 | #endif |
| 750 | 750 | |
| 751 | −/** | |
| 752 | − * memzero_explicit - Fill a region of memory (e.g. sensitive | |
| 753 | − * keying data) with 0s. | |
| 754 | − * @s: Pointer to the start of the area. | |
| 755 | − * @count: The size of the area. | |
| 756 | − * | |
| 757 | − * Note: usually using memset() is just fine (!), but in cases | |
| 758 | − * where clearing out _local_ data at the end of a scope is | |
| 759 | − * necessary, memzero_explicit() should be used instead in | |
| 760 | − * order to prevent the compiler from optimising away zeroing. | |
| 761 | − * | |
| 762 | − * memzero_explicit() doesn't need an arch-specific version as | |
| 763 | − * it just invokes the one of memset() implicitly. | |
| 764 | − */ | |
| 765 | −void memzero_explicit(void *s, size_t count) | |
| 766 | −{ | |
| 767 | − memset(s, 0, count); | |
| 768 | − barrier_data(s); | |
| 769 | −} | |
| 770 | −EXPORT_SYMBOL(memzero_explicit); | |
| 771 | − | |
| 772 | 751 | #ifndef __HAVE_ARCH_MEMSET16 |
| 773 | 752 | /** |
| 774 | 753 | * memset16() - Fill a memory area with a uint16_t |
| @@ -297,6 +297,32 @@ out: · 296 unmodified lines | ||
| 297 | 297 | return 1; |
| 298 | 298 | } |
| 299 | 299 | |
| 300 | +static int __init do_kmem_cache_size_bulk(int size, int *total_failures) | |
| 301 | +{ | |
| 302 | + struct kmem_cache *c; | |
| 303 | + int i, iter, maxiter = 1024; | |
| 304 | + int num, bytes; | |
| 305 | + bool fail = false; | |
| 306 | + void *objects[10]; | |
| 307 | + | |
| 308 | + c = kmem_cache_create("test_cache", size, size, 0, NULL); | |
| 309 | + for (iter = 0; (iter < maxiter) && !fail; iter++) { | |
| 310 | + num = kmem_cache_alloc_bulk(c, GFP_KERNEL, ARRAY_SIZE(objects), | |
| 311 | + objects); | |
| 312 | + for (i = 0; i < num; i++) { | |
| 313 | + bytes = count_nonzero_bytes(objects[i], size); | |
| 314 | + if (bytes) | |
| 315 | + fail = true; | |
| 316 | + fill_with_garbage(objects[i], size); | |
| 317 | + } | |
| 318 | + | |
| 319 | + if (num) | |
| 320 | + kmem_cache_free_bulk(c, num, objects); | |
| 321 | + } | |
| 322 | + *total_failures += fail; | |
| 323 | + return 1; | |
| 324 | +} | |
| 325 | + | |
| 300 | 326 | /* |
| 301 | 327 | * Test kmem_cache allocation by creating caches of different sizes, with and |
| 302 | 328 | * without constructors, with and without SLAB_TYPESAFE_BY_RCU. |
| @@ -318,6 +344,7 @@ static int __init test_kmemcache(int *total_failures) · 15 unmodified lines | ||
| 318 | 344 | num_tests += do_kmem_cache_size(size, ctor, rcu, zero, |
| 319 | 345 | &failures); |
| 320 | 346 | } |
| 347 | + num_tests += do_kmem_cache_size_bulk(size, &failures); | |
| 321 | 348 | } |
| 322 | 349 | REPORT_FAILURES_IN_FN(); |
| 323 | 350 | *total_failures += failures; |
| @@ -47,18 +47,35 @@ static bool is_zeroed(void *from, size_t size) · 46 unmodified lines | ||
| 47 | 47 | static int test_check_nonzero_user(char *kmem, char __user *umem, size_t size) |
| 48 | 48 | { |
| 49 | 49 | int ret = 0; |
| 50 | − size_t start, end, i; | |
| 51 | − size_t zero_start = size / 4; | |
| 52 | − size_t zero_end = size - zero_start; | |
| 50 | + size_t start, end, i, zero_start, zero_end; | |
| 51 | + | |
| 52 | + if (test(size < 2 * PAGE_SIZE, "buffer too small")) | |
| 53 | + return -EINVAL; | |
| 54 | + | |
| 55 | + /* | |
| 56 | + * We want to cross a page boundary to exercise the code more | |
| 57 | + * effectively. We also don't want to make the size we scan too large, | |
| 58 | + * otherwise the test can take a long time and cause soft lockups. So | |
| 59 | + * scan a 1024 byte region across the page boundary. | |
| 60 | + */ | |
| 61 | + size = 1024; | |
| 62 | + start = PAGE_SIZE - (size / 2); | |
| 63 | + | |
| 64 | + kmem += start; | |
| 65 | + umem += start; | |
| 66 | + | |
| 67 | + zero_start = size / 4; | |
| 68 | + zero_end = size - zero_start; | |
| 53 | 69 | |
| 54 | 70 | /* |
| 55 | − * We conduct a series of check_nonzero_user() tests on a block of memory | |
| 56 | − * with the following byte-pattern (trying every possible [start,end] | |
| 57 | − * pair): | |
| 71 | + * We conduct a series of check_nonzero_user() tests on a block of | |
| 72 | + * memory with the following byte-pattern (trying every possible | |
| 73 | + * [start,end] pair): | |
| 58 | 74 | * |
| 59 | 75 | * [ 00 ff 00 ff ... 00 00 00 00 ... ff 00 ff 00 ] |
| 60 | 76 | * |
| 61 | − * And we verify that check_nonzero_user() acts identically to memchr_inv(). | |
| 77 | + * And we verify that check_nonzero_user() acts identically to | |
| 78 | + * memchr_inv(). | |
| 62 | 79 | */ |
| 63 | 80 | |
| 64 | 81 | memset(kmem, 0x0, size); |
16 more lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 11 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 56 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 249 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 135 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 128 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 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 44 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 54 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 47 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 15 lines aren’t shown here.
This diff is large: its 69 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 88 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 82 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 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 12 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 16 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 101 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 27 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 20 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 16 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 72 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
File renamed without changes.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.