diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 000000000000..376d3fe2767e --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,17 @@ +# Copyright (C) 2021 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +load("//build/kleaf:common_kernels.bzl", "define_common_kernels") + +define_common_kernels() diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac2 b/Documentation/ABI/testing/configfs-usb-gadget-uac2 index d4356c8b8cd6..26fb8e9b4e61 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac2 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac2 @@ -8,6 +8,8 @@ Description: c_chmask capture channel mask c_srate capture sampling rate c_ssize capture sample size (bytes) + c_sync capture synchronization type (async/adaptive) + fb_max maximum extra bandwidth in async mode p_chmask playback channel mask p_srate playback sampling rate p_ssize playback sample size (bytes) diff --git a/Documentation/ABI/testing/evm b/Documentation/ABI/testing/evm index 3c477ba48a31..2243b72e4110 100644 --- a/Documentation/ABI/testing/evm +++ b/Documentation/ABI/testing/evm @@ -49,8 +49,30 @@ Description: modification of EVM-protected metadata and disable all further modification of policy - Note that once a key has been loaded, it will no longer be - possible to enable metadata modification. + Echoing a value is additive, the new value is added to the + existing initialization flags. + + For example, after:: + + echo 2 >/evm + + another echo can be performed:: + + echo 1 >/evm + + and the resulting value will be 3. + + Note that once an HMAC key has been loaded, it will no longer + be possible to enable metadata modification. Signaling that an + HMAC key has been loaded will clear the corresponding flag. + For example, if the current value is 6 (2 and 4 set):: + + echo 1 >/evm + + will set the new value to 3 (4 cleared). + + Loading an HMAC key is the only way to disable metadata + modification. Until key loading has been signaled EVM can not create or validate the 'security.evm' xattr, but returns diff --git a/Documentation/ABI/testing/sysfs-bus-papr-pmem b/Documentation/ABI/testing/sysfs-bus-papr-pmem index 8316c33862a0..0aa02bf2bde5 100644 --- a/Documentation/ABI/testing/sysfs-bus-papr-pmem +++ b/Documentation/ABI/testing/sysfs-bus-papr-pmem @@ -39,9 +39,11 @@ KernelVersion: v5.9 Contact: linuxppc-dev , linux-nvdimm@lists.01.org, Description: (RO) Report various performance stats related to papr-scm NVDIMM - device. Each stat is reported on a new line with each line - composed of a stat-identifier followed by it value. Below are - currently known dimm performance stats which are reported: + device. This attribute is only available for NVDIMM devices + that support reporting NVDIMM performance stats. Each stat is + reported on a new line with each line composed of a + stat-identifier followed by it value. Below are currently known + dimm performance stats which are reported: * "CtlResCt" : Controller Reset Count * "CtlResTm" : Controller Reset Elapsed Time diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 093524d70372..e944db6f8eaf 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -605,6 +605,12 @@ loops can be debugged more effectively on production systems. + clocksource.max_cswd_read_retries= [KNL] + Number of clocksource_watchdog() retries due to + external delays before the clock will be marked + unstable. Defaults to three retries, that is, + four attempts to read the clock under test. + clearcpuid=BITNUM[,BITNUM...] [X86] Disable CPUID feature X for the kernel. See arch/x86/include/asm/cpufeatures.h for the valid bit @@ -2306,8 +2312,7 @@ state is kept private from the host. Not valid if the kernel is running in EL2. - Defaults to VHE/nVHE based on hardware support and - the value of CONFIG_ARM64_VHE. + Defaults to VHE/nVHE based on hardware support. kvm-arm.vgic_v3_group0_trap= [KVM,ARM] Trap guest accesses to GICv3 group-0 diff --git a/Documentation/arm64/tagged-address-abi.rst b/Documentation/arm64/tagged-address-abi.rst index 4a9d9c794ee5..7d255249094d 100644 --- a/Documentation/arm64/tagged-address-abi.rst +++ b/Documentation/arm64/tagged-address-abi.rst @@ -45,14 +45,24 @@ how the user addresses are used by the kernel: 1. User addresses not accessed by the kernel but used for address space management (e.g. ``mprotect()``, ``madvise()``). The use of valid - tagged pointers in this context is allowed with the exception of - ``brk()``, ``mmap()`` and the ``new_address`` argument to - ``mremap()`` as these have the potential to alias with existing - user addresses. - - NOTE: This behaviour changed in v5.6 and so some earlier kernels may - incorrectly accept valid tagged pointers for the ``brk()``, - ``mmap()`` and ``mremap()`` system calls. + tagged pointers in this context is allowed with these exceptions: + + - ``brk()``, ``mmap()`` and the ``new_address`` argument to + ``mremap()`` as these have the potential to alias with existing + user addresses. + + NOTE: This behaviour changed in v5.6 and so some earlier kernels may + incorrectly accept valid tagged pointers for the ``brk()``, + ``mmap()`` and ``mremap()`` system calls. + + - The ``range.start``, ``start`` and ``dst`` arguments to the + ``UFFDIO_*`` ``ioctl()``s used on a file descriptor obtained from + ``userfaultfd()``, as fault addresses subsequently obtained by reading + the file descriptor will be untagged, which may otherwise confuse + tag-unaware programs. + + NOTE: This behaviour changed in v5.14 and so some earlier kernels may + incorrectly accept valid tagged pointers for this system call. 2. User addresses accessed by the kernel (e.g. ``write()``). This ABI relaxation is disabled by default and the application thread needs to diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml index e4cf07ab5744..d3c42069e8a7 100644 --- a/Documentation/devicetree/bindings/connector/usb-connector.yaml +++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml @@ -93,6 +93,28 @@ properties: - device - dual + typec-power-opmode: + description: Determines the power operation mode that the Type C connector + will support and will advertise through CC pins when it has no power + delivery support. + - "default" corresponds to default USB voltage and current defined by the + USB 2.0 and USB 3.2 specifications, 5V 500mA for USB 2.0 ports and + 5V 900mA or 1500mA for USB 3.2 ports in single-lane or dual-lane + operation respectively. + - "1.5A" and "3.0A", 5V 1.5A and 5V 3.0A respectively, as defined in USB + Type-C Cable and Connector specification, when Power Delivery is not + supported. + allOf: + - $ref: /schemas/types.yaml#definitions/string + enum: + - default + - 1.5A + - 3.0A + + pd-disable: + description: Set this property if the Type-C connector has no power delivery support. + type: boolean + # The following are optional properties for "usb-c-connector" with power # delivery support. source-pdos: @@ -229,6 +251,12 @@ allOf: type: const: micro +anyOf: + - not: + required: + - typec-power-opmode + - new-source-frs-typec-current + additionalProperties: true examples: diff --git a/Documentation/devicetree/bindings/i2c/i2c-at91.txt b/Documentation/devicetree/bindings/i2c/i2c-at91.txt index 96c914e048f5..2015f50aed0f 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-at91.txt +++ b/Documentation/devicetree/bindings/i2c/i2c-at91.txt @@ -73,7 +73,7 @@ i2c0: i2c@f8034600 { pinctrl-0 = <&pinctrl_i2c0>; pinctrl-1 = <&pinctrl_i2c0_gpio>; sda-gpios = <&pioA 30 GPIO_ACTIVE_HIGH>; - scl-gpios = <&pioA 31 GPIO_ACTIVE_HIGH>; + scl-gpios = <&pioA 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; wm8731: wm8731@1a { compatible = "wm8731"; diff --git a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt index e8d3096d922c..39b5f4c5a511 100644 --- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt @@ -51,6 +51,23 @@ compatible (optional) - standard definition used as a shared pool of DMA buffers for a set of devices. It can be used by an operating system to instantiate the necessary pool management subsystem if necessary. + - restricted-dma-pool: This indicates a region of memory meant to be + used as a pool of restricted DMA buffers for a set of devices. The + memory region would be the only region accessible to those devices. + When using this, the no-map and reusable properties must not be set, + so the operating system can create a virtual mapping that will be used + for synchronization. The main purpose for restricted DMA is to + mitigate the lack of DMA access control on systems without an IOMMU, + which could result in the DMA accessing the system memory at + unexpected times and/or unexpected addresses, possibly leading to data + leakage or corruption. The feature on its own provides a basic level + of protection against the DMA overwriting buffer contents at + unexpected times. However, to protect against general data leakage and + system memory corruption, the system needs to provide way to lock down + the memory access, e.g., MPU. Note that since coherent allocation + needs remapping, one must set up another device coherent pool by + shared-dma-pool and use dma_alloc_from_dev_coherent instead for atomic + coherent allocation. - vendor specific string in the form ,[-] no-map (optional) - empty property - Indicates the operating system must not create a virtual mapping @@ -85,10 +102,11 @@ memory-region-names (optional) - a list of names, one for each corresponding Example ------- -This example defines 3 contiguous regions are defined for Linux kernel: +This example defines 4 contiguous regions for Linux kernel: one default of all device drivers (named linux,cma@72000000 and 64MiB in size), -one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), and -one for multimedia processing (named multimedia-memory@77000000, 64MiB). +one dedicated to the framebuffer device (named framebuffer@78000000, 8MiB), +one for multimedia processing (named multimedia-memory@77000000, 64MiB), and +one for restricted dma pool (named restricted_dma_reserved@0x50000000, 64MiB). / { #address-cells = <1>; @@ -120,6 +138,11 @@ one for multimedia processing (named multimedia-memory@77000000, 64MiB). compatible = "acme,multimedia-memory"; reg = <0x77000000 0x4000000>; }; + + restricted_dma_reserved: restricted_dma_reserved { + compatible = "restricted-dma-pool"; + reg = <0x50000000 0x4000000>; + }; }; /* ... */ @@ -138,4 +161,11 @@ one for multimedia processing (named multimedia-memory@77000000, 64MiB). memory-region = <&multimedia_reserved>; /* ... */ }; + + pcie_device: pcie_device@0,0 { + reg = <0x83010000 0x0 0x00000000 0x0 0x00100000 + 0x83010000 0x0 0x00100000 0x0 0x00100000>; + memory-region = <&restricted_dma_reserved>; + /* ... */ + }; }; diff --git a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml index efc0198eeb74..5444be7667b6 100644 --- a/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml +++ b/Documentation/devicetree/bindings/riscv/sifive-l2-cache.yaml @@ -24,9 +24,9 @@ allOf: select: properties: compatible: - items: - - enum: - - sifive,fu540-c000-ccache + contains: + enum: + - sifive,fu540-c000-ccache required: - compatible diff --git a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml index db61f0731a20..2e35aeaa8781 100644 --- a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml +++ b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml @@ -57,7 +57,7 @@ patternProperties: rate sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle + $ref: /schemas/types.yaml#/definitions/phandle-array description: phandle of the CPU DAI patternProperties: @@ -71,7 +71,7 @@ patternProperties: properties: sound-dai: - $ref: /schemas/types.yaml#/definitions/phandle + $ref: /schemas/types.yaml#/definitions/phandle-array description: phandle of the codec DAI required: diff --git a/Documentation/driver-api/early-userspace/early_userspace_support.rst b/Documentation/driver-api/early-userspace/early_userspace_support.rst index 8a58c61932ff..61bdeac1bae5 100644 --- a/Documentation/driver-api/early-userspace/early_userspace_support.rst +++ b/Documentation/driver-api/early-userspace/early_userspace_support.rst @@ -69,17 +69,17 @@ early userspace image can be built by an unprivileged user. As a technical note, when directories and files are specified, the entire CONFIG_INITRAMFS_SOURCE is passed to -usr/gen_initramfs_list.sh. This means that CONFIG_INITRAMFS_SOURCE +usr/gen_initramfs.sh. This means that CONFIG_INITRAMFS_SOURCE can really be interpreted as any legal argument to -gen_initramfs_list.sh. If a directory is specified as an argument then +gen_initramfs.sh. If a directory is specified as an argument then the contents are scanned, uid/gid translation is performed, and usr/gen_init_cpio file directives are output. If a directory is -specified as an argument to usr/gen_initramfs_list.sh then the +specified as an argument to usr/gen_initramfs.sh then the contents of the file are simply copied to the output. All of the output directives from directory scanning and file contents copying are processed by usr/gen_init_cpio. -See also 'usr/gen_initramfs_list.sh -h'. +See also 'usr/gen_initramfs.sh -h'. Where's this all leading? ========================= diff --git a/Documentation/filesystems/ramfs-rootfs-initramfs.rst b/Documentation/filesystems/ramfs-rootfs-initramfs.rst index 4598b0d90b60..164960631925 100644 --- a/Documentation/filesystems/ramfs-rootfs-initramfs.rst +++ b/Documentation/filesystems/ramfs-rootfs-initramfs.rst @@ -170,7 +170,7 @@ Documentation/driver-api/early-userspace/early_userspace_support.rst for more de The kernel does not depend on external cpio tools. If you specify a directory instead of a configuration file, the kernel's build infrastructure creates a configuration file from that directory (usr/Makefile calls -usr/gen_initramfs_list.sh), and proceeds to package up that directory +usr/gen_initramfs.sh), and proceeds to package up that directory using the config file (by feeding it to usr/gen_init_cpio, which is created from usr/gen_init_cpio.c). The kernel's build-time cpio creation code is entirely self-contained, and the kernel's boot-time extractor is also diff --git a/Documentation/hwmon/max31790.rst b/Documentation/hwmon/max31790.rst index f301385d8cef..7b097c3b9b90 100644 --- a/Documentation/hwmon/max31790.rst +++ b/Documentation/hwmon/max31790.rst @@ -38,6 +38,7 @@ Sysfs entries fan[1-12]_input RO fan tachometer speed in RPM fan[1-12]_fault RO fan experienced fault fan[1-6]_target RW desired fan speed in RPM -pwm[1-6]_enable RW regulator mode, 0=disabled, 1=manual mode, 2=rpm mode -pwm[1-6] RW fan target duty cycle (0-255) +pwm[1-6]_enable RW regulator mode, 0=disabled (duty cycle=0%), 1=manual mode, 2=rpm mode +pwm[1-6] RW read: current pwm duty cycle, + write: target pwm duty cycle (0-255) ================== === ======================================================= diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index f2fdc3809126..40278344dc48 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -751,7 +751,7 @@ tcp_fastopen_blackhole_timeout_sec - INTEGER initial value when the blackhole issue goes away. 0 to disable the blackhole detection. - By default, it is set to 1hr. + By default, it is set to 0 (feature is disabled). tcp_fastopen_key - list of comma separated 32-digit hexadecimal INTEGERs The list consists of a primary key and an optional backup key. The diff --git a/Documentation/trace/histogram.rst b/Documentation/trace/histogram.rst index b71e09f745c3..f99be8062bc8 100644 --- a/Documentation/trace/histogram.rst +++ b/Documentation/trace/histogram.rst @@ -191,7 +191,7 @@ Documentation written by Tom Zanussi with the event, in nanoseconds. May be modified by .usecs to have timestamps interpreted as microseconds. - cpu int the cpu on which the event occurred. + common_cpu int the cpu on which the event occurred. ====================== ==== ======================================= Extended error information diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index 2085e7b24eeb..9d6276f82774 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -728,6 +728,8 @@ The uac2 function provides these attributes in its function directory: c_chmask capture channel mask c_srate capture sampling rate c_ssize capture sample size (bytes) + c_sync capture synchronization type (async/adaptive) + fb_max maximum extra bandwidth in async mode p_chmask playback channel mask p_srate playback sampling rate p_ssize playback sample size (bytes) diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst index c3a2a695b4f9..4ec87b555c62 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst @@ -4161,7 +4161,7 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - :stub-columns: 0 :widths: 1 1 2 - * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT`` + * - ``V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED`` - 0x00000001 - * - ``V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT`` @@ -4369,6 +4369,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field - * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED`` - 0x00000100 - + * - ``V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT`` + - 0x00000200 + - .. c:type:: v4l2_hevc_dpb_entry diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index 88a1441224a1..8881f006d677 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -3094,6 +3094,18 @@ optional features it should have.  This will cause a reset of the cpu registers to their initial values.  If this is not called, KVM_RUN will return ENOEXEC for that vcpu. +The initial values are defined as: + - Processor state: + * AArch64: EL1h, D, A, I and F bits set. All other bits + are cleared. + * AArch32: SVC, A, I and F bits set. All other bits are + cleared. + - General Purpose registers, including PC and SP: set to 0 + - FPSIMD/NEON registers: set to 0 + - SVE registers: set to 0 + - System registers: Reset to their architecturally defined + values as for a warm reset to EL1 (resp. SVC) + Note that because some registers reflect machine topology, all vcpus should be created before this ioctl is invoked. @@ -3313,7 +3325,8 @@ The top 16 bits of the control field are architecture specific control flags which can include the following: - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64] - - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, arm64] + - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390] + - KVM_GUESTDBG_USE_HW: using hardware debug events [arm64] - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86] - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86] - KVM_GUESTDBG_EXIT_PENDING: trigger an immediate guest exit [s390] @@ -4821,6 +4834,43 @@ filter, e.g. MSRs with identical settings in both the old and new filter will have deterministic behavior. +4.130 KVM_ARM_MTE_COPY_TAGS +--------------------------- + +:Capability: KVM_CAP_ARM_MTE +:Architectures: arm64 +:Type: vm ioctl +:Parameters: struct kvm_arm_copy_mte_tags +:Returns: number of bytes copied, < 0 on error (-EINVAL for incorrect + arguments, -EFAULT if memory cannot be accessed). + +:: + + struct kvm_arm_copy_mte_tags { + __u64 guest_ipa; + __u64 length; + void __user *addr; + __u64 flags; + __u64 reserved[2]; + }; + +Copies Memory Tagging Extension (MTE) tags to/from guest tag memory. The +``guest_ipa`` and ``length`` fields must be ``PAGE_SIZE`` aligned. The ``addr`` +field must point to a buffer which the tags will be copied to or from. + +``flags`` specifies the direction of copy, either ``KVM_ARM_TAGS_TO_GUEST`` or +``KVM_ARM_TAGS_FROM_GUEST``. + +The size of the buffer to store the tags is ``(length / 16)`` bytes +(granules in MTE are 16 bytes long). Each byte contains a single tag +value. This matches the format of ``PTRACE_PEEKMTETAGS`` and +``PTRACE_POKEMTETAGS``. + +If an error occurs before any data is copied then a negative error code is +returned. If some tags have been copied before an error occurs then the number +of bytes successfully copied is returned. If the call completes successfully +then ``length`` is returned. + 5. The kvm_run structure ======================== @@ -6027,6 +6077,30 @@ KVM_EXIT_X86_RDMSR and KVM_EXIT_X86_WRMSR exit notifications which user space can then handle to implement model specific MSR handling and/or user notifications to inform a user that an MSR was not handled. +7.26 KVM_CAP_ARM_MTE +-------------------- + +:Architectures: arm64 +:Parameters: none + +This capability indicates that KVM (and the hardware) supports exposing the +Memory Tagging Extensions (MTE) to the guest. It must also be enabled by the +VMM before creating any VCPUs to allow the guest access. Note that MTE is only +available to a guest running in AArch64 mode and enabling this capability will +cause attempts to create AArch32 VCPUs to fail. + +When enabled the guest is able to access tags associated with any memory given +to the guest. KVM will ensure that the tags are maintained during swap or +hibernation of the host; however the VMM needs to manually save/restore the +tags as appropriate if the VM is migrated. + +When this capability is enabled all memory in memslots must be mapped as +not-shareable (no MAP_SHARED), attempts to create a memslot with a +MAP_SHARED mmap will result in an -EINVAL return. + +When enabled the VMM may make use of the ``KVM_ARM_MTE_COPY_TAGS`` ioctl to +perform a bulk copy of tags to/from the guest. + 8. Other capabilities. ====================== @@ -6403,3 +6477,12 @@ When enabled, KVM will disable paravirtual features provided to the guest according to the bits in the KVM_CPUID_FEATURES CPUID leaf (0x40000001). Otherwise, a guest may use the paravirtual features regardless of what has actually been exposed through the CPUID leaf. + +8.31 KVM_CAP_PTP_KVM +-------------------- + +:Architectures: arm64 + +This capability indicates that the KVM virtual PTP service is +supported in the host. A VMM can check whether the service is +available to the guest on migration. diff --git a/Documentation/virt/kvm/arm/index.rst b/Documentation/virt/kvm/arm/index.rst index 3e2b2aba90fc..78a9b670aafe 100644 --- a/Documentation/virt/kvm/arm/index.rst +++ b/Documentation/virt/kvm/arm/index.rst @@ -10,3 +10,4 @@ ARM hyp-abi psci pvtime + ptp_kvm diff --git a/Documentation/virt/kvm/arm/ptp_kvm.rst b/Documentation/virt/kvm/arm/ptp_kvm.rst new file mode 100644 index 000000000000..aecdc80ddcd8 --- /dev/null +++ b/Documentation/virt/kvm/arm/ptp_kvm.rst @@ -0,0 +1,25 @@ +.. SPDX-License-Identifier: GPL-2.0 + +PTP_KVM support for arm/arm64 +============================= + +PTP_KVM is used for high precision time sync between host and guests. +It relies on transferring the wall clock and counter value from the +host to the guest using a KVM-specific hypercall. + +* ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: 0x86000001 + +This hypercall uses the SMC32/HVC32 calling convention: + +ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID + ============== ======== ===================================== + Function ID: (uint32) 0x86000001 + Arguments: (uint32) KVM_PTP_VIRT_COUNTER(0) + KVM_PTP_PHYS_COUNTER(1) + Return Values: (int32) NOT_SUPPORTED(-1) on error, or + (uint32) Upper 32 bits of wall clock time (r0) + (uint32) Lower 32 bits of wall clock time (r1) + (uint32) Upper 32 bits of counter (r2) + (uint32) Lower 32 bits of counter (r3) + Endianness: No Restrictions. + ============== ======== ===================================== diff --git a/Documentation/virt/kvm/devices/arm-vgic-its.rst b/Documentation/virt/kvm/devices/arm-vgic-its.rst index 6c304fd2b1b4..d257eddbae29 100644 --- a/Documentation/virt/kvm/devices/arm-vgic-its.rst +++ b/Documentation/virt/kvm/devices/arm-vgic-its.rst @@ -80,7 +80,7 @@ KVM_DEV_ARM_VGIC_GRP_CTRL -EFAULT Invalid guest ram access -EBUSY One or more VCPUS are running -EACCES The virtual ITS is backed by a physical GICv4 ITS, and the - state is not available + state is not available without GICv4.1 ======= ========================================================== KVM_DEV_ARM_VGIC_GRP_ITS_REGS diff --git a/Documentation/virt/kvm/devices/arm-vgic-v3.rst b/Documentation/virt/kvm/devices/arm-vgic-v3.rst index 5dd3bff51978..51e5e5762571 100644 --- a/Documentation/virt/kvm/devices/arm-vgic-v3.rst +++ b/Documentation/virt/kvm/devices/arm-vgic-v3.rst @@ -228,7 +228,7 @@ Groups: KVM_DEV_ARM_VGIC_CTRL_INIT request the initialization of the VGIC, no additional parameter in - kvm_device_attr.addr. + kvm_device_attr.addr. Must be called after all VCPUs have been created. KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES save all LPI pending bits into guest RAM pending tables. diff --git a/Documentation/virt/kvm/mmu.rst b/Documentation/virt/kvm/mmu.rst index 5bfe28b0728e..20d85daed395 100644 --- a/Documentation/virt/kvm/mmu.rst +++ b/Documentation/virt/kvm/mmu.rst @@ -171,8 +171,8 @@ Shadow pages contain the following information: shadow pages) so role.quadrant takes values in the range 0..3. Each quadrant maps 1GB virtual address space. role.access: - Inherited guest access permissions in the form uwx. Note execute - permission is positive, not negative. + Inherited guest access permissions from the parent ptes in the form uwx. + Note execute permission is positive, not negative. role.invalid: The page is invalid and should not be used. It is a root page that is currently pinned (by a cpu hardware register pointing to it); once it is diff --git a/Documentation/vm/arch_pgtable_helpers.rst b/Documentation/vm/arch_pgtable_helpers.rst index f3591ee3aaa8..552567d863b8 100644 --- a/Documentation/vm/arch_pgtable_helpers.rst +++ b/Documentation/vm/arch_pgtable_helpers.rst @@ -50,7 +50,7 @@ PTE Page Table Helpers +---------------------------+--------------------------------------------------+ | pte_mkwrite | Creates a writable PTE | +---------------------------+--------------------------------------------------+ -| pte_mkwrprotect | Creates a write protected PTE | +| pte_wrprotect | Creates a write protected PTE | +---------------------------+--------------------------------------------------+ | pte_mkspecial | Creates a special PTE | +---------------------------+--------------------------------------------------+ @@ -120,7 +120,7 @@ PMD Page Table Helpers +---------------------------+--------------------------------------------------+ | pmd_mkwrite | Creates a writable PMD | +---------------------------+--------------------------------------------------+ -| pmd_mkwrprotect | Creates a write protected PMD | +| pmd_wrprotect | Creates a write protected PMD | +---------------------------+--------------------------------------------------+ | pmd_mkspecial | Creates a special PMD | +---------------------------+--------------------------------------------------+ @@ -186,7 +186,7 @@ PUD Page Table Helpers +---------------------------+--------------------------------------------------+ | pud_mkwrite | Creates a writable PUD | +---------------------------+--------------------------------------------------+ -| pud_mkwrprotect | Creates a write protected PUD | +| pud_wrprotect | Creates a write protected PUD | +---------------------------+--------------------------------------------------+ | pud_mkdevmap | Creates a ZONE_DEVICE mapped PUD | +---------------------------+--------------------------------------------------+ @@ -224,7 +224,7 @@ HugeTLB Page Table Helpers +---------------------------+--------------------------------------------------+ | huge_pte_mkwrite | Creates a writable HugeTLB | +---------------------------+--------------------------------------------------+ -| huge_pte_mkwrprotect | Creates a write protected HugeTLB | +| huge_pte_wrprotect | Creates a write protected HugeTLB | +---------------------------+--------------------------------------------------+ | huge_ptep_get_and_clear | Clears a HugeTLB | +---------------------------+--------------------------------------------------+ diff --git a/Documentation/vm/slub.rst b/Documentation/vm/slub.rst index 03f294a638bd..d3028554b1e9 100644 --- a/Documentation/vm/slub.rst +++ b/Documentation/vm/slub.rst @@ -181,7 +181,7 @@ SLUB Debug output Here is a sample of slub debug output:: ==================================================================== - BUG kmalloc-8: Redzone overwritten + BUG kmalloc-8: Right Redzone overwritten -------------------------------------------------------------------- INFO: 0xc90f6d28-0xc90f6d2b. First byte 0x00 instead of 0xcc @@ -189,10 +189,10 @@ Here is a sample of slub debug output:: INFO: Object 0xc90f6d20 @offset=3360 fp=0xc90f6d58 INFO: Allocated in get_modalias+0x61/0xf5 age=53 cpu=1 pid=554 - Bytes b4 0xc90f6d10: 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ - Object 0xc90f6d20: 31 30 31 39 2e 30 30 35 1019.005 - Redzone 0xc90f6d28: 00 cc cc cc . - Padding 0xc90f6d50: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ + Bytes b4 (0xc90f6d10): 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ + Object (0xc90f6d20): 31 30 31 39 2e 30 30 35 1019.005 + Redzone (0xc90f6d28): 00 cc cc cc . + Padding (0xc90f6d50): 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ [] dump_trace+0x63/0x1eb [] show_trace_log_lvl+0x1a/0x2f diff --git a/MAINTAINERS b/MAINTAINERS index 354831907474..12bf45f55f6a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9631,10 +9631,10 @@ F: virt/kvm/* KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) M: Marc Zyngier R: James Morse -R: Julien Thierry +R: Alexandru Elisei R: Suzuki K Poulose L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -L: kvmarm@lists.cs.columbia.edu +L: kvmarm@lists.cs.columbia.edu (moderated for non-subscribers) S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git F: arch/arm64/include/asm/kvm* diff --git a/Makefile b/Makefile index 348e4bf08afe..bfc8704540df 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 43 +SUBLEVEL = 63 EXTRAVERSION = NAME = Dare mighty things @@ -720,11 +720,12 @@ $(KCONFIG_CONFIG): # This exploits the 'multi-target pattern rule' trick. # The syncconfig should be executed only once to make all the targets. # (Note: use the grouped target '&:' when we bump to GNU Make 4.3) -quiet_cmd_syncconfig = SYNC $@ - cmd_syncconfig = $(MAKE) -f $(srctree)/Makefile syncconfig - +# +# Do not use $(call cmd,...) here. That would suppress prompts from syncconfig, +# so you cannot notice that Kconfig is waiting for the user input. %/config/auto.conf %/config/auto.conf.cmd %/generated/autoconf.h: $(KCONFIG_CONFIG) - +$(call cmd,syncconfig) + $(Q)$(kecho) " SYNC $@" + $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig else # !may-sync-config # External modules and some install targets need include/generated/autoconf.h # and include/config/auto.conf but do not care if they are up-to-date. @@ -1353,17 +1354,12 @@ endif # needs to be updated, so this check is forced on all builds uts_len := 64 -ifneq (,$(BUILD_NUMBER)) - UTS_RELEASE=$(KERNELRELEASE)-ab$(BUILD_NUMBER) -else - UTS_RELEASE=$(KERNELRELEASE) -endif define filechk_utsrelease.h - if [ `echo -n "$(UTS_RELEASE)" | wc -c ` -gt $(uts_len) ]; then \ - echo '"$(UTS_RELEASE)" exceeds $(uts_len) characters' >&2; \ - exit 1; \ - fi; \ - echo \#define UTS_RELEASE \"$(UTS_RELEASE)\" + if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then \ + echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2; \ + exit 1; \ + fi; \ + echo \#define UTS_RELEASE \"$(KERNELRELEASE)\" endef define filechk_version.h diff --git a/OWNERS_core b/OWNERS_core index 6f977647584f..1280e89f5101 100644 --- a/OWNERS_core +++ b/OWNERS_core @@ -1,3 +1,8 @@ +adelva@google.com +gregkh@google.com +maennich@google.com saravanak@google.com +tkjos@google.com willmcvicker@google.com +surenb@google.com elavila@google.com \ No newline at end of file diff --git a/android/OWNERS b/android/OWNERS index ddf3324dacbf..460c6998132c 100644 --- a/android/OWNERS +++ b/android/OWNERS @@ -12,4 +12,5 @@ per-file abi_gki_aarch64_cuttlefish = adelva@google.com, rammuthiah@google.com per-file abi_gki_aarch64_goldfish = rkir@google.com # Pixel specific ABI +per-file abi_gki_aarch64_generic = set noparent per-file abi_gki_aarch64_generic = saravanak@google.com,elavila@google.com,willmcvicker@google.com diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml deleted file mode 100755 index df919dfae0d3..000000000000 --- a/android/abi_gki_aarch64.xml +++ /dev/null @@ -1,135255 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/abi_gki_aarch64_db845c b/android/abi_gki_aarch64_db845c deleted file mode 100644 index 86ef49b9a976..000000000000 --- a/android/abi_gki_aarch64_db845c +++ /dev/null @@ -1,1795 +0,0 @@ -[abi_symbol_list] -# commonly used symbols - add_uevent_var - alloc_io_pgtable_ops - __alloc_skb - alloc_workqueue - __arch_copy_from_user - __arch_copy_to_user - arm64_const_caps_ready - arm64_use_ng_mappings - bcmp - blocking_notifier_call_chain - blocking_notifier_chain_register - blocking_notifier_chain_unregister - bpf_trace_run1 - bpf_trace_run2 - bpf_trace_run3 - bpf_trace_run4 - bpf_trace_run5 - bpf_trace_run6 - bus_register - bus_unregister - cancel_delayed_work - cancel_delayed_work_sync - cancel_work_sync - capable - cdev_device_add - cdev_device_del - cdev_init - __cfi_slowpath - __check_object_size - __class_register - class_unregister - clk_bulk_disable - clk_bulk_enable - clk_bulk_prepare - clk_bulk_unprepare - clk_disable - clk_enable - clk_fixed_rate_ops - clk_get - __clk_get_name - clk_get_rate - clk_hw_get_parent - clk_hw_get_rate - clk_hw_register - clk_hw_unregister - clk_prepare - clk_put - clk_round_rate - clk_set_rate - clk_sync_state - clk_unprepare - complete - complete_all - completion_done - __const_udelay - consume_skb - _copy_from_iter_full - cpu_hwcap_keys - cpu_hwcaps - cpumask_next - cpu_number - __cpu_online_mask - __cpu_possible_mask - crc32_le - _ctype - debugfs_create_dir - debugfs_create_file - debugfs_create_u32 - debugfs_create_x32 - debugfs_remove - default_llseek - delayed_work_timer_fn - del_timer - del_timer_sync - destroy_workqueue - dev_close - dev_coredumpv - dev_driver_string - _dev_err - dev_err_probe - dev_get_regmap - device_find_child - device_for_each_child - device_get_match_data - device_initialize - device_init_wakeup - device_property_present - device_property_read_u32_array - device_register - device_set_wakeup_capable - device_unregister - device_wakeup_enable - _dev_info - __dev_kfree_skb_any - devm_add_action - devm_clk_bulk_get - devm_clk_bulk_get_all - devm_clk_get - devm_clk_get_optional - devm_clk_hw_register - devm_free_irq - devm_gpiod_get - devm_gpiod_get_optional - devm_ioremap - devm_ioremap_resource - devm_ioremap_wc - devm_iounmap - devm_kasprintf - devm_kfree - devm_kmalloc - devm_memremap - devm_of_clk_add_hw_provider - devm_of_icc_get - __devm_of_phy_provider_register - devm_of_platform_populate - devm_phy_create - devm_phy_get - devm_pinctrl_register - devm_platform_ioremap_resource - devm_regmap_add_irq_chip - devm_regmap_field_alloc - __devm_regmap_init - __devm_regmap_init_i2c - __devm_regmap_init_mmio_clk - devm_regulator_bulk_get - devm_regulator_get - devm_regulator_register - devm_request_threaded_irq - __devm_reset_control_get - devm_reset_controller_register - devm_snd_soc_register_component - __devm_spi_alloc_controller - devm_spi_register_controller - devm_watchdog_register_device - _dev_notice - dev_pm_domain_attach_by_name - dev_pm_domain_detach - dev_pm_genpd_set_performance_state - dev_pm_opp_add - dev_pm_opp_find_freq_ceil - dev_pm_opp_find_freq_exact - dev_pm_opp_get_level - dev_pm_opp_get_opp_count - dev_pm_opp_of_add_table - dev_pm_opp_of_find_icc_paths - dev_pm_opp_of_remove_table - dev_pm_opp_put - dev_pm_opp_put_clkname - dev_pm_opp_set_bw - dev_pm_opp_set_clkname - dev_pm_opp_set_rate - dev_set_name - _dev_warn - disable_irq - divider_get_val - divider_recalc_rate - divider_round_rate_parent - dma_alloc_attrs - dma_buf_export - dma_free_attrs - dmam_alloc_attrs - dma_map_page_attrs - dma_map_sg_attrs - dma_mmap_attrs - dma_release_channel - dma_request_chan - dma_set_coherent_mask - dma_set_mask - dma_sync_single_for_cpu - dma_sync_single_for_device - dma_unmap_page_attrs - dma_unmap_sg_attrs - do_SAK - driver_register - driver_unregister - drm_add_edid_modes - drm_atomic_helper_connector_destroy_state - drm_atomic_helper_connector_duplicate_state - drm_atomic_helper_connector_reset - drm_connector_attach_encoder - drm_connector_cleanup - drm_connector_init - drm_connector_update_edid_property - __drm_err - drm_hdmi_avi_infoframe_from_display_mode - drm_helper_probe_single_connector_modes - drm_mode_vrefresh - enable_irq - eth_mac_addr - eth_platform_get_mac_address - ethtool_op_get_link - eth_type_trans - eth_validate_addr - event_triggers_call - find_next_bit - find_next_zero_bit - finish_wait - flush_work - flush_workqueue - free_io_pgtable_ops - free_irq - gcd - generic_handle_irq - generic_mii_ioctl - get_device - get_random_bytes - gic_nonsecure_priorities - gpiochip_add_data_with_key - gpiochip_add_pin_range - gpiochip_generic_free - gpiochip_generic_request - gpiochip_get_data - gpiochip_remove - gpiod_direction_output - gpiod_direction_output_raw - gpiod_set_consumer_name - gpiod_set_raw_value - gpiod_set_value_cansleep - gpio_to_desc - handle_edge_irq - handle_level_irq - handle_nested_irq - handle_sysrq - hdmi_audio_infoframe_init - i2c_adapter_type - i2c_add_adapter - i2c_add_numbered_adapter - i2c_del_adapter - i2c_del_driver - i2c_parse_fw_timings - i2c_register_driver - __i2c_smbus_xfer - i2c_smbus_xfer - i2c_transfer - icc_disable - icc_enable - icc_link_create - icc_node_add - icc_node_create - icc_nodes_remove - icc_provider_add - icc_provider_del - icc_set_bw - icc_sync_state - ida_alloc_range - ida_free - idr_alloc - idr_alloc_cyclic - idr_destroy - idr_find - idr_for_each - idr_get_next - idr_remove - init_net - __init_swait_queue_head - init_timer_key - init_uts_ns - init_wait_entry - __init_waitqueue_head - iomem_resource - iommu_attach_device - iommu_detach_device - iommu_domain_alloc - iommu_domain_free - iommu_present - iommu_unmap - __ioread32_copy - __ioremap - iounmap - __iowrite32_copy - irq_chip_disable_parent - irq_chip_enable_parent - irq_chip_eoi_parent - irq_chip_mask_parent - irq_chip_set_affinity_parent - irq_chip_set_parent_state - irq_chip_set_type_parent - irq_chip_set_vcpu_affinity_parent - irq_chip_set_wake_parent - irq_chip_unmask_parent - __irq_domain_add - irq_domain_free_irqs_common - irq_domain_remove - irq_domain_xlate_twocell - irq_find_mapping - irq_find_matching_fwspec - irq_modify_status - irq_of_parse_and_map - irq_set_chained_handler_and_data - irq_set_chip_and_handler_name - irq_set_chip_data - irq_set_irq_wake - irq_to_desc - is_vmalloc_addr - jiffies - jiffies_to_msecs - jiffies_to_usecs - kasan_flag_enabled - kasprintf - kernel_connect - kernel_getsockname - kernel_recvmsg - kernel_sendmsg - kfree - kfree_const - kfree_sensitive - kfree_skb - __kmalloc - kmalloc_caches - kmalloc_order_trace - kmem_cache_alloc_trace - kmemdup - kstrdup - kstrdup_const - kstrtoint - kstrtouint - ktime_get - ktime_get_mono_fast_ns - ktime_get_real_ts64 - kvfree - kvfree_call_rcu - kvmalloc_node - __list_add_valid - __list_del_entry_valid - __local_bh_enable_ip - __log_post_read_mmio - __log_read_mmio - __log_write_mmio - mbox_client_txdone - mbox_free_channel - mbox_request_channel - mbox_send_message - memcpy - __memcpy_fromio - __memcpy_toio - memmove - memremap - memset - memstart_addr - memunmap - mii_ethtool_gset - mii_nway_restart - misc_deregister - misc_register - mod_delayed_work_on - mod_timer - module_layout - __msecs_to_jiffies - msleep - __mutex_init - mutex_is_locked - mutex_lock - mutex_unlock - napi_complete_done - napi_disable - __napi_schedule - napi_schedule_prep - __netdev_alloc_skb - netdev_err - netdev_info - netdev_warn - netif_carrier_on - netif_napi_add - __netif_napi_del - __nla_parse - nla_put - no_llseek - nr_cpu_ids - nvmem_cell_get - nvmem_cell_put - nvmem_cell_read - of_address_to_resource - of_alias_get_id - of_clk_add_hw_provider - of_clk_del_provider - of_clk_hw_simple_get - of_clk_set_defaults - of_device_get_match_data - of_device_is_compatible - of_device_uevent_modalias - of_dma_configure_id - of_find_device_by_node - of_find_property - of_fwnode_ops - of_genpd_add_provider_onecell - of_genpd_del_provider - of_get_child_by_name - of_get_named_gpio_flags - of_get_next_available_child - of_get_next_child - of_get_property - of_get_regulator_init_data - of_graph_get_remote_node - of_graph_parse_endpoint - of_icc_xlate_onecell - of_iomap - of_irq_find_parent - of_irq_get - of_irq_get_byname - of_match_device - of_match_node - of_node_name_eq - of_parse_phandle - of_parse_phandle_with_args - of_parse_phandle_with_fixed_args - of_phy_simple_xlate - of_platform_depopulate - of_platform_populate - of_property_count_elems_of_size - of_property_read_string - of_property_read_string_helper - of_property_read_u32_index - of_property_read_variable_u32_array - of_property_read_variable_u8_array - of_prop_next_u32 - of_reserved_mem_lookup - param_ops_bool - param_ops_charp - param_ops_int - param_ops_uint - __pci_register_driver - pci_unregister_driver - perf_trace_buf_alloc - perf_trace_run_bpf_submit - phy_exit - phy_init - phy_power_off - phy_power_on - pinconf_generic_dt_node_to_map - pinctrl_dev_get_drvdata - pinctrl_pm_select_default_state - pinctrl_pm_select_sleep_state - pinctrl_utils_free_map - platform_bus_type - platform_device_register_full - platform_device_unregister - __platform_driver_register - platform_driver_unregister - platform_get_irq - platform_get_irq_byname - platform_get_irq_optional - platform_get_resource - platform_get_resource_byname - pm_genpd_add_subdomain - pm_genpd_init - __pm_runtime_disable - pm_runtime_enable - pm_runtime_forbid - pm_runtime_force_resume - pm_runtime_force_suspend - __pm_runtime_idle - __pm_runtime_resume - pm_runtime_set_autosuspend_delay - __pm_runtime_set_status - __pm_runtime_suspend - __pm_runtime_use_autosuspend - preempt_schedule - preempt_schedule_notrace - prepare_to_wait_event - printk - pskb_expand_head - __pskb_pull_tail - put_device - __put_task_struct - qcom_smem_state_register - qcom_smem_state_unregister - queue_delayed_work_on - queue_work_on - radix_tree_delete - radix_tree_insert - radix_tree_lookup - radix_tree_next_chunk - ___ratelimit - rational_best_approximation - _raw_spin_lock - _raw_spin_lock_bh - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_trylock - _raw_spin_unlock - _raw_spin_unlock_bh - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - __rcu_read_lock - __rcu_read_unlock - rdev_get_drvdata - refcount_warn_saturate - regcache_cache_only - regcache_mark_dirty - regcache_sync - register_netdevice_notifier - register_reboot_notifier - __register_rpmsg_driver - regmap_bulk_read - regmap_bulk_write - regmap_field_read - regmap_field_update_bits_base - __regmap_init - regmap_irq_get_virq - regmap_multi_reg_write - regmap_read - regmap_register_patch - regmap_update_bits_base - regmap_write - regulator_bulk_disable - regulator_bulk_enable - regulator_bulk_get - regulator_disable - regulator_enable - regulator_set_load - regulator_set_voltage - release_firmware - __release_region - remap_pfn_range - request_firmware - request_firmware_direct - request_firmware_into_buf - __request_region - request_threaded_irq - reset_control_assert - reset_control_deassert - reset_control_reset - round_jiffies_up - rpmsg_register_device - rpmsg_send - rpmsg_unregister_device - rproc_add - rproc_add_subdev - rproc_alloc - rproc_coredump_set_elf_info - rproc_del - rproc_free - rproc_remove_subdev - rtnl_is_locked - rtnl_lock - rtnl_unlock - schedule - schedule_timeout - scnprintf - seq_lseek - seq_printf - seq_putc - seq_puts - seq_read - sg_alloc_table - sg_free_table - sg_init_table - sg_next - __sg_page_iter_start - simple_read_from_buffer - single_open - single_release - skb_clone - skb_copy - skb_copy_bits - skb_copy_expand - skb_dequeue - skb_pull - skb_push - skb_put - skb_queue_head - skb_queue_purge - skb_queue_tail - skb_trim - snd_pcm_format_width - snd_soc_component_init_regmap - snd_soc_component_read - snd_soc_component_update_bits - snd_soc_component_write - snd_soc_dapm_add_routes - snd_soc_dapm_get_enum_double - snd_soc_dapm_get_volsw - snd_soc_dapm_kcontrol_dapm - snd_soc_dapm_kcontrol_widget - snd_soc_dapm_mixer_update_power - snd_soc_dapm_mux_update_power - snd_soc_dapm_put_enum_double - snd_soc_dapm_put_volsw - snd_soc_get_enum_double - snd_soc_get_volsw - snd_soc_info_enum_double - snd_soc_info_volsw - snd_soc_jack_report - snd_soc_put_enum_double - snd_soc_put_volsw - snprintf - sock_create_kern - sock_release - sort - __spi_alloc_controller - spi_controller_resume - spi_controller_suspend - spi_finalize_current_transfer - spi_register_controller - spi_unregister_controller - sprintf - sscanf - __stack_chk_fail - __stack_chk_guard - strcmp - strcpy - strlcpy - strlen - strncmp - strncpy - strpbrk - strsep - __sw_hweight16 - __sw_hweight32 - __sw_hweight64 - __sw_hweight8 - synchronize_irq - synchronize_net - synchronize_rcu - syscon_node_to_regmap - syscon_regmap_lookup_by_phandle - sysfs_create_link - sysfs_remove_link - sysrq_mask - system_power_efficient_wq - system_wq - tasklet_init - tasklet_kill - __tasklet_schedule - thermal_cooling_device_unregister - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return - __traceiter_rwmmio_post_read - __traceiter_rwmmio_read - __traceiter_rwmmio_write - __tracepoint_rwmmio_post_read - __tracepoint_rwmmio_read - __tracepoint_rwmmio_write - trace_raw_output_prep - trace_seq_printf - tty_flip_buffer_push - __tty_insert_flip_char - uart_add_one_port - uart_get_baud_rate - uart_register_driver - uart_remove_one_port - uart_resume_port - uart_suspend_port - uart_try_toggle_sysrq - uart_unregister_driver - uart_update_timeout - uart_write_wakeup - __udelay - unregister_chrdev_region - unregister_netdevice_notifier - unregister_reboot_notifier - unregister_rpmsg_driver - usb_deregister - usb_disabled - usbnet_disconnect - usbnet_get_endpoints - usbnet_get_msglevel - usbnet_get_stats64 - usbnet_link_change - usbnet_nway_reset - usbnet_open - usbnet_probe - usbnet_read_cmd - usbnet_read_cmd_nopm - usbnet_resume - usbnet_set_msglevel - usbnet_skb_return - usbnet_start_xmit - usbnet_stop - usbnet_suspend - usbnet_tx_timeout - usbnet_update_max_qlen - usbnet_write_cmd - usbnet_write_cmd_async - usbnet_write_cmd_nopm - usb_register_driver - __usecs_to_jiffies - usleep_range - vabits_actual - vfree - vmalloc - vmap - vunmap - wait_for_completion_timeout - __wake_up - __warn_printk - watchdog_init_timeout - -# required by apr.ko - rpmsg_trysend - -# required by arm_smmu.ko - amba_bustype - bus_set_iommu - device_link_add - device_match_fwnode - driver_find_device - generic_device_group - generic_iommu_put_resv_regions - iommu_alloc_resv_region - iommu_device_register - iommu_device_sysfs_add - iommu_device_sysfs_remove - iommu_device_unregister - iommu_dma_get_resv_regions - iommu_fwspec_add_ids - iommu_fwspec_free - iommu_get_dma_cookie - iommu_group_ref_get - iommu_put_dma_cookie - of_dma_is_coherent - pci_bus_type - pci_device_group - -# required by asix.ko - genphy_resume - mdiobus_alloc_size - mdiobus_free - __mdiobus_register - mdiobus_unregister - mii_check_media - mii_link_ok - phy_connect - phy_disconnect - phy_do_ioctl_running - phy_ethtool_get_link_ksettings - phy_ethtool_nway_reset - phy_ethtool_set_link_ksettings - phy_print_status - phy_start - phy_stop - usbnet_change_mtu - usbnet_get_drvinfo - usbnet_get_link - usbnet_get_link_ksettings - usbnet_set_link_ksettings - usbnet_unlink_rx_urbs - -# required by ath10k_core.ko - cpu_latency_qos_add_request - cpu_latency_qos_remove_request - device_get_mac_address - device_set_wakeup_enable - firmware_request_nowarn - guid_gen - init_dummy_netdev - __kfifo_alloc - __kfifo_free - param_ops_ulong - skb_dequeue_tail - skb_realloc_headroom - strlcat - strscpy - thermal_cooling_device_register - vzalloc - -# required by ath10k_pci.ko - pci_clear_master - pci_disable_device - pci_disable_msi - pcie_capability_read_word - pcie_capability_write_word - pci_enable_device - pci_enable_msi - pci_iomap - pci_read_config_dword - pci_release_region - pci_request_region - pci_set_master - pci_write_config_dword - -# required by ath10k_snoc.ko - __bitmap_clear - devm_clk_bulk_get_optional - iommu_map - -# required by ax88179_178a.ko - ethtool_op_get_ts_info - mii_ethtool_get_link_ksettings - mii_ethtool_set_link_ksettings - -# required by bam_dma.ko - dma_async_device_register - dma_async_device_unregister - dma_async_tx_descriptor_init - dma_get_slave_channel - of_dma_controller_free - of_dma_controller_register - pm_runtime_irq_safe - tasklet_setup - vchan_dma_desc_free_list - vchan_find_desc - vchan_init - vchan_tx_desc_free - vchan_tx_submit - -# required by cfg80211.ko - bpf_trace_run10 - bpf_trace_run7 - debugfs_rename - dev_change_net_namespace - __dev_get_by_index - dev_get_by_index - device_add - device_del - device_rename - genlmsg_multicast_allns - genlmsg_put - genl_register_family - genl_unregister_family - get_net_ns_by_fd - get_net_ns_by_pid - inet_csk_get_port - key_create_or_update - key_put - keyring_alloc - ktime_get_coarse_with_offset - memcmp - netif_rx_ni - netlink_broadcast - netlink_register_notifier - netlink_unicast - netlink_unregister_notifier - net_ns_type_operations - nla_find - nla_memcpy - nla_put_64bit - nla_reserve - __nla_validate - __put_net - rb_erase - rb_insert_color - register_pernet_device - request_firmware_nowait - rfkill_alloc - rfkill_blocked - rfkill_destroy - rfkill_pause_polling - rfkill_register - rfkill_resume_polling - rfkill_set_hw_state - rfkill_unregister - skb_add_rx_frag - __sock_create - trace_print_array_seq - unregister_pernet_device - verify_pkcs7_signature - wireless_nlevent_flush - -# required by clk-qcom.ko - __clk_determine_rate - clk_fixed_factor_ops - clk_hw_get_flags - clk_hw_get_name - clk_hw_get_num_parents - clk_hw_get_parent_by_index - clk_hw_is_enabled - clk_hw_round_rate - __clk_is_enabled - __clk_mux_determine_rate_closest - divider_ro_round_rate_parent - of_find_node_opts_by_path - pm_genpd_remove_subdomain - -# required by clk-rpmh.ko - clk_hw_is_prepared - -# required by clk-spmi-pmic-div.ko - __ndelay - of_clk_get_parent_name - -# required by cqhci.ko - devm_blk_ksm_init - dmam_free_coherent - mmc_cqe_request_done - -# required by extcon-usb-gpio.ko - devm_extcon_dev_allocate - devm_extcon_dev_register - extcon_set_state_sync - gpiod_get_value_cansleep - gpiod_set_debounce - gpiod_to_irq - -# required by fastrpc.ko - dma_buf_attach - dma_buf_detach - dma_buf_fd - dma_buf_get - dma_buf_map_attachment - dma_buf_put - dma_buf_unmap_attachment - dma_get_sgtable_attrs - find_vma - wait_for_completion_interruptible - -# required by gpio-regulator.ko - devm_gpiod_get_index - devm_kmemdup - devm_kstrdup - gpiod_count - gpiod_get_optional - -# required by gpio-wcd934x.ko - devm_gpiochip_add_data_with_key - -# required by i2c-designware-core.ko - i2c_generic_scl_recovery - i2c_recover_bus - -# required by i2c-designware-platform.ko - pm_suspend_global_flags - -# required by i2c-dev.ko - bus_register_notifier - bus_unregister_notifier - __class_create - class_destroy - i2c_bus_type - i2c_for_each_dev - i2c_get_adapter - i2c_put_adapter - i2c_transfer_buffer_flags - i2c_verify_client - memdup_user - register_chrdev_region - -# required by i2c-mux-pca954x.ko - device_create_file - device_remove_file - handle_simple_irq - i2c_get_device_id - i2c_smbus_read_byte - i2c_smbus_write_byte - irq_create_mapping_affinity - irq_dispose_mapping - irq_domain_simple_ops - -# required by i2c-mux.ko - __i2c_transfer - rt_mutex_lock - rt_mutex_trylock - rt_mutex_unlock - -# required by i2c-qcom-geni.ko - i2c_get_dma_safe_msg_buf - i2c_put_dma_safe_msg_buf - of_machine_is_compatible - -# required by i2c-rk3x.ko - clk_notifier_register - clk_notifier_unregister - -# required by icc-bcm-voter.ko - list_sort - of_property_match_string - -# required by icc-osm-l3.ko - icc_std_aggregate - -# required by llcc-qcom.ko - devm_platform_ioremap_resource_byname - -# required by lontium-lt9611.ko - drm_bridge_add - drm_bridge_remove - drm_do_get_edid - drm_kms_helper_hotplug_event - mipi_dsi_attach - mipi_dsi_detach - mipi_dsi_device_register_full - mipi_dsi_device_unregister - of_find_mipi_dsi_host_by_node - -# required by mac80211.ko - alloc_netdev_mqs - __alloc_percpu_gfp - arc4_crypt - arc4_setkey - call_rcu - crc32_be - crypto_aead_decrypt - crypto_aead_encrypt - crypto_aead_setauthsize - crypto_aead_setkey - crypto_alloc_aead - crypto_alloc_shash - crypto_alloc_skcipher - crypto_destroy_tfm - __crypto_memneq - crypto_shash_digest - crypto_shash_finup - crypto_shash_setkey - crypto_shash_update - crypto_skcipher_decrypt - crypto_skcipher_encrypt - crypto_skcipher_setkey - __crypto_xor - dev_alloc_name - dev_fetch_sw_netstats - dev_printk - dev_queue_xmit - ether_setup - flush_delayed_work - free_netdev - free_percpu - get_random_u32 - __hw_addr_init - __hw_addr_sync - __hw_addr_unsync - kernel_param_lock - kernel_param_unlock - kfree_skb_list - ktime_get_seconds - ktime_get_with_offset - napi_gro_receive - netdev_set_default_ethtool_ops - netif_carrier_off - netif_receive_skb - netif_receive_skb_list - netif_rx - netif_tx_stop_all_queues - netif_tx_wake_queue - net_ratelimit - __per_cpu_offset - prandom_bytes - prandom_u32 - ___pskb_trim - rcu_barrier - register_inet6addr_notifier - register_inetaddr_notifier - register_netdevice - rhashtable_free_and_destroy - rhashtable_insert_slow - rhltable_init - __rht_bucket_nested - rht_bucket_nested - rht_bucket_nested_insert - round_jiffies - round_jiffies_relative - sg_init_one - skb_checksum_help - skb_clone_sk - skb_complete_wifi_ack - skb_ensure_writable - __skb_get_hash - __skb_gso_segment - system_freezable_wq - unregister_inet6addr_notifier - unregister_inetaddr_notifier - unregister_netdevice_many - unregister_netdevice_queue - -# required by msm.ko - __bitmap_andnot - __bitmap_weight - bpf_trace_run8 - clk_get_parent - __clk_hw_register_divider - clk_hw_register_fixed_factor - __clk_hw_register_mux - clk_hw_unregister_divider - clk_hw_unregister_fixed_factor - clk_hw_unregister_mux - clk_set_parent - clk_unregister - component_add - component_bind_all - component_del - component_master_add_with_match - component_master_del - component_unbind_all - debugfs_create_bool - debugfs_create_u64 - dev_coredumpm - devfreq_recommended_opp - devfreq_resume_device - devfreq_suspend_device - devm_clk_register - devm_devfreq_add_device - devm_regulator_get_exclusive - dev_pm_opp_find_freq_floor - dev_pm_opp_get_freq - dev_pm_opp_get_voltage - dev_pm_opp_set_supported_hw - dma_fence_context_alloc - dma_fence_init - dma_fence_match_context - dma_fence_release - dma_fence_signal - dma_fence_wait_timeout - dma_resv_add_excl_fence - dma_resv_add_shared_fence - dma_resv_reserve_shared - dma_resv_wait_timeout_rcu - drm_add_modes_noedid - drm_atomic_get_private_obj_state - drm_atomic_helper_check - drm_atomic_helper_check_plane_state - drm_atomic_helper_cleanup_planes - drm_atomic_helper_commit - drm_atomic_helper_commit_hw_done - drm_atomic_helper_commit_modeset_disables - drm_atomic_helper_commit_modeset_enables - drm_atomic_helper_commit_planes - __drm_atomic_helper_crtc_destroy_state - drm_atomic_helper_crtc_destroy_state - __drm_atomic_helper_crtc_duplicate_state - drm_atomic_helper_crtc_duplicate_state - __drm_atomic_helper_crtc_reset - drm_atomic_helper_crtc_reset - drm_atomic_helper_dirtyfb - drm_atomic_helper_disable_plane - drm_atomic_helper_page_flip - __drm_atomic_helper_plane_destroy_state - drm_atomic_helper_plane_destroy_state - __drm_atomic_helper_plane_duplicate_state - drm_atomic_helper_plane_duplicate_state - drm_atomic_helper_plane_reset - __drm_atomic_helper_private_obj_duplicate_state - drm_atomic_helper_set_config - drm_atomic_helper_shutdown - drm_atomic_helper_update_plane - drm_atomic_private_obj_fini - drm_atomic_private_obj_init - drm_bridge_attach - drm_compat_ioctl - drm_connector_has_possible_encoder - drm_connector_init_with_ddc - drm_connector_list_iter_begin - drm_connector_list_iter_end - drm_connector_list_iter_next - drm_crtc_cleanup - drm_crtc_enable_color_mgmt - drm_crtc_handle_vblank - drm_crtc_init_with_planes - drm_crtc_send_vblank_event - drm_crtc_set_max_vblank_count - drm_crtc_vblank_get - drm_crtc_vblank_helper_get_vblank_timestamp - drm_crtc_vblank_off - drm_crtc_vblank_on - drm_crtc_vblank_put - __drm_dbg - __drm_debug - drm_debugfs_create_files - drm_detect_hdmi_monitor - drm_detect_monitor_audio - drm_dev_alloc - drm_dev_dbg - drm_dev_printk - drm_dev_put - drm_dev_register - drm_dev_unregister - drm_dp_aux_register - drm_dp_aux_unregister - drm_dp_bw_code_to_link_rate - drm_dp_channel_eq_ok - drm_dp_clock_recovery_ok - drm_dp_dpcd_read - drm_dp_dpcd_read_link_status - drm_dp_dpcd_write - drm_dp_get_adjust_request_pre_emphasis - drm_dp_get_adjust_request_voltage - drm_dp_get_edid_quirks - drm_dp_link_rate_to_bw_code - drm_dp_link_train_channel_eq_delay - drm_dp_link_train_clock_recovery_delay - drm_edid_block_valid - drm_encoder_cleanup - drm_encoder_init - drm_flip_work_cleanup - drm_flip_work_commit - drm_flip_work_init - drm_flip_work_queue - drm_format_info - drm_framebuffer_init - drm_gem_create_mmap_offset - drm_gem_fb_create_handle - drm_gem_fb_destroy - drm_gem_fb_get_obj - drm_gem_fb_prepare_fb - drm_gem_free_mmap_offset - drm_gem_get_pages - drm_gem_handle_create - drm_gem_mmap - drm_gem_mmap_obj - drm_gem_object_free - drm_gem_object_init - drm_gem_object_lookup - drm_gem_object_put_locked - drm_gem_object_release - drm_gem_prime_fd_to_handle - drm_gem_prime_handle_to_fd - drm_gem_private_object_init - drm_gem_put_pages - drm_gem_vm_close - drm_gem_vm_open - drm_get_edid - drm_get_format_info - drm_get_format_name - drm_handle_vblank - drm_helper_hpd_irq_event - drm_helper_mode_fill_fb_struct - drm_ioctl - drm_irq_install - drm_irq_uninstall - drm_kms_helper_poll_fini - drm_kms_helper_poll_init - drm_mm_init - drm_mm_insert_node_in_range - drmm_mode_config_init - drm_mm_print - drm_mm_remove_node - drm_mm_takedown - drm_mode_config_cleanup - drm_mode_config_helper_resume - drm_mode_config_helper_suspend - drm_mode_config_reset - drm_mode_copy - drm_mode_debug_printmodeline - drm_mode_destroy - drm_mode_duplicate - drm_mode_object_find - drm_mode_object_put - drm_mode_probed_add - drm_modeset_lock - drm_modeset_lock_all - drm_modeset_lock_init - drm_modeset_unlock - drm_modeset_unlock_all - drm_object_attach_property - drm_of_component_match_add - drm_open - drm_panel_disable - drm_panel_enable - drm_panel_get_modes - drm_panel_prepare - drm_panel_unprepare - drm_plane_cleanup - drm_plane_create_rotation_property - drm_plane_create_zpos_property - drm_plane_enable_fb_damage_clips - drm_poll - drm_prime_gem_destroy - drm_prime_pages_to_sg - drm_prime_sg_to_page_addr_arrays - drm_printf - __drm_printfn_coredump - __drm_printfn_info - __drm_printfn_seq_file - drm_property_create_range - drm_puts - __drm_puts_coredump - __drm_puts_seq_file - drm_read - drm_rect_calc_hscale - drm_rect_calc_vscale - drm_rect_intersect - drm_release - drm_rotation_simplify - drm_set_preferred_mode - drm_state_dump - drm_syncobj_add_point - drm_syncobj_find - drm_syncobj_find_fence - drm_syncobj_free - drm_syncobj_replace_fence - drm_universal_plane_init - drm_vblank_init - fd_install - fput - generic_file_llseek - get_pid_task - get_unused_fd_flags - gpiod_direction_input - gpiod_get_value - gpiod_set_value - hdmi_audio_infoframe_pack - hdmi_infoframe_pack - hrtimer_init - hrtimer_start_range_ns - icc_put - invalidate_mapping_pages - iommu_map_sg - iommu_set_fault_handler - irq_domain_xlate_onecell - kstrdup_quotable_cmdline - kstrtouint_from_user - kthread_create_on_node - kthread_create_worker - kthread_destroy_worker - kthread_queue_work - llist_add_batch - memdup_user_nul - memparse - mipi_dsi_create_packet - mipi_dsi_host_register - mipi_dsi_host_unregister - mipi_dsi_packet_format_is_long - mutex_lock_interruptible - mutex_trylock_recursive - nsecs_to_jiffies - of_clk_hw_onecell_get - of_device_is_available - of_drm_find_bridge - of_drm_find_panel - of_find_matching_node_and_match - of_get_compatible_child - of_graph_get_endpoint_by_regs - of_graph_get_next_endpoint - of_graph_get_remote_port_parent - of_icc_get - phy_calibrate - phy_configure - pid_task - pm_runtime_get_if_active - put_pid - put_unused_fd - _raw_read_lock - _raw_read_unlock - _raw_write_lock - _raw_write_unlock - register_shrinker - register_vmap_purge_notifier - regulator_get - regulator_put - reservation_ww_class - sched_set_fifo - schedule_timeout_interruptible - __sg_page_iter_dma_next - shmem_truncate_range - simple_attr_open - simple_attr_read - simple_attr_release - simple_attr_write - simple_open - strstr - sync_file_create - sync_file_get_fence - unmap_mapping_range - unregister_shrinker - unregister_vmap_purge_notifier - vmf_insert_mixed - vm_get_page_prot - vscnprintf - vsnprintf - wake_up_process - ww_mutex_lock_interruptible - ww_mutex_unlock - -# required by msm_serial.ko - tty_termios_baud_rate - tty_termios_encode_baud_rate - -# required by ns.ko - kernel_bind - radix_tree_iter_resume - -# required by nvmem_qfprom.ko - devm_nvmem_register - -# required by ohci-hcd.ko - dma_pool_alloc - dma_pool_create - dma_pool_destroy - dma_pool_free - free_pages - gen_pool_dma_alloc_align - gen_pool_dma_zalloc_align - gen_pool_free_owner - get_zeroed_page - sb800_prefetch - schedule_timeout_uninterruptible - usb_amd_dev_put - usb_amd_quirk_pll_disable - usb_amd_quirk_pll_enable - usb_calc_bus_time - usb_debug_root - usb_hcd_check_unlink_urb - usb_hcd_giveback_urb - usb_hc_died - usb_hcd_link_urb_to_ep - usb_hcd_poll_rh_status - usb_hcd_resume_root_hub - usb_hcds_loaded - usb_hcd_unlink_urb_from_ep - usb_root_hub_lost_power - -# required by ohci-pci.ko - pci_dev_put - pci_get_slot - pci_match_id - usb_amd_prefetch_quirk - usb_amd_quirk_pll_check - usb_hcd_pci_pm_ops - usb_hcd_pci_probe - usb_hcd_pci_remove - usb_hcd_pci_shutdown - -# required by ohci-platform.ko - devm_reset_control_array_get - of_clk_get - usb_add_hcd - usb_create_hcd - usb_hcd_platform_shutdown - usb_put_hcd - usb_remove_hcd - -# required by pdr_interface.ko - strnlen - -# required by phy-qcom-qmp.ko - of_clk_get_by_name - __of_reset_control_get - -# required by phy-qcom-qusb2.ko - devm_nvmem_cell_get - -# required by phy-qcom-usb-hs.ko - extcon_get_edev_by_phandle - extcon_get_state - extcon_register_notifier - extcon_unregister_notifier - -# required by pinctrl-msm.ko - device_property_read_u16_array - gpiochip_line_is_valid - gpiochip_lock_as_irq - gpiochip_unlock_as_irq - handle_bad_irq - handle_fasteoi_ack_irq - handle_fasteoi_irq - irq_get_irq_data - module_put - pinctrl_force_default - pinctrl_force_sleep - pm_power_off - register_restart_handler - try_module_get - unregister_restart_handler - -# required by pinctrl-spmi-gpio.ko - gpiochip_populate_parent_fwspec_fourcell - irq_chip_ack_parent - -# required by pinctrl-spmi-mpp.ko - platform_irq_count - -# required by pm8941-pwrkey.ko - devm_input_allocate_device - input_event - input_register_device - input_set_capability - -# required by q6asm-dai.ko - snd_dma_alloc_pages - snd_dma_free_pages - snd_pcm_hw_constraint_integer - snd_pcm_hw_constraint_list - snd_pcm_hw_constraint_minmax - snd_pcm_hw_constraint_step - snd_pcm_period_elapsed - snd_soc_new_compress - snd_soc_set_runtime_hwparams - -# required by qcom-apcs-ipc-mailbox.ko - devm_mbox_controller_register - -# required by qcom-cpufreq-hw.ko - cpufreq_cpu_get_raw - cpufreq_freq_attr_scaling_available_freqs - cpufreq_freq_attr_scaling_boost_freqs - cpufreq_generic_frequency_table_verify - cpufreq_get_driver_data - cpufreq_register_driver - cpufreq_unregister_driver - dev_pm_opp_adjust_voltage - dev_pm_opp_disable - dev_pm_opp_enable - dev_pm_opp_of_cpumask_remove_table - dev_pm_opp_of_register_em - dev_pm_opp_remove_all_dynamic - dev_pm_opp_set_sharing_cpus - get_cpu_device - of_get_cpu_node - -# required by qcom-geni-se.ko - icc_set_tag - -# required by qcom-pdc.ko - irq_chip_get_parent_state - irq_chip_retrigger_hierarchy - irq_domain_alloc_irqs_parent - irq_domain_create_hierarchy - irq_domain_set_hwirq_and_chip - irq_domain_update_bus_token - -# required by qcom-rpmh-regulator.ko - regulator_list_voltage_linear_range - -# required by qcom-scm.ko - __arm_smccc_smc - __cpu_present_mask - kimage_voffset - -# required by qcom-spmi-pmic.ko - __spmi_driver_register - -# required by qcom_aoss.ko - devm_thermal_of_cooling_device_register - pm_genpd_remove - -# required by qcom_common.ko - rproc_coredump_add_segment - srcu_init_notifier_head - srcu_notifier_call_chain - srcu_notifier_chain_register - srcu_notifier_chain_unregister - -# required by qcom_geni_serial.ko - dev_pm_clear_wake_irq - dev_pm_set_dedicated_wake_irq - oops_in_progress - tty_insert_flip_string_fixed_flag - uart_console_device - uart_console_write - uart_parse_options - uart_set_options - -# required by qcom_glink.ko - device_add_groups - -# required by qcom_hwspinlock.ko - devm_hwspin_lock_register - -# required by qcom_pil_info.ko - __memset_io - of_find_compatible_node - -# required by qcom_q6v5.ko - qcom_smem_state_get - qcom_smem_state_update_bits - rproc_report_crash - -# required by qcom_q6v5_mss.ko - rproc_coredump_add_custom_segment - -# required by qcom_q6v5_wcss.ko - rproc_elf_get_boot_addr - -# required by qcom_rpmh.ko - bitmap_find_next_zero_area_off - __bitmap_set - cpu_pm_register_notifier - __num_online_cpus - -# required by qcom_spmi-regulator.ko - regulator_disable_regmap - regulator_enable_regmap - regulator_is_enabled_regmap - smp_call_function_single - -# required by qcom_sysmon.ko - rproc_get_by_child - try_wait_for_completion - -# required by qcom_tsens.ko - debugfs_lookup - devm_thermal_zone_of_sensor_register - thermal_zone_device_update - thermal_zone_get_slope - -# required by qrtr-tun.ko - _copy_to_iter - -# required by qrtr.ko - autoremove_wake_function - datagram_poll - do_wait_intr_irq - idr_alloc_u32 - lock_sock_nested - proto_register - proto_unregister - radix_tree_iter_delete - _raw_write_lock_bh - _raw_write_unlock_bh - refcount_dec_and_mutex_lock - release_sock - sk_alloc - skb_copy_datagram_iter - skb_free_datagram - __skb_pad - skb_recv_datagram - skb_set_owner_w - sk_free - sock_alloc_send_skb - sock_gettstamp - sock_init_data - sock_no_accept - sock_no_listen - sock_no_mmap - sock_no_sendpage - sock_no_shutdown - sock_no_socketpair - sock_queue_rcv_skb - sock_register - sock_unregister - -# required by reboot-mode.ko - devres_add - devres_alloc_node - devres_free - devres_release - -# required by regmap-spmi.ko - spmi_ext_register_read - spmi_ext_register_readl - spmi_ext_register_write - spmi_ext_register_writel - spmi_register_read - spmi_register_write - spmi_register_zero_write - -# required by rmtfs_mem.ko - alloc_chrdev_region - -# required by rtc-pm8xxx.ko - devm_request_any_context_irq - devm_rtc_allocate_device - __rtc_register_device - rtc_time64_to_tm - rtc_tm_to_time64 - rtc_update_irq - -# required by sdhci-msm.ko - mmc_of_parse - mmc_regulator_get_supply - mmc_regulator_set_ocr - mmc_regulator_set_vqmmc - mmc_send_tuning - regulator_is_supported_voltage - __sdhci_add_host - sdhci_add_host - sdhci_cleanup_host - sdhci_cqe_disable - sdhci_cqe_enable - sdhci_cqe_irq - sdhci_enable_clk - sdhci_get_property - sdhci_pltfm_free - sdhci_pltfm_init - sdhci_remove_host - sdhci_reset - sdhci_set_bus_width - sdhci_set_power_noreg - sdhci_setup_host - -# required by slim-qcom-ngd-ctrl.ko - platform_device_add - platform_device_alloc - -# required by smem.ko - hwspin_lock_free - hwspin_lock_request_specific - __hwspin_lock_timeout - __hwspin_unlock - of_hwspin_lock_get_id - -# required by snd-soc-hdmi-codec.ko - snd_ctl_add - snd_ctl_new1 - snd_pcm_add_chmap_ctls - snd_pcm_create_iec958_consumer_hw_params - snd_pcm_hw_constraint_eld - -# required by snd-soc-qcom-common.ko - snd_soc_dai_link_set_capabilities - snd_soc_of_get_dai_link_codecs - snd_soc_of_get_dai_name - snd_soc_of_parse_audio_routing - snd_soc_of_parse_aux_devs - snd_soc_of_parse_card_name - -# required by snd-soc-rt5663.ko - regcache_cache_bypass - snd_soc_add_component_controls - snd_soc_dapm_disable_pin - snd_soc_dapm_force_enable_pin - snd_soc_dapm_new_controls - snd_soc_dapm_sync - -# required by snd-soc-sdm845.ko - devm_snd_soc_register_card - snd_jack_set_key - snd_soc_card_jack_new - snd_soc_component_set_jack - snd_soc_dai_get_channel_map - snd_soc_dai_set_channel_map - snd_soc_dai_set_fmt - snd_soc_dai_set_sysclk - snd_soc_dai_set_tdm_slot - -# required by snd-soc-wcd9335.ko - kmemdup_nul - snd_soc_get_volsw_sx - snd_soc_info_volsw_sx - snd_soc_put_volsw_sx - strnstr - -# required by snd-soc-wcd934x.ko - kstrndup - of_clk_add_provider - of_clk_src_simple_get - -# required by socinfo.ko - add_device_randomness - soc_device_register - soc_device_unregister - -# required by soundwire-bus.ko - device_get_named_child_node - devm_device_add_group - devm_device_add_groups - dev_pm_domain_attach - fwnode_property_present - fwnode_property_read_u32_array - pm_generic_runtime_resume - pm_generic_runtime_suspend - -# required by spi-pl022.ko - amba_driver_register - amba_driver_unregister - amba_release_regions - amba_request_regions - devm_gpio_request - __dma_request_channel - loops_per_jiffy - pinctrl_pm_select_idle_state - spi_delay_exec - spi_finalize_current_message - spi_get_next_queued_message - -# required by spmi-pmic-arb.ko - irq_domain_set_info - spmi_controller_add - spmi_controller_alloc - spmi_controller_remove - -# required by system_heap.ko - deferred_free - dmabuf_page_pool_alloc - dmabuf_page_pool_create - dmabuf_page_pool_destroy - dmabuf_page_pool_free - dma_heap_add - dma_heap_get_dev - dma_heap_get_name - dma_sync_sg_for_cpu - dma_sync_sg_for_device - __free_pages - __sg_page_iter_next - -# required by ufs_qcom.ko - phy_set_mode_ext - ufshcd_dme_get_attr - ufshcd_dme_set_attr - ufshcd_dump_regs - ufshcd_get_local_unipro_ver - ufshcd_get_pwr_dev_param - ufshcd_pltfrm_init - ufshcd_pltfrm_resume - ufshcd_pltfrm_runtime_idle - ufshcd_pltfrm_runtime_resume - ufshcd_pltfrm_runtime_suspend - ufshcd_pltfrm_shutdown - ufshcd_pltfrm_suspend - ufshcd_remove - ufshcd_uic_hibern8_enter - ufshcd_uic_hibern8_exit - -# required by ulpi.ko - of_device_modalias - of_device_request_module - __request_module - -# required by wcd934x.ko - mfd_add_devices - mfd_remove_devices diff --git a/android/abi_gki_aarch64_exynos b/android/abi_gki_aarch64_exynos deleted file mode 100644 index 721a73fc9370..000000000000 --- a/android/abi_gki_aarch64_exynos +++ /dev/null @@ -1,2284 +0,0 @@ -[abi_symbol_list] - activate_task - add_cpu - add_timer - add_timer_on - add_uevent_var - add_wait_queue - adjust_managed_page_count - alarm_cancel - alarm_init - alarm_start - alarm_start_relative - alloc_anon_inode - alloc_chrdev_region - __alloc_disk_node - alloc_etherdev_mqs - alloc_netdev_mqs - __alloc_pages_nodemask - __alloc_percpu - __alloc_skb - alloc_workqueue - amba_driver_register - amba_driver_unregister - android_debug_symbol - android_rvh_probe_register - anon_inode_getfd - anon_inode_getfile - __arch_clear_user - __arch_copy_from_user - __arch_copy_in_user - __arch_copy_to_user - argv_free - argv_split - arm64_const_caps_ready - arm64_use_ng_mappings - __arm_smccc_hvc - __arm_smccc_smc - atomic_notifier_call_chain - atomic_notifier_chain_register - atomic_notifier_chain_unregister - autoremove_wake_function - available_idle_cpu - backlight_device_register - backlight_device_unregister - bcmp - bdget_disk - bdput - bio_endio - __bitmap_andnot - __bitmap_clear - __bitmap_complement - __bitmap_or - bitmap_parse - bitmap_parselist - bitmap_print_to_pagebuf - __bitmap_set - bitmap_to_arr32 - __bitmap_weight - __bitmap_xor - blk_alloc_queue - blk_cleanup_queue - blkdev_get_by_path - blkdev_put - blk_ksm_init - blk_queue_flag_clear - blk_queue_flag_set - blk_queue_io_min - blk_queue_io_opt - blk_queue_logical_block_size - blk_queue_max_discard_sectors - blk_queue_max_write_zeroes_sectors - blk_queue_physical_block_size - blocking_notifier_call_chain - blocking_notifier_chain_register - blocking_notifier_chain_unregister - bpf_trace_run1 - bpf_trace_run10 - bpf_trace_run12 - bpf_trace_run2 - bpf_trace_run3 - bpf_trace_run4 - bpf_trace_run5 - bpf_trace_run6 - bpf_trace_run7 - bpf_trace_run8 - bpf_trace_run9 - build_skb - bus_find_device - bus_for_each_dev - bus_register - bus_register_notifier - bus_set_iommu - bus_unregister - bus_unregister_notifier - cache_line_size - call_rcu - cancel_delayed_work - cancel_delayed_work_sync - cancel_work_sync - capable - cdev_add - cdev_alloc - cdev_del - cdev_device_add - cdev_device_del - cdev_init - __cfi_slowpath - cgroup_taskset_first - cgroup_taskset_next - __check_object_size - check_preempt_curr - __class_create - class_create_file_ns - class_destroy - class_find_device - __class_register - class_unregister - clear_page - __ClearPageMovable - clk_disable - clk_enable - clk_get - __clk_get_hw - __clk_get_name - clk_get_rate - clk_hw_get_name - clk_hw_get_parent - clk_hw_get_rate - __clk_hw_register_divider - __clk_hw_register_gate - __clk_hw_register_mux - clk_hw_unregister_divider - clk_hw_unregister_gate - clk_hw_unregister_mux - __clk_is_enabled - clk_prepare - clk_put - clk_register - clk_register_clkdev - clk_register_fixed_factor - clk_register_fixed_rate - clk_register_gate - clk_set_parent - clk_set_rate - clk_unprepare - clockevents_config_and_register - __clocksource_register_scale - __close_fd - cma_alloc - cma_release - compat_alloc_user_space - complete - complete_all - complete_and_exit - completion_done - component_add - component_bind_all - component_del - component_master_add_with_match - component_master_del - component_match_add_release - component_unbind_all - config_ep_by_speed - config_group_init_type_name - console_lock - console_printk - console_stop - console_suspend_enabled - console_trylock - console_unlock - __const_udelay - consume_skb - contig_page_data - __cpu_active_mask - cpu_all_bits - cpu_bit_bitmap - cpufreq_add_update_util_hook - cpufreq_cpu_get - cpufreq_cpu_get_raw - cpufreq_cpu_put - cpufreq_disable_fast_switch - cpufreq_driver_fast_switch - cpufreq_driver_resolve_freq - __cpufreq_driver_target - cpufreq_enable_fast_switch - cpufreq_freq_transition_begin - cpufreq_freq_transition_end - cpufreq_frequency_table_get_index - cpufreq_frequency_table_verify - cpufreq_generic_attr - cpufreq_get_policy - cpufreq_quick_get - cpufreq_quick_get_max - cpufreq_register_driver - cpufreq_register_governor - cpufreq_register_notifier - cpufreq_remove_update_util_hook - cpufreq_table_index_unsorted - cpufreq_this_cpu_can_update - cpufreq_unregister_notifier - __cpuhp_remove_state - __cpuhp_setup_state - __cpuhp_setup_state_cpuslocked - __cpuhp_state_add_instance - __cpuhp_state_remove_instance - cpuhp_tasks_frozen - cpu_hwcap_keys - cpu_hwcaps - cpuidle_get_cpu_driver - cpumask_next - cpumask_next_and - cpu_number - __cpu_online_mask - cpu_pm_register_notifier - __cpu_possible_mask - cpu_scale - cpus_read_lock - cpus_read_unlock - cpu_subsys - cpu_topology - crc32_le - crypto_alloc_base - crypto_alloc_shash - crypto_comp_compress - crypto_comp_decompress - crypto_destroy_tfm - crypto_has_alg - __crypto_memneq - crypto_register_alg - crypto_register_scomp - crypto_shash_digest - crypto_shash_final - crypto_shash_update - crypto_unregister_alg - crypto_unregister_scomp - csum_partial - csum_tcpudp_nofold - _ctype - dapm_pinctrl_event - dapm_regulator_event - deactivate_task - debugfs_create_bool - debugfs_create_dir - debugfs_create_file - debugfs_create_symlink - debugfs_create_u32 - debugfs_create_x32 - debugfs_create_x64 - debugfs_remove - debugfs_rename - dec_zone_page_state - default_llseek - default_wake_function - deferred_free - delayed_work_timer_fn - del_gendisk - del_timer - del_timer_sync - destroy_workqueue - dev_alloc_name - dev_change_net_namespace - dev_close - _dev_crit - dev_driver_string - _dev_emerg - _dev_err - dev_err_probe - devfreq_add_device - devfreq_add_governor - devfreq_get_devfreq_by_phandle - devfreq_monitor_resume - devfreq_monitor_start - devfreq_monitor_stop - devfreq_monitor_suspend - devfreq_recommended_opp - devfreq_register_opp_notifier - devfreq_remove_device - devfreq_remove_governor - devfreq_resume_device - devfreq_suspend_device - devfreq_unregister_opp_notifier - devfreq_update_interval - __dev_get_by_index - dev_get_by_index - dev_get_by_name - dev_get_regmap - device_add - device_add_disk - device_create - device_create_bin_file - device_create_file - device_del - device_destroy - device_for_each_child - device_get_dma_attr - device_initialize - device_init_wakeup - device_link_add - device_link_del - device_property_present - device_property_read_string_array - device_property_read_u32_array - device_register - device_remove_file - device_rename - device_set_wakeup_capable - device_set_wakeup_enable - device_show_bool - device_show_int - device_store_bool - device_store_int - device_unregister - device_wakeup_enable - _dev_info - __dev_kfree_skb_any - devm_add_action - devm_backlight_device_register - devm_backlight_device_unregister - devm_clk_get - devm_clk_get_optional - devm_clk_put - devm_devfreq_register_notifier - devm_devfreq_unregister_notifier - __devm_drm_dev_alloc - devm_drm_panel_bridge_add_typed - devm_extcon_dev_allocate - devm_extcon_dev_register - devm_free_irq - devm_gen_pool_create - devm_gpiochip_add_data_with_key - devm_gpiod_get - devm_gpiod_get_optional - devm_gpio_request - devm_gpio_request_one - devm_hwrng_register - devm_i2c_new_dummy_device - devm_iio_device_alloc - __devm_iio_device_register - devm_input_allocate_device - devm_ioremap - devm_ioremap_resource - devm_iounmap - __devm_irq_alloc_descs - devm_kasprintf - devm_kfree - devm_kmalloc - devm_kmemdup - devm_krealloc - devm_kstrdup - devm_kstrdup_const - devm_led_classdev_register_ext - devm_mfd_add_devices - __devm_of_phy_provider_register - devm_phy_create - devm_phy_get - devm_phy_put - devm_pinctrl_get - devm_pinctrl_put - devm_pinctrl_register - devm_platform_get_and_ioremap_resource - devm_platform_ioremap_resource - devm_platform_ioremap_resource_byname - __devm_regmap_init - __devm_regmap_init_i2c - __devm_regmap_init_mmio_clk - devm_regulator_bulk_get - devm_regulator_get - devm_regulator_get_optional - devm_regulator_register - __devm_release_region - __devm_request_region - devm_request_threaded_irq - __devm_reset_control_get - devm_rtc_allocate_device - devm_rtc_device_register - devm_snd_dmaengine_pcm_register - devm_snd_soc_register_card - devm_snd_soc_register_component - devm_thermal_zone_of_sensor_register - devm_usb_get_phy_by_phandle - _dev_notice - dev_pm_opp_add - dev_pm_opp_disable - dev_pm_opp_find_freq_ceil - dev_pm_opp_find_freq_exact - dev_pm_opp_find_freq_floor - dev_pm_opp_get_freq - dev_pm_opp_get_opp_count - dev_pm_opp_get_voltage - dev_pm_opp_of_add_table - dev_pm_opp_of_register_em - dev_pm_opp_of_remove_table - dev_pm_opp_put - dev_pm_opp_put_regulators - dev_pm_opp_set_regulators - dev_pm_qos_add_request - dev_pm_qos_read_value - dev_pm_qos_remove_request - dev_pm_qos_update_request - dev_printk - dev_queue_xmit - devres_add - devres_alloc_node - devres_free - devres_release - dev_set_name - dev_vprintk_emit - _dev_warn - disable_irq - disable_irq_nosync - disable_percpu_irq - disk_end_io_acct - disk_start_io_acct - dma_alloc_attrs - dma_async_device_register - dma_async_device_unregister - dma_async_tx_descriptor_init - dma_buf_attach - dma_buf_begin_cpu_access - dma_buf_begin_cpu_access_partial - dma_buf_detach - dma_buf_dynamic_attach - dma_buf_end_cpu_access - dma_buf_end_cpu_access_partial - dma_buf_export - dma_buf_fd - dma_buf_get - dma_buf_map_attachment - dma_buf_mmap - dma_buf_move_notify - dmabuf_page_pool_alloc - dmabuf_page_pool_create - dmabuf_page_pool_destroy - dmabuf_page_pool_free - dma_buf_pin - dma_buf_put - dma_buf_unmap_attachment - dma_buf_unpin - dma_buf_vmap - dma_buf_vunmap - dmaengine_unmap_put - dma_fence_add_callback - dma_fence_array_create - dma_fence_context_alloc - dma_fence_default_wait - dma_fence_get_status - dma_fence_get_stub - dma_fence_init - dma_fence_release - dma_fence_remove_callback - dma_fence_signal - dma_fence_wait_any_timeout - dma_fence_wait_timeout - dma_free_attrs - dma_get_required_mask - dma_get_slave_caps - dma_get_slave_channel - dma_heap_add - dma_heap_buffer_alloc - dma_heap_buffer_free - dma_heap_find - dma_heap_get_dev - dma_heap_get_drvdata - dma_heap_get_name - dma_heap_put - dmam_alloc_attrs - dma_map_page_attrs - dma_map_resource - dma_map_sg_attrs - dmam_free_coherent - dma_mmap_attrs - dma_pool_alloc - dma_pool_free - dma_release_channel - dma_request_chan - dma_resv_add_excl_fence - dma_resv_add_shared_fence - dma_resv_get_fences_rcu - dma_resv_reserve_shared - dma_resv_test_signaled_rcu - dma_resv_wait_timeout_rcu - dma_set_coherent_mask - dma_set_mask - dma_sync_sg_for_cpu - dma_sync_sg_for_device - dma_sync_single_for_cpu - dma_sync_single_for_device - dma_unmap_page_attrs - dma_unmap_resource - dma_unmap_sg_attrs - do_SAK - do_wait_intr - down - downgrade_write - down_interruptible - down_read - down_read_killable - down_read_trylock - down_trylock - down_write - d_path - drain_workqueue - driver_register - driver_unregister - drm_add_edid_modes - drm_atomic_add_affected_connectors - drm_atomic_add_affected_planes - drm_atomic_commit - drm_atomic_get_crtc_state - drm_atomic_get_plane_state - drm_atomic_get_private_obj_state - drm_atomic_helper_check_modeset - drm_atomic_helper_check_planes - drm_atomic_helper_check_plane_state - drm_atomic_helper_cleanup_planes - drm_atomic_helper_commit_cleanup_done - drm_atomic_helper_commit_duplicated_state - drm_atomic_helper_commit_hw_done - drm_atomic_helper_commit_modeset_disables - drm_atomic_helper_commit_modeset_enables - drm_atomic_helper_commit_planes - drm_atomic_helper_commit_tail - __drm_atomic_helper_connector_destroy_state - drm_atomic_helper_connector_destroy_state - __drm_atomic_helper_connector_duplicate_state - drm_atomic_helper_connector_duplicate_state - drm_atomic_helper_connector_reset - __drm_atomic_helper_crtc_destroy_state - __drm_atomic_helper_crtc_duplicate_state - drm_atomic_helper_disable_plane - drm_atomic_helper_disable_planes_on_crtc - drm_atomic_helper_duplicate_state - drm_atomic_helper_fake_vblank - drm_atomic_helper_page_flip - __drm_atomic_helper_plane_destroy_state - __drm_atomic_helper_plane_duplicate_state - drm_atomic_helper_prepare_planes - __drm_atomic_helper_private_obj_duplicate_state - drm_atomic_helper_set_config - drm_atomic_helper_setup_commit - drm_atomic_helper_swap_state - drm_atomic_helper_update_plane - drm_atomic_helper_wait_for_dependencies - drm_atomic_helper_wait_for_fences - drm_atomic_normalize_zpos - drm_atomic_private_obj_fini - drm_atomic_private_obj_init - drm_atomic_set_crtc_for_plane - drm_atomic_set_fb_for_plane - drm_atomic_set_mode_for_crtc - drm_atomic_state_alloc - __drm_atomic_state_free - drm_bridge_add - drm_bridge_attach - drm_bridge_chain_mode_set - drm_bridge_remove - drm_compat_ioctl - drm_connector_attach_dp_subconnector_property - drm_connector_attach_encoder - drm_connector_cleanup - drm_connector_init - drm_connector_init_with_ddc - drm_connector_list_iter_begin - drm_connector_list_iter_end - drm_connector_list_iter_next - drm_connector_register - drm_connector_unregister - drm_connector_update_edid_property - drm_crtc_arm_vblank_event - drm_crtc_cleanup - drm_crtc_enable_color_mgmt - drm_crtc_handle_vblank - drm_crtc_helper_set_config - drm_crtc_helper_set_mode - drm_crtc_init - drm_crtc_init_with_planes - drm_crtc_send_vblank_event - drm_crtc_vblank_count - drm_crtc_vblank_get - drm_crtc_vblank_helper_get_vblank_timestamp - drm_crtc_vblank_off - drm_crtc_vblank_on - drm_crtc_vblank_put - drm_cvt_mode - __drm_dbg - __drm_debug - drm_debugfs_create_files - drm_detect_hdmi_monitor - drm_dev_alloc - drm_dev_dbg - drm_dev_printk - drm_dev_put - drm_dev_register - drm_dev_unregister - drm_display_mode_to_videomode - drm_dp_aux_init - drm_dp_aux_register - drm_dp_aux_unregister - drm_dp_bw_code_to_link_rate - drm_dp_channel_eq_ok - drm_dp_clock_recovery_ok - drm_dp_dpcd_read - drm_dp_dpcd_read_link_status - drm_dp_dpcd_write - drm_dp_get_adjust_request_pre_emphasis - drm_dp_get_adjust_request_voltage - drm_dp_link_rate_to_bw_code - drm_dp_link_train_channel_eq_delay - drm_dp_link_train_clock_recovery_delay - drm_dp_set_subconnector_property - drm_edid_header_is_valid - drm_edid_is_valid - drm_edid_to_sad - drm_edid_to_speaker_allocation - drm_encoder_cleanup - drm_encoder_init - __drm_err - drm_format_info - drm_framebuffer_cleanup - drm_framebuffer_init - drm_framebuffer_unregister_private - drm_gem_create_mmap_offset - drm_gem_dmabuf_mmap - drm_gem_dmabuf_release - drm_gem_dmabuf_vmap - drm_gem_dmabuf_vunmap - drm_gem_fb_create_handle - drm_gem_fb_destroy - drm_gem_handle_create - drm_gem_mmap - drm_gem_object_free - drm_gem_object_lookup - drm_gem_object_release - drm_gem_prime_export - drm_gem_prime_fd_to_handle - drm_gem_prime_handle_to_fd - drm_gem_prime_import_dev - drm_gem_private_object_init - drm_gem_vm_close - drm_gem_vm_open - drm_get_edid - drm_get_format_info - drm_get_format_name - drm_handle_vblank - drm_hdmi_avi_infoframe_from_display_mode - drm_hdmi_infoframe_set_hdr_metadata - drm_helper_connector_dpms - drm_helper_disable_unused_functions - drm_helper_force_disable_all - drm_helper_hpd_irq_event - drm_helper_mode_fill_fb_struct - drm_helper_probe_single_connector_modes - drm_helper_resume_force_mode - drm_ioctl - drm_irq_install - drm_irq_uninstall - drm_is_current_master - drm_kms_helper_hotplug_event - drm_kms_helper_is_poll_worker - drm_kms_helper_poll_disable - drm_kms_helper_poll_enable - drm_kms_helper_poll_fini - drm_kms_helper_poll_init - drm_mm_init - drm_mm_insert_node_in_range - drmm_mode_config_init - drm_mm_print - drm_mm_remove_node - drm_mm_takedown - drm_mode_config_cleanup - drm_mode_config_reset - drm_mode_convert_to_umode - drm_mode_copy - drm_mode_create_scaling_mode_property - drm_mode_crtc_set_gamma_size - drm_mode_duplicate - drm_mode_equal - drm_mode_match - drm_mode_probed_add - drm_modeset_acquire_fini - drm_modeset_acquire_init - drm_modeset_backoff - drm_mode_set_crtcinfo - drm_modeset_drop_locks - drm_modeset_lock - drm_modeset_lock_all - drm_modeset_lock_all_ctx - drm_mode_set_name - drm_modeset_unlock - drm_modeset_unlock_all - drm_mode_vrefresh - drm_need_swiotlb - drm_object_attach_property - drm_open - drm_panel_add - drm_panel_disable - drm_panel_enable - drm_panel_get_modes - drm_panel_init - drm_panel_prepare - drm_panel_remove - drm_panel_unprepare - drm_plane_cleanup - drm_plane_create_alpha_property - drm_plane_create_blend_mode_property - drm_plane_create_rotation_property - drm_plane_create_zpos_property - drm_poll - drm_prime_gem_destroy - drm_prime_pages_to_sg - drm_prime_sg_to_page_addr_arrays - drm_printf - __drm_printfn_info - __drm_printfn_seq_file - drm_property_blob_get - drm_property_blob_put - drm_property_create - drm_property_create_bitmask - drm_property_create_blob - drm_property_create_bool - drm_property_create_enum - drm_property_create_range - drm_property_create_signed_range - drm_property_lookup_blob - drm_property_replace_blob - __drm_puts_seq_file - drm_read - drm_rect_clip_scaled - drm_rect_intersect - drm_release - drm_rotation_simplify - drm_syncobj_add_point - drm_syncobj_create - drm_syncobj_find - drm_syncobj_find_fence - drm_syncobj_free - drm_syncobj_get_fd - drm_syncobj_get_handle - drm_syncobj_replace_fence - drm_universal_plane_init - drm_vblank_init - drm_vma_node_allow - drm_vma_node_is_allowed - drm_vma_node_revoke - drm_writeback_connector_init - drm_writeback_queue_job - drm_writeback_signal_completion - dump_backtrace - dump_stack - dw_handle_msi_irq - dw_pcie_host_init - dw_pcie_msi_init - dw_pcie_own_conf_map_bus - dw_pcie_read - dw_pcie_setup_rc - dw_pcie_write - emergency_restart - enable_irq - enable_percpu_irq - end_buffer_read_sync - ether_setup - eth_type_trans - event_triggers_call - extcon_get_state - extcon_set_state_sync - failure_tracking - fb_mode_option - __fdget - fd_install - find_get_pid - find_last_bit - find_next_bit - find_next_zero_bit - find_vma - find_vpid - finish_wait - firmware_request_nowarn - flush_dcache_page - flush_delayed_work - flush_work - flush_workqueue - fput - frame_vector_to_pages - free_irq - free_netdev - __free_pages - free_pages - free_percpu - free_percpu_irq - freezing_slow_path - freq_qos_add_request - freq_qos_remove_request - freq_qos_update_request - freq_scale - fsync_bdev - gcd - generic_file_llseek - generic_handle_irq - genlmsg_multicast_allns - genlmsg_put - genl_register_family - genl_unregister_family - gen_pool_add_owner - gen_pool_alloc_algo_owner - gen_pool_avail - gen_pool_create - gen_pool_destroy - gen_pool_first_fit_align - gen_pool_free_owner - gen_pool_has_addr - gen_pool_size - __getblk_gfp - get_cpu_device - get_cpu_idle_time - get_device - __get_free_pages - get_net_ns_by_fd - get_net_ns_by_pid - get_random_bytes - get_random_u32 - __get_task_comm - get_task_exe_file - get_task_mm - get_thermal_instance - get_unused_fd_flags - get_user_pages - get_user_pages_fast - get_user_pages_remote - __get_vm_area_caller - get_zeroed_page - gic_nonsecure_priorities - gpiochip_add_data_with_key - gpiochip_add_pin_range - gpiochip_generic_free - gpiochip_generic_request - gpiochip_get_data - gpiochip_lock_as_irq - gpiochip_remove - gpiochip_unlock_as_irq - gpiod_direction_input - gpiod_direction_output - gpiod_direction_output_raw - gpiod_get_raw_value - gpiod_get_raw_value_cansleep - gpiod_set_raw_value - gpiod_set_raw_value_cansleep - gpiod_set_value - gpiod_set_value_cansleep - gpiod_to_irq - gpio_free - gpio_request - gpio_request_one - gpio_to_desc - gserial_alloc_line - gserial_connect - gserial_disconnect - handle_edge_irq - handle_level_irq - handle_nested_irq - handle_simple_irq - handle_sysrq - hdmi_avi_infoframe_pack - hdmi_drm_infoframe_pack_only - hex_dump_to_buffer - hmm_range_fault - housekeeping_cpumask - hrtimer_active - hrtimer_cancel - hrtimer_forward - hrtimer_init - hrtimer_start_range_ns - i2c_adapter_type - i2c_add_adapter - i2c_add_numbered_adapter - i2c_bit_add_bus - i2c_bus_type - i2c_clients_command - i2c_del_adapter - i2c_del_driver - i2c_for_each_dev - i2c_get_adapter - i2c_new_client_device - i2c_new_dummy_device - i2c_put_adapter - i2c_register_driver - i2c_smbus_read_byte_data - i2c_smbus_read_i2c_block_data - i2c_smbus_read_word_data - i2c_smbus_write_byte_data - i2c_smbus_write_i2c_block_data - i2c_smbus_write_word_data - i2c_smbus_xfer - __i2c_transfer - i2c_transfer - i2c_transfer_buffer_flags - i2c_unregister_device - i2c_verify_client - i3c_generic_ibi_alloc_pool - i3c_generic_ibi_free_pool - i3c_generic_ibi_get_free_slot - i3c_generic_ibi_recycle_slot - i3c_master_add_i3c_dev_locked - i3c_master_defslvs_locked - i3c_master_disec_locked - i3c_master_do_daa - i3c_master_enec_locked - i3c_master_entdaa_locked - i3c_master_get_free_addr - i3c_master_queue_ibi - i3c_master_register - i3c_master_set_info - i3c_master_unregister - ida_alloc_range - ida_destroy - ida_free - idr_alloc - idr_destroy - idr_find - idr_for_each - idr_get_next - idr_remove - idr_replace - ignore_console_lock_warning - iio_channel_get - iio_channel_release - iio_device_alloc - iio_device_free - __iio_device_register - iio_device_unregister - iio_read_channel_processed - inc_zone_page_state - inet_csk_get_port - init_dummy_netdev - init_net - init_pseudo - __init_rwsem - __init_swait_queue_head - init_task - init_timer_key - init_uts_ns - init_wait_entry - __init_waitqueue_head - input_allocate_device - input_close_device - input_event - input_free_device - input_mt_destroy_slots - input_mt_init_slots - input_mt_report_slot_state - input_open_device - input_register_device - input_register_handle - input_register_handler - input_set_abs_params - input_set_capability - input_unregister_device - input_unregister_handle - int_sqrt - iomem_resource - iommu_alloc_resv_region - iommu_attach_group - iommu_device_register - iommu_device_sysfs_add - iommu_device_sysfs_remove - iommu_device_unlink - iommu_device_unregister - iommu_dma_reserve_iova - iommu_domain_alloc - iommu_fwspec_add_ids - iommu_fwspec_free - iommu_get_dma_cookie - iommu_get_domain_for_dev - iommu_group_alloc - iommu_group_for_each_dev - iommu_group_get - iommu_group_get_iommudata - iommu_group_set_iommudata - iommu_group_set_name - iommu_iova_to_phys - iommu_map - iommu_map_sg - iommu_put_dma_cookie - iommu_register_device_fault_handler - iommu_report_device_fault - iommu_unmap - iommu_unregister_device_fault_handler - __ioread32_copy - __ioremap - iounmap - __iowrite32_copy - ip_send_check - iput - __irq_alloc_descs - irq_create_mapping_affinity - __irq_domain_add - irq_domain_get_irq_data - irq_domain_remove - irq_domain_set_info - irq_domain_xlate_onetwocell - irq_domain_xlate_twocell - irq_find_mapping - irq_get_irqchip_state - irq_get_irq_data - irq_modify_status - irq_of_parse_and_map - irq_set_affinity_hint - irq_set_chained_handler_and_data - irq_set_chip - irq_set_chip_and_handler_name - irq_set_chip_data - __irq_set_handler - irq_set_handler_data - irq_set_irqchip_state - irq_set_irq_wake - irq_to_desc - irq_work_queue - irq_work_sync - is_console_locked - is_dma_buf_file - is_vmalloc_addr - iterate_fd - jiffies - jiffies_64_to_clock_t - jiffies64_to_msecs - jiffies_to_msecs - jiffies_to_usecs - kasan_flag_enabled - kasprintf - kernel_kobj - kern_mount - kern_unmount - key_create_or_update - key_put - keyring_alloc - __kfifo_alloc - __kfifo_free - __kfifo_in - __kfifo_init - __kfifo_out - __kfifo_to_user - kfree - kfree_const - kfree_sensitive - kfree_skb - kfree_skb_list - kill_anon_super - kimage_voffset - __kmalloc - kmalloc_caches - kmalloc_order_trace - kmem_cache_alloc - kmem_cache_alloc_trace - kmem_cache_create - kmem_cache_destroy - kmem_cache_free - kmemdup - kobject_add - kobject_create_and_add - kobject_get - kobject_init - kobject_init_and_add - kobject_put - kobject_uevent - kobject_uevent_env - krealloc - kstat - kstrdup - kstrndup - kstrtobool - kstrtobool_from_user - kstrtoint - kstrtoint_from_user - kstrtol_from_user - kstrtoll - kstrtou16 - kstrtou8 - kstrtouint - kstrtouint_from_user - kstrtoull - kstrtoull_from_user - ksys_sync_helper - kthread_bind - kthread_cancel_delayed_work_sync - kthread_cancel_work_sync - kthread_create_on_node - kthread_delayed_work_timer_fn - kthread_flush_work - kthread_flush_worker - __kthread_init_worker - kthread_mod_delayed_work - kthread_park - kthread_parkme - kthread_queue_work - kthread_should_park - kthread_should_stop - kthread_stop - kthread_unpark - kthread_worker_fn - ktime_get - ktime_get_coarse_with_offset - ktime_get_mono_fast_ns - ktime_get_raw - ktime_get_raw_ts64 - ktime_get_real_seconds - ktime_get_real_ts64 - ktime_get_ts64 - ktime_get_with_offset - kvasprintf - kvfree - kvfree_call_rcu - kvmalloc_node - __list_add_valid - __list_del_entry_valid - list_sort - llist_add_batch - __local_bh_enable_ip - __lock_buffer - __lock_page - __log_post_read_mmio - __log_read_mmio - __log_write_mmio - loops_per_jiffy - lzo1x_1_compress - lzo1x_decompress_safe - lzorle1x_1_compress - map_kernel_range - media_device_register_entity - media_entity_pads_init - memchr - memcmp - memcpy - __memcpy_fromio - __memcpy_toio - memdup_user - memmove - memparse - memremap - memset - memset64 - __memset_io - memstart_addr - memunmap - mfd_add_devices - mfd_remove_devices - mipi_dsi_attach - mipi_dsi_compression_mode - mipi_dsi_dcs_read - mipi_dsi_dcs_set_column_address - mipi_dsi_dcs_set_display_brightness - mipi_dsi_dcs_set_page_address - mipi_dsi_dcs_write_buffer - mipi_dsi_detach - mipi_dsi_device_register_full - mipi_dsi_driver_register_full - mipi_dsi_driver_unregister - mipi_dsi_host_register - mipi_dsi_host_unregister - mipi_dsi_picture_parameter_set - misc_deregister - misc_register - mmc_add_host - mmc_alloc_host - mmc_can_gpio_cd - mmc_detect_change - mmc_free_host - mmc_gpio_get_cd - mmc_gpio_get_ro - mmc_of_parse - mmc_regulator_get_supply - mmc_regulator_set_ocr - mmc_regulator_set_vqmmc - mmc_remove_host - mmc_request_done - mmc_wait_for_req - __mmdrop - mmput - mmu_interval_notifier_insert - mmu_interval_notifier_remove - mmu_interval_read_begin - mmu_notifier_synchronize - mod_delayed_work_on - mod_node_page_state - mod_timer - module_layout - module_put - __msecs_to_jiffies - msleep - msleep_interruptible - __mutex_init - mutex_is_locked - mutex_lock - mutex_lock_interruptible - mutex_trylock - mutex_unlock - names_cachep - __napi_alloc_skb - napi_complete_done - napi_disable - napi_gro_flush - napi_gro_receive - __napi_schedule - napi_schedule_prep - __netdev_alloc_skb - netdev_err - netif_carrier_off - netif_carrier_on - netif_napi_add - __netif_napi_del - netif_receive_skb - netif_rx - netif_rx_ni - netif_tx_stop_all_queues - netif_tx_wake_queue - netlink_broadcast - __netlink_kernel_create - netlink_kernel_release - netlink_register_notifier - netlink_unicast - netlink_unregister_notifier - net_ns_type_operations - net_ratelimit - nla_append - nla_find - nla_memcpy - __nla_parse - nla_put - nla_put_64bit - nla_put_nohdr - nla_reserve - __nla_validate - __nlmsg_put - no_llseek - nonseekable_open - noop_llseek - nr_cpu_ids - nr_irqs - nsecs_to_jiffies - ns_to_kernel_old_timeval - ns_to_timespec64 - __num_online_cpus - of_address_to_resource - of_alias_get_highest_id - of_alias_get_id - of_clk_add_hw_provider - of_clk_add_provider - of_clk_del_provider - of_clk_get - of_clk_get_by_name - of_clk_hw_onecell_get - of_clk_src_onecell_get - of_count_phandle_with_args - of_cpu_node_to_id - of_device_get_match_data - of_device_is_available - of_device_is_compatible - of_dma_controller_free - of_dma_controller_register - of_drm_find_bridge - of_drm_find_panel - of_find_compatible_node - of_find_device_by_node - of_find_matching_node_and_match - of_find_node_by_name - of_find_node_by_type - of_find_node_opts_by_path - of_find_node_with_property - of_find_property - of_fwnode_ops - of_genpd_add_provider_simple - of_get_child_by_name - of_get_cpu_node - of_get_dma_window - of_get_named_gpio_flags - of_get_next_available_child - of_get_next_child - of_get_property - of_get_regulator_init_data - of_get_videomode - of_i2c_get_board_info - of_iomap - of_irq_get_byname - of_irq_parse_one - of_machine_is_compatible - of_match_device - of_match_node - of_n_addr_cells - of_node_name_eq - of_n_size_cells - of_parse_phandle - of_parse_phandle_with_args - of_parse_phandle_with_fixed_args - of_phandle_iterator_init - of_phandle_iterator_next - of_platform_populate - of_property_count_elems_of_size - of_property_match_string - of_property_read_string - of_property_read_string_helper - of_property_read_u32_index - of_property_read_u64 - of_property_read_variable_u16_array - of_property_read_variable_u32_array - of_property_read_variable_u8_array - of_prop_next_string - of_prop_next_u32 - of_pwm_xlate_with_flags - of_reserved_mem_device_init_by_idx - of_reserved_mem_device_release - of_reserved_mem_lookup - of_root - of_thermal_get_ntrips - of_usb_host_tpl_support - oops_in_progress - orderly_poweroff - page_endio - page_mapping - __page_pinner_migration_failed - panic - panic_notifier_list - param_array_ops - param_ops_bool - param_ops_byte - param_ops_charp - param_ops_hexint - param_ops_int - param_ops_long - param_ops_string - param_ops_uint - param_ops_ullong - param_ops_ulong - param_set_uint - pci_alloc_irq_vectors_affinity - pci_assign_resource - pci_assign_unassigned_bus_resources - pci_bus_resource_n - pci_bus_type - pci_clear_master - pci_disable_device - pcie_bandwidth_available - pcie_get_mps - pcie_get_speed_cap - pci_enable_atomic_ops_to_root - pci_enable_device - pci_enable_pcie_error_reporting - pci_enable_wake - pci_find_bus - pci_find_capability - pci_find_ext_capability - pci_free_irq_vectors - pci_generic_config_read - pci_generic_config_write - pci_get_device - pci_get_domain_bus_and_slot - pci_iomap - pci_irq_vector - pci_load_and_free_saved_state - pci_load_saved_state - pci_map_rom - pci_msix_vec_count - pci_read_config_dword - pci_read_config_word - __pci_register_driver - pci_release_resource - pci_rescan_bus - pci_resize_resource - pci_restore_state - pci_save_state - pci_set_master - pci_set_power_state - pci_store_saved_state - pci_unmap_rom - pci_unregister_driver - pci_write_config_dword - pci_write_config_word - PDE_DATA - __per_cpu_offset - perf_event_update_userpage - perf_pmu_register - perf_pmu_unregister - perf_trace_buf_alloc - perf_trace_run_bpf_submit - pfn_valid - phy_configure - phy_init - phy_power_off - phy_power_on - phy_reset - pid_task - pinconf_generic_dt_node_to_map - pinctrl_add_gpio_range - pinctrl_dev_get_drvdata - pinctrl_force_sleep - pinctrl_get - pinctrl_lookup_state - pinctrl_pm_select_default_state - pinctrl_pm_select_sleep_state - pinctrl_put - pinctrl_remove_gpio_range - pinctrl_select_state - pinctrl_utils_free_map - pin_get_name - pin_user_pages - pin_user_pages_remote - platform_bus_type - platform_device_add - platform_device_add_properties - platform_device_add_resources - platform_device_alloc - platform_device_del - platform_device_put - platform_device_register - platform_device_register_full - platform_device_unregister - __platform_driver_probe - __platform_driver_register - platform_driver_unregister - platform_find_device_by_driver - platform_get_irq - platform_get_irq_byname - platform_get_resource - platform_get_resource_byname - __platform_register_drivers - pm_genpd_add_subdomain - pm_genpd_init - pm_power_off - __pm_relax - pm_relax - pm_runtime_allow - pm_runtime_autosuspend_expiration - pm_runtime_barrier - __pm_runtime_disable - pm_runtime_enable - pm_runtime_forbid - pm_runtime_force_resume - pm_runtime_force_suspend - pm_runtime_get_if_active - __pm_runtime_idle - pm_runtime_irq_safe - pm_runtime_no_callbacks - __pm_runtime_resume - pm_runtime_set_autosuspend_delay - __pm_runtime_set_status - __pm_runtime_suspend - __pm_runtime_use_autosuspend - __pm_stay_awake - pm_stay_awake - pm_wakeup_dev_event - pm_wakeup_ws_event - power_supply_changed - power_supply_get_by_name - power_supply_get_drvdata - power_supply_get_property - power_supply_is_system_supplied - power_supply_put - power_supply_register - power_supply_set_property - power_supply_unregister - prandom_u32 - preempt_schedule - preempt_schedule_notrace - prepare_to_wait_event - print_hex_dump - printk - __printk_ratelimit - printk_timed_ratelimit - proc_create - proc_create_data - proc_create_seq_private - proc_mkdir - proc_remove - proc_set_size - proc_set_user - proc_symlink - __pskb_copy_fclone - __pskb_pull_tail - put_device - put_disk - __put_net - __put_page - put_pid - __put_task_struct - put_unused_fd - pwmchip_add - pwmchip_remove - pwm_get_chip_data - pwm_set_chip_data - queue_delayed_work_on - queue_work_on - radix_tree_tagged - ___ratelimit - raw_notifier_call_chain - raw_notifier_chain_register - raw_notifier_chain_unregister - _raw_read_lock - _raw_read_lock_bh - _raw_read_lock_irqsave - _raw_read_unlock - _raw_read_unlock_bh - _raw_read_unlock_irqrestore - _raw_spin_lock - _raw_spin_lock_bh - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_trylock - _raw_spin_unlock - _raw_spin_unlock_bh - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - _raw_write_lock - _raw_write_lock_bh - _raw_write_lock_irqsave - _raw_write_trylock - _raw_write_unlock - _raw_write_unlock_bh - _raw_write_unlock_irqrestore - rb_erase - __rb_erase_color - rb_first - rb_first_postorder - __rb_insert_augmented - rb_insert_color - rb_next - rb_next_postorder - rb_prev - rb_replace_node - rcu_barrier - __rcu_read_lock - __rcu_read_unlock - rdev_get_drvdata - rdev_get_id - reciprocal_value - refcount_warn_saturate - refresh_frequency_limits - __refrigerator - regcache_cache_bypass - regcache_cache_only - regcache_drop_region - regcache_mark_dirty - regcache_sync - register_blkdev - __register_chrdev - register_chrdev_region - register_console - register_die_notifier - register_inet6addr_notifier - register_inetaddr_notifier - register_netdev - register_netdevice - register_netdevice_notifier - register_oom_notifier - register_pernet_device - register_pm_notifier - register_reboot_notifier - register_restart_handler - register_shrinker - register_syscore_ops - regmap_async_complete - regmap_bulk_read - regmap_bulk_write - regmap_multi_reg_write - regmap_multi_reg_write_bypassed - regmap_raw_read - regmap_raw_write - regmap_raw_write_async - regmap_read - regmap_register_patch - regmap_update_bits_base - regmap_write - regulator_bulk_disable - regulator_bulk_enable - regulator_disable - regulator_enable - regulator_force_disable - regulator_get - regulator_get_optional - regulator_get_voltage - regulator_is_enabled - regulator_list_voltage_linear - regulator_map_voltage_linear - regulator_put - regulator_set_mode - regulator_set_voltage - release_firmware - release_pages - __release_region - remap_pfn_range - remap_vmalloc_range - remove_cpu - remove_proc_entry - remove_wait_queue - request_firmware - request_firmware_direct - request_firmware_into_buf - request_firmware_nowait - __request_module - __request_percpu_irq - __request_region - request_threaded_irq - reset_control_assert - reset_control_deassert - return_address - revalidate_disk_size - rfkill_alloc - rfkill_blocked - rfkill_destroy - rfkill_pause_polling - rfkill_register - rfkill_resume_polling - rfkill_set_hw_state - rfkill_unregister - rps_needed - rtc_class_close - rtc_class_open - rtc_read_time - __rtc_register_device - rtc_set_time - rtc_time64_to_tm - rtc_tm_to_time64 - rtc_update_irq - rtc_valid_tm - rtnl_is_locked - rtnl_lock - rtnl_unlock - runqueues - sched_clock - sched_set_fifo_low - sched_set_normal - sched_setscheduler - sched_setscheduler_nocheck - schedule - schedule_timeout - schedule_timeout_interruptible - scnprintf - scsi_block_when_processing_errors - scsi_eh_ready_devs - __scsi_execute - scsi_print_sense_hdr - sdev_prefix_printk - sdio_signal_irq - seq_lseek - seq_open - seq_printf - seq_putc - seq_puts - seq_read - seq_release - seq_write - set_cpus_allowed_ptr - set_normalized_timespec64 - set_page_dirty_lock - __SetPageMovable - set_task_cpu - sg_alloc_table - sg_alloc_table_from_pages - sg_copy_to_buffer - sg_free_table - sg_init_one - sg_init_table - sg_miter_next - sg_miter_start - sg_miter_stop - sg_nents_for_len - sg_next - __sg_page_iter_next - __sg_page_iter_start - si_meminfo - simple_attr_open - simple_attr_read - simple_attr_release - simple_attr_write - simple_open - simple_read_from_buffer - simple_strtol - simple_strtoul - simple_write_to_buffer - single_open - single_open_size - single_release - skb_add_rx_frag - skb_clone - skb_copy - skb_copy_bits - skb_copy_expand - skb_dequeue - skb_dequeue_tail - skb_pull - skb_push - skb_put - skb_queue_head - skb_queue_purge - skb_queue_tail - skb_realloc_headroom - skb_trim - smp_call_function - smp_call_function_many - smp_call_function_single - smp_call_on_cpu - snd_compr_stop_error - snd_ctl_add - snd_ctl_boolean_mono_info - snd_ctl_new1 - snd_ctl_notify - snd_device_free - snd_dma_alloc_pages - snd_dmaengine_pcm_prepare_slave_config - snd_dma_free_pages - snd_hwdep_new - snd_pcm_format_physical_width - snd_pcm_format_width - snd_pcm_hw_constraint_integer - snd_pcm_hw_constraint_list - snd_pcm_hw_constraint_mask64 - snd_pcm_lib_free_pages - snd_pcm_lib_ioctl - snd_pcm_lib_malloc_pages - snd_pcm_lib_preallocate_free_for_all - snd_pcm_lib_preallocate_pages - snd_pcm_period_elapsed - snd_pcm_rate_range_to_bits - snd_soc_add_component_controls - snd_soc_bytes_info_ext - snd_soc_bytes_tlv_callback - snd_soc_card_get_kcontrol - snd_soc_component_async_complete - snd_soc_component_disable_pin - snd_soc_component_force_enable_pin - snd_soc_component_init_regmap - snd_soc_component_read - snd_soc_component_set_pll - snd_soc_component_set_sysclk - snd_soc_component_update_bits - snd_soc_component_update_bits_async - snd_soc_component_write - snd_soc_dai_set_bclk_ratio - snd_soc_dai_set_channel_map - snd_soc_dai_set_sysclk - snd_soc_dai_set_tdm_slot - snd_soc_dapm_add_routes - snd_soc_dapm_disable_pin - snd_soc_dapm_enable_pin - snd_soc_dapm_get_enum_double - snd_soc_dapm_get_pin_status - snd_soc_dapm_get_pin_switch - snd_soc_dapm_get_volsw - snd_soc_dapm_ignore_suspend - snd_soc_dapm_info_pin_switch - snd_soc_dapm_kcontrol_dapm - snd_soc_dapm_new_control - snd_soc_dapm_new_controls - snd_soc_dapm_put_enum_double - snd_soc_dapm_put_pin_switch - snd_soc_dapm_put_volsw - snd_soc_dapm_sync - snd_soc_dapm_weak_routes - snd_soc_find_dai - snd_soc_get_enum_double - snd_soc_get_pcm_runtime - snd_soc_get_volsw - snd_soc_get_volsw_range - snd_soc_get_xr_sx - snd_soc_info_enum_double - snd_soc_info_volsw - snd_soc_info_volsw_range - snd_soc_info_volsw_sx - snd_soc_info_xr_sx - snd_soc_new_compress - snd_soc_of_get_dai_link_codecs - snd_soc_of_get_dai_name - snd_soc_of_parse_audio_routing - snd_soc_of_parse_daifmt - snd_soc_of_put_dai_link_codecs - snd_soc_params_to_bclk - snd_soc_pm_ops - snd_soc_put_enum_double - snd_soc_put_volsw - snd_soc_put_volsw_range - snd_soc_put_xr_sx - snd_soc_register_card - snd_soc_register_component - snd_soc_set_runtime_hwparams - snd_soc_tplg_component_load - snd_soc_tplg_component_remove - snd_soc_tplg_widget_bind_event - snd_soc_unregister_card - snd_soc_unregister_component - snd_vendor_set_ops - snprintf - soc_device_register - __sock_create - sock_release - softnet_data - sort - __spi_alloc_controller - spi_bus_type - spi_controller_resume - spi_controller_suspend - spi_finalize_current_message - spi_register_controller - __spi_register_driver - spi_setup - spi_sync - spi_unregister_controller - split_page - sprintf - sprint_symbol - srcu_init_notifier_head - srcu_notifier_call_chain - srcu_notifier_chain_register - srcu_notifier_chain_unregister - sscanf - __stack_chk_fail - __stack_chk_guard - static_key_slow_dec - static_key_slow_inc - stop_one_cpu_nowait - stpcpy - strcasecmp - strcat - strchr - strcmp - strcpy - strcspn - stream_open - strim - strlcat - strlcpy - strlen - strncasecmp - strncat - strnchr - strncmp - strncpy - strnlen - strnstr - strpbrk - strrchr - strscpy - strsep - strspn - strstr - submit_bh - subsys_system_register - __sw_hweight16 - __sw_hweight32 - __sw_hweight64 - __sw_hweight8 - swiotlb_nr_tbl - __sync_dirty_buffer - sync_file_create - sync_file_get_fence - synchronize_irq - synchronize_net - synchronize_rcu - syscon_regmap_lookup_by_phandle - sysfs_add_file_to_group - sysfs_create_bin_file - sysfs_create_file_ns - sysfs_create_files - sysfs_create_group - sysfs_create_groups - sysfs_create_link - sysfs_emit - __sysfs_match_string - sysfs_merge_group - sysfs_notify - sysfs_remove_bin_file - sysfs_remove_file_from_group - sysfs_remove_file_ns - sysfs_remove_files - sysfs_remove_group - sysfs_remove_link - sysfs_streq - sysrq_mask - system_freezable_wq - system_freezing_cnt - system_highpri_wq - system_power_efficient_wq - system_state - system_unbound_wq - system_wq - sys_tz - __tasklet_hi_schedule - tasklet_init - tasklet_kill - __tasklet_schedule - task_rq_lock - thermal_cooling_device_unregister - thermal_of_cooling_device_register - thermal_zone_device_disable - thermal_zone_device_enable - thermal_zone_device_is_enabled - thermal_zone_device_update - thermal_zone_get_temp - thermal_zone_get_zone_by_name - thermal_zone_of_sensor_register - thermal_zone_of_sensor_unregister - time64_to_tm - topology_set_thermal_pressure - _totalram_pages - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return - __traceiter_android_rvh_can_migrate_task - __traceiter_android_rvh_cpu_cgroup_can_attach - __traceiter_android_rvh_dequeue_task - __traceiter_android_rvh_enqueue_task - __traceiter_android_rvh_find_lowest_rq - __traceiter_android_rvh_find_new_ilb - __traceiter_android_rvh_gic_v3_set_affinity - __traceiter_android_rvh_post_init_entity_util_avg - __traceiter_android_rvh_replace_next_task_fair - __traceiter_android_rvh_sched_fork_init - __traceiter_android_rvh_sched_newidle_balance - __traceiter_android_rvh_sched_nohz_balancer_kick - __traceiter_android_rvh_sched_rebalance_domains - __traceiter_android_rvh_select_fallback_rq - __traceiter_android_rvh_select_task_rq_fair - __traceiter_android_rvh_select_task_rq_rt - __traceiter_android_vh_cpu_idle_enter - __traceiter_android_vh_cpu_idle_exit - __traceiter_android_vh_ipi_stop - __traceiter_android_vh_scheduler_tick - __traceiter_android_vh_show_mem - __traceiter_android_vh_ufs_compl_command - __traceiter_android_vh_ufs_prepare_command - __traceiter_cpu_idle - __traceiter_device_pm_callback_end - __traceiter_device_pm_callback_start - __traceiter_dwc3_ep_queue - __traceiter_gpu_mem_total - __traceiter_hrtimer_expire_entry - __traceiter_hrtimer_expire_exit - __traceiter_ipi_entry - __traceiter_ipi_exit - __traceiter_ipi_raise - __traceiter_irq_handler_entry - __traceiter_irq_handler_exit - __traceiter_pelt_cfs_tp - __traceiter_pelt_dl_tp - __traceiter_pelt_irq_tp - __traceiter_pelt_rt_tp - __traceiter_pelt_se_tp - __traceiter_rwmmio_post_read - __traceiter_rwmmio_read - __traceiter_rwmmio_write - __traceiter_sched_overutilized_tp - __traceiter_sched_switch - __traceiter_suspend_resume - __traceiter_workqueue_execute_end - __traceiter_workqueue_execute_start - trace_output_call - __tracepoint_android_rvh_can_migrate_task - __tracepoint_android_rvh_cpu_cgroup_can_attach - __tracepoint_android_rvh_dequeue_task - __tracepoint_android_rvh_enqueue_task - __tracepoint_android_rvh_find_lowest_rq - __tracepoint_android_rvh_find_new_ilb - __tracepoint_android_rvh_gic_v3_set_affinity - __tracepoint_android_rvh_post_init_entity_util_avg - __tracepoint_android_rvh_replace_next_task_fair - __tracepoint_android_rvh_sched_fork_init - __tracepoint_android_rvh_sched_newidle_balance - __tracepoint_android_rvh_sched_nohz_balancer_kick - __tracepoint_android_rvh_sched_rebalance_domains - __tracepoint_android_rvh_select_fallback_rq - __tracepoint_android_rvh_select_task_rq_fair - __tracepoint_android_rvh_select_task_rq_rt - __tracepoint_android_vh_cpu_idle_enter - __tracepoint_android_vh_cpu_idle_exit - __tracepoint_android_vh_ipi_stop - __tracepoint_android_vh_scheduler_tick - __tracepoint_android_vh_show_mem - __tracepoint_android_vh_ufs_compl_command - __tracepoint_android_vh_ufs_prepare_command - __tracepoint_cpu_idle - __tracepoint_device_pm_callback_end - __tracepoint_device_pm_callback_start - __tracepoint_dwc3_ep_queue - __tracepoint_gpu_mem_total - __tracepoint_hrtimer_expire_entry - __tracepoint_hrtimer_expire_exit - __tracepoint_ipi_entry - __tracepoint_ipi_exit - __tracepoint_ipi_raise - __tracepoint_irq_handler_entry - __tracepoint_irq_handler_exit - __tracepoint_pelt_cfs_tp - __tracepoint_pelt_dl_tp - __tracepoint_pelt_irq_tp - __tracepoint_pelt_rt_tp - __tracepoint_pelt_se_tp - tracepoint_probe_register - tracepoint_probe_unregister - __tracepoint_rwmmio_post_read - __tracepoint_rwmmio_read - __tracepoint_rwmmio_write - __tracepoint_sched_overutilized_tp - __tracepoint_sched_switch - __tracepoint_suspend_resume - __tracepoint_workqueue_execute_end - __tracepoint_workqueue_execute_start - trace_print_array_seq - trace_print_flags_seq - trace_print_symbols_seq - trace_raw_output_prep - trace_seq_printf - try_module_get - ttm_bo_bulk_move_lru_tail - ttm_bo_device_init - ttm_bo_device_release - ttm_bo_dma_acc_size - ttm_bo_eviction_valuable - ttm_bo_evict_mm - ttm_bo_glob - ttm_bo_init_reserved - ttm_bo_kmap - ttm_bo_kunmap - ttm_bo_lock_delayed_workqueue - ttm_bo_mem_space - ttm_bo_mmap - ttm_bo_mmap_obj - ttm_bo_move_accel_cleanup - ttm_bo_move_memcpy - ttm_bo_move_to_lru_tail - ttm_bo_move_ttm - ttm_bo_put - ttm_bo_unlock_delayed_workqueue - ttm_bo_validate - ttm_dma_page_alloc_debugfs - ttm_dma_populate - ttm_dma_tt_fini - ttm_dma_unpopulate - ttm_eu_backoff_reservation - ttm_eu_fence_buffer_objects - ttm_eu_reserve_buffers - ttm_page_alloc_debugfs - ttm_populate_and_map_pages - ttm_range_man_fini - ttm_range_man_init - ttm_resource_free - ttm_resource_manager_force_list_clean - ttm_resource_manager_init - ttm_sg_tt_init - ttm_tt_destroy_common - ttm_tt_populate - ttm_tt_set_placement_caching - ttm_unmap_and_unpopulate_pages - tty_flip_buffer_push - tty_insert_flip_string_fixed_flag - tty_kref_put - tty_port_tty_get - typec_get_drvdata - typec_register_partner - typec_register_port - typec_set_data_role - typec_set_pwr_opmode - typec_set_pwr_role - typec_unregister_partner - typec_unregister_port - uart_add_one_port - uart_console_write - uart_get_baud_rate - uart_parse_options - uart_register_driver - uart_remove_one_port - uart_resume_port - uart_set_options - uart_suspend_port - uart_try_toggle_sysrq - uart_unregister_driver - uart_update_timeout - uart_write_wakeup - uclamp_eff_value - __udelay - ufshcd_auto_hibern8_update - ufshcd_dme_get_attr - ufshcd_hold - ufshcd_pltfrm_init - ufshcd_query_flag_retry - ufshcd_release - ufshcd_remove - ufshcd_shutdown - ufshcd_system_resume - ufshcd_system_suspend - unlock_page - unmap_mapping_range - unpin_user_page - unregister_blkdev - __unregister_chrdev - unregister_chrdev_region - unregister_inet6addr_notifier - unregister_inetaddr_notifier - unregister_netdev - unregister_netdevice_notifier - unregister_netdevice_queue - unregister_oom_notifier - unregister_pernet_device - unregister_pm_notifier - unregister_reboot_notifier - unregister_shrinker - up - update_devfreq - up_read - up_write - usb_add_function - usb_add_hcd - usb_choose_configuration - usb_copy_descriptors - __usb_create_hcd - usb_disabled - usb_enable_autosuspend - usb_ep_alloc_request - usb_ep_autoconfig - usb_ep_free_request - usb_ep_queue - usb_function_register - usb_function_unregister - usb_gadget_set_state - usb_hcd_is_primary_hcd - usb_hcd_platform_shutdown - usb_hub_find_child - usb_interface_id - usb_otg_state_string - usb_put_function_instance - usb_put_hcd - usb_register_notify - usb_remove_hcd - usb_speed_string - usb_string_id - usb_unregister_notify - __usecs_to_jiffies - usleep_range - v4l2_ctrl_auto_cluster - v4l2_ctrl_handler_free - v4l2_ctrl_handler_init_class - v4l2_ctrl_handler_setup - v4l2_ctrl_log_status - v4l2_ctrl_new_custom - v4l2_ctrl_new_std - v4l2_ctrl_new_std_menu - v4l2_ctrl_poll - v4l2_ctrl_subscribe_event - v4l2_device_register - v4l2_device_register_subdev - v4l2_device_set_name - v4l2_device_unregister - v4l2_device_unregister_subdev - v4l2_event_unsubscribe - v4l2_fh_add - v4l2_fh_del - v4l2_fh_exit - v4l2_fh_init - v4l2_fh_is_singular - v4l2_fh_open - v4l2_fh_release - v4l2_i2c_subdev_init - v4l2_m2m_buf_queue - v4l2_m2m_buf_remove - v4l2_m2m_ctx_init - v4l2_m2m_ctx_release - v4l2_m2m_dqbuf - v4l2_m2m_fop_mmap - v4l2_m2m_fop_poll - v4l2_m2m_get_curr_priv - v4l2_m2m_get_vq - v4l2_m2m_init - v4l2_m2m_ioctl_dqbuf - v4l2_m2m_ioctl_querybuf - v4l2_m2m_ioctl_reqbufs - v4l2_m2m_ioctl_streamoff - v4l2_m2m_ioctl_streamon - v4l2_m2m_job_finish - v4l2_m2m_mmap - v4l2_m2m_next_buf - v4l2_m2m_poll - v4l2_m2m_qbuf - v4l2_m2m_querybuf - v4l2_m2m_release - v4l2_m2m_reqbufs - v4l2_m2m_streamoff - v4l2_m2m_streamon - v4l2_m2m_try_schedule - v4l2_match_dv_timings - v4l2_spi_subdev_init - v4l2_subdev_call_wrappers - v4l2_subdev_init - v4l_bound_align_image - vabits_actual - vb2_buffer_done - vb2_common_vm_ops - vb2_create_framevec - vb2_destroy_framevec - vb2_dqbuf - vb2_mmap - vb2_ops_wait_finish - vb2_ops_wait_prepare - vb2_plane_cookie - vb2_plane_vaddr - vb2_poll - vb2_prepare_buf - vb2_qbuf - vb2_querybuf - vb2_queue_init - vb2_queue_release - vb2_reqbufs - vb2_streamoff - vb2_streamon - vb2_wait_for_all_buffers - verify_pkcs7_signature - vfree - vfs_fsync - vfs_getattr - vfs_llseek - video_devdata - video_device_alloc - video_device_release - video_device_release_empty - video_ioctl2 - __video_register_device - video_unregister_device - vmalloc - vmalloc_to_page - vmalloc_to_pfn - vmalloc_user - vmap - vmf_insert_pfn_prot - vm_get_page_prot - vm_insert_page - vm_iomap_memory - vm_map_pages - vm_map_ram - vm_unmap_ram - vprintk_emit - vscnprintf - vsnprintf - vsprintf - vunmap - vzalloc - wait_for_completion - wait_for_completion_interruptible - wait_for_completion_interruptible_timeout - wait_for_completion_killable - wait_for_completion_timeout - __wait_on_buffer - __wake_up - __wake_up_locked - __wake_up_locked_key - wake_up_process - wakeup_source_add - wakeup_source_destroy - wakeup_source_register - wakeup_source_unregister - __wake_up_sync - __warn_printk - watchdog_init_timeout - watchdog_register_device - watchdog_set_restart_priority - watchdog_unregister_device - wireless_nlevent_flush - work_busy - ww_mutex_lock - ww_mutex_lock_interruptible - ww_mutex_unlock - xhci_add_endpoint - xhci_address_device - xhci_bus_resume - xhci_bus_suspend - xhci_check_trb_in_td_math - xhci_gen_setup - xhci_get_endpoint_index - xhci_get_ep_ctx - xhci_init_driver - xhci_initialize_ring_info - xhci_link_segments - xhci_resume - xhci_ring_alloc - xhci_run - xhci_segment_free - xhci_suspend - xhci_trb_virt_to_dma - xhci_vendor_get_ops diff --git a/android/abi_gki_aarch64_exynosauto b/android/abi_gki_aarch64_exynosauto deleted file mode 100644 index dc913dc0e1d2..000000000000 --- a/android/abi_gki_aarch64_exynosauto +++ /dev/null @@ -1,1499 +0,0 @@ -[abi_symbol_list] -# commonly used symbols - add_wait_queue - alloc_chrdev_region - __alloc_pages_nodemask - __alloc_percpu - alloc_workqueue - __arch_copy_from_user - __arch_copy_to_user - arm64_const_caps_ready - arm64_use_ng_mappings - __arm_smccc_smc - atomic_notifier_call_chain - atomic_notifier_chain_register - atomic_notifier_chain_unregister - __bitmap_and - blocking_notifier_call_chain - blocking_notifier_chain_register - blocking_notifier_chain_unregister - bpf_trace_run2 - bpf_trace_run4 - cancel_delayed_work - cancel_delayed_work_sync - cancel_work_sync - capable - cdev_add - cdev_del - cdev_init - __cfi_slowpath - __check_object_size - __class_create - class_destroy - clk_disable - clk_enable - clk_get - clk_get_rate - __clk_is_enabled - clk_prepare - clk_put - clk_register - clk_set_rate - clk_unprepare - clk_unregister - cma_alloc - cma_release - complete - complete_all - complete_and_exit - __const_udelay - cpu_bit_bitmap - cpu_hwcap_keys - cpu_hwcaps - cpumask_next - cpu_number - __cpu_online_mask - cpu_pm_register_notifier - __cpu_possible_mask - crc32_le - __crypto_memneq - debugfs_create_dir - debugfs_create_file - debugfs_create_u32 - debugfs_remove - default_llseek - delayed_work_timer_fn - del_timer - del_timer_sync - destroy_workqueue - _dev_crit - dev_driver_string - _dev_emerg - _dev_err - device_create - device_create_file - device_destroy - device_initialize - device_init_wakeup - device_remove_file - _dev_info - devm_clk_get - devm_free_irq - devm_gpiod_get_optional - devm_gpio_request_one - devm_i2c_new_dummy_device - devm_ioremap - devm_ioremap_resource - devm_kasprintf - devm_kfree - devm_kmalloc - devm_kmemdup - __devm_of_phy_provider_register - devm_phy_create - devm_phy_get - devm_pinctrl_get - devm_platform_ioremap_resource - __devm_regmap_init_i2c - devm_regulator_bulk_get - __devm_request_region - devm_request_threaded_irq - devm_rtc_device_register - devm_snd_soc_register_card - devm_snd_soc_register_component - _dev_notice - devres_add - devres_alloc_node - dev_set_name - _dev_warn - disable_irq - disable_irq_nosync - display_timings_release - dma_alloc_attrs - dma_buf_attach - dma_buf_begin_cpu_access - dma_buf_detach - dma_buf_end_cpu_access - dma_buf_export - dma_buf_fd - dma_buf_get - dma_buf_map_attachment - dma_buf_mmap - dma_buf_put - dma_buf_unmap_attachment - dma_buf_vmap - dma_buf_vunmap - dmaengine_unmap_put - dma_fence_add_callback - dma_fence_context_alloc - dma_fence_default_wait - dma_fence_init - dma_fence_release - dma_fence_remove_callback - dma_fence_signal - dma_free_attrs - dma_heap_buffer_alloc - dma_heap_find - dma_heap_get_drvdata - dma_heap_put - dma_map_page_attrs - dma_map_sg_attrs - dma_release_channel - dma_request_chan - dma_set_coherent_mask - dma_set_mask - dma_sync_sg_for_cpu - dma_sync_sg_for_device - dma_sync_single_for_cpu - dma_sync_single_for_device - dma_unmap_page_attrs - dma_unmap_sg_attrs - down_interruptible - down_read - drm_add_edid_modes - drm_atomic_helper_connector_destroy_state - drm_atomic_helper_connector_duplicate_state - drm_atomic_helper_connector_reset - drm_bridge_add - drm_bridge_remove - drm_connector_attach_encoder - drm_connector_cleanup - drm_connector_init - drm_connector_register - drm_connector_update_edid_property - drm_display_mode_from_videomode - __drm_err - drm_helper_probe_single_connector_modes - drm_kms_helper_hotplug_event - drm_mode_copy - drm_mode_create - drm_mode_probed_add - drm_mode_vrefresh - dump_stack - enable_irq - event_triggers_call - fd_install - find_next_bit - find_vma - finish_wait - flush_delayed_work - flush_work - flush_workqueue - fput - frame_vector_to_pages - free_irq - __free_pages - free_pages - free_percpu - freezing_slow_path - generic_file_llseek - generic_handle_irq - gen_pool_add_owner - gen_pool_alloc_algo_owner - gen_pool_free_owner - get_device - __get_free_pages - get_random_bytes - get_task_mm - get_unused_fd_flags - gic_nonsecure_priorities - gpiod_direction_input - gpiod_direction_output_raw - gpiod_get_raw_value - gpiod_set_raw_value - gpiod_set_value_cansleep - gpiod_to_irq - gpio_free - gpio_request - gpio_request_one - gpio_to_desc - handle_edge_irq - handle_level_irq - handle_nested_irq - hrtimer_cancel - hrtimer_forward - hrtimer_init - hrtimer_start_range_ns - i2c_add_numbered_adapter - i2c_del_driver - i2c_register_driver - i2c_transfer - i2c_unregister_device - idr_remove - __init_rwsem - __init_swait_queue_head - init_timer_key - init_wait_entry - __init_waitqueue_head - iomem_resource - iommu_get_domain_for_dev - iommu_register_device_fault_handler - iommu_unregister_device_fault_handler - __ioremap - iounmap - __irq_alloc_descs - __irq_domain_add - irq_domain_remove - irq_find_mapping - irq_get_irq_data - irq_modify_status - irq_of_parse_and_map - irq_set_affinity_hint - irq_set_chip_and_handler_name - irq_set_chip_data - irq_set_irq_wake - irq_to_desc - is_vmalloc_addr - jiffies - jiffies_to_msecs - kasan_flag_enabled - kasprintf - kfree - kimage_voffset - __kmalloc - kmalloc_caches - kmalloc_order_trace - kmem_cache_alloc - kmem_cache_alloc_trace - kmem_cache_create - kmem_cache_destroy - kmem_cache_free - kmemdup - kobject_create_and_add - kobject_get - kobject_init_and_add - kobject_put - krealloc - kset_unregister - kstrdup - kstrtobool - kstrtoint - kstrtou8 - kstrtouint - kstrtoull - kthread_create_on_node - __kthread_init_worker - kthread_queue_work - kthread_stop - kthread_worker_fn - ktime_get - ktime_get_mono_fast_ns - ktime_get_raw_ts64 - ktime_get_real_ts64 - ktime_get_ts64 - kvfree - kvmalloc_node - __list_add_valid - __list_del_entry_valid - __log_post_read_mmio - __log_read_mmio - __log_write_mmio - loops_per_jiffy - memcpy - memdup_user - memset - memstart_addr - mfd_add_devices - mfd_remove_devices - mipi_dsi_attach - mipi_dsi_detach - mipi_dsi_device_register_full - mipi_dsi_device_unregister - mipi_dsi_driver_register_full - mipi_dsi_driver_unregister - misc_deregister - misc_register - mmput - mod_timer - module_layout - __msecs_to_jiffies - msleep - __mutex_init - mutex_lock - mutex_lock_interruptible - mutex_unlock - no_llseek - nonseekable_open - noop_llseek - nr_cpu_ids - ns_to_timespec64 - __num_online_cpus - of_address_to_resource - of_alias_get_id - of_clk_add_provider - of_clk_del_provider - of_clk_get - of_count_phandle_with_args - of_device_get_match_data - of_device_is_available - of_device_is_compatible - of_find_compatible_node - of_find_device_by_node - of_find_matching_node_and_match - of_find_mipi_dsi_host_by_node - of_find_node_by_name - of_find_node_opts_by_path - of_find_property - of_get_child_by_name - of_get_display_timings - of_get_named_gpio_flags - of_get_next_child - of_get_property - of_get_regulator_init_data - of_graph_get_remote_node - of_iomap - of_match_device - of_match_node - of_parse_phandle - of_platform_populate - of_property_count_elems_of_size - of_property_read_string - of_property_read_string_helper - of_property_read_u32_index - of_property_read_variable_u16_array - of_property_read_variable_u32_array - of_property_read_variable_u8_array - of_prop_next_string - of_reserved_mem_device_init_by_idx - of_reserved_mem_lookup - of_root - panic - panic_notifier_list - param_ops_bool - param_ops_int - param_ops_string - param_ops_uint - PDE_DATA - __per_cpu_offset - perf_trace_buf_alloc - perf_trace_run_bpf_submit - phy_power_off - phy_power_on - pinctrl_lookup_state - pinctrl_select_state - platform_bus_type - platform_device_register_full - platform_device_unregister - __platform_driver_probe - __platform_driver_register - platform_driver_unregister - platform_get_irq - platform_get_resource - platform_get_resource_byname - pm_power_off - __pm_runtime_disable - pm_runtime_enable - __pm_runtime_idle - __pm_runtime_resume - pm_runtime_set_autosuspend_delay - __pm_runtime_suspend - __pm_runtime_use_autosuspend - pm_wakeup_dev_event - pm_wakeup_ws_event - preempt_schedule - preempt_schedule_notrace - prepare_to_wait_event - print_hex_dump - printk - proc_create_data - put_device - __put_task_struct - put_unused_fd - queue_delayed_work_on - queue_work_on - radix_tree_delete - radix_tree_insert - radix_tree_lookup - radix_tree_next_chunk - ___ratelimit - _raw_spin_lock - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_unlock - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - __rcu_read_lock - __rcu_read_unlock - rdev_get_drvdata - rdev_get_id - refcount_dec_and_mutex_lock - refcount_warn_saturate - __refrigerator - regcache_mark_dirty - regcache_sync - __register_chrdev - register_pm_notifier - register_reboot_notifier - register_restart_handler - register_syscore_ops - regmap_read - regmap_update_bits_base - regmap_write - regulator_bulk_disable - regulator_bulk_enable - regulator_disable - regulator_enable - regulator_get_optional - regulator_list_voltage_linear - regulator_map_voltage_linear - regulator_put - regulator_register - regulator_unregister - release_firmware - __release_region - remove_proc_entry - request_firmware - __request_region - request_threaded_irq - sched_clock - schedule - schedule_timeout - scnprintf - seq_lseek - seq_printf - seq_putc - seq_puts - seq_read - seq_release - set_cpus_allowed_ptr - set_page_dirty_lock - sg_alloc_table - sg_alloc_table_from_pages - sg_free_table - sg_init_table - sg_next - __sg_page_iter_next - __sg_page_iter_start - simple_attr_open - simple_attr_read - simple_attr_release - simple_attr_write - simple_open - simple_read_from_buffer - simple_strtoul - simple_write_to_buffer - single_open - single_release - smp_call_function - snd_pcm_format_width - snd_soc_component_update_bits - snd_soc_component_write - snd_soc_dai_set_fmt - snd_soc_dai_set_tdm_slot - snd_soc_dai_set_tristate - snd_soc_info_volsw - snd_soc_of_get_dai_link_codecs - snd_soc_of_get_dai_name - snd_soc_of_parse_audio_routing - snd_soc_of_put_dai_link_codecs - snd_soc_pm_ops - snprintf - sort - split_page - sprintf - sscanf - __stack_chk_fail - __stack_chk_guard - strcasecmp - strcmp - strcpy - strcspn - strlcat - strlcpy - strlen - strncmp - strncpy - strnlen - strstr - __sw_hweight64 - sync_file_create - sync_file_get_fence - synchronize_irq - syscon_regmap_lookup_by_phandle - sysfs_create_file_ns - sysfs_create_group - sysfs_create_groups - sysfs_remove_file_ns - sysfs_remove_group - system_freezing_cnt - system_wq - tasklet_kill - __tasklet_schedule - _totalram_pages - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return - __traceiter_rwmmio_post_read - __traceiter_rwmmio_read - __traceiter_rwmmio_write - tracepoint_probe_register - __tracepoint_rwmmio_post_read - __tracepoint_rwmmio_read - __tracepoint_rwmmio_write - trace_raw_output_prep - trace_seq_printf - __udelay - __unregister_chrdev - unregister_chrdev_region - unregister_pm_notifier - unregister_reboot_notifier - up - up_read - __usecs_to_jiffies - usleep_range - v4l2_device_register - v4l2_device_unregister - v4l2_fh_add - v4l2_fh_del - v4l2_fh_exit - v4l2_fh_init - v4l2_subdev_init - vabits_actual - vb2_buffer_done - vb2_dqbuf - vb2_mmap - vb2_plane_cookie - vb2_plane_vaddr - vb2_poll - vb2_qbuf - vb2_querybuf - vb2_queue_init - vb2_queue_release - vb2_reqbufs - vb2_streamoff - vb2_streamon - vfree - video_devdata - video_device_alloc - video_device_release - video_ioctl2 - videomode_from_timings - __video_register_device - video_unregister_device - vmalloc - vmalloc_to_page - vmap - vsnprintf - vunmap - vzalloc - wait_for_completion - wait_for_completion_interruptible_timeout - wait_for_completion_timeout - __wake_up - wake_up_process - wakeup_source_register - wakeup_source_unregister - __warn_printk - work_busy - -# required by adv7511.ko - cec_s_phys_addr - cec_s_phys_addr_from_edid - cec_unregister_adapter - drm_bridge_hpd_notify - drm_detect_hdmi_monitor - drm_do_get_edid - hdmi_avi_infoframe_init - hdmi_avi_infoframe_pack - i2c_new_ancillary_device - regmap_bulk_write - regmap_register_patch - -# required by bts-exynos.ko - strpbrk - -# required by bufq.ko - kstrndup - -# required by clk_exynos.ko - __clk_get_hw - clk_hw_get_parent - clk_register_clkdev - clk_register_fixed_factor - clk_register_fixed_rate - of_clk_src_onecell_get - -# required by cmupmucal.ko - debugfs_create_x32 - kernel_kobj - -# required by dmatest.ko - dmaengine_get_unmap_data - __dma_request_channel - dma_sync_wait - kthread_should_stop - param_get_bool - param_get_string - param_set_bool - param_set_copystring - prandom_bytes - set_freezable - set_user_nice - strim - -# required by dss.ko - android_debug_symbol - arch_timer_read_counter - dump_backtrace - init_task - input_close_device - input_open_device - input_register_handle - input_register_handler - input_unregister_handle - kmsg_dump_get_line - kmsg_dump_rewind - kstat - nr_irqs - proc_create - register_die_notifier - return_address - rtc_time64_to_tm - sys_tz - time64_to_tm - __traceiter_android_vh_ipi_stop - __traceiter_android_vh_logbuf - __traceiter_cpu_idle - __traceiter_device_pm_callback_end - __traceiter_device_pm_callback_start - __traceiter_hrtimer_expire_entry - __traceiter_hrtimer_expire_exit - __traceiter_irq_handler_entry - __traceiter_irq_handler_exit - __traceiter_sched_switch - __traceiter_suspend_resume - __traceiter_workqueue_execute_end - __traceiter_workqueue_execute_start - __tracepoint_android_vh_ipi_stop - __tracepoint_android_vh_logbuf - __tracepoint_cpu_idle - __tracepoint_device_pm_callback_end - __tracepoint_device_pm_callback_start - __tracepoint_hrtimer_expire_entry - __tracepoint_hrtimer_expire_exit - __tracepoint_irq_handler_entry - __tracepoint_irq_handler_exit - __tracepoint_sched_switch - __tracepoint_suspend_resume - __tracepoint_workqueue_execute_end - __tracepoint_workqueue_execute_start - -# required by dwc3-exynosauto-usb.ko - device_for_each_child - device_property_present - devm_regulator_get - phy_exit - phy_init - platform_device_add - platform_device_add_properties - platform_device_add_resources - platform_device_alloc - platform_device_del - platform_device_put - platform_get_irq_byname_optional - __pm_relax - pm_runtime_allow - pm_runtime_forbid - __pm_runtime_set_status - __pm_stay_awake - __traceiter_dwc3_readl - __traceiter_dwc3_writel - __tracepoint_dwc3_readl - __tracepoint_dwc3_writel - usb_gadget_set_state - usb_otg_state_string - -# required by exynos-chipid_v2.ko - soc_device_register - subsys_system_register - -# required by exynos-coresight.ko - __cpuhp_setup_state_cpuslocked - cpu_pm_unregister_notifier - of_prop_next_u32 - -# required by exynos-debug-test.ko - _ctype - kstrtoll - remove_cpu - smp_call_function_single - strsep - -# required by exynos-ehld.ko - sprint_symbol - -# required by exynos-pd.ko - of_genpd_add_provider_simple - pm_genpd_add_subdomain - pm_genpd_init - -# required by exynos9drm.ko - bus_find_device - component_add - component_bind_all - component_del - component_master_add_with_match - component_master_del - component_unbind_all - console_trylock - console_unlock - debugfs_lookup - device_rename - drm_atomic_bridge_chain_enable - drm_atomic_bridge_chain_pre_enable - drm_atomic_helper_check - drm_atomic_helper_cleanup_planes - drm_atomic_helper_commit - drm_atomic_helper_commit_modeset_disables - drm_atomic_helper_commit_planes - drm_atomic_helper_crtc_destroy_state - drm_atomic_helper_crtc_duplicate_state - drm_atomic_helper_crtc_reset - drm_atomic_helper_disable_plane - drm_atomic_helper_disable_planes_on_crtc - drm_atomic_helper_fake_vblank - drm_atomic_helper_page_flip - __drm_atomic_helper_plane_destroy_state - __drm_atomic_helper_plane_duplicate_state - __drm_atomic_helper_plane_reset - __drm_atomic_helper_private_obj_duplicate_state - drm_atomic_helper_set_config - drm_atomic_helper_shutdown - drm_atomic_helper_update_plane - drm_atomic_helper_wait_for_vblanks - drm_atomic_normalize_zpos - drm_atomic_private_obj_init - drm_bridge_attach - drm_compat_ioctl - drm_connector_list_iter_begin - drm_connector_list_iter_end - drm_connector_list_iter_next - drm_connector_set_path_property - drm_connector_set_tile_property - drm_connector_unregister - drm_crtc_arm_vblank_event - drm_crtc_cleanup - __drm_crtc_commit_free - drm_crtc_handle_vblank - drm_crtc_init_with_planes - drm_crtc_send_vblank_event - drm_crtc_vblank_count - drm_crtc_vblank_get - drm_crtc_vblank_off - drm_crtc_vblank_on - drm_crtc_vblank_put - drm_crtc_vblank_waitqueue - __drm_dbg - drm_debugfs_create_files - drm_dev_alloc - drm_dev_dbg - drm_dev_printk - drm_dev_put - drm_dev_register - drm_dev_unregister - drm_display_mode_to_videomode - drm_dp_aux_register - drm_dp_aux_unregister - drm_dp_bw_code_to_link_rate - drm_dp_calc_pbn_mode - drm_dp_channel_eq_ok - drm_dp_check_act_status - drm_dp_clock_recovery_ok - drm_dp_downstream_debug - drm_dp_dpcd_read - drm_dp_dpcd_read_link_status - drm_dp_dpcd_write - drm_dp_dsc_sink_line_buf_depth - drm_dp_dsc_sink_max_slice_count - drm_dp_find_vcpi_slots - drm_dp_get_adjust_request_pre_emphasis - drm_dp_get_adjust_request_voltage - drm_dp_link_train_channel_eq_delay - drm_dp_link_train_clock_recovery_delay - drm_dp_mst_allocate_vcpi - drm_dp_mst_deallocate_vcpi - drm_dp_mst_detect_port - drm_dp_mst_dump_topology - drm_dp_mst_get_port_malloc - drm_dp_mst_hpd_irq - drm_dp_mst_put_port_malloc - drm_dp_mst_reset_vcpi_slots - drm_dp_mst_topology_mgr_init - drm_dp_mst_topology_mgr_set_mst - drm_dp_update_payload_part1 - drm_dp_update_payload_part2 - drm_dsc_compute_rc_parameters - drm_dsc_pps_payload_pack - drm_encoder_cleanup - drm_encoder_init - drm_flip_work_cleanup - drm_flip_work_commit - drm_flip_work_init - drm_flip_work_queue - drm_framebuffer_cleanup - drm_framebuffer_init - drm_gem_create_mmap_offset - drm_gem_handle_create - drm_gem_mmap - drm_gem_object_free - drm_gem_object_lookup - drm_gem_object_release - drm_gem_prime_fd_to_handle - drm_gem_prime_handle_to_fd - drm_gem_private_object_init - drm_gem_vm_close - drm_gem_vm_open - drm_get_connector_status_name - drm_get_edid - drm_get_format_info - drm_helper_connector_dpms - drm_helper_hpd_irq_event - drm_helper_mode_fill_fb_struct - drm_helper_probe_detect - drm_ioctl - drm_kms_helper_poll_fini - drm_kms_helper_poll_init - drmm_mode_config_init - drm_mode_config_cleanup - drm_mode_config_helper_resume - drm_mode_config_helper_suspend - drm_mode_config_reset - drm_mode_object_get - drm_mode_object_put - drm_of_component_match_add - drm_of_crtc_port_mask - drm_of_find_possible_crtcs - drm_open - drm_panel_disable - drm_panel_enable - drm_panel_get_modes - drm_panel_prepare - drm_panel_unprepare - drm_plane_cleanup - drm_plane_create_alpha_property - drm_plane_create_blend_mode_property - drm_plane_create_zpos_immutable_property - drm_plane_create_zpos_property - drm_poll - drm_prime_gem_destroy - drm_read - drm_release - drm_universal_plane_init - drm_vblank_init - mipi_dsi_host_register - mipi_dsi_host_unregister - mutex_is_locked - of_drm_find_bridge - of_drm_find_panel - of_graph_get_endpoint_by_regs - of_graph_get_endpoint_count - of_graph_get_next_endpoint - of_graph_get_port_by_id - of_graph_get_remote_port - of_graph_get_remote_port_parent - of_graph_parse_endpoint - of_phandle_iterator_init - of_phandle_iterator_next - seq_hex_dump - -# required by exynos_mfc.ko - iommu_dma_reserve_iova - iommu_map_sg - iommu_unmap - -# required by exynos_pm_qos.ko - kstrtoint_from_user - _raw_read_lock_irqsave - _raw_read_unlock_irqrestore - _raw_write_lock_irqsave - _raw_write_unlock_irqrestore - -# required by exynos_thermal.ko - of_thermal_get_ntrips - of_thermal_is_trip_valid - thermal_zone_device_update - thermal_zone_of_sensor_register - thermal_zone_of_sensor_unregister - -# required by exynos_tty.ko - dma_get_slave_caps - do_SAK - handle_sysrq - register_console - sysrq_mask - tty_flip_buffer_push - tty_insert_flip_string_fixed_flag - tty_kref_put - tty_port_tty_get - uart_add_one_port - uart_console_write - uart_get_baud_rate - uart_parse_options - uart_register_driver - uart_remove_one_port - uart_resume_port - uart_set_options - uart_suspend_port - uart_try_toggle_sysrq - uart_unregister_driver - uart_update_timeout - uart_write_wakeup - -# required by g2d.ko - add_timer - device_get_dma_attr - dma_fence_signal_locked - frame_vector_create - frame_vector_destroy - get_vaddr_frames - mod_delayed_work_on - put_vaddr_frames - -# required by hardlockup-watchdog.ko - __cpuhp_setup_state - cpus_read_lock - cpus_read_unlock - smp_call_on_cpu - -# required by i2c-exynosauto.ko - i2c_del_adapter - -# required by mali_kbase.ko - anon_inode_getfd - __arch_clear_user - __bitmap_weight - bpf_trace_run1 - bpf_trace_run3 - bpf_trace_run5 - cache_line_size - clear_page - __close_fd - debugfs_create_bool - dev_pm_opp_of_add_table - dev_pm_opp_of_remove_table - dev_pm_opp_put_regulators - dev_pm_opp_set_regulators - dma_fence_get_status - down - downgrade_write - down_trylock - down_write - failure_tracking - __get_task_comm - get_user_pages - get_user_pages_fast - get_user_pages_remote - hrtimer_active - kstrtobool_from_user - ktime_get_raw - kvfree_call_rcu - __mmdrop - module_put - of_machine_is_compatible - __page_pinner_migration_failed - param_array_ops - param_ops_byte - __put_page - rb_erase - rb_first - rb_insert_color - rb_next - rb_prev - rb_replace_node - register_shrinker - remap_pfn_range - remap_vmalloc_range - seq_open - seq_write - static_key_slow_dec - static_key_slow_inc - strncasecmp - __sw_hweight32 - synchronize_rcu - sysfs_streq - __traceiter_gpu_mem_total - trace_output_call - __tracepoint_gpu_mem_total - trace_print_array_seq - trace_print_flags_seq - trace_print_symbols_seq - try_module_get - unmap_mapping_range - unregister_shrinker - up_write - vmalloc_user - vmf_insert_pfn_prot - -# required by mcDrvModule.ko - crypto_alloc_shash - crypto_destroy_tfm - crypto_shash_final - crypto_shash_update - d_path - get_task_exe_file - get_zeroed_page - kstrtol_from_user - kstrtouint_from_user - pin_user_pages - release_pages - sg_miter_next - sg_miter_start - sg_miter_stop - unpin_user_page - wait_for_completion_interruptible - wait_for_completion_killable - -# required by panel-samsung-dummy.ko - drm_panel_add - drm_panel_init - drm_panel_remove - -# required by pcie-exynos-dw-ep.ko - dw_pcie_ep_init - dw_pcie_read_dbi - dw_pcie_write_dbi - pci_epc_clear_bar - pci_epc_map_addr - pci_epc_mem_alloc_addr - pci_epc_mem_free_addr - pci_epc_set_bar - pci_epc_unmap_addr - -# required by pcie-exynos-dw-rc.ko - bitmap_find_free_region - bitmap_release_region - dw_pcie_host_init - dw_pcie_msi_init - dw_pcie_own_conf_map_bus - dw_pcie_read - dw_pcie_setup_rc - dw_pcie_write - irq_chip_ack_parent - irq_chip_mask_parent - irq_chip_unmask_parent - irq_domain_get_irq_data - irq_domain_set_info - irq_domain_update_bus_token - pcie_get_mps - pcie_set_mps - pci_find_bus - pci_generic_config_read - pci_generic_config_write - pci_get_device - pci_load_saved_state - pci_msi_create_irq_domain - pci_msi_mask_irq - pci_msi_unmask_irq - pci_num_vf - pci_rescan_bus - pci_restore_state - pci_save_state - pci_store_saved_state - -# required by pcs-xpcs.ko - mdiobus_read - mdiobus_write - -# required by pinctrl-samsung-core.ko - devm_gpiochip_add_data_with_key - devm_pinctrl_register - gpiochip_generic_free - gpiochip_generic_request - gpiochip_get_data - gpiochip_lock_as_irq - gpiochip_unlock_as_irq - irq_create_mapping_affinity - irq_domain_xlate_twocell - irq_set_chained_handler_and_data - of_node_name_eq - pinctrl_add_gpio_range - pinctrl_dev_get_drvdata - pinctrl_remove_gpio_range - -# required by pl330.ko - amba_driver_register - amba_driver_unregister - dev_err_probe - __devm_reset_control_get - dma_async_device_register - dma_async_device_unregister - dma_async_tx_descriptor_init - dma_get_slave_channel - dma_map_resource - dma_unmap_resource - of_dma_controller_free - of_dma_controller_register - pm_runtime_force_resume - pm_runtime_force_suspend - pm_runtime_irq_safe - reset_control_assert - reset_control_deassert - tasklet_setup - -# required by pps_core.ko - fasync_helper - idr_alloc - idr_get_next - kill_fasync - -# required by ptp.ko - ida_alloc_range - ida_destroy - ida_free - kthread_cancel_delayed_work_sync - kthread_create_worker - kthread_delayed_work_timer_fn - kthread_destroy_worker - kthread_mod_delayed_work - kthread_queue_delayed_work - ktime_get_snapshot - posix_clock_register - posix_clock_unregister - -# required by reboot-mode.ko - devres_free - devres_release - kfree_const - kstrdup_const - -# required by rtc-s2vps01.ko - rtc_update_irq - rtc_valid_tm - -# required by s3c2410_wdt.ko - watchdog_init_timeout - watchdog_register_device - watchdog_set_restart_priority - watchdog_unregister_device - -# required by sam-is.ko - get_task_pid - i2c_get_adapter - i2c_new_client_device - kobject_del - kstrtou16 - kthread_flush_work - kthread_flush_worker - ktime_get_with_offset - phy_configure - pm_relax - pm_stay_awake - regulator_get_voltage - regulator_is_enabled - regulator_set_voltage - sched_set_fifo - tasklet_init - v4l2_device_register_subdev - v4l2_device_unregister_subdev - v4l2_subdev_call_wrappers - -# required by samsung-iommu-group.ko - iommu_group_alloc - iommu_group_set_name - -# required by samsung-secure-iova.ko - gen_pool_avail - gen_pool_create - gen_pool_destroy - gen_pool_first_fit_align - gen_pool_size - -# required by samsung-seqos.ko - alloc_etherdev_mqs - __bitmap_andnot - consume_skb - dev_close - device_get_phy_mode - device_set_wakeup_capable - device_set_wakeup_enable - __dev_kfree_skb_any - dev_open - dql_completed - dql_reset - eth_mac_addr - ethtool_op_get_link - ethtool_op_get_ts_info - eth_type_trans - free_netdev - in4_pton - in6_pton - jiffies_to_usecs - mdiobus_alloc_size - mdiobus_free - mdiobus_get_phy - __mdiobus_register - mdiobus_unregister - napi_complete_done - napi_disable - napi_gro_receive - __napi_schedule - __napi_schedule_irqoff - napi_schedule_prep - netdev_alert - __netdev_alloc_skb - netdev_err - netdev_info - netdev_update_features - netdev_warn - netif_carrier_off - netif_device_attach - netif_device_detach - netif_napi_add - __netif_napi_del - netif_schedule_queue - netif_set_real_num_rx_queues - netif_set_real_num_tx_queues - netif_tx_wake_queue - net_ratelimit - of_get_mac_address - of_mdiobus_register - of_phy_deregister_fixed_link - of_phy_is_fixed_link - of_phy_register_fixed_link - phy_attached_info - phy_disconnect - phy_ethtool_get_eee - phy_ethtool_ksettings_get - phy_ethtool_ksettings_set - phy_ethtool_nway_reset - phy_ethtool_set_eee - phy_get_eee_err - phy_init_eee - phylink_connect_phy - phylink_create - phylink_destroy - phylink_of_phy_connect - phylink_set_port_modes - phylink_start - phy_mac_interrupt - phy_mii_ioctl - phy_resume - phy_start_aneg - phy_stop - phy_suspend - pinctrl_pm_select_default_state - pinctrl_pm_select_sleep_state - platform_get_irq_byname - _raw_spin_lock_bh - _raw_spin_unlock_bh - register_netdev - rtnl_lock - rtnl_unlock - skb_pull - skb_put - skb_tstamp_tx - synchronize_net - unregister_netdev - -# required by samsung_dma_heap.ko - anon_inode_getfile - deferred_free - devm_add_action - devm_gen_pool_create - dmabuf_page_pool_alloc - dmabuf_page_pool_create - dmabuf_page_pool_destroy - dmabuf_page_pool_free - dma_heap_add - dma_heap_get_dev - dma_heap_get_name - is_dma_buf_file - iterate_fd - mutex_trylock - of_reserved_mem_device_release - __traceiter_android_vh_show_mem - __tracepoint_android_vh_show_mem - vm_insert_page - -# required by samsung_iommu.ko - bus_set_iommu - device_link_add - device_link_del - iommu_attach_group - iommu_device_register - iommu_device_sysfs_add - iommu_device_sysfs_remove - iommu_device_unlink - iommu_device_unregister - iommu_domain_alloc - iommu_fwspec_add_ids - iommu_fwspec_free - iommu_get_dma_cookie - iommu_group_for_each_dev - iommu_group_get - iommu_group_get_iommudata - iommu_group_remove_device - iommu_group_set_iommudata - iommu_put_dma_cookie - iommu_report_device_fault - of_get_dma_window - pfn_valid - -# required by scaler.ko - clk_set_parent - dma_heap_buffer_free - v4l2_ctrl_handler_free - v4l2_ctrl_handler_init_class - v4l2_ctrl_handler_setup - v4l2_ctrl_new_custom - v4l2_ctrl_new_std - v4l2_m2m_buf_queue - v4l2_m2m_buf_remove - v4l2_m2m_ctx_init - v4l2_m2m_ctx_release - v4l2_m2m_dqbuf - v4l2_m2m_get_curr_priv - v4l2_m2m_get_vq - v4l2_m2m_init - v4l2_m2m_job_finish - v4l2_m2m_mmap - v4l2_m2m_next_buf - v4l2_m2m_poll - v4l2_m2m_qbuf - v4l2_m2m_querybuf - v4l2_m2m_release - v4l2_m2m_reqbufs - v4l2_m2m_streamoff - v4l2_m2m_streamon - v4l2_m2m_try_schedule - v4l_bound_align_image - -# required by snd-soc-s3c-dma.ko - devm_snd_dmaengine_pcm_register - snd_dmaengine_pcm_prepare_slave_config - -# required by snd-soc-samsung-abox-core.ko - devm_iounmap - __devm_regmap_init - __devm_regmap_init_mmio_clk - dma_mmap_attrs - __platform_register_drivers - platform_unregister_drivers - pm_runtime_no_callbacks - snd_pcm_hw_constraint_integer - snd_pcm_lib_free_pages - snd_pcm_lib_ioctl - snd_pcm_lib_malloc_pages - snd_pcm_lib_preallocate_free_for_all - snd_pcm_lib_preallocate_pages - snd_pcm_period_elapsed - snd_pcm_release_substream - snd_soc_component_init_regmap - snd_soc_component_read - snd_soc_dapm_add_routes - snd_soc_dapm_get_enum_double - snd_soc_dapm_new_control - snd_soc_dapm_new_controls - snd_soc_dapm_put_enum_double - snd_soc_info_enum_double - snd_soc_set_runtime_hwparams - snd_soc_unregister_component - -# required by snd-soc-tas6424.ko - regcache_cache_only - snd_soc_get_volsw - snd_soc_put_volsw - -# required by spi-exynosauto.ko - __spi_alloc_controller - spi_controller_resume - spi_controller_suspend - spi_delay_exec - spi_finalize_current_message - spi_register_controller - spi_unregister_controller - -# required by spidev.ko - driver_unregister - find_next_zero_bit - __spi_register_driver - spi_setup - spi_sync - stream_open - -# required by syscon-reboot-mode.ko - syscon_node_to_regmap - -# required by ufs-exynosauto-core.ko - blk_ksm_init_passthrough - device_get_match_data - __traceiter_android_vh_ufs_fill_prdt - __tracepoint_android_vh_ufs_fill_prdt - ufshcd_config_pwr_mode - ufshcd_dme_get_attr - ufshcd_dme_set_attr - ufshcd_link_recovery - ufshcd_pltfrm_init - ufshcd_remove - ufshcd_shutdown - ufshcd_system_resume - ufshcd_system_suspend - -# required by vbufq-be-module.ko - drain_workqueue - -# required by vdriver-lib-module.ko - kset_create_and_add - -# required by vevdev-fe-module.ko - input_alloc_absinfo - input_allocate_device - input_event - input_free_device - input_mt_init_slots - input_register_device - input_unregister_device - -# required by videobuf2-dma-sg.ko - vb2_common_vm_ops - vb2_create_framevec - vb2_destroy_framevec - vm_map_pages - vm_map_ram - vm_unmap_ram - -# required by vlx-clk-ctrl-common-module.ko - vscnprintf - -# required by vlx-hyp-module.ko - ioremap_cache - irq_create_of_mapping - irq_dispose_mapping - irq_find_matching_fwspec - of_irq_find_parent - proc_mkdir - -# required by vlx-last-kmsg-module.ko - proc_set_size - -# required by vlx-prop-module.ko - kobject_uevent - sysfs_create_bin_file - sysfs_remove_bin_file - -# required by vlx-vdmaheap-module.ko - devm_get_free_pages - idr_alloc_cyclic - idr_find - radix_tree_iter_delete - uuid_gen - __vmalloc - -# required by vlx-vipc-module.ko - sigprocmask - -# required by vlx-vmq-module.ko - default_wake_function - remove_wait_queue - -# required by vrpc-module.ko - current_work - -# required by vvideo2-fe-module.ko - __task_pid_nr_ns - vprintk - -# preserved by --additions-only - system_highpri_wq diff --git a/android/abi_gki_aarch64_fips140 b/android/abi_gki_aarch64_fips140 index cf48b6d66aa9..b4810fec6419 100644 --- a/android/abi_gki_aarch64_fips140 +++ b/android/abi_gki_aarch64_fips140 @@ -38,10 +38,12 @@ crypto_grab_ahash crypto_grab_shash crypto_grab_skcipher + crypto_grab_spawn crypto_inst_setname crypto_put_default_null_skcipher crypto_register_aead crypto_register_alg + crypto_register_rng crypto_register_rngs crypto_register_shash crypto_register_shashes @@ -62,9 +64,11 @@ crypto_skcipher_decrypt crypto_skcipher_encrypt crypto_skcipher_setkey + crypto_spawn_tfm crypto_spawn_tfm2 crypto_unregister_aead crypto_unregister_alg + crypto_unregister_rng crypto_unregister_rngs crypto_unregister_shash crypto_unregister_shashes @@ -115,7 +119,6 @@ skcipher_walk_virt snprintf __stack_chk_fail - __stack_chk_guard strcmp strlcat strlcpy diff --git a/android/abi_gki_aarch64_galaxy b/android/abi_gki_aarch64_galaxy deleted file mode 100644 index a6d6c37a2f7a..000000000000 --- a/android/abi_gki_aarch64_galaxy +++ /dev/null @@ -1,4492 +0,0 @@ -[abi_symbol_list] -PDE_DATA -__ClearPageMovable -__SetPageMovable -___pskb_trim -___ratelimit -__alloc_disk_node -__alloc_pages_nodemask -__alloc_percpu -__alloc_percpu_gfp -__alloc_skb -__arch_clear_user -__arch_copy_from_user -__arch_copy_in_user -__arch_copy_to_user -__arm_smccc_hvc -__arm_smccc_smc -__bitmap_andnot -__bitmap_clear -__bitmap_complement -__bitmap_or -__bitmap_set -__bitmap_weight -__bitmap_xor -__blk_mq_debugfs_rq_show -__blk_mq_end_request -__blk_rq_map_sg -__blkdev_issue_discard -__blkdev_issue_zeroout -__cfi_slowpath -__check_object_size -__class_create -__class_register -__clk_determine_rate -__clk_get_hw -__clk_get_name -__clk_hw_register_divider -__clk_hw_register_gate -__clk_hw_register_mux -__clk_is_enabled -__clk_mux_determine_rate_closest -__clocksource_register_scale -__close_fd -__const_udelay -__cpu_active_mask -__cpu_online_mask -__cpu_possible_mask -__cpu_present_mask -__cpufreq_driver_target -__cpuhp_remove_state -__cpuhp_setup_state -__cpuhp_setup_state_cpuslocked -__cpuhp_state_add_instance -__cpuhp_state_remove_instance -__dev_get_by_index -__dev_kfree_skb_any -__devm_alloc_percpu -__devm_drm_dev_alloc -__devm_iio_device_register -__devm_irq_alloc_descs -__devm_of_phy_provider_register -__devm_regmap_init -__devm_regmap_init_i2c -__devm_regmap_init_mmio_clk -__devm_regmap_init_spi -__devm_release_region -__devm_request_region -__devm_reset_control_get -__devm_spi_alloc_controller -__dma_request_channel -__do_once_done -__do_once_start -__drm_atomic_helper_connector_destroy_state -__drm_atomic_helper_connector_duplicate_state -__drm_atomic_helper_connector_reset -__drm_atomic_helper_crtc_destroy_state -__drm_atomic_helper_crtc_duplicate_state -__drm_atomic_helper_crtc_reset -__drm_atomic_helper_plane_destroy_state -__drm_atomic_helper_plane_duplicate_state -__drm_atomic_helper_private_obj_duplicate_state -__drm_atomic_state_free -__drm_dbg -__drm_debug -__drm_err -__drm_printfn_coredump -__drm_printfn_info -__drm_printfn_seq_file -__drm_puts_coredump -__drm_puts_seq_file -__dynamic_dev_dbg -__dynamic_pr_debug -__ethtool_get_link_ksettings -__fdget -__flush_icache_range -__free_pages -__get_free_pages -__get_task_comm -__hrtimer_get_remaining -__hvc_resize -__hwspin_lock_timeout -__hwspin_unlock -__i2c_smbus_xfer -__i2c_transfer -__iio_device_register -__init_rwsem -__init_swait_queue_head -__init_waitqueue_head -__ioread32_copy -__ioremap -__iowrite32_copy -__ipv6_addr_type -__irq_alloc_descs -__irq_domain_add -__irq_set_handler -__kfifo_alloc -__kfifo_free -__kfifo_in -__kfifo_init -__kfifo_out -__kfifo_out_peek -__kfifo_to_user -__kfree_skb -__kmalloc -__kthread_init_worker -__list_add_valid -__list_del_entry_valid -__local_bh_enable_ip -__lock_page -__log_post_read_mmio -__log_read_mmio -__log_write_mmio -__mdiobus_register -__media_device_register -__memcat_p -__memcpy_fromio -__memcpy_toio -__memset_io -__mmc_claim_host -__mmc_send_status -__mmdrop -__module_get -__msecs_to_jiffies -__mutex_init -__napi_alloc_skb -__napi_schedule -__ndelay -__netdev_alloc_skb -__netif_napi_del -__netif_set_xps_queue -__netlink_kernel_create -__next_zones_zonelist -__nla_parse -__nla_validate -__nlmsg_put -__num_online_cpus -__of_reset_control_get -__pci_register_driver -__per_cpu_offset -__percpu_down_read -__percpu_init_rwsem -__platform_driver_probe -__platform_driver_register -__platform_register_drivers -__pm_relax -__pm_runtime_disable -__pm_runtime_idle -__pm_runtime_resume -__pm_runtime_set_status -__pm_runtime_suspend -__pm_runtime_use_autosuspend -__pm_stay_awake -__printk_ratelimit -__pskb_pull_tail -__put_page -__put_task_struct -__rb_erase_color -__rb_insert_augmented -__rcu_read_lock -__rcu_read_unlock -__refrigerator -__register_chrdev -__register_rpmsg_driver -__regmap_init -__release_region -__request_module -__request_percpu_irq -__request_region -__rht_bucket_nested -__rtc_register_device -__scsi_execute -__scsi_iterate_devices -__scsi_print_sense -__sdhci_add_host -__seq_open_private -__serio_register_driver -__serio_register_port -__sg_page_iter_dma_next -__sg_page_iter_next -__sg_page_iter_start -__skb_ext_put -__skb_flow_dissect -__skb_get_hash -__skb_gso_segment -__skb_pad -__spi_alloc_controller -__spi_register_driver -__splice_from_pipe -__spmi_driver_register -__srcu_read_lock -__srcu_read_unlock -__stack_chk_fail -__stack_chk_guard -__sw_hweight16 -__sw_hweight32 -__sw_hweight64 -__sw_hweight8 -__sysfs_match_string -__task_pid_nr_ns -__task_rq_lock -__tasklet_hi_schedule -__tasklet_schedule -__trace_bprintk -__trace_bputs -__trace_printk -__traceiter_android_rvh_account_irq -__traceiter_android_rvh_build_perf_domains -__traceiter_android_rvh_can_migrate_task -__traceiter_android_rvh_check_preempt_wakeup -__traceiter_android_rvh_cpu_cgroup_attach -__traceiter_android_rvh_cpu_cgroup_can_attach -__traceiter_android_rvh_cpu_cgroup_online -__traceiter_android_rvh_cpu_overutilized -__traceiter_android_rvh_cpufreq_transition -__traceiter_android_rvh_dequeue_task -__traceiter_android_rvh_die_kernel_fault -__traceiter_android_rvh_do_mem_abort -__traceiter_android_rvh_do_sp_pc_abort -__traceiter_android_rvh_enqueue_task -__traceiter_android_rvh_find_busiest_queue -__traceiter_android_rvh_find_energy_efficient_cpu -__traceiter_android_rvh_find_lowest_rq -__traceiter_android_rvh_flush_task -__traceiter_android_rvh_irqs_disable -__traceiter_android_rvh_irqs_enable -__traceiter_android_rvh_migrate_queued_task -__traceiter_android_rvh_new_task_stats -__traceiter_android_rvh_pick_next_entity -__traceiter_android_rvh_place_entity -__traceiter_android_rvh_preempt_disable -__traceiter_android_rvh_preempt_enable -__traceiter_android_rvh_replace_next_task_fair -__traceiter_android_rvh_report_bug -__traceiter_android_rvh_resume_cpus -__traceiter_android_rvh_sched_balance_rt -__traceiter_android_rvh_sched_cpu_dying -__traceiter_android_rvh_sched_cpu_starting -__traceiter_android_rvh_sched_exec -__traceiter_android_rvh_sched_fork -__traceiter_android_rvh_sched_fork_init -__traceiter_android_rvh_sched_newidle_balance -__traceiter_android_rvh_sched_nohz_balancer_kick -__traceiter_android_rvh_sched_rebalance_domains -__traceiter_android_rvh_schedule -__traceiter_android_rvh_schedule_bug -__traceiter_android_rvh_select_fallback_rq -__traceiter_android_rvh_select_task_rq_fair -__traceiter_android_rvh_select_task_rq_rt -__traceiter_android_rvh_set_gfp_zone_flags -__traceiter_android_rvh_set_iowait -__traceiter_android_rvh_set_readahead_gfp_mask -__traceiter_android_rvh_set_skip_swapcache_flags -__traceiter_android_rvh_set_task_cpu -__traceiter_android_rvh_tick_entry -__traceiter_android_rvh_try_to_wake_up -__traceiter_android_rvh_try_to_wake_up_success -__traceiter_android_rvh_ttwu_cond -__traceiter_android_rvh_typec_tcpci_chk_contaminant -__traceiter_android_rvh_typec_tcpci_get_vbus -__traceiter_android_rvh_uclamp_eff_get -__traceiter_android_rvh_update_cpu_capacity -__traceiter_android_rvh_update_cpus_allowed -__traceiter_android_rvh_update_misfit_status -__traceiter_android_rvh_util_est_update -__traceiter_android_rvh_wake_up_new_task -__traceiter_android_vh_allow_domain_state -__traceiter_android_vh_arch_set_freq_scale -__traceiter_android_vh_binder_restore_priority -__traceiter_android_vh_binder_set_priority -__traceiter_android_vh_binder_transaction_init -__traceiter_android_vh_binder_wakeup_ilocked -__traceiter_android_vh_cma_alloc_finish -__traceiter_android_vh_cma_alloc_start -__traceiter_android_vh_cpu_idle_enter -__traceiter_android_vh_cpu_idle_exit -__traceiter_android_vh_dump_throttled_rt_tasks -__traceiter_android_vh_enable_thermal_genl_check -__traceiter_android_vh_ep_create_wakeup_source -__traceiter_android_vh_freq_table_limits -__traceiter_android_vh_ftrace_dump_buffer -__traceiter_android_vh_ftrace_format_check -__traceiter_android_vh_ftrace_oops_enter -__traceiter_android_vh_ftrace_oops_exit -__traceiter_android_vh_ftrace_size_check -__traceiter_android_vh_iommu_setup_dma_ops -__traceiter_android_vh_ipi_stop -__traceiter_android_vh_is_fpsimd_save -__traceiter_android_vh_jiffies_update -__traceiter_android_vh_kfree_skb -__traceiter_android_vh_logbuf -__traceiter_android_vh_logbuf_pr_cont -__traceiter_android_vh_meminfo_proc_show -__traceiter_android_vh_pagecache_get_page -__traceiter_android_vh_printk_hotplug -__traceiter_android_vh_ptype_head -__traceiter_android_vh_rmqueue -__traceiter_android_vh_scheduler_tick -__traceiter_android_vh_show_max_freq -__traceiter_android_vh_show_mem -__traceiter_android_vh_show_resume_epoch_val -__traceiter_android_vh_show_suspend_epoch_val -__traceiter_android_vh_timer_calc_index -__traceiter_android_vh_timerfd_create -__traceiter_android_vh_typec_store_partner_src_caps -__traceiter_android_vh_typec_tcpci_override_toggling -__traceiter_android_vh_typec_tcpm_adj_current_limit -__traceiter_android_vh_typec_tcpm_get_timer -__traceiter_android_vh_ufs_check_int_errors -__traceiter_android_vh_ufs_compl_command -__traceiter_android_vh_ufs_fill_prdt -__traceiter_android_vh_ufs_prepare_command -__traceiter_android_vh_ufs_send_command -__traceiter_android_vh_ufs_send_tm_command -__traceiter_android_vh_ufs_send_uic_command -__traceiter_android_vh_ufs_update_sdev -__traceiter_android_vh_ufs_update_sysfs -__traceiter_clock_set_rate -__traceiter_cpu_frequency -__traceiter_dma_fence_emit -__traceiter_dwc3_readl -__traceiter_dwc3_writel -__traceiter_gpu_mem_total -__traceiter_sched_util_est_se_tp -__traceiter_xdp_exception -__tracepoint_android_rvh_account_irq -__tracepoint_android_rvh_build_perf_domains -__tracepoint_android_rvh_can_migrate_task -__tracepoint_android_rvh_check_preempt_wakeup -__tracepoint_android_rvh_cpu_cgroup_attach -__tracepoint_android_rvh_cpu_cgroup_can_attach -__tracepoint_android_rvh_cpu_cgroup_online -__tracepoint_android_rvh_cpu_overutilized -__tracepoint_android_rvh_cpufreq_transition -__tracepoint_android_rvh_dequeue_task -__tracepoint_android_rvh_die_kernel_fault -__tracepoint_android_rvh_do_mem_abort -__tracepoint_android_rvh_do_sp_pc_abort -__tracepoint_android_rvh_enqueue_task -__tracepoint_android_rvh_find_busiest_queue -__tracepoint_android_rvh_find_energy_efficient_cpu -__tracepoint_android_rvh_find_lowest_rq -__tracepoint_android_rvh_flush_task -__tracepoint_android_rvh_irqs_disable -__tracepoint_android_rvh_irqs_enable -__tracepoint_android_rvh_migrate_queued_task -__tracepoint_android_rvh_new_task_stats -__tracepoint_android_rvh_pick_next_entity -__tracepoint_android_rvh_place_entity -__tracepoint_android_rvh_preempt_disable -__tracepoint_android_rvh_preempt_enable -__tracepoint_android_rvh_replace_next_task_fair -__tracepoint_android_rvh_report_bug -__tracepoint_android_rvh_resume_cpus -__tracepoint_android_rvh_sched_balance_rt -__tracepoint_android_rvh_sched_cpu_dying -__tracepoint_android_rvh_sched_cpu_starting -__tracepoint_android_rvh_sched_exec -__tracepoint_android_rvh_sched_fork -__tracepoint_android_rvh_sched_fork_init -__tracepoint_android_rvh_sched_newidle_balance -__tracepoint_android_rvh_sched_nohz_balancer_kick -__tracepoint_android_rvh_sched_rebalance_domains -__tracepoint_android_rvh_schedule -__tracepoint_android_rvh_schedule_bug -__tracepoint_android_rvh_select_fallback_rq -__tracepoint_android_rvh_select_task_rq_fair -__tracepoint_android_rvh_select_task_rq_rt -__tracepoint_android_rvh_set_gfp_zone_flags -__tracepoint_android_rvh_set_iowait -__tracepoint_android_rvh_set_readahead_gfp_mask -__tracepoint_android_rvh_set_skip_swapcache_flags -__tracepoint_android_rvh_set_task_cpu -__tracepoint_android_rvh_tick_entry -__tracepoint_android_rvh_try_to_wake_up -__tracepoint_android_rvh_try_to_wake_up_success -__tracepoint_android_rvh_ttwu_cond -__tracepoint_android_rvh_typec_tcpci_chk_contaminant -__tracepoint_android_rvh_typec_tcpci_get_vbus -__tracepoint_android_rvh_uclamp_eff_get -__tracepoint_android_rvh_update_cpu_capacity -__tracepoint_android_rvh_update_cpus_allowed -__tracepoint_android_rvh_update_misfit_status -__tracepoint_android_rvh_util_est_update -__tracepoint_android_rvh_wake_up_new_task -__tracepoint_android_vh_allow_domain_state -__tracepoint_android_vh_arch_set_freq_scale -__tracepoint_android_vh_binder_restore_priority -__tracepoint_android_vh_binder_set_priority -__tracepoint_android_vh_binder_transaction_init -__tracepoint_android_vh_binder_wakeup_ilocked -__tracepoint_android_vh_cma_alloc_finish -__tracepoint_android_vh_cma_alloc_start -__tracepoint_android_vh_cpu_idle_enter -__tracepoint_android_vh_cpu_idle_exit -__tracepoint_android_vh_dump_throttled_rt_tasks -__tracepoint_android_vh_enable_thermal_genl_check -__tracepoint_android_vh_ep_create_wakeup_source -__tracepoint_android_vh_freq_table_limits -__tracepoint_android_vh_ftrace_dump_buffer -__tracepoint_android_vh_ftrace_format_check -__tracepoint_android_vh_ftrace_oops_enter -__tracepoint_android_vh_ftrace_oops_exit -__tracepoint_android_vh_ftrace_size_check -__tracepoint_android_vh_iommu_setup_dma_ops -__tracepoint_android_vh_ipi_stop -__tracepoint_android_vh_is_fpsimd_save -__tracepoint_android_vh_jiffies_update -__tracepoint_android_vh_kfree_skb -__tracepoint_android_vh_logbuf -__tracepoint_android_vh_logbuf_pr_cont -__tracepoint_android_vh_meminfo_proc_show -__tracepoint_android_vh_pagecache_get_page -__tracepoint_android_vh_printk_hotplug -__tracepoint_android_vh_ptype_head -__tracepoint_android_vh_rmqueue -__tracepoint_android_vh_scheduler_tick -__tracepoint_android_vh_show_max_freq -__tracepoint_android_vh_show_mem -__tracepoint_android_vh_show_resume_epoch_val -__tracepoint_android_vh_show_suspend_epoch_val -__tracepoint_android_vh_timer_calc_index -__tracepoint_android_vh_timerfd_create -__tracepoint_android_vh_typec_store_partner_src_caps -__tracepoint_android_vh_typec_tcpci_override_toggling -__tracepoint_android_vh_typec_tcpm_adj_current_limit -__tracepoint_android_vh_typec_tcpm_get_timer -__tracepoint_android_vh_ufs_check_int_errors -__tracepoint_android_vh_ufs_compl_command -__tracepoint_android_vh_ufs_fill_prdt -__tracepoint_android_vh_ufs_prepare_command -__tracepoint_android_vh_ufs_send_command -__tracepoint_android_vh_ufs_send_tm_command -__tracepoint_android_vh_ufs_send_uic_command -__tracepoint_android_vh_ufs_update_sdev -__tracepoint_android_vh_ufs_update_sysfs -__tracepoint_binder_transaction_received -__tracepoint_clock_set_rate -__tracepoint_cpu_frequency -__tracepoint_cpu_frequency_limits -__tracepoint_cpu_idle -__tracepoint_device_pm_callback_end -__tracepoint_device_pm_callback_start -__tracepoint_dma_fence_emit -__tracepoint_dwc3_ep_queue -__tracepoint_dwc3_readl -__tracepoint_dwc3_writel -__tracepoint_gpu_mem_total -__tracepoint_hrtimer_expire_entry -__tracepoint_hrtimer_expire_exit -__tracepoint_ipi_entry -__tracepoint_ipi_exit -__tracepoint_ipi_raise -__tracepoint_irq_handler_entry -__tracepoint_irq_handler_exit -__tracepoint_pelt_cfs_tp -__tracepoint_pelt_dl_tp -__tracepoint_pelt_irq_tp -__tracepoint_pelt_rt_tp -__tracepoint_pelt_se_tp -__tracepoint_rwmmio_post_read -__tracepoint_rwmmio_read -__tracepoint_rwmmio_write -__tracepoint_sched_cpu_capacity_tp -__tracepoint_sched_overutilized_tp -__tracepoint_sched_switch -__tracepoint_sched_util_est_cfs_tp -__tracepoint_sched_util_est_se_tp -__tracepoint_suspend_resume -__tracepoint_workqueue_execute_end -__tracepoint_workqueue_execute_start -__tracepoint_xdp_exception -__tty_insert_flip_char -__udelay -__uio_register_device -__unregister_chrdev -__update_load_avg_blocked_se -__usb_create_hcd -__usecs_to_jiffies -__v4l2_device_register_subdev_nodes -__video_register_device -__wait_rcu_gp -__wake_up -__wake_up_locked -__wake_up_locked_key -__wake_up_sync -__warn_printk -__xa_alloc -__xa_insert -__xfrm_state_destroy -_atomic_dec_and_lock -_copy_from_iter -_copy_from_iter_full -_copy_to_iter -_ctype -_dev_alert -_dev_crit -_dev_emerg -_dev_err -_dev_info -_dev_notice -_dev_warn -_raw_read_lock -_raw_read_lock_bh -_raw_read_lock_irq -_raw_read_lock_irqsave -_raw_read_unlock -_raw_read_unlock_bh -_raw_read_unlock_irq -_raw_read_unlock_irqrestore -_raw_spin_lock -_raw_spin_lock_bh -_raw_spin_lock_irq -_raw_spin_lock_irqsave -_raw_spin_trylock -_raw_spin_trylock_bh -_raw_spin_unlock -_raw_spin_unlock_bh -_raw_spin_unlock_irq -_raw_spin_unlock_irqrestore -_raw_write_lock -_raw_write_lock_bh -_raw_write_lock_irq -_raw_write_lock_irqsave -_raw_write_unlock -_raw_write_unlock_bh -_raw_write_unlock_irq -_raw_write_unlock_irqrestore -_snd_ctl_add_follower -_snd_pcm_stream_lock_irqsave -_totalram_pages -access_process_vm -ack_all_badblocks -activate_task -add_cpu -add_device_randomness -add_memory -add_memory_subsection -add_taint -add_timer -add_timer_on -add_uevent_var -add_wait_queue -adjust_managed_page_count -alarm_cancel -alarm_init -alarm_start -alarm_start_relative -alarm_try_to_cancel -alarmtimer_get_rtcdev -all_vm_events -alloc_anon_inode -alloc_chrdev_region -alloc_etherdev_mqs -alloc_io_pgtable_ops -alloc_netdev_mqs -alloc_page_buffers -alloc_pages_exact -alloc_skb_with_frags -alloc_workqueue -amba_bustype -amba_driver_register -amba_driver_unregister -amba_release_regions -amba_request_regions -android_debug_per_cpu_symbol -android_debug_symbol -android_rvh_probe_register -anon_inode_getfd -anon_inode_getfile -arch_timer_read_counter -argv_free -argv_split -arm64_const_caps_ready -arm64_use_ng_mappings -async_schedule_node -async_schedule_node_domain -async_synchronize_full_domain -atomic_notifier_call_chain -atomic_notifier_chain_register -atomic_notifier_chain_unregister -autoremove_wake_function -available_idle_cpu -backlight_device_get_by_type -backlight_device_register -backlight_device_set_brightness -backlight_device_unregister -badblocks_clear -badblocks_exit -badblocks_init -badblocks_set -badblocks_show -badblocks_store -balloon_aops -balloon_page_alloc -balloon_page_dequeue -balloon_page_enqueue -bcmp -bd_link_disk_holder -bd_set_nr_sectors -bd_unlink_disk_holder -bdev_check_media_change -bdev_read_only -bdevname -bdget_disk -bdput -bgpio_init -bin2hex -bio_add_page -bio_alloc_bioset -bio_associate_blkg -bio_chain -bio_clone_blkg_association -bio_endio -bio_init -bio_put -bioset_exit -bioset_init -bitmap_allocate_region -bitmap_find_next_zero_area_off -bitmap_from_arr32 -bitmap_parse -bitmap_parselist -bitmap_parselist_user -bitmap_print_to_pagebuf -bitmap_release_region -bitmap_to_arr32 -bitmap_zalloc -blk_alloc_queue -blk_cleanup_queue -blk_execute_rq -blk_execute_rq_nowait -blk_finish_plug -blk_freeze_queue_start -blk_get_queue -blk_get_request -blk_mq_alloc_request -blk_mq_alloc_request_hctx -blk_mq_alloc_tag_set -blk_mq_complete_request -blk_mq_complete_request_remote -blk_mq_debugfs_rq_show -blk_mq_delay_kick_requeue_list -blk_mq_end_request -blk_mq_free_request -blk_mq_free_tag_set -blk_mq_freeze_queue -blk_mq_freeze_queue_wait -blk_mq_freeze_queue_wait_timeout -blk_mq_init_queue -blk_mq_map_queues -blk_mq_pci_map_queues -blk_mq_quiesce_queue -blk_mq_requeue_request -blk_mq_rq_cpu -blk_mq_run_hw_queues -blk_mq_sched_request_inserted -blk_mq_sched_try_insert_merge -blk_mq_sched_try_merge -blk_mq_start_request -blk_mq_start_stopped_hw_queues -blk_mq_stop_hw_queue -blk_mq_tag_to_rq -blk_mq_tagset_busy_iter -blk_mq_tagset_wait_completed_request -blk_mq_unfreeze_queue -blk_mq_unique_tag -blk_mq_unquiesce_queue -blk_mq_update_nr_hw_queues -blk_mq_virtio_map_queues -blk_poll -blk_put_queue -blk_put_request -blk_queue_alignment_offset -blk_queue_bounce_limit -blk_queue_can_use_dma_map_merging -blk_queue_chunk_sectors -blk_queue_dma_alignment -blk_queue_flag_clear -blk_queue_flag_set -blk_queue_flag_test_and_set -blk_queue_io_min -blk_queue_io_opt -blk_queue_logical_block_size -blk_queue_max_discard_sectors -blk_queue_max_discard_segments -blk_queue_max_hw_sectors -blk_queue_max_segment_size -blk_queue_max_segments -blk_queue_max_write_zeroes_sectors -blk_queue_physical_block_size -blk_queue_rq_timeout -blk_queue_split -blk_queue_virt_boundary -blk_queue_write_cache -blk_register_region -blk_rq_map_kern -blk_rq_map_user -blk_rq_map_user_iov -blk_rq_unmap_user -blk_set_queue_dying -blk_set_stacking_limits -blk_start_plug -blk_status_to_errno -blk_sync_queue -blk_unregister_region -blk_update_request -blk_verify_command -blkdev_fsync -blkdev_get_by_dev -blkdev_get_by_path -blkdev_issue_flush -blkdev_put -blocking_notifier_call_chain -blocking_notifier_chain_register -blocking_notifier_chain_unregister -bmap -bpf_dispatcher_xdp_func -bpf_prog_add -bpf_prog_put -bpf_prog_sub -bpf_stats_enabled_key -bpf_trace_run1 -bpf_trace_run10 -bpf_trace_run11 -bpf_trace_run12 -bpf_trace_run2 -bpf_trace_run3 -bpf_trace_run4 -bpf_trace_run5 -bpf_trace_run6 -bpf_trace_run7 -bpf_trace_run8 -bpf_trace_run9 -bpf_warn_invalid_xdp_action -bsearch -bt_err -bt_info -build_skb -bus_find_device -bus_for_each_dev -bus_for_each_drv -bus_register -bus_register_notifier -bus_set_iommu -bus_unregister -bus_unregister_notifier -cache_line_size -call_netdevice_notifiers -call_rcu -call_rcu_tasks -call_rcu_tasks_trace -call_srcu -cancel_delayed_work -cancel_delayed_work_sync -cancel_work_sync -capable -cdev_add -cdev_alloc -cdev_del -cdev_device_add -cdev_device_del -cdev_init -cec_allocate_adapter -cec_delete_adapter -cec_received_msg_ts -cec_register_adapter -cec_s_log_addrs -cec_s_phys_addr -cec_s_phys_addr_from_edid -cec_transmit_attempt_done_ts -cec_transmit_done_ts -cec_unregister_adapter -cgroup_path_ns -cgroup_taskset_first -cgroup_taskset_next -check_preempt_curr -check_zeroed_user -class_create_file_ns -class_destroy -class_find_device -class_for_each_device -class_interface_unregister -class_remove_file_ns -class_unregister -cleancache_register_ops -cleanup_srcu_struct -clear_page -clk_bulk_disable -clk_bulk_enable -clk_bulk_get_all -clk_bulk_prepare -clk_bulk_put_all -clk_bulk_unprepare -clk_disable -clk_enable -clk_fixed_factor_ops -clk_fixed_rate_ops -clk_get -clk_get_parent -clk_get_rate -clk_hw_get_flags -clk_hw_get_name -clk_hw_get_num_parents -clk_hw_get_parent -clk_hw_get_parent_by_index -clk_hw_get_rate -clk_hw_is_enabled -clk_hw_is_prepared -clk_hw_register -clk_hw_register_fixed_factor -clk_hw_round_rate -clk_hw_set_rate_range -clk_hw_unregister -clk_hw_unregister_divider -clk_hw_unregister_fixed_factor -clk_hw_unregister_gate -clk_hw_unregister_mux -clk_notifier_register -clk_notifier_unregister -clk_prepare -clk_put -clk_register -clk_register_clkdev -clk_register_fixed_factor -clk_register_fixed_rate -clk_register_gate -clk_round_rate -clk_set_parent -clk_set_rate -clk_sync_state -clk_unprepare -clk_unregister -clockevents_config_and_register -clocks_calc_mult_shift -cma_alloc -cma_for_each_area -cma_get_name -cma_release -compat_alloc_user_space -compat_only_sysfs_link_entry_to_kobj -compat_ptr_ioctl -complete -complete_all -complete_and_exit -completion_done -component_add -component_bind_all -component_del -component_master_add_with_match -component_master_del -component_match_add_release -component_unbind_all -cond_synchronize_rcu -config_ep_by_speed -config_group_init -config_group_init_type_name -config_item_get -config_item_put -configfs_register_subsystem -configfs_unregister_subsystem -console_drivers -console_printk -console_stop -console_suspend_enabled -console_trylock -console_unlock -consume_skb -contig_page_data -copy_from_kernel_nofault -copy_page -cpu_all_bits -cpu_bit_bitmap -cpu_hwcap_keys -cpu_hwcaps -cpu_irqtime -cpu_is_hotpluggable -cpu_latency_qos_add_request -cpu_latency_qos_remove_request -cpu_latency_qos_request_active -cpu_latency_qos_update_request -cpu_number -cpu_pm_register_notifier -cpu_pm_unregister_notifier -cpu_scale -cpu_subsys -cpu_topology -cpufreq_add_update_util_hook -cpufreq_cpu_get -cpufreq_cpu_get_raw -cpufreq_cpu_put -cpufreq_disable_fast_switch -cpufreq_driver_fast_switch -cpufreq_driver_resolve_freq -cpufreq_enable_boost_support -cpufreq_enable_fast_switch -cpufreq_freq_attr_scaling_available_freqs -cpufreq_freq_attr_scaling_boost_freqs -cpufreq_freq_transition_begin -cpufreq_freq_transition_end -cpufreq_frequency_table_verify -cpufreq_generic_attr -cpufreq_generic_frequency_table_verify -cpufreq_generic_get -cpufreq_generic_suspend -cpufreq_get_driver_data -cpufreq_get_policy -cpufreq_policy_transition_delay_us -cpufreq_quick_get -cpufreq_quick_get_max -cpufreq_register_driver -cpufreq_register_governor -cpufreq_register_notifier -cpufreq_remove_update_util_hook -cpufreq_table_index_unsorted -cpufreq_this_cpu_can_update -cpufreq_unregister_driver -cpufreq_unregister_notifier -cpufreq_update_policy -cpuhp_tasks_frozen -cpuidle_governor_latency_req -cpuidle_register_governor -cpumask_any_but -cpumask_next -cpumask_next_and -cpumask_next_wrap -cpupri_find_fitness -cpus_read_lock -cpus_read_unlock -crc32_le -crc8 -crc8_populate_msb -create_function_device -crypto_aead_encrypt -crypto_aead_setauthsize -crypto_aead_setkey -crypto_alloc_aead -crypto_alloc_base -crypto_alloc_shash -crypto_alloc_skcipher -crypto_cipher_encrypt_one -crypto_cipher_setkey -crypto_comp_compress -crypto_comp_decompress -crypto_destroy_tfm -crypto_has_alg -crypto_register_alg -crypto_register_rngs -crypto_register_scomp -crypto_shash_digest -crypto_shash_final -crypto_shash_setkey -crypto_shash_update -crypto_skcipher_decrypt -crypto_skcipher_encrypt -crypto_skcipher_setkey -crypto_unregister_alg -crypto_unregister_rngs -crypto_unregister_scomp -css_next_child -csum_ipv6_magic -csum_partial -csum_tcpudp_nofold -current_time -current_work -d_add -d_alloc_name -d_delete -d_make_root -d_path -dapm_pinctrl_event -dapm_regulator_event -datagram_poll -deactivate_task -debugfs_attr_read -debugfs_attr_write -debugfs_create_atomic_t -debugfs_create_blob -debugfs_create_bool -debugfs_create_dir -debugfs_create_file -debugfs_create_file_unsafe -debugfs_create_regset32 -debugfs_create_size_t -debugfs_create_symlink -debugfs_create_u16 -debugfs_create_u32 -debugfs_create_u64 -debugfs_create_u8 -debugfs_create_ulong -debugfs_create_x32 -debugfs_create_x64 -debugfs_create_x8 -debugfs_file_get -debugfs_file_put -debugfs_lookup -debugfs_print_regs32 -debugfs_remove -dec_zone_page_state -default_llseek -deferred_free -del_gendisk -del_timer -del_timer_sync -delayed_work_timer_fn -desc_to_gpio -destroy_workqueue -dev_alloc_name -dev_close -dev_coredumpm -dev_coredumpv -dev_driver_string -dev_err_probe -dev_fwnode -dev_get_by_index -dev_get_by_name -dev_get_regmap -dev_get_stats -dev_mc_sync_multiple -dev_mc_unsync -dev_open -dev_pm_clear_wake_irq -dev_pm_domain_attach -dev_pm_domain_attach_by_name -dev_pm_domain_detach -dev_pm_genpd_add_notifier -dev_pm_genpd_remove_notifier -dev_pm_genpd_set_next_wakeup -dev_pm_genpd_set_performance_state -dev_pm_opp_add -dev_pm_opp_adjust_voltage -dev_pm_opp_disable -dev_pm_opp_enable -dev_pm_opp_find_freq_ceil -dev_pm_opp_find_freq_exact -dev_pm_opp_find_freq_floor -dev_pm_opp_free_cpufreq_table -dev_pm_opp_get_freq -dev_pm_opp_get_level -dev_pm_opp_get_max_transition_latency -dev_pm_opp_get_opp_count -dev_pm_opp_get_opp_table -dev_pm_opp_get_sharing_cpus -dev_pm_opp_get_suspend_opp_freq -dev_pm_opp_get_voltage -dev_pm_opp_init_cpufreq_table -dev_pm_opp_of_add_table -dev_pm_opp_of_cpumask_add_table -dev_pm_opp_of_cpumask_remove_table -dev_pm_opp_of_find_icc_paths -dev_pm_opp_of_get_sharing_cpus -dev_pm_opp_of_register_em -dev_pm_opp_of_remove_table -dev_pm_opp_put -dev_pm_opp_put_clkname -dev_pm_opp_put_opp_table -dev_pm_opp_put_regulators -dev_pm_opp_register_notifier -dev_pm_opp_remove_all_dynamic -dev_pm_opp_set_bw -dev_pm_opp_set_clkname -dev_pm_opp_set_rate -dev_pm_opp_set_regulators -dev_pm_opp_set_sharing_cpus -dev_pm_opp_set_supported_hw -dev_pm_opp_unregister_notifier -dev_pm_qos_add_notifier -dev_pm_qos_add_request -dev_pm_qos_expose_latency_tolerance -dev_pm_qos_hide_latency_tolerance -dev_pm_qos_read_value -dev_pm_qos_remove_notifier -dev_pm_qos_remove_request -dev_pm_qos_update_request -dev_pm_qos_update_user_latency_tolerance -dev_pm_set_dedicated_wake_irq -dev_printk -dev_printk_emit -dev_queue_xmit -dev_set_mtu -dev_set_name -dev_uc_sync_multiple -dev_uc_unsync -devfreq_add_device -devfreq_add_governor -devfreq_cooling_unregister -devfreq_get_devfreq_by_phandle -devfreq_monitor_resume -devfreq_monitor_start -devfreq_monitor_stop -devfreq_monitor_suspend -devfreq_recommended_opp -devfreq_register_opp_notifier -devfreq_remove_device -devfreq_remove_governor -devfreq_resume_device -devfreq_suspend_device -devfreq_unregister_opp_notifier -devfreq_update_interval -device_add -device_add_disk -device_add_groups -device_attach -device_bind_driver -device_create -device_create_bin_file -device_create_file -device_create_with_groups -device_del -device_destroy -device_find_child -device_for_each_child -device_get_dma_attr -device_get_mac_address -device_get_match_data -device_get_named_child_node -device_get_next_child_node -device_init_wakeup -device_initialize -device_link_add -device_link_del -device_match_fwnode -device_match_name -device_match_of_node -device_property_present -device_property_read_string -device_property_read_string_array -device_property_read_u16_array -device_property_read_u32_array -device_property_read_u8_array -device_register -device_release_driver -device_remove_bin_file -device_remove_file -device_remove_file_self -device_remove_groups -device_set_wakeup_capable -device_set_wakeup_enable -device_show_bool -device_show_int -device_store_bool -device_store_int -device_unregister -device_wakeup_disable -device_wakeup_enable -devm_add_action -devm_backlight_device_register -devm_backlight_device_unregister -devm_blk_ksm_init -devm_clk_bulk_get -devm_clk_bulk_get_all -devm_clk_bulk_get_optional -devm_clk_get -devm_clk_get_optional -devm_clk_hw_register -devm_clk_hw_register_clkdev -devm_clk_put -devm_clk_register -devm_devfreq_add_device -devm_devfreq_register_notifier -devm_devfreq_unregister_notifier -devm_device_add_group -devm_device_add_groups -devm_device_remove_group -devm_drm_panel_bridge_add_typed -devm_extcon_dev_allocate -devm_extcon_dev_register -devm_extcon_dev_unregister -devm_extcon_register_notifier -devm_free_irq -devm_free_percpu -devm_gen_pool_create -devm_get_clk_from_child -devm_gpio_free -devm_gpio_request -devm_gpio_request_one -devm_gpiochip_add_data_with_key -devm_gpiod_get -devm_gpiod_get_array -devm_gpiod_get_index -devm_gpiod_get_optional -devm_gpiod_put_array -devm_hwrng_register -devm_hwspin_lock_register -devm_i2c_new_dummy_device -devm_iio_channel_get -devm_iio_device_alloc -devm_input_allocate_device -devm_ioremap -devm_ioremap_resource -devm_ioremap_wc -devm_iounmap -devm_kasprintf -devm_kfree -devm_kmalloc -devm_kmemdup -devm_kstrdup -devm_kstrdup_const -devm_kvasprintf -devm_led_classdev_register_ext -devm_mbox_controller_register -devm_memremap -devm_mfd_add_devices -devm_nvmem_cell_get -devm_nvmem_device_get -devm_nvmem_register -devm_of_clk_add_hw_provider -devm_of_icc_get -devm_of_iomap -devm_of_platform_populate -devm_of_pwm_get -devm_pci_alloc_host_bridge -devm_phy_create -devm_phy_get -devm_phy_put -devm_pinctrl_get -devm_pinctrl_put -devm_pinctrl_register -devm_pinctrl_register_and_init -devm_platform_get_and_ioremap_resource -devm_platform_ioremap_resource -devm_platform_ioremap_resource_byname -devm_power_supply_register -devm_pwm_put -devm_regmap_add_irq_chip -devm_regmap_del_irq_chip -devm_regmap_field_alloc -devm_regulator_bulk_get -devm_regulator_get -devm_regulator_get_exclusive -devm_regulator_get_optional -devm_regulator_put -devm_regulator_register -devm_regulator_register_notifier -devm_request_any_context_irq -devm_request_threaded_irq -devm_reset_control_array_get -devm_reset_controller_register -devm_rtc_allocate_device -devm_rtc_device_register -devm_snd_dmaengine_pcm_register -devm_snd_soc_register_card -devm_snd_soc_register_component -devm_spi_register_controller -devm_thermal_of_cooling_device_register -devm_thermal_zone_of_sensor_register -devm_thermal_zone_of_sensor_unregister -devm_usb_get_phy -devm_usb_get_phy_by_node -devm_usb_get_phy_by_phandle -devm_watchdog_register_device -devres_add -devres_alloc_node -devres_free -devres_release -disable_irq -disable_irq_nosync -disable_percpu_irq -disk_end_io_acct -disk_start_io_acct -divider_get_val -divider_recalc_rate -divider_ro_round_rate_parent -divider_round_rate_parent -dma_alloc_attrs -dma_async_device_register -dma_async_device_unregister -dma_async_tx_descriptor_init -dma_buf_attach -dma_buf_begin_cpu_access -dma_buf_begin_cpu_access_partial -dma_buf_detach -dma_buf_dynamic_attach -dma_buf_end_cpu_access -dma_buf_end_cpu_access_partial -dma_buf_export -dma_buf_fd -dma_buf_get -dma_buf_get_flags -dma_buf_map_attachment -dma_buf_mmap -dma_buf_move_notify -dma_buf_pin -dma_buf_put -dma_buf_unmap_attachment -dma_buf_unpin -dma_buf_vmap -dma_buf_vunmap -dma_contiguous_default_area -dma_fence_add_callback -dma_fence_array_create -dma_fence_array_ops -dma_fence_context_alloc -dma_fence_default_wait -dma_fence_enable_sw_signaling -dma_fence_free -dma_fence_get_status -dma_fence_get_stub -dma_fence_init -dma_fence_match_context -dma_fence_release -dma_fence_remove_callback -dma_fence_signal -dma_fence_signal_locked -dma_fence_wait_any_timeout -dma_fence_wait_timeout -dma_free_attrs -dma_get_merge_boundary -dma_get_required_mask -dma_get_sgtable_attrs -dma_get_slave_caps -dma_get_slave_channel -dma_heap_add -dma_heap_buffer_alloc -dma_heap_buffer_free -dma_heap_find -dma_heap_get_dev -dma_heap_get_drvdata -dma_heap_get_name -dma_heap_put -dma_map_page_attrs -dma_map_resource -dma_map_sg_attrs -dma_max_mapping_size -dma_mmap_attrs -dma_pool_alloc -dma_pool_create -dma_pool_destroy -dma_pool_free -dma_release_channel -dma_request_chan -dma_resv_add_excl_fence -dma_resv_add_shared_fence -dma_resv_fini -dma_resv_get_fences_rcu -dma_resv_init -dma_resv_reserve_shared -dma_resv_test_signaled_rcu -dma_resv_wait_timeout_rcu -dma_set_coherent_mask -dma_set_mask -dma_sync_sg_for_cpu -dma_sync_sg_for_device -dma_sync_single_for_cpu -dma_sync_single_for_device -dma_unmap_page_attrs -dma_unmap_resource -dma_unmap_sg_attrs -dmabuf_page_pool_alloc -dmabuf_page_pool_create -dmabuf_page_pool_destroy -dmabuf_page_pool_free -dmaengine_unmap_put -dmam_alloc_attrs -dmam_free_coherent -dmam_pool_create -do_SAK -do_exit -do_trace_rcu_torture_read -do_wait_intr -do_wait_intr_irq -down -down_interruptible -down_read -down_read_killable -down_read_trylock -down_timeout -down_trylock -down_write -downgrade_write -dput -drain_workqueue -driver_create_file -driver_find_device -driver_register -driver_remove_file -driver_unregister -drm_add_edid_modes -drm_add_modes_noedid -drm_atomic_add_affected_connectors -drm_atomic_add_affected_planes -drm_atomic_commit -drm_atomic_get_connector_state -drm_atomic_get_crtc_state -drm_atomic_get_new_connector_for_encoder -drm_atomic_get_plane_state -drm_atomic_get_private_obj_state -drm_atomic_helper_bridge_destroy_state -drm_atomic_helper_bridge_duplicate_state -drm_atomic_helper_bridge_reset -drm_atomic_helper_check -drm_atomic_helper_check_modeset -drm_atomic_helper_check_plane_state -drm_atomic_helper_check_planes -drm_atomic_helper_cleanup_planes -drm_atomic_helper_commit -drm_atomic_helper_commit_cleanup_done -drm_atomic_helper_commit_duplicated_state -drm_atomic_helper_commit_hw_done -drm_atomic_helper_commit_modeset_disables -drm_atomic_helper_commit_modeset_enables -drm_atomic_helper_commit_planes -drm_atomic_helper_commit_tail -drm_atomic_helper_connector_destroy_state -drm_atomic_helper_connector_duplicate_state -drm_atomic_helper_connector_reset -drm_atomic_helper_crtc_destroy_state -drm_atomic_helper_crtc_duplicate_state -drm_atomic_helper_crtc_reset -drm_atomic_helper_damage_merged -drm_atomic_helper_dirtyfb -drm_atomic_helper_disable_plane -drm_atomic_helper_disable_planes_on_crtc -drm_atomic_helper_duplicate_state -drm_atomic_helper_fake_vblank -drm_atomic_helper_page_flip -drm_atomic_helper_plane_destroy_state -drm_atomic_helper_plane_duplicate_state -drm_atomic_helper_plane_reset -drm_atomic_helper_prepare_planes -drm_atomic_helper_set_config -drm_atomic_helper_setup_commit -drm_atomic_helper_shutdown -drm_atomic_helper_swap_state -drm_atomic_helper_update_legacy_modeset_state -drm_atomic_helper_update_plane -drm_atomic_helper_wait_for_dependencies -drm_atomic_helper_wait_for_fences -drm_atomic_helper_wait_for_flip_done -drm_atomic_helper_wait_for_vblanks -drm_atomic_normalize_zpos -drm_atomic_private_obj_fini -drm_atomic_private_obj_init -drm_atomic_set_crtc_for_connector -drm_atomic_set_crtc_for_plane -drm_atomic_set_fb_for_plane -drm_atomic_set_fence_for_plane -drm_atomic_set_mode_for_crtc -drm_atomic_state_alloc -drm_atomic_state_clear -drm_atomic_state_default_clear -drm_atomic_state_default_release -drm_atomic_state_init -drm_bridge_add -drm_bridge_attach -drm_bridge_chain_disable -drm_bridge_chain_enable -drm_bridge_chain_mode_set -drm_bridge_chain_post_disable -drm_bridge_chain_pre_enable -drm_bridge_hpd_notify -drm_bridge_remove -drm_client_init -drm_client_modeset_commit_locked -drm_client_register -drm_compat_ioctl -drm_connector_attach_dp_subconnector_property -drm_connector_attach_edid_property -drm_connector_attach_encoder -drm_connector_cleanup -drm_connector_has_possible_encoder -drm_connector_init -drm_connector_init_with_ddc -drm_connector_list_iter_begin -drm_connector_list_iter_end -drm_connector_list_iter_next -drm_connector_register -drm_connector_set_tile_property -drm_connector_unregister -drm_connector_update_edid_property -drm_crtc_arm_vblank_event -drm_crtc_cleanup -drm_crtc_enable_color_mgmt -drm_crtc_from_index -drm_crtc_handle_vblank -drm_crtc_helper_set_config -drm_crtc_helper_set_mode -drm_crtc_init -drm_crtc_init_with_planes -drm_crtc_send_vblank_event -drm_crtc_set_max_vblank_count -drm_crtc_vblank_count -drm_crtc_vblank_count_and_time -drm_crtc_vblank_get -drm_crtc_vblank_helper_get_vblank_timestamp -drm_crtc_vblank_off -drm_crtc_vblank_on -drm_crtc_vblank_put -drm_crtc_vblank_reset -drm_crtc_wait_one_vblank -drm_cvt_mode -drm_debugfs_create_files -drm_detect_hdmi_monitor -drm_detect_monitor_audio -drm_dev_alloc -drm_dev_dbg -drm_dev_enter -drm_dev_exit -drm_dev_get -drm_dev_printk -drm_dev_put -drm_dev_register -drm_dev_set_unique -drm_dev_unplug -drm_dev_unregister -drm_display_mode_to_videomode -drm_do_get_edid -drm_dp_atomic_find_vcpi_slots -drm_dp_atomic_release_vcpi_slots -drm_dp_aux_init -drm_dp_aux_register -drm_dp_aux_unregister -drm_dp_bw_code_to_link_rate -drm_dp_calc_pbn_mode -drm_dp_channel_eq_ok -drm_dp_check_act_status -drm_dp_clock_recovery_ok -drm_dp_dpcd_read -drm_dp_dpcd_read_link_status -drm_dp_dpcd_write -drm_dp_find_vcpi_slots -drm_dp_get_adjust_request_pre_emphasis -drm_dp_get_adjust_request_voltage -drm_dp_get_edid_quirks -drm_dp_link_rate_to_bw_code -drm_dp_link_train_channel_eq_delay -drm_dp_link_train_clock_recovery_delay -drm_dp_mst_allocate_vcpi -drm_dp_mst_deallocate_vcpi -drm_dp_mst_detect_port -drm_dp_mst_get_edid -drm_dp_mst_get_port_malloc -drm_dp_mst_hpd_irq -drm_dp_mst_put_port_malloc -drm_dp_mst_reset_vcpi_slots -drm_dp_mst_topology_mgr_destroy -drm_dp_mst_topology_mgr_init -drm_dp_mst_topology_mgr_set_mst -drm_dp_send_power_updown_phy -drm_dp_set_subconnector_property -drm_dp_update_payload_part1 -drm_dp_update_payload_part2 -drm_edid_block_valid -drm_edid_duplicate -drm_edid_get_monitor_name -drm_edid_header_is_valid -drm_edid_is_valid -drm_edid_to_sad -drm_edid_to_speaker_allocation -drm_encoder_cleanup -drm_encoder_init -drm_event_cancel_free -drm_event_reserve_init -drm_event_reserve_init_locked -drm_fb_cma_get_gem_obj -drm_flip_work_cleanup -drm_flip_work_commit -drm_flip_work_init -drm_flip_work_queue -drm_format_info -drm_framebuffer_cleanup -drm_framebuffer_init -drm_framebuffer_lookup -drm_framebuffer_remove -drm_framebuffer_unregister_private -drm_gem_cma_dumb_create_internal -drm_gem_cma_free_object -drm_gem_cma_mmap -drm_gem_cma_prime_get_sg_table -drm_gem_cma_prime_import_sg_table -drm_gem_cma_prime_mmap -drm_gem_cma_prime_vmap -drm_gem_cma_prime_vunmap -drm_gem_cma_vm_ops -drm_gem_create_mmap_offset -drm_gem_dmabuf_mmap -drm_gem_dmabuf_release -drm_gem_dmabuf_vmap -drm_gem_dmabuf_vunmap -drm_gem_fb_create -drm_gem_fb_create_handle -drm_gem_fb_destroy -drm_gem_fb_get_obj -drm_gem_fb_prepare_fb -drm_gem_free_mmap_offset -drm_gem_get_pages -drm_gem_handle_create -drm_gem_lock_reservations -drm_gem_map_attach -drm_gem_map_detach -drm_gem_map_dma_buf -drm_gem_mmap -drm_gem_mmap_obj -drm_gem_object_free -drm_gem_object_init -drm_gem_object_lookup -drm_gem_object_put_locked -drm_gem_object_release -drm_gem_prime_export -drm_gem_prime_fd_to_handle -drm_gem_prime_handle_to_fd -drm_gem_prime_import -drm_gem_prime_import_dev -drm_gem_prime_mmap -drm_gem_private_object_init -drm_gem_put_pages -drm_gem_shmem_create -drm_gem_shmem_free_object -drm_gem_shmem_get_sg_table -drm_gem_shmem_mmap -drm_gem_shmem_pin -drm_gem_shmem_print_info -drm_gem_shmem_unpin -drm_gem_shmem_vmap -drm_gem_shmem_vunmap -drm_gem_unlock_reservations -drm_gem_unmap_dma_buf -drm_gem_vm_close -drm_gem_vm_open -drm_get_connector_status_name -drm_get_edid -drm_get_format_info -drm_get_format_name -drm_handle_vblank -drm_hdmi_avi_infoframe_from_display_mode -drm_helper_connector_dpms -drm_helper_disable_unused_functions -drm_helper_force_disable_all -drm_helper_hpd_irq_event -drm_helper_mode_fill_fb_struct -drm_helper_probe_single_connector_modes -drm_helper_resume_force_mode -drm_ioctl -drm_irq_install -drm_irq_uninstall -drm_is_current_master -drm_kms_helper_hotplug_event -drm_kms_helper_is_poll_worker -drm_kms_helper_poll_disable -drm_kms_helper_poll_enable -drm_kms_helper_poll_fini -drm_kms_helper_poll_init -drm_match_cea_mode -drm_mm_init -drm_mm_insert_node_in_range -drm_mm_print -drm_mm_remove_node -drm_mm_takedown -drm_mode_config_cleanup -drm_mode_config_helper_resume -drm_mode_config_helper_suspend -drm_mode_config_reset -drm_mode_convert_to_umode -drm_mode_convert_umode -drm_mode_copy -drm_mode_create -drm_mode_create_dp_colorspace_property -drm_mode_create_scaling_mode_property -drm_mode_create_tile_group -drm_mode_crtc_set_gamma_size -drm_mode_debug_printmodeline -drm_mode_destroy -drm_mode_duplicate -drm_mode_equal -drm_mode_equal_no_clocks -drm_mode_get_tile_group -drm_mode_is_420_only -drm_mode_match -drm_mode_object_find -drm_mode_object_get -drm_mode_object_put -drm_mode_probed_add -drm_mode_set_crtcinfo -drm_mode_set_name -drm_mode_vrefresh -drm_modeset_acquire_fini -drm_modeset_acquire_init -drm_modeset_backoff -drm_modeset_drop_locks -drm_modeset_lock -drm_modeset_lock_all -drm_modeset_lock_all_ctx -drm_modeset_lock_init -drm_modeset_unlock -drm_modeset_unlock_all -drm_need_swiotlb -drm_object_attach_property -drm_object_property_set_value -drm_of_component_match_add -drm_of_find_possible_crtcs -drm_open -drm_panel_add -drm_panel_disable -drm_panel_enable -drm_panel_get_modes -drm_panel_init -drm_panel_prepare -drm_panel_remove -drm_panel_unprepare -drm_plane_cleanup -drm_plane_create_alpha_property -drm_plane_create_blend_mode_property -drm_plane_create_rotation_property -drm_plane_create_zpos_property -drm_plane_enable_fb_damage_clips -drm_poll -drm_prime_gem_destroy -drm_prime_pages_to_sg -drm_prime_sg_to_page_addr_arrays -drm_printf -drm_property_blob_get -drm_property_blob_put -drm_property_create -drm_property_create_bitmask -drm_property_create_blob -drm_property_create_bool -drm_property_create_enum -drm_property_create_range -drm_property_create_signed_range -drm_property_lookup_blob -drm_property_replace_blob -drm_puts -drm_read -drm_rect_calc_hscale -drm_rect_calc_vscale -drm_rect_clip_scaled -drm_rect_intersect -drm_release -drm_rotation_simplify -drm_send_event -drm_send_event_locked -drm_set_preferred_mode -drm_simple_encoder_init -drm_state_dump -drm_syncobj_add_point -drm_syncobj_create -drm_syncobj_find -drm_syncobj_find_fence -drm_syncobj_free -drm_syncobj_get_fd -drm_syncobj_get_handle -drm_syncobj_replace_fence -drm_sysfs_hotplug_event -drm_universal_plane_init -drm_vblank_init -drm_vma_node_allow -drm_vma_node_is_allowed -drm_vma_node_revoke -drm_wait_one_vblank -drm_writeback_connector_init -drm_writeback_queue_job -drm_writeback_signal_completion -drmm_kmalloc -drmm_mode_config_init -dst_release -dump_backtrace -dump_stack -dup_iter -dw_handle_msi_irq -dw_pcie_host_init -dw_pcie_msi_init -dw_pcie_own_conf_map_bus -dw_pcie_read -dw_pcie_setup_rc -dw_pcie_write -dwc3_send_gadget_ep_cmd -dwc3_stop_active_transfer -edac_device_add_device -edac_device_alloc_ctl_info -edac_device_alloc_index -edac_device_del_device -edac_device_free_ctl_info -edac_device_handle_ce_count -edac_device_handle_ue_count -efi -efi_tpm_final_log_size -elevator_alloc -elv_bio_merge_ok -elv_rb_add -elv_rb_del -elv_rb_find -elv_rb_former_request -elv_rb_latter_request -elv_register -elv_rqhash_add -elv_rqhash_del -elv_unregister -emergency_restart -enable_irq -enable_percpu_irq -eth_commit_mac_addr_change -eth_mac_addr -eth_platform_get_mac_address -eth_prepare_mac_addr_change -eth_type_trans -eth_validate_addr -ether_setup -ethtool_op_get_link -ethtool_op_get_ts_info -ethtool_virtdev_set_link_ksettings -event_triggers_call -eventfd_ctx_fdget -eventfd_ctx_fileget -eventfd_ctx_put -eventfd_ctx_remove_wait_queue -eventfd_signal -extcon_find_edev_by_node -extcon_get_edev_by_phandle -extcon_get_edev_name -extcon_get_extcon_dev -extcon_get_property -extcon_get_state -extcon_register_notifier -extcon_set_property -extcon_set_property_capability -extcon_set_state_sync -extcon_unregister_notifier -fasync_helper -fd_install -fget -file_path -file_ra_state_init -filp_close -filp_open_block -find_get_pid -find_last_bit -find_next_bit -find_next_zero_bit -find_snd_usb_substream -find_task_by_vpid -find_vma -find_vpid -finish_wait -firmware_request_nowarn -fixed_size_llseek -flow_keys_basic_dissector -flush_dcache_page -flush_delayed_work -flush_signals -flush_work -flush_workqueue -fput -frame_vector_create -frame_vector_destroy -frame_vector_to_pages -free_buffer_head -free_io_pgtable_ops -free_irq -free_netdev -free_pages -free_pages_exact -free_percpu -free_percpu_irq -freezing_slow_path -freq_qos_add_request -freq_qos_remove_request -freq_qos_update_request -freq_scale -fs_bio_set -fsync_bdev -ftrace_dump -full_name_hash -fwnode_find_reference -fwnode_get_name -fwnode_get_named_child_node -fwnode_get_next_child_node -fwnode_gpiod_get_index -fwnode_handle_get -fwnode_handle_put -fwnode_property_present -fwnode_property_read_string -fwnode_property_read_u32_array -fwnode_usb_role_switch_get -gcd -gen_pool_add_owner -gen_pool_alloc_algo_owner -gen_pool_avail -gen_pool_best_fit -gen_pool_create -gen_pool_destroy -gen_pool_dma_alloc_align -gen_pool_dma_zalloc_align -gen_pool_first_fit_align -gen_pool_first_fit_order_align -gen_pool_free_owner -gen_pool_has_addr -gen_pool_set_algo -gen_pool_size -gen_pool_virt_to_phys -generic_delete_inode -generic_device_group -generic_file_llseek -generic_file_read_iter -generic_handle_irq -generic_iommu_put_resv_regions -generic_mii_ioctl -generic_perform_write -generic_write_checks -genl_notify -genl_register_family -genl_unregister_family -genlmsg_put -genphy_resume -get_cpu_device -get_cpu_idle_time -get_cpu_idle_time_us -get_cpu_iowait_time_us -get_device -get_device_system_crosststamp -get_governor_parent_kobj -get_next_ino -get_option -get_options -get_pid_task -get_random_bytes -get_random_bytes_arch -get_random_u32 -get_random_u64 -get_sg_io_hdr -get_state_synchronize_rcu -get_task_exe_file -get_task_mm -get_task_pid -get_thermal_instance -get_tree_single -get_unmapped_area -get_unused_fd_flags -get_user_pages -get_user_pages_fast -get_user_pages_remote -get_vaddr_frames -get_zeroed_page -getboottime64 -gfp_zone -gic_nonsecure_priorities -glob_match -gnss_allocate_device -gnss_deregister_device -gnss_insert_raw -gnss_put_device -gnss_register_device -gov_attr_set_get -gov_attr_set_init -gov_attr_set_put -governor_sysfs_ops -gpio_free -gpio_free_array -gpio_request -gpio_request_one -gpio_to_desc -gpiochip_add_data_with_key -gpiochip_add_pin_range -gpiochip_find -gpiochip_generic_config -gpiochip_generic_free -gpiochip_generic_request -gpiochip_get_data -gpiochip_line_is_valid -gpiochip_lock_as_irq -gpiochip_populate_parent_fwspec_fourcell -gpiochip_remove -gpiochip_unlock_as_irq -gpiod_cansleep -gpiod_count -gpiod_direction_input -gpiod_direction_output -gpiod_direction_output_raw -gpiod_get_optional -gpiod_get_raw_value -gpiod_get_raw_value_cansleep -gpiod_get_value -gpiod_get_value_cansleep -gpiod_set_consumer_name -gpiod_set_debounce -gpiod_set_raw_value -gpiod_set_raw_value_cansleep -gpiod_set_value -gpiod_set_value_cansleep -gpiod_to_chip -gpiod_to_irq -gro_cells_destroy -gro_cells_init -gro_cells_receive -gserial_alloc_line -gserial_connect -gserial_disconnect -guid_gen -handle_bad_irq -handle_edge_irq -handle_fasteoi_ack_irq -handle_fasteoi_irq -handle_level_irq -handle_nested_irq -handle_simple_irq -handle_sysrq -hash_digest_size -hashlen_string -have_governor_per_policy -hci_alloc_dev -hci_free_dev -hci_recv_frame -hci_register_dev -hci_unregister_dev -hdmi_audio_infoframe_init -hdmi_audio_infoframe_pack -hdmi_avi_infoframe_init -hdmi_avi_infoframe_pack -hdmi_infoframe_pack -hex2bin -hex_dump_to_buffer -hex_to_bin -hmm_range_fault -hrtimer_active -hrtimer_cancel -hrtimer_forward -hrtimer_init -hrtimer_init_sleeper -hrtimer_sleeper_start_expires -hrtimer_start_range_ns -hrtimer_try_to_cancel -hvc_alloc -hvc_instantiate -hvc_kick -hvc_poll -hvc_remove -hwrng_register -hwrng_unregister -hwspin_lock_free -hwspin_lock_request_specific -hypervisor_kobj -i2c_adapter_type -i2c_add_adapter -i2c_add_numbered_adapter -i2c_bit_add_bus -i2c_bit_add_numbered_bus -i2c_bus_type -i2c_client_type -i2c_del_adapter -i2c_del_driver -i2c_for_each_dev -i2c_generic_scl_recovery -i2c_get_adapter -i2c_get_device_id -i2c_get_dma_safe_msg_buf -i2c_match_id -i2c_new_ancillary_device -i2c_new_client_device -i2c_new_dummy_device -i2c_new_scanned_device -i2c_parse_fw_timings -i2c_put_adapter -i2c_put_dma_safe_msg_buf -i2c_recover_bus -i2c_register_driver -i2c_smbus_read_byte -i2c_smbus_read_byte_data -i2c_smbus_read_i2c_block_data -i2c_smbus_read_word_data -i2c_smbus_write_byte -i2c_smbus_write_byte_data -i2c_smbus_write_i2c_block_data -i2c_smbus_write_word_data -i2c_smbus_xfer -i2c_transfer -i2c_transfer_buffer_flags -i2c_unregister_device -i2c_verify_adapter -i2c_verify_client -icc_disable -icc_enable -icc_get -icc_link_create -icc_node_add -icc_node_create -icc_node_del -icc_node_destroy -icc_nodes_remove -icc_provider_add -icc_provider_del -icc_put -icc_set_bw -icc_set_tag -icc_std_aggregate -icc_sync_state -ida_alloc_range -ida_destroy -ida_free -idr_alloc -idr_alloc_cyclic -idr_alloc_u32 -idr_destroy -idr_find -idr_for_each -idr_get_next -idr_preload -idr_remove -idr_replace -ieee802154_alloc_hw -ieee802154_free_hw -ieee802154_register_hw -ieee802154_rx_irqsafe -ieee802154_unregister_hw -ieee802154_wake_queue -ieee802154_xmit_complete -iio_buffer_init -iio_buffer_put -iio_channel_get -iio_channel_get_all -iio_channel_release -iio_device_alloc -iio_device_attach_buffer -iio_device_free -iio_device_unregister -iio_push_to_buffers -iio_read_channel_processed -iio_read_channel_raw -import_iovec -in4_pton -in6_pton -in_aton -in_egroup_p -inc_zone_page_state -inet_proto_csum_replace4 -init_dummy_netdev -init_iova_domain -init_net -init_on_free -init_pid_ns -init_pseudo -init_srcu_struct -init_task -init_timer_key -init_uts_ns -init_wait_entry -input_alloc_absinfo -input_allocate_device -input_close_device -input_event -input_ff_create -input_ff_destroy -input_free_device -input_mt_assign_slots -input_mt_destroy_slots -input_mt_drop_unused -input_mt_init_slots -input_mt_report_finger_count -input_mt_report_pointer_emulation -input_mt_report_slot_state -input_mt_sync_frame -input_open_device -input_register_device -input_register_handle -input_register_handler -input_set_abs_params -input_set_capability -input_set_timestamp -input_unregister_device -input_unregister_handle -input_unregister_handler -int_pow -int_sqrt -interval_tree_insert -interval_tree_iter_first -interval_tree_iter_next -interval_tree_remove -invalidate_bdev -invalidate_mapping_pages -io_schedule_timeout -iomem_resource -iommu_alloc_resv_region -iommu_attach_device -iommu_attach_group -iommu_aux_attach_device -iommu_aux_detach_device -iommu_aux_get_pasid -iommu_detach_device -iommu_detach_group -iommu_dev_enable_feature -iommu_dev_feature_enabled -iommu_device_register -iommu_device_sysfs_add -iommu_device_sysfs_remove -iommu_device_unlink -iommu_device_unregister -iommu_dma_enable_best_fit_algo -iommu_dma_get_resv_regions -iommu_dma_reserve_iova -iommu_domain_alloc -iommu_domain_free -iommu_domain_get_attr -iommu_domain_set_attr -iommu_fwspec_add_ids -iommu_fwspec_free -iommu_get_dma_cookie -iommu_get_domain_for_dev -iommu_get_msi_cookie -iommu_group_alloc -iommu_group_for_each_dev -iommu_group_get -iommu_group_get_iommudata -iommu_group_put -iommu_group_ref_get -iommu_group_set_iommudata -iommu_group_set_name -iommu_iova_to_phys -iommu_map -iommu_map_sg -iommu_present -iommu_put_dma_cookie -iommu_register_device_fault_handler -iommu_report_device_fault -iommu_set_fault_handler -iommu_unmap -iommu_unregister_device_fault_handler -iounmap -iov_iter_bvec -iov_iter_kvec -ip_compute_csum -ip_send_check -ipi_desc_get -iput -ipv6_ext_hdr -ipv6_find_hdr -ipv6_skip_exthdr -irq_chip_ack_parent -irq_chip_disable_parent -irq_chip_enable_parent -irq_chip_eoi_parent -irq_chip_get_parent_state -irq_chip_mask_parent -irq_chip_retrigger_hierarchy -irq_chip_set_affinity_parent -irq_chip_set_parent_state -irq_chip_set_type_parent -irq_chip_set_vcpu_affinity_parent -irq_chip_set_wake_parent -irq_chip_unmask_parent -irq_create_fwspec_mapping -irq_create_mapping_affinity -irq_create_of_mapping -irq_dispose_mapping -irq_domain_alloc_irqs_parent -irq_domain_create_hierarchy -irq_domain_free_irqs_common -irq_domain_free_irqs_parent -irq_domain_get_irq_data -irq_domain_remove -irq_domain_set_hwirq_and_chip -irq_domain_set_info -irq_domain_simple_ops -irq_domain_update_bus_token -irq_domain_xlate_onecell -irq_domain_xlate_onetwocell -irq_domain_xlate_twocell -irq_find_mapping -irq_find_matching_fwspec -irq_get_irq_data -irq_get_irqchip_state -irq_modify_status -irq_of_parse_and_map -irq_set_affinity_hint -irq_set_affinity_notifier -irq_set_chained_handler_and_data -irq_set_chip -irq_set_chip_and_handler_name -irq_set_chip_data -irq_set_handler_data -irq_set_irq_type -irq_set_irq_wake -irq_set_irqchip_state -irq_set_parent -irq_to_desc -irq_work_queue -irq_work_queue_on -irq_work_sync -is_dma_buf_file -is_vmalloc_addr -jiffies -jiffies64_to_msecs -jiffies_64_to_clock_t -jiffies_to_msecs -jiffies_to_usecs -kasan_flag_enabled -kasprintf -kern_mount -kern_unmount -kernel_bind -kernel_connect -kernel_cpustat -kernel_getsockname -kernel_kobj -kernel_power_off -kernel_recvmsg -kernel_restart -kernel_sendmsg -kernel_sigaction -kernfs_find_and_get_ns -kernfs_notify -kernfs_put -kfree -kfree_const -kfree_sensitive -kfree_skb -kick_all_cpus_sync -kill_anon_super -kill_fasync -kill_litter_super -kimage_vaddr -kimage_voffset -kiocb_set_cancel_fn -kmalloc_caches -kmalloc_order -kmalloc_order_trace -kmem_cache_alloc -kmem_cache_alloc_trace -kmem_cache_create -kmem_cache_create_usercopy -kmem_cache_destroy -kmem_cache_free -kmemdup -kmemdup_nul -kmsg_dump_get_line -kmsg_dump_rewind -kobj_sysfs_ops -kobject_add -kobject_create_and_add -kobject_del -kobject_get -kobject_init -kobject_init_and_add -kobject_put -kobject_set_name -kobject_uevent -kobject_uevent_env -krealloc -kset_create_and_add -ksize -ksoftirqd -kstat -kstat_irqs_cpu -kstat_irqs_usr -kstrdup -kstrdup_const -kstrdup_quotable_cmdline -kstrndup -kstrtobool -kstrtobool_from_user -kstrtoint -kstrtoint_from_user -kstrtol_from_user -kstrtoll -kstrtos8 -kstrtos8_from_user -kstrtou16 -kstrtou16_from_user -kstrtou8 -kstrtou8_from_user -kstrtouint -kstrtouint_from_user -kstrtoul_from_user -kstrtoull -kstrtoull_from_user -ksys_sync_helper -kthread_bind -kthread_bind_mask -kthread_cancel_delayed_work_sync -kthread_cancel_work_sync -kthread_create_on_node -kthread_create_worker -kthread_delayed_work_timer_fn -kthread_destroy_worker -kthread_flush_work -kthread_flush_worker -kthread_mod_delayed_work -kthread_park -kthread_parkme -kthread_queue_delayed_work -kthread_queue_work -kthread_should_park -kthread_should_stop -kthread_stop -kthread_unpark -kthread_unuse_mm -kthread_use_mm -kthread_worker_fn -ktime_add_safe -ktime_get -ktime_get_coarse_with_offset -ktime_get_mono_fast_ns -ktime_get_raw -ktime_get_raw_ts64 -ktime_get_real_seconds -ktime_get_real_ts64 -ktime_get_seconds -ktime_get_ts64 -ktime_get_with_offset -kvasprintf -kvfree -kvfree_call_rcu -kvmalloc_node -led_classdev_flash_register_ext -led_classdev_flash_unregister -led_classdev_register_ext -led_classdev_unregister -led_trigger_event -led_trigger_register_simple -led_trigger_unregister_simple -list_sort -llist_add_batch -llist_reverse_order -lock_sock_nested -log_abnormal_wakeup_reason -log_buf_addr_get -log_buf_len_get -log_threaded_irq_wakeup_reason -loops_per_jiffy -lzo1x_1_compress -lzo1x_decompress_safe -lzorle1x_1_compress -mac_pton -match_string -mbox_chan_received_data -mbox_chan_txdone -mbox_client_txdone -mbox_controller_register -mbox_controller_unregister -mbox_free_channel -mbox_request_channel -mbox_send_message -mdiobus_alloc_size -mdiobus_free -mdiobus_unregister -media_device_cleanup -media_device_init -media_device_unregister -media_entity_pads_init -memblock_end_of_DRAM -memblock_free -memchr -memchr_inv -memcmp -memcpy -memdup_user -memdup_user_nul -memmove -memory_block_size_bytes -memory_read_from_buffer -memparse -mempool_alloc -mempool_alloc_slab -mempool_create -mempool_create_node -mempool_destroy -mempool_exit -mempool_free -mempool_free_slab -mempool_init -mempool_kfree -mempool_kmalloc -memremap -memset -memset64 -memstart_addr -memunmap -mfd_add_devices -mfd_remove_devices -migrate_swap -mii_check_media -mii_ethtool_get_link_ksettings -mii_ethtool_gset -mii_ethtool_set_link_ksettings -mii_link_ok -mii_nway_restart -mipi_dsi_attach -mipi_dsi_compression_mode -mipi_dsi_create_packet -mipi_dsi_dcs_read -mipi_dsi_dcs_set_column_address -mipi_dsi_dcs_set_display_brightness -mipi_dsi_dcs_set_page_address -mipi_dsi_dcs_set_tear_off -mipi_dsi_dcs_write_buffer -mipi_dsi_detach -mipi_dsi_device_register_full -mipi_dsi_device_unregister -mipi_dsi_driver_register_full -mipi_dsi_driver_unregister -mipi_dsi_host_register -mipi_dsi_host_unregister -mipi_dsi_packet_format_is_long -mipi_dsi_picture_parameter_set -misc_deregister -misc_register -mktime64 -mm_trace_rss_stat -mmc_add_host -mmc_alloc_host -mmc_app_cmd -mmc_calc_max_discard -mmc_can_erase -mmc_can_gpio_cd -mmc_can_secure_erase_trim -mmc_can_trim -mmc_cmdq_disable -mmc_cmdq_enable -mmc_cqe_post_req -mmc_cqe_recovery -mmc_cqe_request_done -mmc_cqe_start_req -mmc_detect_card_removed -mmc_detect_change -mmc_erase -mmc_erase_group_aligned -mmc_flush_cache -mmc_free_host -mmc_get_card -mmc_get_ext_csd -mmc_gpio_get_cd -mmc_gpio_get_ro -mmc_gpiod_request_cd -mmc_gpiod_request_cd_irq -mmc_gpiod_request_ro -mmc_hw_reset -mmc_of_parse -mmc_of_parse_voltage -mmc_put_card -mmc_register_driver -mmc_regulator_get_supply -mmc_regulator_set_ocr -mmc_regulator_set_vqmmc -mmc_release_host -mmc_remove_host -mmc_request_done -mmc_retune_pause -mmc_retune_release -mmc_retune_unpause -mmc_run_bkops -mmc_sanitize -mmc_send_status -mmc_send_tuning -mmc_set_data_timeout -mmc_start_request -mmc_switch -mmc_unregister_driver -mmc_wait_for_cmd -mmc_wait_for_req -mmput -mmu_interval_notifier_insert -mmu_interval_notifier_remove -mmu_interval_read_begin -mmu_notifier_synchronize -mod_delayed_work_on -mod_node_page_state -mod_timer -module_layout -module_put -msleep -msleep_interruptible -mutex_is_locked -mutex_lock -mutex_lock_interruptible -mutex_trylock -mutex_trylock_recursive -mutex_unlock -name_to_dev_t -names_cachep -napi_complete_done -napi_consume_skb -napi_disable -napi_gro_flush -napi_gro_receive -napi_schedule_prep -net_namespace_list -net_ratelimit -netdev_change_features -netdev_err -netdev_increment_features -netdev_info -netdev_lower_state_changed -netdev_master_upper_dev_link -netdev_notify_peers -netdev_pick_tx -netdev_rx_handler_register -netdev_rx_handler_unregister -netdev_state_change -netdev_update_features -netdev_upper_dev_link -netdev_upper_dev_unlink -netdev_warn -netif_carrier_off -netif_carrier_on -netif_device_attach -netif_device_detach -netif_napi_add -netif_receive_skb -netif_receive_skb_list -netif_rx -netif_rx_ni -netif_schedule_queue -netif_set_real_num_rx_queues -netif_set_real_num_tx_queues -netif_stacked_transfer_operstate -netif_tx_stop_all_queues -netif_tx_wake_queue -netlink_ack -netlink_broadcast -netlink_capable -netlink_has_listeners -netlink_kernel_release -netlink_register_notifier -netlink_unicast -netlink_unregister_notifier -new_inode -nf_conntrack_destroy -nla_append -nla_find -nla_memcpy -nla_put -nla_put_64bit -nla_put_nohdr -nla_reserve -nla_reserve_64bit -nla_strlcpy -no_llseek -no_seek_end_llseek -nonseekable_open -noop_llseek -nr_cpu_ids -nr_ipi_get -nr_irqs -ns_capable -ns_to_timespec64 -nsec_to_clock_t -nsecs_to_jiffies -nvdimm_bus_register -nvdimm_bus_unregister -nvdimm_pmem_region_create -nvmem_cell_get -nvmem_cell_put -nvmem_cell_read -nvmem_cell_read_u32 -nvmem_cell_write -nvmem_device_put -nvmem_device_read -nvmem_device_write -of_address_to_resource -of_alias_get_highest_id -of_alias_get_id -of_clk_add_hw_provider -of_clk_add_provider -of_clk_del_provider -of_clk_get -of_clk_get_by_name -of_clk_get_from_provider -of_clk_get_parent_count -of_clk_get_parent_name -of_clk_hw_onecell_get -of_clk_hw_simple_get -of_clk_set_defaults -of_clk_src_onecell_get -of_clk_src_simple_get -of_count_phandle_with_args -of_cpu_node_to_id -of_cpufreq_cooling_register -of_devfreq_cooling_register -of_devfreq_cooling_register_power -of_device_get_match_data -of_device_is_available -of_device_is_compatible -of_device_modalias -of_device_request_module -of_device_uevent_modalias -of_dma_configure_id -of_dma_controller_free -of_dma_controller_register -of_dma_is_coherent -of_drm_find_bridge -of_drm_find_panel -of_find_all_nodes -of_find_compatible_node -of_find_device_by_node -of_find_i2c_adapter_by_node -of_find_i2c_device_by_node -of_find_matching_node_and_match -of_find_mipi_dsi_host_by_node -of_find_node_by_name -of_find_node_by_phandle -of_find_node_by_type -of_find_node_opts_by_path -of_find_node_with_property -of_find_property -of_fwnode_ops -of_genpd_add_provider_onecell -of_genpd_add_provider_simple -of_genpd_del_provider -of_get_address -of_get_child_by_name -of_get_compatible_child -of_get_cpu_node -of_get_dma_window -of_get_named_gpio_flags -of_get_next_available_child -of_get_next_child -of_get_next_parent -of_get_parent -of_get_property -of_get_regulator_init_data -of_graph_get_endpoint_by_regs -of_graph_get_next_endpoint -of_graph_get_port_parent -of_graph_get_remote_endpoint -of_graph_get_remote_node -of_graph_get_remote_port -of_graph_get_remote_port_parent -of_graph_is_present -of_graph_parse_endpoint -of_hwspin_lock_get_id -of_i2c_get_board_info -of_icc_get -of_icc_xlate_onecell -of_iomap -of_irq_find_parent -of_irq_get -of_irq_get_byname -of_irq_parse_one -of_machine_is_compatible -of_match_device -of_match_node -of_modalias_node -of_n_addr_cells -of_n_size_cells -of_node_name_eq -of_nvmem_device_get -of_parse_phandle -of_parse_phandle_with_args -of_parse_phandle_with_fixed_args -of_phandle_iterator_init -of_phandle_iterator_next -of_phy_simple_xlate -of_platform_depopulate -of_platform_device_create -of_platform_device_destroy -of_platform_populate -of_prop_next_string -of_prop_next_u32 -of_property_count_elems_of_size -of_property_match_string -of_property_read_string -of_property_read_string_helper -of_property_read_u32_index -of_property_read_u64 -of_property_read_u64_index -of_property_read_variable_u16_array -of_property_read_variable_u32_array -of_property_read_variable_u64_array -of_property_read_variable_u8_array -of_pwm_xlate_with_flags -of_reserved_mem_device_init_by_idx -of_reserved_mem_device_release -of_reserved_mem_lookup -of_reset_control_array_get -of_root -of_thermal_get_ntrips -of_thermal_get_trip_points -of_thermal_is_trip_valid -of_translate_address -of_usb_get_phy_mode -of_usb_host_tpl_support -on_each_cpu -oops_in_progress -orderly_poweroff -overflowuid -page_endio -page_mapping -page_reporting_register -page_reporting_unregister -panic -panic_notifier_list -panic_timeout -param_array_ops -param_get_int -param_get_string -param_get_uint -param_get_ullong -param_ops_bint -param_ops_bool -param_ops_byte -param_ops_charp -param_ops_hexint -param_ops_int -param_ops_long -param_ops_short -param_ops_string -param_ops_uint -param_ops_ullong -param_ops_ulong -param_ops_ushort -param_set_bool -param_set_copystring -param_set_int -param_set_uint -part_end_io_acct -part_start_io_acct -passthru_features_check -pause_cpus -pci_alloc_irq_vectors_affinity -pci_assign_resource -pci_assign_unassigned_bus_resources -pci_bus_resource_n -pci_bus_type -pci_clear_master -pci_d3cold_disable -pci_dev_present -pci_dev_put -pci_device_group -pci_device_is_present -pci_disable_device -pci_disable_msi -pci_enable_atomic_ops_to_root -pci_enable_device -pci_enable_device_mem -pci_enable_msi -pci_enable_wake -pci_find_bus -pci_find_capability -pci_find_ext_capability -pci_find_next_capability -pci_free_irq -pci_free_irq_vectors -pci_generic_config_read -pci_generic_config_write -pci_get_device -pci_get_domain_bus_and_slot -pci_get_slot -pci_host_probe -pci_intx -pci_iomap -pci_iomap_range -pci_ioremap_bar -pci_irq_get_affinity -pci_irq_vector -pci_load_and_free_saved_state -pci_load_saved_state -pci_map_rom -pci_match_id -pci_msi_create_irq_domain -pci_msi_mask_irq -pci_msi_unmask_irq -pci_msix_vec_count -pci_read_config_byte -pci_read_config_dword -pci_read_config_word -pci_release_region -pci_release_regions -pci_release_resource -pci_release_selected_regions -pci_request_irq -pci_request_region -pci_request_regions -pci_request_selected_regions -pci_rescan_bus -pci_resize_resource -pci_restore_msi_state -pci_restore_state -pci_save_state -pci_select_bars -pci_set_master -pci_set_mwi -pci_set_power_state -pci_store_saved_state -pci_unmap_rom -pci_unregister_driver -pci_wake_from_d3 -pci_walk_bus -pci_write_config_byte -pci_write_config_dword -pci_write_config_word -pcibios_resource_to_bus -pcie_aspm_enabled -pcie_bandwidth_available -pcie_capability_read_word -pcie_capability_write_word -pcie_get_mps -pcie_get_speed_cap -pcim_enable_device -per_cpu_ptr_to_phys -percpu_down_write -percpu_ref_exit -percpu_ref_init -percpu_ref_is_zero -percpu_ref_kill_and_confirm -percpu_ref_switch_to_atomic_sync -percpu_ref_switch_to_percpu -percpu_up_write -perf_aux_output_begin -perf_aux_output_end -perf_aux_output_flag -perf_event_addr_filters_sync -perf_event_create_kernel_counter -perf_event_disable -perf_event_enable -perf_event_pause -perf_event_read_local -perf_event_read_value -perf_event_release_kernel -perf_event_update_userpage -perf_get_aux -perf_pmu_migrate_context -perf_pmu_register -perf_pmu_unregister -perf_trace_buf_alloc -perf_trace_run_bpf_submit -pfn_valid -phy_calibrate -phy_configure -phy_connect -phy_disconnect -phy_do_ioctl_running -phy_ethtool_get_link_ksettings -phy_ethtool_nway_reset -phy_ethtool_set_link_ksettings -phy_exit -phy_init -phy_pm_runtime_get_sync -phy_pm_runtime_put_sync -phy_power_off -phy_power_on -phy_print_status -phy_set_mode_ext -phy_start -phy_stop -pick_highest_pushable_task -pid_nr_ns -pid_task -pin_get_name -pin_user_pages -pin_user_pages_fast -pin_user_pages_remote -pinconf_generic_dt_free_map -pinconf_generic_dt_node_to_map -pinctrl_add_gpio_range -pinctrl_dev_get_drvdata -pinctrl_enable -pinctrl_force_default -pinctrl_force_sleep -pinctrl_get -pinctrl_lookup_state -pinctrl_pm_select_default_state -pinctrl_pm_select_idle_state -pinctrl_pm_select_sleep_state -pinctrl_put -pinctrl_remove_gpio_range -pinctrl_select_default_state -pinctrl_select_state -pinctrl_utils_free_map -pipe_lock -pipe_unlock -pktgen_xfrm_outer_mode_output -platform_add_devices -platform_bus_type -platform_device_add -platform_device_add_data -platform_device_add_properties -platform_device_add_resources -platform_device_alloc -platform_device_del -platform_device_put -platform_device_register -platform_device_register_full -platform_device_unregister -platform_driver_unregister -platform_find_device_by_driver -platform_get_irq -platform_get_irq_byname -platform_get_irq_byname_optional -platform_get_irq_optional -platform_get_resource -platform_get_resource_byname -platform_irq_count -pm_clk_add -pm_clk_create -pm_clk_destroy -pm_clk_resume -pm_clk_suspend -pm_generic_resume -pm_generic_runtime_resume -pm_generic_runtime_suspend -pm_generic_suspend -pm_genpd_add_subdomain -pm_genpd_init -pm_genpd_remove -pm_genpd_remove_subdomain -pm_power_off -pm_relax -pm_runtime_allow -pm_runtime_autosuspend_expiration -pm_runtime_barrier -pm_runtime_enable -pm_runtime_forbid -pm_runtime_force_resume -pm_runtime_force_suspend -pm_runtime_get_if_active -pm_runtime_irq_safe -pm_runtime_no_callbacks -pm_runtime_set_autosuspend_delay -pm_stay_awake -pm_suspend_global_flags -pm_system_wakeup -pm_wakeup_dev_event -pm_wakeup_ws_event -policy_has_boost_freq -power_supply_changed -power_supply_get_by_name -power_supply_get_by_phandle_array -power_supply_get_drvdata -power_supply_get_property -power_supply_is_system_supplied -power_supply_put -power_supply_reg_notifier -power_supply_register -power_supply_set_property -power_supply_unreg_notifier -power_supply_unregister -prandom_bytes -prandom_u32 -preempt_schedule -preempt_schedule_notrace -prepare_to_wait -prepare_to_wait_event -print_hex_dump -printk -printk_deferred -printk_timed_ratelimit -proc_create -proc_create_data -proc_create_single_data -proc_dointvec -proc_dointvec_minmax -proc_dostring -proc_douintvec_minmax -proc_mkdir -proc_mkdir_data -proc_remove -proc_set_size -proc_set_user -proc_symlink -proto_register -proto_unregister -ps2_begin_command -ps2_cmd_aborted -ps2_command -ps2_drain -ps2_end_command -ps2_handle_ack -ps2_handle_response -ps2_init -ps2_sendbyte -ps2_sliced_command -pskb_expand_head -pstore_register -pstore_unregister -put_device -put_disk -put_iova_domain -put_pid -put_sg_io_hdr -put_unused_fd -put_vaddr_frames -pwm_apply_state -pwm_get_chip_data -pwm_set_chip_data -pwmchip_add -pwmchip_remove -qcom_smem_state_get -qcom_smem_state_register -qcom_smem_state_unregister -qcom_smem_state_update_bits -qdisc_reset -queue_delayed_work_on -queue_work_on -radix_tree_delete -radix_tree_insert -radix_tree_iter_delete -radix_tree_iter_resume -radix_tree_lookup -radix_tree_maybe_preload -radix_tree_next_chunk -radix_tree_tagged -rational_best_approximation -raw_notifier_call_chain -raw_notifier_chain_register -raw_notifier_chain_unregister -rb_erase -rb_first -rb_first_postorder -rb_insert_color -rb_last -rb_next -rb_next_postorder -rb_prev -rb_replace_node -rcu_barrier -rcu_barrier_tasks -rcu_barrier_tasks_trace -rcu_bind_current_to_nocb -rcu_cpu_stall_suppress -rcu_cpu_stall_suppress_at_boot -rcu_expedite_gp -rcu_force_quiescent_state -rcu_fwd_progress_check -rcu_get_gp_kthreads_prio -rcu_get_gp_seq -rcu_gp_is_expedited -rcu_gp_is_normal -rcu_gp_set_torture_wait -rcu_inkernel_boot_has_ended -rcu_is_watching -rcu_jiffies_till_stall_check -rcu_read_unlock_trace_special -rcu_unexpedite_gp -rcutorture_get_gp_data -rcuwait_wake_up -rdev_get_drvdata -rdev_get_id -reboot_mode -reciprocal_value -refcount_dec_and_lock -refcount_dec_and_mutex_lock -refcount_dec_not_one -refcount_warn_saturate -refresh_frequency_limits -regcache_cache_bypass -regcache_cache_only -regcache_drop_region -regcache_mark_dirty -regcache_sync -regcache_sync_region -register_blkdev -register_chrdev_region -register_console -register_die_notifier -register_filesystem -register_ftrace_export -register_inet6addr_notifier -register_inetaddr_notifier -register_kernel_break_hook -register_kprobe -register_kretprobe -register_memory_notifier -register_module_notifier -register_net_sysctl -register_netdev -register_netdevice -register_netdevice_notifier -register_netevent_notifier -register_oom_notifier -register_pernet_device -register_pernet_subsys -register_pm_notifier -register_reboot_notifier -register_restart_handler -register_shrinker -register_syscore_ops -register_sysctl -register_sysctl_table -register_virtio_device -register_virtio_driver -register_vmap_purge_notifier -regmap_add_irq_chip -regmap_async_complete -regmap_bulk_read -regmap_bulk_write -regmap_check_range_table -regmap_del_irq_chip -regmap_exit -regmap_field_read -regmap_field_update_bits_base -regmap_get_device -regmap_irq_get_domain -regmap_irq_get_virq -regmap_mmio_detach_clk -regmap_multi_reg_write -regmap_multi_reg_write_bypassed -regmap_raw_read -regmap_raw_write -regmap_raw_write_async -regmap_read -regmap_register_patch -regmap_update_bits_base -regmap_write -regulator_allow_bypass -regulator_bulk_disable -regulator_bulk_enable -regulator_bulk_get -regulator_count_voltages -regulator_disable -regulator_disable_deferred -regulator_disable_regmap -regulator_enable -regulator_enable_regmap -regulator_force_disable -regulator_get -regulator_get_current_limit -regulator_get_drvdata -regulator_get_mode -regulator_get_optional -regulator_get_voltage -regulator_get_voltage_rdev -regulator_get_voltage_sel_regmap -regulator_is_enabled -regulator_is_enabled_regmap -regulator_is_supported_voltage -regulator_list_voltage_linear -regulator_list_voltage_linear_range -regulator_list_voltage_table -regulator_map_voltage_ascend -regulator_map_voltage_linear -regulator_notifier_call_chain -regulator_put -regulator_register -regulator_register_notifier -regulator_set_current_limit -regulator_set_load -regulator_set_mode -regulator_set_voltage -regulator_set_voltage_sel_regmap -regulator_unregister -regulator_unregister_notifier -release_firmware -release_pages -release_sock -remap_pfn_range -remap_vmalloc_range -remove_cpu -remove_memory_subsection -remove_proc_entry -remove_wait_queue -report_iommu_fault -request_any_context_irq -request_firmware -request_firmware_direct -request_firmware_into_buf -request_firmware_nowait -request_threaded_irq -resched_curr -reservation_ww_class -reset_control_assert -reset_control_deassert -reset_control_put -reset_control_reset -resume_cpus -return_address -revalidate_disk_size -rfkill_alloc -rfkill_destroy -rfkill_find_type -rfkill_init_sw_state -rfkill_register -rfkill_set_sw_state -rfkill_unregister -rhashtable_destroy -rhashtable_init -rhashtable_insert_slow -rht_bucket_nested -rht_bucket_nested_insert -rndis_deregister -rndis_free_response -rndis_get_next_response -rndis_msg_parser -rndis_register -rndis_set_host_mac -rndis_set_param_dev -rndis_set_param_medium -rndis_set_param_vendor -rndis_signal_connect -rndis_uninit -root_task_group -round_jiffies_relative -round_jiffies_up -rpmsg_get_signals -rpmsg_poll -rpmsg_register_device -rpmsg_send -rpmsg_set_signals -rpmsg_trysend -rpmsg_unregister_device -rproc_add -rproc_add_subdev -rproc_alloc -rproc_boot -rproc_coredump_add_custom_segment -rproc_coredump_add_segment -rproc_coredump_set_elf_info -rproc_coredump_using_sections -rproc_del -rproc_elf_get_boot_addr -rproc_free -rproc_get_by_child -rproc_get_by_phandle -rproc_put -rproc_remove_subdev -rproc_report_crash -rproc_shutdown -rps_needed -rt_mutex_lock -rt_mutex_trylock -rt_mutex_unlock -rtc_class_close -rtc_class_open -rtc_read_time -rtc_set_time -rtc_time64_to_tm -rtc_tm_to_time64 -rtc_update_irq -rtc_valid_tm -rtc_year_days -rtnl_is_locked -rtnl_link_register -rtnl_link_unregister -rtnl_lock -rtnl_register_module -rtnl_trylock -rtnl_unicast -rtnl_unlock -rtnl_unregister -runqueues -sb800_prefetch -sbitmap_queue_min_shallow_depth -sched_clock -sched_feat_keys -sched_feat_names -sched_set_fifo -sched_set_fifo_low -sched_set_normal -sched_setattr -sched_setattr_nocheck -sched_setscheduler -sched_setscheduler_nocheck -sched_show_task -sched_trace_cfs_rq_avg -sched_trace_cfs_rq_cpu -sched_trace_cfs_rq_path -sched_trace_rd_span -sched_trace_rq_avg_dl -sched_trace_rq_avg_irq -sched_trace_rq_avg_rt -sched_trace_rq_cpu -sched_uclamp_used -schedule -schedule_hrtimeout -schedule_timeout -schedule_timeout_interruptible -schedule_timeout_uninterruptible -scnprintf -scsi_autopm_get_device -scsi_autopm_put_device -scsi_block_requests -scsi_block_when_processing_errors -scsi_command_size_tbl -scsi_compat_ioctl -scsi_device_get -scsi_device_put -scsi_device_quiesce -scsi_eh_ready_devs -scsi_ioctl -scsi_ioctl_block_when_processing_errors -scsi_normalize_sense -scsi_print_sense_hdr -scsi_register_interface -scsi_remove_device -scsi_unblock_requests -sdev_prefix_printk -sdhci_add_host -sdhci_cleanup_host -sdhci_cqe_disable -sdhci_cqe_enable -sdhci_cqe_irq -sdhci_enable_clk -sdhci_get_property -sdhci_pltfm_free -sdhci_pltfm_init -sdhci_remove_host -sdhci_reset -sdhci_set_bus_width -sdhci_set_power_noreg -sdhci_setup_host -sdio_claim_host -sdio_disable_func -sdio_enable_func -sdio_f0_readb -sdio_f0_writeb -sdio_get_host_pm_caps -sdio_memcpy_fromio -sdio_memcpy_toio -sdio_readsb -sdio_register_driver -sdio_release_host -sdio_set_block_size -sdio_set_host_pm_flags -sdio_signal_irq -sdio_unregister_driver -sdio_writesb -securityfs_create_dir -securityfs_create_file -securityfs_remove -seq_buf_printf -seq_file_path -seq_hex_dump -seq_list_next -seq_list_start -seq_lseek -seq_open -seq_printf -seq_putc -seq_puts -seq_read -seq_release -seq_release_private -seq_vprintf -seq_write -serdev_device_close -serdev_device_open -serdev_device_set_baudrate -serdev_device_set_flow_control -serdev_device_wait_until_sent -serdev_device_write -serdev_device_write_wakeup -serio_close -serio_interrupt -serio_open -serio_reconnect -serio_rescan -serio_unregister_child_port -serio_unregister_driver -serio_unregister_port -set_blocksize -set_capacity_revalidate_and_notify -set_cpus_allowed_ptr -set_disk_ro -set_freezable -set_normalized_timespec64 -set_page_dirty -set_page_dirty_lock -set_task_cpu -set_user_nice -sg_alloc_table -sg_alloc_table_from_pages -sg_free_table -sg_init_one -sg_init_table -sg_miter_next -sg_miter_start -sg_miter_stop -sg_nents_for_len -sg_next -sg_pcopy_from_buffer -sg_pcopy_to_buffer -sg_scsi_ioctl -sg_zero_buffer -sgl_alloc -sgl_free -shmem_truncate_range -show_rcu_gp_kthreads -show_regs -si_mem_available -si_meminfo -si_swapinfo -sigprocmask -simple_attr_open -simple_attr_read -simple_attr_release -simple_attr_write -simple_dir_inode_operations -simple_dir_operations -simple_open -simple_read_from_buffer -simple_statfs -simple_strtol -simple_strtoll -simple_strtoul -simple_strtoull -simple_write_to_buffer -single_open -single_open_size -single_release -sk_alloc -sk_free -skb_add_rx_frag -skb_append_pagefrags -skb_checksum -skb_clone -skb_coalesce_rx_frag -skb_copy -skb_copy_bits -skb_copy_datagram_iter -skb_copy_expand -skb_copy_ubufs -skb_dequeue -skb_dequeue_tail -skb_ensure_writable -skb_free_datagram -skb_page_frag_refill -skb_partial_csum_set -skb_pull -skb_push -skb_put -skb_queue_head -skb_queue_purge -skb_queue_tail -skb_realloc_headroom -skb_recv_datagram -skb_set_owner_w -skb_store_bits -skb_to_sgvec -skb_trim -skb_tstamp_tx -skb_unlink -skip_spaces -smp_call_function -smp_call_function_any -smp_call_function_many -smp_call_function_single -smp_call_on_cpu -smpboot_register_percpu_thread -smpboot_unregister_percpu_thread -snd_card_disconnect -snd_card_free -snd_card_new -snd_card_register -snd_card_rw_proc_new -snd_component_add -snd_compr_stop_error -snd_ctl_add -snd_ctl_add_vmaster_hook -snd_ctl_apply_vmaster_followers -snd_ctl_boolean_mono_info -snd_ctl_boolean_stereo_info -snd_ctl_enum_info -snd_ctl_find_id -snd_ctl_make_virtual_master -snd_ctl_new1 -snd_ctl_notify -snd_ctl_remove -snd_ctl_remove_id -snd_ctl_sync_vmaster -snd_device_disconnect -snd_device_free -snd_device_new -snd_dma_alloc_pages -snd_dma_free_pages -snd_dmaengine_pcm_prepare_slave_config -snd_hwdep_new -snd_info_create_card_entry -snd_info_create_module_entry -snd_info_free_entry -snd_info_register -snd_interval_refine -snd_jack_new -snd_jack_report -snd_jack_set_key -snd_pci_quirk_lookup -snd_pcm_add_chmap_ctls -snd_pcm_alt_chmaps -snd_pcm_create_iec958_consumer_hw_params -snd_pcm_format_physical_width -snd_pcm_format_width -snd_pcm_hw_constraint_eld -snd_pcm_hw_constraint_integer -snd_pcm_hw_constraint_list -snd_pcm_hw_constraint_minmax -snd_pcm_hw_constraint_msbits -snd_pcm_hw_constraint_step -snd_pcm_hw_limit_rates -snd_pcm_hw_rule_add -snd_pcm_lib_default_mmap -snd_pcm_lib_free_pages -snd_pcm_lib_ioctl -snd_pcm_lib_malloc_pages -snd_pcm_lib_preallocate_free_for_all -snd_pcm_lib_preallocate_pages -snd_pcm_new -snd_pcm_period_elapsed -snd_pcm_rate_range_to_bits -snd_pcm_set_managed_buffer_all -snd_pcm_set_ops -snd_pcm_set_sync -snd_pcm_std_chmaps -snd_pcm_stream_lock -snd_pcm_stream_unlock -snd_pcm_stream_unlock_irqrestore -snd_soc_add_card_controls -snd_soc_add_component_controls -snd_soc_add_dai_controls -snd_soc_bytes_info_ext -snd_soc_bytes_tlv_callback -snd_soc_card_get_kcontrol -snd_soc_card_jack_new -snd_soc_component_async_complete -snd_soc_component_disable_pin -snd_soc_component_exit_regmap -snd_soc_component_force_enable_pin -snd_soc_component_init_regmap -snd_soc_component_read -snd_soc_component_set_jack -snd_soc_component_set_pll -snd_soc_component_set_sysclk -snd_soc_component_update_bits -snd_soc_component_update_bits_async -snd_soc_component_write -snd_soc_dai_get_channel_map -snd_soc_dai_link_set_capabilities -snd_soc_dai_set_bclk_ratio -snd_soc_dai_set_channel_map -snd_soc_dai_set_fmt -snd_soc_dai_set_pll -snd_soc_dai_set_sysclk -snd_soc_dai_set_tdm_slot -snd_soc_dapm_add_routes -snd_soc_dapm_disable_pin -snd_soc_dapm_disable_pin_unlocked -snd_soc_dapm_enable_pin -snd_soc_dapm_force_enable_pin -snd_soc_dapm_force_enable_pin_unlocked -snd_soc_dapm_get_enum_double -snd_soc_dapm_get_pin_status -snd_soc_dapm_get_pin_switch -snd_soc_dapm_get_volsw -snd_soc_dapm_ignore_suspend -snd_soc_dapm_info_pin_switch -snd_soc_dapm_kcontrol_dapm -snd_soc_dapm_kcontrol_widget -snd_soc_dapm_mixer_update_power -snd_soc_dapm_mux_update_power -snd_soc_dapm_new_control -snd_soc_dapm_new_controls -snd_soc_dapm_new_widgets -snd_soc_dapm_put_enum_double -snd_soc_dapm_put_pin_switch -snd_soc_dapm_put_volsw -snd_soc_dapm_sync -snd_soc_dapm_sync_unlocked -snd_soc_dapm_weak_routes -snd_soc_find_dai -snd_soc_get_enum_double -snd_soc_get_pcm_runtime -snd_soc_get_volsw -snd_soc_get_volsw_range -snd_soc_get_volsw_sx -snd_soc_get_xr_sx -snd_soc_info_enum_double -snd_soc_info_multi_ext -snd_soc_info_volsw -snd_soc_info_volsw_range -snd_soc_info_volsw_sx -snd_soc_info_xr_sx -snd_soc_jack_add_gpios -snd_soc_jack_report -snd_soc_lookup_component -snd_soc_new_compress -snd_soc_of_get_dai_link_codecs -snd_soc_of_get_dai_name -snd_soc_of_parse_audio_routing -snd_soc_of_parse_audio_simple_widgets -snd_soc_of_parse_aux_devs -snd_soc_of_parse_card_name -snd_soc_of_parse_daifmt -snd_soc_of_parse_node_prefix -snd_soc_of_parse_tdm_slot -snd_soc_of_put_dai_link_codecs -snd_soc_params_to_bclk -snd_soc_params_to_frame_size -snd_soc_pm_ops -snd_soc_put_enum_double -snd_soc_put_volsw -snd_soc_put_volsw_range -snd_soc_put_volsw_sx -snd_soc_put_xr_sx -snd_soc_register_card -snd_soc_register_component -snd_soc_rtdcom_lookup -snd_soc_runtime_calc_hw -snd_soc_runtime_set_dai_fmt -snd_soc_set_runtime_hwparams -snd_soc_tplg_component_load -snd_soc_tplg_component_remove -snd_soc_tplg_widget_bind_event -snd_soc_unregister_card -snd_soc_unregister_component -snd_usb_enable_audio_stream -snd_vendor_set_ops -snprintf -soc_device_register -soc_device_unregister -sock_alloc_send_skb -sock_create_kern -sock_gettstamp -sock_i_uid -sock_init_data -sock_no_accept -sock_no_listen -sock_no_mmap -sock_no_sendpage -sock_no_shutdown -sock_no_socketpair -sock_queue_rcv_skb -sock_register -sock_release -sock_setsockopt -sock_unregister -sock_wfree -softnet_data -sort -spi_bus_lock -spi_bus_type -spi_bus_unlock -spi_controller_resume -spi_controller_suspend -spi_delay_exec -spi_finalize_current_message -spi_finalize_current_transfer -spi_get_next_queued_message -spi_register_controller -spi_setup -spi_sync -spi_sync_locked -spi_unregister_controller -split_page -spmi_controller_add -spmi_controller_alloc -spmi_controller_remove -spmi_ext_register_read -spmi_ext_register_readl -spmi_ext_register_write -spmi_ext_register_writel -spmi_register_read -spmi_register_write -spmi_register_zero_write -sprint_symbol -sprintf -srcu_barrier -srcu_batches_completed -srcu_init_notifier_head -srcu_notifier_call_chain -srcu_notifier_chain_register -srcu_notifier_chain_unregister -srcu_torture_stats_print -srcutorture_get_gp_data -sscanf -stack_trace_print -stack_trace_save -stack_trace_save_tsk -static_key_disable -static_key_disable_cpuslocked -static_key_slow_dec -static_key_slow_inc -stop_machine -stop_one_cpu_nowait -stpcpy -strcasecmp -strcat -strchr -strchrnul -strcmp -strcpy -strcspn -stream_open -strim -string_get_size -strlcat -strlcpy -strlen -strncasecmp -strncat -strnchr -strncmp -strncpy -strncpy_from_user -strndup_user -strnlen -strnstr -strpbrk -strrchr -strreplace -strscpy -strsep -strspn -strstr -submit_bh -submit_bio -submit_bio_wait -subsys_system_register -swiotlb_nr_tbl -sync_blockdev -sync_file_create -sync_file_get_fence -synchronize_irq -synchronize_net -synchronize_rcu -synchronize_rcu_expedited -synchronize_rcu_tasks -synchronize_rcu_tasks_trace -synchronize_srcu -synchronize_srcu_expedited -sys_tz -syscon_node_to_regmap -syscon_regmap_lookup_by_phandle -sysctl_sched_features -sysctl_sched_latency -sysctl_vals -sysfs_add_file_to_group -sysfs_add_link_to_group -sysfs_create_bin_file -sysfs_create_file_ns -sysfs_create_files -sysfs_create_group -sysfs_create_groups -sysfs_create_link -sysfs_emit -sysfs_emit_at -sysfs_notify -sysfs_remove_bin_file -sysfs_remove_file_from_group -sysfs_remove_file_ns -sysfs_remove_files -sysfs_remove_group -sysfs_remove_groups -sysfs_remove_link -sysfs_remove_link_from_group -sysfs_streq -sysfs_update_group -sysrq_mask -system_freezable_wq -system_freezing_cnt -system_highpri_wq -system_long_wq -system_power_efficient_wq -system_state -system_unbound_wq -system_wq -task_active_pid_ns -task_groups -task_may_not_preempt -task_rq_lock -tasklet_init -tasklet_kill -tasklet_setup -tasklist_lock -tcpci_get_tcpm_port -tcpci_irq -tcpci_register_port -tcpci_unregister_port -tcpm_cc_change -tcpm_is_toggling -tcpm_pd_hard_reset -tcpm_pd_receive -tcpm_pd_transmit_complete -tcpm_sink_frs -tcpm_sourcing_vbus -tcpm_update_sink_capabilities -tcpm_vbus_change -thermal_cdev_update -thermal_cooling_device_register -thermal_cooling_device_unregister -thermal_of_cooling_device_register -thermal_pressure -thermal_zone_device_disable -thermal_zone_device_enable -thermal_zone_device_is_enabled -thermal_zone_device_register -thermal_zone_device_unregister -thermal_zone_device_update -thermal_zone_get_slope -thermal_zone_get_temp -thermal_zone_get_zone_by_name -thermal_zone_of_sensor_register -thermal_zone_of_sensor_unregister -thread_group_cputime_adjusted -tick_nohz_get_idle_calls_cpu -tick_nohz_get_sleep_length -time64_to_tm -timecounter_init -timecounter_read -timer_unstable_counter_workaround -topology_set_thermal_pressure -total_swapcache_pages -trace_clock_local -trace_event_buffer_commit -trace_event_buffer_reserve -trace_event_ignore_this_pid -trace_event_raw_init -trace_event_reg -trace_handle_return -trace_output_call -trace_print_array_seq -trace_print_flags_seq -trace_print_hex_seq -trace_print_symbols_seq -trace_raw_output_prep -trace_seq_printf -trace_seq_putc -tracepoint_probe_register -tracepoint_probe_register_prio -tracepoint_probe_unregister -tracing_off -try_module_get -try_to_del_timer_sync -try_wait_for_completion -ttm_bo_bulk_move_lru_tail -ttm_bo_device_init -ttm_bo_device_release -ttm_bo_dma_acc_size -ttm_bo_evict_mm -ttm_bo_eviction_valuable -ttm_bo_glob -ttm_bo_init_reserved -ttm_bo_kmap -ttm_bo_kunmap -ttm_bo_lock_delayed_workqueue -ttm_bo_mem_space -ttm_bo_mmap -ttm_bo_mmap_obj -ttm_bo_move_accel_cleanup -ttm_bo_move_memcpy -ttm_bo_move_to_lru_tail -ttm_bo_move_ttm -ttm_bo_put -ttm_bo_unlock_delayed_workqueue -ttm_bo_validate -ttm_dma_page_alloc_debugfs -ttm_dma_populate -ttm_dma_tt_fini -ttm_dma_unpopulate -ttm_eu_backoff_reservation -ttm_eu_fence_buffer_objects -ttm_eu_reserve_buffers -ttm_page_alloc_debugfs -ttm_populate_and_map_pages -ttm_range_man_fini -ttm_range_man_init -ttm_resource_free -ttm_resource_manager_force_list_clean -ttm_resource_manager_init -ttm_sg_tt_init -ttm_tt_destroy_common -ttm_tt_populate -ttm_tt_set_placement_caching -ttm_unmap_and_unpopulate_pages -tty_flip_buffer_push -tty_insert_flip_string_fixed_flag -tty_kref_put -tty_port_tty_get -tty_termios_baud_rate -tty_termios_encode_baud_rate -typec_altmode_get_partner -typec_altmode_update_active -typec_get_drvdata -typec_partner_register_altmode -typec_port_register_altmode -typec_register_partner -typec_register_port -typec_set_data_role -typec_set_pwr_opmode -typec_set_pwr_role -typec_switch_get_drvdata -typec_switch_register -typec_switch_unregister -typec_unregister_altmode -typec_unregister_partner -typec_unregister_port -uart_add_one_port -uart_console_device -uart_console_write -uart_get_baud_rate -uart_insert_char -uart_parse_options -uart_register_driver -uart_remove_one_port -uart_resume_port -uart_set_options -uart_suspend_port -uart_try_toggle_sysrq -uart_unregister_driver -uart_update_timeout -uart_write_wakeup -uclamp_eff_value -ucsi_connector_change -ucsi_create -ucsi_destroy -ucsi_get_drvdata -ucsi_register -ucsi_set_drvdata -ucsi_unregister -udp4_hwcsum -ufshcd_auto_hibern8_update -ufshcd_bkops_ctrl -ufshcd_dme_get_attr -ufshcd_dme_set_attr -ufshcd_dump_regs -ufshcd_fixup_dev_quirks -ufshcd_get_local_unipro_ver -ufshcd_get_pwr_dev_param -ufshcd_hold -ufshcd_map_desc_id_to_length -ufshcd_pltfrm_init -ufshcd_pltfrm_resume -ufshcd_pltfrm_runtime_idle -ufshcd_pltfrm_runtime_resume -ufshcd_pltfrm_runtime_suspend -ufshcd_pltfrm_shutdown -ufshcd_pltfrm_suspend -ufshcd_query_attr -ufshcd_query_attr_retry -ufshcd_query_descriptor_retry -ufshcd_query_flag -ufshcd_query_flag_retry -ufshcd_read_desc_param -ufshcd_release -ufshcd_remove -ufshcd_shutdown -ufshcd_system_resume -ufshcd_system_suspend -ufshcd_uic_hibern8_enter -ufshcd_uic_hibern8_exit -uio_unregister_device -unlock_page -unmap_mapping_range -unpin_user_page -unregister_blkdev -unregister_chrdev_region -unregister_console -unregister_die_notifier -unregister_filesystem -unregister_ftrace_export -unregister_inet6addr_notifier -unregister_inetaddr_notifier -unregister_kprobe -unregister_kretprobe -unregister_module_notifier -unregister_netdev -unregister_netdevice_many -unregister_netdevice_notifier -unregister_netdevice_queue -unregister_netevent_notifier -unregister_oom_notifier -unregister_pernet_device -unregister_pernet_subsys -unregister_pm_notifier -unregister_reboot_notifier -unregister_restart_handler -unregister_rpmsg_driver -unregister_shrinker -unregister_syscore_ops -unregister_sysctl_table -unregister_virtio_device -unregister_virtio_driver -unregister_vmap_purge_notifier -up -up_read -up_write -update_devfreq -update_rq_clock -usb_add_function -usb_add_gadget -usb_add_gadget_udc -usb_add_hcd -usb_add_phy_dev -usb_alloc_coherent -usb_alloc_dev -usb_alloc_urb -usb_amd_dev_put -usb_amd_prefetch_quirk -usb_amd_pt_check_port -usb_amd_quirk_pll_check -usb_amd_quirk_pll_disable -usb_amd_quirk_pll_enable -usb_asmedia_modifyflowcontrol -usb_assign_descriptors -usb_autopm_get_interface -usb_autopm_put_interface -usb_bulk_msg -usb_calc_bus_time -usb_choose_configuration -usb_composite_setup_continue -usb_control_msg -usb_copy_descriptors -usb_create_hcd -usb_debug_root -usb_decode_ctrl -usb_del_gadget_udc -usb_deregister -usb_disable_xhci_ports -usb_disabled -usb_enable_autosuspend -usb_enable_intel_xhci_ports -usb_ep_alloc_request -usb_ep_autoconfig -usb_ep_clear_halt -usb_ep_dequeue -usb_ep_disable -usb_ep_enable -usb_ep_fifo_flush -usb_ep_fifo_status -usb_ep_free_request -usb_ep_queue -usb_ep_set_halt -usb_ep_set_maxpacket_limit -usb_find_common_endpoints -usb_free_all_descriptors -usb_free_coherent -usb_free_urb -usb_function_register -usb_function_unregister -usb_gadget_giveback_request -usb_gadget_map_request_by_dev -usb_gadget_probe_driver -usb_gadget_set_state -usb_gadget_udc_reset -usb_gadget_unmap_request_by_dev -usb_gadget_unregister_driver -usb_gadget_vbus_connect -usb_gadget_vbus_disconnect -usb_gadget_vbus_draw -usb_gadget_wakeup -usb_get_dr_mode -usb_get_gadget_udc_name -usb_get_maximum_speed -usb_get_urb -usb_gstrings_attach -usb_hc_died -usb_hcd_check_unlink_urb -usb_hcd_end_port_resume -usb_hcd_giveback_urb -usb_hcd_irq -usb_hcd_is_primary_hcd -usb_hcd_link_urb_to_ep -usb_hcd_map_urb_for_dma -usb_hcd_pci_pm_ops -usb_hcd_pci_probe -usb_hcd_pci_remove -usb_hcd_pci_shutdown -usb_hcd_platform_shutdown -usb_hcd_poll_rh_status -usb_hcd_resume_root_hub -usb_hcd_start_port_resume -usb_hcd_unlink_urb_from_ep -usb_hcds_loaded -usb_hub_clear_tt_buffer -usb_hub_find_child -usb_ifnum_to_if -usb_initialize_gadget -usb_interface_id -usb_kill_urb -usb_otg_state_string -usb_phy_set_charger_current -usb_poison_urb -usb_put_dev -usb_put_function_instance -usb_put_hcd -usb_register_driver -usb_register_notify -usb_remove_hcd -usb_remove_phy -usb_role_switch_find_by_fwnode -usb_role_switch_get -usb_role_switch_get_drvdata -usb_role_switch_put -usb_role_switch_register -usb_role_switch_set_role -usb_role_switch_unregister -usb_root_hub_lost_power -usb_set_device_state -usb_speed_string -usb_string_id -usb_submit_urb -usb_unregister_notify -usb_wakeup_notification -usbnet_change_mtu -usbnet_disconnect -usbnet_get_drvinfo -usbnet_get_endpoints -usbnet_get_link -usbnet_get_link_ksettings -usbnet_get_msglevel -usbnet_get_stats64 -usbnet_link_change -usbnet_nway_reset -usbnet_open -usbnet_probe -usbnet_read_cmd -usbnet_read_cmd_nopm -usbnet_resume -usbnet_set_link_ksettings -usbnet_set_msglevel -usbnet_skb_return -usbnet_start_xmit -usbnet_stop -usbnet_suspend -usbnet_tx_timeout -usbnet_unlink_rx_urbs -usbnet_update_max_qlen -usbnet_write_cmd -usbnet_write_cmd_async -usbnet_write_cmd_nopm -usleep_range -uuid_gen -uuid_null -uuid_parse -v4l2_compat_ioctl32 -v4l2_ctrl_find -v4l2_ctrl_handler_free -v4l2_ctrl_handler_init_class -v4l2_ctrl_handler_setup -v4l2_ctrl_log_status -v4l2_ctrl_new_custom -v4l2_ctrl_new_std -v4l2_ctrl_new_std_menu -v4l2_device_register -v4l2_device_register_subdev -v4l2_device_set_name -v4l2_device_unregister -v4l2_device_unregister_subdev -v4l2_event_dequeue -v4l2_event_pending -v4l2_event_queue -v4l2_event_queue_fh -v4l2_event_subscribe -v4l2_event_unsubscribe -v4l2_fh_add -v4l2_fh_del -v4l2_fh_exit -v4l2_fh_init -v4l2_fh_open -v4l2_fh_release -v4l2_i2c_subdev_init -v4l2_m2m_buf_queue -v4l2_m2m_buf_remove -v4l2_m2m_ctx_init -v4l2_m2m_ctx_release -v4l2_m2m_dqbuf -v4l2_m2m_fop_mmap -v4l2_m2m_fop_poll -v4l2_m2m_get_curr_priv -v4l2_m2m_get_vq -v4l2_m2m_init -v4l2_m2m_ioctl_dqbuf -v4l2_m2m_ioctl_querybuf -v4l2_m2m_ioctl_reqbufs -v4l2_m2m_ioctl_streamoff -v4l2_m2m_ioctl_streamon -v4l2_m2m_job_finish -v4l2_m2m_mmap -v4l2_m2m_next_buf -v4l2_m2m_poll -v4l2_m2m_qbuf -v4l2_m2m_querybuf -v4l2_m2m_release -v4l2_m2m_reqbufs -v4l2_m2m_streamoff -v4l2_m2m_streamon -v4l2_m2m_try_schedule -v4l2_s_ctrl -v4l2_subdev_call_wrappers -v4l2_subdev_init -v4l_bound_align_image -vabits_actual -vb2_buffer_done -vb2_common_vm_ops -vb2_create_framevec -vb2_destroy_framevec -vb2_dqbuf -vb2_fop_mmap -vb2_fop_poll -vb2_fop_read -vb2_fop_release -vb2_ioctl_create_bufs -vb2_ioctl_dqbuf -vb2_ioctl_expbuf -vb2_ioctl_qbuf -vb2_ioctl_querybuf -vb2_ioctl_reqbufs -vb2_ioctl_streamoff -vb2_ioctl_streamon -vb2_mmap -vb2_ops_wait_finish -vb2_ops_wait_prepare -vb2_plane_cookie -vb2_plane_vaddr -vb2_poll -vb2_prepare_buf -vb2_qbuf -vb2_querybuf -vb2_queue_init -vb2_queue_release -vb2_reqbufs -vb2_streamoff -vb2_streamon -vb2_vmalloc_memops -vb2_wait_for_all_buffers -vchan_dma_desc_free_list -vchan_find_desc -vchan_init -vchan_tx_desc_free -vchan_tx_submit -vfree -vfs_fsync_range -video_devdata -video_device_alloc -video_device_release -video_device_release_empty -video_ioctl2 -video_unregister_device -virtio_check_driver_offered_feature -virtio_config_changed -virtio_device_freeze -virtio_device_restore -virtio_max_dma_size -virtio_transport_connect -virtio_transport_deliver_tap_pkt -virtio_transport_destruct -virtio_transport_dgram_allow -virtio_transport_dgram_bind -virtio_transport_dgram_dequeue -virtio_transport_dgram_enqueue -virtio_transport_do_socket_init -virtio_transport_free_pkt -virtio_transport_notify_buffer_size -virtio_transport_notify_poll_in -virtio_transport_notify_poll_out -virtio_transport_notify_recv_init -virtio_transport_notify_recv_post_dequeue -virtio_transport_notify_recv_pre_block -virtio_transport_notify_recv_pre_dequeue -virtio_transport_notify_send_init -virtio_transport_notify_send_post_enqueue -virtio_transport_notify_send_pre_block -virtio_transport_notify_send_pre_enqueue -virtio_transport_recv_pkt -virtio_transport_release -virtio_transport_shutdown -virtio_transport_stream_allow -virtio_transport_stream_dequeue -virtio_transport_stream_enqueue -virtio_transport_stream_has_data -virtio_transport_stream_has_space -virtio_transport_stream_is_active -virtio_transport_stream_rcvhiwat -virtqueue_add_inbuf -virtqueue_add_inbuf_ctx -virtqueue_add_outbuf -virtqueue_add_sgs -virtqueue_detach_unused_buf -virtqueue_disable_cb -virtqueue_enable_cb -virtqueue_enable_cb_delayed -virtqueue_enable_cb_prepare -virtqueue_get_avail_addr -virtqueue_get_buf -virtqueue_get_buf_ctx -virtqueue_get_desc_addr -virtqueue_get_used_addr -virtqueue_get_vring_size -virtqueue_is_broken -virtqueue_kick -virtqueue_kick_prepare -virtqueue_notify -virtqueue_poll -vm_event_states -vm_get_page_prot -vm_insert_page -vm_iomap_memory -vm_map_pages -vm_map_ram -vm_mmap -vm_munmap -vm_node_stat -vm_unmap_ram -vm_zone_stat -vmalloc -vmalloc_nr_pages -vmalloc_to_page -vmalloc_to_pfn -vmalloc_user -vmap -vmemdup_user -vmf_insert_mixed -vmf_insert_pfn -vmf_insert_pfn_prot -vprintk -vring_create_virtqueue -vring_del_virtqueue -vring_interrupt -vring_new_virtqueue -vring_transport_features -vscnprintf -vsnprintf -vsock_core_register -vsock_core_unregister -vsock_for_each_connected_socket -vsprintf -vunmap -vzalloc -vzalloc_node -wait_for_completion -wait_for_completion_interruptible -wait_for_completion_interruptible_timeout -wait_for_completion_io_timeout -wait_for_completion_killable -wait_for_completion_killable_timeout -wait_for_completion_timeout -wait_woken -wake_up_if_idle -wake_up_process -wakeup_source_add -wakeup_source_create -wakeup_source_destroy -wakeup_source_register -wakeup_source_remove -wakeup_source_unregister -watchdog_init_timeout -watchdog_register_device -watchdog_set_restart_priority -watchdog_unregister_device -wireless_send_event -woken_wake_function -work_busy -ww_mutex_lock -ww_mutex_lock_interruptible -ww_mutex_unlock -xa_destroy -xa_erase -xa_find -xa_find_after -xa_load -xa_store -xdp_convert_zc_to_xdp_frame -xdp_do_flush -xdp_do_redirect -xdp_return_frame -xdp_return_frame_rx_napi -xdp_rxq_info_reg -xdp_rxq_info_reg_mem_model -xdp_rxq_info_unreg -xdp_warn -xfrm_state_lookup_byspi -xfrm_stateonly_find -xhci_add_endpoint -xhci_address_device -xhci_alloc_command -xhci_alloc_erst -xhci_check_trb_in_td_math -xhci_free_command -xhci_free_erst -xhci_gen_setup -xhci_get_endpoint_index -xhci_get_ep_ctx -xhci_get_slot_ctx -xhci_handle_event -xhci_init_driver -xhci_initialize_ring_info -xhci_link_segments -xhci_queue_stop_endpoint -xhci_resume -xhci_ring_alloc -xhci_ring_cmd_db -xhci_ring_free -xhci_run -xhci_segment_free -xhci_suspend -xhci_trb_virt_to_dma -xhci_update_erst_dequeue -xhci_vendor_get_ops -zone_watermark_ok -zone_watermark_ok_safe diff --git a/android/abi_gki_aarch64_generic b/android/abi_gki_aarch64_generic index 46db0cd8e0b5..40f3010480af 100644 --- a/android/abi_gki_aarch64_generic +++ b/android/abi_gki_aarch64_generic @@ -24,8 +24,6 @@ amba_driver_unregister android_rvh_probe_register anon_inode_getfd - arc4_crypt - arc4_setkey __arch_clear_user __arch_copy_from_user __arch_copy_in_user @@ -41,6 +39,7 @@ atomic_notifier_chain_unregister autoremove_wake_function available_idle_cpu + backlight_device_set_brightness bcmp bdget_disk bdput @@ -55,7 +54,6 @@ __bitmap_andnot __bitmap_clear __bitmap_equal - bitmap_from_arr32 __bitmap_or bitmap_parse bitmap_parselist @@ -87,7 +85,6 @@ blocking_notifier_chain_unregister bpf_trace_run1 bpf_trace_run10 - bpf_trace_run11 bpf_trace_run12 bpf_trace_run2 bpf_trace_run3 @@ -96,7 +93,6 @@ bpf_trace_run6 bpf_trace_run7 bpf_trace_run8 - bpf_trace_run9 build_skb bus_find_device bus_for_each_dev @@ -107,7 +103,6 @@ bus_unregister bus_unregister_notifier cache_line_size - call_rcu cancel_delayed_work cancel_delayed_work_sync cancel_work_sync @@ -118,6 +113,34 @@ cdev_device_add cdev_device_del cdev_init + __cfg80211_alloc_event_skb + __cfg80211_alloc_reply_skb + cfg80211_chandef_create + cfg80211_ch_switch_notify + cfg80211_connect_done + cfg80211_del_sta_sinfo + cfg80211_disconnected + cfg80211_external_auth_request + cfg80211_find_elem_match + cfg80211_get_bss + cfg80211_ibss_joined + cfg80211_inform_bss_frame_data + cfg80211_mgmt_tx_status + cfg80211_michael_mic_failure + cfg80211_new_sta + cfg80211_port_authorized + cfg80211_put_bss + cfg80211_ready_on_channel + cfg80211_remain_on_channel_expired + cfg80211_roamed + cfg80211_rx_mgmt_khz + cfg80211_scan_done + cfg80211_sched_scan_results + cfg80211_sched_scan_stopped_rtnl + __cfg80211_send_event_skb + cfg80211_unlink_bss + cfg80211_unregister_wdev + cfg80211_vendor_cmd_reply __cfi_slowpath __check_object_size __class_create @@ -132,13 +155,10 @@ clk_get __clk_get_hw __clk_get_name - clk_get_parent clk_get_rate clk_hw_get_name clk_hw_get_parent __clk_is_enabled - clk_notifier_register - clk_notifier_unregister clk_prepare clk_put clk_register @@ -151,10 +171,7 @@ clockevents_config_and_register clocks_calc_mult_shift __clocksource_register_scale - __close_fd cma_alloc - cma_for_each_area - cma_get_name cma_release compat_alloc_user_space complete @@ -196,6 +213,7 @@ cpufreq_frequency_table_verify cpufreq_generic_attr cpufreq_get + cpufreq_get_policy cpufreq_policy_transition_delay_us cpufreq_quick_get cpufreq_register_driver @@ -212,6 +230,8 @@ cpuhp_tasks_frozen cpu_hwcap_keys cpu_hwcaps + cpuidle_pause_and_lock + cpuidle_resume_and_unlock cpu_latency_qos_add_request cpu_latency_qos_remove_request cpu_latency_qos_update_request @@ -228,7 +248,6 @@ cpus_read_lock cpus_read_unlock cpu_subsys - crc32_be crc32_le crc8 crc8_populate_msb @@ -239,26 +258,19 @@ crypto_alloc_aead crypto_alloc_base crypto_alloc_shash - crypto_alloc_skcipher crypto_alloc_sync_skcipher crypto_comp_compress crypto_comp_decompress crypto_destroy_tfm - __crypto_memneq crypto_register_alg crypto_register_scomp crypto_shash_digest crypto_shash_finup crypto_shash_setkey - crypto_shash_update - crypto_skcipher_decrypt crypto_skcipher_encrypt crypto_skcipher_setkey crypto_unregister_alg crypto_unregister_scomp - __crypto_xor - csum_ipv6_magic - csum_tcpudp_nofold _ctype debugfs_attr_read debugfs_attr_write @@ -274,7 +286,6 @@ debugfs_create_x32 debugfs_lookup debugfs_remove - debugfs_rename dec_zone_page_state default_llseek deferred_free @@ -284,36 +295,24 @@ del_timer_sync desc_to_gpio destroy_workqueue - dev_alloc_name - dev_change_net_namespace dev_close _dev_crit dev_driver_string _dev_emerg _dev_err - dev_fetch_sw_netstats devfreq_add_device devfreq_add_governor - devfreq_monitor_resume - devfreq_monitor_start - devfreq_monitor_stop - devfreq_monitor_suspend devfreq_recommended_opp devfreq_register_opp_notifier devfreq_remove_device devfreq_unregister_opp_notifier - devfreq_update_interval dev_fwnode - __dev_get_by_index - dev_get_by_index dev_get_by_name - device_add device_add_disk device_add_groups device_create device_create_file device_create_with_groups - device_del device_destroy device_find_child device_for_each_child @@ -324,12 +323,10 @@ device_link_del device_property_present device_property_read_string - device_property_read_string_array device_property_read_u32_array device_register device_remove_file device_remove_groups - device_rename device_set_wakeup_capable device_set_wakeup_enable device_unregister @@ -337,14 +334,11 @@ _dev_info __dev_kfree_skb_any devm_add_action - __devm_alloc_percpu devm_backlight_device_register devm_backlight_device_unregister devm_blk_ksm_init devm_clk_get devm_clk_get_optional - devm_clk_hw_register - devm_clk_hw_register_clkdev devm_clk_put devm_device_add_groups __devm_drm_dev_alloc @@ -352,7 +346,6 @@ devm_extcon_dev_allocate devm_extcon_dev_register devm_free_irq - devm_free_percpu devm_gen_pool_create devm_gpiochip_add_data_with_key devm_gpiod_get @@ -365,6 +358,7 @@ devm_i2c_new_dummy_device devm_iio_device_alloc __devm_iio_device_register + devm_input_allocate_device devm_ioremap devm_ioremap_resource devm_ioremap_wc @@ -377,7 +371,6 @@ devm_kstrdup_const devm_mfd_add_devices devm_nvmem_register - devm_of_clk_add_hw_provider __devm_of_phy_provider_register devm_of_platform_populate devm_phy_create @@ -390,7 +383,6 @@ devm_platform_ioremap_resource devm_platform_ioremap_resource_byname devm_power_supply_register - devm_pwm_get devm_regmap_add_irq_chip __devm_regmap_init __devm_regmap_init_i2c @@ -406,7 +398,6 @@ devm_snd_soc_register_component devm_thermal_of_cooling_device_register devm_thermal_zone_of_sensor_register - devm_thermal_zone_of_sensor_unregister devm_usb_get_phy_by_phandle _dev_notice dev_pm_domain_attach_by_name @@ -427,12 +418,10 @@ dev_pm_opp_set_regulators dev_pm_qos_read_value dev_pm_qos_update_request - dev_printk dev_printk_emit dev_queue_xmit devres_add devres_alloc_node - devres_free dev_set_name _dev_warn disable_irq @@ -509,12 +498,9 @@ down_read down_read_trylock down_timeout - down_trylock down_write drain_workqueue - driver_create_file driver_register - driver_remove_file driver_unregister drm_add_modes_noedid drm_atomic_add_affected_connectors @@ -545,7 +531,6 @@ __drm_atomic_helper_crtc_destroy_state __drm_atomic_helper_crtc_duplicate_state __drm_atomic_helper_crtc_reset - drm_atomic_helper_disable_all drm_atomic_helper_disable_plane drm_atomic_helper_duplicate_state drm_atomic_helper_fake_vblank @@ -569,7 +554,6 @@ drm_atomic_set_crtc_for_connector drm_atomic_set_crtc_for_plane drm_atomic_set_fb_for_plane - drm_atomic_set_mode_for_crtc drm_atomic_set_mode_prop_for_crtc drm_atomic_state_alloc drm_atomic_state_clear @@ -638,7 +622,6 @@ drmm_mode_config_init drm_mode_config_reset drm_mode_convert_to_umode - drm_mode_copy drm_mode_duplicate drm_mode_equal drm_mode_equal_no_clocks @@ -682,6 +665,7 @@ drm_property_create_bool drm_property_create_enum drm_property_create_range + drm_property_create_signed_range drm_property_lookup_blob drm_property_replace_blob __drm_puts_seq_file @@ -710,12 +694,8 @@ dw_pcie_write __dynamic_dev_dbg __dynamic_pr_debug - emergency_restart enable_irq enable_percpu_irq - ether_setup - eth_mac_addr - ethtool_op_get_link eth_type_trans eventfd_ctx_fdget eventfd_ctx_put @@ -745,7 +725,6 @@ find_vma finish_wait flush_dcache_page - flush_delayed_work flush_work flush_workqueue fput @@ -772,7 +751,6 @@ generic_file_llseek generic_handle_irq generic_iommu_put_resv_regions - genlmsg_multicast_allns genlmsg_put genl_register_family genl_unregister_family @@ -783,6 +761,7 @@ gen_pool_destroy gen_pool_first_fit_align gen_pool_free_owner + gen_pool_has_addr gen_pool_size get_cpu_device get_cpu_idle_time @@ -791,11 +770,8 @@ get_device __get_free_pages get_governor_parent_kobj - get_net_ns_by_fd - get_net_ns_by_pid get_pid_task get_random_bytes - get_random_bytes_arch get_random_u32 get_sg_io_hdr __get_task_comm @@ -817,6 +793,7 @@ gpiochip_get_data gpiochip_lock_as_irq gpiochip_unlock_as_irq + gpiod_cansleep gpiod_count gpiod_direction_input gpiod_direction_output @@ -845,26 +822,12 @@ have_governor_per_policy hex2bin hex_dump_to_buffer - hex_to_bin - hid_add_device - hid_allocate_device - hid_debug - hid_destroy_device - hid_input_report - hid_parse_report hrtimer_active hrtimer_cancel hrtimer_forward hrtimer_init - hrtimer_init_sleeper - hrtimer_sleeper_start_expires hrtimer_start_range_ns hrtimer_try_to_cancel - __hw_addr_init - __hw_addr_sync - __hw_addr_unsync - hwrng_register - hwrng_unregister i2c_adapter_type i2c_add_numbered_adapter i2c_bus_type @@ -878,8 +841,6 @@ i2c_new_dummy_device i2c_put_adapter i2c_register_driver - i2c_smbus_read_byte_data - i2c_smbus_write_byte_data i2c_smbus_xfer i2c_transfer i2c_transfer_buffer_flags @@ -891,15 +852,14 @@ idr_destroy idr_find idr_for_each - idr_get_next idr_preload idr_remove + ieee80211_channel_to_freq_khz + ieee80211_freq_khz_to_channel + ieee80211_get_channel_khz iio_device_unregister import_iovec - in6_pton - in_aton inc_zone_page_state - inet_csk_get_port init_dummy_netdev init_net init_pseudo @@ -907,12 +867,12 @@ __init_swait_queue_head init_task init_timer_key - init_uts_ns init_wait_entry __init_waitqueue_head input_allocate_device input_close_device input_event + input_ff_create input_free_device input_mt_destroy_slots input_mt_init_slots @@ -966,7 +926,6 @@ __ioremap io_schedule_timeout iounmap - ip_send_check iput __irq_alloc_descs irq_create_mapping_affinity @@ -996,29 +955,25 @@ kasprintf kernel_cpustat kernel_kobj - kernel_param_lock - kernel_param_unlock - kernel_restart kern_mount kern_unmount - key_create_or_update - key_put - keyring_alloc __kfifo_alloc __kfifo_free + __kfifo_from_user_r __kfifo_in __kfifo_init + __kfifo_in_r __kfifo_out + __kfifo_skip_r + __kfifo_to_user_r kfree kfree_sensitive kfree_skb - kfree_skb_list kill_anon_super kill_fasync kimage_voffset __kmalloc kmalloc_caches - kmalloc_order kmalloc_order_trace kmem_cache_alloc kmem_cache_alloc_trace @@ -1033,7 +988,6 @@ kobject_init_and_add kobject_put kobject_uevent - kobject_uevent_env kobj_sysfs_ops krealloc kstat @@ -1051,6 +1005,7 @@ kstrtouint kstrtouint_from_user kstrtoull + kstrtoull_from_user kthread_bind kthread_bind_mask kthread_cancel_delayed_work_sync @@ -1068,13 +1023,11 @@ kthread_stop kthread_worker_fn ktime_get - ktime_get_coarse_with_offset ktime_get_mono_fast_ns ktime_get_raw ktime_get_raw_ts64 ktime_get_real_seconds ktime_get_real_ts64 - ktime_get_seconds ktime_get_ts64 ktime_get_with_offset kvfree @@ -1090,15 +1043,11 @@ log_abnormal_wakeup_reason __log_post_read_mmio __log_read_mmio - log_threaded_irq_wakeup_reason __log_write_mmio loops_per_jiffy - lru_cache_disable - lru_cache_enable lzo1x_1_compress lzo1x_decompress_safe lzorle1x_1_compress - mac_pton mbox_chan_received_data mbox_controller_register mbox_controller_unregister @@ -1138,7 +1087,6 @@ mipi_dsi_picture_parameter_set misc_deregister misc_register - mktime64 __mmdrop mod_delayed_work_on mod_timer @@ -1147,7 +1095,6 @@ module_put __msecs_to_jiffies msleep - msleep_interruptible __mutex_init mutex_is_locked mutex_lock @@ -1162,39 +1109,23 @@ __napi_schedule napi_schedule_prep __netdev_alloc_skb - netdev_err - netdev_info - netdev_set_default_ethtool_ops netdev_state_change netdev_update_features - netif_carrier_off - netif_carrier_on netif_napi_add __netif_napi_del netif_receive_skb - netif_receive_skb_list netif_rx netif_rx_ni - netif_tx_stop_all_queues netif_tx_wake_queue - netlink_broadcast __netlink_kernel_create netlink_kernel_release - netlink_register_notifier netlink_unicast - netlink_unregister_notifier - net_ns_type_operations - net_ratelimit - nla_append - nla_find nla_memcpy __nla_parse nla_put nla_put_64bit nla_put_nohdr - nla_reserve nla_strlcpy - __nla_validate __nlmsg_put no_llseek nonseekable_open @@ -1212,10 +1143,8 @@ of_clk_add_provider of_clk_get of_clk_get_by_name - of_clk_hw_simple_get of_clk_src_onecell_get of_count_phandle_with_args - of_cpu_node_to_id of_device_get_match_data of_device_is_available of_device_is_compatible @@ -1223,6 +1152,7 @@ of_dma_controller_register of_drm_find_bridge of_drm_find_panel + of_find_backlight_by_node of_find_compatible_node of_find_device_by_node of_find_i2c_adapter_by_node @@ -1278,7 +1208,6 @@ of_reserved_mem_lookup of_root of_thermal_get_ntrips - of_thermal_get_trip_points of_translate_address of_usb_host_tpl_support page_endio @@ -1292,7 +1221,6 @@ param_ops_charp param_ops_int param_ops_long - param_ops_short param_ops_string param_ops_uint param_ops_ulong @@ -1328,9 +1256,9 @@ PDE_DATA __per_cpu_offset perf_event_create_kernel_counter + perf_event_disable perf_event_enable perf_event_pause - perf_event_read_local perf_event_read_value perf_event_release_kernel perf_event_update_userpage @@ -1343,7 +1271,6 @@ phy_init phy_power_off phy_power_on - pid_task pinconf_generic_dt_free_map pinconf_generic_dt_node_to_map pinctrl_add_gpio_range @@ -1354,9 +1281,8 @@ pinctrl_remove_gpio_range pinctrl_select_state pin_get_name + pin_user_pages pin_user_pages_fast - pin_user_pages_remote - pktgen_xfrm_outer_mode_output platform_bus_type platform_device_add platform_device_add_data @@ -1410,8 +1336,6 @@ power_supply_set_property power_supply_unregister power_supply_unreg_notifier - prandom_bytes - prandom_u32 preempt_schedule preempt_schedule_notrace prepare_to_wait @@ -1426,16 +1350,11 @@ proc_dostring proc_douintvec_minmax proc_mkdir - proc_mkdir_data proc_remove - pskb_expand_head __pskb_pull_tail - ___pskb_trim put_device put_disk - __put_net __put_page - put_pid put_sg_io_hdr __put_task_struct put_unused_fd @@ -1472,7 +1391,6 @@ rb_next rb_prev rb_replace_node - rcu_barrier __rcu_read_lock __rcu_read_unlock rdev_get_drvdata @@ -1494,9 +1412,6 @@ register_netdev register_netdevice register_netdevice_notifier - register_oom_notifier - register_pernet_device - register_pernet_subsys register_pm_notifier register_reboot_notifier register_restart_handler @@ -1522,6 +1437,7 @@ regmap_write regulator_bulk_disable regulator_bulk_enable + regulator_count_voltages regulator_disable regulator_disable_regmap regulator_enable @@ -1539,6 +1455,7 @@ regulator_set_voltage regulator_set_voltage_sel_regmap regulator_unregister + regulatory_hint release_firmware __release_region remap_pfn_range @@ -1555,24 +1472,11 @@ return_address revalidate_disk_size rfkill_alloc - rfkill_blocked rfkill_destroy rfkill_init_sw_state - rfkill_pause_polling rfkill_register - rfkill_resume_polling - rfkill_set_hw_state rfkill_unregister - rhashtable_free_and_destroy - rhashtable_insert_slow - rhltable_init - __rht_bucket_nested - rht_bucket_nested - rht_bucket_nested_insert root_task_group - round_jiffies - round_jiffies_relative - round_jiffies_up rps_needed rtc_class_close rtc_class_open @@ -1588,7 +1492,6 @@ sched_clock sched_feat_keys sched_setattr_nocheck - sched_set_fifo sched_setscheduler sched_setscheduler_nocheck sched_show_task @@ -1630,10 +1533,10 @@ seq_read seq_release seq_release_private + seq_vprintf seq_write set_blocksize set_cpus_allowed_ptr - set_freezable set_normalized_timespec64 set_page_dirty set_page_dirty_lock @@ -1662,20 +1565,11 @@ single_open single_open_size single_release - skb_add_rx_frag - skb_checksum - skb_checksum_help skb_clone - skb_clone_sk - skb_complete_wifi_ack skb_copy - skb_copy_bits skb_copy_expand skb_dequeue skb_dequeue_tail - skb_ensure_writable - __skb_get_hash - __skb_gso_segment skb_pull skb_push skb_put @@ -1712,22 +1606,15 @@ snd_soc_component_enable_pin snd_soc_component_force_enable_pin snd_soc_component_get_pin_status - snd_soc_component_read snd_soc_component_set_jack snd_soc_component_set_pll snd_soc_component_set_sysclk - snd_soc_component_update_bits - snd_soc_component_write snd_soc_dai_set_pll snd_soc_dai_set_sysclk snd_soc_dai_set_tdm_slot snd_soc_dapm_add_routes snd_soc_dapm_del_routes - snd_soc_dapm_disable_pin - snd_soc_dapm_disable_pin_unlocked - snd_soc_dapm_force_enable_pin_unlocked snd_soc_dapm_get_enum_double - snd_soc_dapm_get_pin_status snd_soc_dapm_get_volsw snd_soc_dapm_ignore_suspend snd_soc_dapm_kcontrol_widget @@ -1736,7 +1623,6 @@ snd_soc_dapm_put_enum_double snd_soc_dapm_put_volsw snd_soc_dapm_sync - snd_soc_dapm_sync_unlocked snd_soc_get_enum_double snd_soc_get_volsw snd_soc_get_volsw_range @@ -1745,15 +1631,12 @@ snd_soc_info_volsw snd_soc_info_volsw_range snd_soc_info_volsw_sx - snd_soc_jack_report snd_soc_lookup_component snd_soc_new_compress snd_soc_of_get_dai_link_codecs snd_soc_of_get_dai_name snd_soc_of_parse_card_name snd_soc_of_parse_daifmt - snd_soc_params_to_bclk - snd_soc_params_to_frame_size snd_soc_put_enum_double snd_soc_put_volsw snd_soc_put_volsw_range @@ -1765,14 +1648,10 @@ snd_soc_unregister_component snprintf soc_device_register - __sock_create - sock_release sock_wfree softnet_data sort __spi_alloc_controller - spi_bus_lock - spi_bus_unlock spi_controller_resume spi_controller_suspend spi_finalize_current_message @@ -1780,22 +1659,17 @@ __spi_register_driver spi_setup spi_sync - spi_sync_locked spi_unregister_controller split_page sprintf sprint_symbol - srcu_init_notifier_head - srcu_notifier_call_chain - srcu_notifier_chain_register - srcu_notifier_chain_unregister sscanf __stack_chk_fail - __stack_chk_guard static_key_disable static_key_slow_dec static_key_slow_inc stop_machine + stpcpy strcasecmp strcat strchr @@ -1809,11 +1683,9 @@ strlen strncasecmp strncat - strnchr strncmp strncpy strncpy_from_user - strndup_user strnlen strnstr strpbrk @@ -1825,10 +1697,8 @@ submit_bio submit_bio_wait subsys_system_register - __sw_hweight16 __sw_hweight32 __sw_hweight64 - __sw_hweight8 sync_file_create sync_file_get_fence synchronize_irq @@ -1853,11 +1723,9 @@ sysfs_streq sysfs_update_group sysrq_mask - system_freezable_wq system_freezing_cnt system_highpri_wq system_long_wq - system_power_efficient_wq system_state system_unbound_wq system_wq @@ -1869,7 +1737,6 @@ __task_pid_nr_ns task_rq_lock tcpci_get_tcpm_port - tcpci_irq tcpci_register_port tcpci_unregister_port tcpm_cc_change @@ -1897,7 +1764,6 @@ time64_to_tm topology_set_thermal_pressure _totalram_pages - __trace_bputs trace_event_buffer_commit trace_event_buffer_reserve trace_event_ignore_this_pid @@ -1912,7 +1778,6 @@ __traceiter_android_rvh_find_energy_efficient_cpu __traceiter_android_rvh_irqs_disable __traceiter_android_rvh_irqs_enable - __traceiter_android_rvh_pci_d3_sleep __traceiter_android_rvh_post_init_entity_util_avg __traceiter_android_rvh_preempt_disable __traceiter_android_rvh_preempt_enable @@ -1925,26 +1790,18 @@ __traceiter_android_rvh_ufs_reprogram_all_keys __traceiter_android_rvh_util_est_update __traceiter_android_vh_arch_set_freq_scale - __traceiter_android_vh_cma_alloc_finish - __traceiter_android_vh_cma_alloc_start __traceiter_android_vh_cpu_idle_enter __traceiter_android_vh_cpu_idle_exit __traceiter_android_vh_enable_thermal_genl_check __traceiter_android_vh_ep_create_wakeup_source - __traceiter_android_vh_finish_update_load_avg_se __traceiter_android_vh_ipi_stop - __traceiter_android_vh_meminfo_proc_show __traceiter_android_vh_of_i2c_get_board_info - __traceiter_android_vh_pagecache_get_page - __traceiter_android_vh_rmqueue __traceiter_android_vh_setscheduler_uclamp __traceiter_android_vh_snd_compr_use_pause_in_drain - __traceiter_android_vh_sound_usb_support_cpu_suspend __traceiter_android_vh_thermal_pm_notify_suspend __traceiter_android_vh_timerfd_create __traceiter_android_vh_typec_store_partner_src_caps __traceiter_android_vh_typec_tcpci_override_toggling - __traceiter_android_vh_typec_tcpm_adj_current_limit __traceiter_android_vh_typec_tcpm_get_timer __traceiter_android_vh_typec_tcpm_log __traceiter_android_vh_ufs_check_int_errors @@ -1962,8 +1819,6 @@ __traceiter_dwc3_readl __traceiter_dwc3_writel __traceiter_gpu_mem_total - __traceiter_mm_vmscan_direct_reclaim_begin - __traceiter_mm_vmscan_direct_reclaim_end __traceiter_pelt_cfs_tp __traceiter_pelt_dl_tp __traceiter_pelt_irq_tp @@ -1987,7 +1842,6 @@ __tracepoint_android_rvh_find_energy_efficient_cpu __tracepoint_android_rvh_irqs_disable __tracepoint_android_rvh_irqs_enable - __tracepoint_android_rvh_pci_d3_sleep __tracepoint_android_rvh_post_init_entity_util_avg __tracepoint_android_rvh_preempt_disable __tracepoint_android_rvh_preempt_enable @@ -2000,26 +1854,18 @@ __tracepoint_android_rvh_ufs_reprogram_all_keys __tracepoint_android_rvh_util_est_update __tracepoint_android_vh_arch_set_freq_scale - __tracepoint_android_vh_cma_alloc_finish - __tracepoint_android_vh_cma_alloc_start __tracepoint_android_vh_cpu_idle_enter __tracepoint_android_vh_cpu_idle_exit __tracepoint_android_vh_enable_thermal_genl_check __tracepoint_android_vh_ep_create_wakeup_source - __tracepoint_android_vh_finish_update_load_avg_se __tracepoint_android_vh_ipi_stop - __tracepoint_android_vh_meminfo_proc_show __tracepoint_android_vh_of_i2c_get_board_info - __tracepoint_android_vh_pagecache_get_page - __tracepoint_android_vh_rmqueue __tracepoint_android_vh_setscheduler_uclamp __tracepoint_android_vh_snd_compr_use_pause_in_drain - __tracepoint_android_vh_sound_usb_support_cpu_suspend __tracepoint_android_vh_thermal_pm_notify_suspend __tracepoint_android_vh_timerfd_create __tracepoint_android_vh_typec_store_partner_src_caps __tracepoint_android_vh_typec_tcpci_override_toggling - __tracepoint_android_vh_typec_tcpm_adj_current_limit __tracepoint_android_vh_typec_tcpm_get_timer __tracepoint_android_vh_typec_tcpm_log __tracepoint_android_vh_ufs_check_int_errors @@ -2037,8 +1883,6 @@ __tracepoint_dwc3_readl __tracepoint_dwc3_writel __tracepoint_gpu_mem_total - __tracepoint_mm_vmscan_direct_reclaim_begin - __tracepoint_mm_vmscan_direct_reclaim_end __tracepoint_pelt_cfs_tp __tracepoint_pelt_dl_tp __tracepoint_pelt_irq_tp @@ -2087,7 +1931,6 @@ uart_write_wakeup uclamp_eff_value __udelay - udp4_hwcsum ufshcd_bkops_ctrl ufshcd_hold ufshcd_pltfrm_init @@ -2099,6 +1942,8 @@ ufshcd_shutdown ufshcd_system_resume ufshcd_system_suspend + __uio_register_device + uio_unregister_device unlock_page unmap_mapping_range unpin_user_page @@ -2108,12 +1953,8 @@ unregister_inet6addr_notifier unregister_inetaddr_notifier unregister_netdev - unregister_netdevice_many unregister_netdevice_notifier unregister_netdevice_queue - unregister_oom_notifier - unregister_pernet_device - unregister_pernet_subsys unregister_pm_notifier unregister_reboot_notifier unregister_shrinker @@ -2220,7 +2061,6 @@ vb2_streamon vb2_vmalloc_memops vb2_wait_for_all_buffers - verify_pkcs7_signature vfree video_devdata video_device_alloc @@ -2249,12 +2089,11 @@ vring_interrupt vring_new_virtqueue vsnprintf + vsscanf vunmap vzalloc - vzalloc_node wait_for_completion wait_for_completion_interruptible_timeout - wait_for_completion_killable_timeout wait_for_completion_timeout wait_woken __wake_up @@ -2264,20 +2103,19 @@ wakeup_source_create wakeup_source_destroy wakeup_source_register - wakeup_source_remove wakeup_source_unregister - __wake_up_sync __warn_printk watchdog_init_timeout watchdog_register_device watchdog_set_restart_priority watchdog_unregister_device - wireless_nlevent_flush + wiphy_apply_custom_regulatory + wiphy_free + wiphy_new_nm + wiphy_register + wiphy_unregister woken_wake_function work_busy - __xfrm_state_destroy - xfrm_state_lookup_byspi - xfrm_stateonly_find xhci_address_device xhci_bus_resume xhci_bus_suspend diff --git a/android/abi_gki_aarch64_hikey960 b/android/abi_gki_aarch64_hikey960 deleted file mode 100644 index 93f48f3642bd..000000000000 --- a/android/abi_gki_aarch64_hikey960 +++ /dev/null @@ -1,1270 +0,0 @@ -[abi_symbol_list] -# commonly used symbols - alloc_chrdev_region - __alloc_disk_node - __alloc_pages_nodemask - alloc_workqueue - amba_driver_register - amba_driver_unregister - amba_release_regions - amba_request_regions - __arch_copy_from_user - __arch_copy_to_user - arm64_const_caps_ready - arm64_use_ng_mappings - blk_cleanup_queue - blk_execute_rq - blk_execute_rq_nowait - blk_get_queue - blk_mq_alloc_tag_set - blk_mq_complete_request - blk_mq_end_request - blk_mq_free_request - blk_mq_free_tag_set - blk_mq_init_queue - blk_mq_quiesce_queue - blk_mq_requeue_request - blk_mq_start_request - blk_mq_tagset_busy_iter - blk_mq_tagset_wait_completed_request - blk_mq_unquiesce_queue - blk_put_queue - blk_queue_flag_clear - blk_queue_flag_set - blk_queue_logical_block_size - blk_queue_max_discard_sectors - blk_queue_max_hw_sectors - blk_queue_max_segments - blk_queue_write_cache - __blk_rq_map_sg - bpf_trace_run1 - bpf_trace_run2 - cancel_delayed_work - cancel_delayed_work_sync - cancel_work_sync - capable - cdev_device_add - cdev_device_del - cdev_init - __cfi_slowpath - __check_object_size - __class_create - class_destroy - clk_disable - clk_enable - clk_get - clk_get_rate - clk_prepare - clk_put - clk_set_rate - clk_unprepare - complete - __const_udelay - cpu_hwcap_keys - cpu_hwcaps - cpumask_next - cpu_number - __cpu_online_mask - __cpu_possible_mask - debugfs_attr_read - debugfs_attr_write - debugfs_create_dir - debugfs_create_file - debugfs_create_file_unsafe - debugfs_remove - default_llseek - delayed_work_timer_fn - del_gendisk - del_timer - del_timer_sync - destroy_workqueue - dev_driver_string - _dev_err - device_add_disk - device_create_file - device_get_match_data - device_initialize - device_init_wakeup - device_remove_file - _dev_info - devm_clk_get - devm_gpiod_get - devm_gpiod_get_optional - devm_ioremap - devm_ioremap_resource - devm_kfree - devm_kmalloc - devm_pinctrl_get - devm_platform_ioremap_resource - __devm_regmap_init - __devm_regmap_init_i2c - __devm_regmap_init_mmio_clk - devm_regulator_register - devm_request_threaded_irq - __devm_reset_control_get - dev_pm_opp_get_opp_count - dev_set_name - _dev_warn - disable_irq - dma_alloc_attrs - dma_buf_export - dma_free_attrs - dma_heap_add - dma_heap_get_name - dmam_alloc_attrs - dma_map_page_attrs - dma_map_sg_attrs - dma_pool_alloc - dma_pool_create - dma_pool_destroy - dma_pool_free - dma_release_channel - dma_request_chan - dma_set_coherent_mask - dma_set_mask - dma_sync_sg_for_cpu - dma_sync_sg_for_device - dma_sync_single_for_cpu - dma_sync_single_for_device - dma_unmap_page_attrs - dma_unmap_sg_attrs - down_read - down_write - driver_unregister - drm_atomic_helper_connector_destroy_state - drm_atomic_helper_connector_duplicate_state - drm_atomic_helper_connector_reset - drm_connector_attach_encoder - drm_connector_cleanup - drm_connector_init - __drm_err - drm_helper_probe_single_connector_modes - drm_mode_copy - drm_mode_vrefresh - enable_irq - event_triggers_call - find_next_bit - find_next_zero_bit - finish_wait - flush_work - flush_workqueue - fput - free_irq - __free_pages - free_pages - generic_file_llseek - get_device - __get_free_pages - get_random_bytes - get_zeroed_page - gic_nonsecure_priorities - gpiod_set_value_cansleep - gpio_to_desc - i2c_del_driver - i2c_register_driver - i2c_transfer - ida_alloc_range - ida_destroy - ida_free - __init_swait_queue_head - init_timer_key - init_wait_entry - __init_waitqueue_head - __ioremap - iounmap - irq_get_irq_data - irq_of_parse_and_map - irq_set_irq_wake - jiffies - kasan_flag_enabled - kfree - kfree_const - kfree_skb - __kmalloc - kmalloc_caches - kmalloc_order_trace - kmem_cache_alloc_trace - kmemdup - kstrndup - kstrtoint - kstrtouint - kstrtoul_from_user - kstrtoull - ktime_get - ktime_get_mono_fast_ns - ktime_get_with_offset - __list_add_valid - __list_del_entry_valid - __log_post_read_mmio - __log_read_mmio - __log_write_mmio - memchr_inv - memcpy - memdup_user - memmove - mempool_alloc - mempool_destroy - mempool_free - memset - memstart_addr - mmc_add_host - mmc_alloc_host - mmc_detect_change - mmc_free_host - mmc_gpiod_request_cd - mmc_gpiod_request_ro - mmc_gpio_get_cd - mmc_gpio_get_ro - mmc_hw_reset - mmc_of_parse - mmc_regulator_get_supply - mmc_regulator_set_ocr - mmc_regulator_set_vqmmc - mmc_remove_host - mmc_request_done - mmc_send_tuning - mod_timer - module_layout - module_put - __msecs_to_jiffies - msleep - __mutex_init - mutex_lock - mutex_lock_interruptible - mutex_unlock - nla_put - no_llseek - nonseekable_open - nr_cpu_ids - of_alias_get_id - of_clk_get - of_device_get_match_data - of_device_is_compatible - of_find_compatible_node - of_find_property - of_get_child_by_name - of_get_named_gpio_flags - of_get_property - of_graph_get_remote_node - of_graph_parse_endpoint - of_iomap - of_match_device - of_match_node - of_property_read_string - of_property_read_string_helper - of_property_read_variable_u32_array - param_ops_bool - param_ops_charp - param_ops_int - param_ops_uint - pci_dev_put - __pci_register_driver - pci_unregister_driver - perf_trace_buf_alloc - perf_trace_run_bpf_submit - pinctrl_lookup_state - pinctrl_pm_select_sleep_state - pinctrl_select_state - platform_device_unregister - __platform_driver_register - platform_driver_unregister - platform_get_irq - platform_get_resource - __pm_runtime_disable - pm_runtime_enable - pm_runtime_force_resume - pm_runtime_force_suspend - __pm_runtime_idle - __pm_runtime_resume - pm_runtime_set_autosuspend_delay - __pm_runtime_set_status - __pm_runtime_suspend - __pm_runtime_use_autosuspend - pm_suspend_global_flags - pm_wakeup_dev_event - preempt_schedule - preempt_schedule_notrace - prepare_to_wait_event - printk - put_device - put_disk - __put_task_struct - queue_delayed_work_on - queue_work_on - ___ratelimit - _raw_spin_lock - _raw_spin_lock_bh - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_unlock - _raw_spin_unlock_bh - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - __rcu_read_lock - __rcu_read_unlock - rdev_get_drvdata - refcount_warn_saturate - regmap_read - regmap_update_bits_base - regmap_write - regulator_disable - regulator_enable - regulator_enable_regmap - regulator_get_voltage_sel_regmap - regulator_list_voltage_table - regulator_set_voltage - regulator_set_voltage_sel_regmap - release_firmware - remap_pfn_range - request_firmware - request_threaded_irq - reset_control_assert - reset_control_deassert - schedule - schedule_timeout - scnprintf - seq_lseek - seq_printf - seq_puts - seq_read - set_disk_ro - sg_alloc_table - sg_free_table - sg_init_table - sg_miter_next - sg_miter_start - sg_miter_stop - sg_next - simple_attr_open - simple_attr_release - simple_open - simple_read_from_buffer - single_open - single_release - skb_pull - skb_queue_tail - snprintf - __spi_register_driver - spi_setup - spi_sync - sprintf - sscanf - __stack_chk_fail - __stack_chk_guard - strcmp - strlcpy - strncmp - strncpy - strnlen - __sw_hweight64 - synchronize_irq - synchronize_rcu - syscon_node_to_regmap - syscon_regmap_lookup_by_phandle - sysfs_streq - system_wq - tasklet_init - __tasklet_schedule - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return - __traceiter_rwmmio_post_read - __traceiter_rwmmio_read - __traceiter_rwmmio_write - __tracepoint_rwmmio_post_read - __tracepoint_rwmmio_read - __tracepoint_rwmmio_write - trace_print_symbols_seq - trace_raw_output_prep - trace_seq_printf - trace_seq_putc - try_module_get - unregister_chrdev_region - up_read - up_write - usb_disabled - __usecs_to_jiffies - usleep_range - vabits_actual - vfree - vmalloc - vmap - vunmap - wait_for_completion - wait_for_completion_timeout - __wake_up - __warn_printk - xa_destroy - xa_erase - xa_find - xa_find_after - xa_load - -# required by adv7511.ko - cec_allocate_adapter - cec_delete_adapter - cec_received_msg_ts - cec_register_adapter - cec_s_phys_addr - cec_s_phys_addr_from_edid - cec_transmit_attempt_done_ts - cec_transmit_done_ts - cec_unregister_adapter - devm_regulator_bulk_get - drm_add_edid_modes - drm_bridge_add - drm_bridge_hpd_notify - drm_bridge_remove - drm_connector_update_edid_property - drm_detect_hdmi_monitor - drm_do_get_edid - drm_kms_helper_hotplug_event - hdmi_avi_infoframe_init - hdmi_avi_infoframe_pack - i2c_new_ancillary_device - i2c_unregister_device - mipi_dsi_attach - mipi_dsi_detach - mipi_dsi_device_register_full - mipi_dsi_device_unregister - mipi_dsi_driver_register_full - mipi_dsi_driver_unregister - of_find_mipi_dsi_host_by_node - platform_device_register_full - regcache_mark_dirty - regcache_sync - regmap_bulk_write - regmap_register_patch - regulator_bulk_disable - regulator_bulk_enable - -# required by ambakmi.ko - serio_interrupt - serio_reconnect - __serio_register_port - serio_unregister_port - -# required by armmmci.ko - clk_round_rate - devm_of_iomap - pinctrl_select_default_state - -# required by clk-hi655x.ko - devm_clk_hw_register - devm_of_clk_add_hw_provider - of_clk_hw_simple_get - -# required by cma_heap.ko - cma_alloc - cma_get_name - cma_release - dma_contiguous_default_area - dma_heap_get_drvdata - sg_alloc_table_from_pages - -# required by cn.ko - __alloc_skb - init_net - netlink_broadcast - netlink_has_listeners - __netlink_kernel_create - netlink_kernel_release - netlink_unicast - __nlmsg_put - proc_create_single_data - remove_proc_entry - -# required by cpufreq-dt.ko - cpufreq_enable_boost_support - cpufreq_freq_attr_scaling_available_freqs - cpufreq_freq_attr_scaling_boost_freqs - cpufreq_generic_frequency_table_verify - cpufreq_generic_get - cpufreq_generic_suspend - cpufreq_register_driver - cpufreq_unregister_driver - dev_pm_opp_free_cpufreq_table - dev_pm_opp_get_max_transition_latency - dev_pm_opp_get_opp_table - dev_pm_opp_get_sharing_cpus - dev_pm_opp_get_suspend_opp_freq - dev_pm_opp_init_cpufreq_table - dev_pm_opp_of_cpumask_add_table - dev_pm_opp_of_cpumask_remove_table - dev_pm_opp_of_get_sharing_cpus - dev_pm_opp_of_register_em - dev_pm_opp_put_opp_table - dev_pm_opp_put_regulators - dev_pm_opp_set_rate - dev_pm_opp_set_regulators - dev_pm_opp_set_sharing_cpus - get_cpu_device - policy_has_boost_freq - -# required by dw_mmc.ko - debugfs_create_u32 - debugfs_create_x64 - dev_err_probe - device_property_present - device_property_read_string_array - device_property_read_u32_array - mmc_can_gpio_cd - sdio_signal_irq - -# required by gadgetfs.ko - _copy_from_iter_full - _copy_to_iter - current_time - d_add - d_alloc_name - d_delete - d_make_root - dput - dup_iter - fasync_helper - generic_delete_inode - get_next_ino - get_tree_single - kill_fasync - kill_litter_super - kiocb_set_cancel_fn - kthread_unuse_mm - kthread_use_mm - mutex_trylock - new_inode - register_filesystem - simple_dir_inode_operations - simple_dir_operations - simple_statfs - unregister_filesystem - usb_ep_alloc_request - usb_ep_clear_halt - usb_ep_dequeue - usb_ep_disable - usb_ep_enable - usb_ep_fifo_flush - usb_ep_fifo_status - usb_ep_free_request - usb_ep_queue - usb_ep_set_halt - usb_gadget_probe_driver - usb_gadget_set_state - usb_gadget_unregister_driver - usb_gadget_vbus_draw - usb_get_gadget_udc_name - wait_for_completion_interruptible - -# required by hi3660-i2s.ko - devm_snd_dmaengine_pcm_register - pinctrl_put - snd_dmaengine_pcm_prepare_slave_config - snd_soc_register_component - snd_soc_unregister_component - -# required by hi3660-mailbox.ko - devm_mbox_controller_register - -# required by hi6421-pmic-core.ko - devm_mfd_add_devices - -# required by hi6421v530-regulator.ko - regulator_disable_regmap - regulator_is_enabled_regmap - regulator_map_voltage_ascend - -# required by hi655x-pmic.ko - devm_gpio_request_one - gpiod_to_irq - mfd_add_devices - mfd_remove_devices - regmap_add_irq_chip - regmap_del_irq_chip - regmap_irq_get_domain - -# required by hi655x-regulator.ko - regulator_list_voltage_linear - -# required by hisi_hikey_usb.ko - dev_fwnode - devm_regulator_get - regulator_is_enabled - usb_role_switch_get - usb_role_switch_get_drvdata - usb_role_switch_put - usb_role_switch_register - usb_role_switch_set_role - usb_role_switch_unregister - -# required by hisi_powerkey.ko - devm_input_allocate_device - devm_request_any_context_irq - input_event - input_register_device - input_set_capability - platform_get_irq_byname - -# required by hisi_thermal.ko - _dev_crit - devm_thermal_zone_of_sensor_register - of_thermal_get_ntrips - of_thermal_get_trip_points - thermal_zone_device_disable - thermal_zone_device_enable - thermal_zone_device_update - -# required by i2c-designware-core.ko - i2c_add_numbered_adapter - i2c_generic_scl_recovery - i2c_recover_bus - -# required by i2c-designware-platform.ko - devm_clk_get_optional - i2c_del_adapter - i2c_parse_fw_timings - -# required by i2c-dev.ko - bus_register_notifier - bus_unregister_notifier - device_for_each_child - i2c_adapter_type - i2c_bus_type - i2c_for_each_dev - i2c_get_adapter - i2c_put_adapter - i2c_smbus_xfer - i2c_transfer_buffer_flags - i2c_verify_client - register_chrdev_region - -# required by k3dma.ko - devm_free_irq - dma_async_device_register - dma_async_device_unregister - dma_async_tx_descriptor_init - dma_get_slave_channel - dmam_pool_create - of_dma_controller_free - of_dma_controller_register - tasklet_kill - tasklet_setup - vchan_dma_desc_free_list - vchan_find_desc - vchan_init - vchan_tx_desc_free - vchan_tx_submit - -# required by kirin-drm.ko - component_bind_all - component_master_add_with_match - component_master_del - component_unbind_all - drm_atomic_get_crtc_state - drm_atomic_helper_check - drm_atomic_helper_commit - drm_atomic_helper_crtc_destroy_state - drm_atomic_helper_crtc_duplicate_state - drm_atomic_helper_crtc_reset - drm_atomic_helper_disable_plane - drm_atomic_helper_page_flip - drm_atomic_helper_plane_destroy_state - drm_atomic_helper_plane_duplicate_state - drm_atomic_helper_plane_reset - drm_atomic_helper_set_config - drm_atomic_helper_update_plane - drm_compat_ioctl - drm_crtc_arm_vblank_event - drm_crtc_cleanup - drm_crtc_handle_vblank - drm_crtc_init_with_planes - drm_crtc_send_vblank_event - drm_crtc_vblank_get - drm_crtc_vblank_off - drm_crtc_vblank_on - drm_dev_alloc - drm_dev_put - drm_dev_register - drm_dev_unregister - drm_fb_cma_get_gem_obj - drm_gem_cma_dumb_create_internal - drm_gem_cma_free_object - drm_gem_cma_mmap - drm_gem_cma_prime_get_sg_table - drm_gem_cma_prime_import_sg_table - drm_gem_cma_prime_mmap - drm_gem_cma_prime_vmap - drm_gem_cma_prime_vunmap - drm_gem_cma_vm_ops - drm_gem_fb_create - drm_gem_prime_export - drm_gem_prime_fd_to_handle - drm_gem_prime_handle_to_fd - drm_gem_prime_import - drm_ioctl - drm_kms_helper_poll_fini - drm_kms_helper_poll_init - drmm_mode_config_init - drm_mode_config_cleanup - drm_mode_config_reset - drm_of_component_match_add - drm_open - drm_plane_cleanup - drm_poll - drm_read - drm_release - drm_universal_plane_init - drm_vblank_init - noop_llseek - -# required by kirin-dsi.ko - component_add - component_del - drm_bridge_attach - drm_connector_list_iter_begin - drm_connector_list_iter_end - drm_connector_list_iter_next - drm_connector_unregister - __drm_dbg - drm_encoder_cleanup - drm_encoder_init - drm_of_find_possible_crtcs - drm_panel_disable - drm_panel_enable - drm_panel_get_modes - drm_panel_prepare - drm_panel_unprepare - drm_sysfs_hotplug_event - mipi_dsi_host_register - mipi_dsi_host_unregister - of_drm_find_bridge - of_drm_find_panel - of_graph_get_next_endpoint - of_graph_get_remote_port_parent - -# required by mali_kbase.ko - anon_inode_getfd - __bitmap_weight - cache_line_size - clear_page - __close_fd - debugfs_create_bool - debugfs_create_size_t - devfreq_add_device - devfreq_cooling_unregister - devfreq_recommended_opp - devfreq_register_opp_notifier - devfreq_remove_device - devfreq_resume_device - devfreq_suspend_device - devfreq_unregister_opp_notifier - dev_pm_opp_find_freq_floor - dev_pm_opp_get_voltage - dev_pm_opp_of_add_table - dev_pm_opp_of_remove_table - dev_pm_opp_put - dma_buf_attach - dma_buf_begin_cpu_access - dma_buf_detach - dma_buf_end_cpu_access - dma_buf_get - dma_buf_map_attachment - dma_buf_mmap - dma_buf_put - dma_buf_unmap_attachment - dma_buf_vmap - dma_buf_vunmap - dma_fence_add_callback - dma_fence_context_alloc - dma_fence_default_wait - dma_fence_get_status - dma_fence_init - dma_fence_release - dma_fence_remove_callback - dma_fence_signal - down - downgrade_write - down_trylock - dump_stack - fd_install - find_vma - get_unused_fd_flags - get_user_pages - get_user_pages_fast - get_user_pages_remote - hrtimer_cancel - hrtimer_init - hrtimer_start_range_ns - iomem_resource - kimage_voffset - kstrdup - kstrtobool_from_user - kthread_create_on_node - kthread_should_stop - kthread_stop - ktime_add_safe - ktime_get_raw_ts64 - misc_deregister - misc_register - __mmdrop - mm_trace_rss_stat - msleep_interruptible - of_devfreq_cooling_register_power - of_find_device_by_node - of_get_next_available_child - of_parse_phandle - of_property_read_u64 - __put_page - rb_erase - rb_first - rb_insert_color - rb_next - rb_prev - rb_replace_node - register_shrinker - regulator_get_optional - regulator_put - __release_region - remap_vmalloc_range - __request_region - seq_open - seq_putc - seq_release - seq_write - set_page_dirty_lock - simple_attr_read - simple_attr_write - __sw_hweight32 - sync_file_create - sync_file_get_fence - sysfs_create_group - sysfs_remove_group - thermal_zone_get_temp - thermal_zone_get_zone_by_name - _totalram_pages - unmap_mapping_range - unregister_shrinker - up - vmalloc_user - vmf_insert_pfn - vm_mmap - vzalloc - wake_up_process - -# required by mmc_block.ko - blk_get_request - __blk_mq_end_request - blk_mq_run_hw_queues - blk_put_request - blk_queue_bounce_limit - blk_queue_can_use_dma_map_merging - blk_queue_max_segment_size - blk_queue_rq_timeout - blk_update_request - bus_register - bus_unregister - dma_get_merge_boundary - mmc_app_cmd - mmc_calc_max_discard - mmc_can_erase - mmc_can_secure_erase_trim - mmc_can_trim - __mmc_claim_host - mmc_cmdq_disable - mmc_cmdq_enable - mmc_cqe_post_req - mmc_cqe_recovery - mmc_cqe_start_req - mmc_crypto_prepare_req - mmc_crypto_setup_queue - mmc_detect_card_removed - mmc_erase - mmc_erase_group_aligned - mmc_flush_cache - mmc_get_card - mmc_get_ext_csd - mmc_put_card - mmc_register_driver - mmc_release_host - mmc_retune_pause - mmc_retune_release - mmc_retune_unpause - mmc_run_bkops - mmc_sanitize - __mmc_send_status - mmc_send_status - mmc_set_data_timeout - mmc_start_request - mmc_switch - mmc_unregister_driver - mmc_wait_for_cmd - mmc_wait_for_req - register_blkdev - sg_init_one - simple_strtoul - string_get_size - unregister_blkdev - -# required by mmc_spi.ko - is_vmalloc_addr - mmc_gpiod_request_cd_irq - spi_bus_lock - spi_bus_unlock - spi_sync_locked - -# required by nvme-core.ko - add_uevent_var - bdget_disk - bdput - bd_set_nr_sectors - blk_freeze_queue_start - blk_mq_alloc_request - blk_mq_alloc_request_hctx - blk_mq_delay_kick_requeue_list - blk_mq_freeze_queue - blk_mq_freeze_queue_wait - blk_mq_freeze_queue_wait_timeout - blk_mq_unfreeze_queue - blk_mq_unique_tag - blk_poll - blk_queue_chunk_sectors - blk_queue_dma_alignment - blk_queue_flag_test_and_set - blk_queue_io_min - blk_queue_io_opt - blk_queue_max_discard_segments - blk_queue_max_write_zeroes_sectors - blk_queue_physical_block_size - blk_queue_virt_boundary - blk_rq_map_kern - blk_rq_map_user - blk_rq_unmap_user - blk_set_queue_dying - blk_status_to_errno - blk_sync_queue - bpf_trace_run3 - cleanup_srcu_struct - compat_ptr_ioctl - completion_done - device_add - device_del - device_remove_file_self - dev_pm_qos_expose_latency_tolerance - dev_pm_qos_hide_latency_tolerance - dev_pm_qos_update_user_latency_tolerance - __init_rwsem - init_srcu_struct - kasprintf - kobject_uevent_env - list_sort - param_ops_byte - param_ops_ulong - revalidate_disk_size - set_capacity_revalidate_and_notify - __srcu_read_unlock - synchronize_srcu - sysfs_create_link - sysfs_remove_link - uuid_null - xa_store - -# required by nvme.ko - async_schedule_node - blk_mq_complete_request_remote - blk_mq_map_queues - blk_mq_pci_map_queues - blk_mq_tag_to_rq - blk_mq_update_nr_hw_queues - device_release_driver - dma_max_mapping_size - __do_once_done - __do_once_start - mempool_create_node - mempool_kfree - mempool_kmalloc - param_get_uint - param_set_uint - pci_alloc_irq_vectors_affinity - pcibios_resource_to_bus - pci_device_is_present - pci_disable_device - pcie_aspm_enabled - pci_enable_device_mem - pci_free_irq - pci_free_irq_vectors - pci_irq_vector - pci_load_saved_state - pci_read_config_word - pci_release_selected_regions - pci_request_irq - pci_request_selected_regions - pci_restore_state - pci_save_state - pci_select_bars - pci_set_master - sysfs_remove_file_from_group - wait_for_completion_io_timeout - -# required by nvmet.ko - bin2hex - bio_add_page - bio_alloc_bioset - bio_associate_blkg - bio_chain - bio_endio - bio_init - bio_put - blkdev_get_by_path - __blkdev_issue_discard - blkdev_issue_flush - __blkdev_issue_zeroout - blkdev_put - blk_finish_plug - blk_start_plug - configfs_register_subsystem - configfs_unregister_subsystem - config_group_init - config_group_init_type_name - _ctype - fs_bio_set - hex_to_bin - iov_iter_bvec - kmem_cache_create - kmem_cache_destroy - kmemdup_nul - kstrtobool - kstrtou16 - kvfree_call_rcu - mempool_alloc_slab - mempool_create - mempool_free_slab - mod_delayed_work_on - __per_cpu_offset - percpu_ref_exit - percpu_ref_init - percpu_ref_kill_and_confirm - radix_tree_delete - radix_tree_next_chunk - __request_module - sgl_alloc - sgl_free - sg_pcopy_from_buffer - sg_pcopy_to_buffer - sg_zero_buffer - strcspn - strlen - submit_bio - uuid_gen - uuid_parse - vfs_fallocate - vfs_fsync - vfs_getattr - __xa_insert - -# required by of_mmc_spi.ko - mmc_of_parse_voltage - -# required by ohci-hcd.ko - device_set_wakeup_capable - gen_pool_dma_alloc_align - gen_pool_dma_zalloc_align - gen_pool_free_owner - sb800_prefetch - schedule_timeout_uninterruptible - usb_amd_dev_put - usb_amd_quirk_pll_disable - usb_amd_quirk_pll_enable - usb_calc_bus_time - usb_debug_root - usb_hcd_check_unlink_urb - usb_hcd_giveback_urb - usb_hc_died - usb_hcd_link_urb_to_ep - usb_hcd_poll_rh_status - usb_hcd_resume_root_hub - usb_hcds_loaded - usb_hcd_unlink_urb_from_ep - usb_root_hub_lost_power - -# required by ohci-pci.ko - pci_get_slot - pci_match_id - usb_amd_prefetch_quirk - usb_amd_quirk_pll_check - usb_hcd_pci_pm_ops - usb_hcd_pci_probe - usb_hcd_pci_remove - usb_hcd_pci_shutdown - -# required by ohci-platform.ko - device_wakeup_enable - devm_reset_control_array_get - usb_add_hcd - usb_create_hcd - usb_hcd_platform_shutdown - usb_put_hcd - usb_remove_hcd - -# required by phy-hi3660-usb3.ko - __devm_of_phy_provider_register - devm_phy_create - of_phy_simple_xlate - -# required by reboot-mode.ko - devres_add - devres_alloc_node - devres_free - devres_release - kstrdup_const - register_reboot_notifier - unregister_reboot_notifier - -# required by rfkill-gpio.ko - device_property_read_string - rfkill_alloc - rfkill_destroy - rfkill_find_type - rfkill_register - rfkill_unregister - -# required by rtc-efi.ko - devm_rtc_device_register - efi - __platform_driver_probe - rtc_valid_tm - rtc_year_days - -# required by snd-soc-hdmi-codec.ko - devm_snd_soc_register_component - hdmi_audio_infoframe_init - snd_ctl_add - snd_ctl_new1 - snd_pcm_add_chmap_ctls - snd_pcm_create_iec958_consumer_hw_params - snd_pcm_format_width - snd_pcm_hw_constraint_eld - snd_soc_dapm_add_routes - snd_soc_jack_report - -# required by snd-soc-simple-card-utils.ko - devm_get_clk_from_child - devm_kasprintf - devm_kvasprintf - snd_soc_card_jack_new - snd_soc_dai_set_sysclk - snd_soc_dai_set_tdm_slot - snd_soc_dapm_get_pin_switch - snd_soc_dapm_info_pin_switch - snd_soc_dapm_put_pin_switch - snd_soc_jack_add_gpios - snd_soc_of_parse_audio_routing - snd_soc_of_parse_audio_simple_widgets - snd_soc_of_parse_card_name - snd_soc_of_parse_daifmt - snd_soc_runtime_calc_hw - -# required by snd-soc-simple-card.ko - devm_snd_soc_register_card - of_device_is_available - of_get_next_child - of_get_parent - of_parse_phandle_with_args - snd_soc_dai_link_set_capabilities - snd_soc_of_get_dai_name - snd_soc_of_parse_aux_devs - snd_soc_of_parse_node_prefix - snd_soc_of_parse_tdm_slot - snd_soc_pm_ops - -# required by spi-pl022.ko - devm_gpio_request - devm_spi_register_controller - __dma_request_channel - gpiod_direction_output_raw - gpiod_set_raw_value - loops_per_jiffy - pinctrl_pm_select_default_state - pinctrl_pm_select_idle_state - __spi_alloc_controller - spi_controller_resume - spi_controller_suspend - spi_delay_exec - spi_finalize_current_message - spi_get_next_queued_message - -# required by spidev.ko - device_create - device_destroy - __register_chrdev - stream_open - __unregister_chrdev - -# required by system_heap.ko - deferred_free - dmabuf_page_pool_alloc - dmabuf_page_pool_create - dmabuf_page_pool_destroy - dmabuf_page_pool_free - dma_heap_get_dev - __sg_page_iter_next - __sg_page_iter_start - -# required by tcpci_rt1711h.ko - i2c_smbus_read_word_data - regmap_raw_read - regmap_raw_write - tcpci_irq - tcpci_register_port - tcpci_unregister_port - -# required by wl18xx.ko - kstrtou8_from_user - -# required by wlcore.ko - bcmp - complete_all - consume_skb - device_create_bin_file - device_remove_bin_file - dev_pm_clear_wake_irq - dev_pm_set_dedicated_wake_irq - disable_irq_nosync - get_random_u32 - jiffies_to_msecs - jiffies_to_usecs - __local_bh_enable_ip - __netdev_alloc_skb - __nla_parse - no_seek_end_llseek - _raw_spin_trylock - request_firmware_nowait - skb_dequeue - skb_push - skb_put - skb_queue_head - skb_trim - vscnprintf - -# required by wlcore_sdio.ko - platform_device_add - platform_device_add_data - platform_device_add_resources - platform_device_alloc - platform_device_put - print_hex_dump - sdio_claim_host - sdio_disable_func - sdio_enable_func - sdio_f0_readb - sdio_f0_writeb - sdio_get_host_pm_caps - sdio_memcpy_fromio - sdio_memcpy_toio - sdio_readsb - sdio_register_driver - sdio_release_host - sdio_set_block_size - sdio_set_host_pm_flags - sdio_unregister_driver - sdio_writesb diff --git a/android/abi_gki_aarch64_mtk b/android/abi_gki_aarch64_mtk deleted file mode 100644 index e4353e217f54..000000000000 --- a/android/abi_gki_aarch64_mtk +++ /dev/null @@ -1,2510 +0,0 @@ -[abi_symbol_list] - access_process_vm - activate_task - add_timer - add_uevent_var - add_wait_queue - adjust_managed_page_count - alarm_cancel - alarm_init - alarm_start - alarm_start_relative - alarm_try_to_cancel - alloc_anon_inode - alloc_chrdev_region - __alloc_disk_node - alloc_etherdev_mqs - alloc_io_pgtable_ops - alloc_netdev_mqs - alloc_pages_exact - __alloc_pages_nodemask - __alloc_percpu - __alloc_percpu_gfp - __alloc_skb - alloc_workqueue - android_debug_symbol - android_rvh_probe_register - anon_inode_getfd - anon_inode_getfile - arc4_crypt - arc4_setkey - __arch_copy_from_user - __arch_copy_to_user - arch_timer_read_counter - arm64_const_caps_ready - arm64_use_ng_mappings - __arm_smccc_hvc - __arm_smccc_smc - arp_tbl - async_schedule_node - atomic_notifier_call_chain - atomic_notifier_chain_register - atomic_notifier_chain_unregister - autoremove_wake_function - bcmp - bdget_disk - bdput - bio_add_pc_page - bio_alloc_bioset - bio_endio - bio_put - bio_reset - __bitmap_andnot - __bitmap_clear - bitmap_find_free_region - bitmap_find_next_zero_area_off - bitmap_free - bitmap_from_arr32 - bitmap_print_to_pagebuf - bitmap_release_region - __bitmap_set - bitmap_to_arr32 - __bitmap_weight - bitmap_zalloc - blk_alloc_queue - blk_cleanup_queue - blk_execute_rq - blk_execute_rq_nowait - blk_get_request - blk_mq_free_request - blk_mq_sched_mark_restart_hctx - blk_mq_start_request - blk_put_request - blk_queue_flag_clear - blk_queue_flag_set - blk_queue_io_min - blk_queue_io_opt - blk_queue_logical_block_size - blk_queue_max_discard_sectors - blk_queue_max_write_zeroes_sectors - blk_queue_physical_block_size - blk_rq_append_bio - blocking_notifier_call_chain - blocking_notifier_chain_register - blocking_notifier_chain_unregister - bpf_trace_run10 - bpf_trace_run12 - bpf_trace_run1 - bpf_trace_run2 - bpf_trace_run3 - bpf_trace_run4 - bpf_trace_run5 - bpf_trace_run6 - bpf_trace_run7 - bpf_trace_run8 - bpf_trace_run9 - bus_register - bus_set_iommu - bus_unregister - call_rcu - cancel_delayed_work - cancel_delayed_work_sync - cancel_work_sync - cdev_add - cdev_alloc - cdev_del - cdev_device_add - cdev_device_del - cdev_init - __cfi_slowpath - __check_object_size - check_preempt_curr - __class_create - class_destroy - class_find_device - class_for_each_device - __class_register - class_unregister - __ClearPageMovable - clk_bulk_disable - clk_bulk_enable - clk_bulk_prepare - clk_bulk_put_all - clk_bulk_unprepare - clk_disable - clk_divider_ops - clk_enable - clk_gate_ops - clk_get - __clk_get_hw - __clk_get_name - clk_get_parent - clk_get_rate - clk_hw_get_name - clk_hw_get_num_parents - clk_hw_get_parent - clk_hw_get_parent_by_index - clk_hw_get_rate - clk_hw_is_enabled - clk_hw_is_prepared - __clk_is_enabled - clk_mux_ops - clk_notifier_register - clk_prepare - clk_put - clk_register - clk_register_composite - clk_register_divider_table - clk_register_fixed_factor - clk_register_fixed_rate - clk_set_parent - clk_set_rate - clk_unprepare - clocks_calc_mult_shift - __close_fd - cma_alloc - cma_release - compat_alloc_user_space - compat_ptr_ioctl - complete - complete_all - completion_done - component_add - component_add_typed - component_bind_all - component_del - component_master_add_with_match - component_master_del - component_match_add_release - component_match_add_typed - component_unbind_all - config_ep_by_speed - config_group_init_type_name - console_drivers - console_suspend_enabled - console_unlock - __const_udelay - consume_skb - contig_page_data - _copy_from_iter - copy_from_kernel_nofault - _copy_to_iter - __cpu_active_mask - cpu_all_bits - cpu_bit_bitmap - cpufreq_add_update_util_hook - cpufreq_cpu_get - cpufreq_cpu_put - cpufreq_disable_fast_switch - cpufreq_driver_fast_switch - cpufreq_driver_resolve_freq - __cpufreq_driver_target - cpufreq_enable_fast_switch - cpufreq_generic_attr - cpufreq_generic_frequency_table_verify - cpufreq_get_policy - cpufreq_policy_transition_delay_us - cpufreq_quick_get - cpufreq_register_driver - cpufreq_register_governor - cpufreq_remove_update_util_hook - cpufreq_table_index_unsorted - cpufreq_this_cpu_can_update - cpufreq_unregister_driver - cpufreq_unregister_governor - cpu_hotplug_disable - cpu_hotplug_enable - __cpuhp_remove_state - __cpuhp_setup_state - __cpuhp_state_add_instance - __cpuhp_state_remove_instance - cpu_hwcap_keys - cpu_hwcaps - cpuidle_driver_state_disabled - cpuidle_get_driver - cpuidle_pause_and_lock - cpuidle_resume_and_unlock - cpu_latency_qos_add_request - cpu_latency_qos_remove_request - cpu_latency_qos_update_request - cpumask_any_but - cpumask_next - cpumask_next_and - cpu_number - __cpu_online_mask - __cpu_possible_mask - __cpu_present_mask - cpu_scale - cpus_read_lock - cpus_read_unlock - cpu_subsys - cpu_topology - crc32_be - crc32_le - crc8 - crc8_populate_msb - crypto_aead_decrypt - crypto_aead_encrypt - crypto_aead_setauthsize - crypto_aead_setkey - crypto_alloc_aead - crypto_alloc_base - crypto_alloc_shash - crypto_alloc_skcipher - crypto_comp_compress - crypto_comp_decompress - crypto_destroy_tfm - crypto_has_alg - __crypto_memneq - crypto_register_alg - crypto_register_scomp - crypto_shash_digest - crypto_shash_final - crypto_shash_finup - crypto_shash_setkey - crypto_shash_update - crypto_skcipher_decrypt - crypto_skcipher_encrypt - crypto_skcipher_setkey - crypto_unregister_alg - crypto_unregister_scomp - __crypto_xor - _ctype - dapm_clock_event - dapm_kcontrol_get_value - dapm_regulator_event - deactivate_task - debugfs_attr_read - debugfs_attr_write - debugfs_create_blob - debugfs_create_bool - debugfs_create_devm_seqfile - debugfs_create_dir - debugfs_create_file - debugfs_create_regset32 - debugfs_create_symlink - debugfs_create_u16 - debugfs_create_u32 - debugfs_create_u64 - debugfs_create_u8 - debugfs_create_x32 - debugfs_lookup - debugfs_remove - debugfs_rename - dec_zone_page_state - default_llseek - deferred_free - delayed_work_timer_fn - del_gendisk - del_timer - del_timer_sync - destroy_workqueue - dev_alloc_name - dev_base_lock - dev_change_net_namespace - dev_close - dev_driver_string - _dev_emerg - _dev_err - dev_err_probe - dev_fetch_sw_netstats - devfreq_add_governor - devfreq_get_devfreq_by_phandle - devfreq_monitor_resume - devfreq_monitor_start - devfreq_monitor_stop - devfreq_monitor_suspend - devfreq_recommended_opp - devfreq_remove_device - devfreq_remove_governor - devfreq_resume_device - devfreq_suspend_device - devfreq_update_interval - dev_fwnode - __dev_get_by_index - dev_get_by_index - dev_get_regmap - dev_get_stats - device_add - device_add_disk - device_create - device_create_bin_file - device_create_file - device_create_with_groups - device_del - device_destroy - device_for_each_child - device_get_child_node_count - device_get_match_data - device_get_next_child_node - device_initialize - device_init_wakeup - device_link_add - device_link_remove - device_property_present - device_property_read_string - device_property_read_u32_array - device_register - device_remove_bin_file - device_remove_file - device_rename - device_set_of_node_from_dev - device_show_bool - device_store_bool - device_unregister - _dev_info - __dev_kfree_skb_any - __devm_alloc_percpu - devm_blk_ksm_init - devm_clk_bulk_get - devm_clk_bulk_get_optional - devm_clk_get - devm_clk_get_optional - devm_clk_register - devm_devfreq_add_device - devm_devfreq_register_notifier - devm_devfreq_remove_device - devm_devfreq_unregister_notifier - devm_extcon_dev_allocate - devm_extcon_dev_register - devm_extcon_register_notifier - devm_free_irq - devm_fwnode_pwm_get - devm_gpiochip_add_data_with_key - devm_gpiod_get - devm_gpiod_get_index - devm_gpiod_get_optional - devm_gpiod_put - devm_gpio_free - devm_gpio_request - devm_gpio_request_one - devm_hwrng_register - devm_i2c_new_dummy_device - devm_iio_channel_get - devm_iio_channel_get_all - devm_iio_device_alloc - __devm_iio_device_register - devm_input_allocate_device - devm_ioremap - devm_ioremap_resource - devm_ioremap_wc - devm_kasprintf - devm_kfree - devm_kmalloc - devm_led_classdev_register_ext - devm_led_classdev_unregister - devm_mbox_controller_register - devm_memremap - devm_mfd_add_devices - devm_nvmem_cell_get - devm_nvmem_device_get - devm_nvmem_register - devm_of_phy_get_by_index - __devm_of_phy_provider_register - devm_of_platform_populate - devm_phy_create - devm_phy_get - devm_pinctrl_get - devm_pinctrl_put - devm_pinctrl_register_and_init - devm_platform_ioremap_resource - devm_platform_ioremap_resource_byname - devm_power_supply_get_by_phandle - devm_power_supply_register - devm_regmap_add_irq_chip - devm_regmap_field_alloc - __devm_regmap_init - __devm_regmap_init_i2c - __devm_regmap_init_mmio_clk - devm_regulator_get - devm_regulator_get_exclusive - devm_regulator_get_optional - devm_regulator_put - devm_regulator_register - devm_regulator_register_notifier - devm_regulator_unregister_notifier - devm_request_threaded_irq - __devm_reset_control_get - devm_reset_controller_register - devm_rtc_allocate_device - devm_snd_soc_register_card - devm_snd_soc_register_component - devm_spi_register_controller - devm_thermal_zone_of_sensor_register - devm_watchdog_register_device - _dev_notice - dev_pm_domain_attach_by_id - dev_pm_domain_attach_by_name - dev_pm_domain_detach - dev_pm_genpd_add_notifier - dev_pm_genpd_set_performance_state - dev_pm_opp_add - dev_pm_opp_find_freq_ceil - dev_pm_opp_find_freq_ceil_by_volt - dev_pm_opp_find_freq_floor - dev_pm_opp_get_freq - dev_pm_opp_get_level - dev_pm_opp_get_opp_count - dev_pm_opp_get_opp_table - dev_pm_opp_get_voltage - dev_pm_opp_of_add_table - dev_pm_opp_of_add_table_indexed - dev_pm_opp_of_remove_table - dev_pm_opp_put - dev_pm_opp_put_opp_table - dev_pm_opp_remove_all_dynamic - dev_pm_qos_update_request - dev_printk - dev_queue_xmit - devres_add - devres_alloc_node - devres_free - devres_release - dev_set_name - _dev_warn - disable_irq - disable_irq_nosync - disable_percpu_irq - disk_end_io_acct - disk_start_io_acct - dma_alloc_attrs - dma_async_device_register - dma_async_device_unregister - dma_async_tx_descriptor_init - dma_buf_attach - dma_buf_begin_cpu_access - dma_buf_detach - dma_buf_end_cpu_access - dma_buf_export - dma_buf_fd - dma_buf_get - dma_buf_map_attachment - dmabuf_page_pool_alloc - dmabuf_page_pool_create - dmabuf_page_pool_destroy - dmabuf_page_pool_free - dma_buf_put - dma_buf_unmap_attachment - dma_buf_vmap - dma_buf_vunmap - dma_fence_add_callback - dma_fence_context_alloc - dma_fence_default_wait - dma_fence_free - dma_fence_init - dma_fence_release - dma_fence_signal - dma_fence_signal_locked - dma_fence_signal_timestamp_locked - dma_fence_wait_timeout - dma_free_attrs - dma_get_sgtable_attrs - dma_heap_add - dma_heap_buffer_alloc - dma_heap_bufferfd_alloc - dma_heap_find - dma_heap_get_dev - dma_heap_get_drvdata - dma_heap_get_name - dma_heap_put - dmam_alloc_attrs - dma_map_page_attrs - dma_map_resource - dma_map_sg_attrs - dmam_free_coherent - dma_mmap_attrs - dma_pool_alloc - dma_pool_create - dma_pool_destroy - dma_pool_free - dma_resv_wait_timeout_rcu - dma_run_dependencies - dma_set_coherent_mask - dma_set_mask - dma_sync_sg_for_cpu - dma_sync_sg_for_device - dma_sync_single_for_cpu - dma_unmap_page_attrs - dma_unmap_resource - dma_unmap_sg_attrs - do_exit - do_wait_intr_irq - down - down_interruptible - down_read - down_timeout - down_trylock - down_write - d_path - dput - drain_workqueue - driver_create_file - driver_remove_file - driver_unregister - drm_add_modes_noedid - drm_atomic_add_affected_connectors - drm_atomic_get_crtc_state - drm_atomic_helper_check - drm_atomic_helper_check_plane_state - drm_atomic_helper_cleanup_planes - drm_atomic_helper_commit_modeset_disables - drm_atomic_helper_commit_modeset_enables - drm_atomic_helper_commit_planes - drm_atomic_helper_connector_destroy_state - drm_atomic_helper_connector_duplicate_state - drm_atomic_helper_connector_reset - __drm_atomic_helper_crtc_destroy_state - __drm_atomic_helper_crtc_duplicate_state - drm_atomic_helper_disable_plane - drm_atomic_helper_legacy_gamma_set - drm_atomic_helper_page_flip - __drm_atomic_helper_plane_destroy_state - __drm_atomic_helper_plane_duplicate_state - drm_atomic_helper_prepare_planes - drm_atomic_helper_resume - drm_atomic_helper_set_config - drm_atomic_helper_shutdown - drm_atomic_helper_suspend - drm_atomic_helper_swap_state - drm_atomic_helper_update_plane - drm_atomic_helper_wait_for_vblanks - drm_atomic_state_clear - drm_atomic_state_default_release - __drm_atomic_state_free - drm_atomic_state_init - drm_bridge_attach - drm_calc_timestamping_constants - drm_compat_ioctl - drm_connector_attach_encoder - drm_connector_cleanup - drm_connector_init - drm_crtc_cleanup - drm_crtc_handle_vblank - drm_crtc_init_with_planes - drm_crtc_send_vblank_event - drm_crtc_vblank_get - drm_crtc_vblank_off - drm_crtc_vblank_on - drm_crtc_vblank_put - __drm_dbg - drm_dev_alloc - drm_dev_put - drm_dev_register - drm_dev_unregister - drm_encoder_cleanup - drm_encoder_init - __drm_err - drm_format_info - drm_framebuffer_cleanup - drm_framebuffer_init - drm_framebuffer_lookup - drm_framebuffer_remove - drm_gem_cma_vm_ops - drm_gem_create_mmap_offset - drm_gem_dumb_destroy - drm_gem_handle_create - drm_gem_mmap - drm_gem_mmap_obj - drm_gem_object_free - drm_gem_object_init - drm_gem_object_lookup - drm_gem_object_release - drm_gem_prime_export - drm_gem_prime_fd_to_handle - drm_gem_prime_handle_to_fd - drm_gem_prime_import - drm_gem_private_object_init - drm_gem_vm_close - drm_helper_hpd_irq_event - drm_helper_mode_fill_fb_struct - drm_helper_probe_single_connector_modes - drm_ioctl - drm_is_current_master - drm_kms_helper_poll_disable - drm_kms_helper_poll_enable - drm_kms_helper_poll_fini - drm_kms_helper_poll_init - drmm_mode_config_init - drm_mode_config_cleanup - drm_mode_config_reset - drm_mode_copy - drm_mode_crtc_set_gamma_size - drm_mode_duplicate - drm_mode_object_find - drm_mode_object_put - drm_mode_probed_add - drm_mode_set_crtcinfo - drm_mode_set_name - drm_mode_vrefresh - drm_object_attach_property - drm_open - drm_panel_add - drm_panel_disable - drm_panel_enable - drm_panel_get_modes - drm_panel_init - drm_panel_prepare - drm_panel_remove - drm_panel_unprepare - drm_plane_cleanup - drm_poll - drm_prime_gem_destroy - drm_property_blob_put - drm_property_create_blob - drm_property_create_range - drm_property_lookup_blob - drm_read - drm_release - drm_universal_plane_init - drm_vblank_init - drm_writeback_connector_init - drm_writeback_queue_job - drm_writeback_signal_completion - dump_stack - em_cpu_get - em_dev_register_perf_domain - enable_irq - enable_percpu_irq - ether_setup - eth_header - eth_header_cache - eth_header_cache_update - eth_header_parse - eth_mac_addr - eth_platform_get_mac_address - ethtool_op_get_link - ethtool_op_get_ts_info - eth_type_trans - eth_validate_addr - event_triggers_call - extcon_get_edev_by_phandle - extcon_get_state - extcon_set_state_sync - failure_tracking - fd_install - fget - find_get_pid - find_last_bit - find_next_bit - find_next_zero_bit - find_pid_ns - find_task_by_vpid - find_vma - find_vpid - finish_wait - flush_dcache_page - flush_delayed_work - flush_work - flush_workqueue - follow_pfn - font_vga_8x16 - for_each_kernel_tracepoint - fput - frame_vector_create - frame_vector_destroy - frame_vector_to_pages - frame_vector_to_pfns - free_irq - free_netdev - __free_pages - free_pages - free_pages_exact - free_percpu - free_percpu_irq - freezing_slow_path - freq_qos_add_notifier - freq_qos_add_request - freq_qos_remove_request - freq_qos_update_request - fs_bio_set - fsg_common_create_luns - fsg_common_set_cdev - fsg_common_set_inquiry_string - fsg_common_set_sysfs - fsg_config_from_params - fsync_bdev - fwnode_device_is_available - fwnode_get_name - fwnode_graph_get_next_endpoint - fwnode_graph_get_port_parent - fwnode_graph_get_remote_endpoint - fwnode_graph_get_remote_port_parent - fwnode_graph_parse_endpoint - fwnode_handle_get - fwnode_handle_put - fwnode_property_get_reference_args - fwnode_property_present - fwnode_property_read_string - fwnode_property_read_u32_array - fwnode_property_read_u64_array - gcd - generic_file_llseek - generic_handle_irq - generic_iommu_put_resv_regions - generic_mii_ioctl - genlmsg_multicast_allns - genlmsg_put - genl_register_family - genl_unregister_family - genphy_resume - gen_pool_add_owner - gen_pool_alloc_algo_owner - gen_pool_avail - gen_pool_best_fit - gen_pool_create - gen_pool_destroy - gen_pool_free_owner - gen_pool_has_addr - gen_pool_set_algo - gen_pool_size - gen_pool_virt_to_phys - getboottime64 - get_cpu_device - get_cpu_idle_time - get_cpu_idle_time_us - get_cpu_iowait_time_us - get_device - get_each_dmabuf - get_freelist_nr_pages - __get_free_pages - get_governor_parent_kobj - get_kernel_pages - get_net_ns_by_fd - get_net_ns_by_pid - get_pid_task - get_random_bytes - get_random_u32 - __get_task_comm - get_task_exe_file - get_task_mm - get_unused_fd_flags - get_user_pages_remote - get_vaddr_frames - get_zeroed_page - gic_nonsecure_priorities - gov_attr_set_get - gov_attr_set_init - gov_attr_set_put - governor_sysfs_ops - gpiochip_add_data_with_key - gpiochip_generic_free - gpiochip_generic_request - gpiochip_get_data - gpiochip_lock_as_irq - gpiochip_unlock_as_irq - gpiod_direction_input - gpiod_direction_output - gpiod_direction_output_raw - gpiod_get_raw_value - gpiod_get_value_cansleep - gpiod_set_debounce - gpiod_set_value - gpiod_set_value_cansleep - gpiod_to_irq - gpio_free - gpio_request - gpio_request_one - gpio_to_desc - handle_level_irq - handle_nested_irq - handle_simple_irq - hashlen_string - have_governor_per_policy - hex_asc - hrtimer_active - hrtimer_cancel - hrtimer_forward - hrtimer_init - hrtimer_start_range_ns - hrtimer_try_to_cancel - __hw_addr_init - __hw_addr_sync - __hw_addr_unsync - i2c_add_adapter - i2c_del_adapter - i2c_del_driver - i2c_get_dma_safe_msg_buf - i2c_put_dma_safe_msg_buf - i2c_register_driver - i2c_smbus_read_byte_data - i2c_smbus_read_i2c_block_data - i2c_smbus_write_byte_data - i2c_smbus_write_i2c_block_data - i2c_smbus_write_word_data - i2c_transfer - i2c_transfer_buffer_flags - i2c_unregister_device - icc_link_create - icc_node_add - icc_node_create - icc_node_del - icc_node_destroy - icc_provider_add - icc_provider_del - icc_put - icc_set_bw - icc_sync_state - ida_alloc_range - ida_destroy - ida_free - idr_alloc - idr_destroy - idr_find - idr_for_each - idr_get_next - idr_remove - iio_alloc_pollfunc - iio_buffer_init - iio_buffer_put - iio_channel_get - iio_channel_release - iio_dealloc_pollfunc - iio_device_attach_buffer - __iio_device_register - iio_device_unregister - iio_get_channel_type - iio_get_time_ns - iio_push_to_buffers - iio_read_channel_attribute - iio_read_channel_processed - iio_read_channel_raw - iio_trigger_notify_done - inc_zone_page_state - in_egroup_p - inet_csk_get_port - init_net - init_pseudo - __init_rwsem - __init_swait_queue_head - init_task - init_timer_key - init_uts_ns - init_wait_entry - __init_waitqueue_head - input_allocate_device - input_event - input_free_device - input_mt_init_slots - input_mt_report_slot_state - input_register_device - input_set_abs_params - input_set_capability - input_unregister_device - iommu_alloc_resv_region - iommu_device_register - iommu_device_sysfs_add - iommu_device_sysfs_remove - iommu_device_unregister - iommu_fwspec_add_ids - iommu_fwspec_free - iommu_get_dma_cookie - iommu_get_domain_for_dev - iommu_group_alloc - iommu_group_ref_get - iommu_iova_to_phys - iommu_map - iommu_map_sg - iommu_present - iommu_put_dma_cookie - iommu_unmap - __ioremap - ioremap_cache - iounmap - iput - ipv6_skip_exthdr - irq_create_mapping_affinity - irq_create_of_mapping - irq_dispose_mapping - __irq_domain_add - irq_domain_remove - irq_domain_simple_ops - irq_domain_xlate_onetwocell - irq_domain_xlate_twocell - irq_find_mapping - irq_get_irqchip_state - irq_get_irq_data - irq_modify_status - irq_of_parse_and_map - irq_set_affinity_hint - irq_set_chained_handler_and_data - irq_set_chip - irq_set_chip_and_handler_name - irq_set_chip_data - irq_set_irq_type - irq_set_irq_wake - irq_set_parent - irq_to_desc - irq_work_queue - irq_work_sync - is_dma_buf_file - is_vmalloc_addr - iterate_fd - jiffies - jiffies_to_msecs - jiffies_to_usecs - kasan_flag_enabled - kasprintf - kernel_cpustat - kernel_kobj - kernel_param_lock - kernel_param_unlock - kernel_power_off - kernel_restart - kernel_sigaction - kernfs_path_from_node - kern_mount - kern_unmount - key_create_or_update - key_put - keyring_alloc - __kfifo_alloc - __kfifo_free - __kfifo_in - __kfifo_out - __kfifo_to_user - kfree - kfree_const - kfree_sensitive - kfree_skb - kfree_skb_list - kill_anon_super - kimage_vaddr - kimage_voffset - __kmalloc - kmalloc_caches - kmalloc_order_trace - kmem_cache_alloc - kmem_cache_alloc_trace - kmem_cache_create - kmem_cache_destroy - kmem_cache_free - kmemdup - kobject_add - kobject_create_and_add - kobject_del - kobject_get - kobject_init - kobject_init_and_add - kobject_put - kobject_uevent - kobject_uevent_env - krealloc - kstrdup - kstrdup_const - kstrndup - kstrtobool - kstrtoint - kstrtoint_from_user - kstrtol_from_user - kstrtoll - kstrtou16 - kstrtou8 - kstrtouint - kstrtouint_from_user - kstrtoul_from_user - kstrtoull - kstrtoull_from_user - ksys_sync_helper - kthread_bind - kthread_bind_mask - kthread_cancel_delayed_work_sync - kthread_cancel_work_sync - kthread_create_on_node - kthread_create_worker - kthread_delayed_work_timer_fn - kthread_destroy_worker - kthread_flush_work - kthread_flush_worker - __kthread_init_worker - kthread_queue_delayed_work - kthread_queue_work - kthread_should_stop - kthread_stop - kthread_worker_fn - ktime_get - ktime_get_coarse_with_offset - ktime_get_mono_fast_ns - ktime_get_raw_ts64 - ktime_get_real_ts64 - ktime_get_seconds - ktime_get_ts64 - ktime_get_with_offset - kvfree - kvfree_call_rcu - kvmalloc_node - led_classdev_flash_register_ext - led_classdev_flash_unregister - led_get_flash_fault - led_set_brightness_sync - led_set_flash_brightness - led_set_flash_timeout - led_sysfs_disable - led_sysfs_enable - led_trigger_remove - led_update_brightness - led_update_flash_brightness - __list_add_valid - __list_del_entry_valid - list_sort - __local_bh_enable_ip - __lock_page - log_buf_addr_get - log_buf_len_get - __log_post_read_mmio - __log_read_mmio - log_threaded_irq_wakeup_reason - __log_write_mmio - lzo1x_1_compress - lzo1x_decompress_safe - lzorle1x_1_compress - match_hex - match_int - match_token - mbox_chan_received_data - mbox_client_txdone - mbox_controller_register - mbox_controller_unregister - mbox_free_channel - mbox_request_channel - mbox_send_message - mdiobus_alloc_size - mdiobus_free - __mdiobus_register - mdiobus_unregister - media_create_intf_link - media_create_pad_link - media_device_cleanup - media_device_init - __media_device_register - media_device_unregister - media_devnode_create - media_devnode_remove - media_entity_pads_init - media_entity_remote_pad - media_entity_remove_links - media_graph_walk_next - media_graph_walk_start - media_pipeline_start - media_pipeline_stop - media_request_get_by_fd - media_request_object_complete - media_request_put - memblock_end_of_DRAM - memchr - memcmp - memcpy - __memcpy_fromio - __memcpy_toio - memmove - memory_read_from_buffer - memparse - memremap - memset64 - memset - __memset_io - memstart_addr - memunmap - migrate_swap - mii_check_media - mii_ethtool_get_link_ksettings - mii_ethtool_gset - mii_ethtool_set_link_ksettings - mii_link_ok - mii_nway_restart - mipi_dsi_attach - mipi_dsi_dcs_read - mipi_dsi_dcs_write - mipi_dsi_dcs_write_buffer - mipi_dsi_detach - mipi_dsi_driver_register_full - mipi_dsi_driver_unregister - mipi_dsi_generic_read - mipi_dsi_generic_write - mipi_dsi_host_register - mipi_dsi_host_unregister - misc_deregister - misc_register - mktime64 - mmc_add_host - mmc_alloc_host - mmc_can_gpio_cd - mmc_cqe_request_done - mmc_detect_change - mmc_free_host - mmc_gpio_get_cd - mmc_gpio_get_ro - mmc_hw_reset - mmc_of_parse - mmc_regulator_get_supply - mmc_regulator_set_ocr - mmc_regulator_set_vqmmc - mmc_remove_host - mmc_request_done - mmc_send_tuning - mmput - mod_delayed_work_on - mod_timer - mod_timer_pending - module_layout - __msecs_to_jiffies - msleep - msleep_interruptible - __mutex_init - mutex_is_locked - mutex_lock - mutex_lock_interruptible - mutex_lock_killable - mutex_trylock - mutex_unlock - napi_disable - napi_gro_flush - napi_gro_receive - __napi_schedule - napi_schedule_prep - nd_tbl - netdev_alloc_frag - __netdev_alloc_skb - netdev_err - netdev_info - netdev_set_default_ethtool_ops - netdev_warn - netif_carrier_off - netif_carrier_on - netif_napi_add - netif_receive_skb - netif_receive_skb_list - netif_rx - netif_rx_ni - netif_tx_stop_all_queues - netif_tx_wake_queue - netlink_broadcast - __netlink_kernel_create - netlink_register_notifier - netlink_unicast - netlink_unregister_notifier - net_namespace_list - net_ns_type_operations - net_ratelimit - nf_register_net_hooks - nf_unregister_net_hooks - nla_find - nla_memcpy - __nla_parse - nla_put_64bit - nla_put - nla_reserve - __nla_validate - __nlmsg_put - no_llseek - nonseekable_open - nr_cpu_ids - nsecs_to_jiffies - ns_to_timespec64 - __num_online_cpus - nvmem_cell_get - nvmem_cell_put - nvmem_cell_read - nvmem_cell_read_u32 - nvmem_cell_write - nvmem_device_get - nvmem_device_put - nvmem_device_read - of_address_to_resource - of_alias_get_id - of_clk_add_provider - of_clk_del_provider - of_clk_get - of_clk_get_by_name - of_clk_get_from_provider - of_clk_src_onecell_get - of_clk_src_simple_get - of_count_phandle_with_args - of_cpu_node_to_id - of_device_get_match_data - of_device_is_available - of_device_is_compatible - of_dma_configure_id - of_dma_controller_free - of_dma_controller_register - of_dma_xlate_by_chan_id - of_drm_find_bridge - of_drm_find_panel - of_find_backlight_by_node - of_find_compatible_node - of_find_device_by_node - of_find_matching_node_and_match - of_find_node_by_name - of_find_node_by_phandle - of_find_node_opts_by_path - of_find_node_with_property - of_find_property - of_fwnode_ops - of_genpd_add_device - of_genpd_add_provider_onecell - of_get_address - of_get_child_by_name - of_get_cpu_node - of_get_named_gpio_flags - of_get_next_available_child - of_get_next_child - of_get_next_parent - of_get_parent - of_get_property - of_get_regulator_init_data - of_graph_get_next_endpoint - of_graph_get_remote_node - of_graph_get_remote_port_parent - of_icc_get - of_icc_xlate_onecell - of_iomap - of_irq_find_parent - of_irq_get - of_irq_parse_one - of_irq_to_resource_table - of_machine_is_compatible - of_match_device - of_match_node - of_parse_phandle - of_parse_phandle_with_args - of_parse_phandle_with_fixed_args - of_phandle_iterator_init - of_phandle_iterator_next - of_phy_simple_xlate - of_platform_depopulate - of_platform_device_create - of_platform_populate - of_property_count_elems_of_size - of_property_match_string - of_property_read_string - of_property_read_string_helper - of_property_read_u32_index - of_property_read_u64 - of_property_read_variable_u16_array - of_property_read_variable_u32_array - of_property_read_variable_u64_array - of_property_read_variable_u8_array - of_prop_next_string - of_prop_next_u32 - of_remove_property - of_reserved_mem_device_init_by_idx - of_reserved_mem_lookup - of_thermal_get_trip_points - of_translate_address - on_each_cpu - oops_in_progress - page_endio - page_mapping - __page_pinner_migration_failed - panic - panic_notifier_list - param_array_ops - param_get_bool - param_get_charp - param_get_int - param_get_uint - param_get_ulong - param_ops_bool - param_ops_charp - param_ops_int - param_ops_uint - param_set_bool - param_set_charp - param_set_uint - param_set_ulong - pause_cpus - PDE_DATA - __per_cpu_offset - perf_event_create_kernel_counter - perf_event_disable - perf_event_enable - perf_event_release_kernel - perf_event_update_userpage - perf_pmu_migrate_context - perf_pmu_register - perf_pmu_unregister - perf_trace_buf_alloc - perf_trace_run_bpf_submit - pfn_valid - phy_connect - phy_disconnect - phy_do_ioctl_running - phy_ethtool_get_link_ksettings - phy_ethtool_nway_reset - phy_ethtool_set_link_ksettings - phy_exit - phy_get - phy_init - phy_power_off - phy_power_on - phy_print_status - phy_put - phy_set_mode_ext - phy_start - phy_stop - pid_task - pinconf_generic_parse_dt_config - pinctrl_dev_get_drvdata - pinctrl_enable - pinctrl_gpio_direction_input - pinctrl_gpio_direction_output - pinctrl_lookup_state - pinctrl_pm_select_default_state - pinctrl_pm_select_sleep_state - pinctrl_put - pinctrl_select_state - pinctrl_utils_add_map_configs - pinctrl_utils_free_map - pinctrl_utils_reserve_map - pin_user_pages - pin_user_pages_fast - platform_bus_type - platform_device_add - platform_device_add_data - platform_device_alloc - platform_device_del - platform_device_put - platform_device_register - platform_device_register_full - platform_device_unregister - __platform_driver_register - platform_driver_unregister - platform_find_device_by_driver - platform_get_irq - platform_get_irq_byname - platform_get_irq_byname_optional - platform_get_irq_optional - platform_get_resource - platform_get_resource_byname - __platform_register_drivers - platform_unregister_drivers - pm_genpd_add_device - pm_genpd_add_subdomain - pm_genpd_init - pm_genpd_remove_device - __pm_relax - pm_relax - __pm_runtime_disable - pm_runtime_enable - pm_runtime_force_resume - pm_runtime_force_suspend - pm_runtime_get_if_active - __pm_runtime_idle - __pm_runtime_resume - pm_runtime_set_autosuspend_delay - __pm_runtime_set_status - __pm_runtime_suspend - __pm_runtime_use_autosuspend - __pm_stay_awake - pm_stay_awake - pm_suspend_default_s2idle - pm_system_wakeup - pm_wakeup_dev_event - pm_wakeup_ws_event - pm_wq - power_supply_changed - power_supply_get_by_name - power_supply_get_drvdata - power_supply_get_property - power_supply_put - power_supply_register - power_supply_reg_notifier - power_supply_set_property - prandom_bytes - prandom_u32 - preempt_schedule - preempt_schedule_notrace - prepare_to_wait_event - print_hex_dump - printk - printk_deferred - proc_create - proc_create_data - proc_create_single_data - proc_mkdir - proc_remove - proc_set_user - pskb_expand_head - __pskb_pull_tail - ___pskb_trim - put_device - put_disk - __put_net - __put_page - put_pid - __put_task_struct - put_unused_fd - put_vaddr_frames - pwm_apply_state - pwmchip_add - pwmchip_remove - queue_delayed_work_on - queue_work_on - ___ratelimit - raw_notifier_call_chain - raw_notifier_chain_register - raw_notifier_chain_unregister - _raw_read_lock - _raw_read_lock_bh - _raw_read_lock_irqsave - _raw_read_trylock - _raw_read_unlock - _raw_read_unlock_bh - _raw_read_unlock_irqrestore - _raw_spin_lock - _raw_spin_lock_bh - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_trylock - _raw_spin_unlock - _raw_spin_unlock_bh - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - _raw_write_lock - _raw_write_lock_bh - _raw_write_lock_irqsave - _raw_write_unlock - _raw_write_unlock_bh - _raw_write_unlock_irqrestore - rb_erase - rb_first - rb_insert_color - rb_next - rcu_barrier - rcu_idle_enter - rcu_idle_exit - __rcu_read_lock - __rcu_read_unlock - rdev_get_dev - rdev_get_drvdata - rdev_get_id - rdev_get_regmap - refcount_warn_saturate - __refrigerator - regcache_cache_only - regcache_mark_dirty - regcache_sync - register_blkdev - __register_chrdev - register_chrdev_region - register_die_notifier - register_inet6addr_notifier - register_inetaddr_notifier - register_kprobe - register_module_notifier - register_netdev - register_netdevice - register_netdevice_notifier - register_oom_notifier - register_pernet_device - register_pernet_subsys - register_pm_notifier - register_reboot_notifier - __register_rpmsg_driver - register_shrinker - register_syscore_ops - register_virtio_device - register_virtio_driver - regmap_bulk_read - regmap_bulk_write - regmap_field_read - regmap_field_update_bits_base - __regmap_init - regmap_irq_get_domain - regmap_raw_read - regmap_raw_write - regmap_read - regmap_update_bits_base - regmap_write - regulator_count_voltages - regulator_disable - regulator_disable_regmap - regulator_enable - regulator_enable_regmap - regulator_get - regulator_get_current_limit_regmap - regulator_get_mode - regulator_get_optional - regulator_get_voltage - regulator_get_voltage_sel_regmap - regulator_is_enabled - regulator_is_enabled_regmap - regulator_list_voltage - regulator_list_voltage_linear - regulator_list_voltage_linear_range - regulator_list_voltage_table - regulator_map_voltage_iterate - regulator_map_voltage_linear - regulator_map_voltage_linear_range - regulator_notifier_call_chain - regulator_put - regulator_set_active_discharge_regmap - regulator_set_current_limit - regulator_set_current_limit_regmap - regulator_set_mode - regulator_set_voltage - regulator_set_voltage_sel_regmap - regulator_set_voltage_time - regulator_set_voltage_time_sel - regulator_sync_voltage - release_firmware - release_pages - remap_pfn_range - remap_vmalloc_range - remove_proc_entry - remove_proc_subtree - remove_wait_queue - request_firmware - request_firmware_nowait - __request_percpu_irq - request_threaded_irq - reset_control_assert - reset_control_deassert - reset_controller_register - reset_control_reset - resume_cpus - revalidate_disk_size - rfkill_alloc - rfkill_blocked - rfkill_destroy - rfkill_pause_polling - rfkill_register - rfkill_resume_polling - rfkill_set_hw_state - rfkill_unregister - rhashtable_free_and_destroy - rhashtable_insert_slow - rhltable_init - __rht_bucket_nested - rht_bucket_nested - rht_bucket_nested_insert - root_task_group - round_jiffies - round_jiffies_relative - round_jiffies_up - rpmsg_create_ept - rpmsg_destroy_ept - rpmsg_find_device - rpmsg_register_device - rpmsg_send - rpmsg_trysend - rpmsg_unregister_device - rproc_add - rproc_add_subdev - rproc_alloc - rproc_boot - rproc_del - rproc_free - rproc_get_by_phandle - rproc_put - rproc_remove_subdev - rproc_report_crash - rproc_shutdown - rps_needed - rtc_ktime_to_tm - rtc_nvmem_register - __rtc_register_device - rtc_time64_to_tm - rtc_tm_to_ktime - rtc_tm_to_time64 - rtc_update_irq - rtc_valid_tm - rtnl_is_locked - rtnl_lock - rtnl_unlock - runqueues - __sbitmap_queue_get - sched_clock - sched_feat_keys - sched_setattr_nocheck - sched_set_normal - sched_setscheduler - sched_setscheduler_nocheck - sched_uclamp_used - schedule - schedule_timeout - scmi_driver_register - scmi_driver_unregister - scmi_protocol_register - scnprintf - scsi_autopm_get_device - scsi_autopm_put_device - scsi_block_requests - scsi_command_size_tbl - scsi_device_get - scsi_device_put - scsi_device_quiesce - __scsi_execute - __scsi_iterate_devices - scsi_normalize_sense - scsi_print_sense_hdr - scsi_unblock_requests - sdio_signal_irq - send_sig - seq_hex_dump - seq_lseek - seq_open - seq_open_private - seq_printf - seq_putc - seq_puts - seq_read - seq_release - seq_release_private - seq_write - serial8250_do_set_termios - serial8250_do_shutdown - serial8250_do_startup - serial8250_get_port - serial8250_register_8250_port - serial8250_resume_port - serial8250_rpm_get - serial8250_rpm_put - serial8250_suspend_port - serial8250_unregister_port - set_cpus_allowed_ptr - set_normalized_timespec64 - set_page_dirty_lock - __SetPageMovable - set_task_cpu - set_user_nice - sg_alloc_table - sg_alloc_table_from_pages - sg_free_table - sg_init_one - sg_init_table - sg_miter_next - sg_miter_start - sg_miter_stop - sg_next - __sg_page_iter_next - __sg_page_iter_start - si_mem_available - simple_attr_open - simple_attr_read - simple_attr_release - simple_attr_write - simple_open - simple_read_from_buffer - simple_write_to_buffer - single_open - single_release - skb_add_rx_frag - skb_checksum_help - skb_clone - skb_clone_sk - skb_complete_wifi_ack - skb_copy - skb_copy_bits - skb_copy_expand - skb_dequeue - skb_ensure_writable - __skb_get_hash - __skb_gso_segment - skb_pull - skb_push - skb_put - skb_queue_head - skb_queue_purge - skb_queue_tail - skb_trim - snd_card_add_dev_attr - snd_ctl_boolean_mono_info - snd_jack_set_key - snd_pcm_format_physical_width - snd_pcm_format_width - snd_pcm_hw_constraint_integer - snd_pcm_hw_constraint_minmax - snd_pcm_hw_constraint_step - snd_pcm_lib_free_pages - snd_pcm_lib_malloc_pages - snd_pcm_lib_preallocate_free_for_all - snd_pcm_lib_preallocate_pages_for_all - snd_pcm_period_elapsed - snd_pcm_set_ops - snd_soc_add_component_controls - snd_soc_bytes_info_ext - snd_soc_bytes_tlv_callback - snd_soc_card_jack_new - snd_soc_component_exit_regmap - snd_soc_component_init_regmap - snd_soc_component_read - snd_soc_component_update_bits - snd_soc_component_write - snd_soc_dai_set_sysclk - snd_soc_dapm_add_routes - snd_soc_dapm_disable_pin - snd_soc_dapm_enable_pin - snd_soc_dapm_get_enum_double - snd_soc_dapm_get_pin_switch - snd_soc_dapm_get_volsw - snd_soc_dapm_info_pin_switch - snd_soc_dapm_new_controls - snd_soc_dapm_new_widgets - snd_soc_dapm_put_enum_double - snd_soc_dapm_put_pin_switch - snd_soc_dapm_put_volsw - snd_soc_dapm_sync - snd_soc_get_volsw - snd_soc_info_enum_double - snd_soc_info_volsw - snd_soc_jack_report - snd_soc_new_compress - snd_soc_of_get_dai_link_codecs - snd_soc_poweroff - snd_soc_put_volsw - snd_soc_register_component - snd_soc_resume - snd_soc_rtdcom_lookup - snd_soc_set_runtime_hwparams - snd_soc_unregister_component - snprintf - soc_device_register - soc_device_unregister - __sock_create - sock_release - sort - __spi_alloc_controller - spi_bus_type - spi_finalize_current_transfer - __spi_register_driver - spi_setup - spi_sync - spmi_controller_add - spmi_controller_alloc - spmi_controller_remove - __spmi_driver_register - spmi_ext_register_read - spmi_ext_register_readl - spmi_ext_register_write - spmi_ext_register_writel - spmi_register_read - spmi_register_write - spmi_register_zero_write - sprintf - srcu_init_notifier_head - srcu_notifier_call_chain - srcu_notifier_chain_register - srcu_notifier_chain_unregister - __srcu_read_unlock - sscanf - __stack_chk_fail - __stack_chk_guard - stack_trace_save - static_key_slow_dec - static_key_slow_inc - stop_one_cpu_nowait - stpcpy - strcasecmp - strchr - strcmp - strcpy - strcspn - strim - strlcat - strlcpy - strlen - strncasecmp - strncat - strncmp - strncpy - strncpy_from_user - strnlen - strnstr - strrchr - strreplace - strscpy - strsep - strstr - suspend_set_ops - __sw_hweight16 - __sw_hweight32 - __sw_hweight64 - __sw_hweight8 - sync_file_create - sync_file_get_fence - synchronize_irq - synchronize_net - synchronize_rcu - synchronize_srcu - syscon_node_to_regmap - syscon_regmap_lookup_by_compatible - syscon_regmap_lookup_by_phandle - sysfs_create_bin_file - sysfs_create_file_ns - sysfs_create_group - sysfs_create_link - __sysfs_match_string - sysfs_remove_bin_file - sysfs_remove_file_ns - sysfs_remove_group - sysfs_remove_link - sysfs_streq - system_freezable_power_efficient_wq - system_freezable_wq - system_freezing_cnt - system_highpri_wq - system_power_efficient_wq - system_state - system_unbound_wq - system_wq - sys_tz - task_active_pid_ns - __tasklet_hi_schedule - tasklet_init - tasklet_kill - __tasklet_schedule - tasklet_setup - tasklist_lock - __task_pid_nr_ns - __task_rq_lock - thermal_cooling_device_unregister - thermal_of_cooling_device_register - thermal_zone_get_temp - thermal_zone_get_zone_by_name - tick_nohz_get_idle_calls_cpu - timecounter_init - timecounter_read - timer_unstable_counter_workaround - topology_set_thermal_pressure - _totalram_pages - __trace_bprintk - __trace_bputs - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return - __traceiter_android_rvh_cpu_overutilized - __traceiter_android_rvh_dequeue_task - __traceiter_android_rvh_dequeue_task_fair - __traceiter_android_rvh_enqueue_task - __traceiter_android_rvh_enqueue_task_fair - __traceiter_android_rvh_find_busiest_group - __traceiter_android_rvh_find_energy_efficient_cpu - __traceiter_android_rvh_finish_prio_fork - __traceiter_android_rvh_prepare_prio_fork - __traceiter_android_rvh_rtmutex_prepare_setprio - __traceiter_android_rvh_sched_newidle_balance - __traceiter_android_rvh_select_task_rq_fair - __traceiter_android_rvh_setscheduler - __traceiter_android_rvh_set_user_nice - __traceiter_android_rvh_tick_entry - __traceiter_android_rvh_uclamp_eff_get - __traceiter_android_vh_alter_futex_plist_add - __traceiter_android_vh_alter_rwsem_list_add - __traceiter_android_vh_arch_set_freq_scale - __traceiter_android_vh_binder_restore_priority - __traceiter_android_vh_binder_set_priority - __traceiter_android_vh_binder_transaction_init - __traceiter_android_vh_cgroup_set_task - __traceiter_android_vh_check_bpf_syscall - __traceiter_android_vh_check_file_open - __traceiter_android_vh_check_mmap_file - __traceiter_android_vh_clear_mask_adjust - __traceiter_android_vh_clear_reserved_fmt_fields - __traceiter_android_vh_commit_creds - __traceiter_android_vh_em_cpu_energy - __traceiter_android_vh_exit_creds - __traceiter_android_vh_fill_ext_fmtdesc - __traceiter_android_vh_finish_update_load_avg_se - __traceiter_android_vh_iommu_alloc_iova - __traceiter_android_vh_iommu_free_iova - __traceiter_android_vh_logbuf - __traceiter_android_vh_override_creds - __traceiter_android_vh_prepare_update_load_avg_se - __traceiter_android_vh_revert_creds - __traceiter_android_vh_rwsem_init - __traceiter_android_vh_rwsem_wake - __traceiter_android_vh_rwsem_write_finished - __traceiter_android_vh_scheduler_tick - __traceiter_android_vh_selinux_avc_insert - __traceiter_android_vh_selinux_avc_lookup - __traceiter_android_vh_selinux_avc_node_delete - __traceiter_android_vh_selinux_avc_node_replace - __traceiter_android_vh_selinux_is_initialized - __traceiter_android_vh_set_memory_nx - __traceiter_android_vh_set_memory_ro - __traceiter_android_vh_set_memory_rw - __traceiter_android_vh_set_memory_x - __traceiter_android_vh_set_module_permit_after_init - __traceiter_android_vh_set_module_permit_before_init - __traceiter_android_vh_set_wake_flags - __traceiter_android_vh_syscall_prctl_finished - __traceiter_android_vh_ufs_send_command - __traceiter_android_vh_ufs_send_tm_command - __traceiter_cpu_frequency - __traceiter_pelt_se_tp - __traceiter_rwmmio_post_read - __traceiter_rwmmio_read - __traceiter_rwmmio_write - __traceiter_sched_update_nr_running_tp - __tracepoint_android_rvh_cpu_overutilized - __tracepoint_android_rvh_dequeue_task - __tracepoint_android_rvh_dequeue_task_fair - __tracepoint_android_rvh_enqueue_task - __tracepoint_android_rvh_enqueue_task_fair - __tracepoint_android_rvh_find_busiest_group - __tracepoint_android_rvh_find_energy_efficient_cpu - __tracepoint_android_rvh_finish_prio_fork - __tracepoint_android_rvh_prepare_prio_fork - __tracepoint_android_rvh_rtmutex_prepare_setprio - __tracepoint_android_rvh_sched_newidle_balance - __tracepoint_android_rvh_select_task_rq_fair - __tracepoint_android_rvh_setscheduler - __tracepoint_android_rvh_set_user_nice - __tracepoint_android_rvh_tick_entry - __tracepoint_android_rvh_uclamp_eff_get - __tracepoint_android_vh_alter_futex_plist_add - __tracepoint_android_vh_alter_rwsem_list_add - __tracepoint_android_vh_arch_set_freq_scale - __tracepoint_android_vh_binder_restore_priority - __tracepoint_android_vh_binder_set_priority - __tracepoint_android_vh_binder_transaction_init - __tracepoint_android_vh_cgroup_set_task - __tracepoint_android_vh_check_bpf_syscall - __tracepoint_android_vh_check_file_open - __tracepoint_android_vh_check_mmap_file - __tracepoint_android_vh_clear_mask_adjust - __tracepoint_android_vh_clear_reserved_fmt_fields - __tracepoint_android_vh_commit_creds - __tracepoint_android_vh_em_cpu_energy - __tracepoint_android_vh_exit_creds - __tracepoint_android_vh_fill_ext_fmtdesc - __tracepoint_android_vh_finish_update_load_avg_se - __tracepoint_android_vh_iommu_alloc_iova - __tracepoint_android_vh_iommu_free_iova - __tracepoint_android_vh_logbuf - __tracepoint_android_vh_override_creds - __tracepoint_android_vh_prepare_update_load_avg_se - __tracepoint_android_vh_revert_creds - __tracepoint_android_vh_rwsem_init - __tracepoint_android_vh_rwsem_wake - __tracepoint_android_vh_rwsem_write_finished - __tracepoint_android_vh_scheduler_tick - __tracepoint_android_vh_selinux_avc_insert - __tracepoint_android_vh_selinux_avc_lookup - __tracepoint_android_vh_selinux_avc_node_delete - __tracepoint_android_vh_selinux_avc_node_replace - __tracepoint_android_vh_selinux_is_initialized - __tracepoint_android_vh_set_memory_nx - __tracepoint_android_vh_set_memory_ro - __tracepoint_android_vh_set_memory_rw - __tracepoint_android_vh_set_memory_x - __tracepoint_android_vh_set_module_permit_after_init - __tracepoint_android_vh_set_module_permit_before_init - __tracepoint_android_vh_set_wake_flags - __tracepoint_android_vh_syscall_prctl_finished - __tracepoint_android_vh_ufs_send_command - __tracepoint_android_vh_ufs_send_tm_command - __tracepoint_cpu_frequency - __tracepoint_pelt_se_tp - tracepoint_probe_register - tracepoint_probe_unregister - __tracepoint_rwmmio_post_read - __tracepoint_rwmmio_read - __tracepoint_rwmmio_write - __tracepoint_sched_update_nr_running_tp - tracepoint_srcu - trace_print_array_seq - trace_print_hex_seq - trace_print_symbols_seq - __trace_puts - trace_raw_output_prep - trace_seq_printf - trace_seq_putc - tracing_off - try_wait_for_completion - tty_flip_buffer_push - tty_insert_flip_string_fixed_flag - tty_termios_baud_rate - tty_termios_encode_baud_rate - typec_get_drvdata - typec_mux_get_drvdata - typec_mux_register - typec_mux_set - typec_mux_unregister - typec_partner_set_identity - typec_register_partner - typec_register_port - typec_set_data_role - typec_set_orientation - typec_set_pwr_opmode - typec_set_pwr_role - typec_set_vconn_role - typec_switch_get_drvdata - typec_switch_register - typec_switch_unregister - typec_unregister_partner - uart_get_baud_rate - uart_get_divisor - uart_update_timeout - uclamp_eff_value - __udelay - ufshcd_delay_us - ufshcd_dme_get_attr - ufshcd_dme_set_attr - ufshcd_dump_regs - ufshcd_fixup_dev_quirks - ufshcd_get_pwr_dev_param - ufshcd_hba_enable - ufshcd_hba_stop - ufshcd_hold - ufshcd_link_recovery - ufshcd_make_hba_operational - ufshcd_pltfrm_init - ufshcd_pltfrm_resume - ufshcd_pltfrm_runtime_idle - ufshcd_pltfrm_runtime_resume - ufshcd_pltfrm_runtime_suspend - ufshcd_pltfrm_shutdown - ufshcd_pltfrm_suspend - ufshcd_query_attr - ufshcd_query_attr_retry - ufshcd_query_descriptor_retry - ufshcd_query_flag - ufshcd_read_desc_param - ufshcd_release - ufshcd_remove - ufshcd_uic_hibern8_exit - unlock_page - unpin_user_page - unpin_user_pages - unregister_blkdev - __unregister_chrdev - unregister_chrdev_region - unregister_die_notifier - unregister_inet6addr_notifier - unregister_inetaddr_notifier - unregister_kprobe - unregister_module_notifier - unregister_netdev - unregister_netdevice_many - unregister_netdevice_notifier - unregister_netdevice_queue - unregister_oom_notifier - unregister_pernet_device - unregister_pernet_subsys - unregister_pm_notifier - unregister_reboot_notifier - unregister_rpmsg_driver - unregister_shrinker - unregister_virtio_device - unregister_virtio_driver - up - update_devfreq - update_rq_clock - up_read - up_write - usb_add_config - usb_add_function - usb_add_gadget_udc - usb_add_hcd - usb_composite_probe - usb_composite_unregister - usb_copy_descriptors - usb_create_hcd - usb_create_shared_hcd - usb_debug_root - usb_del_gadget_udc - usb_deregister - usb_disabled - usb_ep_alloc_request - usb_ep_autoconfig - usb_ep_dequeue - usb_ep_disable - usb_ep_enable - usb_ep_free_request - usb_ep_queue - usb_ep_set_halt - usb_ep_set_maxpacket_limit - usb_function_register - usb_function_unregister - usb_gadget_connect - usb_gadget_disconnect - usb_gadget_giveback_request - usb_gadget_map_request - usb_gadget_probe_driver - usb_gadget_set_selfpowered - usb_gadget_set_state - usb_gadget_unmap_request - usb_get_dr_mode - usb_get_function - usb_get_function_instance - usb_get_maximum_speed - usb_hcd_is_primary_hcd - usb_hcd_poll_rh_status - usb_interface_id - usbnet_change_mtu - usbnet_disconnect - usbnet_get_drvinfo - usbnet_get_endpoints - usbnet_get_link - usbnet_get_link_ksettings - usbnet_get_msglevel - usbnet_get_stats64 - usbnet_link_change - usbnet_nway_reset - usbnet_open - usbnet_probe - usbnet_read_cmd - usbnet_read_cmd_nopm - usbnet_resume - usbnet_set_link_ksettings - usbnet_set_msglevel - usbnet_skb_return - usbnet_start_xmit - usbnet_stop - usbnet_suspend - usbnet_tx_timeout - usbnet_unlink_rx_urbs - usbnet_update_max_qlen - usbnet_write_cmd - usbnet_write_cmd_async - usbnet_write_cmd_nopm - usb_put_function - usb_put_function_instance - usb_put_hcd - usb_register_driver - usb_remove_function - usb_remove_hcd - usb_role_switch_get - usb_role_switch_get_drvdata - usb_role_switch_register - usb_role_switch_set_role - usb_role_switch_unregister - usb_speed_string - usb_string_id - __usecs_to_jiffies - usleep_range - uuid_null - v4l2_async_notifier_add_fwnode_subdev - v4l2_async_notifier_add_subdev - v4l2_async_notifier_cleanup - v4l2_async_notifier_init - v4l2_async_notifier_register - v4l2_async_notifier_unregister - v4l2_async_register_subdev - v4l2_async_subdev_notifier_register - v4l2_async_unregister_subdev - v4l2_compat_ioctl32 - v4l2_ctrl_find - v4l2_ctrl_g_ctrl - v4l2_ctrl_g_ctrl_int64 - v4l2_ctrl_handler_free - v4l2_ctrl_handler_init_class - v4l2_ctrl_handler_setup - __v4l2_ctrl_modify_range - v4l2_ctrl_new_custom - v4l2_ctrl_new_std - v4l2_ctrl_new_std_menu - v4l2_ctrl_new_std_menu_items - v4l2_ctrl_request_complete - v4l2_ctrl_request_setup - __v4l2_ctrl_s_ctrl - v4l2_ctrl_subdev_subscribe_event - v4l2_ctrl_subscribe_event - v4l2_device_register - v4l2_device_register_subdev - __v4l2_device_register_subdev_nodes - v4l2_device_unregister - v4l2_device_unregister_subdev - v4l2_event_queue - v4l2_event_queue_fh - v4l2_event_subdev_unsubscribe - v4l2_event_subscribe - v4l2_event_unsubscribe - v4l2_fh_add - v4l2_fh_del - v4l2_fh_exit - v4l2_fh_init - v4l2_fh_is_singular - v4l2_fh_open - __v4l2_find_nearest_size - v4l2_format_info - v4l2_i2c_subdev_init - v4l2_m2m_buf_copy_metadata - v4l2_m2m_buf_queue - v4l2_m2m_buf_remove - v4l2_m2m_ctx_init - v4l2_m2m_ctx_release - v4l2_m2m_dqbuf - v4l2_m2m_fop_mmap - v4l2_m2m_fop_poll - v4l2_m2m_get_curr_priv - v4l2_m2m_get_vq - v4l2_m2m_init - v4l2_m2m_ioctl_create_bufs - v4l2_m2m_ioctl_dqbuf - v4l2_m2m_ioctl_expbuf - v4l2_m2m_ioctl_prepare_buf - v4l2_m2m_ioctl_qbuf - v4l2_m2m_ioctl_querybuf - v4l2_m2m_ioctl_reqbufs - v4l2_m2m_ioctl_streamoff - v4l2_m2m_ioctl_streamon - v4l2_m2m_job_finish - v4l2_m2m_next_buf - v4l2_m2m_qbuf - v4l2_m2m_register_media_controller - v4l2_m2m_release - v4l2_m2m_request_queue - v4l2_m2m_resume - v4l2_m2m_streamoff - v4l2_m2m_suspend - v4l2_m2m_try_schedule - v4l2_m2m_unregister_media_controller - v4l2_pipeline_link_notify - v4l2_src_change_event_subscribe - v4l2_subdev_call_wrappers - v4l2_subdev_init - v4l2_subdev_link_validate - v4l2_subdev_link_validate_default - v4l_bound_align_image - vabits_actual - vb2_buffer_done - vb2_common_vm_ops - vb2_create_framevec - vb2_destroy_framevec - vb2_dma_contig_memops - vb2_fop_mmap - vb2_fop_poll - vb2_fop_release - vb2_ioctl_create_bufs - vb2_ioctl_dqbuf - vb2_ioctl_expbuf - vb2_ioctl_prepare_buf - vb2_ioctl_qbuf - vb2_ioctl_querybuf - vb2_ioctl_reqbufs - vb2_ioctl_streamoff - vb2_ioctl_streamon - vb2_ops_wait_finish - vb2_ops_wait_prepare - vb2_plane_cookie - vb2_plane_vaddr - vb2_queue_init - vb2_queue_release - vb2_request_object_is_buffer - vb2_request_queue - vb2_request_validate - vchan_dma_desc_free_list - vchan_init - vchan_tx_desc_free - vchan_tx_submit - verify_pkcs7_signature - vfree - video_devdata - video_device_alloc - video_device_release - video_device_release_empty - video_ioctl2 - __video_register_device - video_unregister_device - virtqueue_add_inbuf - virtqueue_add_outbuf - virtqueue_detach_unused_buf - virtqueue_get_buf - virtqueue_get_vring_size - virtqueue_kick - virtqueue_kick_prepare - virtqueue_notify - vmalloc - vmalloc_to_page - vmalloc_to_pfn - vmalloc_user - vmap - vm_event_states - vm_map_ram - vm_node_stat - vm_unmap_ram - vm_zone_stat - vring_del_virtqueue - vring_interrupt - vring_new_virtqueue - vscnprintf - vsnprintf - vsprintf - vunmap - vzalloc - wait_for_completion - wait_for_completion_interruptible - wait_for_completion_interruptible_timeout - wait_for_completion_io_timeout - wait_for_completion_killable - wait_for_completion_timeout - wait_woken - __wake_up - __wake_up_locked - wake_up_process - wakeup_source_add - wakeup_source_create - wakeup_source_destroy - wakeup_source_register - wakeup_source_remove - wakeup_source_unregister - __warn_printk - watchdog_init_timeout - watchdog_set_restart_priority - wireless_nlevent_flush - woken_wake_function - work_busy - work_on_cpu - ww_mutex_lock - ww_mutex_unlock - xhci_add_endpoint - xhci_check_bandwidth - xhci_drop_endpoint - xhci_gen_setup - xhci_get_endpoint_index - xhci_get_ep_ctx - xhci_init_driver - xhci_reset_bandwidth - -# preserved by --additions-only - all_vm_events - __arch_clear_user - __bitmap_equal - __bitmap_or - blk_insert_cloned_request - cache_line_size - cgroup_taskset_first - cgroup_taskset_next - class_create_file_ns - class_remove_file_ns - clear_page - cpufreq_update_util_data - cpu_pm_register_notifier - cpu_pm_unregister_notifier - debug_locks_off - devfreq_add_device - devfreq_cooling_unregister - devfreq_register_opp_notifier - devfreq_unregister_opp_notifier - dev_get_by_name - devm_of_pwm_get - devm_rc_allocate_device - devm_rc_register_device - dev_pm_opp_find_freq_exact - dev_pm_opp_put_regulators - dev_pm_opp_set_regulators - dma_buf_mmap - dma_fence_get_status - dma_fence_remove_callback - dma_heap_buffer_free - dma_sync_single_for_device - downgrade_write - down_read_trylock - get_user_pages - get_user_pages_fast - gpiod_set_raw_value - hci_alloc_dev - hci_free_dev - hci_recv_frame - hci_register_dev - hci_unregister_dev - hex_dump_to_buffer - iomem_resource - irq_work_run - jiffies_64_to_clock_t - __kfifo_init - kset_find_obj - kstrtobool_from_user - ktime_get_raw - led_classdev_unregister - __media_entity_setup_link - memdup_user - __mmdrop - module_put - netlink_kernel_release - nla_put_nohdr - n_tty_ioctl_helper - of_devfreq_cooling_register_power - of_root - param_ops_byte - param_ops_string - perf_num_counters - pin_user_pages_remote - put_task_stack - rb_prev - rb_replace_node - __release_region - __request_region - schedutil_cpu_util - sdio_claim_host - sdio_claim_irq - sdio_disable_func - sdio_enable_func - sdio_f0_readb - sdio_f0_writeb - sdio_get_host_pm_caps - sdio_readb - sdio_readl - sdio_readsb - sdio_register_driver - sdio_release_host - sdio_release_irq - sdio_set_block_size - sdio_set_host_pm_flags - sdio_unregister_driver - sdio_writeb - sdio_writel - sdio_writesb - send_sig_info - shmem_file_setup - si_meminfo - skb_pull_rcsum - skb_realloc_headroom - smp_call_function - smp_call_function_single - snd_soc_component_test_bits - sprint_symbol_no_offset - strpbrk - strspn - syscore_resume - syscore_suspend - system_long_wq - thermal_zone_device_update - __traceiter_android_rvh_after_enqueue_task - __traceiter_android_rvh_media_device_setup_link - __traceiter_android_rvh_sched_rebalance_domains - __traceiter_android_rvh_v4l2subdev_set_fmt - __traceiter_android_rvh_v4l2subdev_set_frame_interval - __traceiter_android_rvh_v4l2subdev_set_selection - __traceiter_android_vh_cgroup_attach - __traceiter_android_vh_ipv6_gen_linklocal_addr - __traceiter_android_vh_is_fpsimd_save - __traceiter_android_vh_media_device_setup_link - __traceiter_android_vh_v4l2subdev_set_fmt - __traceiter_android_vh_v4l2subdev_set_frame_interval - __traceiter_android_vh_v4l2subdev_set_selection - __traceiter_gpu_mem_total - __traceiter_task_newtask - __traceiter_xhci_urb_giveback - trace_output_call - __tracepoint_android_rvh_after_enqueue_task - __tracepoint_android_rvh_media_device_setup_link - __tracepoint_android_rvh_sched_rebalance_domains - __tracepoint_android_rvh_v4l2subdev_set_fmt - __tracepoint_android_rvh_v4l2subdev_set_frame_interval - __tracepoint_android_rvh_v4l2subdev_set_selection - __tracepoint_android_vh_cgroup_attach - __tracepoint_android_vh_ipv6_gen_linklocal_addr - __tracepoint_android_vh_is_fpsimd_save - __tracepoint_android_vh_media_device_setup_link - __tracepoint_android_vh_ufs_update_sdev - __tracepoint_android_vh_v4l2subdev_set_fmt - __tracepoint_android_vh_v4l2subdev_set_frame_interval - __tracepoint_android_vh_v4l2subdev_set_selection - __tracepoint_gpu_mem_total - __tracepoint_task_newtask - __tracepoint_xhci_urb_giveback - trace_print_flags_seq - try_module_get - tty_driver_flush_buffer - tty_register_ldisc - tty_unregister_ldisc - ufshcd_auto_hibern8_update - ufshcd_shutdown - unmap_mapping_range - unregister_syscore_ops - v4l2_m2m_buf_remove_by_buf - vmf_insert_pfn_prot - wait_for_completion_killable_timeout - wireless_send_event - ww_mutex_lock_interruptible - zlib_deflate - zlib_deflateEnd - zlib_deflateInit2 - zlib_deflateReset - zlib_deflate_workspacesize diff --git a/android/abi_gki_aarch64_oplus b/android/abi_gki_aarch64_oplus deleted file mode 100644 index 8a16c1d45a1c..000000000000 --- a/android/abi_gki_aarch64_oplus +++ /dev/null @@ -1,2058 +0,0 @@ -[abi_symbol_list] - activate_task - add_cpu - add_device_randomness - add_memory - add_memory_subsection - add_timer - add_uevent_var - add_wait_queue - alloc_anon_inode - alloc_chrdev_region - __alloc_disk_node - alloc_io_pgtable_ops - __alloc_pages_nodemask - __alloc_percpu - __alloc_skb - alloc_skb_with_frags - alloc_workqueue - amba_bustype - amba_driver_register - amba_driver_unregister - android_debug_per_cpu_symbol - android_debug_symbol - android_rvh_probe_register - anon_inode_getfile - __arch_copy_from_user - __arch_copy_in_user - __arch_copy_to_user - arch_timer_read_counter - argv_free - argv_split - arm64_const_caps_ready - arm64_use_ng_mappings - __arm_smccc_smc - atomic_notifier_call_chain - atomic_notifier_chain_register - atomic_notifier_chain_unregister - available_idle_cpu - bdget_disk - bdput - bio_endio - bitmap_allocate_region - __bitmap_andnot - __bitmap_clear - bitmap_find_next_zero_area_off - __bitmap_or - bitmap_parselist_user - bitmap_print_to_pagebuf - bitmap_release_region - __bitmap_set - blk_alloc_queue - blk_cleanup_queue - blk_execute_rq_nowait - blk_get_request - blk_mq_rq_cpu - blk_put_request - blk_queue_flag_clear - blk_queue_flag_set - blk_queue_io_min - blk_queue_io_opt - blk_queue_logical_block_size - blk_queue_max_discard_sectors - blk_queue_max_write_zeroes_sectors - blk_queue_physical_block_size - blk_rq_map_user - blk_rq_map_user_iov - blk_rq_unmap_user - blk_verify_command - blocking_notifier_call_chain - blocking_notifier_chain_register - blocking_notifier_chain_unregister - bpf_trace_run10 - bpf_trace_run12 - bpf_trace_run1 - bpf_trace_run2 - bpf_trace_run3 - bpf_trace_run4 - bpf_trace_run5 - bpf_trace_run6 - bpf_trace_run7 - bpf_trace_run8 - bpf_trace_run9 - bus_find_device - bus_for_each_dev - bus_register - bus_set_iommu - bus_unregister - cancel_delayed_work - cancel_delayed_work_sync - cancel_work_sync - capable - cdev_add - cdev_alloc - cdev_del - cdev_device_add - cdev_device_del - cdev_init - __cfi_slowpath - cgroup_path_ns - cgroup_taskset_first - cgroup_taskset_next - __check_object_size - check_preempt_curr - check_zeroed_user - __class_create - class_destroy - class_find_device - class_for_each_device - class_interface_unregister - __class_register - class_unregister - cleanup_srcu_struct - clear_page - __ClearPageMovable - clk_bulk_disable - clk_bulk_enable - clk_bulk_prepare - clk_bulk_put_all - clk_bulk_unprepare - __clk_determine_rate - clk_disable - clk_enable - clk_fixed_factor_ops - clk_fixed_rate_ops - clk_get - __clk_get_hw - __clk_get_name - clk_get_parent - clk_get_rate - clk_hw_get_flags - clk_hw_get_name - clk_hw_get_num_parents - clk_hw_get_parent - clk_hw_get_parent_by_index - clk_hw_get_rate - clk_hw_is_enabled - clk_hw_is_prepared - clk_hw_register - clk_hw_round_rate - clk_hw_unregister - __clk_is_enabled - __clk_mux_determine_rate_closest - clk_notifier_register - clk_notifier_unregister - clk_prepare - clk_put - clk_round_rate - clk_set_parent - clk_set_rate - clk_sync_state - clk_unprepare - cma_alloc - cma_get_name - cma_release - compat_alloc_user_space - compat_ptr_ioctl - complete - complete_all - completion_done - component_add - component_bind_all - component_del - component_master_add_with_match - component_master_del - component_match_add_release - component_unbind_all - config_ep_by_speed - configfs_register_subsystem - configfs_unregister_subsystem - config_group_init - config_group_init_type_name - config_item_get - config_item_put - console_stop - console_suspend_enabled - __const_udelay - consume_skb - contig_page_data - _copy_from_iter_full - __cpu_active_mask - cpu_bit_bitmap - cpufreq_cooling_unregister - cpufreq_cpu_get - cpufreq_cpu_get_raw - cpufreq_cpu_put - cpufreq_disable_fast_switch - cpufreq_driver_fast_switch - cpufreq_driver_resolve_freq - __cpufreq_driver_target - cpufreq_enable_fast_switch - cpufreq_freq_attr_scaling_available_freqs - cpufreq_freq_attr_scaling_boost_freqs - cpufreq_generic_frequency_table_verify - cpufreq_get_policy - cpufreq_register_driver - cpufreq_register_governor - cpufreq_register_notifier - cpufreq_unregister_driver - cpufreq_unregister_notifier - __cpuhp_remove_state - __cpuhp_setup_state - __cpuhp_setup_state_cpuslocked - __cpuhp_state_add_instance - __cpuhp_state_remove_instance - cpu_hwcap_keys - cpu_hwcaps - cpuidle_governor_latency_req - cpuidle_register_governor - cpu_irqtime - cpu_latency_qos_add_request - cpu_latency_qos_remove_request - cpu_latency_qos_request_active - cpu_latency_qos_update_request - cpu_maps_update_begin - cpu_maps_update_done - cpumask_next - cpumask_next_and - cpu_number - __cpu_online_mask - cpu_pm_register_notifier - cpu_pm_unregister_notifier - __cpu_possible_mask - __cpu_present_mask - cpupri_find_fitness - cpu_scale - cpus_read_lock - cpus_read_unlock - cpu_subsys - cpu_topology - crc32_le - crc8 - crc8_populate_msb - crypto_alloc_base - crypto_alloc_shash - crypto_comp_compress - crypto_comp_decompress - crypto_destroy_tfm - crypto_has_alg - crypto_register_alg - crypto_register_rngs - crypto_register_scomp - crypto_shash_digest - crypto_unregister_alg - crypto_unregister_rngs - crypto_unregister_scomp - css_next_child - _ctype - datagram_poll - deactivate_task - debugfs_attr_read - debugfs_attr_write - debugfs_create_bool - debugfs_create_dir - debugfs_create_file - debugfs_create_file_unsafe - debugfs_create_u32 - debugfs_create_u8 - debugfs_create_x32 - debugfs_create_x8 - debugfs_file_get - debugfs_file_put - debugfs_lookup - debugfs_remove - dec_zone_page_state - default_llseek - deferred_free - delayed_work_timer_fn - del_gendisk - del_timer - del_timer_sync - desc_to_gpio - destroy_workqueue - dev_coredumpv - _dev_crit - dev_driver_string - _dev_err - devfreq_add_device - devfreq_add_governor - devfreq_cooling_unregister - devfreq_get_devfreq_by_node - devfreq_remove_device - devfreq_remove_governor - devfreq_resume_device - devfreq_suspend_device - dev_fwnode - dev_get_by_name - dev_get_regmap - device_add - device_add_disk - device_add_groups - device_create - device_create_file - device_del - device_destroy - device_find_child - device_for_each_child - device_get_match_data - device_initialize - device_init_wakeup - device_link_add - device_match_fwnode - device_match_name - device_property_present - device_property_read_string - device_property_read_u16_array - device_property_read_u32_array - device_register - device_remove_file - device_show_int - device_store_int - device_unregister - device_wakeup_disable - device_wakeup_enable - _dev_info - devm_add_action - devm_blk_ksm_init - devm_clk_bulk_get_all - devm_clk_get - devm_clk_hw_register - devm_clk_put - devm_clk_register - devm_device_add_group - devm_device_remove_group - devm_extcon_dev_allocate - devm_extcon_dev_register - devm_extcon_dev_unregister - devm_free_irq - devm_gpiod_get_optional - devm_gpio_free - devm_gpio_request - devm_gpio_request_one - devm_hwspin_lock_register - devm_iio_channel_get - devm_iio_device_alloc - __devm_iio_device_register - devm_input_allocate_device - devm_ioremap - devm_ioremap_resource - devm_ioremap_wc - devm_iounmap - devm_kasprintf - devm_kfree - devm_kmalloc - devm_kmemdup - devm_kstrdup - devm_led_classdev_register_ext - devm_nvmem_cell_get - devm_nvmem_device_get - devm_nvmem_register - devm_of_clk_add_hw_provider - devm_of_icc_get - __devm_of_phy_provider_register - devm_of_platform_populate - devm_of_pwm_get - devm_pci_alloc_host_bridge - devm_phy_create - devm_phy_get - devm_pinctrl_get - devm_pinctrl_put - devm_pinctrl_register - devm_platform_ioremap_resource - devm_platform_ioremap_resource_byname - devm_power_supply_register - devm_regmap_field_alloc - __devm_regmap_init - __devm_regmap_init_i2c - __devm_regmap_init_mmio_clk - devm_regulator_bulk_get - devm_regulator_get - devm_regulator_get_optional - devm_regulator_put - devm_regulator_register - devm_regulator_register_notifier - devm_request_any_context_irq - devm_request_threaded_irq - __devm_reset_control_get - devm_reset_controller_register - devm_rtc_allocate_device - devm_thermal_of_cooling_device_register - devm_thermal_zone_of_sensor_register - devm_usb_get_phy_by_node - _dev_notice - dev_pm_domain_attach - dev_pm_domain_attach_by_name - dev_pm_domain_detach - dev_pm_genpd_add_notifier - dev_pm_genpd_remove_notifier - dev_pm_genpd_set_next_wakeup - dev_pm_genpd_set_performance_state - dev_pm_opp_add - dev_pm_opp_find_freq_ceil - dev_pm_opp_find_freq_exact - dev_pm_opp_find_freq_floor - dev_pm_opp_get_opp_count - dev_pm_opp_get_voltage - dev_pm_opp_of_add_table - dev_pm_opp_of_find_icc_paths - dev_pm_opp_of_register_em - dev_pm_opp_of_remove_table - dev_pm_opp_put - dev_pm_opp_put_clkname - dev_pm_opp_remove_all_dynamic - dev_pm_opp_set_clkname - dev_pm_opp_set_rate - dev_pm_opp_set_sharing_cpus - dev_pm_qos_add_notifier - dev_pm_qos_add_request - dev_pm_qos_read_value - dev_pm_qos_remove_notifier - dev_pm_qos_remove_request - dev_pm_qos_update_request - devres_add - devres_alloc_node - devres_destroy - devres_free - devres_release - dev_set_name - _dev_warn - disable_irq - disable_irq_nosync - disable_percpu_irq - disk_end_io_acct - disk_start_io_acct - divider_get_val - divider_recalc_rate - divider_ro_round_rate_parent - divider_round_rate_parent - dma_alloc_attrs - dma_async_device_register - dma_async_device_unregister - dma_async_tx_descriptor_init - dma_buf_attach - dma_buf_begin_cpu_access - dma_buf_begin_cpu_access_partial - dma_buf_detach - dma_buf_end_cpu_access - dma_buf_end_cpu_access_partial - dma_buf_export - dma_buf_fd - dma_buf_get - dma_buf_map_attachment - dma_buf_put - dma_buf_unmap_attachment - dma_buf_vmap - dma_buf_vunmap - dma_contiguous_default_area - dma_fence_add_callback - dma_fence_array_create - dma_fence_array_ops - dma_fence_context_alloc - dma_fence_default_wait - dma_fence_enable_sw_signaling - dma_fence_free - dma_fence_get_status - dma_fence_init - dma_fence_release - dma_fence_remove_callback - dma_fence_signal - dma_fence_signal_locked - dma_fence_wait_timeout - dma_free_attrs - dma_get_sgtable_attrs - dma_get_slave_channel - dma_heap_add - dma_heap_buffer_alloc - dma_heap_find - dma_heap_get_dev - dma_heap_get_drvdata - dma_heap_get_name - dmam_alloc_attrs - dma_map_page_attrs - dma_map_resource - dma_map_sg_attrs - dmam_free_coherent - dma_release_channel - dma_request_chan - dma_set_coherent_mask - dma_set_mask - dma_sync_sg_for_cpu - dma_sync_sg_for_device - dma_sync_single_for_cpu - dma_sync_single_for_device - dma_unmap_page_attrs - dma_unmap_resource - dma_unmap_sg_attrs - do_exit - down_read - down_write - d_path - dput - drain_workqueue - driver_find_device - driver_register - driver_unregister - dump_stack - edac_device_add_device - edac_device_alloc_ctl_info - edac_device_alloc_index - edac_device_del_device - edac_device_free_ctl_info - edac_device_handle_ce_count - edac_device_handle_ue_count - enable_irq - enable_percpu_irq - eventfd_ctx_fdget - eventfd_ctx_fileget - eventfd_ctx_put - eventfd_ctx_remove_wait_queue - eventfd_signal - event_triggers_call - extcon_get_edev_by_phandle - extcon_get_edev_name - extcon_get_property - extcon_get_state - extcon_register_notifier - extcon_set_state_sync - failure_tracking - fasync_helper - __fdget - fd_install - fget - filp_close - filp_open_block - find_last_bit - find_next_bit - find_next_zero_bit - find_snd_usb_substream - find_task_by_vpid - find_vma - find_vpid - finish_wait - firmware_request_nowarn - flush_dcache_page - flush_delayed_work - flush_work - flush_workqueue - fput - free_io_pgtable_ops - free_irq - __free_pages - free_pages - free_percpu - free_percpu_irq - freq_qos_add_request - freq_qos_remove_request - freq_qos_update_request - freq_scale - fsync_bdev - fwnode_find_reference - fwnode_get_next_child_node - fwnode_handle_get - fwnode_handle_put - fwnode_property_present - fwnode_property_read_string - fwnode_property_read_u32_array - generic_device_group - generic_handle_irq - generic_iommu_put_resv_regions - genlmsg_put - genl_register_family - genl_unregister_family - gen_pool_add_owner - gen_pool_alloc_algo_owner - gen_pool_avail - gen_pool_best_fit - gen_pool_create - gen_pool_destroy - gen_pool_first_fit_order_align - gen_pool_free_owner - gen_pool_has_addr - gen_pool_set_algo - gen_pool_size - gen_pool_virt_to_phys - getboottime64 - get_cpu_device - get_device - get_each_dmabuf - get_each_object_track - __get_free_pages - get_governor_parent_kobj - get_option - get_page_owner_handle - get_pfnblock_flags_mask - get_pid_task - get_random_bytes - get_random_u32 - get_sg_io_hdr - get_slabinfo - __get_task_comm - get_task_mm - get_task_pid - get_unmapped_area - get_unused_fd_flags - get_user_pages - gic_nonsecure_priorities - gov_attr_set_init - gov_attr_set_put - governor_sysfs_ops - gpiochip_add_data_with_key - gpiochip_add_pin_range - gpiochip_generic_free - gpiochip_generic_request - gpiochip_get_data - gpiochip_line_is_valid - gpiochip_lock_as_irq - gpiochip_remove - gpiochip_unlock_as_irq - gpiod_direction_input - gpiod_direction_output - gpiod_direction_output_raw - gpiod_get_optional - gpiod_get_raw_value - gpiod_get_value - gpiod_set_raw_value - gpiod_set_value - gpiod_set_value_cansleep - gpiod_to_irq - gpio_free - gpio_request - gpio_to_desc - handle_bad_irq - handle_edge_irq - handle_fasteoi_ack_irq - handle_fasteoi_irq - handle_level_irq - handle_nested_irq - handle_simple_irq - handle_sysrq - hashlen_string - hex_dump_to_buffer - hrtimer_active - hrtimer_cancel - hrtimer_forward - __hrtimer_get_remaining - hrtimer_init - hrtimer_start_range_ns - hrtimer_try_to_cancel - hvc_alloc - hvc_kick - hvc_poll - hvc_remove - hwrng_register - hwrng_unregister - hwspin_lock_free - hwspin_lock_request_specific - __hwspin_lock_timeout - __hwspin_unlock - hypervisor_kobj - i2c_add_adapter - i2c_del_adapter - i2c_del_driver - i2c_get_dma_safe_msg_buf - i2c_put_dma_safe_msg_buf - i2c_register_driver - i2c_smbus_read_byte_data - i2c_smbus_read_i2c_block_data - i2c_smbus_read_word_data - i2c_smbus_write_byte_data - i2c_smbus_write_i2c_block_data - i2c_smbus_write_word_data - i2c_transfer - i2c_transfer_buffer_flags - icc_get - icc_link_create - icc_node_add - icc_node_create - icc_node_del - icc_node_destroy - icc_provider_add - icc_provider_del - icc_put - icc_set_bw - icc_set_tag - ida_alloc_range - ida_free - idr_alloc - idr_alloc_cyclic - idr_destroy - idr_find - idr_for_each - idr_get_next - idr_preload - idr_remove - idr_replace - iio_channel_get - iio_channel_get_all - iio_channel_release - iio_read_channel_processed - import_iovec - inc_node_page_state - inc_zone_page_state - in_egroup_p - init_iova_domain - init_net - init_pseudo - __init_rwsem - init_srcu_struct - __init_swait_queue_head - init_task - init_timer_key - init_uts_ns - init_wait_entry - __init_waitqueue_head - input_alloc_absinfo - input_allocate_device - input_close_device - input_event - input_ff_create - input_ff_destroy - input_free_device - input_mt_init_slots - input_mt_report_pointer_emulation - input_mt_report_slot_state - input_open_device - input_register_device - input_register_handle - input_register_handler - input_set_abs_params - input_set_capability - input_unregister_device - input_unregister_handle - input_unregister_handler - interval_tree_insert - interval_tree_iter_first - interval_tree_iter_next - interval_tree_remove - int_sqrt - iommu_alloc_resv_region - iommu_attach_device - iommu_detach_device - iommu_device_register - iommu_device_sysfs_add - iommu_device_sysfs_remove - iommu_device_unregister - iommu_dma_get_resv_regions - iommu_domain_alloc - iommu_domain_free - iommu_domain_get_attr - iommu_domain_set_attr - iommu_fwspec_add_ids - iommu_fwspec_free - iommu_get_dma_cookie - iommu_get_domain_for_dev - iommu_get_msi_cookie - iommu_group_for_each_dev - iommu_group_get - iommu_group_get_iommudata - iommu_group_put - iommu_group_ref_get - iommu_group_set_iommudata - iommu_iova_to_phys - iommu_map - iommu_map_sg - iommu_present - iommu_put_dma_cookie - iommu_set_fault_handler - iommu_unmap - __ioread32_copy - __ioremap - iounmap - __iowrite32_copy - ipi_desc_get - iput - irq_chip_ack_parent - irq_chip_disable_parent - irq_chip_enable_parent - irq_chip_eoi_parent - irq_chip_get_parent_state - irq_chip_mask_parent - irq_chip_retrigger_hierarchy - irq_chip_set_affinity_parent - irq_chip_set_parent_state - irq_chip_set_type_parent - irq_chip_set_vcpu_affinity_parent - irq_chip_set_wake_parent - irq_chip_unmask_parent - irq_create_fwspec_mapping - irq_dispose_mapping - __irq_domain_add - irq_domain_alloc_irqs_parent - irq_domain_create_hierarchy - irq_domain_free_irqs_common - irq_domain_free_irqs_parent - irq_domain_get_irq_data - irq_domain_remove - irq_domain_set_hwirq_and_chip - irq_domain_set_info - irq_domain_update_bus_token - irq_domain_xlate_twocell - irq_do_set_affinity - irq_find_mapping - irq_find_matching_fwspec - irq_get_irqchip_state - irq_get_irq_data - irq_modify_status - irq_of_parse_and_map - irq_set_affinity_hint - irq_set_affinity_notifier - irq_set_chained_handler_and_data - irq_set_chip_and_handler_name - irq_set_chip_data - irq_set_irqchip_state - irq_set_irq_type - irq_set_irq_wake - irq_set_parent - irq_to_desc - irq_work_queue - irq_work_queue_on - irq_work_sync - is_dma_buf_file - isolate_and_split_free_page - isolate_anon_lru_page - is_vmalloc_addr - jiffies - jiffies_to_msecs - jiffies_to_usecs - kasan_flag_enabled - kasprintf - kernel_bind - kernel_connect - kernel_getsockname - kernel_kobj - kernel_power_off - kernel_recvmsg - kernel_restart - kernel_sendmsg - kern_mount - kern_unmount - __kfifo_alloc - __kfifo_in - __kfifo_out - kfree - kfree_const - kfree_sensitive - kfree_skb - kill_anon_super - kill_fasync - kimage_vaddr - kimage_voffset - __kmalloc - kmalloc_caches - kmalloc_order_trace - kmem_cache_alloc - kmem_cache_alloc_trace - kmem_cache_create - kmem_cache_create_usercopy - kmem_cache_destroy - kmem_cache_free - kmemdup - kmemdup_nul - kobject_add - kobject_create_and_add - kobject_del - kobject_init - kobject_init_and_add - kobject_put - kobject_set_name - kobject_uevent - kobj_sysfs_ops - krealloc - kset_create_and_add - ksize - ksoftirqd - kstat - kstat_irqs_cpu - kstat_irqs_usr - kstrdup - kstrdup_const - kstrndup - kstrtobool - kstrtoint - kstrtoll - kstrtou16 - kstrtou16_from_user - kstrtou8 - kstrtou8_from_user - kstrtouint - kstrtouint_from_user - kstrtoul_from_user - kstrtoull - kstrtoull_from_user - kthread_bind_mask - kthread_cancel_work_sync - kthread_create_on_node - kthread_create_worker - kthread_destroy_worker - kthread_flush_worker - __kthread_init_worker - kthread_queue_work - kthread_should_stop - kthread_stop - kthread_worker_fn - ktime_get - ktime_get_mono_fast_ns - ktime_get_real_seconds - ktime_get_real_ts64 - kvfree - kvmalloc_node - led_classdev_flash_register_ext - led_classdev_flash_unregister - led_classdev_unregister - __list_add_valid - __list_del_entry_valid - list_sort - llist_add_batch - llist_reverse_order - __lock_page - lock_sock_nested - log_buf_addr_get - log_buf_len_get - __log_post_read_mmio - __log_read_mmio - __log_write_mmio - lookup_page_ext - lzo1x_1_compress - lzo1x_decompress_safe - lzorle1x_1_compress - match_string - mbox_chan_received_data - mbox_chan_txdone - mbox_client_txdone - mbox_controller_register - mbox_controller_unregister - mbox_free_channel - mbox_request_channel - mbox_send_message - memblock_end_of_DRAM - __memcat_p - memchr - memcpy - __memcpy_fromio - __memcpy_toio - memdup_user - memmove - memory_block_size_bytes - memory_read_from_buffer - memparse - mempool_alloc - mempool_alloc_slab - mempool_create - mempool_destroy - mempool_free - mempool_free_slab - memremap - memset64 - memset - __memset_io - memstart_addr - memunmap - migrate_pages - migrate_swap - misc_deregister - misc_register - mmc_cqe_request_done - mmc_of_parse - mmc_regulator_get_supply - mmc_regulator_set_ocr - mmc_regulator_set_vqmmc - mmc_send_tuning - mmput - mod_delayed_work_on - mod_node_page_state - mod_timer - __module_get - module_layout - module_put - __msecs_to_jiffies - msleep - msleep_interruptible - __mutex_init - mutex_is_locked - mutex_lock - mutex_lock_interruptible - mutex_trylock - mutex_unlock - netlink_broadcast - __netlink_kernel_create - netlink_kernel_release - netlink_unicast - nla_find - nla_put - nla_reserve_64bit - nla_reserve - __nla_validate - __nlmsg_put - no_llseek - nonseekable_open - noop_llseek - nr_cpu_ids - nr_ipi_get - nr_irqs - ns_to_timespec64 - __num_online_cpus - nvmem_cell_get - nvmem_cell_put - nvmem_cell_read - nvmem_cell_read_u32 - nvmem_cell_write - nvmem_device_read - nvmem_device_write - of_address_to_resource - of_alias_get_id - of_clk_add_hw_provider - of_clk_add_provider - of_clk_del_provider - of_clk_hw_simple_get - of_clk_src_simple_get - of_count_phandle_with_args - of_cpufreq_cooling_register - of_cpu_node_to_id - of_devfreq_cooling_register - of_device_get_match_data - of_device_is_available - of_device_is_compatible - of_dma_configure_id - of_dma_controller_free - of_dma_controller_register - of_dma_is_coherent - of_drm_find_panel - of_find_compatible_node - of_find_device_by_node - of_find_i2c_device_by_node - of_find_matching_node_and_match - of_find_node_by_name - of_find_node_by_phandle - of_find_node_opts_by_path - of_find_node_with_property - of_find_property - of_fwnode_ops - of_genpd_add_provider_onecell - of_genpd_del_provider - of_get_address - of_get_child_by_name - of_get_cpu_node - of_get_named_gpio_flags - of_get_next_available_child - of_get_next_child - of_get_next_parent - of_get_property - of_get_regulator_init_data - of_graph_get_next_endpoint - of_graph_get_port_parent - of_graph_get_remote_endpoint - of_graph_is_present - of_graph_parse_endpoint - of_hwspin_lock_get_id - of_icc_get - of_icc_xlate_onecell - of_iomap - of_irq_find_parent - of_irq_get - of_irq_get_byname - of_irq_parse_one - of_match_device - of_match_node - of_n_addr_cells - of_node_name_eq - of_n_size_cells - of_parse_phandle - of_parse_phandle_with_args - of_parse_phandle_with_fixed_args - of_phandle_iterator_init - of_phandle_iterator_next - of_phy_simple_xlate - of_platform_depopulate - of_platform_device_create - of_platform_device_destroy - of_platform_populate - of_property_count_elems_of_size - of_property_match_string - of_property_read_string - of_property_read_string_helper - of_property_read_u32_index - of_property_read_u64_index - of_property_read_variable_u32_array - of_property_read_variable_u8_array - of_prop_next_string - of_prop_next_u32 - of_reserved_mem_device_init_by_idx - of_reserved_mem_device_release - of_reserved_mem_lookup - of_root - of_thermal_get_ntrips - of_thermal_get_trip_points - of_thermal_is_trip_valid - of_translate_address - on_each_cpu - oops_in_progress - overflowuid - page_endio - page_mapping - __page_pinner_migration_failed - panic - panic_notifier_list - panic_timeout - param_get_int - param_ops_bool - param_ops_int - param_ops_string - param_ops_uint - param_set_bool - pause_cpus - pci_alloc_irq_vectors_affinity - pci_assign_resource - pci_bus_type - pci_clear_master - pci_device_group - pci_dev_present - pci_disable_device - pcie_capability_read_word - pci_enable_device - pci_find_ext_capability - pci_free_irq_vectors - pci_get_device - pci_host_probe - pci_iomap - pci_irq_vector - pci_load_and_free_saved_state - pci_load_saved_state - pci_msi_create_irq_domain - pci_msi_mask_irq - pci_msi_unmask_irq - pci_read_config_dword - pci_read_config_word - __pci_register_driver - pci_release_region - pci_request_region - pci_restore_state - pci_save_state - pci_set_master - pci_set_power_state - pci_store_saved_state - pci_unregister_driver - pci_walk_bus - pci_write_config_dword - pcpu_nr_pages - PDE_DATA - __per_cpu_offset - per_cpu_ptr_to_phys - perf_aux_output_begin - perf_aux_output_end - perf_aux_output_flag - perf_event_create_kernel_counter - perf_event_enable - perf_event_read_local - perf_event_read_value - perf_event_release_kernel - perf_get_aux - perf_pmu_register - perf_pmu_unregister - perf_trace_buf_alloc - perf_trace_run_bpf_submit - pfn_valid - phy_calibrate - phy_exit - phy_init - phy_power_off - phy_power_on - phy_set_mode_ext - pick_highest_pushable_task - pid_nr_ns - pid_task - pinconf_generic_dt_node_to_map - pinctrl_dev_get_drvdata - pinctrl_force_default - pinctrl_force_sleep - pinctrl_lookup_state - pinctrl_pm_select_default_state - pinctrl_pm_select_sleep_state - pinctrl_select_state - pinctrl_utils_free_map - platform_bus_type - platform_device_add - platform_device_alloc - platform_device_del - platform_device_put - platform_device_register - platform_device_register_full - platform_device_unregister - __platform_driver_register - platform_driver_unregister - platform_get_irq - platform_get_irq_byname - platform_get_resource - platform_get_resource_byname - platform_irq_count - pm_clk_add - pm_clk_create - pm_clk_destroy - pm_clk_resume - pm_clk_suspend - pm_genpd_add_subdomain - pm_genpd_init - pm_genpd_remove - pm_genpd_remove_subdomain - pm_power_off - __pm_relax - pm_relax - pm_runtime_allow - pm_runtime_barrier - __pm_runtime_disable - pm_runtime_enable - pm_runtime_forbid - pm_runtime_force_resume - pm_runtime_force_suspend - __pm_runtime_idle - pm_runtime_irq_safe - pm_runtime_no_callbacks - __pm_runtime_resume - pm_runtime_set_autosuspend_delay - __pm_runtime_set_status - __pm_runtime_suspend - __pm_runtime_use_autosuspend - __pm_stay_awake - pm_stay_awake - pm_system_wakeup - pm_wakeup_dev_event - pm_wakeup_ws_event - power_supply_changed - power_supply_get_by_name - power_supply_get_drvdata - power_supply_get_property - power_supply_put - power_supply_reg_notifier - power_supply_set_property - power_supply_unregister - power_supply_unreg_notifier - prandom_u32 - preempt_schedule - preempt_schedule_notrace - prepare_to_wait_event - print_hex_dump - printk - printk_deferred - proc_create - proc_create_data - proc_dointvec - proc_dointvec_minmax - proc_dostring - proc_douintvec_minmax - proc_mkdir - proc_remove - proc_symlink - proto_register - proto_unregister - __pskb_pull_tail - public_key_verify_signature - putback_movable_pages - put_device - put_disk - put_iova_domain - __put_page - put_pid - put_sg_io_hdr - __put_task_struct - put_unused_fd - pwm_apply_state - pwmchip_add - pwmchip_remove - qcom_smem_state_get - qcom_smem_state_register - qcom_smem_state_unregister - qcom_smem_state_update_bits - queue_delayed_work_on - queue_work_on - radix_tree_insert - radix_tree_iter_delete - radix_tree_lookup - radix_tree_next_chunk - ___ratelimit - rational_best_approximation - raw_notifier_call_chain - raw_notifier_chain_register - raw_notifier_chain_unregister - _raw_read_lock - _raw_read_lock_bh - _raw_read_lock_irq - _raw_read_lock_irqsave - _raw_read_unlock - _raw_read_unlock_bh - _raw_read_unlock_irq - _raw_read_unlock_irqrestore - _raw_spin_lock - _raw_spin_lock_bh - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_trylock - _raw_spin_trylock_bh - _raw_spin_unlock - _raw_spin_unlock_bh - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - _raw_write_lock - _raw_write_lock_bh - _raw_write_lock_irq - _raw_write_lock_irqsave - _raw_write_unlock - _raw_write_unlock_bh - _raw_write_unlock_irq - _raw_write_unlock_irqrestore - rb_erase - rb_first - rb_insert_color - rb_last - rb_next - rb_prev - __rcu_read_lock - __rcu_read_unlock - rdev_get_drvdata - reboot_mode - refcount_dec_and_lock - refcount_dec_not_one - refcount_warn_saturate - register_blkdev - __register_chrdev - register_chrdev_region - register_console - register_die_notifier - register_ftrace_export - register_kretprobe - register_memory_notifier - register_module_notifier - register_pm_notifier - register_reboot_notifier - register_restart_handler - __register_rpmsg_driver - register_shrinker - register_syscore_ops - register_sysctl_table - regmap_bulk_read - regmap_bulk_write - regmap_check_range_table - regmap_field_read - regmap_field_update_bits_base - __regmap_init - regmap_mmio_detach_clk - regmap_read - regmap_update_bits_base - regmap_write - regulator_allow_bypass - regulator_bulk_disable - regulator_count_voltages - regulator_disable - regulator_enable - regulator_force_disable - regulator_get - regulator_get_drvdata - regulator_get_mode - regulator_get_voltage - regulator_get_voltage_rdev - regulator_is_enabled - regulator_is_supported_voltage - regulator_list_voltage_linear - regulator_notifier_call_chain - regulator_put - regulator_register_notifier - regulator_set_current_limit - regulator_set_load - regulator_set_mode - regulator_set_voltage - regulator_unregister_notifier - release_firmware - release_sock - remap_pfn_range - remove_cpu - remove_memory_subsection - remove_proc_entry - remove_proc_subtree - report_iommu_fault - request_any_context_irq - request_firmware - request_firmware_into_buf - request_firmware_nowait - __request_module - __request_percpu_irq - request_threaded_irq - resched_curr - reset_control_assert - reset_control_deassert - resume_cpus - revalidate_disk_size - rfkill_alloc - rfkill_destroy - rfkill_init_sw_state - rfkill_register - rfkill_unregister - rndis_deregister - rndis_free_response - rndis_get_next_response - rndis_msg_parser - rndis_register - rndis_set_host_mac - rndis_set_param_dev - rndis_set_param_medium - rndis_set_param_vendor - rndis_signal_connect - rndis_uninit - root_task_group - round_jiffies_relative - rpmsg_get_signals - rpmsg_poll - rpmsg_register_device - rpmsg_send - rpmsg_set_signals - rpmsg_trysend - rpmsg_unregister_device - rproc_add - rproc_add_subdev - rproc_alloc - rproc_boot - rproc_coredump_add_custom_segment - rproc_coredump_add_segment - rproc_coredump_set_elf_info - rproc_coredump_using_sections - rproc_del - rproc_free - rproc_get_by_child - rproc_get_by_phandle - rproc_put - rproc_remove_subdev - rproc_report_crash - rproc_shutdown - rtc_class_close - rtc_class_open - rtc_read_time - __rtc_register_device - rtc_time64_to_tm - rtc_tm_to_time64 - rtc_update_irq - rtc_valid_tm - runqueues - sched_clock - sched_feat_keys - sched_feat_names - sched_set_fifo - sched_set_normal - sched_setscheduler - sched_setscheduler_nocheck - sched_trace_rd_span - sched_uclamp_used - schedule - schedule_timeout - schedule_timeout_interruptible - scnprintf - scsi_autopm_get_device - scsi_autopm_put_device - scsi_block_when_processing_errors - scsi_command_size_tbl - scsi_compat_ioctl - scsi_device_get - scsi_device_put - scsi_device_quiesce - scsi_ioctl - scsi_ioctl_block_when_processing_errors - __scsi_iterate_devices - scsi_normalize_sense - __scsi_print_sense - scsi_register_interface - scsi_remove_device - sdev_prefix_printk - __sdhci_add_host - sdhci_add_host - sdhci_cleanup_host - sdhci_cqe_disable - sdhci_cqe_enable - sdhci_cqe_irq - sdhci_enable_clk - sdhci_get_property - sdhci_pltfm_free - sdhci_pltfm_init - sdhci_remove_host - sdhci_request - sdhci_reset - sdhci_set_bus_width - sdhci_set_power_noreg - sdhci_setup_host - seq_buf_printf - seq_lseek - seq_open - seq_printf - seq_putc - seq_puts - seq_read - seq_release - seq_write - set_cpus_allowed_ptr - set_normalized_timespec64 - set_page_dirty_lock - __SetPageMovable - set_task_cpu - set_user_nice - sg_alloc_table - sg_alloc_table_from_pages - sg_free_table - sg_init_one - sg_init_table - sg_miter_next - sg_miter_start - sg_miter_stop - sg_next - __sg_page_iter_dma_next - __sg_page_iter_next - __sg_page_iter_start - sg_scsi_ioctl - show_regs - sigprocmask - si_mem_available - si_meminfo - simple_attr_open - simple_attr_release - simple_open - simple_read_from_buffer - simple_strtol - simple_strtoul - simple_write_to_buffer - single_open - single_release - si_swapinfo - sk_alloc - skb_clone - skb_copy_bits - skb_copy_datagram_iter - skb_dequeue - skb_free_datagram - __skb_pad - skb_push - skb_put - skb_queue_purge - skb_queue_tail - skb_recv_datagram - skb_set_owner_w - skb_store_bits - skb_trim - sk_free - skip_spaces - smp_call_function_single - snd_pcm_format_width - snd_soc_add_component_controls - snd_soc_info_volsw - snd_soc_register_component - snd_soc_unregister_component - snd_usb_enable_audio_stream - snprintf - soc_device_register - soc_device_unregister - sock_alloc_send_skb - sock_create_kern - sock_gettstamp - sock_init_data - sock_no_accept - sock_no_listen - sock_no_mmap - sock_no_sendpage - sock_no_shutdown - sock_no_socketpair - sock_queue_rcv_skb - sock_register - sock_release - sock_setsockopt - sock_unregister - sort - __spi_alloc_controller - spi_register_controller - __spi_register_driver - spi_setup - spi_sync - spi_unregister_controller - spmi_controller_add - spmi_controller_alloc - spmi_controller_remove - __spmi_driver_register - spmi_ext_register_read - spmi_ext_register_readl - spmi_ext_register_write - spmi_ext_register_writel - spmi_register_read - spmi_register_write - spmi_register_zero_write - sprintf - srcu_init_notifier_head - srcu_notifier_call_chain - srcu_notifier_chain_register - srcu_notifier_chain_unregister - __srcu_read_lock - __srcu_read_unlock - sscanf - __stack_chk_fail - __stack_chk_guard - stack_depot_fetch - static_key_disable - stop_machine - stop_one_cpu_nowait - stpcpy - strcasecmp - strcat - strchr - strcmp - strcpy - strim - strlcat - strlcpy - strlen - strncasecmp - strnchr - strncmp - strncpy - strncpy_from_user - strnlen - strnstr - strpbrk - strrchr - strscpy - strsep - strstr - __sw_hweight32 - __sw_hweight64 - __sw_hweight8 - sync_file_create - sync_file_get_fence - synchronize_irq - synchronize_rcu - synchronize_srcu - syscon_node_to_regmap - syscon_regmap_lookup_by_phandle - sysctl_sched_features - sysctl_sched_latency - sysctl_vals - sysfs_add_file_to_group - sysfs_add_link_to_group - sysfs_create_bin_file - sysfs_create_file_ns - sysfs_create_files - sysfs_create_group - sysfs_create_link - sysfs_emit - __sysfs_match_string - sysfs_notify - sysfs_remove_bin_file - sysfs_remove_file_from_group - sysfs_remove_file_ns - sysfs_remove_files - sysfs_remove_group - sysfs_remove_link - sysfs_remove_link_from_group - sysfs_streq - sysrq_mask - system_freezable_wq - system_highpri_wq - system_power_efficient_wq - system_unbound_wq - system_wq - task_active_pid_ns - __tasklet_hi_schedule - tasklet_init - tasklet_kill - __tasklet_schedule - tasklet_setup - tasklist_lock - task_may_not_preempt - __task_pid_nr_ns - __task_rq_lock - task_rq_lock - thermal_cooling_device_register - thermal_cooling_device_unregister - thermal_of_cooling_device_register - thermal_pressure - thermal_zone_device_enable - thermal_zone_device_register - thermal_zone_device_unregister - thermal_zone_device_update - thermal_zone_get_slope - thermal_zone_get_temp - thermal_zone_get_zone_by_name - thermal_zone_of_sensor_register - thermal_zone_of_sensor_unregister - tick_nohz_get_sleep_length - time64_to_tm - topology_set_thermal_pressure - topology_update_done - total_swapcache_pages - trace_array_get_by_name - trace_array_put - trace_array_set_clr_event - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return - __traceiter_android_rvh_account_irq - __traceiter_android_rvh_build_perf_domains - __traceiter_android_rvh_can_migrate_task - __traceiter_android_rvh_check_preempt_wakeup - __traceiter_android_rvh_cpu_cgroup_attach - __traceiter_android_rvh_cpu_cgroup_online - __traceiter_android_rvh_dequeue_task - __traceiter_android_rvh_enqueue_task - __traceiter_android_rvh_find_busiest_queue - __traceiter_android_rvh_find_lowest_rq - __traceiter_android_rvh_flush_task - __traceiter_android_rvh_force_compatible_post - __traceiter_android_rvh_force_compatible_pre - __traceiter_android_rvh_gic_v3_set_affinity - __traceiter_android_rvh_migrate_queued_task - __traceiter_android_rvh_new_task_stats - __traceiter_android_rvh_pick_next_entity - __traceiter_android_rvh_place_entity - __traceiter_android_rvh_replace_next_task_fair - __traceiter_android_rvh_resume_cpus - __traceiter_android_rvh_sched_cpu_dying - __traceiter_android_rvh_sched_cpu_starting - __traceiter_android_rvh_sched_exec - __traceiter_android_rvh_sched_fork - __traceiter_android_rvh_sched_fork_init - __traceiter_android_rvh_sched_newidle_balance - __traceiter_android_rvh_sched_nohz_balancer_kick - __traceiter_android_rvh_sched_setaffinity - __traceiter_android_rvh_schedule - __traceiter_android_rvh_select_task_rq_fair - __traceiter_android_rvh_select_task_rq_rt - __traceiter_android_rvh_set_gfp_zone_flags - __traceiter_android_rvh_set_readahead_gfp_mask - __traceiter_android_rvh_set_skip_swapcache_flags - __traceiter_android_rvh_set_task_cpu - __traceiter_android_rvh_tick_entry - __traceiter_android_rvh_try_to_wake_up - __traceiter_android_rvh_try_to_wake_up_success - __traceiter_android_rvh_ttwu_cond - __traceiter_android_rvh_update_cpu_capacity - __traceiter_android_rvh_update_cpus_allowed - __traceiter_android_rvh_update_misfit_status - __traceiter_android_rvh_wake_up_new_task - __traceiter_android_vh_allow_domain_state - __traceiter_android_vh_alter_mutex_list_add - __traceiter_android_vh_alter_rwsem_list_add - __traceiter_android_vh_binder_restore_priority - __traceiter_android_vh_binder_set_priority - __traceiter_android_vh_binder_wait_for_work - __traceiter_android_vh_binder_wakeup_ilocked - __traceiter_android_vh_build_sched_domains - __traceiter_android_vh_check_uninterruptible_tasks - __traceiter_android_vh_check_uninterruptible_tasks_dn - __traceiter_android_vh_cpu_idle_enter - __traceiter_android_vh_cpu_idle_exit - __traceiter_android_vh_ftrace_dump_buffer - __traceiter_android_vh_ftrace_format_check - __traceiter_android_vh_ftrace_oops_enter - __traceiter_android_vh_ftrace_oops_exit - __traceiter_android_vh_ftrace_size_check - __traceiter_android_vh_gpio_block_read - __traceiter_android_vh_iommu_setup_dma_ops - __traceiter_android_vh_ipi_stop - __traceiter_android_vh_jiffies_update - __traceiter_android_vh_logbuf - __traceiter_android_vh_mutex_unlock_slowpath - __traceiter_android_vh_mutex_wait_finish - __traceiter_android_vh_mutex_wait_start - __traceiter_android_vh_printk_hotplug - __traceiter_android_vh_rwsem_wake - __traceiter_android_vh_rwsem_wake_finish - __traceiter_android_vh_scheduler_tick - __traceiter_android_vh_show_max_freq - __traceiter_android_vh_show_resume_epoch_val - __traceiter_android_vh_show_suspend_epoch_val - __traceiter_android_vh_sync_txn_recvd - __traceiter_android_vh_timer_calc_index - __traceiter_android_vh_update_topology_flags_workfn - __traceiter_binder_transaction_received - __traceiter_cpu_frequency_limits - __traceiter_gpu_mem_total - __traceiter_ipi_entry - __traceiter_ipi_raise - __traceiter_irq_handler_entry - __traceiter_rwmmio_post_read - __traceiter_rwmmio_read - __traceiter_rwmmio_write - __traceiter_sched_overutilized_tp - __traceiter_sched_switch - __traceiter_suspend_resume - __tracepoint_android_rvh_account_irq - __tracepoint_android_rvh_build_perf_domains - __tracepoint_android_rvh_can_migrate_task - __tracepoint_android_rvh_check_preempt_wakeup - __tracepoint_android_rvh_cpu_cgroup_attach - __tracepoint_android_rvh_cpu_cgroup_online - __tracepoint_android_rvh_dequeue_task - __tracepoint_android_rvh_enqueue_task - __tracepoint_android_rvh_find_busiest_queue - __tracepoint_android_rvh_find_lowest_rq - __tracepoint_android_rvh_flush_task - __tracepoint_android_rvh_force_compatible_post - __tracepoint_android_rvh_force_compatible_pre - __tracepoint_android_rvh_gic_v3_set_affinity - __tracepoint_android_rvh_migrate_queued_task - __tracepoint_android_rvh_new_task_stats - __tracepoint_android_rvh_pick_next_entity - __tracepoint_android_rvh_place_entity - __tracepoint_android_rvh_replace_next_task_fair - __tracepoint_android_rvh_resume_cpus - __tracepoint_android_rvh_sched_cpu_dying - __tracepoint_android_rvh_sched_cpu_starting - __tracepoint_android_rvh_sched_exec - __tracepoint_android_rvh_sched_fork - __tracepoint_android_rvh_sched_fork_init - __tracepoint_android_rvh_sched_newidle_balance - __tracepoint_android_rvh_sched_nohz_balancer_kick - __tracepoint_android_rvh_sched_setaffinity - __tracepoint_android_rvh_schedule - __tracepoint_android_rvh_select_task_rq_fair - __tracepoint_android_rvh_select_task_rq_rt - __tracepoint_android_rvh_set_gfp_zone_flags - __tracepoint_android_rvh_set_readahead_gfp_mask - __tracepoint_android_rvh_set_skip_swapcache_flags - __tracepoint_android_rvh_set_task_cpu - __tracepoint_android_rvh_tick_entry - __tracepoint_android_rvh_try_to_wake_up - __tracepoint_android_rvh_try_to_wake_up_success - __tracepoint_android_rvh_ttwu_cond - __tracepoint_android_rvh_update_cpu_capacity - __tracepoint_android_rvh_update_cpus_allowed - __tracepoint_android_rvh_update_misfit_status - __tracepoint_android_rvh_wake_up_new_task - __tracepoint_android_vh_allow_domain_state - __tracepoint_android_vh_alter_mutex_list_add - __tracepoint_android_vh_alter_rwsem_list_add - __tracepoint_android_vh_binder_restore_priority - __tracepoint_android_vh_binder_set_priority - __tracepoint_android_vh_binder_wait_for_work - __tracepoint_android_vh_binder_wakeup_ilocked - __tracepoint_android_vh_build_sched_domains - __tracepoint_android_vh_check_uninterruptible_tasks - __tracepoint_android_vh_check_uninterruptible_tasks_dn - __tracepoint_android_vh_cpu_idle_enter - __tracepoint_android_vh_cpu_idle_exit - __tracepoint_android_vh_ftrace_dump_buffer - __tracepoint_android_vh_ftrace_format_check - __tracepoint_android_vh_ftrace_oops_enter - __tracepoint_android_vh_ftrace_oops_exit - __tracepoint_android_vh_ftrace_size_check - __tracepoint_android_vh_gpio_block_read - __tracepoint_android_vh_iommu_setup_dma_ops - __tracepoint_android_vh_ipi_stop - __tracepoint_android_vh_jiffies_update - __tracepoint_android_vh_logbuf - __tracepoint_android_vh_mutex_unlock_slowpath - __tracepoint_android_vh_mutex_wait_finish - __tracepoint_android_vh_mutex_wait_start - __tracepoint_android_vh_printk_hotplug - __tracepoint_android_vh_rwsem_wake - __tracepoint_android_vh_rwsem_wake_finish - __tracepoint_android_vh_scheduler_tick - __tracepoint_android_vh_show_max_freq - __tracepoint_android_vh_show_resume_epoch_val - __tracepoint_android_vh_show_suspend_epoch_val - __tracepoint_android_vh_sync_txn_recvd - __tracepoint_android_vh_timer_calc_index - __tracepoint_android_vh_update_topology_flags_workfn - __tracepoint_binder_transaction_received - __tracepoint_cpu_frequency_limits - __tracepoint_gpu_mem_total - __tracepoint_ipi_entry - __tracepoint_ipi_raise - __tracepoint_irq_handler_entry - tracepoint_probe_register - tracepoint_probe_register_prio - tracepoint_probe_unregister - __tracepoint_rwmmio_post_read - __tracepoint_rwmmio_read - __tracepoint_rwmmio_write - __tracepoint_sched_overutilized_tp - __tracepoint_sched_switch - __tracepoint_suspend_resume - trace_print_array_seq - trace_print_flags_seq - trace_print_symbols_seq - trace_raw_output_prep - trace_seq_printf - trace_seq_putc - try_module_get - try_wait_for_completion - tty_flip_buffer_push - __tty_insert_flip_char - tty_insert_flip_string_fixed_flag - uart_add_one_port - uart_console_device - uart_console_write - uart_get_baud_rate - uart_insert_char - uart_parse_options - uart_register_driver - uart_remove_one_port - uart_resume_port - uart_set_options - uart_suspend_port - uart_try_toggle_sysrq - uart_unregister_driver - uart_update_timeout - uart_write_wakeup - uclamp_eff_value - ucsi_connector_change - ucsi_create - ucsi_destroy - ucsi_get_drvdata - ucsi_register - ucsi_set_drvdata - ucsi_unregister - __udelay - ufshcd_auto_hibern8_update - ufshcd_dme_get_attr - ufshcd_dme_set_attr - ufshcd_dump_regs - ufshcd_fixup_dev_quirks - ufshcd_get_local_unipro_ver - ufshcd_hold - ufshcd_pltfrm_init - ufshcd_pltfrm_resume - ufshcd_pltfrm_runtime_idle - ufshcd_pltfrm_runtime_resume - ufshcd_pltfrm_runtime_suspend - ufshcd_pltfrm_suspend - ufshcd_query_attr - ufshcd_query_descriptor_retry - ufshcd_query_flag - ufshcd_release - ufshcd_remove - ufshcd_shutdown - ufshcd_uic_hibern8_enter - ufshcd_uic_hibern8_exit - __uio_register_device - uio_unregister_device - unlock_page - unregister_blkdev - __unregister_chrdev - unregister_chrdev_region - unregister_console - unregister_die_notifier - unregister_ftrace_export - unregister_kretprobe - unregister_module_notifier - unregister_pm_notifier - unregister_reboot_notifier - unregister_restart_handler - unregister_rpmsg_driver - unregister_shrinker - unregister_syscore_ops - unregister_sysctl_table - update_devfreq - update_rq_clock - up_read - up_write - usb_add_phy_dev - usb_alloc_coherent - usb_alloc_dev - usb_alloc_urb - usb_assign_descriptors - usb_composite_setup_continue - usb_control_msg - usb_deregister - usb_ep_alloc_request - usb_ep_autoconfig - usb_ep_dequeue - usb_ep_disable - usb_ep_enable - usb_ep_free_request - usb_ep_queue - usb_ep_set_halt - usb_find_common_endpoints - usb_free_all_descriptors - usb_free_coherent - usb_free_urb - usb_function_register - usb_function_unregister - usb_gadget_wakeup - usb_ifnum_to_if - usb_interface_id - usb_phy_set_charger_current - usb_poison_urb - usb_put_dev - usb_put_function_instance - usb_register_driver - usb_register_notify - usb_remove_phy - usb_role_switch_find_by_fwnode - usb_role_switch_get_drvdata - usb_role_switch_register - usb_role_switch_set_role - usb_role_switch_unregister - usb_set_device_state - usb_speed_string - usb_string_id - usb_submit_urb - usb_unregister_notify - __usecs_to_jiffies - usleep_range - v4l2_compat_ioctl32 - v4l2_ctrl_handler_free - v4l2_device_register - v4l2_device_unregister - vabits_actual - vchan_dma_desc_free_list - vchan_find_desc - vchan_init - vchan_tx_desc_free - vchan_tx_submit - vfree - vfs_fsync - video_devdata - video_device_release_empty - video_ioctl2 - __video_register_device - video_unregister_device - vmalloc - vmalloc_nr_pages - vmalloc_to_page - vmalloc_to_pfn - vmap - vmf_insert_pfn - vm_insert_page - vm_iomap_memory - vm_map_pages - vm_node_stat - vm_zone_stat - vscnprintf - vsnprintf - vunmap - vzalloc - wait_for_completion - wait_for_completion_interruptible - wait_for_completion_interruptible_timeout - wait_for_completion_killable - wait_for_completion_killable_timeout - wait_for_completion_timeout - __wake_up - wake_up_if_idle - wake_up_process - wakeup_source_add - wakeup_source_register - wakeup_source_remove - wakeup_source_unregister - __warn_printk - ww_mutex_lock - ww_mutex_unlock - __xa_alloc - xa_destroy - xa_erase - xa_find - xa_find_after - xa_load - xa_store - xhci_alloc_command - xhci_alloc_erst - xhci_free_command - xhci_get_endpoint_index - xhci_queue_stop_endpoint - xhci_ring_alloc - xhci_ring_cmd_db - xhci_ring_free - xhci_trb_virt_to_dma diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom deleted file mode 100644 index bbe789e751d5..000000000000 --- a/android/abi_gki_aarch64_qcom +++ /dev/null @@ -1,3015 +0,0 @@ -[abi_symbol_list] - access_process_vm - activate_task - add_cpu - add_device_randomness - add_memory - add_memory_subsection - add_taint - add_timer - add_timer_on - add_uevent_var - add_wait_queue - adjust_managed_page_count - aes_encrypt - aes_expandkey - alarm_cancel - alarm_init - alarm_start_relative - alloc_anon_inode - alloc_chrdev_region - __alloc_disk_node - alloc_etherdev_mqs - alloc_io_pgtable_ops - alloc_netdev_mqs - __alloc_pages_nodemask - __alloc_percpu - __alloc_percpu_gfp - __alloc_skb - alloc_skb_with_frags - alloc_workqueue - amba_bustype - amba_driver_register - amba_driver_unregister - android_debug_for_each_module - android_debug_per_cpu_symbol - android_debug_symbol - android_rvh_probe_register - anon_inode_getfile - arc4_crypt - arc4_setkey - __arch_clear_user - __arch_copy_from_user - __arch_copy_in_user - __arch_copy_to_user - arch_timer_read_counter - argv_free - argv_split - arm64_const_caps_ready - arm64_use_ng_mappings - __arm_smccc_smc - arp_tbl - atomic_notifier_call_chain - atomic_notifier_chain_register - atomic_notifier_chain_unregister - autoremove_wake_function - available_idle_cpu - backlight_device_get_by_type - backlight_device_register - backlight_device_set_brightness - backlight_device_unregister - bcmp - bdget_disk - bdput - bio_endio - bitmap_allocate_region - __bitmap_andnot - __bitmap_clear - bitmap_find_next_zero_area_off - __bitmap_or - bitmap_parselist - bitmap_parselist_user - bitmap_print_to_pagebuf - bitmap_release_region - __bitmap_set - blk_alloc_queue - blk_cleanup_queue - blk_execute_rq_nowait - blk_get_request - blk_mq_rq_cpu - blk_put_request - blk_queue_flag_clear - blk_queue_flag_set - blk_queue_io_min - blk_queue_io_opt - blk_queue_logical_block_size - blk_queue_max_discard_sectors - blk_queue_max_write_zeroes_sectors - blk_queue_physical_block_size - blk_rq_map_user - blk_rq_map_user_iov - blk_rq_unmap_user - blk_verify_command - blocking_notifier_call_chain - blocking_notifier_chain_register - blocking_notifier_chain_unregister - bpf_trace_run1 - bpf_trace_run10 - bpf_trace_run11 - bpf_trace_run12 - bpf_trace_run2 - bpf_trace_run3 - bpf_trace_run4 - bpf_trace_run5 - bpf_trace_run6 - bpf_trace_run7 - bpf_trace_run8 - bpf_trace_run9 - build_skb - bus_find_device - bus_for_each_dev - bus_register - bus_set_iommu - bus_unregister - call_rcu - call_rcu_tasks - call_rcu_tasks_trace - call_srcu - cancel_delayed_work - cancel_delayed_work_sync - cancel_work_sync - capable - cdev_add - cdev_alloc - cdev_del - cdev_device_add - cdev_device_del - cdev_init - __cfi_slowpath - cgroup_path_ns - cgroup_taskset_first - cgroup_taskset_next - __check_object_size - check_preempt_curr - check_zeroed_user - __class_create - class_destroy - class_find_device - class_for_each_device - class_interface_unregister - __class_register - class_unregister - cleanup_srcu_struct - clear_page - __ClearPageMovable - clk_bulk_disable - clk_bulk_enable - clk_bulk_get_all - clk_bulk_prepare - clk_bulk_put_all - clk_bulk_unprepare - __clk_determine_rate - clk_disable - clk_enable - clk_fixed_factor_ops - clk_fixed_rate_ops - clk_get - __clk_get_hw - __clk_get_name - clk_get_parent - clk_get_rate - clk_hw_get_flags - clk_hw_get_name - clk_hw_get_num_parents - clk_hw_get_parent - clk_hw_get_parent_by_index - clk_hw_get_rate - clk_hw_is_enabled - clk_hw_is_prepared - clk_hw_register - clk_hw_round_rate - clk_hw_unregister - __clk_is_enabled - __clk_mux_determine_rate_closest - clk_notifier_register - clk_notifier_unregister - clk_prepare - clk_put - clk_register - clk_round_rate - clk_set_parent - clk_set_rate - clk_sync_state - clk_unprepare - cma_alloc - cma_get_name - cma_release - compat_alloc_user_space - compat_ptr_ioctl - complete - complete_all - complete_and_exit - completion_done - component_add - component_bind_all - component_del - component_master_add_with_match - component_master_del - component_match_add_release - component_unbind_all - cond_synchronize_rcu - config_ep_by_speed - configfs_register_subsystem - configfs_unregister_subsystem - config_group_init - config_group_init_type_name - config_item_get - config_item_put - console_drivers - console_stop - console_suspend_enabled - __const_udelay - consume_skb - contig_page_data - _copy_from_iter_full - copy_from_kernel_nofault - __cpu_active_mask - cpu_bit_bitmap - cpufreq_cooling_unregister - cpufreq_cpu_get - cpufreq_cpu_get_raw - cpufreq_cpu_put - cpufreq_disable_fast_switch - cpufreq_driver_fast_switch - cpufreq_driver_resolve_freq - __cpufreq_driver_target - cpufreq_enable_fast_switch - cpufreq_freq_attr_scaling_available_freqs - cpufreq_freq_attr_scaling_boost_freqs - cpufreq_generic_frequency_table_verify - cpufreq_get_policy - cpufreq_quick_get - cpufreq_quick_get_max - cpufreq_register_driver - cpufreq_register_governor - cpufreq_register_notifier - cpufreq_unregister_driver - cpufreq_unregister_notifier - __cpuhp_remove_state - __cpuhp_setup_state - __cpuhp_setup_state_cpuslocked - __cpuhp_state_add_instance - __cpuhp_state_remove_instance - cpu_hwcap_keys - cpu_hwcaps - cpuidle_governor_latency_req - cpuidle_register_governor - cpu_irqtime - cpu_is_hotpluggable - cpu_latency_qos_add_request - cpu_latency_qos_remove_request - cpu_latency_qos_request_active - cpu_latency_qos_update_request - cpu_maps_update_begin - cpu_maps_update_done - cpumask_any_but - cpumask_next - cpumask_next_and - cpu_number - __cpu_online_mask - cpu_pm_register_notifier - cpu_pm_unregister_notifier - __cpu_possible_mask - __cpu_present_mask - cpupri_find_fitness - cpu_scale - cpus_read_lock - cpus_read_unlock - cpu_subsys - cpu_topology - crc32_be - crc32_le - crc8 - crc8_populate_msb - crypto_aead_decrypt - crypto_aead_encrypt - crypto_aead_setauthsize - crypto_aead_setkey - crypto_ahash_digest - crypto_ahash_setkey - crypto_alloc_aead - crypto_alloc_ahash - crypto_alloc_base - crypto_alloc_shash - crypto_alloc_skcipher - crypto_alloc_sync_skcipher - crypto_cipher_encrypt_one - crypto_cipher_setkey - crypto_comp_compress - crypto_comp_decompress - crypto_dequeue_request - crypto_destroy_tfm - crypto_enqueue_request - crypto_has_alg - crypto_init_queue - __crypto_memneq - crypto_register_aead - crypto_register_ahash - crypto_register_alg - crypto_register_algs - crypto_register_rngs - crypto_register_scomp - crypto_register_skcipher - crypto_shash_digest - crypto_shash_final - crypto_shash_finup - crypto_shash_setkey - crypto_shash_update - crypto_skcipher_decrypt - crypto_skcipher_encrypt - crypto_skcipher_setkey - crypto_unregister_aead - crypto_unregister_ahash - crypto_unregister_alg - crypto_unregister_algs - crypto_unregister_rngs - crypto_unregister_scomp - crypto_unregister_skcipher - __crypto_xor - css_next_child - csum_ipv6_magic - csum_partial - csum_tcpudp_nofold - _ctype - datagram_poll - deactivate_task - debugfs_attr_read - debugfs_attr_write - debugfs_create_atomic_t - debugfs_create_blob - debugfs_create_bool - debugfs_create_dir - debugfs_create_file - debugfs_create_file_unsafe - debugfs_create_regset32 - debugfs_create_symlink - debugfs_create_u16 - debugfs_create_u32 - debugfs_create_u64 - debugfs_create_u8 - debugfs_create_ulong - debugfs_create_x32 - debugfs_create_x64 - debugfs_create_x8 - debugfs_file_get - debugfs_file_put - debugfs_lookup - debugfs_print_regs32 - debugfs_remove - debugfs_rename - dec_zone_page_state - default_llseek - deferred_free - delayed_work_timer_fn - del_gendisk - del_timer - del_timer_sync - desc_to_gpio - destroy_workqueue - dev_alloc_name - dev_change_net_namespace - dev_close - dev_coredumpv - _dev_crit - __dev_direct_xmit - dev_driver_string - _dev_emerg - _dev_err - dev_err_probe - dev_fetch_sw_netstats - devfreq_add_device - devfreq_add_governor - devfreq_cooling_unregister - devfreq_get_devfreq_by_node - devfreq_remove_device - devfreq_remove_governor - devfreq_resume_device - devfreq_suspend_device - dev_fwnode - __dev_get_by_index - dev_get_by_index - dev_get_by_name - dev_get_by_name_rcu - dev_get_regmap - device_add - device_add_disk - device_add_groups - device_create - device_create_file - device_create_with_groups - device_del - device_destroy - device_find_child - device_for_each_child - device_get_match_data - device_get_next_child_node - device_initialize - device_init_wakeup - device_link_add - device_link_del - device_match_fwnode - device_match_name - device_property_present - device_property_read_string - device_property_read_u16_array - device_property_read_u32_array - device_property_read_u8_array - device_register - device_remove_file - device_rename - device_set_wakeup_capable - device_show_int - device_store_int - device_unregister - device_wakeup_disable - device_wakeup_enable - _dev_info - __dev_kfree_skb_any - devm_add_action - devm_backlight_device_register - devm_blk_ksm_init - devm_clk_bulk_get - devm_clk_bulk_get_all - devm_clk_get - devm_clk_get_optional - devm_clk_hw_register - devm_clk_put - devm_clk_register - devm_device_add_group - devm_device_remove_group - devm_extcon_dev_allocate - devm_extcon_dev_register - devm_extcon_dev_unregister - devm_extcon_register_notifier - devm_free_irq - devm_gpiod_get_optional - devm_gpio_request - devm_gpio_request_one - devm_hwspin_lock_register - devm_iio_channel_get - devm_iio_device_alloc - __devm_iio_device_register - devm_input_allocate_device - devm_ioremap - devm_ioremap_resource - devm_ioremap_wc - devm_iounmap - devm_kasprintf - devm_kfree - devm_kmalloc - devm_kmemdup - devm_kstrdup - devm_led_classdev_register_ext - devm_mbox_controller_register - devm_nvmem_cell_get - devm_nvmem_device_get - devm_nvmem_register - devm_of_clk_add_hw_provider - devm_of_icc_get - __devm_of_phy_provider_register - devm_of_platform_populate - devm_of_pwm_get - devm_pci_alloc_host_bridge - devm_phy_create - devm_phy_get - devm_pinctrl_get - devm_pinctrl_put - devm_pinctrl_register - devm_platform_get_and_ioremap_resource - devm_platform_ioremap_resource - devm_platform_ioremap_resource_byname - devm_power_supply_register - devm_pwm_put - devm_regmap_add_irq_chip - devm_regmap_del_irq_chip - devm_regmap_field_alloc - __devm_regmap_init - __devm_regmap_init_i2c - __devm_regmap_init_mmio_clk - devm_regulator_bulk_get - devm_regulator_get - devm_regulator_get_optional - devm_regulator_put - devm_regulator_register - devm_regulator_register_notifier - devm_request_any_context_irq - __devm_request_region - devm_request_threaded_irq - devm_reset_control_array_get - __devm_reset_control_get - devm_reset_controller_register - devm_rproc_add - devm_rproc_alloc - devm_rtc_allocate_device - devm_snd_soc_register_card - devm_thermal_of_cooling_device_register - devm_thermal_zone_of_sensor_register - devm_usb_get_phy - devm_usb_get_phy_by_node - devm_usb_get_phy_by_phandle - _dev_notice - dev_pm_domain_attach - dev_pm_domain_attach_by_name - dev_pm_domain_detach - dev_pm_genpd_add_notifier - dev_pm_genpd_remove_notifier - dev_pm_genpd_set_next_wakeup - dev_pm_genpd_set_performance_state - dev_pm_opp_add - dev_pm_opp_find_freq_ceil - dev_pm_opp_find_freq_exact - dev_pm_opp_find_freq_floor - dev_pm_opp_get_level - dev_pm_opp_get_opp_count - dev_pm_opp_get_voltage - dev_pm_opp_of_add_table - dev_pm_opp_of_find_icc_paths - dev_pm_opp_of_register_em - dev_pm_opp_of_remove_table - dev_pm_opp_put - dev_pm_opp_put_clkname - dev_pm_opp_register_notifier - dev_pm_opp_remove_all_dynamic - dev_pm_opp_set_clkname - dev_pm_opp_set_rate - dev_pm_opp_set_sharing_cpus - dev_pm_opp_unregister_notifier - dev_pm_qos_add_notifier - dev_pm_qos_add_request - dev_pm_qos_read_value - dev_pm_qos_remove_notifier - dev_pm_qos_remove_request - dev_pm_qos_update_request - dev_printk - dev_queue_xmit - devres_add - devres_alloc_node - devres_free - devres_release - dev_set_name - _dev_warn - disable_irq - disable_irq_nosync - disable_percpu_irq - disk_end_io_acct - disk_start_io_acct - divider_get_val - divider_recalc_rate - divider_ro_round_rate_parent - divider_round_rate_parent - dma_alloc_attrs - dma_async_device_register - dma_async_device_unregister - dma_async_tx_descriptor_init - dma_buf_attach - dma_buf_begin_cpu_access - dma_buf_begin_cpu_access_partial - dma_buf_detach - dma_buf_end_cpu_access - dma_buf_end_cpu_access_partial - dma_buf_export - dma_buf_fd - dma_buf_get - dma_buf_get_flags - dma_buf_map_attachment - dma_buf_put - dma_buf_unmap_attachment - dma_buf_vmap - dma_buf_vunmap - dma_contiguous_default_area - dma_fence_add_callback - dma_fence_array_create - dma_fence_array_ops - dma_fence_context_alloc - dma_fence_default_wait - dma_fence_enable_sw_signaling - dma_fence_free - dma_fence_get_status - dma_fence_init - dma_fence_release - dma_fence_remove_callback - dma_fence_signal - dma_fence_signal_locked - dma_fence_signal_timestamp_locked - dma_fence_wait_timeout - dma_free_attrs - dma_get_sgtable_attrs - dma_get_slave_channel - dma_heap_add - dma_heap_buffer_alloc - dma_heap_buffer_free - dma_heap_find - dma_heap_get_dev - dma_heap_get_drvdata - dma_heap_get_name - dmam_alloc_attrs - dma_map_page_attrs - dma_map_resource - dma_map_sg_attrs - dmam_free_coherent - dma_mmap_attrs - dma_pool_alloc - dma_pool_create - dma_pool_destroy - dma_pool_free - dma_release_channel - dma_request_chan - dma_resv_fini - dma_resv_init - dma_resv_wait_timeout_rcu - dma_set_coherent_mask - dma_set_mask - dma_sync_sg_for_cpu - dma_sync_sg_for_device - dma_sync_single_for_cpu - dma_sync_single_for_device - dma_unmap_page_attrs - dma_unmap_resource - dma_unmap_sg_attrs - do_exit - do_trace_rcu_torture_read - do_wait_intr - down - down_read - down_write - d_path - dput - drain_workqueue - driver_find_device - driver_register - driver_unregister - drm_add_edid_modes - drm_add_modes_noedid - drm_atomic_commit - drm_atomic_get_connector_state - drm_atomic_get_crtc_state - drm_atomic_get_plane_state - drm_atomic_get_private_obj_state - drm_atomic_helper_check - drm_atomic_helper_cleanup_planes - drm_atomic_helper_commit_duplicated_state - drm_atomic_helper_commit_hw_done - drm_atomic_helper_commit_modeset_disables - drm_atomic_helper_commit_modeset_enables - drm_atomic_helper_commit_planes - __drm_atomic_helper_connector_destroy_state - __drm_atomic_helper_connector_duplicate_state - __drm_atomic_helper_connector_reset - __drm_atomic_helper_crtc_destroy_state - __drm_atomic_helper_crtc_duplicate_state - drm_atomic_helper_dirtyfb - drm_atomic_helper_disable_plane - drm_atomic_helper_duplicate_state - drm_atomic_helper_page_flip - __drm_atomic_helper_plane_duplicate_state - drm_atomic_helper_prepare_planes - __drm_atomic_helper_private_obj_duplicate_state - drm_atomic_helper_set_config - drm_atomic_helper_shutdown - drm_atomic_helper_swap_state - drm_atomic_helper_update_legacy_modeset_state - drm_atomic_helper_update_plane - drm_atomic_helper_wait_for_fences - drm_atomic_helper_wait_for_vblanks - drm_atomic_private_obj_init - drm_atomic_set_crtc_for_connector - drm_atomic_set_fence_for_plane - drm_atomic_set_mode_for_crtc - drm_atomic_state_alloc - drm_atomic_state_clear - drm_atomic_state_default_clear - drm_atomic_state_default_release - __drm_atomic_state_free - drm_atomic_state_init - drm_bridge_attach - drm_bridge_chain_disable - drm_bridge_chain_enable - drm_bridge_chain_mode_set - drm_bridge_chain_post_disable - drm_bridge_chain_pre_enable - drm_client_init - drm_client_modeset_commit_locked - drm_client_register - drm_compat_ioctl - drm_connector_attach_encoder - drm_connector_cleanup - drm_connector_init - drm_connector_list_iter_begin - drm_connector_list_iter_end - drm_connector_list_iter_next - drm_connector_register - drm_connector_set_tile_property - drm_connector_unregister - drm_connector_update_edid_property - drm_crtc_cleanup - drm_crtc_from_index - drm_crtc_handle_vblank - drm_crtc_init_with_planes - drm_crtc_send_vblank_event - drm_crtc_set_max_vblank_count - drm_crtc_vblank_off - drm_crtc_vblank_on - drm_crtc_vblank_reset - drm_crtc_wait_one_vblank - __drm_dbg - __drm_debug - drm_detect_hdmi_monitor - drm_detect_monitor_audio - drm_dev_alloc - drm_dev_dbg - drm_dev_printk - drm_dev_put - drm_dev_register - drm_dev_unregister - drm_dp_atomic_find_vcpi_slots - drm_dp_atomic_release_vcpi_slots - drm_dp_aux_register - drm_dp_aux_unregister - drm_dp_bw_code_to_link_rate - drm_dp_calc_pbn_mode - drm_dp_channel_eq_ok - drm_dp_check_act_status - drm_dp_clock_recovery_ok - drm_dp_dpcd_read - drm_dp_dpcd_read_link_status - drm_dp_dpcd_write - drm_dp_find_vcpi_slots - drm_dp_get_adjust_request_pre_emphasis - drm_dp_get_adjust_request_voltage - drm_dp_link_rate_to_bw_code - drm_dp_link_train_channel_eq_delay - drm_dp_link_train_clock_recovery_delay - drm_dp_mst_allocate_vcpi - drm_dp_mst_deallocate_vcpi - drm_dp_mst_detect_port - drm_dp_mst_get_edid - drm_dp_mst_get_port_malloc - drm_dp_mst_hpd_irq - drm_dp_mst_put_port_malloc - drm_dp_mst_reset_vcpi_slots - drm_dp_mst_topology_mgr_destroy - drm_dp_mst_topology_mgr_init - drm_dp_mst_topology_mgr_set_mst - drm_dp_send_power_updown_phy - drm_dp_update_payload_part1 - drm_dp_update_payload_part2 - drm_edid_duplicate - drm_edid_is_valid - drm_encoder_cleanup - drm_encoder_init - __drm_err - drm_event_reserve_init_locked - drm_format_info - drm_framebuffer_init - drm_framebuffer_lookup - drm_framebuffer_remove - drm_framebuffer_unregister_private - drm_gem_create_mmap_offset - drm_gem_fb_create_handle - drm_gem_fb_destroy - drm_gem_fb_get_obj - drm_gem_free_mmap_offset - drm_gem_get_pages - drm_gem_handle_create - drm_gem_mmap - drm_gem_mmap_obj - drm_gem_object_free - drm_gem_object_init - drm_gem_object_lookup - drm_gem_object_put_locked - drm_gem_object_release - drm_gem_prime_export - drm_gem_prime_fd_to_handle - drm_gem_prime_handle_to_fd - drm_gem_private_object_init - drm_gem_put_pages - drm_gem_vm_close - drm_gem_vm_open - drm_get_connector_status_name - drm_get_edid - drm_get_format_info - drm_helper_hpd_irq_event - drm_helper_mode_fill_fb_struct - drm_helper_probe_single_connector_modes - drm_ioctl - drm_irq_install - drm_irq_uninstall - drm_kms_helper_hotplug_event - drm_kms_helper_poll_disable - drm_kms_helper_poll_enable - drm_kms_helper_poll_fini - drm_kms_helper_poll_init - drm_match_cea_mode - drm_mm_init - drm_mm_insert_node_in_range - drmm_mode_config_init - drm_mm_remove_node - drm_mm_takedown - drm_mode_config_cleanup - drm_mode_config_reset - drm_mode_convert_umode - drm_mode_copy - drm_mode_create - drm_mode_create_dp_colorspace_property - drm_mode_create_tile_group - drm_mode_debug_printmodeline - drm_mode_duplicate - drm_mode_equal - drm_mode_get_tile_group - drm_mode_is_420_only - drm_mode_object_find - drm_mode_object_get - drm_mode_object_put - drm_mode_probed_add - drm_modeset_acquire_fini - drm_modeset_acquire_init - drm_modeset_backoff - drm_mode_set_crtcinfo - drm_modeset_drop_locks - drm_modeset_lock - drm_modeset_lock_all - drm_modeset_lock_all_ctx - drm_mode_set_name - drm_modeset_unlock_all - drm_mode_vrefresh - drm_object_attach_property - drm_object_property_set_value - drm_of_component_match_add - drm_open - drm_panel_add - drm_panel_init - drm_panel_remove - drm_plane_cleanup - drm_plane_create_rotation_property - drm_poll - drm_prime_gem_destroy - drm_prime_pages_to_sg - drm_property_blob_get - drm_property_blob_put - drm_property_create - drm_property_create_bitmask - drm_property_create_blob - drm_property_create_enum - drm_property_create_range - drm_property_lookup_blob - drm_read - drm_release - drm_rotation_simplify - drm_send_event_locked - drm_set_preferred_mode - drm_universal_plane_init - drm_vblank_init - drm_wait_one_vblank - dst_release - dump_stack - __dynamic_dev_dbg - __dynamic_pr_debug - edac_device_add_device - edac_device_alloc_ctl_info - edac_device_alloc_index - edac_device_del_device - edac_device_free_ctl_info - edac_device_handle_ce_count - edac_device_handle_ue_count - enable_irq - enable_percpu_irq - ether_setup - eth_mac_addr - ethtool_op_get_link - eth_type_trans - eventfd_ctx_fdget - eventfd_ctx_fileget - eventfd_ctx_put - eventfd_ctx_remove_wait_queue - eventfd_signal - event_triggers_call - extcon_find_edev_by_node - extcon_get_edev_by_phandle - extcon_get_edev_name - extcon_get_extcon_dev - extcon_get_property - extcon_get_state - extcon_register_notifier - extcon_set_state_sync - extcon_unregister_notifier - failure_tracking - fasync_helper - __fdget - fd_install - fget - find_get_pid - find_last_bit - find_next_bit - find_next_zero_bit - find_snd_usb_substream - find_task_by_vpid - find_vma - find_vpid - finish_wait - firmware_request_nowarn - flush_dcache_page - flush_delayed_work - __flush_icache_range - flush_work - flush_workqueue - fput - free_io_pgtable_ops - free_irq - free_netdev - __free_pages - free_pages - free_pages_exact - free_percpu - free_percpu_irq - freezing_slow_path - freq_qos_add_request - freq_qos_remove_request - freq_qos_update_request - freq_scale - fsync_bdev - ftrace_dump - fwnode_find_reference - fwnode_get_name - fwnode_get_named_child_node - fwnode_get_next_child_node - fwnode_handle_get - fwnode_handle_put - fwnode_property_present - fwnode_property_read_string - fwnode_property_read_u32_array - fwnode_usb_role_switch_get - gcd - generic_device_group - generic_file_llseek - generic_handle_irq - generic_iommu_put_resv_regions - genlmsg_multicast_allns - genlmsg_put - genl_register_family - genl_unregister_family - gen_pool_add_owner - gen_pool_alloc_algo_owner - gen_pool_avail - gen_pool_best_fit - gen_pool_create - gen_pool_destroy - gen_pool_first_fit_order_align - gen_pool_free_owner - gen_pool_has_addr - gen_pool_set_algo - gen_pool_size - gen_pool_virt_to_phys - getboottime64 - get_cpu_device - get_device - get_each_dmabuf - get_each_object_track - __get_free_pages - get_governor_parent_kobj - get_net_ns_by_fd - get_net_ns_by_pid - get_option - get_page_owner_handle - get_pfnblock_flags_mask - get_pid_task - get_random_bytes - get_random_u32 - get_sg_io_hdr - get_slabinfo - get_state_synchronize_rcu - __get_task_comm - get_task_mm - get_task_pid - get_unmapped_area - get_unused_fd_flags - get_user_pages - get_zeroed_page - gfp_zone - gic_nonsecure_priorities - gic_resume - gov_attr_set_init - gov_attr_set_put - governor_sysfs_ops - gpiochip_add_data_with_key - gpiochip_add_pin_range - gpiochip_generic_free - gpiochip_generic_request - gpiochip_get_data - gpiochip_line_is_valid - gpiochip_lock_as_irq - gpiochip_remove - gpiochip_unlock_as_irq - gpiod_direction_input - gpiod_direction_output - gpiod_direction_output_raw - gpiod_get_optional - gpiod_get_raw_value - gpiod_get_raw_value_cansleep - gpiod_get_value - gpiod_get_value_cansleep - gpiod_set_debounce - gpiod_set_raw_value - gpiod_set_raw_value_cansleep - gpiod_set_value - gpiod_set_value_cansleep - gpiod_to_irq - gpio_free - gpio_free_array - gpio_request - gpio_request_one - gpio_to_desc - gro_cells_destroy - gro_cells_init - gro_cells_receive - handle_bad_irq - handle_edge_irq - handle_fasteoi_ack_irq - handle_fasteoi_irq - handle_level_irq - handle_nested_irq - handle_simple_irq - handle_sysrq - hashlen_string - hex2bin - hex_dump_to_buffer - hex_to_bin - hrtimer_active - hrtimer_cancel - hrtimer_forward - __hrtimer_get_remaining - hrtimer_init - hrtimer_start_range_ns - hrtimer_try_to_cancel - hvc_alloc - hvc_kick - hvc_poll - hvc_remove - __hw_addr_init - __hw_addr_sync - __hw_addr_unsync - hwrng_register - hwrng_unregister - hwspin_lock_free - hwspin_lock_request_specific - __hwspin_lock_timeout - __hwspin_unlock - hypervisor_kobj - i2c_add_adapter - i2c_del_adapter - i2c_del_driver - i2c_get_dma_safe_msg_buf - i2c_new_client_device - i2c_put_dma_safe_msg_buf - i2c_register_driver - i2c_transfer - i2c_transfer_buffer_flags - i3c_device_disable_ibi - i3c_device_do_priv_xfers - i3c_device_enable_ibi - i3c_device_free_ibi - i3c_device_get_info - i3c_device_request_ibi - i3cdev_to_dev - i3c_driver_register_with_owner - i3c_driver_unregister - i3c_generic_ibi_alloc_pool - i3c_generic_ibi_free_pool - i3c_generic_ibi_get_free_slot - i3c_generic_ibi_recycle_slot - i3c_master_add_i3c_dev_locked - i3c_master_disec_locked - i3c_master_do_daa - i3c_master_enec_locked - i3c_master_entdaa_locked - i3c_master_get_free_addr - i3c_master_queue_ibi - i3c_master_register - i3c_master_set_info - i3c_master_unregister - icc_disable - icc_enable - icc_get - icc_link_create - icc_node_add - icc_node_create - icc_node_del - icc_node_destroy - icc_provider_add - icc_provider_del - icc_put - icc_set_bw - icc_set_tag - ida_alloc_range - ida_free - idr_alloc - idr_alloc_cyclic - idr_alloc_u32 - idr_destroy - idr_find - idr_for_each - idr_get_next - idr_preload - idr_remove - idr_replace - iio_channel_get_all - iio_read_channel_processed - import_iovec - in4_pton - in6_pton - inc_node_page_state - inc_zone_page_state - in_egroup_p - inet_csk_get_port - inet_proto_csum_replace4 - init_dummy_netdev - init_iova_domain - init_net - init_pid_ns - init_pseudo - __init_rwsem - init_srcu_struct - __init_swait_queue_head - init_task - init_timer_key - init_uts_ns - init_wait_entry - __init_waitqueue_head - input_alloc_absinfo - input_allocate_device - input_close_device - input_event - input_ff_create - input_ff_destroy - input_free_device - input_mt_init_slots - input_mt_report_pointer_emulation - input_mt_report_slot_state - input_open_device - input_register_device - input_register_handle - input_register_handler - input_set_abs_params - input_set_capability - input_unregister_device - input_unregister_handle - input_unregister_handler - interval_tree_insert - interval_tree_iter_first - interval_tree_iter_next - interval_tree_remove - int_sqrt - invalidate_mapping_pages - iomem_resource - iommu_alloc_resv_region - iommu_attach_device - iommu_attach_group - iommu_detach_device - iommu_detach_group - iommu_device_register - iommu_device_sysfs_add - iommu_device_sysfs_remove - iommu_device_unregister - iommu_dma_enable_best_fit_algo - iommu_dma_get_resv_regions - iommu_dma_reserve_iova - iommu_domain_alloc - iommu_domain_free - iommu_domain_get_attr - iommu_domain_set_attr - iommu_fwspec_add_ids - iommu_fwspec_free - iommu_get_dma_cookie - iommu_get_domain_for_dev - iommu_get_msi_cookie - iommu_group_for_each_dev - iommu_group_get - iommu_group_get_iommudata - iommu_group_put - iommu_group_ref_get - iommu_group_set_iommudata - iommu_iova_to_phys - iommu_map - iommu_map_sg - iommu_present - iommu_put_dma_cookie - iommu_set_fault_handler - iommu_unmap - __ioread32_copy - __ioremap - iounmap - __iowrite32_copy - ip_compute_csum - ipi_desc_get - ip_route_output_flow - iput - __ipv6_addr_type - ipv6_ext_hdr - ipv6_find_hdr - ipv6_skip_exthdr - ipv6_stub - irq_chip_ack_parent - irq_chip_disable_parent - irq_chip_enable_parent - irq_chip_eoi_parent - irq_chip_get_parent_state - irq_chip_mask_parent - irq_chip_retrigger_hierarchy - irq_chip_set_affinity_parent - irq_chip_set_parent_state - irq_chip_set_type_parent - irq_chip_set_vcpu_affinity_parent - irq_chip_set_wake_parent - irq_chip_unmask_parent - irq_create_fwspec_mapping - irq_create_mapping_affinity - irq_dispose_mapping - __irq_domain_add - irq_domain_alloc_irqs_parent - irq_domain_create_hierarchy - irq_domain_free_irqs_common - irq_domain_free_irqs_parent - irq_domain_get_irq_data - irq_domain_remove - irq_domain_set_hwirq_and_chip - irq_domain_set_info - irq_domain_update_bus_token - irq_domain_xlate_onecell - irq_domain_xlate_twocell - irq_do_set_affinity - irq_find_mapping - irq_find_matching_fwspec - irq_get_irqchip_state - irq_get_irq_data - irq_modify_status - irq_of_parse_and_map - irq_set_affinity_hint - irq_set_affinity_notifier - irq_set_chained_handler_and_data - irq_set_chip_and_handler_name - irq_set_chip_data - irq_set_irqchip_state - irq_set_irq_type - irq_set_irq_wake - irq_set_parent - irq_to_desc - irq_work_queue - irq_work_queue_on - irq_work_sync - is_dma_buf_file - isolate_and_split_free_page - isolate_anon_lru_page - is_vmalloc_addr - iterate_fd - jiffies - jiffies_to_msecs - jiffies_to_usecs - kasan_flag_enabled - kasprintf - kernel_bind - kernel_connect - kernel_getsockname - kernel_kobj - kernel_param_lock - kernel_param_unlock - kernel_power_off - kernel_recvmsg - kernel_restart - kernel_sendmsg - kernfs_find_and_get_ns - kernfs_notify - kernfs_put - kern_mount - kern_unmount - key_create_or_update - key_put - keyring_alloc - __kfifo_alloc - __kfifo_free - __kfifo_in - __kfifo_out - kfree - kfree_const - kfree_sensitive - kfree_skb - kfree_skb_list - kick_all_cpus_sync - kill_anon_super - kill_fasync - kimage_vaddr - kimage_voffset - __kmalloc - kmalloc_caches - kmalloc_order_trace - kmem_cache_alloc - kmem_cache_alloc_trace - kmem_cache_create - kmem_cache_create_usercopy - kmem_cache_destroy - kmem_cache_free - kmemdup - kmemdup_nul - kobject_add - kobject_create_and_add - kobject_del - kobject_init - kobject_init_and_add - kobject_put - kobject_set_name - kobject_uevent - kobject_uevent_env - kobj_sysfs_ops - krealloc - kset_create_and_add - ksize - ksoftirqd - kstat - kstat_irqs_cpu - kstat_irqs_usr - kstrdup - kstrdup_const - kstrndup - kstrtobool - kstrtoint - kstrtoint_from_user - kstrtoll - kstrtos8 - kstrtos8_from_user - kstrtou16 - kstrtou16_from_user - kstrtou8 - kstrtou8_from_user - kstrtouint - kstrtouint_from_user - kstrtoul_from_user - kstrtoull - kstrtoull_from_user - kthread_bind - kthread_bind_mask - kthread_cancel_delayed_work_sync - kthread_cancel_work_sync - kthread_create_on_node - kthread_create_worker - kthread_delayed_work_timer_fn - kthread_destroy_worker - kthread_flush_work - kthread_flush_worker - __kthread_init_worker - kthread_mod_delayed_work - kthread_park - kthread_parkme - kthread_queue_delayed_work - kthread_queue_work - kthread_should_park - kthread_should_stop - kthread_stop - kthread_unpark - kthread_worker_fn - ktime_get - ktime_get_coarse_with_offset - ktime_get_mono_fast_ns - ktime_get_real_seconds - ktime_get_real_ts64 - ktime_get_seconds - ktime_get_with_offset - kvfree - kvfree_call_rcu - kvmalloc_node - led_classdev_flash_register_ext - led_classdev_flash_unregister - led_classdev_unregister - led_trigger_event - led_trigger_register_simple - led_trigger_unregister_simple - __list_add_valid - __list_del_entry_valid - list_sort - llist_add_batch - llist_reverse_order - __local_bh_enable_ip - __lock_page - lock_sock_nested - log_buf_addr_get - log_buf_len_get - __log_post_read_mmio - __log_read_mmio - __log_write_mmio - lookup_page_ext - lzo1x_1_compress - lzo1x_decompress_safe - lzorle1x_1_compress - mac_pton - match_string - mbox_chan_received_data - mbox_chan_txdone - mbox_client_txdone - mbox_controller_register - mbox_controller_unregister - mbox_free_channel - mbox_request_channel - mbox_send_message - media_device_cleanup - media_device_init - __media_device_register - media_device_unregister - media_entity_pads_init - memblock_end_of_DRAM - memblock_free - __memcat_p - memchr - memchr_inv - memcmp - memcpy - __memcpy_fromio - __memcpy_toio - memdup_user - memmove - memory_block_size_bytes - memory_read_from_buffer - memparse - mempool_alloc - mempool_alloc_slab - mempool_create - mempool_destroy - mempool_free - mempool_free_slab - memremap - memset - memset64 - __memset_io - memstart_addr - memunmap - migrate_pages - migrate_swap - mipi_dsi_create_packet - mipi_dsi_dcs_set_display_brightness - mipi_dsi_dcs_set_tear_off - mipi_dsi_host_register - mipi_dsi_host_unregister - misc_deregister - misc_register - mmc_cqe_request_done - mmc_of_parse - mmc_regulator_get_supply - mmc_regulator_set_ocr - mmc_regulator_set_vqmmc - mmc_send_tuning - mmput - mod_delayed_work_on - __mod_node_page_state - mod_node_page_state - mod_timer - __module_get - module_layout - module_put - __mod_zone_page_state - __msecs_to_jiffies - msleep - msleep_interruptible - __mutex_init - mutex_is_locked - mutex_lock - mutex_lock_interruptible - mutex_trylock - mutex_unlock - napi_complete_done - napi_disable - napi_gro_flush - napi_gro_receive - __napi_schedule - napi_schedule_prep - neigh_destroy - __neigh_event_send - neigh_lookup - neigh_xmit - __netdev_alloc_skb - netdev_err - netdev_info - netdev_rx_handler_register - netdev_rx_handler_unregister - netdev_set_default_ethtool_ops - netdev_update_features - netif_carrier_off - netif_carrier_on - netif_device_attach - netif_device_detach - netif_napi_add - __netif_napi_del - netif_receive_skb - netif_receive_skb_core - netif_receive_skb_list - netif_rx - netif_rx_ni - netif_schedule_queue - netif_tx_stop_all_queues - netif_tx_wake_queue - netlink_broadcast - netlink_capable - __netlink_kernel_create - netlink_kernel_release - netlink_register_notifier - netlink_unicast - netlink_unregister_notifier - net_ns_type_operations - net_ratelimit - __next_zones_zonelist - nla_find - nla_memcpy - __nla_parse - nla_put - nla_put_64bit - nla_reserve - nla_reserve_64bit - __nla_validate - __nlmsg_put - no_llseek - nonseekable_open - noop_llseek - nr_cpu_ids - nr_ipi_get - nr_irqs - ns_capable - nsecs_to_jiffies - ns_to_timespec64 - __num_online_cpus - nvmem_cell_get - nvmem_cell_put - nvmem_cell_read - nvmem_cell_read_u32 - nvmem_cell_write - nvmem_device_read - nvmem_device_write - of_address_to_resource - of_alias_get_id - of_clk_add_hw_provider - of_clk_add_provider - of_clk_del_provider - of_clk_get - of_clk_get_from_provider - of_clk_get_parent_count - of_clk_hw_simple_get - of_clk_src_onecell_get - of_clk_src_simple_get - of_count_phandle_with_args - of_cpufreq_cooling_register - of_cpu_node_to_id - of_devfreq_cooling_register - of_device_get_match_data - of_device_is_available - of_device_is_compatible - of_device_uevent_modalias - of_dma_configure_id - of_dma_controller_free - of_dma_controller_register - of_dma_is_coherent - of_drm_find_bridge - of_drm_find_panel - of_find_compatible_node - of_find_device_by_node - of_find_i2c_device_by_node - of_find_matching_node_and_match - of_find_node_by_name - of_find_node_by_phandle - of_find_node_opts_by_path - of_find_node_with_property - of_find_property - of_fwnode_ops - of_genpd_add_provider_onecell - of_genpd_add_provider_simple - of_genpd_del_provider - of_get_address - of_get_child_by_name - of_get_compatible_child - of_get_cpu_node - of_get_named_gpio_flags - of_get_next_available_child - of_get_next_child - of_get_next_parent - of_get_parent - of_get_property - of_get_regulator_init_data - of_graph_get_endpoint_by_regs - of_graph_get_next_endpoint - of_graph_get_port_parent - of_graph_get_remote_endpoint - of_graph_get_remote_node - of_graph_get_remote_port - of_graph_get_remote_port_parent - of_graph_is_present - of_graph_parse_endpoint - of_hwspin_lock_get_id - of_i2c_get_board_info - of_icc_get - of_icc_xlate_onecell - of_iomap - of_irq_find_parent - of_irq_get - of_irq_get_byname - of_irq_parse_one - of_machine_is_compatible - of_match_device - of_match_node - of_modalias_node - of_n_addr_cells - of_node_name_eq - of_n_size_cells - of_parse_phandle - of_parse_phandle_with_args - of_parse_phandle_with_fixed_args - of_phandle_iterator_init - of_phandle_iterator_next - of_phy_simple_xlate - of_platform_depopulate - of_platform_device_create - of_platform_device_destroy - of_platform_populate - of_property_count_elems_of_size - of_property_match_string - of_property_read_string - of_property_read_string_helper - of_property_read_u32_index - of_property_read_u64 - of_property_read_u64_index - of_property_read_variable_u16_array - of_property_read_variable_u32_array - of_property_read_variable_u8_array - of_prop_next_string - of_prop_next_u32 - of_reserved_mem_device_init_by_idx - of_reserved_mem_device_release - of_reserved_mem_lookup - of_reset_control_array_get - of_root - of_thermal_get_ntrips - of_thermal_get_trip_points - of_thermal_is_trip_valid - of_translate_address - of_usb_get_phy_mode - of_usb_host_tpl_support - on_each_cpu - oops_in_progress - overflowuid - page_endio - page_mapping - __page_pinner_migration_failed - panic - panic_notifier_list - panic_timeout - param_array_ops - param_get_int - param_get_string - param_get_ullong - param_ops_bool - param_ops_byte - param_ops_charp - param_ops_int - param_ops_long - param_ops_string - param_ops_uint - param_ops_ullong - param_ops_ulong - param_set_bool - param_set_copystring - param_set_int - pause_cpus - pci_aer_clear_nonfatal_status - pci_alloc_irq_vectors_affinity - pci_assign_resource - pci_bus_type - pci_clear_master - pci_d3cold_disable - pci_device_group - pci_device_is_present - pci_dev_present - pci_disable_device - pci_disable_msi - pci_disable_pcie_error_reporting - pcie_capability_clear_and_set_word - pcie_capability_read_word - pci_enable_device - pci_enable_pcie_error_reporting - pci_find_ext_capability - pci_free_irq_vectors - pci_get_device - pci_get_domain_bus_and_slot - pci_host_probe - pci_iomap - pci_irq_vector - pci_load_and_free_saved_state - pci_load_saved_state - pci_match_id - pcim_enable_device - pci_msi_create_irq_domain - pci_msi_mask_irq - pci_msi_unmask_irq - pci_read_config_byte - pci_read_config_dword - pci_read_config_word - __pci_register_driver - pci_release_region - pci_request_region - pci_restore_state - pci_save_state - pci_set_master - pci_set_mwi - pci_set_power_state - pci_store_saved_state - pci_unregister_driver - pci_walk_bus - pci_write_config_dword - pci_write_config_word - pcpu_nr_pages - PDE_DATA - __percpu_down_read - percpu_down_write - __percpu_init_rwsem - __per_cpu_offset - per_cpu_ptr_to_phys - percpu_up_write - perf_aux_output_begin - perf_aux_output_end - perf_aux_output_flag - perf_event_addr_filters_sync - perf_event_create_kernel_counter - perf_event_disable - perf_event_enable - perf_event_read_local - perf_event_read_value - perf_event_release_kernel - perf_get_aux - perf_pmu_register - perf_pmu_unregister - perf_trace_buf_alloc - perf_trace_run_bpf_submit - pfn_valid - phy_calibrate - phy_exit - phy_init - phy_pm_runtime_get_sync - phy_pm_runtime_put_sync - phy_power_off - phy_power_on - phy_set_mode_ext - pick_highest_pushable_task - pid_nr_ns - pid_task - pinconf_generic_dt_node_to_map - pinctrl_dev_get_drvdata - pinctrl_force_default - pinctrl_force_sleep - pinctrl_get - pinctrl_lookup_state - pinctrl_pm_select_default_state - pinctrl_pm_select_sleep_state - pinctrl_put - pinctrl_select_state - pinctrl_utils_free_map - platform_bus_type - platform_device_add - platform_device_add_data - platform_device_add_properties - platform_device_add_resources - platform_device_alloc - platform_device_del - platform_device_put - platform_device_register - platform_device_register_full - platform_device_unregister - __platform_driver_register - platform_driver_unregister - platform_get_irq - platform_get_irq_byname - platform_get_irq_byname_optional - platform_get_resource - platform_get_resource_byname - platform_irq_count - pm_clk_add - pm_clk_create - pm_clk_destroy - pm_clk_resume - pm_clk_suspend - pm_generic_resume - pm_generic_suspend - pm_genpd_add_subdomain - pm_genpd_init - pm_genpd_remove - pm_genpd_remove_subdomain - pm_power_off - __pm_relax - pm_relax - pm_runtime_allow - pm_runtime_barrier - __pm_runtime_disable - pm_runtime_enable - pm_runtime_forbid - pm_runtime_force_resume - pm_runtime_force_suspend - __pm_runtime_idle - pm_runtime_irq_safe - pm_runtime_no_callbacks - __pm_runtime_resume - pm_runtime_set_autosuspend_delay - __pm_runtime_set_status - __pm_runtime_suspend - __pm_runtime_use_autosuspend - __pm_stay_awake - pm_stay_awake - pm_system_wakeup - pm_wakeup_dev_event - pm_wakeup_ws_event - power_supply_changed - power_supply_get_by_name - power_supply_get_drvdata - power_supply_get_property - power_supply_put - power_supply_register - power_supply_reg_notifier - power_supply_set_property - power_supply_unregister - power_supply_unreg_notifier - prandom_bytes - prandom_u32 - preempt_schedule - preempt_schedule_notrace - prepare_to_wait_event - print_hex_dump - printk - printk_deferred - proc_create - proc_create_data - proc_dointvec - proc_dointvec_minmax - proc_dostring - proc_douintvec_minmax - proc_mkdir - proc_remove - proc_set_user - proto_register - proto_unregister - pskb_expand_head - __pskb_pull_tail - ___pskb_trim - putback_movable_pages - put_device - put_disk - put_iova_domain - __put_net - __put_page - put_pid - put_sg_io_hdr - __put_task_struct - put_unused_fd - pwm_apply_state - pwmchip_add - pwmchip_remove - qcom_smem_state_get - qcom_smem_state_register - qcom_smem_state_unregister - qcom_smem_state_update_bits - qdisc_reset - queue_delayed_work_on - queue_work_on - radix_tree_delete - radix_tree_insert - radix_tree_iter_delete - radix_tree_lookup - radix_tree_maybe_preload - radix_tree_next_chunk - ___ratelimit - rational_best_approximation - raw_notifier_call_chain - raw_notifier_chain_register - raw_notifier_chain_unregister - _raw_read_lock - _raw_read_lock_bh - _raw_read_lock_irq - _raw_read_lock_irqsave - _raw_read_unlock - _raw_read_unlock_bh - _raw_read_unlock_irq - _raw_read_unlock_irqrestore - _raw_spin_lock - _raw_spin_lock_bh - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_trylock - _raw_spin_trylock_bh - _raw_spin_unlock - _raw_spin_unlock_bh - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - _raw_write_lock - _raw_write_lock_bh - _raw_write_lock_irq - _raw_write_lock_irqsave - _raw_write_unlock - _raw_write_unlock_bh - _raw_write_unlock_irq - _raw_write_unlock_irqrestore - rb_erase - rb_first - rb_insert_color - rb_last - rb_next - rb_prev - rcu_barrier - rcu_barrier_tasks - rcu_barrier_tasks_trace - rcu_bind_current_to_nocb - rcu_cpu_stall_suppress - rcu_cpu_stall_suppress_at_boot - rcu_expedite_gp - rcu_force_quiescent_state - rcu_fwd_progress_check - rcu_get_gp_kthreads_prio - rcu_get_gp_seq - rcu_gp_is_expedited - rcu_gp_is_normal - rcu_gp_set_torture_wait - rcu_inkernel_boot_has_ended - rcu_is_watching - rcu_jiffies_till_stall_check - __rcu_read_lock - __rcu_read_unlock - rcu_read_unlock_trace_special - rcutorture_get_gp_data - rcu_unexpedite_gp - rcuwait_wake_up - rdev_get_drvdata - reboot_mode - reclaim_shmem_address_space - refcount_dec_and_lock - refcount_dec_not_one - refcount_warn_saturate - regcache_cache_only - regcache_mark_dirty - regcache_sync - regcache_sync_region - register_blkdev - __register_chrdev - register_chrdev_region - register_console - register_die_notifier - register_ftrace_export - register_inet6addr_notifier - register_inetaddr_notifier - register_kprobe - register_kretprobe - register_memory_notifier - register_module_notifier - register_netdev - register_netdevice - register_netdevice_notifier - register_netevent_notifier - register_oom_notifier - register_pernet_device - register_pm_notifier - register_reboot_notifier - register_restart_handler - __register_rpmsg_driver - register_shrinker - register_syscore_ops - register_sysctl - register_sysctl_table - regmap_bulk_read - regmap_bulk_write - regmap_check_range_table - regmap_field_read - regmap_field_update_bits_base - __regmap_init - regmap_irq_get_virq - regmap_mmio_detach_clk - regmap_read - regmap_update_bits_base - regmap_write - regulator_allow_bypass - regulator_bulk_disable - regulator_count_voltages - regulator_disable - regulator_disable_deferred - regulator_enable - regulator_force_disable - regulator_get - regulator_get_drvdata - regulator_get_mode - regulator_get_voltage - regulator_get_voltage_rdev - regulator_is_enabled - regulator_is_supported_voltage - regulator_list_voltage_linear - regulator_notifier_call_chain - regulator_put - regulator_register_notifier - regulator_set_current_limit - regulator_set_load - regulator_set_mode - regulator_set_voltage - regulator_unregister_notifier - release_firmware - __release_region - release_sock - remap_pfn_range - remove_cpu - remove_memory_subsection - remove_proc_entry - remove_wait_queue - report_iommu_fault - request_any_context_irq - request_firmware - request_firmware_into_buf - request_firmware_nowait - __request_module - __request_percpu_irq - __request_region - request_threaded_irq - resched_curr - reset_control_assert - reset_control_deassert - reset_control_put - reset_control_reset - resume_cpus - return_address - revalidate_disk_size - rfkill_alloc - rfkill_blocked - rfkill_destroy - rfkill_init_sw_state - rfkill_pause_polling - rfkill_register - rfkill_resume_polling - rfkill_set_hw_state - rfkill_unregister - rhashtable_free_and_destroy - rhashtable_insert_slow - rhltable_init - __rht_bucket_nested - rht_bucket_nested - rht_bucket_nested_insert - rndis_deregister - rndis_free_response - rndis_get_next_response - rndis_msg_parser - rndis_register - rndis_set_host_mac - rndis_set_param_dev - rndis_set_param_medium - rndis_set_param_vendor - rndis_signal_connect - rndis_uninit - root_task_group - round_jiffies - round_jiffies_relative - round_jiffies_up - rpmsg_get_signals - rpmsg_poll - rpmsg_register_device - rpmsg_send - rpmsg_set_signals - rpmsg_trysend - rpmsg_unregister_device - rproc_add - rproc_add_subdev - rproc_alloc - rproc_boot - rproc_coredump - rproc_coredump_add_custom_segment - rproc_coredump_add_segment - rproc_coredump_cleanup - rproc_coredump_set_elf_info - rproc_coredump_using_sections - rproc_del - rproc_free - rproc_get_by_child - rproc_get_by_phandle - rproc_put - rproc_remove_subdev - rproc_report_crash - rproc_shutdown - __rtc_register_device - rtc_time64_to_tm - rtc_tm_to_time64 - rtc_update_irq - rt_mutex_lock - rt_mutex_unlock - rtnl_is_locked - rtnl_link_register - rtnl_link_unregister - rtnl_lock - rtnl_register_module - rtnl_trylock - rtnl_unicast - rtnl_unlock - rtnl_unregister - runqueues - scatterwalk_ffwd - scatterwalk_map_and_copy - sched_clock - sched_feat_keys - sched_feat_names - sched_setattr - sched_set_fifo - sched_set_fifo_low - sched_set_normal - sched_setscheduler - sched_setscheduler_nocheck - sched_show_task - sched_trace_rd_span - sched_uclamp_used - schedule - schedule_hrtimeout - schedule_timeout - schedule_timeout_interruptible - schedule_timeout_uninterruptible - scmi_driver_register - scmi_driver_unregister - scmi_protocol_register - scmi_protocol_unregister - scnprintf - scsi_autopm_get_device - scsi_autopm_put_device - scsi_block_when_processing_errors - scsi_command_size_tbl - scsi_compat_ioctl - scsi_device_get - scsi_device_put - scsi_device_quiesce - scsi_ioctl - scsi_ioctl_block_when_processing_errors - __scsi_iterate_devices - scsi_normalize_sense - __scsi_print_sense - scsi_register_interface - scsi_remove_device - sdev_prefix_printk - __sdhci_add_host - sdhci_add_host - sdhci_cleanup_host - sdhci_cqe_disable - sdhci_cqe_enable - sdhci_cqe_irq - sdhci_enable_clk - sdhci_get_property - sdhci_pltfm_free - sdhci_pltfm_init - sdhci_remove_host - sdhci_reset - sdhci_set_bus_width - sdhci_set_power_noreg - sdhci_setup_host - seq_buf_printf - seq_hex_dump - seq_lseek - seq_open - seq_printf - seq_putc - seq_puts - seq_read - seq_release - seq_vprintf - seq_write - set_cpus_allowed_ptr - set_normalized_timespec64 - set_page_dirty_lock - __SetPageMovable - set_task_cpu - set_user_nice - sg_alloc_table - sg_alloc_table_from_pages - sg_copy_from_buffer - sg_copy_to_buffer - sg_free_table - sg_init_one - sg_init_table - sg_miter_next - sg_miter_start - sg_miter_stop - sg_next - __sg_page_iter_dma_next - __sg_page_iter_next - __sg_page_iter_start - sg_pcopy_from_buffer - sg_pcopy_to_buffer - sg_scsi_ioctl - shmem_file_setup - shmem_mark_page_lazyfree - shmem_read_mapping_page_gfp - shmem_truncate_range - show_rcu_gp_kthreads - show_regs - sigprocmask - si_mem_available - si_meminfo - simple_attr_open - simple_attr_read - simple_attr_release - simple_attr_write - simple_open - simple_read_from_buffer - simple_write_to_buffer - single_open - single_release - si_swapinfo - sk_alloc - skb_add_rx_frag - skb_append_pagefrags - skb_checksum - skb_checksum_help - skb_clone - skb_clone_sk - skb_coalesce_rx_frag - skb_complete_wifi_ack - skb_copy - skb_copy_bits - skb_copy_datagram_iter - skb_copy_expand - skb_dequeue - skb_dequeue_tail - skb_ensure_writable - skb_free_datagram - __skb_get_hash - __skb_gso_segment - __skb_pad - skb_pull - skb_push - skb_put - skb_queue_head - skb_queue_purge - skb_queue_tail - skb_recv_datagram - skb_set_owner_w - skb_store_bits - skb_trim - sk_free - skip_spaces - smp_call_function - smp_call_function_any - smp_call_function_single - snd_card_free - snd_card_new - snd_card_register - snd_info_create_card_entry - snd_info_create_module_entry - snd_info_free_entry - snd_info_register - snd_jack_set_key - snd_pcm_format_width - snd_pcm_hw_constraint_integer - snd_pcm_new - snd_pcm_period_elapsed - snd_pcm_set_managed_buffer_all - snd_pcm_set_ops - snd_pcm_stream_lock - _snd_pcm_stream_lock_irqsave - snd_pcm_stream_unlock - snd_pcm_stream_unlock_irqrestore - snd_soc_add_component_controls - snd_soc_card_get_kcontrol - snd_soc_card_jack_new - snd_soc_component_exit_regmap - snd_soc_component_init_regmap - snd_soc_component_read - snd_soc_component_update_bits - snd_soc_component_write - snd_soc_dai_get_channel_map - snd_soc_dai_set_channel_map - snd_soc_dapm_add_routes - snd_soc_dapm_disable_pin - snd_soc_dapm_force_enable_pin - snd_soc_dapm_get_enum_double - snd_soc_dapm_get_volsw - snd_soc_dapm_ignore_suspend - snd_soc_dapm_kcontrol_widget - snd_soc_dapm_mixer_update_power - snd_soc_dapm_mux_update_power - snd_soc_dapm_new_controls - snd_soc_dapm_new_widgets - snd_soc_dapm_put_enum_double - snd_soc_dapm_put_volsw - snd_soc_dapm_sync - snd_soc_get_enum_double - snd_soc_get_pcm_runtime - snd_soc_get_volsw - snd_soc_info_enum_double - snd_soc_info_multi_ext - snd_soc_info_volsw - snd_soc_jack_report - snd_soc_lookup_component - snd_soc_of_parse_audio_routing - snd_soc_of_parse_card_name - snd_soc_pm_ops - snd_soc_put_enum_double - snd_soc_put_volsw - snd_soc_register_component - snd_soc_rtdcom_lookup - snd_soc_unregister_card - snd_soc_unregister_component - snd_usb_enable_audio_stream - snprintf - soc_device_register - soc_device_unregister - sock_alloc_send_skb - __sock_create - sock_create_kern - sock_gettstamp - sock_init_data - sock_no_accept - sock_no_listen - sock_no_mmap - sock_no_sendpage - sock_no_shutdown - sock_no_socketpair - sock_queue_rcv_skb - sock_register - sock_release - sock_setsockopt - sock_unregister - softnet_data - sort - __spi_alloc_controller - spi_register_controller - __spi_register_driver - spi_setup - spi_sync - spi_unregister_controller - split_page - spmi_controller_add - spmi_controller_alloc - spmi_controller_remove - __spmi_driver_register - spmi_ext_register_read - spmi_ext_register_readl - spmi_ext_register_write - spmi_ext_register_writel - spmi_register_read - spmi_register_write - spmi_register_zero_write - sprintf - sprint_symbol - srcu_barrier - srcu_batches_completed - srcu_init_notifier_head - srcu_notifier_call_chain - srcu_notifier_chain_register - srcu_notifier_chain_unregister - __srcu_read_lock - __srcu_read_unlock - srcutorture_get_gp_data - srcu_torture_stats_print - sscanf - __stack_chk_fail - __stack_chk_guard - stack_depot_fetch - stack_trace_print - stack_trace_save - static_key_disable - static_key_disable_cpuslocked - stop_machine - stop_one_cpu_nowait - strcasecmp - strchr - strchrnul - strcmp - strcpy - strim - strlcat - strlcpy - strlen - strncasecmp - strnchr - strncmp - strncpy - strncpy_from_user - strnlen - strnstr - strpbrk - strrchr - strreplace - strscpy - strsep - strstr - __sw_hweight16 - __sw_hweight32 - __sw_hweight64 - __sw_hweight8 - sync_file_create - sync_file_get_fence - synchronize_irq - synchronize_net - synchronize_rcu - synchronize_rcu_expedited - synchronize_rcu_tasks - synchronize_rcu_tasks_trace - synchronize_srcu - synchronize_srcu_expedited - synth_event_create - synth_event_delete - syscon_node_to_regmap - syscon_regmap_lookup_by_phandle - sysctl_sched_features - sysctl_sched_latency - sysctl_vals - sysfs_add_file_to_group - sysfs_add_link_to_group - sysfs_create_bin_file - sysfs_create_file_ns - sysfs_create_files - sysfs_create_group - sysfs_create_groups - sysfs_create_link - sysfs_emit - __sysfs_match_string - sysfs_notify - sysfs_remove_bin_file - sysfs_remove_file_from_group - sysfs_remove_file_ns - sysfs_remove_files - sysfs_remove_group - sysfs_remove_groups - sysfs_remove_link - sysfs_remove_link_from_group - sysfs_streq - sysrq_mask - system_freezable_wq - system_freezing_cnt - system_highpri_wq - system_long_wq - system_power_efficient_wq - system_state - system_unbound_wq - system_wq - sys_tz - task_active_pid_ns - task_groups - __tasklet_hi_schedule - tasklet_init - tasklet_kill - __tasklet_schedule - tasklet_setup - tasklist_lock - task_may_not_preempt - __task_pid_nr_ns - __task_rq_lock - thermal_cooling_device_register - thermal_cooling_device_unregister - thermal_of_cooling_device_register - thermal_pressure - thermal_zone_device_enable - thermal_zone_device_register - thermal_zone_device_unregister - thermal_zone_device_update - thermal_zone_get_slope - thermal_zone_get_temp - thermal_zone_get_zone_by_name - thermal_zone_of_sensor_register - thermal_zone_of_sensor_unregister - tick_nohz_get_sleep_length - time64_to_tm - timer_unstable_counter_workaround - topology_set_thermal_pressure - topology_update_done - _totalram_pages - total_swapcache_pages - trace_array_get_by_name - trace_array_put - trace_array_set_clr_event - __trace_bprintk - __trace_bputs - trace_clock_local - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_get_event_file - trace_handle_return - __traceiter_android_rvh_account_irq - __traceiter_android_rvh_after_dequeue_task - __traceiter_android_rvh_after_enqueue_task - __traceiter_android_rvh_build_perf_domains - __traceiter_android_rvh_can_migrate_task - __traceiter_android_rvh_cgroup_force_kthread_migration - __traceiter_android_rvh_check_preempt_wakeup - __traceiter_android_rvh_cpu_cgroup_attach - __traceiter_android_rvh_cpu_cgroup_online - __traceiter_android_rvh_cpufreq_transition - __traceiter_android_rvh_dequeue_task - __traceiter_android_rvh_enqueue_task - __traceiter_android_rvh_find_busiest_queue - __traceiter_android_rvh_find_lowest_rq - __traceiter_android_rvh_flush_task - __traceiter_android_rvh_force_compatible_post - __traceiter_android_rvh_force_compatible_pre - __traceiter_android_rvh_gic_v3_set_affinity - __traceiter_android_rvh_irqs_disable - __traceiter_android_rvh_irqs_enable - __traceiter_android_rvh_migrate_queued_task - __traceiter_android_rvh_new_task_stats - __traceiter_android_rvh_pick_next_entity - __traceiter_android_rvh_place_entity - __traceiter_android_rvh_preempt_disable - __traceiter_android_rvh_preempt_enable - __traceiter_android_rvh_replace_next_task_fair - __traceiter_android_rvh_resume_cpus - __traceiter_android_rvh_sched_balance_rt - __traceiter_android_rvh_sched_cpu_dying - __traceiter_android_rvh_sched_cpu_starting - __traceiter_android_rvh_sched_exec - __traceiter_android_rvh_sched_fork - __traceiter_android_rvh_sched_fork_init - __traceiter_android_rvh_sched_newidle_balance - __traceiter_android_rvh_sched_nohz_balancer_kick - __traceiter_android_rvh_sched_setaffinity - __traceiter_android_rvh_schedule - __traceiter_android_rvh_schedule_bug - __traceiter_android_rvh_select_task_rq_fair - __traceiter_android_rvh_select_task_rq_rt - __traceiter_android_rvh_set_gfp_zone_flags - __traceiter_android_rvh_set_readahead_gfp_mask - __traceiter_android_rvh_set_skip_swapcache_flags - __traceiter_android_rvh_set_task_cpu - __traceiter_android_rvh_show_max_freq - __traceiter_android_rvh_tick_entry - __traceiter_android_rvh_try_to_wake_up - __traceiter_android_rvh_try_to_wake_up_success - __traceiter_android_rvh_ttwu_cond - __traceiter_android_rvh_update_cpu_capacity - __traceiter_android_rvh_update_cpus_allowed - __traceiter_android_rvh_update_misfit_status - __traceiter_android_rvh_wake_up_new_task - __traceiter_android_vh_allow_domain_state - __traceiter_android_vh_binder_restore_priority - __traceiter_android_vh_binder_set_priority - __traceiter_android_vh_binder_transaction_init - __traceiter_android_vh_binder_wakeup_ilocked - __traceiter_android_vh_cpu_idle_enter - __traceiter_android_vh_cpu_idle_exit - __traceiter_android_vh_cpuidle_psci_enter - __traceiter_android_vh_cpuidle_psci_exit - __traceiter_android_vh_dump_throttled_rt_tasks - __traceiter_android_vh_freq_table_limits - __traceiter_android_vh_ftrace_dump_buffer - __traceiter_android_vh_ftrace_format_check - __traceiter_android_vh_ftrace_oops_enter - __traceiter_android_vh_ftrace_oops_exit - __traceiter_android_vh_ftrace_size_check - __traceiter_android_vh_gic_resume - __traceiter_android_vh_gpio_block_read - __traceiter_android_vh_iommu_setup_dma_ops - __traceiter_android_vh_ipi_stop - __traceiter_android_vh_jiffies_update - __traceiter_android_vh_logbuf - __traceiter_android_vh_logbuf_pr_cont - __traceiter_android_vh_printk_hotplug - __traceiter_android_vh_rproc_recovery - __traceiter_android_vh_scheduler_tick - __traceiter_android_vh_show_max_freq - __traceiter_android_vh_show_resume_epoch_val - __traceiter_android_vh_show_suspend_epoch_val - __traceiter_android_vh_timer_calc_index - __traceiter_android_vh_ufs_check_int_errors - __traceiter_android_vh_ufs_clock_scaling - __traceiter_android_vh_ufs_compl_command - __traceiter_android_vh_ufs_fill_prdt - __traceiter_android_vh_ufs_prepare_command - __traceiter_android_vh_ufs_send_command - __traceiter_android_vh_ufs_send_tm_command - __traceiter_android_vh_ufs_send_uic_command - __traceiter_android_vh_ufs_update_sdev - __traceiter_android_vh_ufs_update_sysfs - __traceiter_android_vh_update_topology_flags_workfn - __traceiter_binder_transaction_received - __traceiter_cpu_frequency - __traceiter_cpu_frequency_limits - __traceiter_cpu_idle - __traceiter_gpu_mem_total - __traceiter_ipi_entry - __traceiter_ipi_raise - __traceiter_irq_handler_entry - __traceiter_rwmmio_post_read - __traceiter_rwmmio_read - __traceiter_rwmmio_write - __traceiter_sched_overutilized_tp - __traceiter_sched_switch - __traceiter_suspend_resume - __tracepoint_android_rvh_account_irq - __tracepoint_android_rvh_after_dequeue_task - __tracepoint_android_rvh_after_enqueue_task - __tracepoint_android_rvh_build_perf_domains - __tracepoint_android_rvh_can_migrate_task - __tracepoint_android_rvh_cgroup_force_kthread_migration - __tracepoint_android_rvh_check_preempt_wakeup - __tracepoint_android_rvh_cpu_cgroup_attach - __tracepoint_android_rvh_cpu_cgroup_online - __tracepoint_android_rvh_cpufreq_transition - __tracepoint_android_rvh_dequeue_task - __tracepoint_android_rvh_enqueue_task - __tracepoint_android_rvh_find_busiest_queue - __tracepoint_android_rvh_find_lowest_rq - __tracepoint_android_rvh_flush_task - __tracepoint_android_rvh_force_compatible_post - __tracepoint_android_rvh_force_compatible_pre - __tracepoint_android_rvh_gic_v3_set_affinity - __tracepoint_android_rvh_irqs_disable - __tracepoint_android_rvh_irqs_enable - __tracepoint_android_rvh_migrate_queued_task - __tracepoint_android_rvh_new_task_stats - __tracepoint_android_rvh_pick_next_entity - __tracepoint_android_rvh_place_entity - __tracepoint_android_rvh_preempt_disable - __tracepoint_android_rvh_preempt_enable - __tracepoint_android_rvh_replace_next_task_fair - __tracepoint_android_rvh_resume_cpus - __tracepoint_android_rvh_sched_balance_rt - __tracepoint_android_rvh_sched_cpu_dying - __tracepoint_android_rvh_sched_cpu_starting - __tracepoint_android_rvh_sched_exec - __tracepoint_android_rvh_sched_fork - __tracepoint_android_rvh_sched_fork_init - __tracepoint_android_rvh_sched_newidle_balance - __tracepoint_android_rvh_sched_nohz_balancer_kick - __tracepoint_android_rvh_sched_setaffinity - __tracepoint_android_rvh_schedule - __tracepoint_android_rvh_schedule_bug - __tracepoint_android_rvh_select_task_rq_fair - __tracepoint_android_rvh_select_task_rq_rt - __tracepoint_android_rvh_set_gfp_zone_flags - __tracepoint_android_rvh_set_readahead_gfp_mask - __tracepoint_android_rvh_set_skip_swapcache_flags - __tracepoint_android_rvh_set_task_cpu - __tracepoint_android_rvh_show_max_freq - __tracepoint_android_rvh_tick_entry - __tracepoint_android_rvh_try_to_wake_up - __tracepoint_android_rvh_try_to_wake_up_success - __tracepoint_android_rvh_ttwu_cond - __tracepoint_android_rvh_update_cpu_capacity - __tracepoint_android_rvh_update_cpus_allowed - __tracepoint_android_rvh_update_misfit_status - __tracepoint_android_rvh_wake_up_new_task - __tracepoint_android_vh_allow_domain_state - __tracepoint_android_vh_alter_rwsem_list_add - __tracepoint_android_vh_binder_restore_priority - __tracepoint_android_vh_binder_set_priority - __tracepoint_android_vh_binder_transaction_init - __tracepoint_android_vh_binder_wakeup_ilocked - __tracepoint_android_vh_check_uninterruptible_tasks - __tracepoint_android_vh_check_uninterruptible_tasks_dn - __tracepoint_android_vh_cpu_idle_enter - __tracepoint_android_vh_cpu_idle_exit - __tracepoint_android_vh_cpuidle_psci_enter - __tracepoint_android_vh_cpuidle_psci_exit - __tracepoint_android_vh_dump_throttled_rt_tasks - __tracepoint_android_vh_freq_table_limits - __tracepoint_android_vh_ftrace_dump_buffer - __tracepoint_android_vh_ftrace_format_check - __tracepoint_android_vh_ftrace_oops_enter - __tracepoint_android_vh_ftrace_oops_exit - __tracepoint_android_vh_ftrace_size_check - __tracepoint_android_vh_gic_resume - __tracepoint_android_vh_gpio_block_read - __tracepoint_android_vh_iommu_setup_dma_ops - __tracepoint_android_vh_ipi_stop - __tracepoint_android_vh_jiffies_update - __tracepoint_android_vh_logbuf - __tracepoint_android_vh_logbuf_pr_cont - __tracepoint_android_vh_oom_check_panic - __tracepoint_android_vh_printk_hotplug - __tracepoint_android_vh_process_killed - __tracepoint_android_vh_psi_event - __tracepoint_android_vh_psi_group - __tracepoint_android_vh_rproc_recovery - __tracepoint_android_vh_scheduler_tick - __tracepoint_android_vh_shmem_alloc_page - __tracepoint_android_vh_show_max_freq - __tracepoint_android_vh_show_resume_epoch_val - __tracepoint_android_vh_show_suspend_epoch_val - __tracepoint_android_vh_timer_calc_index - __tracepoint_android_vh_ufs_check_int_errors - __tracepoint_android_vh_ufs_clock_scaling - __tracepoint_android_vh_ufs_compl_command - __tracepoint_android_vh_ufs_fill_prdt - __tracepoint_android_vh_ufs_prepare_command - __tracepoint_android_vh_ufs_send_command - __tracepoint_android_vh_ufs_send_tm_command - __tracepoint_android_vh_ufs_send_uic_command - __tracepoint_android_vh_ufs_update_sdev - __tracepoint_android_vh_ufs_update_sysfs - __tracepoint_android_vh_update_topology_flags_workfn - __tracepoint_binder_transaction_received - __tracepoint_cpu_frequency - __tracepoint_cpu_frequency_limits - __tracepoint_cpu_idle - __tracepoint_gpu_mem_total - __tracepoint_ipi_entry - __tracepoint_ipi_raise - __tracepoint_irq_handler_entry - tracepoint_probe_register - tracepoint_probe_register_prio - tracepoint_probe_unregister - __tracepoint_rwmmio_post_read - __tracepoint_rwmmio_read - __tracepoint_rwmmio_write - __tracepoint_sched_overutilized_tp - __tracepoint_sched_switch - __tracepoint_suspend_resume - trace_print_array_seq - trace_print_flags_seq - trace_print_hex_seq - __trace_printk - trace_print_symbols_seq - trace_raw_output_prep - trace_seq_printf - trace_seq_putc - tracing_off - try_module_get - try_wait_for_completion - tty_flip_buffer_push - __tty_insert_flip_char - tty_insert_flip_string_fixed_flag - typec_altmode_get_partner - typec_altmode_update_active - typec_get_drvdata - typec_partner_register_altmode - typec_port_register_altmode - typec_register_partner - typec_register_port - typec_set_data_role - typec_set_pwr_opmode - typec_set_pwr_role - typec_unregister_altmode - typec_unregister_partner - typec_unregister_port - uart_add_one_port - uart_console_device - uart_console_write - uart_get_baud_rate - uart_insert_char - uart_parse_options - uart_register_driver - uart_remove_one_port - uart_resume_port - uart_set_options - uart_suspend_port - uart_try_toggle_sysrq - uart_unregister_driver - uart_update_timeout - uart_write_wakeup - uclamp_eff_value - ucsi_connector_change - ucsi_create - ucsi_destroy - ucsi_get_drvdata - ucsi_register - ucsi_set_drvdata - ucsi_unregister - __udelay - ufshcd_auto_hibern8_update - ufshcd_dme_get_attr - ufshcd_dme_set_attr - ufshcd_dump_regs - ufshcd_fixup_dev_quirks - ufshcd_get_local_unipro_ver - ufshcd_hold - ufshcd_pltfrm_init - ufshcd_pltfrm_resume - ufshcd_pltfrm_runtime_idle - ufshcd_pltfrm_runtime_resume - ufshcd_pltfrm_runtime_suspend - ufshcd_pltfrm_shutdown - ufshcd_pltfrm_suspend - ufshcd_query_attr - ufshcd_query_descriptor_retry - ufshcd_query_flag - ufshcd_release - ufshcd_remove - ufshcd_shutdown - ufshcd_uic_hibern8_enter - ufshcd_uic_hibern8_exit - __uio_register_device - uio_unregister_device - unlock_page - unmap_mapping_range - unregister_blkdev - __unregister_chrdev - unregister_chrdev_region - unregister_console - unregister_die_notifier - unregister_ftrace_export - unregister_inet6addr_notifier - unregister_inetaddr_notifier - unregister_kprobe - unregister_kretprobe - unregister_module_notifier - unregister_netdev - unregister_netdevice_many - unregister_netdevice_notifier - unregister_netdevice_queue - unregister_netevent_notifier - unregister_oom_notifier - unregister_pernet_device - unregister_pm_notifier - unregister_reboot_notifier - unregister_restart_handler - unregister_rpmsg_driver - unregister_shrinker - unregister_syscore_ops - unregister_sysctl_table - up - update_devfreq - update_rq_clock - up_read - up_write - usb_add_gadget - usb_add_gadget_udc - usb_add_phy_dev - usb_alloc_coherent - usb_alloc_dev - usb_alloc_urb - usb_amd_dev_put - usb_amd_pt_check_port - usb_amd_quirk_pll_check - usb_amd_quirk_pll_disable - usb_amd_quirk_pll_enable - usb_asmedia_modifyflowcontrol - usb_assign_descriptors - usb_autopm_get_interface - usb_autopm_put_interface - usb_bulk_msg - usb_composite_setup_continue - usb_control_msg - __usb_create_hcd - usb_debug_root - usb_decode_ctrl - usb_del_gadget_udc - usb_deregister - usb_disabled - usb_disable_xhci_ports - usb_enable_intel_xhci_ports - usb_ep_alloc_request - usb_ep_autoconfig - usb_ep_dequeue - usb_ep_disable - usb_ep_enable - usb_ep_free_request - usb_ep_queue - usb_ep_set_halt - usb_ep_set_maxpacket_limit - usb_find_common_endpoints - usb_free_all_descriptors - usb_free_coherent - usb_free_urb - usb_function_register - usb_function_unregister - usb_gadget_giveback_request - usb_gadget_map_request_by_dev - usb_gadget_set_state - usb_gadget_udc_reset - usb_gadget_unmap_request_by_dev - usb_gadget_vbus_connect - usb_gadget_vbus_disconnect - usb_gadget_vbus_draw - usb_gadget_wakeup - usb_get_dr_mode - usb_get_maximum_speed - usb_get_urb - usb_gstrings_attach - usb_hcd_end_port_resume - usb_hc_died - usb_hcd_irq - usb_hcd_map_urb_for_dma - usb_hcd_pci_pm_ops - usb_hcd_pci_probe - usb_hcd_pci_remove - usb_hcd_pci_shutdown - usb_hcd_platform_shutdown - usb_hcd_start_port_resume - usb_hub_clear_tt_buffer - usb_hub_find_child - usb_ifnum_to_if - usb_initialize_gadget - usb_interface_id - usb_kill_urb - usb_phy_set_charger_current - usb_poison_urb - usb_put_dev - usb_put_function_instance - usb_register_driver - usb_register_notify - usb_remove_phy - usb_role_switch_find_by_fwnode - usb_role_switch_get_drvdata - usb_role_switch_register - usb_role_switch_set_role - usb_role_switch_unregister - usb_root_hub_lost_power - usb_set_device_state - usb_speed_string - usb_string_id - usb_submit_urb - usb_unregister_notify - usb_wakeup_notification - __usecs_to_jiffies - usleep_range - v4l2_compat_ioctl32 - v4l2_ctrl_find - v4l2_ctrl_handler_free - v4l2_ctrl_handler_init_class - v4l2_ctrl_new_custom - v4l2_ctrl_new_std - v4l2_ctrl_new_std_menu - v4l2_device_register - v4l2_device_register_subdev - __v4l2_device_register_subdev_nodes - v4l2_device_unregister - v4l2_device_unregister_subdev - v4l2_event_dequeue - v4l2_event_pending - v4l2_event_queue - v4l2_event_queue_fh - v4l2_event_subscribe - v4l2_event_unsubscribe - v4l2_fh_add - v4l2_fh_del - v4l2_fh_exit - v4l2_fh_init - v4l2_fh_open - v4l2_fh_release - v4l2_s_ctrl - v4l2_subdev_call_wrappers - v4l2_subdev_init - vabits_actual - vb2_buffer_done - vb2_dqbuf - vb2_qbuf - vb2_queue_init - vb2_queue_release - vb2_reqbufs - vb2_streamoff - vb2_streamon - vchan_dma_desc_free_list - vchan_find_desc - vchan_init - vchan_tx_desc_free - vchan_tx_submit - verify_pkcs7_signature - vfree - video_devdata - video_device_alloc - video_device_release - video_device_release_empty - video_ioctl2 - __video_register_device - video_unregister_device - vmalloc - vmalloc_nr_pages - vmalloc_to_page - vmalloc_to_pfn - vmap - vmemdup_user - vm_event_states - vmf_insert_mixed - vmf_insert_pfn - vm_get_page_prot - vm_insert_page - vm_iomap_memory - vm_map_pages - vm_memory_committed - vm_mmap - vm_munmap - vm_node_stat - vm_zone_stat - vprintk - vscnprintf - vsnprintf - vunmap - vzalloc - wait_for_completion - wait_for_completion_interruptible - wait_for_completion_interruptible_timeout - wait_for_completion_killable - wait_for_completion_timeout - __wait_rcu_gp - wait_woken - __wake_up - wake_up_if_idle - __wake_up_locked - wake_up_process - wakeup_source_register - wakeup_source_unregister - __warn_printk - wireless_nlevent_flush - wireless_send_event - woken_wake_function - work_busy - ww_mutex_lock - ww_mutex_unlock - __xa_alloc - xa_destroy - xa_erase - xa_find - xa_find_after - xa_load - xa_store - __xfrm_decode_session - xfrm_lookup - xfrm_output - xhci_alloc_command - xhci_alloc_erst - xhci_free_command - xhci_free_erst - xhci_get_endpoint_index - xhci_queue_stop_endpoint - xhci_ring_alloc - xhci_ring_cmd_db - xhci_ring_free - xhci_trb_virt_to_dma - zone_watermark_ok - zone_watermark_ok_safe diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip deleted file mode 100644 index 6c4b0be95bf0..000000000000 --- a/android/abi_gki_aarch64_rockchip +++ /dev/null @@ -1,1518 +0,0 @@ -[abi_symbol_list] - __ClearPageMovable - __SetPageMovable - ___ratelimit - __alloc_disk_node - __alloc_pages_nodemask - __alloc_percpu - __alloc_percpu_gfp - __alloc_skb - __arch_copy_from_user - __arch_copy_to_user - __arm_smccc_hvc - __arm_smccc_smc - __bitmap_and - __bitmap_andnot - __bitmap_clear - __bitmap_set - __bitmap_weight - __blk_rq_map_sg - __cfi_slowpath - __check_object_size - __class_create - __class_register - __clk_get_name - __const_udelay - __cpu_online_mask - __cpu_possible_mask - __cpufreq_driver_target - __cpuhp_remove_state - __cpuhp_setup_state - __cpuhp_state_add_instance - __cpuhp_state_remove_instance - __crypto_memneq - __crypto_xor - __dev_kfree_skb_any - __devm_iio_device_register - __devm_of_phy_provider_register - __devm_regmap_init - __devm_regmap_init_i2c - __devm_regmap_init_mmio_clk - __devm_reset_control_get - __do_once_done - __do_once_start - __drm_err - __fdget - __free_pages - __get_free_pages - __getblk_gfp - __i2c_smbus_xfer - __i2c_transfer - __init_rwsem - __init_swait_queue_head - __init_waitqueue_head - __ioremap - __ipv6_addr_type - __kfifo_alloc - __kfifo_free - __kfifo_in - __kfifo_out - __kfifo_to_user - __kmalloc - __list_add_valid - __list_del_entry_valid - __lock_buffer - __lock_page - __log_post_read_mmio - __log_read_mmio - __log_write_mmio - __mdiobus_register - __memcpy_fromio - __memcpy_toio - __memset_io - __module_get - __msecs_to_jiffies - __mutex_init - __napi_alloc_skb - __napi_schedule - __netdev_alloc_skb - __netif_napi_del - __num_online_cpus - __of_reset_control_get - __page_pinner_migration_failed - __pci_register_driver - __per_cpu_offset - __platform_driver_register - __pm_runtime_disable - __pm_runtime_idle - __pm_runtime_resume - __pm_runtime_set_status - __pm_runtime_suspend - __pm_runtime_use_autosuspend - __printk_ratelimit - __pskb_pull_tail - __put_net - __put_page - __put_task_struct - __rcu_read_lock - __rcu_read_unlock - __refrigerator - __register_chrdev - __rtc_register_device - __scsi_add_device - __scsi_execute - __scsi_print_sense - __sdhci_add_host - __sg_page_iter_next - __sg_page_iter_start - __sock_create - __spi_alloc_controller - __spi_register_driver - __srcu_read_unlock - __stack_chk_fail - __stack_chk_guard - __sw_hweight64 - __sysfs_match_string - __task_pid_nr_ns - __tasklet_hi_schedule - __tasklet_schedule - __traceiter_rwmmio_post_read - __traceiter_rwmmio_read - __traceiter_rwmmio_write - __tracepoint_rwmmio_post_read - __tracepoint_rwmmio_read - __tracepoint_rwmmio_write - __tty_insert_flip_char - __unregister_chrdev - __usecs_to_jiffies - __v4l2_ctrl_modify_range - __v4l2_find_nearest_size - __wait_on_buffer - __wake_up - __warn_printk - _copy_from_iter_full - _copy_to_iter - _ctype - _dev_crit - _dev_err - _dev_info - _dev_warn - _raw_read_lock - _raw_read_lock_bh - _raw_read_lock_irqsave - _raw_read_unlock - _raw_read_unlock_bh - _raw_read_unlock_irqrestore - _raw_spin_lock - _raw_spin_lock_bh - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_trylock - _raw_spin_trylock_bh - _raw_spin_unlock - _raw_spin_unlock_bh - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - _raw_write_lock - _raw_write_lock_bh - _raw_write_lock_irq - _raw_write_lock_irqsave - _raw_write_unlock - _raw_write_unlock_bh - _raw_write_unlock_irq - _raw_write_unlock_irqrestore - add_timer - add_uevent_var - add_wait_queue - aes_encrypt - aes_expandkey - alloc_anon_inode - alloc_chrdev_region - alloc_etherdev_mqs - alloc_netdev_mqs - alloc_pages_exact - alloc_workqueue - amba_driver_register - amba_driver_unregister - arc4_crypt - arc4_setkey - arm64_const_caps_ready - arm64_use_ng_mappings - async_schedule_node - atomic_notifier_chain_register - atomic_notifier_chain_unregister - autoremove_wake_function - backlight_device_register - backlight_device_unregister - bcmp - bd_set_nr_sectors - bdget_disk - bdput - bio_endio - bitmap_find_next_zero_area_off - bitmap_free - bitmap_zalloc - blk_alloc_queue - blk_cleanup_queue - blk_execute_rq - blk_execute_rq_nowait - blk_freeze_queue_start - blk_get_queue - blk_get_request - blk_mq_alloc_request - blk_mq_alloc_request_hctx - blk_mq_alloc_tag_set - blk_mq_complete_request - blk_mq_complete_request_remote - blk_mq_delay_kick_requeue_list - blk_mq_end_request - blk_mq_free_request - blk_mq_free_tag_set - blk_mq_freeze_queue - blk_mq_freeze_queue_wait - blk_mq_freeze_queue_wait_timeout - blk_mq_init_queue - blk_mq_map_queues - blk_mq_pci_map_queues - blk_mq_quiesce_queue - blk_mq_requeue_request - blk_mq_start_request - blk_mq_tag_to_rq - blk_mq_tagset_busy_iter - blk_mq_tagset_wait_completed_request - blk_mq_unfreeze_queue - blk_mq_unique_tag - blk_mq_unquiesce_queue - blk_mq_update_nr_hw_queues - blk_poll - blk_put_queue - blk_put_request - blk_queue_chunk_sectors - blk_queue_dma_alignment - blk_queue_flag_clear - blk_queue_flag_set - blk_queue_flag_test_and_set - blk_queue_io_min - blk_queue_io_opt - blk_queue_logical_block_size - blk_queue_max_discard_sectors - blk_queue_max_discard_segments - blk_queue_max_hw_sectors - blk_queue_max_segments - blk_queue_max_write_zeroes_sectors - blk_queue_physical_block_size - blk_queue_virt_boundary - blk_queue_write_cache - blk_rq_map_kern - blk_rq_map_user - blk_rq_map_user_iov - blk_rq_unmap_user - blk_set_queue_dying - blk_status_to_errno - blk_sync_queue - blk_verify_command - bpf_trace_run1 - bpf_trace_run2 - bpf_trace_run3 - bpf_trace_run4 - bpf_trace_run5 - bpf_trace_run6 - bpf_trace_run7 - bt_err - bus_register - bus_register_notifier - bus_unregister - bus_unregister_notifier - call_netdevice_notifiers - call_rcu - cancel_delayed_work - cancel_delayed_work_sync - cancel_work_sync - capable - cdev_add - cdev_alloc - cdev_del - cdev_device_add - cdev_device_del - cdev_init - ce_aes_expandkey - class_destroy - class_find_device - class_interface_unregister - class_unregister - cleanup_srcu_struct - clk_bulk_disable - clk_bulk_enable - clk_bulk_prepare - clk_bulk_unprepare - clk_disable - clk_enable - clk_get - clk_get_rate - clk_hw_get_name - clk_hw_set_rate_range - clk_notifier_register - clk_notifier_unregister - clk_prepare - clk_put - clk_register - clk_round_rate - clk_set_rate - clk_unprepare - clk_unregister - cma_alloc - cma_get_name - cma_release - compat_ptr_ioctl - complete - completion_done - consume_skb - contig_page_data - cpu_have_feature - cpu_hwcap_keys - cpu_hwcaps - cpu_number - cpufreq_cpu_get_raw - cpufreq_enable_boost_support - cpufreq_freq_attr_scaling_available_freqs - cpufreq_freq_attr_scaling_boost_freqs - cpufreq_generic_frequency_table_verify - cpufreq_generic_get - cpufreq_generic_suspend - cpufreq_register_driver - cpufreq_register_governor - cpufreq_table_index_unsorted - cpufreq_unregister_driver - cpufreq_unregister_governor - cpumask_next - cpus_read_lock - cpus_read_unlock - crc32_be - crc32_le - crypto_aead_decrypt - crypto_aead_encrypt - crypto_aead_setauthsize - crypto_aead_setkey - crypto_ahash_digest - crypto_ahash_setkey - crypto_alloc_aead - crypto_alloc_ahash - crypto_alloc_base - crypto_alloc_shash - crypto_comp_compress - crypto_comp_decompress - crypto_dequeue_request - crypto_destroy_tfm - crypto_enqueue_request - crypto_has_alg - crypto_inc - crypto_init_queue - crypto_register_aead - crypto_register_ahash - crypto_register_alg - crypto_register_scomp - crypto_register_shash - crypto_register_skcipher - crypto_req_done - crypto_sha1_finup - crypto_sha1_update - crypto_shash_final - crypto_shash_setkey - crypto_shash_update - crypto_unregister_aead - crypto_unregister_ahash - crypto_unregister_alg - crypto_unregister_scomp - crypto_unregister_shash - crypto_unregister_skcipher - csum_partial - current_time - d_add - d_make_root - datagram_poll - deactivate_locked_super - debugfs_create_dir - debugfs_create_file - debugfs_create_regset32 - debugfs_create_u32 - debugfs_create_x64 - debugfs_remove - debugfs_rename - dec_zone_page_state - default_llseek - default_wake_function - deferred_free - del_gendisk - del_timer - del_timer_sync - delayed_work_timer_fn - desc_to_gpio - destroy_workqueue - dev_close - dev_driver_string - dev_err_probe - dev_fetch_sw_netstats - dev_fwnode - dev_get_by_name - dev_get_by_name_rcu - dev_get_regmap - dev_open - dev_pm_opp_free_cpufreq_table - dev_pm_opp_get_max_transition_latency - dev_pm_opp_get_opp_count - dev_pm_opp_get_opp_table - dev_pm_opp_get_sharing_cpus - dev_pm_opp_get_suspend_opp_freq - dev_pm_opp_init_cpufreq_table - dev_pm_opp_of_cpumask_add_table - dev_pm_opp_of_cpumask_remove_table - dev_pm_opp_of_get_sharing_cpus - dev_pm_opp_of_register_em - dev_pm_opp_put_opp_table - dev_pm_opp_put_regulators - dev_pm_opp_set_rate - dev_pm_opp_set_regulators - dev_pm_opp_set_sharing_cpus - dev_pm_qos_expose_latency_tolerance - dev_pm_qos_hide_latency_tolerance - dev_pm_qos_update_user_latency_tolerance - dev_printk - dev_queue_xmit - dev_set_name - device_add - device_add_disk - device_create - device_del - device_destroy - device_for_each_child - device_get_child_node_count - device_get_next_child_node - device_get_phy_mode - device_init_wakeup - device_initialize - device_property_present - device_property_read_string - device_property_read_string_array - device_property_read_u32_array - device_property_read_u8_array - device_register - device_release_driver - device_remove_file_self - device_set_wakeup_capable - device_set_wakeup_enable - device_wakeup_enable - devm_add_action - devm_blk_ksm_init - devm_clk_bulk_get - devm_clk_get - devm_clk_get_optional - devm_clk_hw_register - devm_clk_register - devm_extcon_dev_allocate - devm_extcon_dev_register - devm_extcon_register_notifier - devm_free_irq - devm_get_clk_from_child - devm_gpio_request_one - devm_gpiochip_add_data_with_key - devm_gpiod_get - devm_gpiod_get_index - devm_gpiod_get_optional - devm_iio_channel_get - devm_iio_device_alloc - devm_input_allocate_device - devm_ioremap - devm_ioremap_resource - devm_kasprintf - devm_kfree - devm_kmalloc - devm_kmemdup - devm_kstrdup - devm_kvasprintf - devm_led_classdev_register_ext - devm_mfd_add_devices - devm_nvmem_register - devm_of_clk_add_hw_provider - devm_phy_create - devm_phy_get - devm_pinctrl_register - devm_platform_get_and_ioremap_resource - devm_platform_ioremap_resource - devm_power_supply_register - devm_pwm_get - devm_regmap_field_alloc - devm_regulator_bulk_get - devm_regulator_get - devm_regulator_get_optional - devm_regulator_register - devm_request_any_context_irq - devm_request_threaded_irq - devm_reset_control_array_get - devm_rtc_allocate_device - devm_snd_dmaengine_pcm_register - devm_snd_soc_register_card - devm_snd_soc_register_component - devm_spi_register_controller - devm_thermal_zone_of_sensor_register - devm_usb_get_phy - devres_add - devres_alloc_node - devres_free - devres_release - disable_irq - disk_end_io_acct - disk_start_io_acct - dma_alloc_attrs - dma_async_device_register - dma_async_device_unregister - dma_async_tx_descriptor_init - dma_buf_export - dma_buf_fd - dma_buf_put - dma_contiguous_default_area - dma_free_attrs - dma_get_required_mask - dma_get_slave_channel - dma_heap_add - dma_heap_get_dev - dma_heap_get_drvdata - dma_heap_get_name - dma_map_page_attrs - dma_map_resource - dma_map_sg_attrs - dma_max_mapping_size - dma_pool_alloc - dma_pool_create - dma_pool_destroy - dma_pool_free - dma_release_channel - dma_request_chan - dma_set_coherent_mask - dma_set_mask - dma_sync_sg_for_cpu - dma_sync_sg_for_device - dma_sync_single_for_cpu - dma_sync_single_for_device - dma_unmap_page_attrs - dma_unmap_resource - dma_unmap_sg_attrs - dmabuf_page_pool_alloc - dmabuf_page_pool_create - dmabuf_page_pool_destroy - dmabuf_page_pool_free - dmaengine_unmap_put - dmam_alloc_attrs - dmam_free_coherent - down - down_read - down_write - dput - dql_completed - dql_reset - driver_register - driver_unregister - drm_add_edid_modes - drm_atomic_helper_connector_destroy_state - drm_atomic_helper_connector_duplicate_state - drm_atomic_helper_connector_reset - drm_bridge_add - drm_bridge_remove - drm_connector_attach_encoder - drm_connector_cleanup - drm_connector_init - drm_connector_update_edid_property - drm_detect_hdmi_monitor - drm_display_mode_from_videomode - drm_get_edid - drm_hdmi_avi_infoframe_from_display_mode - drm_helper_hpd_irq_event - drm_helper_probe_single_connector_modes - drm_mode_create - drm_mode_duplicate - drm_mode_probed_add - drm_mode_set_name - drm_mode_vrefresh - drm_panel_add - drm_panel_disable - drm_panel_init - drm_panel_remove - drm_panel_unprepare - dump_stack - enable_irq - eth_commit_mac_addr_change - eth_mac_addr - eth_platform_get_mac_address - eth_prepare_mac_addr_change - eth_type_trans - eth_validate_addr - ether_setup - ethtool_op_get_ts_info - event_triggers_call - extcon_get_edev_by_phandle - extcon_get_property - extcon_get_state - extcon_set_state_sync - failure_tracking - fasync_helper - find_next_bit - find_next_zero_bit - find_vma - finish_wait - flush_dcache_page - flush_work - flush_workqueue - fpsimd_context_busy - fput - free_irq - free_netdev - free_pages - free_pages_exact - free_percpu - freezing_slow_path - fsync_bdev - full_name_hash - fwnode_device_is_available - fwnode_get_name - fwnode_graph_get_next_endpoint - fwnode_graph_get_port_parent - fwnode_graph_get_remote_endpoint - fwnode_graph_get_remote_port_parent - fwnode_graph_parse_endpoint - fwnode_handle_put - fwnode_property_get_reference_args - fwnode_property_present - fwnode_property_read_string - fwnode_property_read_u32_array - fwnode_property_read_u64_array - gcd - gen_pool_add_owner - gen_pool_alloc_algo_owner - gen_pool_best_fit - gen_pool_create - gen_pool_destroy - gen_pool_dma_alloc_align - gen_pool_dma_zalloc_align - gen_pool_free_owner - gen_pool_set_algo - gen_pool_virt_to_phys - generic_mii_ioctl - genphy_resume - get_cpu_device - get_cpu_idle_time_us - get_device - get_kernel_pages - get_random_bytes - get_random_u32 - get_sg_io_hdr - get_zeroed_page - gf128mul_lle - gic_nonsecure_priorities - glob_match - gpio_to_desc - gpiochip_add_pin_range - gpiochip_generic_free - gpiochip_generic_request - gpiochip_get_data - gpiod_count - gpiod_direction_output - gpiod_get_optional - gpiod_get_value - gpiod_get_value_cansleep - gpiod_set_consumer_name - gpiod_set_value - gpiod_set_value_cansleep - hdmi_audio_infoframe_init - hdmi_audio_infoframe_pack - hdmi_avi_infoframe_pack - hex_asc_upper - hid_add_device - hid_allocate_device - hid_debug - hid_destroy_device - hid_input_report - hid_parse_report - hrtimer_cancel - hrtimer_init - hrtimer_start_range_ns - hwrng_register - hwrng_unregister - i2c_adapter_type - i2c_add_adapter - i2c_add_numbered_adapter - i2c_bus_type - i2c_del_adapter - i2c_del_driver - i2c_for_each_dev - i2c_get_adapter - i2c_parse_fw_timings - i2c_put_adapter - i2c_register_driver - i2c_smbus_read_byte - i2c_smbus_read_byte_data - i2c_smbus_xfer - i2c_transfer - i2c_transfer_buffer_flags - i2c_verify_client - ida_alloc_range - ida_destroy - ida_free - idr_alloc - idr_destroy - idr_find - idr_for_each - idr_get_next - idr_preload - idr_remove - iio_alloc_pollfunc - iio_buffer_init - iio_buffer_put - iio_channel_get_all - iio_dealloc_pollfunc - iio_device_attach_buffer - iio_get_channel_type - iio_get_time_ns - iio_push_to_buffers - iio_read_channel_processed - iio_trigger_notify_done - import_iovec - in4_pton - in6_pton - in_egroup_p - inc_zone_page_state - init_net - init_pseudo - init_srcu_struct - init_timer_key - init_uts_ns - init_wait_entry - input_alloc_absinfo - input_allocate_device - input_event - input_free_device - input_mt_init_slots - input_mt_report_slot_state - input_mt_sync_frame - input_register_device - input_set_abs_params - input_set_capability - input_unregister_device - iounmap - iput - ipv6_stub - irq_get_irq_data - irq_set_irq_wake - irq_stat - is_vmalloc_addr - jiffies - jiffies_to_msecs - kasan_flag_enabled - kasprintf - kern_mount - kern_unmount - kernel_neon_begin - kernel_neon_end - kernel_sendmsg - kernel_sigaction - key_put - keyring_alloc - kfree - kfree_const - kfree_sensitive - kfree_skb - kill_anon_super - kill_fasync - kimage_voffset - kmalloc_caches - kmalloc_order_trace - kmem_cache_alloc - kmem_cache_alloc_trace - kmem_cache_create - kmem_cache_create_usercopy - kmem_cache_destroy - kmem_cache_free - kmemdup - kobject_get - kobject_put - kobject_uevent_env - kstrdup - kstrdup_const - kstrndup - kstrtobool - kstrtobool_from_user - kstrtoint - kstrtoll - kstrtou16 - kstrtou8 - kstrtouint - kstrtoull - kthread_cancel_delayed_work_sync - kthread_create_on_node - kthread_create_worker - kthread_delayed_work_timer_fn - kthread_destroy_worker - kthread_mod_delayed_work - kthread_queue_delayed_work - ktime_get - ktime_get_coarse_real_ts64 - ktime_get_mono_fast_ns - ktime_get_real_ts64 - ktime_get_snapshot - ktime_get_with_offset - kvfree - kvmalloc_node - led_classdev_register_ext - led_classdev_unregister - list_sort - lock_sock_nested - lockref_get - loops_per_jiffy - lzo1x_1_compress - lzo1x_decompress_safe - lzorle1x_1_compress - match_int - match_token - mdiobus_alloc_size - mdiobus_free - mdiobus_get_phy - mdiobus_read - mdiobus_unregister - mdiobus_write - media_entity_pads_init - memchr - memchr_inv - memcpy - memdup_user - memmove - memparse - mempool_alloc - mempool_alloc_slab - mempool_create - mempool_create_node - mempool_destroy - mempool_free - mempool_free_slab - mempool_kfree - mempool_kmalloc - memremap - memset - memset64 - memstart_addr - memunmap - mii_check_media - mii_ethtool_get_link_ksettings - mii_ethtool_gset - mii_ethtool_set_link_ksettings - mii_link_ok - mii_nway_restart - mipi_dsi_attach - mipi_dsi_detach - mipi_dsi_driver_register_full - mipi_dsi_driver_unregister - mktime64 - mmc_add_host - mmc_alloc_host - mmc_can_gpio_cd - mmc_cqe_request_done - mmc_detect_change - mmc_free_host - mmc_gpio_get_cd - mmc_gpio_get_ro - mmc_of_parse - mmc_regulator_get_supply - mmc_regulator_set_ocr - mmc_regulator_set_vqmmc - mmc_remove_host - mmc_request_done - mmc_send_tuning - mod_delayed_work_on - mod_timer - module_layout - module_put - msleep - msleep_interruptible - mutex_is_locked - mutex_lock - mutex_lock_interruptible - mutex_unlock - n_tty_ioctl_helper - napi_complete_done - napi_disable - napi_gro_receive - napi_schedule_prep - net_ratelimit - netdev_alert - netdev_err - netdev_info - netdev_pick_tx - netdev_update_features - netdev_upper_dev_link - netdev_upper_dev_unlink - netdev_warn - netif_carrier_off - netif_carrier_on - netif_device_attach - netif_device_detach - netif_napi_add - netif_rx - netif_rx_ni - netif_schedule_queue - netif_set_real_num_rx_queues - netif_set_real_num_tx_queues - netif_stacked_transfer_operstate - netif_tx_stop_all_queues - netif_tx_wake_queue - new_inode - no_llseek - nonseekable_open - noop_llseek - nr_cpu_ids - ns_to_timespec64 - of_alias_get_id - of_clk_add_hw_provider - of_clk_add_provider - of_clk_del_provider - of_clk_get - of_clk_get_by_name - of_clk_hw_onecell_get - of_clk_hw_simple_get - of_clk_src_simple_get - of_count_phandle_with_args - of_device_get_match_data - of_device_is_available - of_device_is_compatible - of_dma_controller_free - of_dma_controller_register - of_find_device_by_node - of_find_i2c_adapter_by_node - of_find_property - of_get_child_by_name - of_get_compatible_child - of_get_mac_address - of_get_named_gpio_flags - of_get_next_available_child - of_get_next_child - of_get_parent - of_get_property - of_get_regulator_init_data - of_graph_parse_endpoint - of_irq_get_byname - of_machine_is_compatible - of_match_device - of_match_node - of_mdiobus_register - of_node_name_eq - of_parse_phandle - of_parse_phandle_with_args - of_phy_is_fixed_link - of_phy_simple_xlate - of_platform_device_create - of_property_count_elems_of_size - of_property_read_string - of_property_read_string_helper - of_property_read_u32_index - of_property_read_variable_u16_array - of_property_read_variable_u32_array - of_property_read_variable_u8_array - of_pwm_xlate_with_flags - page_endio - page_mapping - panic_notifier_list - param_array_ops - param_get_int - param_get_uint - param_ops_bool - param_ops_byte - param_ops_charp - param_ops_int - param_ops_string - param_ops_uint - param_ops_ulong - param_ops_ushort - param_set_uint - pci_alloc_irq_vectors_affinity - pci_device_is_present - pci_disable_device - pci_disable_pcie_error_reporting - pci_enable_device_mem - pci_enable_pcie_error_reporting - pci_free_irq - pci_free_irq_vectors - pci_intx - pci_irq_vector - pci_load_saved_state - pci_match_id - pci_read_config_byte - pci_read_config_dword - pci_read_config_word - pci_release_selected_regions - pci_request_irq - pci_request_selected_regions - pci_restore_state - pci_save_state - pci_select_bars - pci_set_master - pci_set_power_state - pci_unregister_driver - pci_write_config_dword - pci_write_config_word - pcibios_resource_to_bus - pcie_aspm_enabled - pcim_enable_device - perf_trace_buf_alloc - perf_trace_run_bpf_submit - pfn_valid - phy_attached_info - phy_disconnect - phy_ethtool_get_link_ksettings - phy_ethtool_nway_reset - phy_ethtool_set_link_ksettings - phy_exit - phy_init - phy_init_eee - phy_mii_ioctl - phy_power_off - phy_power_on - phy_print_status - phy_reset - phy_set_mode_ext - phy_start - phy_stop - phylink_connect_phy - phylink_create - phylink_destroy - phylink_of_phy_connect - phylink_set_port_modes - pin_user_pages_fast - pinconf_generic_dt_node_to_map - pinctrl_dev_get_drvdata - pinctrl_gpio_direction_input - pinctrl_gpio_direction_output - pinctrl_pm_select_default_state - pinctrl_pm_select_sleep_state - pinctrl_utils_free_map - platform_device_put - platform_device_register_full - platform_driver_unregister - platform_get_irq - platform_get_irq_byname - platform_get_irq_byname_optional - platform_get_irq_optional - platform_get_resource - platform_get_resource_byname - pm_power_off - pm_runtime_enable - pm_runtime_forbid - pm_runtime_force_resume - pm_runtime_force_suspend - pm_runtime_get_if_active - pm_runtime_irq_safe - pm_runtime_set_autosuspend_delay - pm_suspend_global_flags - pm_wakeup_dev_event - policy_has_boost_freq - posix_clock_register - posix_clock_unregister - power_supply_changed - power_supply_get_drvdata - power_supply_register - power_supply_unregister - preempt_schedule - preempt_schedule_notrace - prepare_to_wait - prepare_to_wait_event - print_hex_dump - printk - proc_create - proc_create_single_data - proc_mkdir - proto_register - proto_unregister - pskb_expand_head - put_device - put_disk - put_sg_io_hdr - pwm_apply_state - pwmchip_add - pwmchip_remove - queue_delayed_work_on - queue_work_on - rational_best_approximation - rb_erase - rb_first - rb_insert_color - rb_next - rcu_barrier - rdev_get_drvdata - rdev_get_id - read_cache_page - refcount_warn_saturate - regcache_cache_only - regcache_mark_dirty - regcache_sync - register_blkdev - register_chrdev_region - register_filesystem - register_netdev - register_netdevice - register_netdevice_notifier - register_pernet_device - register_pernet_subsys - register_reboot_notifier - register_shrinker - regmap_add_irq_chip - regmap_bulk_read - regmap_bulk_write - regmap_del_irq_chip - regmap_field_read - regmap_field_update_bits_base - regmap_irq_get_domain - regmap_multi_reg_write - regmap_raw_read - regmap_raw_write - regmap_read - regmap_update_bits_base - regmap_write - regulator_bulk_disable - regulator_bulk_enable - regulator_disable - regulator_disable_regmap - regulator_enable - regulator_enable_regmap - regulator_get - regulator_get_voltage - regulator_get_voltage_sel_regmap - regulator_is_enabled - regulator_is_enabled_regmap - regulator_list_voltage_linear - regulator_list_voltage_linear_range - regulator_map_voltage_iterate - regulator_map_voltage_linear - regulator_map_voltage_linear_range - regulator_put - regulator_register_notifier - regulator_set_active_discharge_regmap - regulator_set_voltage_sel_regmap - regulator_set_voltage_time_sel - regulator_unregister_notifier - release_firmware - release_sock - remap_pfn_range - remove_proc_entry - remove_wait_queue - request_firmware - request_threaded_irq - reset_control_assert - reset_control_deassert - reset_control_put - reset_control_reset - revalidate_disk_size - rfkill_alloc - rfkill_destroy - rfkill_register - rfkill_unregister - round_jiffies_relative - rt_mutex_lock - rt_mutex_trylock - rt_mutex_unlock - rtc_time64_to_tm - rtc_tm_to_time64 - rtc_update_irq - rtnl_lock - rtnl_trylock - rtnl_unlock - sb800_prefetch - scatterwalk_map_and_copy - schedule - schedule_timeout - schedule_timeout_interruptible - schedule_timeout_uninterruptible - scmi_driver_register - scmi_driver_unregister - scnprintf - scsi_add_host_with_dma - scsi_autopm_get_device - scsi_autopm_put_device - scsi_block_when_processing_errors - scsi_command_size_tbl - scsi_compat_ioctl - scsi_device_get - scsi_device_lookup - scsi_device_put - scsi_host_put - scsi_ioctl - scsi_ioctl_block_when_processing_errors - scsi_normalize_sense - scsi_print_sense_hdr - scsi_remove_device - scsi_remove_host - sdev_prefix_printk - sdhci_add_host - sdhci_cleanup_host - sdhci_cqe_disable - sdhci_cqe_enable - sdhci_cqe_irq - sdhci_enable_clk - sdhci_get_property - sdhci_pltfm_free - sdhci_pltfm_init - sdhci_remove_host - sdhci_reset - sdhci_set_bus_width - sdhci_setup_host - sdio_signal_irq - send_sig - seq_lseek - seq_printf - seq_putc - seq_puts - seq_read - set_capacity_revalidate_and_notify - set_disk_ro - set_freezable - set_page_dirty - set_user_nice - sg_alloc_table - sg_alloc_table_from_pages - sg_copy_from_buffer - sg_copy_to_buffer - sg_free_table - sg_init_one - sg_init_table - sg_miter_next - sg_miter_start - sg_miter_stop - sg_next - sg_pcopy_from_buffer - sg_pcopy_to_buffer - sg_scsi_ioctl - sigprocmask - simple_dir_operations - simple_read_from_buffer - simple_strtoul - single_open - single_release - sk_alloc - sk_free - skb_add_rx_frag - skb_clone - skb_copy_bits - skb_copy_datagram_iter - skb_copy_expand - skb_dequeue - skb_pull - skb_pull_rcsum - skb_push - skb_put - skb_queue_purge - skb_queue_tail - skb_recv_datagram - skb_trim - skb_tstamp_tx - skcipher_walk_aead_decrypt - skcipher_walk_aead_encrypt - skcipher_walk_done - snd_ctl_add - snd_ctl_new1 - snd_pcm_add_chmap_ctls - snd_pcm_create_iec958_consumer_hw_params - snd_pcm_format_width - snd_pcm_hw_constraint_eld - snd_pcm_hw_constraint_list - snd_soc_card_jack_new - snd_soc_component_update_bits - snd_soc_component_write - snd_soc_dai_link_set_capabilities - snd_soc_dai_set_sysclk - snd_soc_dai_set_tdm_slot - snd_soc_dapm_add_routes - snd_soc_dapm_disable_pin_unlocked - snd_soc_dapm_force_enable_pin_unlocked - snd_soc_dapm_get_enum_double - snd_soc_dapm_get_pin_switch - snd_soc_dapm_get_volsw - snd_soc_dapm_info_pin_switch - snd_soc_dapm_put_enum_double - snd_soc_dapm_put_pin_switch - snd_soc_dapm_put_volsw - snd_soc_dapm_sync_unlocked - snd_soc_get_enum_double - snd_soc_get_volsw - snd_soc_info_enum_double - snd_soc_info_volsw - snd_soc_jack_add_gpios - snd_soc_jack_report - snd_soc_of_get_dai_name - snd_soc_of_parse_audio_routing - snd_soc_of_parse_audio_simple_widgets - snd_soc_of_parse_aux_devs - snd_soc_of_parse_card_name - snd_soc_of_parse_daifmt - snd_soc_of_parse_node_prefix - snd_soc_of_parse_tdm_slot - snd_soc_params_to_frame_size - snd_soc_pm_ops - snd_soc_put_enum_double - snd_soc_put_volsw - snd_soc_runtime_calc_hw - snprintf - sock_init_data - sock_no_accept - sock_no_listen - sock_no_mmap - sock_no_shutdown - sock_no_socketpair - sock_queue_rcv_skb - sock_release - sort - spi_controller_resume - spi_controller_suspend - spi_finalize_current_transfer - spi_setup - spi_sync - sprintf - sscanf - stpcpy - strcasecmp - strchr - strcmp - strcpy - strcspn - stream_open - strim - strlcat - strlcpy - strlen - strncasecmp - strnchr - strncmp - strncpy - strnlen - strpbrk - strscpy - strsep - strspn - synchronize_irq - synchronize_net - synchronize_rcu - synchronize_srcu - sys_tz - syscon_node_to_regmap - syscon_regmap_lookup_by_phandle - sysfs_add_file_to_group - sysfs_create_group - sysfs_create_link - sysfs_remove_file_from_group - sysfs_remove_group - sysfs_remove_link - sysfs_streq - system_freezing_cnt - system_long_wq - system_state - system_wq - tasklet_init - tasklet_kill - tasklet_setup - thermal_zone_device_disable - thermal_zone_device_enable - thermal_zone_device_update - time64_to_tm - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return - trace_print_symbols_seq - trace_raw_output_prep - trace_seq_printf - trace_seq_putc - try_module_get - try_wait_for_completion - tty_flip_buffer_push - tty_hangup - tty_insert_flip_string_fixed_flag - tty_kref_put - tty_mode_ioctl - tty_port_tty_get - tty_register_ldisc - tty_termios_baud_rate - tty_termios_encode_baud_rate - tty_unregister_ldisc - unlock_page - unpin_user_pages - unregister_blkdev - unregister_chrdev_region - unregister_filesystem - unregister_netdev - unregister_netdevice_many - unregister_netdevice_notifier - unregister_netdevice_queue - unregister_pernet_device - unregister_pernet_subsys - unregister_reboot_notifier - unregister_shrinker - up - up_read - up_write - usb_add_gadget_udc - usb_add_hcd - usb_alloc_coherent - usb_alloc_urb - usb_amd_dev_put - usb_amd_quirk_pll_disable - usb_amd_quirk_pll_enable - usb_anchor_urb - usb_bulk_msg - usb_calc_bus_time - usb_control_msg - usb_create_hcd - usb_debug_root - usb_del_gadget_udc - usb_deregister - usb_disabled - usb_ep_set_maxpacket_limit - usb_find_common_endpoints - usb_free_coherent - usb_free_urb - usb_gadget_giveback_request - usb_gadget_map_request - usb_gadget_set_state - usb_gadget_unmap_request - usb_get_dr_mode - usb_hc_died - usb_hcd_check_unlink_urb - usb_hcd_giveback_urb - usb_hcd_link_urb_to_ep - usb_hcd_map_urb_for_dma - usb_hcd_platform_shutdown - usb_hcd_poll_rh_status - usb_hcd_resume_root_hub - usb_hcd_unlink_urb_from_ep - usb_hcds_loaded - usb_hub_clear_tt_buffer - usb_ifnum_to_if - usb_kill_anchored_urbs - usb_kill_urb - usb_phy_set_charger_current - usb_poison_urb - usb_put_dev - usb_put_hcd - usb_register_driver - usb_remove_hcd - usb_role_switch_get_drvdata - usb_role_switch_register - usb_role_switch_unregister - usb_root_hub_lost_power - usb_speed_string - usb_submit_urb - usb_unanchor_urb - usbnet_change_mtu - usbnet_disconnect - usbnet_get_drvinfo - usbnet_get_endpoints - usbnet_get_link - usbnet_get_link_ksettings - usbnet_get_msglevel - usbnet_get_stats64 - usbnet_link_change - usbnet_nway_reset - usbnet_open - usbnet_probe - usbnet_read_cmd - usbnet_read_cmd_nopm - usbnet_resume - usbnet_set_link_ksettings - usbnet_set_msglevel - usbnet_skb_return - usbnet_start_xmit - usbnet_stop - usbnet_suspend - usbnet_tx_timeout - usbnet_write_cmd - usbnet_write_cmd_async - usbnet_write_cmd_nopm - usleep_range - utf16s_to_utf8s - uuid_null - v4l2_async_notifier_add_fwnode_subdev - v4l2_async_notifier_add_subdev - v4l2_async_notifier_cleanup - v4l2_async_notifier_init - v4l2_async_notifier_unregister - v4l2_async_register_subdev - v4l2_async_subdev_notifier_register - v4l2_async_unregister_subdev - v4l2_ctrl_auto_cluster - v4l2_ctrl_handler_free - v4l2_ctrl_handler_init_class - v4l2_ctrl_handler_setup - v4l2_ctrl_new_std - v4l2_ctrl_new_std_menu - v4l2_ctrl_new_std_menu_items - v4l2_i2c_subdev_init - vabits_actual - vfree - vmalloc - vmalloc_to_page - vmap - vscnprintf - vunmap - vzalloc - wait_for_completion - wait_for_completion_interruptible - wait_for_completion_io_timeout - wait_for_completion_killable - wait_for_completion_timeout - wait_woken - wake_up_process - watchdog_init_timeout - watchdog_register_device - watchdog_set_restart_priority - watchdog_unregister_device - woken_wake_function - xa_destroy - xa_erase - xa_find - xa_find_after - xa_load - xa_store diff --git a/android/abi_gki_aarch64_virtual_device b/android/abi_gki_aarch64_virtual_device deleted file mode 100644 index 724632832596..000000000000 --- a/android/abi_gki_aarch64_virtual_device +++ /dev/null @@ -1,1314 +0,0 @@ -[abi_symbol_list] -# commonly used symbols - alloc_anon_inode - __alloc_disk_node - alloc_etherdev_mqs - __alloc_pages_nodemask - __alloc_skb - alloc_workqueue - amba_driver_register - amba_driver_unregister - __arch_copy_from_user - __arch_copy_to_user - arm64_const_caps_ready - arm64_use_ng_mappings - bcmp - bio_alloc_bioset - bio_endio - blk_alloc_queue - blk_cleanup_queue - blk_queue_flag_clear - blk_queue_flag_set - blk_queue_io_min - blk_queue_io_opt - blk_queue_logical_block_size - blk_queue_max_discard_sectors - blk_queue_max_write_zeroes_sectors - blk_queue_physical_block_size - blk_queue_write_cache - blk_status_to_errno - bpf_trace_run2 - bpf_trace_run3 - bus_register - bus_unregister - cancel_delayed_work_sync - cancel_work_sync - capable - __cfi_slowpath - __check_object_size - __class_create - class_destroy - __ClearPageMovable - clk_disable - clk_enable - clk_get_rate - clk_prepare - clk_unprepare - complete - __const_udelay - consume_skb - contig_page_data - __cpuhp_remove_state - __cpuhp_setup_state - __cpuhp_state_add_instance - __cpuhp_state_remove_instance - cpu_hwcap_keys - cpu_hwcaps - cpumask_next - cpu_number - __cpu_online_mask - __cpu_possible_mask - crypto_register_alg - crypto_register_scomp - crypto_unregister_alg - crypto_unregister_scomp - _ctype - debugfs_create_dir - debugfs_create_file - debugfs_remove - delayed_work_timer_fn - del_gendisk - del_timer - del_timer_sync - destroy_workqueue - _dev_err - device_add_disk - device_create - device_initialize - device_register - device_release_driver - device_unregister - _dev_info - __dev_kfree_skb_any - devm_ioremap - devm_ioremap_resource - devm_kfree - devm_kmalloc - devm_request_threaded_irq - _dev_notice - dev_queue_xmit - dev_set_name - _dev_warn - dma_alloc_attrs - dma_buf_export - dma_fence_context_alloc - dma_fence_init - dma_fence_release - dma_fence_signal_locked - dma_free_attrs - dma_map_sg_attrs - dma_set_coherent_mask - dma_set_mask - dma_sync_sg_for_device - dma_unmap_sg_attrs - down_read - down_write - ether_setup - ethtool_op_get_link - eth_validate_addr - event_triggers_call - failure_tracking - fd_install - finish_wait - flush_work - flush_workqueue - fput - free_irq - free_netdev - __free_pages - free_pages - fs_bio_set - get_device - __get_free_pages - get_random_bytes - get_unused_fd_flags - gic_nonsecure_priorities - hwrng_register - hwrng_unregister - ida_alloc_range - ida_free - idr_alloc - idr_destroy - idr_remove - init_pseudo - __init_rwsem - __init_swait_queue_head - init_timer_key - init_wait_entry - __init_waitqueue_head - input_alloc_absinfo - input_allocate_device - input_event - input_free_device - input_mt_init_slots - input_register_device - input_set_abs_params - input_unregister_device - __ioremap - iounmap - iput - jiffies - jiffies_to_msecs - kasan_flag_enabled - kern_mount - kern_unmount - kfree - kfree_skb - kill_anon_super - kimage_voffset - __kmalloc - kmalloc_caches - kmem_cache_alloc - kmem_cache_alloc_trace - kmem_cache_create - kmem_cache_destroy - kmem_cache_free - kmemdup - kobject_add - kobject_init - kobject_put - kobject_uevent - krealloc - kstrdup - kstrndup - kstrtobool - kstrtoint - kstrtouint - kstrtoull - ktime_get - ktime_get_mono_fast_ns - ktime_get_raw_ts64 - ktime_get_real_seconds - ktime_get_real_ts64 - ktime_get_ts64 - ktime_get_with_offset - kvfree - kvmalloc_node - __list_add_valid - __list_del_entry_valid - __local_bh_enable_ip - __log_post_read_mmio - __log_read_mmio - __log_write_mmio - lzo1x_decompress_safe - memcpy - memmove - memparse - memremap - memset - memstart_addr - memunmap - misc_deregister - misc_register - mod_timer - module_layout - module_put - __msecs_to_jiffies - msleep - __mutex_init - mutex_lock - mutex_lock_interruptible - mutex_trylock - mutex_unlock - netdev_err - netdev_info - netdev_rx_handler_register - netdev_rx_handler_unregister - netdev_upper_dev_unlink - netif_carrier_off - netif_carrier_on - netif_device_detach - netif_tx_stop_all_queues - netif_tx_wake_queue - nf_conntrack_destroy - no_llseek - nonseekable_open - noop_llseek - nr_cpu_ids - __num_online_cpus - of_find_property - of_get_property - of_property_read_variable_u32_array - __page_pinner_migration_failed - param_ops_bint - param_ops_bool - param_ops_charp - param_ops_int - param_ops_uint - passthru_features_check - pci_disable_device - pci_enable_device - pci_iomap - pci_read_config_byte - pci_read_config_dword - pci_read_config_word - __pci_register_driver - pci_release_region - pci_release_regions - pci_request_region - pci_request_regions - pci_set_master - pci_unregister_driver - pci_write_config_dword - __per_cpu_offset - perf_trace_buf_alloc - perf_trace_run_bpf_submit - platform_device_unregister - __platform_driver_register - platform_driver_unregister - platform_get_irq - platform_get_resource - pm_runtime_allow - __pm_runtime_disable - pm_runtime_enable - pm_runtime_force_resume - pm_runtime_force_suspend - __pm_runtime_idle - __pm_runtime_resume - pm_runtime_set_autosuspend_delay - __pm_runtime_suspend - __pm_runtime_use_autosuspend - preempt_schedule - preempt_schedule_notrace - prepare_to_wait - prepare_to_wait_event - printk - put_device - put_disk - __put_page - __put_task_struct - put_unused_fd - queue_delayed_work_on - queue_work_on - ___ratelimit - _raw_spin_lock - _raw_spin_lock_bh - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_unlock - _raw_spin_unlock_bh - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - __rcu_read_lock - __rcu_read_unlock - refcount_warn_saturate - register_blkdev - register_netdev - register_netdevice - register_netdevice_notifier - register_shrinker - register_virtio_device - register_virtio_driver - regmap_exit - __regmap_init - regmap_read - regmap_write - remap_pfn_range - __request_module - request_threaded_irq - revalidate_disk_size - rtnl_lock - rtnl_unlock - schedule - schedule_timeout - schedule_timeout_uninterruptible - scnprintf - seq_lseek - seq_open - seq_printf - seq_read - seq_release - serio_close - serio_interrupt - serio_open - serio_reconnect - __serio_register_driver - __serio_register_port - serio_unregister_driver - set_disk_ro - __SetPageMovable - sg_alloc_table - sg_free_table - sg_init_one - sg_init_table - sg_next - simple_strtoul - skb_add_rx_frag - skb_dequeue - skb_push - skb_put - skb_queue_tail - snd_card_disconnect - snd_card_free - snd_card_new - snd_card_register - snd_card_rw_proc_new - snd_component_add - snd_ctl_add - _snd_ctl_add_follower - snd_ctl_boolean_mono_info - snd_ctl_enum_info - snd_ctl_find_id - snd_ctl_make_virtual_master - snd_ctl_new1 - snd_ctl_sync_vmaster - snd_device_new - snd_dma_alloc_pages - snd_dma_free_pages - snd_pci_quirk_lookup - snd_pcm_add_chmap_ctls - snd_pcm_alt_chmaps - snd_pcm_hw_constraint_integer - snd_pcm_hw_limit_rates - snd_pcm_new - snd_pcm_period_elapsed - snd_pcm_set_managed_buffer_all - snd_pcm_set_ops - snd_pcm_std_chmaps - snprintf - sort - sprintf - __stack_chk_fail - __stack_chk_guard - strcmp - strcpy - strlcpy - strlen - strncmp - strncpy - strsep - submit_bio - sync_file_create - synchronize_rcu - sysfs_create_group - __sysfs_match_string - sysfs_remove_group - sysfs_remove_link - system_wq - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return - __traceiter_rwmmio_post_read - __traceiter_rwmmio_read - __traceiter_rwmmio_write - __tracepoint_rwmmio_post_read - __tracepoint_rwmmio_read - __tracepoint_rwmmio_write - trace_raw_output_prep - trace_seq_printf - try_module_get - __udelay - unlock_page - unregister_blkdev - unregister_netdev - unregister_netdevice_notifier - unregister_netdevice_queue - unregister_shrinker - unregister_virtio_device - unregister_virtio_driver - up_read - up_write - __usecs_to_jiffies - usleep_range - vabits_actual - vfree - virtio_check_driver_offered_feature - virtio_config_changed - virtqueue_add_inbuf - virtqueue_add_outbuf - virtqueue_add_sgs - virtqueue_detach_unused_buf - virtqueue_disable_cb - virtqueue_enable_cb - virtqueue_get_avail_addr - virtqueue_get_buf - virtqueue_get_desc_addr - virtqueue_get_used_addr - virtqueue_get_vring_size - virtqueue_is_broken - virtqueue_kick - virtqueue_kick_prepare - virtqueue_notify - vring_create_virtqueue - vring_del_virtqueue - vring_interrupt - vring_transport_features - wait_for_completion - __wake_up - __warn_printk - -# required by ambakmi.ko - amba_release_regions - amba_request_regions - clk_get - clk_put - serio_unregister_port - -# required by armmmci.ko - clk_round_rate - clk_set_rate - devm_clk_get - devm_of_iomap - devm_pinctrl_get - __devm_reset_control_get - dmam_alloc_attrs - dma_release_channel - dma_request_chan - mmc_add_host - mmc_alloc_host - mmc_free_host - mmc_gpiod_request_cd - mmc_gpiod_request_ro - mmc_gpio_get_cd - mmc_gpio_get_ro - mmc_of_parse - mmc_regulator_get_supply - mmc_regulator_set_ocr - mmc_regulator_set_vqmmc - mmc_remove_host - mmc_request_done - mmc_send_tuning - pinctrl_lookup_state - pinctrl_pm_select_sleep_state - pinctrl_select_default_state - pinctrl_select_state - regulator_disable - regulator_enable - reset_control_assert - reset_control_deassert - sg_miter_next - sg_miter_start - sg_miter_stop - -# required by clk-vexpress-osc.ko - clk_hw_set_rate_range - devm_clk_hw_register - devm_of_clk_add_hw_provider - of_clk_hw_simple_get - of_property_read_string - -# required by dummy-cpufreq.ko - cpufreq_generic_attr - cpufreq_register_driver - cpufreq_unregister_driver - -# required by failover.ko - netdev_master_upper_dev_link - rtnl_is_locked - -# required by gnss-cmdline.ko - bus_find_device - device_find_child - device_match_name - platform_bus_type - strstr - -# required by gnss-serial.ko - gnss_allocate_device - gnss_deregister_device - gnss_insert_raw - gnss_put_device - gnss_register_device - serdev_device_close - serdev_device_open - serdev_device_set_baudrate - serdev_device_set_flow_control - serdev_device_wait_until_sent - serdev_device_write - serdev_device_write_wakeup - -# required by goldfish_battery.ko - power_supply_changed - power_supply_get_drvdata - power_supply_register - power_supply_unregister - -# required by goldfish_pipe.ko - get_user_pages_fast - set_page_dirty - tasklet_init - tasklet_kill - __tasklet_schedule - -# required by goldfish_sync.ko - __close_fd - dma_fence_default_wait - dma_fence_free - -# required by hci_vhci.ko - bt_err - _copy_from_iter_full - hci_alloc_dev - hci_free_dev - hci_recv_frame - hci_register_dev - hci_unregister_dev - skb_pull - skb_queue_head - skb_queue_purge - -# required by ledtrig-audio.ko - led_trigger_event - led_trigger_register_simple - led_trigger_unregister_simple - -# required by lzo-rle.ko - lzorle1x_1_compress - -# required by lzo.ko - lzo1x_1_compress - -# required by mac80211_hwsim.ko - alloc_netdev_mqs - debugfs_attr_read - debugfs_attr_write - dev_alloc_name - device_bind_driver - dst_release - eth_mac_addr - genlmsg_put - genl_notify - genl_register_family - genl_unregister_family - hrtimer_cancel - hrtimer_forward - hrtimer_init - hrtimer_start_range_ns - init_net - __netdev_alloc_skb - netif_rx - netlink_broadcast - netlink_register_notifier - netlink_unicast - netlink_unregister_notifier - net_namespace_list - nla_memcpy - __nla_parse - nla_put_64bit - nla_put - param_ops_ushort - register_pernet_device - rhashtable_destroy - rhashtable_init - rhashtable_insert_slow - __rht_bucket_nested - rht_bucket_nested - rht_bucket_nested_insert - schedule_timeout_interruptible - simple_attr_open - simple_attr_release - skb_copy - skb_copy_expand - __skb_ext_put - skb_trim - skb_unlink - unregister_pernet_device - -# required by md-mod.ko - ack_all_badblocks - alloc_page_buffers - _atomic_dec_and_lock - autoremove_wake_function - badblocks_clear - badblocks_exit - badblocks_init - badblocks_set - badblocks_show - badblocks_store - bdev_check_media_change - bdevname - bdev_read_only - bd_link_disk_holder - bd_unlink_disk_holder - bio_add_page - bio_associate_blkg - bio_put - bioset_exit - bioset_init - blkdev_get_by_dev - blkdev_put - blk_finish_plug - blk_queue_split - blk_register_region - blk_set_stacking_limits - blk_start_plug - blk_sync_queue - blk_unregister_region - bmap - fget - file_path - flush_signals - free_buffer_head - int_pow - invalidate_bdev - invalidate_mapping_pages - kernel_sigaction - kernfs_find_and_get_ns - kernfs_notify - kernfs_put - kobject_del - kobject_get - kstrtoll - kthread_create_on_node - kthread_parkme - kthread_should_park - kthread_should_stop - kthread_stop - mempool_alloc - mempool_create - mempool_destroy - mempool_exit - mempool_free - mempool_init - mempool_kfree - mempool_kmalloc - part_end_io_acct - part_start_io_acct - percpu_ref_exit - percpu_ref_init - percpu_ref_is_zero - percpu_ref_switch_to_atomic_sync - percpu_ref_switch_to_percpu - proc_create - proc_dointvec - register_reboot_notifier - register_sysctl_table - remove_proc_entry - seq_file_path - skip_spaces - strreplace - submit_bh - submit_bio_wait - sync_blockdev - sysfs_create_link - unregister_reboot_notifier - unregister_sysctl_table - vfs_fsync - wake_up_process - -# required by nd_virtio.ko - bio_chain - bio_clone_blkg_association - -# required by net_failover.ko - call_netdevice_notifiers - dev_close - dev_get_stats - dev_mc_sync_multiple - dev_mc_unsync - dev_open - dev_set_mtu - dev_uc_sync_multiple - dev_uc_unsync - __ethtool_get_link_ksettings - netdev_change_features - netdev_increment_features - netdev_lower_state_changed - netdev_pick_tx - pci_bus_type - -# required by psmouse.ko - bus_register_notifier - bus_unregister_notifier - device_add_groups - device_create_file - device_remove_file - device_remove_groups - i2c_adapter_type - i2c_bus_type - i2c_client_type - i2c_for_each_dev - i2c_new_scanned_device - i2c_unregister_device - i2c_verify_adapter - input_mt_assign_slots - input_mt_drop_unused - input_mt_report_finger_count - input_mt_report_pointer_emulation - input_mt_report_slot_state - input_mt_sync_frame - input_set_capability - kstrtou8 - pm_wakeup_dev_event - ps2_begin_command - ps2_cmd_aborted - ps2_command - ps2_drain - ps2_end_command - ps2_handle_ack - ps2_handle_response - ps2_init - ps2_sendbyte - ps2_sliced_command - serio_rescan - serio_unregister_child_port - strcasecmp - -# required by pulse8-cec.ko - cec_allocate_adapter - cec_delete_adapter - cec_received_msg_ts - cec_register_adapter - cec_s_log_addrs - cec_s_phys_addr - cec_transmit_attempt_done_ts - cec_unregister_adapter - strscpy - wait_for_completion_timeout - -# required by rtc-test.ko - add_timer - device_init_wakeup - devm_rtc_allocate_device - platform_device_add - platform_device_alloc - platform_device_del - platform_device_put - __rtc_register_device - rtc_time64_to_tm - rtc_tm_to_time64 - rtc_update_irq - -# required by snd-ac97-codec.ko - snd_ctl_remove_id - snd_info_create_card_entry - snd_info_free_entry - snd_interval_refine - snd_pcm_hw_rule_add - strcat - -# required by snd-hda-codec-generic.ko - devm_led_classdev_register_ext - snd_ctl_boolean_stereo_info - strchr - strlcat - __sw_hweight32 - -# required by snd-hda-codec.ko - bpf_trace_run4 - current_work - device_attach - driver_register - driver_unregister - get_device_system_crosststamp - kvasprintf - ns_to_timespec64 - pm_runtime_forbid - __printk_ratelimit - regcache_mark_dirty - snd_ctl_add_vmaster_hook - snd_ctl_apply_vmaster_followers - snd_ctl_remove - snd_device_disconnect - snd_device_free - snd_jack_new - snd_jack_report - snd_jack_set_key - snd_pcm_hw_constraint_minmax - snd_pcm_hw_constraint_step - snd_pcm_lib_default_mmap - snd_pcm_set_sync - strncat - timecounter_read - -# required by snd-hda-core.ko - add_uevent_var - device_add - device_del - kasprintf - kobject_create_and_add - pm_runtime_get_if_active - __pm_runtime_set_status - regcache_cache_only - regcache_sync - regmap_update_bits_base - snd_pcm_format_width - __sw_hweight64 - timecounter_init - -# required by snd-hda-intel.ko - bpf_trace_run1 - complete_all - param_array_ops - param_get_int - param_set_int - pci_dev_put - pci_disable_msi - pci_enable_msi - pci_get_device - pci_intx - pci_ioremap_bar - pci_match_id - pci_set_power_state - pci_write_config_byte - pci_write_config_word - -# required by snd-intel8x0.ko - snd_pcm_hw_constraint_list - snd_pcm_hw_constraint_msbits - -# required by system_heap.ko - deferred_free - dmabuf_page_pool_alloc - dmabuf_page_pool_create - dmabuf_page_pool_destroy - dmabuf_page_pool_free - dma_heap_add - dma_heap_get_dev - dma_heap_get_name - dma_sync_sg_for_cpu - __sg_page_iter_next - __sg_page_iter_start - vmalloc - vmap - vunmap - -# required by tpm.ko - alloc_chrdev_region - cdev_device_add - cdev_device_del - cdev_init - compat_only_sysfs_link_entry_to_kobj - devm_add_action - efi - efi_tpm_final_log_size - hash_digest_size - idr_get_next - idr_replace - jiffies_to_usecs - memchr_inv - of_property_match_string - pm_suspend_global_flags - securityfs_create_dir - securityfs_create_file - securityfs_remove - seq_putc - seq_write - unregister_chrdev_region - -# required by tpm_vtpm_proxy.ko - anon_inode_getfile - compat_ptr_ioctl - -# required by vexpress-config.ko - devres_add - devres_alloc_node - devres_free - of_device_is_compatible - of_find_compatible_node - of_get_next_parent - of_parse_phandle - of_platform_populate - of_root - -# required by vexpress-sysreg.ko - bgpio_init - devm_gpiochip_add_data_with_key - devm_mfd_add_devices - -# required by virt_wifi.ko - __dev_get_by_index - dev_printk - __module_get - netdev_upper_dev_link - netif_stacked_transfer_operstate - rtnl_link_register - rtnl_link_unregister - skb_clone - unregister_netdevice_many - -# required by virt_wifi_sim.ko - release_firmware - request_firmware - -# required by virtio-gpu.ko - __devm_request_region - dma_fence_match_context - dma_fence_wait_timeout - dma_resv_add_excl_fence - dma_resv_test_signaled_rcu - dma_resv_wait_timeout_rcu - drm_add_edid_modes - drm_add_modes_noedid - drm_atomic_get_crtc_state - drm_atomic_helper_check - drm_atomic_helper_check_plane_state - drm_atomic_helper_commit - drm_atomic_helper_connector_destroy_state - drm_atomic_helper_connector_duplicate_state - drm_atomic_helper_connector_reset - drm_atomic_helper_crtc_destroy_state - drm_atomic_helper_crtc_duplicate_state - drm_atomic_helper_crtc_reset - drm_atomic_helper_damage_merged - drm_atomic_helper_dirtyfb - drm_atomic_helper_disable_plane - drm_atomic_helper_page_flip - drm_atomic_helper_plane_destroy_state - drm_atomic_helper_plane_duplicate_state - drm_atomic_helper_plane_reset - drm_atomic_helper_set_config - drm_atomic_helper_shutdown - drm_atomic_helper_update_plane - drm_compat_ioctl - drm_connector_attach_edid_property - drm_connector_attach_encoder - drm_connector_cleanup - drm_connector_init - drm_connector_register - drm_connector_unregister - drm_connector_update_edid_property - drm_crtc_cleanup - drm_crtc_init_with_planes - drm_cvt_mode - __drm_dbg - drm_debugfs_create_files - drm_dev_alloc - drm_dev_enter - drm_dev_exit - drm_dev_get - drm_dev_printk - drm_dev_put - drm_dev_register - drm_dev_set_unique - drm_dev_unplug - drm_do_get_edid - __drm_err - drm_framebuffer_init - drm_gem_create_mmap_offset - drm_gem_dmabuf_mmap - drm_gem_dmabuf_release - drm_gem_dmabuf_vmap - drm_gem_dmabuf_vunmap - drm_gem_fb_create_handle - drm_gem_fb_destroy - drm_gem_free_mmap_offset - drm_gem_handle_create - drm_gem_lock_reservations - drm_gem_map_attach - drm_gem_map_detach - drm_gem_map_dma_buf - drm_gem_mmap - drm_gem_object_free - drm_gem_object_lookup - drm_gem_object_release - drm_gem_prime_fd_to_handle - drm_gem_prime_handle_to_fd - drm_gem_prime_import - drm_gem_prime_mmap - drm_gem_private_object_init - drm_gem_shmem_create - drm_gem_shmem_free_object - drm_gem_shmem_get_sg_table - drm_gem_shmem_mmap - drm_gem_shmem_pin - drm_gem_shmem_print_info - drm_gem_shmem_unpin - drm_gem_shmem_vmap - drm_gem_shmem_vunmap - drm_gem_unlock_reservations - drm_gem_unmap_dma_buf - drm_gem_vm_close - drm_gem_vm_open - drm_helper_hpd_irq_event - drm_helper_mode_fill_fb_struct - drm_helper_probe_single_connector_modes - drm_ioctl - drm_kms_helper_hotplug_event - drm_mm_init - drm_mm_insert_node_in_range - drmm_mode_config_init - drm_mm_print - drm_mm_remove_node - drm_mm_takedown - drm_mode_config_reset - drm_mode_probed_add - drm_open - drm_plane_cleanup - drm_poll - __drm_printfn_seq_file - __drm_puts_seq_file - drm_read - drm_release - drm_set_preferred_mode - drm_simple_encoder_init - drm_universal_plane_init - __get_task_comm - iomem_resource - is_vmalloc_addr - kmalloc_order_trace - memdup_user - seq_puts - sync_file_get_fence - __traceiter_dma_fence_emit - __traceiter_gpu_mem_total - __tracepoint_dma_fence_emit - __tracepoint_gpu_mem_total - vmalloc_to_page - vmemdup_user - vm_get_page_prot - ww_mutex_lock_interruptible - ww_mutex_unlock - -# required by virtio-rng.ko - wait_for_completion_killable - -# required by virtio_balloon.ko - adjust_managed_page_count - all_vm_events - balloon_aops - balloon_page_alloc - balloon_page_dequeue - balloon_page_enqueue - init_on_free - page_reporting_register - page_reporting_unregister - register_oom_notifier - si_mem_available - si_meminfo - system_freezable_wq - unregister_oom_notifier - vm_event_states - vm_node_stat - -# required by virtio_blk.ko - blk_execute_rq - blk_get_request - blk_mq_alloc_tag_set - blk_mq_complete_request - blk_mq_end_request - blk_mq_free_tag_set - blk_mq_init_queue - blk_mq_quiesce_queue - blk_mq_start_request - blk_mq_start_stopped_hw_queues - blk_mq_stop_hw_queue - blk_mq_unquiesce_queue - blk_mq_virtio_map_queues - blk_put_request - blk_queue_alignment_offset - blk_queue_max_discard_segments - blk_queue_max_hw_sectors - blk_queue_max_segments - blk_queue_max_segment_size - blk_rq_map_kern - __blk_rq_map_sg - set_capacity_revalidate_and_notify - string_get_size - virtio_max_dma_size - -# required by virtio_console.ko - cdev_add - cdev_alloc - cdev_del - device_destroy - fasync_helper - freezing_slow_path - hvc_alloc - hvc_instantiate - hvc_kick - hvc_poll - hvc_remove - __hvc_resize - kill_fasync - pipe_lock - pipe_unlock - __refrigerator - __register_chrdev - single_open - single_release - __splice_from_pipe - system_freezing_cnt - __unregister_chrdev - -# required by virtio_mmio.ko - device_for_each_child - devm_platform_ioremap_resource - platform_device_register_full - sscanf - -# required by virtio_net.ko - bpf_dispatcher_xdp_func - bpf_prog_add - bpf_prog_put - bpf_prog_sub - bpf_stats_enabled_key - bpf_warn_invalid_xdp_action - build_skb - cpumask_next_wrap - cpus_read_lock - cpus_read_unlock - eth_commit_mac_addr_change - eth_prepare_mac_addr_change - ethtool_op_get_ts_info - ethtool_virtdev_set_link_ksettings - eth_type_trans - flow_keys_basic_dissector - __napi_alloc_skb - napi_complete_done - napi_consume_skb - napi_disable - napi_gro_receive - __napi_schedule - napi_schedule_prep - netdev_notify_peers - netdev_warn - netif_device_attach - netif_napi_add - __netif_napi_del - netif_schedule_queue - netif_set_real_num_rx_queues - netif_set_real_num_tx_queues - __netif_set_xps_queue - net_ratelimit - __pskb_pull_tail - _raw_spin_trylock - sched_clock - skb_coalesce_rx_frag - __skb_flow_dissect - skb_page_frag_refill - skb_partial_csum_set - skb_to_sgvec - skb_tstamp_tx - softnet_data - synchronize_net - __traceiter_xdp_exception - __tracepoint_xdp_exception - virtqueue_add_inbuf_ctx - virtqueue_enable_cb_delayed - virtqueue_enable_cb_prepare - virtqueue_get_buf_ctx - virtqueue_poll - xdp_convert_zc_to_xdp_frame - xdp_do_flush - xdp_do_redirect - xdp_return_frame - xdp_return_frame_rx_napi - xdp_rxq_info_reg - xdp_rxq_info_reg_mem_model - xdp_rxq_info_unreg - xdp_warn - -# required by virtio_pci.ko - irq_set_affinity_hint - pci_alloc_irq_vectors_affinity - pci_disable_sriov - pci_enable_sriov - pci_find_capability - pci_find_ext_capability - pci_find_next_capability - pci_free_irq_vectors - pci_iomap_range - pci_irq_get_affinity - pci_irq_vector - pci_release_selected_regions - pci_request_selected_regions - pci_vfs_assigned - synchronize_irq - virtio_device_freeze - virtio_device_restore - -# required by virtio_pmem.ko - nvdimm_bus_register - nvdimm_bus_unregister - nvdimm_pmem_region_create - -# required by vmw_vsock_virtio_transport.ko - lock_sock_nested - release_sock - virtio_transport_connect - virtio_transport_deliver_tap_pkt - virtio_transport_destruct - virtio_transport_dgram_allow - virtio_transport_dgram_bind - virtio_transport_dgram_dequeue - virtio_transport_dgram_enqueue - virtio_transport_do_socket_init - virtio_transport_free_pkt - virtio_transport_notify_buffer_size - virtio_transport_notify_poll_in - virtio_transport_notify_poll_out - virtio_transport_notify_recv_init - virtio_transport_notify_recv_post_dequeue - virtio_transport_notify_recv_pre_block - virtio_transport_notify_recv_pre_dequeue - virtio_transport_notify_send_init - virtio_transport_notify_send_post_enqueue - virtio_transport_notify_send_pre_block - virtio_transport_notify_send_pre_enqueue - virtio_transport_recv_pkt - virtio_transport_release - virtio_transport_shutdown - virtio_transport_stream_allow - virtio_transport_stream_dequeue - virtio_transport_stream_enqueue - virtio_transport_stream_has_data - virtio_transport_stream_has_space - virtio_transport_stream_is_active - virtio_transport_stream_rcvhiwat - vsock_core_register - vsock_core_unregister - vsock_for_each_connected_socket - -# required by zram.ko - __alloc_percpu - bdget_disk - bdput - __class_register - class_unregister - crypto_alloc_base - crypto_comp_compress - crypto_comp_decompress - crypto_destroy_tfm - crypto_has_alg - disk_end_io_acct - disk_start_io_acct - flush_dcache_page - free_percpu - fsync_bdev - idr_find - idr_for_each - kstrtou16 - memset64 - mutex_is_locked - page_endio - sysfs_streq - vzalloc - -# required by zsmalloc.ko - dec_zone_page_state - inc_zone_page_state - __lock_page - page_mapping - _raw_read_lock - _raw_read_unlock - _raw_write_lock - _raw_write_unlock - -# required by gs_usb.ko - usb_kill_anchored_urbs - alloc_candev_mqs - register_candev - free_candev - can_change_mtu - open_candev - usb_anchor_urb - usb_unanchor_urb - alloc_can_skb - can_get_echo_skb - alloc_can_err_skb - close_candev - can_put_echo_skb - can_free_echo_skb - unregister_candev - -# required by vcan.ko - sock_efree - -# required by slcan.ko - tty_mode_ioctl - tty_hangup - hex_asc_upper diff --git a/android/abi_gki_aarch64_vivo b/android/abi_gki_aarch64_vivo deleted file mode 100644 index 5f3433d6f311..000000000000 --- a/android/abi_gki_aarch64_vivo +++ /dev/null @@ -1,2019 +0,0 @@ -[abi_symbol_list] - activate_task - add_cpu - add_device_randomness - add_memory - add_memory_subsection - add_timer - add_uevent_var - add_wait_queue - alarm_cancel - alarm_init - alarm_start - alloc_anon_inode - alloc_chrdev_region - __alloc_disk_node - alloc_io_pgtable_ops - __alloc_pages_nodemask - __alloc_percpu - __alloc_skb - alloc_skb_with_frags - alloc_workqueue - amba_bustype - amba_driver_register - amba_driver_unregister - android_debug_per_cpu_symbol - android_debug_symbol - android_rvh_probe_register - anon_inode_getfile - __arch_copy_from_user - __arch_copy_in_user - __arch_copy_to_user - arch_timer_read_counter - argv_free - argv_split - arm64_const_caps_ready - arm64_use_ng_mappings - __arm_smccc_smc - atomic_notifier_call_chain - atomic_notifier_chain_register - atomic_notifier_chain_unregister - available_idle_cpu - bdget_disk - bdput - bio_add_pc_page - bio_endio - bio_reset - bitmap_allocate_region - __bitmap_clear - bitmap_find_next_zero_area_off - __bitmap_or - bitmap_parselist_user - bitmap_print_to_pagebuf - bitmap_release_region - __bitmap_set - blk_alloc_queue - blk_bio_list_merge - blk_cleanup_queue - blk_execute_rq - blk_execute_rq_nowait - blk_get_request - blk_mq_debugfs_rq_show - blk_mq_rq_cpu - blk_mq_run_hw_queue - blk_mq_sched_mark_restart_hctx - blk_mq_sched_request_inserted - blk_put_request - blk_queue_flag_clear - blk_queue_flag_set - blk_queue_io_min - blk_queue_io_opt - blk_queue_logical_block_size - blk_queue_max_discard_sectors - blk_queue_max_write_zeroes_sectors - blk_queue_physical_block_size - blk_rq_append_bio - blk_rq_map_kern - blk_rq_map_user - blk_rq_map_user_iov - blk_rq_unmap_user - blk_stat_enable_accounting - blk_verify_command - blocking_notifier_call_chain - blocking_notifier_chain_register - blocking_notifier_chain_unregister - bpf_trace_run1 - bpf_trace_run10 - bpf_trace_run12 - bpf_trace_run2 - bpf_trace_run3 - bpf_trace_run4 - bpf_trace_run5 - bpf_trace_run6 - bpf_trace_run7 - bpf_trace_run8 - bpf_trace_run9 - bus_find_device - bus_for_each_dev - bus_register - bus_set_iommu - bus_unregister - cancel_delayed_work - cancel_delayed_work_sync - cancel_work_sync - capable - cdev_add - cdev_alloc - cdev_del - cdev_device_add - cdev_device_del - cdev_init - __cfi_slowpath - cgroup_path_ns - cgroup_taskset_first - cgroup_taskset_next - __check_object_size - check_preempt_curr - check_zeroed_user - __class_create - class_destroy - class_find_device - class_for_each_device - class_interface_unregister - __class_register - class_unregister - cleanup_srcu_struct - clear_page - __ClearPageMovable - clk_bulk_disable - clk_bulk_enable - clk_bulk_prepare - clk_bulk_put_all - clk_bulk_unprepare - __clk_determine_rate - clk_disable - clk_enable - clk_fixed_factor_ops - clk_fixed_rate_ops - clk_get - __clk_get_hw - __clk_get_name - clk_get_parent - clk_get_rate - clk_hw_get_flags - clk_hw_get_name - clk_hw_get_num_parents - clk_hw_get_parent - clk_hw_get_parent_by_index - clk_hw_get_rate - clk_hw_is_enabled - clk_hw_is_prepared - clk_hw_register - clk_hw_round_rate - clk_hw_unregister - __clk_is_enabled - __clk_mux_determine_rate_closest - clk_notifier_register - clk_notifier_unregister - clk_prepare - clk_put - clk_round_rate - clk_set_parent - clk_set_rate - clk_sync_state - clk_unprepare - cma_alloc - cma_get_name - cma_release - compat_alloc_user_space - compat_ptr_ioctl - complete - complete_all - completion_done - component_add - component_bind_all - component_del - component_master_add_with_match - component_master_del - component_match_add_release - component_unbind_all - config_ep_by_speed - configfs_register_subsystem - configfs_unregister_subsystem - config_group_init - config_group_init_type_name - config_item_get - config_item_put - console_stop - console_suspend_enabled - __const_udelay - consume_skb - contig_page_data - _copy_from_iter_full - __cpu_active_mask - cpu_bit_bitmap - cpufreq_cpu_get - cpufreq_cpu_get_raw - cpufreq_cpu_put - cpufreq_disable_fast_switch - cpufreq_driver_fast_switch - cpufreq_driver_resolve_freq - __cpufreq_driver_target - cpufreq_enable_fast_switch - cpufreq_freq_attr_scaling_available_freqs - cpufreq_freq_attr_scaling_boost_freqs - cpufreq_generic_frequency_table_verify - cpufreq_get_policy - cpufreq_register_driver - cpufreq_register_governor - cpufreq_register_notifier - cpufreq_unregister_driver - cpufreq_unregister_notifier - __cpuhp_remove_state - __cpuhp_setup_state - __cpuhp_setup_state_cpuslocked - __cpuhp_state_add_instance - __cpuhp_state_remove_instance - cpu_hwcap_keys - cpu_hwcaps - cpuidle_governor_latency_req - cpuidle_register_governor - cpu_irqtime - cpu_latency_qos_add_request - cpu_latency_qos_remove_request - cpu_latency_qos_request_active - cpu_latency_qos_update_request - cpumask_next - cpumask_next_and - cpu_number - __cpu_online_mask - cpu_pm_register_notifier - cpu_pm_unregister_notifier - __cpu_possible_mask - __cpu_present_mask - cpupri_find_fitness - cpu_scale - cpus_read_lock - cpus_read_unlock - cpu_subsys - cpu_topology - crc8 - crc8_populate_msb - crypto_alloc_base - crypto_comp_compress - crypto_comp_decompress - crypto_destroy_tfm - crypto_has_alg - crypto_register_alg - crypto_register_rngs - crypto_register_scomp - crypto_unregister_alg - crypto_unregister_rngs - crypto_unregister_scomp - css_next_child - _ctype - datagram_poll - deactivate_task - debugfs_attr_read - debugfs_attr_write - debugfs_create_bool - debugfs_create_dir - debugfs_create_file - debugfs_create_file_unsafe - debugfs_create_u32 - debugfs_create_u8 - debugfs_create_x32 - debugfs_create_x8 - debugfs_file_get - debugfs_file_put - debugfs_lookup - debugfs_remove - dec_zone_page_state - default_llseek - deferred_free - delayed_work_timer_fn - del_gendisk - del_timer - del_timer_sync - desc_to_gpio - destroy_workqueue - dev_coredumpv - _dev_crit - dev_driver_string - _dev_err - devfreq_add_device - devfreq_add_governor - devfreq_cooling_unregister - devfreq_remove_device - devfreq_remove_governor - devfreq_resume_device - devfreq_suspend_device - dev_fwnode - dev_get_by_name - dev_get_regmap - device_add - device_add_disk - device_add_groups - device_create - device_create_file - device_del - device_destroy - device_find_child - device_for_each_child - device_get_match_data - device_initialize - device_init_wakeup - device_link_add - device_match_fwnode - device_match_name - device_property_present - device_property_read_string - device_property_read_u16_array - device_property_read_u32_array - device_register - device_remove_file - device_show_int - device_store_int - device_unregister - device_wakeup_disable - device_wakeup_enable - _dev_info - devm_add_action - devm_blk_ksm_init - devm_clk_bulk_get_all - devm_clk_get - devm_clk_hw_register - devm_clk_put - devm_clk_register - devm_device_add_group - devm_device_remove_group - devm_extcon_dev_allocate - devm_extcon_dev_register - devm_extcon_dev_unregister - devm_free_irq - devm_gpiod_get_optional - devm_gpio_request - devm_gpio_request_one - devm_hwspin_lock_register - devm_iio_channel_get - devm_iio_device_alloc - __devm_iio_device_register - devm_input_allocate_device - devm_ioremap - devm_ioremap_resource - devm_ioremap_wc - devm_iounmap - devm_kasprintf - devm_kfree - devm_kmalloc - devm_kmemdup - devm_kstrdup - devm_led_classdev_register_ext - devm_nvmem_cell_get - devm_nvmem_device_get - devm_nvmem_register - devm_of_clk_add_hw_provider - devm_of_icc_get - __devm_of_phy_provider_register - devm_of_platform_populate - devm_of_pwm_get - devm_pci_alloc_host_bridge - devm_phy_create - devm_phy_get - devm_pinctrl_get - devm_pinctrl_put - devm_pinctrl_register - devm_platform_ioremap_resource - devm_platform_ioremap_resource_byname - devm_power_supply_register - devm_regmap_field_alloc - __devm_regmap_init - __devm_regmap_init_i2c - __devm_regmap_init_mmio_clk - devm_regulator_bulk_get - devm_regulator_get - devm_regulator_get_optional - devm_regulator_put - devm_regulator_register - devm_regulator_register_notifier - devm_request_any_context_irq - devm_request_threaded_irq - __devm_reset_control_get - devm_reset_controller_register - devm_rtc_allocate_device - devm_thermal_of_cooling_device_register - devm_thermal_zone_of_sensor_register - devm_usb_get_phy_by_node - _dev_notice - dev_pm_domain_attach - dev_pm_domain_attach_by_name - dev_pm_domain_detach - dev_pm_genpd_add_notifier - dev_pm_genpd_remove_notifier - dev_pm_genpd_set_next_wakeup - dev_pm_genpd_set_performance_state - dev_pm_opp_add - dev_pm_opp_find_freq_ceil - dev_pm_opp_find_freq_exact - dev_pm_opp_find_freq_floor - dev_pm_opp_get_opp_count - dev_pm_opp_get_voltage - dev_pm_opp_of_add_table - dev_pm_opp_of_find_icc_paths - dev_pm_opp_of_register_em - dev_pm_opp_of_remove_table - dev_pm_opp_put - dev_pm_opp_put_clkname - dev_pm_opp_remove_all_dynamic - dev_pm_opp_set_clkname - dev_pm_opp_set_rate - dev_pm_opp_set_sharing_cpus - dev_pm_qos_add_notifier - dev_pm_qos_add_request - dev_pm_qos_read_value - dev_pm_qos_remove_notifier - dev_pm_qos_remove_request - dev_pm_qos_update_request - dev_printk - devres_add - devres_alloc_node - devres_free - devres_release - dev_set_name - _dev_warn - disable_irq - disable_irq_nosync - disable_percpu_irq - disk_end_io_acct - disk_start_io_acct - divider_get_val - divider_recalc_rate - divider_ro_round_rate_parent - divider_round_rate_parent - dma_alloc_attrs - dma_async_device_register - dma_async_device_unregister - dma_async_tx_descriptor_init - dma_buf_attach - dma_buf_begin_cpu_access - dma_buf_begin_cpu_access_partial - dma_buf_detach - dma_buf_end_cpu_access - dma_buf_end_cpu_access_partial - dma_buf_export - dma_buf_fd - dma_buf_get - dma_buf_map_attachment - dma_buf_put - dma_buf_unmap_attachment - dma_buf_vmap - dma_buf_vunmap - dma_fence_add_callback - dma_fence_array_create - dma_fence_array_ops - dma_fence_context_alloc - dma_fence_default_wait - dma_fence_enable_sw_signaling - dma_fence_free - dma_fence_get_status - dma_fence_init - dma_fence_release - dma_fence_remove_callback - dma_fence_signal - dma_fence_signal_locked - dma_fence_wait_timeout - dma_free_attrs - dma_get_sgtable_attrs - dma_get_slave_channel - dma_heap_add - dma_heap_buffer_alloc - dma_heap_find - dma_heap_get_dev - dma_heap_get_drvdata - dma_heap_get_name - dmam_alloc_attrs - dma_map_page_attrs - dma_map_resource - dma_map_sg_attrs - dmam_free_coherent - dma_release_channel - dma_request_chan - dma_set_coherent_mask - dma_set_mask - dma_sync_sg_for_cpu - dma_sync_sg_for_device - dma_sync_single_for_cpu - dma_sync_single_for_device - dma_unmap_page_attrs - dma_unmap_resource - dma_unmap_sg_attrs - do_exit - down_read - down_write - d_path - dput - drain_workqueue - driver_find_device - driver_register - driver_unregister - edac_device_add_device - edac_device_alloc_ctl_info - edac_device_alloc_index - edac_device_del_device - edac_device_free_ctl_info - edac_device_handle_ce_count - edac_device_handle_ue_count - elevator_alloc - elv_register - elv_unregister - enable_irq - enable_percpu_irq - eventfd_ctx_fdget - eventfd_ctx_fileget - eventfd_ctx_put - eventfd_ctx_remove_wait_queue - eventfd_signal - event_triggers_call - extcon_get_edev_by_phandle - extcon_get_edev_name - extcon_get_property - extcon_get_state - extcon_register_notifier - extcon_set_state_sync - failure_tracking - fasync_helper - __fdget - fd_install - fget - filp_close - filp_open_block - find_last_bit - find_next_bit - find_next_zero_bit - find_snd_usb_substream - find_task_by_vpid - find_vma - find_vpid - finish_wait - firmware_request_nowarn - flush_dcache_page - flush_delayed_work - flush_work - flush_workqueue - fput - free_io_pgtable_ops - free_irq - __free_pages - free_pages - free_percpu - free_percpu_irq - freq_qos_add_request - freq_qos_remove_request - freq_qos_update_request - freq_scale - fsync_bdev - fwnode_find_reference - fwnode_get_next_child_node - fwnode_handle_get - fwnode_handle_put - fwnode_property_present - fwnode_property_read_string - fwnode_property_read_u32_array - generic_device_group - generic_handle_irq - generic_iommu_put_resv_regions - genlmsg_put - genl_register_family - genl_unregister_family - gen_pool_add_owner - gen_pool_alloc_algo_owner - gen_pool_avail - gen_pool_best_fit - gen_pool_create - gen_pool_destroy - gen_pool_first_fit_order_align - gen_pool_free_owner - gen_pool_has_addr - gen_pool_set_algo - gen_pool_size - gen_pool_virt_to_phys - getboottime64 - get_cpu_device - get_device - __get_free_pages - get_governor_parent_kobj - get_option - get_pid_task - get_random_bytes - get_random_u32 - get_sg_io_hdr - __get_task_comm - get_task_mm - get_task_pid - get_unmapped_area - get_unused_fd_flags - get_user_pages - gfp_zone - gic_nonsecure_priorities - gov_attr_set_init - gov_attr_set_put - governor_sysfs_ops - gpiochip_add_data_with_key - gpiochip_add_pin_range - gpiochip_generic_free - gpiochip_generic_request - gpiochip_get_data - gpiochip_line_is_valid - gpiochip_lock_as_irq - gpiochip_remove - gpiochip_unlock_as_irq - gpiod_direction_input - gpiod_direction_output - gpiod_direction_output_raw - gpiod_get_optional - gpiod_get_raw_value - gpiod_get_raw_value_cansleep - gpiod_get_value - gpiod_set_raw_value - gpiod_set_value - gpiod_set_value_cansleep - gpiod_to_irq - gpio_free - gpio_request - gpio_request_one - gpio_to_desc - handle_bad_irq - handle_edge_irq - handle_fasteoi_ack_irq - handle_fasteoi_irq - handle_level_irq - handle_nested_irq - handle_simple_irq - handle_sysrq - hashlen_string - hex_dump_to_buffer - hrtimer_active - hrtimer_cancel - hrtimer_forward - __hrtimer_get_remaining - hrtimer_init - hrtimer_start_range_ns - hrtimer_try_to_cancel - hvc_alloc - hvc_kick - hvc_poll - hvc_remove - hwrng_register - hwrng_unregister - hwspin_lock_free - hwspin_lock_request_specific - __hwspin_lock_timeout - __hwspin_unlock - hypervisor_kobj - i2c_add_adapter - i2c_del_adapter - i2c_del_driver - i2c_get_dma_safe_msg_buf - i2c_put_dma_safe_msg_buf - i2c_register_driver - i2c_smbus_read_byte_data - i2c_smbus_write_byte_data - i2c_transfer - i2c_transfer_buffer_flags - icc_get - icc_link_create - icc_node_add - icc_node_create - icc_node_del - icc_node_destroy - icc_provider_add - icc_provider_del - icc_put - icc_set_bw - icc_set_tag - ida_alloc_range - ida_free - idr_alloc - idr_alloc_cyclic - idr_destroy - idr_find - idr_for_each - idr_get_next - idr_preload - idr_remove - idr_replace - iio_channel_get - iio_channel_get_all - iio_channel_release - iio_read_channel_processed - import_iovec - inc_zone_page_state - in_egroup_p - init_iova_domain - init_net - init_pseudo - __init_rwsem - init_srcu_struct - __init_swait_queue_head - init_task - init_timer_key - init_uts_ns - init_wait_entry - __init_waitqueue_head - input_alloc_absinfo - input_allocate_device - input_close_device - input_event - input_free_device - input_mt_init_slots - input_mt_report_pointer_emulation - input_mt_report_slot_state - input_open_device - input_register_device - input_register_handle - input_register_handler - input_set_abs_params - input_set_capability - input_unregister_device - input_unregister_handle - input_unregister_handler - interval_tree_insert - interval_tree_iter_first - interval_tree_iter_next - interval_tree_remove - int_sqrt - iommu_alloc_resv_region - iommu_attach_device - iommu_detach_device - iommu_device_register - iommu_device_sysfs_add - iommu_device_sysfs_remove - iommu_device_unregister - iommu_dma_get_resv_regions - iommu_domain_alloc - iommu_domain_free - iommu_domain_get_attr - iommu_domain_set_attr - iommu_fwspec_add_ids - iommu_fwspec_free - iommu_get_dma_cookie - iommu_get_domain_for_dev - iommu_get_msi_cookie - iommu_group_for_each_dev - iommu_group_get - iommu_group_get_iommudata - iommu_group_put - iommu_group_ref_get - iommu_group_set_iommudata - iommu_iova_to_phys - iommu_map - iommu_map_sg - iommu_present - iommu_put_dma_cookie - iommu_set_fault_handler - iommu_unmap - __ioread32_copy - __ioremap - iounmap - __iowrite32_copy - ipi_desc_get - iput - irq_chip_ack_parent - irq_chip_disable_parent - irq_chip_enable_parent - irq_chip_eoi_parent - irq_chip_get_parent_state - irq_chip_mask_parent - irq_chip_retrigger_hierarchy - irq_chip_set_affinity_parent - irq_chip_set_parent_state - irq_chip_set_type_parent - irq_chip_set_vcpu_affinity_parent - irq_chip_set_wake_parent - irq_chip_unmask_parent - irq_create_fwspec_mapping - irq_dispose_mapping - __irq_domain_add - irq_domain_alloc_irqs_parent - irq_domain_create_hierarchy - irq_domain_free_irqs_common - irq_domain_free_irqs_parent - irq_domain_get_irq_data - irq_domain_remove - irq_domain_set_hwirq_and_chip - irq_domain_set_info - irq_domain_update_bus_token - irq_domain_xlate_twocell - irq_find_mapping - irq_find_matching_fwspec - irq_get_irqchip_state - irq_get_irq_data - irq_modify_status - irq_of_parse_and_map - irq_set_affinity_hint - irq_set_affinity_notifier - irq_set_chained_handler_and_data - irq_set_chip_and_handler_name - irq_set_chip_data - irq_set_irqchip_state - irq_set_irq_type - irq_set_irq_wake - irq_set_parent - irq_to_desc - irq_work_queue - irq_work_queue_on - irq_work_sync - is_dma_buf_file - is_vmalloc_addr - jiffies - jiffies_to_msecs - jiffies_to_usecs - kasan_flag_enabled - kasprintf - kernel_bind - kernel_connect - kernel_getsockname - kernel_kobj - kernel_recvmsg - kernel_restart - kernel_sendmsg - kern_mount - kern_unmount - __kfifo_alloc - __kfifo_in - __kfifo_out - kfree - kfree_const - kfree_sensitive - kfree_skb - kill_anon_super - kill_fasync - kimage_vaddr - kimage_voffset - __kmalloc - kmalloc_caches - kmalloc_order_trace - kmem_cache_alloc - kmem_cache_alloc_trace - kmem_cache_create - kmem_cache_create_usercopy - kmem_cache_destroy - kmem_cache_free - kmemdup - kmemdup_nul - kobject_add - kobject_create_and_add - kobject_del - kobject_init - kobject_init_and_add - kobject_put - kobject_set_name - kobject_uevent - kobj_sysfs_ops - krealloc - kset_create_and_add - ksize - ksoftirqd - kstat - kstat_irqs_cpu - kstat_irqs_usr - kstrdup - kstrdup_const - kstrndup - kstrtobool - kstrtoint - kstrtoll - kstrtou16 - kstrtou16_from_user - kstrtou8 - kstrtou8_from_user - kstrtouint - kstrtouint_from_user - kstrtoul_from_user - kstrtoull - kstrtoull_from_user - kthread_bind_mask - kthread_cancel_work_sync - kthread_create_on_node - kthread_create_worker - kthread_destroy_worker - kthread_flush_worker - __kthread_init_worker - kthread_queue_work - kthread_should_stop - kthread_stop - kthread_worker_fn - ktime_get - ktime_get_mono_fast_ns - ktime_get_real_seconds - ktime_get_real_ts64 - ktime_get_with_offset - kvfree - kvmalloc_node - led_classdev_flash_register_ext - led_classdev_flash_unregister - led_classdev_unregister - __list_add_valid - __list_del_entry_valid - list_sort - llist_add_batch - llist_reverse_order - __lock_page - lock_sock_nested - log_buf_addr_get - log_buf_len_get - __log_post_read_mmio - __log_read_mmio - __log_write_mmio - lzo1x_1_compress - lzo1x_decompress_safe - lzorle1x_1_compress - match_string - mbox_chan_received_data - mbox_chan_txdone - mbox_client_txdone - mbox_controller_register - mbox_controller_unregister - mbox_free_channel - mbox_request_channel - mbox_send_message - memblock_end_of_DRAM - __memcat_p - memcpy - __memcpy_fromio - __memcpy_toio - memdup_user - memmove - memory_block_size_bytes - memory_read_from_buffer - memparse - mempool_alloc - mempool_alloc_slab - mempool_create - mempool_destroy - mempool_free - mempool_free_slab - memremap - memset - memset64 - __memset_io - memstart_addr - memunmap - migrate_swap - misc_deregister - misc_register - mmc_cqe_request_done - mmc_of_parse - mmc_regulator_get_supply - mmc_regulator_set_ocr - mmc_regulator_set_vqmmc - mmc_send_tuning - mmput - mod_delayed_work_on - mod_node_page_state - mod_timer - __module_get - module_layout - module_put - __msecs_to_jiffies - msleep - msleep_interruptible - __mutex_init - mutex_is_locked - mutex_lock - mutex_lock_interruptible - mutex_trylock - mutex_unlock - netlink_broadcast - __netlink_kernel_create - netlink_kernel_release - netlink_unicast - __next_zones_zonelist - nla_find - nla_put - nla_reserve - nla_reserve_64bit - __nla_validate - __nlmsg_put - no_llseek - nonseekable_open - noop_llseek - nr_cpu_ids - nr_ipi_get - nr_irqs - ns_to_timespec64 - __num_online_cpus - nvmem_cell_get - nvmem_cell_put - nvmem_cell_read - nvmem_cell_read_u32 - nvmem_cell_write - nvmem_device_read - nvmem_device_write - of_address_to_resource - of_alias_get_id - of_clk_add_hw_provider - of_clk_add_provider - of_clk_del_provider - of_clk_hw_simple_get - of_clk_src_simple_get - of_count_phandle_with_args - of_cpufreq_cooling_register - of_cpu_node_to_id - of_devfreq_cooling_register - of_device_get_match_data - of_device_is_available - of_device_is_compatible - of_dma_configure_id - of_dma_controller_free - of_dma_controller_register - of_dma_is_coherent - of_drm_find_panel - of_find_compatible_node - of_find_device_by_node - of_find_i2c_device_by_node - of_find_matching_node_and_match - of_find_node_by_name - of_find_node_by_phandle - of_find_node_opts_by_path - of_find_node_with_property - of_find_property - of_fwnode_ops - of_genpd_add_provider_onecell - of_genpd_del_provider - of_get_address - of_get_child_by_name - of_get_cpu_node - of_get_named_gpio_flags - of_get_next_available_child - of_get_next_child - of_get_next_parent - of_get_property - of_get_regulator_init_data - of_graph_get_next_endpoint - of_graph_get_port_parent - of_graph_get_remote_endpoint - of_graph_is_present - of_graph_parse_endpoint - of_hwspin_lock_get_id - of_icc_get - of_icc_xlate_onecell - of_iomap - of_irq_find_parent - of_irq_get - of_irq_get_byname - of_irq_parse_one - of_match_device - of_match_node - of_n_addr_cells - of_node_name_eq - of_n_size_cells - of_parse_phandle - of_parse_phandle_with_args - of_parse_phandle_with_fixed_args - of_phandle_iterator_init - of_phandle_iterator_next - of_phy_simple_xlate - of_platform_depopulate - of_platform_device_create - of_platform_device_destroy - of_platform_populate - of_property_count_elems_of_size - of_property_match_string - of_property_read_string - of_property_read_string_helper - of_property_read_u32_index - of_property_read_u64_index - of_property_read_variable_u16_array - of_property_read_variable_u32_array - of_property_read_variable_u8_array - of_prop_next_string - of_prop_next_u32 - of_reserved_mem_device_init_by_idx - of_reserved_mem_device_release - of_reserved_mem_lookup - of_root - of_thermal_get_ntrips - of_thermal_get_trip_points - of_thermal_is_trip_valid - of_translate_address - on_each_cpu - oops_in_progress - overflowuid - page_endio - page_mapping - __page_pinner_migration_failed - panic - panic_notifier_list - panic_timeout - param_get_int - param_ops_bool - param_ops_int - param_ops_uint - param_set_bool - pause_cpus - pci_alloc_irq_vectors_affinity - pci_assign_resource - pci_bus_type - pci_clear_master - pci_device_group - pci_dev_present - pci_disable_device - pcie_capability_read_word - pci_enable_device - pci_find_ext_capability - pci_free_irq_vectors - pci_get_device - pci_host_probe - pci_iomap - pci_irq_vector - pci_load_and_free_saved_state - pci_load_saved_state - pci_msi_create_irq_domain - pci_msi_mask_irq - pci_msi_unmask_irq - pci_read_config_dword - pci_read_config_word - __pci_register_driver - pci_release_region - pci_request_region - pci_restore_state - pci_save_state - pci_set_master - pci_set_power_state - pci_store_saved_state - pci_unregister_driver - pci_walk_bus - pci_write_config_dword - __per_cpu_offset - per_cpu_ptr_to_phys - perf_aux_output_begin - perf_aux_output_end - perf_aux_output_flag - perf_event_create_kernel_counter - perf_event_disable - perf_event_enable - perf_event_read_local - perf_event_read_value - perf_event_release_kernel - perf_get_aux - perf_pmu_register - perf_pmu_unregister - perf_trace_buf_alloc - perf_trace_run_bpf_submit - pfn_valid - phy_calibrate - phy_exit - phy_init - phy_power_off - phy_power_on - phy_set_mode_ext - pick_highest_pushable_task - pid_nr_ns - pid_task - pinconf_generic_dt_node_to_map - pinctrl_dev_get_drvdata - pinctrl_force_default - pinctrl_force_sleep - pinctrl_lookup_state - pinctrl_pm_select_default_state - pinctrl_pm_select_sleep_state - pinctrl_select_state - pinctrl_utils_free_map - platform_bus_type - platform_device_add - platform_device_alloc - platform_device_del - platform_device_put - platform_device_register_full - platform_device_unregister - __platform_driver_register - platform_driver_unregister - platform_get_irq - platform_get_irq_byname - platform_get_resource - platform_get_resource_byname - platform_irq_count - pm_clk_add - pm_clk_create - pm_clk_destroy - pm_clk_resume - pm_clk_suspend - pm_genpd_add_subdomain - pm_genpd_init - pm_genpd_remove - pm_genpd_remove_subdomain - pm_power_off - __pm_relax - pm_relax - pm_runtime_allow - pm_runtime_barrier - __pm_runtime_disable - pm_runtime_enable - pm_runtime_forbid - pm_runtime_force_resume - pm_runtime_force_suspend - __pm_runtime_idle - pm_runtime_irq_safe - pm_runtime_no_callbacks - __pm_runtime_resume - pm_runtime_set_autosuspend_delay - __pm_runtime_set_status - __pm_runtime_suspend - __pm_runtime_use_autosuspend - __pm_stay_awake - pm_stay_awake - pm_wakeup_dev_event - pm_wakeup_ws_event - power_supply_changed - power_supply_get_by_name - power_supply_get_drvdata - power_supply_get_property - power_supply_put - power_supply_register - power_supply_reg_notifier - power_supply_set_property - power_supply_unregister - power_supply_unreg_notifier - prandom_u32 - preempt_schedule - preempt_schedule_notrace - prepare_to_wait_event - print_hex_dump - printk - printk_deferred - proc_dointvec - proc_dointvec_minmax - proc_dostring - proc_douintvec_minmax - proto_register - proto_unregister - __pskb_pull_tail - put_device - put_disk - put_iova_domain - __put_page - put_pid - put_sg_io_hdr - __put_task_struct - put_unused_fd - pwm_apply_state - pwmchip_add - pwmchip_remove - qcom_smem_state_get - qcom_smem_state_register - qcom_smem_state_unregister - qcom_smem_state_update_bits - queue_delayed_work_on - queue_work_on - radix_tree_insert - radix_tree_iter_delete - radix_tree_lookup - radix_tree_next_chunk - ___ratelimit - rational_best_approximation - raw_notifier_call_chain - raw_notifier_chain_register - raw_notifier_chain_unregister - _raw_read_lock - _raw_read_lock_bh - _raw_read_lock_irq - _raw_read_lock_irqsave - _raw_read_unlock - _raw_read_unlock_bh - _raw_read_unlock_irq - _raw_read_unlock_irqrestore - _raw_spin_lock - _raw_spin_lock_bh - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_trylock - _raw_spin_trylock_bh - _raw_spin_unlock - _raw_spin_unlock_bh - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - _raw_write_lock - _raw_write_lock_bh - _raw_write_lock_irq - _raw_write_lock_irqsave - _raw_write_unlock - _raw_write_unlock_bh - _raw_write_unlock_irq - _raw_write_unlock_irqrestore - rb_erase - rb_first - rb_insert_color - rb_last - rb_next - rb_prev - __rcu_read_lock - __rcu_read_unlock - rdev_get_drvdata - reboot_mode - refcount_dec_and_lock - refcount_dec_not_one - refcount_warn_saturate - register_blkdev - __register_chrdev - register_chrdev_region - register_console - register_die_notifier - register_ftrace_export - register_kretprobe - register_memory_notifier - register_module_notifier - register_pm_notifier - register_reboot_notifier - register_restart_handler - __register_rpmsg_driver - register_shrinker - register_syscore_ops - register_sysctl_table - regmap_bulk_read - regmap_bulk_write - regmap_check_range_table - regmap_field_read - regmap_field_update_bits_base - __regmap_init - regmap_mmio_detach_clk - regmap_read - regmap_update_bits_base - regmap_write - regulator_allow_bypass - regulator_bulk_disable - regulator_count_voltages - regulator_disable - regulator_disable_deferred - regulator_enable - regulator_force_disable - regulator_get - regulator_get_drvdata - regulator_get_mode - regulator_get_voltage - regulator_get_voltage_rdev - regulator_is_enabled - regulator_is_supported_voltage - regulator_list_voltage_linear - regulator_notifier_call_chain - regulator_put - regulator_register_notifier - regulator_set_current_limit - regulator_set_load - regulator_set_mode - regulator_set_voltage - regulator_unregister_notifier - release_firmware - release_sock - remap_pfn_range - remove_cpu - remove_memory_subsection - report_iommu_fault - request_any_context_irq - request_firmware - request_firmware_into_buf - request_firmware_nowait - __request_module - __request_percpu_irq - request_threaded_irq - resched_curr - reset_control_assert - reset_control_deassert - resume_cpus - revalidate_disk_size - rfkill_alloc - rfkill_destroy - rfkill_init_sw_state - rfkill_register - rfkill_unregister - rndis_deregister - rndis_free_response - rndis_get_next_response - rndis_msg_parser - rndis_register - rndis_set_host_mac - rndis_set_param_dev - rndis_set_param_medium - rndis_set_param_vendor - rndis_signal_connect - rndis_uninit - root_task_group - round_jiffies_relative - rpmsg_get_signals - rpmsg_poll - rpmsg_register_device - rpmsg_send - rpmsg_set_signals - rpmsg_trysend - rpmsg_unregister_device - rproc_add - rproc_add_subdev - rproc_alloc - rproc_boot - rproc_coredump_add_custom_segment - rproc_coredump_add_segment - rproc_coredump_set_elf_info - rproc_coredump_using_sections - rproc_del - rproc_free - rproc_get_by_child - rproc_get_by_phandle - rproc_put - rproc_remove_subdev - rproc_report_crash - rproc_shutdown - rtc_class_close - rtc_class_open - rtc_read_time - __rtc_register_device - rtc_time64_to_tm - rtc_tm_to_time64 - rtc_update_irq - rtc_valid_tm - runqueues - sbitmap_add_wait_queue - sbitmap_any_bit_set - sbitmap_del_wait_queue - sbitmap_init_node - sbitmap_queue_clear - __sbitmap_queue_get - sbitmap_queue_init_node - sbitmap_queue_min_shallow_depth - sbitmap_queue_resize - sbitmap_queue_show - sched_clock - sched_feat_keys - sched_feat_names - sched_setattr - sched_set_fifo - sched_set_normal - sched_setscheduler - sched_setscheduler_nocheck - sched_uclamp_used - schedule - schedule_timeout - scnprintf - scsi_autopm_get_device - scsi_autopm_put_device - scsi_block_when_processing_errors - scsi_command_size_tbl - scsi_compat_ioctl - scsi_device_get - scsi_device_put - scsi_device_quiesce - scsi_ioctl - scsi_ioctl_block_when_processing_errors - __scsi_iterate_devices - scsi_normalize_sense - __scsi_print_sense - scsi_print_sense_hdr - scsi_register_interface - scsi_remove_device - sdev_prefix_printk - __sdhci_add_host - sdhci_add_host - sdhci_cleanup_host - sdhci_cqe_disable - sdhci_cqe_enable - sdhci_cqe_irq - sdhci_enable_clk - sdhci_get_property - sdhci_pltfm_free - sdhci_pltfm_init - sdhci_remove_host - sdhci_reset - sdhci_set_bus_width - sdhci_set_power_noreg - sdhci_setup_host - seq_buf_printf - seq_list_next - seq_list_start - seq_lseek - seq_open - seq_printf - seq_putc - seq_puts - seq_read - seq_release - set_cpus_allowed_ptr - set_normalized_timespec64 - set_page_dirty_lock - __SetPageMovable - set_task_cpu - set_user_nice - sg_alloc_table - sg_alloc_table_from_pages - sg_free_table - sg_init_one - sg_init_table - sg_miter_next - sg_miter_start - sg_miter_stop - sg_next - __sg_page_iter_dma_next - __sg_page_iter_next - __sg_page_iter_start - sg_scsi_ioctl - show_regs - sigprocmask - si_meminfo - simple_attr_open - simple_attr_release - simple_open - simple_read_from_buffer - simple_write_to_buffer - single_open - single_release - si_swapinfo - sk_alloc - skb_clone - skb_copy_bits - skb_copy_datagram_iter - skb_dequeue - skb_free_datagram - __skb_pad - skb_push - skb_put - skb_queue_purge - skb_queue_tail - skb_recv_datagram - skb_set_owner_w - skb_store_bits - skb_trim - sk_free - skip_spaces - smp_call_function_single - snd_pcm_format_width - snd_soc_add_component_controls - snd_soc_info_volsw - snd_soc_register_component - snd_soc_unregister_component - snd_usb_enable_audio_stream - snprintf - soc_device_register - soc_device_unregister - sock_alloc_send_skb - sock_create_kern - sock_gettstamp - sock_init_data - sock_no_accept - sock_no_listen - sock_no_mmap - sock_no_sendpage - sock_no_shutdown - sock_no_socketpair - sock_queue_rcv_skb - sock_register - sock_release - sock_setsockopt - sock_unregister - sort - __spi_alloc_controller - spi_register_controller - spi_unregister_controller - spmi_controller_add - spmi_controller_alloc - spmi_controller_remove - __spmi_driver_register - spmi_ext_register_read - spmi_ext_register_readl - spmi_ext_register_write - spmi_ext_register_writel - spmi_register_read - spmi_register_write - spmi_register_zero_write - sprintf - srcu_init_notifier_head - srcu_notifier_call_chain - srcu_notifier_chain_register - srcu_notifier_chain_unregister - __srcu_read_lock - __srcu_read_unlock - sscanf - __stack_chk_fail - __stack_chk_guard - stack_trace_save_tsk - static_key_disable - stop_machine - stop_one_cpu_nowait - strcmp - strcpy - strim - strlcat - strlcpy - strlen - strncasecmp - strnchr - strncmp - strncpy - strncpy_from_user - strnlen - strnstr - strpbrk - strrchr - strscpy - strsep - strstr - __sw_hweight32 - __sw_hweight64 - __sw_hweight8 - sync_file_create - sync_file_get_fence - synchronize_irq - synchronize_rcu - synchronize_srcu - syscon_node_to_regmap - syscon_regmap_lookup_by_phandle - sysctl_sched_features - sysctl_vals - sysfs_add_file_to_group - sysfs_add_link_to_group - sysfs_create_bin_file - sysfs_create_file_ns - sysfs_create_files - sysfs_create_group - sysfs_create_link - sysfs_emit - __sysfs_match_string - sysfs_notify - sysfs_remove_bin_file - sysfs_remove_file_from_group - sysfs_remove_file_ns - sysfs_remove_files - sysfs_remove_group - sysfs_remove_link - sysfs_remove_link_from_group - sysfs_streq - sysrq_mask - system_freezable_wq - system_highpri_wq - system_unbound_wq - system_wq - sys_tz - task_active_pid_ns - __tasklet_hi_schedule - tasklet_init - tasklet_kill - __tasklet_schedule - tasklet_setup - tasklist_lock - task_may_not_preempt - __task_pid_nr_ns - __task_rq_lock - thermal_cooling_device_unregister - thermal_of_cooling_device_register - thermal_pressure - thermal_zone_device_enable - thermal_zone_device_register - thermal_zone_device_unregister - thermal_zone_device_update - thermal_zone_get_slope - thermal_zone_get_temp - thermal_zone_get_zone_by_name - thermal_zone_of_sensor_register - thermal_zone_of_sensor_unregister - tick_nohz_get_sleep_length - time64_to_tm - timer_reduce - topology_set_thermal_pressure - total_swapcache_pages - trace_array_get_by_name - trace_array_put - trace_array_set_clr_event - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return - __traceiter_android_rvh_account_irq - __traceiter_android_rvh_build_perf_domains - __traceiter_android_rvh_can_migrate_task - __traceiter_android_rvh_check_preempt_wakeup - __traceiter_android_rvh_cpu_cgroup_attach - __traceiter_android_rvh_cpu_cgroup_online - __traceiter_android_rvh_dequeue_task - __traceiter_android_rvh_enqueue_task - __traceiter_android_rvh_find_busiest_queue - __traceiter_android_rvh_find_lowest_rq - __traceiter_android_rvh_flush_task - __traceiter_android_rvh_migrate_queued_task - __traceiter_android_rvh_new_task_stats - __traceiter_android_rvh_replace_next_task_fair - __traceiter_android_rvh_resume_cpus - __traceiter_android_rvh_sched_cpu_dying - __traceiter_android_rvh_sched_cpu_starting - __traceiter_android_rvh_sched_exec - __traceiter_android_rvh_sched_fork - __traceiter_android_rvh_sched_fork_init - __traceiter_android_rvh_sched_newidle_balance - __traceiter_android_rvh_sched_nohz_balancer_kick - __traceiter_android_rvh_sched_setaffinity - __traceiter_android_rvh_schedule - __traceiter_android_rvh_select_task_rq_fair - __traceiter_android_rvh_select_task_rq_rt - __traceiter_android_rvh_set_gfp_zone_flags - __traceiter_android_rvh_set_readahead_gfp_mask - __traceiter_android_rvh_set_skip_swapcache_flags - __traceiter_android_rvh_set_task_cpu - __traceiter_android_rvh_tick_entry - __traceiter_android_rvh_try_to_wake_up - __traceiter_android_rvh_try_to_wake_up_success - __traceiter_android_rvh_ttwu_cond - __traceiter_android_rvh_update_cpu_capacity - __traceiter_android_rvh_update_cpus_allowed - __traceiter_android_rvh_update_misfit_status - __traceiter_android_rvh_wake_up_new_task - __traceiter_android_vh_allow_domain_state - __traceiter_android_vh_binder_restore_priority - __traceiter_android_vh_binder_set_priority - __traceiter_android_vh_binder_wakeup_ilocked - __traceiter_android_vh_cpu_idle_enter - __traceiter_android_vh_cpu_idle_exit - __traceiter_android_vh_ftrace_dump_buffer - __traceiter_android_vh_ftrace_format_check - __traceiter_android_vh_ftrace_oops_enter - __traceiter_android_vh_ftrace_oops_exit - __traceiter_android_vh_ftrace_size_check - __traceiter_android_vh_iommu_setup_dma_ops - __traceiter_android_vh_ipi_stop - __traceiter_android_vh_jiffies_update - __traceiter_android_vh_mmc_attach_sd - __traceiter_android_vh_mmc_blk_mq_rw_recovery - __traceiter_android_vh_mmc_blk_reset - __traceiter_android_vh_mmc_gpio_cd_irqt - __traceiter_android_vh_printk_hotplug - __traceiter_android_vh_scheduler_tick - __traceiter_android_vh_sdhci_get_cd - __traceiter_android_vh_sd_update_bus_speed_mode - __traceiter_android_vh_show_max_freq - __traceiter_android_vh_show_resume_epoch_val - __traceiter_android_vh_show_suspend_epoch_val - __traceiter_android_vh_timer_calc_index - __traceiter_android_vh_ufs_check_int_errors - __traceiter_android_vh_ufs_compl_command - __traceiter_android_vh_ufs_send_command - __traceiter_android_vh_ufs_update_sdev - __traceiter_binder_transaction_received - __traceiter_cpu_frequency_limits - __traceiter_cpu_idle - __traceiter_dwc3_complete_trb - __traceiter_dwc3_ctrl_req - __traceiter_dwc3_event - __traceiter_ipi_entry - __traceiter_ipi_raise - __traceiter_rwmmio_post_read - __traceiter_rwmmio_read - __traceiter_rwmmio_write - __traceiter_suspend_resume - __traceiter_usb_gadget_connect - __traceiter_usb_gadget_disconnect - __tracepoint_android_rvh_account_irq - __tracepoint_android_rvh_build_perf_domains - __tracepoint_android_rvh_can_migrate_task - __tracepoint_android_rvh_check_preempt_wakeup - __tracepoint_android_rvh_cpu_cgroup_attach - __tracepoint_android_rvh_cpu_cgroup_online - __tracepoint_android_rvh_dequeue_task - __tracepoint_android_rvh_enqueue_task - __tracepoint_android_rvh_find_busiest_queue - __tracepoint_android_rvh_find_lowest_rq - __tracepoint_android_rvh_flush_task - __tracepoint_android_rvh_migrate_queued_task - __tracepoint_android_rvh_new_task_stats - __tracepoint_android_rvh_replace_next_task_fair - __tracepoint_android_rvh_resume_cpus - __tracepoint_android_rvh_sched_cpu_dying - __tracepoint_android_rvh_sched_cpu_starting - __tracepoint_android_rvh_sched_exec - __tracepoint_android_rvh_sched_fork - __tracepoint_android_rvh_sched_fork_init - __tracepoint_android_rvh_sched_newidle_balance - __tracepoint_android_rvh_sched_nohz_balancer_kick - __tracepoint_android_rvh_sched_setaffinity - __tracepoint_android_rvh_schedule - __tracepoint_android_rvh_select_task_rq_fair - __tracepoint_android_rvh_select_task_rq_rt - __tracepoint_android_rvh_set_gfp_zone_flags - __tracepoint_android_rvh_set_readahead_gfp_mask - __tracepoint_android_rvh_set_skip_swapcache_flags - __tracepoint_android_rvh_set_task_cpu - __tracepoint_android_rvh_tick_entry - __tracepoint_android_rvh_try_to_wake_up - __tracepoint_android_rvh_try_to_wake_up_success - __tracepoint_android_rvh_ttwu_cond - __tracepoint_android_rvh_update_cpu_capacity - __tracepoint_android_rvh_update_cpus_allowed - __tracepoint_android_rvh_update_misfit_status - __tracepoint_android_rvh_wake_up_new_task - __tracepoint_android_vh_allow_domain_state - __tracepoint_android_vh_binder_restore_priority - __tracepoint_android_vh_binder_set_priority - __tracepoint_android_vh_binder_wakeup_ilocked - __tracepoint_android_vh_cpu_idle_enter - __tracepoint_android_vh_cpu_idle_exit - __tracepoint_android_vh_ftrace_dump_buffer - __tracepoint_android_vh_ftrace_format_check - __tracepoint_android_vh_ftrace_oops_enter - __tracepoint_android_vh_ftrace_oops_exit - __tracepoint_android_vh_ftrace_size_check - __tracepoint_android_vh_iommu_setup_dma_ops - __tracepoint_android_vh_ipi_stop - __tracepoint_android_vh_jiffies_update - __tracepoint_android_vh_mmc_attach_sd - __tracepoint_android_vh_mmc_blk_mq_rw_recovery - __tracepoint_android_vh_mmc_blk_reset - __tracepoint_android_vh_mmc_gpio_cd_irqt - __tracepoint_android_vh_printk_hotplug - __tracepoint_android_vh_scheduler_tick - __tracepoint_android_vh_sdhci_get_cd - __tracepoint_android_vh_sd_update_bus_speed_mode - __tracepoint_android_vh_show_max_freq - __tracepoint_android_vh_show_resume_epoch_val - __tracepoint_android_vh_show_suspend_epoch_val - __tracepoint_android_vh_timer_calc_index - __tracepoint_android_vh_ufs_check_int_errors - __tracepoint_android_vh_ufs_compl_command - __tracepoint_android_vh_ufs_send_command - __tracepoint_android_vh_ufs_update_sdev - __tracepoint_binder_transaction_received - __tracepoint_cpu_frequency_limits - __tracepoint_cpu_idle - __tracepoint_dwc3_complete_trb - __tracepoint_dwc3_ctrl_req - __tracepoint_dwc3_event - __tracepoint_ipi_entry - __tracepoint_ipi_raise - tracepoint_probe_register - tracepoint_probe_register_prio - tracepoint_probe_unregister - __tracepoint_rwmmio_post_read - __tracepoint_rwmmio_read - __tracepoint_rwmmio_write - __tracepoint_suspend_resume - __tracepoint_usb_gadget_connect - __tracepoint_usb_gadget_disconnect - trace_print_array_seq - trace_print_flags_seq - trace_print_symbols_seq - trace_raw_output_prep - trace_seq_printf - trace_seq_putc - try_module_get - try_wait_for_completion - tty_flip_buffer_push - __tty_insert_flip_char - tty_insert_flip_string_fixed_flag - uart_add_one_port - uart_console_device - uart_console_write - uart_get_baud_rate - uart_insert_char - uart_parse_options - uart_register_driver - uart_remove_one_port - uart_resume_port - uart_set_options - uart_suspend_port - uart_try_toggle_sysrq - uart_unregister_driver - uart_update_timeout - uart_write_wakeup - uclamp_eff_value - ucsi_connector_change - ucsi_create - ucsi_destroy - ucsi_get_drvdata - ucsi_register - ucsi_set_drvdata - ucsi_unregister - __udelay - ufshcd_auto_hibern8_update - ufshcd_dme_get_attr - ufshcd_dme_set_attr - ufshcd_dump_regs - ufshcd_fixup_dev_quirks - ufshcd_get_local_unipro_ver - ufshcd_pltfrm_init - ufshcd_pltfrm_resume - ufshcd_pltfrm_runtime_idle - ufshcd_pltfrm_runtime_resume - ufshcd_pltfrm_runtime_suspend - ufshcd_pltfrm_suspend - ufshcd_query_attr - ufshcd_query_attr_retry - ufshcd_query_descriptor_retry - ufshcd_query_flag - ufshcd_read_desc_param - ufshcd_remove - ufshcd_shutdown - ufshcd_uic_hibern8_enter - ufshcd_uic_hibern8_exit - __uio_register_device - uio_unregister_device - unlock_page - unregister_blkdev - __unregister_chrdev - unregister_chrdev_region - unregister_console - unregister_die_notifier - unregister_ftrace_export - unregister_kretprobe - unregister_module_notifier - unregister_pm_notifier - unregister_reboot_notifier - unregister_restart_handler - unregister_rpmsg_driver - unregister_shrinker - unregister_syscore_ops - update_devfreq - update_rq_clock - up_read - up_write - usb_add_phy_dev - usb_alloc_coherent - usb_alloc_dev - usb_alloc_urb - usb_assign_descriptors - usb_composite_setup_continue - usb_control_msg - usb_deregister - usb_ep_alloc_request - usb_ep_autoconfig - usb_ep_dequeue - usb_ep_disable - usb_ep_enable - usb_ep_free_request - usb_ep_queue - usb_ep_set_halt - usb_find_common_endpoints - usb_free_all_descriptors - usb_free_coherent - usb_free_urb - usb_function_register - usb_function_unregister - usb_gadget_wakeup - usb_ifnum_to_if - usb_interface_id - usb_phy_set_charger_current - usb_poison_urb - usb_put_dev - usb_put_function_instance - usb_register_driver - usb_register_notify - usb_remove_phy - usb_role_switch_find_by_fwnode - usb_role_switch_get_drvdata - usb_role_switch_register - usb_role_switch_set_role - usb_role_switch_unregister - usb_set_device_state - usb_speed_string - usb_string_id - usb_submit_urb - usb_unregister_notify - __usecs_to_jiffies - usleep_range - v4l2_compat_ioctl32 - v4l2_ctrl_handler_free - v4l2_device_register - v4l2_device_unregister - vabits_actual - vchan_dma_desc_free_list - vchan_find_desc - vchan_init - vchan_tx_desc_free - vchan_tx_submit - vfree - video_devdata - video_device_release_empty - video_ioctl2 - __video_register_device - video_unregister_device - vmalloc - vmalloc_nr_pages - vmalloc_to_page - vmalloc_to_pfn - vmap - vmf_insert_pfn - vm_insert_page - vm_iomap_memory - vm_map_pages - vm_node_stat - vm_zone_stat - vscnprintf - vsnprintf - vunmap - vzalloc - wait_for_completion - wait_for_completion_interruptible - wait_for_completion_interruptible_timeout - wait_for_completion_killable - wait_for_completion_timeout - __wake_up - wake_up_if_idle - wake_up_process - wakeup_source_add - wakeup_source_register - wakeup_source_remove - wakeup_source_unregister - __warn_printk - ww_mutex_lock - ww_mutex_unlock - __xa_alloc - xa_destroy - xa_erase - xa_find - xa_find_after - xa_load - xa_store - xhci_alloc_command - xhci_alloc_erst - xhci_free_command - xhci_get_endpoint_index - xhci_queue_stop_endpoint - xhci_ring_alloc - xhci_ring_cmd_db - xhci_ring_free - xhci_trb_virt_to_dma - zone_watermark_ok_safe diff --git a/android/abi_gki_aarch64_xiaomi b/android/abi_gki_aarch64_xiaomi deleted file mode 100644 index 867cd0739539..000000000000 --- a/android/abi_gki_aarch64_xiaomi +++ /dev/null @@ -1,114 +0,0 @@ -[abi_symbol_list] -# commonly used symbols - -# required by xxx.ko - -# required by touch module - proc_mkdir_data - -# required by aw8697-haptic.ko - devm_gpio_free - i2c_smbus_read_byte_data - i2c_smbus_write_byte_data - -#required by memory module - blk_execute_rq - blk_rq_map_kern - scsi_device_lookup - scsi_host_lookup - scsi_host_put - ufshcd_read_desc_param - utf16s_to_utf8s - async_schedule_node - blk_ksm_register - blk_ksm_reprogram_all_keys - blk_mq_alloc_tag_set - blk_mq_init_queue - blk_mq_tagset_busy_iter - bsg_job_done - bsg_remove_queue - bsg_setup_queue - dev_pm_opp_remove - scsi_add_host_with_dma - scsi_block_requests - scsi_dma_unmap - scsi_is_host_device - scsi_remove_host - scsi_report_bus_reset - scsi_scan_host - scsi_unblock_requests - sg_copy_from_buffer - sg_copy_to_buffer - ufshcd_alloc_host - ufshcd_config_pwr_mode - ufshcd_dealloc_host - ufshcd_hba_enable - ufshcd_make_hba_operational - ufshcd_map_desc_id_to_length - ufshcd_query_attr_retry - ufshcd_query_flag_retry - wait_for_completion_io_timeout - __scsi_add_device - __scsi_execute - blk_mq_free_tag_set - -#required by cs35l41 module - regmap_raw_write_async - snd_soc_bytes_tlv_callback - regmap_async_complete - snd_compr_stop_error - snd_soc_component_disable_pin - snd_soc_component_force_enable_pin - snd_pcm_format_physical_width - snd_pcm_hw_constraint_list - regmap_multi_reg_write_bypassed - snd_ctl_boolean_mono_info - snd_soc_put_volsw_range - snd_soc_get_volsw_range - snd_soc_info_volsw_range - regmap_raw_write - regcache_drop_region - regmap_raw_read - regmap_multi_reg_write - regulator_bulk_enable - -#required by mtd module - __blk_mq_end_request - balance_dirty_pages_ratelimited - bdi_alloc - bdi_put - bdi_register - blk_mq_freeze_queue - blk_mq_init_sq_queue - blk_mq_quiesce_queue - blk_mq_start_request - blk_mq_unfreeze_queue - blk_mq_unquiesce_queue - blk_queue_write_cache - blk_update_request - blkdev_get_by_dev - blkdev_get_by_path - blkdev_put - deactivate_locked_super - fixed_size_llseek - generic_shutdown_super - kmsg_dump_get_buffer - kmsg_dump_register - kmsg_dump_rewind - kmsg_dump_unregister - ktime_get_coarse_real_ts64 - lockref_get - logfc - lookup_bdev - name_to_dev_t - nvmem_register - nvmem_unregister - proc_create_single_data - read_cache_page - rq_flush_dcache_pages - set_disk_ro - set_page_dirty - sget_fc - simple_strtoul - sync_blockdev - wait_for_device_probe diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 916e42d74a86..7eea28d6f6c8 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -325,18 +325,19 @@ setup_memory(void *kernel_end) i, cluster->usage, cluster->start_pfn, cluster->start_pfn + cluster->numpages); - /* Bit 0 is console/PALcode reserved. Bit 1 is - non-volatile memory -- we might want to mark - this for later. */ - if (cluster->usage & 3) - continue; - end = cluster->start_pfn + cluster->numpages; if (end > max_low_pfn) max_low_pfn = end; memblock_add(PFN_PHYS(cluster->start_pfn), cluster->numpages << PAGE_SHIFT); + + /* Bit 0 is console/PALcode reserved. Bit 1 is + non-volatile memory -- we might want to mark + this for later. */ + if (cluster->usage & 3) + memblock_reserve(PFN_PHYS(cluster->start_pfn), + cluster->numpages << PAGE_SHIFT); } /* diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index f4dd9f3f3001..cb64e4797d2a 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -166,7 +166,6 @@ smp_callin(void) DBGS(("smp_callin: commencing CPU %d current %p active_mm %p\n", cpuid, current, current->active_mm)); - preempt_disable(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); } @@ -583,7 +582,7 @@ void smp_send_stop(void) { cpumask_t to_whom; - cpumask_copy(&to_whom, cpu_possible_mask); + cpumask_copy(&to_whom, cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), &to_whom); #ifdef DEBUG_IPI_MSG if (hard_smp_processor_id() != boot_cpu_id) diff --git a/arch/arc/include/uapi/asm/sigcontext.h b/arch/arc/include/uapi/asm/sigcontext.h index 95f8a4380e11..7a5449dfcb29 100644 --- a/arch/arc/include/uapi/asm/sigcontext.h +++ b/arch/arc/include/uapi/asm/sigcontext.h @@ -18,6 +18,7 @@ */ struct sigcontext { struct user_regs_struct regs; + struct user_regs_arcv2 v2abi; }; #endif /* _ASM_ARC_SIGCONTEXT_H */ diff --git a/arch/arc/kernel/fpu.c b/arch/arc/kernel/fpu.c index c67c0f0f5f77..ec640219d989 100644 --- a/arch/arc/kernel/fpu.c +++ b/arch/arc/kernel/fpu.c @@ -57,23 +57,26 @@ void fpu_save_restore(struct task_struct *prev, struct task_struct *next) void fpu_init_task(struct pt_regs *regs) { + const unsigned int fwe = 0x80000000; + /* default rounding mode */ write_aux_reg(ARC_REG_FPU_CTRL, 0x100); - /* set "Write enable" to allow explicit write to exception flags */ - write_aux_reg(ARC_REG_FPU_STATUS, 0x80000000); + /* Initialize to zero: setting requires FWE be set */ + write_aux_reg(ARC_REG_FPU_STATUS, fwe); } void fpu_save_restore(struct task_struct *prev, struct task_struct *next) { struct arc_fpu *save = &prev->thread.fpu; struct arc_fpu *restore = &next->thread.fpu; + const unsigned int fwe = 0x80000000; save->ctrl = read_aux_reg(ARC_REG_FPU_CTRL); save->status = read_aux_reg(ARC_REG_FPU_STATUS); write_aux_reg(ARC_REG_FPU_CTRL, restore->ctrl); - write_aux_reg(ARC_REG_FPU_STATUS, restore->status); + write_aux_reg(ARC_REG_FPU_STATUS, (fwe | restore->status)); } #endif diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c index 98e575dbcce5..9d5996e014c0 100644 --- a/arch/arc/kernel/signal.c +++ b/arch/arc/kernel/signal.c @@ -61,6 +61,41 @@ struct rt_sigframe { unsigned int sigret_magic; }; +static int save_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs) +{ + int err = 0; +#ifndef CONFIG_ISA_ARCOMPACT + struct user_regs_arcv2 v2abi; + + v2abi.r30 = regs->r30; +#ifdef CONFIG_ARC_HAS_ACCL_REGS + v2abi.r58 = regs->r58; + v2abi.r59 = regs->r59; +#else + v2abi.r58 = v2abi.r59 = 0; +#endif + err = __copy_to_user(&mctx->v2abi, &v2abi, sizeof(v2abi)); +#endif + return err; +} + +static int restore_arcv2_regs(struct sigcontext *mctx, struct pt_regs *regs) +{ + int err = 0; +#ifndef CONFIG_ISA_ARCOMPACT + struct user_regs_arcv2 v2abi; + + err = __copy_from_user(&v2abi, &mctx->v2abi, sizeof(v2abi)); + + regs->r30 = v2abi.r30; +#ifdef CONFIG_ARC_HAS_ACCL_REGS + regs->r58 = v2abi.r58; + regs->r59 = v2abi.r59; +#endif +#endif + return err; +} + static int stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs, sigset_t *set) @@ -94,6 +129,10 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs, err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), &uregs.scratch, sizeof(sf->uc.uc_mcontext.regs.scratch)); + + if (is_isa_arcv2()) + err |= save_arcv2_regs(&(sf->uc.uc_mcontext), regs); + err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t)); return err ? -EFAULT : 0; @@ -109,6 +148,10 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf) err |= __copy_from_user(&uregs.scratch, &(sf->uc.uc_mcontext.regs.scratch), sizeof(sf->uc.uc_mcontext.regs.scratch)); + + if (is_isa_arcv2()) + err |= restore_arcv2_regs(&(sf->uc.uc_mcontext), regs); + if (err) return -EFAULT; diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index 52906d314537..db0e104d6835 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -189,7 +189,6 @@ void start_kernel_secondary(void) pr_info("## CPU%u LIVE ##: Executing Code...\n", cpu); local_irq_enable(); - preempt_disable(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); } diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S index 33ce59d91461..f67e4ad7b3ce 100644 --- a/arch/arc/kernel/vmlinux.lds.S +++ b/arch/arc/kernel/vmlinux.lds.S @@ -88,6 +88,8 @@ SECTIONS CPUIDLE_TEXT LOCK_TEXT KPROBES_TEXT + IRQENTRY_TEXT + SOFTIRQENTRY_TEXT *(.fixup) *(.gnu.warning) } diff --git a/arch/arm/boot/dts/am335x-baltos.dtsi b/arch/arm/boot/dts/am335x-baltos.dtsi index b7f64c7ba83d..77e23e736854 100644 --- a/arch/arm/boot/dts/am335x-baltos.dtsi +++ b/arch/arm/boot/dts/am335x-baltos.dtsi @@ -393,10 +393,10 @@ status = "okay"; }; -&gpio0 { +&gpio0_target { ti,no-reset-on-init; }; -&gpio3 { +&gpio3_target { ti,no-reset-on-init; }; diff --git a/arch/arm/boot/dts/am335x-cm-t335.dts b/arch/arm/boot/dts/am335x-cm-t335.dts index c6fe9db660e2..08c89f176845 100644 --- a/arch/arm/boot/dts/am335x-cm-t335.dts +++ b/arch/arm/boot/dts/am335x-cm-t335.dts @@ -496,7 +496,7 @@ status = "okay"; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&spi0_pins>; - ti,pindir-d0-out-d1-in = <1>; + ti,pindir-d0-out-d1-in; /* WLS1271 WiFi */ wlcore: wlcore@1 { compatible = "ti,wl1271"; diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index b43b94122d3c..bf05b68274c2 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -648,7 +648,7 @@ status = "okay"; }; -&gpio0 { +&gpio0_target { ti,no-reset-on-init; }; diff --git a/arch/arm/boot/dts/am335x-moxa-uc-2100-common.dtsi b/arch/arm/boot/dts/am335x-moxa-uc-2100-common.dtsi index 4e90f9c23d2e..8121a199607c 100644 --- a/arch/arm/boot/dts/am335x-moxa-uc-2100-common.dtsi +++ b/arch/arm/boot/dts/am335x-moxa-uc-2100-common.dtsi @@ -150,7 +150,7 @@ status = "okay"; }; -&gpio0 { +&gpio0_target { ti,no-reset-on-init; }; diff --git a/arch/arm/boot/dts/am335x-moxa-uc-8100-common.dtsi b/arch/arm/boot/dts/am335x-moxa-uc-8100-common.dtsi index 98d8ed4ad967..39e5d2ce600a 100644 --- a/arch/arm/boot/dts/am335x-moxa-uc-8100-common.dtsi +++ b/arch/arm/boot/dts/am335x-moxa-uc-8100-common.dtsi @@ -353,7 +353,7 @@ status = "okay"; }; -&gpio0 { +&gpio0_target { ti,no-reset-on-init; }; diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi index ea20e4bdf040..29fafb67cfaa 100644 --- a/arch/arm/boot/dts/am33xx-l4.dtsi +++ b/arch/arm/boot/dts/am33xx-l4.dtsi @@ -1723,7 +1723,7 @@ }; }; - target-module@ae000 { /* 0x481ae000, ap 56 3a.0 */ + gpio3_target: target-module@ae000 { /* 0x481ae000, ap 56 3a.0 */ compatible = "ti,sysc-omap2", "ti,sysc"; reg = <0xae000 0x4>, <0xae010 0x4>, diff --git a/arch/arm/boot/dts/am437x-gp-evm.dts b/arch/arm/boot/dts/am437x-gp-evm.dts index 6e4d05d649e9..033b984ff637 100644 --- a/arch/arm/boot/dts/am437x-gp-evm.dts +++ b/arch/arm/boot/dts/am437x-gp-evm.dts @@ -813,11 +813,14 @@ status = "okay"; }; +&gpio5_target { + ti,no-reset-on-init; +}; + &gpio5 { pinctrl-names = "default"; pinctrl-0 = <&display_mux_pins>; status = "okay"; - ti,no-reset-on-init; p8 { /* diff --git a/arch/arm/boot/dts/am437x-l4.dtsi b/arch/arm/boot/dts/am437x-l4.dtsi index 243e35f7a56c..86bf668f3848 100644 --- a/arch/arm/boot/dts/am437x-l4.dtsi +++ b/arch/arm/boot/dts/am437x-l4.dtsi @@ -1576,7 +1576,7 @@ compatible = "ti,am4372-d_can", "ti,am3352-d_can"; reg = <0x0 0x2000>; clocks = <&dcan1_fck>; - clock-name = "fck"; + clock-names = "fck"; syscon-raminit = <&scm_conf 0x644 1>; interrupts = ; status = "disabled"; @@ -2033,7 +2033,7 @@ }; }; - target-module@22000 { /* 0x48322000, ap 116 64.0 */ + gpio5_target: target-module@22000 { /* 0x48322000, ap 116 64.0 */ compatible = "ti,sysc-omap2", "ti,sysc"; reg = <0x22000 0x4>, <0x22010 0x4>, diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts b/arch/arm/boot/dts/am43x-epos-evm.dts index f517d1e843cf..d2aebdbc7e0f 100644 --- a/arch/arm/boot/dts/am43x-epos-evm.dts +++ b/arch/arm/boot/dts/am43x-epos-evm.dts @@ -582,7 +582,7 @@ status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&i2c0_pins>; - clock-frequency = <400000>; + clock-frequency = <100000>; tps65218: tps65218@24 { reg = <0x24>; @@ -860,7 +860,7 @@ pinctrl-names = "default", "sleep"; pinctrl-0 = <&spi0_pins_default>; pinctrl-1 = <&spi0_pins_sleep>; - ti,pindir-d0-out-d1-in = <1>; + ti,pindir-d0-out-d1-in; }; &spi1 { @@ -868,7 +868,7 @@ pinctrl-names = "default", "sleep"; pinctrl-0 = <&spi1_pins_default>; pinctrl-1 = <&spi1_pins_sleep>; - ti,pindir-d0-out-d1-in = <1>; + ti,pindir-d0-out-d1-in; }; &usb2_phy1 { diff --git a/arch/arm/boot/dts/am5718.dtsi b/arch/arm/boot/dts/am5718.dtsi index ebf4d3cc1cfb..6d7530a48c73 100644 --- a/arch/arm/boot/dts/am5718.dtsi +++ b/arch/arm/boot/dts/am5718.dtsi @@ -17,17 +17,13 @@ * VCP1, VCP2 * MLB * ISS - * USB3, USB4 + * USB3 */ &usb3_tm { status = "disabled"; }; -&usb4_tm { - status = "disabled"; -}; - &atl_tm { status = "disabled"; }; diff --git a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts index 0d5fe2bfb683..aed81568a297 100644 --- a/arch/arm/boot/dts/am57xx-cl-som-am57x.dts +++ b/arch/arm/boot/dts/am57xx-cl-som-am57x.dts @@ -454,20 +454,20 @@ &mailbox5 { status = "okay"; - mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { + mbox_ipu1_ipc3x: mbox-ipu1-ipc3x { status = "okay"; }; - mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { + mbox_dsp1_ipc3x: mbox-dsp1-ipc3x { status = "okay"; }; }; &mailbox6 { status = "okay"; - mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { + mbox_ipu2_ipc3x: mbox-ipu2-ipc3x { status = "okay"; }; - mbox_dsp2_ipc3x: mbox_dsp2_ipc3x { + mbox_dsp2_ipc3x: mbox-dsp2-ipc3x { status = "okay"; }; }; @@ -610,12 +610,11 @@ >; }; -&gpio3 { - status = "okay"; +&gpio3_target { ti,no-reset-on-init; }; -&gpio2 { +&gpio2_target { status = "okay"; ti,no-reset-on-init; }; diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts index c76b0046b402..5a4e137fec21 100644 --- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts +++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts @@ -156,10 +156,7 @@ /*W0-W7*/ "","","","","","","","", /*X0-X7*/ "","","","","","","","", /*Y0-Y7*/ "","","","","","","","", - /*Z0-Z7*/ "","","","","","","","", - /*AA0-AA7*/ "","","","","","","","", - /*AB0-AB7*/ "","","","","","","","", - /*AC0-AC7*/ "","","","","","","",""; + /*Z0-Z7*/ "","","","","","","",""; pin_mclr_vpp { gpio-hog; diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts index e86c22ce6d12..0e8851cec979 100644 --- a/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts +++ b/arch/arm/boot/dts/aspeed-bmc-opp-tacoma.dts @@ -127,10 +127,7 @@ /*W0-W7*/ "","","","","","","","", /*X0-X7*/ "","","","","","","","", /*Y0-Y7*/ "","","","","","","","", - /*Z0-Z7*/ "","","","","","","","", - /*AA0-AA7*/ "","","","","","","","", - /*AB0-AB7*/ "","","","","","","","", - /*AC0-AC7*/ "","","","","","","",""; + /*Z0-Z7*/ "","","","","","","",""; }; &fmc { @@ -180,6 +177,7 @@ &emmc { status = "okay"; + clk-phase-mmc-hs200 = <36>, <270>; }; &fsim0 { diff --git a/arch/arm/boot/dts/bcm-cygnus.dtsi b/arch/arm/boot/dts/bcm-cygnus.dtsi index dacaef2c14ca..ea3dc128b764 100644 --- a/arch/arm/boot/dts/bcm-cygnus.dtsi +++ b/arch/arm/boot/dts/bcm-cygnus.dtsi @@ -460,7 +460,7 @@ status = "disabled"; }; - nand: nand@18046000 { + nand_controller: nand-controller@18046000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x18046000 0x600>, <0xf8105408 0x600>, <0x18046f00 0x20>; diff --git a/arch/arm/boot/dts/bcm-hr2.dtsi b/arch/arm/boot/dts/bcm-hr2.dtsi index e8df458aad39..84cda16f68a2 100644 --- a/arch/arm/boot/dts/bcm-hr2.dtsi +++ b/arch/arm/boot/dts/bcm-hr2.dtsi @@ -179,7 +179,7 @@ status = "disabled"; }; - nand: nand@26000 { + nand_controller: nand-controller@26000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x26000 0x600>, <0x11b408 0x600>, diff --git a/arch/arm/boot/dts/bcm-nsp.dtsi b/arch/arm/boot/dts/bcm-nsp.dtsi index e895f7cb8c9f..605b6d2f4a56 100644 --- a/arch/arm/boot/dts/bcm-nsp.dtsi +++ b/arch/arm/boot/dts/bcm-nsp.dtsi @@ -269,7 +269,7 @@ dma-coherent; }; - nand: nand@26000 { + nand_controller: nand-controller@26000 { compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; reg = <0x026000 0x600>, <0x11b408 0x600>, diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts index 09a1182c2936..5395e8c2484e 100644 --- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts +++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts @@ -28,11 +28,11 @@ }; leds { - act { + led-act { gpios = <&gpio 42 GPIO_ACTIVE_HIGH>; }; - pwr { + led-pwr { label = "PWR"; gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; default-state = "keep"; diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi index 4847dd305317..3d040f6e2a20 100644 --- a/arch/arm/boot/dts/bcm2711.dtsi +++ b/arch/arm/boot/dts/bcm2711.dtsi @@ -395,7 +395,7 @@ ranges = <0x0 0x7e000000 0x0 0xfe000000 0x01800000>; dma-ranges = <0x0 0xc0000000 0x0 0x00000000 0x40000000>; - emmc2: emmc2@7e340000 { + emmc2: mmc@7e340000 { compatible = "brcm,bcm2711-emmc2"; reg = <0x0 0x7e340000 0x100>; interrupts = ; diff --git a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts index 6c8ce39833bf..40b9405f1a8e 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-a-plus.dts @@ -14,11 +14,11 @@ }; leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; }; - pwr { + led-pwr { label = "PWR"; gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; default-state = "keep"; diff --git a/arch/arm/boot/dts/bcm2835-rpi-a.dts b/arch/arm/boot/dts/bcm2835-rpi-a.dts index 17fdd48346ff..11edb581dbaf 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-a.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-a.dts @@ -14,7 +14,7 @@ }; leds { - act { + led-act { gpios = <&gpio 16 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts index b0355c229cdc..1b435c64bd9c 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b-plus.dts @@ -15,11 +15,11 @@ }; leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; }; - pwr { + led-pwr { label = "PWR"; gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; default-state = "keep"; diff --git a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts index 33b3b5c02521..a23c25c00eea 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts @@ -15,7 +15,7 @@ }; leds { - act { + led-act { gpios = <&gpio 16 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/bcm2835-rpi-b.dts b/arch/arm/boot/dts/bcm2835-rpi-b.dts index 2b69957e0113..1b63d6b19750 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-b.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-b.dts @@ -15,7 +15,7 @@ }; leds { - act { + led-act { gpios = <&gpio 16 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi index 58059c2ce129..e4e6b6abbfc1 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi @@ -5,7 +5,7 @@ / { leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts index f65448c01e31..33b2b77aa47d 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-zero-w.dts @@ -23,7 +23,7 @@ }; leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_LOW>; }; }; diff --git a/arch/arm/boot/dts/bcm2835-rpi-zero.dts b/arch/arm/boot/dts/bcm2835-rpi-zero.dts index 6dd93c6f4966..6f9b3a908f28 100644 --- a/arch/arm/boot/dts/bcm2835-rpi-zero.dts +++ b/arch/arm/boot/dts/bcm2835-rpi-zero.dts @@ -18,7 +18,7 @@ }; leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; }; }; diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index d94357b21f7e..87ddcad76083 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -4,7 +4,7 @@ leds { compatible = "gpio-leds"; - act { + led-act { label = "ACT"; default-state = "keep"; linux,default-trigger = "heartbeat"; diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts index 0455a680394a..d8af8eeac7b6 100644 --- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts +++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts @@ -15,11 +15,11 @@ }; leds { - act { + led-act { gpios = <&gpio 47 GPIO_ACTIVE_HIGH>; }; - pwr { + led-pwr { label = "PWR"; gpios = <&gpio 35 GPIO_ACTIVE_HIGH>; default-state = "keep"; diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts index 28be0332c1c8..77099a7871b0 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts @@ -19,11 +19,11 @@ }; leds { - act { + led-act { gpios = <&gpio 29 GPIO_ACTIVE_HIGH>; }; - pwr { + led-pwr { label = "PWR"; gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; default-state = "keep"; diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts index 37343148643d..61010266ca9a 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts @@ -20,11 +20,11 @@ }; leds { - act { + led-act { gpios = <&gpio 29 GPIO_ACTIVE_HIGH>; }; - pwr { + led-pwr { label = "PWR"; gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; default-state = "keep"; diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts index 054ecaa355c9..dd4a48604097 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts @@ -20,7 +20,7 @@ }; leds { - act { + led-act { gpios = <&expgpio 2 GPIO_ACTIVE_HIGH>; }; }; diff --git a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi index 925cb37c22f0..828a20561b96 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi +++ b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi @@ -14,7 +14,7 @@ * Since there is no upstream GPIO driver yet, * remove the incomplete node. */ - /delete-node/ act; + /delete-node/ led-act; }; reg_3v3: fixed-regulator { diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index b83a864e2e8b..0f3be55201a5 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi @@ -420,7 +420,7 @@ status = "disabled"; }; - sdhci: sdhci@7e300000 { + sdhci: mmc@7e300000 { compatible = "brcm,bcm2835-sdhci"; reg = <0x7e300000 0x100>; interrupts = <2 30>; diff --git a/arch/arm/boot/dts/bcm5301x.dtsi b/arch/arm/boot/dts/bcm5301x.dtsi index ac3a99cf2079..72b0df6910bd 100644 --- a/arch/arm/boot/dts/bcm5301x.dtsi +++ b/arch/arm/boot/dts/bcm5301x.dtsi @@ -515,27 +515,27 @@ <0x1811b408 0x004>, <0x180293a0 0x01c>; reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg"; - interrupts = , + interrupts = , + , + , , , , - , - , - ; - interrupt-names = "spi_lr_fullness_reached", + ; + interrupt-names = "mspi_done", + "mspi_halted", + "spi_lr_fullness_reached", "spi_lr_session_aborted", "spi_lr_impatient", "spi_lr_session_done", - "spi_lr_overhead", - "mspi_done", - "mspi_halted"; + "spi_lr_overread"; clocks = <&iprocmed>; clock-names = "iprocmed"; num-cs = <2>; #address-cells = <1>; #size-cells = <0>; - spi_nor: spi-nor@0 { + spi_nor: flash@0 { compatible = "jedec,spi-nor"; reg = <0>; spi-max-frequency = <20000000>; diff --git a/arch/arm/boot/dts/bcm63138.dtsi b/arch/arm/boot/dts/bcm63138.dtsi index 9c0325cf9e22..cca49a2e2d62 100644 --- a/arch/arm/boot/dts/bcm63138.dtsi +++ b/arch/arm/boot/dts/bcm63138.dtsi @@ -203,7 +203,7 @@ status = "disabled"; }; - nand: nand@2000 { + nand_controller: nand-controller@2000 { #address-cells = <1>; #size-cells = <0>; compatible = "brcm,nand-bcm63138", "brcm,brcmnand-v7.0", "brcm,brcmnand"; diff --git a/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts b/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts index 8313b7cad542..f92d2cf85972 100644 --- a/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts +++ b/arch/arm/boot/dts/bcm7445-bcm97445svmb.dts @@ -14,10 +14,10 @@ }; }; -&nand { +&nand_controller { status = "okay"; - nandcs@1 { + nand@1 { compatible = "brcm,nandcs"; reg = <1>; nand-ecc-step-size = <512>; diff --git a/arch/arm/boot/dts/bcm7445.dtsi b/arch/arm/boot/dts/bcm7445.dtsi index 58f67c9b830b..5ac2042515b8 100644 --- a/arch/arm/boot/dts/bcm7445.dtsi +++ b/arch/arm/boot/dts/bcm7445.dtsi @@ -148,7 +148,7 @@ reg-names = "aon-ctrl", "aon-sram"; }; - nand: nand@3e2800 { + nand_controller: nand-controller@3e2800 { status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/bcm911360_entphn.dts b/arch/arm/boot/dts/bcm911360_entphn.dts index b2d323f4a5ab..a76c74b44bba 100644 --- a/arch/arm/boot/dts/bcm911360_entphn.dts +++ b/arch/arm/boot/dts/bcm911360_entphn.dts @@ -82,8 +82,8 @@ status = "okay"; }; -&nand { - nandcs@1 { +&nand_controller { + nand@1 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/bcm958300k.dts b/arch/arm/boot/dts/bcm958300k.dts index b4a1392bd5a6..dda3e11b711f 100644 --- a/arch/arm/boot/dts/bcm958300k.dts +++ b/arch/arm/boot/dts/bcm958300k.dts @@ -60,8 +60,8 @@ status = "okay"; }; -&nand { - nandcs@1 { +&nand_controller { + nand@1 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/bcm958305k.dts b/arch/arm/boot/dts/bcm958305k.dts index 3378683321d3..ea3c6b88b313 100644 --- a/arch/arm/boot/dts/bcm958305k.dts +++ b/arch/arm/boot/dts/bcm958305k.dts @@ -68,8 +68,8 @@ status = "okay"; }; -&nand { - nandcs@1 { +&nand_controller { + nand@1 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/bcm958522er.dts b/arch/arm/boot/dts/bcm958522er.dts index 7be4c4e628e0..5dd1001255c6 100644 --- a/arch/arm/boot/dts/bcm958522er.dts +++ b/arch/arm/boot/dts/bcm958522er.dts @@ -74,8 +74,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/bcm958525er.dts b/arch/arm/boot/dts/bcm958525er.dts index e58ed7e95346..0e624c57b585 100644 --- a/arch/arm/boot/dts/bcm958525er.dts +++ b/arch/arm/boot/dts/bcm958525er.dts @@ -74,8 +74,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/bcm958525xmc.dts b/arch/arm/boot/dts/bcm958525xmc.dts index 21f922dc6019..2ac6d61ad297 100644 --- a/arch/arm/boot/dts/bcm958525xmc.dts +++ b/arch/arm/boot/dts/bcm958525xmc.dts @@ -90,8 +90,8 @@ }; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/bcm958622hr.dts b/arch/arm/boot/dts/bcm958622hr.dts index a49c2fd21f4a..e072fa83537a 100644 --- a/arch/arm/boot/dts/bcm958622hr.dts +++ b/arch/arm/boot/dts/bcm958622hr.dts @@ -78,8 +78,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/bcm958623hr.dts b/arch/arm/boot/dts/bcm958623hr.dts index dd6dff6452b8..835f4765efbc 100644 --- a/arch/arm/boot/dts/bcm958623hr.dts +++ b/arch/arm/boot/dts/bcm958623hr.dts @@ -78,8 +78,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/bcm958625hr.dts b/arch/arm/boot/dts/bcm958625hr.dts index a71371b4065e..57974b8fab86 100644 --- a/arch/arm/boot/dts/bcm958625hr.dts +++ b/arch/arm/boot/dts/bcm958625hr.dts @@ -89,8 +89,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/bcm958625k.dts b/arch/arm/boot/dts/bcm958625k.dts index 7782b61c51a1..45a043ea77ce 100644 --- a/arch/arm/boot/dts/bcm958625k.dts +++ b/arch/arm/boot/dts/bcm958625k.dts @@ -68,8 +68,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/bcm963138dvt.dts b/arch/arm/boot/dts/bcm963138dvt.dts index 5b177274f182..df5c8ab90627 100644 --- a/arch/arm/boot/dts/bcm963138dvt.dts +++ b/arch/arm/boot/dts/bcm963138dvt.dts @@ -31,10 +31,10 @@ status = "okay"; }; -&nand { +&nand_controller { status = "okay"; - nandcs@0 { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-ecc-strength = <4>; diff --git a/arch/arm/boot/dts/bcm988312hr.dts b/arch/arm/boot/dts/bcm988312hr.dts index edd0f630e025..16b212cc8a2a 100644 --- a/arch/arm/boot/dts/bcm988312hr.dts +++ b/arch/arm/boot/dts/bcm988312hr.dts @@ -74,8 +74,8 @@ status = "okay"; }; -&nand { - nandcs@0 { +&nand_controller { + nand@0 { compatible = "brcm,nandcs"; reg = <0>; nand-on-flash-bbt; diff --git a/arch/arm/boot/dts/dm816x.dtsi b/arch/arm/boot/dts/dm816x.dtsi index 3551a64963f8..1825d912b8ab 100644 --- a/arch/arm/boot/dts/dm816x.dtsi +++ b/arch/arm/boot/dts/dm816x.dtsi @@ -351,7 +351,7 @@ #mbox-cells = <1>; ti,mbox-num-users = <4>; ti,mbox-num-fifos = <12>; - mbox_dsp: mbox_dsp { + mbox_dsp: mbox-dsp { ti,mbox-tx = <3 0 0>; ti,mbox-rx = <0 0 0>; }; diff --git a/arch/arm/boot/dts/dra7-ipu-dsp-common.dtsi b/arch/arm/boot/dts/dra7-ipu-dsp-common.dtsi index a25749a1c365..a5bdc6431d8d 100644 --- a/arch/arm/boot/dts/dra7-ipu-dsp-common.dtsi +++ b/arch/arm/boot/dts/dra7-ipu-dsp-common.dtsi @@ -5,17 +5,17 @@ &mailbox5 { status = "okay"; - mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { + mbox_ipu1_ipc3x: mbox-ipu1-ipc3x { status = "okay"; }; - mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { + mbox_dsp1_ipc3x: mbox-dsp1-ipc3x { status = "okay"; }; }; &mailbox6 { status = "okay"; - mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { + mbox_ipu2_ipc3x: mbox-ipu2-ipc3x { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/dra7-l4.dtsi b/arch/arm/boot/dts/dra7-l4.dtsi index a294a02f2d23..30b72f431850 100644 --- a/arch/arm/boot/dts/dra7-l4.dtsi +++ b/arch/arm/boot/dts/dra7-l4.dtsi @@ -1315,7 +1315,7 @@ }; }; - target-module@55000 { /* 0x48055000, ap 13 0e.0 */ + gpio2_target: target-module@55000 { /* 0x48055000, ap 13 0e.0 */ compatible = "ti,sysc-omap2", "ti,sysc"; reg = <0x55000 0x4>, <0x55010 0x4>, @@ -1348,7 +1348,7 @@ }; }; - target-module@57000 { /* 0x48057000, ap 15 06.0 */ + gpio3_target: target-module@57000 { /* 0x48057000, ap 15 06.0 */ compatible = "ti,sysc-omap2", "ti,sysc"; reg = <0x57000 0x4>, <0x57010 0x4>, @@ -4095,28 +4095,6 @@ }; }; - usb4_tm: target-module@140000 { /* 0x48940000, ap 75 3c.0 */ - compatible = "ti,sysc-omap4", "ti,sysc"; - reg = <0x140000 0x4>, - <0x140010 0x4>; - reg-names = "rev", "sysc"; - ti,sysc-mask = ; - ti,sysc-midle = , - , - , - ; - ti,sysc-sidle = , - , - , - ; - /* Domains (P, C): l3init_pwrdm, l3init_clkdm */ - clocks = <&l3init_clkctrl DRA7_L3INIT_USB_OTG_SS4_CLKCTRL 0>; - clock-names = "fck"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x140000 0x20000>; - }; - target-module@170000 { /* 0x48970000, ap 21 0a.0 */ compatible = "ti,sysc-omap4", "ti,sysc"; reg = <0x170010 0x4>; diff --git a/arch/arm/boot/dts/dra71x.dtsi b/arch/arm/boot/dts/dra71x.dtsi index cad0e4a2bd8d..9c270d8f75d5 100644 --- a/arch/arm/boot/dts/dra71x.dtsi +++ b/arch/arm/boot/dts/dra71x.dtsi @@ -11,7 +11,3 @@ &rtctarget { status = "disabled"; }; - -&usb4_tm { - status = "disabled"; -}; diff --git a/arch/arm/boot/dts/dra72x.dtsi b/arch/arm/boot/dts/dra72x.dtsi index d403acc754b6..90617261373c 100644 --- a/arch/arm/boot/dts/dra72x.dtsi +++ b/arch/arm/boot/dts/dra72x.dtsi @@ -77,12 +77,12 @@ }; &mailbox5 { - mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { + mbox_ipu1_ipc3x: mbox-ipu1-ipc3x { ti,mbox-tx = <6 2 2>; ti,mbox-rx = <4 2 2>; status = "disabled"; }; - mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { + mbox_dsp1_ipc3x: mbox-dsp1-ipc3x { ti,mbox-tx = <5 2 2>; ti,mbox-rx = <1 2 2>; status = "disabled"; @@ -90,7 +90,7 @@ }; &mailbox6 { - mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { + mbox_ipu2_ipc3x: mbox-ipu2-ipc3x { ti,mbox-tx = <6 2 2>; ti,mbox-rx = <4 2 2>; status = "disabled"; @@ -108,7 +108,3 @@ &pcie2_rc { compatible = "ti,dra726-pcie-rc", "ti,dra7-pcie"; }; - -&usb4_tm { - status = "disabled"; -}; diff --git a/arch/arm/boot/dts/dra74-ipu-dsp-common.dtsi b/arch/arm/boot/dts/dra74-ipu-dsp-common.dtsi index b1147a4b77f9..3256631510c5 100644 --- a/arch/arm/boot/dts/dra74-ipu-dsp-common.dtsi +++ b/arch/arm/boot/dts/dra74-ipu-dsp-common.dtsi @@ -6,7 +6,7 @@ #include "dra7-ipu-dsp-common.dtsi" &mailbox6 { - mbox_dsp2_ipc3x: mbox_dsp2_ipc3x { + mbox_dsp2_ipc3x: mbox-dsp2-ipc3x { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/dra74x.dtsi b/arch/arm/boot/dts/dra74x.dtsi index e1850d6c841a..cfb39dde4930 100644 --- a/arch/arm/boot/dts/dra74x.dtsi +++ b/arch/arm/boot/dts/dra74x.dtsi @@ -49,49 +49,6 @@ reg = <0x41500000 0x100>; }; - target-module@48940000 { - compatible = "ti,sysc-omap4", "ti,sysc"; - reg = <0x48940000 0x4>, - <0x48940010 0x4>; - reg-names = "rev", "sysc"; - ti,sysc-mask = ; - ti,sysc-midle = , - , - , - ; - ti,sysc-sidle = , - , - , - ; - clocks = <&l3init_clkctrl DRA7_L3INIT_USB_OTG_SS4_CLKCTRL 0>; - clock-names = "fck"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x48940000 0x20000>; - - omap_dwc3_4: omap_dwc3_4@0 { - compatible = "ti,dwc3"; - reg = <0 0x10000>; - interrupts = ; - #address-cells = <1>; - #size-cells = <1>; - utmi-mode = <2>; - ranges; - status = "disabled"; - usb4: usb@10000 { - compatible = "snps,dwc3"; - reg = <0x10000 0x17000>; - interrupts = , - , - ; - interrupt-names = "peripheral", - "host", - "otg"; - maximum-speed = "high-speed"; - dr_mode = "otg"; - }; - }; - }; target-module@41501000 { compatible = "ti,sysc-omap2", "ti,sysc"; @@ -188,12 +145,12 @@ }; &mailbox5 { - mbox_ipu1_ipc3x: mbox_ipu1_ipc3x { + mbox_ipu1_ipc3x: mbox-ipu1-ipc3x { ti,mbox-tx = <6 2 2>; ti,mbox-rx = <4 2 2>; status = "disabled"; }; - mbox_dsp1_ipc3x: mbox_dsp1_ipc3x { + mbox_dsp1_ipc3x: mbox-dsp1-ipc3x { ti,mbox-tx = <5 2 2>; ti,mbox-rx = <1 2 2>; status = "disabled"; @@ -201,12 +158,12 @@ }; &mailbox6 { - mbox_ipu2_ipc3x: mbox_ipu2_ipc3x { + mbox_ipu2_ipc3x: mbox-ipu2-ipc3x { ti,mbox-tx = <6 2 2>; ti,mbox-rx = <4 2 2>; status = "disabled"; }; - mbox_dsp2_ipc3x: mbox_dsp2_ipc3x { + mbox_dsp2_ipc3x: mbox-dsp2-ipc3x { ti,mbox-tx = <5 2 2>; ti,mbox-rx = <1 2 2>; status = "disabled"; @@ -224,3 +181,52 @@ &pcie2_rc { compatible = "ti,dra746-pcie-rc", "ti,dra7-pcie"; }; + +&l4_per3 { + segment@0 { + usb4_tm: target-module@140000 { /* 0x48940000, ap 75 3c.0 */ + compatible = "ti,sysc-omap4", "ti,sysc"; + reg = <0x140000 0x4>, + <0x140010 0x4>; + reg-names = "rev", "sysc"; + ti,sysc-mask = ; + ti,sysc-midle = , + , + , + ; + ti,sysc-sidle = , + , + , + ; + /* Domains (P, C): l3init_pwrdm, l3init_clkdm */ + clocks = <&l3init_clkctrl DRA7_L3INIT_USB_OTG_SS4_CLKCTRL 0>; + clock-names = "fck"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x140000 0x20000>; + + omap_dwc3_4: omap_dwc3_4@0 { + compatible = "ti,dwc3"; + reg = <0 0x10000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <1>; + utmi-mode = <2>; + ranges; + status = "disabled"; + usb4: usb@10000 { + compatible = "snps,dwc3"; + reg = <0x10000 0x17000>; + interrupts = , + , + ; + interrupt-names = "peripheral", + "host", + "otg"; + maximum-speed = "high-speed"; + dr_mode = "otg"; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/exynos5422-odroidhc1.dts b/arch/arm/boot/dts/exynos5422-odroidhc1.dts index 812659260278..88f5c150a30a 100644 --- a/arch/arm/boot/dts/exynos5422-odroidhc1.dts +++ b/arch/arm/boot/dts/exynos5422-odroidhc1.dts @@ -22,7 +22,7 @@ label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; - max_brightness = <255>; + max-brightness = <255>; linux,default-trigger = "heartbeat"; }; }; diff --git a/arch/arm/boot/dts/exynos5422-odroidxu4.dts b/arch/arm/boot/dts/exynos5422-odroidxu4.dts index ddd55d3bcadd..4ef0dbc84b0c 100644 --- a/arch/arm/boot/dts/exynos5422-odroidxu4.dts +++ b/arch/arm/boot/dts/exynos5422-odroidxu4.dts @@ -24,7 +24,7 @@ label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; - max_brightness = <255>; + max-brightness = <255>; linux,default-trigger = "heartbeat"; }; }; diff --git a/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi b/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi index 56acd832f0b3..16e1087ec717 100644 --- a/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi +++ b/arch/arm/boot/dts/exynos54xx-odroidxu-leds.dtsi @@ -22,7 +22,7 @@ * Green LED is much brighter than the others * so limit its max brightness */ - max_brightness = <127>; + max-brightness = <127>; linux,default-trigger = "mmc0"; }; @@ -30,7 +30,7 @@ label = "blue:heartbeat"; pwms = <&pwm 2 2000000 0>; pwm-names = "pwm2"; - max_brightness = <255>; + max-brightness = <255>; linux,default-trigger = "heartbeat"; }; }; diff --git a/arch/arm/boot/dts/gemini-dlink-dns-313.dts b/arch/arm/boot/dts/gemini-dlink-dns-313.dts index c6f3d90e3e90..b8acc6eaaa6d 100644 --- a/arch/arm/boot/dts/gemini-dlink-dns-313.dts +++ b/arch/arm/boot/dts/gemini-dlink-dns-313.dts @@ -140,7 +140,7 @@ }; }; - mdio0: ethernet-phy { + mdio0: mdio { compatible = "virtual,mdio-gpio"; /* Uses MDC and MDIO */ gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ diff --git a/arch/arm/boot/dts/gemini-nas4220b.dts b/arch/arm/boot/dts/gemini-nas4220b.dts index 43c45f7e1e0a..13112a8a5dd8 100644 --- a/arch/arm/boot/dts/gemini-nas4220b.dts +++ b/arch/arm/boot/dts/gemini-nas4220b.dts @@ -62,7 +62,7 @@ }; }; - mdio0: ethernet-phy { + mdio0: mdio { compatible = "virtual,mdio-gpio"; gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ diff --git a/arch/arm/boot/dts/gemini-rut1xx.dts b/arch/arm/boot/dts/gemini-rut1xx.dts index 9611ddf06792..0ebda4efd9d0 100644 --- a/arch/arm/boot/dts/gemini-rut1xx.dts +++ b/arch/arm/boot/dts/gemini-rut1xx.dts @@ -56,7 +56,7 @@ }; }; - mdio0: ethernet-phy { + mdio0: mdio { compatible = "virtual,mdio-gpio"; gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ @@ -125,18 +125,6 @@ }; }; - ethernet@60000000 { - status = "okay"; - - ethernet-port@0 { - phy-mode = "rgmii"; - phy-handle = <&phy0>; - }; - ethernet-port@1 { - /* Not used in this platform */ - }; - }; - usb@68000000 { status = "okay"; }; diff --git a/arch/arm/boot/dts/gemini-wbd111.dts b/arch/arm/boot/dts/gemini-wbd111.dts index 3a2761dd460f..5602ba8f30f2 100644 --- a/arch/arm/boot/dts/gemini-wbd111.dts +++ b/arch/arm/boot/dts/gemini-wbd111.dts @@ -68,7 +68,7 @@ }; }; - mdio0: ethernet-phy { + mdio0: mdio { compatible = "virtual,mdio-gpio"; gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ diff --git a/arch/arm/boot/dts/gemini-wbd222.dts b/arch/arm/boot/dts/gemini-wbd222.dts index 52b4dbc0c072..a4a260c36d75 100644 --- a/arch/arm/boot/dts/gemini-wbd222.dts +++ b/arch/arm/boot/dts/gemini-wbd222.dts @@ -67,7 +67,7 @@ }; }; - mdio0: ethernet-phy { + mdio0: mdio { compatible = "virtual,mdio-gpio"; gpios = <&gpio0 22 GPIO_ACTIVE_HIGH>, /* MDC */ <&gpio0 21 GPIO_ACTIVE_HIGH>; /* MDIO */ diff --git a/arch/arm/boot/dts/gemini.dtsi b/arch/arm/boot/dts/gemini.dtsi index 065ed10a79fa..07448c03dac9 100644 --- a/arch/arm/boot/dts/gemini.dtsi +++ b/arch/arm/boot/dts/gemini.dtsi @@ -286,6 +286,7 @@ clock-names = "PCLK", "PCICLK"; pinctrl-names = "default"; pinctrl-0 = <&pci_default_pins>; + device_type = "pci"; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts index f98691ae4415..d3082b9774e4 100644 --- a/arch/arm/boot/dts/imx53-m53menlo.dts +++ b/arch/arm/boot/dts/imx53-m53menlo.dts @@ -388,13 +388,13 @@ pinctrl_power_button: powerbutgrp { fsl,pins = < - MX53_PAD_SD2_DATA2__GPIO1_13 0x1e4 + MX53_PAD_SD2_DATA0__GPIO1_15 0x1e4 >; }; pinctrl_power_out: poweroutgrp { fsl,pins = < - MX53_PAD_SD2_DATA0__GPIO1_15 0x1e4 + MX53_PAD_SD2_DATA2__GPIO1_13 0x1e4 >; }; diff --git a/arch/arm/boot/dts/imx6dl-riotboard.dts b/arch/arm/boot/dts/imx6dl-riotboard.dts index 065d3ab0f50a..e7d9bfbfd0e4 100644 --- a/arch/arm/boot/dts/imx6dl-riotboard.dts +++ b/arch/arm/boot/dts/imx6dl-riotboard.dts @@ -106,6 +106,8 @@ reset-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; reset-assert-us = <10000>; reset-deassert-us = <1000>; + qca,smarteee-tw-us-1g = <24>; + qca,clk-out-frequency = <125000000>; }; }; }; diff --git a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi index d0768ae429fa..e3de2b487cf4 100644 --- a/arch/arm/boot/dts/imx6q-dhcom-som.dtsi +++ b/arch/arm/boot/dts/imx6q-dhcom-som.dtsi @@ -96,30 +96,40 @@ reg = <0>; max-speed = <100>; reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; - reset-delay-us = <1000>; - reset-post-delay-us = <1000>; + reset-assert-us = <1000>; + reset-deassert-us = <1000>; + smsc,disable-energy-detect; /* Make plugin detection reliable */ }; }; }; &i2c1 { clock-frequency = <100000>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c1>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio3 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio3 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; }; &i2c2 { clock-frequency = <100000>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c2>; + pinctrl-1 = <&pinctrl_i2c2_gpio>; + scl-gpios = <&gpio4 12 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio4 13 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; }; &i2c3 { clock-frequency = <100000>; - pinctrl-names = "default"; + pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c3>; + pinctrl-1 = <&pinctrl_i2c3_gpio>; + scl-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio1 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; ltc3676: pmic@3c { @@ -285,6 +295,13 @@ >; }; + pinctrl_i2c1_gpio: i2c1-gpio-grp { + fsl,pins = < + MX6QDL_PAD_EIM_D21__GPIO3_IO21 0x4001b8b1 + MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x4001b8b1 + >; + }; + pinctrl_i2c2: i2c2-grp { fsl,pins = < MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 @@ -292,6 +309,13 @@ >; }; + pinctrl_i2c2_gpio: i2c2-gpio-grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__GPIO4_IO12 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__GPIO4_IO13 0x4001b8b1 + >; + }; + pinctrl_i2c3: i2c3-grp { fsl,pins = < MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1 @@ -299,6 +323,13 @@ >; }; + pinctrl_i2c3_gpio: i2c3-gpio-grp { + fsl,pins = < + MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x4001b8b1 + MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x4001b8b1 + >; + }; + pinctrl_pmic_hw300: pmic-hw300-grp { fsl,pins = < MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x1B0B0 diff --git a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi index 5f84e9f2b576..33a70f436aa3 100644 --- a/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi +++ b/arch/arm/boot/dts/imx6qdl-phytec-pfla02.dtsi @@ -315,8 +315,8 @@ fsl,pins = < MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1 MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1 - MX6QDL_PAD_EIM_D30__UART3_RTS_B 0x1b0b1 - MX6QDL_PAD_EIM_D31__UART3_CTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D31__UART3_RTS_B 0x1b0b1 + MX6QDL_PAD_EIM_D30__UART3_CTS_B 0x1b0b1 >; }; @@ -403,6 +403,7 @@ &uart3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart3>; + uart-has-rtscts; status = "disabled"; }; diff --git a/arch/arm/boot/dts/imx6qdl-sr-som.dtsi b/arch/arm/boot/dts/imx6qdl-sr-som.dtsi index 7e4e5fd0143a..c56337b63c3b 100644 --- a/arch/arm/boot/dts/imx6qdl-sr-som.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sr-som.dtsi @@ -54,7 +54,13 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_microsom_enet_ar8035>; phy-mode = "rgmii-id"; - phy-reset-duration = <2>; + + /* + * The PHY seems to require a long-enough reset duration to avoid + * some rare issues where the PHY gets stuck in an inconsistent and + * non-functional state at boot-up. 10ms proved to be fine . + */ + phy-reset-duration = <10>; phy-reset-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; status = "okay"; diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi index a0545431b3dc..9f1e38282bee 100644 --- a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi +++ b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi @@ -43,6 +43,7 @@ assigned-clock-rates = <0>, <198000000>; cap-power-off-card; keep-power-in-suspend; + max-frequency = <25000000>; mmc-pwrseq = <&wifi_pwrseq>; no-1-8-v; non-removable; diff --git a/arch/arm/boot/dts/omap4-l4.dtsi b/arch/arm/boot/dts/omap4-l4.dtsi index de742bf84efb..5015df4d876c 100644 --- a/arch/arm/boot/dts/omap4-l4.dtsi +++ b/arch/arm/boot/dts/omap4-l4.dtsi @@ -597,11 +597,11 @@ #mbox-cells = <1>; ti,mbox-num-users = <3>; ti,mbox-num-fifos = <8>; - mbox_ipu: mbox_ipu { + mbox_ipu: mbox-ipu { ti,mbox-tx = <0 0 0>; ti,mbox-rx = <1 0 0>; }; - mbox_dsp: mbox_dsp { + mbox_dsp: mbox-dsp { ti,mbox-tx = <3 0 0>; ti,mbox-rx = <2 0 0>; }; diff --git a/arch/arm/boot/dts/omap5-board-common.dtsi b/arch/arm/boot/dts/omap5-board-common.dtsi index d8f13626cfd1..3a8f10231475 100644 --- a/arch/arm/boot/dts/omap5-board-common.dtsi +++ b/arch/arm/boot/dts/omap5-board-common.dtsi @@ -30,14 +30,6 @@ regulator-max-microvolt = <5000000>; }; - vdds_1v8_main: fixedregulator-vdds_1v8_main { - compatible = "regulator-fixed"; - regulator-name = "vdds_1v8_main"; - vin-supply = <&smps7_reg>; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - vmmcsd_fixed: fixedregulator-mmcsd { compatible = "regulator-fixed"; regulator-name = "vmmcsd_fixed"; @@ -487,6 +479,7 @@ regulator-boot-on; }; + vdds_1v8_main: smps7_reg: smps7 { /* VDDS_1v8_OMAP over VDDS_1v8_MAIN */ regulator-name = "smps7"; diff --git a/arch/arm/boot/dts/omap5-l4.dtsi b/arch/arm/boot/dts/omap5-l4.dtsi index f3d3a16b7c64..c67c8698cc30 100644 --- a/arch/arm/boot/dts/omap5-l4.dtsi +++ b/arch/arm/boot/dts/omap5-l4.dtsi @@ -613,11 +613,11 @@ #mbox-cells = <1>; ti,mbox-num-users = <3>; ti,mbox-num-fifos = <8>; - mbox_ipu: mbox_ipu { + mbox_ipu: mbox-ipu { ti,mbox-tx = <0 0 0>; ti,mbox-rx = <1 0 0>; }; - mbox_dsp: mbox_dsp { + mbox_dsp: mbox-dsp { ti,mbox-tx = <3 0 0>; ti,mbox-rx = <2 0 0>; }; diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts index d2240b89ee52..465845323495 100644 --- a/arch/arm/boot/dts/r8a7779-marzen.dts +++ b/arch/arm/boot/dts/r8a7779-marzen.dts @@ -145,7 +145,7 @@ status = "okay"; clocks = <&mstp1_clks R8A7779_CLK_DU>, <&x3_clk>; - clock-names = "du", "dclkin.0"; + clock-names = "du.0", "dclkin.0"; ports { port@0 { diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 74d7e9084eab..3c5fcdfe16b8 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -463,6 +463,7 @@ reg = <0xfff80000 0x40000>; interrupts = ; clocks = <&mstp1_clks R8A7779_CLK_DU>; + clock-names = "du.0"; power-domains = <&sysc R8A7779_PD_ALWAYS_ON>; status = "disabled"; diff --git a/arch/arm/boot/dts/rk3036-kylin.dts b/arch/arm/boot/dts/rk3036-kylin.dts index 7154b827ea2f..e817eba8c622 100644 --- a/arch/arm/boot/dts/rk3036-kylin.dts +++ b/arch/arm/boot/dts/rk3036-kylin.dts @@ -390,7 +390,7 @@ }; }; - sleep { + suspend { global_pwroff: global-pwroff { rockchip,pins = <2 RK_PA7 1 &pcfg_pull_none>; }; diff --git a/arch/arm/boot/dts/rk3066a.dtsi b/arch/arm/boot/dts/rk3066a.dtsi index 252750c97f97..bbc3bff50856 100644 --- a/arch/arm/boot/dts/rk3066a.dtsi +++ b/arch/arm/boot/dts/rk3066a.dtsi @@ -755,7 +755,7 @@ #address-cells = <1>; #size-cells = <0>; - pd_vio@RK3066_PD_VIO { + power-domain@RK3066_PD_VIO { reg = ; clocks = <&cru ACLK_LCDC0>, <&cru ACLK_LCDC1>, @@ -782,7 +782,7 @@ <&qos_rga>; }; - pd_video@RK3066_PD_VIDEO { + power-domain@RK3066_PD_VIDEO { reg = ; clocks = <&cru ACLK_VDPU>, <&cru ACLK_VEPU>, @@ -791,7 +791,7 @@ pm_qos = <&qos_vpu>; }; - pd_gpu@RK3066_PD_GPU { + power-domain@RK3066_PD_GPU { reg = ; clocks = <&cru ACLK_GPU>; pm_qos = <&qos_gpu>; diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index 2298a8d840ba..b6bde9d12c2b 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -150,16 +150,16 @@ compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer"; reg = <0x2000e000 0x20>; interrupts = ; - clocks = <&cru SCLK_TIMER3>, <&cru PCLK_TIMER3>; - clock-names = "timer", "pclk"; + clocks = <&cru PCLK_TIMER3>, <&cru SCLK_TIMER3>; + clock-names = "pclk", "timer"; }; timer6: timer@200380a0 { compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer"; reg = <0x200380a0 0x20>; interrupts = ; - clocks = <&cru SCLK_TIMER6>, <&cru PCLK_TIMER0>; - clock-names = "timer", "pclk"; + clocks = <&cru PCLK_TIMER0>, <&cru SCLK_TIMER6>; + clock-names = "pclk", "timer"; }; i2s0: i2s@1011a000 { @@ -699,7 +699,7 @@ #address-cells = <1>; #size-cells = <0>; - pd_vio@RK3188_PD_VIO { + power-domain@RK3188_PD_VIO { reg = ; clocks = <&cru ACLK_LCDC0>, <&cru ACLK_LCDC1>, @@ -721,7 +721,7 @@ <&qos_rga>; }; - pd_video@RK3188_PD_VIDEO { + power-domain@RK3188_PD_VIDEO { reg = ; clocks = <&cru ACLK_VDPU>, <&cru ACLK_VEPU>, @@ -730,7 +730,7 @@ pm_qos = <&qos_vpu>; }; - pd_gpu@RK3188_PD_GPU { + power-domain@RK3188_PD_GPU { reg = ; clocks = <&cru ACLK_GPU>; pm_qos = <&qos_gpu>; diff --git a/arch/arm/boot/dts/rk322x.dtsi b/arch/arm/boot/dts/rk322x.dtsi index 48e6e8d44a1a..7de8b006ca13 100644 --- a/arch/arm/boot/dts/rk322x.dtsi +++ b/arch/arm/boot/dts/rk322x.dtsi @@ -524,7 +524,7 @@ pinctrl-0 = <&otp_pin>; pinctrl-1 = <&otp_out>; pinctrl-2 = <&otp_pin>; - #thermal-sensor-cells = <0>; + #thermal-sensor-cells = <1>; rockchip,hw-tshut-temp = <95000>; status = "disabled"; }; @@ -565,10 +565,9 @@ compatible = "rockchip,iommu"; reg = <0x20020800 0x100>; interrupts = ; - interrupt-names = "vpu_mmu"; clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; clock-names = "aclk", "iface"; - iommu-cells = <0>; + #iommu-cells = <0>; status = "disabled"; }; @@ -576,10 +575,9 @@ compatible = "rockchip,iommu"; reg = <0x20030480 0x40>, <0x200304c0 0x40>; interrupts = ; - interrupt-names = "vdec_mmu"; clocks = <&cru ACLK_RKVDEC>, <&cru HCLK_RKVDEC>; clock-names = "aclk", "iface"; - iommu-cells = <0>; + #iommu-cells = <0>; status = "disabled"; }; @@ -609,7 +607,6 @@ compatible = "rockchip,iommu"; reg = <0x20053f00 0x100>; interrupts = ; - interrupt-names = "vop_mmu"; clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>; clock-names = "aclk", "iface"; #iommu-cells = <0>; @@ -630,10 +627,9 @@ compatible = "rockchip,iommu"; reg = <0x20070800 0x100>; interrupts = ; - interrupt-names = "iep_mmu"; clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>; clock-names = "aclk", "iface"; - iommu-cells = <0>; + #iommu-cells = <0>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/rk3288-rock2-som.dtsi b/arch/arm/boot/dts/rk3288-rock2-som.dtsi index 44bb5e6f83b1..76363b8afcb9 100644 --- a/arch/arm/boot/dts/rk3288-rock2-som.dtsi +++ b/arch/arm/boot/dts/rk3288-rock2-som.dtsi @@ -218,7 +218,7 @@ flash0-supply = <&vcc_flash>; flash1-supply = <&vccio_pmu>; gpio30-supply = <&vccio_pmu>; - gpio1830 = <&vcc_io>; + gpio1830-supply = <&vcc_io>; lcdc-supply = <&vcc_io>; sdcard-supply = <&vccio_sd>; wifi-supply = <&vcc_18>; diff --git a/arch/arm/boot/dts/rk3288-vyasa.dts b/arch/arm/boot/dts/rk3288-vyasa.dts index aa50f8ed4ca0..b156a83eb7d7 100644 --- a/arch/arm/boot/dts/rk3288-vyasa.dts +++ b/arch/arm/boot/dts/rk3288-vyasa.dts @@ -379,10 +379,10 @@ audio-supply = <&vcc_18>; bb-supply = <&vcc_io>; dvp-supply = <&vcc_io>; - flash0-suuply = <&vcc_18>; + flash0-supply = <&vcc_18>; flash1-supply = <&vcc_lan>; gpio30-supply = <&vcc_io>; - gpio1830 = <&vcc_io>; + gpio1830-supply = <&vcc_io>; lcdc-supply = <&vcc_io>; sdcard-supply = <&vccio_sd>; wifi-supply = <&vcc_18>; diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 68d5a58cfe88..0d89ad274268 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -240,8 +240,8 @@ compatible = "rockchip,rk3288-timer"; reg = <0x0 0xff810000 0x0 0x20>; interrupts = ; - clocks = <&xin24m>, <&cru PCLK_TIMER>; - clock-names = "timer", "pclk"; + clocks = <&cru PCLK_TIMER>, <&xin24m>; + clock-names = "pclk", "timer"; }; display-subsystem { @@ -788,7 +788,7 @@ * *_HDMI HDMI * *_MIPI_* MIPI */ - pd_vio@RK3288_PD_VIO { + power-domain@RK3288_PD_VIO { reg = ; clocks = <&cru ACLK_IEP>, <&cru ACLK_ISP>, @@ -830,7 +830,7 @@ * Note: The following 3 are HEVC(H.265) clocks, * and on the ACLK_HEVC_NIU (NOC). */ - pd_hevc@RK3288_PD_HEVC { + power-domain@RK3288_PD_HEVC { reg = ; clocks = <&cru ACLK_HEVC>, <&cru SCLK_HEVC_CABAC>, @@ -844,7 +844,7 @@ * (video endecoder & decoder) clocks that on the * ACLK_VCODEC_NIU and HCLK_VCODEC_NIU (NOC). */ - pd_video@RK3288_PD_VIDEO { + power-domain@RK3288_PD_VIDEO { reg = ; clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; @@ -855,7 +855,7 @@ * Note: ACLK_GPU is the GPU clock, * and on the ACLK_GPU_NIU (NOC). */ - pd_gpu@RK3288_PD_GPU { + power-domain@RK3288_PD_GPU { reg = ; clocks = <&cru ACLK_GPU>; pm_qos = <&qos_gpu_r>, @@ -1593,7 +1593,7 @@ drive-strength = <12>; }; - sleep { + suspend { global_pwroff: global-pwroff { rockchip,pins = <0 RK_PA0 1 &pcfg_pull_none>; }; diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi index 04f24cf752d3..e5c2c52013e3 100644 --- a/arch/arm/boot/dts/sama5d4.dtsi +++ b/arch/arm/boot/dts/sama5d4.dtsi @@ -809,7 +809,7 @@ 0xffffffff 0x3ffcfe7c 0x1c010101 /* pioA */ 0x7fffffff 0xfffccc3a 0x3f00cc3a /* pioB */ 0xffffffff 0x3ff83fff 0xff00ffff /* pioC */ - 0x0003ff00 0x8002a800 0x00000000 /* pioD */ + 0xb003ff00 0x8002a800 0x00000000 /* pioD */ 0xffffffff 0x7fffffff 0x76fff1bf /* pioE */ >; diff --git a/arch/arm/boot/dts/ste-ab8500.dtsi b/arch/arm/boot/dts/ste-ab8500.dtsi index aab5719cc1a9..16d50369226a 100644 --- a/arch/arm/boot/dts/ste-ab8500.dtsi +++ b/arch/arm/boot/dts/ste-ab8500.dtsi @@ -34,7 +34,7 @@ #clock-cells = <1>; }; - ab8500_gpio: ab8500-gpio { + ab8500_gpio: ab8500-gpiocontroller { compatible = "stericsson,ab8500-gpio"; gpio-controller; #gpio-cells = <2>; @@ -42,15 +42,15 @@ ab8500-rtc { compatible = "stericsson,ab8500-rtc"; - interrupts = <17 IRQ_TYPE_LEVEL_HIGH - 18 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH>, + <18 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "60S", "ALARM"; }; gpadc: ab8500-gpadc { compatible = "stericsson,ab8500-gpadc"; - interrupts = <32 IRQ_TYPE_LEVEL_HIGH - 39 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <32 IRQ_TYPE_LEVEL_HIGH>, + <39 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "HW_CONV_END", "SW_CONV_END"; vddadc-supply = <&ab8500_ldo_tvout_reg>; #address-cells = <1>; @@ -169,13 +169,13 @@ ab8500_usb { compatible = "stericsson,ab8500-usb"; - interrupts = < 90 IRQ_TYPE_LEVEL_HIGH - 96 IRQ_TYPE_LEVEL_HIGH - 14 IRQ_TYPE_LEVEL_HIGH - 15 IRQ_TYPE_LEVEL_HIGH - 79 IRQ_TYPE_LEVEL_HIGH - 74 IRQ_TYPE_LEVEL_HIGH - 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <90 IRQ_TYPE_LEVEL_HIGH>, + <96 IRQ_TYPE_LEVEL_HIGH>, + <14 IRQ_TYPE_LEVEL_HIGH>, + <15 IRQ_TYPE_LEVEL_HIGH>, + <79 IRQ_TYPE_LEVEL_HIGH>, + <74 IRQ_TYPE_LEVEL_HIGH>, + <75 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "ID_WAKEUP_R", "ID_WAKEUP_F", "VBUS_DET_F", @@ -192,8 +192,8 @@ ab8500-ponkey { compatible = "stericsson,ab8500-poweron-key"; - interrupts = <6 IRQ_TYPE_LEVEL_HIGH - 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <6 IRQ_TYPE_LEVEL_HIGH>, + <7 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "ONKEY_DBF", "ONKEY_DBR"; }; diff --git a/arch/arm/boot/dts/ste-ab8505.dtsi b/arch/arm/boot/dts/ste-ab8505.dtsi index 67bc69e67b33..8d2cda0b4d62 100644 --- a/arch/arm/boot/dts/ste-ab8505.dtsi +++ b/arch/arm/boot/dts/ste-ab8505.dtsi @@ -30,7 +30,7 @@ #clock-cells = <1>; }; - ab8505_gpio: ab8505-gpio { + ab8505_gpio: ab8505-gpiocontroller { compatible = "stericsson,ab8505-gpio"; gpio-controller; #gpio-cells = <2>; @@ -38,8 +38,8 @@ ab8500-rtc { compatible = "stericsson,ab8500-rtc"; - interrupts = <17 IRQ_TYPE_LEVEL_HIGH - 18 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH>, + <18 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "60S", "ALARM"; }; @@ -131,13 +131,13 @@ ab8500_usb: ab8500_usb { compatible = "stericsson,ab8500-usb"; - interrupts = < 90 IRQ_TYPE_LEVEL_HIGH - 96 IRQ_TYPE_LEVEL_HIGH - 14 IRQ_TYPE_LEVEL_HIGH - 15 IRQ_TYPE_LEVEL_HIGH - 79 IRQ_TYPE_LEVEL_HIGH - 74 IRQ_TYPE_LEVEL_HIGH - 75 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <90 IRQ_TYPE_LEVEL_HIGH>, + <96 IRQ_TYPE_LEVEL_HIGH>, + <14 IRQ_TYPE_LEVEL_HIGH>, + <15 IRQ_TYPE_LEVEL_HIGH>, + <79 IRQ_TYPE_LEVEL_HIGH>, + <74 IRQ_TYPE_LEVEL_HIGH>, + <75 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "ID_WAKEUP_R", "ID_WAKEUP_F", "VBUS_DET_F", @@ -154,8 +154,8 @@ ab8500-ponkey { compatible = "stericsson,ab8500-poweron-key"; - interrupts = <6 IRQ_TYPE_LEVEL_HIGH - 7 IRQ_TYPE_LEVEL_HIGH>; + interrupts = <6 IRQ_TYPE_LEVEL_HIGH>, + <7 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "ONKEY_DBF", "ONKEY_DBR"; }; diff --git a/arch/arm/boot/dts/ste-href-ab8500.dtsi b/arch/arm/boot/dts/ste-href-ab8500.dtsi index 4946743de7b9..3ccb7b5c7162 100644 --- a/arch/arm/boot/dts/ste-href-ab8500.dtsi +++ b/arch/arm/boot/dts/ste-href-ab8500.dtsi @@ -9,7 +9,7 @@ soc { prcmu@80157000 { ab8500 { - ab8500-gpio { + ab8500-gpiocontroller { /* Hog a few default settings */ pinctrl-names = "default"; pinctrl-0 = <&gpio2_default_mode>, diff --git a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi index c0de1337bdaa..457bddabc32c 100644 --- a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi +++ b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi @@ -19,6 +19,9 @@ <19 IRQ_TYPE_EDGE_RISING>; pinctrl-names = "default"; pinctrl-0 = <&accel_tvk_mode>; + mount-matrix = "0", "-1", "0", + "-1", "0", "0", + "0", "0", "-1"; }; magnetometer@1e { compatible = "st,lsm303dlm-magn"; diff --git a/arch/arm/boot/dts/ste-href.dtsi b/arch/arm/boot/dts/ste-href.dtsi index ff47cbf6ed3b..3586b5d7876a 100644 --- a/arch/arm/boot/dts/ste-href.dtsi +++ b/arch/arm/boot/dts/ste-href.dtsi @@ -4,6 +4,7 @@ */ #include +#include #include "ste-href-family-pinctrl.dtsi" / { @@ -64,17 +65,20 @@ reg = <0>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; + color = ; linux,default-trigger = "heartbeat"; }; chan@1 { reg = <1>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; + color = ; }; chan@2 { reg = <2>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; + color = ; }; }; lp5521@34 { @@ -88,16 +92,19 @@ reg = <0>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; + color = ; }; chan@1 { reg = <1>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; + color = ; }; chan@2 { reg = <2>; led-cur = /bits/ 8 <0x2f>; max-cur = /bits/ 8 <0x5f>; + color = ; }; }; bh1780@29 { @@ -217,7 +224,7 @@ prcmu@80157000 { ab8500 { - ab8500-gpio { + ab8500-gpiocontroller { }; ab8500_usb { diff --git a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi index 4f38aeecadb3..42abea3ea92c 100644 --- a/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi +++ b/arch/arm/boot/dts/ste-nomadik-stn8815.dtsi @@ -755,14 +755,14 @@ status = "disabled"; }; - vica: intc@10140000 { + vica: interrupt-controller@10140000 { compatible = "arm,versatile-vic"; interrupt-controller; #interrupt-cells = <1>; reg = <0x10140000 0x20>; }; - vicb: intc@10140020 { + vicb: interrupt-controller@10140020 { compatible = "arm,versatile-vic"; interrupt-controller; #interrupt-cells = <1>; diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts index 27d8a07718a0..f6e0d71f6c09 100644 --- a/arch/arm/boot/dts/ste-snowball.dts +++ b/arch/arm/boot/dts/ste-snowball.dts @@ -376,7 +376,7 @@ prcmu@80157000 { ab8500 { - ab8500-gpio { + ab8500-gpiocontroller { /* * AB8500 GPIOs are numbered starting from 1, so the first * index 0 is what in the datasheet is called "GPIO1", and diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts index 67e7648de41e..8b0ead46ef9b 100644 --- a/arch/arm/boot/dts/stm32429i-eval.dts +++ b/arch/arm/boot/dts/stm32429i-eval.dts @@ -119,17 +119,15 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "Wake up"; linux,code = ; gpios = <&gpioa 0 0>; }; - button@1 { + button-1 { label = "Tamper"; linux,code = ; gpios = <&gpioc 13 0>; diff --git a/arch/arm/boot/dts/stm32746g-eval.dts b/arch/arm/boot/dts/stm32746g-eval.dts index ca8c192449ee..327613fd9666 100644 --- a/arch/arm/boot/dts/stm32746g-eval.dts +++ b/arch/arm/boot/dts/stm32746g-eval.dts @@ -81,12 +81,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "Wake up"; linux,code = ; gpios = <&gpioc 13 0>; diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts index 3dc068b91ca1..075ac57d0bf4 100644 --- a/arch/arm/boot/dts/stm32f429-disco.dts +++ b/arch/arm/boot/dts/stm32f429-disco.dts @@ -81,12 +81,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 0>; diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi index ad715a0e1c9a..0dc5fa94dbdf 100644 --- a/arch/arm/boot/dts/stm32f429.dtsi +++ b/arch/arm/boot/dts/stm32f429.dtsi @@ -283,8 +283,6 @@ }; timers13: timers@40001c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40001C00 0x400>; clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM13)>; @@ -299,8 +297,6 @@ }; timers14: timers@40002000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40002000 0x400>; clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM14)>; @@ -633,8 +629,6 @@ }; timers10: timers@40014400 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014400 0x400>; clocks = <&rcc 0 STM32F4_APB2_CLOCK(TIM10)>; @@ -649,8 +643,6 @@ }; timers11: timers@40014800 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014800 0x400>; clocks = <&rcc 0 STM32F4_APB2_CLOCK(TIM11)>; @@ -709,7 +701,7 @@ status = "disabled"; }; - rcc: rcc@40023810 { + rcc: rcc@40023800 { #reset-cells = <1>; #clock-cells = <2>; compatible = "st,stm32f42xx-rcc", "st,stm32-rcc"; diff --git a/arch/arm/boot/dts/stm32f469-disco.dts b/arch/arm/boot/dts/stm32f469-disco.dts index 2e1b3bbbe4b5..8c982ae79f43 100644 --- a/arch/arm/boot/dts/stm32f469-disco.dts +++ b/arch/arm/boot/dts/stm32f469-disco.dts @@ -104,12 +104,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; diff --git a/arch/arm/boot/dts/stm32f746.dtsi b/arch/arm/boot/dts/stm32f746.dtsi index 640ff54ed00c..d49e481b3aa6 100644 --- a/arch/arm/boot/dts/stm32f746.dtsi +++ b/arch/arm/boot/dts/stm32f746.dtsi @@ -265,8 +265,6 @@ }; timers13: timers@40001c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40001C00 0x400>; clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM13)>; @@ -281,8 +279,6 @@ }; timers14: timers@40002000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40002000 0x400>; clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM14)>; @@ -364,9 +360,9 @@ status = "disabled"; }; - i2c3: i2c@40005C00 { + i2c3: i2c@40005c00 { compatible = "st,stm32f7-i2c"; - reg = <0x40005C00 0x400>; + reg = <0x40005c00 0x400>; interrupts = <72>, <73>; resets = <&rcc STM32F7_APB1_RESET(I2C3)>; @@ -531,8 +527,6 @@ }; timers10: timers@40014400 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014400 0x400>; clocks = <&rcc 0 STM32F7_APB2_CLOCK(TIM10)>; @@ -547,8 +541,6 @@ }; timers11: timers@40014800 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014800 0x400>; clocks = <&rcc 0 STM32F7_APB2_CLOCK(TIM11)>; diff --git a/arch/arm/boot/dts/stm32f769-disco.dts b/arch/arm/boot/dts/stm32f769-disco.dts index 0ce7fbc20fa4..be943b701980 100644 --- a/arch/arm/boot/dts/stm32f769-disco.dts +++ b/arch/arm/boot/dts/stm32f769-disco.dts @@ -75,12 +75,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; diff --git a/arch/arm/boot/dts/stm32h743.dtsi b/arch/arm/boot/dts/stm32h743.dtsi index 7febe19e780d..1579707ea566 100644 --- a/arch/arm/boot/dts/stm32h743.dtsi +++ b/arch/arm/boot/dts/stm32h743.dtsi @@ -454,8 +454,6 @@ }; lptimer4: timer@58002c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x58002c00 0x400>; clocks = <&rcc LPTIM4_CK>; @@ -470,8 +468,6 @@ }; lptimer5: timer@58003000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x58003000 0x400>; clocks = <&rcc LPTIM5_CK>; diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi index 84757901cd8d..b479016fef00 100644 --- a/arch/arm/boot/dts/stm32mp151.dtsi +++ b/arch/arm/boot/dts/stm32mp151.dtsi @@ -1395,12 +1395,6 @@ status = "disabled"; }; - stmmac_axi_config_0: stmmac-axi-config { - snps,wr_osr_lmt = <0x7>; - snps,rd_osr_lmt = <0x7>; - snps,blen = <0 0 0 0 16 8 4>; - }; - ethernet0: ethernet@5800a000 { compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a"; reg = <0x5800a000 0x2000>; @@ -1424,6 +1418,12 @@ snps,axi-config = <&stmmac_axi_config_0>; snps,tso; status = "disabled"; + + stmmac_axi_config_0: stmmac-axi-config { + snps,wr_osr_lmt = <0x7>; + snps,rd_osr_lmt = <0x7>; + snps,blen = <0 0 0 0 16 8 4>; + }; }; usbh_ohci: usbh-ohci@5800c000 { diff --git a/arch/arm/boot/dts/stm32mp157a-stinger96.dtsi b/arch/arm/boot/dts/stm32mp157a-stinger96.dtsi index 58275bcf9e26..4dd138d691c7 100644 --- a/arch/arm/boot/dts/stm32mp157a-stinger96.dtsi +++ b/arch/arm/boot/dts/stm32mp157a-stinger96.dtsi @@ -184,8 +184,6 @@ vdd_usb: ldo4 { regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; interrupts = ; }; @@ -208,7 +206,6 @@ vref_ddr: vref_ddr { regulator-name = "vref_ddr"; regulator-always-on; - regulator-over-current-protection; }; bst_out: boost { @@ -219,13 +216,13 @@ vbus_otg: pwr_sw1 { regulator-name = "vbus_otg"; interrupts = ; - regulator-active-discharge; + regulator-active-discharge = <1>; }; vbus_sw: pwr_sw2 { regulator-name = "vbus_sw"; interrupts = ; - regulator-active-discharge; + regulator-active-discharge = <1>; }; }; diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi index 6cf49a0a9e69..2d9461006810 100644 --- a/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi +++ b/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi @@ -173,8 +173,6 @@ vdd_usb: ldo4 { regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; interrupts = ; }; @@ -197,7 +195,6 @@ vref_ddr: vref_ddr { regulator-name = "vref_ddr"; regulator-always-on; - regulator-over-current-protection; }; bst_out: boost { @@ -213,7 +210,7 @@ vbus_sw: pwr_sw2 { regulator-name = "vbus_sw"; interrupts = ; - regulator-active-discharge; + regulator-active-discharge = <1>; }; }; @@ -269,7 +266,7 @@ st,neg-edge; bus-width = <8>; vmmc-supply = <&v3v3>; - vqmmc-supply = <&v3v3>; + vqmmc-supply = <&vdd>; mmc-ddr-3_3v; status = "okay"; }; diff --git a/arch/arm/boot/dts/stm32mp157c-odyssey.dts b/arch/arm/boot/dts/stm32mp157c-odyssey.dts index a7ffec8f1516..be1dd5e9e744 100644 --- a/arch/arm/boot/dts/stm32mp157c-odyssey.dts +++ b/arch/arm/boot/dts/stm32mp157c-odyssey.dts @@ -64,7 +64,7 @@ pinctrl-0 = <&sdmmc1_b4_pins_a>; pinctrl-1 = <&sdmmc1_b4_od_pins_a>; pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; - cd-gpios = <&gpiob 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + cd-gpios = <&gpioi 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; disable-wp; st,neg-edge; bus-width = <4>; diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi index 8456f172d4b1..633079245601 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-pdk2.dtsi @@ -34,11 +34,10 @@ gpio-keys-polled { compatible = "gpio-keys-polled"; - #size-cells = <0>; poll-interval = <20>; /* - * The EXTi IRQ line 3 is shared with touchscreen and ethernet, + * The EXTi IRQ line 3 is shared with ethernet, * so mark this as polled GPIO key. */ button-0 { @@ -47,6 +46,16 @@ gpios = <&gpiof 3 GPIO_ACTIVE_LOW>; }; + /* + * The EXTi IRQ line 6 is shared with touchscreen, + * so mark this as polled GPIO key. + */ + button-1 { + label = "TA2-GPIO-B"; + linux,code = ; + gpios = <&gpiod 6 GPIO_ACTIVE_LOW>; + }; + /* * The EXTi IRQ line 0 is shared with PMIC, * so mark this as polled GPIO key. @@ -60,14 +69,6 @@ gpio-keys { compatible = "gpio-keys"; - #size-cells = <0>; - - button-1 { - label = "TA2-GPIO-B"; - linux,code = ; - gpios = <&gpiod 6 GPIO_ACTIVE_LOW>; - wakeup-source; - }; button-3 { label = "TA4-GPIO-D"; @@ -84,6 +85,7 @@ label = "green:led5"; gpios = <&gpioc 6 GPIO_ACTIVE_HIGH>; default-state = "off"; + status = "disabled"; }; led-1 { @@ -184,12 +186,11 @@ }; - polytouch@38 { - compatible = "edt,edt-ft5x06"; + touchscreen@38 { + compatible = "edt,edt-ft5406"; reg = <0x38>; - interrupt-parent = <&gpiog>; - interrupts = <2 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */ - linux,wakeup; + interrupt-parent = <&gpioc>; + interrupts = <6 IRQ_TYPE_EDGE_FALLING>; /* GPIO E */ }; }; diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi index 2d027dafb7bc..000af7177701 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi @@ -118,7 +118,6 @@ max-speed = <100>; phy-handle = <&phy0>; st,eth-ref-clk-sel; - phy-reset-gpios = <&gpioh 3 GPIO_ACTIVE_LOW>; mdio0 { #address-cells = <1>; @@ -127,6 +126,16 @@ phy0: ethernet-phy@1 { reg = <1>; + /* LAN8710Ai */ + compatible = "ethernet-phy-id0007.c0f0", + "ethernet-phy-ieee802.3-c22"; + clocks = <&rcc ETHCK_K>; + reset-gpios = <&gpioh 3 GPIO_ACTIVE_LOW>; + reset-assert-us = <500>; + reset-deassert-us = <500>; + smsc,disable-energy-detect; + interrupt-parent = <&gpioi>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; }; }; }; @@ -226,8 +235,6 @@ vdd_usb: ldo4 { regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; interrupts = ; }; @@ -249,7 +256,6 @@ vref_ddr: vref_ddr { regulator-name = "vref_ddr"; regulator-always-on; - regulator-over-current-protection; }; bst_out: boost { @@ -265,7 +271,7 @@ vbus_sw: pwr_sw2 { regulator-name = "vbus_sw"; interrupts = ; - regulator-active-discharge; + regulator-active-discharge = <1>; }; }; @@ -330,7 +336,7 @@ #size-cells = <0>; status = "okay"; - flash0: mx66l51235l@0 { + flash0: flash@0 { compatible = "jedec,spi-nor"; reg = <0>; spi-rx-bus-width = <4>; diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi index 803eb8bc9c85..a9eb82b2f170 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi @@ -194,7 +194,7 @@ #size-cells = <0>; status = "okay"; - flash0: spi-flash@0 { + flash0: flash@0 { compatible = "jedec,spi-nor"; reg = <0>; spi-rx-bus-width = <4>; diff --git a/arch/arm/boot/dts/stm32mp15xx-osd32.dtsi b/arch/arm/boot/dts/stm32mp15xx-osd32.dtsi index 713485a95795..6706d8311a66 100644 --- a/arch/arm/boot/dts/stm32mp15xx-osd32.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-osd32.dtsi @@ -146,8 +146,6 @@ vdd_usb: ldo4 { regulator-name = "vdd_usb"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; interrupts = ; }; @@ -171,7 +169,6 @@ vref_ddr: vref_ddr { regulator-name = "vref_ddr"; regulator-always-on; - regulator-over-current-protection; }; bst_out: boost { @@ -182,13 +179,13 @@ vbus_otg: pwr_sw1 { regulator-name = "vbus_otg"; interrupts = ; - regulator-active-discharge; + regulator-active-discharge = <1>; }; vbus_sw: pwr_sw2 { regulator-name = "vbus_sw"; interrupts = ; - regulator-active-discharge; + regulator-active-discharge = <1>; }; }; diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts index 97f497854e05..d05fa679dcd3 100644 --- a/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts +++ b/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts @@ -85,7 +85,7 @@ pinctrl-0 = <&emac_rgmii_pins>; phy-supply = <®_gmac_3v3>; phy-handle = <&ext_rgmii_phy>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; status = "okay"; }; diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts index 068aabcffb13..5d0f0fbba1d2 100644 --- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts +++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts @@ -1009,7 +1009,7 @@ nvidia,audio-codec = <&wm8903>; nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>; - nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>; + nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>; nvidia,int-mic-en-gpios = <&wm8903 1 GPIO_ACTIVE_HIGH>; nvidia,headset; diff --git a/arch/arm/boot/dts/tegra20-harmony.dts b/arch/arm/boot/dts/tegra20-harmony.dts index 86494cb4d5a1..ae4312eedcbd 100644 --- a/arch/arm/boot/dts/tegra20-harmony.dts +++ b/arch/arm/boot/dts/tegra20-harmony.dts @@ -748,7 +748,7 @@ nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>; nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) - GPIO_ACTIVE_HIGH>; + GPIO_ACTIVE_LOW>; nvidia,int-mic-en-gpios = <&gpio TEGRA_GPIO(X, 0) GPIO_ACTIVE_HIGH>; nvidia,ext-mic-en-gpios = <&gpio TEGRA_GPIO(X, 1) diff --git a/arch/arm/boot/dts/tegra20-medcom-wide.dts b/arch/arm/boot/dts/tegra20-medcom-wide.dts index a348ca30e522..b31c9bca16e6 100644 --- a/arch/arm/boot/dts/tegra20-medcom-wide.dts +++ b/arch/arm/boot/dts/tegra20-medcom-wide.dts @@ -84,7 +84,7 @@ nvidia,audio-codec = <&wm8903>; nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>; - nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>; + nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>; clocks = <&tegra_car TEGRA20_CLK_PLL_A>, <&tegra_car TEGRA20_CLK_PLL_A_OUT0>, diff --git a/arch/arm/boot/dts/tegra20-plutux.dts b/arch/arm/boot/dts/tegra20-plutux.dts index 378f23b2958b..5811b7006a9b 100644 --- a/arch/arm/boot/dts/tegra20-plutux.dts +++ b/arch/arm/boot/dts/tegra20-plutux.dts @@ -52,7 +52,7 @@ nvidia,audio-codec = <&wm8903>; nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>; - nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>; + nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>; clocks = <&tegra_car TEGRA20_CLK_PLL_A>, <&tegra_car TEGRA20_CLK_PLL_A_OUT0>, diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts index c24d4a37613e..92d494b8c3d2 100644 --- a/arch/arm/boot/dts/tegra20-seaboard.dts +++ b/arch/arm/boot/dts/tegra20-seaboard.dts @@ -911,7 +911,7 @@ nvidia,audio-codec = <&wm8903>; nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>; - nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(X, 1) GPIO_ACTIVE_HIGH>; + nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(X, 1) GPIO_ACTIVE_LOW>; clocks = <&tegra_car TEGRA20_CLK_PLL_A>, <&tegra_car TEGRA20_CLK_PLL_A_OUT0>, diff --git a/arch/arm/boot/dts/tegra20-tec.dts b/arch/arm/boot/dts/tegra20-tec.dts index 44ced60315de..10ff09d86efa 100644 --- a/arch/arm/boot/dts/tegra20-tec.dts +++ b/arch/arm/boot/dts/tegra20-tec.dts @@ -61,7 +61,7 @@ nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>; nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) - GPIO_ACTIVE_HIGH>; + GPIO_ACTIVE_LOW>; clocks = <&tegra_car TEGRA20_CLK_PLL_A>, <&tegra_car TEGRA20_CLK_PLL_A_OUT0>, diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts index 055334ae3d28..fe400fb84f02 100644 --- a/arch/arm/boot/dts/tegra20-ventana.dts +++ b/arch/arm/boot/dts/tegra20-ventana.dts @@ -686,7 +686,7 @@ nvidia,audio-codec = <&wm8903>; nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>; - nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_HIGH>; + nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>; nvidia,int-mic-en-gpios = <&gpio TEGRA_GPIO(X, 0) GPIO_ACTIVE_HIGH>; nvidia,ext-mic-en-gpios = <&gpio TEGRA_GPIO(X, 1) diff --git a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-ti-pmic.dtsi b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-ti-pmic.dtsi index bfc06b988781..215e497652d8 100644 --- a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-ti-pmic.dtsi +++ b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-ti-pmic.dtsi @@ -143,7 +143,7 @@ }; vdd_3v3_sys: regulator@1 { - gpio = <&pmic 7 GPIO_ACTIVE_HIGH>; + gpio = <&pmic 6 GPIO_ACTIVE_HIGH>; enable-active-high; }; }; diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi index dab9989fa760..57aead7d8162 100644 --- a/arch/arm/boot/dts/tegra30-cardhu.dtsi +++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi @@ -589,7 +589,7 @@ nvidia,spkr-en-gpios = <&wm8903 2 GPIO_ACTIVE_HIGH>; nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(W, 2) - GPIO_ACTIVE_HIGH>; + GPIO_ACTIVE_LOW>; clocks = <&tegra_car TEGRA30_CLK_PLL_A>, <&tegra_car TEGRA30_CLK_PLL_A_OUT0>, diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts index 37bd41ff8dff..151c0220047d 100644 --- a/arch/arm/boot/dts/versatile-ab.dts +++ b/arch/arm/boot/dts/versatile-ab.dts @@ -195,16 +195,15 @@ #size-cells = <1>; ranges; - vic: intc@10140000 { + vic: interrupt-controller@10140000 { compatible = "arm,versatile-vic"; interrupt-controller; #interrupt-cells = <1>; reg = <0x10140000 0x1000>; - clear-mask = <0xffffffff>; valid-mask = <0xffffffff>; }; - sic: intc@10003000 { + sic: interrupt-controller@10003000 { compatible = "arm,versatile-sic"; interrupt-controller; #interrupt-cells = <1>; diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts index 06a0fdf24026..e7e751a858d8 100644 --- a/arch/arm/boot/dts/versatile-pb.dts +++ b/arch/arm/boot/dts/versatile-pb.dts @@ -7,7 +7,7 @@ amba { /* The Versatile PB is using more SIC IRQ lines than the AB */ - sic: intc@10003000 { + sic: interrupt-controller@10003000 { clear-mask = <0xffffffff>; /* * Valid interrupt lines mask according to diff --git a/arch/arm/include/asm/archrandom.h b/arch/arm/include/asm/archrandom.h new file mode 100644 index 000000000000..a8e84ca5c2ee --- /dev/null +++ b/arch/arm/include/asm/archrandom.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ARCHRANDOM_H +#define _ASM_ARCHRANDOM_H + +static inline bool __init smccc_probe_trng(void) +{ + return false; +} + +#endif /* _ASM_ARCHRANDOM_H */ diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h index 0d67ed682e07..bc4ffa7ca04c 100644 --- a/arch/arm/include/asm/cpuidle.h +++ b/arch/arm/include/asm/cpuidle.h @@ -7,9 +7,11 @@ #ifdef CONFIG_CPU_IDLE extern int arm_cpuidle_simple_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); +#define __cpuidle_method_section __used __section("__cpuidle_method_of_table") #else static inline int arm_cpuidle_simple_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { return -ENODEV; } +#define __cpuidle_method_section __maybe_unused /* drop silently */ #endif /* Common ARM WFI state */ @@ -42,8 +44,7 @@ struct of_cpuidle_method { #define CPUIDLE_METHOD_OF_DECLARE(name, _method, _ops) \ static const struct of_cpuidle_method __cpuidle_method_of_table_##name \ - __used __section("__cpuidle_method_of_table") \ - = { .method = _method, .ops = _ops } + __cpuidle_method_section = { .method = _method, .ops = _ops } extern int arm_cpuidle_suspend(int index); diff --git a/arch/arm/include/asm/hypervisor.h b/arch/arm/include/asm/hypervisor.h index df8524365637..bd61502b9715 100644 --- a/arch/arm/include/asm/hypervisor.h +++ b/arch/arm/include/asm/hypervisor.h @@ -4,4 +4,7 @@ #include +void kvm_init_hyp_services(void); +bool kvm_arm_hyp_service_available(u32 func_id); + #endif diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c index 2924d7910b10..eb2190477da1 100644 --- a/arch/arm/kernel/perf_event_v7.c +++ b/arch/arm/kernel/perf_event_v7.c @@ -773,10 +773,10 @@ static inline void armv7pmu_write_counter(struct perf_event *event, u64 value) pr_err("CPU%u writing wrong counter %d\n", smp_processor_id(), idx); } else if (idx == ARMV7_IDX_CYCLE_COUNTER) { - asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value)); + asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" ((u32)value)); } else { armv7_pmnc_select_counter(idx); - asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value)); + asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" ((u32)value)); } } diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 4f17074f26b6..b0e2e31c9856 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -544,9 +544,11 @@ void notrace cpu_init(void) * In Thumb-2, msr with an immediate value is not allowed. */ #ifdef CONFIG_THUMB2_KERNEL -#define PLC "r" +#define PLC_l "l" +#define PLC_r "r" #else -#define PLC "I" +#define PLC_l "I" +#define PLC_r "I" #endif /* @@ -568,15 +570,15 @@ void notrace cpu_init(void) "msr cpsr_c, %9" : : "r" (stk), - PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), "I" (offsetof(struct stack, irq[0])), - PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | ABT_MODE), "I" (offsetof(struct stack, abt[0])), - PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | UND_MODE), "I" (offsetof(struct stack, und[0])), - PLC (PSR_F_BIT | PSR_I_BIT | FIQ_MODE), + PLC_r (PSR_F_BIT | PSR_I_BIT | FIQ_MODE), "I" (offsetof(struct stack, fiq[0])), - PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE) + PLC_l (PSR_F_BIT | PSR_I_BIT | SVC_MODE) : "r14"); #endif } diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index ba27e184402a..123432bb500e 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -436,7 +436,6 @@ asmlinkage void secondary_start_kernel(void) #endif pr_debug("CPU%u: Booted secondary processor\n", cpu); - preempt_disable(); trace_hardirqs_off(); /* diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index 700763e07083..83d1d1327f96 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -55,6 +55,7 @@ void __init exynos_sysram_init(void) sysram_base_addr = of_iomap(node, 0); sysram_base_phys = of_translate_address(node, of_get_address(node, 0, NULL, NULL)); + of_node_put(node); break; } @@ -62,6 +63,7 @@ void __init exynos_sysram_init(void) if (!of_device_is_available(node)) continue; sysram_ns_base_addr = of_iomap(node, 0); + of_node_put(node); break; } } diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index 0dfd0ae7a63d..af12668d0bf5 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c @@ -103,6 +103,7 @@ struct mmdc_pmu { struct perf_event *mmdc_events[MMDC_NUM_COUNTERS]; struct hlist_node node; struct fsl_mmdc_devtype_data *devtype_data; + struct clk *mmdc_ipg_clk; }; /* @@ -462,11 +463,14 @@ static int imx_mmdc_remove(struct platform_device *pdev) cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); perf_pmu_unregister(&pmu_mmdc->pmu); + iounmap(pmu_mmdc->mmdc_base); + clk_disable_unprepare(pmu_mmdc->mmdc_ipg_clk); kfree(pmu_mmdc); return 0; } -static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_base) +static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_base, + struct clk *mmdc_ipg_clk) { struct mmdc_pmu *pmu_mmdc; char *name; @@ -494,6 +498,7 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b } mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev); + pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; if (mmdc_num == 0) name = "mmdc"; else @@ -529,7 +534,7 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b #else #define imx_mmdc_remove NULL -#define imx_mmdc_perf_init(pdev, mmdc_base) 0 +#define imx_mmdc_perf_init(pdev, mmdc_base, mmdc_ipg_clk) 0 #endif static int imx_mmdc_probe(struct platform_device *pdev) @@ -567,7 +572,13 @@ static int imx_mmdc_probe(struct platform_device *pdev) val &= ~(1 << BP_MMDC_MAPSR_PSD); writel_relaxed(val, reg); - return imx_mmdc_perf_init(pdev, mmdc_base); + err = imx_mmdc_perf_init(pdev, mmdc_base, mmdc_ipg_clk); + if (err) { + iounmap(mmdc_base); + clk_disable_unprepare(mmdc_ipg_clk); + } + + return err; } int imx_mmdc_get_ddr_type(void) diff --git a/arch/arm/mach-imx/suspend-imx53.S b/arch/arm/mach-imx/suspend-imx53.S index 41b8aad65363..46570ec2fbcf 100644 --- a/arch/arm/mach-imx/suspend-imx53.S +++ b/arch/arm/mach-imx/suspend-imx53.S @@ -28,11 +28,11 @@ * ^ * ^ * imx53_suspend code - * PM_INFO structure(imx53_suspend_info) + * PM_INFO structure(imx5_cpu_suspend_info) * ======================== low address ======================= */ -/* Offsets of members of struct imx53_suspend_info */ +/* Offsets of members of struct imx5_cpu_suspend_info */ #define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0 #define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4 #define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8 diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 2ee527c00284..1026a816dcc0 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -458,20 +458,6 @@ static struct gpiod_lookup_table leds_gpio_table = { #ifdef CONFIG_LEDS_TRIGGERS DEFINE_LED_TRIGGER(ams_delta_camera_led_trigger); - -static int ams_delta_camera_power(struct device *dev, int power) -{ - /* - * turn on camera LED - */ - if (power) - led_trigger_event(ams_delta_camera_led_trigger, LED_FULL); - else - led_trigger_event(ams_delta_camera_led_trigger, LED_OFF); - return 0; -} -#else -#define ams_delta_camera_power NULL #endif static struct platform_device ams_delta_audio_device = { diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 2c1e2b32b9b3..a745d64d4699 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -655,9 +655,13 @@ static int __init omap_pm_init(void) irq = INT_7XX_WAKE_UP_REQ; else if (cpu_is_omap16xx()) irq = INT_1610_WAKE_UP_REQ; - if (request_irq(irq, omap_wakeup_interrupt, 0, "peripheral wakeup", - NULL)) - pr_err("Failed to request irq %d (peripheral wakeup)\n", irq); + else + irq = -1; + + if (irq >= 0) { + if (request_irq(irq, omap_wakeup_interrupt, 0, "peripheral wakeup", NULL)) + pr_err("Failed to request irq %d (peripheral wakeup)\n", irq); + } /* Program new power ramp-up time * (0 for most boards since we don't lower voltage when in deep sleep) diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 418a61ecb827..5e86145db0e2 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -322,6 +322,7 @@ static int n8x0_mmc_get_cover_state(struct device *dev, int slot) static void n8x0_mmc_callback(void *data, u8 card_mask) { +#ifdef CONFIG_MMC_OMAP int bit, *openp, index; if (board_is_n800()) { @@ -339,7 +340,6 @@ static void n8x0_mmc_callback(void *data, u8 card_mask) else *openp = 0; -#ifdef CONFIG_MMC_OMAP omap_mmc_notify_cover_event(mmc_device, index, *openp); #else pr_warn("MMC: notify cover event not available\n"); diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 15b29a179c8a..83d595ebcf1f 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3777,6 +3777,7 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh) struct omap_hwmod_ocp_if *oi; struct clockdomain *clkdm; struct clk_hw_omap *clk; + struct clk_hw *hw; if (!oh) return NULL; @@ -3793,7 +3794,14 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh) c = oi->_clk; } - clk = to_clk_hw_omap(__clk_get_hw(c)); + hw = __clk_get_hw(c); + if (!hw) + return NULL; + + clk = to_clk_hw_omap(hw); + if (!clk) + return NULL; + clkdm = clk->clkdm; if (!clkdm) return NULL; diff --git a/arch/arm/mach-omap2/pm33xx-core.c b/arch/arm/mach-omap2/pm33xx-core.c index 56f2c0bcae5a..bf0d25fd2cea 100644 --- a/arch/arm/mach-omap2/pm33xx-core.c +++ b/arch/arm/mach-omap2/pm33xx-core.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -324,6 +325,44 @@ static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void) return NULL; } +#ifdef CONFIG_SUSPEND +/* + * Block system suspend initially. Later on pm33xx sets up it's own + * platform_suspend_ops after probe. That depends also on loaded + * wkup_m3_ipc and booted am335x-pm-firmware.elf. + */ +static int amx3_suspend_block(suspend_state_t state) +{ + pr_warn("PM not initialized for pm33xx, wkup_m3_ipc, or am335x-pm-firmware.elf\n"); + + return -EINVAL; +} + +static int amx3_pm_valid(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + return 1; + default: + return 0; + } +} + +static const struct platform_suspend_ops amx3_blocked_pm_ops = { + .begin = amx3_suspend_block, + .valid = amx3_pm_valid, +}; + +static void __init amx3_block_suspend(void) +{ + suspend_set_ops(&amx3_blocked_pm_ops); +} +#else +static inline void amx3_block_suspend(void) +{ +} +#endif /* CONFIG_SUSPEND */ + int __init amx3_common_pm_init(void) { struct am33xx_pm_platform_data *pdata; @@ -337,6 +376,7 @@ int __init amx3_common_pm_init(void) devinfo.size_data = sizeof(*pdata); devinfo.id = -1; platform_device_register_full(&devinfo); + amx3_block_suspend(); return 0; } diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index d54d69cf1732..75f3ab531bdf 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -378,7 +378,11 @@ static void __init free_highpages(void) void __init mem_init(void) { #ifdef CONFIG_ARM_LPAE - swiotlb_init(1); + if (swiotlb_force == SWIOTLB_FORCE || + max_pfn > arm_dma_pfn_limit) + swiotlb_init(1); + else + swiotlb_force = SWIOTLB_NO_FORCE; #endif set_max_mapnr(pfn_to_page(max_pfn) - mem_map); diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 0207b6ea6e8a..ce8b04326352 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -1602,6 +1602,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) rn = arm_bpf_get_reg32(src_lo, tmp2[1], ctx); emit_ldx_r(dst, rn, off, ctx, BPF_SIZE(code)); break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + break; /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_W: case BPF_ST | BPF_MEM | BPF_H: diff --git a/arch/arm/probes/kprobes/test-thumb.c b/arch/arm/probes/kprobes/test-thumb.c index 456c181a7bfe..4e11f0b760f8 100644 --- a/arch/arm/probes/kprobes/test-thumb.c +++ b/arch/arm/probes/kprobes/test-thumb.c @@ -441,21 +441,21 @@ void kprobe_thumb32_test_cases(void) "3: mvn r0, r0 \n\t" "2: nop \n\t") - TEST_RX("tbh [pc, r",7, (9f-(1f+4))>>1,"]", + TEST_RX("tbh [pc, r",7, (9f-(1f+4))>>1,", lsl #1]", "9: \n\t" ".short (2f-1b-4)>>1 \n\t" ".short (3f-1b-4)>>1 \n\t" "3: mvn r0, r0 \n\t" "2: nop \n\t") - TEST_RX("tbh [pc, r",12, ((9f-(1f+4))>>1)+1,"]", + TEST_RX("tbh [pc, r",12, ((9f-(1f+4))>>1)+1,", lsl #1]", "9: \n\t" ".short (2f-1b-4)>>1 \n\t" ".short (3f-1b-4)>>1 \n\t" "3: mvn r0, r0 \n\t" "2: nop \n\t") - TEST_RRX("tbh [r",1,9f, ", r",14,1,"]", + TEST_RRX("tbh [r",1,9f, ", r",14,1,", lsl #1]", "9: \n\t" ".short (2f-1b-4)>>1 \n\t" ".short (3f-1b-4)>>1 \n\t" @@ -468,10 +468,10 @@ void kprobe_thumb32_test_cases(void) TEST_UNSUPPORTED("strexb r0, r1, [r2]") TEST_UNSUPPORTED("strexh r0, r1, [r2]") - TEST_UNSUPPORTED("strexd r0, r1, [r2]") + TEST_UNSUPPORTED("strexd r0, r1, r2, [r2]") TEST_UNSUPPORTED("ldrexb r0, [r1]") TEST_UNSUPPORTED("ldrexh r0, [r1]") - TEST_UNSUPPORTED("ldrexd r0, [r1]") + TEST_UNSUPPORTED("ldrexd r0, r1, [r1]") TEST_GROUP("Data-processing (shifted register) and (modified immediate)") diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c index 467fa225c3d0..aae950cd053f 100644 --- a/arch/arm/xen/mm.c +++ b/arch/arm/xen/mm.c @@ -140,7 +140,7 @@ static int __init xen_mm_init(void) struct gnttab_cache_flush cflush; if (!xen_initial_domain()) return 0; - xen_swiotlb_init(1, false); + xen_swiotlb_init(); cflush.op = 0; cflush.a.dev_bus_addr = 0; diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index cf21e80963b5..96d0e0b0aab5 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1426,19 +1426,6 @@ config ARM64_USE_LSE_ATOMICS built with binutils >= 2.25 in order for the new instructions to be used. -config ARM64_VHE - bool "Enable support for Virtualization Host Extensions (VHE)" - default y - help - Virtualization Host Extensions (VHE) allow the kernel to run - directly at EL2 (instead of EL1) on processors that support - it. This leads to better performance for KVM, as they reduce - the cost of the world switch. - - Selecting this option allows the VHE feature to be detected - at runtime, and does not affect processors that do not - implement this feature. - endmenu menu "ARMv8.2 architectural features" diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts index d4069749d721..068cbd955bfc 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts @@ -79,7 +79,7 @@ &emac { pinctrl-names = "default"; pinctrl-0 = <&rgmii_pins>; - phy-mode = "rgmii-id"; + phy-mode = "rgmii-txid"; phy-handle = <&ext_rgmii_phy>; phy-supply = <®_dc1sw>; status = "okay"; diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index f6c55877fbd9..2c0161125ece 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -564,13 +564,13 @@ clocks { compatible = "arm,scpi-clocks"; - scpi_dvfs: scpi-dvfs { + scpi_dvfs: clocks-0 { compatible = "arm,scpi-dvfs-clocks"; #clock-cells = <1>; clock-indices = <0>, <1>, <2>; clock-output-names = "atlclk", "aplclk","gpuclk"; }; - scpi_clk: scpi-clk { + scpi_clk: clocks-1 { compatible = "arm,scpi-variable-clocks"; #clock-cells = <1>; clock-indices = <3>; @@ -578,7 +578,7 @@ }; }; - scpi_devpd: scpi-power-domains { + scpi_devpd: power-controller { compatible = "arm,scpi-power-domains"; num-domains = <2>; #power-domain-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts index dd764b720fb0..f6a79c8080d1 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28-var2.dts @@ -54,6 +54,7 @@ &mscc_felix_port0 { label = "swp0"; + managed = "in-band-status"; phy-handle = <&phy0>; phy-mode = "sgmii"; status = "okay"; @@ -61,6 +62,7 @@ &mscc_felix_port1 { label = "swp1"; + managed = "in-band-status"; phy-handle = <&phy1>; phy-mode = "sgmii"; status = "okay"; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi index f3b58bb9b840..5f42904d53ab 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi @@ -69,7 +69,7 @@ }; }; - sysclk: clock-sysclk { + sysclk: sysclk { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <100000000>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi index e7abb74bd816..4d34d82b898a 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi @@ -625,7 +625,6 @@ clocks = <&clockgen 4 3>; clock-names = "dspi"; spi-num-chipselects = <5>; - bus-num = <0>; }; esdhc: esdhc@2140000 { diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi index 5e0e7d0f1bc4..c86cf786f406 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi @@ -1258,6 +1258,14 @@ <&src IMX8MQ_RESET_PCIE_CTRL_APPS_EN>, <&src IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF>; reset-names = "pciephy", "apps", "turnoff"; + assigned-clocks = <&clk IMX8MQ_CLK_PCIE1_CTRL>, + <&clk IMX8MQ_CLK_PCIE1_PHY>, + <&clk IMX8MQ_CLK_PCIE1_AUX>; + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_250M>, + <&clk IMX8MQ_SYS2_PLL_100M>, + <&clk IMX8MQ_SYS1_PLL_80M>; + assigned-clock-rates = <250000000>, <100000000>, + <10000000>; status = "disabled"; }; @@ -1287,6 +1295,14 @@ <&src IMX8MQ_RESET_PCIE2_CTRL_APPS_EN>, <&src IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF>; reset-names = "pciephy", "apps", "turnoff"; + assigned-clocks = <&clk IMX8MQ_CLK_PCIE2_CTRL>, + <&clk IMX8MQ_CLK_PCIE2_PHY>, + <&clk IMX8MQ_CLK_PCIE2_AUX>; + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_250M>, + <&clk IMX8MQ_SYS2_PLL_100M>, + <&clk IMX8MQ_SYS1_PLL_80M>; + assigned-clock-rates = <250000000>, <100000000>, + <10000000>; status = "disabled"; }; diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts index cca143e4b6bf..bbd34ae12a53 100644 --- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts @@ -19,6 +19,8 @@ aliases { spi0 = &spi0; ethernet1 = ð1; + mmc0 = &sdhci0; + mmc1 = &sdhci1; }; chosen { @@ -108,10 +110,8 @@ }; firmware { - turris-mox-rwtm { - compatible = "cznic,turris-mox-rwtm"; - mboxes = <&rwtm 0>; - status = "okay"; + armada-3700-rwtm { + compatible = "marvell,armada-3700-rwtm-firmware", "cznic,turris-mox-rwtm"; }; }; }; @@ -120,6 +120,7 @@ pinctrl-names = "default"; pinctrl-0 = <&i2c1_pins>; clock-frequency = <100000>; + /delete-property/ mrvl,i2c-fast-mode; status = "okay"; rtc@6f { diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi index a89e47d95eef..83d2d83f7692 100644 --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi @@ -134,7 +134,7 @@ uart0: serial@12000 { compatible = "marvell,armada-3700-uart"; - reg = <0x12000 0x200>; + reg = <0x12000 0x18>; clocks = <&xtalclk>; interrupts = , @@ -502,4 +502,12 @@ }; }; }; + + firmware { + armada-3700-rwtm { + compatible = "marvell,armada-3700-rwtm-firmware"; + mboxes = <&rwtm 0>; + status = "okay"; + }; + }; }; diff --git a/arch/arm64/boot/dts/marvell/cn9130-db.dts b/arch/arm64/boot/dts/marvell/cn9130-db.dts index ce49a70d88a0..d24294888400 100644 --- a/arch/arm64/boot/dts/marvell/cn9130-db.dts +++ b/arch/arm64/boot/dts/marvell/cn9130-db.dts @@ -258,7 +258,7 @@ }; partition@200000 { label = "Linux"; - reg = <0x200000 0xd00000>; + reg = <0x200000 0xe00000>; }; partition@1000000 { label = "Filesystem"; diff --git a/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts index 5969b5cfdc85..cb82864a90ef 100644 --- a/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts +++ b/arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015, LGE Inc. All rights reserved. * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2021, Petr Vorel */ /dts-v1/; @@ -15,6 +16,9 @@ qcom,board-id = <0xb64 0>; qcom,pmic-id = <0x10009 0x1000A 0x0 0x0>; + /* Bullhead firmware doesn't support PSCI */ + /delete-node/ psci; + aliases { serial0 = &blsp1_uart2; }; diff --git a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts index baa55643b40f..ffe1a9bd8f70 100644 --- a/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts +++ b/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts @@ -32,3 +32,7 @@ }; }; }; + +&tlmm { + gpio-reserved-ranges = <85 4>; +}; diff --git a/arch/arm64/boot/dts/qcom/sc7180-idp.dts b/arch/arm64/boot/dts/qcom/sc7180-idp.dts index e77a7926034a..afe0f9c25816 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-idp.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-idp.dts @@ -45,7 +45,7 @@ /* Increase the size from 2MB to 8MB */ &rmtfs_mem { - reg = <0x0 0x84400000 0x0 0x800000>; + reg = <0x0 0x94600000 0x0 0x800000>; }; / { diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi index bf875589d364..5b2a616c6257 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi @@ -622,6 +622,8 @@ edp_brij_i2c: &i2c2 { clocks = <&rpmhcc RPMH_LN_BB_CLK3>; clock-names = "refclk"; + no-hpd; + ports { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts index 888dc23a530e..ad6561843ba2 100644 --- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts +++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts @@ -564,7 +564,7 @@ left_spkr: wsa8810-left{ compatible = "sdw10217211000"; reg = <0 3>; - powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_HIGH>; + powerdown-gpios = <&wcdgpio 1 GPIO_ACTIVE_HIGH>; #thermal-sensor-cells = <0>; sound-name-prefix = "SpkrLeft"; #sound-dai-cells = <0>; @@ -572,7 +572,7 @@ right_spkr: wsa8810-right{ compatible = "sdw10217211000"; - powerdown-gpios = <&wcdgpio 3 GPIO_ACTIVE_HIGH>; + powerdown-gpios = <&wcdgpio 2 GPIO_ACTIVE_HIGH>; reg = <0 4>; #thermal-sensor-cells = <0>; sound-name-prefix = "SpkrRight"; diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi index 597388f87127..bc4bb5dd8bae 100644 --- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi +++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi @@ -271,12 +271,12 @@ &ehci0 { dr_mode = "otg"; status = "okay"; - clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>; + clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&usb2_clksel>, <&versaclock5 3>; }; &ehci1 { status = "okay"; - clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>; + clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&usb2_clksel>, <&versaclock5 3>; }; &hdmi0 { diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi index 289cf711307d..e3773b05c403 100644 --- a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi +++ b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi @@ -295,8 +295,10 @@ status = "okay"; }; -&usb_extal_clk { - clock-frequency = <50000000>; +&usb2_clksel { + clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, + <&versaclock5 3>, <&usb3s0_clk>; + status = "okay"; }; &usb3s0_clk { diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi index c15f1c571eb0..c58a0846db50 100644 --- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi @@ -76,6 +76,7 @@ opp-hz = /bits/ 64 <1500000000>; opp-microvolt = <820000>; clock-latency-ns = <300000>; + opp-suspend; }; }; @@ -835,6 +836,21 @@ status = "disabled"; }; + usb2_clksel: clock-controller@e6590630 { + compatible = "renesas,r8a774a1-rcar-usb2-clock-sel", + "renesas,rcar-gen3-usb2-clock-sel"; + reg = <0 0xe6590630 0 0x02>; + clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, + <&usb_extal_clk>, <&usb3s0_clk>; + clock-names = "ehci_ohci", "hs-usb-if", + "usb_extal", "usb_xtal"; + #clock-cells = <0>; + power-domains = <&sysc R8A774A1_PD_ALWAYS_ON>; + resets = <&cpg 703>, <&cpg 704>; + reset-names = "ehci_ohci", "hs-usb-if"; + status = "disabled"; + }; + usb_dmac0: dma-controller@e65a0000 { compatible = "renesas,r8a774a1-usb-dmac", "renesas,usb-dmac"; diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi index 39a1a26ffb54..9ebf6e58ba31 100644 --- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi @@ -709,6 +709,21 @@ status = "disabled"; }; + usb2_clksel: clock-controller@e6590630 { + compatible = "renesas,r8a774b1-rcar-usb2-clock-sel", + "renesas,rcar-gen3-usb2-clock-sel"; + reg = <0 0xe6590630 0 0x02>; + clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, + <&usb_extal_clk>, <&usb3s0_clk>; + clock-names = "ehci_ohci", "hs-usb-if", + "usb_extal", "usb_xtal"; + #clock-cells = <0>; + power-domains = <&sysc R8A774B1_PD_ALWAYS_ON>; + resets = <&cpg 703>, <&cpg 704>; + reset-names = "ehci_ohci", "hs-usb-if"; + status = "disabled"; + }; + usb_dmac0: dma-controller@e65a0000 { compatible = "renesas,r8a774b1-usb-dmac", "renesas,usb-dmac"; diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi index c29643442e91..708258696b4f 100644 --- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi @@ -890,6 +890,21 @@ status = "disabled"; }; + usb2_clksel: clock-controller@e6590630 { + compatible = "renesas,r8a774e1-rcar-usb2-clock-sel", + "renesas,rcar-gen3-usb2-clock-sel"; + reg = <0 0xe6590630 0 0x02>; + clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, + <&usb_extal_clk>, <&usb3s0_clk>; + clock-names = "ehci_ohci", "hs-usb-if", + "usb_extal", "usb_xtal"; + #clock-cells = <0>; + power-domains = <&sysc R8A774E1_PD_ALWAYS_ON>; + resets = <&cpg 703>, <&cpg 704>; + reset-names = "ehci_ohci", "hs-usb-if"; + status = "disabled"; + }; + usb_dmac0: dma-controller@e65a0000 { compatible = "renesas,r8a774e1-usb-dmac", "renesas,usb-dmac"; diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi index f379c8d1511d..fa9567ed55e4 100644 --- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi @@ -63,18 +63,19 @@ opp-500000000 { opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <820000>; + opp-microvolt = <830000>; clock-latency-ns = <300000>; }; opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <820000>; + opp-microvolt = <830000>; clock-latency-ns = <300000>; }; opp-1500000000 { opp-hz = /bits/ 64 <1500000000>; - opp-microvolt = <820000>; + opp-microvolt = <830000>; clock-latency-ns = <300000>; + opp-suspend; }; opp-1600000000 { opp-hz = /bits/ 64 <1600000000>; diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi index 1ba30313c8b8..b23f49b89cad 100644 --- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi @@ -52,18 +52,19 @@ opp-500000000 { opp-hz = /bits/ 64 <500000000>; - opp-microvolt = <820000>; + opp-microvolt = <830000>; clock-latency-ns = <300000>; }; opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; - opp-microvolt = <820000>; + opp-microvolt = <830000>; clock-latency-ns = <300000>; }; opp-1500000000 { opp-hz = /bits/ 64 <1500000000>; - opp-microvolt = <820000>; + opp-microvolt = <830000>; clock-latency-ns = <300000>; + opp-suspend; }; opp-1600000000 { opp-hz = /bits/ 64 <1600000000>; diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts index 668a1ece9af0..0c66cc0a1367 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts +++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts @@ -59,7 +59,7 @@ memory@48000000 { device_type = "memory"; /* first 128MB is reserved for secure area. */ - reg = <0x0 0x48000000 0x0 0x38000000>; + reg = <0x0 0x48000000 0x0 0x78000000>; }; osc5_clk: osc5-clock { diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi index 86ec32a919d2..bfbb53bf5375 100644 --- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi @@ -111,7 +111,6 @@ <0x0 0xf1060000 0 0x110000>; interrupts = ; - power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>; }; prr: chipid@fff00044 { diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi index 64193292d26c..0d6761074b11 100644 --- a/arch/arm64/boot/dts/rockchip/px30.dtsi +++ b/arch/arm64/boot/dts/rockchip/px30.dtsi @@ -244,20 +244,20 @@ #size-cells = <0>; /* These power domains are grouped by VD_LOGIC */ - pd_usb@PX30_PD_USB { + power-domain@PX30_PD_USB { reg = ; clocks = <&cru HCLK_HOST>, <&cru HCLK_OTG>, <&cru SCLK_OTG_ADP>; pm_qos = <&qos_usb_host>, <&qos_usb_otg>; }; - pd_sdcard@PX30_PD_SDCARD { + power-domain@PX30_PD_SDCARD { reg = ; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; pm_qos = <&qos_sdmmc>; }; - pd_gmac@PX30_PD_GMAC { + power-domain@PX30_PD_GMAC { reg = ; clocks = <&cru ACLK_GMAC>, <&cru PCLK_GMAC>, @@ -265,7 +265,7 @@ <&cru SCLK_GMAC_RX_TX>; pm_qos = <&qos_gmac>; }; - pd_mmc_nand@PX30_PD_MMC_NAND { + power-domain@PX30_PD_MMC_NAND { reg = ; clocks = <&cru HCLK_NANDC>, <&cru HCLK_EMMC>, @@ -278,14 +278,14 @@ pm_qos = <&qos_emmc>, <&qos_nand>, <&qos_sdio>, <&qos_sfc>; }; - pd_vpu@PX30_PD_VPU { + power-domain@PX30_PD_VPU { reg = ; clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>, <&cru SCLK_CORE_VPU>; pm_qos = <&qos_vpu>, <&qos_vpu_r128>; }; - pd_vo@PX30_PD_VO { + power-domain@PX30_PD_VO { reg = ; clocks = <&cru ACLK_RGA>, <&cru ACLK_VOPB>, @@ -301,7 +301,7 @@ pm_qos = <&qos_rga_rd>, <&qos_rga_wr>, <&qos_vop_m0>, <&qos_vop_m1>; }; - pd_vi@PX30_PD_VI { + power-domain@PX30_PD_VI { reg = ; clocks = <&cru ACLK_CIF>, <&cru ACLK_ISP>, @@ -312,7 +312,7 @@ <&qos_isp_wr>, <&qos_isp_m1>, <&qos_vip>; }; - pd_gpu@PX30_PD_GPU { + power-domain@PX30_PD_GPU { reg = ; clocks = <&cru SCLK_GPU>; pm_qos = <&qos_gpu>; diff --git a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts index 7a96be10eaf0..bce6f8b7db43 100644 --- a/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts +++ b/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts @@ -78,8 +78,8 @@ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_HIGH>; - states = <1800000 0x0 - 3300000 0x1>; + states = <1800000 0x0>, + <3300000 0x1>; vin-supply = <&vcc5v0_sys>; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts index 1eecad724f04..83a0bdbe00d6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s.dts @@ -71,8 +71,8 @@ regulator-settling-time-us = <5000>; regulator-type = "voltage"; startup-delay-us = <2000>; - states = <1800000 0x1 - 3300000 0x0>; + states = <1800000 0x1>, + <3300000 0x0>; vin-supply = <&vcc_io_33>; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts index b76282e704de..daa9a0c601a9 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-roc-cc.dts @@ -45,8 +45,8 @@ vcc_sdio: sdmmcio-regulator { compatible = "regulator-gpio"; gpios = <&grf_gpio 0 GPIO_ACTIVE_HIGH>; - states = <1800000 0x1 - 3300000 0x0>; + states = <1800000 0x1>, + <3300000 0x0>; regulator-name = "vcc_sdio"; regulator-type = "voltage"; regulator-min-microvolt = <1800000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts index 86cfb5c50a94..95ab6928cfd4 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3328-rock64.dts @@ -384,6 +384,11 @@ status = "okay"; }; +&usbdrd3 { + dr_mode = "host"; + status = "okay"; +}; + &usb_host0_ehci { status = "okay"; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 93c734d8a46c..e546c9d1d646 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi @@ -318,13 +318,13 @@ #address-cells = <1>; #size-cells = <0>; - pd_hevc@RK3328_PD_HEVC { + power-domain@RK3328_PD_HEVC { reg = ; }; - pd_video@RK3328_PD_VIDEO { + power-domain@RK3328_PD_VIDEO { reg = ; }; - pd_vpu@RK3328_PD_VPU { + power-domain@RK3328_PD_VPU { reg = ; clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>; }; @@ -984,6 +984,25 @@ status = "disabled"; }; + usbdrd3: usb@ff600000 { + compatible = "rockchip,rk3328-dwc3", "snps,dwc3"; + reg = <0x0 0xff600000 0x0 0x100000>; + interrupts = ; + clocks = <&cru SCLK_USB3OTG_REF>, <&cru SCLK_USB3OTG_SUSPEND>, + <&cru ACLK_USB3OTG>; + clock-names = "ref_clk", "suspend_clk", + "bus_clk"; + dr_mode = "otg"; + phy_type = "utmi_wide"; + snps,dis-del-phy-power-chg-quirk; + snps,dis_enblslpm_quirk; + snps,dis-tx-ipgap-linecheck-quirk; + snps,dis-u2-freeclk-exists-quirk; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + status = "disabled"; + }; + gic: interrupt-controller@ff811000 { compatible = "arm,gic-400"; #interrupt-cells = <3>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi index 60cd1c18cd4e..e9ecffc409c0 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi @@ -245,7 +245,7 @@ pp1800_pcie: &pp1800_s0 { }; &ppvar_sd_card_io { - states = <1800000 0x0 3300000 0x1>; + states = <1800000 0x0>, <3300000 0x1>; regulator-max-microvolt = <3300000>; }; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi index 32dcaf210085..765b24a2bcbf 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi @@ -247,8 +247,8 @@ enable-active-high; enable-gpio = <&gpio2 2 GPIO_ACTIVE_HIGH>; gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>; - states = <1800000 0x1 - 3000000 0x0>; + states = <1800000 0x1>, + <3000000 0x0>; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3000000>; diff --git a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi index 20309076dbac..35b7ab3bf10c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi @@ -384,6 +384,7 @@ vcc_sdio: LDO_REG4 { regulator-name = "vcc_sdio"; + regulator-always-on; regulator-boot-on; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3000000>; @@ -488,6 +489,8 @@ regulator-min-microvolt = <712500>; regulator-max-microvolt = <1500000>; regulator-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; vin-supply = <&vcc3v3_sys>; regulator-state-mem { diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts index f0055ce2fda0..f7cb035c68b2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts @@ -27,7 +27,7 @@ }; &uart0 { - status = "okay"; + status = "disabled"; bluetooth { compatible = "brcm,bcm43438-bt"; diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi index 7e69603fb41c..4b6065dbba55 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi @@ -1000,26 +1000,26 @@ #size-cells = <0>; /* These power domains are grouped by VD_CENTER */ - pd_iep@RK3399_PD_IEP { + power-domain@RK3399_PD_IEP { reg = ; clocks = <&cru ACLK_IEP>, <&cru HCLK_IEP>; pm_qos = <&qos_iep>; }; - pd_rga@RK3399_PD_RGA { + power-domain@RK3399_PD_RGA { reg = ; clocks = <&cru ACLK_RGA>, <&cru HCLK_RGA>; pm_qos = <&qos_rga_r>, <&qos_rga_w>; }; - pd_vcodec@RK3399_PD_VCODEC { + power-domain@RK3399_PD_VCODEC { reg = ; clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; pm_qos = <&qos_video_m0>; }; - pd_vdu@RK3399_PD_VDU { + power-domain@RK3399_PD_VDU { reg = ; clocks = <&cru ACLK_VDU>, <&cru HCLK_VDU>; @@ -1028,94 +1028,94 @@ }; /* These power domains are grouped by VD_GPU */ - pd_gpu@RK3399_PD_GPU { + power-domain@RK3399_PD_GPU { reg = ; clocks = <&cru ACLK_GPU>; pm_qos = <&qos_gpu>; }; /* These power domains are grouped by VD_LOGIC */ - pd_edp@RK3399_PD_EDP { + power-domain@RK3399_PD_EDP { reg = ; clocks = <&cru PCLK_EDP_CTRL>; }; - pd_emmc@RK3399_PD_EMMC { + power-domain@RK3399_PD_EMMC { reg = ; clocks = <&cru ACLK_EMMC>; pm_qos = <&qos_emmc>; }; - pd_gmac@RK3399_PD_GMAC { + power-domain@RK3399_PD_GMAC { reg = ; clocks = <&cru ACLK_GMAC>, <&cru PCLK_GMAC>; pm_qos = <&qos_gmac>; }; - pd_sd@RK3399_PD_SD { + power-domain@RK3399_PD_SD { reg = ; clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; pm_qos = <&qos_sd>; }; - pd_sdioaudio@RK3399_PD_SDIOAUDIO { + power-domain@RK3399_PD_SDIOAUDIO { reg = ; clocks = <&cru HCLK_SDIO>; pm_qos = <&qos_sdioaudio>; }; - pd_tcpc0@RK3399_PD_TCPD0 { + power-domain@RK3399_PD_TCPD0 { reg = ; clocks = <&cru SCLK_UPHY0_TCPDCORE>, <&cru SCLK_UPHY0_TCPDPHY_REF>; }; - pd_tcpc1@RK3399_PD_TCPD1 { + power-domain@RK3399_PD_TCPD1 { reg = ; clocks = <&cru SCLK_UPHY1_TCPDCORE>, <&cru SCLK_UPHY1_TCPDPHY_REF>; }; - pd_usb3@RK3399_PD_USB3 { + power-domain@RK3399_PD_USB3 { reg = ; clocks = <&cru ACLK_USB3>; pm_qos = <&qos_usb_otg0>, <&qos_usb_otg1>; }; - pd_vio@RK3399_PD_VIO { + power-domain@RK3399_PD_VIO { reg = ; #address-cells = <1>; #size-cells = <0>; - pd_hdcp@RK3399_PD_HDCP { + power-domain@RK3399_PD_HDCP { reg = ; clocks = <&cru ACLK_HDCP>, <&cru HCLK_HDCP>, <&cru PCLK_HDCP>; pm_qos = <&qos_hdcp>; }; - pd_isp0@RK3399_PD_ISP0 { + power-domain@RK3399_PD_ISP0 { reg = ; clocks = <&cru ACLK_ISP0>, <&cru HCLK_ISP0>; pm_qos = <&qos_isp0_m0>, <&qos_isp0_m1>; }; - pd_isp1@RK3399_PD_ISP1 { + power-domain@RK3399_PD_ISP1 { reg = ; clocks = <&cru ACLK_ISP1>, <&cru HCLK_ISP1>; pm_qos = <&qos_isp1_m0>, <&qos_isp1_m1>; }; - pd_vo@RK3399_PD_VO { + power-domain@RK3399_PD_VO { reg = ; #address-cells = <1>; #size-cells = <0>; - pd_vopb@RK3399_PD_VOPB { + power-domain@RK3399_PD_VOPB { reg = ; clocks = <&cru ACLK_VOP0>, <&cru HCLK_VOP0>; pm_qos = <&qos_vop_big_r>, <&qos_vop_big_w>; }; - pd_vopl@RK3399_PD_VOPL { + power-domain@RK3399_PD_VOPL { reg = ; clocks = <&cru ACLK_VOP1>, <&cru HCLK_VOP1>; @@ -2342,7 +2342,7 @@ }; }; - sleep { + suspend { ap_pwroff: ap-pwroff { rockchip,pins = <1 RK_PA5 1 &pcfg_pull_none>; }; diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts index d12dd89f3405..937dd7280c7a 100644 --- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts +++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts @@ -111,7 +111,7 @@ AM65X_WKUP_IOPAD(0x007c, PIN_INPUT, 0) /* (L5) MCU_RGMII1_RD2 */ AM65X_WKUP_IOPAD(0x0080, PIN_INPUT, 0) /* (M6) MCU_RGMII1_RD1 */ AM65X_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* (L6) MCU_RGMII1_RD0 */ - AM65X_WKUP_IOPAD(0x0070, PIN_INPUT, 0) /* (N1) MCU_RGMII1_TXC */ + AM65X_WKUP_IOPAD(0x0070, PIN_OUTPUT, 0) /* (N1) MCU_RGMII1_TXC */ AM65X_WKUP_IOPAD(0x0074, PIN_INPUT, 0) /* (M1) MCU_RGMII1_RXC */ >; }; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts index ef03e7636b66..e8a4143e1c24 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts @@ -29,7 +29,7 @@ J721E_WKUP_IOPAD(0x008c, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */ J721E_WKUP_IOPAD(0x0090, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */ J721E_WKUP_IOPAD(0x0094, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */ - J721E_WKUP_IOPAD(0x0080, PIN_INPUT, 0) /* MCU_RGMII1_TXC */ + J721E_WKUP_IOPAD(0x0080, PIN_OUTPUT, 0) /* MCU_RGMII1_TXC */ J721E_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* MCU_RGMII1_RXC */ >; }; diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi index 689538244392..5832ad830ed1 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi @@ -446,6 +446,7 @@ "otg"; maximum-speed = "super-speed"; dr_mode = "otg"; + cdns,phyrst-a-enable; }; }; }; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts index 52e121155563..479abff9cb8e 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts @@ -206,7 +206,7 @@ J721E_WKUP_IOPAD(0x007c, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */ J721E_WKUP_IOPAD(0x0080, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */ J721E_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */ - J721E_WKUP_IOPAD(0x0070, PIN_INPUT, 0) /* MCU_RGMII1_TXC */ + J721E_WKUP_IOPAD(0x0070, PIN_OUTPUT, 0) /* MCU_RGMII1_TXC */ J721E_WKUP_IOPAD(0x0074, PIN_INPUT, 0) /* MCU_RGMII1_RXC */ >; }; @@ -560,6 +560,10 @@ status = "okay"; }; +&cmn_refclk1 { + clock-frequency = <100000000>; +}; + &serdes0 { serdes0_pcie_link: link@0 { reg = <0>; diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi index c66ded9079be..6ffdebd60122 100644 --- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi @@ -8,6 +8,20 @@ #include #include +/ { + cmn_refclk: clock-cmnrefclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + cmn_refclk1: clock-cmnrefclk1 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; +}; + &cbass_main { msmc_ram: sram@70000000 { compatible = "mmio-sram"; @@ -369,24 +383,12 @@ pinctrl-single,function-mask = <0xffffffff>; }; - dummy_cmn_refclk: dummy-cmn-refclk { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <100000000>; - }; - - dummy_cmn_refclk1: dummy-cmn-refclk1 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <100000000>; - }; - serdes_wiz0: wiz@5000000 { compatible = "ti,j721e-wiz-16g"; #address-cells = <1>; #size-cells = <1>; power-domains = <&k3_pds 292 TI_SCI_PD_EXCLUSIVE>; - clocks = <&k3_clks 292 5>, <&k3_clks 292 11>, <&dummy_cmn_refclk>; + clocks = <&k3_clks 292 5>, <&k3_clks 292 11>, <&cmn_refclk>; clock-names = "fck", "core_ref_clk", "ext_ref_clk"; assigned-clocks = <&k3_clks 292 11>, <&k3_clks 292 0>; assigned-clock-parents = <&k3_clks 292 15>, <&k3_clks 292 4>; @@ -395,21 +397,21 @@ ranges = <0x5000000 0x0 0x5000000 0x10000>; wiz0_pll0_refclk: pll0-refclk { - clocks = <&k3_clks 292 11>, <&dummy_cmn_refclk>; + clocks = <&k3_clks 292 11>, <&cmn_refclk>; #clock-cells = <0>; assigned-clocks = <&wiz0_pll0_refclk>; assigned-clock-parents = <&k3_clks 292 11>; }; wiz0_pll1_refclk: pll1-refclk { - clocks = <&k3_clks 292 0>, <&dummy_cmn_refclk1>; + clocks = <&k3_clks 292 0>, <&cmn_refclk1>; #clock-cells = <0>; assigned-clocks = <&wiz0_pll1_refclk>; assigned-clock-parents = <&k3_clks 292 0>; }; wiz0_refclk_dig: refclk-dig { - clocks = <&k3_clks 292 11>, <&k3_clks 292 0>, <&dummy_cmn_refclk>, <&dummy_cmn_refclk1>; + clocks = <&k3_clks 292 11>, <&k3_clks 292 0>, <&cmn_refclk>, <&cmn_refclk1>; #clock-cells = <0>; assigned-clocks = <&wiz0_refclk_dig>; assigned-clock-parents = <&k3_clks 292 11>; @@ -443,7 +445,7 @@ #address-cells = <1>; #size-cells = <1>; power-domains = <&k3_pds 293 TI_SCI_PD_EXCLUSIVE>; - clocks = <&k3_clks 293 5>, <&k3_clks 293 13>, <&dummy_cmn_refclk>; + clocks = <&k3_clks 293 5>, <&k3_clks 293 13>, <&cmn_refclk>; clock-names = "fck", "core_ref_clk", "ext_ref_clk"; assigned-clocks = <&k3_clks 293 13>, <&k3_clks 293 0>; assigned-clock-parents = <&k3_clks 293 17>, <&k3_clks 293 4>; @@ -452,21 +454,21 @@ ranges = <0x5010000 0x0 0x5010000 0x10000>; wiz1_pll0_refclk: pll0-refclk { - clocks = <&k3_clks 293 13>, <&dummy_cmn_refclk>; + clocks = <&k3_clks 293 13>, <&cmn_refclk>; #clock-cells = <0>; assigned-clocks = <&wiz1_pll0_refclk>; assigned-clock-parents = <&k3_clks 293 13>; }; wiz1_pll1_refclk: pll1-refclk { - clocks = <&k3_clks 293 0>, <&dummy_cmn_refclk1>; + clocks = <&k3_clks 293 0>, <&cmn_refclk1>; #clock-cells = <0>; assigned-clocks = <&wiz1_pll1_refclk>; assigned-clock-parents = <&k3_clks 293 0>; }; wiz1_refclk_dig: refclk-dig { - clocks = <&k3_clks 293 13>, <&k3_clks 293 0>, <&dummy_cmn_refclk>, <&dummy_cmn_refclk1>; + clocks = <&k3_clks 293 13>, <&k3_clks 293 0>, <&cmn_refclk>, <&cmn_refclk1>; #clock-cells = <0>; assigned-clocks = <&wiz1_refclk_dig>; assigned-clock-parents = <&k3_clks 293 13>; @@ -500,7 +502,7 @@ #address-cells = <1>; #size-cells = <1>; power-domains = <&k3_pds 294 TI_SCI_PD_EXCLUSIVE>; - clocks = <&k3_clks 294 5>, <&k3_clks 294 11>, <&dummy_cmn_refclk>; + clocks = <&k3_clks 294 5>, <&k3_clks 294 11>, <&cmn_refclk>; clock-names = "fck", "core_ref_clk", "ext_ref_clk"; assigned-clocks = <&k3_clks 294 11>, <&k3_clks 294 0>; assigned-clock-parents = <&k3_clks 294 15>, <&k3_clks 294 4>; @@ -509,21 +511,21 @@ ranges = <0x5020000 0x0 0x5020000 0x10000>; wiz2_pll0_refclk: pll0-refclk { - clocks = <&k3_clks 294 11>, <&dummy_cmn_refclk>; + clocks = <&k3_clks 294 11>, <&cmn_refclk>; #clock-cells = <0>; assigned-clocks = <&wiz2_pll0_refclk>; assigned-clock-parents = <&k3_clks 294 11>; }; wiz2_pll1_refclk: pll1-refclk { - clocks = <&k3_clks 294 0>, <&dummy_cmn_refclk1>; + clocks = <&k3_clks 294 0>, <&cmn_refclk1>; #clock-cells = <0>; assigned-clocks = <&wiz2_pll1_refclk>; assigned-clock-parents = <&k3_clks 294 0>; }; wiz2_refclk_dig: refclk-dig { - clocks = <&k3_clks 294 11>, <&k3_clks 294 0>, <&dummy_cmn_refclk>, <&dummy_cmn_refclk1>; + clocks = <&k3_clks 294 11>, <&k3_clks 294 0>, <&cmn_refclk>, <&cmn_refclk1>; #clock-cells = <0>; assigned-clocks = <&wiz2_refclk_dig>; assigned-clock-parents = <&k3_clks 294 11>; @@ -557,7 +559,7 @@ #address-cells = <1>; #size-cells = <1>; power-domains = <&k3_pds 295 TI_SCI_PD_EXCLUSIVE>; - clocks = <&k3_clks 295 5>, <&k3_clks 295 9>, <&dummy_cmn_refclk>; + clocks = <&k3_clks 295 5>, <&k3_clks 295 9>, <&cmn_refclk>; clock-names = "fck", "core_ref_clk", "ext_ref_clk"; assigned-clocks = <&k3_clks 295 9>, <&k3_clks 295 0>; assigned-clock-parents = <&k3_clks 295 13>, <&k3_clks 295 4>; @@ -566,21 +568,21 @@ ranges = <0x5030000 0x0 0x5030000 0x10000>; wiz3_pll0_refclk: pll0-refclk { - clocks = <&k3_clks 295 9>, <&dummy_cmn_refclk>; + clocks = <&k3_clks 295 9>, <&cmn_refclk>; #clock-cells = <0>; assigned-clocks = <&wiz3_pll0_refclk>; assigned-clock-parents = <&k3_clks 295 9>; }; wiz3_pll1_refclk: pll1-refclk { - clocks = <&k3_clks 295 0>, <&dummy_cmn_refclk1>; + clocks = <&k3_clks 295 0>, <&cmn_refclk1>; #clock-cells = <0>; assigned-clocks = <&wiz3_pll1_refclk>; assigned-clock-parents = <&k3_clks 295 0>; }; wiz3_refclk_dig: refclk-dig { - clocks = <&k3_clks 295 9>, <&k3_clks 295 0>, <&dummy_cmn_refclk>, <&dummy_cmn_refclk1>; + clocks = <&k3_clks 295 9>, <&k3_clks 295 0>, <&cmn_refclk>, <&cmn_refclk1>; #clock-cells = <0>; assigned-clocks = <&wiz3_refclk_dig>; assigned-clock-parents = <&k3_clks 295 9>; diff --git a/arch/arm64/configs/db845c_gki.fragment b/arch/arm64/configs/db845c_gki.fragment index e7c8f04055e6..d487757cfa3c 100644 --- a/arch/arm64/configs/db845c_gki.fragment +++ b/arch/arm64/configs/db845c_gki.fragment @@ -1,8 +1,3 @@ -CONFIG_CFG80211=m -CONFIG_NL80211_TESTMODE=y -# CONFIG_CFG80211_DEFAULT_PS is not set -# CONFIG_CFG80211_CRDA_SUPPORT is not set -CONFIG_MAC80211=m CONFIG_QRTR=m CONFIG_QRTR_TUN=m CONFIG_SCSI_UFS_QCOM=m diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index c60629a98f78..cc26ab19b07c 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -109,6 +109,7 @@ CONFIG_GKI_HACKS_TO_FIX=y CONFIG_BINFMT_MISC=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y CONFIG_CLEANCACHE=y @@ -271,7 +272,13 @@ CONFIG_BT_HCIUART=y CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIUART_BCM=y CONFIG_BT_HCIUART_QCA=y +CONFIG_CFG80211=y +CONFIG_NL80211_TESTMODE=y +# CONFIG_CFG80211_DEFAULT_PS is not set +# CONFIG_CFG80211_CRDA_SUPPORT is not set +CONFIG_MAC80211=y CONFIG_RFKILL=y +CONFIG_NFC=y CONFIG_PCI=y CONFIG_PCIEPORTBUS=y CONFIG_PCIEAER=y @@ -302,6 +309,7 @@ CONFIG_SCSI_UFS_DWC_TC_PLATFORM=y CONFIG_SCSI_UFS_HISI=y CONFIG_SCSI_UFS_BSG=y CONFIG_SCSI_UFS_CRYPTO=y +CONFIG_SCSI_UFS_HPB=y CONFIG_MD=y CONFIG_BLK_DEV_DM=y CONFIG_DM_CRYPT=y @@ -365,6 +373,7 @@ CONFIG_SERIAL_8250=y # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_EXAR is not set +CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y @@ -394,6 +403,7 @@ CONFIG_SPMI=y # CONFIG_PINCTRL_SUN50I_H6_R is not set CONFIG_GPIO_GENERIC_PLATFORM=y CONFIG_POWER_RESET_HISI=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_THERMAL=y CONFIG_THERMAL_NETLINK=y @@ -408,7 +418,6 @@ CONFIG_THERMAL_EMULATION=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y CONFIG_MFD_ACT8945A=y -CONFIG_MFD_SYSCON=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_RC_CORE=y @@ -651,6 +660,7 @@ CONFIG_CRYPTO_ZSTD=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRC8=y CONFIG_XZ_DEC=y +CONFIG_DMA_RESTRICTED_POOL=y CONFIG_DMA_CMA=y CONFIG_STACK_HASH_ORDER=12 CONFIG_PRINTK_TIME=y diff --git a/arch/arm64/configs/hikey960_gki.fragment b/arch/arm64/configs/hikey960_gki.fragment index fcc01e20dc7f..ba7e473b55ae 100644 --- a/arch/arm64/configs/hikey960_gki.fragment +++ b/arch/arm64/configs/hikey960_gki.fragment @@ -50,8 +50,3 @@ CONFIG_PHY_HI3660_USB=m CONFIG_PINCTRL_SINGLE=m CONFIG_DMABUF_HEAPS_CMA=m CONFIG_DMABUF_HEAPS_SYSTEM=m -CONFIG_CFG80211=m -CONFIG_NL80211_TESTMODE=y -# CONFIG_CFG80211_DEFAULT_PS is not set -# CONFIG_CFG80211_CRDA_SUPPORT is not set -CONFIG_MAC80211=m diff --git a/arch/arm64/configs/rockpi4_defconfig b/arch/arm64/configs/rockpi4_defconfig deleted file mode 100644 index bbe3a2a2b150..000000000000 --- a/arch/arm64/configs/rockpi4_defconfig +++ /dev/null @@ -1,541 +0,0 @@ -CONFIG_LOCALVERSION="-mainline" -CONFIG_AUDIT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_PREEMPT=y -CONFIG_TASKSTATS=y -CONFIG_TASK_XACCT=y -CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_PSI=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_MEMCG=y -CONFIG_MEMCG_SWAP=y -CONFIG_BLK_CGROUP=y -CONFIG_RT_GROUP_SCHED=y -CONFIG_CGROUP_FREEZER=y -CONFIG_CPUSETS=y -CONFIG_CGROUP_CPUACCT=y -CONFIG_CGROUP_BPF=y -CONFIG_SCHED_AUTOGROUP=y -CONFIG_BLK_DEV_INITRD=y -# CONFIG_RD_BZIP2 is not set -# CONFIG_RD_LZMA is not set -# CONFIG_RD_XZ is not set -# CONFIG_RD_LZO is not set -# CONFIG_RD_LZ4 is not set -# CONFIG_SYSFS_SYSCALL is not set -CONFIG_KALLSYMS_ALL=y -CONFIG_BPF_SYSCALL=y -# CONFIG_RSEQ is not set -CONFIG_EMBEDDED=y -# CONFIG_VM_EVENT_COUNTERS is not set -# CONFIG_COMPAT_BRK is not set -# CONFIG_SLAB_MERGE_DEFAULT is not set -CONFIG_SLAB_FREELIST_RANDOM=y -CONFIG_SLAB_FREELIST_HARDENED=y -CONFIG_PROFILING=y -CONFIG_ARCH_QCOM=y -CONFIG_ARCH_ROCKCHIP=y -CONFIG_SCHED_MC=y -CONFIG_NR_CPUS=32 -CONFIG_SECCOMP=y -CONFIG_PARAVIRT=y -CONFIG_COMPAT=y -CONFIG_ARMV8_DEPRECATED=y -CONFIG_SWP_EMULATION=y -CONFIG_CP15_BARRIER_EMULATION=y -CONFIG_SETEND_EMULATION=y -CONFIG_RANDOMIZE_BASE=y -# CONFIG_DMI is not set -CONFIG_PM_WAKELOCKS=y -CONFIG_PM_WAKELOCKS_LIMIT=0 -# CONFIG_PM_WAKELOCKS_GC is not set -CONFIG_ENERGY_MODEL=y -CONFIG_CPU_IDLE=y -CONFIG_ARM_CPUIDLE=y -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TIMES=y -CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y -CONFIG_ARM_SCPI_CPUFREQ=y -CONFIG_ARM_SCMI_CPUFREQ=y -CONFIG_ARM_SCMI_PROTOCOL=y -# CONFIG_ARM_SCMI_POWER_DOMAIN is not set -CONFIG_ARM_SCPI_PROTOCOL=y -# CONFIG_ARM_SCPI_POWER_DOMAIN is not set -# CONFIG_EFI_ARMSTUB_DTB_LOADER is not set -CONFIG_VIRTUALIZATION=y -CONFIG_KVM=y -CONFIG_VHOST_VSOCK=y -CONFIG_ARM64_CRYPTO=y -CONFIG_CRYPTO_AES_ARM64=y -CONFIG_KPROBES=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODVERSIONS=y -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_BINFMT_MISC=y -# CONFIG_SPARSEMEM_VMEMMAP is not set -CONFIG_MEMORY_HOTPLUG=y -CONFIG_TRANSPARENT_HUGEPAGE=y -CONFIG_CMA=y -CONFIG_CMA_AREAS=16 -CONFIG_ZSMALLOC=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_XFRM_USER=y -CONFIG_XFRM_INTERFACE=y -CONFIG_XFRM_STATISTICS=y -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_NET_IPGRE_DEMUX=y -CONFIG_NET_IPVTI=y -CONFIG_INET_ESP=y -CONFIG_INET_UDP_DIAG=y -CONFIG_INET_DIAG_DESTROY=y -CONFIG_IPV6_ROUTER_PREF=y -CONFIG_IPV6_ROUTE_INFO=y -CONFIG_IPV6_OPTIMISTIC_DAD=y -CONFIG_INET6_ESP=y -CONFIG_INET6_IPCOMP=y -CONFIG_IPV6_MIP6=y -CONFIG_IPV6_VTI=y -CONFIG_IPV6_MULTIPLE_TABLES=y -CONFIG_NETFILTER=y -# CONFIG_BRIDGE_NETFILTER is not set -CONFIG_NF_CONNTRACK=y -CONFIG_NF_CONNTRACK_SECMARK=y -CONFIG_NF_CONNTRACK_EVENTS=y -CONFIG_NF_CONNTRACK_AMANDA=y -CONFIG_NF_CONNTRACK_FTP=y -CONFIG_NF_CONNTRACK_H323=y -CONFIG_NF_CONNTRACK_IRC=y -CONFIG_NF_CONNTRACK_NETBIOS_NS=y -CONFIG_NF_CONNTRACK_PPTP=y -CONFIG_NF_CONNTRACK_SANE=y -CONFIG_NF_CONNTRACK_TFTP=y -CONFIG_NF_CT_NETLINK=y -CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y -CONFIG_NETFILTER_XT_TARGET_CONNMARK=y -CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y -CONFIG_NETFILTER_XT_TARGET_CT=y -CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y -CONFIG_NETFILTER_XT_TARGET_MARK=y -CONFIG_NETFILTER_XT_TARGET_NFLOG=y -CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y -CONFIG_NETFILTER_XT_TARGET_TPROXY=y -CONFIG_NETFILTER_XT_TARGET_TRACE=y -CONFIG_NETFILTER_XT_TARGET_SECMARK=y -CONFIG_NETFILTER_XT_TARGET_TCPMSS=y -CONFIG_NETFILTER_XT_MATCH_BPF=y -CONFIG_NETFILTER_XT_MATCH_COMMENT=y -CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y -CONFIG_NETFILTER_XT_MATCH_CONNMARK=y -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y -CONFIG_NETFILTER_XT_MATCH_HELPER=y -CONFIG_NETFILTER_XT_MATCH_IPRANGE=y -CONFIG_NETFILTER_XT_MATCH_LENGTH=y -CONFIG_NETFILTER_XT_MATCH_LIMIT=y -CONFIG_NETFILTER_XT_MATCH_MAC=y -CONFIG_NETFILTER_XT_MATCH_MARK=y -CONFIG_NETFILTER_XT_MATCH_OWNER=y -CONFIG_NETFILTER_XT_MATCH_POLICY=y -CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y -CONFIG_NETFILTER_XT_MATCH_QUOTA=y -CONFIG_NETFILTER_XT_MATCH_QUOTA2=y -CONFIG_NETFILTER_XT_MATCH_SOCKET=y -CONFIG_NETFILTER_XT_MATCH_STATE=y -CONFIG_NETFILTER_XT_MATCH_STATISTIC=y -CONFIG_NETFILTER_XT_MATCH_STRING=y -CONFIG_NETFILTER_XT_MATCH_TIME=y -CONFIG_NETFILTER_XT_MATCH_U32=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_ECN=y -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_NAT=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_NETMAP=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_IP_NF_MANGLE=y -CONFIG_IP_NF_RAW=y -CONFIG_IP_NF_SECURITY=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y -CONFIG_IP6_NF_IPTABLES=y -CONFIG_IP6_NF_MATCH_RPFILTER=y -CONFIG_IP6_NF_FILTER=y -CONFIG_IP6_NF_TARGET_REJECT=y -CONFIG_IP6_NF_MANGLE=y -CONFIG_IP6_NF_RAW=y -CONFIG_TIPC=y -CONFIG_L2TP=y -CONFIG_BRIDGE=y -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_HTB=y -CONFIG_NET_SCH_INGRESS=y -CONFIG_NET_CLS_U32=y -CONFIG_NET_CLS_BPF=y -CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_U32=y -CONFIG_NET_CLS_ACT=y -CONFIG_VSOCKETS=y -CONFIG_VIRTIO_VSOCKETS=y -CONFIG_BT=y -CONFIG_CFG80211=y -# CONFIG_CFG80211_DEFAULT_PS is not set -# CONFIG_CFG80211_CRDA_SUPPORT is not set -CONFIG_MAC80211=y -# CONFIG_MAC80211_RC_MINSTREL is not set -CONFIG_RFKILL=y -CONFIG_PCI=y -CONFIG_PCI_HOST_GENERIC=y -CONFIG_DEVTMPFS=y -# CONFIG_ALLOW_DEV_COREDUMP is not set -CONFIG_DEBUG_DEVRES=y -CONFIG_ZRAM=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_VIRTIO_BLK=y -CONFIG_UID_SYS_STATS=y -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=y -CONFIG_SCSI_UFSHCD=y -CONFIG_SCSI_UFSHCD_PLATFORM=y -CONFIG_MD=y -CONFIG_BLK_DEV_DM=y -CONFIG_DM_CRYPT=y -CONFIG_DM_UEVENT=y -CONFIG_DM_VERITY=y -CONFIG_DM_VERITY_FEC=y -CONFIG_DM_BOW=y -CONFIG_NETDEVICES=y -CONFIG_TUN=y -CONFIG_VIRTIO_NET=y -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_ADAPTEC is not set -# CONFIG_NET_VENDOR_AGERE is not set -# CONFIG_NET_VENDOR_ALACRITECH is not set -# CONFIG_NET_VENDOR_ALTEON is not set -# CONFIG_NET_VENDOR_AMAZON is not set -# CONFIG_NET_VENDOR_AMD is not set -# CONFIG_NET_VENDOR_AQUANTIA is not set -# CONFIG_NET_VENDOR_ARC is not set -# CONFIG_NET_VENDOR_ATHEROS is not set -# CONFIG_NET_VENDOR_AURORA is not set -# CONFIG_NET_VENDOR_BROADCOM is not set -# CONFIG_NET_VENDOR_BROCADE is not set -# CONFIG_NET_VENDOR_CADENCE is not set -# CONFIG_NET_VENDOR_CAVIUM is not set -# CONFIG_NET_VENDOR_CHELSIO is not set -# CONFIG_NET_VENDOR_CISCO is not set -# CONFIG_NET_VENDOR_CORTINA is not set -# CONFIG_NET_VENDOR_DEC is not set -# CONFIG_NET_VENDOR_DLINK is not set -# CONFIG_NET_VENDOR_EMULEX is not set -# CONFIG_NET_VENDOR_EZCHIP is not set -# CONFIG_NET_VENDOR_HISILICON is not set -# CONFIG_NET_VENDOR_HP is not set -# CONFIG_NET_VENDOR_HUAWEI is not set -# CONFIG_NET_VENDOR_INTEL is not set -# CONFIG_NET_VENDOR_MARVELL is not set -# CONFIG_NET_VENDOR_MELLANOX is not set -# CONFIG_NET_VENDOR_MICREL is not set -# CONFIG_NET_VENDOR_MICROCHIP is not set -# CONFIG_NET_VENDOR_MICROSEMI is not set -# CONFIG_NET_VENDOR_MYRI is not set -# CONFIG_NET_VENDOR_NATSEMI is not set -# CONFIG_NET_VENDOR_NETERION is not set -# CONFIG_NET_VENDOR_NETRONOME is not set -# CONFIG_NET_VENDOR_NI is not set -# CONFIG_NET_VENDOR_NVIDIA is not set -# CONFIG_NET_VENDOR_OKI is not set -# CONFIG_NET_VENDOR_PACKET_ENGINES is not set -# CONFIG_NET_VENDOR_QLOGIC is not set -# CONFIG_NET_VENDOR_QUALCOMM is not set -# CONFIG_NET_VENDOR_RDC is not set -# CONFIG_NET_VENDOR_REALTEK is not set -# CONFIG_NET_VENDOR_RENESAS is not set -# CONFIG_NET_VENDOR_ROCKER is not set -# CONFIG_NET_VENDOR_SAMSUNG is not set -# CONFIG_NET_VENDOR_SEEQ is not set -# CONFIG_NET_VENDOR_SOLARFLARE is not set -# CONFIG_NET_VENDOR_SILAN is not set -# CONFIG_NET_VENDOR_SIS is not set -# CONFIG_NET_VENDOR_SMSC is not set -# CONFIG_NET_VENDOR_SOCIONEXT is not set -CONFIG_STMMAC_ETH=y -# CONFIG_DWMAC_GENERIC is not set -# CONFIG_NET_VENDOR_SUN is not set -# CONFIG_NET_VENDOR_SYNOPSYS is not set -# CONFIG_NET_VENDOR_TEHUTI is not set -# CONFIG_NET_VENDOR_TI is not set -# CONFIG_NET_VENDOR_VIA is not set -# CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_ROCKCHIP_PHY=y -CONFIG_PPP=y -CONFIG_PPP_BSDCOMP=y -CONFIG_PPP_DEFLATE=y -CONFIG_PPP_MPPE=y -CONFIG_PPTP=y -CONFIG_PPPOL2TP=y -CONFIG_USB_RTL8152=y -CONFIG_USB_USBNET=y -# CONFIG_USB_NET_AX8817X is not set -# CONFIG_USB_NET_AX88179_178A is not set -# CONFIG_USB_NET_CDCETHER is not set -# CONFIG_USB_NET_CDC_NCM is not set -# CONFIG_USB_NET_NET1080 is not set -# CONFIG_USB_NET_CDC_SUBSET is not set -# CONFIG_USB_NET_ZAURUS is not set -# CONFIG_WLAN_VENDOR_ADMTEK is not set -# CONFIG_WLAN_VENDOR_ATH is not set -# CONFIG_WLAN_VENDOR_ATMEL is not set -# CONFIG_WLAN_VENDOR_BROADCOM is not set -# CONFIG_WLAN_VENDOR_CISCO is not set -# CONFIG_WLAN_VENDOR_INTEL is not set -# CONFIG_WLAN_VENDOR_INTERSIL is not set -# CONFIG_WLAN_VENDOR_MARVELL is not set -# CONFIG_WLAN_VENDOR_MEDIATEK is not set -# CONFIG_WLAN_VENDOR_RALINK is not set -# CONFIG_WLAN_VENDOR_REALTEK is not set -# CONFIG_WLAN_VENDOR_RSI is not set -# CONFIG_WLAN_VENDOR_ST is not set -# CONFIG_WLAN_VENDOR_TI is not set -# CONFIG_WLAN_VENDOR_ZYDAS is not set -# CONFIG_WLAN_VENDOR_QUANTENNA is not set -CONFIG_VIRT_WIFI=y -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_JOYSTICK=y -CONFIG_INPUT_MISC=y -CONFIG_INPUT_UINPUT=y -# CONFIG_VT is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_DEVMEM is not set -CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_EXAR is not set -CONFIG_SERIAL_8250_NR_UARTS=48 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -CONFIG_SERIAL_8250_DW=y -CONFIG_SERIAL_OF_PLATFORM=y -CONFIG_SERIAL_AMBA_PL011=y -CONFIG_SERIAL_AMBA_PL011_CONSOLE=y -CONFIG_VIRTIO_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_VIRTIO=y -# CONFIG_HW_RANDOM_CAVIUM is not set -# CONFIG_DEVPORT is not set -# CONFIG_I2C_COMPAT is not set -CONFIG_I2C_MUX_PINCTRL=y -CONFIG_I2C_DEMUX_PINCTRL=y -# CONFIG_I2C_HELPER_AUTO is not set -CONFIG_I2C_DESIGNWARE_PLATFORM=y -CONFIG_I2C_DESIGNWARE_SLAVE=y -CONFIG_I2C_RK3X=y -CONFIG_SPI=y -CONFIG_SPI_ROCKCHIP=y -CONFIG_SPMI=y -CONFIG_DEBUG_PINCTRL=y -CONFIG_PINCTRL_AMD=y -CONFIG_PINCTRL_SINGLE=y -CONFIG_PINCTRL_RK805=y -CONFIG_GPIO_SYSFS=y -CONFIG_GPIO_GENERIC_PLATFORM=y -CONFIG_POWER_AVS=y -CONFIG_ROCKCHIP_IODOMAIN=y -CONFIG_POWER_RESET_GPIO=y -CONFIG_POWER_RESET_GPIO_RESTART=y -CONFIG_POWER_RESET_RESTART=y -CONFIG_POWER_RESET_SYSCON=y -CONFIG_POWER_RESET_SYSCON_POWEROFF=y -CONFIG_SYSCON_REBOOT_MODE=y -# CONFIG_HWMON is not set -CONFIG_THERMAL=y -CONFIG_THERMAL_GOV_USER_SPACE=y -CONFIG_CPU_THERMAL=y -CONFIG_DEVFREQ_THERMAL=y -CONFIG_ROCKCHIP_THERMAL=y -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_PRETIMEOUT_GOV=y -# CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP is not set -CONFIG_DW_WATCHDOG=y -CONFIG_MFD_ACT8945A=y -CONFIG_MFD_RK808=y -CONFIG_REGULATOR_DEBUG=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y -CONFIG_REGULATOR_VIRTUAL_CONSUMER=y -CONFIG_REGULATOR_USERSPACE_CONSUMER=y -CONFIG_REGULATOR_GPIO=y -CONFIG_REGULATOR_PWM=y -CONFIG_REGULATOR_RK808=y -CONFIG_REGULATOR_VCTRL=y -CONFIG_MEDIA_SUPPORT=y -CONFIG_MEDIA_CAMERA_SUPPORT=y -CONFIG_MEDIA_CONTROLLER=y -# CONFIG_VGA_ARB is not set -CONFIG_DRM=y -# CONFIG_DRM_FBDEV_EMULATION is not set -CONFIG_DRM_ROCKCHIP=y -CONFIG_ROCKCHIP_DW_HDMI=y -CONFIG_DRM_VIRTIO_GPU=y -# CONFIG_LCD_CLASS_DEVICE is not set -CONFIG_BACKLIGHT_CLASS_DEVICE=y -CONFIG_SOUND=y -CONFIG_SND=y -CONFIG_SND_HRTIMER=y -CONFIG_SND_DYNAMIC_MINORS=y -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_VERBOSE_PROCFS is not set -# CONFIG_SND_DRIVERS is not set -CONFIG_SND_INTEL8X0=y -CONFIG_SND_USB_AUDIO=y -CONFIG_SND_SOC=y -CONFIG_SND_SOC_TS3A227E=y -CONFIG_HIDRAW=y -CONFIG_UHID=y -CONFIG_HID_APPLE=y -CONFIG_HID_ELECOM=y -CONFIG_HID_MAGICMOUSE=y -CONFIG_HID_MICROSOFT=y -CONFIG_HID_MULTITOUCH=y -CONFIG_USB_HIDDEV=y -CONFIG_USB=y -CONFIG_USB_OTG=y -CONFIG_USB_OTG_FSM=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_HCD_PLATFORM=y -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_HCD_PCI is not set -CONFIG_USB_OHCI_HCD_PLATFORM=y -CONFIG_USB_GADGET=y -CONFIG_USB_DUMMY_HCD=m -CONFIG_USB_CONFIGFS=y -CONFIG_USB_CONFIGFS_UEVENT=y -CONFIG_USB_CONFIGFS_F_FS=y -CONFIG_USB_CONFIGFS_F_ACC=y -CONFIG_USB_CONFIGFS_F_AUDIO_SRC=y -CONFIG_USB_CONFIGFS_F_MIDI=y -CONFIG_MMC=y -# CONFIG_PWRSEQ_EMMC is not set -# CONFIG_PWRSEQ_SIMPLE is not set -CONFIG_MMC_SDHCI=y -CONFIG_MMC_SDHCI_PLTFM=y -CONFIG_MMC_SDHCI_OF_ARASAN=y -CONFIG_MMC_SDHCI_OF_DWCMSHC=y -CONFIG_MMC_DW=y -CONFIG_MMC_DW_ROCKCHIP=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_EDAC=y -CONFIG_RTC_CLASS=y -# CONFIG_RTC_SYSTOHC is not set -CONFIG_RTC_DRV_RK808=y -CONFIG_RTC_DRV_PL030=y -CONFIG_RTC_DRV_PL031=y -CONFIG_DMADEVICES=y -CONFIG_PL330_DMA=y -CONFIG_VIRTIO_PCI=y -# CONFIG_VIRTIO_PCI_LEGACY is not set -CONFIG_VIRTIO_INPUT=y -CONFIG_VIRTIO_MMIO=y -CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y -CONFIG_STAGING=y -CONFIG_ASHMEM=y -CONFIG_ANDROID_VSOC=y -CONFIG_ION=y -CONFIG_ION_SYSTEM_HEAP=y -CONFIG_ION_SYSTEM_CONTIG_HEAP=y -CONFIG_COMMON_CLK_RK808=y -CONFIG_COMMON_CLK_SCPI=y -CONFIG_HWSPINLOCK=y -CONFIG_MAILBOX=y -CONFIG_ROCKCHIP_MBOX=y -CONFIG_ROCKCHIP_IOMMU=y -CONFIG_ARM_SMMU=y -CONFIG_QCOM_COMMAND_DB=y -CONFIG_QCOM_RPMH=y -CONFIG_ROCKCHIP_PM_DOMAINS=y -CONFIG_DEVFREQ_GOV_PERFORMANCE=y -CONFIG_DEVFREQ_GOV_POWERSAVE=y -CONFIG_DEVFREQ_GOV_USERSPACE=y -CONFIG_DEVFREQ_GOV_PASSIVE=y -CONFIG_ARM_RK3399_DMC_DEVFREQ=y -CONFIG_PWM=y -CONFIG_PWM_ROCKCHIP=y -CONFIG_QCOM_PDC=y -CONFIG_PHY_ROCKCHIP_EMMC=y -CONFIG_PHY_ROCKCHIP_INNO_HDMI=y -CONFIG_PHY_ROCKCHIP_INNO_USB2=y -CONFIG_PHY_ROCKCHIP_USB=y -CONFIG_RAS=y -CONFIG_ANDROID=y -CONFIG_ANDROID_BINDER_IPC=y -CONFIG_ROCKCHIP_EFUSE=y -CONFIG_INTERCONNECT=y -CONFIG_EXT4_FS=y -CONFIG_EXT4_FS_SECURITY=y -CONFIG_F2FS_FS=y -CONFIG_F2FS_FS_SECURITY=y -CONFIG_FS_ENCRYPTION=y -# CONFIG_DNOTIFY is not set -CONFIG_QUOTA=y -CONFIG_QFMT_V2=y -CONFIG_FUSE_FS=y -CONFIG_OVERLAY_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS_POSIX_ACL=y -# CONFIG_EFIVAR_FS is not set -CONFIG_PSTORE=y -CONFIG_PSTORE_CONSOLE=y -CONFIG_PSTORE_RAM=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y -CONFIG_SECURITY=y -CONFIG_SECURITY_NETWORK=y -CONFIG_HARDENED_USERCOPY=y -CONFIG_SECURITY_SELINUX=y -CONFIG_CRYPTO_ADIANTUM=y -CONFIG_CRYPTO_MD4=y -CONFIG_CRYPTO_SHA512=y -CONFIG_CRYPTO_LZ4=y -CONFIG_CRYPTO_ZSTD=y -CONFIG_CRYPTO_ANSI_CPRNG=y -CONFIG_CRYPTO_DEV_ROCKCHIP=y -CONFIG_CRYPTO_DEV_VIRTIO=y -CONFIG_CRC_CCITT=y -CONFIG_CRC8=y -CONFIG_XZ_DEC=y -CONFIG_DMA_CMA=y -CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_INFO=y -# CONFIG_ENABLE_MUST_CHECK is not set -# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_STACK_USAGE=y -CONFIG_DEBUG_MEMORY_INIT=y -CONFIG_SOFTLOCKUP_DETECTOR=y -# CONFIG_DETECT_HUNG_TASK is not set -CONFIG_PANIC_TIMEOUT=5 -CONFIG_SCHEDSTATS=y -CONFIG_FUNCTION_TRACER=y -# CONFIG_RUNTIME_TESTING_MENU is not set -CONFIG_CORESIGHT=y -CONFIG_CORESIGHT_STM=y diff --git a/arch/arm64/configs/rockpi4_gki.fragment b/arch/arm64/configs/rockpi4_gki.fragment new file mode 100644 index 000000000000..2af01b890c59 --- /dev/null +++ b/arch/arm64/configs/rockpi4_gki.fragment @@ -0,0 +1,82 @@ +# Core features +CONFIG_ARCH_ROCKCHIP=y +# CONFIG_CLK_PX30 is not set +# CONFIG_CLK_RV110X is not set +# CONFIG_CLK_RK3036 is not set +# CONFIG_CLK_RK312X is not set +# CONFIG_CLK_RK3188 is not set +# CONFIG_CLK_RK322X is not set +# CONFIG_CLK_RK3288 is not set +# CONFIG_CLK_RK3308 is not set +# CONFIG_CLK_RK3328 is not set +# CONFIG_CLK_RK3368 is not set +CONFIG_COMMON_CLK_RK808=m +CONFIG_CPUFREQ_DT=m +CONFIG_MFD_RK808=m +CONFIG_PCIE_ROCKCHIP_HOST=m +CONFIG_PHY_ROCKCHIP_PCIE=m +CONFIG_PL330_DMA=m +CONFIG_PWM_ROCKCHIP=m +CONFIG_PWRSEQ_SIMPLE=m +CONFIG_REGULATOR_FAN53555=m +CONFIG_REGULATOR_PWM=m +CONFIG_REGULATOR_RK808=m +CONFIG_ROCKCHIP_EFUSE=m +CONFIG_ROCKCHIP_IOMMU=y +CONFIG_ROCKCHIP_IODOMAIN=m +CONFIG_ROCKCHIP_MBOX=y +CONFIG_ROCKCHIP_PM_DOMAINS=y +CONFIG_ROCKCHIP_THERMAL=m + +# Ethernet +CONFIG_STMMAC_ETH=m +# CONFIG_DWMAC_GENERIC is not set +# CONFIG_DWMAC_IPQ806X is not set +# CONFIG_DWMAC_QCOM_ETHQOS is not set +# CONFIG_DWMAC_SUNXI is not set +# CONFIG_DWMAC_SUN8I is not set + +# I2C +CONFIG_I2C_RK3X=m + +# Watchdog +CONFIG_DW_WATCHDOG=m + +# Display +CONFIG_DRM_ROCKCHIP=m +CONFIG_ROCKCHIP_ANALOGIX_DP=y +CONFIG_ROCKCHIP_DW_HDMI=y +CONFIG_ROCKCHIP_DW_MIPI_DSI=y + +# USB 2.x +CONFIG_PHY_ROCKCHIP_INNO_USB2=m +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_HCD_PCI is not set +CONFIG_USB_OHCI_HCD_PLATFORM=m + +# eMMC / SD-Card +CONFIG_MMC_SDHCI_OF_ARASAN=m +CONFIG_MMC_DW=m +CONFIG_MMC_DW_ROCKCHIP=m +CONFIG_PHY_ROCKCHIP_EMMC=m + +# Real-time clock +CONFIG_RTC_DRV_RK808=m + +# Type-C +CONFIG_PHY_ROCKCHIP_TYPEC=m + +# SAR ADC +CONFIG_ROCKCHIP_SARADC=m + +# Audio +CONFIG_SND_SOC_ROCKCHIP_I2S=m + +# To boot Linux distributions like Debian +CONFIG_DEVTMPFS=y + +# To bootstrap rootfs with QEMU +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_BLK=m +CONFIG_VIRTIO_NET=m diff --git a/arch/arm64/include/asm/alternative-macros.h b/arch/arm64/include/asm/alternative-macros.h index 5cc2c8f11fe3..9e2f222a8543 100644 --- a/arch/arm64/include/asm/alternative-macros.h +++ b/arch/arm64/include/asm/alternative-macros.h @@ -198,11 +198,6 @@ alternative_endif #define _ALTERNATIVE_CFG(insn1, insn2, cap, cfg, ...) \ alternative_insn insn1, insn2, cap, IS_ENABLED(cfg) -.macro user_alt, label, oldinstr, newinstr, cond -9999: alternative_insn "\oldinstr", "\newinstr", \cond - _asm_extable 9999b, \label -.endm - #endif /* __ASSEMBLY__ */ /* diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h index 880b9054d75c..8dc38323d8b7 100644 --- a/arch/arm64/include/asm/arch_gicv3.h +++ b/arch/arm64/include/asm/arch_gicv3.h @@ -124,7 +124,8 @@ static inline u32 gic_read_rpr(void) #define gic_read_lpir(c) readq_relaxed(c) #define gic_write_lpir(v, c) writeq_relaxed(v, c) -#define gic_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l)) +#define gic_flush_dcache_to_poc(a,l) \ + dcache_clean_inval_poc((unsigned long)(a), (unsigned long)(a)+(l)) #define gits_read_baser(c) readq_relaxed(c) #define gits_write_baser(v, c) writeq_relaxed(v, c) diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 9f0ec21d6327..88d20f04c64a 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -165,25 +165,6 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl) isb(); } -/* - * Ensure that reads of the counter are treated the same as memory reads - * for the purposes of ordering by subsequent memory barriers. - * - * This insanity brought to you by speculative system register reads, - * out-of-order memory accesses, sequence locks and Thomas Gleixner. - * - * http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html - */ -#define arch_counter_enforce_ordering(val) do { \ - u64 tmp, _val = (val); \ - \ - asm volatile( \ - " eor %0, %1, %1\n" \ - " add %0, sp, %0\n" \ - " ldr xzr, [%0]" \ - : "=r" (tmp) : "r" (_val)); \ -} while (0) - static __always_inline u64 __arch_counter_get_cntpct_stable(void) { u64 cnt; @@ -224,8 +205,6 @@ static __always_inline u64 __arch_counter_get_cntvct(void) return cnt; } -#undef arch_counter_enforce_ordering - static inline int arch_timer_arch_init(void) { return 0; diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h index ffb1a40d5475..09e43272ccb0 100644 --- a/arch/arm64/include/asm/archrandom.h +++ b/arch/arm64/include/asm/archrandom.h @@ -4,10 +4,26 @@ #ifdef CONFIG_ARCH_RANDOM +#include #include #include #include +#define ARM_SMCCC_TRNG_MIN_VERSION 0x10000UL + +extern bool smccc_trng_available; + +static inline bool __init smccc_probe_trng(void) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_VERSION, &res); + if ((s32)res.a0 < 0) + return false; + + return res.a0 >= ARM_SMCCC_TRNG_MIN_VERSION; +} + static inline bool __arm64_rndr(unsigned long *v) { bool ok; @@ -38,26 +54,55 @@ static inline bool __must_check arch_get_random_int(unsigned int *v) static inline bool __must_check arch_get_random_seed_long(unsigned long *v) { + struct arm_smccc_res res; + + /* + * We prefer the SMCCC call, since its semantics (return actual + * hardware backed entropy) is closer to the idea behind this + * function here than what even the RNDRSS register provides + * (the output of a pseudo RNG freshly seeded by a TRNG). + */ + if (smccc_trng_available) { + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 64, &res); + if ((int)res.a0 >= 0) { + *v = res.a3; + return true; + } + } + /* * Only support the generic interface after we have detected * the system wide capability, avoiding complexity with the * cpufeature code and with potential scheduling between CPUs * with and without the feature. */ - if (!cpus_have_const_cap(ARM64_HAS_RNG)) - return false; + if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v)) + return true; - return __arm64_rndr(v); + return false; } - static inline bool __must_check arch_get_random_seed_int(unsigned int *v) { + struct arm_smccc_res res; unsigned long val; - bool ok = arch_get_random_seed_long(&val); - *v = val; - return ok; + if (smccc_trng_available) { + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 32, &res); + if ((int)res.a0 >= 0) { + *v = res.a3 & GENMASK(31, 0); + return true; + } + } + + if (cpus_have_const_cap(ARM64_HAS_RNG)) { + if (__arm64_rndr(&val)) { + *v = val; + return true; + } + } + + return false; } static inline bool __init __early_cpu_has_rndr(void) @@ -72,12 +117,29 @@ arch_get_random_seed_long_early(unsigned long *v) { WARN_ON(system_state != SYSTEM_BOOTING); - if (!__early_cpu_has_rndr()) - return false; + if (smccc_trng_available) { + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND64, 64, &res); + if ((int)res.a0 >= 0) { + *v = res.a3; + return true; + } + } + + if (__early_cpu_has_rndr() && __arm64_rndr(v)) + return true; - return __arm64_rndr(v); + return false; } #define arch_get_random_seed_long_early arch_get_random_seed_long_early +#else /* !CONFIG_ARCH_RANDOM */ + +static inline bool __init smccc_probe_trng(void) +{ + return false; +} + #endif /* CONFIG_ARCH_RANDOM */ #endif /* _ASM_ARCHRANDOM_H */ diff --git a/arch/arm64/include/asm/asm-uaccess.h b/arch/arm64/include/asm/asm-uaccess.h index 2b5454fa0f24..aa05df4f94e2 100644 --- a/arch/arm64/include/asm/asm-uaccess.h +++ b/arch/arm64/include/asm/asm-uaccess.h @@ -15,10 +15,10 @@ .macro __uaccess_ttbr0_disable, tmp1 mrs \tmp1, ttbr1_el1 // swapper_pg_dir bic \tmp1, \tmp1, #TTBR_ASID_MASK - sub \tmp1, \tmp1, #RESERVED_TTBR0_SIZE // reserved_ttbr0 just before swapper_pg_dir + sub \tmp1, \tmp1, #PAGE_SIZE // reserved_pg_dir just before swapper_pg_dir msr ttbr0_el1, \tmp1 // set reserved TTBR0_EL1 isb - add \tmp1, \tmp1, #RESERVED_TTBR0_SIZE + add \tmp1, \tmp1, #PAGE_SIZE msr ttbr1_el1, \tmp1 // set reserved ASID isb .endm diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h index 4eed9601d9d4..19150fc1c794 100644 --- a/arch/arm64/include/asm/assembler.h +++ b/arch/arm64/include/asm/assembler.h @@ -130,15 +130,27 @@ alternative_endif .endm /* - * Emit an entry into the exception table + * Create an exception table entry for `insn`, which will branch to `fixup` + * when an unhandled fault is taken. */ - .macro _asm_extable, from, to + .macro _asm_extable, insn, fixup .pushsection __ex_table, "a" .align 3 - .long (\from - .), (\to - .) + .long (\insn - .), (\fixup - .) .popsection .endm +/* + * Create an exception table entry for `insn` if `fixup` is provided. Otherwise + * do nothing. + */ + .macro _cond_extable, insn, fixup + .ifnc \fixup, + _asm_extable \insn, \fixup + .endif + .endm + + #define USER(l, x...) \ 9999: x; \ _asm_extable 9999b, l @@ -375,51 +387,53 @@ alternative_cb_end bfi \tcr, \tmp0, \pos, #3 .endm + .macro __dcache_op_workaround_clean_cache, op, addr +alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE + dc \op, \addr +alternative_else + dc civac, \addr +alternative_endif + .endm + /* * Macro to perform a data cache maintenance for the interval - * [kaddr, kaddr + size) + * [start, end) * * op: operation passed to dc instruction * domain: domain used in dsb instruciton - * kaddr: starting virtual address of the region - * size: size of the region - * Corrupts: kaddr, size, tmp1, tmp2 + * start: starting virtual address of the region + * end: end virtual address of the region + * fixup: optional label to branch to on user fault + * Corrupts: start, end, tmp1, tmp2 */ - .macro __dcache_op_workaround_clean_cache, op, kaddr -alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE - dc \op, \kaddr -alternative_else - dc civac, \kaddr -alternative_endif - .endm - - .macro dcache_by_line_op op, domain, kaddr, size, tmp1, tmp2 + .macro dcache_by_line_op op, domain, start, end, tmp1, tmp2, fixup dcache_line_size \tmp1, \tmp2 - add \size, \kaddr, \size sub \tmp2, \tmp1, #1 - bic \kaddr, \kaddr, \tmp2 -9998: + bic \start, \start, \tmp2 +.Ldcache_op\@: .ifc \op, cvau - __dcache_op_workaround_clean_cache \op, \kaddr + __dcache_op_workaround_clean_cache \op, \start .else .ifc \op, cvac - __dcache_op_workaround_clean_cache \op, \kaddr + __dcache_op_workaround_clean_cache \op, \start .else .ifc \op, cvap - sys 3, c7, c12, 1, \kaddr // dc cvap + sys 3, c7, c12, 1, \start // dc cvap .else .ifc \op, cvadp - sys 3, c7, c13, 1, \kaddr // dc cvadp + sys 3, c7, c13, 1, \start // dc cvadp .else - dc \op, \kaddr + dc \op, \start .endif .endif .endif .endif - add \kaddr, \kaddr, \tmp1 - cmp \kaddr, \size - b.lo 9998b + add \start, \start, \tmp1 + cmp \start, \end + b.lo .Ldcache_op\@ dsb \domain + + _cond_extable .Ldcache_op\@, \fixup .endm /* @@ -427,20 +441,22 @@ alternative_endif * [start, end) * * start, end: virtual addresses describing the region - * label: A label to branch to on user fault. + * fixup: optional label to branch to on user fault * Corrupts: tmp1, tmp2 */ - .macro invalidate_icache_by_line start, end, tmp1, tmp2, label + .macro invalidate_icache_by_line start, end, tmp1, tmp2, fixup icache_line_size \tmp1, \tmp2 sub \tmp2, \tmp1, #1 bic \tmp2, \start, \tmp2 -9997: -USER(\label, ic ivau, \tmp2) // invalidate I line PoU +.Licache_op\@: + ic ivau, \tmp2 // invalidate I line PoU add \tmp2, \tmp2, \tmp1 cmp \tmp2, \end - b.lo 9997b + b.lo .Licache_op\@ dsb ish isb + + _cond_extable .Licache_op\@, \fixup .endm /* diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h index 5a8367a2b868..bffa8860af1c 100644 --- a/arch/arm64/include/asm/barrier.h +++ b/arch/arm64/include/asm/barrier.h @@ -71,6 +71,25 @@ static inline unsigned long array_index_mask_nospec(unsigned long idx, return mask; } +/* + * Ensure that reads of the counter are treated the same as memory reads + * for the purposes of ordering by subsequent memory barriers. + * + * This insanity brought to you by speculative system register reads, + * out-of-order memory accesses, sequence locks and Thomas Gleixner. + * + * http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html + */ +#define arch_counter_enforce_ordering(val) do { \ + u64 tmp, _val = (val); \ + \ + asm volatile( \ + " eor %0, %1, %1\n" \ + " add %0, sp, %0\n" \ + " ldr xzr, [%0]" \ + : "=r" (tmp) : "r" (_val)); \ +} while (0) + #define __smp_mb() dmb(ish) #define __smp_rmb() dmb(ishld) #define __smp_wmb() dmb(ishst) diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h index 9384fd8fc13c..c9a478f4b83c 100644 --- a/arch/arm64/include/asm/cacheflush.h +++ b/arch/arm64/include/asm/cacheflush.h @@ -30,50 +30,58 @@ * the implementation assumes non-aliasing VIPT D-cache and (aliasing) * VIPT I-cache. * - * flush_cache_mm(mm) + * All functions below apply to the interval [start, end) + * - start - virtual start address (inclusive) + * - end - virtual end address (exclusive) * - * Clean and invalidate all user space cache entries - * before a change of page tables. + * caches_clean_inval_pou(start, end) * - * flush_icache_range(start, end) + * Ensure coherency between the I-cache and the D-cache region to + * the Point of Unification. * - * Ensure coherency between the I-cache and the D-cache in the - * region described by start, end. - * - start - virtual start address - * - end - virtual end address + * caches_clean_inval_user_pou(start, end) * - * invalidate_icache_range(start, end) + * Ensure coherency between the I-cache and the D-cache region to + * the Point of Unification. + * Use only if the region might access user memory. * - * Invalidate the I-cache in the region described by start, end. - * - start - virtual start address - * - end - virtual end address + * icache_inval_pou(start, end) * - * __flush_cache_user_range(start, end) + * Invalidate I-cache region to the Point of Unification. * - * Ensure coherency between the I-cache and the D-cache in the - * region described by start, end. - * - start - virtual start address - * - end - virtual end address + * dcache_clean_inval_poc(start, end) * - * __flush_dcache_area(kaddr, size) + * Clean and invalidate D-cache region to the Point of Coherency. * - * Ensure that the data held in page is written back. - * - kaddr - page address - * - size - region size + * dcache_inval_poc(start, end) + * + * Invalidate D-cache region to the Point of Coherency. + * + * dcache_clean_poc(start, end) + * + * Clean D-cache region to the Point of Coherency. + * + * dcache_clean_pop(start, end) + * + * Clean D-cache region to the Point of Persistence. + * + * dcache_clean_pou(start, end) + * + * Clean D-cache region to the Point of Unification. */ -extern void __flush_icache_range(unsigned long start, unsigned long end); -extern int invalidate_icache_range(unsigned long start, unsigned long end); -extern void __flush_dcache_area(void *addr, size_t len); -extern void __inval_dcache_area(void *addr, size_t len); -extern void __clean_dcache_area_poc(void *addr, size_t len); -extern void __clean_dcache_area_pop(void *addr, size_t len); -extern void __clean_dcache_area_pou(void *addr, size_t len); -extern long __flush_cache_user_range(unsigned long start, unsigned long end); -extern void sync_icache_aliases(void *kaddr, unsigned long len); +extern void caches_clean_inval_pou(unsigned long start, unsigned long end); +extern void icache_inval_pou(unsigned long start, unsigned long end); +extern void dcache_clean_inval_poc(unsigned long start, unsigned long end); +extern void dcache_inval_poc(unsigned long start, unsigned long end); +extern void dcache_clean_poc(unsigned long start, unsigned long end); +extern void dcache_clean_pop(unsigned long start, unsigned long end); +extern void dcache_clean_pou(unsigned long start, unsigned long end); +extern long caches_clean_inval_user_pou(unsigned long start, unsigned long end); +extern void sync_icache_aliases(unsigned long start, unsigned long end); static inline void flush_icache_range(unsigned long start, unsigned long end) { - __flush_icache_range(start, end); + caches_clean_inval_pou(start, end); /* * IPI all online CPUs so that they undergo a context synchronization @@ -127,7 +135,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *, #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 extern void flush_dcache_page(struct page *); -static __always_inline void __flush_icache_all(void) +static __always_inline void icache_inval_all_pou(void) { if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC)) return; diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index 87fc3b173677..7a2d841a6fd4 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -63,6 +63,23 @@ struct arm64_ftr_bits { s64 safe_val; /* safe value for FTR_EXACT features */ }; +/* + * Describe the early feature override to the core override code: + * + * @val Values that are to be merged into the final + * sanitised value of the register. Only the bitfields + * set to 1 in @mask are valid + * @mask Mask of the features that are overridden by @val + * + * A @mask field set to full-1 indicates that the corresponding field + * in @val is a valid override. + * + * A @mask field set to full-0 with the corresponding @val field set + * to full-0 denotes that this field has no override + * + * A @mask field set to full-0 with the corresponding @val field set + * to full-1 denotes thath this field has an invalid override. + */ struct arm64_ftr_override { u64 val; u64 mask; diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 05c9c55768b8..ff3879ac2267 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -168,6 +168,8 @@ static inline int sve_get_current_vl(void) static inline void sve_user_disable(void) { BUILD_BUG(); } static inline void sve_user_enable(void) { BUILD_BUG(); } +#define sve_cond_update_zcr_vq(val, reg) do { } while (0) + static inline void sve_init_vq_map(void) { } static inline void sve_update_vq_map(void) { } static inline int sve_verify_vq_map(void) { return 0; } diff --git a/arch/arm64/include/asm/hypervisor.h b/arch/arm64/include/asm/hypervisor.h index f9cc1d021791..0ae427f352c8 100644 --- a/arch/arm64/include/asm/hypervisor.h +++ b/arch/arm64/include/asm/hypervisor.h @@ -4,4 +4,7 @@ #include +void kvm_init_hyp_services(void); +bool kvm_arm_hyp_service_available(u32 func_id); + #endif diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h index 19ca76ea60d9..587c504a4c8b 100644 --- a/arch/arm64/include/asm/kernel-pgtable.h +++ b/arch/arm64/include/asm/kernel-pgtable.h @@ -89,12 +89,6 @@ #define INIT_DIR_SIZE (PAGE_SIZE * EARLY_PAGES(KIMAGE_VADDR, _end)) #define IDMAP_DIR_SIZE (IDMAP_PGTABLE_LEVELS * PAGE_SIZE) -#ifdef CONFIG_ARM64_SW_TTBR0_PAN -#define RESERVED_TTBR0_SIZE (PAGE_SIZE) -#else -#define RESERVED_TTBR0_SIZE (0) -#endif - /* Initial memory map size */ #if ARM64_SWAPPER_USES_SECTION_MAPS #define SWAPPER_BLOCK_SHIFT SECTION_SHIFT diff --git a/arch/arm64/include/asm/kexec.h b/arch/arm64/include/asm/kexec.h index d24b527e8c00..9befcd87e9a8 100644 --- a/arch/arm64/include/asm/kexec.h +++ b/arch/arm64/include/asm/kexec.h @@ -90,18 +90,19 @@ static inline void crash_prepare_suspend(void) {} static inline void crash_post_resume(void) {} #endif -#ifdef CONFIG_KEXEC_FILE #define ARCH_HAS_KIMAGE_ARCH struct kimage_arch { void *dtb; - unsigned long dtb_mem; + phys_addr_t dtb_mem; + phys_addr_t kern_reloc; /* Core ELF header buffer */ void *elf_headers; unsigned long elf_headers_mem; unsigned long elf_headers_sz; }; +#ifdef CONFIG_KEXEC_FILE extern const struct kexec_file_ops kexec_image_ops; struct kimage; diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h index 692c9049befa..d436831dd706 100644 --- a/arch/arm64/include/asm/kvm_arm.h +++ b/arch/arm64/include/asm/kvm_arm.h @@ -12,7 +12,8 @@ #include /* Hyp Configuration Register (HCR) bits */ -#define HCR_ATA (UL(1) << 56) +#define HCR_ATA_SHIFT 56 +#define HCR_ATA (UL(1) << HCR_ATA_SHIFT) #define HCR_FWB (UL(1) << 46) #define HCR_API (UL(1) << 41) #define HCR_APK (UL(1) << 40) diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index c453b829783d..24ae7e9b64fe 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -63,6 +63,7 @@ #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector 18 #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize 19 #define __KVM_HOST_SMCCC_FUNC___pkvm_mark_hyp 20 +#define __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc 21 #ifndef __ASSEMBLY__ @@ -201,6 +202,8 @@ extern void __kvm_timer_set_cntvoff(u64 cntvoff); extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); +extern void __kvm_adjust_pc(struct kvm_vcpu *vcpu); + extern u64 __vgic_v3_get_gic_config(void); extern u64 __vgic_v3_read_vmcr(void); extern void __vgic_v3_write_vmcr(u32 vmcr); diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 01b9857757f2..fd418955e31e 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -84,6 +84,9 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) if (cpus_have_const_cap(ARM64_MISMATCHED_CACHE_TYPE) || vcpu_el1_is_32bit(vcpu)) vcpu->arch.hcr_el2 |= HCR_TID2; + + if (kvm_has_mte(vcpu->kvm)) + vcpu->arch.hcr_el2 |= HCR_ATA; } static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 923ffa4cbc5f..f5fc6be4fa99 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -47,6 +47,7 @@ #define KVM_REQ_VCPU_RESET KVM_ARCH_REQ(2) #define KVM_REQ_RECORD_STEAL KVM_ARCH_REQ(3) #define KVM_REQ_RELOAD_GICv4 KVM_ARCH_REQ(4) +#define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5) #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ KVM_DIRTY_LOG_INITIALLY_SET) @@ -133,6 +134,9 @@ struct kvm_arch { u8 pfr0_csv2; u8 pfr0_csv3; + + /* Memory Tagging Extension enabled for the guest */ + bool mte_enabled; }; struct kvm_vcpu_fault_info { @@ -207,6 +211,12 @@ enum vcpu_sysreg { CNTP_CVAL_EL0, CNTP_CTL_EL0, + /* Memory Tagging Extension registers */ + RGSR_EL1, /* Random Allocation Tag Seed Register */ + GCR_EL1, /* Tag Control Register */ + TFSR_EL1, /* Tag Fault Status Register (EL1) */ + TFSRE0_EL1, /* Tag Fault Status Register (EL0) */ + /* 32bit specific registers. Keep them at the end of the range */ DACR32_EL2, /* Domain Access Control Register */ IFSR32_EL2, /* Instruction Fault Status Register */ @@ -645,7 +655,6 @@ void kvm_arm_resume_guest(struct kvm *kvm); #endif /* __KVM_NVHE_HYPERVISOR__ */ void force_vm_exit(const cpumask_t *mask); -void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot); int handle_exit(struct kvm_vcpu *vcpu, int exception_index); void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index); @@ -724,6 +733,9 @@ int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu, int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr); +long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm, + struct kvm_arm_copy_mte_tags *copy_tags); + /* Guest/host FPSIMD coordination helpers */ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu); @@ -772,6 +784,7 @@ bool kvm_arm_vcpu_is_finalized(struct kvm_vcpu *vcpu); #define kvm_arm_vcpu_sve_finalized(vcpu) \ ((vcpu)->arch.flags & KVM_ARM64_VCPU_SVE_FINALIZED) +#define kvm_has_mte(kvm) (system_supports_mte() && (kvm)->arch.mte_enabled) #define kvm_vcpu_has_pmu(vcpu) \ (test_bit(KVM_ARM_VCPU_PMU_V3, (vcpu)->arch.features)) diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h index 8ef9d88826d4..9d60b3006efc 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -102,7 +102,6 @@ u64 __guest_enter(struct kvm_vcpu *vcpu); bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt); -void __noreturn hyp_panic(void); #ifdef __KVM_NVHE_HYPERVISOR__ void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr, u64 elr, u64 par); diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h index 9d64fa73ee67..b52c5c4b9a3d 100644 --- a/arch/arm64/include/asm/kvm_mmu.h +++ b/arch/arm64/include/asm/kvm_mmu.h @@ -121,6 +121,8 @@ void kvm_update_va_mask(struct alt_instr *alt, void kvm_compute_layout(void); void kvm_apply_hyp_relocations(void); +#define __hyp_pa(x) (((phys_addr_t)(x)) + hyp_physvirt_offset) + static __always_inline unsigned long __kern_hyp_va(unsigned long v) { asm volatile(ALTERNATIVE_CB("and %0, %0, #1\n" @@ -178,17 +180,16 @@ static inline void *__kvm_vector_slot2addr(void *base, struct kvm; -#define kvm_flush_dcache_to_poc(a,l) __flush_dcache_area((a), (l)) +#define kvm_flush_dcache_to_poc(a,l) \ + dcache_clean_inval_poc((unsigned long)(a), (unsigned long)(a)+(l)) static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu) { return (vcpu_read_sys_reg(vcpu, SCTLR_EL1) & 0b101) == 0b101; } -static inline void __clean_dcache_guest_page(kvm_pfn_t pfn, unsigned long size) +static inline void __clean_dcache_guest_page(void *va, size_t size) { - void *va = page_address(pfn_to_page(pfn)); - /* * With FWB, we ensure that the guest always accesses memory using * cacheable attributes, and we don't have to clean to PoC when @@ -201,18 +202,14 @@ static inline void __clean_dcache_guest_page(kvm_pfn_t pfn, unsigned long size) kvm_flush_dcache_to_poc(va, size); } -static inline void __invalidate_icache_guest_page(kvm_pfn_t pfn, - unsigned long size) +static inline void __invalidate_icache_guest_page(void *va, size_t size) { if (icache_is_aliasing()) { /* any kind of VIPT cache */ - __flush_icache_all(); + icache_inval_all_pou(); } else if (is_kernel_in_hyp_mode() || !icache_is_vpipt()) { /* PIPT or VPIPT at EL2 (see comment in __kvm_tlb_flush_vmid_ipa) */ - void *va = page_address(pfn_to_page(pfn)); - - invalidate_icache_range((unsigned long)va, - (unsigned long)va + size); + icache_inval_pou((unsigned long)va, (unsigned long)va + size); } } diff --git a/arch/arm64/include/asm/kvm_mte.h b/arch/arm64/include/asm/kvm_mte.h new file mode 100644 index 000000000000..de002636eb1f --- /dev/null +++ b/arch/arm64/include/asm/kvm_mte.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020-2021 ARM Ltd. + */ +#ifndef __ASM_KVM_MTE_H +#define __ASM_KVM_MTE_H + +#ifdef __ASSEMBLY__ + +#include + +#ifdef CONFIG_ARM64_MTE + +.macro mte_switch_to_guest g_ctxt, h_ctxt, reg1 +alternative_if_not ARM64_MTE + b .L__skip_switch\@ +alternative_else_nop_endif + mrs \reg1, hcr_el2 + tbz \reg1, #(HCR_ATA_SHIFT), .L__skip_switch\@ + + mrs_s \reg1, SYS_RGSR_EL1 + str \reg1, [\h_ctxt, #CPU_RGSR_EL1] + mrs_s \reg1, SYS_GCR_EL1 + str \reg1, [\h_ctxt, #CPU_GCR_EL1] + + ldr \reg1, [\g_ctxt, #CPU_RGSR_EL1] + msr_s SYS_RGSR_EL1, \reg1 + ldr \reg1, [\g_ctxt, #CPU_GCR_EL1] + msr_s SYS_GCR_EL1, \reg1 + +.L__skip_switch\@: +.endm + +.macro mte_switch_to_hyp g_ctxt, h_ctxt, reg1 +alternative_if_not ARM64_MTE + b .L__skip_switch\@ +alternative_else_nop_endif + mrs \reg1, hcr_el2 + tbz \reg1, #(HCR_ATA_SHIFT), .L__skip_switch\@ + + mrs_s \reg1, SYS_RGSR_EL1 + str \reg1, [\g_ctxt, #CPU_RGSR_EL1] + mrs_s \reg1, SYS_GCR_EL1 + str \reg1, [\g_ctxt, #CPU_GCR_EL1] + + ldr \reg1, [\h_ctxt, #CPU_RGSR_EL1] + msr_s SYS_RGSR_EL1, \reg1 + ldr \reg1, [\h_ctxt, #CPU_GCR_EL1] + msr_s SYS_GCR_EL1, \reg1 + + isb + +.L__skip_switch\@: +.endm + +#else /* !CONFIG_ARM64_MTE */ + +.macro mte_switch_to_guest g_ctxt, h_ctxt, reg1 +.endm + +.macro mte_switch_to_hyp g_ctxt, h_ctxt, reg1 +.endm + +#endif /* CONFIG_ARM64_MTE */ +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_KVM_MTE_H */ diff --git a/arch/arm64/include/asm/kvm_pgtable.h b/arch/arm64/include/asm/kvm_pgtable.h index c3674c47d48c..f004c0115d89 100644 --- a/arch/arm64/include/asm/kvm_pgtable.h +++ b/arch/arm64/include/asm/kvm_pgtable.h @@ -27,23 +27,29 @@ typedef u64 kvm_pte_t; /** * struct kvm_pgtable_mm_ops - Memory management callbacks. - * @zalloc_page: Allocate a single zeroed memory page. The @arg parameter - * can be used by the walker to pass a memcache. The - * initial refcount of the page is 1. - * @zalloc_pages_exact: Allocate an exact number of zeroed memory pages. The - * @size parameter is in bytes, and is rounded-up to the - * next page boundary. The resulting allocation is - * physically contiguous. - * @free_pages_exact: Free an exact number of memory pages previously - * allocated by zalloc_pages_exact. - * @get_page: Increment the refcount on a page. - * @put_page: Decrement the refcount on a page. When the refcount - * reaches 0 the page is automatically freed. - * @page_count: Return the refcount of a page. - * @phys_to_virt: Convert a physical address into a virtual address mapped - * in the current context. - * @virt_to_phys: Convert a virtual address mapped in the current context - * into a physical address. + * @zalloc_page: Allocate a single zeroed memory page. + * The @arg parameter can be used by the walker + * to pass a memcache. The initial refcount of + * the page is 1. + * @zalloc_pages_exact: Allocate an exact number of zeroed memory pages. + * The @size parameter is in bytes, and is rounded + * up to the next page boundary. The resulting + * allocation is physically contiguous. + * @free_pages_exact: Free an exact number of memory pages previously + * allocated by zalloc_pages_exact. + * @get_page: Increment the refcount on a page. + * @put_page: Decrement the refcount on a page. When the + * refcount reaches 0 the page is automatically + * freed. + * @page_count: Return the refcount of a page. + * @phys_to_virt: Convert a physical address into a virtual + * address mapped in the current context. + * @virt_to_phys: Convert a virtual address mapped in the current + * context into a physical address. + * @dcache_clean_inval_poc: Clean and invalidate the data cache to the PoC + * for the specified memory address range. + * @icache_inval_pou: Invalidate the instruction cache to the PoU + * for the specified memory address range. */ struct kvm_pgtable_mm_ops { void* (*zalloc_page)(void *arg); @@ -54,6 +60,8 @@ struct kvm_pgtable_mm_ops { int (*page_count)(void *addr); void* (*phys_to_virt)(phys_addr_t phys); phys_addr_t (*virt_to_phys)(void *addr); + void (*dcache_clean_inval_poc)(void *addr, size_t size); + void (*icache_inval_pou)(void *addr, size_t size); }; /** diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h index c0ef7f0bdca4..cc58614884b0 100644 --- a/arch/arm64/include/asm/mmu_context.h +++ b/arch/arm64/include/asm/mmu_context.h @@ -36,11 +36,11 @@ static inline void contextidr_thread_switch(struct task_struct *next) } /* - * Set TTBR0 to empty_zero_page. No translations will be possible via TTBR0. + * Set TTBR0 to reserved_pg_dir. No translations will be possible via TTBR0. */ static inline void cpu_set_reserved_ttbr0(void) { - unsigned long ttbr = phys_to_ttbr(__pa_symbol(empty_zero_page)); + unsigned long ttbr = phys_to_ttbr(__pa_symbol(reserved_pg_dir)); write_sysreg(ttbr, ttbr0_el1); isb(); @@ -192,9 +192,9 @@ static inline void update_saved_ttbr0(struct task_struct *tsk, return; if (mm == &init_mm) - ttbr = __pa_symbol(empty_zero_page); + ttbr = phys_to_ttbr(__pa_symbol(reserved_pg_dir)); else - ttbr = virt_to_phys(mm->pgd) | ASID(mm) << 48; + ttbr = phys_to_ttbr(virt_to_phys(mm->pgd)) | ASID(mm) << 48; WRITE_ONCE(task_thread_info(tsk)->ttbr0, ttbr); } diff --git a/arch/arm64/include/asm/mte-def.h b/arch/arm64/include/asm/mte-def.h index cf241b0f0a42..626d359b396e 100644 --- a/arch/arm64/include/asm/mte-def.h +++ b/arch/arm64/include/asm/mte-def.h @@ -7,6 +7,7 @@ #define MTE_GRANULE_SIZE UL(16) #define MTE_GRANULE_MASK (~(MTE_GRANULE_SIZE - 1)) +#define MTE_GRANULES_PER_PAGE (PAGE_SIZE / MTE_GRANULE_SIZE) #define MTE_TAG_SHIFT 56 #define MTE_TAG_SIZE 4 #define MTE_TAG_MASK GENMASK((MTE_TAG_SHIFT + (MTE_TAG_SIZE - 1)), MTE_TAG_SHIFT) diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h index 67bf259ae768..58c7f80f5596 100644 --- a/arch/arm64/include/asm/mte.h +++ b/arch/arm64/include/asm/mte.h @@ -38,7 +38,7 @@ void mte_free_tag_storage(char *storage); #define PG_mte_tagged PG_arch_2 void mte_zero_clear_page_tags(void *addr); -void mte_sync_tags(pte_t *ptep, pte_t pte); +void mte_sync_tags(pte_t old_pte, pte_t pte); void mte_copy_page_tags(void *kto, const void *kfrom); void mte_thread_init_user(void); void mte_thread_switch(struct task_struct *next); @@ -57,7 +57,7 @@ int mte_ptrace_copy_tags(struct task_struct *child, long request, static inline void mte_zero_clear_page_tags(void *addr) { } -static inline void mte_sync_tags(pte_t *ptep, pte_t pte) +static inline void mte_sync_tags(pte_t old_pte, pte_t pte) { } static inline void mte_copy_page_tags(void *kto, const void *kfrom) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 0ffbcccf3553..5c1d05891ed8 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -311,9 +311,25 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, if (pte_present(pte) && pte_user_exec(pte) && !pte_special(pte)) __sync_icache_dcache(pte); - if (system_supports_mte() && - pte_present(pte) && pte_tagged(pte) && !pte_special(pte)) - mte_sync_tags(ptep, pte); + /* + * If the PTE would provide user space access to the tags associated + * with it then ensure that the MTE tags are synchronised. Although + * pte_access_permitted() returns false for exec only mappings, they + * don't expose tags (instruction fetches don't check tags). + */ + if (system_supports_mte() && pte_access_permitted(pte, false) && + !pte_special(pte)) { + pte_t old_pte = READ_ONCE(*ptep); + /* + * We only need to synchronise if the new PTE has tags enabled + * or if swapping in (in which case another mapping may have + * set tags in the past even if this PTE isn't tagged). + * (!pte_none() && !pte_present()) is an open coded version of + * is_swap_pte() + */ + if (pte_tagged(pte) || (!pte_none(old_pte) && !pte_present(old_pte))) + mte_sync_tags(old_pte, pte); + } __check_racy_pte_update(mm, ptep, pte); @@ -540,6 +556,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t idmap_pg_dir[PTRS_PER_PGD]; extern pgd_t idmap_pg_end[]; extern pgd_t tramp_pg_dir[PTRS_PER_PGD]; +extern pgd_t reserved_pg_dir[PTRS_PER_PGD]; extern void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd); diff --git a/arch/arm64/include/asm/preempt.h b/arch/arm64/include/asm/preempt.h index 80e946b2abee..e83f0982b99c 100644 --- a/arch/arm64/include/asm/preempt.h +++ b/arch/arm64/include/asm/preempt.h @@ -23,7 +23,7 @@ static inline void preempt_count_set(u64 pc) } while (0) #define init_idle_preempt_count(p, cpu) do { \ - task_thread_info(p)->preempt_count = PREEMPT_ENABLED; \ + task_thread_info(p)->preempt_count = PREEMPT_DISABLED; \ } while (0) static inline void set_preempt_need_resched(void) diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 050395c4d550..f8347444235f 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -321,7 +321,17 @@ static inline unsigned long kernel_stack_pointer(struct pt_regs *regs) static inline unsigned long regs_return_value(struct pt_regs *regs) { - return regs->regs[0]; + unsigned long val = regs->regs[0]; + + /* + * Audit currently uses regs_return_value() instead of + * syscall_get_return_value(). Apply the same sign-extension here until + * audit is updated to use syscall_get_return_value(). + */ + if (compat_user_mode(regs)) + val = sign_extend64(val, 31); + + return val; } static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h index cfc0672013f6..03e20895453a 100644 --- a/arch/arm64/include/asm/syscall.h +++ b/arch/arm64/include/asm/syscall.h @@ -29,22 +29,23 @@ static inline void syscall_rollback(struct task_struct *task, regs->regs[0] = regs->orig_x0; } - -static inline long syscall_get_error(struct task_struct *task, - struct pt_regs *regs) +static inline long syscall_get_return_value(struct task_struct *task, + struct pt_regs *regs) { - unsigned long error = regs->regs[0]; + unsigned long val = regs->regs[0]; if (is_compat_thread(task_thread_info(task))) - error = sign_extend64(error, 31); + val = sign_extend64(val, 31); - return IS_ERR_VALUE(error) ? error : 0; + return val; } -static inline long syscall_get_return_value(struct task_struct *task, - struct pt_regs *regs) +static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) { - return regs->regs[0]; + unsigned long error = syscall_get_return_value(task, regs); + + return IS_ERR_VALUE(error) ? error : 0; } static inline void syscall_set_return_value(struct task_struct *task, diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 2f09c856b6bc..45175ebc82b1 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -283,6 +283,8 @@ #define SYS_PMSIRR_EL1_INTERVAL_MASK 0xffffffUL /* Filtering controls */ +#define SYS_PMSNEVFR_EL1 sys_reg(3, 0, 9, 9, 1) + #define SYS_PMSFCR_EL1 sys_reg(3, 0, 9, 9, 4) #define SYS_PMSFCR_EL1_FE_SHIFT 0 #define SYS_PMSFCR_EL1_FT_SHIFT 1 @@ -639,7 +641,8 @@ #define INIT_SCTLR_EL2_MMU_ON \ (SCTLR_ELx_M | SCTLR_ELx_C | SCTLR_ELx_SA | SCTLR_ELx_I | \ - SCTLR_ELx_IESB | SCTLR_ELx_WXN | ENDIAN_SET_EL2 | SCTLR_EL2_RES1) + SCTLR_ELx_IESB | SCTLR_ELx_WXN | ENDIAN_SET_EL2 | \ + SCTLR_ELx_ITFSB | SCTLR_EL2_RES1) #define INIT_SCTLR_EL2_MMU_OFF \ (SCTLR_EL2_RES1 | ENDIAN_SET_EL2) diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h index 61c97d3b58c7..c995d1f4594f 100644 --- a/arch/arm64/include/asm/tlb.h +++ b/arch/arm64/include/asm/tlb.h @@ -28,6 +28,10 @@ static void tlb_flush(struct mmu_gather *tlb); */ static inline int tlb_get_level(struct mmu_gather *tlb) { + /* The TTL field is only valid for the leaf entry. */ + if (tlb->freed_tables) + return 0; + if (tlb->cleared_ptes && !(tlb->cleared_pmds || tlb->cleared_puds || tlb->cleared_p4ds)) diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index 2e695e79e07f..7450d252b868 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -116,8 +116,8 @@ static inline void __uaccess_ttbr0_disable(void) local_irq_save(flags); ttbr = read_sysreg(ttbr1_el1); ttbr &= ~TTBR_ASID_MASK; - /* reserved_ttbr0 placed before swapper_pg_dir */ - write_sysreg(ttbr - RESERVED_TTBR0_SIZE, ttbr0_el1); + /* reserved_pg_dir placed before swapper_pg_dir */ + write_sysreg(ttbr - PAGE_SIZE, ttbr0_el1); isb(); /* Set reserved ASID */ write_sysreg(ttbr, ttbr1_el1); diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h index 631ab1281633..4b4c0dac0e14 100644 --- a/arch/arm64/include/asm/vdso/gettimeofday.h +++ b/arch/arm64/include/asm/vdso/gettimeofday.h @@ -83,11 +83,7 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode, */ isb(); asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory"); - /* - * This isb() is required to prevent that the seq lock is - * speculated.# - */ - isb(); + arch_counter_enforce_ordering(res); return res; } diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index 24223adae150..b3edde68bc3e 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -184,6 +184,17 @@ struct kvm_vcpu_events { __u32 reserved[12]; }; +struct kvm_arm_copy_mte_tags { + __u64 guest_ipa; + __u64 length; + void __user *addr; + __u64 flags; + __u64 reserved[2]; +}; + +#define KVM_ARM_TAGS_TO_GUEST 0 +#define KVM_ARM_TAGS_FROM_GUEST 1 + /* If you need to interpret the index values, here is the key: */ #define KVM_REG_ARM_COPROC_MASK 0x000000000FFF0000 #define KVM_REG_ARM_COPROC_SHIFT 16 diff --git a/arch/arm64/kernel/alternative.c b/arch/arm64/kernel/alternative.c index d32363da9017..c396c4979b7d 100644 --- a/arch/arm64/kernel/alternative.c +++ b/arch/arm64/kernel/alternative.c @@ -182,7 +182,7 @@ static void __nocfi __apply_alternatives(void *alt_region, bool is_module, */ if (!is_module) { dsb(ish); - __flush_icache_all(); + icache_inval_all_pou(); isb(); /* Ignore ARM64_CB bit from feature mask */ diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 93da876a58e6..7eef8bead7ad 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -112,6 +112,8 @@ int main(void) DEFINE(VCPU_WORKAROUND_FLAGS, offsetof(struct kvm_vcpu, arch.workaround_flags)); DEFINE(VCPU_HCR_EL2, offsetof(struct kvm_vcpu, arch.hcr_el2)); DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_cpu_context, regs)); + DEFINE(CPU_RGSR_EL1, offsetof(struct kvm_cpu_context, sys_regs[RGSR_EL1])); + DEFINE(CPU_GCR_EL1, offsetof(struct kvm_cpu_context, sys_regs[GCR_EL1])); DEFINE(CPU_APIAKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APIAKEYLO_EL1])); DEFINE(CPU_APIBKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APIBKEYLO_EL1])); DEFINE(CPU_APDAKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APDAKEYLO_EL1])); @@ -139,6 +141,15 @@ int main(void) DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id)); DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state)); + DEFINE(ARM_SMCCC_1_2_REGS_X0_OFFS, offsetof(struct arm_smccc_1_2_regs, a0)); + DEFINE(ARM_SMCCC_1_2_REGS_X2_OFFS, offsetof(struct arm_smccc_1_2_regs, a2)); + DEFINE(ARM_SMCCC_1_2_REGS_X4_OFFS, offsetof(struct arm_smccc_1_2_regs, a4)); + DEFINE(ARM_SMCCC_1_2_REGS_X6_OFFS, offsetof(struct arm_smccc_1_2_regs, a6)); + DEFINE(ARM_SMCCC_1_2_REGS_X8_OFFS, offsetof(struct arm_smccc_1_2_regs, a8)); + DEFINE(ARM_SMCCC_1_2_REGS_X10_OFFS, offsetof(struct arm_smccc_1_2_regs, a10)); + DEFINE(ARM_SMCCC_1_2_REGS_X12_OFFS, offsetof(struct arm_smccc_1_2_regs, a12)); + DEFINE(ARM_SMCCC_1_2_REGS_X14_OFFS, offsetof(struct arm_smccc_1_2_regs, a14)); + DEFINE(ARM_SMCCC_1_2_REGS_X16_OFFS, offsetof(struct arm_smccc_1_2_regs, a16)); BLANK(); DEFINE(HIBERN_PBE_ORIG, offsetof(struct pbe, orig_address)); DEFINE(HIBERN_PBE_ADDR, offsetof(struct pbe, address)); diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index d9e5c16f2037..064829e77cab 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -831,6 +831,12 @@ static void init_cpu_ftr_reg(u32 sys_reg, u64 new) reg->name, ftrp->shift + ftrp->width - 1, ftrp->shift, str, tmp); + } else if ((ftr_mask & reg->override->val) == ftr_mask) { + reg->override->val &= ~ftr_mask; + pr_warn("%s[%d:%d]: impossible override, ignored\n", + reg->name, + ftrp->shift + ftrp->width - 1, + ftrp->shift); } val = arm64_ftr_set_value(ftrp, val, ftr_new); @@ -1700,7 +1706,6 @@ static bool has_amu(const struct arm64_cpu_capabilities *cap, } #endif -#ifdef CONFIG_ARM64_VHE static bool runs_at_el2(const struct arm64_cpu_capabilities *entry, int __unused) { return is_kernel_in_hyp_mode(); @@ -1719,7 +1724,6 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused) if (!alternative_is_applied(ARM64_HAS_VIRT_HOST_EXTN)) write_sysreg(read_sysreg(tpidr_el1), tpidr_el2); } -#endif static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused) { @@ -1947,7 +1951,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .matches = cpufeature_pan_not_uao, }, #endif /* CONFIG_ARM64_PAN */ -#ifdef CONFIG_ARM64_VHE { .desc = "Virtualization Host Extensions", .capability = ARM64_HAS_VIRT_HOST_EXTN, @@ -1955,7 +1958,6 @@ static const struct arm64_cpu_capabilities arm64_features[] = { .matches = runs_at_el2, .cpu_enable = cpu_copy_el2regs, }, -#endif /* CONFIG_ARM64_VHE */ { .capability = ARM64_HAS_32BIT_EL0_DO_NOT_USE, .type = ARM64_CPUCAP_SYSTEM_FEATURE, diff --git a/arch/arm64/kernel/efi-entry.S b/arch/arm64/kernel/efi-entry.S index 0073b24b5d25..61a87fa1c305 100644 --- a/arch/arm64/kernel/efi-entry.S +++ b/arch/arm64/kernel/efi-entry.S @@ -28,7 +28,8 @@ SYM_CODE_START(efi_enter_kernel) * stale icache entries from before relocation. */ ldr w1, =kernel_size - bl __clean_dcache_area_poc + add x1, x0, x1 + bl dcache_clean_poc ic ialluis /* @@ -36,8 +37,8 @@ SYM_CODE_START(efi_enter_kernel) * so that we can safely disable the MMU and caches. */ adr x0, 0f - ldr w1, 3f - bl __clean_dcache_area_poc + adr x1, 3f + bl dcache_clean_poc 0: /* Turn off Dcache and MMU */ mrs x0, CurrentEL @@ -64,5 +65,5 @@ SYM_CODE_START(efi_enter_kernel) mov x2, xzr mov x3, xzr br x19 +3: SYM_CODE_END(efi_enter_kernel) -3: .long . - 0b diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 29c423933e99..5369db4b53a4 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -868,9 +868,10 @@ SYM_CODE_END(ret_to_user) */ .pushsection ".entry.tramp.text", "ax" + // Move from tramp_pg_dir to swapper_pg_dir .macro tramp_map_kernel, tmp mrs \tmp, ttbr1_el1 - add \tmp, \tmp, #(PAGE_SIZE + RESERVED_TTBR0_SIZE) + add \tmp, \tmp, #(2 * PAGE_SIZE) bic \tmp, \tmp, #USER_ASID_FLAG msr ttbr1_el1, \tmp #ifdef CONFIG_QCOM_FALKOR_ERRATUM_1003 @@ -887,9 +888,10 @@ alternative_else_nop_endif #endif /* CONFIG_QCOM_FALKOR_ERRATUM_1003 */ .endm + // Move from swapper_pg_dir to tramp_pg_dir .macro tramp_unmap_kernel, tmp mrs \tmp, ttbr1_el1 - sub \tmp, \tmp, #(PAGE_SIZE + RESERVED_TTBR0_SIZE) + sub \tmp, \tmp, #(2 * PAGE_SIZE) orr \tmp, \tmp, #USER_ASID_FLAG msr ttbr1_el1, \tmp /* diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 6b8af4658ad3..8ffba8f62a9b 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -132,8 +132,8 @@ SYM_CODE_START_LOCAL(preserve_boot_args) dmb sy // needed before dc ivac with // MMU off - mov x1, #0x20 // 4 x 8 bytes - b __inval_dcache_area // tail call + add x1, x0, #0x20 // 4 x 8 bytes + b dcache_inval_poc // tail call SYM_CODE_END(preserve_boot_args) /* @@ -283,8 +283,7 @@ SYM_FUNC_START_LOCAL(__create_page_tables) */ adrp x0, init_pg_dir adrp x1, init_pg_end - sub x1, x1, x0 - bl __inval_dcache_area + bl dcache_inval_poc /* * Clear the init page tables. @@ -397,13 +396,11 @@ SYM_FUNC_START_LOCAL(__create_page_tables) adrp x0, idmap_pg_dir adrp x1, idmap_pg_end - sub x1, x1, x0 - bl __inval_dcache_area + bl dcache_inval_poc adrp x0, init_pg_dir adrp x1, init_pg_end - sub x1, x1, x0 - bl __inval_dcache_area + bl dcache_inval_poc ret x28 SYM_FUNC_END(__create_page_tables) @@ -492,14 +489,13 @@ EXPORT_SYMBOL(kimage_vaddr) * booted in EL1 or EL2 respectively. */ SYM_FUNC_START(init_kernel_el) - mov_q x0, INIT_SCTLR_EL1_MMU_OFF - msr sctlr_el1, x0 - mrs x0, CurrentEL cmp x0, #CurrentEL_EL2 b.eq init_el2 SYM_INNER_LABEL(init_el1, SYM_L_LOCAL) + mov_q x0, INIT_SCTLR_EL1_MMU_OFF + msr sctlr_el1, x0 isb mov_q x0, INIT_PSTATE_EL1 msr spsr_el1, x0 @@ -519,9 +515,43 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL) msr vbar_el2, x0 isb + /* + * Fruity CPUs seem to have HCR_EL2.E2H set to RES1, + * making it impossible to start in nVHE mode. Is that + * compliant with the architecture? Absolutely not! + */ + mrs x0, hcr_el2 + and x0, x0, #HCR_E2H + cbz x0, 1f + + /* Switching to VHE requires a sane SCTLR_EL1 as a start */ + mov_q x0, INIT_SCTLR_EL1_MMU_OFF + msr_s SYS_SCTLR_EL12, x0 + + /* + * Force an eret into a helper "function", and let it return + * to our original caller... This makes sure that we have + * initialised the basic PSTATE state. + */ + mov x0, #INIT_PSTATE_EL2 + msr spsr_el1, x0 + adr x0, __cpu_stick_to_vhe + msr elr_el1, x0 + eret + +1: + mov_q x0, INIT_SCTLR_EL1_MMU_OFF + msr sctlr_el1, x0 + msr elr_el2, lr mov w0, #BOOT_CPU_MODE_EL2 eret + +__cpu_stick_to_vhe: + mov x0, #HVC_VHE_RESTART + hvc #0 + mov x0, #BOOT_CPU_MODE_EL2 + ret SYM_FUNC_END(init_kernel_el) /* diff --git a/arch/arm64/kernel/hibernate-asm.S b/arch/arm64/kernel/hibernate-asm.S index 8ccca660034e..81c0186a5e32 100644 --- a/arch/arm64/kernel/hibernate-asm.S +++ b/arch/arm64/kernel/hibernate-asm.S @@ -45,7 +45,7 @@ * Because this code has to be copied to a 'safe' page, it can't call out to * other functions by PC-relative address. Also remember that it may be * mid-way through over-writing other functions. For this reason it contains - * code from flush_icache_range() and uses the copy_page() macro. + * code from caches_clean_inval_pou() and uses the copy_page() macro. * * This 'safe' page is mapped via ttbr0, and executed from there. This function * switches to a copy of the linear map in ttbr1, performs the restore, then @@ -87,11 +87,12 @@ SYM_CODE_START(swsusp_arch_suspend_exit) copy_page x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 add x1, x10, #PAGE_SIZE - /* Clean the copied page to PoU - based on flush_icache_range() */ + /* Clean the copied page to PoU - based on caches_clean_inval_pou() */ raw_dcache_line_size x2, x3 sub x3, x2, #1 bic x4, x10, x3 -2: dc cvau, x4 /* clean D line / unified line */ +2: /* clean D line / unified line */ +alternative_insn "dc cvau, x4", "dc civac, x4", ARM64_WORKAROUND_CLEAN_CACHE add x4, x4, x2 cmp x4, x1 b.lo 2b diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index 9c9f47e9f7f4..03b4f13cc685 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -250,7 +250,7 @@ static int create_safe_exec_page(void *src_start, size_t length, return -ENOMEM; memcpy(page, src_start, length); - __flush_icache_range((unsigned long)page, (unsigned long)page + length); + caches_clean_inval_pou((unsigned long)page, (unsigned long)page + length); trans_pgd = (void *)get_safe_page(GFP_ATOMIC); if (!trans_pgd) @@ -283,8 +283,6 @@ static int create_safe_exec_page(void *src_start, size_t length, return 0; } -#define dcache_clean_range(start, end) __flush_dcache_area(start, (end - start)) - #ifdef CONFIG_ARM64_MTE static DEFINE_XARRAY(mte_pages); @@ -426,13 +424,18 @@ int swsusp_arch_suspend(void) ret = swsusp_save(); } else { /* Clean kernel core startup/idle code to PoC*/ - dcache_clean_range(__mmuoff_data_start, __mmuoff_data_end); - dcache_clean_range(__idmap_text_start, __idmap_text_end); + dcache_clean_inval_poc((unsigned long)__mmuoff_data_start, + (unsigned long)__mmuoff_data_end); + dcache_clean_inval_poc((unsigned long)__idmap_text_start, + (unsigned long)__idmap_text_end); /* Clean kvm setup code to PoC? */ if (el2_reset_needed()) { - dcache_clean_range(__hyp_idmap_text_start, __hyp_idmap_text_end); - dcache_clean_range(__hyp_text_start, __hyp_text_end); + dcache_clean_inval_poc( + (unsigned long)__hyp_idmap_text_start, + (unsigned long)__hyp_idmap_text_end); + dcache_clean_inval_poc((unsigned long)__hyp_text_start, + (unsigned long)__hyp_text_end); } swsusp_mte_restore_tags(); @@ -695,7 +698,8 @@ int swsusp_arch_resume(void) * The hibernate exit text contains a set of el2 vectors, that will * be executed at el2 with the mmu off in order to reload hyp-stub. */ - __flush_dcache_area(hibernate_exit, exit_size); + dcache_clean_inval_poc((unsigned long)hibernate_exit, + (unsigned long)hibernate_exit + exit_size); /* * KASLR will cause the el2 vectors to be in a different location in diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S index 05d25e645b46..43d212618834 100644 --- a/arch/arm64/kernel/hyp-stub.S +++ b/arch/arm64/kernel/hyp-stub.S @@ -27,12 +27,12 @@ SYM_CODE_START(__hyp_stub_vectors) ventry el2_fiq_invalid // FIQ EL2t ventry el2_error_invalid // Error EL2t - ventry el2_sync_invalid // Synchronous EL2h + ventry elx_sync // Synchronous EL2h ventry el2_irq_invalid // IRQ EL2h ventry el2_fiq_invalid // FIQ EL2h ventry el2_error_invalid // Error EL2h - ventry el1_sync // Synchronous 64-bit EL1 + ventry elx_sync // Synchronous 64-bit EL1 ventry el1_irq_invalid // IRQ 64-bit EL1 ventry el1_fiq_invalid // FIQ 64-bit EL1 ventry el1_error_invalid // Error 64-bit EL1 @@ -45,7 +45,7 @@ SYM_CODE_END(__hyp_stub_vectors) .align 11 -SYM_CODE_START_LOCAL(el1_sync) +SYM_CODE_START_LOCAL(elx_sync) cmp x0, #HVC_SET_VECTORS b.ne 1f msr vbar_el2, x1 @@ -71,7 +71,7 @@ SYM_CODE_START_LOCAL(el1_sync) 9: mov x0, xzr eret -SYM_CODE_END(el1_sync) +SYM_CODE_END(elx_sync) // nVHE? No way! Give me the real thing! SYM_CODE_START_LOCAL(mutate_to_vhe) @@ -225,7 +225,6 @@ SYM_FUNC_END(__hyp_reset_vectors) * Entry point to switch to VHE if deemed capable */ SYM_FUNC_START(switch_to_vhe) -#ifdef CONFIG_ARM64_VHE // Need to have booted at EL2 adr_l x1, __boot_cpu_mode ldr w0, [x1] @@ -241,6 +240,5 @@ SYM_FUNC_START(switch_to_vhe) mov x0, #HVC_VHE_RESTART hvc #0 1: -#endif ret SYM_FUNC_END(switch_to_vhe) diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c index 81b7ecb69cd1..c2b0bfe72839 100644 --- a/arch/arm64/kernel/idreg-override.c +++ b/arch/arm64/kernel/idreg-override.c @@ -25,14 +25,26 @@ struct ftr_set_desc { struct { char name[FTR_DESC_FIELD_LEN]; u8 shift; + bool (*filter)(u64 val); } fields[]; }; +static bool __init mmfr1_vh_filter(u64 val) +{ + /* + * If we ever reach this point while running VHE, we're + * guaranteed to be on one of these funky, VHE-stuck CPUs. If + * the user was trying to force nVHE on us, proceed with + * attitude adjustment. + */ + return !(is_kernel_in_hyp_mode() && val == 0); +} + static const struct ftr_set_desc mmfr1 __initconst = { .name = "id_aa64mmfr1", .override = &id_aa64mmfr1_override, .fields = { - { "vh", ID_AA64MMFR1_VHE_SHIFT }, + { "vh", ID_AA64MMFR1_VHE_SHIFT, mmfr1_vh_filter }, {} }, }; @@ -126,6 +138,18 @@ static void __init match_options(const char *cmdline) if (find_field(cmdline, regs[i], f, &v)) continue; + /* + * If an override gets filtered out, advertise + * it by setting the value to 0xf, but + * clearing the mask... Yes, this is fragile. + */ + if (regs[i]->fields[f].filter && + !regs[i]->fields[f].filter(v)) { + regs[i]->override->val |= mask; + regs[i]->override->mask &= ~mask; + continue; + } + regs[i]->override->val &= ~mask; regs[i]->override->val |= (v << shift) & mask; regs[i]->override->mask |= mask; @@ -218,7 +242,8 @@ asmlinkage void __init init_feature_override(void) for (i = 0; i < ARRAY_SIZE(regs); i++) { if (regs[i]->override) - __flush_dcache_area(regs[i]->override, + dcache_clean_inval_poc((unsigned long)regs[i]->override, + (unsigned long)regs[i]->override + sizeof(*regs[i]->override)); } } diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index fdd60cd1d7e8..c96a9a0043bf 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -35,7 +35,7 @@ __efistub_strnlen = __pi_strnlen; __efistub_strcmp = __pi_strcmp; __efistub_strncmp = __pi_strncmp; __efistub_strrchr = __pi_strrchr; -__efistub___clean_dcache_area_poc = __pi___clean_dcache_area_poc; +__efistub_dcache_clean_poc = __pi_dcache_clean_poc; #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) __efistub___memcpy = __pi_memcpy; @@ -71,8 +71,7 @@ KVM_NVHE_ALIAS(kvm_compute_final_ctr_el0); KVM_NVHE_ALIAS(kvm_vgic_global_state); /* Kernel symbols used to call panic() from nVHE hyp code (via ERET). */ -KVM_NVHE_ALIAS(__hyp_panic_string); -KVM_NVHE_ALIAS(panic); +KVM_NVHE_ALIAS(nvhe_hyp_panic_handler); /* Vectors installed by hyp-init on reset HVC. */ KVM_NVHE_ALIAS(__hyp_stub_vectors); diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index 6c0de2f60ea9..51cb8dc98d00 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c @@ -198,7 +198,7 @@ int __kprobes aarch64_insn_patch_text_nosync(void *addr, u32 insn) ret = aarch64_insn_write(tp, insn); if (ret == 0) - __flush_icache_range((uintptr_t)tp, + caches_clean_inval_pou((uintptr_t)tp, (uintptr_t)tp + AARCH64_INSN_SIZE); return ret; diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c index 27f8939deb1b..8997d6445f21 100644 --- a/arch/arm64/kernel/kaslr.c +++ b/arch/arm64/kernel/kaslr.c @@ -72,7 +72,9 @@ u64 __init kaslr_early_init(void) * we end up running with module randomization disabled. */ module_alloc_base = (u64)_etext - MODULES_VSIZE; - __flush_dcache_area(&module_alloc_base, sizeof(module_alloc_base)); + dcache_clean_inval_poc((unsigned long)&module_alloc_base, + (unsigned long)&module_alloc_base + + sizeof(module_alloc_base)); /* * Try to map the FDT early. If this fails, we simply bail, @@ -168,8 +170,12 @@ u64 __init kaslr_early_init(void) module_alloc_base += (module_range * (seed & ((1 << 21) - 1))) >> 21; module_alloc_base &= PAGE_MASK; - __flush_dcache_area(&module_alloc_base, sizeof(module_alloc_base)); - __flush_dcache_area(&memstart_offset_seed, sizeof(memstart_offset_seed)); + dcache_clean_inval_poc((unsigned long)&module_alloc_base, + (unsigned long)&module_alloc_base + + sizeof(module_alloc_base)); + dcache_clean_inval_poc((unsigned long)&memstart_offset_seed, + (unsigned long)&memstart_offset_seed + + sizeof(memstart_offset_seed)); return offset; } diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c index a0b144cfaea7..9d845585f16b 100644 --- a/arch/arm64/kernel/machine_kexec.c +++ b/arch/arm64/kernel/machine_kexec.c @@ -42,6 +42,7 @@ static void _kexec_image_info(const char *func, int line, pr_debug(" start: %lx\n", kimage->start); pr_debug(" head: %lx\n", kimage->head); pr_debug(" nr_segments: %lu\n", kimage->nr_segments); + pr_debug(" kern_reloc: %pa\n", &kimage->arch.kern_reloc); for (i = 0; i < kimage->nr_segments; i++) { pr_debug(" segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n", @@ -58,6 +59,28 @@ void machine_kexec_cleanup(struct kimage *kimage) /* Empty routine needed to avoid build errors. */ } +int machine_kexec_post_load(struct kimage *kimage) +{ + void *reloc_code = page_to_virt(kimage->control_code_page); + + memcpy(reloc_code, arm64_relocate_new_kernel, + arm64_relocate_new_kernel_size); + kimage->arch.kern_reloc = __pa(reloc_code); + + /* + * For execution with the MMU off, reloc_code needs to be cleaned to the + * PoC and invalidated from the I-cache. + */ + dcache_clean_inval_poc((unsigned long)reloc_code, + (unsigned long)reloc_code + + arm64_relocate_new_kernel_size); + icache_inval_pou((uintptr_t)reloc_code, + (uintptr_t)reloc_code + + arm64_relocate_new_kernel_size); + + return 0; +} + /** * machine_kexec_prepare - Prepare for a kexec reboot. * @@ -86,16 +109,18 @@ static void kexec_list_flush(struct kimage *kimage) for (entry = &kimage->head; ; entry++) { unsigned int flag; - void *addr; + unsigned long addr; /* flush the list entries. */ - __flush_dcache_area(entry, sizeof(kimage_entry_t)); + dcache_clean_inval_poc((unsigned long)entry, + (unsigned long)entry + + sizeof(kimage_entry_t)); flag = *entry & IND_FLAGS; if (flag == IND_DONE) break; - addr = phys_to_virt(*entry & PAGE_MASK); + addr = (unsigned long)phys_to_virt(*entry & PAGE_MASK); switch (flag) { case IND_INDIRECTION: @@ -104,7 +129,7 @@ static void kexec_list_flush(struct kimage *kimage) break; case IND_SOURCE: /* flush the source pages. */ - __flush_dcache_area(addr, PAGE_SIZE); + dcache_clean_inval_poc(addr, addr + PAGE_SIZE); break; case IND_DESTINATION: break; @@ -131,8 +156,10 @@ static void kexec_segment_flush(const struct kimage *kimage) kimage->segment[i].memsz, kimage->segment[i].memsz / PAGE_SIZE); - __flush_dcache_area(phys_to_virt(kimage->segment[i].mem), - kimage->segment[i].memsz); + dcache_clean_inval_poc( + (unsigned long)phys_to_virt(kimage->segment[i].mem), + (unsigned long)phys_to_virt(kimage->segment[i].mem) + + kimage->segment[i].memsz); } } @@ -143,8 +170,6 @@ static void kexec_segment_flush(const struct kimage *kimage) */ void machine_kexec(struct kimage *kimage) { - phys_addr_t reboot_code_buffer_phys; - void *reboot_code_buffer; bool in_kexec_crash = (kimage == kexec_crash_image); bool stuck_cpus = cpus_are_stuck_in_kernel(); @@ -155,31 +180,8 @@ void machine_kexec(struct kimage *kimage) WARN(in_kexec_crash && (stuck_cpus || smp_crash_stop_failed()), "Some CPUs may be stale, kdump will be unreliable.\n"); - reboot_code_buffer_phys = page_to_phys(kimage->control_code_page); - reboot_code_buffer = phys_to_virt(reboot_code_buffer_phys); - kexec_image_info(kimage); - /* - * Copy arm64_relocate_new_kernel to the reboot_code_buffer for use - * after the kernel is shut down. - */ - memcpy(reboot_code_buffer, arm64_relocate_new_kernel, - arm64_relocate_new_kernel_size); - - /* Flush the reboot_code_buffer in preparation for its execution. */ - __flush_dcache_area(reboot_code_buffer, arm64_relocate_new_kernel_size); - - /* - * Although we've killed off the secondary CPUs, we don't update - * the online mask if we're handling a crash kernel and consequently - * need to avoid flush_icache_range(), which will attempt to IPI - * the offline CPUs. Therefore, we must use the __* variant here. - */ - __flush_icache_range((uintptr_t)reboot_code_buffer, - (uintptr_t)reboot_code_buffer + - arm64_relocate_new_kernel_size); - /* Flush the kimage list and its buffers. */ kexec_list_flush(kimage); @@ -193,7 +195,7 @@ void machine_kexec(struct kimage *kimage) /* * cpu_soft_restart will shutdown the MMU, disable data caches, then - * transfer control to the reboot_code_buffer which contains a copy of + * transfer control to the kern_reloc which contains a copy of * the arm64_relocate_new_kernel routine. arm64_relocate_new_kernel * uses physical addressing to relocate the new image to its final * position and transfers control to the image entry point when the @@ -203,12 +205,8 @@ void machine_kexec(struct kimage *kimage) * userspace (kexec-tools). * In kexec_file case, the kernel starts directly without purgatory. */ - cpu_soft_restart(reboot_code_buffer_phys, kimage->head, kimage->start, -#ifdef CONFIG_KEXEC_FILE - kimage->arch.dtb_mem); -#else - 0); -#endif + cpu_soft_restart(kimage->arch.kern_reloc, kimage->head, kimage->start, + kimage->arch.dtb_mem); BUG(); /* Should never get here. */ } diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index 50ae1a7435ae..6984b64bf612 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -35,10 +35,9 @@ DEFINE_STATIC_KEY_FALSE(mte_async_mode); EXPORT_SYMBOL_GPL(mte_async_mode); #endif -static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_swap) +static void mte_sync_page_tags(struct page *page, pte_t old_pte, + bool check_swap, bool pte_is_tagged) { - pte_t old_pte = READ_ONCE(*ptep); - if (check_swap && is_swap_pte(old_pte)) { swp_entry_t entry = pte_to_swp_entry(old_pte); @@ -46,6 +45,9 @@ static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_swap) return; } + if (!pte_is_tagged) + return; + page_kasan_tag_reset(page); /* * We need smp_wmb() in between setting the flags and clearing the @@ -58,16 +60,22 @@ static void mte_sync_page_tags(struct page *page, pte_t *ptep, bool check_swap) mte_clear_page_tags(page_address(page)); } -void mte_sync_tags(pte_t *ptep, pte_t pte) +void mte_sync_tags(pte_t old_pte, pte_t pte) { struct page *page = pte_page(pte); long i, nr_pages = compound_nr(page); bool check_swap = nr_pages == 1; + bool pte_is_tagged = pte_tagged(pte); + + /* Early out if there's nothing to do */ + if (!check_swap && !pte_is_tagged) + return; /* if PG_mte_tagged is set, tags have already been initialised */ for (i = 0; i < nr_pages; i++, page++) { if (!test_and_set_bit(PG_mte_tagged, &page->flags)) - mte_sync_page_tags(page, ptep, check_swap); + mte_sync_page_tags(page, old_pte, check_swap, + pte_is_tagged); } } diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 11852e05ee32..cdb3d4549b3a 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -312,7 +312,7 @@ static ssize_t slots_show(struct device *dev, struct device_attribute *attr, struct arm_pmu *cpu_pmu = container_of(pmu, struct arm_pmu, pmu); u32 slots = cpu_pmu->reg_pmmir & ARMV8_PMU_SLOTS_MASK; - return snprintf(page, PAGE_SIZE, "0x%08x\n", slots); + return sysfs_emit(page, "0x%08x\n", slots); } static DEVICE_ATTR_RO(slots); diff --git a/arch/arm64/kernel/probes/uprobes.c b/arch/arm64/kernel/probes/uprobes.c index 2c247634552b..9be668f3f034 100644 --- a/arch/arm64/kernel/probes/uprobes.c +++ b/arch/arm64/kernel/probes/uprobes.c @@ -21,7 +21,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, memcpy(dst, src, len); /* flush caches (dcache/icache) */ - sync_icache_aliases(dst, len); + sync_icache_aliases((unsigned long)dst, (unsigned long)dst + len); kunmap_atomic(xol_page_kaddr); } diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 7d84854bc0e8..bbb94747bfee 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -1861,7 +1861,7 @@ void syscall_trace_exit(struct pt_regs *regs) audit_syscall_exit(regs); if (flags & _TIF_SYSCALL_TRACEPOINT) - trace_sys_exit(regs, regs_return_value(regs)); + trace_sys_exit(regs, syscall_get_return_value(current, regs)); if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP)) tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT); diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index eb8c29290a00..a6ec917a1240 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -381,7 +381,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p) * faults in case uaccess_enable() is inadvertently called by the init * thread. */ - init_task.thread_info.ttbr0 = __pa_symbol(empty_zero_page); + init_task.thread_info.ttbr0 = phys_to_ttbr(__pa_symbol(reserved_pg_dir)); #endif if (boot_args[1] || boot_args[2] || boot_args[3]) { diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 50852992752b..e62005317ce2 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -890,7 +891,7 @@ static void do_signal(struct pt_regs *regs) retval == -ERESTART_RESTARTBLOCK || (retval == -ERESTARTSYS && !(ksig.ka.sa.sa_flags & SA_RESTART)))) { - regs->regs[0] = -EINTR; + syscall_set_return_value(current, regs, -EINTR, 0); regs->pc = continue_addr; } diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S index d62447964ed9..2def9d0dd3dd 100644 --- a/arch/arm64/kernel/smccc-call.S +++ b/arch/arm64/kernel/smccc-call.S @@ -43,3 +43,60 @@ SYM_FUNC_START(__arm_smccc_hvc) SMCCC hvc SYM_FUNC_END(__arm_smccc_hvc) EXPORT_SYMBOL(__arm_smccc_hvc) + + .macro SMCCC_1_2 instr + /* Save `res` and free a GPR that won't be clobbered */ + stp x1, x19, [sp, #-16]! + + /* Ensure `args` won't be clobbered while loading regs in next step */ + mov x19, x0 + + /* Load the registers x0 - x17 from the struct arm_smccc_1_2_regs */ + ldp x0, x1, [x19, #ARM_SMCCC_1_2_REGS_X0_OFFS] + ldp x2, x3, [x19, #ARM_SMCCC_1_2_REGS_X2_OFFS] + ldp x4, x5, [x19, #ARM_SMCCC_1_2_REGS_X4_OFFS] + ldp x6, x7, [x19, #ARM_SMCCC_1_2_REGS_X6_OFFS] + ldp x8, x9, [x19, #ARM_SMCCC_1_2_REGS_X8_OFFS] + ldp x10, x11, [x19, #ARM_SMCCC_1_2_REGS_X10_OFFS] + ldp x12, x13, [x19, #ARM_SMCCC_1_2_REGS_X12_OFFS] + ldp x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS] + ldp x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS] + + \instr #0 + + /* Load the `res` from the stack */ + ldr x19, [sp] + + /* Store the registers x0 - x17 into the result structure */ + stp x0, x1, [x19, #ARM_SMCCC_1_2_REGS_X0_OFFS] + stp x2, x3, [x19, #ARM_SMCCC_1_2_REGS_X2_OFFS] + stp x4, x5, [x19, #ARM_SMCCC_1_2_REGS_X4_OFFS] + stp x6, x7, [x19, #ARM_SMCCC_1_2_REGS_X6_OFFS] + stp x8, x9, [x19, #ARM_SMCCC_1_2_REGS_X8_OFFS] + stp x10, x11, [x19, #ARM_SMCCC_1_2_REGS_X10_OFFS] + stp x12, x13, [x19, #ARM_SMCCC_1_2_REGS_X12_OFFS] + stp x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS] + stp x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS] + + /* Restore original x19 */ + ldp xzr, x19, [sp], #16 + ret +.endm + +/* + * void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args, + * struct arm_smccc_1_2_regs *res); + */ +SYM_FUNC_START(arm_smccc_1_2_hvc) + SMCCC_1_2 hvc +SYM_FUNC_END(arm_smccc_1_2_hvc) +EXPORT_SYMBOL(arm_smccc_1_2_hvc) + +/* + * void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args, + * struct arm_smccc_1_2_regs *res); + */ +SYM_FUNC_START(arm_smccc_1_2_smc) + SMCCC_1_2 smc +SYM_FUNC_END(arm_smccc_1_2_smc) +EXPORT_SYMBOL(arm_smccc_1_2_smc) diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 22c65fbbf4c5..92a1bbb9f319 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -127,7 +127,9 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) secondary_data.task = idle; secondary_data.stack = task_stack_page(idle) + THREAD_SIZE; update_cpu_boot_status(CPU_MMU_OFF); - __flush_dcache_area(&secondary_data, sizeof(secondary_data)); + dcache_clean_inval_poc((unsigned long)&secondary_data, + (unsigned long)&secondary_data + + sizeof(secondary_data)); /* Now bring the CPU into our world */ ret = boot_secondary(cpu, idle); @@ -148,7 +150,9 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle) pr_crit("CPU%u: failed to come online\n", cpu); secondary_data.task = NULL; secondary_data.stack = NULL; - __flush_dcache_area(&secondary_data, sizeof(secondary_data)); + dcache_clean_inval_poc((unsigned long)&secondary_data, + (unsigned long)&secondary_data + + sizeof(secondary_data)); status = READ_ONCE(secondary_data.status); if (status == CPU_MMU_OFF) status = READ_ONCE(__early_cpu_boot_status); @@ -228,7 +232,6 @@ asmlinkage notrace void secondary_start_kernel(void) init_gic_priority_masking(); rcu_cpu_starting(cpu); - preempt_disable(); trace_hardirqs_off(); /* diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c index a80ff9092e86..883f41f5d1b0 100644 --- a/arch/arm64/kernel/smp_spin_table.c +++ b/arch/arm64/kernel/smp_spin_table.c @@ -36,7 +36,7 @@ static void write_pen_release(u64 val) unsigned long size = sizeof(secondary_holding_pen_release); secondary_holding_pen_release = val; - __flush_dcache_area(start, size); + dcache_clean_inval_poc((unsigned long)start, (unsigned long)start + size); } @@ -89,8 +89,9 @@ static int smp_spin_table_cpu_prepare(unsigned int cpu) * the boot protocol. */ writeq_relaxed(__pa_function(secondary_holding_pen), release_addr); - __flush_dcache_area((__force void *)release_addr, - sizeof(*release_addr)); + dcache_clean_inval_poc((__force unsigned long)release_addr, + (__force unsigned long)release_addr + + sizeof(*release_addr)); /* * Send an event to wake up the secondary CPU. diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 4a03621ea58f..a3367829b154 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c @@ -200,7 +200,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp, const char *loglvl) #ifdef CONFIG_STACKTRACE -noinline void arch_stack_walk(stack_trace_consume_fn consume_entry, +noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, struct task_struct *task, struct pt_regs *regs) { diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c index 265fe3eb1069..db5159a3055f 100644 --- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c @@ -41,7 +41,7 @@ __do_compat_cache_op(unsigned long start, unsigned long end) dsb(ish); } - ret = __flush_cache_user_range(start, start + chunk); + ret = caches_clean_inval_user_pou(start, start + chunk); if (ret) return ret; diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 0bfac95fe464..6f9839d1fc80 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -50,10 +50,7 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno, ret = do_ni_syscall(regs, scno); } - if (is_compat_task()) - ret = lower_32_bits(ret); - - regs->regs[0] = ret; + syscall_set_return_value(current, regs, 0, ret); } static inline bool has_syscall_work(unsigned long flags) @@ -128,7 +125,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, * syscall. do_notify_resume() will send a signal to userspace * before the syscall is restarted. */ - regs->regs[0] = -ERESTARTNOINTR; + syscall_set_return_value(current, regs, -ERESTARTNOINTR, 0); return; } @@ -149,7 +146,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, * anyway. */ if (scno == NO_SYSCALL) - regs->regs[0] = -ENOSYS; + syscall_set_return_value(current, regs, -ENOSYS, 0); scno = syscall_trace_enter(regs); if (scno == NO_SYSCALL) goto trace_exit; diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 51cbe394075d..b00961be177d 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -192,13 +192,11 @@ SECTIONS . += PAGE_SIZE; #endif -#ifdef CONFIG_ARM64_SW_TTBR0_PAN - reserved_ttbr0 = .; - . += RESERVED_TTBR0_SIZE; -#endif + reserved_pg_dir = .; + . += PAGE_SIZE; + swapper_pg_dir = .; . += PAGE_SIZE; - swapper_pg_end = .; . = ALIGN(SEGMENT_ALIGN); __init_begin = .; diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c index 74e0699661e9..3df67c127489 100644 --- a/arch/arm64/kvm/arch_timer.c +++ b/arch/arm64/kvm/arch_timer.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -973,36 +974,154 @@ static int kvm_timer_dying_cpu(unsigned int cpu) return 0; } -int kvm_timer_hyp_init(bool has_gic) +static int timer_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu) { - struct arch_timer_kvm_info *info; - int err; + if (vcpu) + irqd_set_forwarded_to_vcpu(d); + else + irqd_clr_forwarded_to_vcpu(d); - info = arch_timer_get_kvm_info(); - timecounter = &info->timecounter; + return 0; +} - if (!timecounter->cc) { - kvm_err("kvm_arch_timer: uninitialized timecounter\n"); - return -ENODEV; +static int timer_irq_set_irqchip_state(struct irq_data *d, + enum irqchip_irq_state which, bool val) +{ + if (which != IRQCHIP_STATE_ACTIVE || !irqd_is_forwarded_to_vcpu(d)) + return irq_chip_set_parent_state(d, which, val); + + if (val) + irq_chip_mask_parent(d); + else + irq_chip_unmask_parent(d); + + return 0; +} + +static void timer_irq_eoi(struct irq_data *d) +{ + if (!irqd_is_forwarded_to_vcpu(d)) + irq_chip_eoi_parent(d); +} + +static void timer_irq_ack(struct irq_data *d) +{ + d = d->parent_data; + if (d->chip->irq_ack) + d->chip->irq_ack(d); +} + +static struct irq_chip timer_chip = { + .name = "KVM", + .irq_ack = timer_irq_ack, + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_eoi = timer_irq_eoi, + .irq_set_type = irq_chip_set_type_parent, + .irq_set_vcpu_affinity = timer_irq_set_vcpu_affinity, + .irq_set_irqchip_state = timer_irq_set_irqchip_state, +}; + +static int timer_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *arg) +{ + irq_hw_number_t hwirq = (uintptr_t)arg; + + return irq_domain_set_hwirq_and_chip(domain, virq, hwirq, + &timer_chip, NULL); +} + +static void timer_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ +} + +static const struct irq_domain_ops timer_domain_ops = { + .alloc = timer_irq_domain_alloc, + .free = timer_irq_domain_free, +}; + +static struct irq_ops arch_timer_irq_ops = { + .get_input_level = kvm_arch_timer_get_input_level, +}; + +static void kvm_irq_fixup_flags(unsigned int virq, u32 *flags) +{ + *flags = irq_get_trigger_type(virq); + if (*flags != IRQF_TRIGGER_HIGH && *flags != IRQF_TRIGGER_LOW) { + kvm_err("Invalid trigger for timer IRQ%d, assuming level low\n", + virq); + *flags = IRQF_TRIGGER_LOW; } +} - /* First, do the virtual EL1 timer irq */ +static int kvm_irq_init(struct arch_timer_kvm_info *info) +{ + struct irq_domain *domain = NULL; if (info->virtual_irq <= 0) { kvm_err("kvm_arch_timer: invalid virtual timer IRQ: %d\n", info->virtual_irq); return -ENODEV; } + host_vtimer_irq = info->virtual_irq; + kvm_irq_fixup_flags(host_vtimer_irq, &host_vtimer_irq_flags); + + if (kvm_vgic_global_state.no_hw_deactivation) { + struct fwnode_handle *fwnode; + struct irq_data *data; + + fwnode = irq_domain_alloc_named_fwnode("kvm-timer"); + if (!fwnode) + return -ENOMEM; + + /* Assume both vtimer and ptimer in the same parent */ + data = irq_get_irq_data(host_vtimer_irq); + domain = irq_domain_create_hierarchy(data->domain, 0, + NR_KVM_TIMERS, fwnode, + &timer_domain_ops, NULL); + if (!domain) { + irq_domain_free_fwnode(fwnode); + return -ENOMEM; + } + + arch_timer_irq_ops.flags |= VGIC_IRQ_SW_RESAMPLE; + WARN_ON(irq_domain_push_irq(domain, host_vtimer_irq, + (void *)TIMER_VTIMER)); + } - host_vtimer_irq_flags = irq_get_trigger_type(host_vtimer_irq); - if (host_vtimer_irq_flags != IRQF_TRIGGER_HIGH && - host_vtimer_irq_flags != IRQF_TRIGGER_LOW) { - kvm_err("Invalid trigger for vtimer IRQ%d, assuming level low\n", - host_vtimer_irq); - host_vtimer_irq_flags = IRQF_TRIGGER_LOW; + if (info->physical_irq > 0) { + host_ptimer_irq = info->physical_irq; + kvm_irq_fixup_flags(host_ptimer_irq, &host_ptimer_irq_flags); + + if (domain) + WARN_ON(irq_domain_push_irq(domain, host_ptimer_irq, + (void *)TIMER_PTIMER)); } + return 0; +} + +int kvm_timer_hyp_init(bool has_gic) +{ + struct arch_timer_kvm_info *info; + int err; + + info = arch_timer_get_kvm_info(); + timecounter = &info->timecounter; + + if (!timecounter->cc) { + kvm_err("kvm_arch_timer: uninitialized timecounter\n"); + return -ENODEV; + } + + err = kvm_irq_init(info); + if (err) + return err; + + /* First, do the virtual EL1 timer irq */ + err = request_percpu_irq(host_vtimer_irq, kvm_arch_timer_handler, "kvm guest vtimer", kvm_get_running_vcpus()); if (err) { @@ -1027,15 +1146,6 @@ int kvm_timer_hyp_init(bool has_gic) /* Now let's do the physical EL1 timer irq */ if (info->physical_irq > 0) { - host_ptimer_irq = info->physical_irq; - host_ptimer_irq_flags = irq_get_trigger_type(host_ptimer_irq); - if (host_ptimer_irq_flags != IRQF_TRIGGER_HIGH && - host_ptimer_irq_flags != IRQF_TRIGGER_LOW) { - kvm_err("Invalid trigger for ptimer IRQ%d, assuming level low\n", - host_ptimer_irq); - host_ptimer_irq_flags = IRQF_TRIGGER_LOW; - } - err = request_percpu_irq(host_ptimer_irq, kvm_arch_timer_handler, "kvm guest ptimer", kvm_get_running_vcpus()); if (err) { @@ -1143,7 +1253,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) ret = kvm_vgic_map_phys_irq(vcpu, map.direct_vtimer->host_timer_irq, map.direct_vtimer->irq.irq, - kvm_arch_timer_get_input_level); + &arch_timer_irq_ops); if (ret) return ret; @@ -1151,7 +1261,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu) ret = kvm_vgic_map_phys_irq(vcpu, map.direct_ptimer->host_timer_irq, map.direct_ptimer->irq.irq, - kvm_arch_timer_get_input_level); + &arch_timer_irq_ops); } if (ret) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 4705db5c81d3..64e388b01748 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -94,6 +94,16 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, r = 0; kvm->arch.return_nisv_io_abort_to_user = true; break; + case KVM_CAP_ARM_MTE: + mutex_lock(&kvm->lock); + if (!system_supports_mte() || kvm->created_vcpus) { + r = -EINVAL; + } else { + r = 0; + kvm->arch.mte_enabled = true; + } + mutex_unlock(&kvm->lock); + break; default: r = -EINVAL; break; @@ -207,6 +217,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_ARM_INJECT_EXT_DABT: case KVM_CAP_SET_GUEST_DEBUG: case KVM_CAP_VCPU_ATTRIBUTES: + case KVM_CAP_PTP_KVM: r = 1; break; case KVM_CAP_ARM_SET_DEVICE_ADDR: @@ -235,6 +246,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) */ r = 1; break; + case KVM_CAP_ARM_MTE: + r = system_supports_mte(); + break; case KVM_CAP_STEAL_TIME: r = kvm_arm_pvtime_supported(); break; @@ -687,6 +701,10 @@ static void check_vcpu_requests(struct kvm_vcpu *vcpu) vgic_v4_load(vcpu); preempt_enable(); } + + if (kvm_check_request(KVM_REQ_RELOAD_PMU, vcpu)) + kvm_pmu_handle_pmcr(vcpu, + __vcpu_sys_reg(vcpu, PMCR_EL0)); } } @@ -727,11 +745,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) return ret; } - if (run->immediate_exit) - return -EINTR; - vcpu_load(vcpu); + if (run->immediate_exit) { + ret = -EINTR; + goto out; + } + kvm_sigset_activate(vcpu); ret = 1; @@ -904,6 +924,18 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) kvm_sigset_deactivate(vcpu); +out: + /* + * In the unlikely event that we are returning to userspace + * with pending exceptions or PC adjustment, commit these + * adjustments in order to give userspace a consistent view of + * the vcpu state. Note that this relies on __kvm_adjust_pc() + * being preempt-safe on VHE. + */ + if (unlikely(vcpu->arch.flags & (KVM_ARM64_PENDING_EXCEPTION | + KVM_ARM64_INCREMENT_PC))) + kvm_call_hyp(__kvm_adjust_pc, vcpu); + vcpu_put(vcpu); return ret; } @@ -1071,7 +1103,7 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, if (!cpus_have_final_cap(ARM64_HAS_STAGE2_FWB)) stage2_unmap_vm(vcpu->kvm); else - __flush_icache_all(); + icache_inval_all_pou(); } vcpu_reset_hcr(vcpu); @@ -1343,6 +1375,13 @@ long kvm_arch_vm_ioctl(struct file *filp, return 0; } + case KVM_ARM_MTE_COPY_TAGS: { + struct kvm_arm_copy_mte_tags copy_tags; + + if (copy_from_user(©_tags, argp, sizeof(copy_tags))) + return -EFAULT; + return kvm_vm_ioctl_mte_copy_tags(kvm, ©_tags); + } default: return -EINVAL; } @@ -1913,7 +1952,7 @@ static int init_hyp_mode(void) return err; } -void _kvm_host_prot_finalize(void *discard) +static void _kvm_host_prot_finalize(void *discard) { WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize)); } diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index c763808cacdf..015fc1077ad6 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -1000,3 +1000,89 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu, return ret; } + +long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm, + struct kvm_arm_copy_mte_tags *copy_tags) +{ + gpa_t guest_ipa = copy_tags->guest_ipa; + size_t length = copy_tags->length; + void __user *tags = copy_tags->addr; + gpa_t gfn; + bool write = !(copy_tags->flags & KVM_ARM_TAGS_FROM_GUEST); + int ret = 0; + + if (!kvm_has_mte(kvm)) + return -EINVAL; + + if (copy_tags->reserved[0] || copy_tags->reserved[1]) + return -EINVAL; + + if (copy_tags->flags & ~KVM_ARM_TAGS_FROM_GUEST) + return -EINVAL; + + if (length & ~PAGE_MASK || guest_ipa & ~PAGE_MASK) + return -EINVAL; + + gfn = gpa_to_gfn(guest_ipa); + + mutex_lock(&kvm->slots_lock); + + while (length > 0) { + kvm_pfn_t pfn = gfn_to_pfn_prot(kvm, gfn, write, NULL); + void *maddr; + unsigned long num_tags; + struct page *page; + + if (is_error_noslot_pfn(pfn)) { + ret = -EFAULT; + goto out; + } + + page = pfn_to_online_page(pfn); + if (!page) { + /* Reject ZONE_DEVICE memory */ + ret = -EFAULT; + goto out; + } + maddr = page_address(page); + + if (!write) { + if (test_bit(PG_mte_tagged, &page->flags)) + num_tags = mte_copy_tags_to_user(tags, maddr, + MTE_GRANULES_PER_PAGE); + else + /* No tags in memory, so write zeros */ + num_tags = MTE_GRANULES_PER_PAGE - + clear_user(tags, MTE_GRANULES_PER_PAGE); + kvm_release_pfn_clean(pfn); + } else { + num_tags = mte_copy_tags_from_user(maddr, tags, + MTE_GRANULES_PER_PAGE); + + /* + * Set the flag after checking the write + * completed fully + */ + if (num_tags == MTE_GRANULES_PER_PAGE) + set_bit(PG_mte_tagged, &page->flags); + + kvm_release_pfn_dirty(pfn); + } + + if (num_tags != MTE_GRANULES_PER_PAGE) { + ret = -EFAULT; + goto out; + } + + gfn++; + tags += num_tags; + length -= PAGE_SIZE; + } + +out: + mutex_unlock(&kvm->slots_lock); + /* If some data has been copied report the number of bytes copied */ + if (length != copy_tags->length) + return copy_tags->length - length; + return ret; +} diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c index cebe39f3b1b6..6f48336b1d86 100644 --- a/arch/arm64/kvm/handle_exit.c +++ b/arch/arm64/kvm/handle_exit.c @@ -291,3 +291,48 @@ void handle_exit_early(struct kvm_vcpu *vcpu, int exception_index) if (exception_index == ARM_EXCEPTION_EL1_SERROR) kvm_handle_guest_serror(vcpu, kvm_vcpu_get_esr(vcpu)); } + +void __noreturn __cold nvhe_hyp_panic_handler(u64 esr, u64 spsr, u64 elr, + u64 par, uintptr_t vcpu, + u64 far, u64 hpfar) { + u64 elr_in_kimg = __phys_to_kimg(__hyp_pa(elr)); + u64 hyp_offset = elr_in_kimg - kaslr_offset() - elr; + u64 mode = spsr & PSR_MODE_MASK; + + /* + * The nVHE hyp symbols are not included by kallsyms to avoid issues + * with aliasing. That means that the symbols cannot be printed with the + * "%pS" format specifier, so fall back to the vmlinux address if + * there's no better option. + */ + if (mode != PSR_MODE_EL2t && mode != PSR_MODE_EL2h) { + kvm_err("Invalid host exception to nVHE hyp!\n"); + } else if (ESR_ELx_EC(esr) == ESR_ELx_EC_BRK64 && + (esr & ESR_ELx_BRK64_ISS_COMMENT_MASK) == BUG_BRK_IMM) { + struct bug_entry *bug = find_bug(elr_in_kimg); + const char *file = NULL; + unsigned int line = 0; + + /* All hyp bugs, including warnings, are treated as fatal. */ + if (bug) + bug_get_file_line(bug, &file, &line); + + if (file) + kvm_err("nVHE hyp BUG at: %s:%u!\n", file, line); + else + kvm_err("nVHE hyp BUG at: %016llx!\n", elr + hyp_offset); + } else { + kvm_err("nVHE hyp panic at: %016llx!\n", elr + hyp_offset); + } + + /* + * Hyp has panicked and we're going to handle that by panicking the + * kernel. The kernel offset will be revealed in the panic so we're + * also safe to reveal the hyp offset as a debugging aid for translating + * hyp VAs to vmlinux addresses. + */ + kvm_err("Hyp Offset: 0x%llx\n", hyp_offset); + + panic("HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%016lx\n", + spsr, elr, esr, far, hpfar, par, vcpu); +} diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S index e831d3dfd50d..435346ea1504 100644 --- a/arch/arm64/kvm/hyp/entry.S +++ b/arch/arm64/kvm/hyp/entry.S @@ -13,6 +13,7 @@ #include #include #include +#include #include .text @@ -51,6 +52,9 @@ alternative_else_nop_endif add x29, x0, #VCPU_CONTEXT + // mte_switch_to_guest(g_ctxt, h_ctxt, tmp1) + mte_switch_to_guest x29, x1, x2 + // Macro ptrauth_switch_to_guest format: // ptrauth_switch_to_guest(guest cxt, tmp1, tmp2, tmp3) // The below macro to restore guest keys is not implemented in C code @@ -142,6 +146,9 @@ SYM_INNER_LABEL(__guest_exit, SYM_L_GLOBAL) // when this feature is enabled for kernel code. ptrauth_switch_to_hyp x1, x2, x3, x4, x5 + // mte_switch_to_hyp(g_ctxt, h_ctxt, reg1) + mte_switch_to_hyp x1, x2, x3 + // Restore hyp's sp_el0 restore_sp_el0 x2, x3 diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c index 73629094f903..0418399e0a20 100644 --- a/arch/arm64/kvm/hyp/exception.c +++ b/arch/arm64/kvm/hyp/exception.c @@ -112,7 +112,8 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode, new |= (old & PSR_C_BIT); new |= (old & PSR_V_BIT); - // TODO: TCO (if/when ARMv8.5-MemTag is exposed to guests) + if (kvm_has_mte(vcpu->kvm)) + new |= PSR_TCO_BIT; new |= (old & PSR_DIT_BIT); @@ -296,7 +297,7 @@ static void enter_exception32(struct kvm_vcpu *vcpu, u32 mode, u32 vect_offset) *vcpu_pc(vcpu) = vect_offset; } -void kvm_inject_exception(struct kvm_vcpu *vcpu) +static void kvm_inject_exception(struct kvm_vcpu *vcpu) { if (vcpu_el1_is_32bit(vcpu)) { switch (vcpu->arch.flags & KVM_ARM64_EXCEPT_MASK) { @@ -329,3 +330,19 @@ void kvm_inject_exception(struct kvm_vcpu *vcpu) } } } + +/* + * Adjust the guest PC (and potentially exception state) depending on + * flags provided by the emulation code. + */ +void __kvm_adjust_pc(struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.flags & KVM_ARM64_PENDING_EXCEPTION) { + kvm_inject_exception(vcpu); + vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION | + KVM_ARM64_EXCEPT_MASK); + } else if (vcpu->arch.flags & KVM_ARM64_INCREMENT_PC) { + kvm_skip_instr(vcpu); + vcpu->arch.flags &= ~KVM_ARM64_INCREMENT_PC; + } +} diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S index 5f49df4ffdd8..9aa9b73475c9 100644 --- a/arch/arm64/kvm/hyp/hyp-entry.S +++ b/arch/arm64/kvm/hyp/hyp-entry.S @@ -76,6 +76,7 @@ el1_trap: b __guest_exit el1_irq: +el1_fiq: get_vcpu_ptr x1, x0 mov x0, #ARM_EXCEPTION_IRQ b __guest_exit @@ -131,7 +132,6 @@ SYM_CODE_END(\label) invalid_vector el2t_error_invalid invalid_vector el2h_irq_invalid invalid_vector el2h_fiq_invalid - invalid_vector el1_fiq_invalid .ltorg @@ -179,12 +179,12 @@ SYM_CODE_START(__kvm_hyp_vector) valid_vect el1_sync // Synchronous 64-bit EL1 valid_vect el1_irq // IRQ 64-bit EL1 - invalid_vect el1_fiq_invalid // FIQ 64-bit EL1 + valid_vect el1_fiq // FIQ 64-bit EL1 valid_vect el1_error // Error 64-bit EL1 valid_vect el1_sync // Synchronous 32-bit EL1 valid_vect el1_irq // IRQ 32-bit EL1 - invalid_vect el1_fiq_invalid // FIQ 32-bit EL1 + valid_vect el1_fiq // FIQ 32-bit EL1 valid_vect el1_error // Error 32-bit EL1 SYM_CODE_END(__kvm_hyp_vector) diff --git a/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h b/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h index 61716359035d..4fdfeabefeb4 100644 --- a/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h +++ b/arch/arm64/kvm/hyp/include/hyp/adjust_pc.h @@ -13,8 +13,6 @@ #include #include -void kvm_inject_exception(struct kvm_vcpu *vcpu); - static inline void kvm_skip_instr(struct kvm_vcpu *vcpu) { if (vcpu_mode_is_32bit(vcpu)) { @@ -43,22 +41,6 @@ static inline void __kvm_skip_instr(struct kvm_vcpu *vcpu) write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR); } -/* - * Adjust the guest PC on entry, depending on flags provided by EL1 - * for the purpose of emulation (MMIO, sysreg) or exception injection. - */ -static inline void __adjust_pc(struct kvm_vcpu *vcpu) -{ - if (vcpu->arch.flags & KVM_ARM64_PENDING_EXCEPTION) { - kvm_inject_exception(vcpu); - vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION | - KVM_ARM64_EXCEPT_MASK); - } else if (vcpu->arch.flags & KVM_ARM64_INCREMENT_PC) { - kvm_skip_instr(vcpu); - vcpu->arch.flags &= ~KVM_ARM64_INCREMENT_PC; - } -} - /* * Skip an instruction while host sysregs are live. * Assumes host is always 64-bit. diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index cdf42e347d3f..e4a2f295a394 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -30,8 +30,6 @@ #include #include -extern const char __hyp_panic_string[]; - extern struct exception_table_entry __start___kvm_ex_table; extern struct exception_table_entry __stop___kvm_ex_table; diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h index cce43bfe158f..de7e14c862e6 100644 --- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h +++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h @@ -14,6 +14,7 @@ #include #include #include +#include static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt) { @@ -26,6 +27,16 @@ static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt) ctxt_sys_reg(ctxt, TPIDRRO_EL0) = read_sysreg(tpidrro_el0); } +static inline bool ctxt_has_mte(struct kvm_cpu_context *ctxt) +{ + struct kvm_vcpu *vcpu = ctxt->__hyp_running_vcpu; + + if (!vcpu) + vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt); + + return kvm_has_mte(kern_hyp_va(vcpu->kvm)); +} + static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) { ctxt_sys_reg(ctxt, CSSELR_EL1) = read_sysreg(csselr_el1); @@ -46,6 +57,11 @@ static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) ctxt_sys_reg(ctxt, PAR_EL1) = read_sysreg_par(); ctxt_sys_reg(ctxt, TPIDR_EL1) = read_sysreg(tpidr_el1); + if (ctxt_has_mte(ctxt)) { + ctxt_sys_reg(ctxt, TFSR_EL1) = read_sysreg_el1(SYS_TFSR); + ctxt_sys_reg(ctxt, TFSRE0_EL1) = read_sysreg_s(SYS_TFSRE0_EL1); + } + ctxt_sys_reg(ctxt, SP_EL1) = read_sysreg(sp_el1); ctxt_sys_reg(ctxt, ELR_EL1) = read_sysreg_el1(SYS_ELR); ctxt_sys_reg(ctxt, SPSR_EL1) = read_sysreg_el1(SYS_SPSR); @@ -107,6 +123,11 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt) write_sysreg(ctxt_sys_reg(ctxt, PAR_EL1), par_el1); write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL1), tpidr_el1); + if (ctxt_has_mte(ctxt)) { + write_sysreg_el1(ctxt_sys_reg(ctxt, TFSR_EL1), SYS_TFSR); + write_sysreg_s(ctxt_sys_reg(ctxt, TFSRE0_EL1), SYS_TFSRE0_EL1); + } + if (!has_vhe() && cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT) && ctxt->__hyp_running_vcpu) { diff --git a/arch/arm64/kvm/hyp/include/nvhe/gfp.h b/arch/arm64/kvm/hyp/include/nvhe/gfp.h index 55b3f0ce5bc8..fb0f523d1492 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/gfp.h +++ b/arch/arm64/kvm/hyp/include/nvhe/gfp.h @@ -7,7 +7,7 @@ #include #include -#define HYP_NO_ORDER UINT_MAX +#define HYP_NO_ORDER USHRT_MAX struct hyp_pool { /* @@ -19,48 +19,13 @@ struct hyp_pool { struct list_head free_area[MAX_ORDER]; phys_addr_t range_start; phys_addr_t range_end; - unsigned int max_order; + unsigned short max_order; }; -static inline void hyp_page_ref_inc(struct hyp_page *p) -{ - struct hyp_pool *pool = hyp_page_to_pool(p); - - hyp_spin_lock(&pool->lock); - p->refcount++; - hyp_spin_unlock(&pool->lock); -} - -static inline int hyp_page_ref_dec_and_test(struct hyp_page *p) -{ - struct hyp_pool *pool = hyp_page_to_pool(p); - int ret; - - hyp_spin_lock(&pool->lock); - p->refcount--; - ret = (p->refcount == 0); - hyp_spin_unlock(&pool->lock); - - return ret; -} - -static inline void hyp_set_page_refcounted(struct hyp_page *p) -{ - struct hyp_pool *pool = hyp_page_to_pool(p); - - hyp_spin_lock(&pool->lock); - if (p->refcount) { - hyp_spin_unlock(&pool->lock); - hyp_panic(); - } - p->refcount = 1; - hyp_spin_unlock(&pool->lock); -} - /* Allocation */ -void *hyp_alloc_pages(struct hyp_pool *pool, unsigned int order); -void hyp_get_page(void *addr); -void hyp_put_page(void *addr); +void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order); +void hyp_get_page(struct hyp_pool *pool, void *addr); +void hyp_put_page(struct hyp_pool *pool, void *addr); /* Used pages cannot be freed */ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages, diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 42d81ec739fa..9c227d87c36d 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -23,7 +23,7 @@ extern struct host_kvm host_kvm; int __pkvm_prot_finalize(void); int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end); -int kvm_host_prepare_stage2(void *mem_pgt_pool, void *dev_pgt_pool); +int kvm_host_prepare_stage2(void *pgt_pool_base); void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt); static __always_inline void __load_host_stage2(void) diff --git a/arch/arm64/kvm/hyp/include/nvhe/memory.h b/arch/arm64/kvm/hyp/include/nvhe/memory.h index d2fb307c5952..083b401e5840 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/memory.h +++ b/arch/arm64/kvm/hyp/include/nvhe/memory.h @@ -2,23 +2,20 @@ #ifndef __KVM_HYP_MEMORY_H #define __KVM_HYP_MEMORY_H +#include #include #include -struct hyp_pool; struct hyp_page { - unsigned int refcount; - unsigned int order; - struct hyp_pool *pool; - struct list_head node; + unsigned short refcount; + unsigned short order; }; extern s64 hyp_physvirt_offset; extern u64 __hyp_vmemmap; #define hyp_vmemmap ((struct hyp_page *)__hyp_vmemmap) -#define __hyp_pa(virt) ((phys_addr_t)(virt) + hyp_physvirt_offset) #define __hyp_va(phys) ((void *)((phys_addr_t)(phys) - hyp_physvirt_offset)) static inline void *hyp_phys_to_virt(phys_addr_t phys) diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h index 0095f6289742..8ec3a5a7744b 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h @@ -78,19 +78,20 @@ static inline unsigned long hyp_s1_pgtable_pages(void) return res; } -static inline unsigned long host_s2_mem_pgtable_pages(void) +static inline unsigned long host_s2_pgtable_pages(void) { + unsigned long res; + /* * Include an extra 16 pages to safely upper-bound the worst case of * concatenated pgds. */ - return __hyp_pgtable_total_pages() + 16; -} + res = __hyp_pgtable_total_pages() + 16; -static inline unsigned long host_s2_dev_pgtable_pages(void) -{ /* Allow 1 GiB for MMIO mappings */ - return __hyp_pgtable_max_pages(SZ_1G >> PAGE_SHIFT); + res += __hyp_pgtable_max_pages(SZ_1G >> PAGE_SHIFT); + + return res; } #endif /* __KVM_HYP_MM_H */ diff --git a/arch/arm64/kvm/hyp/nvhe/cache.S b/arch/arm64/kvm/hyp/nvhe/cache.S index 36cef6915428..958734f4d6b0 100644 --- a/arch/arm64/kvm/hyp/nvhe/cache.S +++ b/arch/arm64/kvm/hyp/nvhe/cache.S @@ -7,7 +7,7 @@ #include #include -SYM_FUNC_START_PI(__flush_dcache_area) +SYM_FUNC_START_PI(dcache_clean_inval_poc) dcache_by_line_op civac, sy, x0, x1, x2, x3 ret -SYM_FUNC_END_PI(__flush_dcache_area) +SYM_FUNC_END_PI(dcache_clean_inval_poc) diff --git a/arch/arm64/kvm/hyp/nvhe/host.S b/arch/arm64/kvm/hyp/nvhe/host.S index c419648c1d3f..1145731ea9d6 100644 --- a/arch/arm64/kvm/hyp/nvhe/host.S +++ b/arch/arm64/kvm/hyp/nvhe/host.S @@ -79,22 +79,18 @@ SYM_FUNC_START(__hyp_do_panic) mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\ PSR_MODE_EL1h) msr spsr_el2, lr - ldr lr, =panic + ldr lr, =nvhe_hyp_panic_handler hyp_kimg_va lr, x6 msr elr_el2, lr mov x29, x0 - /* Load the format string into x0 and arguments into x1-7 */ - ldr x0, =__hyp_panic_string - hyp_kimg_va x0, x6 - - /* Load the format arguments into x1-7. */ - mov x6, x3 - get_vcpu_ptr x7, x3 - mrs x3, esr_el2 - mrs x4, far_el2 - mrs x5, hpfar_el2 + /* Load the panic arguments into x0-7 */ + mrs x0, esr_el2 + get_vcpu_ptr x4, x5 + mrs x5, far_el2 + mrs x6, hpfar_el2 + mov x7, xzr // Unused argument /* Enter the host, conditionally restoring the host context. */ cbz x29, __host_enter_without_restoring diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index b4eaa7ef13e0..1632f001f4ed 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -28,6 +28,13 @@ static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt) cpu_reg(host_ctxt, 1) = __kvm_vcpu_run(kern_hyp_va(vcpu)); } +static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt) +{ + DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1); + + __kvm_adjust_pc(kern_hyp_va(vcpu)); +} + static void handle___kvm_flush_vm_context(struct kvm_cpu_context *host_ctxt) { __kvm_flush_vm_context(); @@ -170,6 +177,7 @@ typedef void (*hcall_t)(struct kvm_cpu_context *); static const hcall_t host_hcall[] = { HANDLE_FUNC(__kvm_vcpu_run), + HANDLE_FUNC(__kvm_adjust_pc), HANDLE_FUNC(__kvm_flush_vm_context), HANDLE_FUNC(__kvm_tlb_flush_vmid_ipa), HANDLE_FUNC(__kvm_tlb_flush_vmid), @@ -251,6 +259,6 @@ void handle_trap(struct kvm_cpu_context *host_ctxt) handle_host_mem_abort(host_ctxt); break; default: - hyp_panic(); + BUG(); } } diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-smp.c b/arch/arm64/kvm/hyp/nvhe/hyp-smp.c index 879559057dee..9f54833af400 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-smp.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-smp.c @@ -18,8 +18,7 @@ u64 __ro_after_init hyp_cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID u64 cpu_logical_map(unsigned int cpu) { - if (cpu >= ARRAY_SIZE(hyp_cpu_logical_map)) - hyp_panic(); + BUG_ON(cpu >= ARRAY_SIZE(hyp_cpu_logical_map)); return hyp_cpu_logical_map[cpu]; } @@ -30,8 +29,7 @@ unsigned long __hyp_per_cpu_offset(unsigned int cpu) unsigned long this_cpu_base; unsigned long elf_base; - if (cpu >= ARRAY_SIZE(kvm_arm_hyp_percpu_base)) - hyp_panic(); + BUG_ON(cpu >= ARRAY_SIZE(kvm_arm_hyp_percpu_base)); cpu_base_array = (unsigned long *)&kvm_arm_hyp_percpu_base; this_cpu_base = kern_hyp_va(cpu_base_array[cpu]); diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 541820d9c115..a6ce991b1467 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -23,8 +23,7 @@ extern unsigned long hyp_nr_cpus; struct host_kvm host_kvm; -static struct hyp_pool host_s2_mem; -static struct hyp_pool host_s2_dev; +static struct hyp_pool host_s2_pool; /* * Copies of the host's CPU features registers holding sanitized values. @@ -36,7 +35,7 @@ static const u8 pkvm_hyp_id = 1; static void *host_s2_zalloc_pages_exact(size_t size) { - return hyp_alloc_pages(&host_s2_mem, get_order(size)); + return hyp_alloc_pages(&host_s2_pool, get_order(size)); } static void *host_s2_zalloc_page(void *pool) @@ -44,20 +43,24 @@ static void *host_s2_zalloc_page(void *pool) return hyp_alloc_pages(pool, 0); } -static int prepare_s2_pools(void *mem_pgt_pool, void *dev_pgt_pool) +static void host_s2_get_page(void *addr) +{ + hyp_get_page(&host_s2_pool, addr); +} + +static void host_s2_put_page(void *addr) +{ + hyp_put_page(&host_s2_pool, addr); +} + +static int prepare_s2_pool(void *pgt_pool_base) { unsigned long nr_pages, pfn; int ret; - pfn = hyp_virt_to_pfn(mem_pgt_pool); - nr_pages = host_s2_mem_pgtable_pages(); - ret = hyp_pool_init(&host_s2_mem, pfn, nr_pages, 0); - if (ret) - return ret; - - pfn = hyp_virt_to_pfn(dev_pgt_pool); - nr_pages = host_s2_dev_pgtable_pages(); - ret = hyp_pool_init(&host_s2_dev, pfn, nr_pages, 0); + pfn = hyp_virt_to_pfn(pgt_pool_base); + nr_pages = host_s2_pgtable_pages(); + ret = hyp_pool_init(&host_s2_pool, pfn, nr_pages, 0); if (ret) return ret; @@ -67,8 +70,8 @@ static int prepare_s2_pools(void *mem_pgt_pool, void *dev_pgt_pool) .phys_to_virt = hyp_phys_to_virt, .virt_to_phys = hyp_virt_to_phys, .page_count = hyp_page_count, - .get_page = hyp_get_page, - .put_page = hyp_put_page, + .get_page = host_s2_get_page, + .put_page = host_s2_put_page, }; return 0; @@ -86,7 +89,7 @@ static void prepare_host_vtcr(void) id_aa64mmfr1_el1_sys_val, phys_shift); } -int kvm_host_prepare_stage2(void *mem_pgt_pool, void *dev_pgt_pool) +int kvm_host_prepare_stage2(void *pgt_pool_base) { struct kvm_s2_mmu *mmu = &host_kvm.arch.mmu; int ret; @@ -94,7 +97,7 @@ int kvm_host_prepare_stage2(void *mem_pgt_pool, void *dev_pgt_pool) prepare_host_vtcr(); hyp_spin_lock_init(&host_kvm.lock); - ret = prepare_s2_pools(mem_pgt_pool, dev_pgt_pool); + ret = prepare_s2_pool(pgt_pool_base); if (ret) return ret; @@ -190,7 +193,7 @@ static bool range_is_memory(u64 start, u64 end) { struct kvm_mem_range r1, r2; - if (!find_mem_range(start, &r1) || !find_mem_range(end, &r2)) + if (!find_mem_range(start, &r1) || !find_mem_range(end - 1, &r2)) return false; if (r1.start != r2.start) return false; @@ -199,11 +202,10 @@ static bool range_is_memory(u64 start, u64 end) } static inline int __host_stage2_idmap(u64 start, u64 end, - enum kvm_pgtable_prot prot, - struct hyp_pool *pool) + enum kvm_pgtable_prot prot) { return kvm_pgtable_stage2_map(&host_kvm.pgt, start, end - start, start, - prot, pool); + prot, &host_s2_pool); } static int host_stage2_idmap(u64 addr) @@ -211,7 +213,6 @@ static int host_stage2_idmap(u64 addr) enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W; struct kvm_mem_range range; bool is_memory = find_mem_range(addr, &range); - struct hyp_pool *pool = is_memory ? &host_s2_mem : &host_s2_dev; int ret; if (is_memory) @@ -222,22 +223,21 @@ static int host_stage2_idmap(u64 addr) if (ret) goto unlock; - ret = __host_stage2_idmap(range.start, range.end, prot, pool); - if (is_memory || ret != -ENOMEM) + ret = __host_stage2_idmap(range.start, range.end, prot); + if (ret != -ENOMEM) goto unlock; /* - * host_s2_mem has been provided with enough pages to cover all of - * memory with page granularity, so we should never hit the ENOMEM case. - * However, it is difficult to know how much of the MMIO range we will - * need to cover upfront, so we may need to 'recycle' the pages if we - * run out. + * The pool has been provided with enough pages to cover all of memory + * with page granularity, but it is difficult to know how much of the + * MMIO range we will need to cover upfront, so we may need to 'recycle' + * the pages if we run out. */ ret = host_stage2_unmap_dev_all(); if (ret) goto unlock; - ret = __host_stage2_idmap(range.start, range.end, prot, pool); + ret = __host_stage2_idmap(range.start, range.end, prot); unlock: hyp_spin_unlock(&host_kvm.lock); @@ -258,7 +258,7 @@ int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end) hyp_spin_lock(&host_kvm.lock); ret = kvm_pgtable_stage2_set_owner(&host_kvm.pgt, start, end - start, - &host_s2_mem, pkvm_hyp_id); + &host_s2_pool, pkvm_hyp_id); hyp_spin_unlock(&host_kvm.lock); return ret != -EAGAIN ? ret : 0; @@ -271,11 +271,9 @@ void handle_host_mem_abort(struct kvm_cpu_context *host_ctxt) int ret = 0; esr = read_sysreg_el2(SYS_ESR); - if (!__get_fault_info(esr, &fault)) - hyp_panic(); + BUG_ON(!__get_fault_info(esr, &fault)); addr = (fault.hpfar_el2 & HPFAR_MASK) << 8; ret = host_stage2_idmap(addr); - if (ret && ret != -EAGAIN) - hyp_panic(); + BUG_ON(ret && ret != -EAGAIN); } diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c index 237e03bf0cb1..41fc25bdfb34 100644 --- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c +++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c @@ -32,7 +32,7 @@ u64 __hyp_vmemmap; */ static struct hyp_page *__find_buddy_nocheck(struct hyp_pool *pool, struct hyp_page *p, - unsigned int order) + unsigned short order) { phys_addr_t addr = hyp_page_to_phys(p); @@ -51,21 +51,49 @@ static struct hyp_page *__find_buddy_nocheck(struct hyp_pool *pool, /* Find a buddy page currently available for allocation */ static struct hyp_page *__find_buddy_avail(struct hyp_pool *pool, struct hyp_page *p, - unsigned int order) + unsigned short order) { struct hyp_page *buddy = __find_buddy_nocheck(pool, p, order); - if (!buddy || buddy->order != order || list_empty(&buddy->node)) + if (!buddy || buddy->order != order || buddy->refcount) return NULL; return buddy; } +/* + * Pages that are available for allocation are tracked in free-lists, so we use + * the pages themselves to store the list nodes to avoid wasting space. As the + * allocator always returns zeroed pages (which are zeroed on the hyp_put_page() + * path to optimize allocation speed), we also need to clean-up the list node in + * each page when we take it out of the list. + */ +static inline void page_remove_from_list(struct hyp_page *p) +{ + struct list_head *node = hyp_page_to_virt(p); + + __list_del_entry(node); + memset(node, 0, sizeof(*node)); +} + +static inline void page_add_to_list(struct hyp_page *p, struct list_head *head) +{ + struct list_head *node = hyp_page_to_virt(p); + + INIT_LIST_HEAD(node); + list_add_tail(node, head); +} + +static inline struct hyp_page *node_to_page(struct list_head *node) +{ + return hyp_virt_to_page(node); +} + static void __hyp_attach_page(struct hyp_pool *pool, struct hyp_page *p) { - unsigned int order = p->order; + unsigned short order = p->order; struct hyp_page *buddy; memset(hyp_page_to_virt(p), 0, PAGE_SIZE << p->order); @@ -83,32 +111,23 @@ static void __hyp_attach_page(struct hyp_pool *pool, break; /* Take the buddy out of its list, and coallesce with @p */ - list_del_init(&buddy->node); + page_remove_from_list(buddy); buddy->order = HYP_NO_ORDER; p = min(p, buddy); } /* Mark the new head, and insert it */ p->order = order; - list_add_tail(&p->node, &pool->free_area[order]); -} - -static void hyp_attach_page(struct hyp_page *p) -{ - struct hyp_pool *pool = hyp_page_to_pool(p); - - hyp_spin_lock(&pool->lock); - __hyp_attach_page(pool, p); - hyp_spin_unlock(&pool->lock); + page_add_to_list(p, &pool->free_area[order]); } static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool, struct hyp_page *p, - unsigned int order) + unsigned short order) { struct hyp_page *buddy; - list_del_init(&p->node); + page_remove_from_list(p); while (p->order > order) { /* * The buddy of order n - 1 currently has HYP_NO_ORDER as it @@ -119,30 +138,64 @@ static struct hyp_page *__hyp_extract_page(struct hyp_pool *pool, p->order--; buddy = __find_buddy_nocheck(pool, p, p->order); buddy->order = p->order; - list_add_tail(&buddy->node, &pool->free_area[buddy->order]); + page_add_to_list(buddy, &pool->free_area[buddy->order]); } return p; } -void hyp_put_page(void *addr) +static inline void hyp_page_ref_inc(struct hyp_page *p) { - struct hyp_page *p = hyp_virt_to_page(addr); + BUG_ON(p->refcount == USHRT_MAX); + p->refcount++; +} +static inline int hyp_page_ref_dec_and_test(struct hyp_page *p) +{ + p->refcount--; + return (p->refcount == 0); +} + +static inline void hyp_set_page_refcounted(struct hyp_page *p) +{ + BUG_ON(p->refcount); + p->refcount = 1; +} + +static void __hyp_put_page(struct hyp_pool *pool, struct hyp_page *p) +{ if (hyp_page_ref_dec_and_test(p)) - hyp_attach_page(p); + __hyp_attach_page(pool, p); +} + +/* + * Changes to the buddy tree and page refcounts must be done with the hyp_pool + * lock held. If a refcount change requires an update to the buddy tree (e.g. + * hyp_put_page()), both operations must be done within the same critical + * section to guarantee transient states (e.g. a page with null refcount but + * not yet attached to a free list) can't be observed by well-behaved readers. + */ +void hyp_put_page(struct hyp_pool *pool, void *addr) +{ + struct hyp_page *p = hyp_virt_to_page(addr); + + hyp_spin_lock(&pool->lock); + __hyp_put_page(pool, p); + hyp_spin_unlock(&pool->lock); } -void hyp_get_page(void *addr) +void hyp_get_page(struct hyp_pool *pool, void *addr) { struct hyp_page *p = hyp_virt_to_page(addr); + hyp_spin_lock(&pool->lock); hyp_page_ref_inc(p); + hyp_spin_unlock(&pool->lock); } -void *hyp_alloc_pages(struct hyp_pool *pool, unsigned int order) +void *hyp_alloc_pages(struct hyp_pool *pool, unsigned short order) { - unsigned int i = order; + unsigned short i = order; struct hyp_page *p; hyp_spin_lock(&pool->lock); @@ -156,11 +209,11 @@ void *hyp_alloc_pages(struct hyp_pool *pool, unsigned int order) } /* Extract it from the tree at the right order */ - p = list_first_entry(&pool->free_area[i], struct hyp_page, node); + p = node_to_page(pool->free_area[i].next); p = __hyp_extract_page(pool, p, order); - hyp_spin_unlock(&pool->lock); hyp_set_page_refcounted(p); + hyp_spin_unlock(&pool->lock); return hyp_page_to_virt(p); } @@ -181,15 +234,14 @@ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages, /* Init the vmemmap portion */ p = hyp_phys_to_page(phys); - memset(p, 0, sizeof(*p) * nr_pages); for (i = 0; i < nr_pages; i++) { - p[i].pool = pool; - INIT_LIST_HEAD(&p[i].node); + p[i].order = 0; + hyp_set_page_refcounted(&p[i]); } /* Attach the unused pages to the buddy tree */ for (i = reserved_pages; i < nr_pages; i++) - __hyp_attach_page(pool, &p[i]); + __hyp_put_page(pool, &p[i]); return 0; } diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c index 7488f53b0aa2..0b574d106519 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -17,7 +17,6 @@ #include struct hyp_pool hpool; -struct kvm_pgtable_mm_ops pkvm_pgtable_mm_ops; unsigned long hyp_nr_cpus; #define hyp_percpu_size ((unsigned long)__per_cpu_end - \ @@ -25,8 +24,8 @@ unsigned long hyp_nr_cpus; static void *vmemmap_base; static void *hyp_pgt_base; -static void *host_s2_mem_pgt_base; -static void *host_s2_dev_pgt_base; +static void *host_s2_pgt_base; +static struct kvm_pgtable_mm_ops pkvm_pgtable_mm_ops; static int divide_memory_pool(void *virt, unsigned long size) { @@ -45,14 +44,9 @@ static int divide_memory_pool(void *virt, unsigned long size) if (!hyp_pgt_base) return -ENOMEM; - nr_pages = host_s2_mem_pgtable_pages(); - host_s2_mem_pgt_base = hyp_early_alloc_contig(nr_pages); - if (!host_s2_mem_pgt_base) - return -ENOMEM; - - nr_pages = host_s2_dev_pgtable_pages(); - host_s2_dev_pgt_base = hyp_early_alloc_contig(nr_pages); - if (!host_s2_dev_pgt_base) + nr_pages = host_s2_pgtable_pages(); + host_s2_pgt_base = hyp_early_alloc_contig(nr_pages); + if (!host_s2_pgt_base) return -ENOMEM; return 0; @@ -134,7 +128,8 @@ static void update_nvhe_init_params(void) for (i = 0; i < hyp_nr_cpus; i++) { params = per_cpu_ptr(&kvm_init_params, i); params->pgd_pa = __hyp_pa(pkvm_pgtable.pgd); - __flush_dcache_area(params, sizeof(*params)); + dcache_clean_inval_poc((unsigned long)params, + (unsigned long)params + sizeof(*params)); } } @@ -143,6 +138,16 @@ static void *hyp_zalloc_hyp_page(void *arg) return hyp_alloc_pages(&hpool, 0); } +static void hpool_get_page(void *addr) +{ + hyp_get_page(&hpool, addr); +} + +static void hpool_put_page(void *addr) +{ + hyp_put_page(&hpool, addr); +} + void __noreturn __pkvm_init_finalise(void) { struct kvm_host_data *host_data = this_cpu_ptr(&kvm_host_data); @@ -158,7 +163,7 @@ void __noreturn __pkvm_init_finalise(void) if (ret) goto out; - ret = kvm_host_prepare_stage2(host_s2_mem_pgt_base, host_s2_dev_pgt_base); + ret = kvm_host_prepare_stage2(host_s2_pgt_base); if (ret) goto out; @@ -166,8 +171,8 @@ void __noreturn __pkvm_init_finalise(void) .zalloc_page = hyp_zalloc_hyp_page, .phys_to_virt = hyp_phys_to_virt, .virt_to_phys = hyp_virt_to_phys, - .get_page = hyp_get_page, - .put_page = hyp_put_page, + .get_page = hpool_get_page, + .put_page = hpool_put_page, }; pkvm_pgtable.mm_ops = &pkvm_pgtable_mm_ops; diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index e9f6ea704d07..f7af9688c1f7 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -4,7 +4,6 @@ * Author: Marc Zyngier */ -#include #include #include @@ -201,7 +200,7 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) */ __debug_save_host_buffers_nvhe(vcpu); - __adjust_pc(vcpu); + __kvm_adjust_pc(vcpu); /* * We must restore the 32-bit state before the sysregs, thanks diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c index 83dc3b271bc5..38ed0f6f2703 100644 --- a/arch/arm64/kvm/hyp/nvhe/tlb.c +++ b/arch/arm64/kvm/hyp/nvhe/tlb.c @@ -104,7 +104,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, * you should be running with VHE enabled. */ if (icache_is_vpipt()) - __flush_icache_all(); + icache_inval_all_pou(); __tlb_switch_to_host(&cxt); } diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index c37c1dc4feaf..05321f4165e3 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -577,12 +577,24 @@ static void stage2_put_pte(kvm_pte_t *ptep, struct kvm_s2_mmu *mmu, u64 addr, mm_ops->put_page(ptep); } +static bool stage2_pte_cacheable(struct kvm_pgtable *pgt, kvm_pte_t pte) +{ + u64 memattr = pte & KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR; + return memattr == KVM_S2_MEMATTR(pgt, NORMAL); +} + +static bool stage2_pte_executable(kvm_pte_t pte) +{ + return !(pte & KVM_PTE_LEAF_ATTR_HI_S2_XN); +} + static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, struct stage2_map_data *data) { kvm_pte_t new, old = *ptep; u64 granule = kvm_granule_size(level), phys = data->phys; + struct kvm_pgtable *pgt = data->mmu->pgt; struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops; if (!kvm_block_mapping_supported(addr, end, phys, level)) @@ -606,6 +618,14 @@ static int stage2_map_walker_try_leaf(u64 addr, u64 end, u32 level, stage2_put_pte(ptep, data->mmu, addr, level, mm_ops); } + /* Perform CMOs before installation of the guest stage-2 PTE */ + if (mm_ops->dcache_clean_inval_poc && stage2_pte_cacheable(pgt, new)) + mm_ops->dcache_clean_inval_poc(kvm_pte_follow(new, mm_ops), + granule); + + if (mm_ops->icache_inval_pou && stage2_pte_executable(new)) + mm_ops->icache_inval_pou(kvm_pte_follow(new, mm_ops), granule); + smp_store_release(ptep, new); if (stage2_pte_is_counted(new)) mm_ops->get_page(ptep); @@ -798,12 +818,6 @@ int kvm_pgtable_stage2_set_owner(struct kvm_pgtable *pgt, u64 addr, u64 size, return ret; } -static bool stage2_pte_cacheable(struct kvm_pgtable *pgt, kvm_pte_t pte) -{ - u64 memattr = pte & KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR; - return memattr == KVM_S2_MEMATTR(pgt, NORMAL); -} - static int stage2_unmap_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, enum kvm_pgtable_walk_flags flag, void * const arg) @@ -839,8 +853,11 @@ static int stage2_unmap_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, stage2_put_pte(ptep, mmu, addr, level, mm_ops); if (need_flush) { - __flush_dcache_area(kvm_pte_follow(pte, mm_ops), - kvm_granule_size(level)); + kvm_pte_t *pte_follow = kvm_pte_follow(pte, mm_ops); + + dcache_clean_inval_poc((unsigned long)pte_follow, + (unsigned long)pte_follow + + kvm_granule_size(level)); } if (childp) @@ -861,10 +878,11 @@ int kvm_pgtable_stage2_unmap(struct kvm_pgtable *pgt, u64 addr, u64 size) } struct stage2_attr_data { - kvm_pte_t attr_set; - kvm_pte_t attr_clr; - kvm_pte_t pte; - u32 level; + kvm_pte_t attr_set; + kvm_pte_t attr_clr; + kvm_pte_t pte; + u32 level; + struct kvm_pgtable_mm_ops *mm_ops; }; static int stage2_attr_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, @@ -873,6 +891,7 @@ static int stage2_attr_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, { kvm_pte_t pte = *ptep; struct stage2_attr_data *data = arg; + struct kvm_pgtable_mm_ops *mm_ops = data->mm_ops; if (!kvm_pte_valid(pte)) return 0; @@ -887,8 +906,17 @@ static int stage2_attr_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, * but worst-case the access flag update gets lost and will be * set on the next access instead. */ - if (data->pte != pte) + if (data->pte != pte) { + /* + * Invalidate instruction cache before updating the guest + * stage-2 PTE if we are going to add executable permission. + */ + if (mm_ops->icache_inval_pou && + stage2_pte_executable(pte) && !stage2_pte_executable(*ptep)) + mm_ops->icache_inval_pou(kvm_pte_follow(pte, mm_ops), + kvm_granule_size(level)); WRITE_ONCE(*ptep, pte); + } return 0; } @@ -903,6 +931,7 @@ static int stage2_update_leaf_attrs(struct kvm_pgtable *pgt, u64 addr, struct stage2_attr_data data = { .attr_set = attr_set & attr_mask, .attr_clr = attr_clr & attr_mask, + .mm_ops = pgt->mm_ops, }; struct kvm_pgtable_walker walker = { .cb = stage2_attr_walker, @@ -988,11 +1017,15 @@ static int stage2_flush_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep, struct kvm_pgtable *pgt = arg; struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops; kvm_pte_t pte = *ptep; + kvm_pte_t *pte_follow; if (!kvm_pte_valid(pte) || !stage2_pte_cacheable(pgt, pte)) return 0; - __flush_dcache_area(kvm_pte_follow(pte, mm_ops), kvm_granule_size(level)); + pte_follow = kvm_pte_follow(pte, mm_ops); + dcache_clean_inval_poc((unsigned long)pte_follow, + (unsigned long)pte_follow + + kvm_granule_size(level)); return 0; } diff --git a/arch/arm64/kvm/hyp/reserved_mem.c b/arch/arm64/kvm/hyp/reserved_mem.c index 83ca23ac259b..d654921dd09b 100644 --- a/arch/arm64/kvm/hyp/reserved_mem.c +++ b/arch/arm64/kvm/hyp/reserved_mem.c @@ -71,8 +71,7 @@ void __init kvm_hyp_reserve(void) } hyp_mem_pages += hyp_s1_pgtable_pages(); - hyp_mem_pages += host_s2_mem_pgtable_pages(); - hyp_mem_pages += host_s2_dev_pgtable_pages(); + hyp_mem_pages += host_s2_pgtable_pages(); /* * The hyp_vmemmap needs to be backed by pages, but these pages diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c index af8e940d0f03..b3229924d243 100644 --- a/arch/arm64/kvm/hyp/vhe/switch.c +++ b/arch/arm64/kvm/hyp/vhe/switch.c @@ -4,7 +4,6 @@ * Author: Marc Zyngier */ -#include #include #include @@ -27,8 +26,6 @@ #include #include -const char __hyp_panic_string[] = "HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n"; - /* VHE specific context */ DEFINE_PER_CPU(struct kvm_host_data, kvm_host_data); DEFINE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt); @@ -134,7 +131,7 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) __load_guest_stage2(vcpu->arch.hw_mmu); __activate_traps(vcpu); - __adjust_pc(vcpu); + __kvm_adjust_pc(vcpu); sysreg_restore_guest_state_vhe(guest_ctxt); __debug_switch_to_guest(vcpu); @@ -207,7 +204,7 @@ static void __hyp_call_panic(u64 spsr, u64 elr, u64 par) __deactivate_traps(vcpu); sysreg_restore_host_state_vhe(host_ctxt); - panic(__hyp_panic_string, + panic("HYP panic:\nPS:%08llx PC:%016llx ESR:%08llx\nFAR:%016llx HPFAR:%016llx PAR:%016llx\nVCPU:%p\n", spsr, elr, read_sysreg_el2(SYS_ESR), read_sysreg_el2(SYS_FAR), read_sysreg(hpfar_el2), par, vcpu); diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c index ead21b98b620..30da78f72b3b 100644 --- a/arch/arm64/kvm/hypercalls.c +++ b/arch/arm64/kvm/hypercalls.c @@ -9,16 +9,65 @@ #include #include +static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val) +{ + struct system_time_snapshot systime_snapshot; + u64 cycles = ~0UL; + u32 feature; + + /* + * system time and counter value must captured at the same + * time to keep consistency and precision. + */ + ktime_get_snapshot(&systime_snapshot); + + /* + * This is only valid if the current clocksource is the + * architected counter, as this is the only one the guest + * can see. + */ + if (systime_snapshot.cs_id != CSID_ARM_ARCH_COUNTER) + return; + + /* + * The guest selects one of the two reference counters + * (virtual or physical) with the first argument of the SMCCC + * call. In case the identifier is not supported, error out. + */ + feature = smccc_get_arg1(vcpu); + switch (feature) { + case KVM_PTP_VIRT_COUNTER: + cycles = systime_snapshot.cycles - vcpu_read_sys_reg(vcpu, CNTVOFF_EL2); + break; + case KVM_PTP_PHYS_COUNTER: + cycles = systime_snapshot.cycles; + break; + default: + return; + } + + /* + * This relies on the top bit of val[0] never being set for + * valid values of system time, because that is *really* far + * in the future (about 292 years from 1970, and at that stage + * nobody will give a damn about it). + */ + val[0] = upper_32_bits(systime_snapshot.real); + val[1] = lower_32_bits(systime_snapshot.real); + val[2] = upper_32_bits(cycles); + val[3] = lower_32_bits(cycles); +} + int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) { u32 func_id = smccc_get_function(vcpu); - long val = SMCCC_RET_NOT_SUPPORTED; + u64 val[4] = {SMCCC_RET_NOT_SUPPORTED}; u32 feature; gpa_t gpa; switch (func_id) { case ARM_SMCCC_VERSION_FUNC_ID: - val = ARM_SMCCC_VERSION_1_1; + val[0] = ARM_SMCCC_VERSION_1_1; break; case ARM_SMCCC_ARCH_FEATURES_FUNC_ID: feature = smccc_get_arg1(vcpu); @@ -28,10 +77,10 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) case SPECTRE_VULNERABLE: break; case SPECTRE_MITIGATED: - val = SMCCC_RET_SUCCESS; + val[0] = SMCCC_RET_SUCCESS; break; case SPECTRE_UNAFFECTED: - val = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED; + val[0] = SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED; break; } break; @@ -54,22 +103,35 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) break; fallthrough; case SPECTRE_UNAFFECTED: - val = SMCCC_RET_NOT_REQUIRED; + val[0] = SMCCC_RET_NOT_REQUIRED; break; } break; case ARM_SMCCC_HV_PV_TIME_FEATURES: - val = SMCCC_RET_SUCCESS; + val[0] = SMCCC_RET_SUCCESS; break; } break; case ARM_SMCCC_HV_PV_TIME_FEATURES: - val = kvm_hypercall_pv_features(vcpu); + val[0] = kvm_hypercall_pv_features(vcpu); break; case ARM_SMCCC_HV_PV_TIME_ST: gpa = kvm_init_stolen_time(vcpu); if (gpa != GPA_INVALID) - val = gpa; + val[0] = gpa; + break; + case ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID: + val[0] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0; + val[1] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1; + val[2] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2; + val[3] = ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3; + break; + case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID: + val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES); + val[0] |= BIT(ARM_SMCCC_KVM_FUNC_PTP); + break; + case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID: + kvm_ptp_get_time(vcpu, val); break; case ARM_SMCCC_TRNG_VERSION: case ARM_SMCCC_TRNG_FEATURES: @@ -81,6 +143,6 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) return kvm_psci_call(vcpu); } - smccc_set_retval(vcpu, val, 0, 0, 0); + smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]); return 1; } diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 0f16b70befa8..78838678e525 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -126,6 +126,16 @@ static void *kvm_host_va(phys_addr_t phys) return __va(phys); } +static void clean_dcache_guest_page(void *va, size_t size) +{ + __clean_dcache_guest_page(va, size); +} + +static void invalidate_icache_guest_page(void *va, size_t size) +{ + __invalidate_icache_guest_page(va, size); +} + /* * Unmapping vs dcache management: * @@ -432,6 +442,8 @@ static struct kvm_pgtable_mm_ops kvm_s2_mm_ops = { .page_count = kvm_host_page_count, .phys_to_virt = kvm_host_va, .virt_to_phys = kvm_host_pa, + .dcache_clean_inval_poc = clean_dcache_guest_page, + .icache_inval_pou = invalidate_icache_guest_page, }; /** @@ -504,10 +516,11 @@ static void stage2_unmap_memslot(struct kvm *kvm, * +--------------------------------------------+ */ do { - struct vm_area_struct *vma = find_vma(current->mm, hva); + struct vm_area_struct *vma; hva_t vm_start, vm_end; - if (!vma || vma->vm_start >= reg_end) + vma = find_vma_intersection(current->mm, hva, reg_end); + if (!vma) break; /* @@ -638,7 +651,7 @@ static void stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_ * Acquires kvm_mmu_lock. Called with kvm->slots_lock mutex acquired, * serializing operations for VM memory regions. */ -void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot) +static void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot) { struct kvm_memslots *slots = kvm_memslots(kvm); struct kvm_memory_slot *memslot = id_to_memslot(slots, slot); @@ -692,16 +705,6 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm, kvm_mmu_write_protect_pt_masked(kvm, slot, gfn_offset, mask); } -static void clean_dcache_guest_page(kvm_pfn_t pfn, unsigned long size) -{ - __clean_dcache_guest_page(pfn, size); -} - -static void invalidate_icache_guest_page(kvm_pfn_t pfn, unsigned long size) -{ - __invalidate_icache_guest_page(pfn, size); -} - static void kvm_send_hwpoison_signal(unsigned long address, short lsb) { send_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, lsb, current); @@ -821,6 +824,74 @@ transparent_hugepage_adjust(struct kvm_memory_slot *memslot, return PAGE_SIZE; } +static int get_vma_page_shift(struct vm_area_struct *vma, unsigned long hva) +{ + unsigned long pa; + + if (is_vm_hugetlb_page(vma) && !(vma->vm_flags & VM_PFNMAP)) + return huge_page_shift(hstate_vma(vma)); + + if (!(vma->vm_flags & VM_PFNMAP)) + return PAGE_SHIFT; + + VM_BUG_ON(is_vm_hugetlb_page(vma)); + + pa = (vma->vm_pgoff << PAGE_SHIFT) + (hva - vma->vm_start); + +#ifndef __PAGETABLE_PMD_FOLDED + if ((hva & (PUD_SIZE - 1)) == (pa & (PUD_SIZE - 1)) && + ALIGN_DOWN(hva, PUD_SIZE) >= vma->vm_start && + ALIGN(hva, PUD_SIZE) <= vma->vm_end) + return PUD_SHIFT; +#endif + + if ((hva & (PMD_SIZE - 1)) == (pa & (PMD_SIZE - 1)) && + ALIGN_DOWN(hva, PMD_SIZE) >= vma->vm_start && + ALIGN(hva, PMD_SIZE) <= vma->vm_end) + return PMD_SHIFT; + + return PAGE_SHIFT; +} + +/* + * The page will be mapped in stage 2 as Normal Cacheable, so the VM will be + * able to see the page's tags and therefore they must be initialised first. If + * PG_mte_tagged is set, tags have already been initialised. + * + * The race in the test/set of the PG_mte_tagged flag is handled by: + * - preventing VM_SHARED mappings in a memslot with MTE preventing two VMs + * racing to santise the same page + * - mmap_lock protects between a VM faulting a page in and the VMM performing + * an mprotect() to add VM_MTE + */ +static int sanitise_mte_tags(struct kvm *kvm, kvm_pfn_t pfn, + unsigned long size) +{ + unsigned long i, nr_pages = size >> PAGE_SHIFT; + struct page *page; + + if (!kvm_has_mte(kvm)) + return 0; + + /* + * pfn_to_online_page() is used to reject ZONE_DEVICE pages + * that may not support tags. + */ + page = pfn_to_online_page(pfn); + + if (!page) + return -EFAULT; + + for (i = 0; i < nr_pages; i++, page++) { + if (!test_bit(PG_mte_tagged, &page->flags)) { + mte_clear_page_tags(page_address(page)); + set_bit(PG_mte_tagged, &page->flags); + } + } + + return 0; +} + static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, struct kvm_memory_slot *memslot, unsigned long hva, unsigned long fault_status) @@ -829,6 +900,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, bool write_fault, writable, force_pte = false; bool exec_fault; bool device = false; + bool shared; unsigned long mmu_seq; struct kvm *kvm = vcpu->kvm; struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache; @@ -852,7 +924,10 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, return -EFAULT; } - /* Let's check if we will get back a huge page backed by hugetlbfs */ + /* + * Let's check if we will get back a huge page backed by hugetlbfs, or + * get block mapping for device MMIO region. + */ mmap_read_lock(current->mm); vma = find_vma_intersection(current->mm, hva, hva + 1); if (unlikely(!vma)) { @@ -861,17 +936,19 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, return -EFAULT; } - if (is_vm_hugetlb_page(vma)) - vma_shift = huge_page_shift(hstate_vma(vma)); - else - vma_shift = PAGE_SHIFT; - - if (logging_active || - (vma->vm_flags & VM_PFNMAP)) { + /* + * logging_active is guaranteed to never be true for VM_PFNMAP + * memslots. + */ + if (logging_active) { force_pte = true; vma_shift = PAGE_SHIFT; + } else { + vma_shift = get_vma_page_shift(vma, hva); } + shared = (vma->vm_flags & VM_SHARED); + switch (vma_shift) { #ifndef __PAGETABLE_PMD_FOLDED case PUD_SHIFT: @@ -925,10 +1002,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, * unmapped afterwards, the call to kvm_unmap_hva will take it away * from us again properly. This smp_rmb() interacts with the smp_wmb() * in kvm_mmu_notifier_invalidate_. + * + * Besides, __gfn_to_pfn_memslot() instead of gfn_to_pfn_prot() is + * used to avoid unnecessary overhead introduced to locate the memory + * slot because it's always fixed even @gfn is adjusted for huge pages. */ smp_rmb(); - pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable); + pfn = __gfn_to_pfn_memslot(memslot, gfn, false, NULL, + write_fault, &writable); if (pfn == KVM_PFN_ERR_HWPOISON) { kvm_send_hwpoison_signal(hva, vma_shift); return 0; @@ -937,8 +1019,17 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, return -EFAULT; if (kvm_is_device_pfn(pfn)) { + /* + * If the page was identified as device early by looking at + * the VMA flags, vma_pagesize is already representing the + * largest quantity we can map. If instead it was mapped + * via gfn_to_pfn_prot(), vma_pagesize is set to PAGE_SIZE + * and must not be upgraded. + * + * In both cases, we don't let transparent_hugepage_adjust() + * change things at the last minute. + */ device = true; - force_pte = true; } else if (logging_active && !write_fault) { /* * Only actually map the page as writable if this was a write @@ -959,19 +1050,25 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, * If we are not forced to use page mapping, check if we are * backed by a THP and thus use block mapping if possible. */ - if (vma_pagesize == PAGE_SIZE && !force_pte) + if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) vma_pagesize = transparent_hugepage_adjust(memslot, hva, &pfn, &fault_ipa); + + if (fault_status != FSC_PERM && !device && kvm_has_mte(kvm)) { + /* Check the VMM hasn't introduced a new VM_SHARED VMA */ + if (!shared) + ret = sanitise_mte_tags(kvm, pfn, vma_pagesize); + else + ret = -EFAULT; + if (ret) + goto out_unlock; + } + if (writable) prot |= KVM_PGTABLE_PROT_W; - if (fault_status != FSC_PERM && !device) - clean_dcache_guest_page(pfn, vma_pagesize); - - if (exec_fault) { + if (exec_fault) prot |= KVM_PGTABLE_PROT_X; - invalidate_icache_guest_page(pfn, vma_pagesize); - } if (device) prot |= KVM_PGTABLE_PROT_DEVICE; @@ -994,7 +1091,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, /* Mark the page dirty only if the fault is handled successfully */ if (writable && !ret) { kvm_set_pfn_dirty(pfn); - mark_page_dirty(kvm, gfn); + mark_page_dirty_in_slot(memslot, gfn); } out_unlock: @@ -1202,10 +1299,19 @@ int kvm_unmap_hva_range(struct kvm *kvm, static int kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, u64 size, void *data) { kvm_pfn_t *pfn = (kvm_pfn_t *)data; + int ret; WARN_ON(size != PAGE_SIZE); + ret = sanitise_mte_tags(kvm, *pfn, PAGE_SIZE); + if (ret) + return 0; + /* + * We've moved a page around, probably through CoW, so let's treat + * it just like a translation fault and the map handler will clean + * the cache to the PoC. + * * The MMU notifiers will have unmapped a huge PMD before calling * ->change_pte() (which in turn calls kvm_set_spte_hva()) and * therefore we never need to clear out a huge PMD through this @@ -1226,11 +1332,6 @@ int kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte) trace_kvm_set_spte_hva(hva); - /* - * We've moved a page around, probably through CoW, so let's treat it - * just like a translation fault and clean the cache to the PoC. - */ - clean_dcache_guest_page(pfn, PAGE_SIZE); handle_hva_to_gpa(kvm, hva, end, &kvm_set_spte_handler, &pfn); return 0; } @@ -1396,7 +1497,6 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, { hva_t hva = mem->userspace_addr; hva_t reg_end = hva + mem->memory_size; - bool writable = !(mem->flags & KVM_MEM_READONLY); int ret = 0; if (change != KVM_MR_CREATE && change != KVM_MR_MOVE && @@ -1413,8 +1513,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, mmap_read_lock(current->mm); /* * A memory region could potentially cover multiple VMAs, and any holes - * between them, so iterate over all of them to find out if we can map - * any of them right now. + * between them, so iterate over all of them. * * +--------------------------------------------+ * +---------------+----------------+ +----------------+ @@ -1424,51 +1523,30 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, * +--------------------------------------------+ */ do { - struct vm_area_struct *vma = find_vma(current->mm, hva); - hva_t vm_start, vm_end; + struct vm_area_struct *vma; - if (!vma || vma->vm_start >= reg_end) + vma = find_vma_intersection(current->mm, hva, reg_end); + if (!vma) break; /* - * Take the intersection of this VMA with the memory region + * VM_SHARED mappings are not allowed with MTE to avoid races + * when updating the PG_mte_tagged page flag, see + * sanitise_mte_tags for more details. */ - vm_start = max(hva, vma->vm_start); - vm_end = min(reg_end, vma->vm_end); + if (kvm_has_mte(kvm) && vma->vm_flags & VM_SHARED) + return -EINVAL; if (vma->vm_flags & VM_PFNMAP) { - gpa_t gpa = mem->guest_phys_addr + - (vm_start - mem->userspace_addr); - phys_addr_t pa; - - pa = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT; - pa += vm_start - vma->vm_start; - /* IO region dirty page logging not allowed */ if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES) { ret = -EINVAL; - goto out; - } - - ret = kvm_phys_addr_ioremap(kvm, gpa, pa, - vm_end - vm_start, - writable); - if (ret) break; + } } - hva = vm_end; + hva = min(reg_end, vma->vm_end); } while (hva < reg_end); - if (change == KVM_MR_FLAGS_ONLY) - goto out; - - spin_lock(&kvm->mmu_lock); - if (ret) - unmap_stage2_range(&kvm->arch.mmu, mem->guest_phys_addr, mem->memory_size); - else if (!cpus_have_final_cap(ARM64_HAS_STAGE2_FWB)) - stage2_flush_memslot(kvm, memslot); - spin_unlock(&kvm->mmu_lock); -out: mmap_read_unlock(current->mm); return ret; } diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index e32c6e139a09..14957f7c7303 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -578,6 +578,7 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) kvm_pmu_set_counter_value(vcpu, ARMV8_PMU_CYCLE_IDX, 0); if (val & ARMV8_PMU_PMCR_P) { + mask &= ~BIT(ARMV8_PMU_CYCLE_IDX); for_each_set_bit(i, &mask, 32) kvm_pmu_set_counter_value(vcpu, i, 0); } @@ -850,6 +851,9 @@ int kvm_arm_pmu_v3_enable(struct kvm_vcpu *vcpu) return -EINVAL; } + /* One-off reload of the PMU on first run */ + kvm_make_request(KVM_REQ_RELOAD_PMU, vcpu); + return 0; } diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c index 4bbb9b9f6327..c2a7e9ad99fb 100644 --- a/arch/arm64/kvm/reset.c +++ b/arch/arm64/kvm/reset.c @@ -176,6 +176,10 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu) if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1) && is32bit) return false; + /* MTE is incompatible with AArch32 */ + if (kvm_has_mte(vcpu->kvm) && is32bit) + return false; + /* Check that the vcpus are either all 32bit or all 64bit */ kvm_for_each_vcpu(i, tmp, vcpu->kvm) { if (vcpu_has_feature(tmp, KVM_ARM_VCPU_EL1_32BIT) != is32bit) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 47b05731b16c..f6f126eb6ac1 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1047,6 +1047,13 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, break; case SYS_ID_AA64PFR1_EL1: val &= ~FEATURE(ID_AA64PFR1_MTE); + if (kvm_has_mte(vcpu->kvm)) { + u64 pfr, mte; + + pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1); + mte = cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR1_MTE_SHIFT); + val |= FIELD_PREP(FEATURE(ID_AA64PFR1_MTE), mte); + } break; case SYS_ID_AA64ISAR1_EL1: if (!vcpu_has_ptrauth(vcpu)) @@ -1063,6 +1070,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu, val = cpuid_feature_cap_perfmon_field(val, ID_AA64DFR0_PMUVER_SHIFT, kvm_vcpu_has_pmu(vcpu) ? ID_AA64DFR0_PMUVER_8_4 : 0); + /* Hide SPE from guests */ + val &= ~FEATURE(ID_AA64DFR0_PMSVER); break; case SYS_ID_DFR0_EL1: /* Limit guests to PMUv3 for ARMv8.4 */ @@ -1300,6 +1309,23 @@ static bool access_ccsidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, return true; } +static unsigned int mte_visibility(const struct kvm_vcpu *vcpu, + const struct sys_reg_desc *rd) +{ + if (kvm_has_mte(vcpu->kvm)) + return 0; + + return REG_HIDDEN; +} + +#define MTE_REG(name) { \ + SYS_DESC(SYS_##name), \ + .access = undef_access, \ + .reset = reset_unknown, \ + .reg = name, \ + .visibility = mte_visibility, \ +} + /* sys_reg_desc initialiser for known cpufeature ID registers */ #define ID_SANITISED(name) { \ SYS_DESC(SYS_##name), \ @@ -1468,8 +1494,8 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_ACTLR_EL1), access_actlr, reset_actlr, ACTLR_EL1 }, { SYS_DESC(SYS_CPACR_EL1), NULL, reset_val, CPACR_EL1, 0 }, - { SYS_DESC(SYS_RGSR_EL1), undef_access }, - { SYS_DESC(SYS_GCR_EL1), undef_access }, + MTE_REG(RGSR_EL1), + MTE_REG(GCR_EL1), { SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility }, { SYS_DESC(SYS_TRFCR_EL1), undef_access }, @@ -1496,12 +1522,25 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi }, { SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi }, - { SYS_DESC(SYS_TFSR_EL1), undef_access }, - { SYS_DESC(SYS_TFSRE0_EL1), undef_access }, + MTE_REG(TFSR_EL1), + MTE_REG(TFSRE0_EL1), { SYS_DESC(SYS_FAR_EL1), access_vm_reg, reset_unknown, FAR_EL1 }, { SYS_DESC(SYS_PAR_EL1), NULL, reset_unknown, PAR_EL1 }, + { SYS_DESC(SYS_PMSCR_EL1), undef_access }, + { SYS_DESC(SYS_PMSNEVFR_EL1), undef_access }, + { SYS_DESC(SYS_PMSICR_EL1), undef_access }, + { SYS_DESC(SYS_PMSIRR_EL1), undef_access }, + { SYS_DESC(SYS_PMSFCR_EL1), undef_access }, + { SYS_DESC(SYS_PMSEVFR_EL1), undef_access }, + { SYS_DESC(SYS_PMSLATFR_EL1), undef_access }, + { SYS_DESC(SYS_PMSIDR_EL1), undef_access }, + { SYS_DESC(SYS_PMBLIMITR_EL1), undef_access }, + { SYS_DESC(SYS_PMBPTR_EL1), undef_access }, + { SYS_DESC(SYS_PMBSR_EL1), undef_access }, + /* PMBIDR_EL1 is not trapped */ + { PMU_SYS_REG(SYS_PMINTENSET_EL1), .access = access_pminten, .reg = PMINTENSET_EL1 }, { PMU_SYS_REG(SYS_PMINTENCLR_EL1), diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 052917deb149..340c51d87677 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -335,13 +335,14 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm) kfree(dist->spis); dist->spis = NULL; dist->nr_spis = 0; + dist->vgic_dist_base = VGIC_ADDR_UNDEF; - if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { - list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list) { - list_del(&rdreg->list); - kfree(rdreg); - } + if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { + list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list) + vgic_v3_free_redist_region(rdreg); INIT_LIST_HEAD(&dist->rd_regions); + } else { + dist->vgic_cpu_base = VGIC_ADDR_UNDEF; } if (vgic_has_its(kvm)) @@ -362,6 +363,7 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) vgic_flush_pending_lpis(vcpu); INIT_LIST_HEAD(&vgic_cpu->ap_list_head); + vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF; } /* To be called with kvm->lock held */ @@ -480,6 +482,16 @@ static irqreturn_t vgic_maintenance_handler(int irq, void *data) return IRQ_HANDLED; } +static struct gic_kvm_info *gic_kvm_info; + +void __init vgic_set_kvm_info(const struct gic_kvm_info *info) +{ + BUG_ON(gic_kvm_info != NULL); + gic_kvm_info = kmalloc(sizeof(*info), GFP_KERNEL); + if (gic_kvm_info) + *gic_kvm_info = *info; +} + /** * kvm_vgic_init_cpu_hardware - initialize the GIC VE hardware * @@ -507,18 +519,29 @@ void kvm_vgic_init_cpu_hardware(void) */ int kvm_vgic_hyp_init(void) { - const struct gic_kvm_info *gic_kvm_info; + bool has_mask; int ret; - gic_kvm_info = gic_get_kvm_info(); if (!gic_kvm_info) return -ENODEV; - if (!gic_kvm_info->maint_irq) { + has_mask = !gic_kvm_info->no_maint_irq_mask; + + if (has_mask && !gic_kvm_info->maint_irq) { kvm_err("No vgic maintenance irq\n"); return -ENXIO; } + /* + * If we get one of these oddball non-GICs, taint the kernel, + * as we have no idea of how they *really* behave. + */ + if (gic_kvm_info->no_hw_deactivation) { + kvm_info("Non-architectural vgic, tainting kernel\n"); + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); + kvm_vgic_global_state.no_hw_deactivation = true; + } + switch (gic_kvm_info->type) { case GIC_V2: ret = vgic_v2_probe(gic_kvm_info); @@ -534,10 +557,17 @@ int kvm_vgic_hyp_init(void) ret = -ENODEV; } + kvm_vgic_global_state.maint_irq = gic_kvm_info->maint_irq; + + kfree(gic_kvm_info); + gic_kvm_info = NULL; + if (ret) return ret; - kvm_vgic_global_state.maint_irq = gic_kvm_info->maint_irq; + if (!has_mask) + return 0; + ret = request_percpu_irq(kvm_vgic_global_state.maint_irq, vgic_maintenance_handler, "vgic", kvm_get_running_vcpus()); diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c index 40cbaca81333..ec7543a9617c 100644 --- a/arch/arm64/kvm/vgic/vgic-its.c +++ b/arch/arm64/kvm/vgic/vgic-its.c @@ -2218,10 +2218,10 @@ static int vgic_its_save_itt(struct vgic_its *its, struct its_device *device) /* * If an LPI carries the HW bit, this means that this * interrupt is controlled by GICv4, and we do not - * have direct access to that state. Let's simply fail - * the save operation... + * have direct access to that state without GICv4.1. + * Let's simply fail the save operation... */ - if (ite->irq->hw) + if (ite->irq->hw && !kvm_vgic_global_state.has_gicv4_1) return -EACCES; ret = vgic_its_save_ite(its, device, ite, gpa, ite_esz); diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c index 15a6c98ee92f..03a253785700 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c @@ -251,30 +251,35 @@ static void vgic_mmio_write_v3r_ctlr(struct kvm_vcpu *vcpu, vgic_enable_lpis(vcpu); } -static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu, - gpa_t addr, unsigned int len) +static bool vgic_mmio_vcpu_rdist_is_last(struct kvm_vcpu *vcpu) { - unsigned long mpidr = kvm_vcpu_get_mpidr_aff(vcpu); + struct vgic_dist *vgic = &vcpu->kvm->arch.vgic; struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; - struct vgic_redist_region *rdreg = vgic_cpu->rdreg; - int target_vcpu_id = vcpu->vcpu_id; - gpa_t last_rdist_typer = rdreg->base + GICR_TYPER + - (rdreg->free_index - 1) * KVM_VGIC_V3_REDIST_SIZE; - u64 value; + struct vgic_redist_region *iter, *rdreg = vgic_cpu->rdreg; - value = (u64)(mpidr & GENMASK(23, 0)) << 32; - value |= ((target_vcpu_id & 0xffff) << 8); + if (!rdreg) + return false; - if (addr == last_rdist_typer) - value |= GICR_TYPER_LAST; - if (vgic_has_its(vcpu->kvm)) - value |= GICR_TYPER_PLPIS; + if (vgic_cpu->rdreg_index < rdreg->free_index - 1) { + return false; + } else if (rdreg->count && vgic_cpu->rdreg_index == (rdreg->count - 1)) { + struct list_head *rd_regions = &vgic->rd_regions; + gpa_t end = rdreg->base + rdreg->count * KVM_VGIC_V3_REDIST_SIZE; - return extract_bytes(value, addr & 7, len); + /* + * the rdist is the last one of the redist region, + * check whether there is no other contiguous rdist region + */ + list_for_each_entry(iter, rd_regions, list) { + if (iter->base == end && iter->free_index > 0) + return false; + } + } + return true; } -static unsigned long vgic_uaccess_read_v3r_typer(struct kvm_vcpu *vcpu, - gpa_t addr, unsigned int len) +static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu, + gpa_t addr, unsigned int len) { unsigned long mpidr = kvm_vcpu_get_mpidr_aff(vcpu); int target_vcpu_id = vcpu->vcpu_id; @@ -286,7 +291,9 @@ static unsigned long vgic_uaccess_read_v3r_typer(struct kvm_vcpu *vcpu, if (vgic_has_its(vcpu->kvm)) value |= GICR_TYPER_PLPIS; - /* reporting of the Last bit is not supported for userspace */ + if (vgic_mmio_vcpu_rdist_is_last(vcpu)) + value |= GICR_TYPER_LAST; + return extract_bytes(value, addr & 7, len); } @@ -612,7 +619,7 @@ static const struct vgic_register_region vgic_v3_rd_registers[] = { VGIC_ACCESS_32bit), REGISTER_DESC_WITH_LENGTH_UACCESS(GICR_TYPER, vgic_mmio_read_v3r_typer, vgic_mmio_write_wi, - vgic_uaccess_read_v3r_typer, vgic_mmio_uaccess_write_wi, 8, + NULL, vgic_mmio_uaccess_write_wi, 8, VGIC_ACCESS_64bit | VGIC_ACCESS_32bit), REGISTER_DESC_WITH_LENGTH(GICR_WAKER, vgic_mmio_read_raz, vgic_mmio_write_wi, 4, @@ -714,6 +721,7 @@ int vgic_register_redist_iodev(struct kvm_vcpu *vcpu) return -EINVAL; vgic_cpu->rdreg = rdreg; + vgic_cpu->rdreg_index = rdreg->free_index; rd_base = rdreg->base + rdreg->free_index * KVM_VGIC_V3_REDIST_SIZE; @@ -768,7 +776,7 @@ static int vgic_register_all_redist_iodevs(struct kvm *kvm) } /** - * vgic_v3_insert_redist_region - Insert a new redistributor region + * vgic_v3_alloc_redist_region - Allocate a new redistributor region * * Performs various checks before inserting the rdist region in the list. * Those tests depend on whether the size of the rdist region is known @@ -782,8 +790,8 @@ static int vgic_register_all_redist_iodevs(struct kvm *kvm) * * Return 0 on success, < 0 otherwise */ -static int vgic_v3_insert_redist_region(struct kvm *kvm, uint32_t index, - gpa_t base, uint32_t count) +static int vgic_v3_alloc_redist_region(struct kvm *kvm, uint32_t index, + gpa_t base, uint32_t count) { struct vgic_dist *d = &kvm->arch.vgic; struct vgic_redist_region *rdreg; @@ -791,10 +799,6 @@ static int vgic_v3_insert_redist_region(struct kvm *kvm, uint32_t index, size_t size = count * KVM_VGIC_V3_REDIST_SIZE; int ret; - /* single rdist region already set ?*/ - if (!count && !list_empty(rd_regions)) - return -EINVAL; - /* cross the end of memory ? */ if (base + size < base) return -EINVAL; @@ -805,11 +809,15 @@ static int vgic_v3_insert_redist_region(struct kvm *kvm, uint32_t index, } else { rdreg = list_last_entry(rd_regions, struct vgic_redist_region, list); - if (index != rdreg->index + 1) + + /* Don't mix single region and discrete redist regions */ + if (!count && rdreg->count) return -EINVAL; - /* Cannot add an explicitly sized regions after legacy region */ - if (!rdreg->count) + if (!count) + return -EEXIST; + + if (index != rdreg->index + 1) return -EINVAL; } @@ -848,11 +856,17 @@ static int vgic_v3_insert_redist_region(struct kvm *kvm, uint32_t index, return ret; } +void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg) +{ + list_del(&rdreg->list); + kfree(rdreg); +} + int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count) { int ret; - ret = vgic_v3_insert_redist_region(kvm, index, addr, count); + ret = vgic_v3_alloc_redist_region(kvm, index, addr, count); if (ret) return ret; @@ -861,8 +875,13 @@ int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count) * afterwards will register the iodevs when needed. */ ret = vgic_register_all_redist_iodevs(kvm); - if (ret) + if (ret) { + struct vgic_redist_region *rdreg; + + rdreg = vgic_v3_rdist_region_from_index(kvm, index); + vgic_v3_free_redist_region(rdreg); return ret; + } return 0; } diff --git a/arch/arm64/kvm/vgic/vgic-mmio.c b/arch/arm64/kvm/vgic/vgic-mmio.c index b2d73fc0d1ef..48c6067fc5ec 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio.c +++ b/arch/arm64/kvm/vgic/vgic-mmio.c @@ -938,10 +938,9 @@ vgic_get_mmio_region(struct kvm_vcpu *vcpu, struct vgic_io_device *iodev, return region; } -static int vgic_uaccess_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, +static int vgic_uaccess_read(struct kvm_vcpu *vcpu, struct vgic_io_device *iodev, gpa_t addr, u32 *val) { - struct vgic_io_device *iodev = kvm_to_vgic_iodev(dev); const struct vgic_register_region *region; struct kvm_vcpu *r_vcpu; @@ -960,10 +959,9 @@ static int vgic_uaccess_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, return 0; } -static int vgic_uaccess_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, +static int vgic_uaccess_write(struct kvm_vcpu *vcpu, struct vgic_io_device *iodev, gpa_t addr, const u32 *val) { - struct vgic_io_device *iodev = kvm_to_vgic_iodev(dev); const struct vgic_register_region *region; struct kvm_vcpu *r_vcpu; @@ -986,9 +984,9 @@ int vgic_uaccess(struct kvm_vcpu *vcpu, struct vgic_io_device *dev, bool is_write, int offset, u32 *val) { if (is_write) - return vgic_uaccess_write(vcpu, &dev->dev, offset, val); + return vgic_uaccess_write(vcpu, dev, offset, val); else - return vgic_uaccess_read(vcpu, &dev->dev, offset, val); + return vgic_uaccess_read(vcpu, dev, offset, val); } static int dispatch_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev, diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c index 11934c2af2f4..2c580204f1dc 100644 --- a/arch/arm64/kvm/vgic/vgic-v2.c +++ b/arch/arm64/kvm/vgic/vgic-v2.c @@ -108,11 +108,22 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) * If this causes us to lower the level, we have to also clear * the physical active state, since we will otherwise never be * told when the interrupt becomes asserted again. + * + * Another case is when the interrupt requires a helping hand + * on deactivation (no HW deactivation, for example). */ - if (vgic_irq_is_mapped_level(irq) && (val & GICH_LR_PENDING_BIT)) { - irq->line_level = vgic_get_phys_line_level(irq); + if (vgic_irq_is_mapped_level(irq)) { + bool resample = false; + + if (val & GICH_LR_PENDING_BIT) { + irq->line_level = vgic_get_phys_line_level(irq); + resample = !irq->line_level; + } else if (vgic_irq_needs_resampling(irq) && + !(irq->active || irq->pending_latch)) { + resample = true; + } - if (!irq->line_level) + if (resample) vgic_irq_set_phys_active(irq, false); } @@ -152,7 +163,7 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) if (irq->group) val |= GICH_LR_GROUP1; - if (irq->hw) { + if (irq->hw && !vgic_irq_needs_resampling(irq)) { val |= GICH_LR_HW; val |= irq->hwintid << GICH_LR_PHYSID_CPUID_SHIFT; /* diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index 6f530925a231..66004f61cd83 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include +#include #include #include #include @@ -99,11 +101,22 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) * If this causes us to lower the level, we have to also clear * the physical active state, since we will otherwise never be * told when the interrupt becomes asserted again. + * + * Another case is when the interrupt requires a helping hand + * on deactivation (no HW deactivation, for example). */ - if (vgic_irq_is_mapped_level(irq) && (val & ICH_LR_PENDING_BIT)) { - irq->line_level = vgic_get_phys_line_level(irq); + if (vgic_irq_is_mapped_level(irq)) { + bool resample = false; + + if (val & ICH_LR_PENDING_BIT) { + irq->line_level = vgic_get_phys_line_level(irq); + resample = !irq->line_level; + } else if (vgic_irq_needs_resampling(irq) && + !(irq->active || irq->pending_latch)) { + resample = true; + } - if (!irq->line_level) + if (resample) vgic_irq_set_phys_active(irq, false); } @@ -134,7 +147,7 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr) } } - if (irq->hw) { + if (irq->hw && !vgic_irq_needs_resampling(irq)) { val |= ICH_LR_HW; val |= ((u64)irq->hwintid) << ICH_LR_PHYS_ID_SHIFT; /* @@ -356,6 +369,32 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq) return 0; } +/* + * The deactivation of the doorbell interrupt will trigger the + * unmapping of the associated vPE. + */ +static void unmap_all_vpes(struct vgic_dist *dist) +{ + struct irq_desc *desc; + int i; + + for (i = 0; i < dist->its_vm.nr_vpes; i++) { + desc = irq_to_desc(dist->its_vm.vpes[i]->irq); + irq_domain_deactivate_irq(irq_desc_get_irq_data(desc)); + } +} + +static void map_all_vpes(struct vgic_dist *dist) +{ + struct irq_desc *desc; + int i; + + for (i = 0; i < dist->its_vm.nr_vpes; i++) { + desc = irq_to_desc(dist->its_vm.vpes[i]->irq); + irq_domain_activate_irq(irq_desc_get_irq_data(desc), false); + } +} + /** * vgic_v3_save_pending_tables - Save the pending tables into guest RAM * kvm lock and all vcpu lock must be held @@ -365,13 +404,28 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) struct vgic_dist *dist = &kvm->arch.vgic; struct vgic_irq *irq; gpa_t last_ptr = ~(gpa_t)0; - int ret; + bool vlpi_avail = false; + int ret = 0; u8 val; + if (unlikely(!vgic_initialized(kvm))) + return -ENXIO; + + /* + * A preparation for getting any VLPI states. + * The above vgic initialized check also ensures that the allocation + * and enabling of the doorbells have already been done. + */ + if (kvm_vgic_global_state.has_gicv4_1) { + unmap_all_vpes(dist); + vlpi_avail = true; + } + list_for_each_entry(irq, &dist->lpi_list_head, lpi_list) { int byte_offset, bit_nr; struct kvm_vcpu *vcpu; gpa_t pendbase, ptr; + bool is_pending; bool stored; vcpu = irq->target_vcpu; @@ -387,24 +441,35 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) if (ptr != last_ptr) { ret = kvm_read_guest_lock(kvm, ptr, &val, 1); if (ret) - return ret; + goto out; last_ptr = ptr; } stored = val & (1U << bit_nr); - if (stored == irq->pending_latch) + + is_pending = irq->pending_latch; + + if (irq->hw && vlpi_avail) + vgic_v4_get_vlpi_state(irq, &is_pending); + + if (stored == is_pending) continue; - if (irq->pending_latch) + if (is_pending) val |= 1 << bit_nr; else val &= ~(1 << bit_nr); ret = kvm_write_guest_lock(kvm, ptr, &val, 1); if (ret) - return ret; + goto out; } - return 0; + +out: + if (vlpi_avail) + map_all_vpes(dist); + + return ret; } /** diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c index 66508b03094f..c1845d8f5f7e 100644 --- a/arch/arm64/kvm/vgic/vgic-v4.c +++ b/arch/arm64/kvm/vgic/vgic-v4.c @@ -203,6 +203,25 @@ void vgic_v4_configure_vsgis(struct kvm *kvm) kvm_arm_resume_guest(kvm); } +/* + * Must be called with GICv4.1 and the vPE unmapped, which + * indicates the invalidation of any VPT caches associated + * with the vPE, thus we can get the VLPI state by peeking + * at the VPT. + */ +void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val) +{ + struct its_vpe *vpe = &irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe; + int mask = BIT(irq->intid % BITS_PER_BYTE); + void *va; + u8 *ptr; + + va = page_address(vpe->vpt_page); + ptr = va + irq->intid / BITS_PER_BYTE; + + *val = !!(*ptr & mask); +} + /** * vgic_v4_init - Initialize the GICv4 data structures * @kvm: Pointer to the VM being initialized @@ -385,6 +404,7 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq, struct vgic_its *its; struct vgic_irq *irq; struct its_vlpi_map map; + unsigned long flags; int ret; if (!vgic_supports_direct_msis(kvm)) @@ -430,6 +450,24 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq, irq->host_irq = virq; atomic_inc(&map.vpe->vlpi_count); + /* Transfer pending state */ + raw_spin_lock_irqsave(&irq->irq_lock, flags); + if (irq->pending_latch) { + ret = irq_set_irqchip_state(irq->host_irq, + IRQCHIP_STATE_PENDING, + irq->pending_latch); + WARN_RATELIMIT(ret, "IRQ %d", irq->host_irq); + + /* + * Clear pending_latch and communicate this state + * change via vgic_queue_irq_unlock. + */ + irq->pending_latch = false; + vgic_queue_irq_unlock(kvm, irq, flags); + } else { + raw_spin_unlock_irqrestore(&irq->irq_lock, flags); + } + out: mutex_unlock(&its->its_lock); return ret; diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index 1c597c9885fa..1d22365c68e2 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -182,8 +182,8 @@ bool vgic_get_phys_line_level(struct vgic_irq *irq) BUG_ON(!irq->hw); - if (irq->get_input_level) - return irq->get_input_level(irq->intid); + if (irq->ops && irq->ops->get_input_level) + return irq->ops->get_input_level(irq->intid); WARN_ON(irq_get_irqchip_state(irq->host_irq, IRQCHIP_STATE_PENDING, @@ -479,7 +479,7 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, /* @irq->irq_lock must be held */ static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct vgic_irq *irq, unsigned int host_irq, - bool (*get_input_level)(int vindid)) + struct irq_ops *ops) { struct irq_desc *desc; struct irq_data *data; @@ -499,7 +499,7 @@ static int kvm_vgic_map_irq(struct kvm_vcpu *vcpu, struct vgic_irq *irq, irq->hw = true; irq->host_irq = host_irq; irq->hwintid = data->hwirq; - irq->get_input_level = get_input_level; + irq->ops = ops; return 0; } @@ -508,11 +508,11 @@ static inline void kvm_vgic_unmap_irq(struct vgic_irq *irq) { irq->hw = false; irq->hwintid = 0; - irq->get_input_level = NULL; + irq->ops = NULL; } int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, - u32 vintid, bool (*get_input_level)(int vindid)) + u32 vintid, struct irq_ops *ops) { struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid); unsigned long flags; @@ -521,7 +521,7 @@ int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, BUG_ON(!irq); raw_spin_lock_irqsave(&irq->irq_lock, flags); - ret = kvm_vgic_map_irq(vcpu, irq, host_irq, get_input_level); + ret = kvm_vgic_map_irq(vcpu, irq, host_irq, ops); raw_spin_unlock_irqrestore(&irq->irq_lock, flags); vgic_put_irq(vcpu->kvm, irq); diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index 64fcd7511110..dc1f3d1657ee 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -293,6 +293,7 @@ vgic_v3_rd_region_size(struct kvm *kvm, struct vgic_redist_region *rdreg) struct vgic_redist_region *vgic_v3_rdist_region_from_index(struct kvm *kvm, u32 index); +void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg); bool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size); @@ -317,5 +318,6 @@ bool vgic_supports_direct_msis(struct kvm *kvm); int vgic_v4_init(struct kvm *kvm); void vgic_v4_teardown(struct kvm *kvm); void vgic_v4_configure_vsgis(struct kvm *kvm); +void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val); #endif diff --git a/arch/arm64/lib/uaccess_flushcache.c b/arch/arm64/lib/uaccess_flushcache.c index bfa30b75b2b8..2cffff7a876c 100644 --- a/arch/arm64/lib/uaccess_flushcache.c +++ b/arch/arm64/lib/uaccess_flushcache.c @@ -15,7 +15,7 @@ void memcpy_flushcache(void *dst, const void *src, size_t cnt) * barrier to order the cache maintenance against the memcpy. */ memcpy(dst, src, cnt); - __clean_dcache_area_pop(dst, cnt); + dcache_clean_pop((unsigned long)dst, (unsigned long)dst + cnt); } EXPORT_SYMBOL_GPL(memcpy_flushcache); @@ -35,6 +35,6 @@ unsigned long __copy_user_flushcache(void *to, const void __user *from, uaccess_disable_not_uao(); /* See above */ - __clean_dcache_area_pop(to, n - rc); + dcache_clean_pop((unsigned long)to, (unsigned long)to + n - rc); return rc; } diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S index 2d881f34dd9d..5051b3c1a4f1 100644 --- a/arch/arm64/mm/cache.S +++ b/arch/arm64/mm/cache.S @@ -15,7 +15,7 @@ #include /* - * flush_icache_range(start,end) + * caches_clean_inval_pou_macro(start,end) [fixup] * * Ensure that the I and D caches are coherent within specified region. * This is typically used when code has been written to a memory region, @@ -23,12 +23,27 @@ * * - start - virtual start address of region * - end - virtual end address of region + * - fixup - optional label to branch to on user fault */ -SYM_FUNC_START(__flush_icache_range) - /* FALLTHROUGH */ +.macro caches_clean_inval_pou_macro, fixup +alternative_if ARM64_HAS_CACHE_IDC + dsb ishst + b .Ldc_skip_\@ +alternative_else_nop_endif + mov x2, x0 + mov x3, x1 + dcache_by_line_op cvau, ish, x2, x3, x4, x5, \fixup +.Ldc_skip_\@: +alternative_if ARM64_HAS_CACHE_DIC + isb + b .Lic_skip_\@ +alternative_else_nop_endif + invalidate_icache_by_line x0, x1, x2, x3, \fixup +.Lic_skip_\@: +.endm /* - * __flush_cache_user_range(start,end) + * caches_clean_inval_pou(start,end) * * Ensure that the I and D caches are coherent within specified region. * This is typically used when code has been written to a memory region, @@ -37,117 +52,103 @@ SYM_FUNC_START(__flush_icache_range) * - start - virtual start address of region * - end - virtual end address of region */ -SYM_FUNC_START(__flush_cache_user_range) +SYM_FUNC_START(caches_clean_inval_pou) + caches_clean_inval_pou_macro + ret +SYM_FUNC_END(caches_clean_inval_pou) + +/* + * caches_clean_inval_user_pou(start,end) + * + * Ensure that the I and D caches are coherent within specified region. + * This is typically used when code has been written to a memory region, + * and will be executed. + * + * - start - virtual start address of region + * - end - virtual end address of region + */ +SYM_FUNC_START(caches_clean_inval_user_pou) uaccess_ttbr0_enable x2, x3, x4 -alternative_if ARM64_HAS_CACHE_IDC - dsb ishst - b 7f -alternative_else_nop_endif - dcache_line_size x2, x3 - sub x3, x2, #1 - bic x4, x0, x3 -1: -user_alt 9f, "dc cvau, x4", "dc civac, x4", ARM64_WORKAROUND_CLEAN_CACHE - add x4, x4, x2 - cmp x4, x1 - b.lo 1b - dsb ish -7: -alternative_if ARM64_HAS_CACHE_DIC - isb - b 8f -alternative_else_nop_endif - invalidate_icache_by_line x0, x1, x2, x3, 9f -8: mov x0, #0 + caches_clean_inval_pou_macro 2f + mov x0, xzr 1: uaccess_ttbr0_disable x1, x2 ret -9: +2: mov x0, #-EFAULT b 1b -SYM_FUNC_END(__flush_icache_range) -SYM_FUNC_END(__flush_cache_user_range) +SYM_FUNC_END(caches_clean_inval_user_pou) /* - * invalidate_icache_range(start,end) + * icache_inval_pou(start,end) * * Ensure that the I cache is invalid within specified region. * * - start - virtual start address of region * - end - virtual end address of region */ -SYM_FUNC_START(invalidate_icache_range) +SYM_FUNC_START(icache_inval_pou) alternative_if ARM64_HAS_CACHE_DIC - mov x0, xzr isb ret alternative_else_nop_endif - uaccess_ttbr0_enable x2, x3, x4 - - invalidate_icache_by_line x0, x1, x2, x3, 2f - mov x0, xzr -1: - uaccess_ttbr0_disable x1, x2 + invalidate_icache_by_line x0, x1, x2, x3 ret -2: - mov x0, #-EFAULT - b 1b -SYM_FUNC_END(invalidate_icache_range) +SYM_FUNC_END(icache_inval_pou) /* - * __flush_dcache_area(kaddr, size) + * dcache_clean_inval_poc(start, end) * - * Ensure that any D-cache lines for the interval [kaddr, kaddr+size) + * Ensure that any D-cache lines for the interval [start, end) * are cleaned and invalidated to the PoC. * - * - kaddr - kernel address - * - size - size in question + * - start - virtual start address of region + * - end - virtual end address of region */ -SYM_FUNC_START_PI(__flush_dcache_area) +SYM_FUNC_START_PI(dcache_clean_inval_poc) dcache_by_line_op civac, sy, x0, x1, x2, x3 ret -SYM_FUNC_END_PI(__flush_dcache_area) +SYM_FUNC_END_PI(dcache_clean_inval_poc) /* - * __clean_dcache_area_pou(kaddr, size) + * dcache_clean_pou(start, end) * - * Ensure that any D-cache lines for the interval [kaddr, kaddr+size) + * Ensure that any D-cache lines for the interval [start, end) * are cleaned to the PoU. * - * - kaddr - kernel address - * - size - size in question + * - start - virtual start address of region + * - end - virtual end address of region */ -SYM_FUNC_START(__clean_dcache_area_pou) +SYM_FUNC_START(dcache_clean_pou) alternative_if ARM64_HAS_CACHE_IDC dsb ishst ret alternative_else_nop_endif dcache_by_line_op cvau, ish, x0, x1, x2, x3 ret -SYM_FUNC_END(__clean_dcache_area_pou) +SYM_FUNC_END(dcache_clean_pou) /* - * __inval_dcache_area(kaddr, size) + * dcache_inval_poc(start, end) * - * Ensure that any D-cache lines for the interval [kaddr, kaddr+size) + * Ensure that any D-cache lines for the interval [start, end) * are invalidated. Any partial lines at the ends of the interval are * also cleaned to PoC to prevent data loss. * - * - kaddr - kernel address - * - size - size in question + * - start - kernel start address of region + * - end - kernel end address of region */ SYM_FUNC_START_LOCAL(__dma_inv_area) -SYM_FUNC_START_PI(__inval_dcache_area) +SYM_FUNC_START_PI(dcache_inval_poc) /* FALLTHROUGH */ /* - * __dma_inv_area(start, size) + * __dma_inv_area(start, end) * - start - virtual start address of region - * - size - size in question + * - end - virtual end address of region */ - add x1, x1, x0 dcache_line_size x2, x3 sub x3, x2, #1 tst x1, x3 // end cache line aligned? @@ -165,48 +166,48 @@ SYM_FUNC_START_PI(__inval_dcache_area) b.lo 2b dsb sy ret -SYM_FUNC_END_PI(__inval_dcache_area) +SYM_FUNC_END_PI(dcache_inval_poc) SYM_FUNC_END(__dma_inv_area) /* - * __clean_dcache_area_poc(kaddr, size) + * dcache_clean_poc(start, end) * - * Ensure that any D-cache lines for the interval [kaddr, kaddr+size) + * Ensure that any D-cache lines for the interval [start, end) * are cleaned to the PoC. * - * - kaddr - kernel address - * - size - size in question + * - start - virtual start address of region + * - end - virtual end address of region */ SYM_FUNC_START_LOCAL(__dma_clean_area) -SYM_FUNC_START_PI(__clean_dcache_area_poc) +SYM_FUNC_START_PI(dcache_clean_poc) /* FALLTHROUGH */ /* - * __dma_clean_area(start, size) + * __dma_clean_area(start, end) * - start - virtual start address of region - * - size - size in question + * - end - virtual end address of region */ dcache_by_line_op cvac, sy, x0, x1, x2, x3 ret -SYM_FUNC_END_PI(__clean_dcache_area_poc) +SYM_FUNC_END_PI(dcache_clean_poc) SYM_FUNC_END(__dma_clean_area) /* - * __clean_dcache_area_pop(kaddr, size) + * dcache_clean_pop(start, end) * - * Ensure that any D-cache lines for the interval [kaddr, kaddr+size) + * Ensure that any D-cache lines for the interval [start, end) * are cleaned to the PoP. * - * - kaddr - kernel address - * - size - size in question + * - start - virtual start address of region + * - end - virtual end address of region */ -SYM_FUNC_START_PI(__clean_dcache_area_pop) +SYM_FUNC_START_PI(dcache_clean_pop) alternative_if_not ARM64_HAS_DCPOP - b __clean_dcache_area_poc + b dcache_clean_poc alternative_else_nop_endif dcache_by_line_op cvap, sy, x0, x1, x2, x3 ret -SYM_FUNC_END_PI(__clean_dcache_area_pop) +SYM_FUNC_END_PI(dcache_clean_pop) /* * __dma_flush_area(start, size) @@ -217,6 +218,7 @@ SYM_FUNC_END_PI(__clean_dcache_area_pop) * - size - size in question */ SYM_FUNC_START_PI(__dma_flush_area) + add x1, x0, x1 dcache_by_line_op civac, sy, x0, x1, x2, x3 ret SYM_FUNC_END_PI(__dma_flush_area) @@ -228,6 +230,7 @@ SYM_FUNC_END_PI(__dma_flush_area) * - dir - DMA direction */ SYM_FUNC_START_PI(__dma_map_area) + add x1, x0, x1 cmp w2, #DMA_FROM_DEVICE b.eq __dma_inv_area b __dma_clean_area @@ -240,6 +243,7 @@ SYM_FUNC_END_PI(__dma_map_area) * - dir - DMA direction */ SYM_FUNC_START_PI(__dma_unmap_area) + add x1, x0, x1 cmp w2, #DMA_TO_DEVICE b.ne __dma_inv_area ret diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c index 6d44c028d1c9..2aaf950b906c 100644 --- a/arch/arm64/mm/flush.c +++ b/arch/arm64/mm/flush.c @@ -14,28 +14,25 @@ #include #include -void sync_icache_aliases(void *kaddr, unsigned long len) +void sync_icache_aliases(unsigned long start, unsigned long end) { - unsigned long addr = (unsigned long)kaddr; - if (icache_is_aliasing()) { - __clean_dcache_area_pou(kaddr, len); - __flush_icache_all(); + dcache_clean_pou(start, end); + icache_inval_all_pou(); } else { /* * Don't issue kick_all_cpus_sync() after I-cache invalidation * for user mappings. */ - __flush_icache_range(addr, addr + len); + caches_clean_inval_pou(start, end); } } -static void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, - unsigned long uaddr, void *kaddr, - unsigned long len) +static void flush_ptrace_access(struct vm_area_struct *vma, unsigned long start, + unsigned long end) { if (vma->vm_flags & VM_EXEC) - sync_icache_aliases(kaddr, len); + sync_icache_aliases(start, end); } /* @@ -48,7 +45,7 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long len) { memcpy(dst, src, len); - flush_ptrace_access(vma, page, uaddr, dst, len); + flush_ptrace_access(vma, (unsigned long)dst, (unsigned long)dst + len); } void __sync_icache_dcache(pte_t pte) @@ -56,7 +53,9 @@ void __sync_icache_dcache(pte_t pte) struct page *page = pte_page(pte); if (!test_bit(PG_dcache_clean, &page->flags)) { - sync_icache_aliases(page_address(page), page_size(page)); + sync_icache_aliases((unsigned long)page_address(page), + (unsigned long)page_address(page) + + page_size(page)); set_bit(PG_dcache_clean, &page->flags); } } @@ -77,20 +76,20 @@ EXPORT_SYMBOL(flush_dcache_page); /* * Additional functions defined in assembly. */ -EXPORT_SYMBOL(__flush_icache_range); +EXPORT_SYMBOL(caches_clean_inval_pou); #ifdef CONFIG_ARCH_HAS_PMEM_API void arch_wb_cache_pmem(void *addr, size_t size) { /* Ensure order against any prior non-cacheable writes */ dmb(osh); - __clean_dcache_area_pop(addr, size); + dcache_clean_pop((unsigned long)addr, (unsigned long)addr + size); } EXPORT_SYMBOL_GPL(arch_wb_cache_pmem); void arch_invalidate_pmem(void *addr, size_t size) { - __inval_dcache_area(addr, size); + dcache_inval_poc((unsigned long)addr, (unsigned long)addr + size); } EXPORT_SYMBOL_GPL(arch_invalidate_pmem); #endif diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 90181775ba6d..71a12660f747 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -175,14 +175,21 @@ static void __init reserve_elfcorehdr(void) #endif /* CONFIG_CRASH_DUMP */ /* - * Return the maximum physical address for a zone with a given address size - * limit. It currently assumes that for memory starting above 4G, 32-bit - * devices will use a DMA offset. + * Return the maximum physical address for a zone accessible by the given bits + * limit. If DRAM starts above 32-bit, expand the zone to the maximum + * available memory, otherwise cap it at 32-bit. */ static phys_addr_t __init max_zone_phys(unsigned int zone_bits) { - phys_addr_t offset = memblock_start_of_DRAM() & GENMASK_ULL(63, zone_bits); - return min(offset + (1ULL << zone_bits), memblock_end_of_DRAM()); + phys_addr_t zone_mask = DMA_BIT_MASK(zone_bits); + phys_addr_t phys_start = memblock_start_of_DRAM(); + + if (phys_start > U32_MAX) + zone_mask = PHYS_ADDR_MAX; + else if (phys_start > zone_mask) + zone_mask = U32_MAX; + + return min(zone_mask, memblock_end_of_DRAM() - 1) + 1; } static void __init zone_sizes_init(unsigned long min, unsigned long max) diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 91a21d36d38c..57d4539a7d2c 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -469,6 +469,21 @@ void __init mark_linear_text_alias_ro(void) PAGE_KERNEL_RO); } +static bool crash_mem_map __initdata; + +static int __init enable_crash_mem_map(char *arg) +{ + /* + * Proper parameter parsing is done by reserve_crashkernel(). We only + * need to know if the linear map has to avoid block mappings so that + * the crashkernel reservations can be unmapped later. + */ + crash_mem_map = true; + + return 0; +} +early_param("crashkernel", enable_crash_mem_map); + static void __init map_mem(pgd_t *pgdp) { phys_addr_t kernel_start = __pa_symbol(_text); @@ -477,7 +492,7 @@ static void __init map_mem(pgd_t *pgdp) int flags = 0; u64 i; - if (rodata_full || debug_pagealloc_enabled() || + if (rodata_full || crash_mem_map || debug_pagealloc_enabled() || IS_ENABLED(CONFIG_KFENCE)) flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; @@ -488,11 +503,6 @@ static void __init map_mem(pgd_t *pgdp) * the following for-loop */ memblock_mark_nomap(kernel_start, kernel_end - kernel_start); -#ifdef CONFIG_KEXEC_CORE - if (crashk_res.end) - memblock_mark_nomap(crashk_res.start, - resource_size(&crashk_res)); -#endif /* map all the memory banks */ for_each_mem_range(i, &start, &end) { @@ -520,21 +530,6 @@ static void __init map_mem(pgd_t *pgdp) __map_memblock(pgdp, kernel_start, kernel_end, PAGE_KERNEL, NO_CONT_MAPPINGS); memblock_clear_nomap(kernel_start, kernel_end - kernel_start); - -#ifdef CONFIG_KEXEC_CORE - /* - * Use page-level mappings here so that we can shrink the region - * in page granularity and put back unused memory to buddy system - * through /sys/kernel/kexec_crash_size interface. - */ - if (crashk_res.end) { - __map_memblock(pgdp, crashk_res.start, crashk_res.end + 1, - PAGE_KERNEL, - NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS); - memblock_clear_nomap(crashk_res.start, - resource_size(&crashk_res)); - } -#endif } void mark_rodata_ro(void) diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 715c0f9b54b5..6e175dbbb474 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -179,7 +179,7 @@ SYM_FUNC_END(cpu_do_resume) .pushsection ".idmap.text", "awx" .macro __idmap_cpu_set_reserved_ttbr1, tmp1, tmp2 - adrp \tmp1, empty_zero_page + adrp \tmp1, reserved_pg_dir phys_to_ttbr \tmp2, \tmp1 offset_ttbr1 \tmp2, \tmp1 msr ttbr1_el1, \tmp2 diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index af75d5909a0f..4b5dbde3ff11 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -830,6 +830,19 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, return ret; break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + /* + * Nothing required here. + * + * In case of arm64, we rely on the firmware mitigation of + * Speculative Store Bypass as controlled via the ssbd kernel + * parameter. Whenever the mitigation is enabled, it works + * for all of the kernel code with no need to provide any + * additional instructions. + */ + break; + /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_W: case BPF_ST | BPF_MEM | BPF_H: diff --git a/arch/csky/kernel/smp.c b/arch/csky/kernel/smp.c index 041d0de6a1b6..1a8d7eaf1ff7 100644 --- a/arch/csky/kernel/smp.c +++ b/arch/csky/kernel/smp.c @@ -282,7 +282,6 @@ void csky_start_secondary(void) pr_info("CPU%u Online: %s...\n", cpu, __func__); local_irq_enable(); - preempt_disable(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); } diff --git a/arch/csky/mm/syscache.c b/arch/csky/mm/syscache.c index ffade2f9a4c8..cd847ad62c7e 100644 --- a/arch/csky/mm/syscache.c +++ b/arch/csky/mm/syscache.c @@ -12,14 +12,17 @@ SYSCALL_DEFINE3(cacheflush, int, cache) { switch (cache) { - case ICACHE: case BCACHE: - flush_icache_mm_range(current->mm, - (unsigned long)addr, - (unsigned long)addr + bytes); case DCACHE: dcache_wb_range((unsigned long)addr, (unsigned long)addr + bytes); + if (cache != BCACHE) + break; + fallthrough; + case ICACHE: + flush_icache_mm_range(current->mm, + (unsigned long)addr, + (unsigned long)addr + bytes); break; default: return -EINVAL; diff --git a/arch/hexagon/Makefile b/arch/hexagon/Makefile index c168c6980d05..74b644ea8a00 100644 --- a/arch/hexagon/Makefile +++ b/arch/hexagon/Makefile @@ -10,6 +10,9 @@ LDFLAGS_vmlinux += -G0 # Do not use single-byte enums; these will overflow. KBUILD_CFLAGS += -fno-short-enums +# We must use long-calls: +KBUILD_CFLAGS += -mlong-calls + # Modules must use either long-calls, or use pic/plt. # Use long-calls for now, it's easier. And faster. # KBUILD_CFLAGS_MODULE += -fPIC @@ -30,9 +33,6 @@ TIR_NAME := r19 KBUILD_CFLAGS += -ffixed-$(TIR_NAME) -DTHREADINFO_REG=$(TIR_NAME) -D__linux__ KBUILD_AFLAGS += -DTHREADINFO_REG=$(TIR_NAME) -LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name 2>/dev/null) -libs-y += $(LIBGCC) - head-y := arch/hexagon/kernel/head.o core-y += arch/hexagon/kernel/ \ diff --git a/arch/hexagon/include/asm/futex.h b/arch/hexagon/include/asm/futex.h index 6b9c554aee78..9fb00a0ae89f 100644 --- a/arch/hexagon/include/asm/futex.h +++ b/arch/hexagon/include/asm/futex.h @@ -21,7 +21,7 @@ "3:\n" \ ".section .fixup,\"ax\"\n" \ "4: %1 = #%5;\n" \ - " jump 3b\n" \ + " jump ##3b\n" \ ".previous\n" \ ".section __ex_table,\"a\"\n" \ ".long 1b,4b,2b,4b\n" \ @@ -90,7 +90,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, "3:\n" ".section .fixup,\"ax\"\n" "4: %0 = #%6\n" - " jump 3b\n" + " jump ##3b\n" ".previous\n" ".section __ex_table,\"a\"\n" ".long 1b,4b,2b,4b\n" diff --git a/arch/hexagon/include/asm/timex.h b/arch/hexagon/include/asm/timex.h index 78338d8ada83..8d4ec76fceb4 100644 --- a/arch/hexagon/include/asm/timex.h +++ b/arch/hexagon/include/asm/timex.h @@ -8,6 +8,7 @@ #include #include +#include /* Using TCX0 as our clock. CLOCK_TICK_RATE scheduled to be removed. */ #define CLOCK_TICK_RATE TCX0_CLK_RATE @@ -16,7 +17,7 @@ static inline int read_current_timer(unsigned long *timer_val) { - *timer_val = (unsigned long) __vmgettime(); + *timer_val = __vmgettime(); return 0; } diff --git a/arch/hexagon/kernel/hexagon_ksyms.c b/arch/hexagon/kernel/hexagon_ksyms.c index 6fb1aaab1c29..35545a7386a0 100644 --- a/arch/hexagon/kernel/hexagon_ksyms.c +++ b/arch/hexagon/kernel/hexagon_ksyms.c @@ -35,8 +35,8 @@ EXPORT_SYMBOL(_dflt_cache_att); DECLARE_EXPORT(__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes); /* Additional functions */ -DECLARE_EXPORT(__divsi3); -DECLARE_EXPORT(__modsi3); -DECLARE_EXPORT(__udivsi3); -DECLARE_EXPORT(__umodsi3); +DECLARE_EXPORT(__hexagon_divsi3); +DECLARE_EXPORT(__hexagon_modsi3); +DECLARE_EXPORT(__hexagon_udivsi3); +DECLARE_EXPORT(__hexagon_umodsi3); DECLARE_EXPORT(csum_tcpudp_magic); diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c index a5a89e944257..8975f9b4cedf 100644 --- a/arch/hexagon/kernel/ptrace.c +++ b/arch/hexagon/kernel/ptrace.c @@ -35,7 +35,7 @@ void user_disable_single_step(struct task_struct *child) static int genregs_get(struct task_struct *target, const struct user_regset *regset, - srtuct membuf to) + struct membuf to) { struct pt_regs *regs = task_pt_regs(target); @@ -54,7 +54,7 @@ static int genregs_get(struct task_struct *target, membuf_store(&to, regs->m0); membuf_store(&to, regs->m1); membuf_store(&to, regs->usr); - membuf_store(&to, regs->p3_0); + membuf_store(&to, regs->preds); membuf_store(&to, regs->gp); membuf_store(&to, regs->ugp); membuf_store(&to, pt_elr(regs)); // pc diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S index 35b18e55eae8..57465bff1fe4 100644 --- a/arch/hexagon/kernel/vmlinux.lds.S +++ b/arch/hexagon/kernel/vmlinux.lds.S @@ -38,6 +38,8 @@ SECTIONS .text : AT(ADDR(.text)) { _text = .; TEXT_TEXT + IRQENTRY_TEXT + SOFTIRQENTRY_TEXT SCHED_TEXT CPUIDLE_TEXT LOCK_TEXT @@ -59,14 +61,9 @@ SECTIONS _end = .; - /DISCARD/ : { - EXIT_TEXT - EXIT_DATA - EXIT_CALL - } - STABS_DEBUG DWARF_DEBUG ELF_DETAILS + DISCARDS } diff --git a/arch/hexagon/lib/Makefile b/arch/hexagon/lib/Makefile index 54be529d17a2..a64641e89d5f 100644 --- a/arch/hexagon/lib/Makefile +++ b/arch/hexagon/lib/Makefile @@ -2,4 +2,5 @@ # # Makefile for hexagon-specific library files. # -obj-y = checksum.o io.o memcpy.o memset.o +obj-y = checksum.o io.o memcpy.o memset.o memcpy_likely_aligned.o \ + divsi3.o modsi3.o udivsi3.o umodsi3.o diff --git a/arch/hexagon/lib/divsi3.S b/arch/hexagon/lib/divsi3.S new file mode 100644 index 000000000000..783e09424c2c --- /dev/null +++ b/arch/hexagon/lib/divsi3.S @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include + +SYM_FUNC_START(__hexagon_divsi3) + { + p0 = cmp.gt(r0,#-1) + p1 = cmp.gt(r1,#-1) + r3:2 = vabsw(r1:0) + } + { + p3 = xor(p0,p1) + r4 = sub(r2,r3) + r6 = cl0(r2) + p0 = cmp.gtu(r3,r2) + } + { + r0 = mux(p3,#-1,#1) + r7 = cl0(r3) + p1 = cmp.gtu(r3,r4) + } + { + r0 = mux(p0,#0,r0) + p0 = or(p0,p1) + if (p0.new) jumpr:nt r31 + r6 = sub(r7,r6) + } + { + r7 = r6 + r5:4 = combine(#1,r3) + r6 = add(#1,lsr(r6,#1)) + p0 = cmp.gtu(r6,#4) + } + { + r5:4 = vaslw(r5:4,r7) + if (!p0) r6 = #3 + } + { + loop0(1f,r6) + r7:6 = vlsrw(r5:4,#1) + r1:0 = #0 + } + .falign +1: + { + r5:4 = vlsrw(r5:4,#2) + if (!p0.new) r0 = add(r0,r5) + if (!p0.new) r2 = sub(r2,r4) + p0 = cmp.gtu(r4,r2) + } + { + r7:6 = vlsrw(r7:6,#2) + if (!p0.new) r0 = add(r0,r7) + if (!p0.new) r2 = sub(r2,r6) + p0 = cmp.gtu(r6,r2) + }:endloop0 + { + if (!p0) r0 = add(r0,r7) + } + { + if (p3) r0 = sub(r1,r0) + jumpr r31 + } +SYM_FUNC_END(__hexagon_divsi3) diff --git a/arch/hexagon/lib/memcpy_likely_aligned.S b/arch/hexagon/lib/memcpy_likely_aligned.S new file mode 100644 index 000000000000..6a541fb90a54 --- /dev/null +++ b/arch/hexagon/lib/memcpy_likely_aligned.S @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include + +SYM_FUNC_START(__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes) + { + p0 = bitsclr(r1,#7) + p0 = bitsclr(r0,#7) + if (p0.new) r5:4 = memd(r1) + if (p0.new) r7:6 = memd(r1+#8) + } + { + if (!p0) jump:nt .Lmemcpy_call + if (p0) r9:8 = memd(r1+#16) + if (p0) r11:10 = memd(r1+#24) + p0 = cmp.gtu(r2,#64) + } + { + if (p0) jump:nt .Lmemcpy_call + if (!p0) memd(r0) = r5:4 + if (!p0) memd(r0+#8) = r7:6 + p0 = cmp.gtu(r2,#32) + } + { + p1 = cmp.gtu(r2,#40) + p2 = cmp.gtu(r2,#48) + if (p0) r13:12 = memd(r1+#32) + if (p1.new) r15:14 = memd(r1+#40) + } + { + memd(r0+#16) = r9:8 + memd(r0+#24) = r11:10 + } + { + if (p0) memd(r0+#32) = r13:12 + if (p1) memd(r0+#40) = r15:14 + if (!p2) jumpr:t r31 + } + { + p0 = cmp.gtu(r2,#56) + r5:4 = memd(r1+#48) + if (p0.new) r7:6 = memd(r1+#56) + } + { + memd(r0+#48) = r5:4 + if (p0) memd(r0+#56) = r7:6 + jumpr r31 + } + +.Lmemcpy_call: + jump memcpy + +SYM_FUNC_END(__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes) diff --git a/arch/hexagon/lib/modsi3.S b/arch/hexagon/lib/modsi3.S new file mode 100644 index 000000000000..9ea1c86efac2 --- /dev/null +++ b/arch/hexagon/lib/modsi3.S @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include + +SYM_FUNC_START(__hexagon_modsi3) + { + p2 = cmp.ge(r0,#0) + r2 = abs(r0) + r1 = abs(r1) + } + { + r3 = cl0(r2) + r4 = cl0(r1) + p0 = cmp.gtu(r1,r2) + } + { + r3 = sub(r4,r3) + if (p0) jumpr r31 + } + { + p1 = cmp.eq(r3,#0) + loop0(1f,r3) + r0 = r2 + r2 = lsl(r1,r3) + } + .falign +1: + { + p0 = cmp.gtu(r2,r0) + if (!p0.new) r0 = sub(r0,r2) + r2 = lsr(r2,#1) + if (p1) r1 = #0 + }:endloop0 + { + p0 = cmp.gtu(r2,r0) + if (!p0.new) r0 = sub(r0,r1) + if (p2) jumpr r31 + } + { + r0 = neg(r0) + jumpr r31 + } +SYM_FUNC_END(__hexagon_modsi3) diff --git a/arch/hexagon/lib/udivsi3.S b/arch/hexagon/lib/udivsi3.S new file mode 100644 index 000000000000..477f27b9311c --- /dev/null +++ b/arch/hexagon/lib/udivsi3.S @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include + +SYM_FUNC_START(__hexagon_udivsi3) + { + r2 = cl0(r0) + r3 = cl0(r1) + r5:4 = combine(#1,#0) + p0 = cmp.gtu(r1,r0) + } + { + r6 = sub(r3,r2) + r4 = r1 + r1:0 = combine(r0,r4) + if (p0) jumpr r31 + } + { + r3:2 = vlslw(r5:4,r6) + loop0(1f,r6) + } + .falign +1: + { + p0 = cmp.gtu(r2,r1) + if (!p0.new) r1 = sub(r1,r2) + if (!p0.new) r0 = add(r0,r3) + r3:2 = vlsrw(r3:2,#1) + }:endloop0 + { + p0 = cmp.gtu(r2,r1) + if (!p0.new) r0 = add(r0,r3) + jumpr r31 + } +SYM_FUNC_END(__hexagon_udivsi3) diff --git a/arch/hexagon/lib/umodsi3.S b/arch/hexagon/lib/umodsi3.S new file mode 100644 index 000000000000..280bf06a55e7 --- /dev/null +++ b/arch/hexagon/lib/umodsi3.S @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include + +SYM_FUNC_START(__hexagon_umodsi3) + { + r2 = cl0(r0) + r3 = cl0(r1) + p0 = cmp.gtu(r1,r0) + } + { + r2 = sub(r3,r2) + if (p0) jumpr r31 + } + { + loop0(1f,r2) + p1 = cmp.eq(r2,#0) + r2 = lsl(r1,r2) + } + .falign +1: + { + p0 = cmp.gtu(r2,r0) + if (!p0.new) r0 = sub(r0,r2) + r2 = lsr(r2,#1) + if (p1) r1 = #0 + }:endloop0 + { + p0 = cmp.gtu(r2,r0) + if (!p0.new) r0 = sub(r0,r1) + jumpr r31 + } +SYM_FUNC_END(__hexagon_umodsi3) diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h index 779b6972aa84..9f64fdfbf275 100644 --- a/arch/ia64/include/asm/pgtable.h +++ b/arch/ia64/include/asm/pgtable.h @@ -520,8 +520,9 @@ extern struct page *zero_page_memmap_ptr; # ifdef CONFIG_VIRTUAL_MEM_MAP /* arch mem_map init routine is needed due to holes in a virtual mem_map */ - extern void memmap_init (unsigned long size, int nid, unsigned long zone, - unsigned long start_pfn); +void memmap_init(void); +void arch_memmap_init(unsigned long size, int nid, unsigned long zone, + unsigned long start_pfn); # endif /* CONFIG_VIRTUAL_MEM_MAP */ # endif /* !__ASSEMBLY__ */ diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 4d0ab323dee8..2a40268c3d49 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c @@ -343,7 +343,7 @@ init_record_index_pools(void) /* - 2 - */ sect_min_size = sal_log_sect_min_sizes[0]; - for (i = 1; i < sizeof sal_log_sect_min_sizes/sizeof(size_t); i++) + for (i = 1; i < ARRAY_SIZE(sal_log_sect_min_sizes); i++) if (sect_min_size > sal_log_sect_min_sizes[i]) sect_min_size = sal_log_sect_min_sizes[i]; diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 093040f7e626..0cad990385c0 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -440,7 +440,6 @@ start_secondary (void *unused) #endif efi_map_pal_code(); cpu_init(); - preempt_disable(); smp_callin(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 27ca549ff47e..f316a833b703 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -542,7 +542,7 @@ virtual_memmap_init(u64 start, u64 end, void *arg) } void __meminit -memmap_init (unsigned long size, int nid, unsigned long zone, +arch_memmap_init (unsigned long size, int nid, unsigned long zone, unsigned long start_pfn) { if (!vmem_map) { @@ -562,6 +562,10 @@ memmap_init (unsigned long size, int nid, unsigned long zone, } } +void __init memmap_init(void) +{ +} + int ia64_pfn_valid (unsigned long pfn) { diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine index 17e8c3a292d7..e161a4e1493b 100644 --- a/arch/m68k/Kconfig.machine +++ b/arch/m68k/Kconfig.machine @@ -23,6 +23,9 @@ config ATARI this kernel on an Atari, say Y here and browse the material available in ; otherwise say N. +config ATARI_KBD_CORE + bool + config MAC bool "Macintosh support" depends on MMU diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1917ccd39256..1a63f592034e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -418,6 +418,8 @@ config MACH_INGENIC_SOC select MIPS_GENERIC select MACH_INGENIC select SYS_SUPPORTS_ZBOOT_UART16550 + select CPU_SUPPORTS_CPUFREQ + select MIPS_EXTERNAL_TIMER config LANTIQ bool "Lantiq based platforms" diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 686990fcc5f0..acab8018ab44 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -320,7 +320,7 @@ KBUILD_LDFLAGS += -m $(ld-emul) ifdef CONFIG_MIPS CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ - egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ + egrep -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') endif diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile index 337ab1d18cc1..eae0fad30f27 100644 --- a/arch/mips/boot/compressed/Makefile +++ b/arch/mips/boot/compressed/Makefile @@ -39,7 +39,7 @@ KCOV_INSTRUMENT := n UBSAN_SANITIZE := n # decompressor objects (linked with vmlinuz) -vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o +vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/string.o $(obj)/bswapsi.o ifdef CONFIG_DEBUG_ZBOOT vmlinuzobjs-$(CONFIG_DEBUG_ZBOOT) += $(obj)/dbg.o @@ -53,7 +53,7 @@ extra-y += uart-ath79.c $(obj)/uart-ath79.c: $(srctree)/arch/mips/ath79/early_printk.c $(call cmd,shipped) -vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o $(obj)/bswapsi.o +vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o extra-y += ashldi3.c $(obj)/ashldi3.c: $(obj)/%.c: $(srctree)/lib/%.c FORCE diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c index e3946b06e840..1e91155bed80 100644 --- a/arch/mips/boot/compressed/decompress.c +++ b/arch/mips/boot/compressed/decompress.c @@ -7,6 +7,8 @@ * Author: Wu Zhangjin */ +#define DISABLE_BRANCH_PROFILING + #include #include #include diff --git a/arch/mips/generic/board-boston.its.S b/arch/mips/generic/board-boston.its.S index a7f51f97b910..c45ad2759421 100644 --- a/arch/mips/generic/board-boston.its.S +++ b/arch/mips/generic/board-boston.its.S @@ -1,22 +1,22 @@ / { images { - fdt@boston { + fdt-boston { description = "img,boston Device Tree"; data = /incbin/("boot/dts/img/boston.dtb"); type = "flat_dt"; arch = "mips"; compression = "none"; - hash@0 { + hash { algo = "sha1"; }; }; }; configurations { - conf@boston { + conf-boston { description = "Boston Linux kernel"; - kernel = "kernel@0"; - fdt = "fdt@boston"; + kernel = "kernel"; + fdt = "fdt-boston"; }; }; }; diff --git a/arch/mips/generic/board-ni169445.its.S b/arch/mips/generic/board-ni169445.its.S index e4cb4f95a8cc..0a2e8f7a8526 100644 --- a/arch/mips/generic/board-ni169445.its.S +++ b/arch/mips/generic/board-ni169445.its.S @@ -1,22 +1,22 @@ / { images { - fdt@ni169445 { + fdt-ni169445 { description = "NI 169445 device tree"; data = /incbin/("boot/dts/ni/169445.dtb"); type = "flat_dt"; arch = "mips"; compression = "none"; - hash@0 { + hash { algo = "sha1"; }; }; }; configurations { - conf@ni169445 { + conf-ni169445 { description = "NI 169445 Linux Kernel"; - kernel = "kernel@0"; - fdt = "fdt@ni169445"; + kernel = "kernel"; + fdt = "fdt-ni169445"; }; }; }; diff --git a/arch/mips/generic/board-ocelot.its.S b/arch/mips/generic/board-ocelot.its.S index 3da23988149a..8c7e3a1b68d3 100644 --- a/arch/mips/generic/board-ocelot.its.S +++ b/arch/mips/generic/board-ocelot.its.S @@ -1,40 +1,40 @@ /* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ / { images { - fdt@ocelot_pcb123 { + fdt-ocelot_pcb123 { description = "MSCC Ocelot PCB123 Device Tree"; data = /incbin/("boot/dts/mscc/ocelot_pcb123.dtb"); type = "flat_dt"; arch = "mips"; compression = "none"; - hash@0 { + hash { algo = "sha1"; }; }; - fdt@ocelot_pcb120 { + fdt-ocelot_pcb120 { description = "MSCC Ocelot PCB120 Device Tree"; data = /incbin/("boot/dts/mscc/ocelot_pcb120.dtb"); type = "flat_dt"; arch = "mips"; compression = "none"; - hash@0 { + hash { algo = "sha1"; }; }; }; configurations { - conf@ocelot_pcb123 { + conf-ocelot_pcb123 { description = "Ocelot Linux kernel"; - kernel = "kernel@0"; - fdt = "fdt@ocelot_pcb123"; + kernel = "kernel"; + fdt = "fdt-ocelot_pcb123"; }; - conf@ocelot_pcb120 { + conf-ocelot_pcb120 { description = "Ocelot Linux kernel"; - kernel = "kernel@0"; - fdt = "fdt@ocelot_pcb120"; + kernel = "kernel"; + fdt = "fdt-ocelot_pcb120"; }; }; }; diff --git a/arch/mips/generic/board-xilfpga.its.S b/arch/mips/generic/board-xilfpga.its.S index a2e773d3f14f..08c1e900eb4e 100644 --- a/arch/mips/generic/board-xilfpga.its.S +++ b/arch/mips/generic/board-xilfpga.its.S @@ -1,22 +1,22 @@ / { images { - fdt@xilfpga { + fdt-xilfpga { description = "MIPSfpga (xilfpga) Device Tree"; data = /incbin/("boot/dts/xilfpga/nexys4ddr.dtb"); type = "flat_dt"; arch = "mips"; compression = "none"; - hash@0 { + hash { algo = "sha1"; }; }; }; configurations { - conf@xilfpga { + conf-xilfpga { description = "MIPSfpga Linux kernel"; - kernel = "kernel@0"; - fdt = "fdt@xilfpga"; + kernel = "kernel"; + fdt = "fdt-xilfpga"; }; }; }; diff --git a/arch/mips/generic/vmlinux.its.S b/arch/mips/generic/vmlinux.its.S index 1a08438fd893..3e254676540f 100644 --- a/arch/mips/generic/vmlinux.its.S +++ b/arch/mips/generic/vmlinux.its.S @@ -6,7 +6,7 @@ #address-cells = ; images { - kernel@0 { + kernel { description = KERNEL_NAME; data = /incbin/(VMLINUX_BINARY); type = "kernel"; @@ -15,18 +15,18 @@ compression = VMLINUX_COMPRESSION; load = /bits/ ADDR_BITS ; entry = /bits/ ADDR_BITS ; - hash@0 { + hash { algo = "sha1"; }; }; }; configurations { - default = "conf@default"; + default = "conf-default"; - conf@default { + conf-default { description = "Generic Linux kernel"; - kernel = "kernel@0"; + kernel = "kernel"; }; }; }; diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index f2e216eef7da..8294eaa6f902 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h @@ -64,6 +64,8 @@ ((MIPS_ISA_REV >= (ge)) && (MIPS_ISA_REV < (lt))) #define __isa_range_or_flag(ge, lt, flag) \ (__isa_range(ge, lt) || ((MIPS_ISA_REV < (lt)) && __isa(flag))) +#define __isa_range_and_ase(ge, lt, ase) \ + (__isa_range(ge, lt) && __ase(ase)) /* * SMP assumption: Options of CPU 0 are a superset of all processors. @@ -423,7 +425,7 @@ #endif #ifndef cpu_has_mipsmt -#define cpu_has_mipsmt __isa_lt_and_ase(6, MIPS_ASE_MIPSMT) +#define cpu_has_mipsmt __isa_range_and_ase(2, 6, MIPS_ASE_MIPSMT) #endif #ifndef cpu_has_vp diff --git a/arch/mips/include/asm/highmem.h b/arch/mips/include/asm/highmem.h index f1f788b57166..9f021cf51aa7 100644 --- a/arch/mips/include/asm/highmem.h +++ b/arch/mips/include/asm/highmem.h @@ -36,7 +36,7 @@ extern pte_t *pkmap_page_table; * easily, subsequent pte tables have to be allocated in one physical * chunk of RAM. */ -#ifdef CONFIG_PHYS_ADDR_T_64BIT +#if defined(CONFIG_PHYS_ADDR_T_64BIT) || defined(CONFIG_MIPS_HUGE_TLB_SUPPORT) #define LAST_PKMAP 512 #else #define LAST_PKMAP 1024 diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h index 10e3be870df7..c2144409c0c4 100644 --- a/arch/mips/include/asm/hugetlb.h +++ b/arch/mips/include/asm/hugetlb.h @@ -46,7 +46,13 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { - flush_tlb_page(vma, addr & huge_page_mask(hstate_vma(vma))); + /* + * clear the huge pte entry firstly, so that the other smp threads will + * not get old pte entry after finishing flush_tlb_page and before + * setting new huge pte entry + */ + huge_ptep_get_and_clear(vma->vm_mm, addr, ptep); + flush_tlb_page(vma, addr); } #define __HAVE_ARCH_HUGE_PTE_NONE diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index a0e8ae5497b6..7a7467d3f7f0 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -2073,7 +2073,7 @@ _ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c) ({ int __res; \ __asm__ __volatile__( \ ".set\tpush\n\t" \ - ".set\tmips32r2\n\t" \ + ".set\tmips32r5\n\t" \ _ASM_SET_VIRT \ "mfgc0\t%0, " #source ", %1\n\t" \ ".set\tpop" \ @@ -2086,7 +2086,7 @@ _ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c) ({ unsigned long long __res; \ __asm__ __volatile__( \ ".set\tpush\n\t" \ - ".set\tmips64r2\n\t" \ + ".set\tmips64r5\n\t" \ _ASM_SET_VIRT \ "dmfgc0\t%0, " #source ", %1\n\t" \ ".set\tpop" \ @@ -2099,7 +2099,7 @@ _ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c) do { \ __asm__ __volatile__( \ ".set\tpush\n\t" \ - ".set\tmips32r2\n\t" \ + ".set\tmips32r5\n\t" \ _ASM_SET_VIRT \ "mtgc0\t%z0, " #register ", %1\n\t" \ ".set\tpop" \ @@ -2111,7 +2111,7 @@ do { \ do { \ __asm__ __volatile__( \ ".set\tpush\n\t" \ - ".set\tmips64r2\n\t" \ + ".set\tmips64r5\n\t" \ _ASM_SET_VIRT \ "dmtgc0\t%z0, " #register ", %1\n\t" \ ".set\tpop" \ diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h index 8b18424b3120..139b4050259f 100644 --- a/arch/mips/include/asm/pgalloc.h +++ b/arch/mips/include/asm/pgalloc.h @@ -60,10 +60,19 @@ do { \ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) { pmd_t *pmd; + struct page *pg; - pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, PMD_ORDER); - if (pmd) - pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table); + pg = alloc_pages(GFP_KERNEL_ACCOUNT, PMD_ORDER); + if (!pg) + return NULL; + + if (!pgtable_pmd_page_ctor(pg)) { + __free_pages(pg, PMD_ORDER); + return NULL; + } + + pmd = (pmd_t *)page_address(pg); + pmd_init((unsigned long)pmd, (unsigned long)invalid_pte_table); return pmd; } diff --git a/arch/mips/include/asm/vdso/vdso.h b/arch/mips/include/asm/vdso/vdso.h index 737ddfc3411c..a327ca21270e 100644 --- a/arch/mips/include/asm/vdso/vdso.h +++ b/arch/mips/include/asm/vdso/vdso.h @@ -67,7 +67,7 @@ static inline const struct vdso_data *get_vdso_data(void) static inline void __iomem *get_gic(const struct vdso_data *data) { - return (void __iomem *)data - PAGE_SIZE; + return (void __iomem *)((unsigned long)data & PAGE_MASK) - PAGE_SIZE; } #endif /* CONFIG_CLKSRC_MIPS_GIC */ diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index e6ae2bcdbeda..067cb3eb1614 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1827,6 +1827,11 @@ static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu) */ case PRID_COMP_INGENIC_D0: c->isa_level &= ~MIPS_CPU_ISA_M32R2; + + /* FPU is not properly detected on JZ4760(B). */ + if (c->processor_id == 0x2ed0024f) + c->options |= MIPS_CPU_FPU; + fallthrough; /* diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 48d84d5fcc36..ff25926c5458 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -348,7 +348,6 @@ asmlinkage void start_secondary(void) */ calibrate_delay(); - preempt_disable(); cpu = smp_processor_id(); cpu_data[cpu].udelay_val = loops_per_jiffy; diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c index de03838b343b..a9b72eacfc0b 100644 --- a/arch/mips/lib/mips-atomic.c +++ b/arch/mips/lib/mips-atomic.c @@ -37,7 +37,7 @@ */ notrace void arch_local_irq_disable(void) { - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -53,7 +53,7 @@ notrace void arch_local_irq_disable(void) : /* no inputs */ : "memory"); - preempt_enable(); + preempt_enable_notrace(); } EXPORT_SYMBOL(arch_local_irq_disable); @@ -61,7 +61,7 @@ notrace unsigned long arch_local_irq_save(void) { unsigned long flags; - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -78,7 +78,7 @@ notrace unsigned long arch_local_irq_save(void) : /* no inputs */ : "memory"); - preempt_enable(); + preempt_enable_notrace(); return flags; } @@ -88,7 +88,7 @@ notrace void arch_local_irq_restore(unsigned long flags) { unsigned long __tmp1; - preempt_disable(); + preempt_disable_notrace(); __asm__ __volatile__( " .set push \n" @@ -106,7 +106,7 @@ notrace void arch_local_irq_restore(unsigned long flags) : "0" (flags) : "memory"); - preempt_enable(); + preempt_enable_notrace(); } EXPORT_SYMBOL(arch_local_irq_restore); diff --git a/arch/mips/loongson64/numa.c b/arch/mips/loongson64/numa.c index cf9459f79f9b..e4c461df3ee6 100644 --- a/arch/mips/loongson64/numa.c +++ b/arch/mips/loongson64/numa.c @@ -182,6 +182,9 @@ static void __init node_mem_init(unsigned int node) if (node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) memblock_reserve((node_addrspace_offset | 0xfe000000), 32 << 20); + + /* Reserve pfn range 0~node[0]->node_start_pfn */ + memblock_reserve(0, PAGE_SIZE * start_pfn); } } diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index 11e9527c6e44..62ffac500eb5 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c @@ -47,7 +47,8 @@ static struct plat_serial8250_port uart8250_data[] = { .mapbase = 0x1f000900, /* The CBUS UART */ .irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB2, .uartclk = 3686400, /* Twice the usual clk! */ - .iotype = UPIO_MEM32, + .iotype = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) ? + UPIO_MEM32BE : UPIO_MEM32, .flags = CBUS_UART_FLAGS, .regshift = 3, }, diff --git a/arch/mips/net/ebpf_jit.c b/arch/mips/net/ebpf_jit.c index 561154cbcc40..b31b91e57c34 100644 --- a/arch/mips/net/ebpf_jit.c +++ b/arch/mips/net/ebpf_jit.c @@ -1355,6 +1355,9 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, } break; + case BPF_ST | BPF_NOSPEC: /* speculation barrier */ + break; + case BPF_ST | BPF_B | BPF_MEM: case BPF_ST | BPF_H | BPF_MEM: case BPF_ST | BPF_W | BPF_MEM: diff --git a/arch/nds32/mm/mmap.c b/arch/nds32/mm/mmap.c index c206b31ce07a..1bdf5e7d1b43 100644 --- a/arch/nds32/mm/mmap.c +++ b/arch/nds32/mm/mmap.c @@ -59,7 +59,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, vma = find_vma(mm, addr); if (TASK_SIZE - len >= addr && - (!vma || addr + len <= vma->vm_start)) + (!vma || addr + len <= vm_start_gap(vma))) return addr; } diff --git a/arch/openrisc/kernel/smp.c b/arch/openrisc/kernel/smp.c index 29c82ef2e207..e4dad76066ae 100644 --- a/arch/openrisc/kernel/smp.c +++ b/arch/openrisc/kernel/smp.c @@ -134,8 +134,6 @@ asmlinkage __init void secondary_start_kernel(void) set_cpu_online(cpu, true); local_irq_enable(); - - preempt_disable(); /* * OK, it's off to the idle thread for us */ diff --git a/arch/parisc/include/asm/string.h b/arch/parisc/include/asm/string.h index 4a0c9dbd62fd..f6e1132f4e35 100644 --- a/arch/parisc/include/asm/string.h +++ b/arch/parisc/include/asm/string.h @@ -8,19 +8,4 @@ extern void * memset(void *, int, size_t); #define __HAVE_ARCH_MEMCPY void * memcpy(void * dest,const void *src,size_t count); -#define __HAVE_ARCH_STRLEN -extern size_t strlen(const char *s); - -#define __HAVE_ARCH_STRCPY -extern char *strcpy(char *dest, const char *src); - -#define __HAVE_ARCH_STRNCPY -extern char *strncpy(char *dest, const char *src, size_t count); - -#define __HAVE_ARCH_STRCAT -extern char *strcat(char *dest, const char *src); - -#define __HAVE_ARCH_MEMSET -extern void *memset(void *, int, size_t); - #endif diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 8ed409ecec93..e8a6a751dfd8 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -17,10 +17,6 @@ #include EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(strlen); -EXPORT_SYMBOL(strcpy); -EXPORT_SYMBOL(strncpy); -EXPORT_SYMBOL(strcat); #include EXPORT_SYMBOL(__xchg8); diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c index 10227f667c8a..1405b603b91b 100644 --- a/arch/parisc/kernel/smp.c +++ b/arch/parisc/kernel/smp.c @@ -302,7 +302,6 @@ void __init smp_callin(unsigned long pdce_proc) #endif smp_cpu_init(slave_id); - preempt_disable(); flush_cache_all_local(); /* start with known state */ flush_tlb_all_local(NULL); diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile index 2d7a9974dbae..7b197667faf6 100644 --- a/arch/parisc/lib/Makefile +++ b/arch/parisc/lib/Makefile @@ -3,7 +3,7 @@ # Makefile for parisc-specific library files # -lib-y := lusercopy.o bitops.o checksum.o io.o memcpy.o \ - ucmpdi2.o delay.o string.o +lib-y := lusercopy.o bitops.o checksum.o io.o memset.o memcpy.o \ + ucmpdi2.o delay.o obj-y := iomap.o diff --git a/arch/parisc/lib/memset.c b/arch/parisc/lib/memset.c new file mode 100644 index 000000000000..133e4809859a --- /dev/null +++ b/arch/parisc/lib/memset.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#include +#include + +#define OPSIZ (BITS_PER_LONG/8) +typedef unsigned long op_t; + +void * +memset (void *dstpp, int sc, size_t len) +{ + unsigned int c = sc; + long int dstp = (long int) dstpp; + + if (len >= 8) + { + size_t xlen; + op_t cccc; + + cccc = (unsigned char) c; + cccc |= cccc << 8; + cccc |= cccc << 16; + if (OPSIZ > 4) + /* Do the shift in two steps to avoid warning if long has 32 bits. */ + cccc |= (cccc << 16) << 16; + + /* There are at least some bytes to set. + No need to test for LEN == 0 in this alignment loop. */ + while (dstp % OPSIZ != 0) + { + ((unsigned char *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + /* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */ + xlen = len / (OPSIZ * 8); + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + ((op_t *) dstp)[1] = cccc; + ((op_t *) dstp)[2] = cccc; + ((op_t *) dstp)[3] = cccc; + ((op_t *) dstp)[4] = cccc; + ((op_t *) dstp)[5] = cccc; + ((op_t *) dstp)[6] = cccc; + ((op_t *) dstp)[7] = cccc; + dstp += 8 * OPSIZ; + xlen -= 1; + } + len %= OPSIZ * 8; + + /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */ + xlen = len / OPSIZ; + while (xlen > 0) + { + ((op_t *) dstp)[0] = cccc; + dstp += OPSIZ; + xlen -= 1; + } + len %= OPSIZ; + } + + /* Write the last few bytes. */ + while (len > 0) + { + ((unsigned char *) dstp)[0] = c; + dstp += 1; + len -= 1; + } + + return dstpp; +} diff --git a/arch/parisc/lib/string.S b/arch/parisc/lib/string.S deleted file mode 100644 index 4a64264427a6..000000000000 --- a/arch/parisc/lib/string.S +++ /dev/null @@ -1,136 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * PA-RISC assembly string functions - * - * Copyright (C) 2019 Helge Deller - */ - -#include -#include - - .section .text.hot - .level PA_ASM_LEVEL - - t0 = r20 - t1 = r21 - t2 = r22 - -ENTRY_CFI(strlen, frame=0,no_calls) - or,COND(<>) arg0,r0,ret0 - b,l,n .Lstrlen_null_ptr,r0 - depwi 0,31,2,ret0 - cmpb,COND(<>) arg0,ret0,.Lstrlen_not_aligned - ldw,ma 4(ret0),t0 - cmpib,tr 0,r0,.Lstrlen_loop - uxor,nbz r0,t0,r0 -.Lstrlen_not_aligned: - uaddcm arg0,ret0,t1 - shladd t1,3,r0,t1 - mtsar t1 - depwi -1,%sar,32,t0 - uxor,nbz r0,t0,r0 -.Lstrlen_loop: - b,l,n .Lstrlen_end_loop,r0 - ldw,ma 4(ret0),t0 - cmpib,tr 0,r0,.Lstrlen_loop - uxor,nbz r0,t0,r0 -.Lstrlen_end_loop: - extrw,u,<> t0,7,8,r0 - addib,tr,n -3,ret0,.Lstrlen_out - extrw,u,<> t0,15,8,r0 - addib,tr,n -2,ret0,.Lstrlen_out - extrw,u,<> t0,23,8,r0 - addi -1,ret0,ret0 -.Lstrlen_out: - bv r0(rp) - uaddcm ret0,arg0,ret0 -.Lstrlen_null_ptr: - bv,n r0(rp) -ENDPROC_CFI(strlen) - - -ENTRY_CFI(strcpy, frame=0,no_calls) - ldb 0(arg1),t0 - stb t0,0(arg0) - ldo 0(arg0),ret0 - ldo 1(arg1),t1 - cmpb,= r0,t0,2f - ldo 1(arg0),t2 -1: ldb 0(t1),arg1 - stb arg1,0(t2) - ldo 1(t1),t1 - cmpb,<> r0,arg1,1b - ldo 1(t2),t2 -2: bv,n r0(rp) -ENDPROC_CFI(strcpy) - - -ENTRY_CFI(strncpy, frame=0,no_calls) - ldb 0(arg1),t0 - stb t0,0(arg0) - ldo 1(arg1),t1 - ldo 0(arg0),ret0 - cmpb,= r0,t0,2f - ldo 1(arg0),arg1 -1: ldo -1(arg2),arg2 - cmpb,COND(=),n r0,arg2,2f - ldb 0(t1),arg0 - stb arg0,0(arg1) - ldo 1(t1),t1 - cmpb,<> r0,arg0,1b - ldo 1(arg1),arg1 -2: bv,n r0(rp) -ENDPROC_CFI(strncpy) - - -ENTRY_CFI(strcat, frame=0,no_calls) - ldb 0(arg0),t0 - cmpb,= t0,r0,2f - ldo 0(arg0),ret0 - ldo 1(arg0),arg0 -1: ldb 0(arg0),t1 - cmpb,<>,n r0,t1,1b - ldo 1(arg0),arg0 -2: ldb 0(arg1),t2 - stb t2,0(arg0) - ldo 1(arg0),arg0 - ldb 0(arg1),t0 - cmpb,<> r0,t0,2b - ldo 1(arg1),arg1 - bv,n r0(rp) -ENDPROC_CFI(strcat) - - -ENTRY_CFI(memset, frame=0,no_calls) - copy arg0,ret0 - cmpb,COND(=) r0,arg0,4f - copy arg0,t2 - cmpb,COND(=) r0,arg2,4f - ldo -1(arg2),arg3 - subi -1,arg3,t0 - subi 0,t0,t1 - cmpiclr,COND(>=) 0,t1,arg2 - ldo -1(t1),arg2 - extru arg2,31,2,arg0 -2: stb arg1,0(t2) - ldo 1(t2),t2 - addib,>= -1,arg0,2b - ldo -1(arg3),arg3 - cmpiclr,COND(<=) 4,arg2,r0 - b,l,n 4f,r0 -#ifdef CONFIG_64BIT - depd,* r0,63,2,arg2 -#else - depw r0,31,2,arg2 -#endif - ldo 1(t2),t2 -3: stb arg1,-1(t2) - stb arg1,0(t2) - stb arg1,1(t2) - stb arg1,2(t2) - addib,COND(>) -4,arg2,3b - ldo 4(t2),t2 -4: bv,n r0(rp) -ENDPROC_CFI(memset) - - .end diff --git a/arch/powerpc/boot/devtree.c b/arch/powerpc/boot/devtree.c index 5d91036ad626..58fbcfcc98c9 100644 --- a/arch/powerpc/boot/devtree.c +++ b/arch/powerpc/boot/devtree.c @@ -13,6 +13,7 @@ #include "string.h" #include "stdio.h" #include "ops.h" +#include "of.h" void dt_fixup_memory(u64 start, u64 size) { @@ -23,21 +24,25 @@ void dt_fixup_memory(u64 start, u64 size) root = finddevice("/"); if (getprop(root, "#address-cells", &naddr, sizeof(naddr)) < 0) naddr = 2; + else + naddr = be32_to_cpu(naddr); if (naddr < 1 || naddr > 2) fatal("Can't cope with #address-cells == %d in /\n\r", naddr); if (getprop(root, "#size-cells", &nsize, sizeof(nsize)) < 0) nsize = 1; + else + nsize = be32_to_cpu(nsize); if (nsize < 1 || nsize > 2) fatal("Can't cope with #size-cells == %d in /\n\r", nsize); i = 0; if (naddr == 2) - memreg[i++] = start >> 32; - memreg[i++] = start & 0xffffffff; + memreg[i++] = cpu_to_be32(start >> 32); + memreg[i++] = cpu_to_be32(start & 0xffffffff); if (nsize == 2) - memreg[i++] = size >> 32; - memreg[i++] = size & 0xffffffff; + memreg[i++] = cpu_to_be32(size >> 32); + memreg[i++] = cpu_to_be32(size & 0xffffffff); memory = finddevice("/memory"); if (! memory) { @@ -45,9 +50,9 @@ void dt_fixup_memory(u64 start, u64 size) setprop_str(memory, "device_type", "memory"); } - printf("Memory <- <0x%x", memreg[0]); + printf("Memory <- <0x%x", be32_to_cpu(memreg[0])); for (i = 1; i < (naddr + nsize); i++) - printf(" 0x%x", memreg[i]); + printf(" 0x%x", be32_to_cpu(memreg[i])); printf("> (%ldMB)\n\r", (unsigned long)(size >> 20)); setprop(memory, "reg", memreg, (naddr + nsize)*sizeof(u32)); @@ -65,10 +70,10 @@ void dt_fixup_cpu_clocks(u32 cpu, u32 tb, u32 bus) printf("CPU bus-frequency <- 0x%x (%dMHz)\n\r", bus, MHZ(bus)); while ((devp = find_node_by_devtype(devp, "cpu"))) { - setprop_val(devp, "clock-frequency", cpu); - setprop_val(devp, "timebase-frequency", tb); + setprop_val(devp, "clock-frequency", cpu_to_be32(cpu)); + setprop_val(devp, "timebase-frequency", cpu_to_be32(tb)); if (bus > 0) - setprop_val(devp, "bus-frequency", bus); + setprop_val(devp, "bus-frequency", cpu_to_be32(bus)); } timebase_period_ns = 1000000000 / tb; @@ -80,7 +85,7 @@ void dt_fixup_clock(const char *path, u32 freq) if (devp) { printf("%s: clock-frequency <- %x (%dMHz)\n\r", path, freq, MHZ(freq)); - setprop_val(devp, "clock-frequency", freq); + setprop_val(devp, "clock-frequency", cpu_to_be32(freq)); } } @@ -133,8 +138,12 @@ void dt_get_reg_format(void *node, u32 *naddr, u32 *nsize) { if (getprop(node, "#address-cells", naddr, 4) != 4) *naddr = 2; + else + *naddr = be32_to_cpu(*naddr); if (getprop(node, "#size-cells", nsize, 4) != 4) *nsize = 1; + else + *nsize = be32_to_cpu(*nsize); } static void copy_val(u32 *dest, u32 *src, int naddr) @@ -163,9 +172,9 @@ static int add_reg(u32 *reg, u32 *add, int naddr) int i, carry = 0; for (i = MAX_ADDR_CELLS - 1; i >= MAX_ADDR_CELLS - naddr; i--) { - u64 tmp = (u64)reg[i] + add[i] + carry; + u64 tmp = (u64)be32_to_cpu(reg[i]) + be32_to_cpu(add[i]) + carry; carry = tmp >> 32; - reg[i] = (u32)tmp; + reg[i] = cpu_to_be32((u32)tmp); } return !carry; @@ -180,18 +189,18 @@ static int compare_reg(u32 *reg, u32 *range, u32 *rangesize) u32 end; for (i = 0; i < MAX_ADDR_CELLS; i++) { - if (reg[i] < range[i]) + if (be32_to_cpu(reg[i]) < be32_to_cpu(range[i])) return 0; - if (reg[i] > range[i]) + if (be32_to_cpu(reg[i]) > be32_to_cpu(range[i])) break; } for (i = 0; i < MAX_ADDR_CELLS; i++) { - end = range[i] + rangesize[i]; + end = be32_to_cpu(range[i]) + be32_to_cpu(rangesize[i]); - if (reg[i] < end) + if (be32_to_cpu(reg[i]) < end) break; - if (reg[i] > end) + if (be32_to_cpu(reg[i]) > end) return 0; } @@ -240,7 +249,6 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, return 0; dt_get_reg_format(parent, &naddr, &nsize); - if (nsize > 2) return 0; @@ -252,10 +260,10 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, copy_val(last_addr, prop_buf + offset, naddr); - ret_size = prop_buf[offset + naddr]; + ret_size = be32_to_cpu(prop_buf[offset + naddr]); if (nsize == 2) { ret_size <<= 32; - ret_size |= prop_buf[offset + naddr + 1]; + ret_size |= be32_to_cpu(prop_buf[offset + naddr + 1]); } for (;;) { @@ -278,7 +286,6 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, offset = find_range(last_addr, prop_buf, prev_naddr, naddr, prev_nsize, buflen / 4); - if (offset < 0) return 0; @@ -296,8 +303,7 @@ static int dt_xlate(void *node, int res, int reglen, unsigned long *addr, if (naddr > 2) return 0; - ret_addr = ((u64)last_addr[2] << 32) | last_addr[3]; - + ret_addr = ((u64)be32_to_cpu(last_addr[2]) << 32) | be32_to_cpu(last_addr[3]); if (sizeof(void *) == 4 && (ret_addr >= 0x100000000ULL || ret_size > 0x100000000ULL || ret_addr + ret_size > 0x100000000ULL)) @@ -350,11 +356,14 @@ int dt_is_compatible(void *node, const char *compat) int dt_get_virtual_reg(void *node, void **addr, int nres) { unsigned long xaddr; - int n; + int n, i; n = getprop(node, "virtual-reg", addr, nres * 4); - if (n > 0) + if (n > 0) { + for (i = 0; i < n/4; i ++) + ((u32 *)addr)[i] = be32_to_cpu(((u32 *)addr)[i]); return n / 4; + } for (n = 0; n < nres; n++) { if (!dt_xlate_reg(node, n, &xaddr, NULL)) diff --git a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi index 1b4aafc1f6a2..9716a0484ecf 100644 --- a/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p1010si-post.dtsi @@ -122,7 +122,15 @@ }; /include/ "pq3-i2c-0.dtsi" + i2c@3000 { + fsl,i2c-erratum-a004447; + }; + /include/ "pq3-i2c-1.dtsi" + i2c@3100 { + fsl,i2c-erratum-a004447; + }; + /include/ "pq3-duart-0.dtsi" /include/ "pq3-espi-0.dtsi" spi0: spi@7000 { diff --git a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi index 872e4485dc3f..ddc018d42252 100644 --- a/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2041si-post.dtsi @@ -371,7 +371,23 @@ }; /include/ "qoriq-i2c-0.dtsi" + i2c@118000 { + fsl,i2c-erratum-a004447; + }; + + i2c@118100 { + fsl,i2c-erratum-a004447; + }; + /include/ "qoriq-i2c-1.dtsi" + i2c@119000 { + fsl,i2c-erratum-a004447; + }; + + i2c@119100 { + fsl,i2c-erratum-a004447; + }; + /include/ "qoriq-duart-0.dtsi" /include/ "qoriq-duart-1.dtsi" /include/ "qoriq-gpio-0.dtsi" diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c index b0da4466d419..f16d2be1d0f3 100644 --- a/arch/powerpc/boot/ns16550.c +++ b/arch/powerpc/boot/ns16550.c @@ -15,6 +15,7 @@ #include "stdio.h" #include "io.h" #include "ops.h" +#include "of.h" #define UART_DLL 0 /* Out: Divisor Latch Low */ #define UART_DLM 1 /* Out: Divisor Latch High */ @@ -58,16 +59,20 @@ int ns16550_console_init(void *devp, struct serial_console_data *scdp) int n; u32 reg_offset; - if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) + if (dt_get_virtual_reg(devp, (void **)®_base, 1) < 1) { + printf("virt reg parse fail...\r\n"); return -1; + } n = getprop(devp, "reg-offset", ®_offset, sizeof(reg_offset)); if (n == sizeof(reg_offset)) - reg_base += reg_offset; + reg_base += be32_to_cpu(reg_offset); n = getprop(devp, "reg-shift", ®_shift, sizeof(reg_shift)); if (n != sizeof(reg_shift)) reg_shift = 0; + else + reg_shift = be32_to_cpu(reg_shift); scdp->open = ns16550_open; scdp->putc = ns16550_putc; diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h index f53c42380832..8c14f84a8770 100644 --- a/arch/powerpc/include/asm/barrier.h +++ b/arch/powerpc/include/asm/barrier.h @@ -46,6 +46,8 @@ # define SMPWMB eieio #endif +/* clang defines this macro for a builtin, which will not work with runtime patching */ +#undef __lwsync #define __lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : :"memory") #define dma_rmb() __lwsync() #define dma_wmb() __asm__ __volatile__ (stringify_in_c(SMPWMB) : : :"memory") diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index 98c8bd155bf9..b167186aaee4 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h @@ -98,6 +98,36 @@ static inline int cpu_last_thread_sibling(int cpu) return cpu | (threads_per_core - 1); } +/* + * tlb_thread_siblings are siblings which share a TLB. This is not + * architected, is not something a hypervisor could emulate and a future + * CPU may change behaviour even in compat mode, so this should only be + * used on PowerNV, and only with care. + */ +static inline int cpu_first_tlb_thread_sibling(int cpu) +{ + if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) + return cpu & ~0x6; /* Big Core */ + else + return cpu_first_thread_sibling(cpu); +} + +static inline int cpu_last_tlb_thread_sibling(int cpu) +{ + if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) + return cpu | 0x6; /* Big Core */ + else + return cpu_last_thread_sibling(cpu); +} + +static inline int cpu_tlb_thread_sibling_step(void) +{ + if (cpu_has_feature(CPU_FTR_ARCH_300) && (threads_per_core == 8)) + return 2; /* Big Core */ + else + return 1; +} + static inline u32 get_tensr(void) { #ifdef CONFIG_BOOKE diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h index cb89e4bf55ce..964063765662 100644 --- a/arch/powerpc/include/asm/ps3.h +++ b/arch/powerpc/include/asm/ps3.h @@ -71,6 +71,7 @@ struct ps3_dma_region_ops; * @bus_addr: The 'translated' bus address of the region. * @len: The length in bytes of the region. * @offset: The offset from the start of memory of the region. + * @dma_mask: Device dma_mask. * @ioid: The IOID of the device who owns this region * @chunk_list: Opaque variable used by the ioc page manager. * @region_ops: struct ps3_dma_region_ops - dma region operations @@ -85,6 +86,7 @@ struct ps3_dma_region { enum ps3_dma_region_type region_type; unsigned long len; unsigned long offset; + u64 dma_mask; /* driver variables (set by ps3_dma_region_create) */ unsigned long bus_addr; diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index e8c2a6373157..00fafc8b249e 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -276,7 +276,8 @@ int kprobe_handler(struct pt_regs *regs) if (user_mode(regs)) return 0; - if (!(regs->msr & MSR_IR) || !(regs->msr & MSR_DR)) + if (!IS_ENABLED(CONFIG_BOOKE) && + (!(regs->msr & MSR_IR) || !(regs->msr & MSR_DR))) return 0; /* diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index b7e173754a2e..ea8b002820ce 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c @@ -475,12 +475,11 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr, return -1; } -static int mce_handle_ierror(struct pt_regs *regs, +static int mce_handle_ierror(struct pt_regs *regs, unsigned long srr1, const struct mce_ierror_table table[], struct mce_error_info *mce_err, uint64_t *addr, uint64_t *phys_addr) { - uint64_t srr1 = regs->msr; int handled = 0; int i; @@ -683,19 +682,19 @@ static long mce_handle_ue_error(struct pt_regs *regs, } static long mce_handle_error(struct pt_regs *regs, + unsigned long srr1, const struct mce_derror_table dtable[], const struct mce_ierror_table itable[]) { struct mce_error_info mce_err = { 0 }; uint64_t addr, phys_addr = ULONG_MAX; - uint64_t srr1 = regs->msr; long handled; if (SRR1_MC_LOADSTORE(srr1)) handled = mce_handle_derror(regs, dtable, &mce_err, &addr, &phys_addr); else - handled = mce_handle_ierror(regs, itable, &mce_err, &addr, + handled = mce_handle_ierror(regs, srr1, itable, &mce_err, &addr, &phys_addr); if (!handled && mce_err.error_type == MCE_ERROR_TYPE_UE) @@ -711,16 +710,20 @@ long __machine_check_early_realmode_p7(struct pt_regs *regs) /* P7 DD1 leaves top bits of DSISR undefined */ regs->dsisr &= 0x0000ffff; - return mce_handle_error(regs, mce_p7_derror_table, mce_p7_ierror_table); + return mce_handle_error(regs, regs->msr, + mce_p7_derror_table, mce_p7_ierror_table); } long __machine_check_early_realmode_p8(struct pt_regs *regs) { - return mce_handle_error(regs, mce_p8_derror_table, mce_p8_ierror_table); + return mce_handle_error(regs, regs->msr, + mce_p8_derror_table, mce_p8_ierror_table); } long __machine_check_early_realmode_p9(struct pt_regs *regs) { + unsigned long srr1 = regs->msr; + /* * On POWER9 DD2.1 and below, it's possible to get a machine check * caused by a paste instruction where only DSISR bit 25 is set. This @@ -734,10 +737,39 @@ long __machine_check_early_realmode_p9(struct pt_regs *regs) if (SRR1_MC_LOADSTORE(regs->msr) && regs->dsisr == 0x02000000) return 1; - return mce_handle_error(regs, mce_p9_derror_table, mce_p9_ierror_table); + /* + * Async machine check due to bad real address from store or foreign + * link time out comes with the load/store bit (PPC bit 42) set in + * SRR1, but the cause comes in SRR1 not DSISR. Clear bit 42 so we're + * directed to the ierror table so it will find the cause (which + * describes it correctly as a store error). + */ + if (SRR1_MC_LOADSTORE(srr1) && + ((srr1 & 0x081c0000) == 0x08140000 || + (srr1 & 0x081c0000) == 0x08180000)) { + srr1 &= ~PPC_BIT(42); + } + + return mce_handle_error(regs, srr1, + mce_p9_derror_table, mce_p9_ierror_table); } long __machine_check_early_realmode_p10(struct pt_regs *regs) { - return mce_handle_error(regs, mce_p10_derror_table, mce_p10_ierror_table); + unsigned long srr1 = regs->msr; + + /* + * Async machine check due to bad real address from store comes with + * the load/store bit (PPC bit 42) set in SRR1, but the cause comes in + * SRR1 not DSISR. Clear bit 42 so we're directed to the ierror table + * so it will find the cause (which describes it correctly as a store + * error). + */ + if (SRR1_MC_LOADSTORE(srr1) && + (srr1 & 0x081c0000) == 0x08140000) { + srr1 &= ~PPC_BIT(42); + } + + return mce_handle_error(regs, srr1, + mce_p10_derror_table, mce_p10_ierror_table); } diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 1a1d2657fe8d..3064694afea1 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1227,6 +1227,19 @@ struct task_struct *__switch_to(struct task_struct *prev, __flush_tlb_pending(batch); batch->active = 0; } + + /* + * On POWER9 the copy-paste buffer can only paste into + * foreign real addresses, so unprivileged processes can not + * see the data or use it in any way unless they have + * foreign real mappings. If the new process has the foreign + * real address mappings, we must issue a cp_abort to clear + * any state and prevent snooping, corruption or a covert + * channel. ISA v3.1 supports paste into local memory. + */ + if (new->mm && (cpu_has_feature(CPU_FTR_ARCH_31) || + atomic_read(&new->mm->context.vas_windows))) + asm volatile(PPC_CP_ABORT); #endif /* CONFIG_PPC_BOOK3S_64 */ #ifdef CONFIG_PPC_ADV_DEBUG_REGS @@ -1272,30 +1285,33 @@ struct task_struct *__switch_to(struct task_struct *prev, last = _switch(old_thread, new_thread); + /* + * Nothing after _switch will be run for newly created tasks, + * because they switch directly to ret_from_fork/ret_from_kernel_thread + * etc. Code added here should have a comment explaining why that is + * okay. + */ + #ifdef CONFIG_PPC_BOOK3S_64 + /* + * This applies to a process that was context switched while inside + * arch_enter_lazy_mmu_mode(), to re-activate the batch that was + * deactivated above, before _switch(). This will never be the case + * for new tasks. + */ if (current_thread_info()->local_flags & _TLF_LAZY_MMU) { current_thread_info()->local_flags &= ~_TLF_LAZY_MMU; batch = this_cpu_ptr(&ppc64_tlb_batch); batch->active = 1; } - if (current->thread.regs) { + /* + * Math facilities are masked out of the child MSR in copy_thread. + * A new task does not need to restore_math because it will + * demand fault them. + */ + if (current->thread.regs) restore_math(current->thread.regs); - - /* - * On POWER9 the copy-paste buffer can only paste into - * foreign real addresses, so unprivileged processes can not - * see the data or use it in any way unless they have - * foreign real mappings. If the new process has the foreign - * real address mappings, we must issue a cp_abort to clear - * any state and prevent snooping, corruption or a covert - * channel. ISA v3.1 supports paste into local memory. - */ - if (current->mm && - (cpu_has_feature(CPU_FTR_ARCH_31) || - atomic_read(¤t->mm->context.vas_windows))) - asm volatile(PPC_CP_ABORT); - } #endif /* CONFIG_PPC_BOOK3S_64 */ return last; diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index db7ac77bea3a..26a028a9233a 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -600,6 +600,8 @@ static void nmi_stop_this_cpu(struct pt_regs *regs) /* * IRQs are already hard disabled by the smp_handle_nmi_ipi. */ + set_cpu_online(smp_processor_id(), false); + spin_begin(); while (1) spin_cpu_relax(); @@ -615,6 +617,15 @@ void smp_send_stop(void) static void stop_this_cpu(void *dummy) { hard_irq_disable(); + + /* + * Offlining CPUs in stop_this_cpu can result in scheduler warnings, + * (see commit de6e5d38417e), but printk_safe_flush_on_panic() wants + * to know other CPUs are offline before it breaks locks to flush + * printk buffers, in case we panic()ed while holding the lock. + */ + set_cpu_online(smp_processor_id(), false); + spin_begin(); while (1) spin_cpu_relax(); @@ -1426,7 +1437,6 @@ void start_secondary(void *unused) smp_store_cpu_info(cpu); set_dec(tb_ticks_per_jiffy); rcu_cpu_starting(cpu); - preempt_disable(); cpu_callin_map[cpu] = 1; if (smp_ops->setup_cpu) diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c index b6440657ef92..2f926ea9b7b9 100644 --- a/arch/powerpc/kernel/stacktrace.c +++ b/arch/powerpc/kernel/stacktrace.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -230,17 +231,31 @@ static void handle_backtrace_ipi(struct pt_regs *regs) static void raise_backtrace_ipi(cpumask_t *mask) { + struct paca_struct *p; unsigned int cpu; + u64 delay_us; for_each_cpu(cpu, mask) { - if (cpu == smp_processor_id()) + if (cpu == smp_processor_id()) { handle_backtrace_ipi(NULL); - else - smp_send_safe_nmi_ipi(cpu, handle_backtrace_ipi, 5 * USEC_PER_SEC); - } + continue; + } - for_each_cpu(cpu, mask) { - struct paca_struct *p = paca_ptrs[cpu]; + delay_us = 5 * USEC_PER_SEC; + + if (smp_send_safe_nmi_ipi(cpu, handle_backtrace_ipi, delay_us)) { + // Now wait up to 5s for the other CPU to do its backtrace + while (cpumask_test_cpu(cpu, mask) && delay_us) { + udelay(1); + delay_us--; + } + + // Other CPU cleared itself from the mask + if (delay_us) + continue; + } + + p = paca_ptrs[cpu]; cpumask_clear_cpu(cpu, mask); diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 2e08640bb3b4..d36e71ba002c 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -1167,7 +1167,7 @@ static int __init topology_init(void) * CPU. For instance, the boot cpu might never be valid * for hotplugging. */ - if (smp_ops->cpu_offline_self) + if (smp_ops && smp_ops->cpu_offline_self) c->hotpluggable = 1; #endif diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 280f7992ae99..bd7350a608d4 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -2366,8 +2366,10 @@ static int kvmppc_core_vcpu_create_hv(struct kvm_vcpu *vcpu) HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP | HFSCR_PREFIX; if (cpu_has_feature(CPU_FTR_HVMODE)) { vcpu->arch.hfscr &= mfspr(SPRN_HFSCR); +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) vcpu->arch.hfscr |= HFSCR_TM; +#endif } if (cpu_has_feature(CPU_FTR_TM_COMP)) vcpu->arch.hfscr |= HFSCR_TM; @@ -2578,7 +2580,7 @@ static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu) cpumask_t *cpu_in_guest; int i; - cpu = cpu_first_thread_sibling(cpu); + cpu = cpu_first_tlb_thread_sibling(cpu); if (nested) { cpumask_set_cpu(cpu, &nested->need_tlb_flush); cpu_in_guest = &nested->cpu_in_guest; @@ -2592,9 +2594,10 @@ static void radix_flush_cpu(struct kvm *kvm, int cpu, struct kvm_vcpu *vcpu) * the other side is the first smp_mb() in kvmppc_run_core(). */ smp_mb(); - for (i = 0; i < threads_per_core; ++i) - if (cpumask_test_cpu(cpu + i, cpu_in_guest)) - smp_call_function_single(cpu + i, do_nothing, NULL, 1); + for (i = cpu; i <= cpu_last_tlb_thread_sibling(cpu); + i += cpu_tlb_thread_sibling_step()) + if (cpumask_test_cpu(i, cpu_in_guest)) + smp_call_function_single(i, do_nothing, NULL, 1); } static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu) @@ -2625,8 +2628,8 @@ static void kvmppc_prepare_radix_vcpu(struct kvm_vcpu *vcpu, int pcpu) */ if (prev_cpu != pcpu) { if (prev_cpu >= 0 && - cpu_first_thread_sibling(prev_cpu) != - cpu_first_thread_sibling(pcpu)) + cpu_first_tlb_thread_sibling(prev_cpu) != + cpu_first_tlb_thread_sibling(pcpu)) radix_flush_cpu(kvm, prev_cpu, vcpu); if (nested) nested->prev_cpu[vcpu->arch.nested_vcpu_id] = pcpu; @@ -3583,6 +3586,7 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, unsigned long host_tidr = mfspr(SPRN_TIDR); unsigned long host_iamr = mfspr(SPRN_IAMR); unsigned long host_amr = mfspr(SPRN_AMR); + unsigned long host_fscr = mfspr(SPRN_FSCR); s64 dec; u64 tb; int trap, save_pmu; @@ -3726,6 +3730,9 @@ static int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, if (host_amr != vcpu->arch.amr) mtspr(SPRN_AMR, host_amr); + if (host_fscr != vcpu->arch.fscr) + mtspr(SPRN_FSCR, host_fscr); + msr_check_and_set(MSR_FP | MSR_VEC | MSR_VSX); store_fp_state(&vcpu->arch.fp); #ifdef CONFIG_ALTIVEC diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index 8f58dd20b362..4621905bdd9e 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -893,7 +893,7 @@ void kvmppc_check_need_tlb_flush(struct kvm *kvm, int pcpu, * Thus we make all 4 threads use the same bit. */ if (cpu_has_feature(CPU_FTR_ARCH_300)) - pcpu = cpu_first_thread_sibling(pcpu); + pcpu = cpu_first_tlb_thread_sibling(pcpu); if (nested) need_tlb_flush = &nested->need_tlb_flush; diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c index 33b58549a9aa..a5f1ae892ba6 100644 --- a/arch/powerpc/kvm/book3s_hv_nested.c +++ b/arch/powerpc/kvm/book3s_hv_nested.c @@ -51,7 +51,8 @@ void kvmhv_save_hv_regs(struct kvm_vcpu *vcpu, struct hv_guest_state *hr) hr->ppr = vcpu->arch.ppr; } -static void byteswap_pt_regs(struct pt_regs *regs) +/* Use noinline_for_stack due to https://bugs.llvm.org/show_bug.cgi?id=49610 */ +static noinline_for_stack void byteswap_pt_regs(struct pt_regs *regs) { unsigned long *addr = (unsigned long *) regs; @@ -231,6 +232,9 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu) if (vcpu->kvm->arch.l1_ptcr == 0) return H_NOT_AVAILABLE; + if (MSR_TM_TRANSACTIONAL(vcpu->arch.shregs.msr)) + return H_BAD_MODE; + /* copy parameters in */ hv_ptr = kvmppc_get_gpr(vcpu, 4); regs_ptr = kvmppc_get_gpr(vcpu, 5); @@ -253,6 +257,23 @@ long kvmhv_enter_nested_guest(struct kvm_vcpu *vcpu) if (l2_hv.vcpu_token >= NR_CPUS) return H_PARAMETER; + /* + * L1 must have set up a suspended state to enter the L2 in a + * transactional state, and only in that case. These have to be + * filtered out here to prevent causing a TM Bad Thing in the + * host HRFID. We could synthesize a TM Bad Thing back to the L1 + * here but there doesn't seem like much point. + */ + if (MSR_TM_SUSPENDED(vcpu->arch.shregs.msr)) { + if (!MSR_TM_ACTIVE(l2_regs.msr)) + return H_BAD_MODE; + } else { + if (l2_regs.msr & MSR_TS_MASK) + return H_BAD_MODE; + if (WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_TS_MASK)) + return H_BAD_MODE; + } + /* translate lpid */ l2 = kvmhv_get_nested(vcpu->kvm, l2_hv.lpid, true); if (!l2) diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 88da2764c1bb..3ddc83d2e849 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -67,7 +67,7 @@ static int global_invalidates(struct kvm *kvm) * so use the bit for the first thread to represent the core. */ if (cpu_has_feature(CPU_FTR_ARCH_300)) - cpu = cpu_first_thread_sibling(cpu); + cpu = cpu_first_tlb_thread_sibling(cpu); cpumask_clear_cpu(cpu, &kvm->arch.need_tlb_flush); } diff --git a/arch/powerpc/kvm/book3s_rtas.c b/arch/powerpc/kvm/book3s_rtas.c index c5e677508d3b..0f847f1e5ddd 100644 --- a/arch/powerpc/kvm/book3s_rtas.c +++ b/arch/powerpc/kvm/book3s_rtas.c @@ -242,6 +242,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) * value so we can restore it on the way out. */ orig_rets = args.rets; + if (be32_to_cpu(args.nargs) >= ARRAY_SIZE(args.args)) { + /* + * Don't overflow our args array: ensure there is room for + * at least rets[0] (even if the call specifies 0 nret). + * + * Each handler must then check for the correct nargs and nret + * values, but they may always return failure in rets[0]. + */ + rc = -EINVAL; + goto fail; + } args.rets = &args.args[be32_to_cpu(args.nargs)]; mutex_lock(&vcpu->kvm->arch.rtas_token_lock); @@ -269,9 +280,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu) fail: /* * We only get here if the guest has called RTAS with a bogus - * args pointer. That means we can't get to the args, and so we - * can't fail the RTAS call. So fail right out to userspace, - * which should kill the guest. + * args pointer or nargs/nret values that would overflow the + * array. That means we can't get to the args, and so we can't + * fail the RTAS call. So fail right out to userspace, which + * should kill the guest. + * + * SLOF should actually pass the hcall return value from the + * rtas handler call in r3, so enter_rtas could be modified to + * return a failure indication in r3 and we could return such + * errors to the guest rather than failing to host userspace. + * However old guests that don't test for failure could then + * continue silently after errors, so for now we won't do this. */ return rc; } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 32fa0fa3d4ff..543db9157f3b 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -2041,9 +2041,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, { struct kvm_enable_cap cap; r = -EFAULT; - vcpu_load(vcpu); if (copy_from_user(&cap, argp, sizeof(cap))) goto out; + vcpu_load(vcpu); r = kvm_vcpu_ioctl_enable_cap(vcpu, &cap); vcpu_put(vcpu); break; @@ -2067,9 +2067,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp, case KVM_DIRTY_TLB: { struct kvm_dirty_tlb dirty; r = -EFAULT; - vcpu_load(vcpu); if (copy_from_user(&dirty, argp, sizeof(dirty))) goto out; + vcpu_load(vcpu); r = kvm_vcpu_ioctl_dirty_tlb(vcpu, &dirty); vcpu_put(vcpu); break; diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index b487b489d4b6..4c2f75916a7e 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -282,22 +282,30 @@ static inline void fixup_tlbie_lpid(unsigned long lpid) /* * We use 128 set in radix mode and 256 set in hpt mode. */ -static __always_inline void _tlbiel_pid(unsigned long pid, unsigned long ric) +static inline void _tlbiel_pid(unsigned long pid, unsigned long ric) { int set; asm volatile("ptesync": : :"memory"); - /* - * Flush the first set of the TLB, and if we're doing a RIC_FLUSH_ALL, - * also flush the entire Page Walk Cache. - */ - __tlbiel_pid(pid, 0, ric); + switch (ric) { + case RIC_FLUSH_PWC: - /* For PWC, only one flush is needed */ - if (ric == RIC_FLUSH_PWC) { + /* For PWC, only one flush is needed */ + __tlbiel_pid(pid, 0, RIC_FLUSH_PWC); ppc_after_tlbiel_barrier(); return; + case RIC_FLUSH_TLB: + __tlbiel_pid(pid, 0, RIC_FLUSH_TLB); + break; + case RIC_FLUSH_ALL: + default: + /* + * Flush the first set of the TLB, and if + * we're doing a RIC_FLUSH_ALL, also flush + * the entire Page Walk Cache. + */ + __tlbiel_pid(pid, 0, RIC_FLUSH_ALL); } /* For the remaining sets, just flush the TLB */ @@ -1068,7 +1076,7 @@ void radix__tlb_flush(struct mmu_gather *tlb) } } -static __always_inline void __radix__flush_tlb_range_psize(struct mm_struct *mm, +static void __radix__flush_tlb_range_psize(struct mm_struct *mm, unsigned long start, unsigned long end, int psize, bool also_pwc) { diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 72e1b51beb10..55fdba8ba21c 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -198,9 +198,7 @@ static bool bad_kernel_fault(struct pt_regs *regs, unsigned long error_code, { int is_exec = TRAP(regs) == 0x400; - /* NX faults set DSISR_PROTFAULT on the 8xx, DSISR_NOEXEC_OR_G on others */ - if (is_exec && (error_code & (DSISR_NOEXEC_OR_G | DSISR_KEYFAULT | - DSISR_PROTFAULT))) { + if (is_exec) { pr_crit_ratelimited("kernel tried to execute %s page (%lx) - exploit attempt? (uid: %d)\n", address >= TASK_SIZE ? "exec-protected" : "user", address, diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index 022103c6a201..658ca2bab13c 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c @@ -646,6 +646,12 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, } break; + /* + * BPF_ST NOSPEC (speculation barrier) + */ + case BPF_ST | BPF_NOSPEC: + break; + /* * BPF_ST(X) */ diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index ded4a3efd3f0..91452313489f 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -1884,7 +1884,7 @@ static bool is_event_blacklisted(u64 ev) static int power_pmu_event_init(struct perf_event *event) { u64 ev; - unsigned long flags; + unsigned long flags, irq_flags; struct perf_event *ctrs[MAX_HWEVENTS]; u64 events[MAX_HWEVENTS]; unsigned int cflags[MAX_HWEVENTS]; @@ -1992,7 +1992,9 @@ static int power_pmu_event_init(struct perf_event *event) if (check_excludes(ctrs, cflags, n, 1)) return -EINVAL; - cpuhw = &get_cpu_var(cpu_hw_events); + local_irq_save(irq_flags); + cpuhw = this_cpu_ptr(&cpu_hw_events); + err = power_check_constraints(cpuhw, events, cflags, n + 1); if (has_branch_stack(event)) { @@ -2003,13 +2005,13 @@ static int power_pmu_event_init(struct perf_event *event) event->attr.branch_sample_type); if (bhrb_filter == -1) { - put_cpu_var(cpu_hw_events); + local_irq_restore(irq_flags); return -EOPNOTSUPP; } cpuhw->bhrb_filter = bhrb_filter; } - put_cpu_var(cpu_hw_events); + local_irq_restore(irq_flags); if (err) return -EINVAL; diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c index c855a0aeb49c..d7ab868aab54 100644 --- a/arch/powerpc/platforms/cell/smp.c +++ b/arch/powerpc/platforms/cell/smp.c @@ -78,9 +78,6 @@ static inline int smp_startup_cpu(unsigned int lcpu) pcpu = get_hard_smp_processor_id(lcpu); - /* Fixup atomic count: it exited inside IRQ handler. */ - task_thread_info(paca_ptrs[lcpu]->__current)->preempt_count = 0; - /* * If the RTAS start-cpu token does not exist then presume the * cpu is already spinning. diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 5f5fe63a3d1c..7ba0840fc3b5 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -1093,9 +1093,9 @@ struct vas_window *vas_tx_win_open(int vasid, enum vas_cop_type cop, /* * Process closes window during exit. In the case of * multithread application, the child thread can open - * window and can exit without closing it. Expects parent - * thread to use and close the window. So do not need - * to take pid reference for parent thread. + * window and can exit without closing it. so takes tgid + * reference until window closed to make sure tgid is not + * reused. */ txwin->tgid = find_get_pid(task_tgid_vnr(current)); /* @@ -1339,8 +1339,9 @@ int vas_win_close(struct vas_window *window) /* if send window, drop reference to matching receive window */ if (window->tx_win) { if (window->user_win) { - /* Drop references to pid and mm */ + /* Drop references to pid. tgid and mm */ put_pid(window->pid); + put_pid(window->tgid); if (window->mm) { mm_context_remove_vas_window(window->mm); mmdrop(window->mm); diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index d094321964fb..a81eac35d900 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -6,6 +6,7 @@ * Copyright 2006 Sony Corp. */ +#include #include #include #include @@ -1118,6 +1119,7 @@ int ps3_dma_region_init(struct ps3_system_bus_device *dev, enum ps3_dma_region_type region_type, void *addr, unsigned long len) { unsigned long lpar_addr; + int result; lpar_addr = addr ? ps3_mm_phys_to_lpar(__pa(addr)) : 0; @@ -1129,6 +1131,16 @@ int ps3_dma_region_init(struct ps3_system_bus_device *dev, r->offset -= map.r1.offset; r->len = len ? len : ALIGN(map.total, 1 << r->page_size); + dev->core.dma_mask = &r->dma_mask; + + result = dma_set_mask_and_coherent(&dev->core, DMA_BIT_MASK(32)); + + if (result < 0) { + dev_err(&dev->core, "%s:%d: dma_set_mask_and_coherent failed: %d\n", + __func__, __LINE__, result); + return result; + } + switch (dev->dev_type) { case PS3_DEVICE_TYPE_SB: r->region_ops = (USE_DYNAMIC_DMA) diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index 835163f54244..057acbb9116d 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -18,6 +18,7 @@ #include #include #include +#include #define BIND_ANY_ADDR (~0ul) @@ -867,6 +868,20 @@ static ssize_t flags_show(struct device *dev, } DEVICE_ATTR_RO(flags); +static umode_t papr_nd_attribute_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct nvdimm *nvdimm = to_nvdimm(dev); + struct papr_scm_priv *p = nvdimm_provider_data(nvdimm); + + /* For if perf-stats not available remove perf_stats sysfs */ + if (attr == &dev_attr_perf_stats.attr && p->stat_buffer_len == 0) + return 0; + + return attr->mode; +} + /* papr_scm specific dimm attributes */ static struct attribute *papr_nd_attributes[] = { &dev_attr_flags.attr, @@ -876,6 +891,7 @@ static struct attribute *papr_nd_attributes[] = { static struct attribute_group papr_nd_attribute_group = { .name = "papr", + .is_visible = papr_nd_attribute_visible, .attrs = papr_nd_attributes, }; @@ -891,7 +907,6 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) struct nd_region_desc ndr_desc; unsigned long dimm_flags; int target_nid, online_nid; - ssize_t stat_size; p->bus_desc.ndctl = papr_scm_ndctl; p->bus_desc.module = THIS_MODULE; @@ -962,16 +977,6 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) list_add_tail(&p->region_list, &papr_nd_regions); mutex_unlock(&papr_ndr_lock); - /* Try retriving the stat buffer and see if its supported */ - stat_size = drc_pmem_query_stats(p, NULL, 0); - if (stat_size > 0) { - p->stat_buffer_len = stat_size; - dev_dbg(&p->pdev->dev, "Max perf-stat size %lu-bytes\n", - p->stat_buffer_len); - } else { - dev_info(&p->pdev->dev, "Dimm performance stats unavailable\n"); - } - return 0; err: nvdimm_bus_unregister(p->bus); @@ -1047,8 +1052,10 @@ static int papr_scm_probe(struct platform_device *pdev) u32 drc_index, metadata_size; u64 blocks, block_size; struct papr_scm_priv *p; + u8 uuid_raw[UUID_SIZE]; const char *uuid_str; - u64 uuid[2]; + ssize_t stat_size; + uuid_t uuid; int rc; /* check we have all the required DT properties */ @@ -1090,16 +1097,23 @@ static int papr_scm_probe(struct platform_device *pdev) p->is_volatile = !of_property_read_bool(dn, "ibm,cache-flush-required"); /* We just need to ensure that set cookies are unique across */ - uuid_parse(uuid_str, (uuid_t *) uuid); + uuid_parse(uuid_str, &uuid); + /* - * cookie1 and cookie2 are not really little endian - * we store a little endian representation of the - * uuid str so that we can compare this with the label - * area cookie irrespective of the endian config with which - * the kernel is built. + * The cookie1 and cookie2 are not really little endian. + * We store a raw buffer representation of the + * uuid string so that we can compare this with the label + * area cookie irrespective of the endian configuration + * with which the kernel is built. + * + * Historically we stored the cookie in the below format. + * for a uuid string 72511b67-0b3b-42fd-8d1d-5be3cae8bcaa + * cookie1 was 0xfd423b0b671b5172 + * cookie2 was 0xaabce8cae35b1d8d */ - p->nd_set.cookie1 = cpu_to_le64(uuid[0]); - p->nd_set.cookie2 = cpu_to_le64(uuid[1]); + export_uuid(uuid_raw, &uuid); + p->nd_set.cookie1 = get_unaligned_le64(&uuid_raw[0]); + p->nd_set.cookie2 = get_unaligned_le64(&uuid_raw[8]); /* might be zero */ p->metadata_size = metadata_size; @@ -1124,6 +1138,14 @@ static int papr_scm_probe(struct platform_device *pdev) p->res.name = pdev->name; p->res.flags = IORESOURCE_MEM; + /* Try retrieving the stat buffer and see if its supported */ + stat_size = drc_pmem_query_stats(p, NULL, 0); + if (stat_size > 0) { + p->stat_buffer_len = stat_size; + dev_dbg(&p->pdev->dev, "Max perf-stat size %lu-bytes\n", + p->stat_buffer_len); + } + rc = papr_scm_nvdimm_init(p); if (rc) goto err2; diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 090c13f6c881..5f0d446a2325 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -76,7 +76,7 @@ #include "../../../../drivers/pci/pci.h" DEFINE_STATIC_KEY_FALSE(shared_processor); -EXPORT_SYMBOL_GPL(shared_processor); +EXPORT_SYMBOL(shared_processor); int CMO_PrPSP = -1; int CMO_SecPSP = -1; diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 92922491a81c..624e80b00eb1 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -104,9 +104,6 @@ static inline int smp_startup_cpu(unsigned int lcpu) return 1; } - /* Fixup atomic count: it exited inside IRQ handler. */ - task_thread_info(paca_ptrs[lcpu]->__current)->preempt_count = 0; - /* * If the RTAS start-cpu token does not exist then presume the * cpu is already spinning. diff --git a/arch/powerpc/platforms/pseries/svm.c b/arch/powerpc/platforms/pseries/svm.c index 7b739cc7a8a9..87f001b4c4e4 100644 --- a/arch/powerpc/platforms/pseries/svm.c +++ b/arch/powerpc/platforms/pseries/svm.c @@ -55,14 +55,17 @@ void __init svm_swiotlb_init(void) if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, false)) return; - if (io_tlb_start) - memblock_free_early(io_tlb_start, - PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); + + memblock_free_early(__pa(vstart), + PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT)); panic("SVM: Cannot allocate SWIOTLB buffer"); } int set_memory_encrypted(unsigned long addr, int numpages) { + if (!mem_encrypt_active()) + return 0; + if (!PAGE_ALIGNED(addr)) return -EINVAL; @@ -73,6 +76,9 @@ int set_memory_encrypted(unsigned long addr, int numpages) int set_memory_decrypted(unsigned long addr, int numpages) { + if (!mem_encrypt_active()) + return 0; + if (!PAGE_ALIGNED(addr)) return -EINVAL; diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 0289a97325d1..226c366072da 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -14,7 +14,7 @@ ifeq ($(CONFIG_DYNAMIC_FTRACE),y) LDFLAGS_vmlinux := --no-relax endif -ifeq ($(CONFIG_64BIT)$(CONFIG_CMODEL_MEDLOW),yy) +ifeq ($(CONFIG_CMODEL_MEDLOW),y) KBUILD_CFLAGS_MODULE += -mcmodel=medany endif @@ -36,6 +36,15 @@ else KBUILD_LDFLAGS += -melf32lriscv endif +ifeq ($(CONFIG_LD_IS_LLD),y) + KBUILD_CFLAGS += -mno-relax + KBUILD_AFLAGS += -mno-relax +ifneq ($(LLVM_IAS),1) + KBUILD_CFLAGS += -Wa,-mno-relax + KBUILD_AFLAGS += -Wa,-mno-relax +endif +endif + # ISA string setting riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index fa896c5f7ccb..62de075fc60c 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -4,8 +4,9 @@ # ifdef CONFIG_FTRACE -CFLAGS_REMOVE_ftrace.o = -pg -CFLAGS_REMOVE_patch.o = -pg +CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_patch.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_sbi.o = $(CC_FLAGS_FTRACE) endif extra-y += head.o diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c index 2d6395f5ad54..69678ab6457d 100644 --- a/arch/riscv/kernel/ptrace.c +++ b/arch/riscv/kernel/ptrace.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,9 @@ static int riscv_fpr_get(struct task_struct *target, { struct __riscv_d_ext_state *fstate = &target->thread.fstate; + if (target == current) + fstate_save(current, task_pt_regs(current)); + membuf_write(&to, fstate, offsetof(struct __riscv_d_ext_state, fcsr)); membuf_store(&to, fstate->fcsr); return membuf_zero(&to, 4); // explicitly pad diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index 96167d55ed98..0b04e0eae3ab 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -166,7 +166,6 @@ asmlinkage __visible void smp_callin(void) * Disable preemption before enabling interrupts, so we don't try to * schedule a CPU that hasn't actually started yet. */ - preempt_disable(); local_irq_enable(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); } diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile index c0185e556ca5..7ebaef10ea1b 100644 --- a/arch/riscv/mm/Makefile +++ b/arch/riscv/mm/Makefile @@ -2,7 +2,8 @@ CFLAGS_init.o := -mcmodel=medany ifdef CONFIG_FTRACE -CFLAGS_REMOVE_init.o = -pg +CFLAGS_REMOVE_init.o = $(CC_FLAGS_FTRACE) +CFLAGS_REMOVE_cacheflush.o = $(CC_FLAGS_FTRACE) endif KCOV_INSTRUMENT_init.o := n diff --git a/arch/riscv/net/bpf_jit_comp32.c b/arch/riscv/net/bpf_jit_comp32.c index 579575f9cdae..f300f93ba645 100644 --- a/arch/riscv/net/bpf_jit_comp32.c +++ b/arch/riscv/net/bpf_jit_comp32.c @@ -1251,6 +1251,10 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, return -1; break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + break; + case BPF_ST | BPF_MEM | BPF_B: case BPF_ST | BPF_MEM | BPF_H: case BPF_ST | BPF_MEM | BPF_W: diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c index 8a56b5293117..c113ae818b14 100644 --- a/arch/riscv/net/bpf_jit_comp64.c +++ b/arch/riscv/net/bpf_jit_comp64.c @@ -939,6 +939,10 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, emit_ld(rd, 0, RV_REG_T1, ctx); break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + break; + /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_B: emit_imm(RV_REG_T1, imm, ctx); diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 4a2a12be04c9..896b68e541b2 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -154,6 +154,8 @@ config S390 select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_GCC_PLUGINS select HAVE_GENERIC_VDSO + select HAVE_IOREMAP_PROT if PCI + select HAVE_IRQ_EXIT_ON_IRQ_STACK select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZ4 @@ -856,7 +858,7 @@ config CMM_IUCV config APPLDATA_BASE def_bool n prompt "Linux - VM Monitor Stream, base infrastructure" - depends on PROC_FS + depends on PROC_SYSCTL help This provides a kernel interface for creating and updating z/VM APPLDATA monitor records. The monitor records are updated at certain time diff --git a/arch/s390/Makefile b/arch/s390/Makefile index ba94b03c8b2f..92506918da63 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -28,6 +28,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY KBUILD_CFLAGS_DECOMPRESSOR += -fno-delete-null-pointer-checks -msoft-float KBUILD_CFLAGS_DECOMPRESSOR += -fno-asynchronous-unwind-tables KBUILD_CFLAGS_DECOMPRESSOR += -ffreestanding +KBUILD_CFLAGS_DECOMPRESSOR += -fno-stack-protector KBUILD_CFLAGS_DECOMPRESSOR += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),-g) KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option, -gdwarf-4,)) diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c index f94b91d72620..c56bbf58a945 100644 --- a/arch/s390/boot/ipl_parm.c +++ b/arch/s390/boot/ipl_parm.c @@ -28,22 +28,25 @@ static inline int __diag308(unsigned long subcode, void *addr) register unsigned long _addr asm("0") = (unsigned long)addr; register unsigned long _rc asm("1") = 0; unsigned long reg1, reg2; - psw_t old = S390_lowcore.program_new_psw; + psw_t old; asm volatile( + " mvc 0(16,%[psw_old]),0(%[psw_pgm])\n" " epsw %0,%1\n" - " st %0,%[psw_pgm]\n" - " st %1,%[psw_pgm]+4\n" + " st %0,0(%[psw_pgm])\n" + " st %1,4(%[psw_pgm])\n" " larl %0,1f\n" - " stg %0,%[psw_pgm]+8\n" + " stg %0,8(%[psw_pgm])\n" " diag %[addr],%[subcode],0x308\n" - "1: nopr %%r7\n" + "1: mvc 0(16,%[psw_pgm]),0(%[psw_old])\n" : "=&d" (reg1), "=&a" (reg2), - [psw_pgm] "=Q" (S390_lowcore.program_new_psw), + "+Q" (S390_lowcore.program_new_psw), + "=Q" (old), [addr] "+d" (_addr), "+d" (_rc) - : [subcode] "d" (subcode) + : [subcode] "d" (subcode), + [psw_old] "a" (&old), + [psw_pgm] "a" (&S390_lowcore.program_new_psw) : "cc", "memory"); - S390_lowcore.program_new_psw = old; return _rc; } diff --git a/arch/s390/boot/mem_detect.c b/arch/s390/boot/mem_detect.c index 62e7c13ce85c..85049541c191 100644 --- a/arch/s390/boot/mem_detect.c +++ b/arch/s390/boot/mem_detect.c @@ -70,24 +70,27 @@ static int __diag260(unsigned long rx1, unsigned long rx2) register unsigned long _ry asm("4") = 0x10; /* storage configuration */ int rc = -1; /* fail */ unsigned long reg1, reg2; - psw_t old = S390_lowcore.program_new_psw; + psw_t old; asm volatile( + " mvc 0(16,%[psw_old]),0(%[psw_pgm])\n" " epsw %0,%1\n" - " st %0,%[psw_pgm]\n" - " st %1,%[psw_pgm]+4\n" + " st %0,0(%[psw_pgm])\n" + " st %1,4(%[psw_pgm])\n" " larl %0,1f\n" - " stg %0,%[psw_pgm]+8\n" + " stg %0,8(%[psw_pgm])\n" " diag %[rx],%[ry],0x260\n" " ipm %[rc]\n" " srl %[rc],28\n" - "1:\n" + "1: mvc 0(16,%[psw_pgm]),0(%[psw_old])\n" : "=&d" (reg1), "=&a" (reg2), - [psw_pgm] "=Q" (S390_lowcore.program_new_psw), + "+Q" (S390_lowcore.program_new_psw), + "=Q" (old), [rc] "+&d" (rc), [ry] "+d" (_ry) - : [rx] "d" (_rx1), "d" (_rx2) + : [rx] "d" (_rx1), "d" (_rx2), + [psw_old] "a" (&old), + [psw_pgm] "a" (&S390_lowcore.program_new_psw) : "cc", "memory"); - S390_lowcore.program_new_psw = old; return rc == 0 ? _ry : -1; } @@ -112,24 +115,30 @@ static int diag260(void) static int tprot(unsigned long addr) { - unsigned long pgm_addr; + unsigned long reg1, reg2; int rc = -EFAULT; - psw_t old = S390_lowcore.program_new_psw; + psw_t old; - S390_lowcore.program_new_psw.mask = __extract_psw(); asm volatile( - " larl %[pgm_addr],1f\n" - " stg %[pgm_addr],%[psw_pgm_addr]\n" + " mvc 0(16,%[psw_old]),0(%[psw_pgm])\n" + " epsw %[reg1],%[reg2]\n" + " st %[reg1],0(%[psw_pgm])\n" + " st %[reg2],4(%[psw_pgm])\n" + " larl %[reg1],1f\n" + " stg %[reg1],8(%[psw_pgm])\n" " tprot 0(%[addr]),0\n" " ipm %[rc]\n" " srl %[rc],28\n" - "1:\n" - : [pgm_addr] "=&d"(pgm_addr), - [psw_pgm_addr] "=Q"(S390_lowcore.program_new_psw.addr), - [rc] "+&d"(rc) - : [addr] "a"(addr) + "1: mvc 0(16,%[psw_pgm]),0(%[psw_old])\n" + : [reg1] "=&d" (reg1), + [reg2] "=&a" (reg2), + [rc] "+&d" (rc), + "=Q" (S390_lowcore.program_new_psw.addr), + "=Q" (old) + : [psw_old] "a" (&old), + [psw_pgm] "a" (&S390_lowcore.program_new_psw), + [addr] "a" (addr) : "cc", "memory"); - S390_lowcore.program_new_psw = old; return rc; } diff --git a/arch/s390/boot/text_dma.S b/arch/s390/boot/text_dma.S index f7c77cd518f2..5ff5fee02801 100644 --- a/arch/s390/boot/text_dma.S +++ b/arch/s390/boot/text_dma.S @@ -9,16 +9,6 @@ #include #include -#ifdef CC_USING_EXPOLINE - .pushsection .dma.text.__s390_indirect_jump_r14,"axG" -__dma__s390_indirect_jump_r14: - larl %r1,0f - ex 0,0(%r1) - j . -0: br %r14 - .popsection -#endif - .section .dma.text,"ax" /* * Simplified version of expoline thunk. The normal thunks can not be used here, @@ -27,11 +17,10 @@ __dma__s390_indirect_jump_r14: * affects a few functions that are not performance-relevant. */ .macro BR_EX_DMA_r14 -#ifdef CC_USING_EXPOLINE - jg __dma__s390_indirect_jump_r14 -#else - br %r14 -#endif + larl %r1,0f + ex 0,0(%r1) + j . +0: br %r14 .endm /* diff --git a/arch/s390/boot/uv.c b/arch/s390/boot/uv.c index 87641dd65ccf..b3501ea5039e 100644 --- a/arch/s390/boot/uv.c +++ b/arch/s390/boot/uv.c @@ -36,6 +36,7 @@ void uv_query_info(void) uv_info.max_sec_stor_addr = ALIGN(uvcb.max_guest_stor_addr, PAGE_SIZE); uv_info.max_num_sec_conf = uvcb.max_num_sec_conf; uv_info.max_guest_cpu_id = uvcb.max_guest_cpu_id; + uv_info.uv_feature_indications = uvcb.uv_feature_indications; } #ifdef CONFIG_PROTECTED_VIRTUALIZATION_GUEST diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h index 68d362f8d6c1..c72c179a5aae 100644 --- a/arch/s390/include/asm/ftrace.h +++ b/arch/s390/include/asm/ftrace.h @@ -27,6 +27,7 @@ void ftrace_caller(void); extern char ftrace_graph_caller_end; extern unsigned long ftrace_plt; +extern void *ftrace_func; struct dyn_arch_ftrace { }; diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index b5dbae78969b..2338345912a3 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -864,6 +864,25 @@ static inline int pte_unused(pte_t pte) return pte_val(pte) & _PAGE_UNUSED; } +/* + * Extract the pgprot value from the given pte while at the same time making it + * usable for kernel address space mappings where fault driven dirty and + * young/old accounting is not supported, i.e _PAGE_PROTECT and _PAGE_INVALID + * must not be set. + */ +static inline pgprot_t pte_pgprot(pte_t pte) +{ + unsigned long pte_flags = pte_val(pte) & _PAGE_CHG_MASK; + + if (pte_write(pte)) + pte_flags |= pgprot_val(PAGE_KERNEL); + else + pte_flags |= pgprot_val(PAGE_KERNEL_RO); + pte_flags |= pte_val(pte) & mio_wb_bit_mask; + + return __pgprot(pte_flags); +} + /* * pgd/pmd/pte modification functions */ diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h index 6ede29907fbf..b5f545db461a 100644 --- a/arch/s390/include/asm/preempt.h +++ b/arch/s390/include/asm/preempt.h @@ -29,12 +29,6 @@ static inline void preempt_count_set(int pc) old, new) != old); } -#define init_task_preempt_count(p) do { } while (0) - -#define init_idle_preempt_count(p, cpu) do { \ - S390_lowcore.preempt_count = PREEMPT_ENABLED; \ -} while (0) - static inline void set_preempt_need_resched(void) { __atomic_and(~PREEMPT_NEED_RESCHED, &S390_lowcore.preempt_count); @@ -88,12 +82,6 @@ static inline void preempt_count_set(int pc) S390_lowcore.preempt_count = pc; } -#define init_task_preempt_count(p) do { } while (0) - -#define init_idle_preempt_count(p, cpu) do { \ - S390_lowcore.preempt_count = PREEMPT_ENABLED; \ -} while (0) - static inline void set_preempt_need_resched(void) { } @@ -130,6 +118,10 @@ static inline bool should_resched(int preempt_offset) #endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */ +#define init_task_preempt_count(p) do { } while (0) +/* Deferred to CPU bringup time */ +#define init_idle_preempt_count(p, cpu) do { } while (0) + #ifdef CONFIG_PREEMPTION extern asmlinkage void preempt_schedule(void); #define __preempt_schedule() preempt_schedule() diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 962da04234af..0987c3fc45f5 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -211,7 +211,7 @@ static __always_inline unsigned long current_stack_pointer(void) return sp; } -static __no_kasan_or_inline unsigned short stap(void) +static __always_inline unsigned short stap(void) { unsigned short cpu_address; @@ -250,7 +250,7 @@ static inline void __load_psw(psw_t psw) * Set PSW mask to specified value, while leaving the * PSW addr pointing to the next instruction. */ -static __no_kasan_or_inline void __load_psw_mask(unsigned long mask) +static __always_inline void __load_psw_mask(unsigned long mask) { unsigned long addr; psw_t psw; diff --git a/arch/s390/include/asm/stacktrace.h b/arch/s390/include/asm/stacktrace.h index ee056f4a4fa3..90488b0c26f6 100644 --- a/arch/s390/include/asm/stacktrace.h +++ b/arch/s390/include/asm/stacktrace.h @@ -90,12 +90,16 @@ struct stack_frame { CALL_ARGS_4(arg1, arg2, arg3, arg4); \ register unsigned long r4 asm("6") = (unsigned long)(arg5) -#define CALL_FMT_0 "=&d" (r2) : -#define CALL_FMT_1 "+&d" (r2) : -#define CALL_FMT_2 CALL_FMT_1 "d" (r3), -#define CALL_FMT_3 CALL_FMT_2 "d" (r4), -#define CALL_FMT_4 CALL_FMT_3 "d" (r5), -#define CALL_FMT_5 CALL_FMT_4 "d" (r6), +/* + * To keep this simple mark register 2-6 as being changed (volatile) + * by the called function, even though register 6 is saved/nonvolatile. + */ +#define CALL_FMT_0 "=&d" (r2) +#define CALL_FMT_1 "+&d" (r2) +#define CALL_FMT_2 CALL_FMT_1, "+&d" (r3) +#define CALL_FMT_3 CALL_FMT_2, "+&d" (r4) +#define CALL_FMT_4 CALL_FMT_3, "+&d" (r5) +#define CALL_FMT_5 CALL_FMT_4, "+&d" (r6) #define CALL_CLOBBER_5 "0", "1", "14", "cc", "memory" #define CALL_CLOBBER_4 CALL_CLOBBER_5 @@ -117,13 +121,110 @@ struct stack_frame { " brasl 14,%[_fn]\n" \ " la 15,0(%[_prev])\n" \ : [_prev] "=&a" (prev), CALL_FMT_##nr \ - [_stack] "R" (stack), \ + : [_stack] "R" (stack), \ [_bc] "i" (offsetof(struct stack_frame, back_chain)), \ [_frame] "d" (frame), \ [_fn] "X" (fn) : CALL_CLOBBER_##nr); \ r2; \ }) +#define CALL_LARGS_0(...) \ + long dummy = 0 +#define CALL_LARGS_1(t1, a1) \ + long arg1 = (long)(t1)(a1) +#define CALL_LARGS_2(t1, a1, t2, a2) \ + CALL_LARGS_1(t1, a1); \ + long arg2 = (long)(t2)(a2) +#define CALL_LARGS_3(t1, a1, t2, a2, t3, a3) \ + CALL_LARGS_2(t1, a1, t2, a2); \ + long arg3 = (long)(t3)(a3) +#define CALL_LARGS_4(t1, a1, t2, a2, t3, a3, t4, a4) \ + CALL_LARGS_3(t1, a1, t2, a2, t3, a3); \ + long arg4 = (long)(t4)(a4) +#define CALL_LARGS_5(t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \ + CALL_LARGS_4(t1, a1, t2, a2, t3, a3, t4, a4); \ + long arg5 = (long)(t5)(a5) + +#define CALL_REGS_0 \ + register long r2 asm("2") = dummy +#define CALL_REGS_1 \ + register long r2 asm("2") = arg1 +#define CALL_REGS_2 \ + CALL_REGS_1; \ + register long r3 asm("3") = arg2 +#define CALL_REGS_3 \ + CALL_REGS_2; \ + register long r4 asm("4") = arg3 +#define CALL_REGS_4 \ + CALL_REGS_3; \ + register long r5 asm("5") = arg4 +#define CALL_REGS_5 \ + CALL_REGS_4; \ + register long r6 asm("6") = arg5 + +#define CALL_TYPECHECK_0(...) +#define CALL_TYPECHECK_1(t, a, ...) \ + typecheck(t, a) +#define CALL_TYPECHECK_2(t, a, ...) \ + CALL_TYPECHECK_1(__VA_ARGS__); \ + typecheck(t, a) +#define CALL_TYPECHECK_3(t, a, ...) \ + CALL_TYPECHECK_2(__VA_ARGS__); \ + typecheck(t, a) +#define CALL_TYPECHECK_4(t, a, ...) \ + CALL_TYPECHECK_3(__VA_ARGS__); \ + typecheck(t, a) +#define CALL_TYPECHECK_5(t, a, ...) \ + CALL_TYPECHECK_4(__VA_ARGS__); \ + typecheck(t, a) + +#define CALL_PARM_0(...) void +#define CALL_PARM_1(t, a, ...) t +#define CALL_PARM_2(t, a, ...) t, CALL_PARM_1(__VA_ARGS__) +#define CALL_PARM_3(t, a, ...) t, CALL_PARM_2(__VA_ARGS__) +#define CALL_PARM_4(t, a, ...) t, CALL_PARM_3(__VA_ARGS__) +#define CALL_PARM_5(t, a, ...) t, CALL_PARM_4(__VA_ARGS__) +#define CALL_PARM_6(t, a, ...) t, CALL_PARM_5(__VA_ARGS__) + +/* + * Use call_on_stack() to call a function switching to a specified + * stack. Proper sign and zero extension of function arguments is + * done. Usage: + * + * rc = call_on_stack(nr, stack, rettype, fn, t1, a1, t2, a2, ...) + * + * - nr specifies the number of function arguments of fn. + * - stack specifies the stack to be used. + * - fn is the function to be called. + * - rettype is the return type of fn. + * - t1, a1, ... are pairs, where t1 must match the type of the first + * argument of fn, t2 the second, etc. a1 is the corresponding + * first function argument (not name), etc. + */ +#define call_on_stack(nr, stack, rettype, fn, ...) \ +({ \ + rettype (*__fn)(CALL_PARM_##nr(__VA_ARGS__)) = fn; \ + unsigned long frame = current_frame_address(); \ + unsigned long __stack = stack; \ + unsigned long prev; \ + CALL_LARGS_##nr(__VA_ARGS__); \ + CALL_REGS_##nr; \ + \ + CALL_TYPECHECK_##nr(__VA_ARGS__); \ + asm volatile( \ + " lgr %[_prev],15\n" \ + " lg 15,%[_stack]\n" \ + " stg %[_frame],%[_bc](15)\n" \ + " brasl 14,%[_fn]\n" \ + " lgr 15,%[_prev]\n" \ + : [_prev] "=&d" (prev), CALL_FMT_##nr \ + : [_stack] "R" (__stack), \ + [_bc] "i" (offsetof(struct stack_frame, back_chain)), \ + [_frame] "d" (frame), \ + [_fn] "X" (__fn) : CALL_CLOBBER_##nr); \ + (rettype)r2; \ +}) + #define CALL_ON_STACK_NORETURN(fn, stack) \ ({ \ asm volatile( \ diff --git a/arch/s390/include/asm/uv.h b/arch/s390/include/asm/uv.h index 7b98d4caee77..12c5f006c136 100644 --- a/arch/s390/include/asm/uv.h +++ b/arch/s390/include/asm/uv.h @@ -73,6 +73,10 @@ enum uv_cmds_inst { BIT_UVC_CMD_UNPIN_PAGE_SHARED = 22, }; +enum uv_feat_ind { + BIT_UV_FEAT_MISC = 0, +}; + struct uv_cb_header { u16 len; u16 cmd; /* Command Code */ @@ -97,7 +101,8 @@ struct uv_cb_qui { u64 max_guest_stor_addr; u8 reserved88[158 - 136]; u16 max_guest_cpu_id; - u8 reserveda0[200 - 160]; + u64 uv_feature_indications; + u8 reserveda0[200 - 168]; } __packed __aligned(8); /* Initialize Ultravisor */ @@ -274,6 +279,7 @@ struct uv_info { unsigned long max_sec_stor_addr; unsigned int max_num_sec_conf; unsigned short max_guest_cpu_id; + unsigned long uv_feature_indications; }; extern struct uv_info uv_info; diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 81c458e996d9..963e8cb936e2 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -1284,7 +1284,7 @@ ENDPROC(stack_overflow) je 1f larl %r13,.Lsie_entry slgr %r9,%r13 - larl %r13,.Lsie_skip + lghi %r13,.Lsie_skip - .Lsie_entry clgr %r9,%r13 jh 1f oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index b388e87a08bf..923ecccae306 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -57,6 +57,7 @@ * > brasl %r0,ftrace_caller # offset 0 */ +void *ftrace_func __read_mostly = ftrace_stub; unsigned long ftrace_plt; static inline void ftrace_generate_orig_insn(struct ftrace_insn *insn) @@ -120,6 +121,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) int ftrace_update_ftrace_func(ftrace_func_t func) { + ftrace_func = func; return 0; } diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 7458dcfd6464..be9e85e7558a 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S @@ -67,13 +67,13 @@ ENTRY(ftrace_caller) #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES aghik %r2,%r0,-MCOUNT_INSN_SIZE lgrl %r4,function_trace_op - lgrl %r1,ftrace_trace_function + lgrl %r1,ftrace_func #else lgr %r2,%r0 aghi %r2,-MCOUNT_INSN_SIZE larl %r4,function_trace_op lg %r4,0(%r4) - larl %r1,ftrace_trace_function + larl %r1,ftrace_func lg %r1,0(%r1) #endif lgr %r3,%r14 diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index e83ce909686c..5cd9d20af31e 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -166,7 +166,7 @@ static void __init set_preferred_console(void) else if (CONSOLE_IS_3270) add_preferred_console("tty3270", 0, NULL); else if (CONSOLE_IS_VT220) - add_preferred_console("ttyS", 1, NULL); + add_preferred_console("ttysclp", 0, NULL); else if (CONSOLE_IS_HVC) add_preferred_console("hvc", 0, NULL); } @@ -454,6 +454,7 @@ static void __init setup_lowcore_dat_off(void) lc->br_r1_trampoline = 0x07f1; /* br %r1 */ lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW); lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW); + lc->preempt_count = PREEMPT_DISABLED; set_prefix((u32)(unsigned long) lc); lowcore_ptr[0] = lc; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 791bc373418b..5674792726cd 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -215,6 +215,7 @@ static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) lc->br_r1_trampoline = 0x07f1; /* br %r1 */ lc->return_lpswe = gen_lpswe(__LC_RETURN_PSW); lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW); + lc->preempt_count = PREEMPT_DISABLED; if (nmi_alloc_per_cpu(lc)) goto out_async; if (vdso_alloc_per_cpu(lc)) @@ -863,7 +864,6 @@ static void smp_init_secondary(void) set_cpu_flag(CIF_ASCE_SECONDARY); cpu_init(); rcu_cpu_starting(cpu); - preempt_disable(); init_cpu_timer(); vtime_init(); pfault_init(); diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 8d1e8a1a97df..16934fa19069 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -272,6 +272,8 @@ static void __init test_monitor_call(void) { int val = 1; + if (!IS_ENABLED(CONFIG_BUG)) + return; asm volatile( " mc 0,0\n" "0: xgr %0,%0\n" diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c index b2d2ad153067..c811b2313100 100644 --- a/arch/s390/kernel/uv.c +++ b/arch/s390/kernel/uv.c @@ -364,6 +364,15 @@ static ssize_t uv_query_facilities(struct kobject *kobj, static struct kobj_attribute uv_query_facilities_attr = __ATTR(facilities, 0444, uv_query_facilities, NULL); +static ssize_t uv_query_feature_indications(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%lx\n", uv_info.uv_feature_indications); +} + +static struct kobj_attribute uv_query_feature_indications_attr = + __ATTR(feature_indications, 0444, uv_query_feature_indications, NULL); + static ssize_t uv_query_max_guest_cpus(struct kobject *kobj, struct kobj_attribute *attr, char *page) { @@ -396,6 +405,7 @@ static struct kobj_attribute uv_query_max_guest_addr_attr = static struct attribute *uv_query_attrs[] = { &uv_query_facilities_attr.attr, + &uv_query_feature_indications_attr.attr, &uv_query_max_guest_cpus_attr.attr, &uv_query_max_guest_vms_attr.attr, &uv_query_max_guest_addr_attr.attr, diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 20afffd6b982..f94b4f78d4da 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -327,31 +327,31 @@ static void allow_cpu_feat(unsigned long nr) static inline int plo_test_bit(unsigned char nr) { - register unsigned long r0 asm("0") = (unsigned long) nr | 0x100; + unsigned long function = (unsigned long)nr | 0x100; int cc; asm volatile( + " lgr 0,%[function]\n" /* Parameter registers are ignored for "test bit" */ " plo 0,0,0,0(0)\n" " ipm %0\n" " srl %0,28\n" : "=d" (cc) - : "d" (r0) - : "cc"); + : [function] "d" (function) + : "cc", "0"); return cc == 0; } static __always_inline void __insn32_query(unsigned int opcode, u8 *query) { - register unsigned long r0 asm("0") = 0; /* query function */ - register unsigned long r1 asm("1") = (unsigned long) query; - asm volatile( - /* Parameter regs are ignored */ + " lghi 0,0\n" + " lgr 1,%[query]\n" + /* Parameter registers are ignored */ " .insn rrf,%[opc] << 16,2,4,6,0\n" : - : "d" (r0), "a" (r1), [opc] "i" (opcode) - : "cc", "memory"); + : [query] "d" ((unsigned long)query), [opc] "i" (opcode) + : "cc", "memory", "0", "1"); } #define INSN_SORTL 0xb938 diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 996884dcc9fd..ed517fad0d03 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -805,6 +805,32 @@ void do_secure_storage_access(struct pt_regs *regs) struct page *page; int rc; + /* + * bit 61 tells us if the address is valid, if it's not we + * have a major problem and should stop the kernel or send a + * SIGSEGV to the process. Unfortunately bit 61 is not + * reliable without the misc UV feature so we need to check + * for that as well. + */ + if (test_bit_inv(BIT_UV_FEAT_MISC, &uv_info.uv_feature_indications) && + !test_bit_inv(61, ®s->int_parm_long)) { + /* + * When this happens, userspace did something that it + * was not supposed to do, e.g. branching into secure + * memory. Trigger a segmentation fault. + */ + if (user_mode(regs)) { + send_sig(SIGSEGV, current, 0); + return; + } + + /* + * The kernel should never run into this case and we + * have no way out of this situation. + */ + panic("Unexpected PGM 0x3d with TEID bit 61=0"); + } + switch (get_fault_type(regs)) { case USER_FAULT: mm = current->mm; diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 77767850d0d0..9d5960bbc45f 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -180,9 +180,9 @@ static void pv_init(void) return; /* make sure bounce buffers are shared */ + swiotlb_force = SWIOTLB_FORCE; swiotlb_init(1); swiotlb_update_mem_attributes(); - swiotlb_force = SWIOTLB_FORCE; } void __init mem_init(void) diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 0a4182792876..dee01d3b23a4 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -112,7 +112,7 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1) { u32 r1 = reg2hex[b1]; - if (!jit->seen_reg[r1] && r1 >= 6 && r1 <= 15) + if (r1 >= 6 && r1 <= 15 && !jit->seen_reg[r1]) jit->seen_reg[r1] = 1; } @@ -1153,6 +1153,11 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, break; } break; + /* + * BPF_NOSPEC (speculation barrier) + */ + case BPF_ST | BPF_NOSPEC: + break; /* * BPF_ST(X) */ diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 1ae7a76ae97b..ca1a105e3b5d 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -558,9 +558,12 @@ static void zpci_cleanup_bus_resources(struct zpci_dev *zdev) int pcibios_add_device(struct pci_dev *pdev) { + struct zpci_dev *zdev = to_zpci(pdev); struct resource *res; int i; + /* The pdev has a reference to the zdev via its bus */ + zpci_zdev_get(zdev); if (pdev->is_physfn) pdev->no_vf_scan = 1; @@ -580,7 +583,10 @@ int pcibios_add_device(struct pci_dev *pdev) void pcibios_release_device(struct pci_dev *pdev) { + struct zpci_dev *zdev = to_zpci(pdev); + zpci_unmap_resources(pdev); + zpci_zdev_put(zdev); } int pcibios_enable_device(struct pci_dev *pdev, int mask) diff --git a/arch/s390/pci/pci_bus.h b/arch/s390/pci/pci_bus.h index f8dfac0b5b71..55c9488e504c 100644 --- a/arch/s390/pci/pci_bus.h +++ b/arch/s390/pci/pci_bus.h @@ -16,6 +16,11 @@ static inline void zpci_zdev_put(struct zpci_dev *zdev) kref_put(&zdev->kref, zpci_release_device); } +static inline void zpci_zdev_get(struct zpci_dev *zdev) +{ + kref_get(&zdev->kref); +} + int zpci_alloc_domain(int domain); void zpci_free_domain(int domain); int zpci_setup_bus_resources(struct zpci_dev *zdev, diff --git a/arch/s390/purgatory/Makefile b/arch/s390/purgatory/Makefile index c57f8c40e992..21c4ebe29b9a 100644 --- a/arch/s390/purgatory/Makefile +++ b/arch/s390/purgatory/Makefile @@ -24,6 +24,7 @@ KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding KBUILD_CFLAGS += -c -MD -Os -m64 -msoft-float -fno-common +KBUILD_CFLAGS += -fno-stack-protector KBUILD_CFLAGS += $(CLANG_FLAGS) KBUILD_CFLAGS += $(call cc-option,-fno-PIE) KBUILD_AFLAGS := $(filter-out -DCC_USING_EXPOLINE,$(KBUILD_AFLAGS)) diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index 372acdc9033e..65924d9ec245 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c @@ -186,8 +186,6 @@ asmlinkage void start_secondary(void) per_cpu_trap_init(); - preempt_disable(); - notify_cpu_starting(cpu); local_irq_enable(); diff --git a/arch/sparc/kernel/smp_32.c b/arch/sparc/kernel/smp_32.c index 50c127ab46d5..22b148e5a5f8 100644 --- a/arch/sparc/kernel/smp_32.c +++ b/arch/sparc/kernel/smp_32.c @@ -348,7 +348,6 @@ static void sparc_start_secondary(void *arg) */ arch_cpu_pre_starting(arg); - preempt_disable(); cpu = smp_processor_id(); notify_cpu_starting(cpu); diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index e38d8bf454e8..ae5faa1d989d 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -138,9 +138,6 @@ void smp_callin(void) set_cpu_online(cpuid, true); - /* idle thread is expected to have preempt disabled */ - preempt_disable(); - local_irq_enable(); cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c index 3364e2a00989..fef734473c0f 100644 --- a/arch/sparc/net/bpf_jit_comp_64.c +++ b/arch/sparc/net/bpf_jit_comp_64.c @@ -1287,6 +1287,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) return 1; break; } + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + break; /* ST: *(size *)(dst + off) = imm */ case BPF_ST | BPF_MEM | BPF_W: case BPF_ST | BPF_MEM | BPF_H: diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index d8845d4aac6a..6040817c036f 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -256,7 +256,8 @@ static int winch_tramp(int fd, struct tty_port *port, int *fd_out, goto out_close; } - if (os_set_fd_block(*fd_out, 0)) { + err = os_set_fd_block(*fd_out, 0); + if (err) { printk(UM_KERN_ERR "winch_tramp: failed to set thread_fd " "non-blocking.\n"); goto out_close; diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 482a19c5105c..7334019c9e60 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -145,7 +145,8 @@ static int slip_open(void *data) } sfd = err; - if (set_up_tty(sfd)) + err = set_up_tty(sfd); + if (err) goto out_close2; pri->slave = sfd; diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 66c79c960c7e..f400aaf73ffb 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -86,6 +86,7 @@ CONFIG_GKI_HACKS_TO_FIX=y CONFIG_BINFMT_MISC=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y +CONFIG_DEFAULT_MMAP_MIN_ADDR=32768 CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y CONFIG_CLEANCACHE=y @@ -248,7 +249,13 @@ CONFIG_BT_HCIUART=y CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIUART_BCM=y CONFIG_BT_HCIUART_QCA=y +CONFIG_CFG80211=y +CONFIG_NL80211_TESTMODE=y +# CONFIG_CFG80211_DEFAULT_PS is not set +# CONFIG_CFG80211_CRDA_SUPPORT is not set +CONFIG_MAC80211=y CONFIG_RFKILL=y +CONFIG_NFC=y CONFIG_PCI=y CONFIG_PCIEPORTBUS=y CONFIG_PCIEAER=y @@ -275,6 +282,7 @@ CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_UFS_DWC_TC_PLATFORM=y CONFIG_SCSI_UFS_BSG=y CONFIG_SCSI_UFS_CRYPTO=y +CONFIG_SCSI_UFS_HPB=y CONFIG_MD=y CONFIG_BLK_DEV_DM=y CONFIG_DM_CRYPT=y @@ -462,6 +470,7 @@ CONFIG_DMABUF_SYSFS_STATS=y CONFIG_DMABUF_HEAPS_DEFERRED_FREE=y CONFIG_DMABUF_HEAPS_PAGE_POOL=y CONFIG_UIO=y +# CONFIG_VIRTIO_MEM is not set CONFIG_VHOST_VSOCK=y CONFIG_STAGING=y CONFIG_ASHMEM=y diff --git a/arch/x86/crypto/curve25519-x86_64.c b/arch/x86/crypto/curve25519-x86_64.c index 5af8021b98ce..11b4c83c715e 100644 --- a/arch/x86/crypto/curve25519-x86_64.c +++ b/arch/x86/crypto/curve25519-x86_64.c @@ -1500,7 +1500,7 @@ static int __init curve25519_mod_init(void) static void __exit curve25519_mod_exit(void) { if (IS_REACHABLE(CONFIG_CRYPTO_KPP) && - (boot_cpu_has(X86_FEATURE_BMI2) || boot_cpu_has(X86_FEATURE_ADX))) + static_branch_likely(&curve25519_use_bmi2_adx)) crypto_unregister_kpp(&curve25519_alg); } diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c index 2e4d91f3feea..93a3122cd15f 100644 --- a/arch/x86/entry/common.c +++ b/arch/x86/entry/common.c @@ -127,8 +127,8 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs) /* User code screwed up. */ regs->ax = -EFAULT; - instrumentation_end(); local_irq_disable(); + instrumentation_end(); irqentry_exit_to_user_mode(regs); return false; } diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index cad08703c4ad..f18f3932e971 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -508,7 +508,7 @@ SYM_CODE_START(\asmsym) movq %rsp, %rdi /* pt_regs pointer */ - call \cfunc + call kernel_\cfunc /* * No need to switch back to the IST stack. The current stack is either @@ -519,7 +519,7 @@ SYM_CODE_START(\asmsym) /* Switch to the regular task stack */ .Lfrom_usermode_switch_stack_\@: - idtentry_body safe_stack_\cfunc, has_error_code=1 + idtentry_body user_\cfunc, has_error_code=1 _ASM_NOKPROBE(\asmsym) SYM_CODE_END(\asmsym) diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 40669eac9d6d..921f47b9bb24 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -90,6 +90,7 @@ struct perf_ibs { unsigned long offset_mask[1]; int offset_max; unsigned int fetch_count_reset_broken : 1; + unsigned int fetch_ignore_if_zero_rip : 1; struct cpu_perf_ibs __percpu *pcpu; struct attribute **format_attrs; @@ -672,6 +673,10 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) { regs.flags &= ~PERF_EFLAGS_EXACT; } else { + /* Workaround for erratum #1197 */ + if (perf_ibs->fetch_ignore_if_zero_rip && !(ibs_data.regs[1])) + goto out; + set_linear_ip(®s, ibs_data.regs[1]); regs.flags |= PERF_EFLAGS_EXACT; } @@ -769,6 +774,9 @@ static __init void perf_event_ibs_init(void) if (boot_cpu_data.x86 >= 0x16 && boot_cpu_data.x86 <= 0x18) perf_ibs_fetch.fetch_count_reset_broken = 1; + if (boot_cpu_data.x86 == 0x19 && boot_cpu_data.x86_model < 0x10) + perf_ibs_fetch.fetch_ignore_if_zero_rip = 1; + perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch"); if (ibs_caps & IBS_CAPS_OPCNT) { diff --git a/arch/x86/events/amd/power.c b/arch/x86/events/amd/power.c index 16a2369c586e..37d5b380516e 100644 --- a/arch/x86/events/amd/power.c +++ b/arch/x86/events/amd/power.c @@ -213,6 +213,7 @@ static struct pmu pmu_class = { .stop = pmu_event_stop, .read = pmu_event_read, .capabilities = PERF_PMU_CAP_NO_EXCLUDE, + .module = THIS_MODULE, }; static int power_cpu_exit(unsigned int cpu) diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index a88c94d65693..e6db1a1f22d7 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -45,9 +45,11 @@ #include "perf_event.h" struct x86_pmu x86_pmu __read_mostly; +static struct pmu pmu; DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, + .pmu = &pmu, }; DEFINE_STATIC_KEY_FALSE(rdpmc_never_available_key); @@ -372,10 +374,12 @@ int x86_reserve_hardware(void) if (!atomic_inc_not_zero(&pmc_refcount)) { mutex_lock(&pmc_reserve_mutex); if (atomic_read(&pmc_refcount) == 0) { - if (!reserve_pmc_hardware()) + if (!reserve_pmc_hardware()) { err = -EBUSY; - else + } else { reserve_ds_buffers(); + reserve_lbr_buffers(); + } } if (!err) atomic_inc(&pmc_refcount); @@ -710,16 +714,23 @@ void x86_pmu_enable_all(int added) } } -static struct pmu pmu; - static inline int is_x86_event(struct perf_event *event) { return event->pmu == &pmu; } -struct pmu *x86_get_pmu(void) +struct pmu *x86_get_pmu(unsigned int cpu) { - return &pmu; + struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); + + /* + * All CPUs of the hybrid type have been offline. + * The x86_get_pmu() should not be invoked. + */ + if (WARN_ON_ONCE(!cpuc->pmu)) + return &pmu; + + return cpuc->pmu; } /* * Event scheduler state: diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index ee659b5faf71..3b8b8eede1a8 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -4747,7 +4747,7 @@ static void update_tfa_sched(void *ignored) * and if so force schedule out for all event types all contexts */ if (test_bit(3, cpuc->active_mask)) - perf_pmu_resched(x86_get_pmu()); + perf_pmu_resched(x86_get_pmu(smp_processor_id())); } static ssize_t show_sysctl_tfa(struct device *cdev, diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c index 31a7a6566d07..945d470f62d0 100644 --- a/arch/x86/events/intel/ds.c +++ b/arch/x86/events/intel/ds.c @@ -2076,7 +2076,7 @@ void __init intel_ds_init(void) PERF_SAMPLE_TIME; x86_pmu.flags |= PMU_FL_PEBS_ALL; pebs_qual = "-baseline"; - x86_get_pmu()->capabilities |= PERF_PMU_CAP_EXTENDED_REGS; + x86_get_pmu(smp_processor_id())->capabilities |= PERF_PMU_CAP_EXTENDED_REGS; } else { /* Only basic record supported */ x86_pmu.large_pebs_flags &= @@ -2091,7 +2091,7 @@ void __init intel_ds_init(void) if (x86_pmu.intel_cap.pebs_output_pt_available) { pr_cont("PEBS-via-PT, "); - x86_get_pmu()->capabilities |= PERF_PMU_CAP_AUX_OUTPUT; + x86_get_pmu(smp_processor_id())->capabilities |= PERF_PMU_CAP_AUX_OUTPUT; } break; diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c index e2b0efcba101..9c1a013d5682 100644 --- a/arch/x86/events/intel/lbr.c +++ b/arch/x86/events/intel/lbr.c @@ -658,7 +658,6 @@ static inline bool branch_user_callstack(unsigned br_sel) void intel_pmu_lbr_add(struct perf_event *event) { - struct kmem_cache *kmem_cache = event->pmu->task_ctx_cache; struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); if (!x86_pmu.lbr_nr) @@ -696,16 +695,11 @@ void intel_pmu_lbr_add(struct perf_event *event) perf_sched_cb_inc(event->ctx->pmu); if (!cpuc->lbr_users++ && !event->total_time_running) intel_pmu_lbr_reset(); - - if (static_cpu_has(X86_FEATURE_ARCH_LBR) && - kmem_cache && !cpuc->lbr_xsave && - (cpuc->lbr_users != cpuc->lbr_pebs_users)) - cpuc->lbr_xsave = kmem_cache_alloc(kmem_cache, GFP_KERNEL); } void release_lbr_buffers(void) { - struct kmem_cache *kmem_cache = x86_get_pmu()->task_ctx_cache; + struct kmem_cache *kmem_cache; struct cpu_hw_events *cpuc; int cpu; @@ -714,6 +708,7 @@ void release_lbr_buffers(void) for_each_possible_cpu(cpu) { cpuc = per_cpu_ptr(&cpu_hw_events, cpu); + kmem_cache = x86_get_pmu(cpu)->task_ctx_cache; if (kmem_cache && cpuc->lbr_xsave) { kmem_cache_free(kmem_cache, cpuc->lbr_xsave); cpuc->lbr_xsave = NULL; @@ -721,6 +716,27 @@ void release_lbr_buffers(void) } } +void reserve_lbr_buffers(void) +{ + struct kmem_cache *kmem_cache; + struct cpu_hw_events *cpuc; + int cpu; + + if (!static_cpu_has(X86_FEATURE_ARCH_LBR)) + return; + + for_each_possible_cpu(cpu) { + cpuc = per_cpu_ptr(&cpu_hw_events, cpu); + kmem_cache = x86_get_pmu(cpu)->task_ctx_cache; + if (!kmem_cache || cpuc->lbr_xsave) + continue; + + cpuc->lbr_xsave = kmem_cache_alloc_node(kmem_cache, + GFP_KERNEL | __GFP_ZERO, + cpu_to_node(cpu)); + } +} + void intel_pmu_lbr_del(struct perf_event *event) { struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); @@ -1609,7 +1625,7 @@ void intel_pmu_lbr_init_hsw(void) x86_pmu.lbr_sel_mask = LBR_SEL_MASK; x86_pmu.lbr_sel_map = hsw_lbr_sel_map; - x86_get_pmu()->task_ctx_cache = create_lbr_kmem_cache(size, 0); + x86_get_pmu(smp_processor_id())->task_ctx_cache = create_lbr_kmem_cache(size, 0); if (lbr_from_signext_quirk_needed()) static_branch_enable(&lbr_from_quirk_key); @@ -1629,7 +1645,7 @@ __init void intel_pmu_lbr_init_skl(void) x86_pmu.lbr_sel_mask = LBR_SEL_MASK; x86_pmu.lbr_sel_map = hsw_lbr_sel_map; - x86_get_pmu()->task_ctx_cache = create_lbr_kmem_cache(size, 0); + x86_get_pmu(smp_processor_id())->task_ctx_cache = create_lbr_kmem_cache(size, 0); /* * SW branch filter usage: @@ -1726,7 +1742,7 @@ static bool is_arch_lbr_xsave_available(void) void __init intel_pmu_arch_lbr_init(void) { - struct pmu *pmu = x86_get_pmu(); + struct pmu *pmu = x86_get_pmu(smp_processor_id()); union cpuid28_eax eax; union cpuid28_ebx ebx; union cpuid28_ecx ecx; diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index e94af4a54d0d..37129b76135a 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c @@ -62,7 +62,7 @@ static struct pt_cap_desc { PT_CAP(single_range_output, 0, CPUID_ECX, BIT(2)), PT_CAP(output_subsys, 0, CPUID_ECX, BIT(3)), PT_CAP(payloads_lip, 0, CPUID_ECX, BIT(31)), - PT_CAP(num_address_ranges, 1, CPUID_EAX, 0x3), + PT_CAP(num_address_ranges, 1, CPUID_EAX, 0x7), PT_CAP(mtc_periods, 1, CPUID_EAX, 0xffff0000), PT_CAP(cycle_thresholds, 1, CPUID_EBX, 0xffff), PT_CAP(psb_periods, 1, CPUID_EBX, 0xffff0000), diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 3112186a4f4b..2701f87a9a7c 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -3752,11 +3752,11 @@ static int skx_iio_set_mapping(struct intel_uncore_type *type) /* One more for NULL. */ attrs = kcalloc((uncore_max_dies() + 1), sizeof(*attrs), GFP_KERNEL); if (!attrs) - goto err; + goto clear_topology; eas = kcalloc(uncore_max_dies(), sizeof(*eas), GFP_KERNEL); if (!eas) - goto err; + goto clear_attrs; for (die = 0; die < uncore_max_dies(); die++) { sprintf(buf, "die%ld", die); @@ -3777,7 +3777,9 @@ static int skx_iio_set_mapping(struct intel_uncore_type *type) for (; die >= 0; die--) kfree(eas[die].attr.attr.name); kfree(eas); +clear_attrs: kfree(attrs); +clear_topology: kfree(type->topology); clear_attr_update: type->attr_update = NULL; @@ -4667,7 +4669,7 @@ static void __snr_uncore_mmio_init_box(struct intel_uncore_box *box, return; pci_read_config_dword(pdev, SNR_IMC_MMIO_BASE_OFFSET, &pci_dword); - addr = (pci_dword & SNR_IMC_MMIO_BASE_MASK) << 23; + addr = ((resource_size_t)pci_dword & SNR_IMC_MMIO_BASE_MASK) << 23; pci_read_config_dword(pdev, mem_offset, &pci_dword); addr |= (pci_dword & SNR_IMC_MMIO_MEM0_MASK) << 12; @@ -5067,9 +5069,10 @@ static struct intel_uncore_type icx_uncore_m2m = { .perf_ctr = SNR_M2M_PCI_PMON_CTR0, .event_ctl = SNR_M2M_PCI_PMON_CTL0, .event_mask = SNBEP_PMON_RAW_EVENT_MASK, + .event_mask_ext = SNR_M2M_PCI_PMON_UMASK_EXT, .box_ctl = SNR_M2M_PCI_PMON_BOX_CTL, .ops = &snr_m2m_uncore_pci_ops, - .format_group = &skx_uncore_format_group, + .format_group = &snr_m2m_uncore_format_group, }; static struct attribute *icx_upi_uncore_formats_attr[] = { diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h index 6a8edfe59b09..0c3b8fa7e532 100644 --- a/arch/x86/events/perf_event.h +++ b/arch/x86/events/perf_event.h @@ -326,6 +326,8 @@ struct cpu_hw_events { int n_pair; /* Large increment events */ void *kfree_on_online[X86_PERF_KFREE_MAX]; + + struct pmu *pmu; }; #define __EVENT_CONSTRAINT_RANGE(c, e, n, m, w, o, f) { \ @@ -897,7 +899,7 @@ static struct perf_pmu_events_ht_attr event_attr_##v = { \ .event_str_ht = ht, \ } -struct pmu *x86_get_pmu(void); +struct pmu *x86_get_pmu(unsigned int cpu); extern struct x86_pmu x86_pmu __read_mostly; static __always_inline struct x86_perf_task_context_opt *task_context_opt(void *ctx) @@ -1007,9 +1009,10 @@ void x86_pmu_stop(struct perf_event *event, int flags); static inline void x86_pmu_disable_event(struct perf_event *event) { + u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask); struct hw_perf_event *hwc = &event->hw; - wrmsrl(hwc->config_base, hwc->config); + wrmsrl(hwc->config_base, hwc->config & ~disable_mask); if (is_counter_pair(hwc)) wrmsrl(x86_pmu_config_addr(hwc->idx + 1), 0); @@ -1122,6 +1125,8 @@ void reserve_ds_buffers(void); void release_lbr_buffers(void); +void reserve_lbr_buffers(void); + extern struct event_constraint bts_constraint; extern struct event_constraint vlbr_constraint; @@ -1267,6 +1272,10 @@ static inline void release_lbr_buffers(void) { } +static inline void reserve_lbr_buffers(void) +{ +} + static inline int intel_pmu_init(void) { return 0; diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h index ceeba9f63172..4e5af2b00d89 100644 --- a/arch/x86/include/asm/fpu/internal.h +++ b/arch/x86/include/asm/fpu/internal.h @@ -103,6 +103,7 @@ static inline void fpstate_init_fxstate(struct fxregs_state *fx) } extern void fpstate_sanitize_xstate(struct fpu *fpu); +/* Returns 0 or the negated trap number, which results in -EFAULT for #PF */ #define user_insn(insn, output, input...) \ ({ \ int err; \ @@ -110,14 +111,14 @@ extern void fpstate_sanitize_xstate(struct fpu *fpu); might_fault(); \ \ asm volatile(ASM_STAC "\n" \ - "1:" #insn "\n\t" \ + "1: " #insn "\n" \ "2: " ASM_CLAC "\n" \ ".section .fixup,\"ax\"\n" \ - "3: movl $-1,%[err]\n" \ + "3: negl %%eax\n" \ " jmp 2b\n" \ ".previous\n" \ - _ASM_EXTABLE(1b, 3b) \ - : [err] "=r" (err), output \ + _ASM_EXTABLE_FAULT(1b, 3b) \ + : [err] "=a" (err), output \ : "0"(0), input); \ err; \ }) @@ -204,6 +205,14 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu) asm volatile("fxsaveq %[fx]" : [fx] "=m" (fpu->state.fxsave)); } +static inline void fxsave(struct fxregs_state *fx) +{ + if (IS_ENABLED(CONFIG_X86_32)) + asm volatile( "fxsave %[fx]" : [fx] "=m" (*fx)); + else + asm volatile("fxsaveq %[fx]" : [fx] "=m" (*fx)); +} + /* These macros all use (%edi)/(%rdi) as the single memory argument. */ #define XSAVE ".byte " REX_PREFIX "0x0f,0xae,0x27" #define XSAVEOPT ".byte " REX_PREFIX "0x0f,0xae,0x37" @@ -211,16 +220,20 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu) #define XRSTOR ".byte " REX_PREFIX "0x0f,0xae,0x2f" #define XRSTORS ".byte " REX_PREFIX "0x0f,0xc7,0x1f" +/* + * After this @err contains 0 on success or the negated trap number when + * the operation raises an exception. For faults this results in -EFAULT. + */ #define XSTATE_OP(op, st, lmask, hmask, err) \ asm volatile("1:" op "\n\t" \ "xor %[err], %[err]\n" \ "2:\n\t" \ ".pushsection .fixup,\"ax\"\n\t" \ - "3: movl $-2,%[err]\n\t" \ + "3: negl %%eax\n\t" \ "jmp 2b\n\t" \ ".popsection\n\t" \ - _ASM_EXTABLE(1b, 3b) \ - : [err] "=r" (err) \ + _ASM_EXTABLE_FAULT(1b, 3b) \ + : [err] "=a" (err) \ : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ : "memory") @@ -268,28 +281,6 @@ static inline void copy_fxregs_to_kernel(struct fpu *fpu) : "D" (st), "m" (*st), "a" (lmask), "d" (hmask) \ : "memory") -/* - * This function is called only during boot time when x86 caps are not set - * up and alternative can not be used yet. - */ -static inline void copy_xregs_to_kernel_booting(struct xregs_state *xstate) -{ - u64 mask = xfeatures_mask_all; - u32 lmask = mask; - u32 hmask = mask >> 32; - int err; - - WARN_ON(system_state != SYSTEM_BOOTING); - - if (boot_cpu_has(X86_FEATURE_XSAVES)) - XSTATE_OP(XSAVES, xstate, lmask, hmask, err); - else - XSTATE_OP(XSAVE, xstate, lmask, hmask, err); - - /* We should never fault when copying to a kernel buffer: */ - WARN_ON_FPU(err); -} - /* * This function is called only during boot time when x86 caps are not set * up and alternative can not be used yet. @@ -578,10 +569,17 @@ static inline void switch_fpu_finish(struct fpu *new_fpu) * PKRU state is switched eagerly because it needs to be valid before we * return to userland e.g. for a copy_to_user() operation. */ - if (current->mm) { + if (!(current->flags & PF_KTHREAD)) { + /* + * If the PKRU bit in xsave.header.xfeatures is not set, + * then the PKRU component was in init state, which means + * XRSTOR will set PKRU to 0. If the bit is not set then + * get_xsave_addr() will return NULL because the PKRU value + * in memory is not valid. This means pkru_val has to be + * set to 0 and not to init_pkru_value. + */ pk = get_xsave_addr(&new_fpu->state.xsave, XFEATURE_PKRU); - if (pk) - pkru_val = pk->pkru; + pkru_val = pk ? pk->pkru : 0; } __write_pkru(pkru_val); } diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h index 0e3325790f3a..dc2a8b1657f4 100644 --- a/arch/x86/include/asm/idtentry.h +++ b/arch/x86/include/asm/idtentry.h @@ -315,8 +315,8 @@ static __always_inline void __##func(struct pt_regs *regs) */ #define DECLARE_IDTENTRY_VC(vector, func) \ DECLARE_IDTENTRY_RAW_ERRORCODE(vector, func); \ - __visible noinstr void ist_##func(struct pt_regs *regs, unsigned long error_code); \ - __visible noinstr void safe_stack_##func(struct pt_regs *regs, unsigned long error_code) + __visible noinstr void kernel_##func(struct pt_regs *regs, unsigned long error_code); \ + __visible noinstr void user_##func(struct pt_regs *regs, unsigned long error_code) /** * DEFINE_IDTENTRY_IST - Emit code for IST entry points @@ -358,33 +358,24 @@ static __always_inline void __##func(struct pt_regs *regs) DEFINE_IDTENTRY_RAW_ERRORCODE(func) /** - * DEFINE_IDTENTRY_VC_SAFE_STACK - Emit code for VMM communication handler - which runs on a safe stack. + * DEFINE_IDTENTRY_VC_KERNEL - Emit code for VMM communication handler + when raised from kernel mode * @func: Function name of the entry point * * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE */ -#define DEFINE_IDTENTRY_VC_SAFE_STACK(func) \ - DEFINE_IDTENTRY_RAW_ERRORCODE(safe_stack_##func) +#define DEFINE_IDTENTRY_VC_KERNEL(func) \ + DEFINE_IDTENTRY_RAW_ERRORCODE(kernel_##func) /** - * DEFINE_IDTENTRY_VC_IST - Emit code for VMM communication handler - which runs on the VC fall-back stack + * DEFINE_IDTENTRY_VC_USER - Emit code for VMM communication handler + when raised from user mode * @func: Function name of the entry point * * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE */ -#define DEFINE_IDTENTRY_VC_IST(func) \ - DEFINE_IDTENTRY_RAW_ERRORCODE(ist_##func) - -/** - * DEFINE_IDTENTRY_VC - Emit code for VMM communication handler - * @func: Function name of the entry point - * - * Maps to DEFINE_IDTENTRY_RAW_ERRORCODE - */ -#define DEFINE_IDTENTRY_VC(func) \ - DEFINE_IDTENTRY_RAW_ERRORCODE(func) +#define DEFINE_IDTENTRY_VC_USER(func) \ + DEFINE_IDTENTRY_RAW_ERRORCODE(user_##func) #else /* CONFIG_X86_64 */ diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index ef56780022c3..b1cd8334db11 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -84,7 +84,7 @@ #define KVM_REQ_APICV_UPDATE \ KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) #define KVM_REQ_TLB_FLUSH_CURRENT KVM_ARCH_REQ(26) -#define KVM_REQ_HV_TLB_FLUSH \ +#define KVM_REQ_TLB_FLUSH_GUEST \ KVM_ARCH_REQ_FLAGS(27, KVM_REQUEST_NO_WAKEUP) #define KVM_REQ_APF_READY KVM_ARCH_REQ(28) #define KVM_REQ_MSR_FILTER_CHANGED KVM_ARCH_REQ(29) @@ -296,6 +296,7 @@ union kvm_mmu_extended_role { unsigned int cr4_pke:1; unsigned int cr4_smap:1; unsigned int cr4_smep:1; + unsigned int cr4_la57:1; unsigned int maxphyaddr:6; }; }; diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h index 2f62bbdd9d12..31c4df123aa0 100644 --- a/arch/x86/include/asm/mem_encrypt.h +++ b/arch/x86/include/asm/mem_encrypt.h @@ -37,6 +37,7 @@ void __init sme_map_bootdata(char *real_mode_data); void __init sme_unmap_bootdata(char *real_mode_data); void __init sme_early_init(void); +void __init sev_setup_arch(void); void __init sme_encrypt_kernel(struct boot_params *bp); void __init sme_enable(struct boot_params *bp); @@ -69,6 +70,7 @@ static inline void __init sme_map_bootdata(char *real_mode_data) { } static inline void __init sme_unmap_bootdata(char *real_mode_data) { } static inline void __init sme_early_init(void) { } +static inline void __init sev_setup_arch(void) { } static inline void __init sme_encrypt_kernel(struct boot_params *bp) { } static inline void __init sme_enable(struct boot_params *bp) { } diff --git a/arch/x86/include/asm/preempt.h b/arch/x86/include/asm/preempt.h index 69485ca13665..a334dd0d7c42 100644 --- a/arch/x86/include/asm/preempt.h +++ b/arch/x86/include/asm/preempt.h @@ -43,7 +43,7 @@ static __always_inline void preempt_count_set(int pc) #define init_task_preempt_count(p) do { } while (0) #define init_idle_preempt_count(p, cpu) do { \ - per_cpu(__preempt_count, (cpu)) = PREEMPT_ENABLED; \ + per_cpu(__preempt_count, (cpu)) = PREEMPT_DISABLED; \ } while (0) /* diff --git a/arch/x86/include/asm/proto.h b/arch/x86/include/asm/proto.h index b6a9d51d1d79..8c5d1910a848 100644 --- a/arch/x86/include/asm/proto.h +++ b/arch/x86/include/asm/proto.h @@ -4,6 +4,8 @@ #include +struct task_struct; + /* misc architecture specific prototypes */ void syscall_init(void); diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 71d630bb5e08..f8fad50502ad 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -166,6 +166,8 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define V_IGN_TPR_SHIFT 20 #define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT) +#define V_IRQ_INJECTION_BITS_MASK (V_IRQ_MASK | V_INTR_PRIO_MASK | V_IGN_TPR_MASK) + #define V_INTR_MASKING_SHIFT 24 #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) diff --git a/arch/x86/include/uapi/asm/hwcap2.h b/arch/x86/include/uapi/asm/hwcap2.h index 5fdfcb47000f..054604aba9f0 100644 --- a/arch/x86/include/uapi/asm/hwcap2.h +++ b/arch/x86/include/uapi/asm/hwcap2.h @@ -2,10 +2,12 @@ #ifndef _ASM_X86_HWCAP2_H #define _ASM_X86_HWCAP2_H +#include + /* MONITOR/MWAIT enabled in Ring 3 */ -#define HWCAP2_RING3MWAIT (1 << 0) +#define HWCAP2_RING3MWAIT _BITUL(0) /* Kernel allows FSGSBASE instructions available in Ring 3 */ -#define HWCAP2_FSGSBASE BIT(1) +#define HWCAP2_FSGSBASE _BITUL(1) #endif diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 0d4818eab0da..25b1d5c6af96 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -1948,7 +1948,8 @@ static struct irq_chip ioapic_chip __read_mostly = { .irq_set_affinity = ioapic_set_affinity, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_get_irqchip_state = ioapic_irq_get_chip_state, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_AFFINITY_PRE_STARTUP, }; static struct irq_chip ioapic_ir_chip __read_mostly = { @@ -1961,7 +1962,8 @@ static struct irq_chip ioapic_ir_chip __read_mostly = { .irq_set_affinity = ioapic_set_affinity, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_get_irqchip_state = ioapic_irq_get_chip_state, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_AFFINITY_PRE_STARTUP, }; static inline void init_IO_APIC_traps(void) diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c index 6313f0a05db7..6bd98a20fc90 100644 --- a/arch/x86/kernel/apic/msi.c +++ b/arch/x86/kernel/apic/msi.c @@ -86,11 +86,13 @@ msi_set_affinity(struct irq_data *irqd, const struct cpumask *mask, bool force) * The quirk bit is not set in this case. * - The new vector is the same as the old vector * - The old vector is MANAGED_IRQ_SHUTDOWN_VECTOR (interrupt starts up) + * - The interrupt is not yet started up * - The new destination CPU is the same as the old destination CPU */ if (!irqd_msi_nomask_quirk(irqd) || cfg->vector == old_cfg.vector || old_cfg.vector == MANAGED_IRQ_SHUTDOWN_VECTOR || + !irqd_is_started(irqd) || cfg->dest_apicid == old_cfg.dest_apicid) { irq_msi_update_msg(irqd, cfg); return ret; @@ -178,7 +180,8 @@ static struct irq_chip pci_msi_controller = { .irq_ack = irq_chip_ack_parent, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_affinity = msi_set_affinity, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_AFFINITY_PRE_STARTUP, }; int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec, @@ -247,7 +250,8 @@ static struct irq_chip pci_msi_ir_controller = { .irq_mask = pci_msi_mask_irq, .irq_ack = irq_chip_ack_parent, .irq_retrigger = irq_chip_retrigger_hierarchy, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_AFFINITY_PRE_STARTUP, }; static struct msi_domain_info pci_msi_ir_domain_info = { @@ -289,7 +293,8 @@ static struct irq_chip dmar_msi_controller = { .irq_set_affinity = msi_domain_set_affinity, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_write_msi_msg = dmar_msi_write_msg, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | + IRQCHIP_AFFINITY_PRE_STARTUP, }; static int dmar_msi_init(struct irq_domain *domain, @@ -381,7 +386,7 @@ static struct irq_chip hpet_msi_controller __ro_after_init = { .irq_set_affinity = msi_domain_set_affinity, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_write_msi_msg = hpet_msi_write_msg, - .flags = IRQCHIP_SKIP_SET_WAKE, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_AFFINITY_PRE_STARTUP, }; static int hpet_msi_init(struct irq_domain *domain, diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c index a5ee607a3b89..a548d9104604 100644 --- a/arch/x86/kernel/cpu/perfctr-watchdog.c +++ b/arch/x86/kernel/cpu/perfctr-watchdog.c @@ -63,7 +63,7 @@ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) case 15: return msr - MSR_P4_BPU_PERFCTR0; } - fallthrough; + break; case X86_VENDOR_ZHAOXIN: case X86_VENDOR_CENTAUR: return msr - MSR_ARCH_PERFMON_PERFCTR0; @@ -96,7 +96,7 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) case 15: return msr - MSR_P4_BSU_ESCR0; } - fallthrough; + break; case X86_VENDOR_ZHAOXIN: case X86_VENDOR_CENTAUR: return msr - MSR_ARCH_PERFMON_EVENTSEL0; diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index a98519a3a2e6..3075624723b2 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -222,15 +222,14 @@ static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr, unsigned int width) return chunks >>= shift; } -static int __mon_event_count(u32 rmid, struct rmid_read *rr) +static u64 __mon_event_count(u32 rmid, struct rmid_read *rr) { struct mbm_state *m; u64 chunks, tval; tval = __rmid_read(rmid, rr->evtid); if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) { - rr->val = tval; - return -EINVAL; + return tval; } switch (rr->evtid) { case QOS_L3_OCCUP_EVENT_ID: @@ -242,12 +241,6 @@ static int __mon_event_count(u32 rmid, struct rmid_read *rr) case QOS_L3_MBM_LOCAL_EVENT_ID: m = &rr->d->mbm_local[rmid]; break; - default: - /* - * Code would never reach here because - * an invalid event id would fail the __rmid_read. - */ - return -EINVAL; } if (rr->first) { @@ -297,23 +290,29 @@ void mon_event_count(void *info) struct rdtgroup *rdtgrp, *entry; struct rmid_read *rr = info; struct list_head *head; + u64 ret_val; rdtgrp = rr->rgrp; - if (__mon_event_count(rdtgrp->mon.rmid, rr)) - return; + ret_val = __mon_event_count(rdtgrp->mon.rmid, rr); /* - * For Ctrl groups read data from child monitor groups. + * For Ctrl groups read data from child monitor groups and + * add them together. Count events which are read successfully. + * Discard the rmid_read's reporting errors. */ head = &rdtgrp->mon.crdtgrp_list; if (rdtgrp->type == RDTCTRL_GROUP) { list_for_each_entry(entry, head, mon.crdtgrp_list) { - if (__mon_event_count(entry->mon.rmid, rr)) - return; + if (__mon_event_count(entry->mon.rmid, rr) == 0) + ret_val = 0; } } + + /* Report error if none of rmid_reads are successful */ + if (ret_val) + rr->val = ret_val; } /* diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c index c413756ba89f..6bb874441de8 100644 --- a/arch/x86/kernel/fpu/regset.c +++ b/arch/x86/kernel/fpu/regset.c @@ -117,7 +117,7 @@ int xstateregs_set(struct task_struct *target, const struct user_regset *regset, /* * A whole standard-format XSAVE buffer is needed: */ - if ((pos != 0) || (count < fpu_user_xstate_size)) + if (pos != 0 || count != fpu_user_xstate_size) return -EFAULT; xsave = &fpu->state.xsave; diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c index a4ec65317a7f..b7b92cdf3add 100644 --- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -221,28 +221,18 @@ sanitize_restored_user_xstate(union fpregs_state *state, if (use_xsave()) { /* - * Note: we don't need to zero the reserved bits in the - * xstate_header here because we either didn't copy them at all, - * or we checked earlier that they aren't set. + * Clear all feature bits which are not set in + * user_xfeatures and clear all extended features + * for fx_only mode. */ + u64 mask = fx_only ? XFEATURE_MASK_FPSSE : user_xfeatures; /* - * 'user_xfeatures' might have bits clear which are - * set in header->xfeatures. This represents features that - * were in init state prior to a signal delivery, and need - * to be reset back to the init state. Clear any user - * feature bits which are set in the kernel buffer to get - * them back to the init state. - * - * Supervisor state is unchanged by input from userspace. - * Ensure supervisor state bits stay set and supervisor - * state is not modified. + * Supervisor state has to be preserved. The sigframe + * restore can only modify user features, i.e. @mask + * cannot contain them. */ - if (fx_only) - header->xfeatures = XFEATURE_MASK_FPSSE; - else - header->xfeatures &= user_xfeatures | - xfeatures_mask_supervisor(); + header->xfeatures &= mask | xfeatures_mask_supervisor(); } if (use_fxsr()) { @@ -307,13 +297,17 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) return 0; } - if (!access_ok(buf, size)) - return -EACCES; + if (!access_ok(buf, size)) { + ret = -EACCES; + goto out; + } - if (!static_cpu_has(X86_FEATURE_FPU)) - return fpregs_soft_set(current, NULL, - 0, sizeof(struct user_i387_ia32_struct), - NULL, buf) != 0; + if (!static_cpu_has(X86_FEATURE_FPU)) { + ret = fpregs_soft_set(current, NULL, 0, + sizeof(struct user_i387_ia32_struct), + NULL, buf); + goto out; + } if (use_xsave()) { struct _fpx_sw_bytes fx_sw_user; @@ -369,6 +363,25 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) fpregs_unlock(); return 0; } + + /* + * The above did an FPU restore operation, restricted to + * the user portion of the registers, and failed, but the + * microcode might have modified the FPU registers + * nevertheless. + * + * If the FPU registers do not belong to current, then + * invalidate the FPU register state otherwise the task might + * preempt current and return to user space with corrupted + * FPU registers. + * + * In case current owns the FPU registers then no further + * action is required. The fixup below will handle it + * correctly. + */ + if (test_thread_flag(TIF_NEED_FPU_LOAD)) + __cpu_invalidate_fpregs_state(); + fpregs_unlock(); } else { /* @@ -377,7 +390,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) */ ret = __copy_from_user(&env, buf, sizeof(env)); if (ret) - goto err_out; + goto out; envp = &env; } @@ -405,16 +418,9 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) if (use_xsave() && !fx_only) { u64 init_bv = xfeatures_mask_user() & ~user_xfeatures; - if (using_compacted_format()) { - ret = copy_user_to_xstate(&fpu->state.xsave, buf_fx); - } else { - ret = __copy_from_user(&fpu->state.xsave, buf_fx, state_size); - - if (!ret && state_size > offsetof(struct xregs_state, header)) - ret = validate_user_xstate_header(&fpu->state.xsave.header); - } + ret = copy_user_to_xstate(&fpu->state.xsave, buf_fx); if (ret) - goto err_out; + goto out; sanitize_restored_user_xstate(&fpu->state, envp, user_xfeatures, fx_only); @@ -434,7 +440,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) ret = __copy_from_user(&fpu->state.fxsave, buf_fx, state_size); if (ret) { ret = -EFAULT; - goto err_out; + goto out; } sanitize_restored_user_xstate(&fpu->state, envp, user_xfeatures, @@ -452,7 +458,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) } else { ret = __copy_from_user(&fpu->state.fsave, buf_fx, state_size); if (ret) - goto err_out; + goto out; fpregs_lock(); ret = copy_kernel_to_fregs_err(&fpu->state.fsave); @@ -463,7 +469,7 @@ static int __fpu__restore_sig(void __user *buf, void __user *buf_fx, int size) fpregs_deactivate(fpu); fpregs_unlock(); -err_out: +out: if (ret) fpu__clear_user_states(fpu); return ret; diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c index 67f1a03b9b23..80836b94189e 100644 --- a/arch/x86/kernel/fpu/xstate.c +++ b/arch/x86/kernel/fpu/xstate.c @@ -440,6 +440,25 @@ static void __init print_xstate_offset_size(void) } } +/* + * All supported features have either init state all zeros or are + * handled in setup_init_fpu() individually. This is an explicit + * feature list and does not use XFEATURE_MASK*SUPPORTED to catch + * newly added supported features at build time and make people + * actually look at the init state for the new feature. + */ +#define XFEATURES_INIT_FPSTATE_HANDLED \ + (XFEATURE_MASK_FP | \ + XFEATURE_MASK_SSE | \ + XFEATURE_MASK_YMM | \ + XFEATURE_MASK_OPMASK | \ + XFEATURE_MASK_ZMM_Hi256 | \ + XFEATURE_MASK_Hi16_ZMM | \ + XFEATURE_MASK_PKRU | \ + XFEATURE_MASK_BNDREGS | \ + XFEATURE_MASK_BNDCSR | \ + XFEATURE_MASK_PASID) + /* * setup the xstate image representing the init state */ @@ -447,6 +466,10 @@ static void __init setup_init_fpu_buf(void) { static int on_boot_cpu __initdata = 1; + BUILD_BUG_ON((XFEATURE_MASK_USER_SUPPORTED | + XFEATURE_MASK_SUPERVISOR_SUPPORTED) != + XFEATURES_INIT_FPSTATE_HANDLED); + WARN_ON_FPU(!on_boot_cpu); on_boot_cpu = 0; @@ -466,10 +489,22 @@ static void __init setup_init_fpu_buf(void) copy_kernel_to_xregs_booting(&init_fpstate.xsave); /* - * Dump the init state again. This is to identify the init state - * of any feature which is not represented by all zero's. + * All components are now in init state. Read the state back so + * that init_fpstate contains all non-zero init state. This only + * works with XSAVE, but not with XSAVEOPT and XSAVES because + * those use the init optimization which skips writing data for + * components in init state. + * + * XSAVE could be used, but that would require to reshuffle the + * data when XSAVES is available because XSAVES uses xstate + * compaction. But doing so is a pointless exercise because most + * components have an all zeros init state except for the legacy + * ones (FP and SSE). Those can be saved with FXSAVE into the + * legacy area. Adding new features requires to ensure that init + * state is all zeroes or if not to add the necessary handling + * here. */ - copy_xregs_to_kernel_booting(&init_fpstate.xsave); + fxsave(&init_fpstate.fxsave); } static int xfeature_uncompacted_offset(int xfeature_nr) @@ -1049,20 +1084,10 @@ static inline bool xfeatures_mxcsr_quirk(u64 xfeatures) return true; } -static void fill_gap(struct membuf *to, unsigned *last, unsigned offset) -{ - if (*last >= offset) - return; - membuf_write(to, (void *)&init_fpstate.xsave + *last, offset - *last); - *last = offset; -} - -static void copy_part(struct membuf *to, unsigned *last, unsigned offset, - unsigned size, void *from) +static void copy_feature(bool from_xstate, struct membuf *to, void *xstate, + void *init_xstate, unsigned int size) { - fill_gap(to, last, offset); - membuf_write(to, from, size); - *last = offset + size; + membuf_write(to, from_xstate ? xstate : init_xstate, size); } /* @@ -1074,10 +1099,10 @@ static void copy_part(struct membuf *to, unsigned *last, unsigned offset, */ void copy_xstate_to_kernel(struct membuf to, struct xregs_state *xsave) { + const unsigned int off_mxcsr = offsetof(struct fxregs_state, mxcsr); + struct xregs_state *xinit = &init_fpstate.xsave; struct xstate_header header; - const unsigned off_mxcsr = offsetof(struct fxregs_state, mxcsr); - unsigned size = to.left; - unsigned last = 0; + unsigned int zerofrom; int i; /* @@ -1087,41 +1112,68 @@ void copy_xstate_to_kernel(struct membuf to, struct xregs_state *xsave) header.xfeatures = xsave->header.xfeatures; header.xfeatures &= xfeatures_mask_user(); - if (header.xfeatures & XFEATURE_MASK_FP) - copy_part(&to, &last, 0, off_mxcsr, &xsave->i387); - if (header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM)) - copy_part(&to, &last, off_mxcsr, - MXCSR_AND_FLAGS_SIZE, &xsave->i387.mxcsr); - if (header.xfeatures & XFEATURE_MASK_FP) - copy_part(&to, &last, offsetof(struct fxregs_state, st_space), - 128, &xsave->i387.st_space); - if (header.xfeatures & XFEATURE_MASK_SSE) - copy_part(&to, &last, xstate_offsets[XFEATURE_SSE], - 256, &xsave->i387.xmm_space); - /* - * Fill xsave->i387.sw_reserved value for ptrace frame: - */ - copy_part(&to, &last, offsetof(struct fxregs_state, sw_reserved), - 48, xstate_fx_sw_bytes); - /* - * Copy xregs_state->header: - */ - copy_part(&to, &last, offsetof(struct xregs_state, header), - sizeof(header), &header); + /* Copy FP state up to MXCSR */ + copy_feature(header.xfeatures & XFEATURE_MASK_FP, &to, &xsave->i387, + &xinit->i387, off_mxcsr); + + /* Copy MXCSR when SSE or YMM are set in the feature mask */ + copy_feature(header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM), + &to, &xsave->i387.mxcsr, &xinit->i387.mxcsr, + MXCSR_AND_FLAGS_SIZE); + + /* Copy the remaining FP state */ + copy_feature(header.xfeatures & XFEATURE_MASK_FP, + &to, &xsave->i387.st_space, &xinit->i387.st_space, + sizeof(xsave->i387.st_space)); + + /* Copy the SSE state - shared with YMM, but independently managed */ + copy_feature(header.xfeatures & XFEATURE_MASK_SSE, + &to, &xsave->i387.xmm_space, &xinit->i387.xmm_space, + sizeof(xsave->i387.xmm_space)); + + /* Zero the padding area */ + membuf_zero(&to, sizeof(xsave->i387.padding)); + + /* Copy xsave->i387.sw_reserved */ + membuf_write(&to, xstate_fx_sw_bytes, sizeof(xsave->i387.sw_reserved)); + + /* Copy the user space relevant state of @xsave->header */ + membuf_write(&to, &header, sizeof(header)); + + zerofrom = offsetof(struct xregs_state, extended_state_area); for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) { /* - * Copy only in-use xstates: + * The ptrace buffer is in non-compacted XSAVE format. + * In non-compacted format disabled features still occupy + * state space, but there is no state to copy from in the + * compacted init_fpstate. The gap tracking will zero this + * later. + */ + if (!(xfeatures_mask_user() & BIT_ULL(i))) + continue; + + /* + * If there was a feature or alignment gap, zero the space + * in the destination buffer. */ - if ((header.xfeatures >> i) & 1) { - void *src = __raw_xsave_addr(xsave, i); + if (zerofrom < xstate_offsets[i]) + membuf_zero(&to, xstate_offsets[i] - zerofrom); - copy_part(&to, &last, xstate_offsets[i], - xstate_sizes[i], src); - } + copy_feature(header.xfeatures & BIT_ULL(i), &to, + __raw_xsave_addr(xsave, i), + __raw_xsave_addr(xinit, i), + xstate_sizes[i]); + /* + * Keep track of the last copied state in the non-compacted + * target buffer for gap zeroing. + */ + zerofrom = xstate_offsets[i] + xstate_sizes[i]; } - fill_gap(&to, &last, size); + + if (to.left) + membuf_zero(&to, to.left); } /* diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 28c89fce0dab..9497bebb9b2e 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1054,6 +1054,12 @@ void __init setup_arch(char **cmdline_p) memblock_set_current_limit(ISA_END_ADDRESS); e820__memblock_setup(); + /* + * Needs to run after memblock setup because it needs the physical + * memory size. + */ + sev_setup_arch(); + reserve_bios_regions(); efi_fake_memmap(); diff --git a/arch/x86/kernel/sev-es.c b/arch/x86/kernel/sev-es.c index e0cdab7cb632..f3202b2e3c15 100644 --- a/arch/x86/kernel/sev-es.c +++ b/arch/x86/kernel/sev-es.c @@ -12,7 +12,6 @@ #include /* For show_regs() */ #include #include -#include #include #include #include @@ -180,11 +179,19 @@ void noinstr __sev_es_ist_exit(void) this_cpu_write(cpu_tss_rw.x86_tss.ist[IST_INDEX_VC], *(unsigned long *)ist); } -static __always_inline struct ghcb *sev_es_get_ghcb(struct ghcb_state *state) +/* + * Nothing shall interrupt this code path while holding the per-CPU + * GHCB. The backup GHCB is only for NMIs interrupting this path. + * + * Callers must disable local interrupts around it. + */ +static noinstr struct ghcb *__sev_get_ghcb(struct ghcb_state *state) { struct sev_es_runtime_data *data; struct ghcb *ghcb; + WARN_ON(!irqs_disabled()); + data = this_cpu_read(runtime_data); ghcb = &data->ghcb_page; @@ -201,7 +208,9 @@ static __always_inline struct ghcb *sev_es_get_ghcb(struct ghcb_state *state) data->ghcb_active = false; data->backup_ghcb_active = false; + instrumentation_begin(); panic("Unable to handle #VC exception! GHCB and Backup GHCB are already in use"); + instrumentation_end(); } /* Mark backup_ghcb active before writing to it */ @@ -452,11 +461,13 @@ static enum es_result vc_slow_virt_to_phys(struct ghcb *ghcb, struct es_em_ctxt /* Include code shared with pre-decompression boot stage */ #include "sev-es-shared.c" -static __always_inline void sev_es_put_ghcb(struct ghcb_state *state) +static noinstr void __sev_put_ghcb(struct ghcb_state *state) { struct sev_es_runtime_data *data; struct ghcb *ghcb; + WARN_ON(!irqs_disabled()); + data = this_cpu_read(runtime_data); ghcb = &data->ghcb_page; @@ -480,7 +491,7 @@ void noinstr __sev_es_nmi_complete(void) struct ghcb_state state; struct ghcb *ghcb; - ghcb = sev_es_get_ghcb(&state); + ghcb = __sev_get_ghcb(&state); vc_ghcb_invalidate(ghcb); ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_NMI_COMPLETE); @@ -490,7 +501,7 @@ void noinstr __sev_es_nmi_complete(void) sev_es_wr_ghcb_msr(__pa_nodebug(ghcb)); VMGEXIT(); - sev_es_put_ghcb(&state); + __sev_put_ghcb(&state); } static u64 get_jump_table_addr(void) @@ -502,7 +513,7 @@ static u64 get_jump_table_addr(void) local_irq_save(flags); - ghcb = sev_es_get_ghcb(&state); + ghcb = __sev_get_ghcb(&state); vc_ghcb_invalidate(ghcb); ghcb_set_sw_exit_code(ghcb, SVM_VMGEXIT_AP_JUMP_TABLE); @@ -516,7 +527,7 @@ static u64 get_jump_table_addr(void) ghcb_sw_exit_info_2_is_valid(ghcb)) ret = ghcb->save.sw_exit_info_2; - sev_es_put_ghcb(&state); + __sev_put_ghcb(&state); local_irq_restore(flags); @@ -641,7 +652,7 @@ static void sev_es_ap_hlt_loop(void) struct ghcb_state state; struct ghcb *ghcb; - ghcb = sev_es_get_ghcb(&state); + ghcb = __sev_get_ghcb(&state); while (true) { vc_ghcb_invalidate(ghcb); @@ -658,7 +669,7 @@ static void sev_es_ap_hlt_loop(void) break; } - sev_es_put_ghcb(&state); + __sev_put_ghcb(&state); } /* @@ -748,7 +759,7 @@ void __init sev_es_init_vc_handling(void) sev_es_setup_play_dead(); /* Secondary CPUs use the runtime #VC handler */ - initial_vc_handler = (unsigned long)safe_stack_exc_vmm_communication; + initial_vc_handler = (unsigned long)kernel_exc_vmm_communication; } static void __init vc_early_forward_exception(struct es_em_ctxt *ctxt) @@ -1186,14 +1197,6 @@ static enum es_result vc_handle_trap_ac(struct ghcb *ghcb, return ES_EXCEPTION; } -static __always_inline void vc_handle_trap_db(struct pt_regs *regs) -{ - if (user_mode(regs)) - noist_exc_debug(regs); - else - exc_debug(regs); -} - static enum es_result vc_handle_exitcode(struct es_em_ctxt *ctxt, struct ghcb *ghcb, unsigned long exit_code) @@ -1289,44 +1292,15 @@ static __always_inline bool on_vc_fallback_stack(struct pt_regs *regs) return (sp >= __this_cpu_ist_bottom_va(VC2) && sp < __this_cpu_ist_top_va(VC2)); } -/* - * Main #VC exception handler. It is called when the entry code was able to - * switch off the IST to a safe kernel stack. - * - * With the current implementation it is always possible to switch to a safe - * stack because #VC exceptions only happen at known places, like intercepted - * instructions or accesses to MMIO areas/IO ports. They can also happen with - * code instrumentation when the hypervisor intercepts #DB, but the critical - * paths are forbidden to be instrumented, so #DB exceptions currently also - * only happen in safe places. - */ -DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) +static bool vc_raw_handle_exception(struct pt_regs *regs, unsigned long error_code) { - irqentry_state_t irq_state; struct ghcb_state state; struct es_em_ctxt ctxt; enum es_result result; struct ghcb *ghcb; + bool ret = true; - /* - * Handle #DB before calling into !noinstr code to avoid recursive #DB. - */ - if (error_code == SVM_EXIT_EXCP_BASE + X86_TRAP_DB) { - vc_handle_trap_db(regs); - return; - } - - irq_state = irqentry_nmi_enter(regs); - lockdep_assert_irqs_disabled(); - instrumentation_begin(); - - /* - * This is invoked through an interrupt gate, so IRQs are disabled. The - * code below might walk page-tables for user or kernel addresses, so - * keep the IRQs disabled to protect us against concurrent TLB flushes. - */ - - ghcb = sev_es_get_ghcb(&state); + ghcb = __sev_get_ghcb(&state); vc_ghcb_invalidate(ghcb); result = vc_init_em_ctxt(&ctxt, regs, error_code); @@ -1334,7 +1308,7 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) if (result == ES_OK) result = vc_handle_exitcode(&ctxt, ghcb, error_code); - sev_es_put_ghcb(&state); + __sev_put_ghcb(&state); /* Done - now check the result */ switch (result) { @@ -1344,15 +1318,18 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) case ES_UNSUPPORTED: pr_err_ratelimited("Unsupported exit-code 0x%02lx in early #VC exception (IP: 0x%lx)\n", error_code, regs->ip); - goto fail; + ret = false; + break; case ES_VMM_ERROR: pr_err_ratelimited("Failure in communication with VMM (exit-code 0x%02lx IP: 0x%lx)\n", error_code, regs->ip); - goto fail; + ret = false; + break; case ES_DECODE_FAILED: pr_err_ratelimited("Failed to decode instruction (exit-code 0x%02lx IP: 0x%lx)\n", error_code, regs->ip); - goto fail; + ret = false; + break; case ES_EXCEPTION: vc_forward_exception(&ctxt); break; @@ -1368,24 +1345,52 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) BUG(); } -out: - instrumentation_end(); - irqentry_nmi_exit(regs, irq_state); + return ret; +} - return; +static __always_inline bool vc_is_db(unsigned long error_code) +{ + return error_code == SVM_EXIT_EXCP_BASE + X86_TRAP_DB; +} -fail: - if (user_mode(regs)) { - /* - * Do not kill the machine if user-space triggered the - * exception. Send SIGBUS instead and let user-space deal with - * it. - */ - force_sig_fault(SIGBUS, BUS_OBJERR, (void __user *)0); - } else { - pr_emerg("PANIC: Unhandled #VC exception in kernel space (result=%d)\n", - result); +/* + * Runtime #VC exception handler when raised from kernel mode. Runs in NMI mode + * and will panic when an error happens. + */ +DEFINE_IDTENTRY_VC_KERNEL(exc_vmm_communication) +{ + irqentry_state_t irq_state; + /* + * With the current implementation it is always possible to switch to a + * safe stack because #VC exceptions only happen at known places, like + * intercepted instructions or accesses to MMIO areas/IO ports. They can + * also happen with code instrumentation when the hypervisor intercepts + * #DB, but the critical paths are forbidden to be instrumented, so #DB + * exceptions currently also only happen in safe places. + * + * But keep this here in case the noinstr annotations are violated due + * to bug elsewhere. + */ + if (unlikely(on_vc_fallback_stack(regs))) { + instrumentation_begin(); + panic("Can't handle #VC exception from unsupported context\n"); + instrumentation_end(); + } + + /* + * Handle #DB before calling into !noinstr code to avoid recursive #DB. + */ + if (vc_is_db(error_code)) { + exc_debug(regs); + return; + } + + irq_state = irqentry_nmi_enter(regs); + + instrumentation_begin(); + + if (!vc_raw_handle_exception(regs, error_code)) { /* Show some debug info */ show_regs(regs); @@ -1396,23 +1401,38 @@ DEFINE_IDTENTRY_VC_SAFE_STACK(exc_vmm_communication) panic("Returned from Terminate-Request to Hypervisor\n"); } - goto out; + instrumentation_end(); + irqentry_nmi_exit(regs, irq_state); } -/* This handler runs on the #VC fall-back stack. It can cause further #VC exceptions */ -DEFINE_IDTENTRY_VC_IST(exc_vmm_communication) +/* + * Runtime #VC exception handler when raised from user mode. Runs in IRQ mode + * and will kill the current task with SIGBUS when an error happens. + */ +DEFINE_IDTENTRY_VC_USER(exc_vmm_communication) { + /* + * Handle #DB before calling into !noinstr code to avoid recursive #DB. + */ + if (vc_is_db(error_code)) { + noist_exc_debug(regs); + return; + } + + irqentry_enter_from_user_mode(regs); instrumentation_begin(); - panic("Can't handle #VC exception from unsupported context\n"); - instrumentation_end(); -} -DEFINE_IDTENTRY_VC(exc_vmm_communication) -{ - if (likely(!on_vc_fallback_stack(regs))) - safe_stack_exc_vmm_communication(regs, error_code); - else - ist_exc_vmm_communication(regs, error_code); + if (!vc_raw_handle_exception(regs, error_code)) { + /* + * Do not kill the machine if user-space triggered the + * exception. Send SIGBUS instead and let user-space deal with + * it. + */ + force_sig_fault(SIGBUS, BUS_OBJERR, (void __user *)0); + } + + instrumentation_end(); + irqentry_exit_to_user_mode(regs); } bool __init handle_vc_boot_ghcb(struct pt_regs *regs) diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index f51cab3e983d..b001ba811cab 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c @@ -234,10 +234,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, void __user **fpstate) { /* Default to using normal stack */ + bool nested_altstack = on_sig_stack(regs->sp); + bool entering_altstack = false; unsigned long math_size = 0; unsigned long sp = regs->sp; unsigned long buf_fx = 0; - int onsigstack = on_sig_stack(sp); int ret; /* redzone */ @@ -246,15 +247,23 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, /* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { - if (sas_ss_flags(sp) == 0) + /* + * This checks nested_altstack via sas_ss_flags(). Sensible + * programs use SS_AUTODISARM, which disables that check, and + * programs that don't use SS_AUTODISARM get compatible. + */ + if (sas_ss_flags(sp) == 0) { sp = current->sas_ss_sp + current->sas_ss_size; + entering_altstack = true; + } } else if (IS_ENABLED(CONFIG_X86_32) && - !onsigstack && + !nested_altstack && regs->ss != __USER_DS && !(ka->sa.sa_flags & SA_RESTORER) && ka->sa.sa_restorer) { /* This is the legacy signal stack switching. */ sp = (unsigned long) ka->sa.sa_restorer; + entering_altstack = true; } sp = fpu__alloc_mathframe(sp, IS_ENABLED(CONFIG_X86_32), @@ -267,8 +276,15 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, * If we are on the alternate signal stack and would overflow it, don't. * Return an always-bogus address instead so we will die with SIGSEGV. */ - if (onsigstack && !likely(on_sig_stack(sp))) + if (unlikely((nested_altstack || entering_altstack) && + !__on_sig_stack(sp))) { + + if (show_unhandled_signals && printk_ratelimit()) + pr_info("%s[%d] overflowed sigaltstack\n", + current->comm, task_pid_nr(current)); + return (void __user *)-1L; + } /* save i387 and extended state */ ret = copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size); diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 582387fc939f..8baff500914e 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -230,7 +230,6 @@ static void notrace start_secondary(void *unused) cpu_init_exception_handling(); cpu_init(); x86_cpuinit.early_percpu_clock_init(); - preempt_disable(); smp_callin(); enable_start_cpu0 = 0; diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c index f70dffc2771f..56289170753c 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c @@ -1151,7 +1151,8 @@ static struct clocksource clocksource_tsc = { .mask = CLOCKSOURCE_MASK(64), .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_VALID_FOR_HRES | - CLOCK_SOURCE_MUST_VERIFY, + CLOCK_SOURCE_MUST_VERIFY | + CLOCK_SOURCE_VERIFY_PERCPU, .vdso_clock_mode = VDSO_CLOCKMODE_TSC, .enable = tsc_cs_enable, .resume = tsc_resume, diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 56a62d555e92..41b0dc37720e 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -684,7 +684,8 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) edx.split.num_counters_fixed = min(cap.num_counters_fixed, MAX_FIXED_COUNTERS); edx.split.bit_width_fixed = cap.bit_width_fixed; - edx.split.anythread_deprecated = 1; + if (cap.version) + edx.split.anythread_deprecated = 1; edx.split.reserved1 = 0; edx.split.reserved2 = 0; @@ -827,8 +828,14 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U); unsigned phys_as = entry->eax & 0xff; - if (!g_phys_as) + /* + * Use bare metal's MAXPHADDR if the CPU doesn't report guest + * MAXPHYADDR separately, or if TDP (NPT) is disabled, as the + * guest version "applies only to guests using nested paging". + */ + if (!g_phys_as || !tdp_enabled) g_phys_as = phys_as; + entry->eax = g_phys_as | (virt_as << 8); entry->edx = 0; cpuid_entry_override(entry, CPUID_8000_0008_EBX); diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 5c7c4060b45c..bb39f493447c 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -1564,7 +1564,7 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *current_vcpu, u64 ingpa, * vcpu->arch.cr3 may not be up-to-date for running vCPUs so we can't * analyze it here, flush TLB regardless of the specified address space. */ - kvm_make_vcpus_request_mask(kvm, KVM_REQ_HV_TLB_FLUSH, + kvm_make_vcpus_request_mask(kvm, KVM_REQ_TLB_FLUSH_GUEST, NULL, vcpu_mask, &hv_vcpu->tlb_flush); ret_success: diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index 698969e18fe3..ff005fe738a4 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c @@ -96,7 +96,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic) { ioapic->rtc_status.pending_eoi = 0; - bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID); + bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID + 1); } static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic); diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h index 660401700075..11e4065e1617 100644 --- a/arch/x86/kvm/ioapic.h +++ b/arch/x86/kvm/ioapic.h @@ -43,13 +43,13 @@ struct kvm_vcpu; struct dest_map { /* vcpu bitmap where IRQ has been sent */ - DECLARE_BITMAP(map, KVM_MAX_VCPU_ID); + DECLARE_BITMAP(map, KVM_MAX_VCPU_ID + 1); /* * Vector sent to a given vcpu, only valid when * the vcpu's bit in map is set */ - u8 vectors[KVM_MAX_VCPU_ID]; + u8 vectors[KVM_MAX_VCPU_ID + 1]; }; diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 5759eb075d2f..677d21082454 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1405,6 +1405,9 @@ int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len, if (!apic_x2apic_mode(apic)) valid_reg_mask |= APIC_REG_MASK(APIC_ARBPRI); + if (alignment + len > 4) + return 1; + if (offset > 0x3f0 || !(valid_reg_mask & APIC_REG_MASK(offset))) return 1; diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index ac5054763e38..5e25d93ec7d0 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -52,6 +52,8 @@ #include #include "trace.h" +#include "paging.h" + extern bool itlb_multihit_kvm_mitigation; static int __read_mostly nx_huge_pages = -1; @@ -1619,7 +1621,7 @@ static int is_empty_shadow_page(u64 *spt) * aggregate version in order to make the slab shrinker * faster */ -static inline void kvm_mod_used_mmu_pages(struct kvm *kvm, unsigned long nr) +static inline void kvm_mod_used_mmu_pages(struct kvm *kvm, long nr) { kvm->arch.n_used_mmu_pages += nr; percpu_counter_add(&kvm_total_used_mmu_pages, nr); @@ -4133,7 +4135,15 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu, void reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context) { - bool uses_nx = context->nx || + /* + * KVM uses NX when TDP is disabled to handle a variety of scenarios, + * notably for huge SPTEs if iTLB multi-hit mitigation is enabled and + * to generate correct permissions for CR0.WP=0/CR4.SMEP=1/EFER.NX=0. + * The iTLB multi-hit workaround can be toggled at any time, so assume + * NX can be used by any non-nested shadow MMU to avoid having to reset + * MMU contexts. Note, KVM forces EFER.NX=1 when TDP is disabled. + */ + bool uses_nx = context->nx || !tdp_enabled || context->mmu_role.base.smep_andnot_wp; struct rsvd_bits_validate *shadow_zero_check; int i; @@ -4442,6 +4452,7 @@ static union kvm_mmu_extended_role kvm_calc_mmu_role_ext(struct kvm_vcpu *vcpu) ext.cr4_smap = !!kvm_read_cr4_bits(vcpu, X86_CR4_SMAP); ext.cr4_pse = !!is_pse(vcpu); ext.cr4_pke = !!kvm_read_cr4_bits(vcpu, X86_CR4_PKE); + ext.cr4_la57 = !!kvm_read_cr4_bits(vcpu, X86_CR4_LA57); ext.maxphyaddr = cpuid_maxphyaddr(vcpu); ext.valid = 1; @@ -4705,9 +4716,33 @@ static void init_kvm_softmmu(struct kvm_vcpu *vcpu) context->inject_page_fault = kvm_inject_page_fault; } +static union kvm_mmu_role kvm_calc_nested_mmu_role(struct kvm_vcpu *vcpu) +{ + union kvm_mmu_role role = kvm_calc_shadow_root_page_role_common(vcpu, false); + + /* + * Nested MMUs are used only for walking L2's gva->gpa, they never have + * shadow pages of their own and so "direct" has no meaning. Set it + * to "true" to try to detect bogus usage of the nested MMU. + */ + role.base.direct = true; + + if (!is_paging(vcpu)) + role.base.level = 0; + else if (is_long_mode(vcpu)) + role.base.level = is_la57_mode(vcpu) ? PT64_ROOT_5LEVEL : + PT64_ROOT_4LEVEL; + else if (is_pae(vcpu)) + role.base.level = PT32E_ROOT_LEVEL; + else + role.base.level = PT32_ROOT_LEVEL; + + return role; +} + static void init_kvm_nested_mmu(struct kvm_vcpu *vcpu) { - union kvm_mmu_role new_role = kvm_calc_mmu_role_common(vcpu, false); + union kvm_mmu_role new_role = kvm_calc_nested_mmu_role(vcpu); struct kvm_mmu *g_context = &vcpu->arch.nested_mmu; if (new_role.as_u64 == g_context->mmu_role.as_u64) diff --git a/arch/x86/kvm/mmu/paging.h b/arch/x86/kvm/mmu/paging.h new file mode 100644 index 000000000000..de8ab323bb70 --- /dev/null +++ b/arch/x86/kvm/mmu/paging.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Shadow paging constants/helpers that don't need to be #undef'd. */ +#ifndef __KVM_X86_PAGING_H +#define __KVM_X86_PAGING_H + +#define GUEST_PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) +#define PT64_LVL_ADDR_MASK(level) \ + (GUEST_PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \ + * PT64_LEVEL_BITS))) - 1)) +#define PT64_LVL_OFFSET_MASK(level) \ + (GUEST_PT64_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \ + * PT64_LEVEL_BITS))) - 1)) +#endif /* __KVM_X86_PAGING_H */ + diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h index 50e268eb8e1a..f8829134bf34 100644 --- a/arch/x86/kvm/mmu/paging_tmpl.h +++ b/arch/x86/kvm/mmu/paging_tmpl.h @@ -24,7 +24,7 @@ #define pt_element_t u64 #define guest_walker guest_walker64 #define FNAME(name) paging##64_##name - #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK + #define PT_BASE_ADDR_MASK GUEST_PT64_BASE_ADDR_MASK #define PT_LVL_ADDR_MASK(lvl) PT64_LVL_ADDR_MASK(lvl) #define PT_LVL_OFFSET_MASK(lvl) PT64_LVL_OFFSET_MASK(lvl) #define PT_INDEX(addr, level) PT64_INDEX(addr, level) @@ -57,7 +57,7 @@ #define pt_element_t u64 #define guest_walker guest_walkerEPT #define FNAME(name) ept_##name - #define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK + #define PT_BASE_ADDR_MASK GUEST_PT64_BASE_ADDR_MASK #define PT_LVL_ADDR_MASK(lvl) PT64_LVL_ADDR_MASK(lvl) #define PT_LVL_OFFSET_MASK(lvl) PT64_LVL_OFFSET_MASK(lvl) #define PT_INDEX(addr, level) PT64_INDEX(addr, level) @@ -90,8 +90,8 @@ struct guest_walker { gpa_t pte_gpa[PT_MAX_FULL_LEVELS]; pt_element_t __user *ptep_user[PT_MAX_FULL_LEVELS]; bool pte_writable[PT_MAX_FULL_LEVELS]; - unsigned pt_access; - unsigned pte_access; + unsigned int pt_access[PT_MAX_FULL_LEVELS]; + unsigned int pte_access; gfn_t gfn; struct x86_exception fault; }; @@ -418,13 +418,15 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, } walker->ptes[walker->level - 1] = pte; + + /* Convert to ACC_*_MASK flags for struct guest_walker. */ + walker->pt_access[walker->level - 1] = FNAME(gpte_access)(pt_access ^ walk_nx_mask); } while (!is_last_gpte(mmu, walker->level, pte)); pte_pkey = FNAME(gpte_pkeys)(vcpu, pte); accessed_dirty = have_ad ? pte_access & PT_GUEST_ACCESSED_MASK : 0; /* Convert to ACC_*_MASK flags for struct guest_walker. */ - walker->pt_access = FNAME(gpte_access)(pt_access ^ walk_nx_mask); walker->pte_access = FNAME(gpte_access)(pte_access ^ walk_nx_mask); errcode = permission_fault(vcpu, mmu, walker->pte_access, pte_pkey, access); if (unlikely(errcode)) @@ -463,13 +465,13 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, } pgprintk("%s: pte %llx pte_access %x pt_access %x\n", - __func__, (u64)pte, walker->pte_access, walker->pt_access); + __func__, (u64)pte, walker->pte_access, + walker->pt_access[walker->level - 1]); return 1; error: errcode |= write_fault | user_fault; - if (fetch_fault && (mmu->nx || - kvm_read_cr4_bits(vcpu, X86_CR4_SMEP))) + if (fetch_fault && (mmu->nx || mmu->mmu_role.ext.cr4_smep)) errcode |= PFERR_FETCH_MASK; walker->fault.vector = PF_VECTOR; @@ -635,7 +637,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr, bool huge_page_disallowed = exec && nx_huge_page_workaround_enabled; struct kvm_mmu_page *sp = NULL; struct kvm_shadow_walk_iterator it; - unsigned direct_access, access = gw->pt_access; + unsigned int direct_access, access; int top_level, level, req_level, ret; gfn_t base_gfn = gw->gfn; @@ -667,6 +669,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gpa_t addr, sp = NULL; if (!is_shadow_present_pte(*it.sptep)) { table_gfn = gw->table_gfn[it.level - 2]; + access = gw->pt_access[it.level - 2]; sp = kvm_mmu_get_page(vcpu, table_gfn, addr, it.level-1, false, access); } diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h index 2b3a30bd38b0..667f207d3d09 100644 --- a/arch/x86/kvm/mmu/spte.h +++ b/arch/x86/kvm/mmu/spte.h @@ -23,12 +23,6 @@ #else #define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) #endif -#define PT64_LVL_ADDR_MASK(level) \ - (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + (((level) - 1) \ - * PT64_LEVEL_BITS))) - 1)) -#define PT64_LVL_OFFSET_MASK(level) \ - (PT64_BASE_ADDR_MASK & ((1ULL << (PAGE_SHIFT + (((level) - 1) \ - * PT64_LEVEL_BITS))) - 1)) #define PT64_PERM_MASK (PT_PRESENT_MASK | PT_WRITABLE_MASK | shadow_user_mask \ | shadow_x_mask | shadow_nx_mask | shadow_me_mask) diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c index 61c00f8631f1..f2ddf663e72e 100644 --- a/arch/x86/kvm/mmu/tdp_mmu.c +++ b/arch/x86/kvm/mmu/tdp_mmu.c @@ -527,7 +527,7 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu, int write, kvm_pfn_t pfn, bool prefault) { u64 new_spte; - int ret = 0; + int ret = RET_PF_FIXED; int make_spte_ret = 0; if (unlikely(is_noslot_pfn(pfn))) { diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index da6ce73c10bb..df17146e841f 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -147,6 +147,9 @@ void recalc_intercepts(struct vcpu_svm *svm) for (i = 0; i < MAX_INTERCEPT; i++) c->intercepts[i] |= g->intercepts[i]; + + vmcb_set_intercept(c, INTERCEPT_VMLOAD); + vmcb_set_intercept(c, INTERCEPT_VMSAVE); } static void copy_vmcb_control_area(struct vmcb_control_area *dst, @@ -429,7 +432,10 @@ static void nested_prepare_vmcb_save(struct vcpu_svm *svm, struct vmcb *vmcb12) static void nested_prepare_vmcb_control(struct vcpu_svm *svm) { - const u32 mask = V_INTR_MASKING_MASK | V_GIF_ENABLE_MASK | V_GIF_MASK; + const u32 int_ctl_vmcb01_bits = + V_INTR_MASKING_MASK | V_GIF_MASK | V_GIF_ENABLE_MASK; + + const u32 int_ctl_vmcb12_bits = V_TPR_MASK | V_IRQ_INJECTION_BITS_MASK; if (nested_npt_enabled(svm)) nested_svm_init_mmu_context(&svm->vcpu); @@ -437,9 +443,9 @@ static void nested_prepare_vmcb_control(struct vcpu_svm *svm) svm->vmcb->control.tsc_offset = svm->vcpu.arch.tsc_offset = svm->vcpu.arch.l1_tsc_offset + svm->nested.ctl.tsc_offset; - svm->vmcb->control.int_ctl = - (svm->nested.ctl.int_ctl & ~mask) | - (svm->nested.hsave->control.int_ctl & mask); + svm->vmcb->control.int_ctl = + (svm->nested.ctl.int_ctl & int_ctl_vmcb12_bits) | + (svm->nested.hsave->control.int_ctl & int_ctl_vmcb01_bits); svm->vmcb->control.virt_ext = svm->nested.ctl.virt_ext; svm->vmcb->control.int_vector = svm->nested.ctl.int_vector; diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 16b10b9436dc..6c82ef22985d 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -124,15 +124,31 @@ static void sev_asid_free(int asid) for_each_possible_cpu(cpu) { sd = per_cpu(svm_data, cpu); - sd->sev_vmcbs[pos] = NULL; + sd->sev_vmcbs[asid] = NULL; } mutex_unlock(&sev_bitmap_lock); } -static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) +static void sev_decommission(unsigned int handle) { struct sev_data_decommission *decommission; + + if (!handle) + return; + + decommission = kzalloc(sizeof(*decommission), GFP_KERNEL); + if (!decommission) + return; + + decommission->handle = handle; + sev_guest_decommission(decommission, NULL); + + kfree(decommission); +} + +static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) +{ struct sev_data_deactivate *data; if (!handle) @@ -152,15 +168,7 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) kfree(data); - decommission = kzalloc(sizeof(*decommission), GFP_KERNEL); - if (!decommission) - return; - - /* decommission handle */ - decommission->handle = handle; - sev_guest_decommission(decommission, NULL); - - kfree(decommission); + sev_decommission(handle); } static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) @@ -288,8 +296,10 @@ static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) /* Bind ASID to this guest */ ret = sev_bind_asid(kvm, start->handle, error); - if (ret) + if (ret) { + sev_decommission(start->handle); goto e_free_session; + } /* return handle to userspace */ params.handle = start->handle; diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 41d44fb5f753..1c23aee3778c 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1486,17 +1486,17 @@ static void svm_set_vintr(struct vcpu_svm *svm) static void svm_clear_vintr(struct vcpu_svm *svm) { - const u32 mask = V_TPR_MASK | V_GIF_ENABLE_MASK | V_GIF_MASK | V_INTR_MASKING_MASK; svm_clr_intercept(svm, INTERCEPT_VINTR); /* Drop int_ctl fields related to VINTR injection. */ - svm->vmcb->control.int_ctl &= mask; + svm->vmcb->control.int_ctl &= ~V_IRQ_INJECTION_BITS_MASK; if (is_guest_mode(&svm->vcpu)) { - svm->nested.hsave->control.int_ctl &= mask; + svm->nested.hsave->control.int_ctl &= ~V_IRQ_INJECTION_BITS_MASK; WARN_ON((svm->vmcb->control.int_ctl & V_TPR_MASK) != (svm->nested.ctl.int_ctl & V_TPR_MASK)); - svm->vmcb->control.int_ctl |= svm->nested.ctl.int_ctl & ~mask; + svm->vmcb->control.int_ctl |= svm->nested.ctl.int_ctl & + V_IRQ_INJECTION_BITS_MASK; } vmcb_mark_dirty(svm->vmcb, VMCB_INTR); @@ -2745,7 +2745,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) svm_disable_lbrv(vcpu); break; case MSR_VM_HSAVE_PA: - svm->nested.hsave_msr = data; + /* + * Old kernels did not validate the value written to + * MSR_VM_HSAVE_PA. Allow KVM_SET_MSR to set an invalid + * value to allow live migrating buggy or malicious guests + * originating from those kernels. + */ + if (!msr->host_initiated && !page_address_valid(vcpu, data)) + return 1; + + svm->nested.hsave_msr = data & PAGE_MASK; break; case MSR_VM_CR: return svm_set_vm_cr(vcpu, data); diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index aef960f90f26..a2835d784f4b 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -1514,16 +1514,16 @@ TRACE_EVENT(kvm_nested_vmenter_failed, TP_ARGS(msg, err), TP_STRUCT__entry( - __field(const char *, msg) + __string(msg, msg) __field(u32, err) ), TP_fast_assign( - __entry->msg = msg; + __assign_str(msg, msg); __entry->err = err; ), - TP_printk("%s%s", __entry->msg, !__entry->err ? "" : + TP_printk("%s%s", __get_str(msg), !__entry->err ? "" : __print_symbolic(__entry->err, VMX_VMENTER_INSTRUCTION_ERRORS)) ); diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 32e6f33c2c45..e0c7910207c0 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -1142,12 +1142,19 @@ static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3, bool ne /* * Unconditionally skip the TLB flush on fast CR3 switch, all TLB - * flushes are handled by nested_vmx_transition_tlb_flush(). See - * nested_vmx_transition_mmu_sync for details on skipping the MMU sync. + * flushes are handled by nested_vmx_transition_tlb_flush(). */ - if (!nested_ept) - kvm_mmu_new_pgd(vcpu, cr3, true, - !nested_vmx_transition_mmu_sync(vcpu)); + if (!nested_ept) { + kvm_mmu_new_pgd(vcpu, cr3, true, true); + + /* + * A TLB flush on VM-Enter/VM-Exit flushes all linear mappings + * across all PCIDs, i.e. all PGDs need to be synchronized. + * See nested_vmx_transition_mmu_sync() for more details. + */ + if (nested_vmx_transition_mmu_sync(vcpu)) + kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu); + } vcpu->arch.cr3 = cr3; kvm_register_mark_available(vcpu, VCPU_EXREG_CR3); @@ -5477,8 +5484,6 @@ static int nested_vmx_eptp_switching(struct kvm_vcpu *vcpu, { u32 index = kvm_rcx_read(vcpu); u64 new_eptp; - bool accessed_dirty; - struct kvm_mmu *mmu = vcpu->arch.walk_mmu; if (!nested_cpu_has_eptp_switching(vmcs12) || !nested_cpu_has_ept(vmcs12)) @@ -5487,13 +5492,10 @@ static int nested_vmx_eptp_switching(struct kvm_vcpu *vcpu, if (index >= VMFUNC_EPTP_ENTRIES) return 1; - if (kvm_vcpu_read_guest_page(vcpu, vmcs12->eptp_list_address >> PAGE_SHIFT, &new_eptp, index * 8, 8)) return 1; - accessed_dirty = !!(new_eptp & VMX_EPTP_AD_ENABLE_BIT); - /* * If the (L2) guest does a vmfunc to the currently * active ept pointer, we don't have to do anything else @@ -5502,8 +5504,6 @@ static int nested_vmx_eptp_switching(struct kvm_vcpu *vcpu, if (!nested_vmx_check_eptp(vcpu, new_eptp)) return 1; - mmu->ept_ad = accessed_dirty; - mmu->mmu_role.base.ad_disabled = !accessed_dirty; vmcs12->ept_pointer = new_eptp; kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu); @@ -5529,7 +5529,7 @@ static int handle_vmfunc(struct kvm_vcpu *vcpu) } vmcs12 = get_vmcs12(vcpu); - if ((vmcs12->vm_function_control & (1 << function)) == 0) + if (!(vmcs12->vm_function_control & BIT_ULL(function))) goto fail; switch (function) { @@ -5779,7 +5779,8 @@ static bool nested_vmx_l0_wants_exit(struct kvm_vcpu *vcpu, if (is_nmi(intr_info)) return true; else if (is_page_fault(intr_info)) - return vcpu->arch.apf.host_apf_flags || !enable_ept; + return vcpu->arch.apf.host_apf_flags || + vmx_need_pf_intercept(vcpu); else if (is_debug(intr_info) && vcpu->guest_debug & (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) @@ -5787,6 +5788,9 @@ static bool nested_vmx_l0_wants_exit(struct kvm_vcpu *vcpu, else if (is_breakpoint(intr_info) && vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) return true; + else if (is_alignment_check(intr_info) && + !vmx_guest_inject_ac(vcpu)) + return true; return false; case EXIT_REASON_EXTERNAL_INTERRUPT: return true; diff --git a/arch/x86/kvm/vmx/vmcs.h b/arch/x86/kvm/vmx/vmcs.h index 1472c6c376f7..571d9ad80a59 100644 --- a/arch/x86/kvm/vmx/vmcs.h +++ b/arch/x86/kvm/vmx/vmcs.h @@ -117,6 +117,11 @@ static inline bool is_gp_fault(u32 intr_info) return is_exception_n(intr_info, GP_VECTOR); } +static inline bool is_alignment_check(u32 intr_info) +{ + return is_exception_n(intr_info, AC_VECTOR); +} + static inline bool is_machine_check(u32 intr_info) { return is_exception_n(intr_info, MC_VECTOR); diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 45877364e682..de24d3826788 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -4755,7 +4755,7 @@ static int handle_machine_check(struct kvm_vcpu *vcpu) * - Guest has #AC detection enabled in CR0 * - Guest EFLAGS has AC bit set */ -static inline bool guest_inject_ac(struct kvm_vcpu *vcpu) +bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu) { if (!boot_cpu_has(X86_FEATURE_SPLIT_LOCK_DETECT)) return true; @@ -4864,7 +4864,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu) kvm_run->debug.arch.exception = ex_no; break; case AC_VECTOR: - if (guest_inject_ac(vcpu)) { + if (vmx_guest_inject_ac(vcpu)) { kvm_queue_exception_e(vcpu, AC_VECTOR, error_code); return 1; } diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h index ae3a89ac0600..5ff24537393e 100644 --- a/arch/x86/kvm/vmx/vmx.h +++ b/arch/x86/kvm/vmx/vmx.h @@ -352,6 +352,7 @@ void vmx_set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); u64 construct_eptp(struct kvm_vcpu *vcpu, unsigned long root_hpa, int root_level); +bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu); void update_exception_bitmap(struct kvm_vcpu *vcpu); void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu); bool vmx_nmi_blocked(struct kvm_vcpu *vcpu); @@ -487,7 +488,7 @@ static inline void decache_tsc_multiplier(struct vcpu_vmx *vmx) static inline bool vmx_has_waitpkg(struct vcpu_vmx *vmx) { - return vmx->secondary_exec_control & + return secondary_exec_controls_get(vmx) & SECONDARY_EXEC_ENABLE_USR_WAIT_PAUSE; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 109041630d30..812585986bb8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -541,8 +541,6 @@ static void kvm_multiple_exception(struct kvm_vcpu *vcpu, if (!vcpu->arch.exception.pending && !vcpu->arch.exception.injected) { queue: - if (has_error && !is_protmode(vcpu)) - has_error = false; if (reinject) { /* * On vmentry, vcpu->arch.exception.pending is only @@ -3207,7 +3205,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 1; break; case MSR_KVM_ASYNC_PF_ACK: - if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF)) + if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_INT)) return 1; if (data & 0x1) { vcpu->arch.apf.pageready_pending = false; @@ -3536,7 +3534,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) msr_info->data = vcpu->arch.apf.msr_int_val; break; case MSR_KVM_ASYNC_PF_ACK: - if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF)) + if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_INT)) return 1; msr_info->data = 0; @@ -4102,8 +4100,17 @@ static int kvm_cpu_accept_dm_intr(struct kvm_vcpu *vcpu) static int kvm_vcpu_ready_for_interrupt_injection(struct kvm_vcpu *vcpu) { - return kvm_arch_interrupt_allowed(vcpu) && - kvm_cpu_accept_dm_intr(vcpu); + /* + * Do not cause an interrupt window exit if an exception + * is pending or an event needs reinjection; userspace + * might want to inject the interrupt manually using KVM_SET_REGS + * or KVM_SET_SREGS. For that to work, we must be at an + * instruction boundary and with no events half-injected. + */ + return (kvm_arch_interrupt_allowed(vcpu) && + kvm_cpu_accept_dm_intr(vcpu) && + !kvm_event_needs_reinjection(vcpu) && + !vcpu->arch.exception.pending); } static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, @@ -6876,7 +6883,10 @@ static unsigned emulator_get_hflags(struct x86_emulate_ctxt *ctxt) static void emulator_set_hflags(struct x86_emulate_ctxt *ctxt, unsigned emul_flags) { - emul_to_vcpu(ctxt)->arch.hflags = emul_flags; + struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt); + + vcpu->arch.hflags = emul_flags; + kvm_mmu_reset_context(vcpu); } static int emulator_pre_leave_smm(struct x86_emulate_ctxt *ctxt, @@ -7013,6 +7023,11 @@ static void init_emulate_ctxt(struct kvm_vcpu *vcpu) BUILD_BUG_ON(HF_SMM_MASK != X86EMUL_SMM_MASK); BUILD_BUG_ON(HF_SMM_INSIDE_NMI_MASK != X86EMUL_SMM_INSIDE_NMI_MASK); + ctxt->interruptibility = 0; + ctxt->have_exception = false; + ctxt->exception.vector = -1; + ctxt->perm_ok = false; + init_decode_cache(ctxt); vcpu->arch.emulate_regs_need_sync_from_vcpu = false; } @@ -7328,6 +7343,37 @@ static bool is_vmware_backdoor_opcode(struct x86_emulate_ctxt *ctxt) return false; } +/* + * Decode to be emulated instruction. Return EMULATION_OK if success. + */ +int x86_decode_emulated_instruction(struct kvm_vcpu *vcpu, int emulation_type, + void *insn, int insn_len) +{ + int r = EMULATION_OK; + struct x86_emulate_ctxt *ctxt = vcpu->arch.emulate_ctxt; + + init_emulate_ctxt(vcpu); + + /* + * We will reenter on the same instruction since we do not set + * complete_userspace_io. This does not handle watchpoints yet, + * those would be handled in the emulate_ops. + */ + if (!(emulation_type & EMULTYPE_SKIP) && + kvm_vcpu_check_breakpoint(vcpu, &r)) + return r; + + ctxt->ud = emulation_type & EMULTYPE_TRAP_UD; + + r = x86_decode_insn(ctxt, insn, insn_len); + + trace_kvm_emulate_insn_start(vcpu); + ++vcpu->stat.insn_emulation; + + return r; +} +EXPORT_SYMBOL_GPL(x86_decode_emulated_instruction); + int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, int emulation_type, void *insn, int insn_len) { @@ -7347,32 +7393,12 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, */ write_fault_to_spt = vcpu->arch.write_fault_to_shadow_pgtable; vcpu->arch.write_fault_to_shadow_pgtable = false; - kvm_clear_exception_queue(vcpu); if (!(emulation_type & EMULTYPE_NO_DECODE)) { - init_emulate_ctxt(vcpu); - - /* - * We will reenter on the same instruction since - * we do not set complete_userspace_io. This does not - * handle watchpoints yet, those would be handled in - * the emulate_ops. - */ - if (!(emulation_type & EMULTYPE_SKIP) && - kvm_vcpu_check_breakpoint(vcpu, &r)) - return r; - - ctxt->interruptibility = 0; - ctxt->have_exception = false; - ctxt->exception.vector = -1; - ctxt->perm_ok = false; - - ctxt->ud = emulation_type & EMULTYPE_TRAP_UD; - - r = x86_decode_insn(ctxt, insn, insn_len); + kvm_clear_exception_queue(vcpu); - trace_kvm_emulate_insn_start(vcpu); - ++vcpu->stat.insn_emulation; + r = x86_decode_emulated_instruction(vcpu, emulation_type, + insn, insn_len); if (r != EMULATION_OK) { if ((emulation_type & EMULTYPE_TRAP_UD) || (emulation_type & EMULTYPE_TRAP_UD_FORCED)) { @@ -8018,6 +8044,7 @@ void kvm_arch_exit(void) kvm_x86_ops.hardware_enable = NULL; kvm_mmu_module_exit(); free_percpu(user_return_msrs); + kmem_cache_destroy(x86_emulator_cache); kmem_cache_destroy(x86_fpu_cache); } @@ -8261,6 +8288,13 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu) kvm_x86_ops.update_cr8_intercept(vcpu, tpr, max_irr); } +static void kvm_inject_exception(struct kvm_vcpu *vcpu) +{ + if (vcpu->arch.exception.error_code && !is_protmode(vcpu)) + vcpu->arch.exception.error_code = false; + kvm_x86_ops.queue_exception(vcpu); +} + static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit) { int r; @@ -8269,7 +8303,7 @@ static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit /* try to reinject previous events if any */ if (vcpu->arch.exception.injected) { - kvm_x86_ops.queue_exception(vcpu); + kvm_inject_exception(vcpu); can_inject = false; } /* @@ -8332,7 +8366,7 @@ static void inject_pending_event(struct kvm_vcpu *vcpu, bool *req_immediate_exit } } - kvm_x86_ops.queue_exception(vcpu); + kvm_inject_exception(vcpu); can_inject = false; } @@ -8848,7 +8882,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) } if (kvm_check_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu)) kvm_vcpu_flush_tlb_current(vcpu); - if (kvm_check_request(KVM_REQ_HV_TLB_FLUSH, vcpu)) + if (kvm_check_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu)) kvm_vcpu_flush_tlb_guest(vcpu); if (kvm_check_request(KVM_REQ_REPORT_TPR_ACCESS, vcpu)) { @@ -9016,6 +9050,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) set_debugreg(vcpu->arch.eff_db[3], 3); set_debugreg(vcpu->arch.dr6, 6); vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; + } else if (unlikely(hw_breakpoint_active())) { + set_debugreg(0, 7); } exit_fastpath = kvm_x86_ops.run(vcpu); diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 2249a7d7ca27..2bff44f1efec 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -272,6 +272,8 @@ bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn, int page_num); bool kvm_vector_hashing_enabled(void); void kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_code); +int x86_decode_emulated_instruction(struct kvm_vcpu *vcpu, int emulation_type, + void *insn, int insn_len); int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, int emulation_type, void *insn, int insn_len); fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu); diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 9e5ccc56f8e0..356b746dfbe7 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -118,7 +118,9 @@ static void __ioremap_check_other(resource_size_t addr, struct ioremap_desc *des if (!IS_ENABLED(CONFIG_EFI)) return; - if (efi_mem_type(addr) == EFI_RUNTIME_SERVICES_DATA) + if (efi_mem_type(addr) == EFI_RUNTIME_SERVICES_DATA || + (efi_mem_type(addr) == EFI_BOOT_SERVICES_DATA && + efi_mem_attributes(addr) & EFI_MEMORY_RUNTIME)) desc->flags |= IORES_MAP_ENCRYPTED; } diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c index cc85e199108e..868fd69814bf 100644 --- a/arch/x86/mm/mem_encrypt.c +++ b/arch/x86/mm/mem_encrypt.c @@ -198,6 +198,37 @@ void __init sme_early_init(void) swiotlb_force = SWIOTLB_FORCE; } +void __init sev_setup_arch(void) +{ + phys_addr_t total_mem = memblock_phys_mem_size(); + unsigned long size; + + if (!sev_active()) + return; + + /* + * For SEV, all DMA has to occur via shared/unencrypted pages. + * SEV uses SWIOTLB to make this happen without changing device + * drivers. However, depending on the workload being run, the + * default 64MB of SWIOTLB may not be enough and SWIOTLB may + * run out of buffers for DMA, resulting in I/O errors and/or + * performance degradation especially with high I/O workloads. + * + * Adjust the default size of SWIOTLB for SEV guests using + * a percentage of guest memory for SWIOTLB buffers. + * Also, as the SWIOTLB bounce buffer memory is allocated + * from low memory, ensure that the adjusted size is within + * the limits of low available memory. + * + * The percentage of guest memory used here for SWIOTLB buffers + * is more of an approximation of the static adjustment which + * 64MB for <1G, and ~128M to 256M for 1G-to-4G, i.e., the 6% + */ + size = total_mem * 6 / 100; + size = clamp_val(size, IO_TLB_DEFAULT_SIZE, SZ_1G); + swiotlb_adjust_size(size); +} + static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc) { pgprot_t old_prot, new_prot; diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index 5eb4dc2b97da..e94da744386f 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c @@ -254,7 +254,13 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi) /* make sure all non-reserved blocks are inside the limits */ bi->start = max(bi->start, low); - bi->end = min(bi->end, high); + + /* preserve info for non-RAM areas above 'max_pfn': */ + if (bi->end > high) { + numa_add_memblk_to(bi->nid, high, bi->end, + &numa_reserved_meminfo); + bi->end = high; + } /* and there's no empty block */ if (bi->start >= bi->end) diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index a11796bbb9ce..0a962cd6bac1 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -564,6 +564,9 @@ static void bpf_tail_call_direct_fixup(struct bpf_prog *prog) for (i = 0; i < prog->aux->size_poke_tab; i++) { poke = &prog->aux->poke_tab[i]; + if (poke->aux && poke->aux != prog->aux) + continue; + WARN_ON_ONCE(READ_ONCE(poke->tailcall_target_stable)); if (poke->reason != BPF_POKE_REASON_TAIL_CALL) @@ -1138,6 +1141,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, } break; + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + if (boot_cpu_has(X86_FEATURE_XMM2)) + /* Emit 'lfence' */ + EMIT3(0x0F, 0xAE, 0xE8); + break; + /* ST: *(u8*)(dst_reg + off) = imm */ case BPF_ST | BPF_MEM | BPF_B: if (is_ereg(dst_reg)) diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c index 2cf4d217840d..4bd0f98df700 100644 --- a/arch/x86/net/bpf_jit_comp32.c +++ b/arch/x86/net/bpf_jit_comp32.c @@ -1705,6 +1705,12 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, i++; break; } + /* speculation barrier */ + case BPF_ST | BPF_NOSPEC: + if (boot_cpu_has(X86_FEATURE_XMM2)) + /* Emit 'lfence' */ + EMIT3(0x0F, 0xAE, 0xE8); + break; /* ST: *(u8*)(dst_reg + off) = imm */ case BPF_ST | BPF_MEM | BPF_H: case BPF_ST | BPF_MEM | BPF_B: diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 0a0e168be1cb..9b0e771302ce 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -779,4 +779,48 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1571, pci_amd_enable_64bit_bar); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x15b1, pci_amd_enable_64bit_bar); DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1601, pci_amd_enable_64bit_bar); +#define RS690_LOWER_TOP_OF_DRAM2 0x30 +#define RS690_LOWER_TOP_OF_DRAM2_VALID 0x1 +#define RS690_UPPER_TOP_OF_DRAM2 0x31 +#define RS690_HTIU_NB_INDEX 0xA8 +#define RS690_HTIU_NB_INDEX_WR_ENABLE 0x100 +#define RS690_HTIU_NB_DATA 0xAC + +/* + * Some BIOS implementations support RAM above 4GB, but do not configure the + * PCI host to respond to bus master accesses for these addresses. These + * implementations set the TOP_OF_DRAM_SLOT1 register correctly, so PCI DMA + * works as expected for addresses below 4GB. + * + * Reference: "AMD RS690 ASIC Family Register Reference Guide" (pg. 2-57) + * https://www.amd.com/system/files/TechDocs/43372_rs690_rrg_3.00o.pdf + */ +static void rs690_fix_64bit_dma(struct pci_dev *pdev) +{ + u32 val = 0; + phys_addr_t top_of_dram = __pa(high_memory - 1) + 1; + + if (top_of_dram <= (1ULL << 32)) + return; + + pci_write_config_dword(pdev, RS690_HTIU_NB_INDEX, + RS690_LOWER_TOP_OF_DRAM2); + pci_read_config_dword(pdev, RS690_HTIU_NB_DATA, &val); + + if (val) + return; + + pci_info(pdev, "Adjusting top of DRAM to %pa for 64-bit DMA support\n", &top_of_dram); + + pci_write_config_dword(pdev, RS690_HTIU_NB_INDEX, + RS690_UPPER_TOP_OF_DRAM2 | RS690_HTIU_NB_INDEX_WR_ENABLE); + pci_write_config_dword(pdev, RS690_HTIU_NB_DATA, top_of_dram >> 32); + + pci_write_config_dword(pdev, RS690_HTIU_NB_INDEX, + RS690_LOWER_TOP_OF_DRAM2 | RS690_HTIU_NB_INDEX_WR_ENABLE); + pci_write_config_dword(pdev, RS690_HTIU_NB_DATA, + top_of_dram | RS690_LOWER_TOP_OF_DRAM2_VALID); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7910, rs690_fix_64bit_dma); + #endif diff --git a/arch/x86/tools/chkobjdump.awk b/arch/x86/tools/chkobjdump.awk index fd1ab80be0de..a4cf678cf5c8 100644 --- a/arch/x86/tools/chkobjdump.awk +++ b/arch/x86/tools/chkobjdump.awk @@ -10,6 +10,7 @@ BEGIN { /^GNU objdump/ { verstr = "" + gsub(/\(.*\)/, ""); for (i = 3; i <= NF; i++) if (match($(i), "^[0-9]")) { verstr = $(i); diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 8064df638222..d3cdf467d91f 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -586,8 +586,10 @@ DEFINE_IDTENTRY_RAW(xenpv_exc_debug) DEFINE_IDTENTRY_RAW(exc_xen_unknown_trap) { /* This should never happen and there is no way to handle it. */ + instrumentation_begin(); pr_err("Unknown trap in Xen PV mode."); BUG(); + instrumentation_end(); } struct trap_array_entry { diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c index 19ae3e4fe4e9..54f9aa7e8457 100644 --- a/arch/x86/xen/pci-swiotlb-xen.c +++ b/arch/x86/xen/pci-swiotlb-xen.c @@ -59,7 +59,7 @@ int __init pci_xen_swiotlb_detect(void) void __init pci_xen_swiotlb_init(void) { if (xen_swiotlb) { - xen_swiotlb_init(1, true /* early */); + xen_swiotlb_init_early(); dma_ops = &xen_swiotlb_dma_ops; #ifdef CONFIG_PCI @@ -76,7 +76,7 @@ int pci_xen_swiotlb_init_late(void) if (xen_swiotlb) return 0; - rc = xen_swiotlb_init(1, false /* late */); + rc = xen_swiotlb_init(); if (rc) return rc; diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index d0dfa50bd0bb..87e08ad38ea7 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -30,7 +30,7 @@ config XTENSA select HAVE_DMA_CONTIGUOUS select HAVE_EXIT_THREAD select HAVE_FUNCTION_TRACER - select HAVE_FUTEX_CMPXCHG if !MMU + select HAVE_FUTEX_CMPXCHG if !MMU && FUTEX select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_IRQ_TIME_ACCOUNTING select HAVE_OPROFILE diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c index cd85a7a2722b..1254da07ead1 100644 --- a/arch/xtensa/kernel/smp.c +++ b/arch/xtensa/kernel/smp.c @@ -145,7 +145,6 @@ void secondary_start_kernel(void) cpumask_set_cpu(cpu, mm_cpumask(mm)); enter_lazy_tlb(mm, current); - preempt_disable(); trace_hardirqs_off(); calibrate_delay(); diff --git a/block/blk-iocost.c b/block/blk-iocost.c index aaae531135aa..e95b93f72bd5 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -1394,16 +1394,17 @@ static int iocg_wake_fn(struct wait_queue_entry *wq_entry, unsigned mode, return -1; iocg_commit_bio(ctx->iocg, wait->bio, wait->abs_cost, cost); + wait->committed = true; /* * autoremove_wake_function() removes the wait entry only when it - * actually changed the task state. We want the wait always - * removed. Remove explicitly and use default_wake_function(). + * actually changed the task state. We want the wait always removed. + * Remove explicitly and use default_wake_function(). Note that the + * order of operations is important as finish_wait() tests whether + * @wq_entry is removed without grabbing the lock. */ - list_del_init(&wq_entry->entry); - wait->committed = true; - default_wake_function(wq_entry, mode, flags, key); + list_del_init_careful(&wq_entry->entry); return 0; } @@ -3038,19 +3039,19 @@ static ssize_t ioc_weight_write(struct kernfs_open_file *of, char *buf, if (v < CGROUP_WEIGHT_MIN || v > CGROUP_WEIGHT_MAX) return -EINVAL; - spin_lock(&blkcg->lock); + spin_lock_irq(&blkcg->lock); iocc->dfl_weight = v * WEIGHT_ONE; hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) { struct ioc_gq *iocg = blkg_to_iocg(blkg); if (iocg) { - spin_lock_irq(&iocg->ioc->lock); + spin_lock(&iocg->ioc->lock); ioc_now(iocg->ioc, &now); weight_updated(iocg, &now); - spin_unlock_irq(&iocg->ioc->lock); + spin_unlock(&iocg->ioc->lock); } } - spin_unlock(&blkcg->lock); + spin_unlock_irq(&blkcg->lock); return nbytes; } diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c index 81be0096411d..d8b0d8bd132b 100644 --- a/block/blk-iolatency.c +++ b/block/blk-iolatency.c @@ -833,7 +833,11 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf, enable = iolatency_set_min_lat_nsec(blkg, lat_val); if (enable) { - WARN_ON_ONCE(!blk_get_queue(blkg->q)); + if (!blk_get_queue(blkg->q)) { + ret = -ENODEV; + goto out; + } + blkg_get(blkg); } diff --git a/block/blk-merge.c b/block/blk-merge.c index 7cdd56696647..349cd7d3af81 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -552,10 +552,14 @@ static inline unsigned int blk_rq_get_max_segments(struct request *rq) static inline int ll_new_hw_segment(struct request *req, struct bio *bio, unsigned int nr_phys_segs) { - if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req)) + if (blk_integrity_merge_bio(req->q, req, bio) == false) goto no_merge; - if (blk_integrity_merge_bio(req->q, req, bio) == false) + /* discard request merge won't add new segment */ + if (req_op(req) == REQ_OP_DISCARD) + return 1; + + if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req)) goto no_merge; /* diff --git a/block/blk-mq.c b/block/blk-mq.c index a55c0449f411..47817ac5fd8d 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -945,34 +945,14 @@ static bool blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, unsigned long *next = priv; /* - * Just do a quick check if it is expired before locking the request in - * so we're not unnecessarilly synchronizing across CPUs. - */ - if (!blk_mq_req_expired(rq, next)) - return true; - - /* - * We have reason to believe the request may be expired. Take a - * reference on the request to lock this request lifetime into its - * currently allocated context to prevent it from being reallocated in - * the event the completion by-passes this timeout handler. - * - * If the reference was already released, then the driver beat the - * timeout handler to posting a natural completion. - */ - if (!refcount_inc_not_zero(&rq->ref)) - return true; - - /* - * The request is now locked and cannot be reallocated underneath the - * timeout handler's processing. Re-verify this exact request is truly - * expired; if it is not expired, then the request was completed and - * reallocated as a new request. + * blk_mq_queue_tag_busy_iter() has locked the request, so it cannot + * be reallocated underneath the timeout handler's processing, then + * the expire check is reliable. If the request is not expired, then + * it was completed and reallocated as a new request after returning + * from blk_mq_check_expired(). */ if (blk_mq_req_expired(rq, next)) blk_mq_rq_timed_out(rq, reserved); - - blk_mq_put_rq_ref(rq); return true; } @@ -1246,9 +1226,6 @@ static void blk_mq_update_dispatch_busy(struct blk_mq_hw_ctx *hctx, bool busy) { unsigned int ewma; - if (hctx->queue->elevator) - return; - ewma = hctx->dispatch_busy; if (!ewma && !busy) diff --git a/block/blk-rq-qos.c b/block/blk-rq-qos.c index 656460636ad3..e83af7bc7591 100644 --- a/block/blk-rq-qos.c +++ b/block/blk-rq-qos.c @@ -266,8 +266,8 @@ void rq_qos_wait(struct rq_wait *rqw, void *private_data, if (!has_sleeper && acquire_inflight_cb(rqw, private_data)) return; - prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE); - has_sleeper = !wq_has_single_sleeper(&rqw->wait); + has_sleeper = !prepare_to_wait_exclusive(&rqw->wait, &data.wq, + TASK_UNINTERRUPTIBLE); do { /* The memory barrier in set_task_state saves us here. */ if (data.got_token) diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h index 52728614fb27..f000f83e0621 100644 --- a/block/blk-rq-qos.h +++ b/block/blk-rq-qos.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "blk-mq-debugfs.h" @@ -87,8 +88,21 @@ static inline void rq_wait_init(struct rq_wait *rq_wait) static inline void rq_qos_add(struct request_queue *q, struct rq_qos *rqos) { + /* + * No IO can be in-flight when adding rqos, so freeze queue, which + * is fine since we only support rq_qos for blk-mq queue. + * + * Reuse ->queue_lock for protecting against other concurrent + * rq_qos adding/deleting + */ + blk_mq_freeze_queue(q); + + spin_lock_irq(&q->queue_lock); rqos->next = q->rq_qos; q->rq_qos = rqos; + spin_unlock_irq(&q->queue_lock); + + blk_mq_unfreeze_queue(q); if (rqos->ops->debugfs_attrs) blk_mq_debugfs_register_rqos(rqos); @@ -98,12 +112,22 @@ static inline void rq_qos_del(struct request_queue *q, struct rq_qos *rqos) { struct rq_qos **cur; + /* + * See comment in rq_qos_add() about freezing queue & using + * ->queue_lock. + */ + blk_mq_freeze_queue(q); + + spin_lock_irq(&q->queue_lock); for (cur = &q->rq_qos; *cur; cur = &(*cur)->next) { if (*cur == rqos) { *cur = rqos->next; break; } } + spin_unlock_irq(&q->queue_lock); + + blk_mq_unfreeze_queue(q); blk_mq_debugfs_unregister_rqos(rqos); } diff --git a/block/blk-wbt.c b/block/blk-wbt.c index fd410086fe1d..35d81b5deae1 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c @@ -77,7 +77,8 @@ enum { static inline bool rwb_enabled(struct rq_wb *rwb) { - return rwb && rwb->wb_normal != 0; + return rwb && rwb->enable_state != WBT_STATE_OFF_DEFAULT && + rwb->wb_normal != 0; } static void wb_timestamp(struct rq_wb *rwb, unsigned long *var) @@ -636,9 +637,13 @@ void wbt_set_write_cache(struct request_queue *q, bool write_cache_on) void wbt_enable_default(struct request_queue *q) { struct rq_qos *rqos = wbt_rq_qos(q); + /* Throttling already enabled? */ - if (rqos) + if (rqos) { + if (RQWB(rqos)->enable_state == WBT_STATE_OFF_DEFAULT) + RQWB(rqos)->enable_state = WBT_STATE_ON_DEFAULT; return; + } /* Queue not registered? Maybe shutting down... */ if (!blk_queue_registered(q)) @@ -702,7 +707,7 @@ void wbt_disable_default(struct request_queue *q) rwb = RQWB(rqos); if (rwb->enable_state == WBT_STATE_ON_DEFAULT) { blk_stat_deactivate(rwb->cb); - rwb->wb_normal = 0; + rwb->enable_state = WBT_STATE_OFF_DEFAULT; } } EXPORT_SYMBOL_GPL(wbt_disable_default); diff --git a/block/blk-wbt.h b/block/blk-wbt.h index 16bdc85b8df9..2eb01becde8c 100644 --- a/block/blk-wbt.h +++ b/block/blk-wbt.h @@ -34,6 +34,7 @@ enum { enum { WBT_STATE_ON_DEFAULT = 1, WBT_STATE_ON_MANUAL = 2, + WBT_STATE_OFF_DEFAULT }; struct rq_wb { diff --git a/block/partitions/ldm.c b/block/partitions/ldm.c index d333786b5c7e..cc86534c80ad 100644 --- a/block/partitions/ldm.c +++ b/block/partitions/ldm.c @@ -510,7 +510,7 @@ static bool ldm_validate_partition_table(struct parsed_partitions *state) p = (struct msdos_partition *)(data + 0x01BE); for (i = 0; i < 4; i++, p++) - if (SYS_IND (p) == LDM_PARTITION) { + if (p->sys_ind == LDM_PARTITION) { result = true; break; } diff --git a/block/partitions/ldm.h b/block/partitions/ldm.h index d8d6beaa72c4..8693704dcf5e 100644 --- a/block/partitions/ldm.h +++ b/block/partitions/ldm.h @@ -84,9 +84,6 @@ struct parsed_partitions; #define TOC_BITMAP1 "config" /* Names of the two defined */ #define TOC_BITMAP2 "log" /* bitmaps in the TOCBLOCK. */ -/* Borrowed from msdos.c */ -#define SYS_IND(p) (get_unaligned(&(p)->sys_ind)) - struct frag { /* VBLK Fragment handling */ struct list_head list; u32 group; diff --git a/block/partitions/msdos.c b/block/partitions/msdos.c index 8f2fcc080264..c94de377c502 100644 --- a/block/partitions/msdos.c +++ b/block/partitions/msdos.c @@ -38,8 +38,6 @@ */ #include -#define SYS_IND(p) get_unaligned(&p->sys_ind) - static inline sector_t nr_sects(struct msdos_partition *p) { return (sector_t)get_unaligned_le32(&p->nr_sects); @@ -52,9 +50,9 @@ static inline sector_t start_sect(struct msdos_partition *p) static inline int is_extended_partition(struct msdos_partition *p) { - return (SYS_IND(p) == DOS_EXTENDED_PARTITION || - SYS_IND(p) == WIN98_EXTENDED_PARTITION || - SYS_IND(p) == LINUX_EXTENDED_PARTITION); + return (p->sys_ind == DOS_EXTENDED_PARTITION || + p->sys_ind == WIN98_EXTENDED_PARTITION || + p->sys_ind == LINUX_EXTENDED_PARTITION); } #define MSDOS_LABEL_MAGIC1 0x55 @@ -193,7 +191,7 @@ static void parse_extended(struct parsed_partitions *state, put_partition(state, state->next, next, size); set_info(state, state->next, disksig); - if (SYS_IND(p) == LINUX_RAID_PARTITION) + if (p->sys_ind == LINUX_RAID_PARTITION) state->parts[state->next].flags = ADDPART_FLAG_RAID; loopct = 0; if (++state->next == state->limit) @@ -546,7 +544,7 @@ static void parse_minix(struct parsed_partitions *state, * a secondary MBR describing its subpartitions, or * the normal boot sector. */ if (msdos_magic_present(data + 510) && - SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */ + p->sys_ind == MINIX_PARTITION) { /* subpartition table present */ char tmp[1 + BDEVNAME_SIZE + 10 + 9 + 1]; snprintf(tmp, sizeof(tmp), " %s%d: name, origin); @@ -555,7 +553,7 @@ static void parse_minix(struct parsed_partitions *state, if (state->next == state->limit) break; /* add each partition in use */ - if (SYS_IND(p) == MINIX_PARTITION) + if (p->sys_ind == MINIX_PARTITION) put_partition(state, state->next++, start_sect(p), nr_sects(p)); } @@ -643,7 +641,7 @@ int msdos_partition(struct parsed_partitions *state) p = (struct msdos_partition *) (data + 0x1be); for (slot = 1 ; slot <= 4 ; slot++, p++) { /* If this is an EFI GPT disk, msdos should ignore it. */ - if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) { + if (p->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT) { put_dev_sector(sect); return 0; } @@ -685,11 +683,11 @@ int msdos_partition(struct parsed_partitions *state) } put_partition(state, slot, start, size); set_info(state, slot, disksig); - if (SYS_IND(p) == LINUX_RAID_PARTITION) + if (p->sys_ind == LINUX_RAID_PARTITION) state->parts[slot].flags = ADDPART_FLAG_RAID; - if (SYS_IND(p) == DM6_PARTITION) + if (p->sys_ind == DM6_PARTITION) strlcat(state->pp_buf, "[DM]", PAGE_SIZE); - if (SYS_IND(p) == EZD_PARTITION) + if (p->sys_ind == EZD_PARTITION) strlcat(state->pp_buf, "[EZD]", PAGE_SIZE); } @@ -698,7 +696,7 @@ int msdos_partition(struct parsed_partitions *state) /* second pass - output for each on a separate line */ p = (struct msdos_partition *) (0x1be + data); for (slot = 1 ; slot <= 4 ; slot++, p++) { - unsigned char id = SYS_IND(p); + unsigned char id = p->sys_ind; int n; if (!nr_sects(p)) diff --git a/build.config.allmodconfig b/build.config.allmodconfig index a48f8d420208..945c4bac54c6 100644 --- a/build.config.allmodconfig +++ b/build.config.allmodconfig @@ -11,5 +11,5 @@ function update_config() { -e UNWINDER_FRAME_POINTER \ (cd ${OUT_DIR} && \ - make O=${OUT_DIR} $archsubarch CROSS_COMPILE=${CROSS_COMPILE} "${TOOL_ARGS[@]}" ${MAKE_ARGS} olddefconfig) + make O=${OUT_DIR} $archsubarch CROSS_COMPILE=${CROSS_COMPILE} ${TOOL_ARGS} ${MAKE_ARGS} olddefconfig) } diff --git a/build.config.common b/build.config.common index 9c136e7856ef..d72dd30f2ef1 100644 --- a/build.config.common +++ b/build.config.common @@ -1,10 +1,10 @@ -BRANCH=android-gs-pixel-5.10 -KMI_GENERATION=9 +BRANCH=android13-gs-pixel-5.10-gs101 +KMI_GENERATION=0 LLVM=1 DEPMOD=depmod DTC=dtc -CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r416183b/bin +CLANG_PREBUILT_BIN=prebuilts/clang/host/linux-x86/clang-r428724/bin BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86 EXTRA_CMDS='' diff --git a/build.config.db845c b/build.config.db845c index 0cf98815f3be..2e59c3f018d8 100644 --- a/build.config.db845c +++ b/build.config.db845c @@ -17,5 +17,4 @@ arch/arm64/boot/Image.gz arch/arm64/boot/dts/qcom/sdm845-db845c.dtb vmlinux " -KMI_SYMBOL_LIST=android/abi_gki_aarch64_db845c GKI_MODULES_LIST=android/gki_aarch64_modules diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 index 6d38f997f156..5d02ef40c871 100644 --- a/build.config.gki.aarch64 +++ b/build.config.gki.aarch64 @@ -8,25 +8,12 @@ MAKE_GOALS="${MAKE_GOALS} Image.lz4 " -ABI_DEFINITION=android/abi_gki_aarch64.xml TIDY_ABI=1 KMI_SYMBOL_LIST=android/abi_gki_aarch64 ADDITIONAL_KMI_SYMBOL_LISTS=" android/abi_gki_aarch64_core -android/abi_gki_aarch64_db845c -android/abi_gki_aarch64_exynos -android/abi_gki_aarch64_exynosauto android/abi_gki_aarch64_fips140 -android/abi_gki_aarch64_galaxy android/abi_gki_aarch64_generic -android/abi_gki_aarch64_hikey960 -android/abi_gki_aarch64_mtk -android/abi_gki_aarch64_oplus -android/abi_gki_aarch64_qcom -android/abi_gki_aarch64_rockchip -android/abi_gki_aarch64_virtual_device -android/abi_gki_aarch64_vivo -android/abi_gki_aarch64_xiaomi " FILES="${FILES} @@ -40,7 +27,6 @@ GKI_RAMDISK_PREBUILT_BINARY=${ROOT_DIR}/prebuilts/boot-artifacts/ramdisks/ramdis TRIM_NONLISTED_KMI=${TRIM_NONLISTED_KMI:-1} KMI_SYMBOL_LIST_STRICT_MODE=${KMI_SYMBOL_LIST_STRICT_MODE:-1} MODULES_ORDER=android/gki_aarch64_modules -KMI_ENFORCED=1 if [ -n "${GKI_DEFCONFIG_FRAGMENT}" ]; then source ${GKI_DEFCONFIG_FRAGMENT} diff --git a/build.config.gki_kasan b/build.config.gki_kasan index 7ac22d6956a2..c7303e9d48d2 100644 --- a/build.config.gki_kasan +++ b/build.config.gki_kasan @@ -16,6 +16,6 @@ function update_kasan_config() { -d CFI_CLANG \ -d SHADOW_CALL_STACK (cd ${OUT_DIR} && \ - make ${CC_LD_ARG} O=${OUT_DIR} olddefconfig) + make ${TOOL_ARGS} O=${OUT_DIR} olddefconfig) } diff --git a/build.config.gki_kprobes b/build.config.gki_kprobes index 24c58d553d94..688142ad2005 100644 --- a/build.config.gki_kprobes +++ b/build.config.gki_kprobes @@ -14,6 +14,6 @@ function update_kprobes_config() { -e CONFIG_CHECKPOINT_RESTORE \ -d CONFIG_RANDOMIZE_BASE (cd ${OUT_DIR} && \ - make ${CC_LD_ARG} O=${OUT_DIR} olddefconfig) + make ${TOOL_ARGS} O=${OUT_DIR} olddefconfig) } diff --git a/build.config.gs101 b/build.config.gs101 index 8c4146aa4e37..4235d43730a2 100644 --- a/build.config.gs101 +++ b/build.config.gs101 @@ -1,11 +1,12 @@ . ${ROOT_DIR}/${KERNEL_DIR}/build.config.common . ${ROOT_DIR}/${KERNEL_DIR}/build.config.aarch64 -DEFCONFIG=slider_gki_defconfig -PRE_DEFCONFIG_CMDS="KCONFIG_CONFIG=${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/${DEFCONFIG} ${ROOT_DIR}/${KERNEL_DIR}/scripts/kconfig/merge_config.sh -m -r ${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/gki_defconfig ${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/slider_gki.fragment" +DEFCONFIG=${DEFCONFIG:-slider_gki_defconfig} +GKI_FRAGMENT_DEFCONFIG=${GKI_FRAGMENT_DEFCONFIG:-${KERNEL_DIR}/arch/arm64/configs/slider_gki.fragment} +PRE_DEFCONFIG_CMDS="KCONFIG_CONFIG=${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/${DEFCONFIG} ${ROOT_DIR}/${KERNEL_DIR}/scripts/kconfig/merge_config.sh -m -r ${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/gki_defconfig ${ROOT_DIR}/${GKI_FRAGMENT_DEFCONFIG}" POST_DEFCONFIG_CMDS="rm ${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/${DEFCONFIG}" -LIBUFDT_PREBUILTS_BIN=prebuilts-master/misc/linux-x86/libufdt +LIBUFDT_PREBUILTS_BIN=prebuilts/misc/linux-x86/libufdt DTC_OVERLAY_TEST_EXT=${ROOT_DIR}/prebuilts/kernel-build-tools/linux-x86/bin/ufdt_apply_overlay MAKE_GOALS= @@ -36,20 +37,8 @@ ABI_DEFINITION=android/abi_gki_aarch64_generic.xml TIDY_ABI=1 KMI_SYMBOL_LIST=android/abi_gki_aarch64_generic ADDITIONAL_KMI_SYMBOL_LISTS=" -android/abi_gki_aarch64 android/abi_gki_aarch64_core -android/abi_gki_aarch64_db845c -android/abi_gki_aarch64_exynos -android/abi_gki_aarch64_exynosauto android/abi_gki_aarch64_fips140 -android/abi_gki_aarch64_galaxy -android/abi_gki_aarch64_hikey960 -android/abi_gki_aarch64_mtk -android/abi_gki_aarch64_oplus -android/abi_gki_aarch64_qcom -android/abi_gki_aarch64_virtual_device -android/abi_gki_aarch64_vivo -android/abi_gki_aarch64_xiaomi " TRIM_NONLISTED_KMI=${TRIM_NONLISTED_KMI:-1} KMI_SYMBOL_LIST_ADD_ONLY=1 @@ -63,7 +52,7 @@ BOOT_IMAGE_HEADER_VERSION=4 VENDOR_DLKM_MODULES_LIST=${KERNEL_DIR}/vendor_dlkm_modules.slider VENDOR_DLKM_PROPS=${KERNEL_DIR}/vendor_dlkm.props.slider GKI_RAMDISK_PREBUILT_BINARY=${ROOT_DIR}/prebuilts/boot-artifacts/ramdisks/ramdisk-aosp_arm64.img -VENDOR_RAMDISK_BINARY=${ROOT_DIR}/prebuilts/boot-artifacts/ramdisks/vendor_ramdisk-oriole.img +VENDOR_RAMDISK_BINARY=${VENDOR_RAMDISK_BINARY:-${ROOT_DIR}/prebuilts/boot-artifacts/ramdisks/vendor_ramdisk-oriole.img} KERNEL_VENDOR_CMDLINE="earlycon=exynos4210,0x10A00000 console=ttySAC0,115200 androidboot.console=ttySAC0" KERNEL_VENDOR_CMDLINE+=" printk.devkmsg=on" KERNEL_VENDOR_CMDLINE+=" at24.write_timeout=100 buildvariant=userdebug" diff --git a/build.config.hikey960 b/build.config.hikey960 index 29823f124573..a9204f983b7e 100644 --- a/build.config.hikey960 +++ b/build.config.hikey960 @@ -20,5 +20,4 @@ arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dtb vmlinux System.map " -KMI_SYMBOL_LIST=android/abi_gki_aarch64_hikey960 GKI_MODULES_LIST=android/gki_aarch64_modules diff --git a/build.config.rockpi4 b/build.config.rockpi4 new file mode 100644 index 000000000000..424e568f018c --- /dev/null +++ b/build.config.rockpi4 @@ -0,0 +1,19 @@ +. ${ROOT_DIR}/${KERNEL_DIR}/build.config.common +. ${ROOT_DIR}/${KERNEL_DIR}/build.config.aarch64 +TRIM_NONLISTED_KMI="" +KMI_SYMBOL_LIST_STRICT_MODE="" + +BUILD_INITRAMFS=1 +LZ4_RAMDISK=1 +DEFCONFIG=rockpi4_gki_defconfig +FRAGMENT_CONFIG=${KERNEL_DIR}/arch/arm64/configs/rockpi4_gki.fragment +PRE_DEFCONFIG_CMDS="KCONFIG_CONFIG=${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/${DEFCONFIG} ${ROOT_DIR}/${KERNEL_DIR}/scripts/kconfig/merge_config.sh -m -r ${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/gki_defconfig ${ROOT_DIR}/${FRAGMENT_CONFIG}" +POST_DEFCONFIG_CMDS="rm ${ROOT_DIR}/${KERNEL_DIR}/arch/arm64/configs/${DEFCONFIG}" + +MAKE_GOALS="${MAKE_GOALS} +rockchip/rk3399-rock-pi-4b.dtb +" + +FILES="${FILES} +arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dtb +" diff --git a/build_slider.sh b/build_slider.sh index 617031b501c9..06f897543d15 100755 --- a/build_slider.sh +++ b/build_slider.sh @@ -33,10 +33,10 @@ if [ "${BUILD_KERNEL}" = "0" ]; then else USING_PREBUILTS= if [ "${EXPERIMENTAL_BUILD}" != "0" ]; then - GKI_KERNEL_OUT_DIR=android12-5.10-staging + GKI_KERNEL_OUT_DIR=android13-5.10-staging GKI_KERNEL_BUILD_CONFIG=common/build.config.gki.aarch64 else - GKI_KERNEL_OUT_DIR=android12-5.10 + GKI_KERNEL_OUT_DIR=android13-5.10 GKI_KERNEL_BUILD_CONFIG=aosp/build.config.gki.aarch64 fi fi @@ -70,7 +70,7 @@ if [ "${EXPERIMENTAL_BUILD}" = "0" -a "${BUILD_KERNEL}" != "0" ]; then sed -n "s/^.*revision=\"\([0-9a-fA-F]*\)\".*/\1/p") pushd aosp/ > /dev/null # Booting AOSP ToT does not always work; throw a warning to prevent this. - LOCAL_MERGE_BASE=$(git merge-base HEAD aosp/android12-5.10) + LOCAL_MERGE_BASE=$(git merge-base HEAD aosp/android13-5.10) if [ -n "${LOCAL_MERGE_BASE}" -a \ "${MANIFEST_SHA}" != "${LOCAL_MERGE_BASE}" ]; then echo "Your aosp/ directory appears to be synced to a point beyond the" diff --git a/certs/.gitignore b/certs/.gitignore index 2a2483990686..6cbd1f1a5837 100644 --- a/certs/.gitignore +++ b/certs/.gitignore @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0-only x509_certificate_list +x509_revocation_list diff --git a/certs/Kconfig b/certs/Kconfig index c94e93d8bccf..ab88d2a7f3c7 100644 --- a/certs/Kconfig +++ b/certs/Kconfig @@ -83,4 +83,21 @@ config SYSTEM_BLACKLIST_HASH_LIST wrapper to incorporate the list into the kernel. Each should be a string of hex digits. +config SYSTEM_REVOCATION_LIST + bool "Provide system-wide ring of revocation certificates" + depends on SYSTEM_BLACKLIST_KEYRING + depends on PKCS7_MESSAGE_PARSER=y + help + If set, this allows revocation certificates to be stored in the + blacklist keyring and implements a hook whereby a PKCS#7 message can + be checked to see if it matches such a certificate. + +config SYSTEM_REVOCATION_KEYS + string "X.509 certificates to be preloaded into the system blacklist keyring" + depends on SYSTEM_REVOCATION_LIST + help + If set, this option should be the filename of a PEM-formatted file + containing X.509 certificates to be included in the default blacklist + keyring. + endmenu diff --git a/certs/Makefile b/certs/Makefile index f4c25b67aad9..b6db52ebf0be 100644 --- a/certs/Makefile +++ b/certs/Makefile @@ -3,8 +3,9 @@ # Makefile for the linux kernel signature checking certificates. # -obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o -obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o +obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o common.o +obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o common.o +obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o ifneq ($(CONFIG_SYSTEM_BLACKLIST_HASH_LIST),"") obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_hashes.o else @@ -29,7 +30,7 @@ $(obj)/x509_certificate_list: scripts/extract-cert $(SYSTEM_TRUSTED_KEYS_SRCPREF $(call if_changed,extract_certs,$(SYSTEM_TRUSTED_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_TRUSTED_KEYS)) endif # CONFIG_SYSTEM_TRUSTED_KEYRING -clean-files := x509_certificate_list .x509.list +clean-files := x509_certificate_list .x509.list x509_revocation_list ifeq ($(CONFIG_MODULE_SIG),y) ############################################################################### @@ -104,3 +105,17 @@ targets += signing_key.x509 $(obj)/signing_key.x509: scripts/extract-cert $(X509_DEP) FORCE $(call if_changed,extract_certs,$(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY)) endif # CONFIG_MODULE_SIG + +ifeq ($(CONFIG_SYSTEM_REVOCATION_LIST),y) + +$(eval $(call config_filename,SYSTEM_REVOCATION_KEYS)) + +$(obj)/revocation_certificates.o: $(obj)/x509_revocation_list + +quiet_cmd_extract_certs = EXTRACT_CERTS $(patsubst "%",%,$(2)) + cmd_extract_certs = scripts/extract-cert $(2) $@ + +targets += x509_revocation_list +$(obj)/x509_revocation_list: scripts/extract-cert $(SYSTEM_REVOCATION_KEYS_SRCPREFIX)$(SYSTEM_REVOCATION_KEYS_FILENAME) FORCE + $(call if_changed,extract_certs,$(SYSTEM_REVOCATION_KEYS_SRCPREFIX)$(CONFIG_SYSTEM_REVOCATION_KEYS)) +endif diff --git a/certs/blacklist.c b/certs/blacklist.c index f1c434b04b5e..c973de883cf0 100644 --- a/certs/blacklist.c +++ b/certs/blacklist.c @@ -16,9 +16,15 @@ #include #include #include "blacklist.h" +#include "common.h" static struct key *blacklist_keyring; +#ifdef CONFIG_SYSTEM_REVOCATION_LIST +extern __initconst const u8 revocation_certificate_list[]; +extern __initconst const unsigned long revocation_certificate_list_size; +#endif + /* * The description must be a type prefix, a colon and then an even number of * hex digits. The hash is kept in the description. @@ -144,6 +150,49 @@ int is_binary_blacklisted(const u8 *hash, size_t hash_len) } EXPORT_SYMBOL_GPL(is_binary_blacklisted); +#ifdef CONFIG_SYSTEM_REVOCATION_LIST +/** + * add_key_to_revocation_list - Add a revocation certificate to the blacklist + * @data: The data blob containing the certificate + * @size: The size of data blob + */ +int add_key_to_revocation_list(const char *data, size_t size) +{ + key_ref_t key; + + key = key_create_or_update(make_key_ref(blacklist_keyring, true), + "asymmetric", + NULL, + data, + size, + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW), + KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN); + + if (IS_ERR(key)) { + pr_err("Problem with revocation key (%ld)\n", PTR_ERR(key)); + return PTR_ERR(key); + } + + return 0; +} + +/** + * is_key_on_revocation_list - Determine if the key for a PKCS#7 message is revoked + * @pkcs7: The PKCS#7 message to check + */ +int is_key_on_revocation_list(struct pkcs7_message *pkcs7) +{ + int ret; + + ret = pkcs7_validate_trust(pkcs7, blacklist_keyring); + + if (ret == 0) + return -EKEYREJECTED; + + return -ENOKEY; +} +#endif + /* * Initialise the blacklist */ @@ -177,3 +226,18 @@ static int __init blacklist_init(void) * Must be initialised before we try and load the keys into the keyring. */ device_initcall(blacklist_init); + +#ifdef CONFIG_SYSTEM_REVOCATION_LIST +/* + * Load the compiled-in list of revocation X.509 certificates. + */ +static __init int load_revocation_certificate_list(void) +{ + if (revocation_certificate_list_size) + pr_notice("Loading compiled-in revocation X.509 certificates\n"); + + return load_certificate_list(revocation_certificate_list, revocation_certificate_list_size, + blacklist_keyring); +} +late_initcall(load_revocation_certificate_list); +#endif diff --git a/certs/blacklist.h b/certs/blacklist.h index 1efd6fa0dc60..51b320cf8574 100644 --- a/certs/blacklist.h +++ b/certs/blacklist.h @@ -1,3 +1,5 @@ #include +#include +#include extern const char __initconst *const blacklist_hashes[]; diff --git a/certs/common.c b/certs/common.c new file mode 100644 index 000000000000..16a220887a53 --- /dev/null +++ b/certs/common.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "common.h" + +int load_certificate_list(const u8 cert_list[], + const unsigned long list_size, + const struct key *keyring) +{ + key_ref_t key; + const u8 *p, *end; + size_t plen; + + p = cert_list; + end = p + list_size; + while (p < end) { + /* Each cert begins with an ASN.1 SEQUENCE tag and must be more + * than 256 bytes in size. + */ + if (end - p < 4) + goto dodgy_cert; + if (p[0] != 0x30 && + p[1] != 0x82) + goto dodgy_cert; + plen = (p[2] << 8) | p[3]; + plen += 4; + if (plen > end - p) + goto dodgy_cert; + + key = key_create_or_update(make_key_ref(keyring, 1), + "asymmetric", + NULL, + p, + plen, + ((KEY_POS_ALL & ~KEY_POS_SETATTR) | + KEY_USR_VIEW | KEY_USR_READ), + KEY_ALLOC_NOT_IN_QUOTA | + KEY_ALLOC_BUILT_IN | + KEY_ALLOC_BYPASS_RESTRICTION); + if (IS_ERR(key)) { + pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", + PTR_ERR(key)); + } else { + pr_notice("Loaded X.509 cert '%s'\n", + key_ref_to_ptr(key)->description); + key_ref_put(key); + } + p += plen; + } + + return 0; + +dodgy_cert: + pr_err("Problem parsing in-kernel X.509 certificate list\n"); + return 0; +} diff --git a/certs/common.h b/certs/common.h new file mode 100644 index 000000000000..abdb5795936b --- /dev/null +++ b/certs/common.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _CERT_COMMON_H +#define _CERT_COMMON_H + +int load_certificate_list(const u8 cert_list[], const unsigned long list_size, + const struct key *keyring); + +#endif diff --git a/certs/revocation_certificates.S b/certs/revocation_certificates.S new file mode 100644 index 000000000000..f21aae8a8f0e --- /dev/null +++ b/certs/revocation_certificates.S @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#include +#include + + __INITRODATA + + .align 8 + .globl revocation_certificate_list +revocation_certificate_list: +__revocation_list_start: + .incbin "certs/x509_revocation_list" +__revocation_list_end: + + .align 8 + .globl revocation_certificate_list_size +revocation_certificate_list_size: +#ifdef CONFIG_64BIT + .quad __revocation_list_end - __revocation_list_start +#else + .long __revocation_list_end - __revocation_list_start +#endif diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 798291177186..a44a8915c94c 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -15,6 +15,7 @@ #include #include #include +#include "common.h" static struct key *builtin_trusted_keys; #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING @@ -136,54 +137,10 @@ device_initcall(system_trusted_keyring_init); */ static __init int load_system_certificate_list(void) { - key_ref_t key; - const u8 *p, *end; - size_t plen; - pr_notice("Loading compiled-in X.509 certificates\n"); - p = system_certificate_list; - end = p + system_certificate_list_size; - while (p < end) { - /* Each cert begins with an ASN.1 SEQUENCE tag and must be more - * than 256 bytes in size. - */ - if (end - p < 4) - goto dodgy_cert; - if (p[0] != 0x30 && - p[1] != 0x82) - goto dodgy_cert; - plen = (p[2] << 8) | p[3]; - plen += 4; - if (plen > end - p) - goto dodgy_cert; - - key = key_create_or_update(make_key_ref(builtin_trusted_keys, 1), - "asymmetric", - NULL, - p, - plen, - ((KEY_POS_ALL & ~KEY_POS_SETATTR) | - KEY_USR_VIEW | KEY_USR_READ), - KEY_ALLOC_NOT_IN_QUOTA | - KEY_ALLOC_BUILT_IN | - KEY_ALLOC_BYPASS_RESTRICTION); - if (IS_ERR(key)) { - pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", - PTR_ERR(key)); - } else { - pr_notice("Loaded X.509 cert '%s'\n", - key_ref_to_ptr(key)->description); - key_ref_put(key); - } - p += plen; - } - - return 0; - -dodgy_cert: - pr_err("Problem parsing in-kernel X.509 certificate list\n"); - return 0; + return load_certificate_list(system_certificate_list, system_certificate_list_size, + builtin_trusted_keys); } late_initcall(load_system_certificate_list); @@ -241,6 +198,12 @@ int verify_pkcs7_message_sig(const void *data, size_t len, pr_devel("PKCS#7 platform keyring is not available\n"); goto error; } + + ret = is_key_on_revocation_list(pkcs7); + if (ret != -ENOKEY) { + pr_devel("PKCS#7 platform key is on revocation list\n"); + goto error; + } } ret = pkcs7_validate_trust(pkcs7, trusted_keys); if (ret < 0) { diff --git a/crypto/Makefile b/crypto/Makefile index aff52de1f84b..f353273de018 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -202,12 +202,17 @@ ifneq ($(CONFIG_CRYPTO_FIPS140_MOD),) FIPS140_CFLAGS := -D__DISABLE_EXPORTS -DBUILD_FIPS140_KO +CFLAGS_jitterentropy-fips.o := -O0 +KASAN_SANITIZE_jitterentropy-fips.o = n +UBSAN_SANITIZE_jitterentropy-fips.o = n + # # Create a separate FIPS archive containing a duplicate of each builtin generic # module that is in scope for FIPS 140-2 certification # -crypto-fips-objs := drbg.o ecb.o cbc.o ctr.o gcm.o xts.o hmac.o memneq.o \ - gf128mul.o aes_generic.o lib-crypto-aes.o \ +crypto-fips-objs := drbg.o ecb.o cbc.o ctr.o cts.o gcm.o xts.o hmac.o cmac.o \ + memneq.o gf128mul.o aes_generic.o lib-crypto-aes.o \ + jitterentropy.o jitterentropy-kcapi.o \ sha1_generic.o sha256_generic.o sha512_generic.o \ lib-sha1.o lib-crypto-sha256.o crypto-fips-objs := $(foreach o,$(crypto-fips-objs),$(o:.o=-fips.o)) diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c index 6cd7f7025df4..d8a91521144e 100644 --- a/crypto/async_tx/async_xor.c +++ b/crypto/async_tx/async_xor.c @@ -233,7 +233,8 @@ async_xor_offs(struct page *dest, unsigned int offset, if (submit->flags & ASYNC_TX_XOR_DROP_DST) { src_cnt--; src_list++; - src_offs++; + if (src_offs) + src_offs++; } /* wait for any prerequisite operations */ diff --git a/crypto/fips140-generated-testvecs.h b/crypto/fips140-generated-testvecs.h index 9328e9bacca7..d4ccd77eb97f 100644 --- a/crypto/fips140-generated-testvecs.h +++ b/crypto/fips140-generated-testvecs.h @@ -11,19 +11,19 @@ static const u8 fips_message[32] __initconst = static const u8 fips_aes_key[16] __initconst = "128-bit AES key"; -static const u8 fips_aes_iv[16] __initconst = "ABCDEFGHIJKL"; +static const u8 fips_aes_iv[16] __initconst = "ABCDEFGHIJKLMNOP"; static const u8 fips_aes_cbc_ciphertext[32] __initconst = - "\xc4\x6d\xad\xa4\x04\x52\x11\x5a\x7a\xb3\x7c\x68\x85\x8d\x90\xf0" - "\x55\xc3\xd3\x35\xc1\x75\x31\x90\xdf\x90\x4b\x5a\x56\xfd\xa7\x89"; + "\x4c\x3e\xeb\x38\x8d\x1f\x28\xfd\xa2\x3b\xa9\xda\x36\xf2\x99\xe2" + "\x84\x84\x66\x37\x0a\x53\x68\x2f\x17\x95\x8d\x7f\xca\x5a\x68\x4e"; static const u8 fips_aes_ecb_ciphertext[32] __initconst = "\xc1\x9d\xe6\xb8\xb2\x90\xff\xfe\xf2\x77\x18\xb0\x55\xd3\xee\xa9" "\xe2\x6f\x4a\x32\x67\xfd\xb7\xa5\x2f\x4b\x6e\x1a\x86\x2b\x6e\x3a"; static const u8 fips_aes_ctr_ciphertext[32] __initconst = - "\x92\xbe\x23\xa1\x80\x88\x5d\x31\x27\xb3\x9c\x40\x58\x57\x1d\xde" - "\xc1\x8d\x5b\xe7\x42\x93\x09\xf8\xd4\xf7\x49\x42\xcf\x40\x62\x7e"; + "\xed\x06\x2c\xd0\xbc\x48\xd1\x2e\x6a\x4e\x13\xe9\xaa\x17\x40\xca" + "\x00\xb4\xaf\x3b\x4f\xee\x73\xd6\x6c\x41\xf6\x4c\x8b\x0d\x6a\x0f"; static const u8 fips_aes_gcm_assoc[22] __initconst = "associated data string"; @@ -36,8 +36,11 @@ static const u8 fips_aes_xts_key[32] __initconst = "This is an AES-128-XTS key."; static const u8 fips_aes_xts_ciphertext[32] __initconst = - "\x5e\xb9\x98\xd6\x26\xb3\x55\xbf\x44\xab\x3e\xae\x73\xc0\x81\xc9" - "\xf4\x29\x0e\x17\x1e\xc5\xc8\x90\x79\x99\xf1\x43\x3a\x23\x08\x5a"; + "\x4f\xf7\x9f\x6c\x00\xa8\x30\xdf\xff\xf3\x25\x9c\xf6\x0b\x1b\xfd" + "\x3b\x34\x5e\x67\x7c\xf8\x8b\x68\x9a\xb9\x5a\x89\x51\x51\xbd\x35"; + +static const u8 fips_aes_cmac_digest[16] __initconst = + "\x0c\x05\xda\x64\x51\x0c\x8e\x6c\x86\x52\x46\xa8\x2d\xb1\xfe\x0f"; static const u8 fips_hmac_key[16] __initconst = "128-bit HMAC key"; diff --git a/crypto/fips140-module.c b/crypto/fips140-module.c index a91735c37c67..0be7642773e2 100644 --- a/crypto/fips140-module.c +++ b/crypto/fips140-module.c @@ -66,18 +66,37 @@ const u8 *__rodata_start = &__fips140_rodata_start; /* * The list of the crypto API algorithms (by cra_name) that will be unregistered * by this module, in preparation for the module registering its own - * implementation(s) of them. When adding a new algorithm here, make sure to - * consider whether it needs a self-test added to fips140_selftests[] as well. + * implementation(s) of them. + * + * All algorithms that will be declared as FIPS-approved in the module + * certification must be listed here, to ensure that the non-FIPS-approved + * implementations of these algorithms in the kernel image aren't used. + * + * For every algorithm in this list, the module should contain all the "same" + * implementations that the kernel image does, including the C implementation as + * well as any architecture-specific implementations. This is needed to avoid + * performance regressions as well as the possibility of an algorithm being + * unavailable on some CPUs. E.g., "xcbc(aes)" isn't in this list, as the + * module doesn't have a C implementation of it (and it won't be FIPS-approved). + * + * Due to a quirk in the FIPS requirements, "gcm(aes)" isn't actually able to be + * FIPS-approved. However, we otherwise treat it the same as the algorithms + * that will be FIPS-approved, and therefore it's included in this list. + * + * When adding a new algorithm here, make sure to consider whether it needs a + * self-test added to fips140_selftests[] as well. */ static const char * const fips140_algorithms[] __initconst = { "aes", - "gcm(aes)", - + "cmac(aes)", "ecb(aes)", + "cbc(aes)", + "cts(cbc(aes))", "ctr(aes)", "xts(aes)", + "gcm(aes)", "hmac(sha1)", "hmac(sha224)", @@ -91,6 +110,7 @@ static const char * const fips140_algorithms[] __initconst = { "sha512", "stdrng", + "jitterentropy_rng", }; static bool __init is_fips140_algo(struct crypto_alg *alg) diff --git a/crypto/fips140-selftests.c b/crypto/fips140-selftests.c index 3ebf5a914cf0..0ab388a9f213 100644 --- a/crypto/fips140-selftests.c +++ b/crypto/fips140-selftests.c @@ -14,10 +14,6 @@ * is somewhat helpful. Basically, all implementations of all FIPS approved * algorithms (including modes of operation) must be tested. However: * - * - If an implementation won't be used, it doesn't have to be tested. So - * when multiple implementations of the same algorithm are registered with - * the crypto API, we only have to test the default (highest-priority) one. - * * - There are provisions for skipping tests that are already sufficiently * covered by other tests. E.g., HMAC-SHA256 may cover SHA-256. * @@ -28,12 +24,16 @@ * * - Only one key size per algorithm needs to be tested. * + * There is some ambiguity about whether all implementations of each algorithm + * must be tested, or whether it is sufficient to test just the highest priority + * implementation. To be safe we test all implementations, except ones that can + * be excluded by one of the rules above. + * * See fips140_selftests[] for the list of tests we've selected. Currently, all - * our test vectors except the DRBG ones were generated by the script - * tools/crypto/gen_fips140_testvecs.py, using the known-good implementations in - * the Python packages hashlib, pycryptodome, and cryptography. The DRBG test - * vectors were manually extracted from - * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip. + * our test vectors except the AES-CBC-CTS and DRBG ones were generated by the + * script tools/crypto/gen_fips140_testvecs.py, using the known-good + * implementations in the Python packages hashlib, pycryptodome, and + * cryptography. * * Note that we don't reuse the upstream crypto API's self-tests * (crypto/testmgr.{c,h}), for several reasons: @@ -54,22 +54,12 @@ #include #include #include -#include #include #include #include #include "fips140-module.h" -/* Test vector for a block cipher algorithm */ -struct blockcipher_testvec { - const u8 *key; - size_t key_size; - const u8 *plaintext; - const u8 *ciphertext; - size_t block_size; -}; - /* Test vector for an AEAD algorithm */ struct aead_testvec { const u8 *key; @@ -121,15 +111,27 @@ struct drbg_testvec { size_t out_size; }; -/* - * A struct which specifies an algorithm name (using crypto API syntax), a test - * function for that algorithm, and a test vector used by that test function. - */ struct fips_test { + /* The name of the algorithm, in crypto API syntax */ const char *alg; - int __must_check (*func)(const struct fips_test *test); + + /* + * The optional list of implementations to test. @func will be called + * once per implementation, or once with @alg if this list is empty. + * The implementation names must be given in crypto API syntax, or in + * the case of a library implementation should have "-lib" appended. + */ + const char *impls[8]; + + /* + * The test function. It should execute a known-answer test on an + * algorithm implementation, using the below test vector. + */ + int __must_check (*func)(const struct fips_test *test, + const char *impl); + + /* The test vector, with a format specific to the type of algorithm */ union { - struct blockcipher_testvec blockcipher; struct aead_testvec aead; struct skcipher_testvec skcipher; struct hash_testvec hash; @@ -141,17 +143,16 @@ struct fips_test { #define MAX_IV_SIZE 16 static int __init __must_check -fips_check_result(const struct fips_test *test, u8 *result, - const u8 *expected_result, size_t result_size, - const char *operation) +fips_check_result(u8 *result, const u8 *expected_result, size_t result_size, + const char *impl, const char *operation) { #ifdef CONFIG_CRYPTO_FIPS140_MOD_ERROR_INJECTION /* Inject a failure (via corrupting the result) if requested. */ - if (fips140_broken_alg && strcmp(test->alg, fips140_broken_alg) == 0) + if (fips140_broken_alg && strcmp(impl, fips140_broken_alg) == 0) result[0] ^= 0xff; #endif if (memcmp(result, expected_result, result_size) != 0) { - pr_err("wrong result from %s %s\n", test->alg, operation); + pr_err("wrong result from %s %s\n", impl, operation); return -EBADMSG; } return 0; @@ -176,96 +177,56 @@ fips_validate_alg(const struct crypto_alg *alg) return 0; } -/* Test a block cipher using the crypto_cipher API. */ static int __init __must_check -fips_test_blockcipher(const struct fips_test *test) +fips_handle_alloc_tfm_error(const char *impl, int err) { - const struct blockcipher_testvec *vec = &test->blockcipher; - struct crypto_cipher *tfm; - u8 block[MAX_CIPHER_BLOCKSIZE]; - int err; - - if (WARN_ON(vec->block_size > MAX_CIPHER_BLOCKSIZE)) - return -EINVAL; - - tfm = crypto_alloc_cipher(test->alg, 0, 0); - if (IS_ERR(tfm)) { - err = PTR_ERR(tfm); - pr_err("failed to allocate %s tfm: %d\n", test->alg, err); - return err; - } - err = fips_validate_alg(tfm->base.__crt_alg); - if (err) - goto out; - if (crypto_cipher_blocksize(tfm) != vec->block_size) { - pr_err("%s has wrong block size\n", test->alg); - err = -EINVAL; - goto out; - } - - err = crypto_cipher_setkey(tfm, vec->key, vec->key_size); - if (err) { - pr_err("failed to set %s key: %d\n", test->alg, err); - goto out; - } - - /* Encrypt the plaintext, then verify the resulting ciphertext. */ - memcpy(block, vec->plaintext, vec->block_size); - crypto_cipher_encrypt_one(tfm, block, block); - err = fips_check_result(test, block, vec->ciphertext, vec->block_size, - "encryption"); - if (err) - goto out; - - /* Decrypt the ciphertext, then verify the resulting plaintext. */ - crypto_cipher_decrypt_one(tfm, block, block); - err = fips_check_result(test, block, vec->plaintext, vec->block_size, - "decryption"); -out: - crypto_free_cipher(tfm); + if (err == -ENOENT) { + /* + * The requested implementation of the algorithm wasn't found. + * This is expected if the CPU lacks a feature the + * implementation needs, such as the ARMv8 Crypto Extensions. + * + * When this happens, the implementation isn't available for + * use, so we can't test it, nor do we need to. So we just skip + * the test. + */ + pr_info("%s is unavailable (no CPU support?), skipping testing it\n", + impl); + return 0; + } + pr_err("failed to allocate %s tfm: %d\n", impl, err); return err; } -/* - * Test for plain AES (no mode of operation). We test this separately from the - * AES modes because the implementation of AES which is used by the "aes" - * crypto_cipher isn't necessarily the same as that used by the AES modes such - * as "ecb(aes)". Similarly, the aes_{encrypt,decrypt}() library functions may - * use a different implementation as well, so we test them separately too. - */ static int __init __must_check -fips_test_aes(const struct fips_test *test) +fips_test_aes_library(const struct fips_test *test, const char *impl) { - const struct blockcipher_testvec *vec = &test->blockcipher; + const struct skcipher_testvec *vec = &test->skcipher; struct crypto_aes_ctx ctx; u8 block[AES_BLOCK_SIZE]; int err; - if (WARN_ON(vec->block_size != AES_BLOCK_SIZE)) + if (WARN_ON(vec->message_size != AES_BLOCK_SIZE)) return -EINVAL; - err = fips_test_blockcipher(test); - if (err) - return err; - err = aes_expandkey(&ctx, vec->key, vec->key_size); if (err) { pr_err("aes_expandkey() failed: %d\n", err); return err; } aes_encrypt(&ctx, block, vec->plaintext); - err = fips_check_result(test, block, vec->ciphertext, AES_BLOCK_SIZE, - "encryption (library API)"); + err = fips_check_result(block, vec->ciphertext, AES_BLOCK_SIZE, + impl, "encryption"); if (err) return err; aes_decrypt(&ctx, block, block); - return fips_check_result(test, block, vec->plaintext, AES_BLOCK_SIZE, - "decryption (library API)"); + return fips_check_result(block, vec->plaintext, AES_BLOCK_SIZE, + impl, "decryption"); } /* Test a length-preserving symmetric cipher using the crypto_skcipher API. */ static int __init __must_check -fips_test_skcipher(const struct fips_test *test) +fips_test_skcipher(const struct fips_test *test, const char *impl) { const struct skcipher_testvec *vec = &test->skcipher; struct crypto_skcipher *tfm; @@ -277,18 +238,17 @@ fips_test_skcipher(const struct fips_test *test) if (WARN_ON(vec->iv_size > MAX_IV_SIZE)) return -EINVAL; + if (WARN_ON(vec->message_size <= 0)) + return -EINVAL; - tfm = crypto_alloc_skcipher(test->alg, 0, 0); - if (IS_ERR(tfm)) { - err = PTR_ERR(tfm); - pr_err("failed to allocate %s tfm: %d\n", test->alg, err); - return err; - } + tfm = crypto_alloc_skcipher(impl, 0, 0); + if (IS_ERR(tfm)) + return fips_handle_alloc_tfm_error(impl, PTR_ERR(tfm)); err = fips_validate_alg(&crypto_skcipher_alg(tfm)->base); if (err) goto out; if (crypto_skcipher_ivsize(tfm) != vec->iv_size) { - pr_err("%s has wrong IV size\n", test->alg); + pr_err("%s has wrong IV size\n", impl); err = -EINVAL; goto out; } @@ -307,7 +267,7 @@ fips_test_skcipher(const struct fips_test *test) err = crypto_skcipher_setkey(tfm, vec->key, vec->key_size); if (err) { - pr_err("failed to set %s key: %d\n", test->alg, err); + pr_err("failed to set %s key: %d\n", impl, err); goto out; } @@ -315,11 +275,11 @@ fips_test_skcipher(const struct fips_test *test) memcpy(iv, vec->iv, vec->iv_size); err = crypto_skcipher_encrypt(req); if (err) { - pr_err("%s encryption failed: %d\n", test->alg, err); + pr_err("%s encryption failed: %d\n", impl, err); goto out; } - err = fips_check_result(test, message, vec->ciphertext, - vec->message_size, "encryption"); + err = fips_check_result(message, vec->ciphertext, vec->message_size, + impl, "encryption"); if (err) goto out; @@ -327,11 +287,11 @@ fips_test_skcipher(const struct fips_test *test) memcpy(iv, vec->iv, vec->iv_size); err = crypto_skcipher_decrypt(req); if (err) { - pr_err("%s decryption failed: %d\n", test->alg, err); + pr_err("%s decryption failed: %d\n", impl, err); goto out; } - err = fips_check_result(test, message, vec->plaintext, - vec->message_size, "decryption"); + err = fips_check_result(message, vec->plaintext, vec->message_size, + impl, "decryption"); out: kfree(message); skcipher_request_free(req); @@ -341,7 +301,7 @@ fips_test_skcipher(const struct fips_test *test) /* Test an AEAD using the crypto_aead API. */ static int __init __must_check -fips_test_aead(const struct fips_test *test) +fips_test_aead(const struct fips_test *test, const char *impl) { const struct aead_testvec *vec = &test->aead; const int tag_size = vec->ciphertext_size - vec->plaintext_size; @@ -359,17 +319,14 @@ fips_test_aead(const struct fips_test *test) if (WARN_ON(vec->ciphertext_size <= vec->plaintext_size)) return -EINVAL; - tfm = crypto_alloc_aead(test->alg, 0, 0); - if (IS_ERR(tfm)) { - err = PTR_ERR(tfm); - pr_err("failed to allocate %s tfm: %d\n", test->alg, err); - return err; - } + tfm = crypto_alloc_aead(impl, 0, 0); + if (IS_ERR(tfm)) + return fips_handle_alloc_tfm_error(impl, PTR_ERR(tfm)); err = fips_validate_alg(&crypto_aead_alg(tfm)->base); if (err) goto out; if (crypto_aead_ivsize(tfm) != vec->iv_size) { - pr_err("%s has wrong IV size\n", test->alg); + pr_err("%s has wrong IV size\n", impl); err = -EINVAL; goto out; } @@ -393,14 +350,14 @@ fips_test_aead(const struct fips_test *test) err = crypto_aead_setkey(tfm, vec->key, vec->key_size); if (err) { - pr_err("failed to set %s key: %d\n", test->alg, err); + pr_err("failed to set %s key: %d\n", impl, err); goto out; } err = crypto_aead_setauthsize(tfm, tag_size); if (err) { pr_err("failed to set %s authentication tag size: %d\n", - test->alg, err); + impl, err); goto out; } @@ -412,11 +369,11 @@ fips_test_aead(const struct fips_test *test) aead_request_set_crypt(req, sg, sg, vec->plaintext_size, iv); err = crypto_aead_encrypt(req); if (err) { - pr_err("%s encryption failed: %d\n", test->alg, err); + pr_err("%s encryption failed: %d\n", impl, err); goto out; } - err = fips_check_result(test, message, vec->ciphertext, - vec->ciphertext_size, "encryption"); + err = fips_check_result(message, vec->ciphertext, vec->ciphertext_size, + impl, "encryption"); if (err) goto out; @@ -428,11 +385,11 @@ fips_test_aead(const struct fips_test *test) aead_request_set_crypt(req, sg, sg, vec->ciphertext_size, iv); err = crypto_aead_decrypt(req); if (err) { - pr_err("%s decryption failed: %d\n", test->alg, err); + pr_err("%s decryption failed: %d\n", impl, err); goto out; } - err = fips_check_result(test, message, vec->plaintext, - vec->plaintext_size, "decryption"); + err = fips_check_result(message, vec->plaintext, vec->plaintext_size, + impl, "decryption"); out: kfree(message); kfree(assoc); @@ -449,7 +406,7 @@ fips_test_aead(const struct fips_test *test) * be no hash algorithms that can be accessed only through crypto_ahash. */ static int __init __must_check -fips_test_hash(const struct fips_test *test) +fips_test_hash(const struct fips_test *test, const char *impl) { const struct hash_testvec *vec = &test->hash; struct crypto_shash *tfm; @@ -459,17 +416,14 @@ fips_test_hash(const struct fips_test *test) if (WARN_ON(vec->digest_size > HASH_MAX_DIGESTSIZE)) return -EINVAL; - tfm = crypto_alloc_shash(test->alg, 0, 0); - if (IS_ERR(tfm)) { - err = PTR_ERR(tfm); - pr_err("failed to allocate %s tfm: %d\n", test->alg, err); - return err; - } + tfm = crypto_alloc_shash(impl, 0, 0); + if (IS_ERR(tfm)) + return fips_handle_alloc_tfm_error(impl, PTR_ERR(tfm)); err = fips_validate_alg(&crypto_shash_alg(tfm)->base); if (err) goto out; if (crypto_shash_digestsize(tfm) != vec->digest_size) { - pr_err("%s has wrong digest size\n", test->alg); + pr_err("%s has wrong digest size\n", impl); err = -EINVAL; goto out; } @@ -477,7 +431,7 @@ fips_test_hash(const struct fips_test *test) if (vec->key) { err = crypto_shash_setkey(tfm, vec->key, vec->key_size); if (err) { - pr_err("failed to set %s key: %d\n", test->alg, err); + pr_err("failed to set %s key: %d\n", impl, err); goto out; } } @@ -485,22 +439,18 @@ fips_test_hash(const struct fips_test *test) err = crypto_shash_tfm_digest(tfm, vec->message, vec->message_size, digest); if (err) { - pr_err("%s digest computation failed: %d\n", test->alg, err); + pr_err("%s digest computation failed: %d\n", impl, err); goto out; } - err = fips_check_result(test, digest, vec->digest, vec->digest_size, - "digest"); + err = fips_check_result(digest, vec->digest, vec->digest_size, + impl, "digest"); out: crypto_free_shash(tfm); return err; } -/* - * Test the sha256() library function, as it may not be covered by the "sha256" - * crypto_shash, and thus may not be covered by the "hmac(sha256)" test we do. - */ static int __init __must_check -fips_test_sha256_library(const struct fips_test *test) +fips_test_sha256_library(const struct fips_test *test, const char *impl) { const struct hash_testvec *vec = &test->hash; u8 digest[SHA256_DIGEST_SIZE]; @@ -509,13 +459,13 @@ fips_test_sha256_library(const struct fips_test *test) return -EINVAL; sha256(vec->message, vec->message_size, digest); - return fips_check_result(test, digest, vec->digest, vec->digest_size, - "digest (library API)"); + return fips_check_result(digest, vec->digest, vec->digest_size, + impl, "digest"); } /* Test a DRBG using the crypto_rng API. */ static int __init __must_check -fips_test_drbg(const struct fips_test *test) +fips_test_drbg(const struct fips_test *test, const char *impl) { const struct drbg_testvec *vec = &test->drbg; struct crypto_rng *rng; @@ -524,12 +474,9 @@ fips_test_drbg(const struct fips_test *test) struct drbg_string addtl, pers, testentropy; int err; - rng = crypto_alloc_rng(test->alg, 0, 0); - if (IS_ERR(rng)) { - err = PTR_ERR(rng); - pr_err("failed to allocate %s tfm: %d\n", test->alg, err); - return PTR_ERR(rng); - } + rng = crypto_alloc_rng(impl, 0, 0); + if (IS_ERR(rng)) + return fips_handle_alloc_tfm_error(impl, PTR_ERR(rng)); err = fips_validate_alg(&crypto_rng_alg(rng)->base); if (err) goto out; @@ -549,7 +496,7 @@ fips_test_drbg(const struct fips_test *test) drbg_string_fill(&pers, vec->pers, vec->pers_size); err = crypto_drbg_reset_test(rng, &pers, &test_data); if (err) { - pr_err("failed to reset %s\n", test->alg); + pr_err("failed to reset %s\n", impl); goto out; } @@ -570,7 +517,7 @@ fips_test_drbg(const struct fips_test *test) } if (err) { pr_err("failed to get bytes from %s (try 1): %d\n", - test->alg, err); + impl, err); goto out; } @@ -590,13 +537,13 @@ fips_test_drbg(const struct fips_test *test) } if (err) { pr_err("failed to get bytes from %s (try 2): %d\n", - test->alg, err); + impl, err); goto out; } /* Check that the DRBG generated the expected output. */ - err = fips_check_result(test, output, vec->output, vec->out_size, - "get_bytes"); + err = fips_check_result(output, vec->output, vec->out_size, + impl, "get_bytes"); out: kfree(output); crypto_free_rng(rng); @@ -606,33 +553,144 @@ fips_test_drbg(const struct fips_test *test) /* Include the test vectors generated by the Python script. */ #include "fips140-generated-testvecs.h" -/* List of all self-tests. Keep this in sync with fips140_algorithms[]. */ +/* + * List of all self-tests. Keep this in sync with fips140_algorithms[]. + * + * When possible, we have followed the FIPS 140-2 Implementation Guidance (IG) + * document when creating this list of tests. The result is intended to be a + * list of tests that is near-minimal (and thus minimizes runtime overhead) + * while complying with all requirements. For additional details, see the + * comment at the beginning of this file. + */ static const struct fips_test fips140_selftests[] __initconst = { /* - * Tests for AES and AES modes. + * Test for the AES library API. + * + * Since the AES library API may use its own AES implementation and the + * module provides no support for composing it with a mode of operation + * (it's just plain AES), we must test it directly. * - * The full list of AES algorithms we potentially need to test are AES - * by itself, AES-CBC, AES-CTR, AES-ECB, AES-GCM, and AES-XTS. We can - * follow the FIPS 140-2 Implementation Guidance (IG) document to try to - * reduce this list, but we run into the issue that the architecture- - * specific implementations of these algorithms in Linux often don't - * share the "same" underlying AES implementation. E.g., the ARMv8 CE - * optimized implementations issue ARMv8 CE instructions directly rather - * than going through a separate AES implementation. In this case, - * separate tests are needed according to section 9.2 of the IG. + * In contrast, we don't need to directly test the "aes" ciphers that + * are accessible through the crypto_cipher API (e.g. "aes-ce"), as they + * are covered indirectly by AES-CMAC and AES-ECB tests. */ { .alg = "aes", - .func = fips_test_aes, - .blockcipher = { + .impls = {"aes-lib"}, + .func = fips_test_aes_library, + .skcipher = { .key = fips_aes_key, .key_size = sizeof(fips_aes_key), .plaintext = fips_message, .ciphertext = fips_aes_ecb_ciphertext, - .block_size = 16, + .message_size = 16, } - }, { + }, + /* + * Tests for AES-CMAC, a.k.a. "cmac(aes)" in crypto API syntax. + * + * The IG requires that each underlying AES implementation be tested in + * an authenticated mode, if implemented. Of such modes, this module + * implements AES-GCM and AES-CMAC. However, AES-GCM doesn't "count" + * because this module's implementations of AES-GCM won't actually be + * FIPS-approved, due to a quirk in the FIPS requirements. + * + * Therefore, for us this requirement applies to AES-CMAC, so we must + * test the "cmac" template composed with each "aes" implementation. + * + * Separately from the above, we also must test all standalone + * implementations of "cmac(aes)" such as "cmac-aes-ce", as they don't + * reuse another full AES implementation and thus can't be covered by + * another test. + */ + { + .alg = "cmac(aes)", + .impls = { + /* "cmac" template with all "aes" implementations */ + "cmac(aes-generic)", + "cmac(aes-arm64)", + "cmac(aes-ce)", + /* All standalone implementations of "cmac(aes)" */ + "cmac-aes-neon", + "cmac-aes-ce", + }, + .func = fips_test_hash, + .hash = { + .key = fips_aes_key, + .key_size = sizeof(fips_aes_key), + .message = fips_message, + .message_size = sizeof(fips_message), + .digest = fips_aes_cmac_digest, + .digest_size = sizeof(fips_aes_cmac_digest), + } + }, + /* + * Tests for AES-ECB, a.k.a. "ecb(aes)" in crypto API syntax. + * + * The IG requires that each underlying AES implementation be tested in + * a mode that exercises the encryption direction of AES and in a mode + * that exercises the decryption direction of AES. CMAC only covers the + * encryption direction, so we choose ECB to test decryption. Thus, we + * test the "ecb" template composed with each "aes" implementation. + * + * Separately from the above, we also must test all standalone + * implementations of "ecb(aes)" such as "ecb-aes-ce", as they don't + * reuse another full AES implementation and thus can't be covered by + * another test. + */ + { + .alg = "ecb(aes)", + .impls = { + /* "ecb" template with all "aes" implementations */ + "ecb(aes-generic)", + "ecb(aes-arm64)", + "ecb(aes-ce)", + /* All standalone implementations of "ecb(aes)" */ + "ecb-aes-neon", + "ecb-aes-neonbs", + "ecb-aes-ce", + }, + .func = fips_test_skcipher, + .skcipher = { + .key = fips_aes_key, + .key_size = sizeof(fips_aes_key), + .plaintext = fips_message, + .ciphertext = fips_aes_ecb_ciphertext, + .message_size = sizeof(fips_message) + } + }, + /* + * Tests for AES-CBC, AES-CBC-CTS, AES-CTR, AES-XTS, and AES-GCM. + * + * According to the IG, an AES mode of operation doesn't need to have + * its own test, provided that (a) both the encryption and decryption + * directions of the underlying AES implementation are already tested + * via other mode(s), and (b) in the case of an authenticated mode, at + * least one other authenticated mode is already tested. The tests of + * the "cmac" and "ecb" templates fulfill these conditions; therefore, + * we don't need to test any other AES mode templates. + * + * This does *not* apply to standalone implementations of these modes + * such as "cbc-aes-ce", as such implementations don't reuse another + * full AES implementation and thus can't be covered by another test. + * We must test all such standalone implementations. + * + * The AES-GCM test isn't actually required, as it's expected that this + * module's AES-GCM implementation won't actually be able to be + * FIPS-approved. This is unfortunate; it's caused by the FIPS + * requirements for GCM being incompatible with GCM implementations that + * don't generate their own IVs. We choose to still include the AES-GCM + * test to keep it on par with the other FIPS-approved algorithms, in + * case it turns out that AES-GCM can be approved after all. + */ + { .alg = "cbc(aes)", + .impls = { + /* All standalone implementations of "cbc(aes)" */ + "cbc-aes-neon", + "cbc-aes-neonbs", + "cbc-aes-ce", + }, .func = fips_test_skcipher, .skcipher = { .key = fips_aes_key, @@ -643,8 +701,40 @@ static const struct fips_test fips140_selftests[] __initconst = { .ciphertext = fips_aes_cbc_ciphertext, .message_size = sizeof(fips_message), } + }, { + .alg = "cts(cbc(aes))", + .impls = { + /* All standalone implementations of "cts(cbc(aes))" */ + "cts-cbc-aes-neon", + "cts-cbc-aes-ce", + }, + .func = fips_test_skcipher, + /* Test vector taken from RFC 3962 */ + .skcipher = { + .key = "\x63\x68\x69\x63\x6b\x65\x6e\x20" + "\x74\x65\x72\x69\x79\x61\x6b\x69", + .key_size = 16, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + .iv_size = 16, + .plaintext = "\x49\x20\x77\x6f\x75\x6c\x64\x20" + "\x6c\x69\x6b\x65\x20\x74\x68\x65" + "\x20\x47\x65\x6e\x65\x72\x61\x6c" + "\x20\x47\x61\x75\x27\x73\x20", + .ciphertext = "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1" + "\xd4\x45\xd4\xc8\xef\xf7\xed\x22" + "\x97\x68\x72\x68\xd6\xec\xcc\xc0" + "\xc0\x7b\x25\xe2\x5e\xcf\xe5", + .message_size = 31, + } }, { .alg = "ctr(aes)", + .impls = { + /* All standalone implementations of "ctr(aes)" */ + "ctr-aes-neon", + "ctr-aes-neonbs", + "ctr-aes-ce", + }, .func = fips_test_skcipher, .skcipher = { .key = fips_aes_key, @@ -656,23 +746,35 @@ static const struct fips_test fips140_selftests[] __initconst = { .message_size = sizeof(fips_message), } }, { - .alg = "ecb(aes)", + .alg = "xts(aes)", + .impls = { + /* All standalone implementations of "xts(aes)" */ + "xts-aes-neon", + "xts-aes-neonbs", + "xts-aes-ce", + }, .func = fips_test_skcipher, .skcipher = { - .key = fips_aes_key, - .key_size = sizeof(fips_aes_key), + .key = fips_aes_xts_key, + .key_size = sizeof(fips_aes_xts_key), + .iv = fips_aes_iv, + .iv_size = sizeof(fips_aes_iv), .plaintext = fips_message, - .ciphertext = fips_aes_ecb_ciphertext, - .message_size = sizeof(fips_message) + .ciphertext = fips_aes_xts_ciphertext, + .message_size = sizeof(fips_message), } }, { .alg = "gcm(aes)", + .impls = { + /* All standalone implementations of "gcm(aes)" */ + "gcm-aes-ce", + }, .func = fips_test_aead, .aead = { .key = fips_aes_key, .key_size = sizeof(fips_aes_key), .iv = fips_aes_iv, - /* The GCM implementation assumes an IV size of 12. */ + /* The GCM implementations assume an IV size of 12. */ .iv_size = 12, .assoc = fips_aes_gcm_assoc, .assoc_size = sizeof(fips_aes_gcm_assoc), @@ -681,39 +783,16 @@ static const struct fips_test fips140_selftests[] __initconst = { .ciphertext = fips_aes_gcm_ciphertext, .ciphertext_size = sizeof(fips_aes_gcm_ciphertext), } - }, { - .alg = "xts(aes)", - .func = fips_test_skcipher, - .skcipher = { - .key = fips_aes_xts_key, - .key_size = sizeof(fips_aes_xts_key), - .iv = fips_aes_iv, - .iv_size = sizeof(fips_aes_iv), - .plaintext = fips_message, - .ciphertext = fips_aes_xts_ciphertext, - .message_size = sizeof(fips_message), - } - /* - * Tests for SHA-1, SHA-256, HMAC-SHA256, and SHA-512. - * - * The selection of these specific tests follows the guidance from - * section 9 of the FIPS 140-2 Implementation Guidance (IG) document to - * achieve a minimal list of tests, rather than testing all of - * SHA-{1,224,256,384,512} and HMAC-SHA{1,224,256,384,512}. As per the - * IG, testing SHA-224 is only required if SHA-256 isn't implemented, - * and testing SHA-384 is only required if SHA-512 isn't implemented. - * Also, HMAC only has to be tested with one underlying SHA, and the - * HMAC test also fulfills the test for its underlying SHA. That would - * result in a test list of e.g. SHA-1, HMAC-SHA256, and SHA-512. - * - * However we also need to take into account cases where implementations - * aren't shared in the "natural" way assumed by the IG. Currently the - * only known exception w.r.t. SHA-* and HMAC-* is the sha256() library - * function which may not be covered by the test of the "hmac(sha256)" - * crypto_shash. So, we test sha256() separately. - */ - }, { + }, + + /* Tests for SHA-1 */ + { .alg = "sha1", + .impls = { + /* All implementations of "sha1" */ + "sha1-generic", + "sha1-ce" + }, .func = fips_test_hash, .hash = { .message = fips_message, @@ -721,28 +800,55 @@ static const struct fips_test fips140_selftests[] __initconst = { .digest = fips_sha1_digest, .digest_size = sizeof(fips_sha1_digest) } - }, { + }, + /* + * Tests for all SHA-256 implementations other than the sha256() library + * function. As per the IG, these tests also fulfill the tests for the + * corresponding SHA-224 implementations. + */ + { .alg = "sha256", - .func = fips_test_sha256_library, + .impls = { + /* All implementations of "sha256" */ + "sha256-generic", + "sha256-arm64", + "sha256-ce", + }, + .func = fips_test_hash, .hash = { .message = fips_message, .message_size = sizeof(fips_message), .digest = fips_sha256_digest, .digest_size = sizeof(fips_sha256_digest) } - }, { - .alg = "hmac(sha256)", - .func = fips_test_hash, + }, + /* + * Test for the sha256() library function. This must be tested + * separately because it may use its own SHA-256 implementation. + */ + { + .alg = "sha256", + .impls = {"sha256-lib"}, + .func = fips_test_sha256_library, .hash = { - .key = fips_hmac_key, - .key_size = sizeof(fips_hmac_key), .message = fips_message, .message_size = sizeof(fips_message), - .digest = fips_hmac_sha256_digest, - .digest_size = sizeof(fips_hmac_sha256_digest) + .digest = fips_sha256_digest, + .digest_size = sizeof(fips_sha256_digest) } - }, { + }, + /* + * Tests for all SHA-512 implementations. As per the IG, these tests + * also fulfill the tests for the corresponding SHA-384 implementations. + */ + { .alg = "sha512", + .impls = { + /* All implementations of "sha512" */ + "sha512-generic", + "sha512-arm64", + "sha512-ce", + }, .func = fips_test_hash, .hash = { .message = fips_message, @@ -750,52 +856,56 @@ static const struct fips_test fips140_selftests[] __initconst = { .digest = fips_sha512_digest, .digest_size = sizeof(fips_sha512_digest) } + }, /* - * Tests for DRBG algorithms. + * Test for HMAC. As per the IG, only one HMAC test is required, + * provided that the same HMAC code is shared by all HMAC-SHA*. This is + * true in our case. We choose HMAC-SHA256 for the test. * - * Only the default variant (the one that users get when they request - * "stdrng") is required to be tested, as we don't consider the other - * variants to be used / usable in the FIPS security policy. This is - * similar to how e.g. we don't test both "xts(aes-generic)" and - * "xts-aes-ce" but rather just "xts(aes)". - * - * Currently the default one is "drbg_nopr_hmac_sha256"; however, just - * in case we also test the prediction-resistant enabled variant too. + * Note that as per the IG, this can fulfill the test for the underlying + * SHA. However, we don't currently rely on this. */ - }, { - .alg = "drbg_nopr_hmac_sha256", - .func = fips_test_drbg, - .drbg = { - .entropy = - "\xf9\x7a\x3c\xfd\x91\xfa\xa0\x46\xb9\xe6\x1b\x94" - "\x93\xd4\x36\xc4\x93\x1f\x60\x4b\x22\xf1\x08\x15" - "\x21\xb3\x41\x91\x51\xe8\xff\x06\x11\xf3\xa7\xd4" - "\x35\x95\x35\x7d\x58\x12\x0b\xd1\xe2\xdd\x8a\xed", - .entropy_size = 48, - .output = - "\xc6\x87\x1c\xff\x08\x24\xfe\x55\xea\x76\x89\xa5" - "\x22\x29\x88\x67\x30\x45\x0e\x5d\x36\x2d\xa5\xbf" - "\x59\x0d\xcf\x9a\xcd\x67\xfe\xd4\xcb\x32\x10\x7d" - "\xf5\xd0\x39\x69\xa6\x6b\x1f\x64\x94\xfd\xf5\xd6" - "\x3d\x5b\x4d\x0d\x34\xea\x73\x99\xa0\x7d\x01\x16" - "\x12\x6d\x0d\x51\x8c\x7c\x55\xba\x46\xe1\x2f\x62" - "\xef\xc8\xfe\x28\xa5\x1c\x9d\x42\x8e\x6d\x37\x1d" - "\x73\x97\xab\x31\x9f\xc7\x3d\xed\x47\x22\xe5\xb4" - "\xf3\x00\x04\x03\x2a\x61\x28\xdf\x5e\x74\x97\xec" - "\xf8\x2c\xa7\xb0\xa5\x0e\x86\x7e\xf6\x72\x8a\x4f" - "\x50\x9a\x8c\x85\x90\x87\x03\x9c", - .out_size = 128, - .add_a = - "\x51\x72\x89\xaf\xe4\x44\xa0\xfe\x5e\xd1\xa4\x1d" - "\xbb\xb5\xeb\x17\x15\x00\x79\xbd\xd3\x1e\x29\xcf" - "\x2f\xf3\x00\x34\xd8\x26\x8e\x3b", - .add_b = - "\x88\x02\x8d\x29\xef\x80\xb4\xe6\xf0\xfe\x12\xf9" - "\x1d\x74\x49\xfe\x75\x06\x26\x82\xe8\x9c\x57\x14" - "\x40\xc0\xc9\xb5\x2c\x42\xa6\xe0", - .add_size = 32, + { + .alg = "hmac(sha256)", + .func = fips_test_hash, + .hash = { + .key = fips_hmac_key, + .key_size = sizeof(fips_hmac_key), + .message = fips_message, + .message_size = sizeof(fips_message), + .digest = fips_hmac_sha256_digest, + .digest_size = sizeof(fips_hmac_sha256_digest) } - }, { + }, + /* + * Known-answer tests for the SP800-90A DRBG algorithms. + * + * These test vectors were manually extracted from + * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip. + * + * The selection of these tests follows the FIPS 140-2 IG as well as + * Section 11 of SP800-90A: + * + * - We must test all DRBG types (HMAC, Hash, and CTR) that the module + * implements. However, currently the module only implements + * HMAC_DRBG (since CONFIG_CRYPTO_DRBG_CTR and CONFIG_CRYPTO_DRBG_HASH + * aren't enabled). Therefore, we only need to test HMAC_DRBG. + * + * - We only need to test one HMAC variant. + * + * - We must test all DRBG operations: Instantiate(), Reseed(), and + * Generate(). However, a single test sequence with a single output + * comparison may cover all three operations, and this is what we do. + * Note that Reseed() happens implicitly via the use of the additional + * input and also via the use of prediction resistance when enabled. + * + * - The personalization string, additional input, and prediction + * resistance support must be tested. Therefore we have chosen test + * vectors that have a nonempty personalization string and nonempty + * additional input, and we test the prediction-resistant variant. + * Testing the non-prediction-resistant variant is not required. + */ + { .alg = "drbg_pr_hmac_sha256", .func = fips_test_drbg, .drbg = { @@ -845,19 +955,44 @@ static const struct fips_test fips140_selftests[] __initconst = { } }; -bool __init fips140_run_selftests(void) +static int __init __must_check +fips_run_test(const struct fips_test *test) { int i; + int err; - pr_info("running self-tests\n"); - for (i = 0; i < ARRAY_SIZE(fips140_selftests); i++) { - const struct fips_test *test = &fips140_selftests[i]; - int err; + /* + * If no implementations were specified, then just test the default one. + * Otherwise, test the specified list of implementations. + */ - err = test->func(test); - if (err) { + if (test->impls[0] == NULL) { + err = test->func(test, test->alg); + if (err) pr_emerg("self-tests failed for algorithm %s: %d\n", test->alg, err); + return err; + } + + for (i = 0; i < ARRAY_SIZE(test->impls) && test->impls[i] != NULL; + i++) { + err = test->func(test, test->impls[i]); + if (err) { + pr_emerg("self-tests failed for algorithm %s, implementation %s: %d\n", + test->alg, test->impls[i], err); + return err; + } + } + return 0; +} + +bool __init fips140_run_selftests(void) +{ + int i; + + pr_info("running self-tests\n"); + for (i = 0; i < ARRAY_SIZE(fips140_selftests); i++) { + if (fips_run_test(&fips140_selftests[i]) != 0) { /* The caller is responsible for calling panic(). */ return false; } diff --git a/crypto/sm2.c b/crypto/sm2.c index 767e160333f6..db8a4a265669 100644 --- a/crypto/sm2.c +++ b/crypto/sm2.c @@ -79,10 +79,17 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec) goto free; rc = -ENOMEM; + + ec->Q = mpi_point_new(0); + if (!ec->Q) + goto free; + /* mpi_ec_setup_elliptic_curve */ ec->G = mpi_point_new(0); - if (!ec->G) + if (!ec->G) { + mpi_point_release(ec->Q); goto free; + } mpi_set(ec->G->x, x); mpi_set(ec->G->y, y); @@ -91,6 +98,7 @@ static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec) rc = -EINVAL; ec->n = mpi_scanval(ecp->n); if (!ec->n) { + mpi_point_release(ec->Q); mpi_point_release(ec->G); goto free; } @@ -119,12 +127,6 @@ static void sm2_ec_ctx_deinit(struct mpi_ec_ctx *ec) memset(ec, 0, sizeof(*ec)); } -static int sm2_ec_ctx_reset(struct mpi_ec_ctx *ec) -{ - sm2_ec_ctx_deinit(ec); - return sm2_ec_ctx_init(ec); -} - /* RESULT must have been initialized and is set on success to the * point given by VALUE. */ @@ -132,55 +134,48 @@ static int sm2_ecc_os2ec(MPI_POINT result, MPI value) { int rc; size_t n; - const unsigned char *buf; - unsigned char *buf_memory; + unsigned char *buf; MPI x, y; - n = (mpi_get_nbits(value)+7)/8; - buf_memory = kmalloc(n, GFP_KERNEL); - rc = mpi_print(GCRYMPI_FMT_USG, buf_memory, n, &n, value); - if (rc) { - kfree(buf_memory); - return rc; - } - buf = buf_memory; + n = MPI_NBYTES(value); + buf = kmalloc(n, GFP_KERNEL); + if (!buf) + return -ENOMEM; - if (n < 1) { - kfree(buf_memory); - return -EINVAL; - } - if (*buf != 4) { - kfree(buf_memory); - return -EINVAL; /* No support for point compression. */ - } - if (((n-1)%2)) { - kfree(buf_memory); - return -EINVAL; - } - n = (n-1)/2; + rc = mpi_print(GCRYMPI_FMT_USG, buf, n, &n, value); + if (rc) + goto err_freebuf; + + rc = -EINVAL; + if (n < 1 || ((n - 1) % 2)) + goto err_freebuf; + /* No support for point compression */ + if (*buf != 0x4) + goto err_freebuf; + + rc = -ENOMEM; + n = (n - 1) / 2; x = mpi_read_raw_data(buf + 1, n); - if (!x) { - kfree(buf_memory); - return -ENOMEM; - } + if (!x) + goto err_freebuf; y = mpi_read_raw_data(buf + 1 + n, n); - kfree(buf_memory); - if (!y) { - mpi_free(x); - return -ENOMEM; - } + if (!y) + goto err_freex; mpi_normalize(x); mpi_normalize(y); - mpi_set(result->x, x); mpi_set(result->y, y); mpi_set_ui(result->z, 1); - mpi_free(x); - mpi_free(y); + rc = 0; - return 0; + mpi_free(y); +err_freex: + mpi_free(x); +err_freebuf: + kfree(buf); + return rc; } struct sm2_signature_ctx { @@ -399,31 +394,15 @@ static int sm2_set_pub_key(struct crypto_akcipher *tfm, MPI a; int rc; - rc = sm2_ec_ctx_reset(ec); - if (rc) - return rc; - - ec->Q = mpi_point_new(0); - if (!ec->Q) - return -ENOMEM; - /* include the uncompressed flag '0x04' */ - rc = -ENOMEM; a = mpi_read_raw_data(key, keylen); if (!a) - goto error; + return -ENOMEM; mpi_normalize(a); rc = sm2_ecc_os2ec(ec->Q, a); mpi_free(a); - if (rc) - goto error; - return 0; - -error: - mpi_point_release(ec->Q); - ec->Q = NULL; return rc; } diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index edf1558c1105..b5ea34c340cc 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -359,7 +359,7 @@ config ACPI_TABLE_UPGRADE config ACPI_TABLE_OVERRIDE_VIA_BUILTIN_INITRD bool "Override ACPI tables from built-in initrd" depends on ACPI_TABLE_UPGRADE - depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION="" + depends on INITRAMFS_SOURCE!="" && INITRAMFS_COMPRESSION_NONE help This option provides functionality to override arbitrary ACPI tables from built-in uncompressed initrd. diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 44e412506317..4466156474ee 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -8,6 +8,11 @@ ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT # # ACPI Boot-Time Table Parsing # +ifeq ($(CONFIG_ACPI_CUSTOM_DSDT),y) +tables.o: $(src)/../../include/$(subst $\",,$(CONFIG_ACPI_CUSTOM_DSDT_FILE)) ; + +endif + obj-$(CONFIG_ACPI) += tables.o obj-$(CONFIG_X86) += blacklist.o diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c index 49b781a9cd97..ab8a4e0191b1 100644 --- a/drivers/acpi/acpi_amba.c +++ b/drivers/acpi/acpi_amba.c @@ -76,6 +76,7 @@ static int amba_handler_attach(struct acpi_device *adev, case IORESOURCE_MEM: if (!address_found) { dev->res = *rentry->res; + dev->res.name = dev_name(&dev->dev); address_found = true; } break; diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index b8745ce48a47..b84ab722feb4 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -261,7 +261,7 @@ static uint32_t acpi_pad_idle_cpus_num(void) return ps_tsk_num; } -static ssize_t acpi_pad_rrtime_store(struct device *dev, +static ssize_t rrtime_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long num; @@ -275,16 +275,14 @@ static ssize_t acpi_pad_rrtime_store(struct device *dev, return count; } -static ssize_t acpi_pad_rrtime_show(struct device *dev, +static ssize_t rrtime_show(struct device *dev, struct device_attribute *attr, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", round_robin_time); } -static DEVICE_ATTR(rrtime, S_IRUGO|S_IWUSR, - acpi_pad_rrtime_show, - acpi_pad_rrtime_store); +static DEVICE_ATTR_RW(rrtime); -static ssize_t acpi_pad_idlepct_store(struct device *dev, +static ssize_t idlepct_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long num; @@ -298,16 +296,14 @@ static ssize_t acpi_pad_idlepct_store(struct device *dev, return count; } -static ssize_t acpi_pad_idlepct_show(struct device *dev, +static ssize_t idlepct_show(struct device *dev, struct device_attribute *attr, char *buf) { return scnprintf(buf, PAGE_SIZE, "%d\n", idle_pct); } -static DEVICE_ATTR(idlepct, S_IRUGO|S_IWUSR, - acpi_pad_idlepct_show, - acpi_pad_idlepct_store); +static DEVICE_ATTR_RW(idlepct); -static ssize_t acpi_pad_idlecpus_store(struct device *dev, +static ssize_t idlecpus_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long num; @@ -319,16 +315,14 @@ static ssize_t acpi_pad_idlecpus_store(struct device *dev, return count; } -static ssize_t acpi_pad_idlecpus_show(struct device *dev, +static ssize_t idlecpus_show(struct device *dev, struct device_attribute *attr, char *buf) { return cpumap_print_to_pagebuf(false, buf, to_cpumask(pad_busy_cpus_bits)); } -static DEVICE_ATTR(idlecpus, S_IRUGO|S_IWUSR, - acpi_pad_idlecpus_show, - acpi_pad_idlecpus_store); +static DEVICE_ATTR_RW(idlecpus); static int acpi_pad_add_sysfs(struct acpi_device *device) { diff --git a/drivers/acpi/acpi_tad.c b/drivers/acpi/acpi_tad.c index 7d45cce0c3c1..e9b8e8305e23 100644 --- a/drivers/acpi/acpi_tad.c +++ b/drivers/acpi/acpi_tad.c @@ -237,7 +237,7 @@ static ssize_t time_show(struct device *dev, struct device_attribute *attr, rt.tz, rt.daylight); } -static DEVICE_ATTR(time, S_IRUSR | S_IWUSR, time_show, time_store); +static DEVICE_ATTR_RW(time); static struct attribute *acpi_tad_time_attrs[] = { &dev_attr_time.attr, @@ -446,7 +446,7 @@ static ssize_t ac_alarm_show(struct device *dev, struct device_attribute *attr, return acpi_tad_alarm_read(dev, buf, ACPI_TAD_AC_TIMER); } -static DEVICE_ATTR(ac_alarm, S_IRUSR | S_IWUSR, ac_alarm_show, ac_alarm_store); +static DEVICE_ATTR_RW(ac_alarm); static ssize_t ac_policy_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -462,7 +462,7 @@ static ssize_t ac_policy_show(struct device *dev, struct device_attribute *attr, return acpi_tad_policy_read(dev, buf, ACPI_TAD_AC_TIMER); } -static DEVICE_ATTR(ac_policy, S_IRUSR | S_IWUSR, ac_policy_show, ac_policy_store); +static DEVICE_ATTR_RW(ac_policy); static ssize_t ac_status_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -478,7 +478,7 @@ static ssize_t ac_status_show(struct device *dev, struct device_attribute *attr, return acpi_tad_status_read(dev, buf, ACPI_TAD_AC_TIMER); } -static DEVICE_ATTR(ac_status, S_IRUSR | S_IWUSR, ac_status_show, ac_status_store); +static DEVICE_ATTR_RW(ac_status); static struct attribute *acpi_tad_attrs[] = { &dev_attr_caps.attr, @@ -505,7 +505,7 @@ static ssize_t dc_alarm_show(struct device *dev, struct device_attribute *attr, return acpi_tad_alarm_read(dev, buf, ACPI_TAD_DC_TIMER); } -static DEVICE_ATTR(dc_alarm, S_IRUSR | S_IWUSR, dc_alarm_show, dc_alarm_store); +static DEVICE_ATTR_RW(dc_alarm); static ssize_t dc_policy_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -521,7 +521,7 @@ static ssize_t dc_policy_show(struct device *dev, struct device_attribute *attr, return acpi_tad_policy_read(dev, buf, ACPI_TAD_DC_TIMER); } -static DEVICE_ATTR(dc_policy, S_IRUSR | S_IWUSR, dc_policy_show, dc_policy_store); +static DEVICE_ATTR_RW(dc_policy); static ssize_t dc_status_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -537,7 +537,7 @@ static ssize_t dc_status_show(struct device *dev, struct device_attribute *attr, return acpi_tad_status_read(dev, buf, ACPI_TAD_DC_TIMER); } -static DEVICE_ATTR(dc_status, S_IRUSR | S_IWUSR, dc_status_show, dc_status_store); +static DEVICE_ATTR_RW(dc_status); static struct attribute *acpi_tad_dc_attrs[] = { &dev_attr_dc_alarm.attr, diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index a322a7bd286b..eb04b2f828ee 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -543,6 +543,15 @@ static const struct dmi_system_id video_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"), }, }, + { + .callback = video_set_report_key_events, + .driver_data = (void *)((uintptr_t)REPORT_BRIGHTNESS_KEY_EVENTS), + .ident = "Dell Vostro 3350", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3350"), + }, + }, /* * Some machines change the brightness themselves when a brightness * hotkey gets pressed, despite us telling them not to. In this case diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index fce7ade2aba9..0c8330ed1ffd 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -441,28 +441,35 @@ static void ghes_kick_task_work(struct callback_head *head) gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, node_len); } -static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, - int sev) +static bool ghes_do_memory_failure(u64 physical_addr, int flags) { unsigned long pfn; - int flags = -1; - int sec_sev = ghes_severity(gdata->error_severity); - struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata); if (!IS_ENABLED(CONFIG_ACPI_APEI_MEMORY_FAILURE)) return false; - if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) - return false; - - pfn = mem_err->physical_addr >> PAGE_SHIFT; + pfn = PHYS_PFN(physical_addr); if (!pfn_valid(pfn)) { pr_warn_ratelimited(FW_WARN GHES_PFX "Invalid address in generic error data: %#llx\n", - mem_err->physical_addr); + physical_addr); return false; } + memory_failure_queue(pfn, flags); + return true; +} + +static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, + int sev) +{ + int flags = -1; + int sec_sev = ghes_severity(gdata->error_severity); + struct cper_sec_mem_err *mem_err = acpi_hest_get_payload(gdata); + + if (!(mem_err->validation_bits & CPER_MEM_VALID_PA)) + return false; + /* iff following two events can be handled properly by now */ if (sec_sev == GHES_SEV_CORRECTED && (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED)) @@ -470,14 +477,56 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE) flags = 0; - if (flags != -1) { - memory_failure_queue(pfn, flags); - return true; - } + if (flags != -1) + return ghes_do_memory_failure(mem_err->physical_addr, flags); return false; } +static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev) +{ + struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); + bool queued = false; + int sec_sev, i; + char *p; + + log_arm_hw_error(err); + + sec_sev = ghes_severity(gdata->error_severity); + if (sev != GHES_SEV_RECOVERABLE || sec_sev != GHES_SEV_RECOVERABLE) + return false; + + p = (char *)(err + 1); + for (i = 0; i < err->err_info_num; i++) { + struct cper_arm_err_info *err_info = (struct cper_arm_err_info *)p; + bool is_cache = (err_info->type == CPER_ARM_CACHE_ERROR); + bool has_pa = (err_info->validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR); + const char *error_type = "unknown error"; + + /* + * The field (err_info->error_info & BIT(26)) is fixed to set to + * 1 in some old firmware of HiSilicon Kunpeng920. We assume that + * firmware won't mix corrected errors in an uncorrected section, + * and don't filter out 'corrected' error here. + */ + if (is_cache && has_pa) { + queued = ghes_do_memory_failure(err_info->physical_fault_addr, 0); + p += err_info->length; + continue; + } + + if (err_info->type < ARRAY_SIZE(cper_proc_error_type_strs)) + error_type = cper_proc_error_type_strs[err_info->type]; + + pr_warn_ratelimited(FW_WARN GHES_PFX + "Unhandled processor error type: %s\n", + error_type); + p += err_info->length; + } + + return queued; +} + /* * PCIe AER errors need to be sent to the AER driver for reporting and * recovery. The GHES severities map to the following AER severities and @@ -605,9 +654,7 @@ static bool ghes_do_proc(struct ghes *ghes, ghes_handle_aer(gdata); } else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { - struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); - - log_arm_hw_error(err); + queued = ghes_handle_arm_hw_error(gdata, sev); } else { void *err = acpi_hest_get_payload(gdata); diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c index 251f961c28cc..e0d14017706e 100644 --- a/drivers/acpi/bgrt.c +++ b/drivers/acpi/bgrt.c @@ -15,40 +15,19 @@ static void *bgrt_image; static struct kobject *bgrt_kobj; -static ssize_t show_version(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.version); -} -static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); - -static ssize_t show_status(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.status); -} -static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); - -static ssize_t show_type(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_type); -} -static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); - -static ssize_t show_xoffset(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_x); -} -static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL); - -static ssize_t show_yoffset(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_y); -} -static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL); +#define BGRT_SHOW(_name, _member) \ + static ssize_t _name##_show(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf) \ + { \ + return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab._member); \ + } \ + struct kobj_attribute bgrt_attr_##_name = __ATTR_RO(_name) + +BGRT_SHOW(version, version); +BGRT_SHOW(status, status); +BGRT_SHOW(type, image_type); +BGRT_SHOW(xoffset, image_offset_x); +BGRT_SHOW(yoffset, image_offset_y); static ssize_t image_read(struct file *file, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) @@ -60,11 +39,11 @@ static ssize_t image_read(struct file *file, struct kobject *kobj, static BIN_ATTR_RO(image, 0); /* size gets filled in later */ static struct attribute *bgrt_attributes[] = { - &dev_attr_version.attr, - &dev_attr_status.attr, - &dev_attr_type.attr, - &dev_attr_xoffset.attr, - &dev_attr_yoffset.attr, + &bgrt_attr_version.attr, + &bgrt_attr_status.attr, + &bgrt_attr_type.attr, + &bgrt_attr_xoffset.attr, + &bgrt_attr_yoffset.attr, NULL, }; diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 1682f8b454a2..e317214aabec 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -1245,6 +1245,7 @@ static int __init acpi_init(void) result = acpi_bus_init(); if (result) { + kobject_put(acpi_kobj); disable_acpi(); return result; } diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 48ff6821a83d..ecd2ddc2215f 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -18,6 +18,7 @@ #include #include +#include "fan.h" #include "internal.h" #define _COMPONENT ACPI_POWER_COMPONENT @@ -1298,10 +1299,7 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) * with the generic ACPI PM domain. */ static const struct acpi_device_id special_pm_ids[] = { - {"PNP0C0B", }, /* Generic ACPI fan */ - {"INT3404", }, /* Fan */ - {"INTC1044", }, /* Fan for Tiger Lake generation */ - {"INTC1048", }, /* Fan for Alder Lake generation */ + ACPI_FAN_DEVICE_IDS, {} }; struct acpi_device *adev = ACPI_COMPANION(dev); diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index bfca116482b8..fe8c7e79f472 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -325,11 +325,11 @@ int acpi_device_modalias(struct device *dev, char *buf, int size) EXPORT_SYMBOL_GPL(acpi_device_modalias); static ssize_t -acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) +modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { return __acpi_device_modalias(to_acpi_device(dev), buf, 1024); } -static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); +static DEVICE_ATTR_RO(modalias); static ssize_t real_power_state_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -358,8 +358,8 @@ static ssize_t power_state_show(struct device *dev, static DEVICE_ATTR_RO(power_state); static ssize_t -acpi_eject_store(struct device *d, struct device_attribute *attr, - const char *buf, size_t count) +eject_store(struct device *d, struct device_attribute *attr, + const char *buf, size_t count) { struct acpi_device *acpi_device = to_acpi_device(d); acpi_object_type not_used; @@ -387,28 +387,28 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, return status == AE_NO_MEMORY ? -ENOMEM : -EAGAIN; } -static DEVICE_ATTR(eject, 0200, NULL, acpi_eject_store); +static DEVICE_ATTR_WO(eject); static ssize_t -acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *buf) +hid_show(struct device *dev, struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); return sprintf(buf, "%s\n", acpi_device_hid(acpi_dev)); } -static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); +static DEVICE_ATTR_RO(hid); -static ssize_t acpi_device_uid_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t uid_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id); } -static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL); +static DEVICE_ATTR_RO(uid); -static ssize_t acpi_device_adr_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t adr_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); @@ -417,16 +417,16 @@ static ssize_t acpi_device_adr_show(struct device *dev, else return sprintf(buf, "0x%08llx\n", acpi_dev->pnp.bus_address); } -static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL); +static DEVICE_ATTR_RO(adr); -static ssize_t acpi_device_path_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t path_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); return acpi_object_path(acpi_dev->handle, buf); } -static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL); +static DEVICE_ATTR_RO(path); /* sysfs file that shows description text from the ACPI _STR method */ static ssize_t description_show(struct device *dev, @@ -446,7 +446,7 @@ static ssize_t description_show(struct device *dev, (wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer, acpi_dev->pnp.str_obj->buffer.length, UTF16_LITTLE_ENDIAN, buf, - PAGE_SIZE); + PAGE_SIZE - 1); buf[result++] = '\n'; @@ -455,8 +455,8 @@ static ssize_t description_show(struct device *dev, static DEVICE_ATTR_RO(description); static ssize_t -acpi_device_sun_show(struct device *dev, struct device_attribute *attr, - char *buf) { +sun_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); acpi_status status; unsigned long long sun; @@ -467,11 +467,11 @@ acpi_device_sun_show(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%llu\n", sun); } -static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); +static DEVICE_ATTR_RO(sun); static ssize_t -acpi_device_hrv_show(struct device *dev, struct device_attribute *attr, - char *buf) { +hrv_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct acpi_device *acpi_dev = to_acpi_device(dev); acpi_status status; unsigned long long hrv; @@ -482,7 +482,7 @@ acpi_device_hrv_show(struct device *dev, struct device_attribute *attr, return sprintf(buf, "%llu\n", hrv); } -static DEVICE_ATTR(hrv, 0444, acpi_device_hrv_show, NULL); +static DEVICE_ATTR_RO(hrv); static ssize_t status_show(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 24e076f44d23..0937ceab052e 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -484,7 +484,7 @@ int dock_notify(struct acpi_device *adev, u32 event) /* * show_docked - read method for "docked" file in sysfs */ -static ssize_t show_docked(struct device *dev, +static ssize_t docked_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dock_station *dock_station = dev->platform_data; @@ -493,25 +493,25 @@ static ssize_t show_docked(struct device *dev, acpi_bus_get_device(dock_station->handle, &adev); return snprintf(buf, PAGE_SIZE, "%u\n", acpi_device_enumerated(adev)); } -static DEVICE_ATTR(docked, S_IRUGO, show_docked, NULL); +static DEVICE_ATTR_RO(docked); /* * show_flags - read method for flags file in sysfs */ -static ssize_t show_flags(struct device *dev, +static ssize_t flags_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dock_station *dock_station = dev->platform_data; return snprintf(buf, PAGE_SIZE, "%d\n", dock_station->flags); } -static DEVICE_ATTR(flags, S_IRUGO, show_flags, NULL); +static DEVICE_ATTR_RO(flags); /* * write_undock - write method for "undock" file in sysfs */ -static ssize_t write_undock(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t undock_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { int ret; struct dock_station *dock_station = dev->platform_data; @@ -525,13 +525,13 @@ static ssize_t write_undock(struct device *dev, struct device_attribute *attr, acpi_scan_lock_release(); return ret ? ret: count; } -static DEVICE_ATTR(undock, S_IWUSR, NULL, write_undock); +static DEVICE_ATTR_WO(undock); /* * show_dock_uid - read method for "uid" file in sysfs */ -static ssize_t show_dock_uid(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t uid_show(struct device *dev, + struct device_attribute *attr, char *buf) { unsigned long long lbuf; struct dock_station *dock_station = dev->platform_data; @@ -542,10 +542,10 @@ static ssize_t show_dock_uid(struct device *dev, return snprintf(buf, PAGE_SIZE, "%llx\n", lbuf); } -static DEVICE_ATTR(uid, S_IRUGO, show_dock_uid, NULL); +static DEVICE_ATTR_RO(uid); -static ssize_t show_dock_type(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t type_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct dock_station *dock_station = dev->platform_data; char *type; @@ -561,7 +561,7 @@ static ssize_t show_dock_type(struct device *dev, return snprintf(buf, PAGE_SIZE, "%s\n", type); } -static DEVICE_ATTR(type, S_IRUGO, show_dock_type, NULL); +static DEVICE_ATTR_RO(type); static struct attribute *dock_attributes[] = { &dev_attr_docked.attr, diff --git a/drivers/acpi/dptf/dptf_pch_fivr.c b/drivers/acpi/dptf/dptf_pch_fivr.c index 5fca18296bf6..550b9081fcbc 100644 --- a/drivers/acpi/dptf/dptf_pch_fivr.c +++ b/drivers/acpi/dptf/dptf_pch_fivr.c @@ -9,6 +9,42 @@ #include #include +struct pch_fivr_resp { + u64 status; + u64 result; +}; + +static int pch_fivr_read(acpi_handle handle, char *method, struct pch_fivr_resp *fivr_resp) +{ + struct acpi_buffer resp = { sizeof(struct pch_fivr_resp), fivr_resp}; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer format = { sizeof("NN"), "NN" }; + union acpi_object *obj; + acpi_status status; + int ret = -EFAULT; + + status = acpi_evaluate_object(handle, method, NULL, &buffer); + if (ACPI_FAILURE(status)) + return ret; + + obj = buffer.pointer; + if (!obj || obj->type != ACPI_TYPE_PACKAGE) + goto release_buffer; + + status = acpi_extract_package(obj, &format, &resp); + if (ACPI_FAILURE(status)) + goto release_buffer; + + if (fivr_resp->status) + goto release_buffer; + + ret = 0; + +release_buffer: + kfree(buffer.pointer); + return ret; +} + /* * Presentation of attributes which are defined for INT1045 * They are: @@ -23,15 +59,14 @@ static ssize_t name##_show(struct device *dev,\ char *buf)\ {\ struct acpi_device *acpi_dev = dev_get_drvdata(dev);\ - unsigned long long val;\ - acpi_status status;\ + struct pch_fivr_resp fivr_resp;\ + int status;\ \ - status = acpi_evaluate_integer(acpi_dev->handle, #method,\ - NULL, &val);\ - if (ACPI_SUCCESS(status))\ - return sprintf(buf, "%d\n", (int)val);\ - else\ - return -EINVAL;\ + status = pch_fivr_read(acpi_dev->handle, #method, &fivr_resp);\ + if (status)\ + return status;\ +\ + return sprintf(buf, "%llu\n", fivr_resp.result);\ } #define PCH_FIVR_STORE(name, method) \ diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index e0cb1bcfffb2..be3e0921a6c0 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -183,6 +183,7 @@ static struct workqueue_struct *ec_query_wq; static int EC_FLAGS_CORRECT_ECDT; /* Needs ECDT port address correction */ static int EC_FLAGS_IGNORE_DSDT_GPE; /* Needs ECDT GPE as correction setting */ +static int EC_FLAGS_TRUST_DSDT_GPE; /* Needs DSDT GPE as correction setting */ static int EC_FLAGS_CLEAR_ON_RESUME; /* Needs acpi_ec_clear() on boot/resume */ /* -------------------------------------------------------------------------- @@ -1606,7 +1607,8 @@ static int acpi_ec_add(struct acpi_device *device) } if (boot_ec && ec->command_addr == boot_ec->command_addr && - ec->data_addr == boot_ec->data_addr) { + ec->data_addr == boot_ec->data_addr && + !EC_FLAGS_TRUST_DSDT_GPE) { /* * Trust PNP0C09 namespace location rather than * ECDT ID. But trust ECDT GPE rather than _GPE @@ -1829,6 +1831,18 @@ static int ec_correct_ecdt(const struct dmi_system_id *id) return 0; } +/* + * Some ECDTs contain wrong GPE setting, but they share the same port addresses + * with DSDT EC, don't duplicate the DSDT EC with ECDT EC in this case. + * https://bugzilla.kernel.org/show_bug.cgi?id=209989 + */ +static int ec_honor_dsdt_gpe(const struct dmi_system_id *id) +{ + pr_debug("Detected system needing DSDT GPE setting.\n"); + EC_FLAGS_TRUST_DSDT_GPE = 1; + return 0; +} + /* * Some DSDTs contain wrong GPE setting. * Asus FX502VD/VE, GL702VMK, X550VXK, X580VD @@ -1859,6 +1873,22 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "GL702VMK"),}, NULL}, { + ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BA", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X505BA"),}, NULL}, + { + ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X505BP", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X505BP"),}, NULL}, + { + ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BA", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X542BA"),}, NULL}, + { + ec_honor_ecdt_gpe, "ASUSTeK COMPUTER INC. X542BP", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "X542BP"),}, NULL}, + { ec_honor_ecdt_gpe, "ASUS X550VXK", { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "X550VXK"),}, NULL}, @@ -1867,6 +1897,11 @@ static const struct dmi_system_id ec_dmi_table[] __initconst = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "X580VD"),}, NULL}, { + /* https://bugzilla.kernel.org/show_bug.cgi?id=209989 */ + ec_honor_dsdt_gpe, "HP Pavilion Gaming Laptop 15-cx0xxx", { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Gaming Laptop 15-cx0xxx"),}, NULL}, + { ec_clear_on_resume, "Samsung hardware", { DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD.")}, NULL}, {}, diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 66c3983f0ccc..5cd0ceb50bc8 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -16,6 +16,8 @@ #include #include +#include "fan.h" + MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI Fan Driver"); MODULE_LICENSE("GPL"); @@ -24,10 +26,7 @@ static int acpi_fan_probe(struct platform_device *pdev); static int acpi_fan_remove(struct platform_device *pdev); static const struct acpi_device_id fan_device_ids[] = { - {"PNP0C0B", 0}, - {"INT3404", 0}, - {"INTC1044", 0}, - {"INTC1048", 0}, + ACPI_FAN_DEVICE_IDS, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, fan_device_ids); diff --git a/drivers/acpi/fan.h b/drivers/acpi/fan.h new file mode 100644 index 000000000000..dc9a6efa514b --- /dev/null +++ b/drivers/acpi/fan.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * ACPI fan device IDs are shared between the fan driver and the device power + * management code. + * + * Add new device IDs before the generic ACPI fan one. + */ +#define ACPI_FAN_DEVICE_IDS \ + {"INT3404", }, /* Fan */ \ + {"INTC1044", }, /* Fan for Tiger Lake generation */ \ + {"INTC1048", }, /* Fan for Alder Lake generation */ \ + {"PNP0C0B", } /* Generic ACPI fan */ diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index 4c97b0f44fce..cb18cb5c51b1 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -3031,6 +3031,9 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev; struct nd_mapping_desc *mapping; + /* range index 0 == unmapped in SPA or invalid-SPA */ + if (memdev->range_index == 0 || spa->range_index == 0) + continue; if (memdev->range_index != spa->range_index) continue; if (count >= ND_MAX_MAPPINGS) { diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 8048da85b7e0..61115ed8b93f 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -886,15 +886,16 @@ static void acpi_release_power_resource(struct device *dev) kfree(resource); } -static ssize_t acpi_power_in_use_show(struct device *dev, - struct device_attribute *attr, - char *buf) { +static ssize_t resource_in_use_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ struct acpi_power_resource *resource; resource = to_power_resource(to_acpi_device(dev)); return sprintf(buf, "%u\n", !!resource->ref_count); } -static DEVICE_ATTR(resource_in_use, 0444, acpi_power_in_use_show, NULL); +static DEVICE_ATTR_RO(resource_in_use); static void acpi_power_sysfs_remove(struct acpi_device *device) { diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index fb161a21d0ae..8377c3ed10ff 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -16,6 +16,7 @@ #include #include #include /* need_resched() */ +#include #include #include #include @@ -389,10 +390,37 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, return; } +static int acpi_cst_latency_cmp(const void *a, const void *b) +{ + const struct acpi_processor_cx *x = a, *y = b; + + if (!(x->valid && y->valid)) + return 0; + if (x->latency > y->latency) + return 1; + if (x->latency < y->latency) + return -1; + return 0; +} +static void acpi_cst_latency_swap(void *a, void *b, int n) +{ + struct acpi_processor_cx *x = a, *y = b; + u32 tmp; + + if (!(x->valid && y->valid)) + return; + tmp = x->latency; + x->latency = y->latency; + y->latency = tmp; +} + static int acpi_processor_power_verify(struct acpi_processor *pr) { unsigned int i; unsigned int working = 0; + unsigned int last_latency = 0; + unsigned int last_type = 0; + bool buggy_latency = false; pr->power.timer_broadcast_on_state = INT_MAX; @@ -416,12 +444,24 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) } if (!cx->valid) continue; + if (cx->type >= last_type && cx->latency < last_latency) + buggy_latency = true; + last_latency = cx->latency; + last_type = cx->type; lapic_timer_check_state(i, pr, cx); tsc_check_state(cx->type); working++; } + if (buggy_latency) { + pr_notice("FW issue: working around C-state latencies out of order\n"); + sort(&pr->power.states[1], max_cstate, + sizeof(struct acpi_processor_cx), + acpi_cst_latency_cmp, + acpi_cst_latency_swap); + } + lapic_timer_propagate_broadcast(pr); return (working); diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index aff13bf4d947..31c9d0c8ae11 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -1290,10 +1290,8 @@ static void acpi_sleep_hibernate_setup(void) return; acpi_get_table(ACPI_SIG_FACS, 1, (struct acpi_table_header **)&facs); - if (facs) { + if (facs) s4_hardware_signature = facs->hardware_signature; - acpi_put_table((struct acpi_table_header *)facs); - } } #else /* !CONFIG_HIBERNATION */ static inline void acpi_sleep_hibernate_setup(void) {} diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 83cd4c95faf0..33474fd96991 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -385,6 +385,30 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "BA51_MV"), }, }, + { + .callback = video_detect_force_native, + .ident = "ASUSTeK COMPUTER INC. GA401", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA401"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "ASUSTeK COMPUTER INC. GA502", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA502"), + }, + }, + { + .callback = video_detect_force_native, + .ident = "ASUSTeK COMPUTER INC. GA503", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA503"), + }, + }, /* * Desktops which falsely report a backlight and which our heuristics diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index cb69b737cb49..56b695136977 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -200,7 +200,7 @@ static void ahci_sunxi_start_engine(struct ata_port *ap) } static const struct ata_port_info ahci_sunxi_port_info = { - .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ, + .flags = AHCI_FLAG_COMMON | ATA_FLAG_NCQ | ATA_FLAG_NO_DIPM, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, .port_ops = &ahci_platform_ops, diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index ae7189d1a568..b71ea4a680b0 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -637,6 +637,20 @@ unsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc, unsigned char *buf, } EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); +static void ata_pio_xfer(struct ata_queued_cmd *qc, struct page *page, + unsigned int offset, size_t xfer_size) +{ + bool do_write = (qc->tf.flags & ATA_TFLAG_WRITE); + unsigned char *buf; + + buf = kmap_atomic(page); + qc->ap->ops->sff_data_xfer(qc, buf + offset, xfer_size, do_write); + kunmap_atomic(buf); + + if (!do_write && !PageSlab(page)) + flush_dcache_page(page); +} + /** * ata_pio_sector - Transfer a sector of data. * @qc: Command on going @@ -648,11 +662,9 @@ EXPORT_SYMBOL_GPL(ata_sff_data_xfer32); */ static void ata_pio_sector(struct ata_queued_cmd *qc) { - int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); struct ata_port *ap = qc->ap; struct page *page; unsigned int offset; - unsigned char *buf; if (!qc->cursg) { qc->curbytes = qc->nbytes; @@ -670,13 +682,20 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); - /* do the actual data transfer */ - buf = kmap_atomic(page); - ap->ops->sff_data_xfer(qc, buf + offset, qc->sect_size, do_write); - kunmap_atomic(buf); + /* + * Split the transfer when it splits a page boundary. Note that the + * split still has to be dword aligned like all ATA data transfers. + */ + WARN_ON_ONCE(offset % 4); + if (offset + qc->sect_size > PAGE_SIZE) { + unsigned int split_len = PAGE_SIZE - offset; - if (!do_write && !PageSlab(page)) - flush_dcache_page(page); + ata_pio_xfer(qc, page, offset, split_len); + ata_pio_xfer(qc, nth_page(page, 1), 0, + qc->sect_size - split_len); + } else { + ata_pio_xfer(qc, page, offset, qc->sect_size); + } qc->curbytes += qc->sect_size; qc->cursg_ofs += qc->sect_size; diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c index badab6708893..46208ececbb6 100644 --- a/drivers/ata/pata_ep93xx.c +++ b/drivers/ata/pata_ep93xx.c @@ -928,7 +928,7 @@ static int ep93xx_pata_probe(struct platform_device *pdev) /* INT[3] (IRQ_EP93XX_EXT3) line connected as pull down */ irq = platform_get_irq(pdev, 0); if (irq < 0) { - err = -ENXIO; + err = irq; goto err_rel_gpio; } diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index bd87476ab481..b5a3f710d76d 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -898,10 +898,11 @@ static int octeon_cf_probe(struct platform_device *pdev) return -EINVAL; } - irq_handler = octeon_cf_interrupt; i = platform_get_irq(dma_dev, 0); - if (i > 0) + if (i > 0) { irq = i; + irq_handler = octeon_cf_interrupt; + } } of_node_put(dma_node); } diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c index 479c4b29b856..303f8c375b3a 100644 --- a/drivers/ata/pata_rb532_cf.c +++ b/drivers/ata/pata_rb532_cf.c @@ -115,10 +115,12 @@ static int rb532_pata_driver_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq <= 0) { + if (irq < 0) { dev_err(&pdev->dev, "no IRQ resource found\n"); - return -ENOENT; + return irq; } + if (!irq) + return -EINVAL; gpiod = devm_gpiod_get(&pdev->dev, NULL, GPIOD_IN); if (IS_ERR(gpiod)) { diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 64b2ef15ec19..8440203e835e 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -469,10 +469,12 @@ static int ahci_highbank_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq <= 0) { + if (irq < 0) { dev_err(dev, "no irq\n"); - return -EINVAL; + return irq; } + if (!irq) + return -EINVAL; hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); if (!hpriv) { diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index eef637fd90b3..a59554e5b8b0 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -3279,7 +3279,7 @@ static void __exit ia_module_exit(void) { pci_unregister_driver(&ia_driver); - del_timer(&ia_timer); + del_timer_sync(&ia_timer); } module_init(ia_module_init); diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 09ad73361879..6eb4ed256a7e 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -297,7 +297,7 @@ static void __exit nicstar_cleanup(void) { XPRINTK("nicstar: nicstar_cleanup() called.\n"); - del_timer(&ns_timer); + del_timer_sync(&ns_timer); pci_unregister_driver(&nicstar_driver); @@ -525,6 +525,15 @@ static int ns_init_card(int i, struct pci_dev *pcidev) /* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */ writel(0x00000000, card->membase + VPM); + card->intcnt = 0; + if (request_irq + (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) { + pr_err("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq); + error = 9; + ns_init_card_error(card, error); + return error; + } + /* Initialize TSQ */ card->tsq.org = dma_alloc_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT, @@ -751,15 +760,6 @@ static int ns_init_card(int i, struct pci_dev *pcidev) card->efbie = 1; - card->intcnt = 0; - if (request_irq - (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) { - printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq); - error = 9; - ns_init_card_error(card, error); - return error; - } - /* Register device */ card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops, -1, NULL); @@ -837,10 +837,12 @@ static void ns_init_card_error(ns_dev *card, int error) dev_kfree_skb_any(hb); } if (error >= 12) { - kfree(card->rsq.org); + dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT, + card->rsq.org, card->rsq.dma); } if (error >= 11) { - kfree(card->tsq.org); + dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT, + card->tsq.org, card->tsq.dma); } if (error >= 10) { free_irq(card->pcidev->irq, card); diff --git a/drivers/base/core.c b/drivers/base/core.c index 6c3cf5926be3..6baad6445fa9 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "base.h" @@ -571,8 +572,10 @@ static void devlink_remove_symlinks(struct device *dev, return; } - snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); - sysfs_remove_link(&con->kobj, buf); + if (device_is_registered(con)) { + snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup)); + sysfs_remove_link(&con->kobj, buf); + } snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con)); sysfs_remove_link(&sup->kobj, buf); kfree(buf); @@ -2728,12 +2731,16 @@ void device_initialize(struct device *dev) device_pm_init(dev); set_dev_node(dev, -1); #ifdef CONFIG_GENERIC_MSI_IRQ + raw_spin_lock_init(&dev->msi_lock); INIT_LIST_HEAD(&dev->msi_list); #endif INIT_LIST_HEAD(&dev->links.consumers); INIT_LIST_HEAD(&dev->links.suppliers); INIT_LIST_HEAD(&dev->links.defer_sync); dev->links.status = DL_DEV_NO_DRIVER; +#ifdef CONFIG_SWIOTLB + dev->dma_io_tlb_mem = &io_tlb_default_mem; +#endif } EXPORT_SYMBOL_GPL(device_initialize); diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 2f9c01203fe0..8d9d0fce0e7b 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -617,8 +617,6 @@ static int really_probe(struct device *dev, struct device_driver *drv) else if (drv->remove) drv->remove(dev); probe_failed: - kfree(dev->dma_range_map); - dev->dma_range_map = NULL; if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_DRIVER_NOT_BOUND, dev); @@ -626,6 +624,8 @@ static int really_probe(struct device *dev, struct device_driver *drv) device_links_no_driver(dev); devres_release_all(dev); arch_teardown_dma_ops(dev); + kfree(dev->dma_range_map); + dev->dma_range_map = NULL; driver_sysfs_remove(dev); dev->driver = NULL; dev_set_drvdata(dev, NULL); diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c index 4dec4b79ae06..0fdd18ce2c52 100644 --- a/drivers/base/firmware_loader/fallback.c +++ b/drivers/base/firmware_loader/fallback.c @@ -89,12 +89,11 @@ static void __fw_load_abort(struct fw_priv *fw_priv) { /* * There is a small window in which user can write to 'loading' - * between loading done and disappearance of 'loading' + * between loading done/aborted and disappearance of 'loading' */ - if (fw_sysfs_done(fw_priv)) + if (fw_state_is_aborted(fw_priv) || fw_sysfs_done(fw_priv)) return; - list_del_init(&fw_priv->pending_list); fw_state_aborted(fw_priv); } @@ -280,7 +279,6 @@ static ssize_t firmware_loading_store(struct device *dev, * Same logic as fw_load_abort, only the DONE bit * is ignored and we set ABORT only on failure. */ - list_del_init(&fw_priv->pending_list); if (rc) { fw_state_aborted(fw_priv); written = rc; @@ -513,6 +511,11 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, long timeout) } mutex_lock(&fw_lock); + if (fw_state_is_aborted(fw_priv)) { + mutex_unlock(&fw_lock); + retval = -EINTR; + goto out; + } list_add(&fw_priv->pending_list, &pending_fw_head); mutex_unlock(&fw_lock); @@ -535,11 +538,10 @@ static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs, long timeout) if (fw_state_is_aborted(fw_priv)) { if (retval == -ERESTARTSYS) retval = -EINTR; - else - retval = -EAGAIN; } else if (fw_priv->is_paged_buf && !fw_priv->data) retval = -ENOMEM; +out: device_del(f_dev); err_put_dev: put_device(f_dev); diff --git a/drivers/base/firmware_loader/firmware.h b/drivers/base/firmware_loader/firmware.h index 63bd29fdcb9c..a3014e9e2c85 100644 --- a/drivers/base/firmware_loader/firmware.h +++ b/drivers/base/firmware_loader/firmware.h @@ -117,8 +117,16 @@ static inline void __fw_state_set(struct fw_priv *fw_priv, WRITE_ONCE(fw_st->status, status); - if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) + if (status == FW_STATUS_DONE || status == FW_STATUS_ABORTED) { +#ifdef CONFIG_FW_LOADER_USER_HELPER + /* + * Doing this here ensures that the fw_priv is deleted from + * the pending list in all abort/done paths. + */ + list_del_init(&fw_priv->pending_list); +#endif complete_all(&fw_st->completion); + } } static inline void fw_state_aborted(struct fw_priv *fw_priv) diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 78355095e00d..a529235e6bfe 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -781,8 +781,10 @@ static void fw_abort_batch_reqs(struct firmware *fw) return; fw_priv = fw->priv; + mutex_lock(&fw_lock); if (!fw_state_is_aborted(fw_priv)) fw_state_aborted(fw_priv); + mutex_unlock(&fw_lock); } /* called from request_firmware() and request_firmware_work_func() */ diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index f40ebe9f5047..f2548049aa0e 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -230,7 +230,7 @@ config BLK_DEV_LOOP_MIN_COUNT dynamically allocated with the /dev/loop-control interface. config BLK_DEV_CRYPTOLOOP - tristate "Cryptoloop Support" + tristate "Cryptoloop Support (DEPRECATED)" select CRYPTO select CRYPTO_CBC depends on BLK_DEV_LOOP @@ -242,7 +242,7 @@ config BLK_DEV_CRYPTOLOOP WARNING: This device is not safe for journaled file systems like ext3 or Reiserfs. Please use the Device Mapper crypto module instead, which can be configured to be on-disk compatible with the - cryptoloop device. + cryptoloop device. cryptoloop support will be removed in Linux 5.16. source "drivers/block/drbd/Kconfig" diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c index 3cabc335ae74..f0a91faa43a8 100644 --- a/drivers/block/cryptoloop.c +++ b/drivers/block/cryptoloop.c @@ -189,6 +189,8 @@ init_cryptoloop(void) if (rc) printk(KERN_ERR "cryptoloop: loop_register_transfer failed\n"); + else + pr_warn("the cryptoloop driver has been deprecated and will be removed in in Linux 5.16\n"); return rc; } diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 295da442329f..7df79ae6b0a1 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4120,23 +4120,23 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) if (fdc_state[FDC(drive)].rawcmd == 1) fdc_state[FDC(drive)].rawcmd = 2; - if (mode & (FMODE_READ|FMODE_WRITE)) { - drive_state[drive].last_checked = 0; - clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &drive_state[drive].flags); - if (bdev_check_media_change(bdev)) - floppy_revalidate(bdev->bd_disk); - if (test_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags)) - goto out; - if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &drive_state[drive].flags)) + if (!(mode & FMODE_NDELAY)) { + if (mode & (FMODE_READ|FMODE_WRITE)) { + drive_state[drive].last_checked = 0; + clear_bit(FD_OPEN_SHOULD_FAIL_BIT, + &drive_state[drive].flags); + if (bdev_check_media_change(bdev)) + floppy_revalidate(bdev->bd_disk); + if (test_bit(FD_DISK_CHANGED_BIT, &drive_state[drive].flags)) + goto out; + if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &drive_state[drive].flags)) + goto out; + } + res = -EROFS; + if ((mode & FMODE_WRITE) && + !test_bit(FD_DISK_WRITABLE_BIT, &drive_state[drive].flags)) goto out; } - - res = -EROFS; - - if ((mode & FMODE_WRITE) && - !test_bit(FD_DISK_WRITABLE_BIT, &drive_state[drive].flags)) - goto out; - mutex_unlock(&open_lock); mutex_unlock(&floppy_mutex); return 0; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index a34fc3f42e3b..32f0ec984fff 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1161,6 +1161,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode, blk_queue_physical_block_size(lo->lo_queue, bsize); blk_queue_io_min(lo->lo_queue, bsize); + loop_config_discard(lo); loop_update_rotational(lo); loop_update_dio(lo); loop_sysfs_init(lo); @@ -1223,6 +1224,9 @@ static int __loop_clr_fd(struct loop_device *lo, bool release) goto out_unlock; } + if (test_bit(QUEUE_FLAG_WC, &lo->lo_queue->queue_flags)) + blk_queue_write_cache(lo->lo_queue, false, false); + /* freeze request queue during the transition */ blk_mq_freeze_queue(lo->lo_queue); diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 9a70eab7edbf..59c452fff835 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -812,6 +812,10 @@ static bool nbd_clear_req(struct request *req, void *data, bool reserved) { struct nbd_cmd *cmd = blk_mq_rq_to_pdu(req); + /* don't abort one completed request */ + if (blk_mq_request_completed(req)) + return true; + mutex_lock(&cmd->lock); cmd->status = BLK_STS_IOERR; mutex_unlock(&cmd->lock); @@ -2024,15 +2028,19 @@ static void nbd_disconnect_and_put(struct nbd_device *nbd) { mutex_lock(&nbd->config_lock); nbd_disconnect(nbd); - nbd_clear_sock(nbd); - mutex_unlock(&nbd->config_lock); + sock_shutdown(nbd); /* * Make sure recv thread has finished, so it does not drop the last * config ref and try to destroy the workqueue from inside the work - * queue. + * queue. And this also ensure that we can safely call nbd_clear_que() + * to cancel the inflight I/Os. */ if (nbd->recv_workq) flush_workqueue(nbd->recv_workq); + nbd_clear_que(nbd); + nbd->task_setup = NULL; + mutex_unlock(&nbd->config_lock); + if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF, &nbd->config->runtime_flags)) nbd_config_put(nbd); diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index f84128abade3..340b1df365f7 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -4147,8 +4147,6 @@ static void rbd_acquire_lock(struct work_struct *work) static bool rbd_quiesce_lock(struct rbd_device *rbd_dev) { - bool need_wait; - dout("%s rbd_dev %p\n", __func__, rbd_dev); lockdep_assert_held_write(&rbd_dev->lock_rwsem); @@ -4160,11 +4158,11 @@ static bool rbd_quiesce_lock(struct rbd_device *rbd_dev) */ rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING; rbd_assert(!completion_done(&rbd_dev->releasing_wait)); - need_wait = !list_empty(&rbd_dev->running_list); - downgrade_write(&rbd_dev->lock_rwsem); - if (need_wait) - wait_for_completion(&rbd_dev->releasing_wait); - up_read(&rbd_dev->lock_rwsem); + if (list_empty(&rbd_dev->running_list)) + return true; + + up_write(&rbd_dev->lock_rwsem); + wait_for_completion(&rbd_dev->releasing_wait); down_write(&rbd_dev->lock_rwsem); if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING) @@ -4250,15 +4248,11 @@ static void rbd_handle_acquired_lock(struct rbd_device *rbd_dev, u8 struct_v, if (!rbd_cid_equal(&cid, &rbd_empty_cid)) { down_write(&rbd_dev->lock_rwsem); if (rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { - /* - * we already know that the remote client is - * the owner - */ - up_write(&rbd_dev->lock_rwsem); - return; + dout("%s rbd_dev %p cid %llu-%llu == owner_cid\n", + __func__, rbd_dev, cid.gid, cid.handle); + } else { + rbd_set_owner_cid(rbd_dev, &cid); } - - rbd_set_owner_cid(rbd_dev, &cid); downgrade_write(&rbd_dev->lock_rwsem); } else { down_read(&rbd_dev->lock_rwsem); @@ -4283,14 +4277,12 @@ static void rbd_handle_released_lock(struct rbd_device *rbd_dev, u8 struct_v, if (!rbd_cid_equal(&cid, &rbd_empty_cid)) { down_write(&rbd_dev->lock_rwsem); if (!rbd_cid_equal(&cid, &rbd_dev->owner_cid)) { - dout("%s rbd_dev %p unexpected owner, cid %llu-%llu != owner_cid %llu-%llu\n", + dout("%s rbd_dev %p cid %llu-%llu != owner_cid %llu-%llu\n", __func__, rbd_dev, cid.gid, cid.handle, rbd_dev->owner_cid.gid, rbd_dev->owner_cid.handle); - up_write(&rbd_dev->lock_rwsem); - return; + } else { + rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); } - - rbd_set_owner_cid(rbd_dev, &rbd_empty_cid); downgrade_write(&rbd_dev->lock_rwsem); } else { down_read(&rbd_dev->lock_rwsem); diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 616ced8a8677..018fb172a098 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -948,6 +948,8 @@ static int virtblk_freeze(struct virtio_device *vdev) blk_mq_quiesce_queue(vblk->disk->queue); vdev->config->del_vqs(vdev); + kfree(vblk->vqs); + return 0; } diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c index ce9dcffdc5bf..7551cac3fd7a 100644 --- a/drivers/bluetooth/btqca.c +++ b/drivers/bluetooth/btqca.c @@ -143,7 +143,7 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev) EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd); static void qca_tlv_check_data(struct qca_fw_config *config, - const struct firmware *fw, enum qca_btsoc_type soc_type) + u8 *fw_data, enum qca_btsoc_type soc_type) { const u8 *data; u32 type_len; @@ -154,7 +154,7 @@ static void qca_tlv_check_data(struct qca_fw_config *config, struct tlv_type_nvm *tlv_nvm; uint8_t nvm_baud_rate = config->user_baud_rate; - tlv = (struct tlv_type_hdr *)fw->data; + tlv = (struct tlv_type_hdr *)fw_data; type_len = le32_to_cpu(tlv->type_len); length = (type_len >> 8) & 0x00ffffff; @@ -350,8 +350,9 @@ static int qca_download_firmware(struct hci_dev *hdev, enum qca_btsoc_type soc_type) { const struct firmware *fw; + u8 *data; const u8 *segment; - int ret, remain, i = 0; + int ret, size, remain, i = 0; bt_dev_info(hdev, "QCA Downloading %s", config->fwname); @@ -362,10 +363,22 @@ static int qca_download_firmware(struct hci_dev *hdev, return ret; } - qca_tlv_check_data(config, fw, soc_type); + size = fw->size; + data = vmalloc(fw->size); + if (!data) { + bt_dev_err(hdev, "QCA Failed to allocate memory for file: %s", + config->fwname); + release_firmware(fw); + return -ENOMEM; + } + + memcpy(data, fw->data, size); + release_firmware(fw); + + qca_tlv_check_data(config, data, soc_type); - segment = fw->data; - remain = fw->size; + segment = data; + remain = size; while (remain > 0) { int segsize = min(MAX_SIZE_PER_TLV_SEGMENT, remain); @@ -395,7 +408,7 @@ static int qca_download_firmware(struct hci_dev *hdev, ret = qca_inject_cmd_complete_event(hdev); out: - release_firmware(fw); + vfree(data); return ret; } diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 175cb1c0d569..e0859f4e2807 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -269,6 +269,8 @@ static const struct usb_device_id blacklist_table[] = { BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0cf3, 0xe500), .driver_info = BTUSB_QCA_ROME | + BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0489, 0xe092), .driver_info = BTUSB_QCA_ROME | BTUSB_WIDEBAND_SPEECH }, { USB_DEVICE(0x0489, 0xe09f), .driver_info = BTUSB_QCA_ROME | @@ -385,6 +387,8 @@ static const struct usb_device_id blacklist_table[] = { /* Realtek 8822CE Bluetooth devices */ { USB_DEVICE(0x0bda, 0xb00c), .driver_info = BTUSB_REALTEK | BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0bda, 0xc822), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, /* Realtek Bluetooth devices */ { USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01), @@ -482,6 +486,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = { #define BTUSB_HW_RESET_ACTIVE 12 #define BTUSB_TX_WAIT_VND_EVT 13 #define BTUSB_WAKEUP_DISABLE 14 +#define BTUSB_USE_ALT3_FOR_WBS 15 struct btusb_data { struct hci_dev *hdev; @@ -1714,9 +1719,20 @@ static void btusb_work(struct work_struct *work) /* Bluetooth USB spec recommends alt 6 (63 bytes), but * many adapters do not support it. Alt 1 appears to * work for all adapters that do not have alt 6, and - * which work with WBS at all. + * which work with WBS at all. Some devices prefer + * alt 3 (HCI payload >= 60 Bytes let air packet + * data satisfy 60 bytes), requiring + * MTU >= 3 (packets) * 25 (size) - 3 (headers) = 72 + * see also Core spec 5, vol 4, B 2.1.1 & Table 2.1. */ - new_alts = btusb_find_altsetting(data, 6) ? 6 : 1; + if (btusb_find_altsetting(data, 6)) + new_alts = 6; + else if (btusb_find_altsetting(data, 3) && + hdev->sco_mtu >= 72 && + test_bit(BTUSB_USE_ALT3_FOR_WBS, &data->flags)) + new_alts = 3; + else + new_alts = 1; } if (btusb_switch_alt_setting(hdev, new_alts) < 0) @@ -2961,11 +2977,6 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev, struct btmtk_wmt_hdr *hdr; int err; - /* Submit control IN URB on demand to process the WMT event */ - err = btusb_mtk_submit_wmt_recv_urb(hdev); - if (err < 0) - return err; - /* Send the WMT command and wait until the WMT event returns */ hlen = sizeof(*hdr) + wmt_params->dlen; if (hlen > 255) @@ -2987,6 +2998,11 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev, return err; } + /* Submit control IN URB on demand to process the WMT event */ + err = btusb_mtk_submit_wmt_recv_urb(hdev); + if (err < 0) + return err; + /* The vendor specific WMT commands are all answered by a vendor * specific event and will have the Command Status or Command * Complete as with usual HCI command flow control. @@ -3547,6 +3563,11 @@ static int btusb_setup_qca_download_fw(struct hci_dev *hdev, sent += size; count -= size; + /* ep2 need time to switch from function acl to function dfu, + * so we add 20ms delay here. + */ + msleep(20); + while (count) { size = min_t(size_t, count, QCA_DFU_PACKET_LEN); @@ -4154,6 +4175,7 @@ static int btusb_probe(struct usb_interface *intf, * (DEVICE_REMOTE_WAKEUP) */ set_bit(BTUSB_WAKEUP_DISABLE, &data->flags); + set_bit(BTUSB_USE_ALT3_FOR_WBS, &data->flags); } if (!reset) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index ad47ff0d55c2..4184faef9f16 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -1809,8 +1809,6 @@ static void qca_power_shutdown(struct hci_uart *hu) unsigned long flags; enum qca_btsoc_type soc_type = qca_soc_type(hu); - qcadev = serdev_device_get_drvdata(hu->serdev); - /* From this point we go into power off state. But serial port is * still open, stop queueing the IBS data and flush all the buffered * data in skb's. @@ -1826,6 +1824,8 @@ static void qca_power_shutdown(struct hci_uart *hu) if (!hu->serdev) return; + qcadev = serdev_device_get_drvdata(hu->serdev); + if (qca_is_wcn399x(soc_type)) { host_set_baudrate(hu, 2400); qca_send_power_pulse(hu, false); diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c index d86ce1a06b75..614dd287cb4f 100644 --- a/drivers/bus/mhi/core/main.c +++ b/drivers/bus/mhi/core/main.c @@ -706,11 +706,18 @@ static void mhi_process_cmd_completion(struct mhi_controller *mhi_cntrl, cmd_pkt = mhi_to_virtual(mhi_ring, ptr); chan = MHI_TRE_GET_CMD_CHID(cmd_pkt); - mhi_chan = &mhi_cntrl->mhi_chan[chan]; - write_lock_bh(&mhi_chan->lock); - mhi_chan->ccs = MHI_TRE_GET_EV_CODE(tre); - complete(&mhi_chan->completion); - write_unlock_bh(&mhi_chan->lock); + + if (chan < mhi_cntrl->max_chan && + mhi_cntrl->mhi_chan[chan].configured) { + mhi_chan = &mhi_cntrl->mhi_chan[chan]; + write_lock_bh(&mhi_chan->lock); + mhi_chan->ccs = MHI_TRE_GET_EV_CODE(tre); + complete(&mhi_chan->completion); + write_unlock_bh(&mhi_chan->lock); + } else { + dev_err(&mhi_cntrl->mhi_dev->dev, + "Completion packet for invalid channel ID: %d\n", chan); + } mhi_del_ring_element(mhi_cntrl, mhi_ring); } diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c index aeb895c08460..044dcdd723a7 100644 --- a/drivers/bus/mhi/core/pm.c +++ b/drivers/bus/mhi/core/pm.c @@ -809,6 +809,7 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl) ret = wait_event_timeout(mhi_cntrl->state_event, mhi_cntrl->dev_state == MHI_STATE_M0 || + mhi_cntrl->dev_state == MHI_STATE_M2 || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state), msecs_to_jiffies(mhi_cntrl->timeout_ms)); diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 818dc7f54f03..159b57c6dc4d 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -100,6 +100,7 @@ static const char * const clock_names[SYSC_MAX_CLOCKS] = { * @cookie: data used by legacy platform callbacks * @name: name if available * @revision: interconnect target module revision + * @reserved: target module is reserved and already in use * @enabled: sysc runtime enabled status * @needs_resume: runtime resume needed on resume from suspend * @child_needs_resume: runtime resume needed for child on resume from suspend @@ -130,6 +131,7 @@ struct sysc { struct ti_sysc_cookie cookie; const char *name; u32 revision; + unsigned int reserved:1; unsigned int enabled:1; unsigned int needs_resume:1; unsigned int child_needs_resume:1; @@ -2918,6 +2920,8 @@ static int sysc_init_soc(struct sysc *ddata) case SOC_3430 ... SOC_3630: sysc_add_disabled(0x48304000); /* timer12 */ break; + case SOC_AM3: + sysc_add_disabled(0x48310000); /* rng */ default: break; }; @@ -3057,7 +3061,9 @@ static int sysc_probe(struct platform_device *pdev) return error; error = sysc_check_active_timer(ddata); - if (error) + if (error == -ENXIO) + ddata->reserved = true; + else if (error) return error; error = sysc_get_clocks(ddata); @@ -3094,11 +3100,15 @@ static int sysc_probe(struct platform_device *pdev) sysc_show_registers(ddata); ddata->dev->type = &sysc_device_type; - error = of_platform_populate(ddata->dev->of_node, sysc_match_table, - pdata ? pdata->auxdata : NULL, - ddata->dev); - if (error) - goto err; + + if (!ddata->reserved) { + error = of_platform_populate(ddata->dev->of_node, + sysc_match_table, + pdata ? pdata->auxdata : NULL, + ddata->dev); + if (error) + goto err; + } INIT_DELAYED_WORK(&ddata->idle_work, ti_sysc_idle); diff --git a/drivers/char/hw_random/exynos-trng.c b/drivers/char/hw_random/exynos-trng.c index 8e1fe3f8dd2d..c8db62bc5ff7 100644 --- a/drivers/char/hw_random/exynos-trng.c +++ b/drivers/char/hw_random/exynos-trng.c @@ -132,7 +132,7 @@ static int exynos_trng_probe(struct platform_device *pdev) return PTR_ERR(trng->mem); pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "Could not get runtime PM.\n"); goto err_pm_get; @@ -165,7 +165,7 @@ static int exynos_trng_probe(struct platform_device *pdev) clk_disable_unprepare(trng->clk); err_clock: - pm_runtime_put_sync(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); err_pm_get: pm_runtime_disable(&pdev->dev); diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index f78156d93c3f..6384510c48d6 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -371,16 +371,18 @@ static int __ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, data[0] = 0; WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); - if ((ipmi_version_major > 1) - || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) { - /* This is an IPMI 1.5-only feature. */ - data[0] |= WDOG_DONT_STOP_ON_SET; - } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { - /* - * In ipmi 1.0, setting the timer stops the watchdog, we - * need to start it back up again. - */ - hbnow = 1; + if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { + if ((ipmi_version_major > 1) || + ((ipmi_version_major == 1) && (ipmi_version_minor >= 5))) { + /* This is an IPMI 1.5-only feature. */ + data[0] |= WDOG_DONT_STOP_ON_SET; + } else { + /* + * In ipmi 1.0, setting the timer stops the watchdog, we + * need to start it back up again. + */ + hbnow = 1; + } } data[1] = 0; diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 89681f07bc78..9468e9520cee 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -544,6 +544,10 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq) io_read_num_rec_bytes(iobase, &num_bytes_read); if (num_bytes_read >= 4) { DEBUGP(2, dev, "NumRecBytes = %i\n", num_bytes_read); + if (num_bytes_read > 4) { + rc = -EIO; + goto exit_setprotocol; + } break; } usleep_range(10000, 11000); diff --git a/drivers/char/random.c b/drivers/char/random.c index 340ad21491e2..79164fce1bf9 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1261,8 +1261,6 @@ void add_interrupt_randomness(int irq, int irq_flags) cycles_t cycles = random_get_entropy(); __u32 c_high, j_high; __u64 ip; - unsigned long seed; - int credit = 0; if (cycles == 0) cycles = get_reg(fast_pool, regs); @@ -1298,23 +1296,12 @@ void add_interrupt_randomness(int irq, int irq_flags) fast_pool->last = now; __mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool)); - - /* - * If we have architectural seed generator, produce a seed and - * add it to the pool. For the sake of paranoia don't let the - * architectural seed generator dominate the input from the - * interrupt noise. - */ - if (arch_get_random_seed_long(&seed)) { - __mix_pool_bytes(r, &seed, sizeof(seed)); - credit = 1; - } spin_unlock(&r->lock); fast_pool->count = 0; /* award one bit for the contents of the fast pool */ - credit_entropy_bits(r, credit + 1); + credit_entropy_bits(r, 1); } EXPORT_SYMBOL_GPL(add_interrupt_randomness); diff --git a/drivers/char/tpm/tpm_ftpm_tee.c b/drivers/char/tpm/tpm_ftpm_tee.c index 2ccdf8ac6994..6e3235565a4d 100644 --- a/drivers/char/tpm/tpm_ftpm_tee.c +++ b/drivers/char/tpm/tpm_ftpm_tee.c @@ -254,11 +254,11 @@ static int ftpm_tee_probe(struct device *dev) pvt_data->session = sess_arg.session; /* Allocate dynamic shared memory with fTPM TA */ - pvt_data->shm = tee_shm_alloc(pvt_data->ctx, - MAX_COMMAND_SIZE + MAX_RESPONSE_SIZE, - TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); + pvt_data->shm = tee_shm_alloc_kernel_buf(pvt_data->ctx, + MAX_COMMAND_SIZE + + MAX_RESPONSE_SIZE); if (IS_ERR(pvt_data->shm)) { - dev_err(dev, "%s: tee_shm_alloc failed\n", __func__); + dev_err(dev, "%s: tee_shm_alloc_kernel_buf failed\n", __func__); rc = -ENOMEM; goto out_shm_alloc; } diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 55b9d3965ae1..69579efb247b 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -196,13 +196,24 @@ static u8 tpm_tis_status(struct tpm_chip *chip) return 0; if (unlikely((status & TPM_STS_READ_ZERO) != 0)) { - /* - * If this trips, the chances are the read is - * returning 0xff because the locality hasn't been - * acquired. Usually because tpm_try_get_ops() hasn't - * been called before doing a TPM operation. - */ - WARN_ONCE(1, "TPM returned invalid status\n"); + if (!test_and_set_bit(TPM_TIS_INVALID_STATUS, &priv->flags)) { + /* + * If this trips, the chances are the read is + * returning 0xff because the locality hasn't been + * acquired. Usually because tpm_try_get_ops() hasn't + * been called before doing a TPM operation. + */ + dev_err(&chip->dev, "invalid TPM_STS.x 0x%02x, dumping stack for forensics\n", + status); + + /* + * Dump stack for forensics, as invalid TPM_STS.x could be + * potentially triggered by impaired tpm_try_get_ops() or + * tpm_find_get_ops(). + */ + dump_stack(); + } + return 0; } diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index 9b2d32a59f67..b2a3c6c72882 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h @@ -83,6 +83,7 @@ enum tis_defaults { enum tpm_tis_flags { TPM_TIS_ITPM_WORKAROUND = BIT(0), + TPM_TIS_INVALID_STATUS = BIT(1), }; struct tpm_tis_data { @@ -90,7 +91,7 @@ struct tpm_tis_data { int locality; int irq; bool irq_tested; - unsigned int flags; + unsigned long flags; void __iomem *ilb_base_addr; u16 clkrun_enabled; wait_queue_head_t int_queue; diff --git a/drivers/char/tpm/tpm_tis_spi_main.c b/drivers/char/tpm/tpm_tis_spi_main.c index 3856f6ebcb34..de4209003a44 100644 --- a/drivers/char/tpm/tpm_tis_spi_main.c +++ b/drivers/char/tpm/tpm_tis_spi_main.c @@ -260,6 +260,8 @@ static int tpm_tis_spi_remove(struct spi_device *dev) } static const struct spi_device_id tpm_tis_spi_id[] = { + { "st33htpm-spi", (unsigned long)tpm_tis_spi_probe }, + { "slb9670", (unsigned long)tpm_tis_spi_probe }, { "tpm_tis_spi", (unsigned long)tpm_tis_spi_probe }, { "cr50", (unsigned long)cr50_spi_probe }, {} diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 1836cc56e357..673522874cec 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -475,7 +475,7 @@ static struct port_buffer *get_inbuf(struct port *port) buf = virtqueue_get_buf(port->in_vq, &len); if (buf) { - buf->len = len; + buf->len = min_t(size_t, len, buf->size); buf->offset = 0; port->stats.bytes_received += len; } @@ -1712,7 +1712,7 @@ static void control_work_handler(struct work_struct *work) while ((buf = virtqueue_get_buf(vq, &len))) { spin_unlock(&portdev->c_ivq_lock); - buf->len = len; + buf->len = min_t(size_t, len, buf->size); buf->offset = 0; handle_control_message(vq->vdev, portdev, buf); diff --git a/drivers/clk/actions/owl-s500.c b/drivers/clk/actions/owl-s500.c index 61bb224f6330..cbeb51c804eb 100644 --- a/drivers/clk/actions/owl-s500.c +++ b/drivers/clk/actions/owl-s500.c @@ -127,8 +127,7 @@ static struct clk_factor_table sd_factor_table[] = { { 12, 1, 13 }, { 13, 1, 14 }, { 14, 1, 15 }, { 15, 1, 16 }, { 16, 1, 17 }, { 17, 1, 18 }, { 18, 1, 19 }, { 19, 1, 20 }, { 20, 1, 21 }, { 21, 1, 22 }, { 22, 1, 23 }, { 23, 1, 24 }, - { 24, 1, 25 }, { 25, 1, 26 }, { 26, 1, 27 }, { 27, 1, 28 }, - { 28, 1, 29 }, { 29, 1, 30 }, { 30, 1, 31 }, { 31, 1, 32 }, + { 24, 1, 25 }, /* bit8: /128 */ { 256, 1, 1 * 128 }, { 257, 1, 2 * 128 }, { 258, 1, 3 * 128 }, { 259, 1, 4 * 128 }, @@ -137,19 +136,20 @@ static struct clk_factor_table sd_factor_table[] = { { 268, 1, 13 * 128 }, { 269, 1, 14 * 128 }, { 270, 1, 15 * 128 }, { 271, 1, 16 * 128 }, { 272, 1, 17 * 128 }, { 273, 1, 18 * 128 }, { 274, 1, 19 * 128 }, { 275, 1, 20 * 128 }, { 276, 1, 21 * 128 }, { 277, 1, 22 * 128 }, { 278, 1, 23 * 128 }, { 279, 1, 24 * 128 }, - { 280, 1, 25 * 128 }, { 281, 1, 26 * 128 }, { 282, 1, 27 * 128 }, { 283, 1, 28 * 128 }, - { 284, 1, 29 * 128 }, { 285, 1, 30 * 128 }, { 286, 1, 31 * 128 }, { 287, 1, 32 * 128 }, + { 280, 1, 25 * 128 }, { 0, 0, 0 }, }; -static struct clk_factor_table bisp_factor_table[] = { - { 0, 1, 1 }, { 1, 1, 2 }, { 2, 1, 3 }, { 3, 1, 4 }, - { 4, 1, 5 }, { 5, 1, 6 }, { 6, 1, 7 }, { 7, 1, 8 }, +static struct clk_factor_table de_factor_table[] = { + { 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 }, + { 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 }, + { 8, 1, 12 }, { 0, 0, 0 }, }; -static struct clk_factor_table ahb_factor_table[] = { - { 1, 1, 2 }, { 2, 1, 3 }, +static struct clk_factor_table hde_factor_table[] = { + { 0, 1, 1 }, { 1, 2, 3 }, { 2, 1, 2 }, { 3, 2, 5 }, + { 4, 1, 3 }, { 5, 1, 4 }, { 6, 1, 6 }, { 7, 1, 8 }, { 0, 0, 0 }, }; @@ -158,6 +158,13 @@ static struct clk_div_table rmii_ref_div_table[] = { { 0, 0 }, }; +static struct clk_div_table std12rate_div_table[] = { + { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, + { 4, 5 }, { 5, 6 }, { 6, 7 }, { 7, 8 }, + { 8, 9 }, { 9, 10 }, { 10, 11 }, { 11, 12 }, + { 0, 0 }, +}; + static struct clk_div_table i2s_div_table[] = { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 6 }, { 5, 8 }, { 6, 12 }, { 7, 16 }, @@ -174,7 +181,6 @@ static struct clk_div_table nand_div_table[] = { /* mux clock */ static OWL_MUX(dev_clk, "dev_clk", dev_clk_mux_p, CMU_DEVPLL, 12, 1, CLK_SET_RATE_PARENT); -static OWL_MUX(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, CMU_BUSCLK1, 8, 3, CLK_SET_RATE_PARENT); /* gate clocks */ static OWL_GATE(gpio_clk, "gpio_clk", "apb_clk", CMU_DEVCLKEN0, 18, 0, 0); @@ -187,45 +193,54 @@ static OWL_GATE(timer_clk, "timer_clk", "hosc", CMU_DEVCLKEN1, 27, 0, 0); static OWL_GATE(hdmi_clk, "hdmi_clk", "hosc", CMU_DEVCLKEN1, 3, 0, 0); /* divider clocks */ -static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 12, 2, NULL, 0, 0); +static OWL_DIVIDER(h_clk, "h_clk", "ahbprediv_clk", CMU_BUSCLK1, 2, 2, NULL, 0, 0); static OWL_DIVIDER(apb_clk, "apb_clk", "ahb_clk", CMU_BUSCLK1, 14, 2, NULL, 0, 0); static OWL_DIVIDER(rmii_ref_clk, "rmii_ref_clk", "ethernet_pll_clk", CMU_ETHERNETPLL, 1, 1, rmii_ref_div_table, 0, 0); /* factor clocks */ -static OWL_FACTOR(ahb_clk, "ahb_clk", "h_clk", CMU_BUSCLK1, 2, 2, ahb_factor_table, 0, 0); -static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 3, bisp_factor_table, 0, 0); -static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 3, bisp_factor_table, 0, 0); +static OWL_FACTOR(de1_clk, "de_clk1", "de_clk", CMU_DECLK, 0, 4, de_factor_table, 0, 0); +static OWL_FACTOR(de2_clk, "de_clk2", "de_clk", CMU_DECLK, 4, 4, de_factor_table, 0, 0); /* composite clocks */ +static OWL_COMP_DIV(ahbprediv_clk, "ahbprediv_clk", ahbprediv_clk_mux_p, + OWL_MUX_HW(CMU_BUSCLK1, 8, 3), + { 0 }, + OWL_DIVIDER_HW(CMU_BUSCLK1, 12, 2, 0, NULL), + CLK_SET_RATE_PARENT); + +static OWL_COMP_FIXED_FACTOR(ahb_clk, "ahb_clk", "h_clk", + { 0 }, + 1, 1, 0); + static OWL_COMP_FACTOR(vce_clk, "vce_clk", hde_clk_mux_p, OWL_MUX_HW(CMU_VCECLK, 4, 2), OWL_GATE_HW(CMU_DEVCLKEN0, 26, 0), - OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, bisp_factor_table), + OWL_FACTOR_HW(CMU_VCECLK, 0, 3, 0, hde_factor_table), 0); static OWL_COMP_FACTOR(vde_clk, "vde_clk", hde_clk_mux_p, OWL_MUX_HW(CMU_VDECLK, 4, 2), OWL_GATE_HW(CMU_DEVCLKEN0, 25, 0), - OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, bisp_factor_table), + OWL_FACTOR_HW(CMU_VDECLK, 0, 3, 0, hde_factor_table), 0); -static OWL_COMP_FACTOR(bisp_clk, "bisp_clk", bisp_clk_mux_p, +static OWL_COMP_DIV(bisp_clk, "bisp_clk", bisp_clk_mux_p, OWL_MUX_HW(CMU_BISPCLK, 4, 1), OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), - OWL_FACTOR_HW(CMU_BISPCLK, 0, 3, 0, bisp_factor_table), + OWL_DIVIDER_HW(CMU_BISPCLK, 0, 4, 0, std12rate_div_table), 0); -static OWL_COMP_FACTOR(sensor0_clk, "sensor0_clk", sensor_clk_mux_p, +static OWL_COMP_DIV(sensor0_clk, "sensor0_clk", sensor_clk_mux_p, OWL_MUX_HW(CMU_SENSORCLK, 4, 1), OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), - OWL_FACTOR_HW(CMU_SENSORCLK, 0, 3, 0, bisp_factor_table), - CLK_IGNORE_UNUSED); + OWL_DIVIDER_HW(CMU_SENSORCLK, 0, 4, 0, std12rate_div_table), + 0); -static OWL_COMP_FACTOR(sensor1_clk, "sensor1_clk", sensor_clk_mux_p, +static OWL_COMP_DIV(sensor1_clk, "sensor1_clk", sensor_clk_mux_p, OWL_MUX_HW(CMU_SENSORCLK, 4, 1), OWL_GATE_HW(CMU_DEVCLKEN0, 14, 0), - OWL_FACTOR_HW(CMU_SENSORCLK, 8, 3, 0, bisp_factor_table), - CLK_IGNORE_UNUSED); + OWL_DIVIDER_HW(CMU_SENSORCLK, 8, 4, 0, std12rate_div_table), + 0); static OWL_COMP_FACTOR(sd0_clk, "sd0_clk", sd_clk_mux_p, OWL_MUX_HW(CMU_SD0CLK, 9, 1), @@ -305,7 +320,7 @@ static OWL_COMP_FIXED_FACTOR(i2c3_clk, "i2c3_clk", "ethernet_pll_clk", static OWL_COMP_DIV(uart0_clk, "uart0_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART0CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 6, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART0CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p, @@ -317,31 +332,31 @@ static OWL_COMP_DIV(uart1_clk, "uart1_clk", uart_clk_mux_p, static OWL_COMP_DIV(uart2_clk, "uart2_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART2CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 8, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART2CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart3_clk, "uart3_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART3CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 19, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART3CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart4_clk, "uart4_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART4CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 20, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART4CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart5_clk, "uart5_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART5CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 21, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART5CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(uart6_clk, "uart6_clk", uart_clk_mux_p, OWL_MUX_HW(CMU_UART6CLK, 16, 1), OWL_GATE_HW(CMU_DEVCLKEN1, 18, 0), - OWL_DIVIDER_HW(CMU_UART1CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), + OWL_DIVIDER_HW(CMU_UART6CLK, 0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL), CLK_IGNORE_UNUSED); static OWL_COMP_DIV(i2srx_clk, "i2srx_clk", i2s_clk_mux_p, diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c index be160764911b..f9d5b7334341 100644 --- a/drivers/clk/clk-devres.c +++ b/drivers/clk/clk-devres.c @@ -92,13 +92,20 @@ int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks, } EXPORT_SYMBOL_GPL(devm_clk_bulk_get_optional); +static void devm_clk_bulk_release_all(struct device *dev, void *res) +{ + struct clk_bulk_devres *devres = res; + + clk_bulk_put_all(devres->num_clks, devres->clks); +} + int __must_check devm_clk_bulk_get_all(struct device *dev, struct clk_bulk_data **clks) { struct clk_bulk_devres *devres; int ret; - devres = devres_alloc(devm_clk_bulk_release, + devres = devres_alloc(devm_clk_bulk_release_all, sizeof(*devres), GFP_KERNEL); if (!devres) return -ENOMEM; diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index e0446e66fa64..eb22f4fdbc6b 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -92,12 +92,22 @@ struct clk_si5341_output_config { #define SI5341_PN_BASE 0x0002 #define SI5341_DEVICE_REV 0x0005 #define SI5341_STATUS 0x000C +#define SI5341_LOS 0x000D +#define SI5341_STATUS_STICKY 0x0011 +#define SI5341_LOS_STICKY 0x0012 #define SI5341_SOFT_RST 0x001C #define SI5341_IN_SEL 0x0021 +#define SI5341_DEVICE_READY 0x00FE #define SI5341_XAXB_CFG 0x090E #define SI5341_IN_EN 0x0949 #define SI5341_INX_TO_PFD_EN 0x094A +/* Status bits */ +#define SI5341_STATUS_SYSINCAL BIT(0) +#define SI5341_STATUS_LOSXAXB BIT(1) +#define SI5341_STATUS_LOSREF BIT(2) +#define SI5341_STATUS_LOL BIT(3) + /* Input selection */ #define SI5341_IN_SEL_MASK 0x06 #define SI5341_IN_SEL_SHIFT 1 @@ -340,6 +350,8 @@ static const struct si5341_reg_default si5341_reg_defaults[] = { { 0x094A, 0x00 }, /* INx_TO_PFD_EN (disabled) */ { 0x0A02, 0x00 }, /* Not in datasheet */ { 0x0B44, 0x0F }, /* PDIV_ENB (datasheet does not mention what it is) */ + { 0x0B57, 0x10 }, /* VCO_RESET_CALCODE (not described in datasheet) */ + { 0x0B58, 0x05 }, /* VCO_RESET_CALCODE (not described in datasheet) */ }; /* Read and interpret a 44-bit followed by a 32-bit value in the regmap */ @@ -623,6 +635,9 @@ static unsigned long si5341_synth_clk_recalc_rate(struct clk_hw *hw, SI5341_SYNTH_N_NUM(synth->index), &n_num, &n_den); if (err < 0) return err; + /* Check for bogus/uninitialized settings */ + if (!n_num || !n_den) + return 0; /* * n_num and n_den are shifted left as much as possible, so to prevent @@ -806,6 +821,9 @@ static long si5341_output_clk_round_rate(struct clk_hw *hw, unsigned long rate, { unsigned long r; + if (!rate) + return 0; + r = *parent_rate >> 1; /* If rate is an even divisor, no changes to parent required */ @@ -834,11 +852,16 @@ static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct clk_si5341_output *output = to_clk_si5341_output(hw); - /* Frequency divider is (r_div + 1) * 2 */ - u32 r_div = (parent_rate / rate) >> 1; + u32 r_div; int err; u8 r[3]; + if (!rate) + return -EINVAL; + + /* Frequency divider is (r_div + 1) * 2 */ + r_div = (parent_rate / rate) >> 1; + if (r_div <= 1) r_div = 0; else if (r_div >= BIT(24)) @@ -1083,7 +1106,7 @@ static const struct si5341_reg_default si5341_preamble[] = { { 0x0B25, 0x00 }, { 0x0502, 0x01 }, { 0x0505, 0x03 }, - { 0x0957, 0x1F }, + { 0x0957, 0x17 }, { 0x0B4E, 0x1A }, }; @@ -1189,6 +1212,32 @@ static const struct regmap_range_cfg si5341_regmap_ranges[] = { }, }; +static int si5341_wait_device_ready(struct i2c_client *client) +{ + int count; + + /* Datasheet warns: Any attempt to read or write any register other + * than DEVICE_READY before DEVICE_READY reads as 0x0F may corrupt the + * NVM programming and may corrupt the register contents, as they are + * read from NVM. Note that this includes accesses to the PAGE register. + * Also: DEVICE_READY is available on every register page, so no page + * change is needed to read it. + * Do this outside regmap to avoid automatic PAGE register access. + * May take up to 300ms to complete. + */ + for (count = 0; count < 15; ++count) { + s32 result = i2c_smbus_read_byte_data(client, + SI5341_DEVICE_READY); + if (result < 0) + return result; + if (result == 0x0F) + return 0; + msleep(20); + } + dev_err(&client->dev, "timeout waiting for DEVICE_READY\n"); + return -EIO; +} + static const struct regmap_config si5341_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -1378,6 +1427,7 @@ static int si5341_probe(struct i2c_client *client, unsigned int i; struct clk_si5341_output_config config[SI5341_MAX_NUM_OUTPUTS]; bool initialization_required; + u32 status; data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); if (!data) @@ -1385,6 +1435,11 @@ static int si5341_probe(struct i2c_client *client, data->i2c_client = client; + /* Must be done before otherwise touching hardware */ + err = si5341_wait_device_ready(client); + if (err) + return err; + for (i = 0; i < SI5341_NUM_INPUTS; ++i) { input = devm_clk_get(&client->dev, si5341_input_clock_names[i]); if (IS_ERR(input)) { @@ -1540,6 +1595,22 @@ static int si5341_probe(struct i2c_client *client, return err; } + /* wait for device to report input clock present and PLL lock */ + err = regmap_read_poll_timeout(data->regmap, SI5341_STATUS, status, + !(status & (SI5341_STATUS_LOSREF | SI5341_STATUS_LOL)), + 10000, 250000); + if (err) { + dev_err(&client->dev, "Error waiting for input clock or PLL lock\n"); + return err; + } + + /* clear sticky alarm bits from initialization */ + err = regmap_write(data->regmap, SI5341_STATUS_STICKY, 0); + if (err) { + dev_err(&client->dev, "unable to clear sticky status\n"); + return err; + } + /* Free the names, clk framework makes copies */ for (i = 0; i < data->num_synth; ++i) devm_kfree(&client->dev, (void *)synth_clock_names[i]); diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 18117ce5ff85..5c75e3d906c2 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -526,7 +526,7 @@ struct stm32f4_pll { struct stm32f4_pll_post_div_data { int idx; - u8 pll_num; + int pll_idx; const char *name; const char *parent; u8 flag; @@ -557,13 +557,13 @@ static const struct clk_div_table post_divr_table[] = { #define MAX_POST_DIV 3 static const struct stm32f4_pll_post_div_data post_div_data[MAX_POST_DIV] = { - { CLK_I2SQ_PDIV, PLL_I2S, "plli2s-q-div", "plli2s-q", + { CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q", CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL}, - { CLK_SAIQ_PDIV, PLL_SAI, "pllsai-q-div", "pllsai-q", + { CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q", CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL }, - { NO_IDX, PLL_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT, + { NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table }, }; @@ -1774,7 +1774,7 @@ static void __init stm32f4_rcc_init(struct device_node *np) post_div->width, post_div->flag_div, post_div->div_table, - clks[post_div->pll_num], + clks[post_div->pll_idx], &stm32f4_clk_lock); if (post_div->idx != NO_IDX) diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index 43db67337bc0..4e741f94baf0 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -69,7 +69,10 @@ #define VC5_FEEDBACK_FRAC_DIV(n) (0x19 + (n)) #define VC5_RC_CONTROL0 0x1e #define VC5_RC_CONTROL1 0x1f -/* Register 0x20 is factory reserved */ + +/* These registers are named "Unused Factory Reserved Registers" */ +#define VC5_RESERVED_X0(idx) (0x20 + ((idx) * 0x10)) +#define VC5_RESERVED_X0_BYPASS_SYNC BIT(7) /* bypass_sync bit */ /* Output divider control for divider 1,2,3,4 */ #define VC5_OUT_DIV_CONTROL(idx) (0x21 + ((idx) * 0x10)) @@ -87,7 +90,6 @@ #define VC5_OUT_DIV_SKEW_INT(idx, n) (0x2b + ((idx) * 0x10) + (n)) #define VC5_OUT_DIV_INT(idx, n) (0x2d + ((idx) * 0x10) + (n)) #define VC5_OUT_DIV_SKEW_FRAC(idx) (0x2f + ((idx) * 0x10)) -/* Registers 0x30, 0x40, 0x50 are factory reserved */ /* Clock control register for clock 1,2 */ #define VC5_CLK_OUTPUT_CFG(idx, n) (0x60 + ((idx) * 0x2) + (n)) @@ -140,6 +142,8 @@ #define VC5_HAS_INTERNAL_XTAL BIT(0) /* chip has PFD requency doubler */ #define VC5_HAS_PFD_FREQ_DBL BIT(1) +/* chip has bits to disable FOD sync */ +#define VC5_HAS_BYPASS_SYNC_BIT BIT(2) /* Supported IDT VC5 models. */ enum vc5_model { @@ -581,6 +585,23 @@ static int vc5_clk_out_prepare(struct clk_hw *hw) unsigned int src; int ret; + /* + * When enabling a FOD, all currently enabled FODs are briefly + * stopped in order to synchronize all of them. This causes a clock + * disruption to any unrelated chips that might be already using + * other clock outputs. Bypass the sync feature to avoid the issue, + * which is possible on the VersaClock 6E family via reserved + * registers. + */ + if (vc5->chip_info->flags & VC5_HAS_BYPASS_SYNC_BIT) { + ret = regmap_update_bits(vc5->regmap, + VC5_RESERVED_X0(hwdata->num), + VC5_RESERVED_X0_BYPASS_SYNC, + VC5_RESERVED_X0_BYPASS_SYNC); + if (ret) + return ret; + } + /* * If the input mux is disabled, enable it first and * select source from matching FOD. @@ -1102,7 +1123,7 @@ static const struct vc5_chip_info idt_5p49v6965_info = { .model = IDT_VC6_5P49V6965, .clk_fod_cnt = 4, .clk_out_cnt = 5, - .flags = 0, + .flags = VC5_HAS_BYPASS_SYNC_BIT, }; static const struct i2c_device_id vc5_id[] = { diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index f444bbe8244c..7d07dd92a7b4 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -974,6 +974,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) hws[IMX6QDL_CLK_PLL3_USB_OTG]->clk); } - imx_register_uart_clocks(1); + imx_register_uart_clocks(2); } CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 4e6c81a70221..aac6bcc65c20 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -350,46 +350,26 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) hws[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_hw_sscg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0); /* SYS PLL1 fixed output */ - hws[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_hw_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9); - hws[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_hw_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11); - hws[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_hw_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13); - hws[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_hw_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15); - hws[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_hw_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17); - hws[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_hw_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19); - hws[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_hw_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21); - hws[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_hw_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23); - hws[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_hw_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25); - - hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20); - hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10); - hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8); - hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6); - hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5); - hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4); - hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3); - hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2); - hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1); + hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_out", 1, 20); + hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_out", 1, 10); + hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_out", 1, 8); + hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_out", 1, 6); + hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_out", 1, 5); + hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_out", 1, 4); + hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_out", 1, 3); + hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_out", 1, 2); + hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_out", 1, 1); /* SYS PLL2 fixed output */ - hws[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_hw_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9); - hws[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_hw_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11); - hws[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_hw_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13); - hws[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_hw_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15); - hws[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_hw_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17); - hws[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_hw_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19); - hws[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_hw_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21); - hws[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_hw_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23); - hws[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_hw_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25); - - hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20); - hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10); - hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8); - hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6); - hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5); - hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4); - hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3); - hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2); - hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1); + hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_out", 1, 20); + hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_out", 1, 10); + hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_out", 1, 8); + hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_out", 1, 6); + hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_out", 1, 5); + hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_out", 1, 4); + hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_out", 1, 3); + hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_out", 1, 2); + hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_out", 1, 1); np = dev->of_node; base = devm_platform_ioremap_resource(pdev, 0); diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 3cb8196c8e29..203fa4476f8a 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -1603,7 +1603,7 @@ static struct clk_regmap g12b_cpub_clk_trace = { }; static const struct pll_mult_range g12a_gp0_pll_mult_range = { - .min = 55, + .min = 125, .max = 255, }; diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 564431130a76..1a571c04a76c 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -1214,7 +1214,7 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw) return -EINVAL; /* Setup PLL for calibration frequency */ - regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l); + regmap_write(pll->clkr.regmap, PLL_CAL_L_VAL(pll), cal_l); /* Bringup the PLL at calibration frequency */ ret = clk_alpha_pll_enable(hw); diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index 51ed640e527b..4ece326ea233 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -357,27 +357,43 @@ static int gdsc_init(struct gdsc *sc) if (on < 0) return on; - /* - * Votable GDSCs can be ON due to Vote from other masters. - * If a Votable GDSC is ON, make sure we have a Vote. - */ - if ((sc->flags & VOTABLE) && on) - gdsc_enable(&sc->pd); + if (on) { + /* The regulator must be on, sync the kernel state */ + if (sc->rsupply) { + ret = regulator_enable(sc->rsupply); + if (ret < 0) + return ret; + } - /* - * Make sure the retain bit is set if the GDSC is already on, otherwise - * we end up turning off the GDSC and destroying all the register - * contents that we thought we were saving. - */ - if ((sc->flags & RETAIN_FF_ENABLE) && on) - gdsc_retain_ff_on(sc); + /* + * Votable GDSCs can be ON due to Vote from other masters. + * If a Votable GDSC is ON, make sure we have a Vote. + */ + if (sc->flags & VOTABLE) { + ret = regmap_update_bits(sc->regmap, sc->gdscr, + SW_COLLAPSE_MASK, val); + if (ret) + return ret; + } + + /* Turn on HW trigger mode if supported */ + if (sc->flags & HW_CTRL) { + ret = gdsc_hwctrl(sc, true); + if (ret < 0) + return ret; + } - /* If ALWAYS_ON GDSCs are not ON, turn them ON */ - if (sc->flags & ALWAYS_ON) { - if (!on) - gdsc_enable(&sc->pd); + /* + * Make sure the retain bit is set if the GDSC is already on, + * otherwise we end up turning off the GDSC and destroying all + * the register contents that we thought we were saving. + */ + if (sc->flags & RETAIN_FF_ENABLE) + gdsc_retain_ff_on(sc); + } else if (sc->flags & ALWAYS_ON) { + /* If ALWAYS_ON GDSCs are not ON, turn them ON */ + gdsc_enable(&sc->pd); on = true; - sc->pd.flags |= GENPD_FLAG_ALWAYS_ON; } if (on || (sc->pwrsts & PWRSTS_RET)) @@ -385,6 +401,8 @@ static int gdsc_init(struct gdsc *sc) else gdsc_clear_mem_on(sc); + if (sc->flags & ALWAYS_ON) + sc->pd.flags |= GENPD_FLAG_ALWAYS_ON; if (!sc->pd.power_off) sc->pd.power_off = gdsc_disable; if (!sc->pd.power_on) diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c index 5b4691117b47..026e2612c33c 100644 --- a/drivers/clk/renesas/r8a77995-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c @@ -75,6 +75,7 @@ static const struct cpg_core_clk r8a77995_core_clks[] __initconst = { DEF_RATE(".oco", CLK_OCO, 8 * 1000 * 1000), /* Core Clock Outputs */ + DEF_FIXED("za2", R8A77995_CLK_ZA2, CLK_PLL0D3, 2, 1), DEF_FIXED("z2", R8A77995_CLK_Z2, CLK_PLL0D3, 1, 1), DEF_FIXED("ztr", R8A77995_CLK_ZTR, CLK_PLL1, 6, 1), DEF_FIXED("zt", R8A77995_CLK_ZT, CLK_PLL1, 4, 1), diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c b/drivers/clk/renesas/rcar-usb2-clock-sel.c index d4c02986c34e..7a64dcb7209e 100644 --- a/drivers/clk/renesas/rcar-usb2-clock-sel.c +++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c @@ -128,10 +128,8 @@ static int rcar_usb2_clock_sel_resume(struct device *dev) static int rcar_usb2_clock_sel_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct usb2_clock_sel_priv *priv = platform_get_drvdata(pdev); of_clk_del_provider(dev->of_node); - clk_hw_unregister(&priv->hw); pm_runtime_put(dev); pm_runtime_disable(dev); @@ -164,9 +162,6 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) if (IS_ERR(priv->rsts)) return PTR_ERR(priv->rsts); - pm_runtime_enable(dev); - pm_runtime_get_sync(dev); - clk = devm_clk_get(dev, "usb_extal"); if (!IS_ERR(clk) && !clk_prepare_enable(clk)) { priv->extal = !!clk_get_rate(clk); @@ -183,6 +178,8 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) return -ENOENT; } + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); platform_set_drvdata(pdev, priv); dev_set_drvdata(dev, priv); @@ -193,11 +190,20 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev) init.num_parents = 0; priv->hw.init = &init; - clk = clk_register(NULL, &priv->hw); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ret = devm_clk_hw_register(dev, &priv->hw); + if (ret) + goto pm_put; + + ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw); + if (ret) + goto pm_put; + + return 0; - return of_clk_add_hw_provider(np, of_clk_hw_simple_get, &priv->hw); +pm_put: + pm_runtime_put(dev); + pm_runtime_disable(dev); + return ret; } static const struct dev_pm_ops rcar_usb2_clock_sel_pm_ops = { diff --git a/drivers/clk/socfpga/clk-agilex.c b/drivers/clk/socfpga/clk-agilex.c index bb3e80928ebe..438075a50b9f 100644 --- a/drivers/clk/socfpga/clk-agilex.c +++ b/drivers/clk/socfpga/clk-agilex.c @@ -186,6 +186,41 @@ static const struct clk_parent_data noc_mux[] = { .name = "boot_clk", }, }; +static const struct clk_parent_data sdmmc_mux[] = { + { .fw_name = "sdmmc_free_clk", + .name = "sdmmc_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data s2f_user1_mux[] = { + { .fw_name = "s2f_user1_free_clk", + .name = "s2f_user1_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data psi_mux[] = { + { .fw_name = "psi_ref_free_clk", + .name = "psi_ref_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data gpio_db_mux[] = { + { .fw_name = "gpio_db_free_clk", + .name = "gpio_db_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data emac_ptp_mux[] = { + { .fw_name = "emac_ptp_free_clk", + .name = "emac_ptp_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + /* clocks in AO (always on) controller */ static const struct stratix10_pll_clock agilex_pll_clks[] = { { AGILEX_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0, @@ -211,11 +246,9 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = { { AGILEX_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux), 0, 0x3C, 0, 0, 0}, { AGILEX_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), - 0, 0x40, 0, 0, 1}, - { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0, - 0, 4, 0, 0}, - { AGILEX_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), - 0, 0, 0, 0x30, 1}, + 0, 0x40, 0, 0, 0}, + { AGILEX_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, + 0, 4, 0x30, 1}, { AGILEX_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux), 0, 0xD4, 0, 0x88, 0}, { AGILEX_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux), @@ -225,7 +258,7 @@ static const struct stratix10_perip_cnt_clock agilex_main_perip_cnt_clks[] = { { AGILEX_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux, ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3}, { AGILEX_SDMMC_FREE_CLK, "sdmmc_free_clk", NULL, sdmmc_free_mux, - ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0x88, 4}, + ARRAY_SIZE(sdmmc_free_mux), 0, 0xE4, 0, 0, 0}, { AGILEX_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL, s2f_usr0_free_mux, ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0, 0}, { AGILEX_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL, s2f_usr1_free_mux, @@ -241,24 +274,24 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = { 0, 0, 0, 0, 0, 0, 4}, { AGILEX_MPU_CCU_CLK, "mpu_ccu_clk", "mpu_clk", NULL, 1, 0, 0x24, 0, 0, 0, 0, 0, 0, 2}, - { AGILEX_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x24, - 1, 0x44, 0, 2, 0, 0, 0}, - { AGILEX_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x24, - 2, 0x44, 8, 2, 0, 0, 0}, + { AGILEX_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, + 1, 0x44, 0, 2, 0x30, 1, 0}, + { AGILEX_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, + 2, 0x44, 8, 2, 0x30, 1, 0}, /* * The l4_sp_clk feeds a 100 MHz clock to various peripherals, one of them * being the SP timers, thus cannot get gated. */ - { AGILEX_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x24, - 3, 0x44, 16, 2, 0, 0, 0}, - { AGILEX_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x24, - 4, 0x44, 24, 2, 0, 0, 0}, - { AGILEX_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x24, - 4, 0x44, 26, 2, 0, 0, 0}, + { AGILEX_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x24, + 3, 0x44, 16, 2, 0x30, 1, 0}, + { AGILEX_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, + 4, 0x44, 24, 2, 0x30, 1, 0}, + { AGILEX_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, + 4, 0x44, 26, 2, 0x30, 1, 0}, { AGILEX_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24, 4, 0x44, 28, 1, 0, 0, 0}, - { AGILEX_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x24, - 5, 0, 0, 0, 0, 0, 0}, + { AGILEX_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x24, + 5, 0, 0, 0, 0x30, 1, 0}, { AGILEX_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x24, 6, 0, 0, 0, 0, 0, 0}, { AGILEX_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C, @@ -267,16 +300,16 @@ static const struct stratix10_gate_clock agilex_gate_clks[] = { 1, 0, 0, 0, 0x94, 27, 0}, { AGILEX_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0x7C, 2, 0, 0, 0, 0x94, 28, 0}, - { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0x7C, - 3, 0, 0, 0, 0, 0, 0}, - { AGILEX_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0x7C, - 4, 0x98, 0, 16, 0, 0, 0}, - { AGILEX_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0x7C, - 5, 0, 0, 0, 0, 0, 4}, - { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0x7C, - 6, 0, 0, 0, 0, 0, 0}, - { AGILEX_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0x7C, - 7, 0, 0, 0, 0, 0, 0}, + { AGILEX_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0x7C, + 3, 0, 0, 0, 0x88, 2, 0}, + { AGILEX_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0x7C, + 4, 0x98, 0, 16, 0x88, 3, 0}, + { AGILEX_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0x7C, + 5, 0, 0, 0, 0x88, 4, 4}, + { AGILEX_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0x7C, + 6, 0, 0, 0, 0x88, 5, 0}, + { AGILEX_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0x7C, + 7, 0, 0, 0, 0x88, 6, 0}, { AGILEX_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, 8, 0, 0, 0, 0, 0, 0}, { AGILEX_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c index 397b77b89b16..bae595f17061 100644 --- a/drivers/clk/socfpga/clk-periph-s10.c +++ b/drivers/clk/socfpga/clk-periph-s10.c @@ -49,16 +49,21 @@ static u8 clk_periclk_get_parent(struct clk_hw *hwclk) { struct socfpga_periph_clk *socfpgaclk = to_periph_clk(hwclk); u32 clk_src, mask; - u8 parent; + u8 parent = 0; + /* handle the bypass first */ if (socfpgaclk->bypass_reg) { mask = (0x1 << socfpgaclk->bypass_shift); parent = ((readl(socfpgaclk->bypass_reg) & mask) >> socfpgaclk->bypass_shift); - } else { + if (parent) + return parent; + } + + if (socfpgaclk->hw.reg) { clk_src = readl(socfpgaclk->hw.reg); parent = (clk_src >> CLK_MGR_FREE_SHIFT) & - CLK_MGR_FREE_MASK; + CLK_MGR_FREE_MASK; } return parent; } diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c index 661a8e9bfb9b..aaf69058b1dc 100644 --- a/drivers/clk/socfpga/clk-s10.c +++ b/drivers/clk/socfpga/clk-s10.c @@ -144,6 +144,41 @@ static const struct clk_parent_data mpu_free_mux[] = { .name = "f2s-free-clk", }, }; +static const struct clk_parent_data sdmmc_mux[] = { + { .fw_name = "sdmmc_free_clk", + .name = "sdmmc_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data s2f_user1_mux[] = { + { .fw_name = "s2f_user1_free_clk", + .name = "s2f_user1_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data psi_mux[] = { + { .fw_name = "psi_ref_free_clk", + .name = "psi_ref_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data gpio_db_mux[] = { + { .fw_name = "gpio_db_free_clk", + .name = "gpio_db_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + +static const struct clk_parent_data emac_ptp_mux[] = { + { .fw_name = "emac_ptp_free_clk", + .name = "emac_ptp_free_clk", }, + { .fw_name = "boot_clk", + .name = "boot_clk", }, +}; + /* clocks in AO (always on) controller */ static const struct stratix10_pll_clock s10_pll_clks[] = { { STRATIX10_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0, @@ -167,7 +202,7 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { { STRATIX10_MPU_FREE_CLK, "mpu_free_clk", NULL, mpu_free_mux, ARRAY_SIZE(mpu_free_mux), 0, 0x48, 0, 0, 0}, { STRATIX10_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux, ARRAY_SIZE(noc_free_mux), - 0, 0x4C, 0, 0, 0}, + 0, 0x4C, 0, 0x3C, 1}, { STRATIX10_MAIN_EMACA_CLK, "main_emaca_clk", "main_noc_base_clk", NULL, 1, 0, 0x50, 0, 0, 0}, { STRATIX10_MAIN_EMACB_CLK, "main_emacb_clk", "main_noc_base_clk", NULL, 1, 0, @@ -200,10 +235,8 @@ static const struct stratix10_perip_cnt_clock s10_main_perip_cnt_clks[] = { 0, 0xD4, 0, 0, 0}, { STRATIX10_PERI_PSI_REF_CLK, "peri_psi_ref_clk", "peri_noc_base_clk", NULL, 1, 0, 0xD8, 0, 0, 0}, - { STRATIX10_L4_SYS_FREE_CLK, "l4_sys_free_clk", "noc_free_clk", NULL, 1, 0, - 0, 4, 0, 0}, - { STRATIX10_NOC_CLK, "noc_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), - 0, 0, 0, 0x3C, 1}, + { STRATIX10_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, + 0, 4, 0x3C, 1}, { STRATIX10_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux, ARRAY_SIZE(emaca_free_mux), 0, 0, 2, 0xB0, 0}, { STRATIX10_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux, ARRAY_SIZE(emacb_free_mux), @@ -227,20 +260,20 @@ static const struct stratix10_gate_clock s10_gate_clks[] = { 0, 0, 0, 0, 0, 0, 4}, { STRATIX10_MPU_L2RAM_CLK, "mpu_l2ram_clk", "mpu_clk", NULL, 1, 0, 0x30, 0, 0, 0, 0, 0, 0, 2}, - { STRATIX10_L4_MAIN_CLK, "l4_main_clk", "noc_clk", NULL, 1, 0, 0x30, - 1, 0x70, 0, 2, 0, 0, 0}, - { STRATIX10_L4_MP_CLK, "l4_mp_clk", "noc_clk", NULL, 1, 0, 0x30, - 2, 0x70, 8, 2, 0, 0, 0}, - { STRATIX10_L4_SP_CLK, "l4_sp_clk", "noc_clk", NULL, 1, CLK_IS_CRITICAL, 0x30, - 3, 0x70, 16, 2, 0, 0, 0}, - { STRATIX10_CS_AT_CLK, "cs_at_clk", "noc_clk", NULL, 1, 0, 0x30, - 4, 0x70, 24, 2, 0, 0, 0}, - { STRATIX10_CS_TRACE_CLK, "cs_trace_clk", "noc_clk", NULL, 1, 0, 0x30, - 4, 0x70, 26, 2, 0, 0, 0}, + { STRATIX10_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, + 1, 0x70, 0, 2, 0x3C, 1, 0}, + { STRATIX10_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, + 2, 0x70, 8, 2, 0x3C, 1, 0}, + { STRATIX10_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), CLK_IS_CRITICAL, 0x30, + 3, 0x70, 16, 2, 0x3C, 1, 0}, + { STRATIX10_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, + 4, 0x70, 24, 2, 0x3C, 1, 0}, + { STRATIX10_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, + 4, 0x70, 26, 2, 0x3C, 1, 0}, { STRATIX10_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x30, 4, 0x70, 28, 1, 0, 0, 0}, - { STRATIX10_CS_TIMER_CLK, "cs_timer_clk", "noc_clk", NULL, 1, 0, 0x30, - 5, 0, 0, 0, 0, 0, 0}, + { STRATIX10_CS_TIMER_CLK, "cs_timer_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0, 0x30, + 5, 0, 0, 0, 0x3C, 1, 0}, { STRATIX10_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_usr0_mux, ARRAY_SIZE(s2f_usr0_mux), 0, 0x30, 6, 0, 0, 0, 0, 0, 0}, { STRATIX10_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4, @@ -249,16 +282,16 @@ static const struct stratix10_gate_clock s10_gate_clks[] = { 1, 0, 0, 0, 0xDC, 27, 0}, { STRATIX10_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux), 0, 0xA4, 2, 0, 0, 0, 0xDC, 28, 0}, - { STRATIX10_EMAC_PTP_CLK, "emac_ptp_clk", "emac_ptp_free_clk", NULL, 1, 0, 0xA4, - 3, 0, 0, 0, 0, 0, 0}, - { STRATIX10_GPIO_DB_CLK, "gpio_db_clk", "gpio_db_free_clk", NULL, 1, 0, 0xA4, - 4, 0xE0, 0, 16, 0, 0, 0}, - { STRATIX10_SDMMC_CLK, "sdmmc_clk", "sdmmc_free_clk", NULL, 1, 0, 0xA4, - 5, 0, 0, 0, 0, 0, 4}, - { STRATIX10_S2F_USER1_CLK, "s2f_user1_clk", "s2f_user1_free_clk", NULL, 1, 0, 0xA4, - 6, 0, 0, 0, 0, 0, 0}, - { STRATIX10_PSI_REF_CLK, "psi_ref_clk", "psi_ref_free_clk", NULL, 1, 0, 0xA4, - 7, 0, 0, 0, 0, 0, 0}, + { STRATIX10_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux, ARRAY_SIZE(emac_ptp_mux), 0, 0xA4, + 3, 0, 0, 0, 0xB0, 2, 0}, + { STRATIX10_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux, ARRAY_SIZE(gpio_db_mux), 0, 0xA4, + 4, 0xE0, 0, 16, 0xB0, 3, 0}, + { STRATIX10_SDMMC_CLK, "sdmmc_clk", NULL, sdmmc_mux, ARRAY_SIZE(sdmmc_mux), 0, 0xA4, + 5, 0, 0, 0, 0xB0, 4, 4}, + { STRATIX10_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux, ARRAY_SIZE(s2f_user1_mux), 0, 0xA4, + 6, 0, 0, 0, 0xB0, 5, 0}, + { STRATIX10_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux, ARRAY_SIZE(psi_mux), 0, 0xA4, + 7, 0, 0, 0, 0xB0, 6, 0}, { STRATIX10_USB_CLK, "usb_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, 8, 0, 0, 0, 0, 0, 0}, { STRATIX10_SPI_M_CLK, "spi_m_clk", "l4_mp_clk", NULL, 1, 0, 0xA4, diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index 4b31beefc9fc..dc3f92678407 100644 --- a/drivers/clk/tegra/clk-periph-gate.c +++ b/drivers/clk/tegra/clk-periph-gate.c @@ -48,18 +48,9 @@ static int clk_periph_is_enabled(struct clk_hw *hw) return state; } -static int clk_periph_enable(struct clk_hw *hw) +static void clk_periph_enable_locked(struct clk_hw *hw) { struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); - unsigned long flags = 0; - - spin_lock_irqsave(&periph_ref_lock, flags); - - gate->enable_refcnt[gate->clk_num]++; - if (gate->enable_refcnt[gate->clk_num] > 1) { - spin_unlock_irqrestore(&periph_ref_lock, flags); - return 0; - } write_enb_set(periph_clk_to_bit(gate), gate); udelay(2); @@ -78,6 +69,32 @@ static int clk_periph_enable(struct clk_hw *hw) udelay(1); writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE); } +} + +static void clk_periph_disable_locked(struct clk_hw *hw) +{ + struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); + + /* + * If peripheral is in the APB bus then read the APB bus to + * flush the write operation in apb bus. This will avoid the + * peripheral access after disabling clock + */ + if (gate->flags & TEGRA_PERIPH_ON_APB) + tegra_read_chipid(); + + write_enb_clr(periph_clk_to_bit(gate), gate); +} + +static int clk_periph_enable(struct clk_hw *hw) +{ + struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); + unsigned long flags = 0; + + spin_lock_irqsave(&periph_ref_lock, flags); + + if (!gate->enable_refcnt[gate->clk_num]++) + clk_periph_enable_locked(hw); spin_unlock_irqrestore(&periph_ref_lock, flags); @@ -91,21 +108,28 @@ static void clk_periph_disable(struct clk_hw *hw) spin_lock_irqsave(&periph_ref_lock, flags); - gate->enable_refcnt[gate->clk_num]--; - if (gate->enable_refcnt[gate->clk_num] > 0) { - spin_unlock_irqrestore(&periph_ref_lock, flags); - return; - } + WARN_ON(!gate->enable_refcnt[gate->clk_num]); + + if (--gate->enable_refcnt[gate->clk_num] == 0) + clk_periph_disable_locked(hw); + + spin_unlock_irqrestore(&periph_ref_lock, flags); +} + +static void clk_periph_disable_unused(struct clk_hw *hw) +{ + struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw); + unsigned long flags = 0; + + spin_lock_irqsave(&periph_ref_lock, flags); /* - * If peripheral is in the APB bus then read the APB bus to - * flush the write operation in apb bus. This will avoid the - * peripheral access after disabling clock + * Some clocks are duplicated and some of them are marked as critical, + * like fuse and fuse_burn for example, thus the enable_refcnt will + * be non-zero here if the "unused" duplicate is disabled by CCF. */ - if (gate->flags & TEGRA_PERIPH_ON_APB) - tegra_read_chipid(); - - write_enb_clr(periph_clk_to_bit(gate), gate); + if (!gate->enable_refcnt[gate->clk_num]) + clk_periph_disable_locked(hw); spin_unlock_irqrestore(&periph_ref_lock, flags); } @@ -114,6 +138,7 @@ const struct clk_ops tegra_clk_periph_gate_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .disable = clk_periph_disable, + .disable_unused = clk_periph_disable_unused, }; struct clk *tegra_clk_register_periph_gate(const char *name, @@ -148,9 +173,6 @@ struct clk *tegra_clk_register_periph_gate(const char *name, gate->enable_refcnt = enable_refcnt; gate->regs = pregs; - if (read_enb(gate) & periph_clk_to_bit(gate)) - enable_refcnt[clk_num]++; - /* Data in .init is copied by clk_register(), so stack variable OK */ gate->hw.init = &init; diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c index 67620c7ecd9e..79ca3aa072b7 100644 --- a/drivers/clk/tegra/clk-periph.c +++ b/drivers/clk/tegra/clk-periph.c @@ -100,6 +100,15 @@ static void clk_periph_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); } +static void clk_periph_disable_unused(struct clk_hw *hw) +{ + struct tegra_clk_periph *periph = to_clk_periph(hw); + const struct clk_ops *gate_ops = periph->gate_ops; + struct clk_hw *gate_hw = &periph->gate.hw; + + gate_ops->disable_unused(gate_hw); +} + static void clk_periph_restore_context(struct clk_hw *hw) { struct tegra_clk_periph *periph = to_clk_periph(hw); @@ -126,6 +135,7 @@ const struct clk_ops tegra_clk_periph_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .disable = clk_periph_disable, + .disable_unused = clk_periph_disable_unused, .restore_context = clk_periph_restore_context, }; @@ -135,6 +145,7 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = { .is_enabled = clk_periph_is_enabled, .enable = clk_periph_enable, .disable = clk_periph_disable, + .disable_unused = clk_periph_disable_unused, .restore_context = clk_periph_restore_context, }; diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index c5cc0a2dac6f..d709ecb7d8d7 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1131,7 +1131,8 @@ static int clk_pllu_enable(struct clk_hw *hw) if (pll->lock) spin_lock_irqsave(pll->lock, flags); - _clk_pll_enable(hw); + if (!clk_pll_is_enabled(hw)) + _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); if (ret < 0) @@ -1748,15 +1749,13 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw) return -EINVAL; } - if (clk_pll_is_enabled(hw)) - return 0; - input_rate = clk_hw_get_rate(__clk_get_hw(osc)); if (pll->lock) spin_lock_irqsave(pll->lock, flags); - _clk_pll_enable(hw); + if (!clk_pll_is_enabled(hw)) + _clk_pll_enable(hw); ret = clk_pll_wait_for_lock(pll); if (ret < 0) diff --git a/drivers/clk/tegra/clk-sdmmc-mux.c b/drivers/clk/tegra/clk-sdmmc-mux.c index 316912d3b1a4..4f2c3309eea4 100644 --- a/drivers/clk/tegra/clk-sdmmc-mux.c +++ b/drivers/clk/tegra/clk-sdmmc-mux.c @@ -194,6 +194,15 @@ static void clk_sdmmc_mux_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); } +static void clk_sdmmc_mux_disable_unused(struct clk_hw *hw) +{ + struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw); + const struct clk_ops *gate_ops = sdmmc_mux->gate_ops; + struct clk_hw *gate_hw = &sdmmc_mux->gate.hw; + + gate_ops->disable_unused(gate_hw); +} + static void clk_sdmmc_mux_restore_context(struct clk_hw *hw) { struct clk_hw *parent = clk_hw_get_parent(hw); @@ -218,6 +227,7 @@ static const struct clk_ops tegra_clk_sdmmc_mux_ops = { .is_enabled = clk_sdmmc_mux_is_enabled, .enable = clk_sdmmc_mux_enable, .disable = clk_sdmmc_mux_disable, + .disable_unused = clk_sdmmc_mux_disable_unused, .restore_context = clk_sdmmc_mux_restore_context, }; diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 9cf249c344d9..31e752318a10 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1248,7 +1248,7 @@ static struct tegra_clk_init_table init_table[] __initdata = { { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 }, { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 }, { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 }, - { TEGRA30_CLK_VDE, TEGRA30_CLK_PLL_C, 600000000, 0 }, + { TEGRA30_CLK_VDE, TEGRA30_CLK_PLL_C, 300000000, 0 }, { TEGRA30_CLK_SPDIF_IN_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, { TEGRA30_CLK_I2S0_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, { TEGRA30_CLK_I2S1_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 }, diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index d0177824c518..5aeab5445f0b 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,8 @@ #include #include #include +#include +#include #include #include @@ -191,6 +194,7 @@ static u64 arch_counter_read_cc(const struct cyclecounter *cc) static struct clocksource clocksource_counter = { .name = "arch_sys_counter", + .id = CSID_ARM_ARCH_COUNTER, .rating = 400, .read = arch_counter_read, .mask = CLOCKSOURCE_MASK(56), @@ -352,7 +356,7 @@ static u64 notrace arm64_858921_read_cntvct_el0(void) do { \ _val = read_sysreg(reg); \ _retries--; \ - } while (((_val + 1) & GENMASK(9, 0)) <= 1 && _retries); \ + } while (((_val + 1) & GENMASK(8, 0)) <= 1 && _retries); \ \ WARN_ON_ONCE(!_retries); \ _val; \ @@ -1657,3 +1661,35 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) } TIMER_ACPI_DECLARE(arch_timer, ACPI_SIG_GTDT, arch_timer_acpi_init); #endif + +int kvm_arch_ptp_get_crosststamp(u64 *cycle, struct timespec64 *ts, + struct clocksource **cs) +{ + struct arm_smccc_res hvc_res; + u32 ptp_counter; + ktime_t ktime; + + if (!IS_ENABLED(CONFIG_HAVE_ARM_SMCCC_DISCOVERY)) + return -EOPNOTSUPP; + + if (arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) + ptp_counter = KVM_PTP_VIRT_COUNTER; + else + ptp_counter = KVM_PTP_PHYS_COUNTER; + + arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID, + ptp_counter, &hvc_res); + + if ((int)(hvc_res.a0) < 0) + return -EOPNOTSUPP; + + ktime = (u64)hvc_res.a0 << 32 | hvc_res.a1; + *ts = ktime_to_timespec64(ktime); + if (cycle) + *cycle = (u64)hvc_res.a2 << 32 | hvc_res.a3; + if (cs) + *cs = &clocksource_counter; + + return 0; +} +EXPORT_SYMBOL_GPL(kvm_arch_ptp_get_crosststamp); diff --git a/drivers/clocksource/timer-ti-dm.c b/drivers/clocksource/timer-ti-dm.c index 33eeabf9c3d1..e5c631f1b5cb 100644 --- a/drivers/clocksource/timer-ti-dm.c +++ b/drivers/clocksource/timer-ti-dm.c @@ -78,6 +78,9 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg, static void omap_timer_restore_context(struct omap_dm_timer *timer) { + __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, + timer->context.ocp_cfg, 0); + omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, timer->context.twer); omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, @@ -95,6 +98,9 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer) static void omap_timer_save_context(struct omap_dm_timer *timer) { + timer->context.ocp_cfg = + __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0); + timer->context.tclr = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); timer->context.twer = diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c index e4782f562e7a..2de7fd18f66a 100644 --- a/drivers/cpufreq/armada-37xx-cpufreq.c +++ b/drivers/cpufreq/armada-37xx-cpufreq.c @@ -102,7 +102,11 @@ struct armada_37xx_dvfs { }; static struct armada_37xx_dvfs armada_37xx_dvfs[] = { - {.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} }, + /* + * The cpufreq scaling for 1.2 GHz variant of the SOC is currently + * unstable because we do not know how to configure it properly. + */ + /* {.cpu_freq_max = 1200*1000*1000, .divider = {1, 2, 4, 6} }, */ {.cpu_freq_max = 1000*1000*1000, .divider = {1, 2, 4, 5} }, {.cpu_freq_max = 800*1000*1000, .divider = {1, 2, 3, 4} }, {.cpu_freq_max = 600*1000*1000, .divider = {2, 4, 5, 6} }, diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 1c192a42f11e..a3734014db47 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -136,6 +136,7 @@ static const struct of_device_id blacklist[] __initconst = { { .compatible = "qcom,qcs404", }, { .compatible = "qcom,sc7180", }, { .compatible = "qcom,sdm845", }, + { .compatible = "qcom,sm8150", }, { .compatible = "st,stih407", }, { .compatible = "st,stih410", }, diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 89dbff9a8501..a7b43780ebf0 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1380,9 +1380,14 @@ static int cpufreq_online(unsigned int cpu) goto out_free_policy; } + /* + * The initialization has succeeded and the policy is online. + * If there is a problem with its frequency table, take it + * offline and drop it. + */ ret = cpufreq_table_validate_and_sort(policy); if (ret) - goto out_exit_policy; + goto out_offline_policy; /* related_cpus should at least include policy->cpus. */ cpumask_copy(policy->related_cpus, policy->cpus); @@ -1526,6 +1531,10 @@ static int cpufreq_online(unsigned int cpu) up_write(&policy->rwsem); +out_offline_policy: + if (cpufreq_driver->offline) + cpufreq_driver->offline(policy); + out_exit_policy: if (cpufreq_driver->exit) cpufreq_driver->exit(policy); diff --git a/drivers/crypto/cavium/nitrox/nitrox_isr.c b/drivers/crypto/cavium/nitrox/nitrox_isr.c index 3dec570a190a..10e3408bf704 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_isr.c +++ b/drivers/crypto/cavium/nitrox/nitrox_isr.c @@ -306,6 +306,10 @@ int nitrox_register_interrupts(struct nitrox_device *ndev) * Entry 192: NPS_CORE_INT_ACTIVE */ nr_vecs = pci_msix_vec_count(pdev); + if (nr_vecs < 0) { + dev_err(DEV(ndev), "Error in getting vec count %d\n", nr_vecs); + return nr_vecs; + } /* Enable MSI-X */ ret = pci_alloc_irq_vectors(pdev, nr_vecs, nr_vecs, PCI_IRQ_MSIX); diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 21caed429cc5..d0018794e92e 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -42,6 +42,10 @@ static int psp_probe_timeout = 5; module_param(psp_probe_timeout, int, 0644); MODULE_PARM_DESC(psp_probe_timeout, " default timeout value, in seconds, during PSP device probe"); +MODULE_FIRMWARE("amd/amd_sev_fam17h_model0xh.sbin"); /* 1st gen EPYC */ +MODULE_FIRMWARE("amd/amd_sev_fam17h_model3xh.sbin"); /* 2nd gen EPYC */ +MODULE_FIRMWARE("amd/amd_sev_fam19h_model0xh.sbin"); /* 3rd gen EPYC */ + static bool psp_dead; static int psp_timeout; diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c index f471dbaef1fb..7d346d842a39 100644 --- a/drivers/crypto/ccp/sp-pci.c +++ b/drivers/crypto/ccp/sp-pci.c @@ -222,7 +222,7 @@ static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) { dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n", ret); - goto e_err; + goto free_irqs; } } @@ -230,10 +230,12 @@ static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) ret = sp_init(sp); if (ret) - goto e_err; + goto free_irqs; return 0; +free_irqs: + sp_free_irqs(sp); e_err: dev_notice(dev, "initialization failed\n"); return ret; diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c index 41f1fcacb280..630dcb59ad56 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -1515,11 +1515,11 @@ static struct skcipher_alg sec_skciphers[] = { AES_BLOCK_SIZE, AES_BLOCK_SIZE) SEC_SKCIPHER_ALG("ecb(des3_ede)", sec_setkey_3des_ecb, - SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE, + SEC_DES3_3KEY_SIZE, SEC_DES3_3KEY_SIZE, DES3_EDE_BLOCK_SIZE, 0) SEC_SKCIPHER_ALG("cbc(des3_ede)", sec_setkey_3des_cbc, - SEC_DES3_2KEY_SIZE, SEC_DES3_3KEY_SIZE, + SEC_DES3_3KEY_SIZE, SEC_DES3_3KEY_SIZE, DES3_EDE_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE) SEC_SKCIPHER_ALG("xts(sm4)", sec_setkey_sm4_xts, diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 276012e7c482..5e474a7a1912 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -149,6 +149,8 @@ struct crypt_ctl { struct ablk_ctx { struct buffer_desc *src; struct buffer_desc *dst; + u8 iv[MAX_IVLEN]; + bool encrypt; }; struct aead_ctx { @@ -330,7 +332,7 @@ static void free_buf_chain(struct device *dev, struct buffer_desc *buf, buf1 = buf->next; phys1 = buf->phys_next; - dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir); + dma_unmap_single(dev, buf->phys_addr, buf->buf_len, buf->dir); dma_pool_free(buffer_pool, buf, phys); buf = buf1; phys = phys1; @@ -381,6 +383,20 @@ static void one_packet(dma_addr_t phys) case CTL_FLAG_PERFORM_ABLK: { struct skcipher_request *req = crypt->data.ablk_req; struct ablk_ctx *req_ctx = skcipher_request_ctx(req); + struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); + unsigned int ivsize = crypto_skcipher_ivsize(tfm); + unsigned int offset; + + if (ivsize > 0) { + offset = req->cryptlen - ivsize; + if (req_ctx->encrypt) { + scatterwalk_map_and_copy(req->iv, req->dst, + offset, ivsize, 0); + } else { + memcpy(req->iv, req_ctx->iv, ivsize); + memzero_explicit(req_ctx->iv, ivsize); + } + } if (req_ctx->dst) { free_buf_chain(dev, req_ctx->dst, crypt->dst_buf); @@ -876,6 +892,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt) struct ablk_ctx *req_ctx = skcipher_request_ctx(req); struct buffer_desc src_hook; struct device *dev = &pdev->dev; + unsigned int offset; gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; @@ -885,6 +902,7 @@ static int ablk_perform(struct skcipher_request *req, int encrypt) return -EAGAIN; dir = encrypt ? &ctx->encrypt : &ctx->decrypt; + req_ctx->encrypt = encrypt; crypt = get_crypt_desc(); if (!crypt) @@ -900,6 +918,10 @@ static int ablk_perform(struct skcipher_request *req, int encrypt) BUG_ON(ivsize && !req->iv); memcpy(crypt->iv, req->iv, ivsize); + if (ivsize > 0 && !encrypt) { + offset = req->cryptlen - ivsize; + scatterwalk_map_and_copy(req_ctx->iv, req->src, offset, ivsize, 0); + } if (req->src != req->dst) { struct buffer_desc dst_hook; crypt->mode |= NPE_OP_NOT_IN_PLACE; diff --git a/drivers/crypto/nx/nx-842-pseries.c b/drivers/crypto/nx/nx-842-pseries.c index 2de5e3672e42..c5ec50a28f30 100644 --- a/drivers/crypto/nx/nx-842-pseries.c +++ b/drivers/crypto/nx/nx-842-pseries.c @@ -538,13 +538,15 @@ static int nx842_OF_set_defaults(struct nx842_devdata *devdata) * The status field indicates if the device is enabled when the status * is 'okay'. Otherwise the device driver will be disabled. * - * @prop - struct property point containing the maxsyncop for the update + * @devdata: struct nx842_devdata to use for dev_info + * @prop: struct property point containing the maxsyncop for the update * * Returns: * 0 - Device is available * -ENODEV - Device is not available */ -static int nx842_OF_upd_status(struct property *prop) +static int nx842_OF_upd_status(struct nx842_devdata *devdata, + struct property *prop) { const char *status = (const char *)prop->value; @@ -758,7 +760,7 @@ static int nx842_OF_upd(struct property *new_prop) goto out; /* Perform property updates */ - ret = nx842_OF_upd_status(status); + ret = nx842_OF_upd_status(new_devdata, status); if (ret) goto error_out; @@ -1071,6 +1073,7 @@ static const struct vio_device_id nx842_vio_driver_ids[] = { {"ibm,compression-v1", "ibm,compression"}, {"", ""}, }; +MODULE_DEVICE_TABLE(vio, nx842_vio_driver_ids); static struct vio_driver nx842_vio_driver = { .name = KBUILD_MODNAME, diff --git a/drivers/crypto/nx/nx-aes-ctr.c b/drivers/crypto/nx/nx-aes-ctr.c index 6d5ce1a66f1e..02ad26012c66 100644 --- a/drivers/crypto/nx/nx-aes-ctr.c +++ b/drivers/crypto/nx/nx-aes-ctr.c @@ -118,7 +118,7 @@ static int ctr3686_aes_nx_crypt(struct skcipher_request *req) struct nx_crypto_ctx *nx_ctx = crypto_skcipher_ctx(tfm); u8 iv[16]; - memcpy(iv, nx_ctx->priv.ctr.nonce, CTR_RFC3686_IV_SIZE); + memcpy(iv, nx_ctx->priv.ctr.nonce, CTR_RFC3686_NONCE_SIZE); memcpy(iv + CTR_RFC3686_NONCE_SIZE, req->iv, CTR_RFC3686_IV_SIZE); iv[12] = iv[13] = iv[14] = 0; iv[15] = 1; diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index a3b38d2c92e7..39d17ed1db2f 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -371,7 +371,7 @@ static int omap_sham_hw_init(struct omap_sham_dev *dd) { int err; - err = pm_runtime_get_sync(dd->dev); + err = pm_runtime_resume_and_get(dd->dev); if (err < 0) { dev_err(dd->dev, "failed to get sync: %d\n", err); return err; @@ -2243,7 +2243,7 @@ static int omap_sham_suspend(struct device *dev) static int omap_sham_resume(struct device *dev) { - int err = pm_runtime_get_sync(dev); + int err = pm_runtime_resume_and_get(dev); if (err < 0) { dev_err(dev, "failed to get sync: %d\n", err); return err; diff --git a/drivers/crypto/qat/qat_common/qat_hal.c b/drivers/crypto/qat/qat_common/qat_hal.c index 52ef80efeddc..b40e81e0088f 100644 --- a/drivers/crypto/qat/qat_common/qat_hal.c +++ b/drivers/crypto/qat/qat_common/qat_hal.c @@ -1213,7 +1213,11 @@ static int qat_hal_put_rel_wr_xfer(struct icp_qat_fw_loader_handle *handle, pr_err("QAT: bad xfrAddr=0x%x\n", xfr_addr); return -EINVAL; } - qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval); + status = qat_hal_rd_rel_reg(handle, ae, ctx, ICP_GPB_REL, gprnum, &gprval); + if (status) { + pr_err("QAT: failed to read register"); + return status; + } gpr_addr = qat_hal_get_reg_addr(ICP_GPB_REL, gprnum); data16low = 0xffff & data; data16hi = 0xffff & (data >> 0x10); diff --git a/drivers/crypto/qat/qat_common/qat_uclo.c b/drivers/crypto/qat/qat_common/qat_uclo.c index 5d1f28cd6680..6adc91fedb08 100644 --- a/drivers/crypto/qat/qat_common/qat_uclo.c +++ b/drivers/crypto/qat/qat_common/qat_uclo.c @@ -342,7 +342,6 @@ static int qat_uclo_init_umem_seg(struct icp_qat_fw_loader_handle *handle, return 0; } -#define ICP_DH895XCC_PESRAM_BAR_SIZE 0x80000 static int qat_uclo_init_ae_memory(struct icp_qat_fw_loader_handle *handle, struct icp_qat_uof_initmem *init_mem) { diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c index a2d3da0ad95f..d8053789c882 100644 --- a/drivers/crypto/qce/skcipher.c +++ b/drivers/crypto/qce/skcipher.c @@ -71,7 +71,7 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req) struct scatterlist *sg; bool diff_dst; gfp_t gfp; - int ret; + int dst_nents, src_nents, ret; rctx->iv = req->iv; rctx->ivsize = crypto_skcipher_ivsize(skcipher); @@ -122,21 +122,26 @@ qce_skcipher_async_req_handle(struct crypto_async_request *async_req) sg_mark_end(sg); rctx->dst_sg = rctx->dst_tbl.sgl; - ret = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); - if (ret < 0) + dst_nents = dma_map_sg(qce->dev, rctx->dst_sg, rctx->dst_nents, dir_dst); + if (dst_nents < 0) { + ret = dst_nents; goto error_free; + } if (diff_dst) { - ret = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src); - if (ret < 0) + src_nents = dma_map_sg(qce->dev, req->src, rctx->src_nents, dir_src); + if (src_nents < 0) { + ret = src_nents; goto error_unmap_dst; + } rctx->src_sg = req->src; } else { rctx->src_sg = rctx->dst_sg; + src_nents = dst_nents - 1; } - ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, rctx->src_nents, - rctx->dst_sg, rctx->dst_nents, + ret = qce_dma_prep_sgs(&qce->dma, rctx->src_sg, src_nents, + rctx->dst_sg, dst_nents, qce_skcipher_done, async_req); if (ret) goto error_unmap_src; diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c index 4640fe0c1f22..f15fc1fb3707 100644 --- a/drivers/crypto/sa2ul.c +++ b/drivers/crypto/sa2ul.c @@ -2270,9 +2270,9 @@ static int sa_dma_init(struct sa_crypto_data *dd) dd->dma_rx2 = dma_request_chan(dd->dev, "rx2"); if (IS_ERR(dd->dma_rx2)) { - dma_release_channel(dd->dma_rx1); - return dev_err_probe(dd->dev, PTR_ERR(dd->dma_rx2), - "Unable to request rx2 DMA channel\n"); + ret = dev_err_probe(dd->dev, PTR_ERR(dd->dma_rx2), + "Unable to request rx2 DMA channel\n"); + goto err_dma_rx2; } dd->dma_tx = dma_request_chan(dd->dev, "tx"); @@ -2293,28 +2293,31 @@ static int sa_dma_init(struct sa_crypto_data *dd) if (ret) { dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n", ret); - return ret; + goto err_dma_config; } ret = dmaengine_slave_config(dd->dma_rx2, &cfg); if (ret) { dev_err(dd->dev, "can't configure IN dmaengine slave: %d\n", ret); - return ret; + goto err_dma_config; } ret = dmaengine_slave_config(dd->dma_tx, &cfg); if (ret) { dev_err(dd->dev, "can't configure OUT dmaengine slave: %d\n", ret); - return ret; + goto err_dma_config; } return 0; +err_dma_config: + dma_release_channel(dd->dma_tx); err_dma_tx: - dma_release_channel(dd->dma_rx1); dma_release_channel(dd->dma_rx2); +err_dma_rx2: + dma_release_channel(dd->dma_rx1); return ret; } @@ -2353,13 +2356,14 @@ static int sa_ul_probe(struct platform_device *pdev) if (ret < 0) { dev_err(&pdev->dev, "%s: failed to get sync: %d\n", __func__, ret); + pm_runtime_disable(dev); return ret; } sa_init_mem(dev_data); ret = sa_dma_init(dev_data); if (ret) - goto disable_pm_runtime; + goto destroy_dma_pool; spin_lock_init(&dev_data->scid_lock); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -2389,9 +2393,9 @@ static int sa_ul_probe(struct platform_device *pdev) dma_release_channel(dev_data->dma_rx1); dma_release_channel(dev_data->dma_tx); +destroy_dma_pool: dma_pool_destroy(dev_data->sc_pool); -disable_pm_runtime: pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c index 3d407eebb2ba..1e2daf403032 100644 --- a/drivers/crypto/ux500/hash/hash_core.c +++ b/drivers/crypto/ux500/hash/hash_core.c @@ -1009,6 +1009,7 @@ static int hash_hw_final(struct ahash_request *req) goto out; } } else if (req->nbytes == 0 && ctx->keylen > 0) { + ret = -EPERM; dev_err(device_data->dev, "%s: Empty message with keylength > 0, NOT supported\n", __func__); goto out; diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 98f03a02d112..829128c0cc68 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -789,6 +789,7 @@ struct devfreq *devfreq_add_device(struct device *dev, if (devfreq->profile->timer < 0 || devfreq->profile->timer >= DEVFREQ_TIMER_NUM) { mutex_unlock(&devfreq->lock); + err = -EINVAL; goto err_dev; } diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 5a5a1da01a00..f0c822952c20 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -211,8 +211,8 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, struct sync_file *b) { struct sync_file *sync_file; - struct dma_fence **fences, **nfences, **a_fences, **b_fences; - int i, i_a, i_b, num_fences, a_num_fences, b_num_fences; + struct dma_fence **fences = NULL, **nfences, **a_fences, **b_fences; + int i = 0, i_a, i_b, num_fences, a_num_fences, b_num_fences; sync_file = sync_file_alloc(); if (!sync_file) @@ -236,7 +236,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, * If a sync_file can only be created with sync_file_merge * and sync_file_create, this is a reasonable assumption. */ - for (i = i_a = i_b = 0; i_a < a_num_fences && i_b < b_num_fences; ) { + for (i_a = i_b = 0; i_a < a_num_fences && i_b < b_num_fences; ) { struct dma_fence *pt_a = a_fences[i_a]; struct dma_fence *pt_b = b_fences[i_b]; @@ -278,15 +278,16 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, fences = nfences; } - if (sync_file_set_fence(sync_file, fences, i) < 0) { - kfree(fences); + if (sync_file_set_fence(sync_file, fences, i) < 0) goto err; - } strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name)); return sync_file; err: + while (i) + dma_fence_put(fences[--i]); + kfree(fences); fput(sync_file->file); return NULL; diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 1d263fc15a53..a04186651e95 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -59,6 +59,7 @@ config DMA_OF #devices config ALTERA_MSGDMA tristate "Altera / Intel mSGDMA Engine" + depends on HAS_IOMEM select DMA_ENGINE help Enable support for Altera / Intel mSGDMA controller. @@ -698,6 +699,7 @@ config XILINX_ZYNQMP_DMA config XILINX_ZYNQMP_DPDMA tristate "Xilinx DPDMA Engine" + depends on HAS_IOMEM && OF select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help diff --git a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c index 4ec909e0b810..4ae057922ef1 100644 --- a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c +++ b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c @@ -332,6 +332,7 @@ static int __cold dpaa2_qdma_setup(struct fsl_mc_device *ls_dev) } if (priv->dpdmai_attr.version.major > DPDMAI_VER_MAJOR) { + err = -EINVAL; dev_err(dev, "DPDMAI major version mismatch\n" "Found %u.%u, supported version is %u.%u\n", priv->dpdmai_attr.version.major, @@ -341,6 +342,7 @@ static int __cold dpaa2_qdma_setup(struct fsl_mc_device *ls_dev) } if (priv->dpdmai_attr.version.minor > DPDMAI_VER_MINOR) { + err = -EINVAL; dev_err(dev, "DPDMAI minor version mismatch\n" "Found %u.%u, supported version is %u.%u\n", priv->dpdmai_attr.version.major, @@ -475,6 +477,7 @@ static int __cold dpaa2_qdma_dpio_setup(struct dpaa2_qdma_priv *priv) ppriv->store = dpaa2_io_store_create(DPAA2_QDMA_STORE_SIZE, dev); if (!ppriv->store) { + err = -ENOMEM; dev_err(dev, "dpaa2_io_store_create() failed\n"); goto err_store; } diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c index ed2ab46b15e7..045ead46ec8f 100644 --- a/drivers/dma/fsl-qdma.c +++ b/drivers/dma/fsl-qdma.c @@ -1235,7 +1235,11 @@ static int fsl_qdma_probe(struct platform_device *pdev) fsl_qdma->dma_dev.device_synchronize = fsl_qdma_synchronize; fsl_qdma->dma_dev.device_terminate_all = fsl_qdma_terminate_all; - dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)); + ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)); + if (ret) { + dev_err(&pdev->dev, "dma_set_mask failure.\n"); + return ret; + } platform_set_drvdata(pdev, fsl_qdma); diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index f4c7ce8cb399..048a23018a3d 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -518,6 +518,7 @@ module_init(idxd_init_module); static void __exit idxd_exit_module(void) { + idxd_unregister_driver(); pci_unregister_driver(&idxd_pci_driver); idxd_cdev_remove(); idxd_unregister_bus_type(); diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 670db04b0757..52e361ed43e3 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -831,6 +831,8 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg( dma_length += sg_dma_len(sg); } + imxdma_config_write(chan, &imxdmac->config, direction); + switch (imxdmac->word_size) { case DMA_SLAVE_BUSWIDTH_4_BYTES: if (sg_dma_len(sgl) & 3 || sgl->dma_address & 3) diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c b/drivers/dma/mediatek/mtk-uart-apdma.c index 27c07350971d..375e7e647df6 100644 --- a/drivers/dma/mediatek/mtk-uart-apdma.c +++ b/drivers/dma/mediatek/mtk-uart-apdma.c @@ -131,10 +131,7 @@ static unsigned int mtk_uart_apdma_read(struct mtk_chan *c, unsigned int reg) static void mtk_uart_apdma_desc_free(struct virt_dma_desc *vd) { - struct dma_chan *chan = vd->tx.chan; - struct mtk_chan *c = to_mtk_uart_apdma_chan(chan); - - kfree(c->desc); + kfree(container_of(vd, struct mtk_uart_apdma_desc, vd)); } static void mtk_uart_apdma_start_tx(struct mtk_chan *c) @@ -207,14 +204,9 @@ static void mtk_uart_apdma_start_rx(struct mtk_chan *c) static void mtk_uart_apdma_tx_handler(struct mtk_chan *c) { - struct mtk_uart_apdma_desc *d = c->desc; - mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_TX_INT_CLR_B); mtk_uart_apdma_write(c, VFF_INT_EN, VFF_INT_EN_CLR_B); mtk_uart_apdma_write(c, VFF_EN, VFF_EN_CLR_B); - - list_del(&d->vd.node); - vchan_cookie_complete(&d->vd); } static void mtk_uart_apdma_rx_handler(struct mtk_chan *c) @@ -245,9 +237,17 @@ static void mtk_uart_apdma_rx_handler(struct mtk_chan *c) c->rx_status = d->avail_len - cnt; mtk_uart_apdma_write(c, VFF_RPT, wg); +} - list_del(&d->vd.node); - vchan_cookie_complete(&d->vd); +static void mtk_uart_apdma_chan_complete_handler(struct mtk_chan *c) +{ + struct mtk_uart_apdma_desc *d = c->desc; + + if (d) { + list_del(&d->vd.node); + vchan_cookie_complete(&d->vd); + c->desc = NULL; + } } static irqreturn_t mtk_uart_apdma_irq_handler(int irq, void *dev_id) @@ -261,6 +261,7 @@ static irqreturn_t mtk_uart_apdma_irq_handler(int irq, void *dev_id) mtk_uart_apdma_rx_handler(c); else if (c->dir == DMA_MEM_TO_DEV) mtk_uart_apdma_tx_handler(c); + mtk_uart_apdma_chan_complete_handler(c); spin_unlock_irqrestore(&c->vc.lock, flags); return IRQ_HANDLED; @@ -348,7 +349,7 @@ static struct dma_async_tx_descriptor *mtk_uart_apdma_prep_slave_sg return NULL; /* Now allocate and setup the descriptor */ - d = kzalloc(sizeof(*d), GFP_ATOMIC); + d = kzalloc(sizeof(*d), GFP_NOWAIT); if (!d) return NULL; @@ -366,7 +367,7 @@ static void mtk_uart_apdma_issue_pending(struct dma_chan *chan) unsigned long flags; spin_lock_irqsave(&c->vc.lock, flags); - if (vchan_issue_pending(&c->vc)) { + if (vchan_issue_pending(&c->vc) && !c->desc) { vd = vchan_next_desc(&c->vc); c->desc = to_mtk_uart_apdma_desc(&vd->tx); diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c index 8a4f608904b9..4be433482053 100644 --- a/drivers/dma/of-dma.c +++ b/drivers/dma/of-dma.c @@ -67,8 +67,12 @@ static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec, return NULL; ofdma_target = of_dma_find_controller(&dma_spec_target); - if (!ofdma_target) - return NULL; + if (!ofdma_target) { + ofdma->dma_router->route_free(ofdma->dma_router->dev, + route_data); + chan = ERR_PTR(-EPROBE_DEFER); + goto err; + } chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target); if (IS_ERR_OR_NULL(chan)) { @@ -79,6 +83,7 @@ static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec, chan->route_data = route_data; } +err: /* * Need to put the node back since the ofdma->of_dma_route_allocate * has taken it for generating the new, translated dma_spec diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index b038f3ffc5ff..bbf79a73a14a 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2996,13 +2996,15 @@ struct dma_async_tx_descriptor *__pl330_prep_dma_cyclic(struct dma_chan *chan, for (i = 0; i < len / period_len; i++) { desc = pl330_get_desc(pch); if (!desc) { + unsigned long iflags; + dev_err(pch->dmac->ddma.dev, "%s:%d Unable to fetch desc\n", __func__, __LINE__); if (!first) return NULL; - spin_lock_irqsave(&pl330->pool_lock, flags); + spin_lock_irqsave(&pl330->pool_lock, iflags); while (!list_empty(&first->node)) { desc = list_entry(first->node.next, @@ -3012,7 +3014,7 @@ struct dma_async_tx_descriptor *__pl330_prep_dma_cyclic(struct dma_chan *chan, list_move_tail(&first->node, &pl330->desc_pool); - spin_unlock_irqrestore(&pl330->pool_lock, flags); + spin_unlock_irqrestore(&pl330->pool_lock, iflags); return NULL; } diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig index 3bcb689162c6..ef038f3c5e32 100644 --- a/drivers/dma/qcom/Kconfig +++ b/drivers/dma/qcom/Kconfig @@ -10,6 +10,7 @@ config QCOM_BAM_DMA config QCOM_HIDMA_MGMT tristate "Qualcomm Technologies HIDMA Management support" + depends on HAS_IOMEM select DMA_ENGINE help Enable support for the Qualcomm Technologies HIDMA Management. diff --git a/drivers/dma/sf-pdma/Kconfig b/drivers/dma/sf-pdma/Kconfig index f8ffa02e279f..ba46a0a15a93 100644 --- a/drivers/dma/sf-pdma/Kconfig +++ b/drivers/dma/sf-pdma/Kconfig @@ -1,5 +1,6 @@ config SF_PDMA tristate "Sifive PDMA controller driver" + depends on HAS_IOMEM select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index a57705356e8b..991a7b5da29f 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -1874,7 +1874,7 @@ static int rcar_dmac_probe(struct platform_device *pdev) /* Enable runtime PM and initialize the device. */ pm_runtime_enable(&pdev->dev); - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "runtime PM get sync failed (%d)\n", ret); return ret; diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index 8f7ceb698226..1cc06900153e 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c @@ -855,8 +855,8 @@ static int usb_dmac_probe(struct platform_device *pdev) error: of_dma_controller_free(pdev->dev.of_node); - pm_runtime_put(&pdev->dev); error_pm: + pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); return ret; } diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 77ab1f4730be..b35b97cb8fd2 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -3676,6 +3676,9 @@ static int __init d40_probe(struct platform_device *pdev) kfree(base->lcla_pool.base_unaligned); + if (base->lcpa_base) + iounmap(base->lcpa_base); + if (base->phy_lcpa) release_mem_region(base->phy_lcpa, base->lcpa_size); diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c index d0055d2f0b9a..1150aa90eab6 100644 --- a/drivers/dma/stm32-dma.c +++ b/drivers/dma/stm32-dma.c @@ -1187,7 +1187,7 @@ static int stm32_dma_alloc_chan_resources(struct dma_chan *c) chan->config_init = false; - ret = pm_runtime_get_sync(dmadev->ddev.dev); + ret = pm_runtime_resume_and_get(dmadev->ddev.dev); if (ret < 0) return ret; @@ -1455,7 +1455,7 @@ static int stm32_dma_suspend(struct device *dev) struct stm32_dma_device *dmadev = dev_get_drvdata(dev); int id, ret, scr; - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) return ret; diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c index a10ccd964376..bddd3b23f33f 100644 --- a/drivers/dma/stm32-dmamux.c +++ b/drivers/dma/stm32-dmamux.c @@ -137,7 +137,7 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec, /* Set dma request */ spin_lock_irqsave(&dmamux->lock, flags); - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) { spin_unlock_irqrestore(&dmamux->lock, flags); goto error; @@ -336,7 +336,7 @@ static int stm32_dmamux_suspend(struct device *dev) struct stm32_dmamux_data *stm32_dmamux = platform_get_drvdata(pdev); int i, ret; - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) return ret; @@ -361,7 +361,7 @@ static int stm32_dmamux_resume(struct device *dev) if (ret < 0) return ret; - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) return ret; diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c index 08cfbfab837b..9d473923712a 100644 --- a/drivers/dma/stm32-mdma.c +++ b/drivers/dma/stm32-mdma.c @@ -1448,7 +1448,7 @@ static int stm32_mdma_alloc_chan_resources(struct dma_chan *c) return -ENOMEM; } - ret = pm_runtime_get_sync(dmadev->ddev.dev); + ret = pm_runtime_resume_and_get(dmadev->ddev.dev); if (ret < 0) return ret; @@ -1714,7 +1714,7 @@ static int stm32_mdma_pm_suspend(struct device *dev) u32 ccr, id; int ret; - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) return ret; diff --git a/drivers/dma/uniphier-xdmac.c b/drivers/dma/uniphier-xdmac.c index 16b19654873d..d6b8a202474f 100644 --- a/drivers/dma/uniphier-xdmac.c +++ b/drivers/dma/uniphier-xdmac.c @@ -209,8 +209,8 @@ static int uniphier_xdmac_chan_stop(struct uniphier_xdmac_chan *xc) writel(0, xc->reg_ch_base + XDMAC_TSS); /* wait until transfer is stopped */ - return readl_poll_timeout(xc->reg_ch_base + XDMAC_STAT, val, - !(val & XDMAC_STAT_TENF), 100, 1000); + return readl_poll_timeout_atomic(xc->reg_ch_base + XDMAC_STAT, val, + !(val & XDMAC_STAT_TENF), 100, 1000); } /* xc->vc.lock must be held by caller */ diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 79777550a6ff..9ffdbeec436b 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -394,6 +394,7 @@ struct xilinx_dma_tx_descriptor { * @genlock: Support genlock mode * @err: Channel has errors * @idle: Check for channel idle + * @terminating: Check for channel being synchronized by user * @tasklet: Cleanup work after irq * @config: Device configuration info * @flush_on_fsync: Flush on Frame sync @@ -431,6 +432,7 @@ struct xilinx_dma_chan { bool genlock; bool err; bool idle; + bool terminating; struct tasklet_struct tasklet; struct xilinx_vdma_config config; bool flush_on_fsync; @@ -1049,6 +1051,13 @@ static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan) /* Run any dependencies, then free the descriptor */ dma_run_dependencies(&desc->async_tx); xilinx_dma_free_tx_descriptor(chan, desc); + + /* + * While we ran a callback the user called a terminate function, + * which takes care of cleaning up any remaining descriptors + */ + if (chan->terminating) + break; } spin_unlock_irqrestore(&chan->lock, flags); @@ -1965,6 +1974,8 @@ static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx) if (desc->cyclic) chan->cyclic = true; + chan->terminating = false; + spin_unlock_irqrestore(&chan->lock, flags); return cookie; @@ -2436,6 +2447,7 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan) xilinx_dma_chan_reset(chan); /* Remove and free all of the descriptors in the lists */ + chan->terminating = true; xilinx_dma_free_descriptors(chan); chan->idle = true; diff --git a/drivers/dma/xilinx/xilinx_dpdma.c b/drivers/dma/xilinx/xilinx_dpdma.c index 70b29bd079c9..6c709803203a 100644 --- a/drivers/dma/xilinx/xilinx_dpdma.c +++ b/drivers/dma/xilinx/xilinx_dpdma.c @@ -113,6 +113,7 @@ #define XILINX_DPDMA_CH_VDO 0x020 #define XILINX_DPDMA_CH_PYLD_SZ 0x024 #define XILINX_DPDMA_CH_DESC_ID 0x028 +#define XILINX_DPDMA_CH_DESC_ID_MASK GENMASK(15, 0) /* DPDMA descriptor fields */ #define XILINX_DPDMA_DESC_CONTROL_PREEMBLE 0xa5 @@ -866,7 +867,8 @@ static void xilinx_dpdma_chan_queue_transfer(struct xilinx_dpdma_chan *chan) * will be used, but it should be enough. */ list_for_each_entry(sw_desc, &desc->descriptors, node) - sw_desc->hw.desc_id = desc->vdesc.tx.cookie; + sw_desc->hw.desc_id = desc->vdesc.tx.cookie + & XILINX_DPDMA_CH_DESC_ID_MASK; sw_desc = list_first_entry(&desc->descriptors, struct xilinx_dpdma_sw_desc, node); @@ -1086,7 +1088,8 @@ static void xilinx_dpdma_chan_vsync_irq(struct xilinx_dpdma_chan *chan) if (!chan->running || !pending) goto out; - desc_id = dpdma_read(chan->reg, XILINX_DPDMA_CH_DESC_ID); + desc_id = dpdma_read(chan->reg, XILINX_DPDMA_CH_DESC_ID) + & XILINX_DPDMA_CH_DESC_ID_MASK; /* If the retrigger raced with vsync, retry at the next frame. */ sw_desc = list_first_entry(&pending->descriptors, @@ -1459,7 +1462,7 @@ static void xilinx_dpdma_enable_irq(struct xilinx_dpdma_device *xdev) */ static void xilinx_dpdma_disable_irq(struct xilinx_dpdma_device *xdev) { - dpdma_write(xdev->reg, XILINX_DPDMA_IDS, XILINX_DPDMA_INTR_ERR_ALL); + dpdma_write(xdev->reg, XILINX_DPDMA_IDS, XILINX_DPDMA_INTR_ALL); dpdma_write(xdev->reg, XILINX_DPDMA_EIDS, XILINX_DPDMA_EINTR_ALL); } @@ -1596,6 +1599,26 @@ static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec, return dma_get_slave_channel(&xdev->chan[chan_id]->vchan.chan); } +static void dpdma_hw_init(struct xilinx_dpdma_device *xdev) +{ + unsigned int i; + void __iomem *reg; + + /* Disable all interrupts */ + xilinx_dpdma_disable_irq(xdev); + + /* Stop all channels */ + for (i = 0; i < ARRAY_SIZE(xdev->chan); i++) { + reg = xdev->reg + XILINX_DPDMA_CH_BASE + + XILINX_DPDMA_CH_OFFSET * i; + dpdma_clr(reg, XILINX_DPDMA_CH_CNTL, XILINX_DPDMA_CH_CNTL_ENABLE); + } + + /* Clear the interrupt status registers */ + dpdma_write(xdev->reg, XILINX_DPDMA_ISR, XILINX_DPDMA_INTR_ALL); + dpdma_write(xdev->reg, XILINX_DPDMA_EISR, XILINX_DPDMA_EINTR_ALL); +} + static int xilinx_dpdma_probe(struct platform_device *pdev) { struct xilinx_dpdma_device *xdev; @@ -1622,6 +1645,8 @@ static int xilinx_dpdma_probe(struct platform_device *pdev) if (IS_ERR(xdev->reg)) return PTR_ERR(xdev->reg); + dpdma_hw_init(xdev); + xdev->irq = platform_get_irq(pdev, 0); if (xdev->irq < 0) { dev_err(xdev->dev, "failed to get platform irq\n"); diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c index d8419565b92c..5fecf5aa6e85 100644 --- a/drivers/dma/xilinx/zynqmp_dma.c +++ b/drivers/dma/xilinx/zynqmp_dma.c @@ -468,7 +468,7 @@ static int zynqmp_dma_alloc_chan_resources(struct dma_chan *dchan) struct zynqmp_dma_desc_sw *desc; int i, ret; - ret = pm_runtime_get_sync(chan->dev); + ret = pm_runtime_resume_and_get(chan->dev); if (ret < 0) return ret; diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index 7b52691c45d2..4912a7b88380 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -263,6 +263,9 @@ static int __init i10nm_init(void) if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) return -EBUSY; + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) + return -ENODEV; + id = x86_match_cpu(i10nm_cpuids); if (!id) return -ENODEV; diff --git a/drivers/edac/pnd2_edac.c b/drivers/edac/pnd2_edac.c index 928f63a374c7..c94ca1f790c4 100644 --- a/drivers/edac/pnd2_edac.c +++ b/drivers/edac/pnd2_edac.c @@ -1554,6 +1554,9 @@ static int __init pnd2_init(void) if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) return -EBUSY; + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) + return -ENODEV; + id = x86_match_cpu(pnd2_cpuids); if (!id) return -ENODEV; diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 93daa4297f2e..4c626fcd4dcb 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -3510,6 +3510,9 @@ static int __init sbridge_init(void) if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) return -EBUSY; + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) + return -ENODEV; + id = x86_match_cpu(sbridge_cpuids); if (!id) return -ENODEV; diff --git a/drivers/edac/skx_base.c b/drivers/edac/skx_base.c index 2c7db95df326..f887e3166651 100644 --- a/drivers/edac/skx_base.c +++ b/drivers/edac/skx_base.c @@ -656,6 +656,9 @@ static int __init skx_init(void) if (owner && strncmp(owner, EDAC_MOD_STR, sizeof(EDAC_MOD_STR))) return -EBUSY; + if (cpu_feature_enabled(X86_FEATURE_HYPERVISOR)) + return -ENODEV; + id = x86_match_cpu(skx_cpuids); if (!id) return -ENODEV; diff --git a/drivers/edac/ti_edac.c b/drivers/edac/ti_edac.c index e7eae20f83d1..169f96e51c29 100644 --- a/drivers/edac/ti_edac.c +++ b/drivers/edac/ti_edac.c @@ -197,6 +197,7 @@ static const struct of_device_id ti_edac_of_match[] = { { .compatible = "ti,emif-dra7xx", .data = (void *)EMIF_TYPE_DRA7 }, {}, }; +MODULE_DEVICE_TABLE(of, ti_edac_of_match); static int _emif_get_id(struct device_node *node) { diff --git a/drivers/extcon/extcon-intel-mrfld.c b/drivers/extcon/extcon-intel-mrfld.c index f47016fb28a8..cd1a5f230077 100644 --- a/drivers/extcon/extcon-intel-mrfld.c +++ b/drivers/extcon/extcon-intel-mrfld.c @@ -197,6 +197,7 @@ static int mrfld_extcon_probe(struct platform_device *pdev) struct intel_soc_pmic *pmic = dev_get_drvdata(dev->parent); struct regmap *regmap = pmic->regmap; struct mrfld_extcon_data *data; + unsigned int status; unsigned int id; int irq, ret; @@ -244,6 +245,14 @@ static int mrfld_extcon_probe(struct platform_device *pdev) /* Get initial state */ mrfld_extcon_role_detect(data); + /* + * Cached status value is used for cable detection, see comments + * in mrfld_extcon_cable_detect(), we need to sync cached value + * with a real state of the hardware. + */ + regmap_read(regmap, BCOVE_SCHGRIRQ1, &status); + data->status = status; + mrfld_extcon_clear(data, BCOVE_MIRQLVL1, BCOVE_LVL1_CHGR); mrfld_extcon_clear(data, BCOVE_MCHGRIRQ1, BCOVE_CHGRIRQ_ALL); diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 337b0eea4e62..64008808675e 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -729,7 +729,7 @@ static int max8997_muic_probe(struct platform_device *pdev) 2, info->status); if (ret) { dev_err(info->dev, "failed to read MUIC register\n"); - return ret; + goto err_irq; } cable_type = max8997_muic_get_cable_type(info, MAX8997_CABLE_GROUP_ADC, &attached); @@ -784,3 +784,4 @@ module_platform_driver(max8997_muic_driver); MODULE_DESCRIPTION("Maxim MAX8997 Extcon driver"); MODULE_AUTHOR("Donggeun Kim "); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:max8997-muic"); diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c index 106d4da647bd..5e0718dee03b 100644 --- a/drivers/extcon/extcon-sm5502.c +++ b/drivers/extcon/extcon-sm5502.c @@ -88,7 +88,6 @@ static struct reg_data sm5502_reg_data[] = { | SM5502_REG_INTM2_MHL_MASK, .invert = true, }, - { } }; /* List of detectable cables */ diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index bfef3d8d14e7..359f6516b5ac 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -9,7 +9,7 @@ menu "Firmware Drivers" config ARM_SCMI_PROTOCOL tristate "ARM System Control and Management Interface (SCMI) Message Protocol" depends on ARM || ARM64 || COMPILE_TEST - depends on MAILBOX + depends on MAILBOX || HAVE_ARM_SMCCC_DISCOVERY help ARM System Control and Management Interface (SCMI) protocol is a set of operating system-independent software interfaces that are diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index 88149a46e6d9..10234e031990 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -139,6 +139,9 @@ int scmi_driver_register(struct scmi_driver *driver, struct module *owner, { int retval; + if (!driver->probe) + return -EINVAL; + retval = scmi_request_protocol_device(driver->id_table); if (retval) return retval; diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 9a0519db4865..96436657fff1 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -329,7 +329,7 @@ struct scmi_desc { }; extern const struct scmi_desc scmi_mailbox_desc; -#ifdef CONFIG_HAVE_ARM_SMCCC +#ifdef CONFIG_HAVE_ARM_SMCCC_DISCOVERY extern const struct scmi_desc scmi_smc_desc; #endif diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 02cee8468639..1732fb3e332b 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -49,7 +49,6 @@ enum scmi_error_codes { SCMI_ERR_GENERIC = -8, /* Generic Error */ SCMI_ERR_HARDWARE = -9, /* Hardware Error */ SCMI_ERR_PROTOCOL = -10,/* Protocol Error */ - SCMI_ERR_MAX }; /* List of all SCMI devices active in system */ @@ -168,8 +167,10 @@ static const int scmi_linux_errmap[] = { static inline int scmi_to_linux_errno(int errno) { - if (errno < SCMI_SUCCESS && errno > SCMI_ERR_MAX) - return scmi_linux_errmap[-errno]; + int err_idx = -errno; + + if (err_idx >= SCMI_SUCCESS && err_idx < ARRAY_SIZE(scmi_linux_errmap)) + return scmi_linux_errmap[err_idx]; return -EIO; } @@ -337,6 +338,10 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, return; } + /* rx.len could be shrunk in the sync do_xfer, so reset to maxsz */ + if (msg_type == MSG_TYPE_DELAYED_RESP) + xfer->rx.len = info->desc->max_msg_size; + scmi_dump_header_dbg(dev, &xfer->hdr); info->desc->ops->fetch_response(cinfo, xfer); @@ -516,8 +521,12 @@ static int do_xfer_with_response(const struct scmi_protocol_handle *ph, xfer->async_done = &async_response; ret = do_xfer(ph, xfer); - if (!ret && !wait_for_completion_timeout(xfer->async_done, timeout)) - ret = -ETIMEDOUT; + if (!ret) { + if (!wait_for_completion_timeout(xfer->async_done, timeout)) + ret = -ETIMEDOUT; + else if (xfer->hdr.status) + ret = scmi_to_linux_errno(xfer->hdr.status); + } xfer->async_done = NULL; return ret; @@ -1025,8 +1034,9 @@ static int __scmi_xfer_info_init(struct scmi_info *sinfo, const struct scmi_desc *desc = sinfo->desc; /* Pre-allocated messages, no more than what hdr.seq can support */ - if (WARN_ON(desc->max_msg >= MSG_TOKEN_MAX)) { - dev_err(dev, "Maximum message of %d exceeds supported %ld\n", + if (WARN_ON(!desc->max_msg || desc->max_msg > MSG_TOKEN_MAX)) { + dev_err(dev, + "Invalid maximum messages %d, not in range [1 - %lu]\n", desc->max_msg, MSG_TOKEN_MAX); return -EINVAL; } @@ -1571,7 +1581,9 @@ ATTRIBUTE_GROUPS(versions); /* Each compatible listed below must have descriptor associated with it */ static const struct of_device_id scmi_of_match[] = { +#ifdef CONFIG_MAILBOX { .compatible = "arm,scmi", .data = &scmi_mailbox_desc }, +#endif #ifdef CONFIG_HAVE_ARM_SMCCC_DISCOVERY { .compatible = "arm,scmi-smc", .data = &scmi_smc_desc}, #endif diff --git a/drivers/firmware/broadcom/tee_bnxt_fw.c b/drivers/firmware/broadcom/tee_bnxt_fw.c index ed10da5313e8..a5bf4c3f6dc7 100644 --- a/drivers/firmware/broadcom/tee_bnxt_fw.c +++ b/drivers/firmware/broadcom/tee_bnxt_fw.c @@ -212,10 +212,9 @@ static int tee_bnxt_fw_probe(struct device *dev) pvt_data.dev = dev; - fw_shm_pool = tee_shm_alloc(pvt_data.ctx, MAX_SHM_MEM_SZ, - TEE_SHM_MAPPED | TEE_SHM_DMA_BUF); + fw_shm_pool = tee_shm_alloc_kernel_buf(pvt_data.ctx, MAX_SHM_MEM_SZ); if (IS_ERR(fw_shm_pool)) { - dev_err(pvt_data.dev, "tee_shm_alloc failed\n"); + dev_err(pvt_data.dev, "tee_shm_alloc_kernel_buf failed\n"); err = PTR_ERR(fw_shm_pool); goto out_sess; } @@ -242,6 +241,14 @@ static int tee_bnxt_fw_remove(struct device *dev) return 0; } +static void tee_bnxt_fw_shutdown(struct device *dev) +{ + tee_shm_free(pvt_data.fw_shm_pool); + tee_client_close_session(pvt_data.ctx, pvt_data.session_id); + tee_client_close_context(pvt_data.ctx); + pvt_data.ctx = NULL; +} + static const struct tee_client_device_id tee_bnxt_fw_id_table[] = { {UUID_INIT(0x6272636D, 0x2019, 0x0716, 0x42, 0x43, 0x4D, 0x5F, 0x53, 0x43, 0x48, 0x49)}, @@ -257,6 +264,7 @@ static struct tee_client_driver tee_bnxt_fw_driver = { .bus = &tee_bus_type, .probe = tee_bnxt_fw_probe, .remove = tee_bnxt_fw_remove, + .shutdown = tee_bnxt_fw_shutdown, }, }; diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 4b7ee3fa9224..847f33ffc4ae 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -896,6 +896,7 @@ static int __init efi_memreserve_map_root(void) static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) { struct resource *res, *parent; + int ret; res = kzalloc(sizeof(struct resource), GFP_ATOMIC); if (!res) @@ -908,7 +909,17 @@ static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) /* we expect a conflict with a 'System RAM' region */ parent = request_resource_conflict(&iomem_resource, res); - return parent ? request_resource(parent, res) : 0; + ret = parent ? request_resource(parent, res) : 0; + + /* + * Given that efi_mem_reserve_iomem() can be called at any + * time, only call memblock_reserve() if the architecture + * keeps the infrastructure around. + */ + if (IS_ENABLED(CONFIG_ARCH_KEEP_MEMBLOCK) && !ret) + memblock_reserve(addr, size); + + return ret; } int __ref efi_mem_reserve_persistent(phys_addr_t addr, u64 size) diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index 22ece1ad68a8..c1b57dfb1277 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c @@ -35,15 +35,48 @@ efi_status_t check_platform_features(void) } /* - * Although relocatable kernels can fix up the misalignment with respect to - * MIN_KIMG_ALIGN, the resulting virtual text addresses are subtly out of - * sync with those recorded in the vmlinux when kaslr is disabled but the - * image required relocation anyway. Therefore retain 2M alignment unless - * KASLR is in use. + * Distro versions of GRUB may ignore the BSS allocation entirely (i.e., fail + * to provide space, and fail to zero it). Check for this condition by double + * checking that the first and the last byte of the image are covered by the + * same EFI memory map entry. */ -static u64 min_kimg_align(void) +static bool check_image_region(u64 base, u64 size) { - return efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN; + unsigned long map_size, desc_size, buff_size; + efi_memory_desc_t *memory_map; + struct efi_boot_memmap map; + efi_status_t status; + bool ret = false; + int map_offset; + + map.map = &memory_map; + map.map_size = &map_size; + map.desc_size = &desc_size; + map.desc_ver = NULL; + map.key_ptr = NULL; + map.buff_size = &buff_size; + + status = efi_get_memory_map(&map); + if (status != EFI_SUCCESS) + return false; + + for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { + efi_memory_desc_t *md = (void *)memory_map + map_offset; + u64 end = md->phys_addr + md->num_pages * EFI_PAGE_SIZE; + + /* + * Find the region that covers base, and return whether + * it covers base+size bytes. + */ + if (base >= md->phys_addr && base < end) { + ret = (base + size) <= end; + break; + } + } + + efi_bs_call(free_pool, memory_map); + + return ret; } efi_status_t handle_kernel_image(unsigned long *image_addr, @@ -56,6 +89,16 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, unsigned long kernel_size, kernel_memsize = 0; u32 phys_seed = 0; + /* + * Although relocatable kernels can fix up the misalignment with + * respect to MIN_KIMG_ALIGN, the resulting virtual text addresses are + * subtly out of sync with those recorded in the vmlinux when kaslr is + * disabled but the image required relocation anyway. Therefore retain + * 2M alignment if KASLR was explicitly disabled, even if it was not + * going to be activated to begin with. + */ + u64 min_kimg_align = efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN; + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { if (!efi_nokaslr) { status = efi_get_random_bytes(sizeof(phys_seed), @@ -76,6 +119,10 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, if (image->image_base != _text) efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n"); + if (!IS_ALIGNED((u64)_text, EFI_KIMG_ALIGN)) + efi_err("FIRMWARE BUG: kernel image not aligned on %ldk boundary\n", + EFI_KIMG_ALIGN >> 10); + kernel_size = _edata - _text; kernel_memsize = kernel_size + (_end - _edata); *reserve_size = kernel_memsize; @@ -85,14 +132,16 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, * If KASLR is enabled, and we have some randomness available, * locate the kernel at a randomized offset in physical memory. */ - status = efi_random_alloc(*reserve_size, min_kimg_align(), + status = efi_random_alloc(*reserve_size, min_kimg_align, reserve_addr, phys_seed); } else { status = EFI_OUT_OF_RESOURCES; } if (status != EFI_SUCCESS) { - if (IS_ALIGNED((u64)_text, min_kimg_align())) { + if (!check_image_region((u64)_text, kernel_memsize)) { + efi_err("FIRMWARE BUG: Image BSS overlaps adjacent EFI memory region\n"); + } else if (IS_ALIGNED((u64)_text, min_kimg_align)) { /* * Just execute from wherever we were loaded by the * UEFI PE/COFF loader if the alignment is suitable. @@ -103,7 +152,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, } status = efi_allocate_pages_aligned(*reserve_size, reserve_addr, - ULONG_MAX, min_kimg_align()); + ULONG_MAX, min_kimg_align); if (status != EFI_SUCCESS) { efi_err("Failed to relocate kernel\n"); diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c index a408df474d83..724155b9e10d 100644 --- a/drivers/firmware/efi/libstub/randomalloc.c +++ b/drivers/firmware/efi/libstub/randomalloc.c @@ -30,6 +30,8 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md, region_end = min(md->phys_addr + md->num_pages * EFI_PAGE_SIZE - 1, (u64)ULONG_MAX); + if (region_end < size) + return 0; first_slot = round_up(md->phys_addr, align); last_slot = round_down(region_end - size + 1, align); diff --git a/drivers/firmware/efi/mokvar-table.c b/drivers/firmware/efi/mokvar-table.c index d8bc01340686..38722d2009e2 100644 --- a/drivers/firmware/efi/mokvar-table.c +++ b/drivers/firmware/efi/mokvar-table.c @@ -180,7 +180,10 @@ void __init efi_mokvar_table_init(void) pr_err("EFI MOKvar config table is not valid\n"); return; } - efi_mem_reserve(efi.mokvar_table, map_size_needed); + + if (md.type == EFI_BOOT_SERVICES_DATA) + efi_mem_reserve(efi.mokvar_table, map_size_needed); + efi_mokvar_table_size = map_size_needed; } diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c index c1955d320fec..8f665678e9e3 100644 --- a/drivers/firmware/efi/tpm.c +++ b/drivers/firmware/efi/tpm.c @@ -62,9 +62,11 @@ int __init efi_tpm_eventlog_init(void) tbl_size = sizeof(*log_tbl) + log_tbl->size; memblock_reserve(efi.tpm_log, tbl_size); - if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR || - log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { - pr_warn(FW_BUG "TPM Final Events table missing or invalid\n"); + if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR) { + pr_info("TPM Final Events table not present\n"); + goto out; + } else if (log_tbl->version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) { + pr_warn(FW_BUG "TPM Final Events table invalid\n"); goto out; } diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c index fd68c3341d85..47feb83c7249 100644 --- a/drivers/firmware/psci/psci.c +++ b/drivers/firmware/psci/psci.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -506,6 +507,7 @@ static int __init psci_probe(void) psci_init_cpu_suspend(); psci_init_system_suspend(); psci_init_system_reset2(); + kvm_init_hyp_services(); } return 0; diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 0078260fbabe..172c751a4f6c 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -299,15 +299,13 @@ static int fw_cfg_do_platform_probe(struct platform_device *pdev) return 0; } -static ssize_t fw_cfg_showrev(struct kobject *k, struct attribute *a, char *buf) +static ssize_t fw_cfg_showrev(struct kobject *k, struct kobj_attribute *a, + char *buf) { return sprintf(buf, "%u\n", fw_cfg_rev); } -static const struct { - struct attribute attr; - ssize_t (*show)(struct kobject *k, struct attribute *a, char *buf); -} fw_cfg_rev_attr = { +static const struct kobj_attribute fw_cfg_rev_attr = { .attr = { .name = "rev", .mode = S_IRUSR }, .show = fw_cfg_showrev, }; diff --git a/drivers/firmware/smccc/Makefile b/drivers/firmware/smccc/Makefile index 72ab84042832..40d19144a860 100644 --- a/drivers/firmware/smccc/Makefile +++ b/drivers/firmware/smccc/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 # -obj-$(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) += smccc.o +obj-$(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) += smccc.o kvm_guest.o obj-$(CONFIG_ARM_SMCCC_SOC_ID) += soc_id.o diff --git a/drivers/firmware/smccc/kvm_guest.c b/drivers/firmware/smccc/kvm_guest.c new file mode 100644 index 000000000000..2d3e866decaa --- /dev/null +++ b/drivers/firmware/smccc/kvm_guest.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define pr_fmt(fmt) "smccc: KVM: " fmt + +#include +#include +#include +#include + +#include + +static DECLARE_BITMAP(__kvm_arm_hyp_services, ARM_SMCCC_KVM_NUM_FUNCS) __ro_after_init = { }; + +void __init kvm_init_hyp_services(void) +{ + struct arm_smccc_res res; + u32 val[4]; + + if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_HVC) + return; + + arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res); + if (res.a0 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0 || + res.a1 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1 || + res.a2 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2 || + res.a3 != ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3) + return; + + memset(&res, 0, sizeof(res)); + arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID, &res); + + val[0] = lower_32_bits(res.a0); + val[1] = lower_32_bits(res.a1); + val[2] = lower_32_bits(res.a2); + val[3] = lower_32_bits(res.a3); + + bitmap_from_arr32(__kvm_arm_hyp_services, val, ARM_SMCCC_KVM_NUM_FUNCS); + + pr_info("hypervisor services detected (0x%08lx 0x%08lx 0x%08lx 0x%08lx)\n", + res.a3, res.a2, res.a1, res.a0); +} + +bool kvm_arm_hyp_service_available(u32 func_id) +{ + if (func_id >= ARM_SMCCC_KVM_NUM_FUNCS) + return false; + + return test_bit(func_id, __kvm_arm_hyp_services); +} +EXPORT_SYMBOL_GPL(kvm_arm_hyp_service_available); diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c index 00c88b809c0c..028f81d702cc 100644 --- a/drivers/firmware/smccc/smccc.c +++ b/drivers/firmware/smccc/smccc.c @@ -5,16 +5,23 @@ #define pr_fmt(fmt) "smccc: " fmt +#include #include #include +#include +#include static u32 smccc_version = ARM_SMCCC_VERSION_1_0; static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE; +bool __ro_after_init smccc_trng_available = false; + void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit) { smccc_version = version; smccc_conduit = conduit; + + smccc_trng_available = smccc_probe_trng(); } enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void) diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c index 3aa489dba30a..2a7687911c09 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -1034,24 +1034,32 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) /* add svc client device(s) */ svc = devm_kzalloc(dev, sizeof(*svc), GFP_KERNEL); - if (!svc) - return -ENOMEM; + if (!svc) { + ret = -ENOMEM; + goto err_free_kfifo; + } svc->stratix10_svc_rsu = platform_device_alloc(STRATIX10_RSU, 0); if (!svc->stratix10_svc_rsu) { dev_err(dev, "failed to allocate %s device\n", STRATIX10_RSU); - return -ENOMEM; + ret = -ENOMEM; + goto err_free_kfifo; } ret = platform_device_add(svc->stratix10_svc_rsu); - if (ret) { - platform_device_put(svc->stratix10_svc_rsu); - return ret; - } + if (ret) + goto err_put_device; + dev_set_drvdata(dev, svc); pr_info("Intel Service Layer Driver Initialized\n"); + return 0; + +err_put_device: + platform_device_put(svc->stratix10_svc_rsu); +err_free_kfifo: + kfifo_free(&controller->svc_fifo); return ret; } diff --git a/drivers/firmware/tegra/Makefile b/drivers/firmware/tegra/Makefile index 49c87e00fafb..620cf3fdd607 100644 --- a/drivers/firmware/tegra/Makefile +++ b/drivers/firmware/tegra/Makefile @@ -3,6 +3,7 @@ tegra-bpmp-y = bpmp.o tegra-bpmp-$(CONFIG_ARCH_TEGRA_210_SOC) += bpmp-tegra210.o tegra-bpmp-$(CONFIG_ARCH_TEGRA_186_SOC) += bpmp-tegra186.o tegra-bpmp-$(CONFIG_ARCH_TEGRA_194_SOC) += bpmp-tegra186.o +tegra-bpmp-$(CONFIG_ARCH_TEGRA_234_SOC) += bpmp-tegra186.o tegra-bpmp-$(CONFIG_DEBUG_FS) += bpmp-debugfs.o obj-$(CONFIG_TEGRA_BPMP) += tegra-bpmp.o obj-$(CONFIG_TEGRA_IVC) += ivc.o diff --git a/drivers/firmware/tegra/bpmp-private.h b/drivers/firmware/tegra/bpmp-private.h index 54d560c48398..182bfe396516 100644 --- a/drivers/firmware/tegra/bpmp-private.h +++ b/drivers/firmware/tegra/bpmp-private.h @@ -24,7 +24,8 @@ struct tegra_bpmp_ops { }; #if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \ - IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) + IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \ + IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) extern const struct tegra_bpmp_ops tegra186_bpmp_ops; #endif #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) diff --git a/drivers/firmware/tegra/bpmp-tegra210.c b/drivers/firmware/tegra/bpmp-tegra210.c index ae15940a078e..c32754055c60 100644 --- a/drivers/firmware/tegra/bpmp-tegra210.c +++ b/drivers/firmware/tegra/bpmp-tegra210.c @@ -210,7 +210,7 @@ static int tegra210_bpmp_init(struct tegra_bpmp *bpmp) priv->tx_irq_data = irq_get_irq_data(err); if (!priv->tx_irq_data) { dev_err(&pdev->dev, "failed to get IRQ data for TX IRQ\n"); - return err; + return -ENOENT; } err = platform_get_irq_byname(pdev, "rx"); diff --git a/drivers/firmware/tegra/bpmp.c b/drivers/firmware/tegra/bpmp.c index 0742a90cb844..5654c5e9862b 100644 --- a/drivers/firmware/tegra/bpmp.c +++ b/drivers/firmware/tegra/bpmp.c @@ -809,7 +809,8 @@ static const struct dev_pm_ops tegra_bpmp_pm_ops = { }; #if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC) || \ - IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) + IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \ + IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) static const struct tegra_bpmp_soc tegra186_soc = { .channels = { .cpu_tx = { diff --git a/drivers/firmware/turris-mox-rwtm.c b/drivers/firmware/turris-mox-rwtm.c index 50bb2a6d6ccf..0bef988580ad 100644 --- a/drivers/firmware/turris-mox-rwtm.c +++ b/drivers/firmware/turris-mox-rwtm.c @@ -147,11 +147,14 @@ MOX_ATTR_RO(pubkey, "%s\n", pubkey); static int mox_get_status(enum mbox_cmd cmd, u32 retval) { - if (MBOX_STS_CMD(retval) != cmd || - MBOX_STS_ERROR(retval) != MBOX_STS_SUCCESS) + if (MBOX_STS_CMD(retval) != cmd) return -EIO; else if (MBOX_STS_ERROR(retval) == MBOX_STS_FAIL) return -(int)MBOX_STS_VALUE(retval); + else if (MBOX_STS_ERROR(retval) == MBOX_STS_BADCMD) + return -ENOSYS; + else if (MBOX_STS_ERROR(retval) != MBOX_STS_SUCCESS) + return -EIO; else return MBOX_STS_VALUE(retval); } @@ -201,11 +204,14 @@ static int mox_get_board_info(struct mox_rwtm *rwtm) return ret; ret = mox_get_status(MBOX_CMD_BOARD_INFO, reply->retval); - if (ret < 0 && ret != -ENODATA) { - return ret; - } else if (ret == -ENODATA) { + if (ret == -ENODATA) { dev_warn(rwtm->dev, "Board does not have manufacturing information burned!\n"); + } else if (ret == -ENOSYS) { + dev_notice(rwtm->dev, + "Firmware does not support the BOARD_INFO command\n"); + } else if (ret < 0) { + return ret; } else { rwtm->serial_number = reply->status[1]; rwtm->serial_number <<= 32; @@ -234,10 +240,13 @@ static int mox_get_board_info(struct mox_rwtm *rwtm) return ret; ret = mox_get_status(MBOX_CMD_ECDSA_PUB_KEY, reply->retval); - if (ret < 0 && ret != -ENODATA) { - return ret; - } else if (ret == -ENODATA) { + if (ret == -ENODATA) { dev_warn(rwtm->dev, "Board has no public key burned!\n"); + } else if (ret == -ENOSYS) { + dev_notice(rwtm->dev, + "Firmware does not support the ECDSA_PUB_KEY command\n"); + } else if (ret < 0) { + return ret; } else { u32 *s = reply->status; @@ -251,6 +260,27 @@ static int mox_get_board_info(struct mox_rwtm *rwtm) return 0; } +static int check_get_random_support(struct mox_rwtm *rwtm) +{ + struct armada_37xx_rwtm_tx_msg msg; + int ret; + + msg.command = MBOX_CMD_GET_RANDOM; + msg.args[0] = 1; + msg.args[1] = rwtm->buf_phys; + msg.args[2] = 4; + + ret = mbox_send_message(rwtm->mbox, &msg); + if (ret < 0) + return ret; + + ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2); + if (ret < 0) + return ret; + + return mox_get_status(MBOX_CMD_GET_RANDOM, rwtm->reply.retval); +} + static int mox_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait) { struct mox_rwtm *rwtm = (struct mox_rwtm *) rng->priv; @@ -488,6 +518,13 @@ static int turris_mox_rwtm_probe(struct platform_device *pdev) if (ret < 0) dev_warn(dev, "Cannot read board information: %i\n", ret); + ret = check_get_random_support(rwtm); + if (ret < 0) { + dev_notice(dev, + "Firmware does not support the GET_RANDOM command\n"); + goto free_channel; + } + rwtm->hwrng.name = DRIVER_NAME "_hwrng"; rwtm->hwrng.read = mox_hwrng_read; rwtm->hwrng.priv = (unsigned long) rwtm; @@ -505,6 +542,8 @@ static int turris_mox_rwtm_probe(struct platform_device *pdev) goto free_channel; } + dev_info(dev, "HWRNG successfully registered\n"); + return 0; free_channel: @@ -530,6 +569,7 @@ static int turris_mox_rwtm_remove(struct platform_device *pdev) static const struct of_device_id turris_mox_rwtm_match[] = { { .compatible = "cznic,turris-mox-rwtm", }, + { .compatible = "marvell,armada-3700-rwtm-firmware", }, { }, }; diff --git a/drivers/fpga/dfl-fme-perf.c b/drivers/fpga/dfl-fme-perf.c index 531266287eee..329b03244fd2 100644 --- a/drivers/fpga/dfl-fme-perf.c +++ b/drivers/fpga/dfl-fme-perf.c @@ -953,6 +953,8 @@ static int fme_perf_offline_cpu(unsigned int cpu, struct hlist_node *node) return 0; priv->cpu = target; + perf_pmu_migrate_context(&priv->pmu, cpu, target); + return 0; } diff --git a/drivers/fpga/stratix10-soc.c b/drivers/fpga/stratix10-soc.c index 657a70c5fc99..9e34bbbce26e 100644 --- a/drivers/fpga/stratix10-soc.c +++ b/drivers/fpga/stratix10-soc.c @@ -454,6 +454,7 @@ static int s10_remove(struct platform_device *pdev) struct s10_priv *priv = mgr->priv; fpga_mgr_unregister(mgr); + fpga_mgr_free(mgr); stratix10_svc_free_channel(priv->chan); return 0; diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 4e60e84cd17a..59ddc9fd5bca 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -724,7 +724,7 @@ static ssize_t cfam_read(struct file *filep, char __user *buf, size_t count, rc = count; fail: *offset = off; - return count; + return rc; } static ssize_t cfam_write(struct file *filep, const char __user *buf, @@ -761,7 +761,7 @@ static ssize_t cfam_write(struct file *filep, const char __user *buf, rc = count; fail: *offset = off; - return count; + return rc; } static loff_t cfam_llseek(struct file *file, loff_t offset, int whence) diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c index 90dbe58ca1ed..dbad73162c83 100644 --- a/drivers/fsi/fsi-master-aspeed.c +++ b/drivers/fsi/fsi-master-aspeed.c @@ -645,6 +645,7 @@ static const struct of_device_id fsi_master_aspeed_match[] = { { .compatible = "aspeed,ast2600-fsi-master" }, { }, }; +MODULE_DEVICE_TABLE(of, fsi_master_aspeed_match); static struct platform_driver fsi_master_aspeed_driver = { .driver = { diff --git a/drivers/fsi/fsi-master-ast-cf.c b/drivers/fsi/fsi-master-ast-cf.c index 57a779a89b07..70c03e304d6c 100644 --- a/drivers/fsi/fsi-master-ast-cf.c +++ b/drivers/fsi/fsi-master-ast-cf.c @@ -1427,6 +1427,7 @@ static const struct of_device_id fsi_master_acf_match[] = { { .compatible = "aspeed,ast2500-cf-fsi-master" }, { }, }; +MODULE_DEVICE_TABLE(of, fsi_master_acf_match); static struct platform_driver fsi_master_acf = { .driver = { diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index aa97c4a250cb..7d5f29b4b595 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -882,6 +882,7 @@ static const struct of_device_id fsi_master_gpio_match[] = { { .compatible = "fsi-master-gpio" }, { }, }; +MODULE_DEVICE_TABLE(of, fsi_master_gpio_match); static struct platform_driver fsi_master_gpio_driver = { .driver = { diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c index 9eeb856c8905..a9beef2ae5a0 100644 --- a/drivers/fsi/fsi-occ.c +++ b/drivers/fsi/fsi-occ.c @@ -445,6 +445,7 @@ int fsi_occ_submit(struct device *dev, const void *request, size_t req_len, goto done; if (resp->return_status == OCC_RESP_CMD_IN_PRG || + resp->return_status == OCC_RESP_CRIT_INIT || resp->seq_no != seq_no) { rc = -ETIMEDOUT; @@ -578,6 +579,7 @@ static const struct of_device_id occ_match[] = { { .compatible = "ibm,p9-occ" }, { }, }; +MODULE_DEVICE_TABLE(of, occ_match); static struct platform_driver occ_driver = { .driver = { diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c index bfd5e5da8020..84cb965bfed5 100644 --- a/drivers/fsi/fsi-sbefifo.c +++ b/drivers/fsi/fsi-sbefifo.c @@ -325,7 +325,8 @@ static int sbefifo_up_write(struct sbefifo *sbefifo, __be32 word) static int sbefifo_request_reset(struct sbefifo *sbefifo) { struct device *dev = &sbefifo->fsi_dev->dev; - u32 status, timeout; + unsigned long end_time; + u32 status; int rc; dev_dbg(dev, "Requesting FIFO reset\n"); @@ -341,7 +342,8 @@ static int sbefifo_request_reset(struct sbefifo *sbefifo) } /* Wait for it to complete */ - for (timeout = 0; timeout < SBEFIFO_RESET_TIMEOUT; timeout++) { + end_time = jiffies + msecs_to_jiffies(SBEFIFO_RESET_TIMEOUT); + while (!time_after(jiffies, end_time)) { rc = sbefifo_regr(sbefifo, SBEFIFO_UP | SBEFIFO_STS, &status); if (rc) { dev_err(dev, "Failed to read UP fifo status during reset" @@ -355,7 +357,7 @@ static int sbefifo_request_reset(struct sbefifo *sbefifo) return 0; } - msleep(1); + cond_resched(); } dev_err(dev, "FIFO reset timed out\n"); @@ -400,7 +402,7 @@ static int sbefifo_cleanup_hw(struct sbefifo *sbefifo) /* The FIFO already contains a reset request from the SBE ? */ if (down_status & SBEFIFO_STS_RESET_REQ) { dev_info(dev, "Cleanup: FIFO reset request set, resetting\n"); - rc = sbefifo_regw(sbefifo, SBEFIFO_UP, SBEFIFO_PERFORM_RESET); + rc = sbefifo_regw(sbefifo, SBEFIFO_DOWN, SBEFIFO_PERFORM_RESET); if (rc) { sbefifo->broken = true; dev_err(dev, "Cleanup: Reset reg write failed, rc=%d\n", rc); diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index b45bfab7b7f5..75d1389e2626 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -38,9 +38,10 @@ #define SCOM_STATUS_PIB_RESP_MASK 0x00007000 #define SCOM_STATUS_PIB_RESP_SHIFT 12 -#define SCOM_STATUS_ANY_ERR (SCOM_STATUS_PROTECTION | \ - SCOM_STATUS_PARITY | \ - SCOM_STATUS_PIB_ABORT | \ +#define SCOM_STATUS_FSI2PIB_ERROR (SCOM_STATUS_PROTECTION | \ + SCOM_STATUS_PARITY | \ + SCOM_STATUS_PIB_ABORT) +#define SCOM_STATUS_ANY_ERR (SCOM_STATUS_FSI2PIB_ERROR | \ SCOM_STATUS_PIB_RESP_MASK) /* SCOM address encodings */ #define XSCOM_ADDR_IND_FLAG BIT_ULL(63) @@ -240,13 +241,14 @@ static int handle_fsi2pib_status(struct scom_device *scom, uint32_t status) { uint32_t dummy = -1; - if (status & SCOM_STATUS_PROTECTION) - return -EPERM; - if (status & SCOM_STATUS_PARITY) { + if (status & SCOM_STATUS_FSI2PIB_ERROR) fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy, sizeof(uint32_t)); + + if (status & SCOM_STATUS_PROTECTION) + return -EPERM; + if (status & SCOM_STATUS_PARITY) return -EIO; - } /* Return -EBUSY on PIB abort to force a retry */ if (status & SCOM_STATUS_PIB_ABORT) return -EBUSY; diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 14751c7ccd1f..d1300fc003ed 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1337,6 +1337,7 @@ config GPIO_TPS68470 config GPIO_TQMX86 tristate "TQ-Systems QTMX86 GPIO" depends on MFD_TQMX86 || COMPILE_TEST + depends on HAS_IOPORT_MAP select GPIOLIB_IRQCHIP help This driver supports GPIO on the TQMX86 IO controller. @@ -1404,6 +1405,7 @@ menu "PCI GPIO expanders" config GPIO_AMD8111 tristate "AMD 8111 GPIO driver" depends on X86 || COMPILE_TEST + depends on HAS_IOPORT_MAP help The AMD 8111 south bridge contains 32 GPIO pins which can be used. diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c index 6dfca83bcd90..3c2fa44d9279 100644 --- a/drivers/gpio/gpio-mpc8xxx.c +++ b/drivers/gpio/gpio-mpc8xxx.c @@ -396,7 +396,7 @@ static int mpc8xxx_probe(struct platform_device *pdev) ret = devm_request_irq(&pdev->dev, mpc8xxx_gc->irqn, mpc8xxx_gpio_irq_cascade, - IRQF_SHARED, "gpio-cascade", + IRQF_NO_THREAD | IRQF_SHARED, "gpio-cascade", mpc8xxx_gc); if (ret) { dev_err(&pdev->dev, "%s: failed to devm_request_irq(%d), ret = %d\n", diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 643f4c557ac2..ba6ed2a413f5 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -361,7 +361,7 @@ static int mxc_gpio_init_gc(struct mxc_gpio_port *port, int irq_base) ct->chip.irq_unmask = irq_gc_mask_set_bit; ct->chip.irq_set_type = gpio_set_irq_type; ct->chip.irq_set_wake = gpio_set_wake_irq; - ct->chip.flags = IRQCHIP_MASK_ON_SUSPEND; + ct->chip.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_ENABLE_WAKEUP_ON_SUSPEND; ct->regs.ack = GPIO_ISR; ct->regs.mask = GPIO_IMR; diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 6898c27f71f8..7cc7d137133a 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -1239,6 +1239,7 @@ static const struct of_device_id pca953x_dt_ids[] = { { .compatible = "onnn,cat9554", .data = OF_953X( 8, PCA_INT), }, { .compatible = "onnn,pca9654", .data = OF_953X( 8, PCA_INT), }, + { .compatible = "onnn,pca9655", .data = OF_953X(16, PCA_INT), }, { .compatible = "exar,xra1202", .data = OF_953X( 8, 0), }, { } diff --git a/drivers/gpio/gpio-tqmx86.c b/drivers/gpio/gpio-tqmx86.c index 5022e0ad0fae..0f5d17f343f1 100644 --- a/drivers/gpio/gpio-tqmx86.c +++ b/drivers/gpio/gpio-tqmx86.c @@ -238,8 +238,8 @@ static int tqmx86_gpio_probe(struct platform_device *pdev) struct resource *res; int ret, irq; - irq = platform_get_irq(pdev, 0); - if (irq < 0) + irq = platform_get_irq_optional(pdev, 0); + if (irq < 0 && irq != -ENXIO) return irq; res = platform_get_resource(pdev, IORESOURCE_IO, 0); @@ -278,7 +278,7 @@ static int tqmx86_gpio_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); - if (irq) { + if (irq > 0) { struct irq_chip *irq_chip = &gpio->irq_chip; u8 irq_status; diff --git a/drivers/gpio/gpio-wcd934x.c b/drivers/gpio/gpio-wcd934x.c index 1cbce5990855..97e6caedf1f3 100644 --- a/drivers/gpio/gpio-wcd934x.c +++ b/drivers/gpio/gpio-wcd934x.c @@ -7,7 +7,7 @@ #include #include -#define WCD_PIN_MASK(p) BIT(p - 1) +#define WCD_PIN_MASK(p) BIT(p) #define WCD_REG_DIR_CTL_OFFSET 0x42 #define WCD_REG_VAL_CTL_OFFSET 0x43 #define WCD934X_NPINS 5 diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index 3521c1dc3ac0..c288a7502de2 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -736,6 +736,11 @@ static int __maybe_unused zynq_gpio_suspend(struct device *dev) struct zynq_gpio *gpio = dev_get_drvdata(dev); struct irq_data *data = irq_get_irq_data(gpio->irq); + if (!data) { + dev_err(dev, "irq_get_irq_data() failed\n"); + return -EINVAL; + } + if (!device_may_wakeup(dev)) disable_irq(gpio->irq); @@ -753,6 +758,11 @@ static int __maybe_unused zynq_gpio_resume(struct device *dev) struct irq_data *data = irq_get_irq_data(gpio->irq); int ret; + if (!data) { + dev_err(dev, "irq_get_irq_data() failed\n"); + return -EINVAL; + } + if (!device_may_wakeup(dev)) enable_irq(gpio->irq); @@ -1001,8 +1011,11 @@ static int zynq_gpio_probe(struct platform_device *pdev) static int zynq_gpio_remove(struct platform_device *pdev) { struct zynq_gpio *gpio = platform_get_drvdata(pdev); + int ret; - pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_get_sync(&pdev->dev); + if (ret < 0) + dev_warn(&pdev->dev, "pm_runtime_get_sync() Failed\n"); gpiochip_remove(&gpio->chip); clk_disable_unprepare(gpio->clk); device_set_wakeup_capable(&pdev->dev, 0); diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index ade3ecf2ee49..2613881a66e6 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -1865,6 +1865,7 @@ static void gpio_v2_line_info_changed_to_v1( struct gpio_v2_line_info_changed *lic_v2, struct gpioline_info_changed *lic_v1) { + memset(lic_v1, 0, sizeof(*lic_v1)); gpio_v2_line_info_to_v1(&lic_v2->info, &lic_v1->info); lic_v1->timestamp = lic_v2->timestamp_ns; lic_v1->event_type = lic_v2->event_type; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 5da487b64a66..26f8a2138377 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -48,12 +48,6 @@ static struct { spinlock_t mem_limit_lock; } kfd_mem_limit; -/* Struct used for amdgpu_amdkfd_bo_validate */ -struct amdgpu_vm_parser { - uint32_t domain; - bool wait; -}; - static const char * const domain_bit_to_string[] = { "CPU", "GTT", @@ -337,11 +331,9 @@ static int amdgpu_amdkfd_bo_validate(struct amdgpu_bo *bo, uint32_t domain, return ret; } -static int amdgpu_amdkfd_validate(void *param, struct amdgpu_bo *bo) +static int amdgpu_amdkfd_validate_vm_bo(void *_unused, struct amdgpu_bo *bo) { - struct amdgpu_vm_parser *p = param; - - return amdgpu_amdkfd_bo_validate(bo, p->domain, p->wait); + return amdgpu_amdkfd_bo_validate(bo, bo->allowed_domains, false); } /* vm_validate_pt_pd_bos - Validate page table and directory BOs @@ -355,20 +347,15 @@ static int vm_validate_pt_pd_bos(struct amdgpu_vm *vm) { struct amdgpu_bo *pd = vm->root.base.bo; struct amdgpu_device *adev = amdgpu_ttm_adev(pd->tbo.bdev); - struct amdgpu_vm_parser param; int ret; - param.domain = AMDGPU_GEM_DOMAIN_VRAM; - param.wait = false; - - ret = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_amdkfd_validate, - ¶m); + ret = amdgpu_vm_validate_pt_bos(adev, vm, amdgpu_amdkfd_validate_vm_bo, NULL); if (ret) { pr_err("failed to validate PT BOs\n"); return ret; } - ret = amdgpu_amdkfd_validate(¶m, pd); + ret = amdgpu_amdkfd_validate_vm_bo(NULL, pd); if (ret) { pr_err("failed to validate PD\n"); return ret; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 87c7c45f1bb7..97723f2b5ece 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2619,12 +2619,11 @@ static void amdgpu_device_delay_enable_gfx_off(struct work_struct *work) struct amdgpu_device *adev = container_of(work, struct amdgpu_device, gfx.gfx_off_delay_work.work); - mutex_lock(&adev->gfx.gfx_off_mutex); - if (!adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) { - if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true)) - adev->gfx.gfx_off_state = true; - } - mutex_unlock(&adev->gfx.gfx_off_mutex); + WARN_ON_ONCE(adev->gfx.gfx_off_state); + WARN_ON_ONCE(adev->gfx.gfx_off_req_count); + + if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true)) + adev->gfx.gfx_off_state = true; } /** @@ -2760,7 +2759,7 @@ static int amdgpu_device_ip_reinit_early_sriov(struct amdgpu_device *adev) AMD_IP_BLOCK_TYPE_IH, }; - for (i = 0; i < ARRAY_SIZE(ip_order); i++) { + for (i = 0; i < adev->num_ip_blocks; i++) { int j; struct amdgpu_ip_block *block; @@ -3322,13 +3321,13 @@ int amdgpu_device_init(struct amdgpu_device *adev, r = amdgpu_device_get_job_timeout_settings(adev); if (r) { dev_err(adev->dev, "invalid lockup_timeout parameter syntax\n"); - goto failed_unmap; + return r; } /* early init functions */ r = amdgpu_device_ip_early_init(adev); if (r) - goto failed_unmap; + return r; /* doorbell bar mapping and doorbell index init*/ amdgpu_device_doorbell_init(adev); @@ -3532,10 +3531,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, if (boco) vga_switcheroo_fini_domain_pm_ops(adev->dev); -failed_unmap: - iounmap(adev->rmmio); - adev->rmmio = NULL; - return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index 1b56dbc1f304..e93ccdc5faf4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -238,9 +238,21 @@ static int amdgpu_dma_buf_pin(struct dma_buf_attachment *attach) { struct drm_gem_object *obj = attach->dmabuf->priv; struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj); + int r; /* pin buffer into GTT */ - return amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); + r = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT); + if (r) + return r; + + if (bo->tbo.moving) { + r = dma_fence_wait(bo->tbo.moving, true); + if (r) { + amdgpu_bo_unpin(bo); + return r; + } + } + return 0; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index a2425f7ca759..ed13a2f76884 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -1344,6 +1344,8 @@ static int amdgpu_pmops_runtime_suspend(struct device *dev) pci_set_power_state(pdev, PCI_D3cold); } drm_dev->switch_power_state = DRM_SWITCH_POWER_DYNAMIC_OFF; + } else if (amdgpu_device_supports_boco(drm_dev)) { + /* nothing to do */ } else if (amdgpu_device_supports_baco(drm_dev)) { amdgpu_device_baco_enter(drm_dev); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c index 8f4a8f8d8146..39b6c6bfab45 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c @@ -101,7 +101,8 @@ static int amdgpu_fru_read_eeprom(struct amdgpu_device *adev, uint32_t addrptr, int amdgpu_fru_get_product_info(struct amdgpu_device *adev) { unsigned char buff[34]; - int addrptr = 0, size = 0; + int addrptr, size; + int len; if (!is_fru_eeprom_supported(adev)) return 0; @@ -109,7 +110,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) /* If algo exists, it means that the i2c_adapter's initialized */ if (!adev->pm.smu_i2c.algo) { DRM_WARN("Cannot access FRU, EEPROM accessor not initialized"); - return 0; + return -ENODEV; } /* There's a lot of repetition here. This is due to the FRU having @@ -128,7 +129,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) size = amdgpu_fru_read_eeprom(adev, addrptr, buff); if (size < 1) { DRM_ERROR("Failed to read FRU Manufacturer, ret:%d", size); - return size; + return -EINVAL; } /* Increment the addrptr by the size of the field, and 1 due to the @@ -138,43 +139,45 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) size = amdgpu_fru_read_eeprom(adev, addrptr, buff); if (size < 1) { DRM_ERROR("Failed to read FRU product name, ret:%d", size); - return size; + return -EINVAL; } + len = size; /* Product name should only be 32 characters. Any more, * and something could be wrong. Cap it at 32 to be safe */ - if (size > 32) { + if (len >= sizeof(adev->product_name)) { DRM_WARN("FRU Product Number is larger than 32 characters. This is likely a mistake"); - size = 32; + len = sizeof(adev->product_name) - 1; } /* Start at 2 due to buff using fields 0 and 1 for the address */ - memcpy(adev->product_name, &buff[2], size); - adev->product_name[size] = '\0'; + memcpy(adev->product_name, &buff[2], len); + adev->product_name[len] = '\0'; addrptr += size + 1; size = amdgpu_fru_read_eeprom(adev, addrptr, buff); if (size < 1) { DRM_ERROR("Failed to read FRU product number, ret:%d", size); - return size; + return -EINVAL; } + len = size; /* Product number should only be 16 characters. Any more, * and something could be wrong. Cap it at 16 to be safe */ - if (size > 16) { + if (len >= sizeof(adev->product_number)) { DRM_WARN("FRU Product Number is larger than 16 characters. This is likely a mistake"); - size = 16; + len = sizeof(adev->product_number) - 1; } - memcpy(adev->product_number, &buff[2], size); - adev->product_number[size] = '\0'; + memcpy(adev->product_number, &buff[2], len); + adev->product_number[len] = '\0'; addrptr += size + 1; size = amdgpu_fru_read_eeprom(adev, addrptr, buff); if (size < 1) { DRM_ERROR("Failed to read FRU product version, ret:%d", size); - return size; + return -EINVAL; } addrptr += size + 1; @@ -182,18 +185,19 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) if (size < 1) { DRM_ERROR("Failed to read FRU serial number, ret:%d", size); - return size; + return -EINVAL; } + len = size; /* Serial number should only be 16 characters. Any more, * and something could be wrong. Cap it at 16 to be safe */ - if (size > 16) { + if (len >= sizeof(adev->serial)) { DRM_WARN("FRU Serial Number is larger than 16 characters. This is likely a mistake"); - size = 16; + len = sizeof(adev->serial) - 1; } - memcpy(adev->serial, &buff[2], size); - adev->serial[size] = '\0'; + memcpy(adev->serial, &buff[2], len); + adev->serial[len] = '\0'; return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index c485ec86804e..9f9f55a2b257 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -556,24 +556,38 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) mutex_lock(&adev->gfx.gfx_off_mutex); - if (!enable) - adev->gfx.gfx_off_req_count++; - else if (adev->gfx.gfx_off_req_count > 0) + if (enable) { + /* If the count is already 0, it means there's an imbalance bug somewhere. + * Note that the bug may be in a different caller than the one which triggers the + * WARN_ON_ONCE. + */ + if (WARN_ON_ONCE(adev->gfx.gfx_off_req_count == 0)) + goto unlock; + adev->gfx.gfx_off_req_count--; - if (enable && !adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) { - schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE); - } else if (!enable && adev->gfx.gfx_off_state) { - if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false)) { - adev->gfx.gfx_off_state = false; + if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state) + schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE); + } else { + if (adev->gfx.gfx_off_req_count == 0) { + cancel_delayed_work_sync(&adev->gfx.gfx_off_delay_work); + + if (adev->gfx.gfx_off_state && + !amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false)) { + adev->gfx.gfx_off_state = false; - if (adev->gfx.funcs->init_spm_golden) { - dev_dbg(adev->dev, "GFXOFF is disabled, re-init SPM golden settings\n"); - amdgpu_gfx_init_spm_golden(adev); + if (adev->gfx.funcs->init_spm_golden) { + dev_dbg(adev->dev, + "GFXOFF is disabled, re-init SPM golden settings\n"); + amdgpu_gfx_init_spm_golden(adev); + } } } + + adev->gfx.gfx_off_req_count++; } +unlock: mutex_unlock(&adev->gfx.gfx_off_mutex); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 28f20f0b722f..163188ce02bd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -128,7 +128,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, struct amdgpu_device *adev = ring->adev; struct amdgpu_ib *ib = &ibs[0]; struct dma_fence *tmp = NULL; - bool skip_preamble, need_ctx_switch; + bool need_ctx_switch; unsigned patch_offset = ~0; struct amdgpu_vm *vm; uint64_t fence_ctx; @@ -221,7 +221,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, if (need_ctx_switch) status |= AMDGPU_HAVE_CTX_SWITCH; - skip_preamble = ring->current_ctx == fence_ctx; if (job && ring->funcs->emit_cntxcntl) { status |= job->preamble_status; status |= job->preemption_status; @@ -239,14 +238,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, for (i = 0; i < num_ibs; ++i) { ib = &ibs[i]; - /* drop preamble IBs if we don't have a context switch */ - if ((ib->flags & AMDGPU_IB_FLAG_PREAMBLE) && - skip_preamble && - !(status & AMDGPU_PREAMBLE_IB_PRESENT_FIRST) && - !amdgpu_mcbp && - !amdgpu_sriov_vf(adev)) /* for SRIOV preemption, Preamble CE ib must be inserted anyway */ - continue; - if (job && ring->funcs->emit_frame_cntl) { if (secure != !!(ib->flags & AMDGPU_IB_FLAGS_SECURE)) { amdgpu_ring_emit_frame_cntl(ring, false, secure); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h index 919d2fb7427b..60b7563f4c05 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h @@ -73,6 +73,7 @@ struct psp_ring uint64_t ring_mem_mc_addr; void *ring_mem_handle; uint32_t ring_size; + uint32_t ring_wptr; }; /* More registers may will be supported */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 5207ad654f18..46292a1a6071 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1357,7 +1357,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_bo_device *bdev, } #ifdef CONFIG_SWIOTLB - if (adev->need_swiotlb && swiotlb_nr_tbl()) { + if (adev->need_swiotlb && is_swiotlb_active(adev->dev)) { return ttm_dma_populate(>t->ttm, adev->dev, ctx); } #endif @@ -1401,7 +1401,7 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_bo_device *bdev, struct ttm_tt * adev = amdgpu_ttm_adev(bdev); #ifdef CONFIG_SWIOTLB - if (adev->need_swiotlb && swiotlb_nr_tbl()) { + if (adev->need_swiotlb && is_swiotlb_active(adev->dev)) { ttm_dma_unpopulate(>t->ttm, adev->dev); return; } @@ -2589,7 +2589,7 @@ int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev) count = ARRAY_SIZE(amdgpu_ttm_debugfs_list); #ifdef CONFIG_SWIOTLB - if (!(adev->need_swiotlb && swiotlb_nr_tbl())) + if (!(adev->need_swiotlb && is_swiotlb_active(adev->dev))) --count; #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h index 183814493658..bda4438c3925 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.h @@ -21,6 +21,11 @@ #ifndef __AMDGPU_UMC_H__ #define __AMDGPU_UMC_H__ +/* + * (addr / 256) * 4096, the higher 26 bits in ErrorAddr + * is the index of 4KB block + */ +#define ADDR_OF_4KB_BLOCK(addr) (((addr) & ~0xffULL) << 4) /* * (addr / 256) * 8192, the higher 26 bits in ErrorAddr * is the index of 8KB block diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index fc8da5fed779..0e3ff5c3766e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -3137,6 +3137,7 @@ static const struct soc15_reg_golden golden_settings_gc_10_3[] = SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER7_SELECT, 0xf0f001ff, 0x00000000), SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER8_SELECT, 0xf0f001ff, 0x00000000), SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_PERFCOUNTER9_SELECT, 0xf0f001ff, 0x00000000), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSX_DEBUG_1, 0x00010000, 0x00010020), SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffbfffff, 0x00a00000) }; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index fb15e8b5af32..ac3a88197b2f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c @@ -1271,6 +1271,16 @@ static bool is_raven_kicker(struct amdgpu_device *adev) return false; } +static bool check_if_enlarge_doorbell_range(struct amdgpu_device *adev) +{ + if ((adev->asic_type == CHIP_RENOIR) && + (adev->gfx.me_fw_version >= 0x000000a5) && + (adev->gfx.me_feature_version >= 52)) + return true; + else + return false; +} + static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev) { if (gfx_v9_0_should_disable_gfxoff(adev->pdev)) @@ -3619,7 +3629,16 @@ static int gfx_v9_0_kiq_init_register(struct amdgpu_ring *ring) if (ring->use_doorbell) { WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_LOWER, (adev->doorbell_index.kiq * 2) << 2); - WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER, + /* If GC has entered CGPG, ringing doorbell > first page + * doesn't wakeup GC. Enlarge CP_MEC_DOORBELL_RANGE_UPPER to + * workaround this issue. And this change has to align with firmware + * update. + */ + if (check_if_enlarge_doorbell_range(adev)) + WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER, + (adev->doorbell.size - 4)); + else + WREG32_SOC15(GC, 0, mmCP_MEC_DOORBELL_RANGE_UPPER, (adev->doorbell_index.userqueue_end * 2) << 2); } diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 6c5d9612abcb..cb764b554552 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -732,7 +732,7 @@ static uint32_t psp_v11_0_ring_get_wptr(struct psp_context *psp) struct amdgpu_device *adev = psp->adev; if (amdgpu_sriov_vf(adev)) - data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102); + data = psp->km_ring.ring_wptr; else data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67); @@ -746,6 +746,7 @@ static void psp_v11_0_ring_set_wptr(struct psp_context *psp, uint32_t value) if (amdgpu_sriov_vf(adev)) { WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102, value); WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, GFX_CTRL_CMD_ID_CONSUME_CMD); + psp->km_ring.ring_wptr = value; } else WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, value); } diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c index c4828bd3264b..b0ee77ee80b9 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c @@ -67,7 +67,7 @@ static int psp_v12_0_init_microcode(struct psp_context *psp) err = psp_init_asd_microcode(psp, chip_name); if (err) - goto out; + return err; snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_ta.bin", chip_name); err = request_firmware(&adev->psp.ta_fw, fw_name, adev->dev); @@ -80,7 +80,7 @@ static int psp_v12_0_init_microcode(struct psp_context *psp) } else { err = amdgpu_ucode_validate(adev->psp.ta_fw); if (err) - goto out2; + goto out; ta_hdr = (const struct ta_firmware_header_v1_0 *) adev->psp.ta_fw->data; @@ -105,10 +105,9 @@ static int psp_v12_0_init_microcode(struct psp_context *psp) return 0; -out2: +out: release_firmware(adev->psp.ta_fw); adev->psp.ta_fw = NULL; -out: if (err) { dev_err(adev->dev, "psp v12.0: Failed to load firmware \"%s\"\n", diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c index f2e725f72d2f..908664a5774b 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c @@ -379,7 +379,7 @@ static uint32_t psp_v3_1_ring_get_wptr(struct psp_context *psp) struct amdgpu_device *adev = psp->adev; if (amdgpu_sriov_vf(adev)) - data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_102); + data = psp->km_ring.ring_wptr; else data = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67); return data; @@ -394,6 +394,7 @@ static void psp_v3_1_ring_set_wptr(struct psp_context *psp, uint32_t value) /* send interrupt to PSP for SRIOV ring write pointer update */ WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_101, GFX_CTRL_CMD_ID_CONSUME_CMD); + psp->km_ring.ring_wptr = value; } else WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_67, value); } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index e82f49f62f6e..1f2e2460e121 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -143,7 +143,7 @@ static const struct soc15_reg_golden golden_settings_sdma_4_1[] = { SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_IB_CNTL, 0x800f0111, 0x00000100), SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), - SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0), + SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003e0), SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x00000000) }; @@ -269,7 +269,7 @@ static const struct soc15_reg_golden golden_settings_sdma_4_3[] = { SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_POWER_CNTL, 0x003fff07, 0x40000051), SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC0_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_RLC1_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), - SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003c0), + SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_PAGE, 0x000003ff, 0x000003e0), SOC15_REG_GOLDEN_VALUE(SDMA0, 0, mmSDMA0_UTCL1_WATERMK, 0xfc000000, 0x03fbe1fe) }; diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c b/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c index 5665c77a9d58..afbbe9f05d5e 100644 --- a/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c +++ b/drivers/gpu/drm/amd/amdgpu/umc_v8_7.c @@ -233,7 +233,7 @@ static void umc_v8_7_query_error_address(struct amdgpu_device *adev, err_addr &= ~((0x1ULL << lsb) - 1); /* translate umc channel address to soc pa, 3 parts are included */ - retired_page = ADDR_OF_8KB_BLOCK(err_addr) | + retired_page = ADDR_OF_4KB_BLOCK(err_addr) | ADDR_OF_256B_BLOCK(channel_index) | OFFSET_IN_256B_BLOCK(err_addr); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 6ea8a4b6efde..352a32dc609b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -486,9 +486,6 @@ static int destroy_queue_nocpsch_locked(struct device_queue_manager *dqm, if (retval == -ETIME) qpd->reset_wavefronts = true; - - mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj); - list_del(&q->list); if (list_empty(&qpd->queues_list)) { if (qpd->reset_wavefronts) { @@ -523,6 +520,8 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm, int retval; uint64_t sdma_val = 0; struct kfd_process_device *pdd = qpd_to_pdd(qpd); + struct mqd_manager *mqd_mgr = + dqm->mqd_mgrs[get_mqd_type_from_queue_type(q->properties.type)]; /* Get the SDMA queue stats */ if ((q->properties.type == KFD_QUEUE_TYPE_SDMA) || @@ -540,6 +539,8 @@ static int destroy_queue_nocpsch(struct device_queue_manager *dqm, pdd->sdma_past_activity_counter += sdma_val; dqm_unlock(dqm); + mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj); + return retval; } @@ -1632,7 +1633,7 @@ static int set_trap_handler(struct device_queue_manager *dqm, static int process_termination_nocpsch(struct device_queue_manager *dqm, struct qcm_process_device *qpd) { - struct queue *q, *next; + struct queue *q; struct device_process_node *cur, *next_dpn; int retval = 0; bool found = false; @@ -1640,12 +1641,19 @@ static int process_termination_nocpsch(struct device_queue_manager *dqm, dqm_lock(dqm); /* Clear all user mode queues */ - list_for_each_entry_safe(q, next, &qpd->queues_list, list) { + while (!list_empty(&qpd->queues_list)) { + struct mqd_manager *mqd_mgr; int ret; + q = list_first_entry(&qpd->queues_list, struct queue, list); + mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type( + q->properties.type)]; ret = destroy_queue_nocpsch_locked(dqm, qpd, q); if (ret) retval = ret; + dqm_unlock(dqm); + mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj); + dqm_lock(dqm); } /* Unregister process */ @@ -1677,36 +1685,34 @@ static int get_wave_state(struct device_queue_manager *dqm, u32 *save_area_used_size) { struct mqd_manager *mqd_mgr; - int r; dqm_lock(dqm); - if (q->properties.type != KFD_QUEUE_TYPE_COMPUTE || - q->properties.is_active || !q->device->cwsr_enabled) { - r = -EINVAL; - goto dqm_unlock; - } - mqd_mgr = dqm->mqd_mgrs[KFD_MQD_TYPE_CP]; - if (!mqd_mgr->get_wave_state) { - r = -EINVAL; - goto dqm_unlock; + if (q->properties.type != KFD_QUEUE_TYPE_COMPUTE || + q->properties.is_active || !q->device->cwsr_enabled || + !mqd_mgr->get_wave_state) { + dqm_unlock(dqm); + return -EINVAL; } - r = mqd_mgr->get_wave_state(mqd_mgr, q->mqd, ctl_stack, - ctl_stack_used_size, save_area_used_size); - -dqm_unlock: dqm_unlock(dqm); - return r; + + /* + * get_wave_state is outside the dqm lock to prevent circular locking + * and the queue should be protected against destruction by the process + * lock. + */ + return mqd_mgr->get_wave_state(mqd_mgr, q->mqd, ctl_stack, + ctl_stack_used_size, save_area_used_size); } static int process_termination_cpsch(struct device_queue_manager *dqm, struct qcm_process_device *qpd) { int retval; - struct queue *q, *next; + struct queue *q; struct kernel_queue *kq, *kq_next; struct mqd_manager *mqd_mgr; struct device_process_node *cur, *next_dpn; @@ -1763,24 +1769,26 @@ static int process_termination_cpsch(struct device_queue_manager *dqm, qpd->reset_wavefronts = false; } - dqm_unlock(dqm); - - /* Outside the DQM lock because under the DQM lock we can't do - * reclaim or take other locks that others hold while reclaiming. - */ - if (found) - kfd_dec_compute_active(dqm->dev); - /* Lastly, free mqd resources. * Do free_mqd() after dqm_unlock to avoid circular locking. */ - list_for_each_entry_safe(q, next, &qpd->queues_list, list) { + while (!list_empty(&qpd->queues_list)) { + q = list_first_entry(&qpd->queues_list, struct queue, list); mqd_mgr = dqm->mqd_mgrs[get_mqd_type_from_queue_type( q->properties.type)]; list_del(&q->list); qpd->queue_count--; + dqm_unlock(dqm); mqd_mgr->free_mqd(mqd_mgr, q->mqd, q->mqd_mem_obj); + dqm_lock(dqm); } + dqm_unlock(dqm); + + /* Outside the DQM lock because under the DQM lock we can't do + * reclaim or take other locks that others hold while reclaiming. + */ + if (found) + kfd_dec_compute_active(dqm->dev); return retval; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 65803e153a22..d243e60c6eef 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -452,13 +452,9 @@ static const struct sysfs_ops procfs_stats_ops = { .show = kfd_procfs_stats_show, }; -static struct attribute *procfs_stats_attrs[] = { - NULL -}; - static struct kobj_type procfs_stats_type = { .sysfs_ops = &procfs_stats_ops, - .default_attrs = procfs_stats_attrs, + .release = kfd_procfs_kobj_release, }; int kfd_procfs_add_queue(struct queue *q) @@ -973,9 +969,11 @@ static void kfd_process_wq_release(struct work_struct *work) list_for_each_entry(pdd, &p->per_device_data, per_device_list) { sysfs_remove_file(p->kobj, &pdd->attr_vram); sysfs_remove_file(p->kobj, &pdd->attr_sdma); - sysfs_remove_file(p->kobj, &pdd->attr_evict); - if (pdd->dev->kfd2kgd->get_cu_occupancy != NULL) - sysfs_remove_file(p->kobj, &pdd->attr_cu_occupancy); + + sysfs_remove_file(pdd->kobj_stats, &pdd->attr_evict); + if (pdd->dev->kfd2kgd->get_cu_occupancy) + sysfs_remove_file(pdd->kobj_stats, + &pdd->attr_cu_occupancy); kobject_del(pdd->kobj_stats); kobject_put(pdd->kobj_stats); pdd->kobj_stats = NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index eb1635ac8988..43c07ac2c6fc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -153,6 +153,7 @@ void pqm_uninit(struct process_queue_manager *pqm) if (pqn->q && pqn->q->gws) amdgpu_amdkfd_remove_gws_from_process(pqm->process->kgd_process_info, pqn->q->gws); + kfd_procfs_del_queue(pqn->q); uninit_queue(pqn->q); list_del(&pqn->process_queue_list); kfree(pqn); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index fbbb1bde6b06..bc9df3f216f5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -870,7 +870,8 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu); } - adev->dm.dc->ctx->dmub_srv = dc_dmub_srv_create(adev->dm.dc, dmub_srv); + if (!adev->dm.dc->ctx->dmub_srv) + adev->dm.dc->ctx->dmub_srv = dc_dmub_srv_create(adev->dm.dc, dmub_srv); if (!adev->dm.dc->ctx->dmub_srv) { DRM_ERROR("Couldn't allocate DC DMUB server!\n"); return -ENOMEM; @@ -1300,6 +1301,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) } hdr = (const struct dmcub_firmware_header_v1_0 *)adev->dm.dmub_fw->data; + adev->dm.dmcub_fw_version = le32_to_cpu(hdr->header.ucode_version); if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { adev->firmware.ucode[AMDGPU_UCODE_ID_DMCUB].ucode_id = @@ -1313,7 +1315,6 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) adev->dm.dmcub_fw_version); } - adev->dm.dmcub_fw_version = le32_to_cpu(hdr->header.ucode_version); adev->dm.dmub_srv = kzalloc(sizeof(*adev->dm.dmub_srv), GFP_KERNEL); dmub_srv = adev->dm.dmub_srv; @@ -1755,7 +1756,6 @@ static int dm_suspend(void *handle) amdgpu_dm_irq_suspend(adev); - dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3); return 0; @@ -2162,9 +2162,9 @@ static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector) max_cll = conn_base->hdr_sink_metadata.hdmi_type1.max_cll; min_cll = conn_base->hdr_sink_metadata.hdmi_type1.min_cll; - if (caps->ext_caps->bits.oled == 1 || + if (caps->ext_caps->bits.oled == 1 /*|| caps->ext_caps->bits.sdr_aux_backlight_control == 1 || - caps->ext_caps->bits.hdr_aux_backlight_control == 1) + caps->ext_caps->bits.hdr_aux_backlight_control == 1*/) caps->aux_support = true; if (amdgpu_backlight == 0) @@ -3685,6 +3685,23 @@ static int fill_dc_scaling_info(const struct drm_plane_state *state, scaling_info->src_rect.x = state->src_x >> 16; scaling_info->src_rect.y = state->src_y >> 16; + /* + * For reasons we don't (yet) fully understand a non-zero + * src_y coordinate into an NV12 buffer can cause a + * system hang. To avoid hangs (and maybe be overly cautious) + * let's reject both non-zero src_x and src_y. + * + * We currently know of only one use-case to reproduce a + * scenario with non-zero src_x and src_y for NV12, which + * is to gesture the YouTube Android app into full screen + * on ChromeOS. + */ + if (state->fb && + state->fb->format->format == DRM_FORMAT_NV12 && + (scaling_info->src_rect.x != 0 || + scaling_info->src_rect.y != 0)) + return -EINVAL; + /* * For reasons we don't (yet) fully understand a non-zero * src_y coordinate into an NV12 buffer can cause a @@ -8291,7 +8308,8 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, BUG_ON(dm_new_crtc_state->stream == NULL); /* Scaling or underscan settings */ - if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state)) + if (is_scaling_state_different(dm_old_conn_state, dm_new_conn_state) || + drm_atomic_crtc_needs_modeset(new_crtc_state)) update_stream_scaling_settings( &new_crtc_state->mode, dm_new_conn_state, dm_new_crtc_state->stream); @@ -8744,6 +8762,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled) continue; + ret = amdgpu_dm_verify_lut_sizes(new_crtc_state); + if (ret) + goto fail; + if (!new_crtc_state->enable) continue; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 1df7f1b18049..6c7235bb2f41 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -498,6 +498,7 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev); #define MAX_COLOR_LEGACY_LUT_ENTRIES 256 void amdgpu_dm_init_color_mod(void); +int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state); int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc); int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc, struct dc_plane_state *dc_plane_state); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c index 5df05f0d18bc..179ff4b42f20 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c @@ -284,6 +284,37 @@ static int __set_input_tf(struct dc_transfer_func *func, return res ? 0 : -ENOMEM; } +/** + * Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of + * the expected size. + * Returns 0 on success. + */ +int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state) +{ + const struct drm_color_lut *lut = NULL; + uint32_t size = 0; + + lut = __extract_blob_lut(crtc_state->degamma_lut, &size); + if (lut && size != MAX_COLOR_LUT_ENTRIES) { + DRM_DEBUG_DRIVER( + "Invalid Degamma LUT size. Should be %u but got %u.\n", + MAX_COLOR_LUT_ENTRIES, size); + return -EINVAL; + } + + lut = __extract_blob_lut(crtc_state->gamma_lut, &size); + if (lut && size != MAX_COLOR_LUT_ENTRIES && + size != MAX_COLOR_LEGACY_LUT_ENTRIES) { + DRM_DEBUG_DRIVER( + "Invalid Gamma LUT size. Should be %u (or %u for legacy) but got %u.\n", + MAX_COLOR_LUT_ENTRIES, MAX_COLOR_LEGACY_LUT_ENTRIES, + size); + return -EINVAL; + } + + return 0; +} + /** * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream. * @crtc: amdgpu_dm crtc state @@ -317,14 +348,12 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc) bool is_legacy; int r; - degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, °amma_size); - if (degamma_lut && degamma_size != MAX_COLOR_LUT_ENTRIES) - return -EINVAL; + r = amdgpu_dm_verify_lut_sizes(&crtc->base); + if (r) + return r; + degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, °amma_size); regamma_lut = __extract_blob_lut(crtc->base.gamma_lut, ®amma_size); - if (regamma_lut && regamma_size != MAX_COLOR_LUT_ENTRIES && - regamma_size != MAX_COLOR_LEGACY_LUT_ENTRIES) - return -EINVAL; has_degamma = degamma_lut && !__is_lut_linear(degamma_lut, degamma_size); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index 281b274e2b9b..80b448ae90d2 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -531,7 +531,7 @@ static void amdgpu_dm_irq_schedule_work(struct amdgpu_device *adev, handler_data = container_of(handler_list->next, struct amdgpu_dm_irq_handler_data, list); /*allocate a new amdgpu_dm_irq_handler_data*/ - handler_data_add = kzalloc(sizeof(*handler_data), GFP_KERNEL); + handler_data_add = kzalloc(sizeof(*handler_data), GFP_ATOMIC); if (!handler_data_add) { DRM_ERROR("DM_IRQ: failed to allocate irq handler!\n"); return; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 1e448f1b39a1..955a055bd980 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -268,6 +268,9 @@ dm_dp_mst_detect(struct drm_connector *connector, struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); struct amdgpu_dm_connector *master = aconnector->mst_port; + if (drm_connector_is_unregistered(connector)) + return connector_status_disconnected; + return drm_dp_mst_detect_port(connector, ctx, &master->mst_mgr, aconnector->port); } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c index f2114bc910bf..6b744edcd75f 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c @@ -135,7 +135,7 @@ void dcn20_update_clocks_update_dentist(struct clk_mgr_internal *clk_mgr) REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_wdivider); -// REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 5, 100); + REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_CHG_DONE, 1, 50, 1000); REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_WDIVIDER, dppclk_wdivider); REG_WAIT(DENTIST_DISPCLK_CNTL, DENTIST_DPPCLK_CHG_DONE, 1, 5, 100); diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c index 1c6e401dd4cc..0eba391e597f 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c @@ -66,9 +66,11 @@ int rn_get_active_display_cnt_wa( for (i = 0; i < context->stream_count; i++) { const struct dc_stream_state *stream = context->streams[i]; + /* Extend the WA to DP for Linux*/ if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A || stream->signal == SIGNAL_TYPE_DVI_SINGLE_LINK || - stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK) + stream->signal == SIGNAL_TYPE_DVI_DUAL_LINK || + stream->signal == SIGNAL_TYPE_DISPLAY_PORT) tmds_present = true; } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c index 32b73ea86673..a7f8caf1086b 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c @@ -1704,6 +1704,8 @@ static void set_dp_mst_mode(struct dc_link *link, bool mst_enable) link->type = dc_connection_single; link->local_sink = link->remote_sinks[0]; link->local_sink->sink_signal = SIGNAL_TYPE_DISPLAY_PORT; + dc_sink_retain(link->local_sink); + dm_helpers_dp_mst_stop_top_mgr(link->ctx, link); } else if (mst_enable == true && link->type == dc_connection_single && link->remote_sinks[0] != NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c index fce37c527a0b..8bb5912d837d 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp_dscl.c @@ -482,10 +482,13 @@ static enum lb_memory_config dpp1_dscl_find_lb_memory_config(struct dcn10_dpp *d int vtaps_c = scl_data->taps.v_taps_c; int ceil_vratio = dc_fixpt_ceil(scl_data->ratios.vert); int ceil_vratio_c = dc_fixpt_ceil(scl_data->ratios.vert_c); - enum lb_memory_config mem_cfg = LB_MEMORY_CONFIG_0; - if (dpp->base.ctx->dc->debug.use_max_lb) - return mem_cfg; + if (dpp->base.ctx->dc->debug.use_max_lb) { + if (scl_data->format == PIXEL_FORMAT_420BPP8 + || scl_data->format == PIXEL_FORMAT_420BPP10) + return LB_MEMORY_CONFIG_3; + return LB_MEMORY_CONFIG_0; + } dpp->base.caps->dscl_calc_lb_num_partitions( scl_data, LB_MEMORY_CONFIG_1, &num_part_y, &num_part_c); diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c index f1e9b3b06b92..9d3ccdd35582 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -243,7 +243,7 @@ void dcn20_dccg_init(struct dce_hwseq *hws) REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x1186a0); /* This value is dependent on the hardware pipeline delay so set once per SOC */ - REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0x801003c); + REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0xe01003c); } void dcn20_disable_vga( diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c index d8b18c515d06..e3cfb442a062 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c @@ -357,7 +357,7 @@ void optc2_lock_doublebuffer_enable(struct timing_generator *optc) REG_UPDATE_2(OTG_GLOBAL_CONTROL1, MASTER_UPDATE_LOCK_DB_X, - h_blank_start - 200 - 1, + (h_blank_start - 200 - 1) / optc1->opp_count, MASTER_UPDATE_LOCK_DB_Y, v_blank_start - 1); } diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c index 33488b3c5c3c..cfe85ba1018e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c @@ -2077,8 +2077,10 @@ int dcn20_populate_dml_pipes_from_context( - timing->v_border_bottom; pipes[pipe_cnt].pipe.dest.htotal = timing->h_total; pipes[pipe_cnt].pipe.dest.vtotal = v_total; - pipes[pipe_cnt].pipe.dest.hactive = timing->h_addressable; - pipes[pipe_cnt].pipe.dest.vactive = timing->v_addressable; + pipes[pipe_cnt].pipe.dest.hactive = + timing->h_addressable + timing->h_border_left + timing->h_border_right; + pipes[pipe_cnt].pipe.dest.vactive = + timing->v_addressable + timing->v_border_top + timing->v_border_bottom; pipes[pipe_cnt].pipe.dest.interlaced = timing->flags.INTERLACE; pipes[pipe_cnt].pipe.dest.pixel_rate_mhz = timing->pix_clk_100hz/10000.0; if (timing->timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING) @@ -3232,7 +3234,7 @@ static noinline bool dcn20_validate_bandwidth_fp(struct dc *dc, voltage_supported = dcn20_validate_bandwidth_internal(dc, context, false); dummy_pstate_supported = context->bw_ctx.bw.dcn.clk.p_state_change_support; - if (voltage_supported && dummy_pstate_supported) { + if (voltage_supported && (dummy_pstate_supported || !(context->stream_count))) { context->bw_ctx.bw.dcn.clk.p_state_change_support = false; goto restore_dml_state; } diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index 8465cae180da..e5f4f93317cf 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -1875,7 +1875,6 @@ static bool dcn30_split_stream_for_mpc_or_odm( } pri_pipe->next_odm_pipe = sec_pipe; sec_pipe->prev_odm_pipe = pri_pipe; - ASSERT(sec_pipe->top_pipe == NULL); sec_pipe->stream_res.opp = pool->opps[pipe_idx]; if (sec_pipe->stream->timing.flags.DSC == 1) { diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c index 367c82b5ab4c..c09bca335068 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c @@ -4888,7 +4888,7 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l } } while ((locals->PrefetchSupported[i][j] != true || locals->VRatioInPrefetchSupported[i][j] != true) && (mode_lib->vba.NextMaxVStartup != mode_lib->vba.MaxMaxVStartup[0][0] - || mode_lib->vba.NextPrefetchMode < mode_lib->vba.MaxPrefetchMode)); + || mode_lib->vba.NextPrefetchMode <= mode_lib->vba.MaxPrefetchMode)); if (locals->PrefetchSupported[i][j] == true && locals->VRatioInPrefetchSupported[i][j] == true) { mode_lib->vba.BandwidthAvailableForImmediateFlip = locals->ReturnBWPerState[i][0]; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c index 9e0ae18e71fa..2663f1b31842 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c @@ -64,6 +64,7 @@ typedef struct { #define BPP_INVALID 0 #define BPP_BLENDED_PIPE 0xffffffff #define DCN30_MAX_DSC_IMAGE_WIDTH 5184 +#define DCN30_MAX_FMT_420_BUFFER_WIDTH 4096 static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib); static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation( @@ -2052,7 +2053,7 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman v->DISPCLKWithoutRamping, v->DISPCLKDPPCLKVCOSpeed); v->MaxDispclkRoundedToDFSGranularity = RoundToDFSGranularityDown( - v->soc.clock_limits[mode_lib->soc.num_states].dispclk_mhz, + v->soc.clock_limits[mode_lib->soc.num_states - 1].dispclk_mhz, v->DISPCLKDPPCLKVCOSpeed); if (v->DISPCLKWithoutRampingRoundedToDFSGranularity > v->MaxDispclkRoundedToDFSGranularity) { @@ -3957,20 +3958,20 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) { v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k] * (1.0 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * (1.0 + v->DISPCLKRampingMargin / 100.0); - if ((v->PlaneRequiredDISPCLKWithoutODMCombine >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states] - && v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states])) { + if ((v->PlaneRequiredDISPCLKWithoutODMCombine >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1] + && v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) { v->PlaneRequiredDISPCLKWithoutODMCombine = v->PixelClock[k] * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); } v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * (1 + v->DISPCLKRampingMargin / 100.0); - if ((v->PlaneRequiredDISPCLKWithODMCombine2To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states] - && v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states])) { + if ((v->PlaneRequiredDISPCLKWithODMCombine2To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1] + && v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) { v->PlaneRequiredDISPCLKWithODMCombine2To1 = v->PixelClock[k] / 2 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); } v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * (1 + v->DISPCLKRampingMargin / 100.0); - if ((v->PlaneRequiredDISPCLKWithODMCombine4To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states] - && v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states])) { + if ((v->PlaneRequiredDISPCLKWithODMCombine4To1 >= v->MaxDispclk[i] && v->MaxDispclk[i] == v->MaxDispclk[mode_lib->soc.num_states - 1] + && v->MaxDppclk[i] == v->MaxDppclk[mode_lib->soc.num_states - 1])) { v->PlaneRequiredDISPCLKWithODMCombine4To1 = v->PixelClock[k] / 4 * (1 + v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0); } @@ -3987,19 +3988,30 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l } else if (v->PlaneRequiredDISPCLKWithoutODMCombine > v->MaxDispclkRoundedDownToDFSGranularity) { v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1; - } else if (v->DSCEnabled[k] && (v->HActive[k] > DCN30_MAX_DSC_IMAGE_WIDTH)) { - v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; - v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1; } else { v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_disabled; v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithoutODMCombine; - /*420 format workaround*/ - if (v->HActive[k] > 4096 && v->OutputFormat[k] == dm_420) { + } + if (v->DSCEnabled[k] && v->HActive[k] > DCN30_MAX_DSC_IMAGE_WIDTH + && v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) { + if (v->HActive[k] / 2 > DCN30_MAX_DSC_IMAGE_WIDTH) { + v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1; + v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1; + } else { + v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; + v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1; + } + } + if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN30_MAX_FMT_420_BUFFER_WIDTH + && v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) { + if (v->HActive[k] / 2 > DCN30_MAX_FMT_420_BUFFER_WIDTH) { + v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1; + v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1; + } else { v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_2to1; v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine2To1; } } - if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) { v->MPCCombine[i][j][k] = false; v->NoOfDPP[i][j][k] = 4; @@ -4281,42 +4293,8 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l } } - for (i = 0; i < v->soc.num_states; i++) { - v->DSCCLKRequiredMoreThanSupported[i] = false; - for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) { - if (v->BlendingAndTiming[k] == k) { - if (v->Output[k] == dm_dp || v->Output[k] == dm_edp) { - if (v->OutputFormat[k] == dm_420) { - v->DSCFormatFactor = 2; - } else if (v->OutputFormat[k] == dm_444) { - v->DSCFormatFactor = 1; - } else if (v->OutputFormat[k] == dm_n422) { - v->DSCFormatFactor = 2; - } else { - v->DSCFormatFactor = 1; - } - if (v->RequiresDSC[i][k] == true) { - if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_4to1) { - if (v->PixelClockBackEnd[k] / 12.0 / v->DSCFormatFactor - > (1.0 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * v->MaxDSCCLK[i]) { - v->DSCCLKRequiredMoreThanSupported[i] = true; - } - } else if (v->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_2to1) { - if (v->PixelClockBackEnd[k] / 6.0 / v->DSCFormatFactor - > (1.0 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * v->MaxDSCCLK[i]) { - v->DSCCLKRequiredMoreThanSupported[i] = true; - } - } else { - if (v->PixelClockBackEnd[k] / 3.0 / v->DSCFormatFactor - > (1.0 - v->DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) * v->MaxDSCCLK[i]) { - v->DSCCLKRequiredMoreThanSupported[i] = true; - } - } - } - } - } - } - } + /* Skip dscclk validation: as long as dispclk is supported, dscclk is also implicitly supported */ + for (i = 0; i < v->soc.num_states; i++) { v->NotEnoughDSCUnits[i] = false; v->TotalDSCUnitsRequired = 0.0; @@ -5319,7 +5297,7 @@ void dml30_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l for (j = 0; j < 2; j++) { if (v->ScaleRatioAndTapsSupport == 1 && v->SourceFormatPixelAndScanSupport == 1 && v->ViewportSizeSupport[i][j] == 1 && v->DIOSupport[i] == 1 && v->ODMCombine4To1SupportCheckOK[i] == 1 - && v->NotEnoughDSCUnits[i] == 0 && v->DSCCLKRequiredMoreThanSupported[i] == 0 + && v->NotEnoughDSCUnits[i] == 0 && v->DTBCLKRequiredMoreThanSupported[i] == 0 && v->ROBSupport[i][j] == 1 && v->DISPCLK_DPPCLK_Support[i][j] == 1 && v->TotalAvailablePipesSupport[i][j] == 1 && EnoughWritebackUnits == 1 && WritebackModeSupport == 1 diff --git a/drivers/gpu/drm/amd/display/dc/irq_types.h b/drivers/gpu/drm/amd/display/dc/irq_types.h index d0ccd81ad5b4..ad3e5621a174 100644 --- a/drivers/gpu/drm/amd/display/dc/irq_types.h +++ b/drivers/gpu/drm/amd/display/dc/irq_types.h @@ -163,7 +163,7 @@ enum irq_type }; #define DAL_VALID_IRQ_SRC_NUM(src) \ - ((src) <= DAL_IRQ_SOURCES_NUMBER && (src) > DC_IRQ_SOURCE_INVALID) + ((src) < DAL_IRQ_SOURCES_NUMBER && (src) > DC_IRQ_SOURCE_INVALID) /* Number of Page Flip IRQ Sources. */ #define DAL_PFLIP_IRQ_SRC_NUM \ diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c index 20e554e771d1..fa8aeec304ef 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp.c @@ -260,7 +260,6 @@ enum mod_hdcp_status mod_hdcp_setup(struct mod_hdcp *hdcp, struct mod_hdcp_output output; enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; - memset(hdcp, 0, sizeof(struct mod_hdcp)); memset(&output, 0, sizeof(output)); hdcp->config = *config; HDCP_TOP_INTERFACE_TRACE(hdcp); diff --git a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c index f244b72e74e0..53eab2b8e2c8 100644 --- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c @@ -29,8 +29,10 @@ static inline enum mod_hdcp_status validate_bksv(struct mod_hdcp *hdcp) { uint64_t n = 0; uint8_t count = 0; + u8 bksv[sizeof(n)] = { }; - memcpy(&n, hdcp->auth.msg.hdcp1.bksv, sizeof(uint64_t)); + memcpy(bksv, hdcp->auth.msg.hdcp1.bksv, sizeof(hdcp->auth.msg.hdcp1.bksv)); + n = *(uint64_t *)bksv; while (n) { count++; diff --git a/drivers/gpu/drm/amd/include/navi10_enum.h b/drivers/gpu/drm/amd/include/navi10_enum.h index d5ead9680c6e..84bcb96f76ea 100644 --- a/drivers/gpu/drm/amd/include/navi10_enum.h +++ b/drivers/gpu/drm/amd/include/navi10_enum.h @@ -430,7 +430,7 @@ ARRAY_2D_DEPTH = 0x00000001, */ typedef enum ENUM_NUM_SIMD_PER_CU { -NUM_SIMD_PER_CU = 0x00000004, +NUM_SIMD_PER_CU = 0x00000002, } ENUM_NUM_SIMD_PER_CU; /* diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index 132c269c7c89..4dc27ec4d012 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -5122,6 +5122,13 @@ static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf) return size; } +static bool vega10_get_power_profile_mode_quirks(struct pp_hwmgr *hwmgr) +{ + struct amdgpu_device *adev = hwmgr->adev; + + return (adev->pdev->device == 0x6860); +} + static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint32_t size) { struct vega10_hwmgr *data = hwmgr->backend; @@ -5158,9 +5165,15 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui } out: - smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask, + if (vega10_get_power_profile_mode_quirks(hwmgr)) + smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask, + 1 << power_profile_mode, + NULL); + else + smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask, (!power_profile_mode) ? 0 : 1 << (power_profile_mode - 1), NULL); + hwmgr->power_profile_mode = power_profile_mode; return 0; diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 351a85088d0e..f1e8bc39b16d 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -922,6 +922,11 @@ static const struct drm_plane_helper_funcs malidp_de_plane_helper_funcs = { .atomic_disable = malidp_de_plane_disable, }; +static const uint64_t linear_only_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + int malidp_de_planes_init(struct drm_device *drm) { struct malidp_drm *malidp = drm->dev_private; @@ -985,8 +990,8 @@ int malidp_de_planes_init(struct drm_device *drm) */ ret = drm_universal_plane_init(drm, &plane->base, crtcs, &malidp_de_plane_funcs, formats, n, - (id == DE_SMART) ? NULL : modifiers, plane_type, - NULL); + (id == DE_SMART) ? linear_only_modifiers : modifiers, + plane_type, NULL); if (ret < 0) goto cleanup; diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index 88121c0e0d05..cd93c44f2662 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -189,6 +189,9 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size) u32 i, data; u32 boot_address; + if (ast->config_mode != ast_use_p2a) + return false; + data = ast_mindwm(ast, 0x1e6e2100) & 0x01; if (data) { boot_address = get_fw_base(ast); @@ -207,6 +210,9 @@ static bool ast_launch_m68k(struct drm_device *dev) u8 *fw_addr = NULL; u8 jreg; + if (ast->config_mode != ast_use_p2a) + return false; + data = ast_mindwm(ast, 0x1e6e2100) & 0x01; if (!data) { @@ -271,25 +277,55 @@ u8 ast_get_dp501_max_clk(struct drm_device *dev) struct ast_private *ast = to_ast_private(dev); u32 boot_address, offset, data; u8 linkcap[4], linkrate, linklanes, maxclk = 0xff; + u32 *plinkcap; - boot_address = get_fw_base(ast); - - /* validate FW version */ - offset = 0xf000; - data = ast_mindwm(ast, boot_address + offset); - if ((data & 0xf0) != 0x10) /* version: 1x */ - return maxclk; - - /* Read Link Capability */ - offset = 0xf014; - *(u32 *)linkcap = ast_mindwm(ast, boot_address + offset); - if (linkcap[2] == 0) { - linkrate = linkcap[0]; - linklanes = linkcap[1]; - data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes); - if (data > 0xff) - data = 0xff; - maxclk = (u8)data; + if (ast->config_mode == ast_use_p2a) { + boot_address = get_fw_base(ast); + + /* validate FW version */ + offset = AST_DP501_GBL_VERSION; + data = ast_mindwm(ast, boot_address + offset); + if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) /* version: 1x */ + return maxclk; + + /* Read Link Capability */ + offset = AST_DP501_LINKRATE; + plinkcap = (u32 *)linkcap; + *plinkcap = ast_mindwm(ast, boot_address + offset); + if (linkcap[2] == 0) { + linkrate = linkcap[0]; + linklanes = linkcap[1]; + data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes); + if (data > 0xff) + data = 0xff; + maxclk = (u8)data; + } + } else { + if (!ast->dp501_fw_buf) + return AST_DP501_DEFAULT_DCLK; /* 1024x768 as default */ + + /* dummy read */ + offset = 0x0000; + data = readl(ast->dp501_fw_buf + offset); + + /* validate FW version */ + offset = AST_DP501_GBL_VERSION; + data = readl(ast->dp501_fw_buf + offset); + if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) /* version: 1x */ + return maxclk; + + /* Read Link Capability */ + offset = AST_DP501_LINKRATE; + plinkcap = (u32 *)linkcap; + *plinkcap = readl(ast->dp501_fw_buf + offset); + if (linkcap[2] == 0) { + linkrate = linkcap[0]; + linklanes = linkcap[1]; + data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes); + if (data > 0xff) + data = 0xff; + maxclk = (u8)data; + } } return maxclk; } @@ -298,26 +334,57 @@ bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata) { struct ast_private *ast = to_ast_private(dev); u32 i, boot_address, offset, data; + u32 *pEDIDidx; - boot_address = get_fw_base(ast); - - /* validate FW version */ - offset = 0xf000; - data = ast_mindwm(ast, boot_address + offset); - if ((data & 0xf0) != 0x10) - return false; - - /* validate PnP Monitor */ - offset = 0xf010; - data = ast_mindwm(ast, boot_address + offset); - if (!(data & 0x01)) - return false; + if (ast->config_mode == ast_use_p2a) { + boot_address = get_fw_base(ast); - /* Read EDID */ - offset = 0xf020; - for (i = 0; i < 128; i += 4) { - data = ast_mindwm(ast, boot_address + offset + i); - *(u32 *)(ediddata + i) = data; + /* validate FW version */ + offset = AST_DP501_GBL_VERSION; + data = ast_mindwm(ast, boot_address + offset); + if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) + return false; + + /* validate PnP Monitor */ + offset = AST_DP501_PNPMONITOR; + data = ast_mindwm(ast, boot_address + offset); + if (!(data & AST_DP501_PNP_CONNECTED)) + return false; + + /* Read EDID */ + offset = AST_DP501_EDID_DATA; + for (i = 0; i < 128; i += 4) { + data = ast_mindwm(ast, boot_address + offset + i); + pEDIDidx = (u32 *)(ediddata + i); + *pEDIDidx = data; + } + } else { + if (!ast->dp501_fw_buf) + return false; + + /* dummy read */ + offset = 0x0000; + data = readl(ast->dp501_fw_buf + offset); + + /* validate FW version */ + offset = AST_DP501_GBL_VERSION; + data = readl(ast->dp501_fw_buf + offset); + if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) + return false; + + /* validate PnP Monitor */ + offset = AST_DP501_PNPMONITOR; + data = readl(ast->dp501_fw_buf + offset); + if (!(data & AST_DP501_PNP_CONNECTED)) + return false; + + /* Read EDID */ + offset = AST_DP501_EDID_DATA; + for (i = 0; i < 128; i += 4) { + data = readl(ast->dp501_fw_buf + offset + i); + pEDIDidx = (u32 *)(ediddata + i); + *pEDIDidx = data; + } } return true; diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 467049ca8430..b68b1ddfecb7 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -120,6 +120,7 @@ struct ast_private { void __iomem *regs; void __iomem *ioregs; + void __iomem *dp501_fw_buf; enum ast_chip chip; bool vga2_clone; @@ -298,6 +299,17 @@ int ast_mode_config_init(struct ast_private *ast); #define AST_MM_ALIGN_SHIFT 4 #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1) +#define AST_DP501_FW_VERSION_MASK GENMASK(7, 4) +#define AST_DP501_FW_VERSION_1 BIT(4) +#define AST_DP501_PNP_CONNECTED BIT(1) + +#define AST_DP501_DEFAULT_DCLK 65 + +#define AST_DP501_GBL_VERSION 0xf000 +#define AST_DP501_PNPMONITOR 0xf010 +#define AST_DP501_LINKRATE 0xf014 +#define AST_DP501_EDID_DATA 0xf020 + int ast_mm_init(struct ast_private *ast); /* ast post */ diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 77066bca8793..0d163511564e 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -98,7 +98,7 @@ static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) { /* Double check it's actually working */ data = ast_read32(ast, 0xf004); - if (data != 0xFFFFFFFF) { + if ((data != 0xFFFFFFFF) && (data != 0x00)) { /* P2A works, grab silicon revision */ ast->config_mode = ast_use_p2a; @@ -409,7 +409,7 @@ struct ast_private *ast_device_create(struct drm_driver *drv, dev->pdev = pdev; pci_set_drvdata(pdev, dev); - ast->regs = pci_iomap(dev->pdev, 1, 0); + ast->regs = pcim_iomap(pdev, 1, 0); if (!ast->regs) return ERR_PTR(-EIO); @@ -425,7 +425,7 @@ struct ast_private *ast_device_create(struct drm_driver *drv, /* "map" IO regs if the above hasn't done so already */ if (!ast->ioregs) { - ast->ioregs = pci_iomap(dev->pdev, 2, 0); + ast->ioregs = pcim_iomap(pdev, 2, 0); if (!ast->ioregs) return ERR_PTR(-EIO); } @@ -446,6 +446,14 @@ struct ast_private *ast_device_create(struct drm_driver *drv, if (ret) return ERR_PTR(ret); + /* map reserved buffer */ + ast->dp501_fw_buf = NULL; + if (dev->vram_mm->vram_size < pci_resource_len(dev->pdev, 0)) { + ast->dp501_fw_buf = pci_iomap_range(dev->pdev, 0, dev->vram_mm->vram_size, 0); + if (!ast->dp501_fw_buf) + drm_info(dev, "failed to map reserved buffer!\n"); + } + ret = ast_mode_config_init(ast); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index e145cbb35bac..4e82647a621e 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -130,7 +130,7 @@ config DRM_SIL_SII8620 tristate "Silicon Image SII8620 HDMI/MHL bridge" depends on OF select DRM_KMS_HELPER - imply EXTCON + select EXTCON depends on RC_CORE || !RC_CORE help Silicon Image SII8620 HDMI/MHL bridge chip driver. diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c index d0c65610ebb5..f56ff97c9899 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c @@ -2369,9 +2369,9 @@ static int cdns_mhdp_probe(struct platform_device *pdev) clk_prepare_enable(clk); pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { - dev_err(dev, "pm_runtime_get_sync failed\n"); + dev_err(dev, "pm_runtime_resume_and_get failed\n"); pm_runtime_disable(dev); goto clk_disable; } diff --git a/drivers/gpu/drm/bridge/cdns-dsi.c b/drivers/gpu/drm/bridge/cdns-dsi.c index 76373e31df92..b31281f76117 100644 --- a/drivers/gpu/drm/bridge/cdns-dsi.c +++ b/drivers/gpu/drm/bridge/cdns-dsi.c @@ -1028,7 +1028,7 @@ static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host, struct mipi_dsi_packet packet; int ret, i, tx_len, rx_len; - ret = pm_runtime_get_sync(host->dev); + ret = pm_runtime_resume_and_get(host->dev); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/bridge/lontium-lt9611.c b/drivers/gpu/drm/bridge/lontium-lt9611.c index d734d9402c35..c1926154eda8 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611.c @@ -1209,6 +1209,7 @@ static struct i2c_device_id lt9611_id[] = { { "lontium,lt9611", 0 }, {} }; +MODULE_DEVICE_TABLE(i2c, lt9611_id); static const struct of_device_id lt9611_match_table[] = { { .compatible = "lontium,lt9611" }, diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c index 66b67402f1ac..c65ca860712d 100644 --- a/drivers/gpu/drm/bridge/nwl-dsi.c +++ b/drivers/gpu/drm/bridge/nwl-dsi.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -742,7 +743,9 @@ static int nwl_dsi_disable(struct nwl_dsi *dsi) return 0; } -static void nwl_dsi_bridge_disable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -803,17 +806,6 @@ static int nwl_dsi_get_dphy_params(struct nwl_dsi *dsi, return 0; } -static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - /* At least LCDIF + NWL needs active high sync */ - adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); - adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC); - - return true; -} - static enum drm_mode_status nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, const struct drm_display_info *info, @@ -831,6 +823,24 @@ nwl_dsi_bridge_mode_valid(struct drm_bridge *bridge, return MODE_OK; } +static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; + + /* At least LCDIF + NWL needs active high sync */ + adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); + adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC); + + /* Do a full modeset if crtc_state->active is changed to be true. */ + if (crtc_state->active_changed && crtc_state->active) + crtc_state->mode_changed = true; + + return 0; +} + static void nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *mode, @@ -862,7 +872,9 @@ nwl_dsi_bridge_mode_set(struct drm_bridge *bridge, drm_mode_debug_printmodeline(adjusted_mode); } -static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -897,7 +909,9 @@ static void nwl_dsi_bridge_pre_enable(struct drm_bridge *bridge) } } -static void nwl_dsi_bridge_enable(struct drm_bridge *bridge) +static void +nwl_dsi_bridge_atomic_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct nwl_dsi *dsi = bridge_to_dsi(bridge); int ret; @@ -942,14 +956,17 @@ static void nwl_dsi_bridge_detach(struct drm_bridge *bridge) } static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = { - .pre_enable = nwl_dsi_bridge_pre_enable, - .enable = nwl_dsi_bridge_enable, - .disable = nwl_dsi_bridge_disable, - .mode_fixup = nwl_dsi_bridge_mode_fixup, - .mode_set = nwl_dsi_bridge_mode_set, - .mode_valid = nwl_dsi_bridge_mode_valid, - .attach = nwl_dsi_bridge_attach, - .detach = nwl_dsi_bridge_detach, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_check = nwl_dsi_bridge_atomic_check, + .atomic_pre_enable = nwl_dsi_bridge_atomic_pre_enable, + .atomic_enable = nwl_dsi_bridge_atomic_enable, + .atomic_disable = nwl_dsi_bridge_atomic_disable, + .mode_set = nwl_dsi_bridge_mode_set, + .mode_valid = nwl_dsi_bridge_mode_valid, + .attach = nwl_dsi_bridge_attach, + .detach = nwl_dsi_bridge_detach, }; static int nwl_dsi_parse_dt(struct nwl_dsi *dsi) diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index f2d46b7ac6f9..232abbba3686 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -314,9 +314,10 @@ int drm_master_open(struct drm_file *file_priv) void drm_master_release(struct drm_file *file_priv) { struct drm_device *dev = file_priv->minor->dev; - struct drm_master *master = file_priv->master; + struct drm_master *master; mutex_lock(&dev->master_mutex); + master = file_priv->master; if (file_priv->magic) idr_remove(&file_priv->master->magic_map, file_priv->magic); diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 64f0effb52ac..044acd07c153 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -522,6 +522,9 @@ void drm_bridge_chain_pre_enable(struct drm_bridge *bridge) list_for_each_entry_reverse(iter, &encoder->bridge_chain, chain_node) { if (iter->funcs->pre_enable) iter->funcs->pre_enable(iter); + + if (iter == bridge) + break; } } EXPORT_SYMBOL(drm_bridge_chain_pre_enable); diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index deeed73f4ed6..3c55753bab16 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -602,7 +602,14 @@ int drm_dp_read_downstream_info(struct drm_dp_aux *aux, !(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) return 0; + /* Some branches advertise having 0 downstream ports, despite also advertising they have a + * downstream port present. The DP spec isn't clear on if this is allowed or not, but since + * some branches do it we need to handle it regardless. + */ len = drm_dp_downstream_port_count(dpcd); + if (!len) + return 0; + if (dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DETAILED_CAP_INFO_AVAILABLE) len *= 4; diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index a08cc6b53bc2..861f16dfd1a3 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -94,6 +94,9 @@ static int drm_dp_mst_register_i2c_bus(struct drm_dp_mst_port *port); static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_mst_port *port); static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr); +static bool drm_dp_mst_port_downstream_of_branch(struct drm_dp_mst_port *port, + struct drm_dp_mst_branch *branch); + #define DBG_PREFIX "[dp_mst]" #define DP_STR(x) [DP_ ## x] = #x @@ -2499,7 +2502,7 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb, { struct drm_dp_mst_topology_mgr *mgr = mstb->mgr; struct drm_dp_mst_port *port; - int old_ddps, old_input, ret, i; + int old_ddps, ret; u8 new_pdt; bool new_mcs; bool dowork = false, create_connector = false; @@ -2531,7 +2534,6 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb, } old_ddps = port->ddps; - old_input = port->input; port->input = conn_stat->input_port; port->ldps = conn_stat->legacy_device_plug_status; port->ddps = conn_stat->displayport_device_plug_status; @@ -2554,28 +2556,6 @@ drm_dp_mst_handle_conn_stat(struct drm_dp_mst_branch *mstb, dowork = false; } - if (!old_input && old_ddps != port->ddps && !port->ddps) { - for (i = 0; i < mgr->max_payloads; i++) { - struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i]; - struct drm_dp_mst_port *port_validated; - - if (!vcpi) - continue; - - port_validated = - container_of(vcpi, struct drm_dp_mst_port, vcpi); - port_validated = - drm_dp_mst_topology_get_port_validated(mgr, port_validated); - if (!port_validated) { - mutex_lock(&mgr->payload_lock); - vcpi->num_slots = 0; - mutex_unlock(&mgr->payload_lock); - } else { - drm_dp_mst_topology_put_port(port_validated); - } - } - } - if (port->connector) drm_modeset_unlock(&mgr->base.lock); else if (create_connector) @@ -3385,6 +3365,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) struct drm_dp_mst_port *port; int i, j; int cur_slots = 1; + bool skip; mutex_lock(&mgr->payload_lock); for (i = 0; i < mgr->max_payloads; i++) { @@ -3399,6 +3380,16 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) port = container_of(vcpi, struct drm_dp_mst_port, vcpi); + mutex_lock(&mgr->lock); + skip = !drm_dp_mst_port_downstream_of_branch(port, mgr->mst_primary); + mutex_unlock(&mgr->lock); + + if (skip) { + drm_dbg_kms(mgr->dev, + "Virtual channel %d is not in current topology\n", + i); + continue; + } /* Validated ports don't matter if we're releasing * VCPI */ @@ -3406,8 +3397,16 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr) port = drm_dp_mst_topology_get_port_validated( mgr, port); if (!port) { - mutex_unlock(&mgr->payload_lock); - return -EINVAL; + if (vcpi->num_slots == payload->num_slots) { + cur_slots += vcpi->num_slots; + payload->start_slot = req_payload.start_slot; + continue; + } else { + drm_dbg_kms(mgr->dev, + "Fail:set payload to invalid sink"); + mutex_unlock(&mgr->payload_lock); + return -EINVAL; + } } put_port = true; } @@ -3491,6 +3490,7 @@ int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr) struct drm_dp_mst_port *port; int i; int ret = 0; + bool skip; mutex_lock(&mgr->payload_lock); for (i = 0; i < mgr->max_payloads; i++) { @@ -3500,6 +3500,13 @@ int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr) port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi); + mutex_lock(&mgr->lock); + skip = !drm_dp_mst_port_downstream_of_branch(port, mgr->mst_primary); + mutex_unlock(&mgr->lock); + + if (skip) + continue; + DRM_DEBUG_KMS("payload %d %d\n", i, mgr->payloads[i].payload_state); if (mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL) { ret = drm_dp_create_payload_step2(mgr, port, mgr->proposed_vcpis[i]->vcpi, &mgr->payloads[i]); @@ -4581,9 +4588,18 @@ EXPORT_SYMBOL(drm_dp_mst_reset_vcpi_slots); void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port) { + bool skip; + if (!port->vcpi.vcpi) return; + mutex_lock(&mgr->lock); + skip = !drm_dp_mst_port_downstream_of_branch(port, mgr->mst_primary); + mutex_unlock(&mgr->lock); + + if (skip) + return; + drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); port->vcpi.num_slots = 0; port->vcpi.pbn = 0; diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c index dc734d4828a1..aaf8d625ce1a 100644 --- a/drivers/gpu/drm/drm_ioc32.c +++ b/drivers/gpu/drm/drm_ioc32.c @@ -865,8 +865,6 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, req.request.sequence = req32.request.sequence; req.request.signal = req32.request.signal; err = drm_ioctl_kernel(file, drm_wait_vblank_ioctl, &req, DRM_UNLOCKED); - if (err) - return err; req32.reply.type = req.reply.type; req32.reply.sequence = req.reply.sequence; @@ -875,7 +873,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, if (copy_to_user(argp, &req32, sizeof(req32))) return -EFAULT; - return 0; + return err; } #if defined(CONFIG_X86) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 9a2c76524c02..9aa3909fb6cd 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -118,17 +118,18 @@ int drm_getunique(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_unique *u = data; - struct drm_master *master = file_priv->master; + struct drm_master *master; - mutex_lock(&master->dev->master_mutex); + mutex_lock(&dev->master_mutex); + master = file_priv->master; if (u->unique_len >= master->unique_len) { if (copy_to_user(u->unique, master->unique, master->unique_len)) { - mutex_unlock(&master->dev->master_mutex); + mutex_unlock(&dev->master_mutex); return -EFAULT; } } u->unique_len = master->unique_len; - mutex_unlock(&master->dev->master_mutex); + mutex_unlock(&dev->master_mutex); return 0; } @@ -826,6 +827,9 @@ long drm_ioctl(struct file *filp, if (drm_dev_is_unplugged(dev)) return -ENODEV; + if (DRM_IOCTL_TYPE(cmd) != DRM_IOCTL_BASE) + return -ENOTTY; + is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END; if (is_driver_ioctl) { diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 4438e3aadcce..69bab4ff4500 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -224,6 +224,7 @@ mipi_dsi_device_register_full(struct mipi_dsi_host *host, } dsi->dev.of_node = info->node; + dsi->dev.fwnode = of_fwnode_handle(info->node); dsi->channel = info->channel; strlcpy(dsi->name, info->type, sizeof(dsi->name)); diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 54d9876b5305..6ef4ea07d1bb 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -435,6 +435,7 @@ static struct drm_framebuffer *psb_user_framebuffer_create const struct drm_mode_fb_cmd2 *cmd) { struct drm_gem_object *obj; + struct drm_framebuffer *fb; /* * Find the GEM object and thus the gtt range object that is @@ -445,7 +446,11 @@ static struct drm_framebuffer *psb_user_framebuffer_create return ERR_PTR(-ENOENT); /* Let the core code do all the work */ - return psb_framebuffer_create(dev, cmd, obj); + fb = psb_framebuffer_create(dev, cmd, obj); + if (IS_ERR(fb)) + drm_gem_object_put(obj); + + return fb; } static int psbfb_probe(struct drm_fb_helper *fb_helper, diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index eb02ecb6e345..65d73eb5e155 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5080,7 +5080,7 @@ static int intel_dp_vsc_sdp_unpack(struct drm_dp_vsc_sdp *vsc, if (size < sizeof(struct dp_sdp)) return -EINVAL; - memset(vsc, 0, size); + memset(vsc, 0, sizeof(*vsc)); if (sdp->sdp_header.HB0 != 0) return -EINVAL; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index bd3046e5a934..0c083af5a59d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -24,7 +24,6 @@ #include "i915_gem_clflush.h" #include "i915_gem_context.h" #include "i915_gem_ioctls.h" -#include "i915_sw_fence_work.h" #include "i915_trace.h" #include "i915_user_extensions.h" @@ -1401,6 +1400,10 @@ static u32 *reloc_gpu(struct i915_execbuffer *eb, int err; struct intel_engine_cs *engine = eb->engine; + /* If we need to copy for the cmdparser, we will stall anyway */ + if (eb_use_cmdparser(eb)) + return ERR_PTR(-EWOULDBLOCK); + if (!reloc_can_use_engine(engine)) { engine = engine->gt->engine_class[COPY_ENGINE_CLASS][0]; if (!engine) @@ -2267,152 +2270,6 @@ shadow_batch_pin(struct i915_execbuffer *eb, return vma; } -struct eb_parse_work { - struct dma_fence_work base; - struct intel_engine_cs *engine; - struct i915_vma *batch; - struct i915_vma *shadow; - struct i915_vma *trampoline; - unsigned long batch_offset; - unsigned long batch_length; -}; - -static int __eb_parse(struct dma_fence_work *work) -{ - struct eb_parse_work *pw = container_of(work, typeof(*pw), base); - - return intel_engine_cmd_parser(pw->engine, - pw->batch, - pw->batch_offset, - pw->batch_length, - pw->shadow, - pw->trampoline); -} - -static void __eb_parse_release(struct dma_fence_work *work) -{ - struct eb_parse_work *pw = container_of(work, typeof(*pw), base); - - if (pw->trampoline) - i915_active_release(&pw->trampoline->active); - i915_active_release(&pw->shadow->active); - i915_active_release(&pw->batch->active); -} - -static const struct dma_fence_work_ops eb_parse_ops = { - .name = "eb_parse", - .work = __eb_parse, - .release = __eb_parse_release, -}; - -static inline int -__parser_mark_active(struct i915_vma *vma, - struct intel_timeline *tl, - struct dma_fence *fence) -{ - struct intel_gt_buffer_pool_node *node = vma->private; - - return i915_active_ref(&node->active, tl->fence_context, fence); -} - -static int -parser_mark_active(struct eb_parse_work *pw, struct intel_timeline *tl) -{ - int err; - - mutex_lock(&tl->mutex); - - err = __parser_mark_active(pw->shadow, tl, &pw->base.dma); - if (err) - goto unlock; - - if (pw->trampoline) { - err = __parser_mark_active(pw->trampoline, tl, &pw->base.dma); - if (err) - goto unlock; - } - -unlock: - mutex_unlock(&tl->mutex); - return err; -} - -static int eb_parse_pipeline(struct i915_execbuffer *eb, - struct i915_vma *shadow, - struct i915_vma *trampoline) -{ - struct eb_parse_work *pw; - int err; - - GEM_BUG_ON(overflows_type(eb->batch_start_offset, pw->batch_offset)); - GEM_BUG_ON(overflows_type(eb->batch_len, pw->batch_length)); - - pw = kzalloc(sizeof(*pw), GFP_KERNEL); - if (!pw) - return -ENOMEM; - - err = i915_active_acquire(&eb->batch->vma->active); - if (err) - goto err_free; - - err = i915_active_acquire(&shadow->active); - if (err) - goto err_batch; - - if (trampoline) { - err = i915_active_acquire(&trampoline->active); - if (err) - goto err_shadow; - } - - dma_fence_work_init(&pw->base, &eb_parse_ops); - - pw->engine = eb->engine; - pw->batch = eb->batch->vma; - pw->batch_offset = eb->batch_start_offset; - pw->batch_length = eb->batch_len; - pw->shadow = shadow; - pw->trampoline = trampoline; - - /* Mark active refs early for this worker, in case we get interrupted */ - err = parser_mark_active(pw, eb->context->timeline); - if (err) - goto err_commit; - - err = dma_resv_reserve_shared(pw->batch->resv, 1); - if (err) - goto err_commit; - - /* Wait for all writes (and relocs) into the batch to complete */ - err = i915_sw_fence_await_reservation(&pw->base.chain, - pw->batch->resv, NULL, false, - 0, I915_FENCE_GFP); - if (err < 0) - goto err_commit; - - /* Keep the batch alive and unwritten as we parse */ - dma_resv_add_shared_fence(pw->batch->resv, &pw->base.dma); - - /* Force execution to wait for completion of the parser */ - dma_resv_add_excl_fence(shadow->resv, &pw->base.dma); - - dma_fence_work_commit_imm(&pw->base); - return 0; - -err_commit: - i915_sw_fence_set_error_once(&pw->base.chain, err); - dma_fence_work_commit_imm(&pw->base); - return err; - -err_shadow: - i915_active_release(&shadow->active); -err_batch: - i915_active_release(&eb->batch->vma->active); -err_free: - kfree(pw); - return err; -} - static struct i915_vma *eb_dispatch_secure(struct i915_execbuffer *eb, struct i915_vma *vma) { /* @@ -2500,7 +2357,11 @@ static int eb_parse(struct i915_execbuffer *eb) goto err_trampoline; } - err = eb_parse_pipeline(eb, shadow, trampoline); + err = intel_engine_cmd_parser(eb->engine, + eb->batch->vma, + eb->batch_start_offset, + eb->batch_len, + shadow, trampoline); if (err) goto err_unpin_batch; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c index ad22f42541bd..4b7afa0fc85d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c @@ -42,7 +42,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) max_order = MAX_ORDER; #ifdef CONFIG_SWIOTLB - if (swiotlb_nr_tbl()) { + if (is_swiotlb_active(obj->base.dev->dev)) { unsigned int max_segment; max_segment = swiotlb_max_segment(); diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c index f08e25e95746..be27f9889431 100644 --- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c +++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c @@ -299,10 +299,7 @@ static void __gen8_ppgtt_alloc(struct i915_address_space * const vm, __i915_gem_object_pin_pages(pt->base); i915_gem_object_make_unshrinkable(pt->base); - if (lvl || - gen8_pt_count(*start, end) < I915_PDES || - intel_vgpu_active(vm->i915)) - fill_px(pt, vm->scratch[lvl]->encode); + fill_px(pt, vm->scratch[lvl]->encode); spin_lock(&pd->lock); if (likely(!pd->entry[idx])) { diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c index b5937b39145a..cd71631bef0c 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c @@ -348,7 +348,7 @@ static struct i915_fence_reg *fence_find(struct i915_ggtt *ggtt) if (intel_has_pending_fb_unpin(ggtt->vm.i915)) return ERR_PTR(-EAGAIN); - return ERR_PTR(-EDEADLK); + return ERR_PTR(-ENOBUFS); } int __i915_vma_pin_fence(struct i915_vma *vma) diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c index 8015964043eb..e25385ad2c1e 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.c +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c @@ -296,6 +296,14 @@ static void intel_timeline_fini(struct intel_timeline *timeline) i915_gem_object_unpin_map(timeline->hwsp_ggtt->obj); i915_vma_put(timeline->hwsp_ggtt); + + /* + * A small race exists between intel_gt_retire_requests_timeout and + * intel_timeline_exit which could result in the syncmap not getting + * free'd. Rather than work to hard to seal this race, simply cleanup + * the syncmap on fini. + */ + i915_syncmap_free(&timeline->sync); } struct intel_timeline * diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index eb342a759943..0b1ea29dcffa 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1728,6 +1728,21 @@ static int elsp_mmio_write(struct intel_vgpu *vgpu, unsigned int offset, if (drm_WARN_ON(&i915->drm, !engine)) return -EINVAL; + /* + * Due to d3_entered is used to indicate skipping PPGTT invalidation on + * vGPU reset, it's set on D0->D3 on PCI config write, and cleared after + * vGPU reset if in resuming. + * In S0ix exit, the device power state also transite from D3 to D0 as + * S3 resume, but no vGPU reset (triggered by QEMU devic model). After + * S0ix exit, all engines continue to work. However the d3_entered + * remains set which will break next vGPU reset logic (miss the expected + * PPGTT invalidation). + * Engines can only work in D0. Thus the 1st elsp write gives GVT a + * chance to clear d3_entered. + */ + if (vgpu->d3_entered) + vgpu->d3_entered = false; + execlist = &vgpu->submission.execlist[engine->id]; execlist->elsp_dwords.data[3 - execlist->elsp_dwords.index] = data; diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 9ce174950340..635aae9145cb 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -1143,27 +1143,30 @@ find_reg(const struct intel_engine_cs *engine, u32 addr) /* Returns a vmap'd pointer to dst_obj, which the caller must unmap */ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, struct drm_i915_gem_object *src_obj, - unsigned long offset, unsigned long length) + u32 offset, u32 length) { - bool needs_clflush; + unsigned int src_needs_clflush; + unsigned int dst_needs_clflush; void *dst, *src; int ret; + ret = i915_gem_object_prepare_write(dst_obj, &dst_needs_clflush); + if (ret) + return ERR_PTR(ret); + dst = i915_gem_object_pin_map(dst_obj, I915_MAP_FORCE_WB); + i915_gem_object_finish_access(dst_obj); if (IS_ERR(dst)) return dst; - ret = i915_gem_object_pin_pages(src_obj); + ret = i915_gem_object_prepare_read(src_obj, &src_needs_clflush); if (ret) { i915_gem_object_unpin_map(dst_obj); return ERR_PTR(ret); } - needs_clflush = - !(src_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ); - src = ERR_PTR(-ENODEV); - if (needs_clflush && i915_has_memcpy_from_wc()) { + if (src_needs_clflush && i915_has_memcpy_from_wc()) { src = i915_gem_object_pin_map(src_obj, I915_MAP_WC); if (!IS_ERR(src)) { i915_unaligned_memcpy_from_wc(dst, @@ -1185,7 +1188,7 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, * validate up to the end of the batch. */ remain = length; - if (!(dst_obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_READ)) + if (dst_needs_clflush & CLFLUSH_BEFORE) remain = round_up(remain, boot_cpu_data.x86_clflush_size); @@ -1195,7 +1198,7 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, int len = min(remain, PAGE_SIZE - x); src = kmap_atomic(i915_gem_object_get_page(src_obj, n)); - if (needs_clflush) + if (src_needs_clflush) drm_clflush_virt_range(src + x, len); memcpy(ptr, src + x, len); kunmap_atomic(src); @@ -1206,11 +1209,10 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, } } - i915_gem_object_unpin_pages(src_obj); + i915_gem_object_finish_access(src_obj); memset32(dst + length, 0, (dst_obj->base.size - length) / sizeof(u32)); - /* dst_obj is returned with vmap pinned */ return dst; } @@ -1417,6 +1419,7 @@ static unsigned long *alloc_whitelist(u32 batch_length) * Return: non-zero if the parser finds violations or otherwise fails; -EACCES * if the batch appears legal but should use hardware parsing */ + int intel_engine_cmd_parser(struct intel_engine_cs *engine, struct i915_vma *batch, unsigned long batch_offset, @@ -1437,7 +1440,8 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, batch->size)); GEM_BUG_ON(!batch_length); - cmd = copy_batch(shadow->obj, batch->obj, batch_offset, batch_length); + cmd = copy_batch(shadow->obj, batch->obj, + batch_offset, batch_length); if (IS_ERR(cmd)) { DRM_DEBUG("CMD: Failed to copy batch\n"); return PTR_ERR(cmd); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index cf6e47adfde6..9ce8f043ad7f 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -727,9 +727,18 @@ static void err_print_gt(struct drm_i915_error_state_buf *m, if (INTEL_GEN(m->i915) >= 12) { int i; - for (i = 0; i < GEN12_SFC_DONE_MAX; i++) + for (i = 0; i < GEN12_SFC_DONE_MAX; i++) { + /* + * SFC_DONE resides in the VD forcewake domain, so it + * only exists if the corresponding VCS engine is + * present. + */ + if (!HAS_ENGINE(gt->_gt, _VCS(i * 2))) + continue; + err_printf(m, " SFC_DONE[%d]: 0x%08x\n", i, gt->sfc_done[i]); + } err_printf(m, " GAM_DONE: 0x%08x\n", gt->gam_done); } @@ -1594,6 +1603,14 @@ static void gt_record_regs(struct intel_gt_coredump *gt) if (INTEL_GEN(i915) >= 12) { for (i = 0; i < GEN12_SFC_DONE_MAX; i++) { + /* + * SFC_DONE resides in the VD forcewake domain, so it + * only exists if the corresponding VCS engine is + * present. + */ + if (!HAS_ENGINE(gt->_gt, _VCS(i * 2))) + continue; + gt->sfc_done[i] = intel_uncore_read(uncore, GEN12_SFC_DONE(i)); } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5cd83eac940c..ce8c91c5fdd3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -413,7 +413,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg) #define GEN11_VECS_SFC_USAGE(engine) _MMIO((engine)->mmio_base + 0x2014) #define GEN11_VECS_SFC_USAGE_BIT (1 << 0) -#define GEN12_SFC_DONE(n) _MMIO(0x1cc00 + (n) * 0x100) +#define GEN12_SFC_DONE(n) _MMIO(0x1cc000 + (n) * 0x1000) #define GEN12_SFC_DONE_MAX 4 #define RING_PP_DIR_BASE(base) _MMIO((base) + 0x228) diff --git a/drivers/gpu/drm/i915/i915_request.c b/drivers/gpu/drm/i915/i915_request.c index 0e813819b041..d8fef42ca38e 100644 --- a/drivers/gpu/drm/i915/i915_request.c +++ b/drivers/gpu/drm/i915/i915_request.c @@ -1285,10 +1285,8 @@ i915_request_await_execution(struct i915_request *rq, do { fence = *child++; - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { - i915_sw_fence_set_error_once(&rq->submit, fence->error); + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) continue; - } if (fence->context == rq->fence.context) continue; @@ -1386,10 +1384,8 @@ i915_request_await_dma_fence(struct i915_request *rq, struct dma_fence *fence) do { fence = *child++; - if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) { - i915_sw_fence_set_error_once(&rq->submit, fence->error); + if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) continue; - } /* * Requests on the same timeline are explicitly ordered, along diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index a3d1617d7c67..b6bb5fc7d183 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -347,7 +347,7 @@ static void ingenic_drm_plane_enable(struct ingenic_drm *priv, unsigned int en_bit; if (priv->soc_info->has_osd) { - if (plane->type == DRM_PLANE_TYPE_PRIMARY) + if (plane != &priv->f0) en_bit = JZ_LCD_OSDC_F1EN; else en_bit = JZ_LCD_OSDC_F0EN; @@ -362,7 +362,7 @@ void ingenic_drm_plane_disable(struct device *dev, struct drm_plane *plane) unsigned int en_bit; if (priv->soc_info->has_osd) { - if (plane->type == DRM_PLANE_TYPE_PRIMARY) + if (plane != &priv->f0) en_bit = JZ_LCD_OSDC_F1EN; else en_bit = JZ_LCD_OSDC_F0EN; @@ -389,8 +389,7 @@ void ingenic_drm_plane_config(struct device *dev, ingenic_drm_plane_enable(priv, plane); - if (priv->soc_info->has_osd && - plane->type == DRM_PLANE_TYPE_PRIMARY) { + if (priv->soc_info->has_osd && plane != &priv->f0) { switch (fourcc) { case DRM_FORMAT_XRGB1555: ctrl |= JZ_LCD_OSDCTRL_RGB555; @@ -423,7 +422,7 @@ void ingenic_drm_plane_config(struct device *dev, } if (priv->soc_info->has_osd) { - if (plane->type == DRM_PLANE_TYPE_PRIMARY) { + if (plane != &priv->f0) { xy_reg = JZ_REG_LCD_XYP1; size_reg = JZ_REG_LCD_SIZE1; } else { @@ -455,7 +454,7 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, height = state->src_h >> 16; cpp = state->fb->format->cpp[0]; - if (priv->soc_info->has_osd && plane->type == DRM_PLANE_TYPE_OVERLAY) + if (!priv->soc_info->has_osd || plane == &priv->f0) hwdesc = priv->dma_hwdesc_f0; else hwdesc = priv->dma_hwdesc_f1; @@ -692,6 +691,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) const struct jz_soc_info *soc_info; struct ingenic_drm *priv; struct clk *parent_clk; + struct drm_plane *primary; struct drm_bridge *bridge; struct drm_panel *panel; struct drm_encoder *encoder; @@ -784,9 +784,11 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) if (soc_info->has_osd) priv->ipu_plane = drm_plane_from_index(drm, 0); - drm_plane_helper_add(&priv->f1, &ingenic_drm_plane_helper_funcs); + primary = priv->soc_info->has_osd ? &priv->f1 : &priv->f0; + + drm_plane_helper_add(primary, &ingenic_drm_plane_helper_funcs); - ret = drm_universal_plane_init(drm, &priv->f1, 1, + ret = drm_universal_plane_init(drm, primary, 1, &ingenic_drm_primary_plane_funcs, ingenic_drm_primary_formats, ARRAY_SIZE(ingenic_drm_primary_formats), @@ -798,7 +800,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) drm_crtc_helper_add(&priv->crtc, &ingenic_drm_crtc_helper_funcs); - ret = drm_crtc_init_with_planes(drm, &priv->crtc, &priv->f1, + ret = drm_crtc_init_with_planes(drm, &priv->crtc, primary, NULL, &ingenic_drm_crtc_funcs, NULL); if (ret) { dev_err(dev, "Failed to init CRTC: %i\n", ret); diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c b/drivers/gpu/drm/ingenic/ingenic-ipu.c index fc8c6e970ee3..06fd118b1444 100644 --- a/drivers/gpu/drm/ingenic/ingenic-ipu.c +++ b/drivers/gpu/drm/ingenic/ingenic-ipu.c @@ -753,7 +753,7 @@ static int ingenic_ipu_bind(struct device *dev, struct device *master, void *d) err = drm_universal_plane_init(drm, plane, 1, &ingenic_ipu_plane_funcs, soc_info->formats, soc_info->num_formats, - NULL, DRM_PLANE_TYPE_PRIMARY, NULL); + NULL, DRM_PLANE_TYPE_OVERLAY, NULL); if (err) { dev_err(dev, "Failed to init plane: %i\n", err); return err; diff --git a/drivers/gpu/drm/mcde/mcde_dsi.c b/drivers/gpu/drm/mcde/mcde_dsi.c index b3fd3501c412..5275b2723293 100644 --- a/drivers/gpu/drm/mcde/mcde_dsi.c +++ b/drivers/gpu/drm/mcde/mcde_dsi.c @@ -577,7 +577,7 @@ static void mcde_dsi_setup_video_mode(struct mcde_dsi *d, * porches and sync. */ /* (ps/s) / (pixels/s) = ps/pixels */ - pclk = DIV_ROUND_UP_ULL(1000000000000, mode->clock); + pclk = DIV_ROUND_UP_ULL(1000000000000, (mode->clock * 1000)); dev_dbg(d->dev, "picoseconds between two pixels: %llu\n", pclk); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c index ac038572164d..dfd5ed15a7f4 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -274,7 +274,7 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc) drm_connector_list_iter_end(&conn_iter); } - ret = pm_runtime_get_sync(crtc->dev->dev); + ret = pm_runtime_resume_and_get(crtc->dev->dev); if (ret < 0) { DRM_ERROR("Failed to enable power domain: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c index 3064eac1a750..e747ff7ba3dc 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c @@ -34,6 +34,7 @@ #define DISP_AAL_EN 0x0000 #define DISP_AAL_SIZE 0x0030 +#define DISP_AAL_OUTPUT_SIZE 0x04d8 #define DISP_CCORR_EN 0x0000 #define CCORR_EN BIT(0) @@ -180,7 +181,8 @@ static void mtk_aal_config(struct mtk_ddp_comp *comp, unsigned int w, unsigned int h, unsigned int vrefresh, unsigned int bpc, struct cmdq_pkt *cmdq_pkt) { - mtk_ddp_write(cmdq_pkt, h << 16 | w, comp, DISP_AAL_SIZE); + mtk_ddp_write(cmdq_pkt, w << 16 | h, comp, DISP_AAL_SIZE); + mtk_ddp_write(cmdq_pkt, w << 16 | h, comp, DISP_AAL_OUTPUT_SIZE); } static void mtk_aal_start(struct mtk_ddp_comp *comp) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h index 1d9e00b69462..5aa52b7afeec 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h @@ -7,6 +7,7 @@ #define MTK_DRM_DDP_COMP_H #include +#include struct device; struct device_node; @@ -35,39 +36,6 @@ enum mtk_ddp_comp_type { MTK_DDP_COMP_TYPE_MAX, }; -enum mtk_ddp_comp_id { - DDP_COMPONENT_AAL0, - DDP_COMPONENT_AAL1, - DDP_COMPONENT_BLS, - DDP_COMPONENT_CCORR, - DDP_COMPONENT_COLOR0, - DDP_COMPONENT_COLOR1, - DDP_COMPONENT_DITHER, - DDP_COMPONENT_DPI0, - DDP_COMPONENT_DPI1, - DDP_COMPONENT_DSI0, - DDP_COMPONENT_DSI1, - DDP_COMPONENT_DSI2, - DDP_COMPONENT_DSI3, - DDP_COMPONENT_GAMMA, - DDP_COMPONENT_OD0, - DDP_COMPONENT_OD1, - DDP_COMPONENT_OVL0, - DDP_COMPONENT_OVL_2L0, - DDP_COMPONENT_OVL_2L1, - DDP_COMPONENT_OVL1, - DDP_COMPONENT_PWM0, - DDP_COMPONENT_PWM1, - DDP_COMPONENT_PWM2, - DDP_COMPONENT_RDMA0, - DDP_COMPONENT_RDMA1, - DDP_COMPONENT_RDMA2, - DDP_COMPONENT_UFOE, - DDP_COMPONENT_WDMA0, - DDP_COMPONENT_WDMA1, - DDP_COMPONENT_ID_MAX, -}; - struct mtk_ddp_comp; struct cmdq_pkt; struct mtk_ddp_comp_funcs { diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h index 446e7961da48..0f3cafab8860 100644 --- a/drivers/gpu/drm/meson/meson_registers.h +++ b/drivers/gpu/drm/meson/meson_registers.h @@ -634,6 +634,11 @@ #define VPP_WRAP_OSD3_MATRIX_PRE_OFFSET2 0x3dbc #define VPP_WRAP_OSD3_MATRIX_EN_CTRL 0x3dbd +/* osd1 HDR */ +#define OSD1_HDR2_CTRL 0x38a0 +#define OSD1_HDR2_CTRL_VDIN0_HDR2_TOP_EN BIT(13) +#define OSD1_HDR2_CTRL_REG_ONLY_MAT BIT(16) + /* osd2 scaler */ #define OSD2_VSC_PHASE_STEP 0x3d00 #define OSD2_VSC_INI_PHASE 0x3d01 diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c index aede0c67a57f..259f3e6bec90 100644 --- a/drivers/gpu/drm/meson/meson_viu.c +++ b/drivers/gpu/drm/meson/meson_viu.c @@ -425,9 +425,14 @@ void meson_viu_init(struct meson_drm *priv) if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) meson_viu_load_matrix(priv); - else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) + else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { meson_viu_set_g12a_osd1_matrix(priv, RGB709_to_YUV709l_coeff, true); + /* fix green/pink color distortion from vendor u-boot */ + writel_bits_relaxed(OSD1_HDR2_CTRL_REG_ONLY_MAT | + OSD1_HDR2_CTRL_VDIN0_HDR2_TOP_EN, 0, + priv->io_base + _REG(OSD1_HDR2_CTRL)); + } /* Initialize OSD1 fifo control register */ reg = VIU_OSD_DDR_PRIORITY_URGENT | diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 722c2fe3bfd5..2dcbe02846cd 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -154,7 +154,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) * GPU registers so we need to add 0x1a800 to the register value on A630 * to get the right value from PM4. */ - get_stats_counter(ring, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L + 0x1a800, + get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO, rbmemptr_stats(ring, index, alwayson_start)); /* Invalidate CCU depth and color */ @@ -184,7 +184,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP_0_LO, rbmemptr_stats(ring, index, cpcycles_end)); - get_stats_counter(ring, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L + 0x1a800, + get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO, rbmemptr_stats(ring, index, alwayson_end)); /* Write the fence to the scratch register */ @@ -203,8 +203,8 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) OUT_RING(ring, submit->seqno); trace_msm_gpu_submit_flush(submit, - gmu_read64(&a6xx_gpu->gmu, REG_A6XX_GMU_ALWAYS_ON_COUNTER_L, - REG_A6XX_GMU_ALWAYS_ON_COUNTER_H)); + gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO, + REG_A6XX_CP_ALWAYS_ON_COUNTER_HI)); a6xx_flush(gpu, ring); } @@ -459,6 +459,113 @@ static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state) gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0); } +/* For a615, a616, a618, A619, a630, a640 and a680 */ +static const u32 a6xx_protect[] = { + A6XX_PROTECT_RDONLY(0x00000, 0x04ff), + A6XX_PROTECT_RDONLY(0x00501, 0x0005), + A6XX_PROTECT_RDONLY(0x0050b, 0x02f4), + A6XX_PROTECT_NORDWR(0x0050e, 0x0000), + A6XX_PROTECT_NORDWR(0x00510, 0x0000), + A6XX_PROTECT_NORDWR(0x00534, 0x0000), + A6XX_PROTECT_NORDWR(0x00800, 0x0082), + A6XX_PROTECT_NORDWR(0x008a0, 0x0008), + A6XX_PROTECT_NORDWR(0x008ab, 0x0024), + A6XX_PROTECT_RDONLY(0x008de, 0x00ae), + A6XX_PROTECT_NORDWR(0x00900, 0x004d), + A6XX_PROTECT_NORDWR(0x0098d, 0x0272), + A6XX_PROTECT_NORDWR(0x00e00, 0x0001), + A6XX_PROTECT_NORDWR(0x00e03, 0x000c), + A6XX_PROTECT_NORDWR(0x03c00, 0x00c3), + A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff), + A6XX_PROTECT_NORDWR(0x08630, 0x01cf), + A6XX_PROTECT_NORDWR(0x08e00, 0x0000), + A6XX_PROTECT_NORDWR(0x08e08, 0x0000), + A6XX_PROTECT_NORDWR(0x08e50, 0x001f), + A6XX_PROTECT_NORDWR(0x09624, 0x01db), + A6XX_PROTECT_NORDWR(0x09e70, 0x0001), + A6XX_PROTECT_NORDWR(0x09e78, 0x0187), + A6XX_PROTECT_NORDWR(0x0a630, 0x01cf), + A6XX_PROTECT_NORDWR(0x0ae02, 0x0000), + A6XX_PROTECT_NORDWR(0x0ae50, 0x032f), + A6XX_PROTECT_NORDWR(0x0b604, 0x0000), + A6XX_PROTECT_NORDWR(0x0be02, 0x0001), + A6XX_PROTECT_NORDWR(0x0be20, 0x17df), + A6XX_PROTECT_NORDWR(0x0f000, 0x0bff), + A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff), + A6XX_PROTECT_NORDWR(0x11c00, 0x0000), /* note: infinite range */ +}; + +/* These are for a620 and a650 */ +static const u32 a650_protect[] = { + A6XX_PROTECT_RDONLY(0x00000, 0x04ff), + A6XX_PROTECT_RDONLY(0x00501, 0x0005), + A6XX_PROTECT_RDONLY(0x0050b, 0x02f4), + A6XX_PROTECT_NORDWR(0x0050e, 0x0000), + A6XX_PROTECT_NORDWR(0x00510, 0x0000), + A6XX_PROTECT_NORDWR(0x00534, 0x0000), + A6XX_PROTECT_NORDWR(0x00800, 0x0082), + A6XX_PROTECT_NORDWR(0x008a0, 0x0008), + A6XX_PROTECT_NORDWR(0x008ab, 0x0024), + A6XX_PROTECT_RDONLY(0x008de, 0x00ae), + A6XX_PROTECT_NORDWR(0x00900, 0x004d), + A6XX_PROTECT_NORDWR(0x0098d, 0x0272), + A6XX_PROTECT_NORDWR(0x00e00, 0x0001), + A6XX_PROTECT_NORDWR(0x00e03, 0x000c), + A6XX_PROTECT_NORDWR(0x03c00, 0x00c3), + A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff), + A6XX_PROTECT_NORDWR(0x08630, 0x01cf), + A6XX_PROTECT_NORDWR(0x08e00, 0x0000), + A6XX_PROTECT_NORDWR(0x08e08, 0x0000), + A6XX_PROTECT_NORDWR(0x08e50, 0x001f), + A6XX_PROTECT_NORDWR(0x08e80, 0x027f), + A6XX_PROTECT_NORDWR(0x09624, 0x01db), + A6XX_PROTECT_NORDWR(0x09e60, 0x0011), + A6XX_PROTECT_NORDWR(0x09e78, 0x0187), + A6XX_PROTECT_NORDWR(0x0a630, 0x01cf), + A6XX_PROTECT_NORDWR(0x0ae02, 0x0000), + A6XX_PROTECT_NORDWR(0x0ae50, 0x032f), + A6XX_PROTECT_NORDWR(0x0b604, 0x0000), + A6XX_PROTECT_NORDWR(0x0b608, 0x0007), + A6XX_PROTECT_NORDWR(0x0be02, 0x0001), + A6XX_PROTECT_NORDWR(0x0be20, 0x17df), + A6XX_PROTECT_NORDWR(0x0f000, 0x0bff), + A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff), + A6XX_PROTECT_NORDWR(0x18400, 0x1fff), + A6XX_PROTECT_NORDWR(0x1a800, 0x1fff), + A6XX_PROTECT_NORDWR(0x1f400, 0x0443), + A6XX_PROTECT_RDONLY(0x1f844, 0x007b), + A6XX_PROTECT_NORDWR(0x1f887, 0x001b), + A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000), /* note: infinite range */ +}; + +static void a6xx_set_cp_protect(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + const u32 *regs = a6xx_protect; + unsigned i, count = ARRAY_SIZE(a6xx_protect), count_max = 32; + + BUILD_BUG_ON(ARRAY_SIZE(a6xx_protect) > 32); + BUILD_BUG_ON(ARRAY_SIZE(a650_protect) > 48); + + if (adreno_is_a650(adreno_gpu)) { + regs = a650_protect; + count = ARRAY_SIZE(a650_protect); + count_max = 48; + } + + /* + * Enable access protection to privileged registers, fault on an access + * protect violation and select the last span to protect from the start + * address all the way to the end of the register address space + */ + gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, BIT(0) | BIT(1) | BIT(3)); + + for (i = 0; i < count - 1; i++) + gpu_write(gpu, REG_A6XX_CP_PROTECT(i), regs[i]); + /* last CP_PROTECT to have "infinite" length on the last entry */ + gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]); +} + static void a6xx_set_ubwc_config(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); @@ -486,7 +593,7 @@ static void a6xx_set_ubwc_config(struct msm_gpu *gpu) rgb565_predicator << 11 | amsbc << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, lower_bit << 1); gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, - uavflagprd_inv >> 4 | lower_bit << 1); + uavflagprd_inv << 4 | lower_bit << 1); gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL, lower_bit << 21); } @@ -722,41 +829,7 @@ static int a6xx_hw_init(struct msm_gpu *gpu) } /* Protect registers from the CP */ - gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL, 0x00000003); - - gpu_write(gpu, REG_A6XX_CP_PROTECT(0), - A6XX_PROTECT_RDONLY(0x600, 0x51)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(1), A6XX_PROTECT_RW(0xae50, 0x2)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(2), A6XX_PROTECT_RW(0x9624, 0x13)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(3), A6XX_PROTECT_RW(0x8630, 0x8)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(4), A6XX_PROTECT_RW(0x9e70, 0x1)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(5), A6XX_PROTECT_RW(0x9e78, 0x187)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(6), A6XX_PROTECT_RW(0xf000, 0x810)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(7), - A6XX_PROTECT_RDONLY(0xfc00, 0x3)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(8), A6XX_PROTECT_RW(0x50e, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(9), A6XX_PROTECT_RDONLY(0x50f, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(10), A6XX_PROTECT_RW(0x510, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(11), - A6XX_PROTECT_RDONLY(0x0, 0x4f9)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(12), - A6XX_PROTECT_RDONLY(0x501, 0xa)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(13), - A6XX_PROTECT_RDONLY(0x511, 0x44)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(14), A6XX_PROTECT_RW(0xe00, 0xe)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(15), A6XX_PROTECT_RW(0x8e00, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(16), A6XX_PROTECT_RW(0x8e50, 0xf)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(17), A6XX_PROTECT_RW(0xbe02, 0x0)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(18), - A6XX_PROTECT_RW(0xbe20, 0x11f3)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(19), A6XX_PROTECT_RW(0x800, 0x82)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(20), A6XX_PROTECT_RW(0x8a0, 0x8)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(21), A6XX_PROTECT_RW(0x8ab, 0x19)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(22), A6XX_PROTECT_RW(0x900, 0x4d)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(23), A6XX_PROTECT_RW(0x98d, 0x76)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(24), - A6XX_PROTECT_RDONLY(0x980, 0x4)); - gpu_write(gpu, REG_A6XX_CP_PROTECT(25), A6XX_PROTECT_RW(0xa630, 0x0)); + a6xx_set_cp_protect(gpu); /* Enable expanded apriv for targets that support it */ if (gpu->hw_apriv) { @@ -1055,7 +1128,7 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu) if (ret) return ret; - if (adreno_gpu->base.hw_apriv || a6xx_gpu->has_whereami) + if (a6xx_gpu->shadow_bo) for (i = 0; i < gpu->nr_rings; i++) a6xx_gpu->shadow[i] = 0; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h index 3eeebf6a754b..69765a722cae 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h @@ -37,7 +37,7 @@ struct a6xx_gpu { * REG_CP_PROTECT_REG(n) - this will block both reads and writes for _len * registers starting at _reg. */ -#define A6XX_PROTECT_RW(_reg, _len) \ +#define A6XX_PROTECT_NORDWR(_reg, _len) \ ((1 << 31) | \ (((_len) & 0x3FFF) << 18) | ((_reg) & 0x3FFFF)) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 60b304b72b7c..b39980b9db1d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -168,7 +168,7 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = { static const struct dpu_mdp_cfg sm8250_mdp[] = { { .name = "top_0", .id = MDP_TOP, - .base = 0x0, .len = 0x45C, + .base = 0x0, .len = 0x494, .features = 0, .highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */ .clk_ctrls[DPU_CLK_CTRL_VIG0] = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c index 3416e9617ee9..96f3908e4c5b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c @@ -222,7 +222,7 @@ int dpu_mdss_init(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; struct dpu_mdss *dpu_mdss; struct dss_module_power *mp; - int ret = 0; + int ret; int irq; dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL); @@ -250,8 +250,10 @@ int dpu_mdss_init(struct drm_device *dev) goto irq_domain_error; irq = platform_get_irq(pdev, 0); - if (irq < 0) + if (irq < 0) { + ret = irq; goto irq_error; + } irq_set_chained_handler_and_data(irq, dpu_mdss_irq, dpu_mdss); @@ -260,7 +262,7 @@ int dpu_mdss_init(struct drm_device *dev) pm_runtime_enable(dev->dev); - return ret; + return 0; irq_error: _dpu_mdss_irq_domain_fini(dpu_mdss); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c index dbf8d429223e..2f75e3905202 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_kms.c @@ -88,8 +88,6 @@ static int mdp4_hw_init(struct msm_kms *kms) if (mdp4_kms->rev > 1) mdp4_write(mdp4_kms, REG_MDP4_RESET_STATUS, 1); - dev->mode_config.allow_fb_modifiers = true; - out: pm_runtime_put_sync(dev->dev); diff --git a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c index da3cc1d8c331..ee1dbb2b84af 100644 --- a/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp4/mdp4_plane.c @@ -347,6 +347,12 @@ enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane) return mdp4_plane->pipe; } +static const uint64_t supported_format_modifiers[] = { + DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + /* initialize plane */ struct drm_plane *mdp4_plane_init(struct drm_device *dev, enum mdp4_pipe pipe_id, bool private_plane) @@ -375,7 +381,7 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev, type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, mdp4_plane->formats, mdp4_plane->nformats, - NULL, type, NULL); + supported_format_modifiers, type, NULL); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 4963bfe6a472..aeca8b2ac5c6 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -740,6 +740,7 @@ int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog) dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY, dp_catalog->width_blanking); dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active); + dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0); return 0; } diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 0aacc43faefa..edee4c2a76ce 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -505,6 +505,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) priv->event_thread[i].worker = kthread_create_worker(0, "crtc_event:%d", priv->event_thread[i].crtc_id); if (IS_ERR(priv->event_thread[i].worker)) { + ret = PTR_ERR(priv->event_thread[i].worker); DRM_DEV_ERROR(dev, "failed to create crtc_event kthread\n"); goto err_msm_uninit; } diff --git a/drivers/gpu/drm/mxsfb/Kconfig b/drivers/gpu/drm/mxsfb/Kconfig index 0143d539f8f8..ee22cd25d3e3 100644 --- a/drivers/gpu/drm/mxsfb/Kconfig +++ b/drivers/gpu/drm/mxsfb/Kconfig @@ -10,7 +10,6 @@ config DRM_MXSFB depends on COMMON_CLK select DRM_MXS select DRM_KMS_HELPER - select DRM_KMS_FB_HELPER select DRM_KMS_CMA_HELPER select DRM_PANEL select DRM_PANEL_BRIDGE diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 5b8cabb099eb..c2d34c91e840 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -2202,6 +2202,33 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) interlock[NV50_DISP_INTERLOCK_CORE] = 0; } + /* Finish updating head(s)... + * + * NVD is rather picky about both where window assignments can change, + * *and* about certain core and window channel states matching. + * + * The EFI GOP driver on newer GPUs configures window channels with a + * different output format to what we do, and the core channel update + * in the assign_windows case above would result in a state mismatch. + * + * Delay some of the head update until after that point to workaround + * the issue. This only affects the initial modeset. + * + * TODO: handle this better when adding flexible window mapping + */ + for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { + struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state); + struct nv50_head *head = nv50_head(crtc); + + NV_ATOMIC(drm, "%s: set %04x (clr %04x)\n", crtc->name, + asyh->set.mask, asyh->clr.mask); + + if (asyh->set.mask) { + nv50_head_flush_set_wndw(head, asyh); + interlock[NV50_DISP_INTERLOCK_CORE] = 1; + } + } + /* Update plane(s). */ for_each_new_plane_in_state(state, plane, new_plane_state, i) { struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state); diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index 841edfaf5b9d..61826cac3061 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -49,11 +49,8 @@ nv50_head_flush_clr(struct nv50_head *head, } void -nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) +nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh) { - if (asyh->set.view ) head->func->view (head, asyh); - if (asyh->set.mode ) head->func->mode (head, asyh); - if (asyh->set.core ) head->func->core_set(head, asyh); if (asyh->set.olut ) { asyh->olut.offset = nv50_lut_load(&head->olut, asyh->olut.buffer, @@ -61,6 +58,14 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) asyh->olut.load); head->func->olut_set(head, asyh); } +} + +void +nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) +{ + if (asyh->set.view ) head->func->view (head, asyh); + if (asyh->set.mode ) head->func->mode (head, asyh); + if (asyh->set.core ) head->func->core_set(head, asyh); if (asyh->set.curs ) head->func->curs_set(head, asyh); if (asyh->set.base ) head->func->base (head, asyh); if (asyh->set.ovly ) head->func->ovly (head, asyh); diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.h b/drivers/gpu/drm/nouveau/dispnv50/head.h index dae841dc05fd..0bac6be9ba34 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.h +++ b/drivers/gpu/drm/nouveau/dispnv50/head.h @@ -21,6 +21,7 @@ struct nv50_head { struct nv50_head *nv50_head_create(struct drm_device *, int index); void nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh); +void nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh); void nv50_head_flush_clr(struct nv50_head *head, struct nv50_head_atom *asyh, bool flush); diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 7daa12eec01b..5679552cde32 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -590,7 +590,7 @@ nouveau_bo_sync_for_device(struct nouveau_bo *nvbo) struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm; int i; - if (!ttm_dma) + if (!ttm_dma || !ttm_dma->dma_address) return; /* Don't waste time looping if the object is coherent */ @@ -610,7 +610,7 @@ nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo) struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm; int i; - if (!ttm_dma) + if (!ttm_dma || !ttm_dma->dma_address) return; /* Don't waste time looping if the object is coherent */ @@ -1328,7 +1328,7 @@ nouveau_ttm_tt_populate(struct ttm_bo_device *bdev, #endif #if IS_ENABLED(CONFIG_SWIOTLB) && IS_ENABLED(CONFIG_X86) - if (swiotlb_nr_tbl()) { + if (is_swiotlb_active(dev)) { return ttm_dma_populate((void *)ttm, dev, ctx); } #endif @@ -1358,7 +1358,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_bo_device *bdev, #endif #if IS_ENABLED(CONFIG_SWIOTLB) && IS_ENABLED(CONFIG_X86) - if (swiotlb_nr_tbl()) { + if (is_swiotlb_active(dev)) { ttm_dma_unpopulate((void *)ttm, dev); return; } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index bceb48a2dfca..f2ad6f49fb72 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -700,7 +700,6 @@ nouveau_display_create(struct drm_device *dev) dev->mode_config.preferred_depth = 24; dev->mode_config.prefer_shadow = 1; - dev->mode_config.allow_fb_modifiers = true; if (drm->client.device.info.chipset < 0x11) dev->mode_config.async_page_flip = false; diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index b2ecb91f8ddc..5f5b87f99546 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -111,7 +111,22 @@ int nouveau_gem_prime_pin(struct drm_gem_object *obj) if (ret) return -EINVAL; - return 0; + ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL); + if (ret) + goto error; + + if (nvbo->bo.moving) + ret = dma_fence_wait(nvbo->bo.moving, true); + + ttm_bo_unreserve(&nvbo->bo); + if (ret) + goto error; + + return ret; + +error: + nouveau_bo_unpin(nvbo); + return ret; } void nouveau_gem_prime_unpin(struct drm_gem_object *obj) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c index 3800aeb507d0..2a7b8bc3ec4d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c @@ -419,7 +419,7 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps) return ret; } -static void +void nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior) { struct nvkm_dp *dp = nvkm_dp(outp); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h index 428b3f488f03..e484d0c3b0d4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.h @@ -32,6 +32,7 @@ struct nvkm_dp { int nvkm_dp_new(struct nvkm_disp *, int index, struct dcb_output *, struct nvkm_outp **); +void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *); /* DPCD Receiver Capabilities */ #define DPCD_RC00_DPCD_REV 0x00000 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c index dffcac249211..129982fef7ef 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "outp.h" +#include "dp.h" #include "ior.h" #include @@ -257,6 +258,14 @@ nvkm_outp_init_route(struct nvkm_outp *outp) if (!ior->arm.head || ior->arm.proto != proto) { OUTP_DBG(outp, "no heads (%x %d %d)", ior->arm.head, ior->arm.proto, proto); + + /* The EFI GOP driver on Ampere can leave unused DP links routed, + * which we don't expect. The DisableLT IED script *should* get + * us back to where we need to be. + */ + if (ior->func->route.get && !ior->arm.head && outp->info.type == DCB_OUTPUT_DP) + nvkm_dp_disable(outp, ior); + return; } diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35510.c b/drivers/gpu/drm/panel/panel-novatek-nt35510.c index ef70140c5b09..873cbd38e6d3 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt35510.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt35510.c @@ -706,9 +706,7 @@ static int nt35510_power_on(struct nt35510 *nt) if (ret) return ret; - ret = nt35510_read_id(nt); - if (ret) - return ret; + nt35510_read_id(nt); /* Set up stuff in manufacturer control, page 1 */ ret = nt35510_send_long(nt, dsi, MCS_CMD_MAUCCTR, diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c index 5e9ccefb88f6..bbdd086be7f5 100644 --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c @@ -447,7 +447,6 @@ static int rpi_touchscreen_remove(struct i2c_client *i2c) drm_panel_remove(&ts->base); mipi_dsi_device_unregister(ts->dsi); - kfree(ts->dsi); return 0; } diff --git a/drivers/gpu/drm/pl111/Kconfig b/drivers/gpu/drm/pl111/Kconfig index 80f6748055e3..3aae387a96af 100644 --- a/drivers/gpu/drm/pl111/Kconfig +++ b/drivers/gpu/drm/pl111/Kconfig @@ -3,6 +3,7 @@ config DRM_PL111 tristate "DRM Support for PL111 CLCD Controller" depends on DRM depends on ARM || ARM64 || COMPILE_TEST + depends on VEXPRESS_CONFIG || VEXPRESS_CONFIG=n depends on COMMON_CLK select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c index c04cd5a2553c..e377bdbff90d 100644 --- a/drivers/gpu/drm/qxl/qxl_dumb.c +++ b/drivers/gpu/drm/qxl/qxl_dumb.c @@ -58,6 +58,8 @@ int qxl_mode_dumb_create(struct drm_file *file_priv, surf.height = args->height; surf.stride = pitch; surf.format = format; + surf.data = 0; + r = qxl_gem_object_create_with_handle(qdev, file_priv, QXL_GEM_DOMAIN_SURFACE, args->size, &surf, &qobj, diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index e0ae911ef427..71bdafac9210 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1334,6 +1334,7 @@ radeon_user_framebuffer_create(struct drm_device *dev, /* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */ if (obj->import_attach) { DRM_DEBUG_KMS("Cannot create framebuffer from imported dma_buf\n"); + drm_gem_object_put(obj); return ERR_PTR(-EINVAL); } diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 4cd30613fa1d..e9df5e8ef0a5 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -416,13 +416,13 @@ radeon_pci_shutdown(struct pci_dev *pdev) if (radeon_device_is_virtual()) radeon_pci_remove(pdev); -#ifdef CONFIG_PPC64 +#if defined(CONFIG_PPC64) || defined(CONFIG_MACH_LOONGSON64) /* * Some adapters need to be suspended before a * shutdown occurs in order to prevent an error - * during kexec. - * Make this power specific becauase it breaks - * some non-power boards. + * during kexec, shutdown or reboot. + * Make this power and Loongson specific because + * it breaks some other boards. */ radeon_suspend_kms(pci_get_drvdata(pdev), true, true, false); #endif diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c index b9de0e51c0be..cbad81578190 100644 --- a/drivers/gpu/drm/radeon/radeon_prime.c +++ b/drivers/gpu/drm/radeon/radeon_prime.c @@ -94,9 +94,19 @@ int radeon_gem_prime_pin(struct drm_gem_object *obj) /* pin buffer into GTT */ ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL); - if (likely(ret == 0)) - bo->prime_shared_count++; - + if (unlikely(ret)) + goto error; + + if (bo->tbo.moving) { + ret = dma_fence_wait(bo->tbo.moving, false); + if (unlikely(ret)) { + radeon_bo_unpin(bo); + goto error; + } + } + + bo->prime_shared_count++; +error: radeon_bo_unreserve(bo); return ret; } diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index a65cb349fac2..93e2794d5b8f 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -658,7 +658,7 @@ static int radeon_ttm_tt_populate(struct ttm_bo_device *bdev, #endif #ifdef CONFIG_SWIOTLB - if (rdev->need_swiotlb && swiotlb_nr_tbl()) { + if (rdev->need_swiotlb && is_swiotlb_active(rdev->dev)) { return ttm_dma_populate(>t->ttm, rdev->dev, ctx); } #endif @@ -689,7 +689,7 @@ static void radeon_ttm_tt_unpopulate(struct ttm_bo_device *bdev, struct ttm_tt * #endif #ifdef CONFIG_SWIOTLB - if (rdev->need_swiotlb && swiotlb_nr_tbl()) { + if (rdev->need_swiotlb && is_swiotlb_active(rdev->dev)) { ttm_dma_unpopulate(>t->ttm, rdev->dev); return; } @@ -1100,7 +1100,7 @@ static int radeon_ttm_debugfs_init(struct radeon_device *rdev) count = ARRAY_SIZE(radeon_ttm_debugfs_list); #ifdef CONFIG_SWIOTLB - if (!(rdev->need_swiotlb && swiotlb_nr_tbl())) + if (!(rdev->need_swiotlb && is_swiotlb_active(rdev->dev))) --count; #endif diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 57fb3eb3a4b4..1f4e3396d097 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c @@ -286,7 +286,7 @@ int radeon_uvd_resume(struct radeon_device *rdev) if (rdev->uvd.vcpu_bo == NULL) return -EINVAL; - memcpy(rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); + memcpy_toio((void __iomem *)rdev->uvd.cpu_addr, rdev->uvd_fw->data, rdev->uvd_fw->size); size = radeon_bo_size(rdev->uvd.vcpu_bo); size -= rdev->uvd_fw->size; @@ -294,7 +294,7 @@ int radeon_uvd_resume(struct radeon_device *rdev) ptr = rdev->uvd.cpu_addr; ptr += rdev->uvd_fw->size; - memset(ptr, 0, size); + memset_io((void __iomem *)ptr, 0, size); return 0; } diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c index a4a45daf93f2..6802d9b65f82 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -73,6 +73,7 @@ static int cdn_dp_grf_write(struct cdn_dp_device *dp, ret = regmap_write(dp->grf, reg, val); if (ret) { DRM_DEV_ERROR(dp->dev, "Could not write to GRF: %d\n", ret); + clk_disable_unprepare(dp->grf_clk); return ret; } diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c index 9d2163ef4d6e..33fb4d05c506 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c @@ -658,7 +658,7 @@ int cdn_dp_config_video(struct cdn_dp_device *dp) */ do { tu_size_reg += 2; - symbol = tu_size_reg * mode->clock * bit_per_pix; + symbol = (u64)tu_size_reg * mode->clock * bit_per_pix; do_div(symbol, dp->max_lanes * link_rate * 8); rem = do_div(symbol, 1000); if (tu_size_reg > 64) { diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c index 542dcf7eddd6..d0c9610ad220 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -243,7 +243,6 @@ struct dw_mipi_dsi_rockchip { struct dw_mipi_dsi *dmd; const struct rockchip_dw_dsi_chip_data *cdata; struct dw_mipi_dsi_plat_data pdata; - int devcnt; }; struct dphy_pll_parameter_map { @@ -692,13 +691,8 @@ static const struct dw_mipi_dsi_phy_ops dw_mipi_dsi_rockchip_phy_ops = { .get_timing = dw_mipi_dsi_phy_get_timing, }; -static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi, - int mux) +static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi) { - if (dsi->cdata->lcdsel_grf_reg) - regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg, - mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big); - if (dsi->cdata->lanecfg1_grf_reg) regmap_write(dsi->grf_regmap, dsi->cdata->lanecfg1_grf_reg, dsi->cdata->lanecfg1); @@ -712,6 +706,13 @@ static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi, dsi->cdata->enable); } +static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi, + int mux) +{ + regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg, + mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big); +} + static int dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, @@ -767,9 +768,9 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder) return; } - dw_mipi_dsi_rockchip_config(dsi, mux); + dw_mipi_dsi_rockchip_set_lcdsel(dsi, mux); if (dsi->slave) - dw_mipi_dsi_rockchip_config(dsi->slave, mux); + dw_mipi_dsi_rockchip_set_lcdsel(dsi->slave, mux); clk_disable_unprepare(dsi->grf_clk); } @@ -923,6 +924,24 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev, return ret; } + /* + * With the GRF clock running, write lane and dual-mode configurations + * that won't change immediately. If we waited until enable() to do + * this, things like panel preparation would not be able to send + * commands over DSI. + */ + ret = clk_prepare_enable(dsi->grf_clk); + if (ret) { + DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret); + return ret; + } + + dw_mipi_dsi_rockchip_config(dsi); + if (dsi->slave) + dw_mipi_dsi_rockchip_config(dsi->slave); + + clk_disable_unprepare(dsi->grf_clk); + ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev); if (ret) { DRM_DEV_ERROR(dev, "Failed to create drm encoder\n"); @@ -1121,9 +1140,6 @@ static int dw_mipi_dsi_rockchip_remove(struct platform_device *pdev) { struct dw_mipi_dsi_rockchip *dsi = platform_get_drvdata(pdev); - if (dsi->devcnt == 0) - component_del(dsi->dev, &dw_mipi_dsi_rockchip_ops); - dw_mipi_dsi_remove(dsi->dmd); return 0; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index c80f7d9fd13f..0f23144491e4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1013,6 +1013,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, VOP_WIN_SET(vop, win, alpha_en, 1); } else { VOP_WIN_SET(vop, win, src_alpha_ctl, SRC_ALPHA_EN(0)); + VOP_WIN_SET(vop, win, alpha_en, 0); } VOP_WIN_SET(vop, win, enable, 1); diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c index 41edd0a421b2..7c20b4a24a7e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_lvds.c +++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c @@ -499,11 +499,11 @@ static int px30_lvds_probe(struct platform_device *pdev, if (IS_ERR(lvds->dphy)) return PTR_ERR(lvds->dphy); - phy_init(lvds->dphy); + ret = phy_init(lvds->dphy); if (ret) return ret; - phy_set_mode(lvds->dphy, PHY_MODE_LVDS); + ret = phy_set_mode(lvds->dphy, PHY_MODE_LVDS); if (ret) return ret; diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c index 80053d91a301..a6fe03c3748a 100644 --- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c +++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c @@ -349,8 +349,8 @@ static const struct vop_win_phy rk3066_win0_data = { .nformats = ARRAY_SIZE(formats_win_full), .format_modifiers = format_modifiers_win_full, .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0), - .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 4), - .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 19), + .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4), + .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19), .act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0), .dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0), .dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0), @@ -361,13 +361,12 @@ static const struct vop_win_phy rk3066_win0_data = { }; static const struct vop_win_phy rk3066_win1_data = { - .scl = &rk3066_win_scl, .data_formats = formats_win_full, .nformats = ARRAY_SIZE(formats_win_full), .format_modifiers = format_modifiers_win_full, .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1), - .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 7), - .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 23), + .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7), + .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23), .act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0), .dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0), .dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0), @@ -382,8 +381,8 @@ static const struct vop_win_phy rk3066_win2_data = { .nformats = ARRAY_SIZE(formats_win_lite), .format_modifiers = format_modifiers_win_lite, .enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 2), - .format = VOP_REG(RK3066_SYS_CTRL0, 0x7, 10), - .rb_swap = VOP_REG(RK3066_SYS_CTRL0, 0x1, 27), + .format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 10), + .rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 27), .dsp_info = VOP_REG(RK3066_WIN2_DSP_INFO, 0x0fff0fff, 0), .dsp_st = VOP_REG(RK3066_WIN2_DSP_ST, 0x1fff1fff, 0), .yrgb_mst = VOP_REG(RK3066_WIN2_MST, 0xffffffff, 0), @@ -408,6 +407,9 @@ static const struct vop_common rk3066_common = { .dither_down_en = VOP_REG(RK3066_DSP_CTRL0, 0x1, 11), .dither_down_mode = VOP_REG(RK3066_DSP_CTRL0, 0x1, 10), .dsp_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 24), + .dither_up = VOP_REG(RK3066_DSP_CTRL0, 0x1, 9), + .dsp_lut_en = VOP_REG(RK3066_SYS_CTRL1, 0x1, 31), + .data_blank = VOP_REG(RK3066_DSP_CTRL1, 0x1, 25), }; static const struct vop_win_data rk3066_vop_win_data[] = { @@ -505,7 +507,10 @@ static const struct vop_common rk3188_common = { .dither_down_sel = VOP_REG(RK3188_DSP_CTRL0, 0x1, 27), .dither_down_en = VOP_REG(RK3188_DSP_CTRL0, 0x1, 11), .dither_down_mode = VOP_REG(RK3188_DSP_CTRL0, 0x1, 10), - .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24), + .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 24), + .dither_up = VOP_REG(RK3188_DSP_CTRL0, 0x1, 9), + .dsp_lut_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 28), + .data_blank = VOP_REG(RK3188_DSP_CTRL1, 0x1, 25), }; static const struct vop_win_data rk3188_vop_win_data[] = { diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index 146380118962..3f7f761df4cd 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -113,7 +113,8 @@ static bool drm_sched_entity_is_idle(struct drm_sched_entity *entity) rmb(); /* for list_empty to work without lock */ if (list_empty(&entity->list) || - spsc_queue_count(&entity->job_queue) == 0) + spsc_queue_count(&entity->job_queue) == 0 || + entity->stopped) return true; return false; @@ -218,11 +219,16 @@ static void drm_sched_entity_kill_jobs_cb(struct dma_fence *f, static void drm_sched_entity_kill_jobs(struct drm_sched_entity *entity) { struct drm_sched_job *job; + struct dma_fence *f; int r; while ((job = to_drm_sched_job(spsc_queue_pop(&entity->job_queue)))) { struct drm_sched_fence *s_fence = job->s_fence; + /* Wait for all dependencies to avoid data corruptions */ + while ((f = job->sched->ops->dependency(job, entity))) + dma_fence_wait(f, false); + drm_sched_fence_scheduled(s_fence); dma_fence_set_error(&s_fence->finished, -ESRCH); diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index 7111e0f527b0..b6c2757c3d83 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -887,9 +887,33 @@ EXPORT_SYMBOL(drm_sched_init); */ void drm_sched_fini(struct drm_gpu_scheduler *sched) { + struct drm_sched_entity *s_entity; + int i; + if (sched->thread) kthread_stop(sched->thread); + for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) { + struct drm_sched_rq *rq = &sched->sched_rq[i]; + + if (!rq) + continue; + + spin_lock(&rq->lock); + list_for_each_entry(s_entity, &rq->entities, list) + /* + * Prevents reinsertion and marks job_queue as idle, + * it will removed from rq in drm_sched_entity_fini + * eventually + */ + s_entity->stopped = true; + spin_unlock(&rq->lock); + + } + + /* Wakeup everyone stuck in drm_sched_entity_flush for this scheduler */ + wake_up_all(&sched->job_scheduled); + /* Confirm no work left behind accessing device structures */ cancel_delayed_work_sync(&sched->work_tdr); diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c index bbdfd5e26ec8..f75fb157f2ff 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c @@ -209,7 +209,7 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, goto err_disable_clk_tmds; } - ret = sun8i_hdmi_phy_probe(hdmi, phy_node); + ret = sun8i_hdmi_phy_get(hdmi, phy_node); of_node_put(phy_node); if (ret) { dev_err(dev, "Couldn't get the HDMI PHY\n"); @@ -242,7 +242,6 @@ static int sun8i_dw_hdmi_bind(struct device *dev, struct device *master, cleanup_encoder: drm_encoder_cleanup(encoder); - sun8i_hdmi_phy_remove(hdmi); err_disable_clk_tmds: clk_disable_unprepare(hdmi->clk_tmds); err_assert_ctrl_reset: @@ -263,7 +262,6 @@ static void sun8i_dw_hdmi_unbind(struct device *dev, struct device *master, struct sun8i_dw_hdmi *hdmi = dev_get_drvdata(dev); dw_hdmi_unbind(hdmi->hdmi); - sun8i_hdmi_phy_remove(hdmi); clk_disable_unprepare(hdmi->clk_tmds); reset_control_assert(hdmi->rst_ctrl); gpiod_set_value(hdmi->ddc_en, 0); @@ -320,7 +318,32 @@ static struct platform_driver sun8i_dw_hdmi_pltfm_driver = { .of_match_table = sun8i_dw_hdmi_dt_ids, }, }; -module_platform_driver(sun8i_dw_hdmi_pltfm_driver); + +static int __init sun8i_dw_hdmi_init(void) +{ + int ret; + + ret = platform_driver_register(&sun8i_dw_hdmi_pltfm_driver); + if (ret) + return ret; + + ret = platform_driver_register(&sun8i_hdmi_phy_driver); + if (ret) { + platform_driver_unregister(&sun8i_dw_hdmi_pltfm_driver); + return ret; + } + + return ret; +} + +static void __exit sun8i_dw_hdmi_exit(void) +{ + platform_driver_unregister(&sun8i_dw_hdmi_pltfm_driver); + platform_driver_unregister(&sun8i_hdmi_phy_driver); +} + +module_init(sun8i_dw_hdmi_init); +module_exit(sun8i_dw_hdmi_exit); MODULE_AUTHOR("Jernej Skrabec "); MODULE_DESCRIPTION("Allwinner DW HDMI bridge"); diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h index d4b55af0592f..74f6ed0e2570 100644 --- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h +++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h @@ -195,14 +195,15 @@ struct sun8i_dw_hdmi { struct gpio_desc *ddc_en; }; +extern struct platform_driver sun8i_hdmi_phy_driver; + static inline struct sun8i_dw_hdmi * encoder_to_sun8i_dw_hdmi(struct drm_encoder *encoder) { return container_of(encoder, struct sun8i_dw_hdmi, encoder); } -int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node); -void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi); +int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node); void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy); void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy, diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c index 9994edf67509..c9239708d398 100644 --- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c @@ -5,6 +5,7 @@ #include #include +#include #include "sun8i_dw_hdmi.h" @@ -597,10 +598,30 @@ static const struct of_device_id sun8i_hdmi_phy_of_table[] = { { /* sentinel */ } }; -int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) +int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node) +{ + struct platform_device *pdev = of_find_device_by_node(node); + struct sun8i_hdmi_phy *phy; + + if (!pdev) + return -EPROBE_DEFER; + + phy = platform_get_drvdata(pdev); + if (!phy) + return -EPROBE_DEFER; + + hdmi->phy = phy; + + put_device(&pdev->dev); + + return 0; +} + +static int sun8i_hdmi_phy_probe(struct platform_device *pdev) { const struct of_device_id *match; - struct device *dev = hdmi->dev; + struct device *dev = &pdev->dev; + struct device_node *node = dev->of_node; struct sun8i_hdmi_phy *phy; struct resource res; void __iomem *regs; @@ -704,7 +725,7 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) clk_prepare_enable(phy->clk_phy); } - hdmi->phy = phy; + platform_set_drvdata(pdev, phy); return 0; @@ -728,9 +749,9 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node) return ret; } -void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi) +static int sun8i_hdmi_phy_remove(struct platform_device *pdev) { - struct sun8i_hdmi_phy *phy = hdmi->phy; + struct sun8i_hdmi_phy *phy = platform_get_drvdata(pdev); clk_disable_unprepare(phy->clk_mod); clk_disable_unprepare(phy->clk_bus); @@ -744,4 +765,14 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi) clk_put(phy->clk_pll1); clk_put(phy->clk_mod); clk_put(phy->clk_bus); + return 0; } + +struct platform_driver sun8i_hdmi_phy_driver = { + .probe = sun8i_hdmi_phy_probe, + .remove = sun8i_hdmi_phy_remove, + .driver = { + .name = "sun8i-hdmi-phy", + .of_match_table = sun8i_hdmi_phy_of_table, + }, +}; diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 3aa9a7406085..ceb86338c003 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -947,6 +947,11 @@ static const struct drm_plane_helper_funcs tegra_cursor_plane_helper_funcs = { .atomic_disable = tegra_cursor_atomic_disable, }; +static const uint64_t linear_modifiers[] = { + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, struct tegra_dc *dc) { @@ -975,7 +980,7 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, &tegra_plane_funcs, formats, - num_formats, NULL, + num_formats, linear_modifiers, DRM_PLANE_TYPE_CURSOR, NULL); if (err < 0) { kfree(plane); @@ -1094,7 +1099,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, &tegra_plane_funcs, formats, - num_formats, NULL, type, NULL); + num_formats, linear_modifiers, + type, NULL); if (err < 0) { kfree(plane); return ERR_PTR(err); diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index e4baf07992a4..2c6ebc328b24 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -1127,8 +1127,6 @@ static int host1x_drm_probe(struct host1x_device *dev) drm->mode_config.max_width = 4096; drm->mode_config.max_height = 4096; - drm->mode_config.allow_fb_modifiers = true; - drm->mode_config.normalize_zpos = true; drm->mode_config.funcs = &tegra_drm_mode_config_funcs; diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 7b88261f57bb..32c83f2e386c 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -3125,21 +3125,21 @@ static int tegra_sor_init(struct host1x_client *client) if (err < 0) { dev_err(sor->dev, "failed to acquire SOR reset: %d\n", err); - return err; + goto rpm_put; } err = reset_control_assert(sor->rst); if (err < 0) { dev_err(sor->dev, "failed to assert SOR reset: %d\n", err); - return err; + goto rpm_put; } } err = clk_prepare_enable(sor->clk); if (err < 0) { dev_err(sor->dev, "failed to enable clock: %d\n", err); - return err; + goto rpm_put; } usleep_range(1000, 3000); @@ -3150,7 +3150,7 @@ static int tegra_sor_init(struct host1x_client *client) dev_err(sor->dev, "failed to deassert SOR reset: %d\n", err); clk_disable_unprepare(sor->clk); - return err; + goto rpm_put; } reset_control_release(sor->rst); @@ -3171,6 +3171,12 @@ static int tegra_sor_init(struct host1x_client *client) } return 0; + +rpm_put: + if (sor->rst) + pm_runtime_put(sor->dev); + + return err; } static int tegra_sor_exit(struct host1x_client *client) @@ -3916,17 +3922,10 @@ static int tegra_sor_probe(struct platform_device *pdev) platform_set_drvdata(pdev, sor); pm_runtime_enable(&pdev->dev); - INIT_LIST_HEAD(&sor->client.list); + host1x_client_init(&sor->client); sor->client.ops = &sor_client_ops; sor->client.dev = &pdev->dev; - err = host1x_client_register(&sor->client); - if (err < 0) { - dev_err(&pdev->dev, "failed to register host1x client: %d\n", - err); - goto rpm_disable; - } - /* * On Tegra210 and earlier, provide our own implementation for the * pad output clock. @@ -3938,13 +3937,13 @@ static int tegra_sor_probe(struct platform_device *pdev) sor->index); if (!name) { err = -ENOMEM; - goto unregister; + goto uninit; } err = host1x_client_resume(&sor->client); if (err < 0) { dev_err(sor->dev, "failed to resume: %d\n", err); - goto unregister; + goto uninit; } sor->clk_pad = tegra_clk_sor_pad_register(sor, name); @@ -3955,14 +3954,20 @@ static int tegra_sor_probe(struct platform_device *pdev) err = PTR_ERR(sor->clk_pad); dev_err(sor->dev, "failed to register SOR pad clock: %d\n", err); - goto unregister; + goto uninit; + } + + err = __host1x_client_register(&sor->client); + if (err < 0) { + dev_err(&pdev->dev, "failed to register host1x client: %d\n", + err); + goto uninit; } return 0; -unregister: - host1x_client_unregister(&sor->client); -rpm_disable: +uninit: + host1x_client_exit(&sor->client); pm_runtime_disable(&pdev->dev); remove: tegra_output_remove(&sor->output); diff --git a/drivers/gpu/drm/ttm/ttm_range_manager.c b/drivers/gpu/drm/ttm/ttm_range_manager.c index 1da0e277c511..ce9d127edbb5 100644 --- a/drivers/gpu/drm/ttm/ttm_range_manager.c +++ b/drivers/gpu/drm/ttm/ttm_range_manager.c @@ -147,6 +147,9 @@ int ttm_range_man_fini(struct ttm_bo_device *bdev, struct drm_mm *mm = &rman->mm; int ret; + if (!man) + return 0; + ttm_resource_manager_set_used(man, false); ret = ttm_resource_manager_force_list_clean(bdev, man); diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 1d2416d466a3..f4ccca922e44 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1001,7 +1001,7 @@ static const struct vc4_pv_data bcm2711_pv3_data = { .fifo_depth = 64, .pixels_per_clock = 1, .encoder_types = { - [0] = VC4_ENCODER_TYPE_VEC, + [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC, }, }; @@ -1042,6 +1042,9 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm, struct vc4_encoder *vc4_encoder; int i; + if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL) + continue; + vc4_encoder = to_vc4_encoder(encoder); for (i = 0; i < ARRAY_SIZE(pv_data->encoder_types); i++) { if (vc4_encoder->type == encoder_types[i]) { diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index c5f2944d5bc6..9809c3a856c6 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -837,7 +837,7 @@ void vc4_crtc_destroy_state(struct drm_crtc *crtc, void vc4_crtc_reset(struct drm_crtc *crtc); void vc4_crtc_handle_vblank(struct vc4_crtc *crtc); void vc4_crtc_get_margins(struct drm_crtc_state *state, - unsigned int *right, unsigned int *left, + unsigned int *left, unsigned int *right, unsigned int *top, unsigned int *bottom); /* vc4_debugfs.c */ diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index af5f01eff872..c58b8840090a 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -146,6 +146,8 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); bool connected = false; + WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev)); + if (vc4_hdmi->hpd_gpio) { if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^ vc4_hdmi->hpd_active_low) @@ -167,10 +169,12 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) } } + pm_runtime_put(&vc4_hdmi->pdev->dev); return connector_status_connected; } cec_phys_addr_invalidate(vc4_hdmi->cec_adap); + pm_runtime_put(&vc4_hdmi->pdev->dev); return connector_status_disconnected; } @@ -415,7 +419,6 @@ static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder) HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE); clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock); - clk_disable_unprepare(vc4_hdmi->hsm_clock); clk_disable_unprepare(vc4_hdmi->pixel_clock); ret = pm_runtime_put(&vc4_hdmi->pdev->dev); @@ -624,7 +627,7 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder) unsigned long pixel_rate, hsm_rate; int ret; - ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev); + ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); if (ret < 0) { DRM_ERROR("Failed to retain power domain: %d\n", ret); return; @@ -666,13 +669,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder) return; } - ret = clk_prepare_enable(vc4_hdmi->hsm_clock); - if (ret) { - DRM_ERROR("Failed to turn on HSM clock: %d\n", ret); - clk_disable_unprepare(vc4_hdmi->pixel_clock); - return; - } - vc4_hdmi_cec_update_clk_div(vc4_hdmi); /* @@ -683,7 +679,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder) (hsm_rate > VC4_HSM_MID_CLOCK ? 150000000 : 75000000)); if (ret) { DRM_ERROR("Failed to set pixel bvb clock rate: %d\n", ret); - clk_disable_unprepare(vc4_hdmi->hsm_clock); clk_disable_unprepare(vc4_hdmi->pixel_clock); return; } @@ -691,7 +686,6 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder) ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock); if (ret) { DRM_ERROR("Failed to turn on pixel bvb clock: %d\n", ret); - clk_disable_unprepare(vc4_hdmi->hsm_clock); clk_disable_unprepare(vc4_hdmi->pixel_clock); return; } @@ -1724,6 +1718,29 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi) return 0; } +#ifdef CONFIG_PM +static int vc4_hdmi_runtime_suspend(struct device *dev) +{ + struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); + + clk_disable_unprepare(vc4_hdmi->hsm_clock); + + return 0; +} + +static int vc4_hdmi_runtime_resume(struct device *dev) +{ + struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(vc4_hdmi->hsm_clock); + if (ret) + return ret; + + return 0; +} +#endif + static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) { const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev); @@ -1778,7 +1795,7 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) &hpd_gpio_flags); if (vc4_hdmi->hpd_gpio < 0) { ret = vc4_hdmi->hpd_gpio; - goto err_unprepare_hsm; + goto err_put_ddc; } vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW; @@ -1790,6 +1807,14 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) if (vc4_hdmi->variant->reset) vc4_hdmi->variant->reset(vc4_hdmi); + if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") || + of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi1")) && + HDMI_READ(HDMI_VID_CTL) & VC4_HD_VID_CTL_ENABLE) { + clk_prepare_enable(vc4_hdmi->pixel_clock); + clk_prepare_enable(vc4_hdmi->hsm_clock); + clk_prepare_enable(vc4_hdmi->pixel_bvb_clock); + } + pm_runtime_enable(dev); drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); @@ -1819,8 +1844,8 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) vc4_hdmi_connector_destroy(&vc4_hdmi->connector); err_destroy_encoder: drm_encoder_cleanup(encoder); -err_unprepare_hsm: pm_runtime_disable(dev); +err_put_ddc: put_device(&vc4_hdmi->ddc->dev); return ret; @@ -1959,11 +1984,18 @@ static const struct of_device_id vc4_hdmi_dt_match[] = { {} }; +static const struct dev_pm_ops vc4_hdmi_pm_ops = { + SET_RUNTIME_PM_OPS(vc4_hdmi_runtime_suspend, + vc4_hdmi_runtime_resume, + NULL) +}; + struct platform_driver vc4_hdmi_driver = { .probe = vc4_hdmi_dev_probe, .remove = vc4_hdmi_dev_remove, .driver = { .name = "vc4_hdmi", .of_match_table = vc4_hdmi_dt_match, + .pm = &vc4_hdmi_pm_ops, }, }; diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c index 849dcafbfff1..d13502ae973d 100644 --- a/drivers/gpu/drm/vc4/vc4_txp.c +++ b/drivers/gpu/drm/vc4/vc4_txp.c @@ -503,7 +503,7 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data) return ret; encoder = &txp->connector.encoder; - encoder->possible_crtcs |= drm_crtc_mask(crtc); + encoder->possible_crtcs = drm_crtc_mask(crtc); ret = devm_request_irq(dev, irq, vc4_txp_interrupt, 0, dev_name(dev), txp); diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index eed57a931309..a28b01f92793 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -209,6 +209,7 @@ int virtio_gpu_init(struct drm_device *dev) err_vbufs: vgdev->vdev->config->del_vqs(vgdev->vdev); err_vqs: + dev->dev_private = NULL; kfree(vgdev); return ret; } diff --git a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h index 4db25bd9fa22..127eaf0a0a58 100644 --- a/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h +++ b/drivers/gpu/drm/vmwgfx/device_include/svga3d_surfacedefs.h @@ -1467,6 +1467,7 @@ struct svga3dsurface_cache { /** * struct svga3dsurface_loc - Surface location + * @sheet: The multisample sheet. * @sub_resource: Surface subresource. Defined as layer * num_mip_levels + * mip_level. * @x: X coordinate. @@ -1474,6 +1475,7 @@ struct svga3dsurface_cache { * @z: Z coordinate. */ struct svga3dsurface_loc { + u32 sheet; u32 sub_resource; u32 x, y, z; }; @@ -1566,8 +1568,8 @@ svga3dsurface_get_loc(const struct svga3dsurface_cache *cache, u32 layer; int i; - if (offset >= cache->sheet_bytes) - offset %= cache->sheet_bytes; + loc->sheet = offset / cache->sheet_bytes; + offset -= loc->sheet * cache->sheet_bytes; layer = offset / cache->mip_chain_bytes; offset -= layer * cache->mip_chain_bytes; @@ -1631,6 +1633,7 @@ svga3dsurface_min_loc(const struct svga3dsurface_cache *cache, u32 sub_resource, struct svga3dsurface_loc *loc) { + loc->sheet = 0; loc->sub_resource = sub_resource; loc->x = loc->y = loc->z = 0; } @@ -1652,6 +1655,7 @@ svga3dsurface_max_loc(const struct svga3dsurface_cache *cache, const struct drm_vmw_size *size; u32 mip; + loc->sheet = 0; loc->sub_resource = sub_resource + 1; mip = sub_resource % cache->num_mip_levels; size = &cache->mip[mip].size; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index e67e2e8f6e6f..83e1b54eb864 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -2759,12 +2759,24 @@ static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv, { VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXGenMips) = container_of(header, typeof(*cmd), header); - struct vmw_resource *ret; + struct vmw_resource *view; + struct vmw_res_cache_entry *rcache; - ret = vmw_view_id_val_add(sw_context, vmw_view_sr, - cmd->body.shaderResourceViewId); + view = vmw_view_id_val_add(sw_context, vmw_view_sr, + cmd->body.shaderResourceViewId); + if (IS_ERR(view)) + return PTR_ERR(view); - return PTR_ERR_OR_ZERO(ret); + /* + * Normally the shader-resource view is not gpu-dirtying, but for + * this particular command it is... + * So mark the last looked-up surface, which is the surface + * the view points to, gpu-dirty. + */ + rcache = &sw_context->res_cache[vmw_res_surface]; + vmw_validation_res_set_dirty(sw_context->ctx, rcache->private, + VMW_RES_DIRTY_SET); + return 0; } /** diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index 3914bfee0533..f493b20c7a38 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -1802,6 +1802,19 @@ static void vmw_surface_tex_dirty_range_add(struct vmw_resource *res, svga3dsurface_get_loc(cache, &loc2, end - 1); svga3dsurface_inc_loc(cache, &loc2); + if (loc1.sheet != loc2.sheet) { + u32 sub_res; + + /* + * Multiple multisample sheets. To do this in an optimized + * fashion, compute the dirty region for each sheet and the + * resulting union. Since this is not a common case, just dirty + * the whole surface. + */ + for (sub_res = 0; sub_res < dirty->num_subres; ++sub_res) + vmw_subres_dirty_full(dirty, sub_res); + return; + } if (loc1.sub_resource + 1 == loc2.sub_resource) { /* Dirty range covers a single sub-resource */ vmw_subres_dirty_add(dirty, &loc1, &loc2); diff --git a/drivers/gpu/drm/zte/Kconfig b/drivers/gpu/drm/zte/Kconfig index 90ebaedc11fd..aa8594190b50 100644 --- a/drivers/gpu/drm/zte/Kconfig +++ b/drivers/gpu/drm/zte/Kconfig @@ -3,7 +3,6 @@ config DRM_ZTE tristate "DRM Support for ZTE SoCs" depends on DRM && ARCH_ZX select DRM_KMS_CMA_HELPER - select DRM_KMS_FB_HELPER select DRM_KMS_HELPER select SND_SOC_HDMI_CODEC if SND_SOC select VIDEOMODE_HELPERS diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 9e2cb6968819..6e3b49d0de66 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -703,6 +703,29 @@ void host1x_driver_unregister(struct host1x_driver *driver) } EXPORT_SYMBOL(host1x_driver_unregister); +/** + * __host1x_client_init() - initialize a host1x client + * @client: host1x client + * @key: lock class key for the client-specific mutex + */ +void __host1x_client_init(struct host1x_client *client, struct lock_class_key *key) +{ + INIT_LIST_HEAD(&client->list); + __mutex_init(&client->lock, "host1x client lock", key); + client->usecount = 0; +} +EXPORT_SYMBOL(__host1x_client_init); + +/** + * host1x_client_exit() - uninitialize a host1x client + * @client: host1x client + */ +void host1x_client_exit(struct host1x_client *client) +{ + mutex_destroy(&client->lock); +} +EXPORT_SYMBOL(host1x_client_exit); + /** * __host1x_client_register() - register a host1x client * @client: host1x client @@ -715,16 +738,11 @@ EXPORT_SYMBOL(host1x_driver_unregister); * device and call host1x_device_init(), which will in turn call each client's * &host1x_client_ops.init implementation. */ -int __host1x_client_register(struct host1x_client *client, - struct lock_class_key *key) +int __host1x_client_register(struct host1x_client *client) { struct host1x *host1x; int err; - INIT_LIST_HEAD(&client->list); - __mutex_init(&client->lock, "host1x client lock", key); - client->usecount = 0; - mutex_lock(&devices_lock); list_for_each_entry(host1x, &devices, list) { diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/ipu-v3/ipu-cpmem.c index a1c85d1521f5..82b244cb313e 100644 --- a/drivers/gpu/ipu-v3/ipu-cpmem.c +++ b/drivers/gpu/ipu-v3/ipu-cpmem.c @@ -585,21 +585,21 @@ static const struct ipu_rgb def_bgra_16 = { .bits_per_pixel = 16, }; -#define Y_OFFSET(pix, x, y) ((x) + pix->width * (y)) -#define U_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * ((y) / 2) / 2) + (x) / 2) -#define V_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * pix->height / 4) + \ - (pix->width * ((y) / 2) / 2) + (x) / 2) -#define U2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * (y) / 2) + (x) / 2) -#define V2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * pix->height / 2) + \ - (pix->width * (y) / 2) + (x) / 2) -#define UV_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * ((y) / 2)) + (x)) -#define UV2_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * y) + (x)) +#define Y_OFFSET(pix, x, y) ((x) + pix->bytesperline * (y)) +#define U_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * ((y) / 2) / 2) + (x) / 2) +#define V_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * pix->height / 4) + \ + (pix->bytesperline * ((y) / 2) / 2) + (x) / 2) +#define U2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * (y) / 2) + (x) / 2) +#define V2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * pix->height / 2) + \ + (pix->bytesperline * (y) / 2) + (x) / 2) +#define UV_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * ((y) / 2)) + (x)) +#define UV2_OFFSET(pix, x, y) ((pix->bytesperline * pix->height) + \ + (pix->bytesperline * y) + (x)) #define NUM_ALPHA_CHANNELS 7 diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 8e9dfbb5e5f7..a347368ecaef 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -93,11 +93,11 @@ menu "Special HID drivers" depends on HID config HID_A4TECH - tristate "A4 tech mice" + tristate "A4TECH mice" depends on HID default !EXPERT help - Support for A4 tech X5 and WOP-35 / Trust 450L mice. + Support for some A4TECH mice with two scroll wheels. config HID_ACCUTOUCH tristate "Accutouch touch device" diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c index 3a8c4a5971f7..2cbc32dda7f7 100644 --- a/drivers/hid/hid-a4tech.c +++ b/drivers/hid/hid-a4tech.c @@ -147,6 +147,8 @@ static const struct hid_device_id a4_devices[] = { .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649), .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, + { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_NB_95), + .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, { } }; MODULE_DEVICE_TABLE(hid, a4_devices); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 097cb1ee3126..5550c943f985 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2005,6 +2005,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) case BUS_I2C: bus = "I2C"; break; + case BUS_VIRTUAL: + bus = "VIRTUAL"; + break; default: bus = ""; } @@ -2303,12 +2306,8 @@ static int hid_device_remove(struct device *dev) { struct hid_device *hdev = to_hid_device(dev); struct hid_driver *hdrv; - int ret = 0; - if (down_interruptible(&hdev->driver_input_lock)) { - ret = -EINTR; - goto end; - } + down(&hdev->driver_input_lock); hdev->io_started = false; hdrv = hdev->driver; @@ -2323,8 +2322,8 @@ static int hid_device_remove(struct device *dev) if (!hdev->io_started) up(&hdev->driver_input_lock); -end: - return ret; + + return 0; } static ssize_t modalias_show(struct device *dev, struct device_attribute *a, diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index d7eaf9100370..982737827b87 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -929,6 +929,7 @@ static const char *keys[KEY_MAX + 1] = { [KEY_APPSELECT] = "AppSelect", [KEY_SCREENSAVER] = "ScreenSaver", [KEY_VOICECOMMAND] = "VoiceCommand", + [KEY_EMOJI_PICKER] = "EmojiPicker", [KEY_BRIGHTNESS_MIN] = "BrightnessMin", [KEY_BRIGHTNESS_MAX] = "BrightnessMax", [KEY_BRIGHTNESS_AUTO] = "BrightnessAuto", diff --git a/drivers/hid/hid-gt683r.c b/drivers/hid/hid-gt683r.c index 898871c8c768..29ccb0accfba 100644 --- a/drivers/hid/hid-gt683r.c +++ b/drivers/hid/hid-gt683r.c @@ -54,6 +54,7 @@ static const struct hid_device_id gt683r_led_id[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GT683R_LED_PANEL) }, { } }; +MODULE_DEVICE_TABLE(hid, gt683r_led_id); static void gt683r_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 77194ef18641..3bed3731bfce 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -26,6 +26,7 @@ #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 #define USB_DEVICE_ID_A4TECH_X5_005D 0x000a #define USB_DEVICE_ID_A4TECH_RP_649 0x001a +#define USB_DEVICE_ID_A4TECH_NB_95 0x022b #define USB_VENDOR_ID_AASHIMA 0x06d6 #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 @@ -741,6 +742,7 @@ #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 #define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 #define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 +#define USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E 0x600e #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e @@ -1037,6 +1039,7 @@ #define USB_DEVICE_ID_SAITEK_X52 0x075c #define USB_DEVICE_ID_SAITEK_X52_2 0x0255 #define USB_DEVICE_ID_SAITEK_X52_PRO 0x0762 +#define USB_DEVICE_ID_SAITEK_X65 0x0b6a #define USB_VENDOR_ID_SAMSUNG 0x0419 #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 32024905fd70..d1ab2dccf6fd 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -957,6 +957,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; case 0x0cf: map_key_clear(KEY_VOICECOMMAND); break; + + case 0x0d9: map_key_clear(KEY_EMOJI_PICKER); break; + case 0x0e0: map_abs_clear(ABS_VOLUME); break; case 0x0e2: map_key_clear(KEY_MUTE); break; case 0x0e5: map_key_clear(KEY_BASSBOOST); break; diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 8580ace596c2..e5a3704b9fe8 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -1580,13 +1580,13 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) /* we do not set suffix = "Touchscreen" */ hi->input->name = hdev->name; break; - case HID_DG_STYLUS: - /* force BTN_STYLUS to allow tablet matching in udev */ - __set_bit(BTN_STYLUS, hi->input->keybit); - break; case HID_VD_ASUS_CUSTOM_MEDIA_KEYS: suffix = "Custom Media Keys"; break; + case HID_DG_STYLUS: + /* force BTN_STYLUS to allow tablet matching in udev */ + __set_bit(BTN_STYLUS, hi->input->keybit); + fallthrough; case HID_DG_PEN: suffix = "Stylus"; break; diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 2e38340e19df..be53c723c729 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -110,6 +110,7 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_M912), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL }, + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E), HID_QUIRK_ALWAYS_POLL }, @@ -158,6 +159,7 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_PRO), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, + { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X65), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, { HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET }, @@ -212,6 +214,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, + { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_NB_95) }, #endif #if IS_ENABLED(CONFIG_HID_ACCUTOUCH) { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) }, diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 3dd7d3246737..f9983145d4e7 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -210,16 +210,21 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, buffer_size = buffer_size / sizeof(__s32); if (buffer_size) { for (i = 0; i < buffer_size; ++i) { - hid_set_field(report->field[field_index], i, - (__force __s32)cpu_to_le32(*buf32)); + ret = hid_set_field(report->field[field_index], i, + (__force __s32)cpu_to_le32(*buf32)); + if (ret) + goto done_proc; + ++buf32; } } if (remaining_bytes) { value = 0; memcpy(&value, (u8 *)buf32, remaining_bytes); - hid_set_field(report->field[field_index], i, - (__force __s32)cpu_to_le32(value)); + ret = hid_set_field(report->field[field_index], i, + (__force __s32)cpu_to_le32(value)); + if (ret) + goto done_proc; } hid_hw_request(hsdev->hdev, report, HID_REQ_SET_REPORT); hid_hw_wait(hsdev->hdev); diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 17a29ee0ac6c..8d4ac4b9fb9d 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -374,7 +374,7 @@ static int hid_submit_ctrl(struct hid_device *hid) raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; dir = usbhid->ctrl[usbhid->ctrltail].dir; - len = ((report->size - 1) >> 3) + 1 + (report->id > 0); + len = hid_report_len(report); if (dir == USB_DIR_OUT) { usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); usbhid->urbctrl->transfer_buffer_length = len; diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 2d70dc4bea65..4228ddc3df0e 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -3829,7 +3829,7 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, wacom_wac->shared->touch->product == 0xF6) { input_dev->evbit[0] |= BIT_MASK(EV_SW); __set_bit(SW_MUTE_DEVICE, input_dev->swbit); - wacom_wac->shared->has_mute_touch_switch = true; + wacom_wac->has_mute_touch_switch = true; } fallthrough; diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 195910dd2154..e3835407e8d2 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -122,7 +122,7 @@ #define WACOM_HID_WD_TOUCHONOFF (WACOM_HID_UP_WACOMDIGITIZER | 0x0454) #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b) #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910) -#define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950) +#define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0940) #define WACOM_HID_WD_MODE_CHANGE (WACOM_HID_UP_WACOMDIGITIZER | 0x0980) #define WACOM_HID_WD_MUTE_DEVICE (WACOM_HID_UP_WACOMDIGITIZER | 0x0981) #define WACOM_HID_WD_CONTROLPANEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0982) diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index 11170d9a2e1a..bfd7f00a59ec 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -229,8 +229,10 @@ int vmbus_connect(void) */ for (i = 0; ; i++) { - if (i == ARRAY_SIZE(vmbus_versions)) + if (i == ARRAY_SIZE(vmbus_versions)) { + ret = -EDOM; goto cleanup; + } version = vmbus_versions[i]; if (version > max_version) diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index 05566ecdbe4b..1b914e418e41 100644 --- a/drivers/hv/hv_util.c +++ b/drivers/hv/hv_util.c @@ -696,8 +696,8 @@ static int hv_timesync_init(struct hv_util_service *srv) */ hv_ptp_clock = ptp_clock_register(&ptp_hyperv_info, NULL); if (IS_ERR_OR_NULL(hv_ptp_clock)) { - pr_err("cannot register PTP clock: %ld\n", - PTR_ERR(hv_ptp_clock)); + pr_err("cannot register PTP clock: %d\n", + PTR_ERR_OR_ZERO(hv_ptp_clock)); hv_ptp_clock = NULL; } diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index ae2b84263a44..6b884ea00987 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c @@ -22,10 +22,10 @@ #include #include #include +#include +#include #include #include -#include -#include #define DRVNAME "lm70" @@ -148,50 +148,17 @@ static const struct of_device_id lm70_of_ids[] = { MODULE_DEVICE_TABLE(of, lm70_of_ids); #endif -#ifdef CONFIG_ACPI -static const struct acpi_device_id lm70_acpi_ids[] = { - { - .id = "LM000070", - .driver_data = LM70_CHIP_LM70, - }, - { - .id = "TMP00121", - .driver_data = LM70_CHIP_TMP121, - }, - { - .id = "LM000071", - .driver_data = LM70_CHIP_LM71, - }, - { - .id = "LM000074", - .driver_data = LM70_CHIP_LM74, - }, - {}, -}; -MODULE_DEVICE_TABLE(acpi, lm70_acpi_ids); -#endif - static int lm70_probe(struct spi_device *spi) { - const struct of_device_id *of_match; struct device *hwmon_dev; struct lm70 *p_lm70; int chip; - of_match = of_match_device(lm70_of_ids, &spi->dev); - if (of_match) - chip = (int)(uintptr_t)of_match->data; - else { -#ifdef CONFIG_ACPI - const struct acpi_device_id *acpi_match; - - acpi_match = acpi_match_device(lm70_acpi_ids, &spi->dev); - if (acpi_match) - chip = (int)(uintptr_t)acpi_match->driver_data; - else -#endif - chip = spi_get_device_id(spi)->driver_data; - } + if (dev_fwnode(&spi->dev)) + chip = (int)(uintptr_t)device_get_match_data(&spi->dev); + else + chip = spi_get_device_id(spi)->driver_data; + /* signaling is SPI_MODE_0 */ if (spi->mode & (SPI_CPOL | SPI_CPHA)) @@ -227,7 +194,6 @@ static struct spi_driver lm70_driver = { .driver = { .name = "lm70", .of_match_table = of_match_ptr(lm70_of_ids), - .acpi_match_table = ACPI_PTR(lm70_acpi_ids), }, .id_table = lm70_ids, .probe = lm70_probe, diff --git a/drivers/hwmon/max31722.c b/drivers/hwmon/max31722.c index 062eceb7be0d..613338cbcb17 100644 --- a/drivers/hwmon/max31722.c +++ b/drivers/hwmon/max31722.c @@ -6,7 +6,6 @@ * Copyright (c) 2016, Intel Corporation. */ -#include #include #include #include @@ -133,20 +132,12 @@ static const struct spi_device_id max31722_spi_id[] = { {"max31723", 0}, {} }; - -static const struct acpi_device_id __maybe_unused max31722_acpi_id[] = { - {"MAX31722", 0}, - {"MAX31723", 0}, - {} -}; - MODULE_DEVICE_TABLE(spi, max31722_spi_id); static struct spi_driver max31722_driver = { .driver = { .name = "max31722", .pm = &max31722_pm_ops, - .acpi_match_table = ACPI_PTR(max31722_acpi_id), }, .probe = max31722_probe, .remove = max31722_remove, diff --git a/drivers/hwmon/max31790.c b/drivers/hwmon/max31790.c index 86e6c71db685..67677c437768 100644 --- a/drivers/hwmon/max31790.c +++ b/drivers/hwmon/max31790.c @@ -27,6 +27,7 @@ /* Fan Config register bits */ #define MAX31790_FAN_CFG_RPM_MODE 0x80 +#define MAX31790_FAN_CFG_CTRL_MON 0x10 #define MAX31790_FAN_CFG_TACH_INPUT_EN 0x08 #define MAX31790_FAN_CFG_TACH_INPUT 0x01 @@ -104,7 +105,7 @@ static struct max31790_data *max31790_update_device(struct device *dev) data->tach[NR_CHANNEL + i] = rv; } else { rv = i2c_smbus_read_word_swapped(client, - MAX31790_REG_PWMOUT(i)); + MAX31790_REG_PWM_DUTY_CYCLE(i)); if (rv < 0) goto abort; data->pwm[i] = rv; @@ -170,7 +171,7 @@ static int max31790_read_fan(struct device *dev, u32 attr, int channel, switch (attr) { case hwmon_fan_input: - sr = get_tach_period(data->fan_dynamics[channel]); + sr = get_tach_period(data->fan_dynamics[channel % NR_CHANNEL]); rpm = RPM_FROM_REG(data->tach[channel], sr); *val = rpm; return 0; @@ -271,12 +272,12 @@ static int max31790_read_pwm(struct device *dev, u32 attr, int channel, *val = data->pwm[channel] >> 8; return 0; case hwmon_pwm_enable: - if (fan_config & MAX31790_FAN_CFG_RPM_MODE) + if (fan_config & MAX31790_FAN_CFG_CTRL_MON) + *val = 0; + else if (fan_config & MAX31790_FAN_CFG_RPM_MODE) *val = 2; - else if (fan_config & MAX31790_FAN_CFG_TACH_INPUT_EN) - *val = 1; else - *val = 0; + *val = 1; return 0; default: return -EOPNOTSUPP; @@ -299,31 +300,41 @@ static int max31790_write_pwm(struct device *dev, u32 attr, int channel, err = -EINVAL; break; } - data->pwm[channel] = val << 8; + data->valid = false; err = i2c_smbus_write_word_swapped(client, MAX31790_REG_PWMOUT(channel), - data->pwm[channel]); + val << 8); break; case hwmon_pwm_enable: fan_config = data->fan_config[channel]; if (val == 0) { - fan_config &= ~(MAX31790_FAN_CFG_TACH_INPUT_EN | - MAX31790_FAN_CFG_RPM_MODE); + fan_config |= MAX31790_FAN_CFG_CTRL_MON; + /* + * Disable RPM mode; otherwise disabling fan speed + * monitoring is not possible. + */ + fan_config &= ~MAX31790_FAN_CFG_RPM_MODE; } else if (val == 1) { - fan_config = (fan_config | - MAX31790_FAN_CFG_TACH_INPUT_EN) & - ~MAX31790_FAN_CFG_RPM_MODE; + fan_config &= ~(MAX31790_FAN_CFG_CTRL_MON | MAX31790_FAN_CFG_RPM_MODE); } else if (val == 2) { - fan_config |= MAX31790_FAN_CFG_TACH_INPUT_EN | - MAX31790_FAN_CFG_RPM_MODE; + fan_config &= ~MAX31790_FAN_CFG_CTRL_MON; + /* + * The chip sets MAX31790_FAN_CFG_TACH_INPUT_EN on its + * own if MAX31790_FAN_CFG_RPM_MODE is set. + * Do it here as well to reflect the actual register + * value in the cache. + */ + fan_config |= (MAX31790_FAN_CFG_RPM_MODE | MAX31790_FAN_CFG_TACH_INPUT_EN); } else { err = -EINVAL; break; } - data->fan_config[channel] = fan_config; - err = i2c_smbus_write_byte_data(client, - MAX31790_REG_FAN_CONFIG(channel), - fan_config); + if (fan_config != data->fan_config[channel]) { + err = i2c_smbus_write_byte_data(client, MAX31790_REG_FAN_CONFIG(channel), + fan_config); + if (!err) + data->fan_config[channel] = fan_config; + } break; default: err = -EOPNOTSUPP; diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c index 25aac40f2764..919877970ae3 100644 --- a/drivers/hwmon/scpi-hwmon.c +++ b/drivers/hwmon/scpi-hwmon.c @@ -99,6 +99,15 @@ scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) scpi_scale_reading(&value, sensor); + /* + * Temperature sensor values are treated as signed values based on + * observation even though that is not explicitly specified, and + * because an unsigned u64 temperature does not really make practical + * sense especially when the temperature is below zero degrees Celsius. + */ + if (sensor->info.class == TEMPERATURE) + return sprintf(buf, "%lld\n", (s64)value); + return sprintf(buf, "%llu\n", value); } diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 1504eb09f8e5..4956a8159227 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -608,7 +608,7 @@ static struct coresight_device * coresight_find_enabled_sink(struct coresight_device *csdev) { int i; - struct coresight_device *sink; + struct coresight_device *sink = NULL; if ((csdev->type == CORESIGHT_DEV_TYPE_SINK || csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) && @@ -1386,7 +1386,7 @@ static int coresight_fixup_device_conns(struct coresight_device *csdev) } } - return 0; + return ret; } static int coresight_remove_match(struct device *dev, void *data) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c index 45b85edfc690..cd0fb7bfba68 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -530,7 +530,7 @@ static unsigned long tmc_update_etf_buffer(struct coresight_device *csdev, buf_ptr = buf->data_pages[cur] + offset; *buf_ptr = readl_relaxed(drvdata->base + TMC_RRD); - if (lost && *barrier) { + if (lost && i < CORESIGHT_BARRIER_PKT_SIZE) { *buf_ptr = *barrier; barrier++; } diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index c9ac3dc65113..9cb8c7d13d46 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -215,6 +215,22 @@ static ssize_t port_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(port); +static void intel_th_trace_prepare(struct intel_th_device *thdev) +{ + struct intel_th_device *hub = to_intel_th_hub(thdev); + struct intel_th_driver *hubdrv = to_intel_th_driver(hub->dev.driver); + + if (hub->type != INTEL_TH_SWITCH) + return; + + if (thdev->type != INTEL_TH_OUTPUT) + return; + + pm_runtime_get_sync(&thdev->dev); + hubdrv->prepare(hub, &thdev->output); + pm_runtime_put(&thdev->dev); +} + static int intel_th_output_activate(struct intel_th_device *thdev) { struct intel_th_driver *thdrv = @@ -235,6 +251,7 @@ static int intel_th_output_activate(struct intel_th_device *thdev) if (ret) goto fail_put; + intel_th_trace_prepare(thdev); if (thdrv->activate) ret = thdrv->activate(thdev); else diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c index 28509b02a0b5..b3308934a687 100644 --- a/drivers/hwtracing/intel_th/gth.c +++ b/drivers/hwtracing/intel_th/gth.c @@ -564,6 +564,21 @@ static void gth_tscu_resync(struct gth_device *gth) iowrite32(reg, gth->base + REG_TSCU_TSUCTRL); } +static void intel_th_gth_prepare(struct intel_th_device *thdev, + struct intel_th_output *output) +{ + struct gth_device *gth = dev_get_drvdata(&thdev->dev); + int count; + + /* + * Wait until the output port is in reset before we start + * programming it. + */ + for (count = GTH_PLE_WAITLOOP_DEPTH; + count && !(gth_output_get(gth, output->port) & BIT(5)); count--) + cpu_relax(); +} + /** * intel_th_gth_enable() - enable tracing to an output device * @thdev: GTH device @@ -815,6 +830,7 @@ static struct intel_th_driver intel_th_gth_driver = { .assign = intel_th_gth_assign, .unassign = intel_th_gth_unassign, .set_output = intel_th_gth_set_output, + .prepare = intel_th_gth_prepare, .enable = intel_th_gth_enable, .trig_switch = intel_th_gth_switch, .disable = intel_th_gth_disable, diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h index 5fe694708b7a..595615b79108 100644 --- a/drivers/hwtracing/intel_th/intel_th.h +++ b/drivers/hwtracing/intel_th/intel_th.h @@ -143,6 +143,7 @@ intel_th_output_assigned(struct intel_th_device *thdev) * @remove: remove method * @assign: match a given output type device against available outputs * @unassign: deassociate an output type device from an output port + * @prepare: prepare output port for tracing * @enable: enable tracing for a given output device * @disable: disable tracing for a given output device * @irq: interrupt callback @@ -164,6 +165,8 @@ struct intel_th_driver { struct intel_th_device *othdev); void (*unassign)(struct intel_th_device *thdev, struct intel_th_device *othdev); + void (*prepare)(struct intel_th_device *thdev, + struct intel_th_output *output); void (*enable)(struct intel_th_device *thdev, struct intel_th_output *output); void (*trig_switch)(struct intel_th_device *thdev, diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index e42b87e96f74..eab6fd6b890e 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -974,6 +974,9 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, } out: + /* Unlock the SMBus device for use by BIOS/ACPI */ + outb_p(SMBHSTSTS_INUSE_STS, SMBHSTSTS(priv)); + pm_runtime_mark_last_busy(&priv->pci_dev->dev); pm_runtime_put_autosuspend(&priv->pci_dev->dev); mutex_unlock(&priv->acpi_lock); diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index d94f05c8b8b7..af349661fd76 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #define CCR_MTX 0x10 #define CCR_TXAK 0x08 #define CCR_RSTA 0x04 +#define CCR_RSVD 0x02 #define CSR_MCF 0x80 #define CSR_MAAS 0x40 @@ -70,6 +72,7 @@ struct mpc_i2c { u8 fdr, dfsrr; #endif struct clk *clk_per; + bool has_errata_A004447; }; struct mpc_i2c_divider { @@ -176,6 +179,75 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) return 0; } +static int i2c_mpc_wait_sr(struct mpc_i2c *i2c, int mask) +{ + void __iomem *addr = i2c->base + MPC_I2C_SR; + u8 val; + + return readb_poll_timeout(addr, val, val & mask, 0, 100); +} + +/* + * Workaround for Erratum A004447. From the P2040CE Rev Q + * + * 1. Set up the frequency divider and sampling rate. + * 2. I2CCR - a0h + * 3. Poll for I2CSR[MBB] to get set. + * 4. If I2CSR[MAL] is set (an indication that SDA is stuck low), then go to + * step 5. If MAL is not set, then go to step 13. + * 5. I2CCR - 00h + * 6. I2CCR - 22h + * 7. I2CCR - a2h + * 8. Poll for I2CSR[MBB] to get set. + * 9. Issue read to I2CDR. + * 10. Poll for I2CSR[MIF] to be set. + * 11. I2CCR - 82h + * 12. Workaround complete. Skip the next steps. + * 13. Issue read to I2CDR. + * 14. Poll for I2CSR[MIF] to be set. + * 15. I2CCR - 80h + */ +static void mpc_i2c_fixup_A004447(struct mpc_i2c *i2c) +{ + int ret; + u32 val; + + writeccr(i2c, CCR_MEN | CCR_MSTA); + ret = i2c_mpc_wait_sr(i2c, CSR_MBB); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MBB\n"); + return; + } + + val = readb(i2c->base + MPC_I2C_SR); + + if (val & CSR_MAL) { + writeccr(i2c, 0x00); + writeccr(i2c, CCR_MSTA | CCR_RSVD); + writeccr(i2c, CCR_MEN | CCR_MSTA | CCR_RSVD); + ret = i2c_mpc_wait_sr(i2c, CSR_MBB); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MBB\n"); + return; + } + val = readb(i2c->base + MPC_I2C_DR); + ret = i2c_mpc_wait_sr(i2c, CSR_MIF); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MIF\n"); + return; + } + writeccr(i2c, CCR_MEN | CCR_RSVD); + } else { + val = readb(i2c->base + MPC_I2C_DR); + ret = i2c_mpc_wait_sr(i2c, CSR_MIF); + if (ret) { + dev_err(i2c->dev, "timeout waiting for CSR_MIF\n"); + return; + } + writeccr(i2c, CCR_MEN); + } +} + #if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x) static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23}, @@ -586,7 +658,7 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { writeb(status & ~CSR_MAL, i2c->base + MPC_I2C_SR); - mpc_i2c_fixup(i2c); + i2c_recover_bus(&i2c->adap); } return -EIO; } @@ -622,7 +694,7 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) { writeb(status & ~CSR_MAL, i2c->base + MPC_I2C_SR); - mpc_i2c_fixup(i2c); + i2c_recover_bus(&i2c->adap); } return -EIO; } @@ -637,6 +709,18 @@ static u32 mpc_functionality(struct i2c_adapter *adap) | I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL; } +static int fsl_i2c_bus_recovery(struct i2c_adapter *adap) +{ + struct mpc_i2c *i2c = i2c_get_adapdata(adap); + + if (i2c->has_errata_A004447) + mpc_i2c_fixup_A004447(i2c); + else + mpc_i2c_fixup(i2c); + + return 0; +} + static const struct i2c_algorithm mpc_algo = { .master_xfer = mpc_xfer, .functionality = mpc_functionality, @@ -648,6 +732,10 @@ static struct i2c_adapter mpc_ops = { .timeout = HZ, }; +static struct i2c_bus_recovery_info fsl_i2c_recovery_info = { + .recover_bus = fsl_i2c_bus_recovery, +}; + static const struct of_device_id mpc_i2c_of_match[]; static int fsl_i2c_probe(struct platform_device *op) { @@ -732,6 +820,8 @@ static int fsl_i2c_probe(struct platform_device *op) dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ); platform_set_drvdata(op, i2c); + if (of_property_read_bool(op->dev.of_node, "fsl,i2c-erratum-a004447")) + i2c->has_errata_A004447 = true; i2c->adap = mpc_ops; of_address_to_resource(op->dev.of_node, 0, &res); @@ -740,6 +830,7 @@ static int fsl_i2c_probe(struct platform_device *op) i2c_set_adapdata(&i2c->adap, i2c); i2c->adap.dev.parent = &op->dev; i2c->adap.dev.of_node = of_node_get(op->dev.of_node); + i2c->adap.bus_recovery_info = &fsl_i2c_recovery_info; result = i2c_add_adapter(&i2c->adap); if (result < 0) diff --git a/drivers/i2c/busses/i2c-robotfuzz-osif.c b/drivers/i2c/busses/i2c-robotfuzz-osif.c index a39f7d092797..66dfa211e736 100644 --- a/drivers/i2c/busses/i2c-robotfuzz-osif.c +++ b/drivers/i2c/busses/i2c-robotfuzz-osif.c @@ -83,7 +83,7 @@ static int osif_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, } } - ret = osif_usb_read(adapter, OSIFI2C_STOP, 0, 0, NULL, 0); + ret = osif_usb_write(adapter, OSIFI2C_STOP, 0, 0, NULL, 0); if (ret) { dev_err(&adapter->dev, "failure sending STOP\n"); return -EREMOTEIO; @@ -153,7 +153,7 @@ static int osif_probe(struct usb_interface *interface, * Set bus frequency. The frequency is: * 120,000,000 / ( 16 + 2 * div * 4^prescale). * Using dev = 52, prescale = 0 give 100KHz */ - ret = osif_usb_read(&priv->adapter, OSIFI2C_SET_BIT_RATE, 52, 0, + ret = osif_usb_write(&priv->adapter, OSIFI2C_SET_BIT_RATE, 52, 0, NULL, 0); if (ret) { dev_err(&interface->dev, "failure sending bit rate"); diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index c13e7f107dd3..bdce6d3e5327 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -585,6 +586,8 @@ static void i2c_device_shutdown(struct device *dev) driver = to_i2c_driver(dev->driver); if (driver->shutdown) driver->shutdown(client); + else if (client->irq > 0) + disable_irq(client->irq); } static void i2c_client_dev_release(struct device *dev) diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 6ef38a8ee95c..f358120d59b3 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -141,7 +141,7 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count, if (count > 8192) count = 8192; - tmp = kmalloc(count, GFP_KERNEL); + tmp = kzalloc(count, GFP_KERNEL); if (tmp == NULL) return -ENOMEM; @@ -150,7 +150,8 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count, ret = i2c_master_recv(client, tmp, count); if (ret >= 0) - ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret; + if (copy_to_user(buf, tmp, ret)) + ret = -EFAULT; kfree(tmp); return ret; } diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 6b74c2b04c15..da56488182d0 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -55,7 +55,7 @@ struct bma180_part_info { u8 int_reset_reg, int_reset_mask; u8 sleep_reg, sleep_mask; - u8 bw_reg, bw_mask; + u8 bw_reg, bw_mask, bw_offset; u8 scale_reg, scale_mask; u8 power_reg, power_mask, lowpower_val; u8 int_enable_reg, int_enable_mask; @@ -127,6 +127,7 @@ struct bma180_part_info { #define BMA250_RANGE_MASK GENMASK(3, 0) /* Range of accel values */ #define BMA250_BW_MASK GENMASK(4, 0) /* Accel bandwidth */ +#define BMA250_BW_OFFSET 8 #define BMA250_SUSPEND_MASK BIT(7) /* chip will sleep */ #define BMA250_LOWPOWER_MASK BIT(6) #define BMA250_DATA_INTEN_MASK BIT(4) @@ -143,6 +144,7 @@ struct bma180_part_info { #define BMA254_RANGE_MASK GENMASK(3, 0) /* Range of accel values */ #define BMA254_BW_MASK GENMASK(4, 0) /* Accel bandwidth */ +#define BMA254_BW_OFFSET 8 #define BMA254_SUSPEND_MASK BIT(7) /* chip will sleep */ #define BMA254_LOWPOWER_MASK BIT(6) #define BMA254_DATA_INTEN_MASK BIT(4) @@ -162,7 +164,11 @@ struct bma180_data { int scale; int bw; bool pmode; - u8 buff[16]; /* 3x 16-bit + 8-bit + padding + timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + s16 chan[4]; + s64 timestamp __aligned(8); + } scan; }; enum bma180_chan { @@ -283,7 +289,8 @@ static int bma180_set_bw(struct bma180_data *data, int val) for (i = 0; i < data->part_info->num_bw; ++i) { if (data->part_info->bw_table[i] == val) { ret = bma180_set_bits(data, data->part_info->bw_reg, - data->part_info->bw_mask, i); + data->part_info->bw_mask, + i + data->part_info->bw_offset); if (ret) { dev_err(&data->client->dev, "failed to set bandwidth\n"); @@ -876,6 +883,7 @@ static const struct bma180_part_info bma180_part_info[] = { .sleep_mask = BMA250_SUSPEND_MASK, .bw_reg = BMA250_BW_REG, .bw_mask = BMA250_BW_MASK, + .bw_offset = BMA250_BW_OFFSET, .scale_reg = BMA250_RANGE_REG, .scale_mask = BMA250_RANGE_MASK, .power_reg = BMA250_POWER_REG, @@ -905,6 +913,7 @@ static const struct bma180_part_info bma180_part_info[] = { .sleep_mask = BMA254_SUSPEND_MASK, .bw_reg = BMA254_BW_REG, .bw_mask = BMA254_BW_MASK, + .bw_offset = BMA254_BW_OFFSET, .scale_reg = BMA254_RANGE_REG, .scale_mask = BMA254_RANGE_MASK, .power_reg = BMA254_POWER_REG, @@ -938,12 +947,12 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p) mutex_unlock(&data->mutex); goto err; } - ((s16 *)data->buff)[i++] = ret; + data->scan.chan[i++] = ret; } mutex_unlock(&data->mutex); - iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns); + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, time_ns); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/accel/bma220_spi.c b/drivers/iio/accel/bma220_spi.c index 3c9b0c6954e6..e8a9db1a82ad 100644 --- a/drivers/iio/accel/bma220_spi.c +++ b/drivers/iio/accel/bma220_spi.c @@ -63,7 +63,11 @@ static const int bma220_scale_table[][2] = { struct bma220_data { struct spi_device *spi_device; struct mutex lock; - s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 8x8 timestamp */ + struct { + s8 chans[3]; + /* Ensure timestamp is naturally aligned. */ + s64 timestamp __aligned(8); + } scan; u8 tx_buf[2] ____cacheline_aligned; }; @@ -94,12 +98,12 @@ static irqreturn_t bma220_trigger_handler(int irq, void *p) mutex_lock(&data->lock); data->tx_buf[0] = BMA220_REG_ACCEL_X | BMA220_READ_MASK; - ret = spi_write_then_read(spi, data->tx_buf, 1, data->buffer, + ret = spi_write_then_read(spi, data->tx_buf, 1, &data->scan.chans, ARRAY_SIZE(bma220_channels) - 1); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: mutex_unlock(&data->lock); diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c index 4c5e594024f8..f05840d17fb7 100644 --- a/drivers/iio/accel/hid-sensor-accel-3d.c +++ b/drivers/iio/accel/hid-sensor-accel-3d.c @@ -27,8 +27,11 @@ struct accel_3d_state { struct hid_sensor_hub_callbacks callbacks; struct hid_sensor_common common_attributes; struct hid_sensor_hub_attribute_info accel[ACCEL_3D_CHANNEL_MAX]; - /* Reserve for 3 channels + padding + timestamp */ - u32 accel_val[ACCEL_3D_CHANNEL_MAX + 3]; + /* Ensure timestamp is naturally aligned */ + struct { + u32 accel_val[3]; + s64 timestamp __aligned(8); + } scan; int scale_pre_decml; int scale_post_decml; int scale_precision; @@ -239,8 +242,8 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev, accel_state->timestamp = iio_get_time_ns(indio_dev); hid_sensor_push_data(indio_dev, - accel_state->accel_val, - sizeof(accel_state->accel_val), + &accel_state->scan, + sizeof(accel_state->scan), accel_state->timestamp); accel_state->timestamp = 0; @@ -265,7 +268,7 @@ static int accel_3d_capture_sample(struct hid_sensor_hub_device *hsdev, case HID_USAGE_SENSOR_ACCEL_Y_AXIS: case HID_USAGE_SENSOR_ACCEL_Z_AXIS: offset = usage_id - HID_USAGE_SENSOR_ACCEL_X_AXIS; - accel_state->accel_val[CHANNEL_SCAN_INDEX_X + offset] = + accel_state->scan.accel_val[CHANNEL_SCAN_INDEX_X + offset] = *(u32 *)raw_data; ret = 0; break; diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 560a3373ff20..c99e90469a24 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -132,13 +132,24 @@ enum kx_acpi_type { ACPI_KIOX010A, }; +enum kxcjk1013_axis { + AXIS_X, + AXIS_Y, + AXIS_Z, + AXIS_MAX +}; + struct kxcjk1013_data { struct i2c_client *client; struct iio_trigger *dready_trig; struct iio_trigger *motion_trig; struct iio_mount_matrix orientation; struct mutex mutex; - s16 buffer[8]; + /* Ensure timestamp naturally aligned */ + struct { + s16 chans[AXIS_MAX]; + s64 timestamp __aligned(8); + } scan; u8 odr_bits; u8 range; int wake_thres; @@ -152,13 +163,6 @@ struct kxcjk1013_data { enum kx_acpi_type acpi_type; }; -enum kxcjk1013_axis { - AXIS_X, - AXIS_Y, - AXIS_Z, - AXIS_MAX, -}; - enum kxcjk1013_mode { STANDBY, OPERATION, @@ -1092,12 +1096,12 @@ static irqreturn_t kxcjk1013_trigger_handler(int irq, void *p) ret = i2c_smbus_read_i2c_block_data_or_emulated(data->client, KXCJK1013_REG_XOUT_L, AXIS_MAX * 2, - (u8 *)data->buffer); + (u8 *)data->scan.chans); mutex_unlock(&data->mutex); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, data->timestamp); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c index f877263dc6ef..5a2b0ffbb145 100644 --- a/drivers/iio/accel/mxc4005.c +++ b/drivers/iio/accel/mxc4005.c @@ -56,7 +56,11 @@ struct mxc4005_data { struct mutex mutex; struct regmap *regmap; struct iio_trigger *dready_trig; - __be16 buffer[8]; + /* Ensure timestamp is naturally aligned */ + struct { + __be16 chans[3]; + s64 timestamp __aligned(8); + } scan; bool trigger_enabled; }; @@ -135,7 +139,7 @@ static int mxc4005_read_xyz(struct mxc4005_data *data) int ret; ret = regmap_bulk_read(data->regmap, MXC4005_REG_XOUT_UPPER, - data->buffer, sizeof(data->buffer)); + data->scan.chans, sizeof(data->scan.chans)); if (ret < 0) { dev_err(data->dev, "failed to read axes\n"); return ret; @@ -301,7 +305,7 @@ static irqreturn_t mxc4005_trigger_handler(int irq, void *private) if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: diff --git a/drivers/iio/accel/stk8312.c b/drivers/iio/accel/stk8312.c index 3b59887a8581..7d24801e8aa7 100644 --- a/drivers/iio/accel/stk8312.c +++ b/drivers/iio/accel/stk8312.c @@ -103,7 +103,11 @@ struct stk8312_data { u8 mode; struct iio_trigger *dready_trig; bool dready_trigger_on; - s8 buffer[16]; /* 3x8-bit channels + 5x8 padding + 64-bit timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + s8 chans[3]; + s64 timestamp __aligned(8); + } scan; }; static IIO_CONST_ATTR(in_accel_scale_available, STK8312_SCALE_AVAIL); @@ -438,7 +442,7 @@ static irqreturn_t stk8312_trigger_handler(int irq, void *p) ret = i2c_smbus_read_i2c_block_data(data->client, STK8312_REG_XOUT, STK8312_ALL_CHANNEL_SIZE, - data->buffer); + data->scan.chans); if (ret < STK8312_ALL_CHANNEL_SIZE) { dev_err(&data->client->dev, "register read failed\n"); mutex_unlock(&data->lock); @@ -452,12 +456,12 @@ static irqreturn_t stk8312_trigger_handler(int irq, void *p) mutex_unlock(&data->lock); goto err; } - data->buffer[i++] = ret; + data->scan.chans[i++] = ret; } } mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c index 3ead378b02c9..e8087d7ee49f 100644 --- a/drivers/iio/accel/stk8ba50.c +++ b/drivers/iio/accel/stk8ba50.c @@ -91,12 +91,11 @@ struct stk8ba50_data { u8 sample_rate_idx; struct iio_trigger *dready_trig; bool dready_trigger_on; - /* - * 3 x 16-bit channels (10-bit data, 6-bit padding) + - * 1 x 16 padding + - * 4 x 16 64-bit timestamp - */ - s16 buffer[8]; + /* Ensure timestamp is naturally aligned */ + struct { + s16 chans[3]; + s64 timetamp __aligned(8); + } scan; }; #define STK8BA50_ACCEL_CHANNEL(index, reg, axis) { \ @@ -324,7 +323,7 @@ static irqreturn_t stk8ba50_trigger_handler(int irq, void *p) ret = i2c_smbus_read_i2c_block_data(data->client, STK8BA50_REG_XOUT, STK8BA50_ALL_CHANNEL_SIZE, - (u8 *)data->buffer); + (u8 *)data->scan.chans); if (ret < STK8BA50_ALL_CHANNEL_SIZE) { dev_err(&data->client->dev, "register read failed\n"); goto err; @@ -337,10 +336,10 @@ static irqreturn_t stk8ba50_trigger_handler(int irq, void *p) if (ret < 0) goto err; - data->buffer[i++] = ret; + data->scan.chans[i++] = ret; } } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: mutex_unlock(&data->lock); diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c index b917a4714a9c..b8139c435a4b 100644 --- a/drivers/iio/adc/at91-sama5d2_adc.c +++ b/drivers/iio/adc/at91-sama5d2_adc.c @@ -403,7 +403,8 @@ struct at91_adc_state { struct at91_adc_dma dma_st; struct at91_adc_touch touch_st; struct iio_dev *indio_dev; - u16 buffer[AT91_BUFFER_MAX_HWORDS]; + /* Ensure naturally aligned timestamp */ + u16 buffer[AT91_BUFFER_MAX_HWORDS] __aligned(8); /* * lock to prevent concurrent 'single conversion' requests through * sysfs. diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c index 6a173531d355..f7ee856a6b8b 100644 --- a/drivers/iio/adc/hx711.c +++ b/drivers/iio/adc/hx711.c @@ -86,9 +86,9 @@ struct hx711_data { struct mutex lock; /* * triggered buffer - * 2x32-bit channel + 64-bit timestamp + * 2x32-bit channel + 64-bit naturally aligned timestamp */ - u32 buffer[4]; + u32 buffer[4] __aligned(8); /* * delay after a rising edge on SCK until the data is ready DOUT * this is dependent on the hx711 where the datasheet tells a diff --git a/drivers/iio/adc/mxs-lradc-adc.c b/drivers/iio/adc/mxs-lradc-adc.c index 30e29f44ebd2..c480cb489c1a 100644 --- a/drivers/iio/adc/mxs-lradc-adc.c +++ b/drivers/iio/adc/mxs-lradc-adc.c @@ -115,7 +115,8 @@ struct mxs_lradc_adc { struct device *dev; void __iomem *base; - u32 buffer[10]; + /* Maximum of 8 channels + 8 byte ts */ + u32 buffer[10] __aligned(8); struct iio_trigger *trig; struct completion completion; spinlock_t lock; diff --git a/drivers/iio/adc/palmas_gpadc.c b/drivers/iio/adc/palmas_gpadc.c index 889b88768b63..f4756671cddb 100644 --- a/drivers/iio/adc/palmas_gpadc.c +++ b/drivers/iio/adc/palmas_gpadc.c @@ -654,8 +654,8 @@ static int palmas_adc_wakeup_configure(struct palmas_gpadc *adc) adc_period = adc->auto_conversion_period; for (i = 0; i < 16; ++i) { - if (((1000 * (1 << i)) / 32) < adc_period) - continue; + if (((1000 * (1 << i)) / 32) >= adc_period) + break; } if (i > 0) i--; diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 9fef39bcf997..5b828428be77 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -395,10 +395,14 @@ static irqreturn_t ads1015_trigger_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct ads1015_data *data = iio_priv(indio_dev); - s16 buf[8]; /* 1x s16 ADC val + 3x s16 padding + 4x s16 timestamp */ + /* Ensure natural alignment of timestamp */ + struct { + s16 chan; + s64 timestamp __aligned(8); + } scan; int chan, ret, res; - memset(buf, 0, sizeof(buf)); + memset(&scan, 0, sizeof(scan)); mutex_lock(&data->lock); chan = find_first_bit(indio_dev->active_scan_mask, @@ -409,10 +413,10 @@ static irqreturn_t ads1015_trigger_handler(int irq, void *p) goto err; } - buf[0] = res; + scan.chan = res; mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, buf, + iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev)); err: diff --git a/drivers/iio/adc/ti-ads7950.c b/drivers/iio/adc/ti-ads7950.c index 2383eacada87..a2b83f0bd526 100644 --- a/drivers/iio/adc/ti-ads7950.c +++ b/drivers/iio/adc/ti-ads7950.c @@ -568,7 +568,6 @@ static int ti_ads7950_probe(struct spi_device *spi) st->ring_xfer.tx_buf = &st->tx_buf[0]; st->ring_xfer.rx_buf = &st->rx_buf[0]; /* len will be set later */ - st->ring_xfer.cs_change = true; spi_message_add_tail(&st->ring_xfer, &st->ring_msg); diff --git a/drivers/iio/adc/ti-ads8688.c b/drivers/iio/adc/ti-ads8688.c index 16bcb37eebb7..79c803537dc4 100644 --- a/drivers/iio/adc/ti-ads8688.c +++ b/drivers/iio/adc/ti-ads8688.c @@ -383,7 +383,8 @@ static irqreturn_t ads8688_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; - u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)]; + /* Ensure naturally aligned timestamp */ + u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8); int i, j = 0; for (i = 0; i < indio_dev->masklength; i++) { diff --git a/drivers/iio/adc/vf610_adc.c b/drivers/iio/adc/vf610_adc.c index 1d794cf3e3f1..fd57fc43e8e5 100644 --- a/drivers/iio/adc/vf610_adc.c +++ b/drivers/iio/adc/vf610_adc.c @@ -167,7 +167,11 @@ struct vf610_adc { u32 sample_freq_avail[5]; struct completion completion; - u16 buffer[8]; + /* Ensure the timestamp is naturally aligned */ + struct { + u16 chan; + s64 timestamp __aligned(8); + } scan; }; static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 }; @@ -579,9 +583,9 @@ static irqreturn_t vf610_adc_isr(int irq, void *dev_id) if (coco & VF610_ADC_HS_COCO0) { info->value = vf610_adc_read_data(info); if (iio_buffer_enabled(indio_dev)) { - info->buffer[0] = info->value; + info->scan.chan = info->value; iio_push_to_buffers_with_timestamp(indio_dev, - info->buffer, + &info->scan, iio_get_time_ns(indio_dev)); iio_trigger_notify_done(indio_dev->trig); } else diff --git a/drivers/iio/chemical/atlas-sensor.c b/drivers/iio/chemical/atlas-sensor.c index cdab9d04dedd..0c8a50de8940 100644 --- a/drivers/iio/chemical/atlas-sensor.c +++ b/drivers/iio/chemical/atlas-sensor.c @@ -91,8 +91,8 @@ struct atlas_data { struct regmap *regmap; struct irq_work work; unsigned int interrupt_enabled; - - __be32 buffer[6]; /* 96-bit data + 32-bit pad + 64-bit timestamp */ + /* 96-bit data + 32-bit pad + 64-bit timestamp */ + __be32 buffer[6] __aligned(8); }; static const struct regmap_config atlas_regmap_config = { diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index 82c050a3899d..8f885b0af38e 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c @@ -563,8 +563,10 @@ static int adf4350_probe(struct spi_device *spi) st->lock_detect_gpiod = devm_gpiod_get_optional(&spi->dev, NULL, GPIOD_IN); - if (IS_ERR(st->lock_detect_gpiod)) - return PTR_ERR(st->lock_detect_gpiod); + if (IS_ERR(st->lock_detect_gpiod)) { + ret = PTR_ERR(st->lock_detect_gpiod); + goto error_disable_reg; + } if (pdata->power_up_frequency) { ret = adf4350_set_freq(st, pdata->power_up_frequency); diff --git a/drivers/iio/gyro/bmg160_core.c b/drivers/iio/gyro/bmg160_core.c index 8ddda96455fc..39fe0b178592 100644 --- a/drivers/iio/gyro/bmg160_core.c +++ b/drivers/iio/gyro/bmg160_core.c @@ -96,7 +96,11 @@ struct bmg160_data { struct iio_trigger *motion_trig; struct iio_mount_matrix orientation; struct mutex mutex; - s16 buffer[8]; + /* Ensure naturally aligned timestamp */ + struct { + s16 chans[3]; + s64 timestamp __aligned(8); + } scan; u32 dps_range; int ev_enable_state; int slope_thres; @@ -880,12 +884,12 @@ static irqreturn_t bmg160_trigger_handler(int irq, void *p) mutex_lock(&data->mutex); ret = regmap_bulk_read(data->regmap, BMG160_REG_XOUT_L, - data->buffer, AXIS_MAX * 2); + data->scan.chans, AXIS_MAX * 2); mutex_unlock(&data->mutex); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/gyro/fxas21002c_core.c b/drivers/iio/gyro/fxas21002c_core.c index b7523357d8eb..ec6bd15bd2d4 100644 --- a/drivers/iio/gyro/fxas21002c_core.c +++ b/drivers/iio/gyro/fxas21002c_core.c @@ -366,14 +366,7 @@ static int fxas21002c_write(struct fxas21002c_data *data, static int fxas21002c_pm_get(struct fxas21002c_data *data) { - struct device *dev = regmap_get_device(data->regmap); - int ret; - - ret = pm_runtime_get_sync(dev); - if (ret < 0) - pm_runtime_put_noidle(dev); - - return ret; + return pm_runtime_resume_and_get(regmap_get_device(data->regmap)); } static int fxas21002c_pm_put(struct fxas21002c_data *data) @@ -1005,7 +998,6 @@ int fxas21002c_core_probe(struct device *dev, struct regmap *regmap, int irq, pm_disable: pm_runtime_disable(dev); pm_runtime_set_suspended(dev); - pm_runtime_put_noidle(dev); return ret; } @@ -1019,7 +1011,6 @@ void fxas21002c_core_remove(struct device *dev) pm_runtime_disable(dev); pm_runtime_set_suspended(dev); - pm_runtime_put_noidle(dev); } EXPORT_SYMBOL_GPL(fxas21002c_core_remove); diff --git a/drivers/iio/humidity/am2315.c b/drivers/iio/humidity/am2315.c index 02ad1767c845..3398fa413ec5 100644 --- a/drivers/iio/humidity/am2315.c +++ b/drivers/iio/humidity/am2315.c @@ -33,7 +33,11 @@ struct am2315_data { struct i2c_client *client; struct mutex lock; - s16 buffer[8]; /* 2x16-bit channels + 2x16 padding + 4x16 timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + s16 chans[2]; + s64 timestamp __aligned(8); + } scan; }; struct am2315_sensor_data { @@ -167,20 +171,20 @@ static irqreturn_t am2315_trigger_handler(int irq, void *p) mutex_lock(&data->lock); if (*(indio_dev->active_scan_mask) == AM2315_ALL_CHANNEL_MASK) { - data->buffer[0] = sensor_data.hum_data; - data->buffer[1] = sensor_data.temp_data; + data->scan.chans[0] = sensor_data.hum_data; + data->scan.chans[1] = sensor_data.temp_data; } else { i = 0; for_each_set_bit(bit, indio_dev->active_scan_mask, indio_dev->masklength) { - data->buffer[i] = (bit ? sensor_data.temp_data : - sensor_data.hum_data); + data->scan.chans[i] = (bit ? sensor_data.temp_data : + sensor_data.hum_data); i++; } } mutex_unlock(&data->lock); - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c index 2a957f19048e..9e0fce917ce4 100644 --- a/drivers/iio/humidity/hdc100x.c +++ b/drivers/iio/humidity/hdc100x.c @@ -25,6 +25,8 @@ #include #include +#include + #define HDC100X_REG_TEMP 0x00 #define HDC100X_REG_HUMIDITY 0x01 @@ -166,7 +168,7 @@ static int hdc100x_get_measurement(struct hdc100x_data *data, struct iio_chan_spec const *chan) { struct i2c_client *client = data->client; - int delay = data->adc_int_us[chan->address]; + int delay = data->adc_int_us[chan->address] + 1*USEC_PER_MSEC; int ret; __be16 val; @@ -316,7 +318,7 @@ static irqreturn_t hdc100x_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct hdc100x_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; - int delay = data->adc_int_us[0] + data->adc_int_us[1]; + int delay = data->adc_int_us[0] + data->adc_int_us[1] + 2*USEC_PER_MSEC; int ret; /* dual read starts at temp register */ diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index 319b64b2fd88..f8b7837d8b8f 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -415,12 +415,11 @@ int __adis_initial_startup(struct adis *adis) int ret; /* check if the device has rst pin low */ - gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset", GPIOD_ASIS); + gpio = devm_gpiod_get_optional(&adis->spi->dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(gpio)) return PTR_ERR(gpio); if (gpio) { - gpiod_set_value_cansleep(gpio, 1); msleep(10); /* bring device out of reset */ gpiod_set_value_cansleep(gpio, 0); diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c index 785a4ce606d8..4aff16466da0 100644 --- a/drivers/iio/imu/adis16400.c +++ b/drivers/iio/imu/adis16400.c @@ -647,9 +647,6 @@ static irqreturn_t adis16400_trigger_handler(int irq, void *p) void *buffer; int ret; - if (!adis->buffer) - return -ENOMEM; - if (!(st->variant->flags & ADIS16400_NO_BURST) && st->adis.spi->max_speed_hz > ADIS16400_SPI_BURST) { st->adis.spi->max_speed_hz = ADIS16400_SPI_BURST; diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c index 197d48240991..3c4e4deb8760 100644 --- a/drivers/iio/imu/adis16475.c +++ b/drivers/iio/imu/adis16475.c @@ -990,7 +990,7 @@ static irqreturn_t adis16475_trigger_handler(int irq, void *p) ret = spi_sync(adis->spi, &adis->msg); if (ret) - return ret; + goto check_burst32; adis->spi->max_speed_hz = cached_spi_speed_hz; buffer = adis->buffer; diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c index ac354321f63a..175af154e443 100644 --- a/drivers/iio/imu/adis_buffer.c +++ b/drivers/iio/imu/adis_buffer.c @@ -129,9 +129,6 @@ static irqreturn_t adis_trigger_handler(int irq, void *p) struct adis *adis = iio_device_get_drvdata(indio_dev); int ret; - if (!adis->buffer) - return -ENOMEM; - if (adis->data->has_paging) { mutex_lock(&adis->state_lock); if (adis->current_page != 0) { diff --git a/drivers/iio/light/isl29125.c b/drivers/iio/light/isl29125.c index b93b85dbc3a6..ba53b50d711a 100644 --- a/drivers/iio/light/isl29125.c +++ b/drivers/iio/light/isl29125.c @@ -51,7 +51,11 @@ struct isl29125_data { struct i2c_client *client; u8 conf1; - u16 buffer[8]; /* 3x 16-bit, padding, 8 bytes timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chans[3]; + s64 timestamp __aligned(8); + } scan; }; #define ISL29125_CHANNEL(_color, _si) { \ @@ -184,10 +188,10 @@ static irqreturn_t isl29125_trigger_handler(int irq, void *p) if (ret < 0) goto done; - data->buffer[j++] = ret; + data->scan.chans[j++] = ret; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c index b4323d2db0b1..74ed2d88a3ed 100644 --- a/drivers/iio/light/ltr501.c +++ b/drivers/iio/light/ltr501.c @@ -32,9 +32,12 @@ #define LTR501_PART_ID 0x86 #define LTR501_MANUFAC_ID 0x87 #define LTR501_ALS_DATA1 0x88 /* 16-bit, little endian */ +#define LTR501_ALS_DATA1_UPPER 0x89 /* upper 8 bits of LTR501_ALS_DATA1 */ #define LTR501_ALS_DATA0 0x8a /* 16-bit, little endian */ +#define LTR501_ALS_DATA0_UPPER 0x8b /* upper 8 bits of LTR501_ALS_DATA0 */ #define LTR501_ALS_PS_STATUS 0x8c #define LTR501_PS_DATA 0x8d /* 16-bit, little endian */ +#define LTR501_PS_DATA_UPPER 0x8e /* upper 8 bits of LTR501_PS_DATA */ #define LTR501_INTR 0x8f /* output mode, polarity, mode */ #define LTR501_PS_THRESH_UP 0x90 /* 11 bit, ps upper threshold */ #define LTR501_PS_THRESH_LOW 0x92 /* 11 bit, ps lower threshold */ @@ -406,18 +409,19 @@ static int ltr501_read_als(const struct ltr501_data *data, __le16 buf[2]) static int ltr501_read_ps(const struct ltr501_data *data) { - int ret, status; + __le16 status; + int ret; ret = ltr501_drdy(data, LTR501_STATUS_PS_RDY); if (ret < 0) return ret; ret = regmap_bulk_read(data->regmap, LTR501_PS_DATA, - &status, 2); + &status, sizeof(status)); if (ret < 0) return ret; - return status; + return le16_to_cpu(status); } static int ltr501_read_intr_prst(const struct ltr501_data *data, @@ -1205,7 +1209,7 @@ static struct ltr501_chip_info ltr501_chip_info_tbl[] = { .als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl), .ps_gain = ltr559_ps_gain_tbl, .ps_gain_tbl_size = ARRAY_SIZE(ltr559_ps_gain_tbl), - .als_mode_active = BIT(1), + .als_mode_active = BIT(0), .als_gain_mask = BIT(2) | BIT(3) | BIT(4), .als_gain_shift = 2, .info = <r501_info, @@ -1354,9 +1358,12 @@ static bool ltr501_is_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case LTR501_ALS_DATA1: + case LTR501_ALS_DATA1_UPPER: case LTR501_ALS_DATA0: + case LTR501_ALS_DATA0_UPPER: case LTR501_ALS_PS_STATUS: case LTR501_PS_DATA: + case LTR501_PS_DATA_UPPER: return true; default: return false; diff --git a/drivers/iio/light/tcs3414.c b/drivers/iio/light/tcs3414.c index 6fe5d46f80d4..0593abd600ec 100644 --- a/drivers/iio/light/tcs3414.c +++ b/drivers/iio/light/tcs3414.c @@ -53,7 +53,11 @@ struct tcs3414_data { u8 control; u8 gain; u8 timing; - u16 buffer[8]; /* 4x 16-bit + 8 bytes timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chans[4]; + s64 timestamp __aligned(8); + } scan; }; #define TCS3414_CHANNEL(_color, _si, _addr) { \ @@ -209,10 +213,10 @@ static irqreturn_t tcs3414_trigger_handler(int irq, void *p) if (ret < 0) goto done; - data->buffer[j++] = ret; + data->scan.chans[j++] = ret; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: diff --git a/drivers/iio/light/tcs3472.c b/drivers/iio/light/tcs3472.c index a0dc447aeb68..371c6a39a165 100644 --- a/drivers/iio/light/tcs3472.c +++ b/drivers/iio/light/tcs3472.c @@ -64,7 +64,11 @@ struct tcs3472_data { u8 control; u8 atime; u8 apers; - u16 buffer[8]; /* 4 16-bit channels + 64-bit timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chans[4]; + s64 timestamp __aligned(8); + } scan; }; static const struct iio_event_spec tcs3472_events[] = { @@ -386,10 +390,10 @@ static irqreturn_t tcs3472_trigger_handler(int irq, void *p) if (ret < 0) goto done; - data->buffer[j++] = ret; + data->scan.chans[j++] = ret; } - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: @@ -531,7 +535,8 @@ static int tcs3472_probe(struct i2c_client *client, return 0; free_irq: - free_irq(client->irq, indio_dev); + if (client->irq) + free_irq(client->irq, indio_dev); buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); return ret; @@ -559,7 +564,8 @@ static int tcs3472_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); iio_device_unregister(indio_dev); - free_irq(client->irq, indio_dev); + if (client->irq) + free_irq(client->irq, indio_dev); iio_triggered_buffer_cleanup(indio_dev); tcs3472_powerdown(iio_priv(indio_dev)); diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index fff4b36b8b58..f4feb44903b3 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -910,7 +910,7 @@ static irqreturn_t vcnl4010_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct vcnl4000_data *data = iio_priv(indio_dev); const unsigned long *active_scan_mask = indio_dev->active_scan_mask; - u16 buffer[8] = {0}; /* 1x16-bit + ts */ + u16 buffer[8] __aligned(8) = {0}; /* 1x16-bit + naturally aligned ts */ bool data_read = false; unsigned long isr; int val = 0; diff --git a/drivers/iio/light/vcnl4035.c b/drivers/iio/light/vcnl4035.c index 765c44adac57..1bd85e21fd11 100644 --- a/drivers/iio/light/vcnl4035.c +++ b/drivers/iio/light/vcnl4035.c @@ -102,7 +102,8 @@ static irqreturn_t vcnl4035_trigger_consumer_handler(int irq, void *p) struct iio_poll_func *pf = p; struct iio_dev *indio_dev = pf->indio_dev; struct vcnl4035_data *data = iio_priv(indio_dev); - u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)]; + /* Ensure naturally aligned timestamp */ + u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)] __aligned(8); int ret; ret = regmap_read(data->regmap, VCNL4035_ALS_DATA, (int *)buffer); diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c index fc6840f9c1fa..8eacfaf584cf 100644 --- a/drivers/iio/magnetometer/bmc150_magn.c +++ b/drivers/iio/magnetometer/bmc150_magn.c @@ -136,8 +136,11 @@ struct bmc150_magn_data { struct mutex mutex; struct regmap *regmap; struct iio_mount_matrix orientation; - /* 4 x 32 bits for x, y z, 4 bytes align, 64 bits timestamp */ - s32 buffer[6]; + /* Ensure timestamp is naturally aligned */ + struct { + s32 chans[3]; + s64 timestamp __aligned(8); + } scan; struct iio_trigger *dready_trig; bool dready_trigger_on; int max_odr; @@ -260,7 +263,7 @@ static int bmc150_magn_set_power_state(struct bmc150_magn_data *data, bool on) int ret; if (on) { - ret = pm_runtime_get_sync(data->dev); + ret = pm_runtime_resume_and_get(data->dev); } else { pm_runtime_mark_last_busy(data->dev); ret = pm_runtime_put_autosuspend(data->dev); @@ -269,9 +272,6 @@ static int bmc150_magn_set_power_state(struct bmc150_magn_data *data, bool on) if (ret < 0) { dev_err(data->dev, "failed to change power state to %d\n", on); - if (on) - pm_runtime_put_noidle(data->dev); - return ret; } #endif @@ -673,11 +673,11 @@ static irqreturn_t bmc150_magn_trigger_handler(int irq, void *p) int ret; mutex_lock(&data->mutex); - ret = bmc150_magn_read_xyz(data, data->buffer); + ret = bmc150_magn_read_xyz(data, data->scan.chans); if (ret < 0) goto err; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, pf->timestamp); err: @@ -941,12 +941,14 @@ int bmc150_magn_probe(struct device *dev, struct regmap *regmap, ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(dev, "unable to register iio device\n"); - goto err_buffer_cleanup; + goto err_disable_runtime_pm; } dev_dbg(dev, "Registered device %s\n", name); return 0; +err_disable_runtime_pm: + pm_runtime_disable(dev); err_buffer_cleanup: iio_triggered_buffer_cleanup(indio_dev); err_free_irq: @@ -970,7 +972,6 @@ int bmc150_magn_remove(struct device *dev) pm_runtime_disable(dev); pm_runtime_set_suspended(dev); - pm_runtime_put_noidle(dev); iio_triggered_buffer_cleanup(indio_dev); diff --git a/drivers/iio/magnetometer/hmc5843.h b/drivers/iio/magnetometer/hmc5843.h index 3f6c0b662941..242f742f2643 100644 --- a/drivers/iio/magnetometer/hmc5843.h +++ b/drivers/iio/magnetometer/hmc5843.h @@ -33,7 +33,8 @@ enum hmc5843_ids { * @lock: update and read regmap data * @regmap: hardware access register maps * @variant: describe chip variants - * @buffer: 3x 16-bit channels + padding + 64-bit timestamp + * @scan: buffer to pack data for passing to + * iio_push_to_buffers_with_timestamp() */ struct hmc5843_data { struct device *dev; @@ -41,7 +42,10 @@ struct hmc5843_data { struct regmap *regmap; const struct hmc5843_chip_info *variant; struct iio_mount_matrix orientation; - __be16 buffer[8]; + struct { + __be16 chans[3]; + s64 timestamp __aligned(8); + } scan; }; int hmc5843_common_probe(struct device *dev, struct regmap *regmap, diff --git a/drivers/iio/magnetometer/hmc5843_core.c b/drivers/iio/magnetometer/hmc5843_core.c index 780faea61d82..221563e0c18f 100644 --- a/drivers/iio/magnetometer/hmc5843_core.c +++ b/drivers/iio/magnetometer/hmc5843_core.c @@ -446,13 +446,13 @@ static irqreturn_t hmc5843_trigger_handler(int irq, void *p) } ret = regmap_bulk_read(data->regmap, HMC5843_DATA_OUT_MSB_REGS, - data->buffer, 3 * sizeof(__be16)); + data->scan.chans, sizeof(data->scan.chans)); mutex_unlock(&data->lock); if (ret < 0) goto done; - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); done: diff --git a/drivers/iio/magnetometer/rm3100-core.c b/drivers/iio/magnetometer/rm3100-core.c index 7242897a05e9..720234a91db1 100644 --- a/drivers/iio/magnetometer/rm3100-core.c +++ b/drivers/iio/magnetometer/rm3100-core.c @@ -78,7 +78,8 @@ struct rm3100_data { bool use_interrupt; int conversion_time; int scale; - u8 buffer[RM3100_SCAN_BYTES]; + /* Ensure naturally aligned timestamp */ + u8 buffer[RM3100_SCAN_BYTES] __aligned(8); struct iio_trigger *drdy_trig; /* diff --git a/drivers/iio/potentiostat/lmp91000.c b/drivers/iio/potentiostat/lmp91000.c index f34ca769dc20..d7ff74a798ba 100644 --- a/drivers/iio/potentiostat/lmp91000.c +++ b/drivers/iio/potentiostat/lmp91000.c @@ -71,8 +71,8 @@ struct lmp91000_data { struct completion completion; u8 chan_select; - - u32 buffer[4]; /* 64-bit data + 64-bit timestamp */ + /* 64-bit data + 64-bit naturally aligned timestamp */ + u32 buffer[4] __aligned(8); }; static const struct iio_chan_spec lmp91000_channels[] = { diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c index b79ada839e01..98330e26ac3b 100644 --- a/drivers/iio/proximity/as3935.c +++ b/drivers/iio/proximity/as3935.c @@ -59,7 +59,11 @@ struct as3935_state { unsigned long noise_tripped; u32 tune_cap; u32 nflwdth_reg; - u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u8 chan; + s64 timestamp __aligned(8); + } scan; u8 buf[2] ____cacheline_aligned; }; @@ -225,8 +229,8 @@ static irqreturn_t as3935_trigger_handler(int irq, void *private) if (ret) goto err_read; - st->buffer[0] = val & AS3935_DATA_MASK; - iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer, + st->scan.chan = val & AS3935_DATA_MASK; + iio_push_to_buffers_with_timestamp(indio_dev, &st->scan, iio_get_time_ns(indio_dev)); err_read: iio_trigger_notify_done(indio_dev->trig); diff --git a/drivers/iio/proximity/isl29501.c b/drivers/iio/proximity/isl29501.c index 90e76451c972..5b6ea783795d 100644 --- a/drivers/iio/proximity/isl29501.c +++ b/drivers/iio/proximity/isl29501.c @@ -938,7 +938,7 @@ static irqreturn_t isl29501_trigger_handler(int irq, void *p) struct iio_dev *indio_dev = pf->indio_dev; struct isl29501_private *isl29501 = iio_priv(indio_dev); const unsigned long *active_mask = indio_dev->active_scan_mask; - u32 buffer[4] = {}; /* 1x16-bit + ts */ + u32 buffer[4] __aligned(8) = {}; /* 1x16-bit + naturally aligned ts */ if (test_bit(ISL29501_DISTANCE_SCAN_INDEX, active_mask)) isl29501_register_read(isl29501, REG_DISTANCE, buffer); diff --git a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c index cc206bfa09c7..d854b8d5fbba 100644 --- a/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c +++ b/drivers/iio/proximity/pulsedlight-lidar-lite-v2.c @@ -44,7 +44,11 @@ struct lidar_data { int (*xfer)(struct lidar_data *data, u8 reg, u8 *val, int len); int i2c_enabled; - u16 buffer[8]; /* 2 byte distance + 8 byte timestamp */ + /* Ensure timestamp is naturally aligned */ + struct { + u16 chan; + s64 timestamp __aligned(8); + } scan; }; static const struct iio_chan_spec lidar_channels[] = { @@ -230,9 +234,9 @@ static irqreturn_t lidar_trigger_handler(int irq, void *private) struct lidar_data *data = iio_priv(indio_dev); int ret; - ret = lidar_get_measurement(data, data->buffer); + ret = lidar_get_measurement(data, &data->scan.chan); if (!ret) { - iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + iio_push_to_buffers_with_timestamp(indio_dev, &data->scan, iio_get_time_ns(indio_dev)); } else if (ret != -EINVAL) { dev_err(&data->client->dev, "cannot read LIDAR measurement"); diff --git a/drivers/iio/proximity/srf08.c b/drivers/iio/proximity/srf08.c index 70beac5c9c1d..9b0886760f76 100644 --- a/drivers/iio/proximity/srf08.c +++ b/drivers/iio/proximity/srf08.c @@ -63,11 +63,11 @@ struct srf08_data { int range_mm; struct mutex lock; - /* - * triggered buffer - * 1x16-bit channel + 3x16 padding + 4x16 timestamp - */ - s16 buffer[8]; + /* Ensure timestamp is naturally aligned */ + struct { + s16 chan; + s64 timestamp __aligned(8); + } scan; /* Sensor-Type */ enum srf08_sensor_type sensor_type; @@ -190,9 +190,9 @@ static irqreturn_t srf08_trigger_handler(int irq, void *p) mutex_lock(&data->lock); - data->buffer[0] = sensor_data; + data->scan.chan = sensor_data; iio_push_to_buffers_with_timestamp(indio_dev, - data->buffer, pf->timestamp); + &data->scan, pf->timestamp); mutex_unlock(&data->lock); err: diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index d1e94147fb16..34b94e525390 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1856,6 +1856,7 @@ static void _destroy_id(struct rdma_id_private *id_priv, { cma_cancel_operation(id_priv, state); + rdma_restrack_del(&id_priv->res); if (id_priv->cma_dev) { if (rdma_cap_ib_cm(id_priv->id.device, 1)) { if (id_priv->cm_id.ib) @@ -1865,7 +1866,6 @@ static void _destroy_id(struct rdma_id_private *id_priv, iw_destroy_cm_id(id_priv->cm_id.iw); } cma_leave_mc_groups(id_priv); - rdma_restrack_del(&id_priv->res); cma_release_dev(id_priv); } @@ -2476,8 +2476,10 @@ static int cma_iw_listen(struct rdma_id_private *id_priv, int backlog) if (IS_ERR(id)) return PTR_ERR(id); + mutex_lock(&id_priv->qp_mutex); id->tos = id_priv->tos; id->tos_set = id_priv->tos_set; + mutex_unlock(&id_priv->qp_mutex); id_priv->cm_id.iw = id; memcpy(&id_priv->cm_id.iw->local_addr, cma_src_addr(id_priv), @@ -2537,8 +2539,10 @@ static int cma_listen_on_dev(struct rdma_id_private *id_priv, cma_id_get(id_priv); dev_id_priv->internal_id = 1; dev_id_priv->afonly = id_priv->afonly; + mutex_lock(&id_priv->qp_mutex); dev_id_priv->tos_set = id_priv->tos_set; dev_id_priv->tos = id_priv->tos; + mutex_unlock(&id_priv->qp_mutex); ret = rdma_listen(&dev_id_priv->id, id_priv->backlog); if (ret) @@ -2585,8 +2589,10 @@ void rdma_set_service_type(struct rdma_cm_id *id, int tos) struct rdma_id_private *id_priv; id_priv = container_of(id, struct rdma_id_private, id); + mutex_lock(&id_priv->qp_mutex); id_priv->tos = (u8) tos; id_priv->tos_set = true; + mutex_unlock(&id_priv->qp_mutex); } EXPORT_SYMBOL(rdma_set_service_type); @@ -2613,8 +2619,10 @@ int rdma_set_ack_timeout(struct rdma_cm_id *id, u8 timeout) return -EINVAL; id_priv = container_of(id, struct rdma_id_private, id); + mutex_lock(&id_priv->qp_mutex); id_priv->timeout = timeout; id_priv->timeout_set = true; + mutex_unlock(&id_priv->qp_mutex); return 0; } @@ -2785,7 +2793,8 @@ static int cma_resolve_ib_route(struct rdma_id_private *id_priv, cma_init_resolve_route_work(work, id_priv); - route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL); + if (!route->path_rec) + route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL); if (!route->path_rec) { ret = -ENOMEM; goto err1; @@ -3000,8 +3009,11 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) u8 default_roce_tos = id_priv->cma_dev->default_roce_tos[id_priv->id.port_num - rdma_start_port(id_priv->cma_dev->device)]; - u8 tos = id_priv->tos_set ? id_priv->tos : default_roce_tos; + u8 tos; + mutex_lock(&id_priv->qp_mutex); + tos = id_priv->tos_set ? id_priv->tos : default_roce_tos; + mutex_unlock(&id_priv->qp_mutex); work = kzalloc(sizeof *work, GFP_KERNEL); if (!work) @@ -3048,8 +3060,12 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) * PacketLifeTime = local ACK timeout/2 * as a reasonable approximation for RoCE networks. */ - route->path_rec->packet_life_time = id_priv->timeout_set ? - id_priv->timeout - 1 : CMA_IBOE_PACKET_LIFETIME; + mutex_lock(&id_priv->qp_mutex); + if (id_priv->timeout_set && id_priv->timeout) + route->path_rec->packet_life_time = id_priv->timeout - 1; + else + route->path_rec->packet_life_time = CMA_IBOE_PACKET_LIFETIME; + mutex_unlock(&id_priv->qp_mutex); if (!route->path_rec->mtu) { ret = -EINVAL; @@ -4073,8 +4089,11 @@ static int cma_connect_iw(struct rdma_id_private *id_priv, if (IS_ERR(cm_id)) return PTR_ERR(cm_id); + mutex_lock(&id_priv->qp_mutex); cm_id->tos = id_priv->tos; cm_id->tos_set = id_priv->tos_set; + mutex_unlock(&id_priv->qp_mutex); + id_priv->cm_id.iw = cm_id; memcpy(&cm_id->local_addr, cma_src_addr(id_priv), diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 418d133a8fb0..466026825dd7 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -3000,12 +3000,29 @@ static int ib_uverbs_ex_modify_wq(struct uverbs_attr_bundle *attrs) if (!wq) return -EINVAL; - wq_attr.curr_wq_state = cmd.curr_wq_state; - wq_attr.wq_state = cmd.wq_state; if (cmd.attr_mask & IB_WQ_FLAGS) { wq_attr.flags = cmd.flags; wq_attr.flags_mask = cmd.flags_mask; } + + if (cmd.attr_mask & IB_WQ_CUR_STATE) { + if (cmd.curr_wq_state > IB_WQS_ERR) + return -EINVAL; + + wq_attr.curr_wq_state = cmd.curr_wq_state; + } else { + wq_attr.curr_wq_state = wq->state; + } + + if (cmd.attr_mask & IB_WQ_STATE) { + if (cmd.wq_state > IB_WQS_ERR) + return -EINVAL; + + wq_attr.wq_state = cmd.wq_state; + } else { + wq_attr.wq_state = wq_attr.curr_wq_state; + } + ret = wq->device->ops.modify_wq(wq, &wq_attr, cmd.attr_mask, &attrs->driver_udata); rdma_lookup_put_uobject(&wq->uobject->uevent.uobject, diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index 266de55f5719..441952a5eca4 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c @@ -1691,6 +1691,7 @@ int bnxt_re_create_srq(struct ib_srq *ib_srq, if (nq) nq->budget++; atomic_inc(&rdev->srq_count); + spin_lock_init(&srq->lock); return 0; diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c index 04621ba8fa76..9ef6aea29ff1 100644 --- a/drivers/infiniband/hw/bnxt_re/main.c +++ b/drivers/infiniband/hw/bnxt_re/main.c @@ -119,6 +119,7 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev, u8 wqe_mode) if (!chip_ctx) return -ENOMEM; chip_ctx->chip_num = bp->chip_num; + chip_ctx->hw_stats_size = bp->hw_ring_stats_size; rdev->chip_ctx = chip_ctx; /* rest members to follow eventually */ @@ -507,6 +508,7 @@ static int bnxt_re_net_stats_ctx_alloc(struct bnxt_re_dev *rdev, dma_addr_t dma_map, u32 *fw_stats_ctx_id) { + struct bnxt_qplib_chip_ctx *chip_ctx = rdev->chip_ctx; struct hwrm_stat_ctx_alloc_output resp = {0}; struct hwrm_stat_ctx_alloc_input req = {0}; struct bnxt_en_dev *en_dev = rdev->en_dev; @@ -523,7 +525,7 @@ static int bnxt_re_net_stats_ctx_alloc(struct bnxt_re_dev *rdev, bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_ALLOC, -1, -1); req.update_period_ms = cpu_to_le32(1000); req.stats_dma_addr = cpu_to_le64(dma_map); - req.stats_dma_length = cpu_to_le16(sizeof(struct ctx_hw_stats_ext)); + req.stats_dma_length = cpu_to_le16(chip_ctx->hw_stats_size); req.stat_ctx_flags = STAT_CTX_ALLOC_REQ_STAT_CTX_FLAGS_ROCE; bnxt_re_fill_fw_msg(&fw_msg, (void *)&req, sizeof(req), (void *)&resp, sizeof(resp), DFLT_HWRM_CMD_TIMEOUT); @@ -1408,7 +1410,6 @@ static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode) memset(&rattr, 0, sizeof(rattr)); rc = bnxt_re_register_netdev(rdev); if (rc) { - rtnl_unlock(); ibdev_err(&rdev->ibdev, "Failed to register with netedev: %#x\n", rc); return -EINVAL; diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c index 3ca47004b752..754dcebeb4ca 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_res.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c @@ -56,6 +56,7 @@ static void bnxt_qplib_free_stats_ctx(struct pci_dev *pdev, struct bnxt_qplib_stats *stats); static int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev, + struct bnxt_qplib_chip_ctx *cctx, struct bnxt_qplib_stats *stats); /* PBL */ @@ -559,7 +560,7 @@ int bnxt_qplib_alloc_ctx(struct bnxt_qplib_res *res, goto fail; stats_alloc: /* Stats */ - rc = bnxt_qplib_alloc_stats_ctx(res->pdev, &ctx->stats); + rc = bnxt_qplib_alloc_stats_ctx(res->pdev, res->cctx, &ctx->stats); if (rc) goto fail; @@ -889,15 +890,12 @@ static void bnxt_qplib_free_stats_ctx(struct pci_dev *pdev, } static int bnxt_qplib_alloc_stats_ctx(struct pci_dev *pdev, + struct bnxt_qplib_chip_ctx *cctx, struct bnxt_qplib_stats *stats) { memset(stats, 0, sizeof(*stats)); stats->fw_id = -1; - /* 128 byte aligned context memory is required only for 57500. - * However making this unconditional, it does not harm previous - * generation. - */ - stats->size = ALIGN(sizeof(struct ctx_hw_stats), 128); + stats->size = cctx->hw_stats_size; stats->dma = dma_alloc_coherent(&pdev->dev, stats->size, &stats->dma_map, GFP_KERNEL); if (!stats->dma) { diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.h b/drivers/infiniband/hw/bnxt_re/qplib_res.h index 7a1ab38b95da..58bad6f78456 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_res.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_res.h @@ -60,6 +60,7 @@ struct bnxt_qplib_chip_ctx { u16 chip_num; u8 chip_rev; u8 chip_metal; + u16 hw_stats_size; struct bnxt_qplib_drv_modes modes; }; diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 5df4bb52bb10..861e19fdfeb4 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -295,6 +295,7 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, if (user && (!wq->sq.bar2_pa || (need_rq && !wq->rq.bar2_pa))) { pr_warn("%s: sqid %u or rqid %u not in BAR2 range\n", pci_name(rdev->lldi.pdev), wq->sq.qid, wq->rq.qid); + ret = -EINVAL; goto free_dma; } diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c index 6faed3a81e08..ffdd18f4217f 100644 --- a/drivers/infiniband/hw/efa/efa_main.c +++ b/drivers/infiniband/hw/efa/efa_main.c @@ -377,6 +377,7 @@ static int efa_enable_msix(struct efa_dev *dev) } if (irq_num != msix_vecs) { + efa_disable_msix(dev); dev_err(&dev->pdev->dev, "Allocated %d MSI-X (out of %d requested)\n", irq_num, msix_vecs); diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index a307d4c8b15a..ac6f87137b63 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -3055,6 +3055,7 @@ static void __sdma_process_event(struct sdma_engine *sde, static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) { int i; + struct sdma_desc *descp; /* Handle last descriptor */ if (unlikely((tx->num_desc == (MAX_DESC - 1)))) { @@ -3075,12 +3076,10 @@ static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) if (unlikely(tx->num_desc == MAX_DESC)) goto enomem; - tx->descp = kmalloc_array( - MAX_DESC, - sizeof(struct sdma_desc), - GFP_ATOMIC); - if (!tx->descp) + descp = kmalloc_array(MAX_DESC, sizeof(struct sdma_desc), GFP_ATOMIC); + if (!descp) goto enomem; + tx->descp = descp; /* reserve last descriptor for coalescing */ tx->desc_limit = MAX_DESC - 1; diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index cd0fba6b0964..7b11aff8a5ea 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -580,12 +580,9 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, props->cq_caps.max_cq_moderation_count = MLX4_MAX_CQ_COUNT; props->cq_caps.max_cq_moderation_period = MLX4_MAX_CQ_PERIOD; - if (!mlx4_is_slave(dev->dev)) - err = mlx4_get_internal_clock_params(dev->dev, &clock_params); - if (uhw->outlen >= resp.response_length + sizeof(resp.hca_core_clock_offset)) { resp.response_length += sizeof(resp.hca_core_clock_offset); - if (!err && !mlx4_is_slave(dev->dev)) { + if (!mlx4_get_internal_clock_params(dev->dev, &clock_params)) { resp.comp_mask |= MLX4_IB_QUERY_DEV_RESP_MASK_CORE_CLOCK_OFFSET; resp.hca_core_clock_offset = clock_params.offset % PAGE_SIZE; } diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 5cb8e602294c..6bc0818f4b2c 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -4244,13 +4244,8 @@ int mlx4_ib_modify_wq(struct ib_wq *ibwq, struct ib_wq_attr *wq_attr, if (wq_attr_mask & IB_WQ_FLAGS) return -EOPNOTSUPP; - cur_state = wq_attr_mask & IB_WQ_CUR_STATE ? wq_attr->curr_wq_state : - ibwq->state; - new_state = wq_attr_mask & IB_WQ_STATE ? wq_attr->wq_state : cur_state; - - if (cur_state < IB_WQS_RESET || cur_state > IB_WQS_ERR || - new_state < IB_WQS_RESET || new_state > IB_WQS_ERR) - return -EINVAL; + cur_state = wq_attr->curr_wq_state; + new_state = wq_attr->wq_state; if ((new_state == IB_WQS_RDY) && (cur_state == IB_WQS_ERR)) return -EINVAL; diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c index fb62f1d04afa..74644b6ea0ff 100644 --- a/drivers/infiniband/hw/mlx5/cq.c +++ b/drivers/infiniband/hw/mlx5/cq.c @@ -838,15 +838,14 @@ static void destroy_cq_user(struct mlx5_ib_cq *cq, struct ib_udata *udata) ib_umem_release(cq->buf.umem); } -static void init_cq_frag_buf(struct mlx5_ib_cq *cq, - struct mlx5_ib_cq_buf *buf) +static void init_cq_frag_buf(struct mlx5_ib_cq_buf *buf) { int i; void *cqe; struct mlx5_cqe64 *cqe64; for (i = 0; i < buf->nent; i++) { - cqe = get_cqe(cq, i); + cqe = mlx5_frag_buf_get_wqe(&buf->fbc, i); cqe64 = buf->cqe_size == 64 ? cqe : cqe + 64; cqe64->op_own = MLX5_CQE_INVALID << 4; } @@ -872,7 +871,7 @@ static int create_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq, if (err) goto err_db; - init_cq_frag_buf(cq, &cq->buf); + init_cq_frag_buf(&cq->buf); *inlen = MLX5_ST_SZ_BYTES(create_cq_in) + MLX5_FLD_SZ_BYTES(create_cq_in, pas[0]) * @@ -931,7 +930,6 @@ int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, u32 *cqb = NULL; void *cqc; int cqe_size; - unsigned int irqn; int eqn; int err; @@ -970,7 +968,7 @@ int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, INIT_WORK(&cq->notify_work, notify_soft_wc_handler); } - err = mlx5_vector2eqn(dev->mdev, vector, &eqn, &irqn); + err = mlx5_vector2eqn(dev->mdev, vector, &eqn); if (err) goto err_cqb; @@ -993,7 +991,6 @@ int mlx5_ib_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, goto err_cqb; mlx5_ib_dbg(dev, "cqn 0x%x\n", cq->mcq.cqn); - cq->mcq.irqn = irqn; if (udata) cq->mcq.tasklet_ctx.comp = mlx5_ib_cq_comp; else @@ -1177,7 +1174,7 @@ static int resize_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq, if (err) goto ex; - init_cq_frag_buf(cq, cq->resize_buf); + init_cq_frag_buf(cq->resize_buf); return 0; diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c index 06a873257619..343e6709d9fc 100644 --- a/drivers/infiniband/hw/mlx5/devx.c +++ b/drivers/infiniband/hw/mlx5/devx.c @@ -904,7 +904,6 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_EQN)( struct mlx5_ib_dev *dev; int user_vector; int dev_eqn; - unsigned int irqn; int err; if (uverbs_copy_from(&user_vector, attrs, @@ -916,7 +915,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_QUERY_EQN)( return PTR_ERR(c); dev = to_mdev(c->ibucontext.device); - err = mlx5_vector2eqn(dev->mdev, user_vector, &dev_eqn, &irqn); + err = mlx5_vector2eqn(dev->mdev, user_vector, &dev_eqn); if (err < 0) return err; diff --git a/drivers/infiniband/hw/mlx5/fs.c b/drivers/infiniband/hw/mlx5/fs.c index 13d50b178166..b3391ecedda7 100644 --- a/drivers/infiniband/hw/mlx5/fs.c +++ b/drivers/infiniband/hw/mlx5/fs.c @@ -2136,6 +2136,13 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)( if (err) goto end; + if (obj->ns_type == MLX5_FLOW_NAMESPACE_FDB && + mlx5_eswitch_mode(dev->mdev->priv.eswitch) != + MLX5_ESWITCH_OFFLOADS) { + err = -EINVAL; + goto end; + } + uobj->object = obj; obj->mdev = dev->mdev; atomic_set(&obj->usecnt, 0); diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index b19506707e45..eb69bec77e5d 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -3440,8 +3440,6 @@ static void mlx5_ib_unbind_slave_port(struct mlx5_ib_dev *ibdev, port->mp.mpi = NULL; - list_add_tail(&mpi->list, &mlx5_ib_unaffiliated_port_list); - spin_unlock(&port->mp.mpi_lock); err = mlx5_nic_vport_unaffiliate_multiport(mpi->mdev); @@ -3594,6 +3592,8 @@ static void mlx5_ib_cleanup_multiport_master(struct mlx5_ib_dev *dev) dev->port[i].mp.mpi = NULL; } else { mlx5_ib_dbg(dev, "unbinding port_num: %d\n", i + 1); + list_add_tail(&dev->port[i].mp.mpi->list, + &mlx5_ib_unaffiliated_port_list); mlx5_ib_unbind_slave_port(dev, dev->port[i].mp.mpi); } } diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index 971694e781b6..19346693c1da 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -526,8 +526,8 @@ static void __cache_work_func(struct mlx5_cache_ent *ent) */ spin_unlock_irq(&ent->lock); need_delay = need_resched() || someone_adding(cache) || - time_after(jiffies, - READ_ONCE(cache->last_add) + 300 * HZ); + !time_after(jiffies, + READ_ONCE(cache->last_add) + 300 * HZ); spin_lock_irq(&ent->lock); if (ent->disabled) goto out; diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 6d2715f65d78..8beba002e5dd 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -5236,10 +5236,8 @@ int mlx5_ib_modify_wq(struct ib_wq *wq, struct ib_wq_attr *wq_attr, rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx); - curr_wq_state = (wq_attr_mask & IB_WQ_CUR_STATE) ? - wq_attr->curr_wq_state : wq->state; - wq_state = (wq_attr_mask & IB_WQ_STATE) ? - wq_attr->wq_state : curr_wq_state; + curr_wq_state = wq_attr->curr_wq_state; + wq_state = wq_attr->wq_state; if (curr_wq_state == IB_WQS_ERR) curr_wq_state = MLX5_RQC_STATE_ERR; if (wq_state == IB_WQS_ERR) diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c index d2ce852447c1..026285f7f36a 100644 --- a/drivers/infiniband/sw/rxe/rxe_mr.c +++ b/drivers/infiniband/sw/rxe/rxe_mr.c @@ -139,7 +139,7 @@ int rxe_mem_init_user(struct rxe_pd *pd, u64 start, if (IS_ERR(umem)) { pr_warn("err %d from rxe_umem_get\n", (int)PTR_ERR(umem)); - err = -EINVAL; + err = PTR_ERR(umem); goto err1; } diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index bce44502ab0e..c071d5b1b85a 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -212,10 +212,8 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port, /* Create UDP socket */ err = udp_sock_create(net, &udp_cfg, &sock); - if (err < 0) { - pr_err("failed to create udp socket. err = %d\n", err); + if (err < 0) return ERR_PTR(err); - } tnl_cfg.encap_type = 1; tnl_cfg.encap_rcv = rxe_udp_encap_recv; @@ -616,6 +614,12 @@ static int rxe_net_ipv6_init(void) recv_sockets.sk6 = rxe_setup_udp_tunnel(&init_net, htons(ROCE_V2_UDP_DPORT), true); + if (PTR_ERR(recv_sockets.sk6) == -EAFNOSUPPORT) { + recv_sockets.sk6 = NULL; + pr_warn("IPv6 is not supported, can not create a UDPv6 socket\n"); + return 0; + } + if (IS_ERR(recv_sockets.sk6)) { recv_sockets.sk6 = NULL; pr_err("Failed to create IPv6 UDP tunnel\n"); diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c index 1e716fe7014c..a1b79015e6f2 100644 --- a/drivers/infiniband/sw/rxe/rxe_qp.c +++ b/drivers/infiniband/sw/rxe/rxe_qp.c @@ -125,7 +125,6 @@ static void free_rd_atomic_resources(struct rxe_qp *qp) void free_rd_atomic_resource(struct rxe_qp *qp, struct resp_res *res) { if (res->type == RXE_ATOMIC_MASK) { - rxe_drop_ref(qp); kfree_skb(res->atomic.skb); } else if (res->type == RXE_READ_MASK) { if (res->read.mr) diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c index c7e3b6a4af38..83c03212099a 100644 --- a/drivers/infiniband/sw/rxe/rxe_resp.c +++ b/drivers/infiniband/sw/rxe/rxe_resp.c @@ -966,8 +966,6 @@ static int send_atomic_ack(struct rxe_qp *qp, struct rxe_pkt_info *pkt, goto out; } - rxe_add_ref(qp); - res = &qp->resp.resources[qp->resp.res_head]; free_rd_atomic_resource(qp, res); rxe_advance_resp_resource(qp); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c index d5a90a66b45c..5b05cf3837da 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c @@ -163,6 +163,7 @@ static size_t ipoib_get_size(const struct net_device *dev) static struct rtnl_link_ops ipoib_link_ops __read_mostly = { .kind = "ipoib", + .netns_refund = true, .maxtype = IFLA_IPOIB_MAX, .policy = ipoib_policy, .priv_size = sizeof(struct ipoib_dev_priv), diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index e653c83f8a35..edea37da8a5b 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -35,10 +35,10 @@ static const struct kernel_param_ops sg_tablesize_ops = { .get = param_get_int, }; -static int isert_sg_tablesize = ISCSI_ISER_DEF_SG_TABLESIZE; +static int isert_sg_tablesize = ISCSI_ISER_MIN_SG_TABLESIZE; module_param_cb(sg_tablesize, &sg_tablesize_ops, &isert_sg_tablesize, 0644); MODULE_PARM_DESC(sg_tablesize, - "Number of gather/scatter entries in a single scsi command, should >= 128 (default: 256, max: 4096)"); + "Number of gather/scatter entries in a single scsi command, should >= 128 (default: 128, max: 4096)"); static DEFINE_MUTEX(device_list_mutex); static LIST_HEAD(device_list); diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index 6c5af13db4e0..ca8cfebe26ca 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h @@ -65,9 +65,6 @@ */ #define ISER_RX_SIZE (ISCSI_DEF_MAX_RECV_SEG_LEN + 1024) -/* Default I/O size is 1MB */ -#define ISCSI_ISER_DEF_SG_TABLESIZE 256 - /* Minimum I/O size is 512KB */ #define ISCSI_ISER_MIN_SG_TABLESIZE 128 diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index 7db550ba25d7..46fad202a380 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -811,6 +811,9 @@ static struct rtrs_clt_sess *get_next_path_min_inflight(struct path_it *it) int inflight; list_for_each_entry_rcu(sess, &clt->paths_list, s.entry) { + if (unlikely(READ_ONCE(sess->state) != RTRS_CLT_CONNECTED)) + continue; + if (unlikely(!list_empty(raw_cpu_ptr(sess->mp_skip_entry)))) continue; @@ -1724,7 +1727,19 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con, queue_depth); return -ECONNRESET; } - if (!sess->rbufs || sess->queue_depth < queue_depth) { + if (sess->queue_depth > 0 && queue_depth != sess->queue_depth) { + rtrs_err(clt, "Error: queue depth changed\n"); + + /* + * Stop any more reconnection attempts + */ + sess->reconnect_attempts = -1; + rtrs_err(clt, + "Disabling auto-reconnect. Trigger a manual reconnect after issue is resolved\n"); + return -ECONNRESET; + } + + if (!sess->rbufs) { kfree(sess->rbufs); sess->rbufs = kcalloc(queue_depth, sizeof(*sess->rbufs), GFP_KERNEL); @@ -1738,7 +1753,7 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con, sess->chunk_size = sess->max_io_size + sess->max_hdr_size; /* - * Global queue depth and IO size is always a minimum. + * Global IO size is always a minimum. * If while a reconnection server sends us a value a bit * higher - client does not care and uses cached minimum. * @@ -1746,8 +1761,7 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con, * connections in parallel, use lock. */ mutex_lock(&clt->paths_mutex); - clt->queue_depth = min_not_zero(sess->queue_depth, - clt->queue_depth); + clt->queue_depth = sess->queue_depth; clt->max_io_size = min_not_zero(sess->max_io_size, clt->max_io_size); mutex_unlock(&clt->paths_mutex); @@ -2692,6 +2706,8 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops, if (err) { list_del_rcu(&sess->s.entry); rtrs_clt_close_conns(sess, true); + free_percpu(sess->stats->pcpu_stats); + kfree(sess->stats); free_sess(sess); goto close_all_sess; } @@ -2700,6 +2716,8 @@ struct rtrs_clt *rtrs_clt_open(struct rtrs_clt_ops *ops, if (err) { list_del_rcu(&sess->s.entry); rtrs_clt_close_conns(sess, true); + free_percpu(sess->stats->pcpu_stats); + kfree(sess->stats); free_sess(sess); goto close_all_sess; } @@ -2959,6 +2977,8 @@ int rtrs_clt_create_path_from_sysfs(struct rtrs_clt *clt, close_sess: rtrs_clt_remove_path_from_arr(sess); rtrs_clt_close_conns(sess, true); + free_percpu(sess->stats->pcpu_stats); + kfree(sess->stats); free_sess(sess); return err; diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h index 8caad0a2322b..51c60f542876 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h +++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h @@ -47,12 +47,15 @@ enum { MAX_PATHS_NUM = 128, /* - * With the size of struct rtrs_permit allocated on the client, 4K - * is the maximum number of rtrs_permits we can allocate. This number is - * also used on the client to allocate the IU for the user connection - * to receive the RDMA addresses from the server. + * Max IB immediate data size is 2^28 (MAX_IMM_PAYL_BITS) + * and the minimum chunk size is 4096 (2^12). + * So the maximum sess_queue_depth is 65536 (2^16) in theory. + * But mempool_create, create_qp and ib_post_send fail with + * "cannot allocate memory" error if sess_queue_depth is too big. + * Therefore the pratical max value of sess_queue_depth is + * somewhere between 1 and 65536 and it depends on the system. */ - MAX_SESS_QUEUE_DEPTH = 4096, + MAX_SESS_QUEUE_DEPTH = 65536, RTRS_HB_INTERVAL_MS = 5000, RTRS_HB_MISSED_MAX = 5, diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c index 39708ab4f26e..7c75e1459017 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c @@ -214,6 +214,7 @@ rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_sess *sess) device_del(&srv->dev); put_device(&srv->dev); } else { + put_device(&srv->dev); mutex_unlock(&srv->paths_mutex); } } diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c index 43806180f85e..b033bfa9f383 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c @@ -1490,6 +1490,7 @@ static void free_sess(struct rtrs_srv_sess *sess) kobject_del(&sess->kobj); kobject_put(&sess->kobj); } else { + kfree(sess->stats); kfree(sess); } } @@ -1613,7 +1614,7 @@ static int create_con(struct rtrs_srv_sess *sess, struct rtrs_sess *s = &sess->s; struct rtrs_srv_con *con; - u32 cq_size, wr_queue_size; + u32 cq_size, max_send_wr, max_recv_wr, wr_limit; int err, cq_vector; con = kzalloc(sizeof(*con), GFP_KERNEL); @@ -1634,30 +1635,42 @@ static int create_con(struct rtrs_srv_sess *sess, * All receive and all send (each requiring invalidate) * + 2 for drain and heartbeat */ - wr_queue_size = SERVICE_CON_QUEUE_DEPTH * 3 + 2; - cq_size = wr_queue_size; + max_send_wr = SERVICE_CON_QUEUE_DEPTH * 2 + 2; + max_recv_wr = SERVICE_CON_QUEUE_DEPTH + 2; + cq_size = max_send_wr + max_recv_wr; } else { - /* - * If we have all receive requests posted and - * all write requests posted and each read request - * requires an invalidate request + drain - * and qp gets into error state. - */ - cq_size = srv->queue_depth * 3 + 1; /* * In theory we might have queue_depth * 32 * outstanding requests if an unsafe global key is used * and we have queue_depth read requests each consisting * of 32 different addresses. div 3 for mlx5. */ - wr_queue_size = sess->s.dev->ib_dev->attrs.max_qp_wr / 3; + wr_limit = sess->s.dev->ib_dev->attrs.max_qp_wr / 3; + /* when always_invlaidate enalbed, we need linv+rinv+mr+imm */ + if (always_invalidate) + max_send_wr = + min_t(int, wr_limit, + srv->queue_depth * (1 + 4) + 1); + else + max_send_wr = + min_t(int, wr_limit, + srv->queue_depth * (1 + 2) + 1); + + max_recv_wr = srv->queue_depth + 1; + /* + * If we have all receive requests posted and + * all write requests posted and each read request + * requires an invalidate request + drain + * and qp gets into error state. + */ + cq_size = max_send_wr + max_recv_wr; } - atomic_set(&con->sq_wr_avail, wr_queue_size); + atomic_set(&con->sq_wr_avail, max_send_wr); cq_vector = rtrs_srv_get_next_cq_vector(sess); /* TODO: SOFTIRQ can be faster, but be careful with softirq context */ err = rtrs_cq_qp_create(&sess->s, &con->c, 1, cq_vector, cq_size, - wr_queue_size, wr_queue_size, + max_send_wr, max_recv_wr, IB_POLL_WORKQUEUE); if (err) { rtrs_err(s, "rtrs_cq_qp_create(), err: %d\n", err); diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c index d13aff0aa816..4629bb758126 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs.c +++ b/drivers/infiniband/ulp/rtrs/rtrs.c @@ -373,7 +373,6 @@ void rtrs_stop_hb(struct rtrs_sess *sess) { cancel_delayed_work_sync(&sess->hb_dwork); sess->hb_missed_cnt = 0; - sess->hb_missed_max = 0; } EXPORT_SYMBOL_GPL(rtrs_stop_hb); diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index a8f85993dab3..86d5c4c92b36 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -998,7 +998,6 @@ static int srp_alloc_req_data(struct srp_rdma_ch *ch) struct srp_device *srp_dev = target->srp_host->srp_dev; struct ib_device *ibdev = srp_dev->dev; struct srp_request *req; - void *mr_list; dma_addr_t dma_addr; int i, ret = -ENOMEM; @@ -1009,12 +1008,12 @@ static int srp_alloc_req_data(struct srp_rdma_ch *ch) for (i = 0; i < target->req_ring_size; ++i) { req = &ch->req_ring[i]; - mr_list = kmalloc_array(target->mr_per_cmd, sizeof(void *), - GFP_KERNEL); - if (!mr_list) - goto out; - if (srp_dev->use_fast_reg) - req->fr_list = mr_list; + if (srp_dev->use_fast_reg) { + req->fr_list = kmalloc_array(target->mr_per_cmd, + sizeof(void *), GFP_KERNEL); + if (!req->fr_list) + goto out; + } req->indirect_desc = kmalloc(target->indirect_size, GFP_KERNEL); if (!req->indirect_desc) goto out; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 430dc6975004..675fcd0952a2 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -500,7 +500,7 @@ static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev, memcpy(joydev->keypam, keypam, len); for (i = 0; i < joydev->nkey; i++) - joydev->keymap[keypam[i] - BTN_MISC] = i; + joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; out: kfree(keypam); diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 793ecbbda32c..9f60f1559e49 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -67,9 +67,6 @@ config KEYBOARD_AMIGA To compile this driver as a module, choose M here: the module will be called amikbd. -config ATARI_KBD_CORE - bool - config KEYBOARD_APPLESPI tristate "Apple SPI keyboard and trackpad" depends on ACPI && EFI diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index bb29a7c9a1c0..54afb38601b9 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -512,6 +512,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) HIL_IDD_NUM_AXES_PER_SET(*idd)) { printk(KERN_INFO PREFIX "combo devices are not supported.\n"); + error = -EINVAL; goto bail1; } diff --git a/drivers/input/touchscreen/goodix.c b/drivers/input/touchscreen/goodix.c index 45113767db96..a06385c55af2 100644 --- a/drivers/input/touchscreen/goodix.c +++ b/drivers/input/touchscreen/goodix.c @@ -178,51 +178,6 @@ static const unsigned long goodix_irq_flags[] = { IRQ_TYPE_LEVEL_HIGH, }; -/* - * Those tablets have their coordinates origin at the bottom right - * of the tablet, as if rotated 180 degrees - */ -static const struct dmi_system_id rotated_screen[] = { -#if defined(CONFIG_DMI) && defined(CONFIG_X86) - { - .ident = "Teclast X89", - .matches = { - /* tPAD is too generic, also match on bios date */ - DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), - DMI_MATCH(DMI_BOARD_NAME, "tPAD"), - DMI_MATCH(DMI_BIOS_DATE, "12/19/2014"), - }, - }, - { - .ident = "Teclast X98 Pro", - .matches = { - /* - * Only match BIOS date, because the manufacturers - * BIOS does not report the board name at all - * (sometimes)... - */ - DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), - DMI_MATCH(DMI_BIOS_DATE, "10/28/2015"), - }, - }, - { - .ident = "WinBook TW100", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), - DMI_MATCH(DMI_PRODUCT_NAME, "TW100") - } - }, - { - .ident = "WinBook TW700", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), - DMI_MATCH(DMI_PRODUCT_NAME, "TW700") - }, - }, -#endif - {} -}; - static const struct dmi_system_id nine_bytes_report[] = { #if defined(CONFIG_DMI) && defined(CONFIG_X86) { @@ -1121,13 +1076,6 @@ static int goodix_configure_dev(struct goodix_ts_data *ts) ABS_MT_POSITION_Y, ts->prop.max_y); } - if (dmi_check_system(rotated_screen)) { - ts->prop.invert_x = true; - ts->prop.invert_y = true; - dev_dbg(&ts->client->dev, - "Applying '180 degrees rotated screen' quirk\n"); - } - if (dmi_check_system(nine_bytes_report)) { ts->contact_size = 9; diff --git a/drivers/input/touchscreen/hideep.c b/drivers/input/touchscreen/hideep.c index ddad4a82a5e5..e9547ee29756 100644 --- a/drivers/input/touchscreen/hideep.c +++ b/drivers/input/touchscreen/hideep.c @@ -361,13 +361,16 @@ static int hideep_enter_pgm(struct hideep_ts *ts) return -EIO; } -static void hideep_nvm_unlock(struct hideep_ts *ts) +static int hideep_nvm_unlock(struct hideep_ts *ts) { u32 unmask_code; + int error; hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_SFR_RPAGE); - hideep_pgm_r_reg(ts, 0x0000000C, &unmask_code); + error = hideep_pgm_r_reg(ts, 0x0000000C, &unmask_code); hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_DEFAULT_PAGE); + if (error) + return error; /* make it unprotected code */ unmask_code &= ~HIDEEP_PROT_MODE; @@ -384,6 +387,8 @@ static void hideep_nvm_unlock(struct hideep_ts *ts) NVM_W_SFR(HIDEEP_NVM_MASK_OFS, ts->nvm_mask); SET_FLASH_HWCONTROL(); hideep_pgm_w_reg(ts, HIDEEP_FLASH_CFG, HIDEEP_NVM_DEFAULT_PAGE); + + return 0; } static int hideep_check_status(struct hideep_ts *ts) @@ -462,7 +467,9 @@ static int hideep_program_nvm(struct hideep_ts *ts, u32 addr = 0; int error; - hideep_nvm_unlock(ts); + error = hideep_nvm_unlock(ts); + if (error) + return error; while (ucode_len > 0) { xfer_len = min_t(size_t, ucode_len, HIDEEP_NVM_PAGE_SIZE); diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 397cb1d3f481..544a8f40b81f 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -251,7 +251,7 @@ static int e2i_init(struct usbtouch_usb *usbtouch) int ret; struct usb_device *udev = interface_to_usbdev(usbtouch->interface); - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, 0x02, 0x0000, 0x0081, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -531,7 +531,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) if (ret) return ret; - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), MTOUCHUSB_RESET, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -543,7 +543,7 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) msleep(150); for (i = 0; i < 3; i++) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), MTOUCHUSB_ASYNC_REPORT, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1, 1, NULL, 0, USB_CTRL_SET_TIMEOUT); @@ -722,7 +722,7 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) } /* start sending data */ - ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0), + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), TSC10_CMD_DATA1, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c index 8a1e70e00876..7887941730db 100644 --- a/drivers/interconnect/core.c +++ b/drivers/interconnect/core.c @@ -403,7 +403,7 @@ struct icc_path *devm_of_icc_get(struct device *dev, const char *name) { struct icc_path **ptr, *path; - ptr = devres_alloc(devm_icc_release, sizeof(**ptr), GFP_KERNEL); + ptr = devres_alloc(devm_icc_release, sizeof(*ptr), GFP_KERNEL); if (!ptr) return ERR_PTR(-ENOMEM); @@ -973,9 +973,14 @@ void icc_node_add(struct icc_node *node, struct icc_provider *provider) } node->avg_bw = node->init_avg; node->peak_bw = node->init_peak; + + if (provider->pre_aggregate) + provider->pre_aggregate(node); + if (provider->aggregate) provider->aggregate(node, 0, node->init_avg, node->init_peak, &node->avg_bw, &node->peak_bw); + provider->set(node, node); node->avg_bw = 0; node->peak_bw = 0; @@ -1106,6 +1111,8 @@ void icc_sync_state(struct device *dev) dev_dbg(p->dev, "interconnect provider is in synced state\n"); list_for_each_entry(n, &p->nodes, node_list) { if (n->init_avg || n->init_peak) { + n->init_avg = 0; + n->init_peak = 0; aggregate_requests(n); p->set(n, n); } diff --git a/drivers/interconnect/qcom/icc-rpmh.c b/drivers/interconnect/qcom/icc-rpmh.c index bf01d09dba6c..f6fae64861ce 100644 --- a/drivers/interconnect/qcom/icc-rpmh.c +++ b/drivers/interconnect/qcom/icc-rpmh.c @@ -57,6 +57,11 @@ int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, qn->sum_avg[i] += avg_bw; qn->max_peak[i] = max_t(u32, qn->max_peak[i], peak_bw); } + + if (node->init_avg || node->init_peak) { + qn->sum_avg[i] = max_t(u64, qn->sum_avg[i], node->init_avg); + qn->max_peak[i] = max_t(u64, qn->max_peak[i], node->init_peak); + } } *agg_avg += avg_bw; @@ -79,7 +84,6 @@ EXPORT_SYMBOL_GPL(qcom_icc_aggregate); int qcom_icc_set(struct icc_node *src, struct icc_node *dst) { struct qcom_icc_provider *qp; - struct qcom_icc_node *qn; struct icc_node *node; if (!src) @@ -88,12 +92,6 @@ int qcom_icc_set(struct icc_node *src, struct icc_node *dst) node = src; qp = to_qcom_provider(node->provider); - qn = node->data; - - qn->sum_avg[QCOM_ICC_BUCKET_AMC] = max_t(u64, qn->sum_avg[QCOM_ICC_BUCKET_AMC], - node->avg_bw); - qn->max_peak[QCOM_ICC_BUCKET_AMC] = max_t(u64, qn->max_peak[QCOM_ICC_BUCKET_AMC], - node->peak_bw); qcom_icc_bcm_voter_commit(qp->voter); diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index cc9869cc48e4..fa57986c2309 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -1914,8 +1914,8 @@ static void print_iommu_info(void) pci_info(pdev, "Found IOMMU cap 0x%hx\n", iommu->cap_ptr); if (iommu->cap & (1 << IOMMU_CAP_EFR)) { - pci_info(pdev, "Extended features (%#llx):", - iommu->features); + pr_info("Extended features (%#llx):", iommu->features); + for (i = 0; i < ARRAY_SIZE(feat_str); ++i) { if (iommu_feature(iommu, (1ULL << i))) pr_cont(" %s", feat_str[i]); diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 2b83d31a7058..6c9a69305636 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -74,7 +74,7 @@ static bool using_legacy_binding, using_generic_binding; static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu) { if (pm_runtime_enabled(smmu->dev)) - return pm_runtime_get_sync(smmu->dev); + return pm_runtime_resume_and_get(smmu->dev); return 0; } @@ -1278,6 +1278,7 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain, u64 phys; unsigned long va, flags; int ret, idx = cfg->cbndx; + phys_addr_t addr = 0; ret = arm_smmu_rpm_get(smmu); if (ret < 0) @@ -1297,6 +1298,7 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain, dev_err(dev, "iova to phys timed out on %pad. Falling back to software table walk.\n", &iova); + arm_smmu_rpm_put(smmu); return ops->iova_to_phys(ops, iova); } @@ -1305,12 +1307,14 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain, if (phys & ARM_SMMU_CB_PAR_F) { dev_err(dev, "translation fault!\n"); dev_err(dev, "PAR = 0x%llx\n", phys); - return 0; + goto out; } + addr = (phys & GENMASK_ULL(39, 12)) | (iova & 0xfff); +out: arm_smmu_rpm_put(smmu); - return (phys & GENMASK_ULL(39, 12)) | (iova & 0xfff); + return addr; } static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 61e546d53287..6d509be4f6c4 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -217,9 +217,11 @@ static int iova_reserve_pci_windows(struct pci_dev *dev, lo = iova_pfn(iovad, start); hi = iova_pfn(iovad, end); reserve_iova(iovad, lo, hi); - } else { + } else if (end < start) { /* dma_ranges list should be sorted */ - dev_err(&dev->dev, "Failed to reserve IOVA\n"); + dev_err(&dev->dev, + "Failed to reserve IOVA [%pa-%pa]\n", + &start, &end); return -EINVAL; } diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index b21c8224b1c8..0a52eccab267 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -3803,20 +3803,15 @@ static const struct dma_map_ops intel_dma_ops = { .get_required_mask = intel_get_required_mask, }; -static void -bounce_sync_single(struct device *dev, dma_addr_t addr, size_t size, - enum dma_data_direction dir, enum dma_sync_target target) +static phys_addr_t bounce_sync_single(struct device *dev, dma_addr_t addr) { struct dmar_domain *domain; - phys_addr_t tlb_addr; domain = find_domain(dev); if (WARN_ON(!domain)) - return; + return 0; - tlb_addr = intel_iommu_iova_to_phys(&domain->domain, addr); - if (is_swiotlb_buffer(tlb_addr)) - swiotlb_tbl_sync_single(dev, tlb_addr, size, dir, target); + return intel_iommu_iova_to_phys(&domain->domain, addr); } static dma_addr_t @@ -3898,9 +3893,8 @@ bounce_map_single(struct device *dev, phys_addr_t paddr, size_t size, return (phys_addr_t)iova_pfn << PAGE_SHIFT; mapping_error: - if (is_swiotlb_buffer(tlb_addr)) - swiotlb_tbl_unmap_single(dev, tlb_addr, size, - aligned_size, dir, attrs); + if (is_swiotlb_buffer(dev, tlb_addr)) + swiotlb_tbl_unmap_single(dev, tlb_addr, size, dir, attrs); swiotlb_error: free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages)); dev_err(dev, "Device bounce map: %zx@%llx dir %d --- failed\n", @@ -3913,7 +3907,6 @@ static void bounce_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, enum dma_data_direction dir, unsigned long attrs) { - size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE); struct dmar_domain *domain; phys_addr_t tlb_addr; @@ -3926,9 +3919,8 @@ bounce_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size, return; intel_unmap(dev, dev_addr, size); - if (is_swiotlb_buffer(tlb_addr)) - swiotlb_tbl_unmap_single(dev, tlb_addr, size, - aligned_size, dir, attrs); + if (is_swiotlb_buffer(dev, tlb_addr)) + swiotlb_tbl_unmap_single(dev, tlb_addr, size, dir, attrs); trace_bounce_unmap_single(dev, dev_addr, size); } @@ -4005,14 +3997,20 @@ static void bounce_sync_single_for_cpu(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) { - bounce_sync_single(dev, addr, size, dir, SYNC_FOR_CPU); + phys_addr_t tlb_addr = bounce_sync_single(dev, addr); + + if (is_swiotlb_buffer(dev, tlb_addr)) + swiotlb_sync_single_for_cpu(dev, tlb_addr, size, dir); } static void bounce_sync_single_for_device(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) { - bounce_sync_single(dev, addr, size, dir, SYNC_FOR_DEVICE); + phys_addr_t tlb_addr = bounce_sync_single(dev, addr); + + if (is_swiotlb_buffer(dev, tlb_addr)) + swiotlb_sync_single_for_device(dev, tlb_addr, size, dir); } static void @@ -4023,8 +4021,8 @@ bounce_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, int i; for_each_sg(sglist, sg, nelems, i) - bounce_sync_single(dev, sg_dma_address(sg), - sg_dma_len(sg), dir, SYNC_FOR_CPU); + bounce_sync_single_for_cpu(dev, sg_dma_address(sg), + sg_dma_len(sg), dir); } static void @@ -4035,8 +4033,8 @@ bounce_sync_sg_for_device(struct device *dev, struct scatterlist *sglist, int i; for_each_sg(sglist, sg, nelems, i) - bounce_sync_single(dev, sg_dma_address(sg), - sg_dma_len(sg), dir, SYNC_FOR_DEVICE); + bounce_sync_single_for_device(dev, sg_dma_address(sg), + sg_dma_len(sg), dir); } static const struct dma_map_ops bounce_dma_ops = { diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c index 1e7c17989084..fb911b6c418f 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -466,20 +466,6 @@ pasid_cache_invalidation_with_pasid(struct intel_iommu *iommu, qi_submit_sync(iommu, &desc, 1, 0); } -static void -iotlb_invalidation_with_pasid(struct intel_iommu *iommu, u16 did, u32 pasid) -{ - struct qi_desc desc; - - desc.qw0 = QI_EIOTLB_PASID(pasid) | QI_EIOTLB_DID(did) | - QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) | QI_EIOTLB_TYPE; - desc.qw1 = 0; - desc.qw2 = 0; - desc.qw3 = 0; - - qi_submit_sync(iommu, &desc, 1, 0); -} - static void devtlb_invalidation_with_pasid(struct intel_iommu *iommu, struct device *dev, u32 pasid) @@ -511,20 +497,26 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev, u32 pasid, bool fault_ignore) { struct pasid_entry *pte; - u16 did; + u16 did, pgtt; pte = intel_pasid_get_entry(dev, pasid); if (WARN_ON(!pte)) return; did = pasid_get_domain_id(pte); + pgtt = pasid_pte_get_pgtt(pte); + intel_pasid_clear_entry(dev, pasid, fault_ignore); if (!ecap_coherent(iommu->ecap)) clflush_cache_range(pte, sizeof(*pte)); pasid_cache_invalidation_with_pasid(iommu, did, pasid); - iotlb_invalidation_with_pasid(iommu, did, pasid); + + if (pgtt == PASID_ENTRY_PGTT_PT || pgtt == PASID_ENTRY_PGTT_FL_ONLY) + qi_flush_piotlb(iommu, did, pasid, 0, -1, 0); + else + iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH); /* Device IOTLB doesn't need to be flushed in caching mode. */ if (!cap_caching_mode(iommu->cap)) @@ -540,7 +532,7 @@ static void pasid_flush_caches(struct intel_iommu *iommu, if (cap_caching_mode(iommu->cap)) { pasid_cache_invalidation_with_pasid(iommu, did, pasid); - iotlb_invalidation_with_pasid(iommu, did, pasid); + qi_flush_piotlb(iommu, did, pasid, 0, -1, 0); } else { iommu_flush_write_buffer(iommu); } diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h index 086ebd697319..30cb30046b15 100644 --- a/drivers/iommu/intel/pasid.h +++ b/drivers/iommu/intel/pasid.h @@ -99,6 +99,12 @@ static inline bool pasid_pte_is_present(struct pasid_entry *pte) return READ_ONCE(pte->val[0]) & PASID_PTE_PRESENT; } +/* Get PGTT field of a PASID table entry */ +static inline u16 pasid_pte_get_pgtt(struct pasid_entry *pte) +{ + return (u16)((READ_ONCE(pte->val[0]) >> 6) & 0x7); +} + extern unsigned int intel_pasid_max_id; int intel_pasid_alloc_id(void *ptr, int start, int end, gfp_t gfp); void intel_pasid_free_id(u32 pasid); diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c index 6168dec7cb40..aabf56272b86 100644 --- a/drivers/iommu/intel/svm.c +++ b/drivers/iommu/intel/svm.c @@ -123,53 +123,16 @@ static void __flush_svm_range_dev(struct intel_svm *svm, unsigned long address, unsigned long pages, int ih) { - struct qi_desc desc; + struct device_domain_info *info = get_domain_info(sdev->dev); - if (pages == -1) { - desc.qw0 = QI_EIOTLB_PASID(svm->pasid) | - QI_EIOTLB_DID(sdev->did) | - QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) | - QI_EIOTLB_TYPE; - desc.qw1 = 0; - } else { - int mask = ilog2(__roundup_pow_of_two(pages)); - - desc.qw0 = QI_EIOTLB_PASID(svm->pasid) | - QI_EIOTLB_DID(sdev->did) | - QI_EIOTLB_GRAN(QI_GRAN_PSI_PASID) | - QI_EIOTLB_TYPE; - desc.qw1 = QI_EIOTLB_ADDR(address) | - QI_EIOTLB_IH(ih) | - QI_EIOTLB_AM(mask); - } - desc.qw2 = 0; - desc.qw3 = 0; - qi_submit_sync(sdev->iommu, &desc, 1, 0); - - if (sdev->dev_iotlb) { - desc.qw0 = QI_DEV_EIOTLB_PASID(svm->pasid) | - QI_DEV_EIOTLB_SID(sdev->sid) | - QI_DEV_EIOTLB_QDEP(sdev->qdep) | - QI_DEIOTLB_TYPE; - if (pages == -1) { - desc.qw1 = QI_DEV_EIOTLB_ADDR(-1ULL >> 1) | - QI_DEV_EIOTLB_SIZE; - } else if (pages > 1) { - /* The least significant zero bit indicates the size. So, - * for example, an "address" value of 0x12345f000 will - * flush from 0x123440000 to 0x12347ffff (256KiB). */ - unsigned long last = address + ((unsigned long)(pages - 1) << VTD_PAGE_SHIFT); - unsigned long mask = __rounddown_pow_of_two(address ^ last); - - desc.qw1 = QI_DEV_EIOTLB_ADDR((address & ~mask) | - (mask - 1)) | QI_DEV_EIOTLB_SIZE; - } else { - desc.qw1 = QI_DEV_EIOTLB_ADDR(address); - } - desc.qw2 = 0; - desc.qw3 = 0; - qi_submit_sync(sdev->iommu, &desc, 1, 0); - } + if (WARN_ON(!pages)) + return; + + qi_flush_piotlb(sdev->iommu, sdev->did, svm->pasid, address, pages, ih); + if (info->ats_enabled) + qi_flush_dev_iotlb_pasid(sdev->iommu, sdev->sid, info->pfsid, + svm->pasid, sdev->qdep, address, + order_base_2(pages)); } static void intel_flush_svm_range_dev(struct intel_svm *svm, diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 6276c8c16068..d41031198d77 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -880,6 +880,9 @@ void iommu_group_remove_device(struct device *dev) struct iommu_group *group = dev->iommu_group; struct group_device *tmp_device, *device = NULL; + if (!group) + return; + dev_info(dev, "Removing from iommu group %d\n", group->id); /* Pre-notify listeners that a device is being removed. */ diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c index ec71063fff76..c1098f40e03f 100644 --- a/drivers/ipack/carriers/tpci200.c +++ b/drivers/ipack/carriers/tpci200.c @@ -91,16 +91,13 @@ static void tpci200_unregister(struct tpci200_board *tpci200) free_irq(tpci200->info->pdev->irq, (void *) tpci200); pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); - pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR); pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); - pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); pci_disable_device(tpci200->info->pdev); - pci_dev_put(tpci200->info->pdev); } static void tpci200_enable_irq(struct tpci200_board *tpci200, @@ -259,7 +256,7 @@ static int tpci200_register(struct tpci200_board *tpci200) "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_disable_pci; + goto err_disable_device; } /* Request IO ID INT space (Bar 3) */ @@ -271,7 +268,7 @@ static int tpci200_register(struct tpci200_board *tpci200) "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_release_ip_space; + goto err_ip_interface_bar; } /* Request MEM8 space (Bar 5) */ @@ -282,7 +279,7 @@ static int tpci200_register(struct tpci200_board *tpci200) "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_release_ioid_int_space; + goto err_io_id_int_spaces_bar; } /* Request MEM16 space (Bar 4) */ @@ -293,7 +290,7 @@ static int tpci200_register(struct tpci200_board *tpci200) "(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_release_mem8_space; + goto err_mem8_space_bar; } /* Map internal tpci200 driver user space */ @@ -307,7 +304,7 @@ static int tpci200_register(struct tpci200_board *tpci200) tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); res = -ENOMEM; - goto out_release_mem8_space; + goto err_mem16_space_bar; } /* Initialize lock that protects interface_regs */ @@ -346,18 +343,22 @@ static int tpci200_register(struct tpci200_board *tpci200) "(bn 0x%X, sn 0x%X) unable to register IRQ !", tpci200->info->pdev->bus->number, tpci200->info->pdev->devfn); - goto out_release_ioid_int_space; + goto err_interface_regs; } return 0; -out_release_mem8_space: +err_interface_regs: + pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs); +err_mem16_space_bar: + pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR); +err_mem8_space_bar: pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR); -out_release_ioid_int_space: +err_io_id_int_spaces_bar: pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR); -out_release_ip_space: +err_ip_interface_bar: pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR); -out_disable_pci: +err_disable_device: pci_disable_device(tpci200->info->pdev); return res; } @@ -529,7 +530,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev, tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL); if (!tpci200->info) { ret = -ENOMEM; - goto out_err_info; + goto err_tpci200; } pci_dev_get(pdev); @@ -540,7 +541,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev, if (ret) { dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory"); ret = -EBUSY; - goto out_err_pci_request; + goto err_tpci200_info; } tpci200->info->cfg_regs = ioremap( pci_resource_start(pdev, TPCI200_CFG_MEM_BAR), @@ -548,7 +549,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev, if (!tpci200->info->cfg_regs) { dev_err(&pdev->dev, "Failed to map PCI Configuration Memory"); ret = -EFAULT; - goto out_err_ioremap; + goto err_request_region; } /* Disable byte swapping for 16 bit IP module access. This will ensure @@ -571,7 +572,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev, if (ret) { dev_err(&pdev->dev, "error during tpci200 install\n"); ret = -ENODEV; - goto out_err_install; + goto err_cfg_regs; } /* Register the carrier in the industry pack bus driver */ @@ -583,7 +584,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev, dev_err(&pdev->dev, "error registering the carrier on ipack driver\n"); ret = -EFAULT; - goto out_err_bus_register; + goto err_tpci200_install; } /* save the bus number given by ipack to logging purpose */ @@ -594,16 +595,16 @@ static int tpci200_pci_probe(struct pci_dev *pdev, tpci200_create_device(tpci200, i); return 0; -out_err_bus_register: +err_tpci200_install: tpci200_uninstall(tpci200); -out_err_install: - iounmap(tpci200->info->cfg_regs); -out_err_ioremap: +err_cfg_regs: + pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); +err_request_region: pci_release_region(pdev, TPCI200_CFG_MEM_BAR); -out_err_pci_request: - pci_dev_put(pdev); +err_tpci200_info: kfree(tpci200->info); -out_err_info: + pci_dev_put(pdev); +err_tpci200: kfree(tpci200); return ret; } @@ -613,6 +614,12 @@ static void __tpci200_pci_remove(struct tpci200_board *tpci200) ipack_bus_unregister(tpci200->info->ipack_bus); tpci200_uninstall(tpci200); + pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs); + + pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR); + + pci_dev_put(tpci200->info->pdev); + kfree(tpci200->info); kfree(tpci200); } diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index f47b41dfd023..a610821c8ff2 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -12,19 +12,6 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock); -static const struct gic_kvm_info *gic_kvm_info; - -const struct gic_kvm_info *gic_get_kvm_info(void) -{ - return gic_kvm_info; -} - -void gic_set_kvm_info(const struct gic_kvm_info *info) -{ - BUG_ON(gic_kvm_info != NULL); - gic_kvm_info = info; -} - void gic_enable_of_quirks(const struct device_node *np, const struct gic_quirk *quirks, void *data) { diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h index ccba8b0fe0f5..27e3d4ed4f32 100644 --- a/drivers/irqchip/irq-gic-common.h +++ b/drivers/irqchip/irq-gic-common.h @@ -28,6 +28,4 @@ void gic_enable_quirks(u32 iidr, const struct gic_quirk *quirks, void gic_enable_of_quirks(const struct device_node *np, const struct gic_quirk *quirks, void *data); -void gic_set_kvm_info(const struct gic_kvm_info *info); - #endif /* _IRQ_GIC_COMMON_H */ diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 34391b00c546..de11f893d40c 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -794,8 +794,13 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its, its_encode_alloc(cmd, alloc); - /* We can only signal PTZ when alloc==1. Why do we have two bits? */ - its_encode_ptz(cmd, alloc); + /* + * GICv4.1 provides a way to get the VLPI state, which needs the vPE + * to be unmapped first, and in this case, we may remap the vPE + * back while the VPT is not empty. So we can't assume that the + * VPT is empty on map. This is why we never advertise PTZ. + */ + its_encode_ptz(cmd, false); its_encode_vconf_addr(cmd, vconf_addr); its_encode_vmapp_default_db(cmd, desc->its_vmapp_cmd.vpe->vpe_db_lpi); @@ -4551,6 +4556,15 @@ static void its_vpe_irq_domain_deactivate(struct irq_domain *domain, its_send_vmapp(its, vpe, false); } + + /* + * There may be a direct read to the VPT after unmapping the + * vPE, to guarantee the validity of this, we make the VPT + * memory coherent with the CPU caches here. + */ + if (find_4_1_its() && !atomic_read(&vpe->vmapp_count)) + gic_flush_dcache_to_poc(page_address(vpe->vpt_page), + LPI_PENDBASE_SZ); } static const struct irq_domain_ops its_vpe_domain_ops = { diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 0fbc02fa6459..e7fb1c12bcc5 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -95,7 +95,7 @@ EXPORT_SYMBOL(gic_nonsecure_priorities); /* ppi_nmi_refs[n] == number of cpus having ppi[n + 16] set as NMI */ static refcount_t *ppi_nmi_refs; -static struct gic_kvm_info gic_v3_kvm_info; +static struct gic_kvm_info gic_v3_kvm_info __initdata; static DEFINE_PER_CPU(bool, has_rss); #define MPIDR_RS(mpidr) (((mpidr) & 0xF0UL) >> 4) @@ -634,11 +634,45 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs) nmi_exit(); } +static u32 do_read_iar(struct pt_regs *regs) +{ + u32 iar; + + if (gic_supports_nmi() && unlikely(!interrupts_enabled(regs))) { + u64 pmr; + + /* + * We were in a context with IRQs disabled. However, the + * entry code has set PMR to a value that allows any + * interrupt to be acknowledged, and not just NMIs. This can + * lead to surprising effects if the NMI has been retired in + * the meantime, and that there is an IRQ pending. The IRQ + * would then be taken in NMI context, something that nobody + * wants to debug twice. + * + * Until we sort this, drop PMR again to a level that will + * actually only allow NMIs before reading IAR, and then + * restore it to what it was. + */ + pmr = gic_read_pmr(); + gic_pmr_mask_irqs(); + isb(); + + iar = gic_read_iar(); + + gic_write_pmr(pmr); + } else { + iar = gic_read_iar(); + } + + return iar; +} + static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) { u32 irqnr; - irqnr = gic_read_iar(); + irqnr = do_read_iar(regs); /* Check for special IDs first */ if ((irqnr >= 1020 && irqnr <= 1023)) @@ -1879,7 +1913,7 @@ static void __init gic_of_setup_kvm_info(struct device_node *node) gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis; gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid; - gic_set_kvm_info(&gic_v3_kvm_info); + vgic_set_kvm_info(&gic_v3_kvm_info); } static int __init gic_of_init(struct device_node *node, struct device_node *parent) @@ -2195,7 +2229,7 @@ static void __init gic_acpi_setup_kvm_info(void) gic_v3_kvm_info.has_v4 = gic_data.rdists.has_vlpis; gic_v3_kvm_info.has_v4_1 = gic_data.rdists.has_rvpeid; - gic_set_kvm_info(&gic_v3_kvm_info); + vgic_set_kvm_info(&gic_v3_kvm_info); } static int __init diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 6053245a4754..e35f453a2001 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -119,7 +119,7 @@ static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly; -static struct gic_kvm_info gic_v2_kvm_info; +static struct gic_kvm_info gic_v2_kvm_info __initdata; static DEFINE_PER_CPU(u32, sgi_intid); @@ -1457,7 +1457,7 @@ static void __init gic_of_setup_kvm_info(struct device_node *node) return; if (static_branch_likely(&supports_deactivate_key)) - gic_set_kvm_info(&gic_v2_kvm_info); + vgic_set_kvm_info(&gic_v2_kvm_info); } int __init @@ -1624,7 +1624,7 @@ static void __init gic_acpi_setup_kvm_info(void) gic_v2_kvm_info.maint_irq = irq; - gic_set_kvm_info(&gic_v2_kvm_info); + vgic_set_kvm_info(&gic_v2_kvm_info); } static int __init gic_v2_acpi_init(union acpi_subtable_headers *header, diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index 56bd2e9db6ed..e501cb03f211 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c @@ -2342,7 +2342,7 @@ static void __exit HFC_cleanup(void) { if (timer_pending(&hfc_tl)) - del_timer(&hfc_tl); + del_timer_sync(&hfc_tl); pci_unregister_driver(&hfc_driver); } diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index ee925b58bbce..2a1ddd47a096 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -1100,7 +1100,6 @@ nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent) card->typ = NETJET_S_TJ300; card->base = pci_resource_start(pdev, 0); - card->irq = pdev->irq; pci_set_drvdata(pdev, card); err = setup_instance(card); if (err) diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 849d3c5f908e..56e8198e13d1 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -199,6 +199,7 @@ config LEDS_LM3530 config LEDS_LM3532 tristate "LCD Backlight driver for LM3532" + select REGMAP_I2C depends on LEDS_CLASS depends on I2C help diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 131ca83f5fb3..4365c1cc4505 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -286,10 +286,6 @@ struct led_classdev *__must_check devm_of_led_get(struct device *dev, if (!dev) return ERR_PTR(-EINVAL); - /* Not using device tree? */ - if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) - return ERR_PTR(-ENOTSUPP); - led = of_led_get(dev->of_node, index); if (IS_ERR(led)) return led; diff --git a/drivers/leds/leds-as3645a.c b/drivers/leds/leds-as3645a.c index e8922fa03379..80411d41e802 100644 --- a/drivers/leds/leds-as3645a.c +++ b/drivers/leds/leds-as3645a.c @@ -545,6 +545,7 @@ static int as3645a_parse_node(struct as3645a *flash, if (!flash->indicator_node) { dev_warn(&flash->client->dev, "can't find indicator node\n"); + rval = -ENODEV; goto out_err; } diff --git a/drivers/leds/leds-ktd2692.c b/drivers/leds/leds-ktd2692.c index 632f10db4b3f..f341da1503a4 100644 --- a/drivers/leds/leds-ktd2692.c +++ b/drivers/leds/leds-ktd2692.c @@ -256,6 +256,17 @@ static void ktd2692_setup(struct ktd2692_context *led) | KTD2692_REG_FLASH_CURRENT_BASE); } +static void regulator_disable_action(void *_data) +{ + struct device *dev = _data; + struct ktd2692_context *led = dev_get_drvdata(dev); + int ret; + + ret = regulator_disable(led->regulator); + if (ret) + dev_err(dev, "Failed to disable supply: %d\n", ret); +} + static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev, struct ktd2692_led_config_data *cfg) { @@ -286,8 +297,14 @@ static int ktd2692_parse_dt(struct ktd2692_context *led, struct device *dev, if (led->regulator) { ret = regulator_enable(led->regulator); - if (ret) + if (ret) { dev_err(dev, "Failed to enable supply: %d\n", ret); + } else { + ret = devm_add_action_or_reset(dev, + regulator_disable_action, dev); + if (ret) + return ret; + } } child_node = of_get_next_available_child(np, NULL); @@ -377,17 +394,9 @@ static int ktd2692_probe(struct platform_device *pdev) static int ktd2692_remove(struct platform_device *pdev) { struct ktd2692_context *led = platform_get_drvdata(pdev); - int ret; led_classdev_flash_unregister(&led->fled_cdev); - if (led->regulator) { - ret = regulator_disable(led->regulator); - if (ret) - dev_err(&pdev->dev, - "Failed to disable supply: %d\n", ret); - } - mutex_destroy(&led->lock); return 0; diff --git a/drivers/leds/leds-lm36274.c b/drivers/leds/leds-lm36274.c index aadb03468a40..a23a9424c2f3 100644 --- a/drivers/leds/leds-lm36274.c +++ b/drivers/leds/leds-lm36274.c @@ -127,6 +127,7 @@ static int lm36274_probe(struct platform_device *pdev) ret = lm36274_init(chip); if (ret) { + fwnode_handle_put(init_data.fwnode); dev_err(chip->dev, "Failed to init the device\n"); return ret; } diff --git a/drivers/leds/leds-lm3692x.c b/drivers/leds/leds-lm3692x.c index e945de45388c..55e6443997ec 100644 --- a/drivers/leds/leds-lm3692x.c +++ b/drivers/leds/leds-lm3692x.c @@ -435,6 +435,7 @@ static int lm3692x_probe_dt(struct lm3692x_led *led) ret = fwnode_property_read_u32(child, "reg", &led->led_enable); if (ret) { + fwnode_handle_put(child); dev_err(&led->client->dev, "reg DT property missing\n"); return ret; } @@ -449,12 +450,11 @@ static int lm3692x_probe_dt(struct lm3692x_led *led) ret = devm_led_classdev_register_ext(&led->client->dev, &led->led_dev, &init_data); - if (ret) { + if (ret) dev_err(&led->client->dev, "led register err: %d\n", ret); - return ret; - } - return 0; + fwnode_handle_put(init_data.fwnode); + return ret; } static int lm3692x_probe(struct i2c_client *client, diff --git a/drivers/leds/leds-lm3697.c b/drivers/leds/leds-lm3697.c index 7d216cdb91a8..912e8bb22a99 100644 --- a/drivers/leds/leds-lm3697.c +++ b/drivers/leds/leds-lm3697.c @@ -203,11 +203,9 @@ static int lm3697_probe_dt(struct lm3697 *priv) priv->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR(priv->enable_gpio)) { - ret = PTR_ERR(priv->enable_gpio); - dev_err(dev, "Failed to get enable gpio: %d\n", ret); - return ret; - } + if (IS_ERR(priv->enable_gpio)) + return dev_err_probe(dev, PTR_ERR(priv->enable_gpio), + "Failed to get enable GPIO\n"); priv->regulator = devm_regulator_get(dev, "vled"); if (IS_ERR(priv->regulator)) diff --git a/drivers/leds/leds-lp50xx.c b/drivers/leds/leds-lp50xx.c index f13117eed976..d4529082935b 100644 --- a/drivers/leds/leds-lp50xx.c +++ b/drivers/leds/leds-lp50xx.c @@ -496,6 +496,7 @@ static int lp50xx_probe_dt(struct lp50xx *priv) ret = fwnode_property_read_u32(led_node, "color", &color_id); if (ret) { + fwnode_handle_put(led_node); dev_err(priv->dev, "Cannot read color\n"); goto child_out; } @@ -519,7 +520,6 @@ static int lp50xx_probe_dt(struct lp50xx *priv) goto child_out; } i++; - fwnode_handle_put(child); } return 0; diff --git a/drivers/leds/leds-tlc591xx.c b/drivers/leds/leds-tlc591xx.c index 5b9dfdf743ec..cb7bd1353f9f 100644 --- a/drivers/leds/leds-tlc591xx.c +++ b/drivers/leds/leds-tlc591xx.c @@ -148,16 +148,20 @@ static int tlc591xx_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct device_node *np = dev_of_node(&client->dev), *child; + struct device_node *np, *child; struct device *dev = &client->dev; const struct tlc591xx *tlc591xx; struct tlc591xx_priv *priv; int err, count, reg; - tlc591xx = device_get_match_data(dev); + np = dev_of_node(dev); if (!np) return -ENODEV; + tlc591xx = device_get_match_data(dev); + if (!tlc591xx) + return -ENODEV; + count = of_get_available_child_count(np); if (!count || count > tlc591xx->max_leds) return -EINVAL; diff --git a/drivers/leds/leds-turris-omnia.c b/drivers/leds/leds-turris-omnia.c index 880fc8def530..ec87a958f151 100644 --- a/drivers/leds/leds-turris-omnia.c +++ b/drivers/leds/leds-turris-omnia.c @@ -277,6 +277,7 @@ static const struct i2c_device_id omnia_id[] = { { "omnia", 0 }, { } }; +MODULE_DEVICE_TABLE(i2c, omnia_id); static struct i2c_driver omnia_leds_driver = { .probe = omnia_leds_probe, diff --git a/drivers/mailbox/qcom-apcs-ipc-mailbox.c b/drivers/mailbox/qcom-apcs-ipc-mailbox.c index 077e5c6a9ef7..3d100a004760 100644 --- a/drivers/mailbox/qcom-apcs-ipc-mailbox.c +++ b/drivers/mailbox/qcom-apcs-ipc-mailbox.c @@ -128,7 +128,7 @@ static int qcom_apcs_ipc_probe(struct platform_device *pdev) if (apcs_data->clk_name) { apcs->clk = platform_device_register_data(&pdev->dev, apcs_data->clk_name, - PLATFORM_DEVID_NONE, + PLATFORM_DEVID_AUTO, NULL, 0); if (IS_ERR(apcs->clk)) dev_err(&pdev->dev, "failed to register APCS clk\n"); diff --git a/drivers/mailbox/qcom-ipcc.c b/drivers/mailbox/qcom-ipcc.c index 2d13c72944c6..584700cd1585 100644 --- a/drivers/mailbox/qcom-ipcc.c +++ b/drivers/mailbox/qcom-ipcc.c @@ -155,6 +155,11 @@ static int qcom_ipcc_mbox_send_data(struct mbox_chan *chan, void *data) return 0; } +static void qcom_ipcc_mbox_shutdown(struct mbox_chan *chan) +{ + chan->con_priv = NULL; +} + static struct mbox_chan *qcom_ipcc_mbox_xlate(struct mbox_controller *mbox, const struct of_phandle_args *ph) { @@ -184,6 +189,7 @@ static struct mbox_chan *qcom_ipcc_mbox_xlate(struct mbox_controller *mbox, static const struct mbox_chan_ops ipcc_mbox_chan_ops = { .send_data = qcom_ipcc_mbox_send_data, + .shutdown = qcom_ipcc_mbox_shutdown, }; static int qcom_ipcc_setup_mbox(struct qcom_ipcc *ipcc) diff --git a/drivers/md/dm-verity-verify-sig.c b/drivers/md/dm-verity-verify-sig.c index 614e43db93aa..919154ae4cae 100644 --- a/drivers/md/dm-verity-verify-sig.c +++ b/drivers/md/dm-verity-verify-sig.c @@ -15,7 +15,7 @@ #define DM_VERITY_VERIFY_ERR(s) DM_VERITY_ROOT_HASH_VERIFICATION " " s static bool require_signatures; -module_param(require_signatures, bool, false); +module_param(require_signatures, bool, 0444); MODULE_PARM_DESC(require_signatures, "Verify the roothash of dm-verity hash tree"); diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index 8628c4aa2e85..9d6ae3e64285 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -532,7 +532,7 @@ static void ssd_commit_superblock(struct dm_writecache *wc) region.bdev = wc->ssd_dev->bdev; region.sector = 0; - region.count = PAGE_SIZE >> SECTOR_SHIFT; + region.count = max(4096U, wc->block_size) >> SECTOR_SHIFT; if (unlikely(region.sector + region.count > wc->metadata_sectors)) region.count = wc->metadata_sectors - region.sector; @@ -1301,8 +1301,12 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) writecache_flush(wc); if (writecache_has_error(wc)) goto unlock_error; + if (unlikely(wc->cleaner)) + goto unlock_remap_origin; goto unlock_submit; } else { + if (dm_bio_get_target_bio_nr(bio)) + goto unlock_remap_origin; writecache_offload_bio(wc, bio); goto unlock_return; } @@ -1360,14 +1364,18 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) } else { do { bool found_entry = false; + bool search_used = false; if (writecache_has_error(wc)) goto unlock_error; e = writecache_find_entry(wc, bio->bi_iter.bi_sector, 0); if (e) { - if (!writecache_entry_is_committed(wc, e)) + if (!writecache_entry_is_committed(wc, e)) { + search_used = true; goto bio_copy; + } if (!WC_MODE_PMEM(wc) && !e->write_in_progress) { wc->overwrote_committed = true; + search_used = true; goto bio_copy; } found_entry = true; @@ -1377,7 +1385,7 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) } e = writecache_pop_from_freelist(wc, (sector_t)-1); if (unlikely(!e)) { - if (!found_entry) { + if (!WC_MODE_PMEM(wc) && !found_entry) { direct_write: e = writecache_find_entry(wc, bio->bi_iter.bi_sector, WFE_RETURN_FOLLOWING); if (e) { @@ -1404,13 +1412,31 @@ static int writecache_map(struct dm_target *ti, struct bio *bio) sector_t current_cache_sec = start_cache_sec + (bio_size >> SECTOR_SHIFT); while (bio_size < bio->bi_iter.bi_size) { - struct wc_entry *f = writecache_pop_from_freelist(wc, current_cache_sec); - if (!f) - break; - write_original_sector_seq_count(wc, f, bio->bi_iter.bi_sector + - (bio_size >> SECTOR_SHIFT), wc->seq_count); - writecache_insert_entry(wc, f); - wc->uncommitted_blocks++; + if (!search_used) { + struct wc_entry *f = writecache_pop_from_freelist(wc, current_cache_sec); + if (!f) + break; + write_original_sector_seq_count(wc, f, bio->bi_iter.bi_sector + + (bio_size >> SECTOR_SHIFT), wc->seq_count); + writecache_insert_entry(wc, f); + wc->uncommitted_blocks++; + } else { + struct wc_entry *f; + struct rb_node *next = rb_next(&e->rb_node); + if (!next) + break; + f = container_of(next, struct wc_entry, rb_node); + if (f != e + 1) + break; + if (read_original_sector(wc, f) != + read_original_sector(wc, e) + (wc->block_size >> SECTOR_SHIFT)) + break; + if (unlikely(f->write_in_progress)) + break; + if (writecache_entry_is_committed(wc, f)) + wc->overwrote_committed = true; + e = f; + } bio_size += wc->block_size; current_cache_sec += wc->block_size >> SECTOR_SHIFT; } @@ -2465,7 +2491,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv) goto bad; } - ti->num_flush_bios = 1; + ti->num_flush_bios = WC_MODE_PMEM(wc) ? 1 : 2; ti->flush_supported = true; ti->num_discard_bios = 1; diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c index b298fefb022e..510090797461 100644 --- a/drivers/md/dm-zoned-metadata.c +++ b/drivers/md/dm-zoned-metadata.c @@ -1390,6 +1390,13 @@ static int dmz_init_zone(struct blk_zone *blkz, unsigned int num, void *data) return -ENXIO; } + /* + * Devices that have zones with a capacity smaller than the zone size + * (e.g. NVMe zoned namespaces) are not supported. + */ + if (blkz->capacity != blkz->len) + return -ENXIO; + switch (blkz->type) { case BLK_ZONE_TYPE_CONVENTIONAL: set_bit(DMZ_RND, &zone->flags); diff --git a/drivers/md/dm.c b/drivers/md/dm.c index ca7e320b9f46..08b0d3a84648 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1231,8 +1231,8 @@ static int dm_dax_zero_page_range(struct dax_device *dax_dev, pgoff_t pgoff, /* * A target may call dm_accept_partial_bio only from the map routine. It is - * allowed for all bio types except REQ_PREFLUSH, REQ_OP_ZONE_RESET, - * REQ_OP_ZONE_OPEN, REQ_OP_ZONE_CLOSE and REQ_OP_ZONE_FINISH. + * allowed for all bio types except REQ_PREFLUSH, REQ_OP_ZONE_* zone management + * operations and REQ_OP_ZONE_APPEND (zone append writes). * * dm_accept_partial_bio informs the dm that the target only wants to process * additional n_sectors sectors of the bio and the rest of the data should be @@ -1262,9 +1262,13 @@ void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors) { struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone); unsigned bi_size = bio->bi_iter.bi_size >> SECTOR_SHIFT; + BUG_ON(bio->bi_opf & REQ_PREFLUSH); + BUG_ON(op_is_zone_mgmt(bio_op(bio))); + BUG_ON(bio_op(bio) == REQ_OP_ZONE_APPEND); BUG_ON(bi_size > *tio->len_ptr); BUG_ON(n_sectors > bi_size); + *tio->len_ptr -= bi_size - n_sectors; bio->bi_iter.bi_size = n_sectors << SECTOR_SHIFT; } diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c index eff04fa23dfa..9e4d1212f4c1 100644 --- a/drivers/md/persistent-data/dm-btree-remove.c +++ b/drivers/md/persistent-data/dm-btree-remove.c @@ -549,7 +549,8 @@ int dm_btree_remove(struct dm_btree_info *info, dm_block_t root, delete_at(n, index); } - *new_root = shadow_root(&spine); + if (!r) + *new_root = shadow_root(&spine); exit_shadow_spine(&spine); return r; diff --git a/drivers/md/persistent-data/dm-space-map-disk.c b/drivers/md/persistent-data/dm-space-map-disk.c index bf4c5e2ccb6f..e0acae7a3815 100644 --- a/drivers/md/persistent-data/dm-space-map-disk.c +++ b/drivers/md/persistent-data/dm-space-map-disk.c @@ -171,6 +171,14 @@ static int sm_disk_new_block(struct dm_space_map *sm, dm_block_t *b) * Any block we allocate has to be free in both the old and current ll. */ r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, smd->begin, smd->ll.nr_blocks, b); + if (r == -ENOSPC) { + /* + * There's no free block between smd->begin and the end of the metadata device. + * We search before smd->begin in case something has been freed. + */ + r = sm_ll_find_common_free_block(&smd->old_ll, &smd->ll, 0, smd->begin, b); + } + if (r) return r; @@ -199,7 +207,6 @@ static int sm_disk_commit(struct dm_space_map *sm) return r; memcpy(&smd->old_ll, &smd->ll, sizeof(smd->old_ll)); - smd->begin = 0; smd->nr_allocated_this_transaction = 0; r = sm_disk_get_nr_free(sm, &nr_free); diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c index 9e3c64ec2026..da439ac85796 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.c +++ b/drivers/md/persistent-data/dm-space-map-metadata.c @@ -452,6 +452,14 @@ static int sm_metadata_new_block_(struct dm_space_map *sm, dm_block_t *b) * Any block we allocate has to be free in both the old and current ll. */ r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, smm->begin, smm->ll.nr_blocks, b); + if (r == -ENOSPC) { + /* + * There's no free block between smm->begin and the end of the metadata device. + * We search before smm->begin in case something has been freed. + */ + r = sm_ll_find_common_free_block(&smm->old_ll, &smm->ll, 0, smm->begin, b); + } + if (r) return r; @@ -503,7 +511,6 @@ static int sm_metadata_commit(struct dm_space_map *sm) return r; memcpy(&smm->old_ll, &smm->ll, sizeof(smm->old_ll)); - smm->begin = 0; smm->allocated_this_transaction = 0; return 0; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index a6480568c7eb..fb31e5dd54a6 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -472,8 +472,6 @@ static void raid1_end_write_request(struct bio *bio) /* * When the device is faulty, it is not necessary to * handle write error. - * For failfast, this is the only remaining device, - * We need to retry the write without FailFast. */ if (!test_bit(Faulty, &rdev->flags)) set_bit(R1BIO_WriteError, &r1_bio->state); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 9f9d8b67b5dd..70dccc3c9631 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -470,12 +470,12 @@ static void raid10_end_write_request(struct bio *bio) /* * When the device is faulty, it is not necessary to * handle write error. - * For failfast, this is the only remaining device, - * We need to retry the write without FailFast. */ if (!test_bit(Faulty, &rdev->flags)) set_bit(R10BIO_WriteError, &r10_bio->state); else { + /* Fail the request */ + set_bit(R10BIO_Degraded, &r10_bio->state); r10_bio->devs[slot].bio = NULL; to_put = bio; dec_rdev = 1; diff --git a/drivers/media/cec/platform/s5p/s5p_cec.c b/drivers/media/cec/platform/s5p/s5p_cec.c index 2a3e7ffefe0a..028a09a7531e 100644 --- a/drivers/media/cec/platform/s5p/s5p_cec.c +++ b/drivers/media/cec/platform/s5p/s5p_cec.c @@ -35,10 +35,13 @@ MODULE_PARM_DESC(debug, "debug level (0-2)"); static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) { + int ret; struct s5p_cec_dev *cec = cec_get_drvdata(adap); if (enable) { - pm_runtime_get_sync(cec->dev); + ret = pm_runtime_resume_and_get(cec->dev); + if (ret < 0) + return ret; s5p_cec_reset(cec); @@ -51,7 +54,7 @@ static int s5p_cec_adap_enable(struct cec_adapter *adap, bool enable) } else { s5p_cec_mask_tx_interrupts(cec); s5p_cec_mask_rx_interrupts(cec); - pm_runtime_disable(cec->dev); + pm_runtime_put(cec->dev); } return 0; diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index c1511094fdc7..b735e2370137 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -908,7 +908,7 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, void *buffer, size_t size) { struct sms_firmware *firmware = (struct sms_firmware *) buffer; - struct sms_msg_data4 *msg; + struct sms_msg_data5 *msg; u32 mem_address, calc_checksum = 0; u32 i, *ptr; u8 *payload = firmware->payload; @@ -989,24 +989,20 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, goto exit_fw_download; if (coredev->mode == DEVICE_MODE_NONE) { - struct sms_msg_data *trigger_msg = - (struct sms_msg_data *) msg; - pr_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ\n"); SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, - sizeof(struct sms_msg_hdr) + - sizeof(u32) * 5); + sizeof(*msg)); - trigger_msg->msg_data[0] = firmware->start_address; + msg->msg_data[0] = firmware->start_address; /* Entry point */ - trigger_msg->msg_data[1] = 6; /* Priority */ - trigger_msg->msg_data[2] = 0x200; /* Stack size */ - trigger_msg->msg_data[3] = 0; /* Parameter */ - trigger_msg->msg_data[4] = 4; /* Task ID */ + msg->msg_data[1] = 6; /* Priority */ + msg->msg_data[2] = 0x200; /* Stack size */ + msg->msg_data[3] = 0; /* Parameter */ + msg->msg_data[4] = 4; /* Task ID */ - rc = smscore_sendrequest_and_wait(coredev, trigger_msg, - trigger_msg->x_msg_header.msg_length, + rc = smscore_sendrequest_and_wait(coredev, msg, + msg->x_msg_header.msg_length, &coredev->trigger_done); } else { SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_EXEC_REQ, diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h index b3b793b5caf3..16c45afabc53 100644 --- a/drivers/media/common/siano/smscoreapi.h +++ b/drivers/media/common/siano/smscoreapi.h @@ -629,9 +629,9 @@ struct sms_msg_data2 { u32 msg_data[2]; }; -struct sms_msg_data4 { +struct sms_msg_data5 { struct sms_msg_hdr x_msg_header; - u32 msg_data[4]; + u32 msg_data[5]; }; struct sms_data_download { diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index ae17407e477a..7cc654bc52d3 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -1176,6 +1176,10 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, return 0; media_graph_error: + mutex_lock(&g_smsdvb_clientslock); + list_del(&client->entry); + mutex_unlock(&g_smsdvb_clientslock); + smsdvb_debugfs_release(client); client_error: diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 89e38392509c..72350343a56a 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -1573,6 +1573,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, struct media_request *req) { struct vb2_buffer *vb; + enum vb2_buffer_state orig_state; int ret; if (q->error) { @@ -1673,6 +1674,7 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, * Add to the queued buffers list, a buffer will stay on it until * dequeued in dqbuf. */ + orig_state = vb->state; list_add_tail(&vb->queued_entry, &q->queued_list); q->queued_count++; q->waiting_for_buffers = false; @@ -1703,8 +1705,17 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb, if (q->streaming && !q->start_streaming_called && q->queued_count >= q->min_buffers_needed) { ret = vb2_start_streaming(q); - if (ret) + if (ret) { + /* + * Since vb2_core_qbuf will return with an error, + * we should return it to state DEQUEUED since + * the error indicates that the buffer wasn't queued. + */ + list_del(&vb->queued_entry); + q->queued_count--; + vb->state = orig_state; return ret; + } } dprintk(q, 2, "qbuf of buffer %d succeeded\n", vb->index); diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 89620da983ba..dddebea644bb 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -1462,14 +1463,20 @@ static int dvb_net_do_ioctl(struct file *file, struct net_device *netdev; struct dvb_net_priv *priv_data; struct dvb_net_if *dvbnetif = parg; + int if_num = dvbnetif->if_num; - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || - !dvbnet->state[dvbnetif->if_num]) { + if (if_num >= DVB_NET_DEVICES_MAX) { ret = -EINVAL; goto ioctl_error; } + if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); - netdev = dvbnet->device[dvbnetif->if_num]; + if (!dvbnet->state[if_num]) { + ret = -EINVAL; + goto ioctl_error; + } + + netdev = dvbnet->device[if_num]; priv_data = netdev_priv(netdev); dvbnetif->pid=priv_data->pid; @@ -1522,14 +1529,20 @@ static int dvb_net_do_ioctl(struct file *file, struct net_device *netdev; struct dvb_net_priv *priv_data; struct __dvb_net_if_old *dvbnetif = parg; + int if_num = dvbnetif->if_num; + + if (if_num >= DVB_NET_DEVICES_MAX) { + ret = -EINVAL; + goto ioctl_error; + } + if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX); - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || - !dvbnet->state[dvbnetif->if_num]) { + if (!dvbnet->state[if_num]) { ret = -EINVAL; goto ioctl_error; } - netdev = dvbnet->device[dvbnetif->if_num]; + netdev = dvbnet->device[if_num]; priv_data = netdev_priv(netdev); dvbnetif->pid=priv_data->pid; diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c index e8119ad0bc71..92376592455e 100644 --- a/drivers/media/i2c/ir-kbd-i2c.c +++ b/drivers/media/i2c/ir-kbd-i2c.c @@ -678,8 +678,8 @@ static int zilog_tx(struct rc_dev *rcdev, unsigned int *txbuf, goto out_unlock; } - i = i2c_master_recv(ir->tx_c, buf, 1); - if (i != 1) { + ret = i2c_master_recv(ir->tx_c, buf, 1); + if (ret != 1) { dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret); ret = -EIO; goto out_unlock; diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 42f64175a6df..fb78a1cedc03 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -204,6 +204,7 @@ struct ov2659 { struct i2c_client *client; struct v4l2_ctrl_handler ctrls; struct v4l2_ctrl *link_frequency; + struct clk *clk; const struct ov2659_framesize *frame_size; struct sensor_register *format_ctrl_regs; struct ov2659_pll_ctrl pll; @@ -1270,6 +1271,8 @@ static int ov2659_power_off(struct device *dev) gpiod_set_value(ov2659->pwdn_gpio, 1); + clk_disable_unprepare(ov2659->clk); + return 0; } @@ -1278,9 +1281,17 @@ static int ov2659_power_on(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct v4l2_subdev *sd = i2c_get_clientdata(client); struct ov2659 *ov2659 = to_ov2659(sd); + int ret; dev_dbg(&client->dev, "%s:\n", __func__); + ret = clk_prepare_enable(ov2659->clk); + if (ret) { + dev_err(&client->dev, "%s: failed to enable clock\n", + __func__); + return ret; + } + gpiod_set_value(ov2659->pwdn_gpio, 0); if (ov2659->resetb_gpio) { @@ -1425,7 +1436,6 @@ static int ov2659_probe(struct i2c_client *client) const struct ov2659_platform_data *pdata = ov2659_get_pdata(client); struct v4l2_subdev *sd; struct ov2659 *ov2659; - struct clk *clk; int ret; if (!pdata) { @@ -1440,11 +1450,11 @@ static int ov2659_probe(struct i2c_client *client) ov2659->pdata = pdata; ov2659->client = client; - clk = devm_clk_get(&client->dev, "xvclk"); - if (IS_ERR(clk)) - return PTR_ERR(clk); + ov2659->clk = devm_clk_get(&client->dev, "xvclk"); + if (IS_ERR(ov2659->clk)) + return PTR_ERR(ov2659->clk); - ov2659->xvclk_frequency = clk_get_rate(clk); + ov2659->xvclk_frequency = clk_get_rate(ov2659->clk); if (ov2659->xvclk_frequency < 6000000 || ov2659->xvclk_frequency > 27000000) return -EINVAL; @@ -1506,7 +1516,9 @@ static int ov2659_probe(struct i2c_client *client) ov2659->frame_size = &ov2659_framesizes[2]; ov2659->format_ctrl_regs = ov2659_formats[0].format_ctrl_regs; - ov2659_power_on(&client->dev); + ret = ov2659_power_on(&client->dev); + if (ret < 0) + goto error; ret = ov2659_detect(sd); if (ret < 0) diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 5b4c4a3547c9..71804a70bc6d 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1386,7 +1386,7 @@ static int __s5c73m3_power_on(struct s5c73m3 *state) s5c73m3_gpio_deassert(state, STBY); usleep_range(100, 200); - s5c73m3_gpio_deassert(state, RST); + s5c73m3_gpio_deassert(state, RSET); usleep_range(50, 100); return 0; @@ -1401,7 +1401,7 @@ static int __s5c73m3_power_off(struct s5c73m3 *state) { int i, ret; - if (s5c73m3_gpio_assert(state, RST)) + if (s5c73m3_gpio_assert(state, RSET)) usleep_range(10, 50); if (s5c73m3_gpio_assert(state, STBY)) @@ -1606,7 +1606,7 @@ static int s5c73m3_get_platform_data(struct s5c73m3 *state) state->mclk_frequency = pdata->mclk_frequency; state->gpio[STBY] = pdata->gpio_stby; - state->gpio[RST] = pdata->gpio_reset; + state->gpio[RSET] = pdata->gpio_reset; return 0; } diff --git a/drivers/media/i2c/s5c73m3/s5c73m3.h b/drivers/media/i2c/s5c73m3/s5c73m3.h index ef7e85b34263..c3fcfdd3ea66 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3.h +++ b/drivers/media/i2c/s5c73m3/s5c73m3.h @@ -353,7 +353,7 @@ struct s5c73m3_ctrls { enum s5c73m3_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; diff --git a/drivers/media/i2c/s5k4ecgx.c b/drivers/media/i2c/s5k4ecgx.c index b2d53417badf..4e97309a67f4 100644 --- a/drivers/media/i2c/s5k4ecgx.c +++ b/drivers/media/i2c/s5k4ecgx.c @@ -173,7 +173,7 @@ static const char * const s5k4ecgx_supply_names[] = { enum s5k4ecgx_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; @@ -476,7 +476,7 @@ static int __s5k4ecgx_power_on(struct s5k4ecgx *priv) if (s5k4ecgx_gpio_set_value(priv, STBY, priv->gpio[STBY].level)) usleep_range(30, 50); - if (s5k4ecgx_gpio_set_value(priv, RST, priv->gpio[RST].level)) + if (s5k4ecgx_gpio_set_value(priv, RSET, priv->gpio[RSET].level)) usleep_range(30, 50); return 0; @@ -484,7 +484,7 @@ static int __s5k4ecgx_power_on(struct s5k4ecgx *priv) static int __s5k4ecgx_power_off(struct s5k4ecgx *priv) { - if (s5k4ecgx_gpio_set_value(priv, RST, !priv->gpio[RST].level)) + if (s5k4ecgx_gpio_set_value(priv, RSET, !priv->gpio[RSET].level)) usleep_range(30, 50); if (s5k4ecgx_gpio_set_value(priv, STBY, !priv->gpio[STBY].level)) @@ -872,7 +872,7 @@ static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv, int ret; priv->gpio[STBY].gpio = -EINVAL; - priv->gpio[RST].gpio = -EINVAL; + priv->gpio[RSET].gpio = -EINVAL; ret = s5k4ecgx_config_gpio(gpio->gpio, gpio->level, "S5K4ECGX_STBY"); @@ -891,7 +891,7 @@ static int s5k4ecgx_config_gpios(struct s5k4ecgx *priv, s5k4ecgx_free_gpios(priv); return ret; } - priv->gpio[RST] = *gpio; + priv->gpio[RSET] = *gpio; if (gpio_is_valid(gpio->gpio)) gpio_set_value(gpio->gpio, 0); diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c index ec6f22efe19a..ec65a8e084c6 100644 --- a/drivers/media/i2c/s5k5baf.c +++ b/drivers/media/i2c/s5k5baf.c @@ -235,7 +235,7 @@ struct s5k5baf_gpio { enum s5k5baf_gpio_id { STBY, - RST, + RSET, NUM_GPIOS, }; @@ -969,7 +969,7 @@ static int s5k5baf_power_on(struct s5k5baf *state) s5k5baf_gpio_deassert(state, STBY); usleep_range(50, 100); - s5k5baf_gpio_deassert(state, RST); + s5k5baf_gpio_deassert(state, RSET); return 0; err_reg_dis: @@ -987,7 +987,7 @@ static int s5k5baf_power_off(struct s5k5baf *state) state->apply_cfg = 0; state->apply_crop = 0; - s5k5baf_gpio_assert(state, RST); + s5k5baf_gpio_assert(state, RSET); s5k5baf_gpio_assert(state, STBY); if (!IS_ERR(state->clock)) diff --git a/drivers/media/i2c/s5k6aa.c b/drivers/media/i2c/s5k6aa.c index 72439fae7968..6516e205e9a3 100644 --- a/drivers/media/i2c/s5k6aa.c +++ b/drivers/media/i2c/s5k6aa.c @@ -177,7 +177,7 @@ static const char * const s5k6aa_supply_names[] = { enum s5k6aa_gpio_id { STBY, - RST, + RSET, GPIO_NUM, }; @@ -841,7 +841,7 @@ static int __s5k6aa_power_on(struct s5k6aa *s5k6aa) ret = s5k6aa->s_power(1); usleep_range(4000, 5000); - if (s5k6aa_gpio_deassert(s5k6aa, RST)) + if (s5k6aa_gpio_deassert(s5k6aa, RSET)) msleep(20); return ret; @@ -851,7 +851,7 @@ static int __s5k6aa_power_off(struct s5k6aa *s5k6aa) { int ret; - if (s5k6aa_gpio_assert(s5k6aa, RST)) + if (s5k6aa_gpio_assert(s5k6aa, RSET)) usleep_range(100, 150); if (s5k6aa->s_power) { @@ -1510,7 +1510,7 @@ static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa, int ret; s5k6aa->gpio[STBY].gpio = -EINVAL; - s5k6aa->gpio[RST].gpio = -EINVAL; + s5k6aa->gpio[RSET].gpio = -EINVAL; gpio = &pdata->gpio_stby; if (gpio_is_valid(gpio->gpio)) { @@ -1533,7 +1533,7 @@ static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa, if (ret < 0) return ret; - s5k6aa->gpio[RST] = *gpio; + s5k6aa->gpio[RSET] = *gpio; } return 0; diff --git a/drivers/media/i2c/saa6588.c b/drivers/media/i2c/saa6588.c index ecb491d5f2ab..d1e0716bdfff 100644 --- a/drivers/media/i2c/saa6588.c +++ b/drivers/media/i2c/saa6588.c @@ -380,7 +380,7 @@ static void saa6588_configure(struct saa6588 *s) /* ---------------------------------------------------------------------- */ -static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) +static long saa6588_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { struct saa6588 *s = to_saa6588(sd); struct saa6588_command *a = arg; @@ -433,7 +433,7 @@ static int saa6588_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt) /* ----------------------------------------------------------------------- */ static const struct v4l2_subdev_core_ops saa6588_core_ops = { - .ioctl = saa6588_ioctl, + .command = saa6588_command, }; static const struct v4l2_subdev_tuner_ops saa6588_tuner_ops = { diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index 1b309bb743c7..f21da11caf22 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -1974,6 +1974,7 @@ static int tc358743_probe_of(struct tc358743_state *state) bps_pr_lane = 2 * endpoint.link_frequencies[0]; if (bps_pr_lane < 62500000U || bps_pr_lane > 1000000000U) { dev_err(dev, "unsupported bps per lane: %u bps\n", bps_pr_lane); + ret = -EINVAL; goto disable_clk; } diff --git a/drivers/media/mc/Makefile b/drivers/media/mc/Makefile index 119037f0e686..2b7af42ba59c 100644 --- a/drivers/media/mc/Makefile +++ b/drivers/media/mc/Makefile @@ -3,7 +3,7 @@ mc-objs := mc-device.o mc-devnode.o mc-entity.o \ mc-request.o -ifeq ($(CONFIG_USB),y) +ifneq ($(CONFIG_USB),) mc-objs += mc-dev-allocator.o endif diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c index 79ba15a9385a..0705913972c6 100644 --- a/drivers/media/pci/bt8xx/bt878.c +++ b/drivers/media/pci/bt8xx/bt878.c @@ -300,7 +300,8 @@ static irqreturn_t bt878_irq(int irq, void *dev_id) } if (astat & BT878_ARISCI) { bt->finished_block = (stat & BT878_ARISCS) >> 28; - tasklet_schedule(&bt->tasklet); + if (bt->tasklet.callback) + tasklet_schedule(&bt->tasklet); break; } count++; @@ -477,6 +478,9 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) btwrite(0, BT878_AINT_MASK); bt878_num++; + if (!bt->tasklet.func) + tasklet_disable(&bt->tasklet); + return 0; fail2: diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 8824dd0fb331..35a51e9b539d 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -3187,7 +3187,7 @@ static int radio_release(struct file *file) btv->radio_user--; - bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd); + bttv_call_all(btv, core, command, SAA6588_CMD_CLOSE, &cmd); if (btv->radio_user == 0) btv->has_radio_tuner = 0; @@ -3268,7 +3268,7 @@ static ssize_t radio_read(struct file *file, char __user *data, cmd.result = -ENODEV; radio_enable(btv); - bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd); + bttv_call_all(btv, core, command, SAA6588_CMD_READ, &cmd); return cmd.result; } @@ -3289,7 +3289,7 @@ static __poll_t radio_poll(struct file *file, poll_table *wait) cmd.instance = file; cmd.event_list = wait; cmd.poll_mask = res; - bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd); + bttv_call_all(btv, core, command, SAA6588_CMD_POLL, &cmd); return cmd.poll_mask; } diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index 0695078ef812..1bd8bbe57a30 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c @@ -667,6 +667,7 @@ static int cobalt_probe(struct pci_dev *pci_dev, return -ENOMEM; cobalt->pci_dev = pci_dev; cobalt->instance = i; + mutex_init(&cobalt->pci_lock); retval = v4l2_device_register(&pci_dev->dev, &cobalt->v4l2_dev); if (retval) { diff --git a/drivers/media/pci/cobalt/cobalt-driver.h b/drivers/media/pci/cobalt/cobalt-driver.h index bca68572b324..12c33e035904 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.h +++ b/drivers/media/pci/cobalt/cobalt-driver.h @@ -251,6 +251,8 @@ struct cobalt { int instance; struct pci_dev *pci_dev; struct v4l2_device v4l2_dev; + /* serialize PCI access in cobalt_s_bit_sysctrl() */ + struct mutex pci_lock; void __iomem *bar0, *bar1; @@ -320,10 +322,13 @@ static inline u32 cobalt_g_sysctrl(struct cobalt *cobalt) static inline void cobalt_s_bit_sysctrl(struct cobalt *cobalt, int bit, int val) { - u32 ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); + u32 ctrl; + mutex_lock(&cobalt->pci_lock); + ctrl = cobalt_read_bar1(cobalt, COBALT_SYS_CTRL_BASE); cobalt_write_bar1(cobalt, COBALT_SYS_CTRL_BASE, (ctrl & ~(1UL << bit)) | (val << bit)); + mutex_unlock(&cobalt->pci_lock); } static inline u32 cobalt_g_sysstat(struct cobalt *cobalt) diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c index dcbfe8c9abc7..2fe4a0bd0284 100644 --- a/drivers/media/pci/intel/ipu3/ipu3-cio2.c +++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c @@ -1476,7 +1476,8 @@ static int cio2_parse_firmware(struct cio2_device *cio2) struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_CSI2_DPHY }; - struct sensor_async_subdev *s_asd = NULL; + struct sensor_async_subdev *s_asd; + struct v4l2_async_subdev *asd; struct fwnode_handle *ep; ep = fwnode_graph_get_endpoint_by_id( @@ -1490,27 +1491,23 @@ static int cio2_parse_firmware(struct cio2_device *cio2) if (ret) goto err_parse; - s_asd = kzalloc(sizeof(*s_asd), GFP_KERNEL); - if (!s_asd) { - ret = -ENOMEM; + asd = v4l2_async_notifier_add_fwnode_remote_subdev( + &cio2->notifier, ep, sizeof(*s_asd)); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); goto err_parse; } + s_asd = container_of(asd, struct sensor_async_subdev, asd); s_asd->csi2.port = vep.base.port; s_asd->csi2.lanes = vep.bus.mipi_csi2.num_data_lanes; - ret = v4l2_async_notifier_add_fwnode_remote_subdev( - &cio2->notifier, ep, &s_asd->asd); - if (ret) - goto err_parse; - fwnode_handle_put(ep); continue; err_parse: fwnode_handle_put(ep); - kfree(s_asd); return ret; } diff --git a/drivers/media/pci/ngene/ngene-core.c b/drivers/media/pci/ngene/ngene-core.c index f9f94f47d76b..e1a8c611d01b 100644 --- a/drivers/media/pci/ngene/ngene-core.c +++ b/drivers/media/pci/ngene/ngene-core.c @@ -385,7 +385,7 @@ static int ngene_command_config_free_buf(struct ngene *dev, u8 *config) com.cmd.hdr.Opcode = CMD_CONFIGURE_FREE_BUFFER; com.cmd.hdr.Length = 6; - memcpy(&com.cmd.ConfigureBuffers.config, config, 6); + memcpy(&com.cmd.ConfigureFreeBuffers.config, config, 6); com.in_len = 6; com.out_len = 0; diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h index 84f04e0e0cb9..3d296f1998a1 100644 --- a/drivers/media/pci/ngene/ngene.h +++ b/drivers/media/pci/ngene/ngene.h @@ -407,12 +407,14 @@ enum _BUFFER_CONFIGS { struct FW_CONFIGURE_FREE_BUFFERS { struct FW_HEADER hdr; - u8 UVI1_BufferLength; - u8 UVI2_BufferLength; - u8 TVO_BufferLength; - u8 AUD1_BufferLength; - u8 AUD2_BufferLength; - u8 TVA_BufferLength; + struct { + u8 UVI1_BufferLength; + u8 UVI2_BufferLength; + u8 TVO_BufferLength; + u8 AUD1_BufferLength; + u8 AUD2_BufferLength; + u8 TVA_BufferLength; + } __packed config; } __attribute__ ((__packed__)); struct FW_CONFIGURE_UART { diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 9a6a6b68f8e3..85d082baaadc 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -1178,7 +1178,7 @@ static int video_release(struct file *file) saa_call_all(dev, tuner, standby); if (vdev->vfl_type == VFL_TYPE_RADIO) - saa_call_all(dev, core, ioctl, SAA6588_CMD_CLOSE, &cmd); + saa_call_all(dev, core, command, SAA6588_CMD_CLOSE, &cmd); mutex_unlock(&dev->lock); return 0; @@ -1197,7 +1197,7 @@ static ssize_t radio_read(struct file *file, char __user *data, cmd.result = -ENODEV; mutex_lock(&dev->lock); - saa_call_all(dev, core, ioctl, SAA6588_CMD_READ, &cmd); + saa_call_all(dev, core, command, SAA6588_CMD_READ, &cmd); mutex_unlock(&dev->lock); return cmd.result; @@ -1213,7 +1213,7 @@ static __poll_t radio_poll(struct file *file, poll_table *wait) cmd.event_list = wait; cmd.poll_mask = 0; mutex_lock(&dev->lock); - saa_call_all(dev, core, ioctl, SAA6588_CMD_POLL, &cmd); + saa_call_all(dev, core, command, SAA6588_CMD_POLL, &cmd); mutex_unlock(&dev->lock); return rc | cmd.poll_mask; diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index 0fb9f9ba1219..31cee69adbe1 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -1021,7 +1021,9 @@ static int vpfe_initialize_device(struct vpfe_device *vpfe) if (ret) return ret; - pm_runtime_get_sync(vpfe->pdev); + ret = pm_runtime_resume_and_get(vpfe->pdev); + if (ret < 0) + return ret; vpfe_config_enable(&vpfe->ccdc, 1); @@ -2443,7 +2445,11 @@ static int vpfe_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); /* for now just enable it here instead of waiting for the open */ - pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) { + vpfe_err(vpfe, "Unable to resume device.\n"); + goto probe_out_v4l2_unregister; + } vpfe_ccdc_config_defaults(ccdc); @@ -2530,6 +2536,11 @@ static int vpfe_suspend(struct device *dev) /* only do full suspend if streaming has started */ if (vb2_start_streaming_called(&vpfe->buffer_queue)) { + /* + * ignore RPM resume errors here, as it is already too late. + * A check like that should happen earlier, either at + * open() or just before start streaming. + */ pm_runtime_get_sync(dev); vpfe_config_enable(ccdc, 1); diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index d19bad997f30..bf3c3e76b921 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -47,7 +47,7 @@ static int venc_is_second_field(struct vpbe_display *disp_dev) ret = v4l2_subdev_call(vpbe_dev->venc, core, - ioctl, + command, VENC_GET_FLD, &val); if (ret < 0) { diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c index 8caa084e5704..bde241c26d79 100644 --- a/drivers/media/platform/davinci/vpbe_venc.c +++ b/drivers/media/platform/davinci/vpbe_venc.c @@ -521,9 +521,7 @@ static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output, return ret; } -static long venc_ioctl(struct v4l2_subdev *sd, - unsigned int cmd, - void *arg) +static long venc_command(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { u32 val; @@ -542,7 +540,7 @@ static long venc_ioctl(struct v4l2_subdev *sd, } static const struct v4l2_subdev_core_ops venc_core_ops = { - .ioctl = venc_ioctl, + .command = venc_command, }; static const struct v4l2_subdev_video_ops venc_video_ops = { diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c index 27a3c92c73bc..f1cf847d1cc2 100644 --- a/drivers/media/platform/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c @@ -56,10 +56,8 @@ static void __gsc_m2m_job_abort(struct gsc_ctx *ctx) static int gsc_m2m_start_streaming(struct vb2_queue *q, unsigned int count) { struct gsc_ctx *ctx = q->drv_priv; - int ret; - ret = pm_runtime_get_sync(&ctx->gsc_dev->pdev->dev); - return ret > 0 ? 0 : ret; + return pm_runtime_resume_and_get(&ctx->gsc_dev->pdev->dev); } static void __gsc_m2m_cleanup_queue(struct gsc_ctx *ctx) diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 6000a4e789ad..808b490c1910 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -478,11 +478,9 @@ static int fimc_capture_open(struct file *file) goto unlock; set_bit(ST_CAPT_BUSY, &fimc->state); - ret = pm_runtime_get_sync(&fimc->pdev->dev); - if (ret < 0) { - pm_runtime_put_sync(&fimc->pdev->dev); + ret = pm_runtime_resume_and_get(&fimc->pdev->dev); + if (ret < 0) goto unlock; - } ret = v4l2_fh_open(file); if (ret) { diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 32ab01e89196..d26fa5967d82 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -828,9 +828,9 @@ static int fimc_is_probe(struct platform_device *pdev) goto err_irq; } - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) - goto err_pm; + goto err_irq; vb2_dma_contig_set_max_seg_size(dev, DMA_BIT_MASK(32)); diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index 612b9872afc8..83688a7982f7 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -275,7 +275,7 @@ static int isp_video_open(struct file *file) if (ret < 0) goto unlock; - ret = pm_runtime_get_sync(&isp->pdev->dev); + ret = pm_runtime_resume_and_get(&isp->pdev->dev); if (ret < 0) goto rel_fh; @@ -293,7 +293,6 @@ static int isp_video_open(struct file *file) if (!ret) goto unlock; rel_fh: - pm_runtime_put_noidle(&isp->pdev->dev); v4l2_fh_release(file); unlock: mutex_unlock(&isp->video_lock); @@ -306,17 +305,20 @@ static int isp_video_release(struct file *file) struct fimc_is_video *ivc = &isp->video_capture; struct media_entity *entity = &ivc->ve.vdev.entity; struct media_device *mdev = entity->graph_obj.mdev; + bool is_singular_file; mutex_lock(&isp->video_lock); - if (v4l2_fh_is_singular_file(file) && ivc->streaming) { + is_singular_file = v4l2_fh_is_singular_file(file); + + if (is_singular_file && ivc->streaming) { media_pipeline_stop(entity); ivc->streaming = 0; } _vb2_fop_release(file, NULL); - if (v4l2_fh_is_singular_file(file)) { + if (is_singular_file) { fimc_pipeline_call(&ivc->ve, close); mutex_lock(&mdev->graph_mutex); diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index a77c49b18511..74b49d30901e 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -304,11 +304,10 @@ static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on) pr_debug("on: %d\n", on); if (on) { - ret = pm_runtime_get_sync(&is->pdev->dev); - if (ret < 0) { - pm_runtime_put(&is->pdev->dev); + ret = pm_runtime_resume_and_get(&is->pdev->dev); + if (ret < 0) return ret; - } + set_bit(IS_ST_PWR_ON, &is->state); ret = fimc_is_start_firmware(is); diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index fdd0d369b192..d279f282d592 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -469,9 +469,9 @@ static int fimc_lite_open(struct file *file) } set_bit(ST_FLITE_IN_USE, &fimc->state); - ret = pm_runtime_get_sync(&fimc->pdev->dev); + ret = pm_runtime_resume_and_get(&fimc->pdev->dev); if (ret < 0) - goto err_pm; + goto err_in_use; ret = v4l2_fh_open(file); if (ret < 0) @@ -499,6 +499,7 @@ static int fimc_lite_open(struct file *file) v4l2_fh_release(file); err_pm: pm_runtime_put_sync(&fimc->pdev->dev); +err_in_use: clear_bit(ST_FLITE_IN_USE, &fimc->state); unlock: mutex_unlock(&fimc->lock); diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c index 4acb179556c4..24b1badd2080 100644 --- a/drivers/media/platform/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c @@ -73,17 +73,14 @@ static void fimc_m2m_shutdown(struct fimc_ctx *ctx) static int start_streaming(struct vb2_queue *q, unsigned int count) { struct fimc_ctx *ctx = q->drv_priv; - int ret; - ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev); - return ret > 0 ? 0 : ret; + return pm_runtime_resume_and_get(&ctx->fimc_dev->pdev->dev); } static void stop_streaming(struct vb2_queue *q) { struct fimc_ctx *ctx = q->drv_priv; - fimc_m2m_shutdown(ctx); fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR); pm_runtime_put(&ctx->fimc_dev->pdev->dev); diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index e636c33e847b..a9a8f0433fb2 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -508,11 +508,9 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) if (!fmd->pmf) return -ENXIO; - ret = pm_runtime_get_sync(fmd->pmf); - if (ret < 0) { - pm_runtime_put(fmd->pmf); + ret = pm_runtime_resume_and_get(fmd->pmf); + if (ret < 0) return ret; - } fmd->num_sensors = 0; @@ -1282,13 +1280,11 @@ static DEVICE_ATTR(subdev_conf_mode, S_IWUSR | S_IRUGO, static int cam_clk_prepare(struct clk_hw *hw) { struct cam_clk *camclk = to_cam_clk(hw); - int ret; if (camclk->fmd->pmf == NULL) return -ENODEV; - ret = pm_runtime_get_sync(camclk->fmd->pmf); - return ret < 0 ? ret : 0; + return pm_runtime_resume_and_get(camclk->fmd->pmf); } static void cam_clk_unprepare(struct clk_hw *hw) diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index 1aac167abb17..ebf39c856894 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -494,7 +494,7 @@ static int s5pcsis_s_power(struct v4l2_subdev *sd, int on) struct device *dev = &state->pdev->dev; if (on) - return pm_runtime_get_sync(dev); + return pm_runtime_resume_and_get(dev); return pm_runtime_put_sync(dev); } @@ -509,11 +509,9 @@ static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable) if (enable) { s5pcsis_clear_counters(state); - ret = pm_runtime_get_sync(&state->pdev->dev); - if (ret && ret != 1) { - pm_runtime_put_noidle(&state->pdev->dev); + ret = pm_runtime_resume_and_get(&state->pdev->dev); + if (ret < 0) return ret; - } } mutex_lock(&state->lock); @@ -535,7 +533,7 @@ static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable) if (!enable) pm_runtime_put(&state->pdev->dev); - return ret == 1 ? 0 : ret; + return ret; } static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd, diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index 34266fba824f..e56c5e56e824 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -918,6 +918,7 @@ static int mclk_enable(struct clk_hw *hw) struct mcam_camera *cam = container_of(hw, struct mcam_camera, mclk_hw); int mclk_src; int mclk_div; + int ret; /* * Clock the sensor appropriately. Controller clock should @@ -931,7 +932,9 @@ static int mclk_enable(struct clk_hw *hw) mclk_div = 2; } - pm_runtime_get_sync(cam->dev); + ret = pm_runtime_resume_and_get(cam->dev); + if (ret < 0) + return ret; clk_enable(cam->clk[0]); mcam_reg_write(cam, REG_CLKCTRL, (mclk_src << 29) | mclk_div); mcam_ctlr_power_up(cam); @@ -1611,7 +1614,9 @@ static int mcam_v4l_open(struct file *filp) ret = sensor_call(cam, core, s_power, 1); if (ret) goto out; - pm_runtime_get_sync(cam->dev); + ret = pm_runtime_resume_and_get(cam->dev); + if (ret < 0) + goto out; __mcam_cam_reset(cam); mcam_set_config_needed(cam, 1); } diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c index 724c7333b6e5..45fc741c5541 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_m2m.c @@ -394,12 +394,12 @@ static int mtk_mdp_m2m_start_streaming(struct vb2_queue *q, unsigned int count) struct mtk_mdp_ctx *ctx = q->drv_priv; int ret; - ret = pm_runtime_get_sync(&ctx->mdp_dev->pdev->dev); + ret = pm_runtime_resume_and_get(&ctx->mdp_dev->pdev->dev); if (ret < 0) - mtk_mdp_dbg(1, "[%d] pm_runtime_get_sync failed:%d", + mtk_mdp_dbg(1, "[%d] pm_runtime_resume_and_get failed:%d", ctx->id, ret); - return 0; + return ret; } static void *mtk_mdp_m2m_buf_remove(struct mtk_mdp_ctx *ctx, diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c index 145686d2c219..f59ef8c8c9db 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c @@ -126,7 +126,9 @@ static int fops_vcodec_open(struct file *file) mtk_vcodec_dec_set_default_params(ctx); if (v4l2_fh_is_singular(&ctx->fh)) { - mtk_vcodec_dec_pw_on(&dev->pm); + ret = mtk_vcodec_dec_pw_on(&dev->pm); + if (ret < 0) + goto err_load_fw; /* * Does nothing if firmware was already loaded. */ diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c index ddee7046ce42..6038db96f71c 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c @@ -88,13 +88,15 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev) put_device(dev->pm.larbvdec); } -void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm) { int ret; - ret = pm_runtime_get_sync(pm->dev); + ret = pm_runtime_resume_and_get(pm->dev); if (ret) - mtk_v4l2_err("pm_runtime_get_sync fail %d", ret); + mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret); + + return ret; } void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm) diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h index 872d8bf8cfaf..280aeaefdb65 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h @@ -12,7 +12,7 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev); void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev); -void mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm); +int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm); void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm); void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm); diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index b1fc4518e275..1311b4996ece 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -2126,21 +2126,6 @@ static void isp_parse_of_csi1_endpoint(struct device *dev, buscfg->bus.ccp2.crc = 1; } -static int isp_alloc_isd(struct isp_async_subdev **isd, - struct isp_bus_cfg **buscfg) -{ - struct isp_async_subdev *__isd; - - __isd = kzalloc(sizeof(*__isd), GFP_KERNEL); - if (!__isd) - return -ENOMEM; - - *isd = __isd; - *buscfg = &__isd->bus; - - return 0; -} - static struct { u32 phy; u32 csi2_if; @@ -2156,7 +2141,7 @@ static int isp_parse_of_endpoints(struct isp_device *isp) { struct fwnode_handle *ep; struct isp_async_subdev *isd = NULL; - struct isp_bus_cfg *buscfg; + struct v4l2_async_subdev *asd; unsigned int i; ep = fwnode_graph_get_endpoint_by_id( @@ -2174,20 +2159,15 @@ static int isp_parse_of_endpoints(struct isp_device *isp) ret = v4l2_fwnode_endpoint_parse(ep, &vep); if (!ret) { - ret = isp_alloc_isd(&isd, &buscfg); - if (ret) - return ret; - } - - if (!ret) { - isp_parse_of_parallel_endpoint(isp->dev, &vep, buscfg); - ret = v4l2_async_notifier_add_fwnode_remote_subdev( - &isp->notifier, ep, &isd->asd); + asd = v4l2_async_notifier_add_fwnode_remote_subdev( + &isp->notifier, ep, sizeof(*isd)); + if (!IS_ERR(asd)) { + isd = container_of(asd, struct isp_async_subdev, asd); + isp_parse_of_parallel_endpoint(isp->dev, &vep, &isd->bus); + } } fwnode_handle_put(ep); - if (ret) - kfree(isd); } for (i = 0; i < ARRAY_SIZE(isp_bus_interfaces); i++) { @@ -2206,15 +2186,8 @@ static int isp_parse_of_endpoints(struct isp_device *isp) dev_dbg(isp->dev, "parsing serial interface %u, node %pOF\n", i, to_of_node(ep)); - ret = isp_alloc_isd(&isd, &buscfg); - if (ret) - return ret; - ret = v4l2_fwnode_endpoint_parse(ep, &vep); - if (!ret) { - buscfg->interface = isp_bus_interfaces[i].csi2_if; - isp_parse_of_csi2_endpoint(isp->dev, &vep, buscfg); - } else if (ret == -ENXIO) { + if (ret == -ENXIO) { vep = (struct v4l2_fwnode_endpoint) { .bus_type = V4L2_MBUS_CSI1 }; ret = v4l2_fwnode_endpoint_parse(ep, &vep); @@ -2224,21 +2197,35 @@ static int isp_parse_of_endpoints(struct isp_device *isp) { .bus_type = V4L2_MBUS_CCP2 }; ret = v4l2_fwnode_endpoint_parse(ep, &vep); } - if (!ret) { - buscfg->interface = - isp_bus_interfaces[i].csi1_if; - isp_parse_of_csi1_endpoint(isp->dev, &vep, - buscfg); - } } - if (!ret) - ret = v4l2_async_notifier_add_fwnode_remote_subdev( - &isp->notifier, ep, &isd->asd); + if (!ret) { + asd = v4l2_async_notifier_add_fwnode_remote_subdev( + &isp->notifier, ep, sizeof(*isd)); + + if (!IS_ERR(asd)) { + isd = container_of(asd, struct isp_async_subdev, asd); + + switch (vep.bus_type) { + case V4L2_MBUS_CSI2_DPHY: + isd->bus.interface = + isp_bus_interfaces[i].csi2_if; + isp_parse_of_csi2_endpoint(isp->dev, &vep, &isd->bus); + break; + case V4L2_MBUS_CSI1: + case V4L2_MBUS_CCP2: + isd->bus.interface = + isp_bus_interfaces[i].csi1_if; + isp_parse_of_csi1_endpoint(isp->dev, &vep, + &isd->bus); + break; + default: + break; + } + } + } fwnode_handle_put(ep); - if (ret) - kfree(isd); } return 0; diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index fd5993b3e674..58ddebbb8446 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -48,52 +48,86 @@ static const struct hfi_core_ops venus_core_ops = { .event_notify = venus_event_notify, }; +#define RPM_WAIT_FOR_IDLE_MAX_ATTEMPTS 10 + static void venus_sys_error_handler(struct work_struct *work) { struct venus_core *core = container_of(work, struct venus_core, work.work); - int ret = 0; - - pm_runtime_get_sync(core->dev); + int ret, i, max_attempts = RPM_WAIT_FOR_IDLE_MAX_ATTEMPTS; + const char *err_msg = ""; + bool failed = false; + + ret = pm_runtime_get_sync(core->dev); + if (ret < 0) { + err_msg = "resume runtime PM"; + max_attempts = 0; + failed = true; + } hfi_core_deinit(core, true); - dev_warn(core->dev, "system error has occurred, starting recovery!\n"); - mutex_lock(&core->lock); - while (pm_runtime_active(core->dev_dec) || pm_runtime_active(core->dev_enc)) + for (i = 0; i < max_attempts; i++) { + if (!pm_runtime_active(core->dev_dec) && !pm_runtime_active(core->dev_enc)) + break; msleep(10); + } venus_shutdown(core); pm_runtime_put_sync(core->dev); - while (core->pmdomains[0] && pm_runtime_active(core->pmdomains[0])) + for (i = 0; i < max_attempts; i++) { + if (!core->pmdomains[0] || !pm_runtime_active(core->pmdomains[0])) + break; usleep_range(1000, 1500); + } hfi_reinit(core); - pm_runtime_get_sync(core->dev); + ret = pm_runtime_get_sync(core->dev); + if (ret < 0) { + err_msg = "resume runtime PM"; + failed = true; + } + + ret = venus_boot(core); + if (ret && !failed) { + err_msg = "boot Venus"; + failed = true; + } - ret |= venus_boot(core); - ret |= hfi_core_resume(core, true); + ret = hfi_core_resume(core, true); + if (ret && !failed) { + err_msg = "resume HFI"; + failed = true; + } enable_irq(core->irq); mutex_unlock(&core->lock); - ret |= hfi_core_init(core); + ret = hfi_core_init(core); + if (ret && !failed) { + err_msg = "init HFI"; + failed = true; + } pm_runtime_put_sync(core->dev); - if (ret) { + if (failed) { disable_irq_nosync(core->irq); - dev_warn(core->dev, "recovery failed (%d)\n", ret); + dev_warn_ratelimited(core->dev, + "System error has occurred, recovery failed to %s\n", + err_msg); schedule_delayed_work(&core->work, msecs_to_jiffies(10)); return; } + dev_warn(core->dev, "system error has occurred (recovered)\n"); + mutex_lock(&core->lock); core->sys_error = false; mutex_unlock(&core->lock); diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index 15bcb7f6e113..1cb5eaabf340 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -276,6 +276,9 @@ static int g2d_release(struct file *file) struct g2d_dev *dev = video_drvdata(file); struct g2d_ctx *ctx = fh2ctx(file->private_data); + mutex_lock(&dev->mutex); + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); + mutex_unlock(&dev->mutex); v4l2_ctrl_handler_free(&ctx->ctrl_handler); v4l2_fh_del(&ctx->fh); v4l2_fh_exit(&ctx->fh); diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 9b22dd8e34f4..d515eb08c3ee 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -2566,11 +2566,8 @@ static void s5p_jpeg_buf_queue(struct vb2_buffer *vb) static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count) { struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q); - int ret; - - ret = pm_runtime_get_sync(ctx->jpeg->dev); - return ret > 0 ? 0 : ret; + return pm_runtime_resume_and_get(ctx->jpeg->dev); } static void s5p_jpeg_stop_streaming(struct vb2_queue *q) diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index b22dc1d72527..7d30e0c9447e 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -1133,7 +1133,11 @@ static int sh_vou_open(struct file *file) if (v4l2_fh_is_singular_file(file) && vou_dev->status == SH_VOU_INITIALISING) { /* First open */ - pm_runtime_get_sync(vou_dev->v4l2_dev.dev); + err = pm_runtime_resume_and_get(vou_dev->v4l2_dev.dev); + if (err < 0) { + v4l2_fh_release(file); + goto done_open; + } err = sh_vou_hw_init(vou_dev); if (err < 0) { pm_runtime_put(vou_dev->v4l2_dev.dev); diff --git a/drivers/media/platform/sti/bdisp/Makefile b/drivers/media/platform/sti/bdisp/Makefile index caf7ccd193ea..39ade0a34723 100644 --- a/drivers/media/platform/sti/bdisp/Makefile +++ b/drivers/media/platform/sti/bdisp/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_VIDEO_STI_BDISP) := bdisp.o +obj-$(CONFIG_VIDEO_STI_BDISP) += bdisp.o bdisp-objs := bdisp-v4l2.o bdisp-hw.o bdisp-debug.o diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 060ca85f64d5..85288da9d2ae 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -499,7 +499,7 @@ static int bdisp_start_streaming(struct vb2_queue *q, unsigned int count) { struct bdisp_ctx *ctx = q->drv_priv; struct vb2_v4l2_buffer *buf; - int ret = pm_runtime_get_sync(ctx->bdisp_dev->dev); + int ret = pm_runtime_resume_and_get(ctx->bdisp_dev->dev); if (ret < 0) { dev_err(ctx->bdisp_dev->dev, "failed to set runtime PM\n"); @@ -1364,10 +1364,10 @@ static int bdisp_probe(struct platform_device *pdev) /* Power management */ pm_runtime_enable(dev); - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { dev_err(dev, "failed to set PM\n"); - goto err_pm; + goto err_remove; } /* Filters */ @@ -1395,6 +1395,7 @@ static int bdisp_probe(struct platform_device *pdev) bdisp_hw_free_filters(bdisp->dev); err_pm: pm_runtime_put(dev); +err_remove: bdisp_debugfs_remove(bdisp); v4l2_device_unregister(&bdisp->v4l2_dev); err_clk: diff --git a/drivers/media/platform/sti/delta/Makefile b/drivers/media/platform/sti/delta/Makefile index 92b37e216f00..32412fa4c632 100644 --- a/drivers/media/platform/sti/delta/Makefile +++ b/drivers/media/platform/sti/delta/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) := st-delta.o +obj-$(CONFIG_VIDEO_STI_DELTA_DRIVER) += st-delta.o st-delta-y := delta-v4l2.o delta-mem.o delta-ipc.o delta-debug.o # MJPEG support diff --git a/drivers/media/platform/sti/hva/Makefile b/drivers/media/platform/sti/hva/Makefile index 74b41ec52f97..b5a5478bdd01 100644 --- a/drivers/media/platform/sti/hva/Makefile +++ b/drivers/media/platform/sti/hva/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_VIDEO_STI_HVA) := st-hva.o +obj-$(CONFIG_VIDEO_STI_HVA) += st-hva.o st-hva-y := hva-v4l2.o hva-hw.o hva-mem.o hva-h264.o st-hva-$(CONFIG_VIDEO_STI_HVA_DEBUGFS) += hva-debugfs.o diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c index 43f279e2a6a3..cf4c891bf619 100644 --- a/drivers/media/platform/sti/hva/hva-hw.c +++ b/drivers/media/platform/sti/hva/hva-hw.c @@ -130,8 +130,7 @@ static irqreturn_t hva_hw_its_irq_thread(int irq, void *arg) ctx_id = (hva->sts_reg & 0xFF00) >> 8; if (ctx_id >= HVA_MAX_INSTANCES) { dev_err(dev, "%s %s: bad context identifier: %d\n", - ctx->name, __func__, ctx_id); - ctx->hw_err = true; + HVA_PREFIX, __func__, ctx_id); goto out; } diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c index eb15c8c725ca..64f25921463e 100644 --- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c @@ -118,6 +118,7 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi) struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_PARALLEL, }; + struct v4l2_async_subdev *asd; struct fwnode_handle *ep; int ret; @@ -134,10 +135,12 @@ static int sun4i_csi_notifier_init(struct sun4i_csi *csi) csi->bus = vep.bus.parallel; - ret = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier, - ep, &csi->asd); - if (ret) + asd = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier, + ep, sizeof(*asd)); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); goto out; + } csi->notifier.ops = &sun4i_csi_notify_ops; diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h index 0f67ff652c2e..a5f61ee0ec4d 100644 --- a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h @@ -139,7 +139,6 @@ struct sun4i_csi { struct v4l2_mbus_framefmt subdev_fmt; /* V4L2 Async variables */ - struct v4l2_async_subdev asd; struct v4l2_async_notifier notifier; struct v4l2_subdev *src_subdev; int src_pad; diff --git a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c index 3f81dd17755c..fbcca59a0517 100644 --- a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c +++ b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c @@ -494,7 +494,7 @@ static int rotate_start_streaming(struct vb2_queue *vq, unsigned int count) struct device *dev = ctx->dev->dev; int ret; - ret = pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); if (ret < 0) { dev_err(dev, "Failed to enable module\n"); diff --git a/drivers/media/platform/video-mux.c b/drivers/media/platform/video-mux.c index 53570250a25d..640ce76fe0d9 100644 --- a/drivers/media/platform/video-mux.c +++ b/drivers/media/platform/video-mux.c @@ -362,7 +362,7 @@ static int video_mux_async_register(struct video_mux *vmux, for (i = 0; i < num_input_pads; i++) { struct v4l2_async_subdev *asd; - struct fwnode_handle *ep; + struct fwnode_handle *ep, *remote_ep; ep = fwnode_graph_get_endpoint_by_id( dev_fwnode(vmux->subdev.dev), i, 0, @@ -370,19 +370,21 @@ static int video_mux_async_register(struct video_mux *vmux, if (!ep) continue; - asd = kzalloc(sizeof(*asd), GFP_KERNEL); - if (!asd) { + /* Skip dangling endpoints for backwards compatibility */ + remote_ep = fwnode_graph_get_remote_endpoint(ep); + if (!remote_ep) { fwnode_handle_put(ep); - return -ENOMEM; + continue; } + fwnode_handle_put(remote_ep); - ret = v4l2_async_notifier_add_fwnode_remote_subdev( - &vmux->notifier, ep, asd); + asd = v4l2_async_notifier_add_fwnode_remote_subdev( + &vmux->notifier, ep, sizeof(*asd)); fwnode_handle_put(ep); - if (ret) { - kfree(asd); + if (IS_ERR(asd)) { + ret = PTR_ERR(asd); /* OK if asd already exists */ if (ret != -EEXIST) return ret; diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c index 3fe3edd80876..afae0afe3f81 100644 --- a/drivers/media/rc/bpf-lirc.c +++ b/drivers/media/rc/bpf-lirc.c @@ -326,7 +326,8 @@ int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr) } if (attr->query.prog_cnt != 0 && prog_ids && cnt) - ret = bpf_prog_array_copy_to_user(progs, prog_ids, cnt); + ret = bpf_prog_array_copy_to_user(progs, prog_ids, + attr->query.prog_cnt); unlock: mutex_unlock(&ir_raw_handler_lock); diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index a8a72d5fbd12..caefac07af92 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -199,8 +199,8 @@ static int au0828_media_device_init(struct au0828_dev *dev, struct media_device *mdev; mdev = media_device_usb_allocate(udev, KBUILD_MODNAME, THIS_MODULE); - if (!mdev) - return -ENOMEM; + if (IS_ERR(mdev)) + return PTR_ERR(mdev); dev->media_dev = mdev; #endif diff --git a/drivers/media/usb/cpia2/cpia2.h b/drivers/media/usb/cpia2/cpia2.h index 50835f5f7512..57b7f1ea68da 100644 --- a/drivers/media/usb/cpia2/cpia2.h +++ b/drivers/media/usb/cpia2/cpia2.h @@ -429,6 +429,7 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd); int cpia2_do_command(struct camera_data *cam, unsigned int command, unsigned char direction, unsigned char param); +void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf); struct camera_data *cpia2_init_camera_struct(struct usb_interface *intf); int cpia2_init_camera(struct camera_data *cam); int cpia2_allocate_buffers(struct camera_data *cam); diff --git a/drivers/media/usb/cpia2/cpia2_core.c b/drivers/media/usb/cpia2/cpia2_core.c index e747548ab286..b5a2d06fb356 100644 --- a/drivers/media/usb/cpia2/cpia2_core.c +++ b/drivers/media/usb/cpia2/cpia2_core.c @@ -2163,6 +2163,18 @@ static void reset_camera_struct(struct camera_data *cam) cam->height = cam->params.roi.height; } +/****************************************************************************** + * + * cpia2_init_camera_struct + * + * Deinitialize camera struct + *****************************************************************************/ +void cpia2_deinit_camera_struct(struct camera_data *cam, struct usb_interface *intf) +{ + v4l2_device_unregister(&cam->v4l2_dev); + kfree(cam); +} + /****************************************************************************** * * cpia2_init_camera_struct diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c index 3ab80a7b4498..76aac06f9fb8 100644 --- a/drivers/media/usb/cpia2/cpia2_usb.c +++ b/drivers/media/usb/cpia2/cpia2_usb.c @@ -844,15 +844,13 @@ static int cpia2_usb_probe(struct usb_interface *intf, ret = set_alternate(cam, USBIF_CMDONLY); if (ret < 0) { ERR("%s: usb_set_interface error (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } if((ret = cpia2_init_camera(cam)) < 0) { ERR("%s: failed to initialize cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } LOG(" CPiA Version: %d.%02d (%d.%d)\n", cam->params.version.firmware_revision_hi, @@ -872,11 +870,14 @@ static int cpia2_usb_probe(struct usb_interface *intf, ret = cpia2_register_camera(cam); if (ret < 0) { ERR("%s: Failed to register cpia2 camera (ret = %d)\n", __func__, ret); - kfree(cam); - return ret; + goto alt_err; } return 0; + +alt_err: + cpia2_deinit_camera_struct(cam, intf); + return ret; } /****************************************************************************** diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 91460e4d0c30..c278b9b0f102 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -37,7 +37,16 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req) } else { /* read */ requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); - pipe = usb_rcvctrlpipe(d->udev, 0); + + /* + * Zero-length transfers must use usb_sndctrlpipe() and + * rtl28xxu_identify_state() uses a zero-length i2c read + * command to determine the chip type. + */ + if (req->size) + pipe = usb_rcvctrlpipe(d->udev, 0); + else + pipe = usb_sndctrlpipe(d->udev, 0); } ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value, diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c index 969a7ec71dff..4116ba5c45fc 100644 --- a/drivers/media/usb/dvb-usb/cinergyT2-core.c +++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c @@ -78,6 +78,8 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) ret = dvb_usb_generic_rw(d, st->data, 1, st->data, 3, 0); if (ret < 0) { + if (adap->fe_adap[0].fe) + adap->fe_adap[0].fe->ops.release(adap->fe_adap[0].fe); deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep state info\n"); } mutex_unlock(&d->data_mutex); diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 761992ad05e2..7707de7bae7c 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c @@ -1947,7 +1947,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { .size_of_priv = sizeof(struct cxusb_state), - .num_adapters = 2, + .num_adapters = 1, .adapter = { { .num_frontends = 1, diff --git a/drivers/media/usb/dvb-usb/dtv5100.c b/drivers/media/usb/dvb-usb/dtv5100.c index fba06932a9e0..1c13e493322c 100644 --- a/drivers/media/usb/dvb-usb/dtv5100.c +++ b/drivers/media/usb/dvb-usb/dtv5100.c @@ -26,6 +26,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) { struct dtv5100_state *st = d->priv; + unsigned int pipe; u8 request; u8 type; u16 value; @@ -34,6 +35,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, switch (wlen) { case 1: /* write { reg }, read { value } */ + pipe = usb_rcvctrlpipe(d->udev, 0); request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ : DTV5100_TUNER_READ); type = USB_TYPE_VENDOR | USB_DIR_IN; @@ -41,6 +43,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, break; case 2: /* write { reg, value } */ + pipe = usb_sndctrlpipe(d->udev, 0); request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE : DTV5100_TUNER_WRITE); type = USB_TYPE_VENDOR | USB_DIR_OUT; @@ -54,7 +57,7 @@ static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, memcpy(st->data, rbuf, rlen); msleep(1); /* avoid I2C errors */ - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request, + return usb_control_msg(d->udev, pipe, request, type, value, index, st->data, rlen, DTV5100_USB_TIMEOUT); } @@ -141,7 +144,7 @@ static int dtv5100_probe(struct usb_interface *intf, /* initialize non qt1010/zl10353 part? */ for (i = 0; dtv5100_init[i].request; i++) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), dtv5100_init[i].request, USB_TYPE_VENDOR | USB_DIR_OUT, dtv5100_init[i].value, diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 5aa15a7a49de..59529cbf9cd0 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -720,7 +720,8 @@ static int em28xx_ir_init(struct em28xx *dev) dev->board.has_ir_i2c = 0; dev_warn(&dev->intf->dev, "No i2c IR remote control device found.\n"); - return -ENODEV; + err = -ENODEV; + goto ref_put; } } @@ -735,7 +736,7 @@ static int em28xx_ir_init(struct em28xx *dev) ir = kzalloc(sizeof(*ir), GFP_KERNEL); if (!ir) - return -ENOMEM; + goto ref_put; rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!rc) goto error; @@ -839,6 +840,9 @@ static int em28xx_ir_init(struct em28xx *dev) dev->ir = NULL; rc_free_device(rc); kfree(ir); +ref_put: + em28xx_shutdown_buttons(dev); + kref_put(&dev->ref, em28xx_free_device); return err; } diff --git a/drivers/media/usb/gspca/gl860/gl860.c b/drivers/media/usb/gspca/gl860/gl860.c index 2c05ea2598e7..ce4ee8bc75c8 100644 --- a/drivers/media/usb/gspca/gl860/gl860.c +++ b/drivers/media/usb/gspca/gl860/gl860.c @@ -561,8 +561,8 @@ int gl860_RTx(struct gspca_dev *gspca_dev, len, 400 + 200 * (len > 1)); memcpy(pdata, gspca_dev->usb_buf, len); } else { - r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - req, pref, val, index, NULL, len, 400); + gspca_err(gspca_dev, "zero-length read request\n"); + r = -EINVAL; } } diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c index 949111070971..32504ebcfd4d 100644 --- a/drivers/media/usb/gspca/sq905.c +++ b/drivers/media/usb/gspca/sq905.c @@ -116,7 +116,7 @@ static int sq905_command(struct gspca_dev *gspca_dev, u16 index) } ret = usb_control_msg(gspca_dev->dev, - usb_sndctrlpipe(gspca_dev->dev, 0), + usb_rcvctrlpipe(gspca_dev->dev, 0), USB_REQ_SYNCH_FRAME, /* request */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, SQ905_PING, 0, gspca_dev->usb_buf, 1, diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c index ace3da40006e..971dee0a56da 100644 --- a/drivers/media/usb/gspca/sunplus.c +++ b/drivers/media/usb/gspca/sunplus.c @@ -242,6 +242,10 @@ static void reg_r(struct gspca_dev *gspca_dev, gspca_err(gspca_dev, "reg_r: buffer overflow\n"); return; } + if (len == 0) { + gspca_err(gspca_dev, "reg_r: zero-length read\n"); + return; + } if (gspca_dev->usb_err < 0) return; ret = usb_control_msg(gspca_dev->dev, @@ -250,7 +254,7 @@ static void reg_r(struct gspca_dev *gspca_dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, - len ? gspca_dev->usb_buf : NULL, len, + gspca_dev->usb_buf, len, 500); if (ret < 0) { pr_err("reg_r err %d\n", ret); @@ -727,7 +731,7 @@ static int sd_start(struct gspca_dev *gspca_dev) case MegaImageVI: reg_w_riv(gspca_dev, 0xf0, 0, 0); spca504B_WaitCmdStatus(gspca_dev); - reg_r(gspca_dev, 0xf0, 4, 0); + reg_w_riv(gspca_dev, 0xf0, 4, 0); spca504B_WaitCmdStatus(gspca_dev); break; default: diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index f4a727918e35..d38dee1792e4 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2676,9 +2676,8 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw) pvr2_stream_destroy(hdw->vid_stream); hdw->vid_stream = NULL; } - pvr2_i2c_core_done(hdw); v4l2_device_unregister(&hdw->v4l2_dev); - pvr2_hdw_remove_usb_stuff(hdw); + pvr2_hdw_disconnect(hdw); mutex_lock(&pvr2_unit_mtx); do { if ((hdw->unit_number >= 0) && @@ -2705,6 +2704,7 @@ void pvr2_hdw_disconnect(struct pvr2_hdw *hdw) { pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw); LOCK_TAKE(hdw->big_lock); + pvr2_i2c_core_done(hdw); LOCK_TAKE(hdw->ctl_lock); pvr2_hdw_remove_usb_stuff(hdw); LOCK_GIVE(hdw->ctl_lock); diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c index a45d464427c4..0e231e576dc3 100644 --- a/drivers/media/usb/stkwebcam/stk-webcam.c +++ b/drivers/media/usb/stkwebcam/stk-webcam.c @@ -1346,7 +1346,7 @@ static int stk_camera_probe(struct usb_interface *interface, if (!dev->isoc_ep) { pr_err("Could not find isoc-in endpoint\n"); err = -ENODEV; - goto error; + goto error_put; } dev->vsettings.palette = V4L2_PIX_FMT_RGB565; dev->vsettings.mode = MODE_VGA; @@ -1359,10 +1359,12 @@ static int stk_camera_probe(struct usb_interface *interface, err = stk_register_video_device(dev); if (err) - goto error; + goto error_put; return 0; +error_put: + usb_put_intf(interface); error: v4l2_ctrl_handler_free(hdl); v4l2_device_unregister(&dev->v4l2_dev); diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index 5ad528264135..282f3d2388cc 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -1588,6 +1588,31 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain, return -EINVAL; } + /* + * Some devices reference an output terminal as the + * source of extension units. This is incorrect, as + * output terminals only have an input pin, and thus + * can't be connected to any entity in the forward + * direction. The resulting topology would cause issues + * when registering the media controller graph. To + * avoid this problem, connect the extension unit to + * the source of the output terminal instead. + */ + if (UVC_ENTITY_IS_OTERM(entity)) { + struct uvc_entity *source; + + source = uvc_entity_by_id(chain->dev, + entity->baSourceID[0]); + if (!source) { + uvc_trace(UVC_TRACE_DESCR, + "Can't connect extension unit %u in chain\n", + forward->id); + break; + } + + forward->baSourceID[0] = source->id; + } + list_add_tail(&forward->chain, &chain->entities); if (uvc_trace_param & UVC_TRACE_PROBE) { if (!found) @@ -1608,6 +1633,13 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain, return -EINVAL; } + if (UVC_ENTITY_IS_OTERM(entity)) { + uvc_trace(UVC_TRACE_DESCR, + "Unsupported connection between output terminals %u and %u\n", + entity->id, forward->id); + break; + } + list_add_tail(&forward->chain, &chain->entities); if (uvc_trace_param & UVC_TRACE_PROBE) { if (!found) diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index a6a441d92b94..5878c7833486 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -124,10 +124,37 @@ int uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit, static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, struct uvc_streaming_control *ctrl) { + static const struct usb_device_id elgato_cam_link_4k = { + USB_DEVICE(0x0fd9, 0x0066) + }; struct uvc_format *format = NULL; struct uvc_frame *frame = NULL; unsigned int i; + /* + * The response of the Elgato Cam Link 4K is incorrect: The second byte + * contains bFormatIndex (instead of being the second byte of bmHint). + * The first byte is always zero. The third byte is always 1. + * + * The UVC 1.5 class specification defines the first five bits in the + * bmHint bitfield. The remaining bits are reserved and should be zero. + * Therefore a valid bmHint will be less than 32. + * + * Latest Elgato Cam Link 4K firmware as of 2021-03-23 needs this fix. + * MCU: 20.02.19, FPGA: 67 + */ + if (usb_match_one_id(stream->dev->intf, &elgato_cam_link_4k) && + ctrl->bmHint > 255) { + u8 corrected_format_index = ctrl->bmHint >> 8; + + /* uvc_dbg(stream->dev, VIDEO, + "Correct USB video probe response from {bmHint: 0x%04x, bFormatIndex: %u} to {bmHint: 0x%04x, bFormatIndex: %u}\n", + ctrl->bmHint, ctrl->bFormatIndex, + 1, corrected_format_index); */ + ctrl->bmHint = 1; + ctrl->bFormatIndex = corrected_format_index; + } + for (i = 0; i < stream->nformats; ++i) { if (stream->format[i].index == ctrl->bFormatIndex) { format = &stream->format[i]; diff --git a/drivers/media/usb/zr364xx/zr364xx.c b/drivers/media/usb/zr364xx/zr364xx.c index 8c670934d920..08b86b22e5e8 100644 --- a/drivers/media/usb/zr364xx/zr364xx.c +++ b/drivers/media/usb/zr364xx/zr364xx.c @@ -1034,6 +1034,7 @@ static int zr364xx_start_readpipe(struct zr364xx_camera *cam) DBG("submitting URB %p\n", pipe_info->stream_urb); retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); if (retval) { + usb_free_urb(pipe_info->stream_urb); printk(KERN_ERR KBUILD_MODNAME ": start read pipe failed\n"); return retval; } @@ -1183,15 +1184,11 @@ static int zr364xx_open(struct file *file) return err; } -static void zr364xx_release(struct v4l2_device *v4l2_dev) +static void zr364xx_board_uninit(struct zr364xx_camera *cam) { - struct zr364xx_camera *cam = - container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev); unsigned long i; - v4l2_device_unregister(&cam->v4l2_dev); - - videobuf_mmap_free(&cam->vb_vidq); + zr364xx_stop_readpipe(cam); /* release sys buffers */ for (i = 0; i < FRAMES; i++) { @@ -1202,9 +1199,19 @@ static void zr364xx_release(struct v4l2_device *v4l2_dev) cam->buffer.frame[i].lpvbits = NULL; } - v4l2_ctrl_handler_free(&cam->ctrl_handler); /* release transfer buffer */ kfree(cam->pipe->transfer_buffer); +} + +static void zr364xx_release(struct v4l2_device *v4l2_dev) +{ + struct zr364xx_camera *cam = + container_of(v4l2_dev, struct zr364xx_camera, v4l2_dev); + + videobuf_mmap_free(&cam->vb_vidq); + v4l2_ctrl_handler_free(&cam->ctrl_handler); + zr364xx_board_uninit(cam); + v4l2_device_unregister(&cam->v4l2_dev); kfree(cam); } @@ -1327,6 +1334,7 @@ static int zr364xx_board_init(struct zr364xx_camera *cam) { struct zr364xx_pipeinfo *pipe = cam->pipe; unsigned long i; + int err; DBG("board init: %p\n", cam); memset(pipe, 0, sizeof(*pipe)); @@ -1359,9 +1367,8 @@ static int zr364xx_board_init(struct zr364xx_camera *cam) if (i == 0) { printk(KERN_INFO KBUILD_MODNAME ": out of memory. Aborting\n"); - kfree(cam->pipe->transfer_buffer); - cam->pipe->transfer_buffer = NULL; - return -ENOMEM; + err = -ENOMEM; + goto err_free; } else cam->buffer.dwFrames = i; @@ -1376,9 +1383,20 @@ static int zr364xx_board_init(struct zr364xx_camera *cam) /*** end create system buffers ***/ /* start read pipe */ - zr364xx_start_readpipe(cam); + err = zr364xx_start_readpipe(cam); + if (err) + goto err_free_frames; + DBG(": board initialized\n"); return 0; + +err_free_frames: + for (i = 0; i < FRAMES; i++) + vfree(cam->buffer.frame[i].lpvbits); +err_free: + kfree(cam->pipe->transfer_buffer); + cam->pipe->transfer_buffer = NULL; + return err; } static int zr364xx_probe(struct usb_interface *intf, @@ -1403,12 +1421,10 @@ static int zr364xx_probe(struct usb_interface *intf, if (!cam) return -ENOMEM; - cam->v4l2_dev.release = zr364xx_release; err = v4l2_device_register(&intf->dev, &cam->v4l2_dev); if (err < 0) { dev_err(&udev->dev, "couldn't register v4l2_device\n"); - kfree(cam); - return err; + goto free_cam; } hdl = &cam->ctrl_handler; v4l2_ctrl_handler_init(hdl, 1); @@ -1417,7 +1433,7 @@ static int zr364xx_probe(struct usb_interface *intf, if (hdl->error) { err = hdl->error; dev_err(&udev->dev, "couldn't register control\n"); - goto fail; + goto free_hdlr_and_unreg_dev; } /* save the init method used by this camera */ cam->method = id->driver_info; @@ -1490,7 +1506,7 @@ static int zr364xx_probe(struct usb_interface *intf, if (!cam->read_endpoint) { err = -ENOMEM; dev_err(&intf->dev, "Could not find bulk-in endpoint\n"); - goto fail; + goto free_hdlr_and_unreg_dev; } /* v4l */ @@ -1501,10 +1517,11 @@ static int zr364xx_probe(struct usb_interface *intf, /* load zr364xx board specific */ err = zr364xx_board_init(cam); - if (!err) - err = v4l2_ctrl_handler_setup(hdl); if (err) - goto fail; + goto free_hdlr_and_unreg_dev; + err = v4l2_ctrl_handler_setup(hdl); + if (err) + goto board_uninit; spin_lock_init(&cam->slock); @@ -1519,16 +1536,20 @@ static int zr364xx_probe(struct usb_interface *intf, err = video_register_device(&cam->vdev, VFL_TYPE_VIDEO, -1); if (err) { dev_err(&udev->dev, "video_register_device failed\n"); - goto fail; + goto board_uninit; } + cam->v4l2_dev.release = zr364xx_release; dev_info(&udev->dev, DRIVER_DESC " controlling device %s\n", video_device_node_name(&cam->vdev)); return 0; -fail: +board_uninit: + zr364xx_board_uninit(cam); +free_hdlr_and_unreg_dev: v4l2_ctrl_handler_free(hdl); v4l2_device_unregister(&cam->v4l2_dev); +free_cam: kfree(cam); return err; } @@ -1575,10 +1596,19 @@ static int zr364xx_resume(struct usb_interface *intf) if (!cam->was_streaming) return 0; - zr364xx_start_readpipe(cam); + res = zr364xx_start_readpipe(cam); + if (res) + return res; + res = zr364xx_prepare(cam); - if (!res) - zr364xx_start_acquire(cam); + if (res) + goto err_prepare; + + zr364xx_start_acquire(cam); + return 0; + +err_prepare: + zr364xx_stop_readpipe(cam); return res; } #endif diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index e3ab003a6c85..33babe6e8b3a 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -673,26 +673,26 @@ v4l2_async_notifier_add_fwnode_subdev(struct v4l2_async_notifier *notifier, } EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_subdev); -int +struct v4l2_async_subdev * v4l2_async_notifier_add_fwnode_remote_subdev(struct v4l2_async_notifier *notif, struct fwnode_handle *endpoint, - struct v4l2_async_subdev *asd) + unsigned int asd_struct_size) { + struct v4l2_async_subdev *asd; struct fwnode_handle *remote; - int ret; remote = fwnode_graph_get_remote_port_parent(endpoint); if (!remote) - return -ENOTCONN; + return ERR_PTR(-ENOTCONN); - asd->match_type = V4L2_ASYNC_MATCH_FWNODE; - asd->match.fwnode = remote; - - ret = v4l2_async_notifier_add_subdev(notif, asd); - if (ret) - fwnode_handle_put(remote); - - return ret; + asd = v4l2_async_notifier_add_fwnode_subdev(notif, remote, + asd_struct_size); + /* + * Calling v4l2_async_notifier_add_fwnode_subdev grabs a refcount, + * so drop the one we got in fwnode_graph_get_remote_port_parent. + */ + fwnode_handle_put(remote); + return asd; } EXPORT_SYMBOL_GPL(v4l2_async_notifier_add_fwnode_remote_subdev); diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c index 684574f58e82..90eec79ee995 100644 --- a/drivers/media/v4l2-core/v4l2-fh.c +++ b/drivers/media/v4l2-core/v4l2-fh.c @@ -96,6 +96,7 @@ int v4l2_fh_release(struct file *filp) v4l2_fh_del(fh); v4l2_fh_exit(fh); kfree(fh); + filp->private_data = NULL; } return 0; } diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index ac6ce031c7b7..4a9599137d03 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -431,30 +431,6 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK); - case VIDIOC_DQEVENT_TIME32: { - struct v4l2_event_time32 *ev32 = arg; - struct v4l2_event ev = { }; - - if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) - return -ENOIOCTLCMD; - - rval = v4l2_event_dequeue(vfh, &ev, file->f_flags & O_NONBLOCK); - - *ev32 = (struct v4l2_event_time32) { - .type = ev.type, - .pending = ev.pending, - .sequence = ev.sequence, - .timestamp.tv_sec = ev.timestamp.tv_sec, - .timestamp.tv_nsec = ev.timestamp.tv_nsec, - .id = ev.id, - }; - - memcpy(&ev32->u, &ev.u, sizeof(ev.u)); - memcpy(&ev32->reserved, &ev.reserved, sizeof(ev.reserved)); - - return rval; - } - case VIDIOC_SUBSCRIBE_EVENT: return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg); diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index 14386d0b5f57..c267283b01fd 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c @@ -600,8 +600,10 @@ static int atmel_ebi_probe(struct platform_device *pdev) child); ret = atmel_ebi_dev_disable(ebi, child); - if (ret) + if (ret) { + of_node_put(child); return ret; + } } } diff --git a/drivers/memory/fsl_ifc.c b/drivers/memory/fsl_ifc.c index 89f99b5b6450..d062c2f8250f 100644 --- a/drivers/memory/fsl_ifc.c +++ b/drivers/memory/fsl_ifc.c @@ -97,7 +97,6 @@ static int fsl_ifc_ctrl_remove(struct platform_device *dev) iounmap(ctrl->gregs); dev_set_drvdata(&dev->dev, NULL); - kfree(ctrl); return 0; } @@ -209,7 +208,8 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) dev_info(&dev->dev, "Freescale Integrated Flash Controller\n"); - fsl_ifc_ctrl_dev = kzalloc(sizeof(*fsl_ifc_ctrl_dev), GFP_KERNEL); + fsl_ifc_ctrl_dev = devm_kzalloc(&dev->dev, sizeof(*fsl_ifc_ctrl_dev), + GFP_KERNEL); if (!fsl_ifc_ctrl_dev) return -ENOMEM; @@ -219,8 +219,7 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) fsl_ifc_ctrl_dev->gregs = of_iomap(dev->dev.of_node, 0); if (!fsl_ifc_ctrl_dev->gregs) { dev_err(&dev->dev, "failed to get memory region\n"); - ret = -ENODEV; - goto err; + return -ENODEV; } if (of_property_read_bool(dev->dev.of_node, "little-endian")) { @@ -295,6 +294,7 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev) free_irq(fsl_ifc_ctrl_dev->irq, fsl_ifc_ctrl_dev); irq_dispose_mapping(fsl_ifc_ctrl_dev->irq); err: + iounmap(fsl_ifc_ctrl_dev->gregs); return ret; } diff --git a/drivers/memory/pl353-smc.c b/drivers/memory/pl353-smc.c index 9c0a28416777..b0b251bb207f 100644 --- a/drivers/memory/pl353-smc.c +++ b/drivers/memory/pl353-smc.c @@ -407,6 +407,7 @@ static int pl353_smc_probe(struct amba_device *adev, const struct amba_id *id) break; } if (!match) { + err = -ENODEV; dev_err(&adev->dev, "no matching children\n"); goto out_clk_disable; } diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c index 4d5758c419c5..ffec26a99313 100644 --- a/drivers/memory/stm32-fmc2-ebi.c +++ b/drivers/memory/stm32-fmc2-ebi.c @@ -1048,16 +1048,19 @@ static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi) if (ret) { dev_err(dev, "could not retrieve reg property: %d\n", ret); + of_node_put(child); return ret; } if (bank >= FMC2_MAX_BANKS) { dev_err(dev, "invalid reg value: %d\n", bank); + of_node_put(child); return -EINVAL; } if (ebi->bank_assigned & BIT(bank)) { dev_err(dev, "bank already assigned: %d\n", bank); + of_node_put(child); return -EINVAL; } @@ -1066,6 +1069,7 @@ static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2_ebi *ebi) if (ret) { dev_err(dev, "setup chip select %d failed: %d\n", bank, ret); + of_node_put(child); return ret; } } diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c index 76ace42a688a..dae816e840a9 100644 --- a/drivers/memory/tegra/tegra124-emc.c +++ b/drivers/memory/tegra/tegra124-emc.c @@ -265,8 +265,8 @@ #define EMC_PUTERM_ADJ 0x574 #define DRAM_DEV_SEL_ALL 0 -#define DRAM_DEV_SEL_0 (2 << 30) -#define DRAM_DEV_SEL_1 (1 << 30) +#define DRAM_DEV_SEL_0 BIT(31) +#define DRAM_DEV_SEL_1 BIT(30) #define EMC_CFG_POWER_FEATURES_MASK \ (EMC_CFG_DYN_SREF | EMC_CFG_DRAM_ACPD | EMC_CFG_DRAM_CLKSTOP_SR | \ diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index 055af0e08a2e..1bd6d3d827aa 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -145,8 +145,8 @@ #define EMC_SELF_REF_CMD_ENABLED BIT(0) #define DRAM_DEV_SEL_ALL (0 << 30) -#define DRAM_DEV_SEL_0 (2 << 30) -#define DRAM_DEV_SEL_1 (1 << 30) +#define DRAM_DEV_SEL_0 BIT(31) +#define DRAM_DEV_SEL_1 BIT(30) #define DRAM_BROADCAST(num) \ ((num) > 1 ? DRAM_DEV_SEL_ALL : DRAM_DEV_SEL_0) diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c index 102dbb8080da..29271ad4728a 100644 --- a/drivers/memstick/host/rtsx_usb_ms.c +++ b/drivers/memstick/host/rtsx_usb_ms.c @@ -799,9 +799,9 @@ static int rtsx_usb_ms_drv_probe(struct platform_device *pdev) return 0; err_out: - memstick_free_host(msh); pm_runtime_disable(ms_dev(host)); pm_runtime_put_noidle(ms_dev(host)); + memstick_free_host(msh); return err; } @@ -828,9 +828,6 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev) } mutex_unlock(&host->host_mutex); - memstick_remove_host(msh); - memstick_free_host(msh); - /* Balance possible unbalanced usage count * e.g. unconditional module removal */ @@ -838,10 +835,11 @@ static int rtsx_usb_ms_drv_remove(struct platform_device *pdev) pm_runtime_put(ms_dev(host)); pm_runtime_disable(ms_dev(host)); - platform_set_drvdata(pdev, NULL); - + memstick_remove_host(msh); dev_dbg(ms_dev(host), ": Realtek USB Memstick controller has been removed\n"); + memstick_free_host(msh); + platform_set_drvdata(pdev, NULL); return 0; } diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index a51e96454c16..3773964def9e 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -465,6 +465,7 @@ config MFD_MP2629 tristate "Monolithic Power Systems MP2629 ADC and Battery charger" depends on I2C select REGMAP_I2C + select MFD_CORE help Select this option to enable support for Monolithic Power Systems battery charger. This provides ADC, thermal and battery charger power diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index 47556d2d9abe..8ebfc7bbe4e0 100644 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c @@ -113,6 +113,7 @@ static const struct i2c_device_id da9052_i2c_id[] = { {"da9053-bc", DA9053_BC}, {} }; +MODULE_DEVICE_TABLE(i2c, da9052_i2c_id); #ifdef CONFIG_OF static const struct of_device_id dialog_dt_ids[] = { diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c index 30d82bfe5b02..6fb206da2729 100644 --- a/drivers/mfd/motorola-cpcap.c +++ b/drivers/mfd/motorola-cpcap.c @@ -327,6 +327,10 @@ static int cpcap_probe(struct spi_device *spi) if (ret) return ret; + /* Parent SPI controller uses DMA, CPCAP and child devices do not */ + spi->dev.coherent_dma_mask = 0; + spi->dev.dma_mask = &spi->dev.coherent_dma_mask; + return devm_mfd_add_devices(&spi->dev, 0, cpcap_mfd_devices, ARRAY_SIZE(cpcap_mfd_devices), NULL, 0, NULL); } diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c index dc452df1f1bf..652a5e60067f 100644 --- a/drivers/mfd/rn5t618.c +++ b/drivers/mfd/rn5t618.c @@ -104,7 +104,7 @@ static int rn5t618_irq_init(struct rn5t618 *rn5t618) ret = devm_regmap_add_irq_chip(rn5t618->dev, rn5t618->regmap, rn5t618->irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, 0, irq_chip, &rn5t618->irq_data); if (ret) dev_err(rn5t618->dev, "Failed to register IRQ chip\n"); diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 61aa020199f5..cd2f45257dc1 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -109,7 +109,7 @@ static const struct i2c_device_id stmpe_i2c_id[] = { { "stmpe2403", STMPE2403 }, { } }; -MODULE_DEVICE_TABLE(i2c, stmpe_id); +MODULE_DEVICE_TABLE(i2c, stmpe_i2c_id); static struct i2c_driver stmpe_i2c_driver = { .driver = { diff --git a/drivers/misc/cardreader/alcor_pci.c b/drivers/misc/cardreader/alcor_pci.c index cd402c89189e..de6d44a158bb 100644 --- a/drivers/misc/cardreader/alcor_pci.c +++ b/drivers/misc/cardreader/alcor_pci.c @@ -139,7 +139,13 @@ static void alcor_pci_init_check_aspm(struct alcor_pci_priv *priv) u32 val32; priv->pdev_cap_off = alcor_pci_find_cap_offset(priv, priv->pdev); - priv->parent_cap_off = alcor_pci_find_cap_offset(priv, + /* + * A device might be attached to root complex directly and + * priv->parent_pdev will be NULL. In this case we don't check its + * capability and disable ASPM completely. + */ + if (priv->parent_pdev) + priv->parent_cap_off = alcor_pci_find_cap_offset(priv, priv->parent_pdev); if ((priv->pdev_cap_off == 0) || (priv->parent_cap_off == 0)) { diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 7a6f01ace78a..305ffad131a2 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -714,23 +714,20 @@ static int at24_probe(struct i2c_client *client) } /* - * If the 'label' property is not present for the AT24 EEPROM, - * then nvmem_config.id is initialised to NVMEM_DEVID_AUTO, - * and this will append the 'devid' to the name of the NVMEM - * device. This is purely legacy and the AT24 driver has always - * defaulted to this. However, if the 'label' property is - * present then this means that the name is specified by the - * firmware and this name should be used verbatim and so it is - * not necessary to append the 'devid'. + * We initialize nvmem_config.id to NVMEM_DEVID_AUTO even if the + * label property is set as some platform can have multiple eeproms + * with same label and we can not register each of those with same + * label. Failing to register those eeproms trigger cascade failure + * on such platform. */ + nvmem_config.id = NVMEM_DEVID_AUTO; + if (device_property_present(dev, "label")) { - nvmem_config.id = NVMEM_DEVID_NONE; err = device_property_read_string(dev, "label", &nvmem_config.name); if (err) return err; } else { - nvmem_config.id = NVMEM_DEVID_AUTO; nvmem_config.name = dev_name(dev); } diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c index 81c70e5bc168..3e4a594c110b 100644 --- a/drivers/misc/eeprom/idt_89hpesx.c +++ b/drivers/misc/eeprom/idt_89hpesx.c @@ -1126,11 +1126,10 @@ static void idt_get_fw_data(struct idt_89hpesx_dev *pdev) device_for_each_child_node(dev, fwnode) { ee_id = idt_ee_match_id(fwnode); - if (!ee_id) { - dev_warn(dev, "Skip unsupported EEPROM device"); - continue; - } else + if (ee_id) break; + + dev_warn(dev, "Skip unsupported EEPROM device %pfw\n", fwnode); } /* If there is no fwnode EEPROM device, then set zero size */ @@ -1161,6 +1160,7 @@ static void idt_get_fw_data(struct idt_89hpesx_dev *pdev) else /* if (!fwnode_property_read_bool(node, "read-only")) */ pdev->eero = false; + fwnode_handle_put(fwnode); dev_info(dev, "EEPROM of %d bytes found by 0x%x", pdev->eesize, pdev->eeaddr); } diff --git a/drivers/misc/habanalabs/common/habanalabs_drv.c b/drivers/misc/habanalabs/common/habanalabs_drv.c index 3bcef64a677a..ded92b3cbdb2 100644 --- a/drivers/misc/habanalabs/common/habanalabs_drv.c +++ b/drivers/misc/habanalabs/common/habanalabs_drv.c @@ -421,6 +421,7 @@ static int hl_pci_probe(struct pci_dev *pdev, return 0; disable_device: + pci_disable_pcie_error_reporting(pdev); pci_set_drvdata(pdev, NULL); destroy_hdev(hdev); diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c index 68f661aca3ff..37edd663603f 100644 --- a/drivers/misc/habanalabs/gaudi/gaudi.c +++ b/drivers/misc/habanalabs/gaudi/gaudi.c @@ -2164,7 +2164,7 @@ static void gaudi_init_mme_qman(struct hl_device *hdev, u32 mme_offset, /* Configure RAZWI IRQ */ mme_id = mme_offset / - (mmMME1_QM_GLBL_CFG0 - mmMME0_QM_GLBL_CFG0); + (mmMME1_QM_GLBL_CFG0 - mmMME0_QM_GLBL_CFG0) / 2; mme_qm_err_cfg = MME_QMAN_GLBL_ERR_CFG_MSG_EN_MASK; if (hdev->stop_on_err) { @@ -3708,6 +3708,7 @@ static int gaudi_pin_memory_before_cs(struct hl_device *hdev, return 0; unpin_memory: + list_del(&userptr->job_node); hl_unpin_host_memory(hdev, userptr); free_userptr: kfree(userptr); diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c index 986ed3c07208..5b5d6275c249 100644 --- a/drivers/misc/habanalabs/goya/goya.c +++ b/drivers/misc/habanalabs/goya/goya.c @@ -3190,6 +3190,7 @@ static int goya_pin_memory_before_cs(struct hl_device *hdev, return 0; unpin_memory: + list_del(&userptr->job_node); hl_unpin_host_memory(hdev, userptr); free_userptr: kfree(userptr); diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index 4edad6c445d3..dc8a06c06c63 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c @@ -111,7 +111,7 @@ static int ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) result = ibmasm_init_remote_input_dev(sp); if (result) { dev_err(sp->dev, "Failed to initialize remote queue\n"); - goto error_send_message; + goto error_init_remote; } result = ibmasm_send_driver_vpd(sp); @@ -131,8 +131,9 @@ static int ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return 0; error_send_message: - disable_sp_interrupts(sp->base_address); ibmasm_free_remote_input_dev(sp); +error_init_remote: + disable_sp_interrupts(sp->base_address); free_irq(sp->irq, (void *)sp); error_request_irq: iounmap(sp->base_address); diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c index a0675d4154d2..a337f97b30e2 100644 --- a/drivers/misc/lkdtm/bugs.c +++ b/drivers/misc/lkdtm/bugs.c @@ -144,6 +144,9 @@ void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void) if (*p == 0) val = 0x87654321; *p = val; + + if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) + pr_err("XFAIL: arch has CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS\n"); } void lkdtm_SOFTLOCKUP(void) diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index 97803f213d9d..c802db9aaeb0 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -173,9 +173,7 @@ static const struct crashtype crashtypes[] = { CRASHTYPE(USERCOPY_KERNEL), CRASHTYPE(STACKLEAK_ERASING), CRASHTYPE(CFI_FORWARD_PROTO), -#ifdef CONFIG_X86_32 CRASHTYPE(DOUBLE_FAULT), -#endif }; diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index fd092f2c85ae..e46ac5cb2165 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -1011,6 +1011,12 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) switch (mq_rq->drv_op) { case MMC_DRV_OP_IOCTL: + if (card->ext_csd.cmdq_en) { + ret = mmc_cmdq_disable(card); + if (ret) + break; + } + fallthrough; case MMC_DRV_OP_IOCTL_RPMB: idata = mq_rq->drv_op_data; for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { @@ -1021,6 +1027,8 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req) /* Always switch back to main area after RPMB access */ if (rpmb_ioctl) mmc_blk_part_switch(card, 0); + else if (card->reenable_cmdq && !card->ext_csd.cmdq_en) + mmc_cmdq_enable(card); break; case MMC_DRV_OP_BOOT_WP: ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 99fd9c17f9cc..f086ce1ac9bf 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -937,11 +937,14 @@ int mmc_execute_tuning(struct mmc_card *card) err = host->ops->execute_tuning(host, opcode); - if (err) + if (err) { pr_err("%s: tuning execution failed: %d\n", mmc_hostname(host), err); - else + } else { + host->retune_now = 0; + host->need_retune = 0; mmc_retune_enable(host); + } return err; } diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 3f4f06d33385..6a6e050133a5 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -75,7 +75,8 @@ static void mmc_host_classdev_release(struct device *dev) { struct mmc_host *host = cls_dev_to_mmc_host(dev); wakeup_source_unregister(host->ws); - ida_simple_remove(&mmc_host_ida, host->index); + if (of_alias_get_id(host->parent->of_node, "mmc") < 0) + ida_simple_remove(&mmc_host_ida, host->index); kfree(host); } @@ -437,7 +438,7 @@ static int mmc_first_nonreserved_index(void) */ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) { - int err; + int index; struct mmc_host *host; int alias_id, min_idx, max_idx; @@ -450,20 +451,19 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) alias_id = of_alias_get_id(dev->of_node, "mmc"); if (alias_id >= 0) { - min_idx = alias_id; - max_idx = alias_id + 1; + index = alias_id; } else { min_idx = mmc_first_nonreserved_index(); max_idx = 0; - } - err = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL); - if (err < 0) { - kfree(host); - return NULL; + index = ida_simple_get(&mmc_host_ida, min_idx, max_idx, GFP_KERNEL); + if (index < 0) { + kfree(host); + return NULL; + } } - host->index = err; + host->index = index; dev_set_name(&host->class_dev, "mmc%d", host->index); host->ws = wakeup_source_register(NULL, dev_name(&host->class_dev)); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index da5cf1b5d681..2819e6b42a67 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -851,11 +851,13 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr) return err; /* - * In case CCS and S18A in the response is set, start Signal Voltage - * Switch procedure. SPI mode doesn't support CMD11. + * In case the S18A bit is set in the response, let's start the signal + * voltage switch procedure. SPI mode doesn't support CMD11. + * Note that, according to the spec, the S18A bit is not valid unless + * the CCS bit is set as well. We deliberately deviate from the spec in + * regards to this, which allows UHS-I to be supported for SDSC cards. */ - if (!mmc_host_is_spi(host) && rocr && - ((*rocr & 0x41000000) == 0x41000000)) { + if (!mmc_host_is_spi(host) && rocr && (*rocr & 0x01000000)) { err = mmc_set_uhs_voltage(host, pocr); if (err == -EAGAIN) { retries--; diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 43c5795691fb..8b5d542e20f3 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2018,8 +2018,8 @@ static void dw_mci_tasklet_func(unsigned long priv) continue; } - dw_mci_stop_dma(host); send_stop_abort(host, data); + dw_mci_stop_dma(host); state = STATE_SENDING_STOP; break; } @@ -2043,10 +2043,10 @@ static void dw_mci_tasklet_func(unsigned long priv) */ if (test_and_clear_bit(EVENT_DATA_ERROR, &host->pending_events)) { - dw_mci_stop_dma(host); if (!(host->data_status & (SDMMC_INT_DRTO | SDMMC_INT_EBE))) send_stop_abort(host, data); + dw_mci_stop_dma(host); state = STATE_DATA_ERROR; break; } @@ -2079,10 +2079,10 @@ static void dw_mci_tasklet_func(unsigned long priv) */ if (test_and_clear_bit(EVENT_DATA_ERROR, &host->pending_events)) { - dw_mci_stop_dma(host); if (!(host->data_status & (SDMMC_INT_DRTO | SDMMC_INT_EBE))) send_stop_abort(host, data); + dw_mci_stop_dma(host); state = STATE_DATA_ERROR; break; } diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 4ec41579940a..d3f40c9a8c6c 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -165,6 +165,7 @@ struct meson_host { unsigned int bounce_buf_size; void *bounce_buf; + void __iomem *bounce_iomem_buf; dma_addr_t bounce_dma_addr; struct sd_emmc_desc *descs; dma_addr_t descs_dma_addr; @@ -734,6 +735,47 @@ static void meson_mmc_desc_chain_transfer(struct mmc_host *mmc, u32 cmd_cfg) writel(start, host->regs + SD_EMMC_START); } +/* local sg copy to buffer version with _to/fromio usage for dram_access_quirk */ +static void meson_mmc_copy_buffer(struct meson_host *host, struct mmc_data *data, + size_t buflen, bool to_buffer) +{ + unsigned int sg_flags = SG_MITER_ATOMIC; + struct scatterlist *sgl = data->sg; + unsigned int nents = data->sg_len; + struct sg_mapping_iter miter; + unsigned int offset = 0; + + if (to_buffer) + sg_flags |= SG_MITER_FROM_SG; + else + sg_flags |= SG_MITER_TO_SG; + + sg_miter_start(&miter, sgl, nents, sg_flags); + + while ((offset < buflen) && sg_miter_next(&miter)) { + unsigned int len; + + len = min(miter.length, buflen - offset); + + /* When dram_access_quirk, the bounce buffer is a iomem mapping */ + if (host->dram_access_quirk) { + if (to_buffer) + memcpy_toio(host->bounce_iomem_buf + offset, miter.addr, len); + else + memcpy_fromio(miter.addr, host->bounce_iomem_buf + offset, len); + } else { + if (to_buffer) + memcpy(host->bounce_buf + offset, miter.addr, len); + else + memcpy(miter.addr, host->bounce_buf + offset, len); + } + + offset += len; + } + + sg_miter_stop(&miter); +} + static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) { struct meson_host *host = mmc_priv(mmc); @@ -777,8 +819,7 @@ static void meson_mmc_start_cmd(struct mmc_host *mmc, struct mmc_command *cmd) if (data->flags & MMC_DATA_WRITE) { cmd_cfg |= CMD_CFG_DATA_WR; WARN_ON(xfer_bytes > host->bounce_buf_size); - sg_copy_to_buffer(data->sg, data->sg_len, - host->bounce_buf, xfer_bytes); + meson_mmc_copy_buffer(host, data, xfer_bytes, true); dma_wmb(); } @@ -947,8 +988,7 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) if (meson_mmc_bounce_buf_read(data)) { xfer_bytes = data->blksz * data->blocks; WARN_ON(xfer_bytes > host->bounce_buf_size); - sg_copy_from_buffer(data->sg, data->sg_len, - host->bounce_buf, xfer_bytes); + meson_mmc_copy_buffer(host, data, xfer_bytes, false); } next_cmd = meson_mmc_get_next_command(cmd); @@ -1168,7 +1208,7 @@ static int meson_mmc_probe(struct platform_device *pdev) * instead of the DDR memory */ host->bounce_buf_size = SD_EMMC_SRAM_DATA_BUF_LEN; - host->bounce_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF; + host->bounce_iomem_buf = host->regs + SD_EMMC_SRAM_DATA_BUF_OFF; host->bounce_dma_addr = res->start + SD_EMMC_SRAM_DATA_BUF_OFF; } else { /* data bounce buffer */ diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c index 51db30acf4dc..fdaa11f92fe6 100644 --- a/drivers/mmc/host/mmci_stm32_sdmmc.c +++ b/drivers/mmc/host/mmci_stm32_sdmmc.c @@ -479,8 +479,9 @@ static int sdmmc_post_sig_volt_switch(struct mmci_host *host, u32 status; int ret = 0; - if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) { - spin_lock_irqsave(&host->lock, flags); + spin_lock_irqsave(&host->lock, flags); + if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180 && + host->pwr_reg & MCI_STM32_VSWITCHEN) { mmci_write_pwrreg(host, host->pwr_reg | MCI_STM32_VSWITCH); spin_unlock_irqrestore(&host->lock, flags); @@ -492,9 +493,11 @@ static int sdmmc_post_sig_volt_switch(struct mmci_host *host, writel_relaxed(MCI_STM32_VSWENDC | MCI_STM32_CKSTOPC, host->base + MMCICLEAR); + spin_lock_irqsave(&host->lock, flags); mmci_write_pwrreg(host, host->pwr_reg & ~(MCI_STM32_VSWITCHEN | MCI_STM32_VSWITCH)); } + spin_unlock_irqrestore(&host->lock, flags); return ret; } diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index acb9c81a4e45..addaaf2810e2 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -660,14 +660,19 @@ static int renesas_sdhi_execute_tuning(struct mmc_host *mmc, u32 opcode) /* Issue CMD19 twice for each tap */ for (i = 0; i < 2 * priv->tap_num; i++) { + int cmd_error; + /* Set sampling clock position */ sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TAPSET, i % priv->tap_num); - if (mmc_send_tuning(mmc, opcode, NULL) == 0) + if (mmc_send_tuning(mmc, opcode, &cmd_error) == 0) set_bit(i, priv->taps); if (sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_SMPCMP) == 0) set_bit(i, priv->smpcmp); + + if (cmd_error) + mmc_abort_tuning(mmc, opcode); } ret = renesas_sdhi_select_tuning(host); @@ -897,7 +902,7 @@ static const struct soc_device_attribute sdhi_quirks_match[] = { { .soc_id = "r8a7795", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps2367 }, { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 }, - { .soc_id = "r8a7796", .revision = "ES3.*", .data = &sdhi_quirks_bad_taps1357 }, + { .soc_id = "r8a77961", .data = &sdhi_quirks_bad_taps1357 }, { .soc_id = "r8a77965", .data = &sdhi_quirks_r8a77965 }, { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 }, { .soc_id = "r8a77990", .data = &sdhi_quirks_r8a77990 }, diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c index 54205e3be9e8..a2cdb37fcbbe 100644 --- a/drivers/mmc/host/sdhci-acpi.c +++ b/drivers/mmc/host/sdhci-acpi.c @@ -788,6 +788,17 @@ static const struct dmi_system_id sdhci_acpi_quirks[] = { }, .driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT, }, + { + /* + * The Toshiba WT8-B's microSD slot always reports the card being + * write-protected. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "TOSHIBA ENCORE 2 WT8-B"), + }, + .driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT, + }, {} /* Terminating entry */ }; diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c index ddeaf8e1f72f..b9eb2ec61a83 100644 --- a/drivers/mmc/host/sdhci-iproc.c +++ b/drivers/mmc/host/sdhci-iproc.c @@ -173,6 +173,23 @@ static unsigned int sdhci_iproc_get_max_clock(struct sdhci_host *host) return pltfm_host->clock; } +/* + * There is a known bug on BCM2711's SDHCI core integration where the + * controller will hang when the difference between the core clock and the bus + * clock is too great. Specifically this can be reproduced under the following + * conditions: + * + * - No SD card plugged in, polling thread is running, probing cards at + * 100 kHz. + * - BCM2711's core clock configured at 500MHz or more + * + * So we set 200kHz as the minimum clock frequency available for that SoC. + */ +static unsigned int sdhci_iproc_bcm2711_get_min_clock(struct sdhci_host *host) +{ + return 200000; +} + static const struct sdhci_ops sdhci_iproc_ops = { .set_clock = sdhci_set_clock, .get_max_clock = sdhci_iproc_get_max_clock, @@ -271,6 +288,7 @@ static const struct sdhci_ops sdhci_iproc_bcm2711_ops = { .set_clock = sdhci_set_clock, .set_power = sdhci_set_power_and_bus_voltage, .get_max_clock = sdhci_iproc_get_max_clock, + .get_min_clock = sdhci_iproc_bcm2711_get_min_clock, .set_bus_width = sdhci_set_bus_width, .reset = sdhci_reset, .set_uhs_signaling = sdhci_set_uhs_signaling, diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 485e1bcb1305..bef081d35305 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -2087,6 +2087,23 @@ static void sdhci_msm_cqe_disable(struct mmc_host *mmc, bool recovery) sdhci_cqe_disable(mmc, recovery); } +static void sdhci_msm_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) +{ + u32 count, start = 15; + + __sdhci_set_timeout(host, cmd); + count = sdhci_readb(host, SDHCI_TIMEOUT_CONTROL); + /* + * Update software timeout value if its value is less than hardware data + * timeout value. Qcom SoC hardware data timeout value was calculated + * using 4 * MCLK * 2^(count + 13). where MCLK = 1 / host->clock. + */ + if (cmd && cmd->data && host->clock > 400000 && + host->clock <= 50000000 && + ((1 << (count + start)) > (10 * host->clock))) + host->data_timeout = 22LL * NSEC_PER_SEC; +} + static const struct cqhci_host_ops sdhci_msm_cqhci_ops = { .enable = sdhci_msm_cqe_enable, .disable = sdhci_msm_cqe_disable, @@ -2444,6 +2461,7 @@ static const struct sdhci_ops sdhci_msm_ops = { .irq = sdhci_msm_cqe_irq, .dump_vendor_regs = sdhci_msm_dump_vendor_regs, .set_power = sdhci_set_power_noreg, + .set_timeout = sdhci_msm_set_timeout, }; static const struct sdhci_pltfm_data sdhci_msm_pdata = { diff --git a/drivers/mmc/host/sdhci-sprd.c b/drivers/mmc/host/sdhci-sprd.c index 19cbb6171b35..9cd8862e6cbd 100644 --- a/drivers/mmc/host/sdhci-sprd.c +++ b/drivers/mmc/host/sdhci-sprd.c @@ -393,6 +393,7 @@ static void sdhci_sprd_request_done(struct sdhci_host *host, static struct sdhci_ops sdhci_sprd_ops = { .read_l = sdhci_sprd_readl, .write_l = sdhci_sprd_writel, + .write_w = sdhci_sprd_writew, .write_b = sdhci_sprd_writeb, .set_clock = sdhci_sprd_set_clock, .get_max_clock = sdhci_sprd_get_max_clock, diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 3a89cfcb1827..29ab0352d0fb 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -1815,6 +1814,10 @@ static u16 sdhci_get_preset_value(struct sdhci_host *host) u16 preset = 0; switch (host->timing) { + case MMC_TIMING_MMC_HS: + case MMC_TIMING_SD_HS: + preset = sdhci_readw(host, SDHCI_PRESET_FOR_HIGH_SPEED); + break; case MMC_TIMING_UHS_SDR12: preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12); break; @@ -4591,12 +4594,8 @@ int sdhci_setup_host(struct sdhci_host *host) mmc->max_segs = SDHCI_MAX_SEGS; } else if (host->flags & SDHCI_USE_SDMA) { mmc->max_segs = 1; - if (swiotlb_max_segment()) { - unsigned int max_req_size = (1 << IO_TLB_SHIFT) * - IO_TLB_SEGSIZE; - mmc->max_req_size = min(mmc->max_req_size, - max_req_size); - } + mmc->max_req_size = min_t(size_t, mmc->max_req_size, + dma_max_mapping_size(mmc_dev(mmc))); } else { /* PIO */ mmc->max_segs = SDHCI_MAX_SEGS; } diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 63f51491fffe..15ecf856a7c7 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -254,6 +254,7 @@ /* 60-FB reserved */ +#define SDHCI_PRESET_FOR_HIGH_SPEED 0x64 #define SDHCI_PRESET_FOR_SDR12 0x66 #define SDHCI_PRESET_FOR_SDR25 0x68 #define SDHCI_PRESET_FOR_SDR50 0x6A diff --git a/drivers/mmc/host/usdhi6rol0.c b/drivers/mmc/host/usdhi6rol0.c index 615f3d008af1..b9b79b1089a0 100644 --- a/drivers/mmc/host/usdhi6rol0.c +++ b/drivers/mmc/host/usdhi6rol0.c @@ -1801,6 +1801,7 @@ static int usdhi6_probe(struct platform_device *pdev) version = usdhi6_read(host, USDHI6_VERSION); if ((version & 0xfff) != 0xa0d) { + ret = -EPERM; dev_err(dev, "Version not recognized %x\n", version); goto e_clk_off; } diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c index 9b755ea0fa03..f07c71db3caf 100644 --- a/drivers/mmc/host/via-sdmmc.c +++ b/drivers/mmc/host/via-sdmmc.c @@ -857,6 +857,9 @@ static void via_sdc_data_isr(struct via_crdr_mmc_host *host, u16 intmask) { BUG_ON(intmask == 0); + if (!host->data) + return; + if (intmask & VIA_CRDR_SDSTS_DT) host->data->error = -ETIMEDOUT; else if (intmask & (VIA_CRDR_SDSTS_RC | VIA_CRDR_SDSTS_WC)) diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index 739cf63ef6e2..4950d10d3a19 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c @@ -2279,7 +2279,7 @@ static int vub300_probe(struct usb_interface *interface, if (retval < 0) goto error5; retval = - usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), + usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), SET_ROM_WAIT_STATES, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, firmware_rom_wait_states, 0x0000, NULL, 0, HZ); diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index a1f3e1031c3d..96a27e06401f 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -119,7 +119,7 @@ static int cfi_use_status_reg(struct cfi_private *cfi) struct cfi_pri_amdstd *extp = cfi->cmdset_priv; u8 poll_mask = CFI_POLL_STATUS_REG | CFI_POLL_DQ; - return extp->MinorVersion >= '5' && + return extp && extp->MinorVersion >= '5' && (extp->SoftwareFeatures & poll_mask) == CFI_POLL_STATUS_REG; } diff --git a/drivers/mtd/nand/raw/arasan-nand-controller.c b/drivers/mtd/nand/raw/arasan-nand-controller.c index fbb4ea751be8..0ee3192916d9 100644 --- a/drivers/mtd/nand/raw/arasan-nand-controller.c +++ b/drivers/mtd/nand/raw/arasan-nand-controller.c @@ -272,6 +272,37 @@ static int anfc_pkt_len_config(unsigned int len, unsigned int *steps, return 0; } +static int anfc_select_target(struct nand_chip *chip, int target) +{ + struct anand *anand = to_anand(chip); + struct arasan_nfc *nfc = to_anfc(chip->controller); + int ret; + + /* Update the controller timings and the potential ECC configuration */ + writel_relaxed(anand->timings, nfc->base + DATA_INTERFACE_REG); + + /* Update clock frequency */ + if (nfc->cur_clk != anand->clk) { + clk_disable_unprepare(nfc->controller_clk); + ret = clk_set_rate(nfc->controller_clk, anand->clk); + if (ret) { + dev_err(nfc->dev, "Failed to change clock rate\n"); + return ret; + } + + ret = clk_prepare_enable(nfc->controller_clk); + if (ret) { + dev_err(nfc->dev, + "Failed to re-enable the controller clock\n"); + return ret; + } + + nfc->cur_clk = anand->clk; + } + + return 0; +} + /* * When using the embedded hardware ECC engine, the controller is in charge of * feeding the engine with, first, the ECC residue present in the data array. @@ -400,6 +431,18 @@ static int anfc_read_page_hw_ecc(struct nand_chip *chip, u8 *buf, return 0; } +static int anfc_sel_read_page_hw_ecc(struct nand_chip *chip, u8 *buf, + int oob_required, int page) +{ + int ret; + + ret = anfc_select_target(chip, chip->cur_cs); + if (ret) + return ret; + + return anfc_read_page_hw_ecc(chip, buf, oob_required, page); +}; + static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, int oob_required, int page) { @@ -460,6 +503,18 @@ static int anfc_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, return ret; } +static int anfc_sel_write_page_hw_ecc(struct nand_chip *chip, const u8 *buf, + int oob_required, int page) +{ + int ret; + + ret = anfc_select_target(chip, chip->cur_cs); + if (ret) + return ret; + + return anfc_write_page_hw_ecc(chip, buf, oob_required, page); +}; + /* NAND framework ->exec_op() hooks and related helpers */ static int anfc_parse_instructions(struct nand_chip *chip, const struct nand_subop *subop, @@ -752,37 +807,6 @@ static const struct nand_op_parser anfc_op_parser = NAND_OP_PARSER( NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)), ); -static int anfc_select_target(struct nand_chip *chip, int target) -{ - struct anand *anand = to_anand(chip); - struct arasan_nfc *nfc = to_anfc(chip->controller); - int ret; - - /* Update the controller timings and the potential ECC configuration */ - writel_relaxed(anand->timings, nfc->base + DATA_INTERFACE_REG); - - /* Update clock frequency */ - if (nfc->cur_clk != anand->clk) { - clk_disable_unprepare(nfc->controller_clk); - ret = clk_set_rate(nfc->controller_clk, anand->clk); - if (ret) { - dev_err(nfc->dev, "Failed to change clock rate\n"); - return ret; - } - - ret = clk_prepare_enable(nfc->controller_clk); - if (ret) { - dev_err(nfc->dev, - "Failed to re-enable the controller clock\n"); - return ret; - } - - nfc->cur_clk = anand->clk; - } - - return 0; -} - static int anfc_check_op(struct nand_chip *chip, const struct nand_operation *op) { @@ -1006,8 +1030,8 @@ static int anfc_init_hw_ecc_controller(struct arasan_nfc *nfc, if (!anand->bch) return -EINVAL; - ecc->read_page = anfc_read_page_hw_ecc; - ecc->write_page = anfc_write_page_hw_ecc; + ecc->read_page = anfc_sel_read_page_hw_ecc; + ecc->write_page = anfc_sel_write_page_hw_ecc; return 0; } diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index f5ca2002d08e..d00c916f133b 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -3036,8 +3036,10 @@ static int __maybe_unused marvell_nfc_resume(struct device *dev) return ret; ret = clk_prepare_enable(nfc->reg_clk); - if (ret < 0) + if (ret < 0) { + clk_disable_unprepare(nfc->core_clk); return ret; + } /* * Reset nfc->selected_chip so the next command will cause the timing diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 558d8a14810b..8794a1f6eacd 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -419,7 +419,7 @@ static int spinand_check_ecc_status(struct spinand_device *spinand, u8 status) * fixed, so let's return the maximum possible value so that * wear-leveling layers move the data immediately. */ - return nanddev_get_ecc_conf(nand)->strength; + return nanddev_get_ecc_requirements(nand)->strength; case STATUS_ECC_UNCOR_ERROR: return -EBADMSG; @@ -1090,8 +1090,8 @@ static int spinand_init(struct spinand_device *spinand) mtd->oobavail = ret; /* Propagate ECC information to mtd_info */ - mtd->ecc_strength = nanddev_get_ecc_conf(nand)->strength; - mtd->ecc_step_size = nanddev_get_ecc_conf(nand)->step_size; + mtd->ecc_strength = nanddev_get_ecc_requirements(nand)->strength; + mtd->ecc_step_size = nanddev_get_ecc_requirements(nand)->step_size; return 0; diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c index 8e801e4c3a00..cd7a9cacc3fb 100644 --- a/drivers/mtd/nand/spi/macronix.c +++ b/drivers/mtd/nand/spi/macronix.c @@ -84,11 +84,11 @@ static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand, * data around if it's not necessary. */ if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr)) - return nanddev_get_ecc_conf(nand)->strength; + return nanddev_get_ecc_requirements(nand)->strength; - if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength || + if (WARN_ON(eccsr > nanddev_get_ecc_requirements(nand)->strength || !eccsr)) - return nanddev_get_ecc_conf(nand)->strength; + return nanddev_get_ecc_requirements(nand)->strength; return eccsr; diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c index 21fde2875674..6fe7bd2a94d2 100644 --- a/drivers/mtd/nand/spi/toshiba.c +++ b/drivers/mtd/nand/spi/toshiba.c @@ -90,12 +90,12 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand, * data around if it's not necessary. */ if (spi_mem_exec_op(spinand->spimem, &op)) - return nanddev_get_ecc_conf(nand)->strength; + return nanddev_get_ecc_requirements(nand)->strength; mbf >>= 4; - if (WARN_ON(mbf > nanddev_get_ecc_conf(nand)->strength || !mbf)) - return nanddev_get_ecc_conf(nand)->strength; + if (WARN_ON(mbf > nanddev_get_ecc_requirements(nand)->strength || !mbf)) + return nanddev_get_ecc_requirements(nand)->strength; return mbf; diff --git a/drivers/mtd/parsers/redboot.c b/drivers/mtd/parsers/redboot.c index 91146bdc4713..3ccd6363ee8c 100644 --- a/drivers/mtd/parsers/redboot.c +++ b/drivers/mtd/parsers/redboot.c @@ -45,6 +45,7 @@ static inline int redboot_checksum(struct fis_image_desc *img) static void parse_redboot_of(struct mtd_info *master) { struct device_node *np; + struct device_node *npart; u32 dirblock; int ret; @@ -52,7 +53,11 @@ static void parse_redboot_of(struct mtd_info *master) if (!np) return; - ret = of_property_read_u32(np, "fis-index-block", &dirblock); + npart = of_get_child_by_name(np, "partitions"); + if (!npart) + return; + + ret = of_property_read_u32(npart, "fis-index-block", &dirblock); if (ret) return; diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index ba8e70a8e312..6b12ce822e51 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c @@ -327,6 +327,8 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) break; } + dev->base_addr = ioaddr; + /* Reserve any actual interrupt. */ if (dev->irq) { retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev); @@ -334,8 +336,6 @@ static int __init cops_probe1(struct net_device *dev, int ioaddr) goto err_out; } - dev->base_addr = ioaddr; - lp = netdev_priv(dev); spin_lock_init(&lp->lock); diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c index 59c1724bcd0e..39b128205f25 100644 --- a/drivers/net/bareudp.c +++ b/drivers/net/bareudp.c @@ -71,12 +71,18 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) family = AF_INET6; if (bareudp->ethertype == htons(ETH_P_IP)) { - struct iphdr *iphdr; + __u8 ipversion; - iphdr = (struct iphdr *)(skb->data + BAREUDP_BASE_HLEN); - if (iphdr->version == 4) { - proto = bareudp->ethertype; - } else if (bareudp->multi_proto_mode && (iphdr->version == 6)) { + if (skb_copy_bits(skb, BAREUDP_BASE_HLEN, &ipversion, + sizeof(ipversion))) { + bareudp->dev->stats.rx_dropped++; + goto drop; + } + ipversion >>= 4; + + if (ipversion == 4) { + proto = htons(ETH_P_IP); + } else if (ipversion == 6 && bareudp->multi_proto_mode) { proto = htons(ETH_P_IPV6); } else { bareudp->dev->stats.rx_dropped++; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 47afc5938c26..018af1e38eb9 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -385,24 +385,85 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev, static int bond_ipsec_add_sa(struct xfrm_state *xs) { struct net_device *bond_dev = xs->xso.dev; + struct bond_ipsec *ipsec; struct bonding *bond; struct slave *slave; + int err; if (!bond_dev) return -EINVAL; + rcu_read_lock(); bond = netdev_priv(bond_dev); slave = rcu_dereference(bond->curr_active_slave); - xs->xso.real_dev = slave->dev; - bond->xs = xs; + if (!slave) { + rcu_read_unlock(); + return -ENODEV; + } - if (!(slave->dev->xfrmdev_ops - && slave->dev->xfrmdev_ops->xdo_dev_state_add)) { + if (!slave->dev->xfrmdev_ops || + !slave->dev->xfrmdev_ops->xdo_dev_state_add || + netif_is_bond_master(slave->dev)) { slave_warn(bond_dev, slave->dev, "Slave does not support ipsec offload\n"); + rcu_read_unlock(); return -EINVAL; } - return slave->dev->xfrmdev_ops->xdo_dev_state_add(xs); + ipsec = kmalloc(sizeof(*ipsec), GFP_ATOMIC); + if (!ipsec) { + rcu_read_unlock(); + return -ENOMEM; + } + xs->xso.real_dev = slave->dev; + + err = slave->dev->xfrmdev_ops->xdo_dev_state_add(xs); + if (!err) { + ipsec->xs = xs; + INIT_LIST_HEAD(&ipsec->list); + spin_lock_bh(&bond->ipsec_lock); + list_add(&ipsec->list, &bond->ipsec_list); + spin_unlock_bh(&bond->ipsec_lock); + } else { + kfree(ipsec); + } + rcu_read_unlock(); + return err; +} + +static void bond_ipsec_add_sa_all(struct bonding *bond) +{ + struct net_device *bond_dev = bond->dev; + struct bond_ipsec *ipsec; + struct slave *slave; + + rcu_read_lock(); + slave = rcu_dereference(bond->curr_active_slave); + if (!slave) + goto out; + + if (!slave->dev->xfrmdev_ops || + !slave->dev->xfrmdev_ops->xdo_dev_state_add || + netif_is_bond_master(slave->dev)) { + spin_lock_bh(&bond->ipsec_lock); + if (!list_empty(&bond->ipsec_list)) + slave_warn(bond_dev, slave->dev, + "%s: no slave xdo_dev_state_add\n", + __func__); + spin_unlock_bh(&bond->ipsec_lock); + goto out; + } + + spin_lock_bh(&bond->ipsec_lock); + list_for_each_entry(ipsec, &bond->ipsec_list, list) { + ipsec->xs->xso.real_dev = slave->dev; + if (slave->dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs)) { + slave_warn(bond_dev, slave->dev, "%s: failed to add SA\n", __func__); + ipsec->xs->xso.real_dev = NULL; + } + } + spin_unlock_bh(&bond->ipsec_lock); +out: + rcu_read_unlock(); } /** @@ -412,27 +473,77 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs) static void bond_ipsec_del_sa(struct xfrm_state *xs) { struct net_device *bond_dev = xs->xso.dev; + struct bond_ipsec *ipsec; struct bonding *bond; struct slave *slave; if (!bond_dev) return; + rcu_read_lock(); bond = netdev_priv(bond_dev); slave = rcu_dereference(bond->curr_active_slave); if (!slave) - return; + goto out; - xs->xso.real_dev = slave->dev; + if (!xs->xso.real_dev) + goto out; - if (!(slave->dev->xfrmdev_ops - && slave->dev->xfrmdev_ops->xdo_dev_state_delete)) { + WARN_ON(xs->xso.real_dev != slave->dev); + + if (!slave->dev->xfrmdev_ops || + !slave->dev->xfrmdev_ops->xdo_dev_state_delete || + netif_is_bond_master(slave->dev)) { slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__); - return; + goto out; } slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs); +out: + spin_lock_bh(&bond->ipsec_lock); + list_for_each_entry(ipsec, &bond->ipsec_list, list) { + if (ipsec->xs == xs) { + list_del(&ipsec->list); + kfree(ipsec); + break; + } + } + spin_unlock_bh(&bond->ipsec_lock); + rcu_read_unlock(); +} + +static void bond_ipsec_del_sa_all(struct bonding *bond) +{ + struct net_device *bond_dev = bond->dev; + struct bond_ipsec *ipsec; + struct slave *slave; + + rcu_read_lock(); + slave = rcu_dereference(bond->curr_active_slave); + if (!slave) { + rcu_read_unlock(); + return; + } + + spin_lock_bh(&bond->ipsec_lock); + list_for_each_entry(ipsec, &bond->ipsec_list, list) { + if (!ipsec->xs->xso.real_dev) + continue; + + if (!slave->dev->xfrmdev_ops || + !slave->dev->xfrmdev_ops->xdo_dev_state_delete || + netif_is_bond_master(slave->dev)) { + slave_warn(bond_dev, slave->dev, + "%s: no slave xdo_dev_state_delete\n", + __func__); + } else { + slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs); + } + ipsec->xs->xso.real_dev = NULL; + } + spin_unlock_bh(&bond->ipsec_lock); + rcu_read_unlock(); } /** @@ -443,21 +554,37 @@ static void bond_ipsec_del_sa(struct xfrm_state *xs) static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs) { struct net_device *bond_dev = xs->xso.dev; - struct bonding *bond = netdev_priv(bond_dev); - struct slave *curr_active = rcu_dereference(bond->curr_active_slave); - struct net_device *slave_dev = curr_active->dev; + struct net_device *real_dev; + struct slave *curr_active; + struct bonding *bond; + int err; - if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) - return true; + bond = netdev_priv(bond_dev); + rcu_read_lock(); + curr_active = rcu_dereference(bond->curr_active_slave); + real_dev = curr_active->dev; - if (!(slave_dev->xfrmdev_ops - && slave_dev->xfrmdev_ops->xdo_dev_offload_ok)) { - slave_warn(bond_dev, slave_dev, "%s: no slave xdo_dev_offload_ok\n", __func__); - return false; + if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) { + err = false; + goto out; + } + + if (!xs->xso.real_dev) { + err = false; + goto out; } - xs->xso.real_dev = slave_dev; - return slave_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs); + if (!real_dev->xfrmdev_ops || + !real_dev->xfrmdev_ops->xdo_dev_offload_ok || + netif_is_bond_master(real_dev)) { + err = false; + goto out; + } + + err = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs); +out: + rcu_read_unlock(); + return err; } static const struct xfrmdev_ops bond_xfrmdev_ops = { @@ -974,8 +1101,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) return; #ifdef CONFIG_XFRM_OFFLOAD - if (old_active && bond->xs) - bond_ipsec_del_sa(bond->xs); + bond_ipsec_del_sa_all(bond); #endif /* CONFIG_XFRM_OFFLOAD */ if (new_active) { @@ -1051,10 +1177,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) } #ifdef CONFIG_XFRM_OFFLOAD - if (new_active && bond->xs) { - xfrm_dev_state_flush(dev_net(bond->dev), bond->dev, true); - bond_ipsec_add_sa(bond->xs); - } + bond_ipsec_add_sa_all(bond); #endif /* CONFIG_XFRM_OFFLOAD */ /* resend IGMP joins since active slave has changed or @@ -1502,6 +1625,7 @@ static struct slave *bond_alloc_slave(struct bonding *bond, slave->bond = bond; slave->dev = slave_dev; + INIT_DELAYED_WORK(&slave->notify_work, bond_netdev_notify_work); if (bond_kobj_init(slave)) return NULL; @@ -1514,7 +1638,6 @@ static struct slave *bond_alloc_slave(struct bonding *bond, return NULL; } } - INIT_DELAYED_WORK(&slave->notify_work, bond_netdev_notify_work); return slave; } @@ -3293,6 +3416,9 @@ static int bond_master_netdev_event(unsigned long event, return bond_event_changename(event_bond); case NETDEV_UNREGISTER: bond_remove_proc_entry(event_bond); +#ifdef CONFIG_XFRM_OFFLOAD + xfrm_dev_state_flush(dev_net(bond_dev), bond_dev, true); +#endif /* CONFIG_XFRM_OFFLOAD */ break; case NETDEV_REGISTER: bond_create_proc_entry(event_bond); @@ -4726,7 +4852,8 @@ void bond_setup(struct net_device *bond_dev) #ifdef CONFIG_XFRM_OFFLOAD /* set up xfrm device ops (only supported in active-backup right now) */ bond_dev->xfrmdev_ops = &bond_xfrmdev_ops; - bond->xs = NULL; + INIT_LIST_HEAD(&bond->ipsec_list); + spin_lock_init(&bond->ipsec_lock); #endif /* CONFIG_XFRM_OFFLOAD */ /* don't acquire bond device's netif_tx_lock when transmitting */ diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index d025ea434933..39fbd0be179c 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -351,6 +351,7 @@ static int ldisc_open(struct tty_struct *tty) rtnl_lock(); result = register_netdevice(dev); if (result) { + tty_kref_put(tty); rtnl_unlock(); free_netdev(dev); return -ENODEV; diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c index 40c33b8a5fda..ac5801a98680 100644 --- a/drivers/net/can/peak_canfd/peak_canfd.c +++ b/drivers/net/can/peak_canfd/peak_canfd.c @@ -351,8 +351,8 @@ static int pucan_handle_status(struct peak_canfd_priv *priv, return err; } - /* start network queue (echo_skb array is empty) */ - netif_start_queue(ndev); + /* wake network queue up (echo_skb array is empty) */ + netif_wake_queue(ndev); return 0; } diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c index 73d48c3b8ded..7d2315c8cacb 100644 --- a/drivers/net/can/spi/hi311x.c +++ b/drivers/net/can/spi/hi311x.c @@ -218,7 +218,7 @@ static int hi3110_spi_trans(struct spi_device *spi, int len) return ret; } -static u8 hi3110_cmd(struct spi_device *spi, u8 command) +static int hi3110_cmd(struct spi_device *spi, u8 command) { struct hi3110_priv *priv = spi_get_drvdata(spi); diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 4f52810bebf8..249d2fba28c7 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -255,6 +255,8 @@ struct ems_usb { unsigned int free_slots; /* remember number of available slots */ struct ems_cpc_msg active_params; /* active controller parameters */ + void *rxbuf[MAX_RX_URBS]; + dma_addr_t rxbuf_dma[MAX_RX_URBS]; }; static void ems_usb_read_interrupt_callback(struct urb *urb) @@ -587,6 +589,7 @@ static int ems_usb_start(struct ems_usb *dev) for (i = 0; i < MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf = NULL; + dma_addr_t buf_dma; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -596,7 +599,7 @@ static int ems_usb_start(struct ems_usb *dev) } buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, - &urb->transfer_dma); + &buf_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); @@ -604,6 +607,8 @@ static int ems_usb_start(struct ems_usb *dev) break; } + urb->transfer_dma = buf_dma; + usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), buf, RX_BUFFER_SIZE, ems_usb_read_bulk_callback, dev); @@ -619,6 +624,9 @@ static int ems_usb_start(struct ems_usb *dev) break; } + dev->rxbuf[i] = buf; + dev->rxbuf_dma[i] = buf_dma; + /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); } @@ -684,6 +692,10 @@ static void unlink_all_urbs(struct ems_usb *dev) usb_kill_anchored_urbs(&dev->rx_submitted); + for (i = 0; i < MAX_RX_URBS; ++i) + usb_free_coherent(dev->udev, RX_BUFFER_SIZE, + dev->rxbuf[i], dev->rxbuf_dma[i]); + usb_kill_anchored_urbs(&dev->tx_submitted); atomic_set(&dev->active_tx_urbs, 0); @@ -1053,7 +1065,6 @@ static void ems_usb_disconnect(struct usb_interface *intf) if (dev) { unregister_netdev(dev->netdev); - free_candev(dev->netdev); unlink_all_urbs(dev); @@ -1061,6 +1072,8 @@ static void ems_usb_disconnect(struct usb_interface *intf) kfree(dev->intr_in_buffer); kfree(dev->tx_msg_buffer); + + free_candev(dev->netdev); } } diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index b5d7ed21d7d9..8847942a8d97 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -195,6 +195,8 @@ struct esd_usb2 { int net_count; u32 version; int rxinitdone; + void *rxbuf[MAX_RX_URBS]; + dma_addr_t rxbuf_dma[MAX_RX_URBS]; }; struct esd_usb2_net_priv { @@ -222,8 +224,8 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv, if (id == ESD_EV_CAN_ERROR_EXT) { u8 state = msg->msg.rx.data[0]; u8 ecc = msg->msg.rx.data[1]; - u8 txerr = msg->msg.rx.data[2]; - u8 rxerr = msg->msg.rx.data[3]; + u8 rxerr = msg->msg.rx.data[2]; + u8 txerr = msg->msg.rx.data[3]; skb = alloc_can_err_skb(priv->netdev, &cf); if (skb == NULL) { @@ -544,6 +546,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) for (i = 0; i < MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf = NULL; + dma_addr_t buf_dma; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -553,7 +556,7 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) } buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, - &urb->transfer_dma); + &buf_dma); if (!buf) { dev_warn(dev->udev->dev.parent, "No memory left for USB buffer\n"); @@ -561,6 +564,8 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) goto freeurb; } + urb->transfer_dma = buf_dma; + usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), buf, RX_BUFFER_SIZE, @@ -573,8 +578,12 @@ static int esd_usb2_setup_rx_urbs(struct esd_usb2 *dev) usb_unanchor_urb(urb); usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, urb->transfer_dma); + goto freeurb; } + dev->rxbuf[i] = buf; + dev->rxbuf_dma[i] = buf_dma; + freeurb: /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); @@ -662,6 +671,11 @@ static void unlink_all_urbs(struct esd_usb2 *dev) int i, j; usb_kill_anchored_urbs(&dev->rx_submitted); + + for (i = 0; i < MAX_RX_URBS; ++i) + usb_free_coherent(dev->udev, RX_BUFFER_SIZE, + dev->rxbuf[i], dev->rxbuf_dma[i]); + for (i = 0; i < dev->net_count; i++) { priv = dev->nets[i]; if (priv) { diff --git a/drivers/net/can/usb/mcba_usb.c b/drivers/net/can/usb/mcba_usb.c index e97f2e0da6b0..912160fd2ca0 100644 --- a/drivers/net/can/usb/mcba_usb.c +++ b/drivers/net/can/usb/mcba_usb.c @@ -82,6 +82,8 @@ struct mcba_priv { bool can_ka_first_pass; bool can_speed_check; atomic_t free_ctx_cnt; + void *rxbuf[MCBA_MAX_RX_URBS]; + dma_addr_t rxbuf_dma[MCBA_MAX_RX_URBS]; }; /* CAN frame */ @@ -633,6 +635,7 @@ static int mcba_usb_start(struct mcba_priv *priv) for (i = 0; i < MCBA_MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf; + dma_addr_t buf_dma; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -642,7 +645,7 @@ static int mcba_usb_start(struct mcba_priv *priv) } buf = usb_alloc_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE, - GFP_KERNEL, &urb->transfer_dma); + GFP_KERNEL, &buf_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); @@ -650,6 +653,8 @@ static int mcba_usb_start(struct mcba_priv *priv) break; } + urb->transfer_dma = buf_dma; + usb_fill_bulk_urb(urb, priv->udev, usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_IN), buf, MCBA_USB_RX_BUFF_SIZE, @@ -661,11 +666,14 @@ static int mcba_usb_start(struct mcba_priv *priv) if (err) { usb_unanchor_urb(urb); usb_free_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE, - buf, urb->transfer_dma); + buf, buf_dma); usb_free_urb(urb); break; } + priv->rxbuf[i] = buf; + priv->rxbuf_dma[i] = buf_dma; + /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); } @@ -708,7 +716,14 @@ static int mcba_usb_open(struct net_device *netdev) static void mcba_urb_unlink(struct mcba_priv *priv) { + int i; + usb_kill_anchored_urbs(&priv->rx_submitted); + + for (i = 0; i < MCBA_MAX_RX_URBS; ++i) + usb_free_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE, + priv->rxbuf[i], priv->rxbuf_dma[i]); + usb_kill_anchored_urbs(&priv->tx_submitted); } diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c index 63bd2ed96697..ce2d0761c4e5 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c @@ -117,7 +117,8 @@ MODULE_SUPPORTED_DEVICE("PEAK-System PCAN-USB adapter"); #define PCAN_USB_BERR_MASK (PCAN_USB_ERR_RXERR | PCAN_USB_ERR_TXERR) /* identify bus event packets with rx/tx error counters */ -#define PCAN_USB_ERR_CNT 0x80 +#define PCAN_USB_ERR_CNT_DEC 0x00 /* counters are decreasing */ +#define PCAN_USB_ERR_CNT_INC 0x80 /* counters are increasing */ /* private to PCAN-USB adapter */ struct pcan_usb { @@ -611,11 +612,12 @@ static int pcan_usb_handle_bus_evt(struct pcan_usb_msg_context *mc, u8 ir) /* acccording to the content of the packet */ switch (ir) { - case PCAN_USB_ERR_CNT: + case PCAN_USB_ERR_CNT_DEC: + case PCAN_USB_ERR_CNT_INC: /* save rx/tx error counters from in the device context */ - pdev->bec.rxerr = mc->ptr[0]; - pdev->bec.txerr = mc->ptr[1]; + pdev->bec.rxerr = mc->ptr[1]; + pdev->bec.txerr = mc->ptr[2]; break; default: diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c index 62749c67c959..ca7c55d6a41d 100644 --- a/drivers/net/can/usb/usb_8dev.c +++ b/drivers/net/can/usb/usb_8dev.c @@ -137,7 +137,8 @@ struct usb_8dev_priv { u8 *cmd_msg_buffer; struct mutex usb_8dev_cmd_lock; - + void *rxbuf[MAX_RX_URBS]; + dma_addr_t rxbuf_dma[MAX_RX_URBS]; }; /* tx frame */ @@ -733,6 +734,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) for (i = 0; i < MAX_RX_URBS; i++) { struct urb *urb = NULL; u8 *buf; + dma_addr_t buf_dma; /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -742,7 +744,7 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) } buf = usb_alloc_coherent(priv->udev, RX_BUFFER_SIZE, GFP_KERNEL, - &urb->transfer_dma); + &buf_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); @@ -750,6 +752,8 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) break; } + urb->transfer_dma = buf_dma; + usb_fill_bulk_urb(urb, priv->udev, usb_rcvbulkpipe(priv->udev, USB_8DEV_ENDP_DATA_RX), @@ -767,6 +771,9 @@ static int usb_8dev_start(struct usb_8dev_priv *priv) break; } + priv->rxbuf[i] = buf; + priv->rxbuf_dma[i] = buf_dma; + /* Drop reference, USB core will take care of freeing it */ usb_free_urb(urb); } @@ -836,6 +843,10 @@ static void unlink_all_urbs(struct usb_8dev_priv *priv) usb_kill_anchored_urbs(&priv->rx_submitted); + for (i = 0; i < MAX_RX_URBS; ++i) + usb_free_coherent(priv->udev, RX_BUFFER_SIZE, + priv->rxbuf[i], priv->rxbuf_dma[i]); + usb_kill_anchored_urbs(&priv->tx_submitted); atomic_set(&priv->active_tx_urbs, 0); diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c index aa1142d6a9f5..dcf1fc89451f 100644 --- a/drivers/net/dsa/lan9303-core.c +++ b/drivers/net/dsa/lan9303-core.c @@ -557,12 +557,12 @@ static int lan9303_alr_make_entry_raw(struct lan9303 *chip, u32 dat0, u32 dat1) return 0; } -typedef void alr_loop_cb_t(struct lan9303 *chip, u32 dat0, u32 dat1, - int portmap, void *ctx); +typedef int alr_loop_cb_t(struct lan9303 *chip, u32 dat0, u32 dat1, + int portmap, void *ctx); -static void lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx) +static int lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx) { - int i; + int ret = 0, i; mutex_lock(&chip->alr_mutex); lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, @@ -582,13 +582,17 @@ static void lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx) LAN9303_ALR_DAT1_PORT_BITOFFS; portmap = alrport_2_portmap[alrport]; - cb(chip, dat0, dat1, portmap, ctx); + ret = cb(chip, dat0, dat1, portmap, ctx); + if (ret) + break; lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, LAN9303_ALR_CMD_GET_NEXT); lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0); } mutex_unlock(&chip->alr_mutex); + + return ret; } static void alr_reg_to_mac(u32 dat0, u32 dat1, u8 mac[6]) @@ -606,18 +610,20 @@ struct del_port_learned_ctx { }; /* Clear learned (non-static) entry on given port */ -static void alr_loop_cb_del_port_learned(struct lan9303 *chip, u32 dat0, - u32 dat1, int portmap, void *ctx) +static int alr_loop_cb_del_port_learned(struct lan9303 *chip, u32 dat0, + u32 dat1, int portmap, void *ctx) { struct del_port_learned_ctx *del_ctx = ctx; int port = del_ctx->port; if (((BIT(port) & portmap) == 0) || (dat1 & LAN9303_ALR_DAT1_STATIC)) - return; + return 0; /* learned entries has only one port, we can just delete */ dat1 &= ~LAN9303_ALR_DAT1_VALID; /* delete entry */ lan9303_alr_make_entry_raw(chip, dat0, dat1); + + return 0; } struct port_fdb_dump_ctx { @@ -626,19 +632,19 @@ struct port_fdb_dump_ctx { dsa_fdb_dump_cb_t *cb; }; -static void alr_loop_cb_fdb_port_dump(struct lan9303 *chip, u32 dat0, - u32 dat1, int portmap, void *ctx) +static int alr_loop_cb_fdb_port_dump(struct lan9303 *chip, u32 dat0, + u32 dat1, int portmap, void *ctx) { struct port_fdb_dump_ctx *dump_ctx = ctx; u8 mac[ETH_ALEN]; bool is_static; if ((BIT(dump_ctx->port) & portmap) == 0) - return; + return 0; alr_reg_to_mac(dat0, dat1, mac); is_static = !!(dat1 & LAN9303_ALR_DAT1_STATIC); - dump_ctx->cb(mac, 0, is_static, dump_ctx->data); + return dump_ctx->cb(mac, 0, is_static, dump_ctx->data); } /* Set a static ALR entry. Delete entry if port_map is zero */ @@ -1210,9 +1216,7 @@ static int lan9303_port_fdb_dump(struct dsa_switch *ds, int port, }; dev_dbg(chip->dev, "%s(%d)\n", __func__, port); - lan9303_alr_loop(chip, alr_loop_cb_fdb_port_dump, &dump_ctx); - - return 0; + return lan9303_alr_loop(chip, alr_loop_cb_fdb_port_dump, &dump_ctx); } static int lan9303_port_mdb_prepare(struct dsa_switch *ds, int port, diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c index 93c7fa1fd4cb..a455534740cd 100644 --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c @@ -1416,11 +1416,17 @@ static int gswip_port_fdb_dump(struct dsa_switch *ds, int port, addr[1] = mac_bridge.key[2] & 0xff; addr[0] = (mac_bridge.key[2] >> 8) & 0xff; if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC) { - if (mac_bridge.val[0] & BIT(port)) - cb(addr, 0, true, data); + if (mac_bridge.val[0] & BIT(port)) { + err = cb(addr, 0, true, data); + if (err) + return err; + } } else { - if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) - cb(addr, 0, false, data); + if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) { + err = cb(addr, 0, false, data); + if (err) + return err; + } } } return 0; diff --git a/drivers/net/dsa/microchip/ksz8795.c b/drivers/net/dsa/microchip/ksz8795.c index 1e101ab56cea..ada0533b81fa 100644 --- a/drivers/net/dsa/microchip/ksz8795.c +++ b/drivers/net/dsa/microchip/ksz8795.c @@ -790,20 +790,79 @@ static int ksz8795_port_vlan_filtering(struct dsa_switch *ds, int port, if (switchdev_trans_ph_prepare(trans)) return 0; + /* Discard packets with VID not enabled on the switch */ ksz_cfg(dev, S_MIRROR_CTRL, SW_VLAN_ENABLE, flag); + /* Discard packets with VID not enabled on the ingress port */ + for (port = 0; port < dev->phy_port_cnt; ++port) + ksz_port_cfg(dev, port, REG_PORT_CTRL_2, PORT_INGRESS_FILTER, + flag); + return 0; } +static bool ksz8795_port_vlan_changes_remove_tag( + struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan) +{ + bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; + struct ksz_device *dev = ds->priv; + struct ksz_port *p = &dev->ports[port]; + + /* If a VLAN is added with untagged flag different from the + * port's Remove Tag flag, we need to change the latter. + * Ignore VID 0, which is always untagged. + * Ignore CPU port, which will always be tagged. + */ + return untagged != p->remove_tag && + !(vlan->vid_begin == 0 && vlan->vid_end == 0) && + port != dev->cpu_port; +} + +int ksz8795_port_vlan_prepare(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan) +{ + struct ksz_device *dev = ds->priv; + + /* Reject attempts to add a VLAN that requires the Remove Tag + * flag to be changed, unless there are no other VLANs + * currently configured. + */ + if (ksz8795_port_vlan_changes_remove_tag(ds, port, vlan)) { + unsigned int vid; + + for (vid = 1; vid < dev->num_vlans; ++vid) { + u8 fid, member, valid; + + /* Skip the VIDs we are going to add or reconfigure */ + if (vid == vlan->vid_begin) { + vid = vlan->vid_end; + continue; + } + + ksz8795_from_vlan(dev->vlan_cache[vid].table[0], + &fid, &member, &valid); + if (valid && (member & BIT(port))) + return -EINVAL; + } + } + + return ksz_port_vlan_prepare(ds, port, vlan); +} + static void ksz8795_port_vlan_add(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan) { bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; struct ksz_device *dev = ds->priv; + struct ksz_port *p = &dev->ports[port]; u16 data, vid, new_pvid = 0; u8 fid, member, valid; - ksz_port_cfg(dev, port, P_TAG_CTRL, PORT_REMOVE_TAG, untagged); + if (ksz8795_port_vlan_changes_remove_tag(ds, port, vlan)) { + ksz_port_cfg(dev, port, P_TAG_CTRL, PORT_REMOVE_TAG, untagged); + p->remove_tag = untagged; + } for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { ksz8795_r_vlan_table(dev, vid, &data); @@ -827,25 +886,25 @@ static void ksz8795_port_vlan_add(struct dsa_switch *ds, int port, if (new_pvid) { ksz_pread16(dev, port, REG_PORT_CTRL_VID, &vid); - vid &= 0xfff; + vid &= ~VLAN_VID_MASK; vid |= new_pvid; ksz_pwrite16(dev, port, REG_PORT_CTRL_VID, vid); + + ksz_pwrite8(dev, port, REG_PORT_CTRL_12, 0x0f); } } static int ksz8795_port_vlan_del(struct dsa_switch *ds, int port, const struct switchdev_obj_port_vlan *vlan) { - bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; struct ksz_device *dev = ds->priv; - u16 data, vid, pvid, new_pvid = 0; + u16 data, vid, pvid; u8 fid, member, valid; + bool del_pvid = false; ksz_pread16(dev, port, REG_PORT_CTRL_VID, &pvid); pvid = pvid & 0xFFF; - ksz_port_cfg(dev, port, P_TAG_CTRL, PORT_REMOVE_TAG, untagged); - for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) { ksz8795_r_vlan_table(dev, vid, &data); ksz8795_from_vlan(data, &fid, &member, &valid); @@ -859,14 +918,14 @@ static int ksz8795_port_vlan_del(struct dsa_switch *ds, int port, } if (pvid == vid) - new_pvid = 1; + del_pvid = true; ksz8795_to_vlan(fid, member, valid, &data); ksz8795_w_vlan_table(dev, vid, data); } - if (new_pvid != pvid) - ksz_pwrite16(dev, port, REG_PORT_CTRL_VID, pvid); + if (del_pvid) + ksz_pwrite8(dev, port, REG_PORT_CTRL_12, 0x00); return 0; } @@ -1079,6 +1138,8 @@ static int ksz8795_setup(struct dsa_switch *ds) ksz_cfg(dev, S_MIRROR_CTRL, SW_MIRROR_RX_TX, false); + ksz_cfg(dev, REG_SW_CTRL_19, SW_INS_TAG_ENABLE, true); + /* set broadcast storm protection 10% rate */ regmap_update_bits(dev->regmap[1], S_REPLACE_VID_CTRL, BROADCAST_STORM_RATE, @@ -1117,7 +1178,7 @@ static const struct dsa_switch_ops ksz8795_switch_ops = { .port_stp_state_set = ksz8795_port_stp_state_set, .port_fast_age = ksz_port_fast_age, .port_vlan_filtering = ksz8795_port_vlan_filtering, - .port_vlan_prepare = ksz_port_vlan_prepare, + .port_vlan_prepare = ksz8795_port_vlan_prepare, .port_vlan_add = ksz8795_port_vlan_add, .port_vlan_del = ksz8795_port_vlan_del, .port_fdb_dump = ksz_port_fdb_dump, @@ -1266,6 +1327,16 @@ static int ksz8795_switch_init(struct ksz_device *dev) /* set the real number of ports */ dev->ds->num_ports = dev->port_cnt + 1; + /* We rely on software untagging on the CPU port, so that we + * can support both tagged and untagged VLANs + */ + dev->ds->untag_bridge_pvid = true; + + /* VLAN filtering is partly controlled by the global VLAN + * Enable flag + */ + dev->ds->vlan_filtering_is_global = true; + return 0; } diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index abfd3802bb51..b3aa99eb6c2c 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -1532,6 +1532,7 @@ static const struct ksz_chip_data ksz9477_switch_chips[] = { .num_statics = 16, .cpu_ports = 0x7F, /* can be configured as cpu port */ .port_cnt = 7, /* total physical port count */ + .phy_errata_9477 = true, }, }; diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index d4a64dbde315..88fa0779e0bc 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -432,7 +432,7 @@ int ksz_switch_register(struct ksz_device *dev, if (of_property_read_u32(port, "reg", &port_num)) continue; - if (port_num >= dev->port_cnt) + if (port_num >= dev->mib_port_cnt) return -EINVAL; of_get_phy_mode(port, &dev->ports[port_num].interface); diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index cf866e48ff66..309ad4a72d78 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -27,6 +27,7 @@ struct ksz_port_mib { struct ksz_port { u16 member; u16 vid_member; + bool remove_tag; /* Remove Tag flag set, for ksz8795 only */ int stp_state; struct phy_device phydev; @@ -210,12 +211,8 @@ static inline int ksz_read64(struct ksz_device *dev, u32 reg, u64 *val) int ret; ret = regmap_bulk_read(dev->regmap[2], reg, value, 2); - if (!ret) { - /* Ick! ToDo: Add 64bit R/W to regmap on 32bit systems */ - value[0] = swab32(value[0]); - value[1] = swab32(value[1]); - *val = swab64((u64)*value); - } + if (!ret) + *val = (u64)value[0] << 32 | value[1]; return ret; } diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index 190025a0a98e..73de09093c35 100644 --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c @@ -45,6 +45,7 @@ static const struct mt7530_mib_desc mt7530_mib[] = { MIB_DESC(2, 0x48, "TxBytes"), MIB_DESC(1, 0x60, "RxDrop"), MIB_DESC(1, 0x64, "RxFiltering"), + MIB_DESC(1, 0x68, "RxUnicast"), MIB_DESC(1, 0x6c, "RxMulticast"), MIB_DESC(1, 0x70, "RxBroadcast"), MIB_DESC(1, 0x74, "RxAlignErr"), @@ -1160,11 +1161,8 @@ mt7530_port_bridge_leave(struct dsa_switch *ds, int port, /* Remove this port from the port matrix of the other ports * in the same bridge. If the port is disabled, port matrix * is kept and not being setup until the port becomes enabled. - * And the other port's port matrix cannot be broken when the - * other port is still a VLAN-aware port. */ - if (dsa_is_user_port(ds, i) && i != port && - !dsa_port_is_vlan_filtering(dsa_to_port(ds, i))) { + if (dsa_is_user_port(ds, i) && i != port) { if (dsa_to_port(ds, i)->bridge_dev != bridge) continue; if (priv->ports[i].enable) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 70ec17f3c300..184cbc93328c 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -3407,7 +3407,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .port_set_cmode = mv88e6341_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6390_g1_stats_snapshot, - .stats_set_histogram = mv88e6095_g1_stats_set_histogram, + .stats_set_histogram = mv88e6390_g1_stats_set_histogram, .stats_get_sset_count = mv88e6320_stats_get_sset_count, .stats_get_strings = mv88e6320_stats_get_strings, .stats_get_stats = mv88e6390_stats_get_stats, @@ -3417,6 +3417,9 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, .reset = mv88e6352_g1_reset, + .rmu_disable = mv88e6390_g1_rmu_disable, + .atu_get_hash = mv88e6165_g1_atu_get_hash, + .atu_set_hash = mv88e6165_g1_atu_set_hash, .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, @@ -3430,6 +3433,11 @@ static const struct mv88e6xxx_ops mv88e6141_ops = { .serdes_irq_enable = mv88e6390_serdes_irq_enable, .serdes_irq_status = mv88e6390_serdes_irq_status, .gpio_ops = &mv88e6352_gpio_ops, + .serdes_get_sset_count = mv88e6390_serdes_get_sset_count, + .serdes_get_strings = mv88e6390_serdes_get_strings, + .serdes_get_stats = mv88e6390_serdes_get_stats, + .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, + .serdes_get_regs = mv88e6390_serdes_get_regs, .phylink_validate = mv88e6341_phylink_validate, }; @@ -3613,6 +3621,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = { .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, + .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods, .port_set_ether_type = mv88e6351_port_set_ether_type, @@ -4173,7 +4182,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .port_set_cmode = mv88e6341_port_set_cmode, .port_setup_message_port = mv88e6xxx_setup_message_port, .stats_snapshot = mv88e6390_g1_stats_snapshot, - .stats_set_histogram = mv88e6095_g1_stats_set_histogram, + .stats_set_histogram = mv88e6390_g1_stats_set_histogram, .stats_get_sset_count = mv88e6320_stats_get_sset_count, .stats_get_strings = mv88e6320_stats_get_strings, .stats_get_stats = mv88e6390_stats_get_stats, @@ -4183,6 +4192,9 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu, .pot_clear = mv88e6xxx_g2_pot_clear, .reset = mv88e6352_g1_reset, + .rmu_disable = mv88e6390_g1_rmu_disable, + .atu_get_hash = mv88e6165_g1_atu_get_hash, + .atu_set_hash = mv88e6165_g1_atu_set_hash, .vtu_getnext = mv88e6352_g1_vtu_getnext, .vtu_loadpurge = mv88e6352_g1_vtu_loadpurge, .serdes_power = mv88e6390_serdes_power, @@ -4198,6 +4210,11 @@ static const struct mv88e6xxx_ops mv88e6341_ops = { .gpio_ops = &mv88e6352_gpio_ops, .avb_ops = &mv88e6390_avb_ops, .ptp_ops = &mv88e6352_ptp_ops, + .serdes_get_sset_count = mv88e6390_serdes_get_sset_count, + .serdes_get_strings = mv88e6390_serdes_get_strings, + .serdes_get_stats = mv88e6390_serdes_get_stats, + .serdes_get_regs_len = mv88e6390_serdes_get_regs_len, + .serdes_get_regs = mv88e6390_serdes_get_regs, .phylink_validate = mv88e6341_phylink_validate, }; @@ -4253,6 +4270,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = { .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, .port_set_speed_duplex = mv88e6185_port_set_speed_duplex, .port_tag_remap = mv88e6095_port_tag_remap, + .port_set_policy = mv88e6352_port_set_policy, .port_set_frame_mode = mv88e6351_port_set_frame_mode, .port_set_egress_floods = mv88e6352_port_set_egress_floods, .port_set_ether_type = mv88e6351_port_set_ether_type, diff --git a/drivers/net/dsa/mv88e6xxx/serdes.c b/drivers/net/dsa/mv88e6xxx/serdes.c index 9c07b4f3d345..6920e62c864d 100644 --- a/drivers/net/dsa/mv88e6xxx/serdes.c +++ b/drivers/net/dsa/mv88e6xxx/serdes.c @@ -590,7 +590,7 @@ static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = { int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port) { - if (mv88e6390_serdes_get_lane(chip, port) == 0) + if (mv88e6xxx_serdes_get_lane(chip, port) == 0) return 0; return ARRAY_SIZE(mv88e6390_serdes_hw_stats); @@ -602,7 +602,7 @@ int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip, struct mv88e6390_serdes_hw_stat *stat; int i; - if (mv88e6390_serdes_get_lane(chip, port) == 0) + if (mv88e6xxx_serdes_get_lane(chip, port) == 0) return 0; for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) { @@ -638,7 +638,7 @@ int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, int lane; int i; - lane = mv88e6390_serdes_get_lane(chip, port); + lane = mv88e6xxx_serdes_get_lane(chip, port); if (lane == 0) return 0; diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c index ebbaf6817ec8..7026523f886c 100644 --- a/drivers/net/dsa/ocelot/seville_vsc9953.c +++ b/drivers/net/dsa/ocelot/seville_vsc9953.c @@ -1214,6 +1214,11 @@ static int seville_probe(struct platform_device *pdev) felix->info = &seville_info_vsc9953; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + err = -EINVAL; + dev_err(&pdev->dev, "Invalid resource\n"); + goto err_alloc_felix; + } felix->switch_base = res->start; ds = kzalloc(sizeof(struct dsa_switch), GFP_KERNEL); diff --git a/drivers/net/dsa/qca/ar9331.c b/drivers/net/dsa/qca/ar9331.c index 4d49c5f2b790..661745932a53 100644 --- a/drivers/net/dsa/qca/ar9331.c +++ b/drivers/net/dsa/qca/ar9331.c @@ -689,16 +689,24 @@ static int ar9331_mdio_write(void *ctx, u32 reg, u32 val) return 0; } - ret = __ar9331_mdio_write(sbus, AR9331_SW_MDIO_PHY_MODE_REG, reg, val); + /* In case of this switch we work with 32bit registers on top of 16bit + * bus. Some registers (for example access to forwarding database) have + * trigger bit on the first 16bit half of request, the result and + * configuration of request in the second half. + * To make it work properly, we should do the second part of transfer + * before the first one is done. + */ + ret = __ar9331_mdio_write(sbus, AR9331_SW_MDIO_PHY_MODE_REG, reg + 2, + val >> 16); if (ret < 0) goto error; - ret = __ar9331_mdio_write(sbus, AR9331_SW_MDIO_PHY_MODE_REG, reg + 2, - val >> 16); + ret = __ar9331_mdio_write(sbus, AR9331_SW_MDIO_PHY_MODE_REG, reg, val); if (ret < 0) goto error; return 0; + error: dev_err_ratelimited(&sbus->dev, "Bus error. Failed to write register.\n"); return ret; diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index e273b2bd82ba..c03d76c10868 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -350,6 +350,12 @@ static int sja1105_init_static_vlan(struct sja1105_private *priv) if (dsa_is_cpu_port(ds, port)) v->pvid = true; list_add(&v->list, &priv->dsa_8021q_vlans); + + v = kmemdup(v, sizeof(*v), GFP_KERNEL); + if (!v) + return -ENOMEM; + + list_add(&v->list, &priv->bridge_vlans); } ((struct sja1105_vlan_lookup_entry *)table->entries)[0] = pvid; @@ -1254,10 +1260,11 @@ static int sja1105et_is_fdb_entry_in_bin(struct sja1105_private *priv, int bin, int sja1105et_fdb_add(struct dsa_switch *ds, int port, const unsigned char *addr, u16 vid) { - struct sja1105_l2_lookup_entry l2_lookup = {0}; + struct sja1105_l2_lookup_entry l2_lookup = {0}, tmp; struct sja1105_private *priv = ds->priv; struct device *dev = ds->dev; int last_unused = -1; + int start, end, i; int bin, way, rc; bin = sja1105et_fdb_hash(priv, addr, vid); @@ -1269,7 +1276,7 @@ int sja1105et_fdb_add(struct dsa_switch *ds, int port, * mask? If yes, we need to do nothing. If not, we need * to rewrite the entry by adding this port to it. */ - if (l2_lookup.destports & BIT(port)) + if ((l2_lookup.destports & BIT(port)) && l2_lookup.lockeds) return 0; l2_lookup.destports |= BIT(port); } else { @@ -1300,6 +1307,7 @@ int sja1105et_fdb_add(struct dsa_switch *ds, int port, index, NULL, false); } } + l2_lookup.lockeds = true; l2_lookup.index = sja1105et_fdb_index(bin, way); rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, @@ -1308,6 +1316,29 @@ int sja1105et_fdb_add(struct dsa_switch *ds, int port, if (rc < 0) return rc; + /* Invalidate a dynamically learned entry if that exists */ + start = sja1105et_fdb_index(bin, 0); + end = sja1105et_fdb_index(bin, way); + + for (i = start; i < end; i++) { + rc = sja1105_dynamic_config_read(priv, BLK_IDX_L2_LOOKUP, + i, &tmp); + if (rc == -ENOENT) + continue; + if (rc) + return rc; + + if (tmp.macaddr != ether_addr_to_u64(addr) || tmp.vlanid != vid) + continue; + + rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, + i, NULL, false); + if (rc) + return rc; + + break; + } + return sja1105_static_fdb_change(priv, port, &l2_lookup, true); } @@ -1349,31 +1380,24 @@ int sja1105et_fdb_del(struct dsa_switch *ds, int port, int sja1105pqrs_fdb_add(struct dsa_switch *ds, int port, const unsigned char *addr, u16 vid) { - struct sja1105_l2_lookup_entry l2_lookup = {0}; + struct sja1105_l2_lookup_entry l2_lookup = {0}, tmp; struct sja1105_private *priv = ds->priv; int rc, i; /* Search for an existing entry in the FDB table */ l2_lookup.macaddr = ether_addr_to_u64(addr); l2_lookup.vlanid = vid; - l2_lookup.iotag = SJA1105_S_TAG; l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0); - if (priv->vlan_state != SJA1105_VLAN_UNAWARE) { - l2_lookup.mask_vlanid = VLAN_VID_MASK; - l2_lookup.mask_iotag = BIT(0); - } else { - l2_lookup.mask_vlanid = 0; - l2_lookup.mask_iotag = 0; - } + l2_lookup.mask_vlanid = VLAN_VID_MASK; l2_lookup.destports = BIT(port); rc = sja1105_dynamic_config_read(priv, BLK_IDX_L2_LOOKUP, SJA1105_SEARCH, &l2_lookup); if (rc == 0) { - /* Found and this port is already in the entry's + /* Found a static entry and this port is already in the entry's * port mask => job done */ - if (l2_lookup.destports & BIT(port)) + if ((l2_lookup.destports & BIT(port)) && l2_lookup.lockeds) return 0; /* l2_lookup.index is populated by the switch in case it * found something. @@ -1396,16 +1420,46 @@ int sja1105pqrs_fdb_add(struct dsa_switch *ds, int port, dev_err(ds->dev, "FDB is full, cannot add entry.\n"); return -EINVAL; } - l2_lookup.lockeds = true; l2_lookup.index = i; skip_finding_an_index: + l2_lookup.lockeds = true; + rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, l2_lookup.index, &l2_lookup, true); if (rc < 0) return rc; + /* The switch learns dynamic entries and looks up the FDB left to + * right. It is possible that our addition was concurrent with the + * dynamic learning of the same address, so now that the static entry + * has been installed, we are certain that address learning for this + * particular address has been turned off, so the dynamic entry either + * is in the FDB at an index smaller than the static one, or isn't (it + * can also be at a larger index, but in that case it is inactive + * because the static FDB entry will match first, and the dynamic one + * will eventually age out). Search for a dynamically learned address + * prior to our static one and invalidate it. + */ + tmp = l2_lookup; + + rc = sja1105_dynamic_config_read(priv, BLK_IDX_L2_LOOKUP, + SJA1105_SEARCH, &tmp); + if (rc < 0) { + dev_err(ds->dev, + "port %d failed to read back entry for %pM vid %d: %pe\n", + port, addr, vid, ERR_PTR(rc)); + return rc; + } + + if (tmp.index < l2_lookup.index) { + rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, + tmp.index, NULL, false); + if (rc < 0) + return rc; + } + return sja1105_static_fdb_change(priv, port, &l2_lookup, true); } @@ -1419,15 +1473,8 @@ int sja1105pqrs_fdb_del(struct dsa_switch *ds, int port, l2_lookup.macaddr = ether_addr_to_u64(addr); l2_lookup.vlanid = vid; - l2_lookup.iotag = SJA1105_S_TAG; l2_lookup.mask_macaddr = GENMASK_ULL(ETH_ALEN * 8 - 1, 0); - if (priv->vlan_state != SJA1105_VLAN_UNAWARE) { - l2_lookup.mask_vlanid = VLAN_VID_MASK; - l2_lookup.mask_iotag = BIT(0); - } else { - l2_lookup.mask_vlanid = 0; - l2_lookup.mask_iotag = 0; - } + l2_lookup.mask_vlanid = VLAN_VID_MASK; l2_lookup.destports = BIT(port); rc = sja1105_dynamic_config_read(priv, BLK_IDX_L2_LOOKUP, @@ -1519,7 +1566,9 @@ static int sja1105_fdb_dump(struct dsa_switch *ds, int port, /* We need to hide the dsa_8021q VLANs from the user. */ if (priv->vlan_state == SJA1105_VLAN_UNAWARE) l2_lookup.vlanid = 0; - cb(macaddr, l2_lookup.vlanid, l2_lookup.lockeds, data); + rc = cb(macaddr, l2_lookup.vlanid, l2_lookup.lockeds, data); + if (rc) + return rc; } return 0; } @@ -1711,6 +1760,12 @@ static int sja1105_reload_cbs(struct sja1105_private *priv) { int rc = 0, i; + /* The credit based shapers are only allocated if + * CONFIG_NET_SCH_CBS is enabled. + */ + if (!priv->cbs) + return 0; + for (i = 0; i < priv->info->num_cbs_shapers; i++) { struct sja1105_cbs_entry *cbs = &priv->cbs[i]; diff --git a/drivers/net/ethernet/aeroflex/greth.c b/drivers/net/ethernet/aeroflex/greth.c index 9c5891bbfe61..f4f50b3a472e 100644 --- a/drivers/net/ethernet/aeroflex/greth.c +++ b/drivers/net/ethernet/aeroflex/greth.c @@ -1539,10 +1539,11 @@ static int greth_of_remove(struct platform_device *of_dev) mdiobus_unregister(greth->mdio); unregister_netdev(ndev); - free_netdev(ndev); of_iounmap(&of_dev->resource[0], greth->regs, resource_size(&of_dev->resource[0])); + free_netdev(ndev); + return 0; } diff --git a/drivers/net/ethernet/apm/xgene-v2/main.c b/drivers/net/ethernet/apm/xgene-v2/main.c index 860c18fb7aae..80399c8980bd 100644 --- a/drivers/net/ethernet/apm/xgene-v2/main.c +++ b/drivers/net/ethernet/apm/xgene-v2/main.c @@ -677,11 +677,13 @@ static int xge_probe(struct platform_device *pdev) ret = register_netdev(ndev); if (ret) { netdev_err(ndev, "Failed to register netdev\n"); - goto err; + goto err_mdio_remove; } return 0; +err_mdio_remove: + xge_mdio_remove(ndev); err: free_netdev(ndev); diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h index f5fba8b8cdea..a47e2710487e 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.h @@ -91,7 +91,7 @@ struct aq_macsec_txsc { u32 hw_sc_idx; unsigned long tx_sa_idx_busy; const struct macsec_secy *sw_secy; - u8 tx_sa_key[MACSEC_NUM_AN][MACSEC_KEYID_LEN]; + u8 tx_sa_key[MACSEC_NUM_AN][MACSEC_MAX_KEY_LEN]; struct aq_macsec_tx_sc_stats stats; struct aq_macsec_tx_sa_stats tx_sa_stats[MACSEC_NUM_AN]; }; @@ -101,7 +101,7 @@ struct aq_macsec_rxsc { unsigned long rx_sa_idx_busy; const struct macsec_secy *sw_secy; const struct macsec_rx_sc *sw_rxsc; - u8 rx_sa_key[MACSEC_NUM_AN][MACSEC_KEYID_LEN]; + u8 rx_sa_key[MACSEC_NUM_AN][MACSEC_MAX_KEY_LEN]; struct aq_macsec_rx_sa_stats rx_sa_stats[MACSEC_NUM_AN]; }; diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index 9e02f8864593..5e90df42b201 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -1849,6 +1849,7 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) free_netdev(netdev); out_pci_release: pci_release_mem_regions(pdev); + pci_disable_pcie_error_reporting(pdev); out_pci_disable: pci_disable_device(pdev); return err; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 1a6ec1a12d53..b5d954cb409a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2669,7 +2669,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) } /* Allocated memory for FW statistics */ - if (bnx2x_alloc_fw_stats_mem(bp)) + rc = bnx2x_alloc_fw_stats_mem(bp); + if (rc) LOAD_ERROR_EXIT(bp, load_error0); /* request pf to initialize status blocks */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 9c2f51f23035..9108b497b3c9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -1224,8 +1224,10 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, goto failed; /* SR-IOV capability was enabled but there are no VFs*/ - if (iov->total == 0) + if (iov->total == 0) { + err = -EINVAL; goto failed; + } iov->nr_virtfn = min_t(u16, iov->total, num_vfs_param); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index adfaa9a850dd..849ae99a955a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -69,7 +69,8 @@ #include "bnxt_debugfs.h" #define BNXT_TX_TIMEOUT (5 * HZ) -#define BNXT_DEF_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_HW) +#define BNXT_DEF_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_HW | \ + NETIF_MSG_TX_ERR) MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Broadcom BCM573xx network driver"); @@ -360,6 +361,33 @@ static u16 bnxt_xmit_get_cfa_action(struct sk_buff *skb) return md_dst->u.port_info.port_id; } +static void bnxt_txr_db_kick(struct bnxt *bp, struct bnxt_tx_ring_info *txr, + u16 prod) +{ + bnxt_db_write(bp, &txr->tx_db, prod); + txr->kick_pending = 0; +} + +static bool bnxt_txr_netif_try_stop_queue(struct bnxt *bp, + struct bnxt_tx_ring_info *txr, + struct netdev_queue *txq) +{ + netif_tx_stop_queue(txq); + + /* netif_tx_stop_queue() must be done before checking + * tx index in bnxt_tx_avail() below, because in + * bnxt_tx_int(), we update tx index before checking for + * netif_tx_queue_stopped(). + */ + smp_mb(); + if (bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh) { + netif_tx_wake_queue(txq); + return false; + } + + return true; +} + static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bnxt *bp = netdev_priv(dev); @@ -378,6 +406,7 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) i = skb_get_queue_mapping(skb); if (unlikely(i >= bp->tx_nr_rings)) { dev_kfree_skb_any(skb); + atomic_long_inc(&dev->tx_dropped); return NETDEV_TX_OK; } @@ -387,8 +416,12 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) free_size = bnxt_tx_avail(bp, txr); if (unlikely(free_size < skb_shinfo(skb)->nr_frags + 2)) { - netif_tx_stop_queue(txq); - return NETDEV_TX_BUSY; + /* We must have raced with NAPI cleanup */ + if (net_ratelimit() && txr->kick_pending) + netif_warn(bp, tx_err, dev, + "bnxt: ring busy w/ flush pending!\n"); + if (bnxt_txr_netif_try_stop_queue(bp, txr, txq)) + return NETDEV_TX_BUSY; } length = skb->len; @@ -490,21 +523,16 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) normal_tx: if (length < BNXT_MIN_PKT_SIZE) { pad = BNXT_MIN_PKT_SIZE - length; - if (skb_pad(skb, pad)) { + if (skb_pad(skb, pad)) /* SKB already freed. */ - tx_buf->skb = NULL; - return NETDEV_TX_OK; - } + goto tx_kick_pending; length = BNXT_MIN_PKT_SIZE; } mapping = dma_map_single(&pdev->dev, skb->data, len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(&pdev->dev, mapping))) { - dev_kfree_skb_any(skb); - tx_buf->skb = NULL; - return NETDEV_TX_OK; - } + if (unlikely(dma_mapping_error(&pdev->dev, mapping))) + goto tx_free; dma_unmap_addr_set(tx_buf, mapping, mapping); flags = (len << TX_BD_LEN_SHIFT) | TX_BD_TYPE_LONG_TX_BD | @@ -589,24 +617,17 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) txr->tx_prod = prod; if (!netdev_xmit_more() || netif_xmit_stopped(txq)) - bnxt_db_write(bp, &txr->tx_db, prod); + bnxt_txr_db_kick(bp, txr, prod); + else + txr->kick_pending = 1; tx_done: if (unlikely(bnxt_tx_avail(bp, txr) <= MAX_SKB_FRAGS + 1)) { if (netdev_xmit_more() && !tx_buf->is_push) - bnxt_db_write(bp, &txr->tx_db, prod); - - netif_tx_stop_queue(txq); + bnxt_txr_db_kick(bp, txr, prod); - /* netif_tx_stop_queue() must be done before checking - * tx index in bnxt_tx_avail() below, because in - * bnxt_tx_int(), we update tx index before checking for - * netif_tx_queue_stopped(). - */ - smp_mb(); - if (bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh) - netif_tx_wake_queue(txq); + bnxt_txr_netif_try_stop_queue(bp, txr, txq); } return NETDEV_TX_OK; @@ -616,7 +637,6 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) /* start back at beginning and unmap skb */ prod = txr->tx_prod; tx_buf = &txr->tx_buf_ring[prod]; - tx_buf->skb = NULL; dma_unmap_single(&pdev->dev, dma_unmap_addr(tx_buf, mapping), skb_headlen(skb), PCI_DMA_TODEVICE); prod = NEXT_TX(prod); @@ -630,7 +650,13 @@ static netdev_tx_t bnxt_start_xmit(struct sk_buff *skb, struct net_device *dev) PCI_DMA_TODEVICE); } +tx_free: dev_kfree_skb_any(skb); +tx_kick_pending: + if (txr->kick_pending) + bnxt_txr_db_kick(bp, txr, txr->tx_prod); + txr->tx_buf_ring[txr->tx_prod].skb = NULL; + atomic_long_inc(&dev->tx_dropped); return NETDEV_TX_OK; } @@ -690,14 +716,9 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int nr_pkts) smp_mb(); if (unlikely(netif_tx_queue_stopped(txq)) && - (bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh)) { - __netif_tx_lock(txq, smp_processor_id()); - if (netif_tx_queue_stopped(txq) && - bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh && - txr->dev_state != BNXT_DEV_STATE_CLOSING) - netif_tx_wake_queue(txq); - __netif_tx_unlock(txq); - } + bnxt_tx_avail(bp, txr) > bp->tx_wake_thresh && + READ_ONCE(txr->dev_state) != BNXT_DEV_STATE_CLOSING) + netif_tx_wake_queue(txq); } static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping, @@ -1633,11 +1654,16 @@ static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp, if ((tpa_info->flags2 & RX_CMP_FLAGS2_META_FORMAT_VLAN) && (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)) { - u16 vlan_proto = tpa_info->metadata >> - RX_CMP_FLAGS2_METADATA_TPID_SFT; + __be16 vlan_proto = htons(tpa_info->metadata >> + RX_CMP_FLAGS2_METADATA_TPID_SFT); u16 vtag = tpa_info->metadata & RX_CMP_FLAGS2_METADATA_TCI_MASK; - __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag); + if (eth_type_vlan(vlan_proto)) { + __vlan_hwaccel_put_tag(skb, vlan_proto, vtag); + } else { + dev_kfree_skb(skb); + return NULL; + } } skb_checksum_none_assert(skb); @@ -1721,6 +1747,10 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, if (!RX_CMP_VALID(rxcmp1, tmp_raw_cons)) return -EBUSY; + /* The valid test of the entry must be done first before + * reading any further. + */ + dma_rmb(); prod = rxr->rx_prod; if (cmp_type == CMP_TYPE_RX_L2_TPA_START_CMP) { @@ -1858,9 +1888,15 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, (skb->dev->features & BNXT_HW_FEATURE_VLAN_ALL_RX)) { u32 meta_data = le32_to_cpu(rxcmp1->rx_cmp_meta_data); u16 vtag = meta_data & RX_CMP_FLAGS2_METADATA_TCI_MASK; - u16 vlan_proto = meta_data >> RX_CMP_FLAGS2_METADATA_TPID_SFT; + __be16 vlan_proto = htons(meta_data >> + RX_CMP_FLAGS2_METADATA_TPID_SFT); - __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vtag); + if (eth_type_vlan(vlan_proto)) { + __vlan_hwaccel_put_tag(skb, vlan_proto, vtag); + } else { + dev_kfree_skb(skb); + goto next_rx; + } } skb_checksum_none_assert(skb); @@ -1918,6 +1954,10 @@ static int bnxt_force_rx_discard(struct bnxt *bp, if (!RX_CMP_VALID(rxcmp1, tmp_raw_cons)) return -EBUSY; + /* The valid test of the entry must be done first before + * reading any further. + */ + dma_rmb(); cmp_type = RX_CMP_TYPE(rxcmp); if (cmp_type == CMP_TYPE_RX_L2_CMP) { rxcmp1->rx_cmp_cfa_code_errors_v2 |= @@ -2362,6 +2402,10 @@ static int bnxt_poll_nitroa0(struct napi_struct *napi, int budget) if (!TX_CMP_VALID(txcmp, raw_cons)) break; + /* The valid test of the entry must be done first before + * reading any further. + */ + dma_rmb(); if ((TX_CMP_TYPE(txcmp) & 0x30) == 0x10) { tmp_raw_cons = NEXT_RAW_CMP(raw_cons); cp_cons = RING_CMP(tmp_raw_cons); @@ -7184,7 +7228,7 @@ static int bnxt_alloc_ctx_mem(struct bnxt *bp) entries_sp = ctx->vnic_max_vnic_entries + ctx->qp_max_l2_entries + 2 * (extra_qps + ctx->qp_min_qp1_entries) + min; entries_sp = roundup(entries_sp, ctx->tqm_entries_multiple); - entries = ctx->qp_max_l2_entries + extra_qps + ctx->qp_min_qp1_entries; + entries = ctx->qp_max_l2_entries + 2 * (extra_qps + ctx->qp_min_qp1_entries); entries = roundup(entries, ctx->tqm_entries_multiple); entries = clamp_t(u32, entries, min, ctx->tqm_max_entries_per_ring); for (i = 0; i < ctx->tqm_fp_rings_count + 1; i++) { @@ -8838,10 +8882,9 @@ static void bnxt_disable_napi(struct bnxt *bp) for (i = 0; i < bp->cp_nr_rings; i++) { struct bnxt_cp_ring_info *cpr = &bp->bnapi[i]->cp_ring; + napi_disable(&bp->bnapi[i]->napi); if (bp->bnapi[i]->rx_ring) cancel_work_sync(&cpr->dim.work); - - napi_disable(&bp->bnapi[i]->napi); } } @@ -8874,9 +8917,11 @@ void bnxt_tx_disable(struct bnxt *bp) if (bp->tx_ring) { for (i = 0; i < bp->tx_nr_rings; i++) { txr = &bp->tx_ring[i]; - txr->dev_state = BNXT_DEV_STATE_CLOSING; + WRITE_ONCE(txr->dev_state, BNXT_DEV_STATE_CLOSING); } } + /* Make sure napi polls see @dev_state change */ + synchronize_net(); /* Drop carrier first to prevent TX timeout */ netif_carrier_off(bp->dev); /* Stop all TX queues */ @@ -8890,8 +8935,10 @@ void bnxt_tx_enable(struct bnxt *bp) for (i = 0; i < bp->tx_nr_rings; i++) { txr = &bp->tx_ring[i]; - txr->dev_state = 0; + WRITE_ONCE(txr->dev_state, 0); } + /* Make sure napi polls see @dev_state change */ + synchronize_net(); netif_tx_wake_all_queues(bp->dev); if (bp->link_info.link_up) netif_carrier_on(bp->dev); @@ -9830,6 +9877,12 @@ int bnxt_half_open_nic(struct bnxt *bp) { int rc = 0; + if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) { + netdev_err(bp->dev, "A previous firmware reset has not completed, aborting half open\n"); + rc = -ENODEV; + goto half_open_err; + } + rc = bnxt_alloc_mem(bp, false); if (rc) { netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); @@ -10355,6 +10408,9 @@ static bool bnxt_rfs_supported(struct bnxt *bp) return true; return false; } + /* 212 firmware is broken for aRFS */ + if (BNXT_FW_MAJ(bp) == 212) + return false; if (BNXT_PF(bp) && !BNXT_CHIP_TYPE_NITRO_A0(bp)) return true; if (bp->flags & BNXT_FLAG_NEW_RSS_CAP) @@ -11353,6 +11409,8 @@ static void bnxt_fw_init_one_p3(struct bnxt *bp) bnxt_hwrm_coal_params_qcaps(bp); } +static int bnxt_probe_phy(struct bnxt *bp, bool fw_dflt); + static int bnxt_fw_init_one(struct bnxt *bp) { int rc; @@ -11367,6 +11425,9 @@ static int bnxt_fw_init_one(struct bnxt *bp) netdev_err(bp->dev, "Firmware init phase 2 failed\n"); return rc; } + rc = bnxt_probe_phy(bp, false); + if (rc) + return rc; rc = bnxt_approve_mac(bp, bp->dev->dev_addr, false); if (rc) return rc; @@ -11475,6 +11536,10 @@ static void bnxt_fw_reset_task(struct work_struct *work) } bp->fw_reset_timestamp = jiffies; rtnl_lock(); + if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state)) { + rtnl_unlock(); + goto fw_reset_abort; + } bnxt_fw_reset_close(bp); if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) { bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN; @@ -12741,6 +12806,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) bnxt_hwrm_func_drv_unrgtr(bp); bnxt_free_hwrm_short_cmd_req(bp); bnxt_free_hwrm_resources(bp); + bnxt_ethtool_free(bp); kfree(bp->fw_health); bp->fw_health = NULL; bnxt_cleanup_pci(bp); @@ -12895,7 +12961,8 @@ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev, if (netif_running(netdev)) bnxt_close(netdev); - pci_disable_device(pdev); + if (pci_is_enabled(pdev)) + pci_disable_device(pdev); bnxt_free_ctx_mem(bp); kfree(bp->ctx); bp->ctx = NULL; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index a95c5afa2f01..95d10e7bbb04 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -770,6 +770,7 @@ struct bnxt_tx_ring_info { u16 tx_prod; u16 tx_cons; u16 txq_index; + u8 kick_pending; struct bnxt_db_info tx_db; struct tx_bd *tx_desc_ring[MAX_TX_PAGES]; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c index 64dbbb04b043..abf169001bf3 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c @@ -479,15 +479,16 @@ struct bnxt_en_dev *bnxt_ulp_probe(struct net_device *dev) if (!edev) return ERR_PTR(-ENOMEM); edev->en_ops = &bnxt_en_ops_tbl; - if (bp->flags & BNXT_FLAG_ROCEV1_CAP) - edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP; - if (bp->flags & BNXT_FLAG_ROCEV2_CAP) - edev->flags |= BNXT_EN_FLAG_ROCEV2_CAP; edev->net = dev; edev->pdev = bp->pdev; edev->l2_db_size = bp->db_size; edev->l2_db_size_nc = bp->db_size; bp->edev = edev; } + edev->flags &= ~BNXT_EN_FLAG_ROCE_CAP; + if (bp->flags & BNXT_FLAG_ROCEV1_CAP) + edev->flags |= BNXT_EN_FLAG_ROCEV1_CAP; + if (bp->flags & BNXT_FLAG_ROCEV2_CAP) + edev->flags |= BNXT_EN_FLAG_ROCEV2_CAP; return bp->edev; } diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index fcca023f22e5..db74241935ab 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1640,7 +1640,8 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv, switch (mode) { case GENET_POWER_PASSIVE: - reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS); + reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS | + EXT_ENERGY_DET_MASK); if (GENET_IS_V5(priv)) { reg &= ~(EXT_PWR_DOWN_PHY_EN | EXT_PWR_DOWN_PHY_RD | @@ -3237,15 +3238,21 @@ static void bcmgenet_get_hw_addr(struct bcmgenet_priv *priv, /* Returns a reusable dma control register value */ static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv) { + unsigned int i; u32 reg; u32 dma_ctrl; /* disable DMA */ dma_ctrl = 1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT) | DMA_EN; + for (i = 0; i < priv->hw_params->tx_queues; i++) + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); reg = bcmgenet_tdma_readl(priv, DMA_CTRL); reg &= ~dma_ctrl; bcmgenet_tdma_writel(priv, reg, DMA_CTRL); + dma_ctrl = 1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT) | DMA_EN; + for (i = 0; i < priv->hw_params->rx_queues; i++) + dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT)); reg = bcmgenet_rdma_readl(priv, DMA_CTRL); reg &= ~dma_ctrl; bcmgenet_rdma_writel(priv, reg, DMA_CTRL); @@ -3292,7 +3299,6 @@ static int bcmgenet_open(struct net_device *dev) { struct bcmgenet_priv *priv = netdev_priv(dev); unsigned long dma_ctrl; - u32 reg; int ret; netif_dbg(priv, ifup, dev, "bcmgenet_open\n"); @@ -3318,12 +3324,6 @@ static int bcmgenet_open(struct net_device *dev) bcmgenet_set_hw_addr(priv, dev->dev_addr); - if (priv->internal_phy) { - reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); - reg |= EXT_ENERGY_DET_MASK; - bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); - } - /* Disable RX/TX DMA and flush TX queues */ dma_ctrl = bcmgenet_dma_disable(priv); @@ -4139,7 +4139,6 @@ static int bcmgenet_resume(struct device *d) struct bcmgenet_priv *priv = netdev_priv(dev); struct bcmgenet_rxnfc_rule *rule; unsigned long dma_ctrl; - u32 reg; int ret; if (!netif_running(dev)) @@ -4176,12 +4175,6 @@ static int bcmgenet_resume(struct device *d) if (rule->state != BCMGENET_RXNFC_STATE_UNUSED) bcmgenet_hfb_create_rxnfc_filter(priv, rule); - if (priv->internal_phy) { - reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); - reg |= EXT_ENERGY_DET_MASK; - bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); - } - /* Disable RX/TX DMA and flush TX queues */ dma_ctrl = bcmgenet_dma_disable(priv); @@ -4296,3 +4289,4 @@ MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom GENET Ethernet controller driver"); MODULE_ALIAS("platform:bcmgenet"); MODULE_LICENSE("GPL"); +MODULE_SOFTDEP("pre: mdio-bcm-unimac"); diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c index 1c86eddb1b51..e84ad587fb21 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c @@ -187,12 +187,6 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, reg |= CMD_RX_EN; bcmgenet_umac_writel(priv, reg, UMAC_CMD); - if (priv->hw_params->flags & GENET_HAS_EXT) { - reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT); - reg &= ~EXT_ENERGY_DET_MASK; - bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); - } - reg = UMAC_IRQ_MPD_R; if (hfb_enable) reg |= UMAC_IRQ_HFB_SM | UMAC_IRQ_HFB_MM; diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 6fb6c3556285..f9e91304d232 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -423,6 +423,10 @@ static int bcmgenet_mii_register(struct bcmgenet_priv *priv) int id, ret; pres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!pres) { + dev_err(&pdev->dev, "Invalid resource\n"); + return -EINVAL; + } memset(&res, 0, sizeof(res)); memset(&ppd, 0, sizeof(ppd)); diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 390f45e49eaf..1e8bf6b9834b 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -2709,6 +2709,9 @@ static struct net_device_stats *gem_get_stats(struct macb *bp) struct gem_stats *hwstat = &bp->hw_stats.gem; struct net_device_stats *nstat = &bp->dev->stats; + if (!netif_running(bp->dev)) + return nstat; + gem_update_stats(bp); nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors + diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c index 283918aeb741..09d64a29f56e 100644 --- a/drivers/net/ethernet/cadence/macb_ptp.c +++ b/drivers/net/ethernet/cadence/macb_ptp.c @@ -275,6 +275,12 @@ void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb, if (GEM_BFEXT(DMA_RXVALID, desc->addr)) { desc_ptp = macb_ptp_desc(bp, desc); + /* Unlikely but check */ + if (!desc_ptp) { + dev_warn_ratelimited(&bp->pdev->dev, + "Timestamp not supported in BD\n"); + return; + } gem_hw_timestamp(bp, desc_ptp->ts_1, desc_ptp->ts_2, &ts); memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps)); shhwtstamps->hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec); @@ -307,8 +313,11 @@ int gem_ptp_txstamp(struct macb_queue *queue, struct sk_buff *skb, if (CIRC_SPACE(head, tail, PTP_TS_BUFFER_SIZE) == 0) return -ENOMEM; - skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; desc_ptp = macb_ptp_desc(queue->bp, desc); + /* Unlikely but check */ + if (!desc_ptp) + return -EINVAL; + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; tx_timestamp = &queue->tx_timestamps[head]; tx_timestamp->skb = skb; /* ensure ts_1/ts_2 is loaded after ctrl (TX_USED check) */ diff --git a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c index 4cddd628d41b..9ed3d1ab2ca5 100644 --- a/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c +++ b/drivers/net/ethernet/cavium/liquidio/cn23xx_pf_device.c @@ -420,7 +420,7 @@ static int cn23xx_pf_setup_global_input_regs(struct octeon_device *oct) * bits 32:47 indicate the PVF num. */ for (q_no = 0; q_no < ern; q_no++) { - reg_val = oct->pcie_port << CN23XX_PKT_INPUT_CTL_MAC_NUM_POS; + reg_val = (u64)oct->pcie_port << CN23XX_PKT_INPUT_CTL_MAC_NUM_POS; /* for VF assigned queues. */ if (q_no < oct->sriov_info.pf_srn) { diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c index 61ea3ec5c3fc..83ed10ac8660 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c @@ -1337,13 +1337,27 @@ static int cxgb4_ethtool_flash_phy(struct net_device *netdev, return ret; } - spin_lock_bh(&adap->win0_lock); + /* We have to RESET the chip/firmware because we need the + * chip in uninitialized state for loading new PHY image. + * Otherwise, the running firmware will only store the PHY + * image in local RAM which will be lost after next reset. + */ + ret = t4_fw_reset(adap, adap->mbox, PIORSTMODE_F | PIORST_F); + if (ret < 0) { + dev_err(adap->pdev_dev, + "Set FW to RESET for flashing PHY FW failed. ret: %d\n", + ret); + return ret; + } + ret = t4_load_phy_fw(adap, MEMWIN_NIC, NULL, data, size); - spin_unlock_bh(&adap->win0_lock); - if (ret) - dev_err(adap->pdev_dev, "Failed to load PHY FW\n"); + if (ret < 0) { + dev_err(adap->pdev_dev, "Failed to load PHY FW. ret: %d\n", + ret); + return ret; + } - return ret; + return 0; } static int cxgb4_ethtool_flash_fw(struct net_device *netdev, @@ -1610,16 +1624,14 @@ static struct filter_entry *cxgb4_get_filter_entry(struct adapter *adap, u32 ftid) { struct tid_info *t = &adap->tids; - struct filter_entry *f; - if (ftid < t->nhpftids) - f = &adap->tids.hpftid_tab[ftid]; - else if (ftid < t->nftids) - f = &adap->tids.ftid_tab[ftid - t->nhpftids]; - else - f = lookup_tid(&adap->tids, ftid); + if (ftid >= t->hpftid_base && ftid < t->hpftid_base + t->nhpftids) + return &t->hpftid_tab[ftid - t->hpftid_base]; - return f; + if (ftid >= t->ftid_base && ftid < t->ftid_base + t->nftids) + return &t->ftid_tab[ftid - t->ftid_base]; + + return lookup_tid(t, ftid); } static void cxgb4_fill_filter_rule(struct ethtool_rx_flow_spec *fs, @@ -1826,6 +1838,11 @@ static int cxgb4_ntuple_del_filter(struct net_device *dev, filter_id = filter_info->loc_array[cmd->fs.location]; f = cxgb4_get_filter_entry(adapter, filter_id); + if (f->fs.prio) + filter_id -= adapter->tids.hpftid_base; + else if (!f->fs.hash) + filter_id -= (adapter->tids.ftid_base - adapter->tids.nhpftids); + ret = cxgb4_flow_rule_destroy(dev, f->fs.tc_prio, &f->fs, filter_id); if (ret) goto err; @@ -1885,6 +1902,11 @@ static int cxgb4_ntuple_set_filter(struct net_device *netdev, filter_info = &adapter->ethtool_filters->port[pi->port_id]; + if (fs.prio) + tid += adapter->tids.hpftid_base; + else if (!fs.hash) + tid += (adapter->tids.ftid_base - adapter->tids.nhpftids); + filter_info->loc_array[cmd->fs.location] = tid; set_bit(cmd->fs.location, filter_info->bmap); filter_info->in_use++; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c index e664e05b9f02..5fbc087268db 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c @@ -198,7 +198,7 @@ static void set_nat_params(struct adapter *adap, struct filter_entry *f, WORD_MASK, f->fs.nat_lip[3] | f->fs.nat_lip[2] << 8 | f->fs.nat_lip[1] << 16 | - (u64)f->fs.nat_lip[0] << 25, 1); + (u64)f->fs.nat_lip[0] << 24, 1); } } diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 04dcb5e4b316..3c28a1c3c1ed 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -2643,6 +2643,9 @@ static void detach_ulds(struct adapter *adap) { unsigned int i; + if (!is_uld(adap)) + return; + mutex_lock(&uld_mutex); list_del(&adap->list_node); @@ -4428,10 +4431,8 @@ static int adap_init0_phy(struct adapter *adap) /* Load PHY Firmware onto adapter. */ - spin_lock_bh(&adap->win0_lock); ret = t4_load_phy_fw(adap, MEMWIN_NIC, phy_info->phy_fw_version, (u8 *)phyf->data, phyf->size); - spin_unlock_bh(&adap->win0_lock); if (ret < 0) dev_err(adap->pdev_dev, "PHY Firmware transfer error %d\n", -ret); @@ -5071,6 +5072,7 @@ static int adap_init0(struct adapter *adap, int vpd_skip) ret = -ENOMEM; goto bye; } + bitmap_zero(adap->sge.blocked_fl, adap->sge.egr_sz); #endif params[0] = FW_PARAM_PFVF(CLIP_START); @@ -6791,13 +6793,11 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) setup_memwin(adapter); err = adap_init0(adapter, 0); -#ifdef CONFIG_DEBUG_FS - bitmap_zero(adapter->sge.blocked_fl, adapter->sge.egr_sz); -#endif - setup_memwin_rdma(adapter); if (err) goto out_unmap_bar; + setup_memwin_rdma(adapter); + /* configure SGE_STAT_CFG_A to read WC stats */ if (!is_t4(adapter->params.chip)) t4_write_reg(adapter, SGE_STAT_CFG_A, STATSOURCE_T5_V(7) | @@ -7147,10 +7147,13 @@ static void remove_one(struct pci_dev *pdev) */ destroy_workqueue(adapter->workq); - if (is_uld(adapter)) { - detach_ulds(adapter); - t4_uld_clean_up(adapter); - } + detach_ulds(adapter); + + for_each_port(adapter, i) + if (adapter->port[i]->reg_state == NETREG_REGISTERED) + unregister_netdev(adapter->port[i]); + + t4_uld_clean_up(adapter); adap_free_hma_mem(adapter); @@ -7158,10 +7161,6 @@ static void remove_one(struct pci_dev *pdev) cxgb4_free_mps_ref_entries(adapter); - for_each_port(adapter, i) - if (adapter->port[i]->reg_state == NETREG_REGISTERED) - unregister_netdev(adapter->port[i]); - debugfs_remove_recursive(adapter->debugfs_root); if (!is_t4(adapter->params.chip)) diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c index 743af9e654aa..17faac715882 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c @@ -581,6 +581,9 @@ void t4_uld_clean_up(struct adapter *adap) { unsigned int i; + if (!is_uld(adap)) + return; + mutex_lock(&uld_mutex); for (i = 0; i < CXGB4_ULD_MAX; i++) { if (!adap->uld[i].handle) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 581670dced6e..964ea3491b80 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -3067,16 +3067,19 @@ int t4_read_flash(struct adapter *adapter, unsigned int addr, * @addr: the start address to write * @n: length of data to write in bytes * @data: the data to write + * @byte_oriented: whether to store data as bytes or as words * * Writes up to a page of data (256 bytes) to the serial flash starting * at the given address. All the data must be written to the same page. + * If @byte_oriented is set the write data is stored as byte stream + * (i.e. matches what on disk), otherwise in big-endian. */ static int t4_write_flash(struct adapter *adapter, unsigned int addr, - unsigned int n, const u8 *data) + unsigned int n, const u8 *data, bool byte_oriented) { - int ret; - u32 buf[64]; unsigned int i, c, left, val, offset = addr & 0xff; + u32 buf[64]; + int ret; if (addr >= adapter->params.sf_size || offset + n > SF_PAGE_SIZE) return -EINVAL; @@ -3087,10 +3090,14 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr, (ret = sf1_write(adapter, 4, 1, 1, val)) != 0) goto unlock; - for (left = n; left; left -= c) { + for (left = n; left; left -= c, data += c) { c = min(left, 4U); - for (val = 0, i = 0; i < c; ++i) - val = (val << 8) + *data++; + for (val = 0, i = 0; i < c; ++i) { + if (byte_oriented) + val = (val << 8) + data[i]; + else + val = (val << 8) + data[c - i - 1]; + } ret = sf1_write(adapter, c, c != left, 1, val); if (ret) @@ -3103,7 +3110,8 @@ static int t4_write_flash(struct adapter *adapter, unsigned int addr, t4_write_reg(adapter, SF_OP_A, 0); /* unlock SF */ /* Read the page to verify the write succeeded */ - ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 1); + ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, + byte_oriented); if (ret) return ret; @@ -3699,7 +3707,7 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size) */ memcpy(first_page, fw_data, SF_PAGE_SIZE); ((struct fw_hdr *)first_page)->fw_ver = cpu_to_be32(0xffffffff); - ret = t4_write_flash(adap, fw_start, SF_PAGE_SIZE, first_page); + ret = t4_write_flash(adap, fw_start, SF_PAGE_SIZE, first_page, true); if (ret) goto out; @@ -3707,14 +3715,14 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size) for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) { addr += SF_PAGE_SIZE; fw_data += SF_PAGE_SIZE; - ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data); + ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data, true); if (ret) goto out; } - ret = t4_write_flash(adap, - fw_start + offsetof(struct fw_hdr, fw_ver), - sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver); + ret = t4_write_flash(adap, fw_start + offsetof(struct fw_hdr, fw_ver), + sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver, + true); out: if (ret) dev_err(adap->pdev_dev, "firmware download failed, error %d\n", @@ -3819,9 +3827,11 @@ int t4_load_phy_fw(struct adapter *adap, int win, /* Copy the supplied PHY Firmware image to the adapter memory location * allocated by the adapter firmware. */ + spin_lock_bh(&adap->win0_lock); ret = t4_memory_rw(adap, win, mtype, maddr, phy_fw_size, (__be32 *)phy_fw_data, T4_MEMORY_WRITE); + spin_unlock_bh(&adap->win0_lock); if (ret) return ret; @@ -10215,7 +10225,7 @@ int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) n = size - i; else n = SF_PAGE_SIZE; - ret = t4_write_flash(adap, addr, n, cfg_data); + ret = t4_write_flash(adap, addr, n, cfg_data, true); if (ret) goto out; @@ -10684,13 +10694,14 @@ int t4_load_boot(struct adapter *adap, u8 *boot_data, for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) { addr += SF_PAGE_SIZE; boot_data += SF_PAGE_SIZE; - ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, boot_data); + ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, boot_data, + false); if (ret) goto out; } ret = t4_write_flash(adap, boot_sector, SF_PAGE_SIZE, - (const u8 *)header); + (const u8 *)header, false); out: if (ret) @@ -10765,7 +10776,7 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) for (i = 0; i < size; i += SF_PAGE_SIZE) { n = min_t(u32, size - i, SF_PAGE_SIZE); - ret = t4_write_flash(adap, addr, n, cfg_data); + ret = t4_write_flash(adap, addr, n, cfg_data, false); if (ret) goto out; @@ -10777,7 +10788,8 @@ int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size) for (i = 0; i < npad; i++) { u8 data = 0; - ret = t4_write_flash(adap, cfg_addr + size + i, 1, &data); + ret = t4_write_flash(adap, cfg_addr + size + i, 1, &data, + false); if (ret) goto out; } diff --git a/drivers/net/ethernet/dec/tulip/winbond-840.c b/drivers/net/ethernet/dec/tulip/winbond-840.c index 89cbdc1f4857..6161e1c604c0 100644 --- a/drivers/net/ethernet/dec/tulip/winbond-840.c +++ b/drivers/net/ethernet/dec/tulip/winbond-840.c @@ -357,7 +357,7 @@ static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) int i, option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; void __iomem *ioaddr; - i = pci_enable_device(pdev); + i = pcim_enable_device(pdev); if (i) return i; pci_set_master(pdev); @@ -379,7 +379,7 @@ static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) ioaddr = pci_iomap(pdev, TULIP_BAR, netdev_res_size); if (!ioaddr) - goto err_out_free_res; + goto err_out_netdev; for (i = 0; i < 3; i++) ((__le16 *)dev->dev_addr)[i] = cpu_to_le16(eeprom_read(ioaddr, i)); @@ -458,8 +458,6 @@ static int w840_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) err_out_cleardev: pci_iounmap(pdev, ioaddr); -err_out_free_res: - pci_release_regions(pdev); err_out_netdev: free_netdev (dev); return -ENODEV; @@ -1526,7 +1524,6 @@ static void w840_remove1(struct pci_dev *pdev) if (dev) { struct netdev_private *np = netdev_priv(dev); unregister_netdev(dev); - pci_release_regions(pdev); pci_iounmap(pdev, np->base_addr); free_netdev(dev); } diff --git a/drivers/net/ethernet/ec_bhf.c b/drivers/net/ethernet/ec_bhf.c index 46b0dbab8aad..7c992172933b 100644 --- a/drivers/net/ethernet/ec_bhf.c +++ b/drivers/net/ethernet/ec_bhf.c @@ -576,10 +576,12 @@ static void ec_bhf_remove(struct pci_dev *dev) struct ec_bhf_priv *priv = netdev_priv(net_dev); unregister_netdev(net_dev); - free_netdev(net_dev); pci_iounmap(dev, priv->dma_io); pci_iounmap(dev, priv->io); + + free_netdev(net_dev); + pci_release_regions(dev); pci_clear_master(dev); pci_disable_device(dev); diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 701c12c9e033..649c5c429bd7 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -550,7 +550,7 @@ int be_process_mcc(struct be_adapter *adapter) int num = 0, status = 0; struct be_mcc_obj *mcc_obj = &adapter->mcc_obj; - spin_lock_bh(&adapter->mcc_cq_lock); + spin_lock(&adapter->mcc_cq_lock); while ((compl = be_mcc_compl_get(adapter))) { if (compl->flags & CQE_FLAGS_ASYNC_MASK) { @@ -566,7 +566,7 @@ int be_process_mcc(struct be_adapter *adapter) if (num) be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num); - spin_unlock_bh(&adapter->mcc_cq_lock); + spin_unlock(&adapter->mcc_cq_lock); return status; } @@ -581,7 +581,9 @@ static int be_mcc_wait_compl(struct be_adapter *adapter) if (be_check_error(adapter, BE_ERROR_ANY)) return -EIO; + local_bh_disable(); status = be_process_mcc(adapter); + local_bh_enable(); if (atomic_read(&mcc_obj->q.used) == 0) break; diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 676e437d78f6..89697cb09d1c 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -5509,7 +5509,9 @@ static void be_worker(struct work_struct *work) * mcc completions */ if (!netif_running(adapter->netdev)) { + local_bh_disable(); be_process_mcc(adapter); + local_bh_enable(); goto reschedule; } @@ -5905,6 +5907,7 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id) unmap_bars: be_unmap_pci_bars(adapter); free_netdev: + pci_disable_pcie_error_reporting(pdev); free_netdev(netdev); rel_reg: pci_release_regions(pdev); diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c index 815fb62c4b02..3d74401b4f10 100644 --- a/drivers/net/ethernet/ezchip/nps_enet.c +++ b/drivers/net/ethernet/ezchip/nps_enet.c @@ -610,7 +610,7 @@ static s32 nps_enet_probe(struct platform_device *pdev) /* Get IRQ number */ priv->irq = platform_get_irq(pdev, 0); - if (!priv->irq) { + if (priv->irq < 0) { dev_err(dev, "failed to retrieve value from device tree\n"); err = -ENODEV; goto out_netdev; @@ -645,8 +645,8 @@ static s32 nps_enet_remove(struct platform_device *pdev) struct nps_enet_priv *priv = netdev_priv(ndev); unregister_netdev(ndev); - free_netdev(ndev); netif_napi_del(&priv->napi); + free_netdev(ndev); return 0; } diff --git a/drivers/net/ethernet/faraday/ftgmac100.c b/drivers/net/ethernet/faraday/ftgmac100.c index c9c380c50879..5bc11d1bb9df 100644 --- a/drivers/net/ethernet/faraday/ftgmac100.c +++ b/drivers/net/ethernet/faraday/ftgmac100.c @@ -1831,14 +1831,17 @@ static int ftgmac100_probe(struct platform_device *pdev) if (np && of_get_property(np, "use-ncsi", NULL)) { if (!IS_ENABLED(CONFIG_NET_NCSI)) { dev_err(&pdev->dev, "NCSI stack not enabled\n"); + err = -EINVAL; goto err_ncsi_dev; } dev_info(&pdev->dev, "Using NCSI interface\n"); priv->use_ncsi = true; priv->ndev = ncsi_register_dev(netdev, ftgmac100_ncsi_handler); - if (!priv->ndev) + if (!priv->ndev) { + err = -EINVAL; goto err_ncsi_dev; + } } else if (np && of_get_property(np, "phy-handle", NULL)) { struct phy_device *phy; @@ -1846,6 +1849,7 @@ static int ftgmac100_probe(struct platform_device *pdev) &ftgmac100_adjust_link); if (!phy) { dev_err(&pdev->dev, "Failed to connect to phy\n"); + err = -EINVAL; goto err_setup_mdio; } diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 960def41cc55..94eb838a0176 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -75,6 +75,8 @@ static void fec_enet_itr_coal_init(struct net_device *ndev); #define DRIVER_NAME "fec" +static const u16 fec_enet_vlan_pri_to_queue[8] = {0, 0, 1, 1, 1, 2, 2, 2}; + /* Pause frame feild and FIFO threshold */ #define FEC_ENET_FCE (1 << 5) #define FEC_ENET_RSEM_V 0x84 @@ -3222,10 +3224,40 @@ static int fec_set_features(struct net_device *netdev, return 0; } +static u16 fec_enet_get_raw_vlan_tci(struct sk_buff *skb) +{ + struct vlan_ethhdr *vhdr; + unsigned short vlan_TCI = 0; + + if (skb->protocol == htons(ETH_P_ALL)) { + vhdr = (struct vlan_ethhdr *)(skb->data); + vlan_TCI = ntohs(vhdr->h_vlan_TCI); + } + + return vlan_TCI; +} + +static u16 fec_enet_select_queue(struct net_device *ndev, struct sk_buff *skb, + struct net_device *sb_dev) +{ + struct fec_enet_private *fep = netdev_priv(ndev); + u16 vlan_tag; + + if (!(fep->quirks & FEC_QUIRK_HAS_AVB)) + return netdev_pick_tx(ndev, skb, NULL); + + vlan_tag = fec_enet_get_raw_vlan_tci(skb); + if (!vlan_tag) + return vlan_tag; + + return fec_enet_vlan_pri_to_queue[vlan_tag >> 13]; +} + static const struct net_device_ops fec_netdev_ops = { .ndo_open = fec_enet_open, .ndo_stop = fec_enet_close, .ndo_start_xmit = fec_enet_start_xmit, + .ndo_select_queue = fec_enet_select_queue, .ndo_set_rx_mode = set_multicast_list, .ndo_validate_addr = eth_validate_addr, .ndo_tx_timeout = fec_timeout, @@ -3790,13 +3822,13 @@ fec_drv_remove(struct platform_device *pdev) if (of_phy_is_fixed_link(np)) of_phy_deregister_fixed_link(np); of_node_put(fep->phy_node); - free_netdev(ndev); clk_disable_unprepare(fep->clk_ahb); clk_disable_unprepare(fep->clk_ipg); pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); + free_netdev(ndev); return 0; } diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 1753807cbf97..d71eac7e1924 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -215,15 +215,13 @@ static u64 fec_ptp_read(const struct cyclecounter *cc) { struct fec_enet_private *fep = container_of(cc, struct fec_enet_private, cc); - const struct platform_device_id *id_entry = - platform_get_device_id(fep->pdev); u32 tempval; tempval = readl(fep->hwp + FEC_ATIME_CTRL); tempval |= FEC_T_CTRL_CAPTURE; writel(tempval, fep->hwp + FEC_ATIME_CTRL); - if (id_entry->driver_data & FEC_QUIRK_BUG_CAPTURE) + if (fep->quirks & FEC_QUIRK_BUG_CAPTURE) udelay(1); return readl(fep->hwp + FEC_ATIME); @@ -604,6 +602,10 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx) fep->ptp_caps.enable = fec_ptp_enable; fep->cycle_speed = clk_get_rate(fep->clk_ptp); + if (!fep->cycle_speed) { + fep->cycle_speed = NSEC_PER_SEC; + dev_err(&fep->pdev->dev, "clk_ptp clock rate is zero\n"); + } fep->ptp_inc = NSEC_PER_SEC / fep->cycle_speed; spin_lock_init(&fep->tmreg_lock); diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index d6e35421d8f7..0b714b606ba1 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -1286,8 +1286,8 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent) gve_write_version(®_bar->driver_version); /* Get max queues to alloc etherdev */ - max_rx_queues = ioread32be(®_bar->max_tx_queues); - max_tx_queues = ioread32be(®_bar->max_rx_queues); + max_tx_queues = ioread32be(®_bar->max_tx_queues); + max_rx_queues = ioread32be(®_bar->max_rx_queues); /* Alloc and setup the netdev and priv */ dev = alloc_etherdev_mqs(sizeof(*priv), max_tx_queues, max_rx_queues); if (!dev) { @@ -1340,13 +1340,16 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err = register_netdev(dev); if (err) - goto abort_with_wq; + goto abort_with_gve_init; dev_info(&pdev->dev, "GVE version %s\n", gve_version_str); gve_clear_probe_in_progress(priv); queue_work(priv->gve_wq, &priv->service_task); return 0; +abort_with_gve_init: + gve_teardown_priv_resources(priv); + abort_with_wq: destroy_workqueue(priv->gve_wq); diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c index 12f6c2442a7a..e53512f6878a 100644 --- a/drivers/net/ethernet/hisilicon/hip04_eth.c +++ b/drivers/net/ethernet/hisilicon/hip04_eth.c @@ -131,7 +131,7 @@ /* buf unit size is cache_line_size, which is 64, so the shift is 6 */ #define PPE_BUF_SIZE_SHIFT 6 #define PPE_TX_BUF_HOLD BIT(31) -#define CACHE_LINE_MASK 0x3F +#define SOC_CACHE_LINE_MASK 0x3F #else #define PPE_CFG_QOS_VMID_GRP_SHIFT 8 #define PPE_CFG_RX_CTRL_ALIGN_SHIFT 11 @@ -531,8 +531,8 @@ hip04_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev) #if defined(CONFIG_HI13X1_GMAC) desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV | TX_RELEASE_TO_PPE | priv->port << TX_POOL_SHIFT); - desc->data_offset = (__force u32)cpu_to_be32(phys & CACHE_LINE_MASK); - desc->send_addr = (__force u32)cpu_to_be32(phys & ~CACHE_LINE_MASK); + desc->data_offset = (__force u32)cpu_to_be32(phys & SOC_CACHE_LINE_MASK); + desc->send_addr = (__force u32)cpu_to_be32(phys & ~SOC_CACHE_LINE_MASK); #else desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV); desc->send_addr = (__force u32)cpu_to_be32(phys); diff --git a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h index 98a9f5e3fe86..98f55fbe6c3d 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h +++ b/drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h @@ -134,7 +134,8 @@ struct hclge_mbx_vf_to_pf_cmd { u8 mbx_need_resp; u8 rsv1[1]; u8 msg_len; - u8 rsv2[3]; + u8 rsv2; + u16 match_id; struct hclge_vf_to_pf_msg msg; }; @@ -144,7 +145,8 @@ struct hclge_mbx_pf_to_vf_cmd { u8 dest_vfid; u8 rsv[3]; u8 msg_len; - u8 rsv1[3]; + u8 rsv1; + u16 match_id; struct hclge_pf_to_vf_msg msg; }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c index e6321dda0f3f..6f9f759ce0c0 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.c @@ -521,9 +521,13 @@ static void hclge_cmd_uninit_regs(struct hclge_hw *hw) void hclge_cmd_uninit(struct hclge_dev *hdev) { + set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state); + /* wait to ensure that the firmware completes the possible left + * over commands. + */ + msleep(HCLGE_CMDQ_CLEAR_WAIT_TIME); spin_lock_bh(&hdev->hw.cmq.csq.lock); spin_lock(&hdev->hw.cmq.crq.lock); - set_bit(HCLGE_STATE_CMD_DISABLE, &hdev->state); hclge_cmd_uninit_regs(&hdev->hw); spin_unlock(&hdev->hw.cmq.crq.lock); spin_unlock_bh(&hdev->hw.cmq.csq.lock); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index 36690fc5c1af..3d70c3a47d63 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -9,6 +9,7 @@ #include "hnae3.h" #define HCLGE_CMDQ_TX_TIMEOUT 30000 +#define HCLGE_CMDQ_CLEAR_WAIT_TIME 200 #define HCLGE_DESC_DATA_LEN 6 struct hclge_dev; @@ -262,6 +263,9 @@ enum hclge_opcode_type { /* Led command */ HCLGE_OPC_LED_STATUS_CFG = 0xB000, + /* clear hardware resource command */ + HCLGE_OPC_CLEAR_HW_RESOURCE = 0x700B, + /* NCL config command */ HCLGE_OPC_QUERY_NCL_CONFIG = 0x7011, diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c index 3606240025a8..a93c7eb4e7cb 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c @@ -283,21 +283,12 @@ static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc) u64 requests[HNAE3_MAX_TC], indications[HNAE3_MAX_TC]; struct hclge_vport *vport = hclge_get_vport(h); struct hclge_dev *hdev = vport->back; - u8 i, j, pfc_map, *prio_tc; int ret; + u8 i; memset(pfc, 0, sizeof(*pfc)); pfc->pfc_cap = hdev->pfc_max; - prio_tc = hdev->tm_info.prio_tc; - pfc_map = hdev->tm_info.hw_pfc_map; - - /* Pfc setting is based on TC */ - for (i = 0; i < hdev->tm_info.num_tc; i++) { - for (j = 0; j < HNAE3_MAX_USER_PRIO; j++) { - if ((prio_tc[j] == i) && (pfc_map & BIT(i))) - pfc->pfc_en |= BIT(j); - } - } + pfc->pfc_en = hdev->tm_info.pfc_en; ret = hclge_pfc_tx_stats_get(hdev, requests); if (ret) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 98190aa90781..2261de5caf86 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -8792,7 +8792,11 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) static void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, bool writen_to_tbl) { - struct hclge_vport_vlan_cfg *vlan; + struct hclge_vport_vlan_cfg *vlan, *tmp; + + list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node) + if (vlan->vlan_id == vlan_id) + return; vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); if (!vlan) @@ -10030,6 +10034,28 @@ static void hclge_clear_resetting_state(struct hclge_dev *hdev) } } +static int hclge_clear_hw_resource(struct hclge_dev *hdev) +{ + struct hclge_desc desc; + int ret; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CLEAR_HW_RESOURCE, false); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + /* This new command is only supported by new firmware, it will + * fail with older firmware. Error value -EOPNOSUPP can only be + * returned by older firmware running this command, to keep code + * backward compatible we will override this value and return + * success. + */ + if (ret && ret != -EOPNOTSUPP) { + dev_err(&hdev->pdev->dev, + "failed to clear hw resource, ret = %d\n", ret); + return ret; + } + return 0; +} + static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) { struct pci_dev *pdev = ae_dev->pdev; @@ -10067,6 +10093,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) if (ret) goto err_cmd_uninit; + ret = hclge_clear_hw_resource(hdev); + if (ret) + goto err_cmd_uninit; + ret = hclge_get_cap(hdev); if (ret) goto err_cmd_uninit; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index 2c2d53f5c56e..61f6f0287cbe 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -47,6 +47,7 @@ static int hclge_gen_resp_to_vf(struct hclge_vport *vport, resp_pf_to_vf->dest_vfid = vf_to_pf_req->mbx_src_vfid; resp_pf_to_vf->msg_len = vf_to_pf_req->msg_len; + resp_pf_to_vf->match_id = vf_to_pf_req->match_id; resp_pf_to_vf->msg.code = HCLGE_MBX_PF_VF_RESP; resp_pf_to_vf->msg.vf_mbx_msg_code = vf_to_pf_req->msg.code; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c index 66866c1cfb12..cae6db17cb19 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c @@ -472,12 +472,17 @@ static void hclgevf_cmd_uninit_regs(struct hclgevf_hw *hw) void hclgevf_cmd_uninit(struct hclgevf_dev *hdev) { + set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); + /* wait to ensure that the firmware completes the possible left + * over commands. + */ + msleep(HCLGEVF_CMDQ_CLEAR_WAIT_TIME); spin_lock_bh(&hdev->hw.cmq.csq.lock); spin_lock(&hdev->hw.cmq.crq.lock); - set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state); hclgevf_cmd_uninit_regs(&hdev->hw); spin_unlock(&hdev->hw.cmq.crq.lock); spin_unlock_bh(&hdev->hw.cmq.csq.lock); + hclgevf_free_cmd_desc(&hdev->hw.cmq.csq); hclgevf_free_cmd_desc(&hdev->hw.cmq.crq); } diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h index 9460c128c095..f90ff8a84b7e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.h @@ -8,6 +8,7 @@ #include "hnae3.h" #define HCLGEVF_CMDQ_TX_TIMEOUT 30000 +#define HCLGEVF_CMDQ_CLEAR_WAIT_TIME 200 #define HCLGEVF_CMDQ_RX_INVLD_B 0 #define HCLGEVF_CMDQ_RX_OUTVLD_B 1 diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index ac6980acb6f0..d3010d5ab366 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -2518,6 +2518,16 @@ static int hclgevf_rss_init_hw(struct hclgevf_dev *hdev) static int hclgevf_init_vlan_config(struct hclgevf_dev *hdev) { + struct hnae3_handle *nic = &hdev->nic; + int ret; + + ret = hclgevf_en_hw_strip_rxvtag(nic, true); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to enable rx vlan offload, ret = %d\n", ret); + return ret; + } + return hclgevf_set_vlan_filter(&hdev->nic, htons(ETH_P_8021Q), 0, false); } diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index c2e740475786..f63066736425 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -2617,10 +2617,8 @@ static int ehea_restart_qps(struct net_device *dev) u16 dummy16 = 0; cb0 = (void *)get_zeroed_page(GFP_KERNEL); - if (!cb0) { - ret = -ENOMEM; - goto out; - } + if (!cb0) + return -ENOMEM; for (i = 0; i < (port->num_def_qps); i++) { struct ehea_port_res *pr = &port->port_res[i]; @@ -2640,6 +2638,7 @@ static int ehea_restart_qps(struct net_device *dev) cb0); if (hret != H_SUCCESS) { netdev_err(dev, "query_ehea_qp failed (1)\n"); + ret = -EFAULT; goto out; } @@ -2652,6 +2651,7 @@ static int ehea_restart_qps(struct net_device *dev) &dummy64, &dummy16, &dummy16); if (hret != H_SUCCESS) { netdev_err(dev, "modify_ehea_qp failed (1)\n"); + ret = -EFAULT; goto out; } @@ -2660,6 +2660,7 @@ static int ehea_restart_qps(struct net_device *dev) cb0); if (hret != H_SUCCESS) { netdev_err(dev, "query_ehea_qp failed (2)\n"); + ret = -EFAULT; goto out; } diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 8cc444684491..3134c1988db3 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -212,12 +212,11 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter, mutex_lock(&adapter->fw_lock); adapter->fw_done_rc = 0; reinit_completion(&adapter->fw_done); - rc = send_request_map(adapter, ltb->addr, - ltb->size, ltb->map_id); + + rc = send_request_map(adapter, ltb->addr, ltb->size, ltb->map_id); if (rc) { - dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); - mutex_unlock(&adapter->fw_lock); - return rc; + dev_err(dev, "send_request_map failed, rc = %d\n", rc); + goto out; } rc = ibmvnic_wait_for_completion(adapter, &adapter->fw_done, 10000); @@ -225,20 +224,23 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter, dev_err(dev, "Long term map request aborted or timed out,rc = %d\n", rc); - dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); - mutex_unlock(&adapter->fw_lock); - return rc; + goto out; } if (adapter->fw_done_rc) { dev_err(dev, "Couldn't map long term buffer,rc = %d\n", adapter->fw_done_rc); + rc = -1; + goto out; + } + rc = 0; +out: + if (rc) { dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); - mutex_unlock(&adapter->fw_lock); - return -1; + ltb->buff = NULL; } mutex_unlock(&adapter->fw_lock); - return 0; + return rc; } static void free_long_term_buff(struct ibmvnic_adapter *adapter, @@ -258,6 +260,8 @@ static void free_long_term_buff(struct ibmvnic_adapter *adapter, adapter->reset_reason != VNIC_RESET_TIMEOUT) send_request_unmap(adapter, ltb->map_id); dma_free_coherent(dev, ltb->size, ltb->buff, ltb->addr); + ltb->buff = NULL; + ltb->map_id = 0; } static int reset_long_term_buff(struct ibmvnic_adapter *adapter, @@ -747,8 +751,11 @@ static int init_tx_pools(struct net_device *netdev) adapter->tso_pool = kcalloc(tx_subcrqs, sizeof(struct ibmvnic_tx_pool), GFP_KERNEL); - if (!adapter->tso_pool) + if (!adapter->tso_pool) { + kfree(adapter->tx_pool); + adapter->tx_pool = NULL; return -1; + } adapter->num_active_tx_pools = tx_subcrqs; @@ -1166,6 +1173,11 @@ static int __ibmvnic_open(struct net_device *netdev) netif_tx_start_all_queues(netdev); + if (prev_state == VNIC_CLOSED) { + for (i = 0; i < adapter->req_rx_queues; i++) + napi_schedule(&adapter->napi[i]); + } + adapter->state = VNIC_OPEN; return rc; } diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 8cc651d37a7f..609e47b8287d 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -1395,7 +1395,7 @@ static int e100_phy_check_without_mii(struct nic *nic) u8 phy_type; int without_mii; - phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f; + phy_type = (le16_to_cpu(nic->eeprom[eeprom_phy_iface]) >> 8) & 0x0f; switch (phy_type) { case NoSuchPhy: /* Non-MII PHY; UNTESTED! */ @@ -1515,7 +1515,7 @@ static int e100_phy_init(struct nic *nic) mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr); } else if ((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && - (nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled))) { + (le16_to_cpu(nic->eeprom[eeprom_cnfg_mdix]) & eeprom_mdix_enabled))) { /* enable/disable MDI/MDI-X auto-switching. */ mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH); @@ -2263,9 +2263,9 @@ static int e100_asf(struct nic *nic) { /* ASF can be enabled from eeprom */ return (nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) && - (nic->eeprom[eeprom_config_asf] & eeprom_asf) && - !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) && - ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE); + (le16_to_cpu(nic->eeprom[eeprom_config_asf]) & eeprom_asf) && + !(le16_to_cpu(nic->eeprom[eeprom_config_asf]) & eeprom_gcl) && + ((le16_to_cpu(nic->eeprom[eeprom_smbus_addr]) & 0xFF) != 0xFE); } static int e100_up(struct nic *nic) @@ -2920,7 +2920,7 @@ static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Wol magic packet can be enabled from eeprom */ if ((nic->mac >= mac_82558_D101_A4) && - (nic->eeprom[eeprom_id] & eeprom_id_wol)) { + (le16_to_cpu(nic->eeprom[eeprom_id]) & eeprom_id_wol)) { nic->flags |= wol_magic; device_set_wakeup_enable(&pdev->dev, true); } diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 6fb46682b058..854c585de2e1 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1006,6 +1006,8 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link) { u32 reg = link << (E1000_LTRV_REQ_SHIFT + E1000_LTRV_NOSNOOP_SHIFT) | link << E1000_LTRV_REQ_SHIFT | E1000_LTRV_SEND; + u16 max_ltr_enc_d = 0; /* maximum LTR decoded by platform */ + u16 lat_enc_d = 0; /* latency decoded */ u16 lat_enc = 0; /* latency encoded */ if (link) { @@ -1059,7 +1061,17 @@ static s32 e1000_platform_pm_pch_lpt(struct e1000_hw *hw, bool link) E1000_PCI_LTR_CAP_LPT + 2, &max_nosnoop); max_ltr_enc = max_t(u16, max_snoop, max_nosnoop); - if (lat_enc > max_ltr_enc) + lat_enc_d = (lat_enc & E1000_LTRV_VALUE_MASK) * + (1U << (E1000_LTRV_SCALE_FACTOR * + ((lat_enc & E1000_LTRV_SCALE_MASK) + >> E1000_LTRV_SCALE_SHIFT))); + + max_ltr_enc_d = (max_ltr_enc & E1000_LTRV_VALUE_MASK) * + (1U << (E1000_LTRV_SCALE_FACTOR * + ((max_ltr_enc & E1000_LTRV_SCALE_MASK) + >> E1000_LTRV_SCALE_SHIFT))); + + if (lat_enc_d > max_ltr_enc_d) lat_enc = max_ltr_enc; } @@ -4122,13 +4134,17 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) return ret_val; if (!(data & valid_csum_mask)) { - data |= valid_csum_mask; - ret_val = e1000_write_nvm(hw, word, 1, &data); - if (ret_val) - return ret_val; - ret_val = e1000e_update_nvm_checksum(hw); - if (ret_val) - return ret_val; + e_dbg("NVM Checksum Invalid\n"); + + if (hw->mac.type < e1000_pch_cnp) { + data |= valid_csum_mask; + ret_val = e1000_write_nvm(hw, word, 1, &data); + if (ret_val) + return ret_val; + ret_val = e1000e_update_nvm_checksum(hw); + if (ret_val) + return ret_val; + } } return e1000e_validate_nvm_checksum_generic(hw); diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h index 1502895eb45d..e757896287eb 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.h +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h @@ -274,8 +274,11 @@ /* Latency Tolerance Reporting */ #define E1000_LTRV 0x000F8 +#define E1000_LTRV_VALUE_MASK 0x000003FF #define E1000_LTRV_SCALE_MAX 5 #define E1000_LTRV_SCALE_FACTOR 5 +#define E1000_LTRV_SCALE_SHIFT 10 +#define E1000_LTRV_SCALE_MASK 0x00001C00 #define E1000_LTRV_REQ_SHIFT 15 #define E1000_LTRV_NOSNOOP_SHIFT 16 #define E1000_LTRV_SEND (1 << 30) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index a0948002ddf8..361b8d0bd78d 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5222,18 +5222,20 @@ static void e1000_watchdog_task(struct work_struct *work) pm_runtime_resume(netdev->dev.parent); /* Checking if MAC is in DMoff state*/ - pcim_state = er32(STATUS); - while (pcim_state & E1000_STATUS_PCIM_STATE) { - if (tries++ == dmoff_exit_timeout) { - e_dbg("Error in exiting dmoff\n"); - break; - } - usleep_range(10000, 20000); + if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) { pcim_state = er32(STATUS); - - /* Checking if MAC exited DMoff state */ - if (!(pcim_state & E1000_STATUS_PCIM_STATE)) - e1000_phy_hw_reset(&adapter->hw); + while (pcim_state & E1000_STATUS_PCIM_STATE) { + if (tries++ == dmoff_exit_timeout) { + e_dbg("Error in exiting dmoff\n"); + break; + } + usleep_range(10000, 20000); + pcim_state = er32(STATUS); + + /* Checking if MAC exited DMoff state */ + if (!(pcim_state & E1000_STATUS_PCIM_STATE)) + e1000_phy_hw_reset(&adapter->hw); + } } /* update snapshot of PHY registers on LSC */ @@ -7655,6 +7657,7 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err_ioremap: free_netdev(netdev); err_alloc_etherdev: + pci_disable_pcie_error_reporting(pdev); pci_release_mem_regions(pdev); err_pci_reg: err_dma: diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c index 9e3103fae723..caedf24c24c1 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_pci.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_pci.c @@ -2227,6 +2227,7 @@ static int fm10k_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err_ioremap: free_netdev(netdev); err_alloc_netdev: + pci_disable_pcie_error_reporting(pdev); pci_release_mem_regions(pdev); err_pci_reg: err_dma: diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 5d48bc0c3f6c..a2bdb2906519 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -980,7 +980,7 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw, default: /* if we got here and link is up something bad is afoot */ netdev_info(netdev, - "WARNING: Link is up but PHY type 0x%x is not recognized.\n", + "WARNING: Link is up but PHY type 0x%x is not recognized, or incorrect cable is in use\n", hw_link_info->phy_type); } @@ -1262,8 +1262,7 @@ static int i40e_set_link_ksettings(struct net_device *netdev, if (ethtool_link_ksettings_test_link_mode(&safe_ks, supported, Autoneg) && - hw->phy.link_info.phy_type != - I40E_PHY_TYPE_10GBASE_T) { + hw->phy.media_type != I40E_MEDIA_TYPE_BASET) { netdev_info(netdev, "Autoneg cannot be disabled on this phy\n"); err = -EINVAL; goto done; @@ -5107,6 +5106,10 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags) dev_warn(&pf->pdev->dev, "Device configuration forbids SW from starting the LLDP agent.\n"); return -EINVAL; + case I40E_AQ_RC_EAGAIN: + dev_warn(&pf->pdev->dev, + "Stop FW LLDP agent command is still being processed, please try again in a second.\n"); + return -EBUSY; default: dev_warn(&pf->pdev->dev, "Starting FW LLDP agent failed: error: %s, %s\n", diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index f0edea7cdbcc..bc648ce0743c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -31,7 +31,7 @@ static void i40e_vsi_reinit_locked(struct i40e_vsi *vsi); static void i40e_handle_reset_warning(struct i40e_pf *pf, bool lock_acquired); static int i40e_add_vsi(struct i40e_vsi *vsi); static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi); -static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit); +static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acquired); static int i40e_setup_misc_vector(struct i40e_pf *pf); static void i40e_determine_queue_usage(struct i40e_pf *pf); static int i40e_setup_pf_filter_control(struct i40e_pf *pf); @@ -4425,11 +4425,10 @@ int i40e_control_wait_tx_q(int seid, struct i40e_pf *pf, int pf_q, } /** - * i40e_vsi_control_tx - Start or stop a VSI's rings + * i40e_vsi_enable_tx - Start a VSI's rings * @vsi: the VSI being configured - * @enable: start or stop the rings **/ -static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) +static int i40e_vsi_enable_tx(struct i40e_vsi *vsi) { struct i40e_pf *pf = vsi->back; int i, pf_q, ret = 0; @@ -4438,7 +4437,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { ret = i40e_control_wait_tx_q(vsi->seid, pf, pf_q, - false /*is xdp*/, enable); + false /*is xdp*/, true); if (ret) break; @@ -4447,7 +4446,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable) ret = i40e_control_wait_tx_q(vsi->seid, pf, pf_q + vsi->alloc_queue_pairs, - true /*is xdp*/, enable); + true /*is xdp*/, true); if (ret) break; } @@ -4545,32 +4544,25 @@ int i40e_control_wait_rx_q(struct i40e_pf *pf, int pf_q, bool enable) } /** - * i40e_vsi_control_rx - Start or stop a VSI's rings + * i40e_vsi_enable_rx - Start a VSI's rings * @vsi: the VSI being configured - * @enable: start or stop the rings **/ -static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable) +static int i40e_vsi_enable_rx(struct i40e_vsi *vsi) { struct i40e_pf *pf = vsi->back; int i, pf_q, ret = 0; pf_q = vsi->base_queue; for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) { - ret = i40e_control_wait_rx_q(pf, pf_q, enable); + ret = i40e_control_wait_rx_q(pf, pf_q, true); if (ret) { dev_info(&pf->pdev->dev, - "VSI seid %d Rx ring %d %sable timeout\n", - vsi->seid, pf_q, (enable ? "en" : "dis")); + "VSI seid %d Rx ring %d enable timeout\n", + vsi->seid, pf_q); break; } } - /* Due to HW errata, on Rx disable only, the register can indicate done - * before it really is. Needs 50ms to be sure - */ - if (!enable) - mdelay(50); - return ret; } @@ -4583,29 +4575,47 @@ int i40e_vsi_start_rings(struct i40e_vsi *vsi) int ret = 0; /* do rx first for enable and last for disable */ - ret = i40e_vsi_control_rx(vsi, true); + ret = i40e_vsi_enable_rx(vsi); if (ret) return ret; - ret = i40e_vsi_control_tx(vsi, true); + ret = i40e_vsi_enable_tx(vsi); return ret; } +#define I40E_DISABLE_TX_GAP_MSEC 50 + /** * i40e_vsi_stop_rings - Stop a VSI's rings * @vsi: the VSI being configured **/ void i40e_vsi_stop_rings(struct i40e_vsi *vsi) { + struct i40e_pf *pf = vsi->back; + int pf_q, err, q_end; + /* When port TX is suspended, don't wait */ if (test_bit(__I40E_PORT_SUSPENDED, vsi->back->state)) return i40e_vsi_stop_rings_no_wait(vsi); - /* do rx first for enable and last for disable - * Ignore return value, we need to shutdown whatever we can - */ - i40e_vsi_control_tx(vsi, false); - i40e_vsi_control_rx(vsi, false); + q_end = vsi->base_queue + vsi->num_queue_pairs; + for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) + i40e_pre_tx_queue_cfg(&pf->hw, (u32)pf_q, false); + + for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) { + err = i40e_control_wait_rx_q(pf, pf_q, false); + if (err) + dev_info(&pf->pdev->dev, + "VSI seid %d Rx ring %d dissable timeout\n", + vsi->seid, pf_q); + } + + msleep(I40E_DISABLE_TX_GAP_MSEC); + pf_q = vsi->base_queue; + for (pf_q = vsi->base_queue; pf_q < q_end; pf_q++) + wr32(&pf->hw, I40E_QTX_ENA(pf_q), 0); + + i40e_vsi_wait_queues_disabled(vsi); } /** @@ -6923,6 +6933,8 @@ static int i40e_validate_mqprio_qopt(struct i40e_vsi *vsi, } if (vsi->num_queue_pairs < (mqprio_qopt->qopt.offset[i] + mqprio_qopt->qopt.count[i])) { + dev_err(&vsi->back->pdev->dev, + "Failed to create traffic channel, insufficient number of queues.\n"); return -EINVAL; } if (sum_max_rate > i40e_get_link_speed(vsi)) { @@ -8347,6 +8359,8 @@ int i40e_vsi_open(struct i40e_vsi *vsi) dev_driver_string(&pf->pdev->dev), dev_name(&pf->pdev->dev)); err = i40e_vsi_request_irq(vsi, int_name); + if (err) + goto err_setup_rx; } else { err = -EINVAL; @@ -10112,7 +10126,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) /* do basic switch setup */ if (!lock_acquired) rtnl_lock(); - ret = i40e_setup_pf_switch(pf, reinit); + ret = i40e_setup_pf_switch(pf, reinit, true); if (ret) goto end_unlock; @@ -12797,6 +12811,7 @@ static const struct net_device_ops i40e_netdev_ops = { .ndo_poll_controller = i40e_netpoll, #endif .ndo_setup_tc = __i40e_setup_tc, + .ndo_select_queue = i40e_lan_select_queue, .ndo_set_features = i40e_set_features, .ndo_set_vf_mac = i40e_ndo_set_vf_mac, .ndo_set_vf_vlan = i40e_ndo_set_vf_port_vlan, @@ -14167,10 +14182,11 @@ int i40e_fetch_switch_configuration(struct i40e_pf *pf, bool printconfig) * i40e_setup_pf_switch - Setup the HW switch on startup or after reset * @pf: board private structure * @reinit: if the Main VSI needs to re-initialized. + * @lock_acquired: indicates whether or not the lock has been acquired * * Returns 0 on success, negative value on failure **/ -static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit) +static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acquired) { u16 flags = 0; int ret; @@ -14272,9 +14288,15 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit) i40e_ptp_init(pf); + if (!lock_acquired) + rtnl_lock(); + /* repopulate tunnel port filters */ udp_tunnel_nic_reset_ntf(pf->vsi[pf->lan_vsi]->netdev); + if (!lock_acquired) + rtnl_unlock(); + return ret; } @@ -15046,7 +15068,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pf->flags |= I40E_FLAG_VEB_MODE_ENABLED; } #endif - err = i40e_setup_pf_switch(pf, false); + err = i40e_setup_pf_switch(pf, false, false); if (err) { dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err); goto err_vsis; diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c index 7a879614ca55..1dad6c93ac9c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c @@ -11,13 +11,14 @@ * operate with the nanosecond field directly without fear of overflow. * * Much like the 82599, the update period is dependent upon the link speed: - * At 40Gb link or no link, the period is 1.6ns. - * At 10Gb link, the period is multiplied by 2. (3.2ns) + * At 40Gb, 25Gb, or no link, the period is 1.6ns. + * At 10Gb or 5Gb link, the period is multiplied by 2. (3.2ns) * At 1Gb link, the period is multiplied by 20. (32ns) * 1588 functionality is not supported at 100Mbps. */ #define I40E_PTP_40GB_INCVAL 0x0199999999ULL #define I40E_PTP_10GB_INCVAL_MULT 2 +#define I40E_PTP_5GB_INCVAL_MULT 2 #define I40E_PTP_1GB_INCVAL_MULT 20 #define I40E_PRTTSYN_CTL1_TSYNTYPE_V1 BIT(I40E_PRTTSYN_CTL1_TSYNTYPE_SHIFT) @@ -465,6 +466,9 @@ void i40e_ptp_set_increment(struct i40e_pf *pf) case I40E_LINK_SPEED_10GB: mult = I40E_PTP_10GB_INCVAL_MULT; break; + case I40E_LINK_SPEED_5GB: + mult = I40E_PTP_5GB_INCVAL_MULT; + break; case I40E_LINK_SPEED_1GB: mult = I40E_PTP_1GB_INCVAL_MULT; break; diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index c40ac82db863..5ad28129fab2 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -3524,6 +3524,55 @@ static inline int i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb, return -1; } +static u16 i40e_swdcb_skb_tx_hash(struct net_device *dev, + const struct sk_buff *skb, + u16 num_tx_queues) +{ + u32 jhash_initval_salt = 0xd631614b; + u32 hash; + + if (skb->sk && skb->sk->sk_hash) + hash = skb->sk->sk_hash; + else + hash = (__force u16)skb->protocol ^ skb->hash; + + hash = jhash_1word(hash, jhash_initval_salt); + + return (u16)(((u64)hash * num_tx_queues) >> 32); +} + +u16 i40e_lan_select_queue(struct net_device *netdev, + struct sk_buff *skb, + struct net_device __always_unused *sb_dev) +{ + struct i40e_netdev_priv *np = netdev_priv(netdev); + struct i40e_vsi *vsi = np->vsi; + struct i40e_hw *hw; + u16 qoffset; + u16 qcount; + u8 tclass; + u16 hash; + u8 prio; + + /* is DCB enabled at all? */ + if (vsi->tc_config.numtc == 1) + return netdev_pick_tx(netdev, skb, sb_dev); + + prio = skb->priority; + hw = &vsi->back->hw; + tclass = hw->local_dcbx_config.etscfg.prioritytable[prio]; + /* sanity check */ + if (unlikely(!(vsi->tc_config.enabled_tc & BIT(tclass)))) + tclass = 0; + + /* select a queue assigned for the given TC */ + qcount = vsi->tc_config.tc_info[tclass].qcount; + hash = i40e_swdcb_skb_tx_hash(netdev, skb, qcount); + + qoffset = vsi->tc_config.tc_info[tclass].qoffset; + return qoffset + hash; +} + /** * i40e_xmit_xdp_ring - transmits an XDP buffer to an XDP Tx ring * @xdpf: data to transmit diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h index 2feed920ef8a..93ac201f68b8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h @@ -449,6 +449,8 @@ static inline unsigned int i40e_rx_pg_order(struct i40e_ring *ring) bool i40e_alloc_rx_buffers(struct i40e_ring *rxr, u16 cleaned_count); netdev_tx_t i40e_lan_xmit_frame(struct sk_buff *skb, struct net_device *netdev); +u16 i40e_lan_select_queue(struct net_device *netdev, struct sk_buff *skb, + struct net_device *sb_dev); void i40e_clean_tx_ring(struct i40e_ring *tx_ring); void i40e_clean_rx_ring(struct i40e_ring *rx_ring); int i40e_setup_tx_descriptors(struct i40e_ring *tx_ring); diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h index 8a65525a7c0d..6766446a33f4 100644 --- a/drivers/net/ethernet/intel/iavf/iavf.h +++ b/drivers/net/ethernet/intel/iavf/iavf.h @@ -134,6 +134,7 @@ struct iavf_q_vector { struct iavf_mac_filter { struct list_head list; u8 macaddr[ETH_ALEN]; + bool is_new_mac; /* filter is new, wait for PF decision */ bool remove; /* filter needs to be removed */ bool add; /* filter needs to be added */ }; diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index ebd08543791b..7023aa147043 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -751,6 +751,7 @@ struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, list_add_tail(&f->list, &adapter->mac_filter_list); f->add = true; + f->is_new_mac = true; adapter->aq_required |= IAVF_FLAG_AQ_ADD_MAC_FILTER; } else { f->remove = false; @@ -1489,11 +1490,6 @@ static int iavf_reinit_interrupt_scheme(struct iavf_adapter *adapter) set_bit(__IAVF_VSI_DOWN, adapter->vsi.state); iavf_map_rings_to_vectors(adapter); - - if (RSS_AQ(adapter)) - adapter->aq_required |= IAVF_FLAG_AQ_CONFIGURE_RSS; - else - err = iavf_init_rss(adapter); err: return err; } @@ -2167,6 +2163,14 @@ static void iavf_reset_task(struct work_struct *work) goto reset_err; } + if (RSS_AQ(adapter)) { + adapter->aq_required |= IAVF_FLAG_AQ_CONFIGURE_RSS; + } else { + err = iavf_init_rss(adapter); + if (err) + goto reset_err; + } + adapter->aq_required |= IAVF_FLAG_AQ_GET_CONFIG; adapter->aq_required |= IAVF_FLAG_AQ_MAP_VECTORS; @@ -3759,6 +3763,7 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err_ioremap: free_netdev(netdev); err_alloc_etherdev: + pci_disable_pcie_error_reporting(pdev); pci_release_regions(pdev); err_pci_reg: err_dma: diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c index ed08ace4f05a..8be3151f2c62 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c @@ -537,6 +537,47 @@ void iavf_del_ether_addrs(struct iavf_adapter *adapter) kfree(veal); } +/** + * iavf_mac_add_ok + * @adapter: adapter structure + * + * Submit list of filters based on PF response. + **/ +static void iavf_mac_add_ok(struct iavf_adapter *adapter) +{ + struct iavf_mac_filter *f, *ftmp; + + spin_lock_bh(&adapter->mac_vlan_list_lock); + list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) { + f->is_new_mac = false; + } + spin_unlock_bh(&adapter->mac_vlan_list_lock); +} + +/** + * iavf_mac_add_reject + * @adapter: adapter structure + * + * Remove filters from list based on PF response. + **/ +static void iavf_mac_add_reject(struct iavf_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct iavf_mac_filter *f, *ftmp; + + spin_lock_bh(&adapter->mac_vlan_list_lock); + list_for_each_entry_safe(f, ftmp, &adapter->mac_filter_list, list) { + if (f->remove && ether_addr_equal(f->macaddr, netdev->dev_addr)) + f->remove = false; + + if (f->is_new_mac) { + list_del(&f->list); + kfree(f); + } + } + spin_unlock_bh(&adapter->mac_vlan_list_lock); +} + /** * iavf_add_vlans * @adapter: adapter structure @@ -1295,6 +1336,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, case VIRTCHNL_OP_ADD_ETH_ADDR: dev_err(&adapter->pdev->dev, "Failed to add MAC filter, error %s\n", iavf_stat_str(&adapter->hw, v_retval)); + iavf_mac_add_reject(adapter); /* restore administratively set MAC address */ ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr); break; @@ -1364,10 +1406,11 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, } } switch (v_opcode) { - case VIRTCHNL_OP_ADD_ETH_ADDR: { + case VIRTCHNL_OP_ADD_ETH_ADDR: + if (!v_retval) + iavf_mac_add_ok(adapter); if (!ether_addr_equal(netdev->dev_addr, adapter->hw.mac.addr)) ether_addr_copy(netdev->dev_addr, adapter->hw.mac.addr); - } break; case VIRTCHNL_OP_GET_STATS: { struct iavf_eth_stats *stats = diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c index 511da59bd6f2..f18ce43b7e74 100644 --- a/drivers/net/ethernet/intel/ice/ice_devlink.c +++ b/drivers/net/ethernet/intel/ice/ice_devlink.c @@ -23,7 +23,9 @@ static int ice_info_pba(struct ice_pf *pf, char *buf, size_t len) status = ice_read_pba_string(hw, (u8 *)buf, len); if (status) - return -EIO; + /* We failed to locate the PBA, so just skip this entry */ + dev_dbg(ice_pf_to_dev(pf), "Failed to read Product Board Assembly string, status %s\n", + ice_stat_str(status)); return 0; } diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index a7975afecf70..14eba9bc174d 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -3492,13 +3492,9 @@ static int ice_get_rc_coalesce(struct ethtool_coalesce *ec, enum ice_container_type c_type, struct ice_ring_container *rc) { - struct ice_pf *pf; - if (!rc->ring) return -EINVAL; - pf = rc->ring->vsi->back; - switch (c_type) { case ICE_RX_CONTAINER: ec->use_adaptive_rx_coalesce = ITR_IS_DYNAMIC(rc->itr_setting); @@ -3510,7 +3506,7 @@ ice_get_rc_coalesce(struct ethtool_coalesce *ec, enum ice_container_type c_type, ec->tx_coalesce_usecs = rc->itr_setting & ~ICE_ITR_DYNAMIC; break; default: - dev_dbg(ice_pf_to_dev(pf), "Invalid c_type %d\n", c_type); + dev_dbg(ice_pf_to_dev(rc->ring->vsi->back), "Invalid c_type %d\n", c_type); return -EINVAL; } diff --git a/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h b/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h index 4ec24c3e813f..c0ee0541e53f 100644 --- a/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h +++ b/drivers/net/ethernet/intel/ice/ice_lan_tx_rx.h @@ -608,7 +608,7 @@ static const struct ice_rx_ptype_decoded ice_ptype_lkup[] = { /* L2 Packet types */ ICE_PTT_UNUSED_ENTRY(0), ICE_PTT(1, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2), - ICE_PTT(2, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE), + ICE_PTT_UNUSED_ENTRY(2), ICE_PTT_UNUSED_ENTRY(3), ICE_PTT_UNUSED_ENTRY(4), ICE_PTT_UNUSED_ENTRY(5), @@ -722,7 +722,7 @@ static const struct ice_rx_ptype_decoded ice_ptype_lkup[] = { /* Non Tunneled IPv6 */ ICE_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3), ICE_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3), - ICE_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY3), + ICE_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY4), ICE_PTT_UNUSED_ENTRY(91), ICE_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4), ICE_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4), diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index fb20c6971f4c..dc944d605a74 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -1705,12 +1705,13 @@ int ice_vsi_cfg_rxqs(struct ice_vsi *vsi) * ice_vsi_cfg_txqs - Configure the VSI for Tx * @vsi: the VSI being configured * @rings: Tx ring array to be configured + * @count: number of Tx ring array elements * * Return 0 on success and a negative value on error * Configure the Tx VSI for operation. */ static int -ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_ring **rings) +ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_ring **rings, u16 count) { struct ice_aqc_add_tx_qgrp *qg_buf; u16 q_idx = 0; @@ -1722,7 +1723,7 @@ ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_ring **rings) qg_buf->num_txqs = 1; - for (q_idx = 0; q_idx < vsi->num_txq; q_idx++) { + for (q_idx = 0; q_idx < count; q_idx++) { err = ice_vsi_cfg_txq(vsi, rings[q_idx], qg_buf); if (err) goto err_cfg_txqs; @@ -1742,7 +1743,7 @@ ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_ring **rings) */ int ice_vsi_cfg_lan_txqs(struct ice_vsi *vsi) { - return ice_vsi_cfg_txqs(vsi, vsi->tx_rings); + return ice_vsi_cfg_txqs(vsi, vsi->tx_rings, vsi->num_txq); } /** @@ -1757,7 +1758,7 @@ int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi) int ret; int i; - ret = ice_vsi_cfg_txqs(vsi, vsi->xdp_rings); + ret = ice_vsi_cfg_txqs(vsi, vsi->xdp_rings, vsi->num_xdp_txq); if (ret) return ret; @@ -1955,17 +1956,18 @@ int ice_vsi_stop_all_rx_rings(struct ice_vsi *vsi) * @rst_src: reset source * @rel_vmvf_num: Relative ID of VF/VM * @rings: Tx ring array to be stopped + * @count: number of Tx ring array elements */ static int ice_vsi_stop_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, - u16 rel_vmvf_num, struct ice_ring **rings) + u16 rel_vmvf_num, struct ice_ring **rings, u16 count) { u16 q_idx; if (vsi->num_txq > ICE_LAN_TXQ_MAX_QDIS) return -EINVAL; - for (q_idx = 0; q_idx < vsi->num_txq; q_idx++) { + for (q_idx = 0; q_idx < count; q_idx++) { struct ice_txq_meta txq_meta = { }; int status; @@ -1993,7 +1995,7 @@ int ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, u16 rel_vmvf_num) { - return ice_vsi_stop_tx_rings(vsi, rst_src, rel_vmvf_num, vsi->tx_rings); + return ice_vsi_stop_tx_rings(vsi, rst_src, rel_vmvf_num, vsi->tx_rings, vsi->num_txq); } /** @@ -2002,7 +2004,7 @@ ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src, */ int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi) { - return ice_vsi_stop_tx_rings(vsi, ICE_NO_RESET, 0, vsi->xdp_rings); + return ice_vsi_stop_tx_rings(vsi, ICE_NO_RESET, 0, vsi->xdp_rings, vsi->num_xdp_txq); } /** diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 6f30aad7695f..a46780570cd9 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -189,6 +189,14 @@ static int ice_add_mac_to_unsync_list(struct net_device *netdev, const u8 *addr) struct ice_netdev_priv *np = netdev_priv(netdev); struct ice_vsi *vsi = np->vsi; + /* Under some circumstances, we might receive a request to delete our + * own device address from our uc list. Because we store the device + * address in the VSI's MAC filter list, we need to ignore such + * requests and not delete our device address from this list. + */ + if (ether_addr_equal(addr, netdev->dev_addr)) + return 0; + if (ice_fltr_add_mac_to_list(vsi, &vsi->tmp_unsync_list, addr, ICE_FWD_TO_VSI)) return -EINVAL; @@ -2539,6 +2547,20 @@ ice_xdp_setup_prog(struct ice_vsi *vsi, struct bpf_prog *prog, return (ret || xdp_ring_err) ? -ENOMEM : 0; } +/** + * ice_xdp_safe_mode - XDP handler for safe mode + * @dev: netdevice + * @xdp: XDP command + */ +static int ice_xdp_safe_mode(struct net_device __always_unused *dev, + struct netdev_bpf *xdp) +{ + NL_SET_ERR_MSG_MOD(xdp->extack, + "Please provide working DDP firmware package in order to use XDP\n" + "Refer to Documentation/networking/device_drivers/ethernet/intel/ice.rst"); + return -EOPNOTSUPP; +} + /** * ice_xdp - implements XDP handler * @dev: netdevice @@ -3977,6 +3999,11 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) struct ice_hw *hw; int i, err; + if (pdev->is_virtfn) { + dev_err(dev, "can't probe a virtual function\n"); + return -EINVAL; + } + /* this driver uses devres, see * Documentation/driver-api/driver-model/devres.rst */ @@ -4862,7 +4889,7 @@ static int ice_set_mac_address(struct net_device *netdev, void *pi) return -EADDRNOTAVAIL; if (ether_addr_equal(netdev->dev_addr, mac)) { - netdev_warn(netdev, "already using mac %pM\n", mac); + netdev_dbg(netdev, "already using mac %pM\n", mac); return 0; } @@ -4873,6 +4900,7 @@ static int ice_set_mac_address(struct net_device *netdev, void *pi) return -EBUSY; } + netif_addr_lock_bh(netdev); /* Clean up old MAC filter. Not an error if old filter doesn't exist */ status = ice_fltr_remove_mac(vsi, netdev->dev_addr, ICE_FWD_TO_VSI); if (status && status != ICE_ERR_DOES_NOT_EXIST) { @@ -4882,30 +4910,28 @@ static int ice_set_mac_address(struct net_device *netdev, void *pi) /* Add filter for new MAC. If filter exists, return success */ status = ice_fltr_add_mac(vsi, mac, ICE_FWD_TO_VSI); - if (status == ICE_ERR_ALREADY_EXISTS) { + if (status == ICE_ERR_ALREADY_EXISTS) /* Although this MAC filter is already present in hardware it's * possible in some cases (e.g. bonding) that dev_addr was * modified outside of the driver and needs to be restored back * to this value. */ - memcpy(netdev->dev_addr, mac, netdev->addr_len); netdev_dbg(netdev, "filter for MAC %pM already exists\n", mac); - return 0; - } - - /* error if the new filter addition failed */ - if (status) + else if (status) + /* error if the new filter addition failed */ err = -EADDRNOTAVAIL; err_update_filters: if (err) { netdev_err(netdev, "can't set MAC %pM. filter update failed\n", mac); + netif_addr_unlock_bh(netdev); return err; } /* change the netdev's MAC address */ memcpy(netdev->dev_addr, mac, netdev->addr_len); + netif_addr_unlock_bh(netdev); netdev_dbg(vsi->netdev, "updated MAC address to %pM\n", netdev->dev_addr); @@ -6786,6 +6812,7 @@ static const struct net_device_ops ice_netdev_safe_mode_ops = { .ndo_change_mtu = ice_change_mtu, .ndo_get_stats64 = ice_get_stats64, .ndo_tx_timeout = ice_tx_timeout, + .ndo_bpf = ice_xdp_safe_mode, }; static const struct net_device_ops ice_netdev_ops = { diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h index 1bed183d96a0..ee3497d25464 100644 --- a/drivers/net/ethernet/intel/ice/ice_type.h +++ b/drivers/net/ethernet/intel/ice/ice_type.h @@ -63,7 +63,7 @@ enum ice_aq_res_ids { /* FW update timeout definitions are in milliseconds */ #define ICE_NVM_TIMEOUT 180000 #define ICE_CHANGE_LOCK_TIMEOUT 1000 -#define ICE_GLOBAL_CFG_LOCK_TIMEOUT 3000 +#define ICE_GLOBAL_CFG_LOCK_TIMEOUT 5000 enum ice_aq_res_access_type { ICE_RES_READ = 1, diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 5c87c0a7ce3d..e24fb122c03a 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -931,6 +931,7 @@ static void igb_configure_msix(struct igb_adapter *adapter) **/ static int igb_request_msix(struct igb_adapter *adapter) { + unsigned int num_q_vectors = adapter->num_q_vectors; struct net_device *netdev = adapter->netdev; int i, err = 0, vector = 0, free_vector = 0; @@ -939,7 +940,13 @@ static int igb_request_msix(struct igb_adapter *adapter) if (err) goto err_out; - for (i = 0; i < adapter->num_q_vectors; i++) { + if (num_q_vectors > MAX_Q_VECTORS) { + num_q_vectors = MAX_Q_VECTORS; + dev_warn(&adapter->pdev->dev, + "The number of queue vectors (%d) is higher than max allowed (%d)\n", + adapter->num_q_vectors, MAX_Q_VECTORS); + } + for (i = 0; i < num_q_vectors; i++) { struct igb_q_vector *q_vector = adapter->q_vector[i]; vector++; @@ -1678,14 +1685,15 @@ static bool is_any_txtime_enabled(struct igb_adapter *adapter) **/ static void igb_config_tx_modes(struct igb_adapter *adapter, int queue) { - struct igb_ring *ring = adapter->tx_ring[queue]; struct net_device *netdev = adapter->netdev; struct e1000_hw *hw = &adapter->hw; + struct igb_ring *ring; u32 tqavcc, tqavctrl; u16 value; WARN_ON(hw->mac.type != e1000_i210); WARN_ON(queue < 0 || queue > 1); + ring = adapter->tx_ring[queue]; /* If any of the Qav features is enabled, configure queues as SR and * with HIGH PRIO. If none is, then configure them with LOW PRIO and @@ -2643,7 +2651,8 @@ static int igb_parse_cls_flower(struct igb_adapter *adapter, } input->filter.match_flags |= IGB_FILTER_FLAG_VLAN_TCI; - input->filter.vlan_tci = match.key->vlan_priority; + input->filter.vlan_tci = + (__force __be16)match.key->vlan_priority; } } @@ -3615,6 +3624,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) err_ioremap: free_netdev(netdev); err_alloc_etherdev: + pci_disable_pcie_error_reporting(pdev); pci_release_mem_regions(pdev); err_pci_reg: err_dma: @@ -4835,6 +4845,8 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring) DMA_TO_DEVICE); } + tx_buffer->next_to_watch = NULL; + /* move us one more past the eop_desc for start of next pkt */ tx_buffer++; i++; @@ -6288,12 +6300,12 @@ int igb_xmit_xdp_ring(struct igb_adapter *adapter, cmd_type |= len | IGB_TXD_DCMD; tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type); - olinfo_status = cpu_to_le32(len << E1000_ADVTXD_PAYLEN_SHIFT); + olinfo_status = len << E1000_ADVTXD_PAYLEN_SHIFT; /* 82575 requires a unique index per ring */ if (test_bit(IGB_RING_FLAG_TX_CTX_IDX, &tx_ring->flags)) olinfo_status |= tx_ring->reg_idx << 4; - tx_desc->read.olinfo_status = olinfo_status; + tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status); netdev_tx_sent_queue(txring_txq(tx_ring), tx_buffer->bytecount); @@ -8617,7 +8629,7 @@ static void igb_process_skb_fields(struct igb_ring *rx_ring, if (igb_test_staterr(rx_desc, E1000_RXDEXT_STATERR_LB) && test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &rx_ring->flags)) - vid = be16_to_cpu(rx_desc->wb.upper.vlan); + vid = be16_to_cpu((__force __be16)rx_desc->wb.upper.vlan); else vid = le16_to_cpu(rx_desc->wb.upper.vlan); diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index ee9f8c1dca83..07c9e9e0546f 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -83,14 +83,14 @@ static int igbvf_desc_unused(struct igbvf_ring *ring) static void igbvf_receive_skb(struct igbvf_adapter *adapter, struct net_device *netdev, struct sk_buff *skb, - u32 status, u16 vlan) + u32 status, __le16 vlan) { u16 vid; if (status & E1000_RXD_STAT_VP) { if ((adapter->flags & IGBVF_FLAG_RX_LB_VLAN_BSWAP) && (status & E1000_RXDEXT_STATERR_LB)) - vid = be16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; + vid = be16_to_cpu((__force __be16)vlan) & E1000_RXD_SPC_VLAN_MASK; else vid = le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK; if (test_bit(vid, adapter->active_vlans)) diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h index 6dca67d9c25d..a97bf7a5f1d6 100644 --- a/drivers/net/ethernet/intel/igc/igc.h +++ b/drivers/net/ethernet/intel/igc/igc.h @@ -532,7 +532,7 @@ static inline s32 igc_read_phy_reg(struct igc_hw *hw, u32 offset, u16 *data) if (hw->phy.ops.read_reg) return hw->phy.ops.read_reg(hw, offset, data); - return 0; + return -EOPNOTSUPP; } void igc_reinit_locked(struct igc_adapter *); diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 7b822cdcc6c5..013dd2955381 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -138,6 +138,9 @@ static void igc_release_hw_control(struct igc_adapter *adapter) struct igc_hw *hw = &adapter->hw; u32 ctrl_ext; + if (!pci_device_is_present(adapter->pdev)) + return; + /* Let firmware take over control of h/w */ ctrl_ext = rd32(IGC_CTRL_EXT); wr32(IGC_CTRL_EXT, @@ -207,6 +210,8 @@ static void igc_clean_tx_ring(struct igc_ring *tx_ring) DMA_TO_DEVICE); } + tx_buffer->next_to_watch = NULL; + /* move us one more past the eop_desc for start of next pkt */ tx_buffer++; i++; @@ -3780,26 +3785,29 @@ void igc_down(struct igc_adapter *adapter) igc_ptp_suspend(adapter); - /* disable receives in the hardware */ - rctl = rd32(IGC_RCTL); - wr32(IGC_RCTL, rctl & ~IGC_RCTL_EN); - /* flush and sleep below */ - + if (pci_device_is_present(adapter->pdev)) { + /* disable receives in the hardware */ + rctl = rd32(IGC_RCTL); + wr32(IGC_RCTL, rctl & ~IGC_RCTL_EN); + /* flush and sleep below */ + } /* set trans_start so we don't get spurious watchdogs during reset */ netif_trans_update(netdev); netif_carrier_off(netdev); netif_tx_stop_all_queues(netdev); - /* disable transmits in the hardware */ - tctl = rd32(IGC_TCTL); - tctl &= ~IGC_TCTL_EN; - wr32(IGC_TCTL, tctl); - /* flush both disables and wait for them to finish */ - wrfl(); - usleep_range(10000, 20000); + if (pci_device_is_present(adapter->pdev)) { + /* disable transmits in the hardware */ + tctl = rd32(IGC_TCTL); + tctl &= ~IGC_TCTL_EN; + wr32(IGC_TCTL, tctl); + /* flush both disables and wait for them to finish */ + wrfl(); + usleep_range(10000, 20000); - igc_irq_disable(adapter); + igc_irq_disable(adapter); + } adapter->flags &= ~IGC_FLAG_NEED_LINK_UPDATE; @@ -4753,7 +4761,7 @@ static bool validate_schedule(struct igc_adapter *adapter, if (e->command != TC_TAPRIO_CMD_SET_GATES) return false; - for (i = 0; i < IGC_MAX_TX_QUEUES; i++) { + for (i = 0; i < adapter->num_tx_queues; i++) { if (e->gate_mask & BIT(i)) queue_uses[i]++; @@ -4810,7 +4818,7 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter, end_time += e->interval; - for (i = 0; i < IGC_MAX_TX_QUEUES; i++) { + for (i = 0; i < adapter->num_tx_queues; i++) { struct igc_ring *ring = adapter->tx_ring[i]; if (!(e->gate_mask & BIT(i))) @@ -5221,6 +5229,7 @@ static int igc_probe(struct pci_dev *pdev, err_ioremap: free_netdev(netdev); err_alloc_etherdev: + pci_disable_pcie_error_reporting(pdev); pci_release_mem_regions(pdev); err_pci_reg: err_dma: diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c index 545f4d0e67cf..4ab46eee3d93 100644 --- a/drivers/net/ethernet/intel/igc/igc_ptp.c +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c @@ -557,7 +557,8 @@ void igc_ptp_suspend(struct igc_adapter *adapter) adapter->ptp_tx_skb = NULL; clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state); - igc_ptp_time_save(adapter); + if (pci_device_is_present(adapter->pdev)) + igc_ptp_time_save(adapter); } /** diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 1bfba87f1ff6..37439b76fcb5 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1825,7 +1825,8 @@ static void ixgbe_dma_sync_frag(struct ixgbe_ring *rx_ring, struct sk_buff *skb) { if (ring_uses_build_skb(rx_ring)) { - unsigned long offset = (unsigned long)(skb->data) & ~PAGE_MASK; + unsigned long mask = (unsigned long)ixgbe_rx_pg_size(rx_ring) - 1; + unsigned long offset = (unsigned long)(skb->data) & mask; dma_sync_single_range_for_cpu(rx_ring->dev, IXGBE_CB(skb)->dma, @@ -11081,6 +11082,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) disable_dev = !test_and_set_bit(__IXGBE_DISABLED, &adapter->state); free_netdev(netdev); err_alloc_etherdev: + pci_disable_pcie_error_reporting(pdev); pci_release_mem_regions(pdev); err_pci_reg: err_dma: diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c index f72d2978263b..d60da7a89092 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c @@ -52,8 +52,11 @@ static int ixgbe_xsk_pool_enable(struct ixgbe_adapter *adapter, /* Kick start the NAPI context so that receiving will start */ err = ixgbe_xsk_wakeup(adapter->netdev, qid, XDP_WAKEUP_RX); - if (err) + if (err) { + clear_bit(qid, adapter->af_xdp_zc_qps); + xsk_pool_dma_unmap(pool, IXGBE_RX_DMA_ATTR); return err; + } } return 0; diff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c b/drivers/net/ethernet/intel/ixgbevf/ipsec.c index caaea2c920a6..e3e4676af9e4 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c +++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c @@ -211,7 +211,7 @@ struct xfrm_state *ixgbevf_ipsec_find_rx_state(struct ixgbevf_ipsec *ipsec, static int ixgbevf_ipsec_parse_proto_keys(struct xfrm_state *xs, u32 *mykey, u32 *mysalt) { - struct net_device *dev = xs->xso.dev; + struct net_device *dev = xs->xso.real_dev; unsigned char *key_data; char *alg_name = NULL; int key_len; @@ -260,12 +260,15 @@ static int ixgbevf_ipsec_parse_proto_keys(struct xfrm_state *xs, **/ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs) { - struct net_device *dev = xs->xso.dev; - struct ixgbevf_adapter *adapter = netdev_priv(dev); - struct ixgbevf_ipsec *ipsec = adapter->ipsec; + struct net_device *dev = xs->xso.real_dev; + struct ixgbevf_adapter *adapter; + struct ixgbevf_ipsec *ipsec; u16 sa_idx; int ret; + adapter = netdev_priv(dev); + ipsec = adapter->ipsec; + if (xs->id.proto != IPPROTO_ESP && xs->id.proto != IPPROTO_AH) { netdev_err(dev, "Unsupported protocol 0x%04x for IPsec offload\n", xs->id.proto); @@ -383,11 +386,14 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs) **/ static void ixgbevf_ipsec_del_sa(struct xfrm_state *xs) { - struct net_device *dev = xs->xso.dev; - struct ixgbevf_adapter *adapter = netdev_priv(dev); - struct ixgbevf_ipsec *ipsec = adapter->ipsec; + struct net_device *dev = xs->xso.real_dev; + struct ixgbevf_adapter *adapter; + struct ixgbevf_ipsec *ipsec; u16 sa_idx; + adapter = netdev_priv(dev); + ipsec = adapter->ipsec; + if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_RX_INDEX; diff --git a/drivers/net/ethernet/lantiq_xrx200.c b/drivers/net/ethernet/lantiq_xrx200.c index 135ba5b6ae98..072075bc60ee 100644 --- a/drivers/net/ethernet/lantiq_xrx200.c +++ b/drivers/net/ethernet/lantiq_xrx200.c @@ -154,6 +154,7 @@ static int xrx200_close(struct net_device *net_dev) static int xrx200_alloc_skb(struct xrx200_chan *ch) { + struct sk_buff *skb = ch->skb[ch->dma.desc]; dma_addr_t mapping; int ret = 0; @@ -168,6 +169,7 @@ static int xrx200_alloc_skb(struct xrx200_chan *ch) XRX200_DMA_DATA_LEN, DMA_FROM_DEVICE); if (unlikely(dma_mapping_error(ch->priv->dev, mapping))) { dev_kfree_skb_any(ch->skb[ch->dma.desc]); + ch->skb[ch->dma.desc] = skb; ret = -ENOMEM; goto skip; } @@ -198,7 +200,6 @@ static int xrx200_hw_receive(struct xrx200_chan *ch) ch->dma.desc %= LTQ_DESC_NUM; if (ret) { - ch->skb[ch->dma.desc] = skb; net_dev->stats.rx_dropped++; netdev_err(net_dev, "failed to allocate new rx buffer\n"); return ret; @@ -352,8 +353,8 @@ static irqreturn_t xrx200_dma_irq(int irq, void *ptr) struct xrx200_chan *ch = ptr; if (napi_schedule_prep(&ch->napi)) { - __napi_schedule(&ch->napi); ltq_dma_disable_irq(&ch->dma); + __napi_schedule(&ch->napi); } ltq_dma_ack_irq(&ch->dma); diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index c6b735b30515..74e266c0b8e1 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -103,7 +103,7 @@ #define MVNETA_DESC_SWAP BIT(6) #define MVNETA_TX_BRST_SZ_MASK(burst) ((burst) << 22) #define MVNETA_PORT_STATUS 0x2444 -#define MVNETA_TX_IN_PRGRS BIT(1) +#define MVNETA_TX_IN_PRGRS BIT(0) #define MVNETA_TX_FIFO_EMPTY BIT(8) #define MVNETA_RX_MIN_FRAME_SIZE 0x247c /* Only exists on Armada XP and Armada 370 */ diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h index a1aefce55e65..d825eb021b22 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h @@ -854,7 +854,7 @@ enum mvpp22_ptp_packet_format { #define MVPP2_BM_COOKIE_POOL_OFFS 8 #define MVPP2_BM_COOKIE_CPU_OFFS 24 -#define MVPP2_BM_SHORT_FRAME_SIZE 704 /* frame size 128 */ +#define MVPP2_BM_SHORT_FRAME_SIZE 736 /* frame size 128 */ #define MVPP2_BM_LONG_FRAME_SIZE 2240 /* frame size 1664 */ #define MVPP2_BM_JUMBO_FRAME_SIZE 10432 /* frame size 9856 */ /* BM short pool packet size diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index 6aa13c9f9fc9..ec9b6c564300 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -6871,6 +6871,10 @@ static int mvpp2_probe(struct platform_device *pdev) return PTR_ERR(priv->lms_base); } else { res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(&pdev->dev, "Invalid resource\n"); + return -EINVAL; + } if (has_acpi_companion(&pdev->dev)) { /* In case the MDIO memory region is declared in * the ACPI, it can already appear as 'in-use' @@ -7045,6 +7049,8 @@ static int mvpp2_probe(struct platform_device *pdev) return 0; err_port_probe: + fwnode_handle_put(port_fwnode); + i = 0; fwnode_for_each_available_child_node(fwnode, port_fwnode) { if (priv->port_list[i]) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c index 662fb80dbb9d..c6d408de0605 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c @@ -230,15 +230,14 @@ static int otx2_set_channels(struct net_device *dev, err = otx2_set_real_num_queues(dev, channel->tx_count, channel->rx_count); if (err) - goto fail; + return err; pfvf->hw.rx_queues = channel->rx_count; pfvf->hw.tx_queues = channel->tx_count; pfvf->qset.cq_cnt = pfvf->hw.tx_queues + pfvf->hw.rx_queues; -fail: if (if_up) - dev->netdev_ops->ndo_open(dev); + err = dev->netdev_ops->ndo_open(dev); netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n", pfvf->hw.tx_queues, pfvf->hw.rx_queues); @@ -342,7 +341,7 @@ static int otx2_set_ringparam(struct net_device *netdev, qs->rqe_cnt = rx_count; if (if_up) - netdev->netdev_ops->ndo_open(netdev); + return netdev->netdev_ops->ndo_open(netdev); return 0; } diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c index 9fef9be015e5..044a5b1196ac 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -1592,6 +1592,7 @@ int otx2_open(struct net_device *netdev) err_tx_stop_queues: netif_tx_stop_all_queues(netdev); netif_carrier_off(netdev); + pf->flags |= OTX2_FLAG_INTF_DOWN; err_free_cints: otx2_free_cints(pf, qidx); vec = pci_irq_vector(pf->pdev, @@ -1619,6 +1620,10 @@ int otx2_stop(struct net_device *netdev) struct otx2_rss_info *rss; int qidx, vec, wrk; + /* If the DOWN flag is set resources are already freed */ + if (pf->flags & OTX2_FLAG_INTF_DOWN) + return 0; + netif_carrier_off(netdev); netif_tx_stop_all_queues(netdev); diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index f6cfec81ccc3..dc4ac1a2b6b6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -823,6 +823,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_MAD_DEMUX_OFFSET 0xb0 #define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_BASE_OFFSET 0xa8 #define QUERY_DEV_CAP_DMFS_HIGH_RATE_QPN_RANGE_OFFSET 0xac +#define QUERY_DEV_CAP_MAP_CLOCK_TO_USER 0xc1 #define QUERY_DEV_CAP_QP_RATE_LIMIT_NUM_OFFSET 0xcc #define QUERY_DEV_CAP_QP_RATE_LIMIT_MAX_OFFSET 0xd0 #define QUERY_DEV_CAP_QP_RATE_LIMIT_MIN_OFFSET 0xd2 @@ -841,6 +842,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) if (mlx4_is_mfunc(dev)) disable_unsupported_roce_caps(outbox); + MLX4_GET(field, outbox, QUERY_DEV_CAP_MAP_CLOCK_TO_USER); + dev_cap->map_clock_to_user = field & 0x80; MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_QP_OFFSET); dev_cap->reserved_qps = 1 << (field & 0xf); MLX4_GET(field, outbox, QUERY_DEV_CAP_MAX_QP_OFFSET); diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h index 8f020f26ebf5..cf64e54eecb0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.h +++ b/drivers/net/ethernet/mellanox/mlx4/fw.h @@ -131,6 +131,7 @@ struct mlx4_dev_cap { u32 health_buffer_addrs; struct mlx4_port_cap port_cap[MLX4_MAX_PORTS + 1]; bool wol_port[MLX4_MAX_PORTS + 1]; + bool map_clock_to_user; }; struct mlx4_func_cap { diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index c326b434734e..28ac4693da3c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -498,6 +498,7 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) } } + dev->caps.map_clock_to_user = dev_cap->map_clock_to_user; dev->caps.uar_page_size = PAGE_SIZE; dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE; dev->caps.local_ca_ack_delay = dev_cap->local_ca_ack_delay; @@ -1948,6 +1949,11 @@ int mlx4_get_internal_clock_params(struct mlx4_dev *dev, if (mlx4_is_slave(dev)) return -EOPNOTSUPP; + if (!dev->caps.map_clock_to_user) { + mlx4_dbg(dev, "Map clock to user is not supported.\n"); + return -EOPNOTSUPP; + } + if (!params) return -EINVAL; @@ -3529,6 +3535,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, if (!SRIOV_VALID_STATE(dev->flags)) { mlx4_err(dev, "Invalid SRIOV state\n"); + err = -EINVAL; goto err_close; } } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cq.c b/drivers/net/ethernet/mellanox/mlx5/core/cq.c index df3e4938ecdd..360e093874d4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cq.c @@ -134,6 +134,7 @@ int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq, cq->cqn); cq->uar = dev->priv.uar; + cq->irqn = eq->core.irqn; return 0; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c index 2eb022ad7fd0..3dfcb20e97c6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c @@ -1019,12 +1019,19 @@ int mlx5_fw_tracer_init(struct mlx5_fw_tracer *tracer) MLX5_NB_INIT(&tracer->nb, fw_tracer_event, DEVICE_TRACER); mlx5_eq_notifier_register(dev, &tracer->nb); - mlx5_fw_tracer_start(tracer); - + err = mlx5_fw_tracer_start(tracer); + if (err) { + mlx5_core_warn(dev, "FWTracer: Failed to start tracer %d\n", err); + goto err_notifier_unregister; + } return 0; +err_notifier_unregister: + mlx5_eq_notifier_unregister(dev, &tracer->nb); + mlx5_core_destroy_mkey(dev, &tracer->buff.mkey); err_dealloc_pd: mlx5_core_dealloc_pd(dev, tracer->buff.pdn); + cancel_work_sync(&tracer->read_fw_strings_work); return err; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c index 3d45341e2216..26f7fab109d9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -532,9 +532,6 @@ void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv) struct mlx5_core_dev *mdev = priv->mdev; struct net_device *netdev = priv->netdev; - if (!priv->ipsec) - return; - if (!(mlx5_accel_ipsec_device_caps(mdev) & MLX5_ACCEL_IPSEC_CAP_ESP) || !MLX5_CAP_ETH(mdev, swp)) { mlx5_core_dbg(mdev, "mlx5e: ESP and SWP offload not supported\n"); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index f18b52be32e9..6b4a3d90c9f7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -1547,15 +1547,9 @@ static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev, struct mlx5e_cq *cq) { struct mlx5_core_cq *mcq = &cq->mcq; - int eqn_not_used; - unsigned int irqn; int err; u32 i; - err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn_not_used, &irqn); - if (err) - return err; - err = mlx5_cqwq_create(mdev, ¶m->wq, param->cqc, &cq->wq, &cq->wq_ctrl); if (err) @@ -1569,7 +1563,6 @@ static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev, mcq->vector = param->eq_ix; mcq->comp = mlx5e_completion_event; mcq->event = mlx5e_cq_error_event; - mcq->irqn = irqn; for (i = 0; i < mlx5_cqwq_get_size(&cq->wq); i++) { struct mlx5_cqe64 *cqe = mlx5_cqwq_get_wqe(&cq->wq, i); @@ -1615,11 +1608,10 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param) void *in; void *cqc; int inlen; - unsigned int irqn_not_used; int eqn; int err; - err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn, &irqn_not_used); + err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn); if (err) return err; @@ -1977,9 +1969,8 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, struct mlx5e_channel *c; unsigned int irq; int err; - int eqn; - err = mlx5_vector2eqn(priv->mdev, ix, &eqn, &irq); + err = mlx5_vector2irqn(priv->mdev, ix, &irq); if (err) return err; @@ -4958,13 +4949,9 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) } if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev)) { - netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM; - netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM; - netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM; - netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL | - NETIF_F_GSO_UDP_TUNNEL_CSUM; + netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL; + netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL; + netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL; } if (mlx5e_tunnel_proto_supported(mdev, IPPROTO_GRE)) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index 7e1f8660dfec..f327b78261ec 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -1318,7 +1318,8 @@ static void mlx5e_handle_rx_cqe_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe) if (rep->vlan && skb_vlan_tag_present(skb)) skb_vlan_pop(skb); - if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv)) { + if (unlikely(!mlx5_ipsec_is_rx_flow(cqe) && + !mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv))) { dev_kfree_skb_any(skb); goto free_wqe; } @@ -1375,7 +1376,8 @@ static void mlx5e_handle_rx_cqe_mpwrq_rep(struct mlx5e_rq *rq, struct mlx5_cqe64 mlx5e_complete_rx_cqe(rq, cqe, cqe_bcnt, skb); - if (!mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv)) { + if (unlikely(!mlx5_ipsec_is_rx_flow(cqe) && + !mlx5e_rep_tc_update_skb(cqe, skb, &tc_priv))) { dev_kfree_skb_any(skb); goto mpwrq_cqe_out; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 80abdb0b47d7..1ad1692a5b2d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -481,12 +481,32 @@ static void mlx5e_detach_mod_hdr(struct mlx5e_priv *priv, static struct mlx5_core_dev *mlx5e_hairpin_get_mdev(struct net *net, int ifindex) { + struct mlx5_core_dev *mdev; struct net_device *netdev; struct mlx5e_priv *priv; - netdev = __dev_get_by_index(net, ifindex); + netdev = dev_get_by_index(net, ifindex); + if (!netdev) + return ERR_PTR(-ENODEV); + priv = netdev_priv(netdev); - return priv->mdev; + mdev = priv->mdev; + dev_put(netdev); + + /* Mirred tc action holds a refcount on the ifindex net_device (see + * net/sched/act_mirred.c:tcf_mirred_get_dev). So, it's okay to continue using mdev + * after dev_put(netdev), while we're in the context of adding a tc flow. + * + * The mdev pointer corresponds to the peer/out net_device of a hairpin. It is then + * stored in a hairpin object, which exists until all flows, that refer to it, get + * removed. + * + * On the other hand, after a hairpin object has been created, the peer net_device may + * be removed/unbound while there are still some hairpin flows that are using it. This + * case is handled by mlx5e_tc_hairpin_update_dead_peer, which is hooked to + * NETDEV_UNREGISTER event of the peer net_device. + */ + return mdev; } static int mlx5e_hairpin_create_transport(struct mlx5e_hairpin *hp) @@ -685,6 +705,10 @@ mlx5e_hairpin_create(struct mlx5e_priv *priv, struct mlx5_hairpin_params *params func_mdev = priv->mdev; peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex); + if (IS_ERR(peer_mdev)) { + err = PTR_ERR(peer_mdev); + goto create_pair_err; + } pair = mlx5_core_hairpin_create(func_mdev, peer_mdev, params); if (IS_ERR(pair)) { @@ -823,6 +847,11 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, int err; peer_mdev = mlx5e_hairpin_get_mdev(dev_net(priv->netdev), peer_ifindex); + if (IS_ERR(peer_mdev)) { + NL_SET_ERR_MSG_MOD(extack, "invalid ifindex of mirred device"); + return PTR_ERR(peer_mdev); + } + if (!MLX5_CAP_GEN(priv->mdev, hairpin) || !MLX5_CAP_GEN(peer_mdev, hairpin)) { NL_SET_ERR_MSG_MOD(extack, "hairpin is not supported"); return -EOPNOTSUPP; @@ -5206,7 +5235,7 @@ static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv, list_for_each_entry_safe(hpe, tmp, &init_wait_list, dead_peer_wait_list) { wait_for_completion(&hpe->res_ready); if (!IS_ERR_OR_NULL(hpe->hp) && hpe->peer_vhca_id == peer_vhca_id) - hpe->hp->pair->peer_gone = true; + mlx5_core_hairpin_clear_dead_peer(hpe->hp->pair); mlx5e_hairpin_put(priv, hpe); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c index ccd53a7a2b80..4f4f79ca37a8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c @@ -859,8 +859,8 @@ static int create_comp_eqs(struct mlx5_core_dev *dev) return err; } -int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, - unsigned int *irqn) +static int vector2eqnirqn(struct mlx5_core_dev *dev, int vector, int *eqn, + unsigned int *irqn) { struct mlx5_eq_table *table = dev->priv.eq_table; struct mlx5_eq_comp *eq, *n; @@ -869,8 +869,10 @@ int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, list_for_each_entry_safe(eq, n, &table->comp_eqs_list, list) { if (i++ == vector) { - *eqn = eq->core.eqn; - *irqn = eq->core.irqn; + if (irqn) + *irqn = eq->core.irqn; + if (eqn) + *eqn = eq->core.eqn; err = 0; break; } @@ -878,8 +880,18 @@ int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn, return err; } + +int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn) +{ + return vector2eqnirqn(dev, vector, eqn, NULL); +} EXPORT_SYMBOL(mlx5_vector2eqn); +int mlx5_vector2irqn(struct mlx5_core_dev *dev, int vector, unsigned int *irqn) +{ + return vector2eqnirqn(dev, vector, NULL, irqn); +} + unsigned int mlx5_comp_vectors_count(struct mlx5_core_dev *dev) { return dev->priv.eq_table->num_comp_eqs; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index d61539b5567c..401b2f5128dd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1302,6 +1302,12 @@ static int esw_enable_vport(struct mlx5_eswitch *esw, u16 vport_num, (!vport_num && mlx5_core_is_ecpf(esw->dev))) vport->info.trusted = true; + /* External controller host PF has factory programmed MAC. + * Read it from the device. + */ + if (mlx5_core_is_ecpf(esw->dev) && vport_num == MLX5_VPORT_PF) + mlx5_query_nic_vport_mac_address(esw->dev, vport_num, true, vport->info.mac); + esw_vport_change_handle_locked(vport); esw->enabled_vports++; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c index 80da50e12915..a42bd493293a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c @@ -417,7 +417,6 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size) struct mlx5_wq_param wqp; struct mlx5_cqe64 *cqe; int inlen, err, eqn; - unsigned int irqn; void *cqc, *in; __be64 *pas; u32 i; @@ -446,7 +445,7 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size) goto err_cqwq; } - err = mlx5_vector2eqn(mdev, smp_processor_id(), &eqn, &irqn); + err = mlx5_vector2eqn(mdev, smp_processor_id(), &eqn); if (err) { kvfree(in); goto err_cqwq; @@ -476,7 +475,6 @@ static int mlx5_fpga_conn_create_cq(struct mlx5_fpga_conn *conn, int cq_size) *conn->cq.mcq.arm_db = 0; conn->cq.mcq.vector = 0; conn->cq.mcq.comp = mlx5_fpga_conn_cq_complete; - conn->cq.mcq.irqn = irqn; conn->cq.mcq.uar = fdev->conn_res.uar; tasklet_setup(&conn->cq.tasklet, mlx5_fpga_conn_cq_tasklet); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 79fc5755735f..1d4b4e6f6fb4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -1024,17 +1024,19 @@ static int connect_fwd_rules(struct mlx5_core_dev *dev, static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table *ft, struct fs_prio *prio) { - struct mlx5_flow_table *next_ft; + struct mlx5_flow_table *next_ft, *first_ft; int err = 0; /* Connect_prev_fts and update_root_ft_create are mutually exclusive */ - if (list_empty(&prio->node.children)) { + first_ft = list_first_entry_or_null(&prio->node.children, + struct mlx5_flow_table, node.list); + if (!first_ft || first_ft->level > ft->level) { err = connect_prev_fts(dev, ft, prio); if (err) return err; - next_ft = find_next_chained_ft(prio); + next_ft = first_ft ? first_ft : find_next_chained_ft(prio); err = connect_fwd_rules(dev, ft, next_ft); if (err) return err; @@ -2113,7 +2115,7 @@ static int disconnect_flow_table(struct mlx5_flow_table *ft) node.list) == ft)) return 0; - next_ft = find_next_chained_ft(prio); + next_ft = find_next_ft(ft); err = connect_fwd_rules(dev, next_ft, ft); if (err) return err; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag.c index 9025e5f38bb6..fe5476a76464 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag.c @@ -118,17 +118,24 @@ static bool __mlx5_lag_is_sriov(struct mlx5_lag *ldev) static void mlx5_infer_tx_affinity_mapping(struct lag_tracker *tracker, u8 *port1, u8 *port2) { + bool p1en; + bool p2en; + + p1en = tracker->netdev_state[MLX5_LAG_P1].tx_enabled && + tracker->netdev_state[MLX5_LAG_P1].link_up; + + p2en = tracker->netdev_state[MLX5_LAG_P2].tx_enabled && + tracker->netdev_state[MLX5_LAG_P2].link_up; + *port1 = 1; *port2 = 2; - if (!tracker->netdev_state[MLX5_LAG_P1].tx_enabled || - !tracker->netdev_state[MLX5_LAG_P1].link_up) { - *port1 = 2; + if ((!p1en && !p2en) || (p1en && p2en)) return; - } - if (!tracker->netdev_state[MLX5_LAG_P2].tx_enabled || - !tracker->netdev_state[MLX5_LAG_P2].link_up) + if (p1en) *port2 = 1; + else + *port1 = 2; } void mlx5_modify_lag(struct mlx5_lag *ldev, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h index 81f2cc4ca1da..fa79e6e6a98a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h @@ -98,4 +98,6 @@ void mlx5_core_eq_free_irqs(struct mlx5_core_dev *dev); struct cpu_rmap *mlx5_eq_table_get_rmap(struct mlx5_core_dev *dev); #endif +int mlx5_vector2irqn(struct mlx5_core_dev *dev, int vector, unsigned int *irqn); + #endif diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mr.c b/drivers/net/ethernet/mellanox/mlx5/core/mr.c index 9eb51f06d3ae..d1972508338c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/mr.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/mr.c @@ -54,7 +54,7 @@ int mlx5_core_create_mkey(struct mlx5_core_dev *dev, mkey_index = MLX5_GET(create_mkey_out, lout, mkey_index); mkey->iova = MLX5_GET64(mkc, mkc, start_addr); mkey->size = MLX5_GET64(mkc, mkc, len); - mkey->key |= mlx5_idx_to_mkey(mkey_index); + mkey->key = (u32)mlx5_mkey_variant(mkey->key) | mlx5_idx_to_mkey(mkey_index); mkey->pd = MLX5_GET(mkc, mkc, pd); mlx5_core_dbg(dev, "out 0x%x, mkey 0x%x\n", mkey_index, mkey->key); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c index 8e0dddc6383f..2389239acadc 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c @@ -156,6 +156,9 @@ void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev) { int err; + if (!MLX5_CAP_GEN(dev, roce)) + return; + err = mlx5_nic_vport_enable_roce(dev); if (err) { mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c index 51bbd88ff021..fd56cae0d54f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c @@ -78,9 +78,9 @@ int mlx5dr_cmd_query_esw_caps(struct mlx5_core_dev *mdev, caps->uplink_icm_address_tx = MLX5_CAP64_ESW_FLOWTABLE(mdev, sw_steering_uplink_icm_address_tx); - caps->sw_owner = - MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, - sw_owner); + caps->sw_owner_v2 = MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, sw_owner_v2); + if (!caps->sw_owner_v2) + caps->sw_owner = MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, sw_owner); return 0; } @@ -113,10 +113,15 @@ int mlx5dr_cmd_query_device(struct mlx5_core_dev *mdev, caps->nic_tx_allow_address = MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_tx_action_allow_icm_address); - caps->rx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner); - caps->max_ft_level = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_ft_level); + caps->rx_sw_owner_v2 = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner_v2); + caps->tx_sw_owner_v2 = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner_v2); + + if (!caps->rx_sw_owner_v2) + caps->rx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner); + if (!caps->tx_sw_owner_v2) + caps->tx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner); - caps->tx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner); + caps->max_ft_level = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_ft_level); caps->log_icm_size = MLX5_CAP_DEV_MEM(mdev, log_steering_sw_icm_size); caps->hdr_modify_icm_addr = diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c index aa2c2d6c44e6..00d861361428 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c @@ -4,6 +4,11 @@ #include #include "dr_types.h" +#define DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, dmn_type) \ + ((dmn)->info.caps.dmn_type##_sw_owner || \ + ((dmn)->info.caps.dmn_type##_sw_owner_v2 && \ + (dmn)->info.caps.sw_format_ver <= MLX5_STEERING_FORMAT_CONNECTX_6DX)) + static int dr_domain_init_cache(struct mlx5dr_domain *dmn) { /* Per vport cached FW FT for checksum recalculation, this @@ -181,6 +186,7 @@ static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev, return ret; dmn->info.caps.fdb_sw_owner = dmn->info.caps.esw_caps.sw_owner; + dmn->info.caps.fdb_sw_owner_v2 = dmn->info.caps.esw_caps.sw_owner_v2; dmn->info.caps.esw_rx_drop_address = dmn->info.caps.esw_caps.drop_icm_address_rx; dmn->info.caps.esw_tx_drop_address = dmn->info.caps.esw_caps.drop_icm_address_tx; @@ -223,18 +229,13 @@ static int dr_domain_caps_init(struct mlx5_core_dev *mdev, if (ret) return ret; - if (dmn->info.caps.sw_format_ver != MLX5_STEERING_FORMAT_CONNECTX_5) { - mlx5dr_err(dmn, "SW steering is not supported on this device\n"); - return -EOPNOTSUPP; - } - ret = dr_domain_query_fdb_caps(mdev, dmn); if (ret) return ret; switch (dmn->type) { case MLX5DR_DOMAIN_TYPE_NIC_RX: - if (!dmn->info.caps.rx_sw_owner) + if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, rx)) return -ENOTSUPP; dmn->info.supp_sw_steering = true; @@ -243,7 +244,7 @@ static int dr_domain_caps_init(struct mlx5_core_dev *mdev, dmn->info.rx.drop_icm_addr = dmn->info.caps.nic_rx_drop_address; break; case MLX5DR_DOMAIN_TYPE_NIC_TX: - if (!dmn->info.caps.tx_sw_owner) + if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, tx)) return -ENOTSUPP; dmn->info.supp_sw_steering = true; @@ -255,7 +256,7 @@ static int dr_domain_caps_init(struct mlx5_core_dev *mdev, if (!dmn->info.caps.eswitch_manager) return -ENOTSUPP; - if (!dmn->info.caps.fdb_sw_owner) + if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, fdb)) return -ENOTSUPP; dmn->info.rx.ste_type = MLX5DR_STE_TYPE_RX; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c index 24dede1b0a20..ea3c6cf27db4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c @@ -711,7 +711,6 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, struct mlx5_cqe64 *cqe; struct mlx5dr_cq *cq; int inlen, err, eqn; - unsigned int irqn; void *cqc, *in; __be64 *pas; int vector; @@ -744,7 +743,7 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, goto err_cqwq; vector = raw_smp_processor_id() % mlx5_comp_vectors_count(mdev); - err = mlx5_vector2eqn(mdev, vector, &eqn, &irqn); + err = mlx5_vector2eqn(mdev, vector, &eqn); if (err) { kvfree(in); goto err_cqwq; @@ -780,7 +779,6 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, *cq->mcq.arm_db = cpu_to_be32(2 << 28); cq->mcq.vector = 0; - cq->mcq.irqn = irqn; cq->mcq.uar = uar; return cq; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h index cf62ea4f882e..42c49f09e9d3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h @@ -597,7 +597,8 @@ struct mlx5dr_esw_caps { u64 drop_icm_address_tx; u64 uplink_icm_address_rx; u64 uplink_icm_address_tx; - bool sw_owner; + u8 sw_owner:1; + u8 sw_owner_v2:1; }; struct mlx5dr_cmd_vport_cap { @@ -630,6 +631,9 @@ struct mlx5dr_cmd_caps { bool rx_sw_owner; bool tx_sw_owner; bool fdb_sw_owner; + u8 rx_sw_owner_v2:1; + u8 tx_sw_owner_v2:1; + u8 fdb_sw_owner_v2:1; u32 num_vports; struct mlx5dr_esw_caps esw_caps; struct mlx5dr_cmd_vport_cap *vports_caps; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h b/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h index 7914fe3fc68d..454968ba6831 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5dr.h @@ -124,7 +124,11 @@ int mlx5dr_action_destroy(struct mlx5dr_action *action); static inline bool mlx5dr_is_supported(struct mlx5_core_dev *dev) { - return MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner); + return MLX5_CAP_GEN(dev, roce) && + (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner) || + (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, sw_owner_v2) && + (MLX5_CAP_GEN(dev, steering_format_version) <= + MLX5_STEERING_FORMAT_CONNECTX_6DX))); } #endif /* _MLX5DR_H_ */ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/transobj.c b/drivers/net/ethernet/mellanox/mlx5/core/transobj.c index 01cc00ad8acf..b6931bbe52d2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/transobj.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/transobj.c @@ -424,6 +424,15 @@ static int mlx5_hairpin_pair_queues(struct mlx5_hairpin *hp) return err; } +static void mlx5_hairpin_unpair_peer_sq(struct mlx5_hairpin *hp) +{ + int i; + + for (i = 0; i < hp->num_channels; i++) + mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY, + MLX5_SQC_STATE_RST, 0, 0); +} + static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp) { int i; @@ -432,13 +441,9 @@ static void mlx5_hairpin_unpair_queues(struct mlx5_hairpin *hp) for (i = 0; i < hp->num_channels; i++) mlx5_hairpin_modify_rq(hp->func_mdev, hp->rqn[i], MLX5_RQC_STATE_RDY, MLX5_RQC_STATE_RST, 0, 0); - /* unset peer SQs */ - if (hp->peer_gone) - return; - for (i = 0; i < hp->num_channels; i++) - mlx5_hairpin_modify_sq(hp->peer_mdev, hp->sqn[i], MLX5_SQC_STATE_RDY, - MLX5_SQC_STATE_RST, 0, 0); + if (!hp->peer_gone) + mlx5_hairpin_unpair_peer_sq(hp); } struct mlx5_hairpin * @@ -485,3 +490,16 @@ void mlx5_core_hairpin_destroy(struct mlx5_hairpin *hp) mlx5_hairpin_destroy_queues(hp); kfree(hp); } + +void mlx5_core_hairpin_clear_dead_peer(struct mlx5_hairpin *hp) +{ + int i; + + mlx5_hairpin_unpair_peer_sq(hp); + + /* destroy peer SQ */ + for (i = 0; i < hp->num_channels; i++) + mlx5_core_destroy_sq(hp->peer_mdev, hp->sqn[i]); + + hp->peer_gone = true; +} diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c index bdafc85fd874..fc91bbf7d0c3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c @@ -464,8 +464,6 @@ int mlx5_modify_nic_vport_node_guid(struct mlx5_core_dev *mdev, void *in; int err; - if (!vport) - return -EINVAL; if (!MLX5_CAP_GEN(mdev, vport_group_manager)) return -EACCES; diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c index bf85ce9835d7..42e4437ac3c1 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c @@ -708,7 +708,8 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz) MLXSW_THERMAL_TRIP_MASK, module_tz, &mlxsw_thermal_module_ops, - NULL, 0, 0); + NULL, 0, + module_tz->parent->polling_delay); if (IS_ERR(module_tz->tzdev)) { err = PTR_ERR(module_tz->tzdev); return err; @@ -830,7 +831,8 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz) MLXSW_THERMAL_TRIP_MASK, gearbox_tz, &mlxsw_thermal_gearbox_ops, - NULL, 0, 0); + NULL, 0, + gearbox_tz->parent->polling_delay); if (IS_ERR(gearbox_tz->tzdev)) return PTR_ERR(gearbox_tz->tzdev); diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 3c3069afc0a3..c670bf3464c2 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -3641,7 +3641,7 @@ MLXSW_ITEM32(reg, qeec, max_shaper_bs, 0x1C, 0, 6); #define MLXSW_REG_QEEC_HIGHEST_SHAPER_BS 25 #define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP1 5 #define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP2 11 -#define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP3 5 +#define MLXSW_REG_QEEC_LOWEST_SHAPER_BS_SP3 11 static inline void mlxsw_reg_qeec_pack(char *payload, u8 local_port, enum mlxsw_reg_qeec_hr hr, u8 index, diff --git a/drivers/net/ethernet/micrel/ks8842.c b/drivers/net/ethernet/micrel/ks8842.c index caa251d0e381..b27713906d3a 100644 --- a/drivers/net/ethernet/micrel/ks8842.c +++ b/drivers/net/ethernet/micrel/ks8842.c @@ -1135,6 +1135,10 @@ static int ks8842_probe(struct platform_device *pdev) unsigned i; iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iomem) { + dev_err(&pdev->dev, "Invalid resource\n"); + return -EINVAL; + } if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME)) goto err_mem_region; diff --git a/drivers/net/ethernet/moxa/moxart_ether.c b/drivers/net/ethernet/moxa/moxart_ether.c index 49fd843c4c8a..a0e1ccca505b 100644 --- a/drivers/net/ethernet/moxa/moxart_ether.c +++ b/drivers/net/ethernet/moxa/moxart_ether.c @@ -481,14 +481,13 @@ static int moxart_mac_probe(struct platform_device *pdev) priv->ndev = ndev; priv->pdev = pdev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - ndev->base_addr = res->start; - priv->base = devm_ioremap_resource(p_dev, res); + priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(priv->base)) { dev_err(p_dev, "devm_ioremap_resource failed\n"); ret = PTR_ERR(priv->base); goto init_fail; } + ndev->base_addr = res->start; spin_lock_init(&priv->txlock); @@ -542,10 +541,8 @@ static int moxart_mac_probe(struct platform_device *pdev) SET_NETDEV_DEV(ndev, &pdev->dev); ret = register_netdev(ndev); - if (ret) { - free_netdev(ndev); + if (ret) goto init_fail; - } netdev_dbg(ndev, "%s: IRQ=%d address=%pM\n", __func__, ndev->irq, ndev->dev_addr); diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index aa400b925b08..5bfc7acfd13a 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -355,6 +355,7 @@ static u32 ocelot_read_eq_avail(struct ocelot *ocelot, int port) int ocelot_port_flush(struct ocelot *ocelot, int port) { + unsigned int pause_ena; int err, val; /* Disable dequeuing from the egress queues */ @@ -363,6 +364,7 @@ int ocelot_port_flush(struct ocelot *ocelot, int port) QSYS_PORT_MODE, port); /* Disable flow control */ + ocelot_fields_read(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, &pause_ena); ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, 0); /* Disable priority flow control */ @@ -398,6 +400,9 @@ int ocelot_port_flush(struct ocelot *ocelot, int port) /* Clear flushing again. */ ocelot_rmw_gix(ocelot, 0, REW_PORT_CFG_FLUSH_ENA, REW_PORT_CFG, port); + /* Re-enable flow control */ + ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, pause_ena); + return err; } EXPORT_SYMBOL(ocelot_port_flush); diff --git a/drivers/net/ethernet/mscc/ocelot_io.c b/drivers/net/ethernet/mscc/ocelot_io.c index ea4e83410fe4..7390fa3980ec 100644 --- a/drivers/net/ethernet/mscc/ocelot_io.c +++ b/drivers/net/ethernet/mscc/ocelot_io.c @@ -21,7 +21,7 @@ u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset) ocelot->map[target][reg & REG_MASK] + offset, &val); return val; } -EXPORT_SYMBOL(__ocelot_read_ix); +EXPORT_SYMBOL_GPL(__ocelot_read_ix); void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset) { @@ -32,7 +32,7 @@ void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset) regmap_write(ocelot->targets[target], ocelot->map[target][reg & REG_MASK] + offset, val); } -EXPORT_SYMBOL(__ocelot_write_ix); +EXPORT_SYMBOL_GPL(__ocelot_write_ix); void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg, u32 offset) @@ -45,7 +45,7 @@ void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg, ocelot->map[target][reg & REG_MASK] + offset, mask, val); } -EXPORT_SYMBOL(__ocelot_rmw_ix); +EXPORT_SYMBOL_GPL(__ocelot_rmw_ix); u32 ocelot_port_readl(struct ocelot_port *port, u32 reg) { @@ -58,7 +58,7 @@ u32 ocelot_port_readl(struct ocelot_port *port, u32 reg) regmap_read(port->target, ocelot->map[target][reg & REG_MASK], &val); return val; } -EXPORT_SYMBOL(ocelot_port_readl); +EXPORT_SYMBOL_GPL(ocelot_port_readl); void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg) { @@ -69,7 +69,7 @@ void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg) regmap_write(port->target, ocelot->map[target][reg & REG_MASK], val); } -EXPORT_SYMBOL(ocelot_port_writel); +EXPORT_SYMBOL_GPL(ocelot_port_writel); void ocelot_port_rmwl(struct ocelot_port *port, u32 val, u32 mask, u32 reg) { @@ -77,7 +77,7 @@ void ocelot_port_rmwl(struct ocelot_port *port, u32 val, u32 mask, u32 reg) ocelot_port_writel(port, (cur & (~mask)) | val, reg); } -EXPORT_SYMBOL(ocelot_port_rmwl); +EXPORT_SYMBOL_GPL(ocelot_port_rmwl); u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target, u32 reg, u32 offset) @@ -128,7 +128,7 @@ int ocelot_regfields_init(struct ocelot *ocelot, return 0; } -EXPORT_SYMBOL(ocelot_regfields_init); +EXPORT_SYMBOL_GPL(ocelot_regfields_init); static struct regmap_config ocelot_regmap_config = { .reg_bits = 32, @@ -148,4 +148,4 @@ struct regmap *ocelot_regmap_init(struct ocelot *ocelot, struct resource *res) return devm_regmap_init_mmio(ocelot->dev, regs, &ocelot_regmap_config); } -EXPORT_SYMBOL(ocelot_regmap_init); +EXPORT_SYMBOL_GPL(ocelot_regmap_init); diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index c84c8bf2bc20..fc99ad8e4a38 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -3815,6 +3815,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&pdev->dev, "invalid sram_size %dB or board span %ldB\n", mgp->sram_size, mgp->board_span); + status = -EINVAL; goto abort_with_ioremap; } memcpy_fromio(mgp->eeprom_strings, diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c index b81e1487945c..14a17ad730f0 100644 --- a/drivers/net/ethernet/natsemi/natsemi.c +++ b/drivers/net/ethernet/natsemi/natsemi.c @@ -819,7 +819,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) printk(version); #endif - i = pci_enable_device(pdev); + i = pcim_enable_device(pdev); if (i) return i; /* natsemi has a non-standard PM control register @@ -852,7 +852,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) ioaddr = ioremap(iostart, iosize); if (!ioaddr) { i = -ENOMEM; - goto err_ioremap; + goto err_pci_request_regions; } /* Work around the dropped serial bit. */ @@ -974,9 +974,6 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent) err_register_netdev: iounmap(ioaddr); - err_ioremap: - pci_release_regions(pdev); - err_pci_request_regions: free_netdev(dev); return i; @@ -3241,7 +3238,6 @@ static void natsemi_remove1(struct pci_dev *pdev) NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround); unregister_netdev (dev); - pci_release_regions (pdev); iounmap(ioaddr); free_netdev (dev); } diff --git a/drivers/net/ethernet/neterion/vxge/vxge-main.c b/drivers/net/ethernet/neterion/vxge/vxge-main.c index 87892bd992b1..56556373548c 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-main.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c @@ -3527,13 +3527,13 @@ static void vxge_device_unregister(struct __vxge_hw_device *hldev) kfree(vdev->vpaths); - /* we are safe to free it now */ - free_netdev(dev); - vxge_debug_init(vdev->level_trace, "%s: ethernet device unregistered", buf); vxge_debug_entryexit(vdev->level_trace, "%s: %s:%d Exiting...", buf, __func__, __LINE__); + + /* we are safe to free it now */ + free_netdev(dev); } /* diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c index 9c9ae33d84ce..c036a1d0f8de 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c @@ -286,6 +286,8 @@ nfp_net_get_link_ksettings(struct net_device *netdev, /* Init to unknowns */ ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); + ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); + ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); cmd->base.port = PORT_OTHER; cmd->base.speed = SPEED_UNKNOWN; cmd->base.duplex = DUPLEX_UNKNOWN; diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index ade8c44c01cd..2942102efd48 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -107,7 +107,7 @@ static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) { u8 *data = skb->data; unsigned int offset; - u16 *hi, *id; + u16 hi, id; u32 lo; if (ptp_classify_raw(skb) == PTP_CLASS_NONE) @@ -118,14 +118,11 @@ static int pch_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid) if (skb->len < offset + OFF_PTP_SEQUENCE_ID + sizeof(seqid)) return 0; - hi = (u16 *)(data + offset + OFF_PTP_SOURCE_UUID); - id = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID); + hi = get_unaligned_be16(data + offset + OFF_PTP_SOURCE_UUID + 0); + lo = get_unaligned_be32(data + offset + OFF_PTP_SOURCE_UUID + 2); + id = get_unaligned_be16(data + offset + OFF_PTP_SEQUENCE_ID); - memcpy(&lo, &hi[1], sizeof(lo)); - - return (uid_hi == *hi && - uid_lo == lo && - seqid == *id); + return (uid_hi == hi && uid_lo == lo && seqid == id); } static void @@ -135,7 +132,6 @@ pch_rx_timestamp(struct pch_gbe_adapter *adapter, struct sk_buff *skb) struct pci_dev *pdev; u64 ns; u32 hi, lo, val; - u16 uid, seq; if (!adapter->hwts_rx_en) return; @@ -151,10 +147,7 @@ pch_rx_timestamp(struct pch_gbe_adapter *adapter, struct sk_buff *skb) lo = pch_src_uuid_lo_read(pdev); hi = pch_src_uuid_hi_read(pdev); - uid = hi & 0xffff; - seq = (hi >> 16) & 0xffff; - - if (!pch_ptp_match(skb, htons(uid), htonl(lo), htons(seq))) + if (!pch_ptp_match(skb, hi, lo, hi >> 16)) goto out; ns = pch_rx_snap_read(pdev); @@ -2536,9 +2529,13 @@ static int pch_gbe_probe(struct pci_dev *pdev, adapter->pdev = pdev; adapter->hw.back = adapter; adapter->hw.reg = pcim_iomap_table(pdev)[PCH_GBE_PCI_BAR]; + adapter->pdata = (struct pch_gbe_privdata *)pci_id->driver_data; - if (adapter->pdata && adapter->pdata->platform_init) - adapter->pdata->platform_init(pdev); + if (adapter->pdata && adapter->pdata->platform_init) { + ret = adapter->pdata->platform_init(pdev); + if (ret) + goto err_free_netdev; + } adapter->ptp_pdev = pci_get_domain_bus_and_slot(pci_domain_nr(adapter->pdev->bus), @@ -2633,7 +2630,7 @@ static int pch_gbe_probe(struct pci_dev *pdev, */ static int pch_gbe_minnow_platform_init(struct pci_dev *pdev) { - unsigned long flags = GPIOF_DIR_OUT | GPIOF_INIT_HIGH | GPIOF_EXPORT; + unsigned long flags = GPIOF_OUT_INIT_HIGH; unsigned gpio = MINNOW_PHY_RESET_GPIO; int ret; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index d0ae1cf43592..6dc7ce649448 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -52,7 +52,19 @@ static void ionic_dim_work(struct work_struct *work) cur_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix); qcq = container_of(dim, struct ionic_qcq, dim); new_coal = ionic_coal_usec_to_hw(qcq->q.lif->ionic, cur_moder.usec); - qcq->intr.dim_coal_hw = new_coal ? new_coal : 1; + new_coal = new_coal ? new_coal : 1; + + if (qcq->intr.dim_coal_hw != new_coal) { + unsigned int qi = qcq->cq.bound_q->index; + struct ionic_lif *lif = qcq->q.lif; + + qcq->intr.dim_coal_hw = new_coal; + + ionic_intr_coal_init(lif->ionic->idev.intr_ctrl, + lif->rxqcqs[qi]->intr.index, + qcq->intr.dim_coal_hw); + } + dim->state = DIM_START_MEASURE; } diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c index 909eca14f647..46dbb49f837c 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c @@ -197,12 +197,11 @@ static void ionic_rx_clean(struct ionic_queue *q, } } - if (likely(netdev->features & NETIF_F_RXCSUM)) { - if (comp->csum_flags & IONIC_RXQ_COMP_CSUM_F_CALC) { - skb->ip_summed = CHECKSUM_COMPLETE; - skb->csum = (__force __wsum)le16_to_cpu(comp->csum); - stats->csum_complete++; - } + if (likely(netdev->features & NETIF_F_RXCSUM) && + (comp->csum_flags & IONIC_RXQ_COMP_CSUM_F_CALC)) { + skb->ip_summed = CHECKSUM_COMPLETE; + skb->csum = (__force __wsum)le16_to_cpu(comp->csum); + stats->csum_complete++; } else { stats->csum_none++; } @@ -417,11 +416,12 @@ void ionic_rx_empty(struct ionic_queue *q) } } -static void ionic_dim_update(struct ionic_qcq *qcq) +static void ionic_dim_update(struct ionic_qcq *qcq, int napi_mode) { struct dim_sample dim_sample; struct ionic_lif *lif; unsigned int qi; + u64 pkts, bytes; if (!qcq->intr.dim_coal_hw) return; @@ -429,14 +429,23 @@ static void ionic_dim_update(struct ionic_qcq *qcq) lif = qcq->q.lif; qi = qcq->cq.bound_q->index; - ionic_intr_coal_init(lif->ionic->idev.intr_ctrl, - lif->rxqcqs[qi]->intr.index, - qcq->intr.dim_coal_hw); + switch (napi_mode) { + case IONIC_LIF_F_TX_DIM_INTR: + pkts = lif->txqstats[qi].pkts; + bytes = lif->txqstats[qi].bytes; + break; + case IONIC_LIF_F_RX_DIM_INTR: + pkts = lif->rxqstats[qi].pkts; + bytes = lif->rxqstats[qi].bytes; + break; + default: + pkts = lif->txqstats[qi].pkts + lif->rxqstats[qi].pkts; + bytes = lif->txqstats[qi].bytes + lif->rxqstats[qi].bytes; + break; + } dim_update_sample(qcq->cq.bound_intr->rearm_count, - lif->txqstats[qi].pkts, - lif->txqstats[qi].bytes, - &dim_sample); + pkts, bytes, &dim_sample); net_dim(&qcq->dim, dim_sample); } @@ -457,7 +466,7 @@ int ionic_tx_napi(struct napi_struct *napi, int budget) ionic_tx_service, NULL, NULL); if (work_done < budget && napi_complete_done(napi, work_done)) { - ionic_dim_update(qcq); + ionic_dim_update(qcq, IONIC_LIF_F_TX_DIM_INTR); flags |= IONIC_INTR_CRED_UNMASK; cq->bound_intr->rearm_count++; } @@ -493,7 +502,7 @@ int ionic_rx_napi(struct napi_struct *napi, int budget) ionic_rx_fill(cq->bound_q); if (work_done < budget && napi_complete_done(napi, work_done)) { - ionic_dim_update(qcq); + ionic_dim_update(qcq, IONIC_LIF_F_RX_DIM_INTR); flags |= IONIC_INTR_CRED_UNMASK; cq->bound_intr->rearm_count++; } @@ -535,7 +544,7 @@ int ionic_txrx_napi(struct napi_struct *napi, int budget) ionic_rx_fill_cb(rxcq->bound_q); if (rx_work_done < budget && napi_complete_done(napi, rx_work_done)) { - ionic_dim_update(qcq); + ionic_dim_update(qcq, 0); flags |= IONIC_INTR_CRED_UNMASK; rxcq->bound_intr->rearm_count++; } diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index d258e0ccf946..e2046b6d65a3 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1602,6 +1602,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) free_netdev(netdev); err_out_free_res: + if (NX_IS_REVISION_P3(pdev->revision)) + pci_disable_pcie_error_reporting(pdev); pci_release_regions(pdev); err_out_disable_pdev: diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c index 17d5b649eb36..e81dd34a3cac 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c @@ -1266,9 +1266,11 @@ int qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn, p_hwfn->p_dcbx_info->set.ver_num |= DCBX_CONFIG_VERSION_STATIC; p_hwfn->p_dcbx_info->set.enabled = dcbx_info->operational.enabled; + BUILD_BUG_ON(sizeof(dcbx_info->operational.params) != + sizeof(p_hwfn->p_dcbx_info->set.config.params)); memcpy(&p_hwfn->p_dcbx_info->set.config.params, &dcbx_info->operational.params, - sizeof(struct qed_dcbx_admin_params)); + sizeof(p_hwfn->p_dcbx_info->set.config.params)); p_hwfn->p_dcbx_info->set.config.valid = true; memcpy(params, &p_hwfn->p_dcbx_info->set, sizeof(struct qed_dcbx_set)); diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c index 49783f365079..f2c8273dce67 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c @@ -327,6 +327,9 @@ static int qed_ll2_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) unsigned long flags; int rc = -EINVAL; + if (!p_ll2_conn) + return rc; + spin_lock_irqsave(&p_tx->lock, flags); if (p_tx->b_completing_packet) { rc = -EBUSY; @@ -500,7 +503,16 @@ static int qed_ll2_rxq_completion(struct qed_hwfn *p_hwfn, void *cookie) unsigned long flags = 0; int rc = 0; + if (!p_ll2_conn) + return rc; + spin_lock_irqsave(&p_rx->lock, flags); + + if (!QED_LL2_RX_REGISTERED(p_ll2_conn)) { + spin_unlock_irqrestore(&p_rx->lock, flags); + return 0; + } + cq_new_idx = le16_to_cpu(*p_rx->p_fw_cons); cq_old_idx = qed_chain_get_cons_idx(&p_rx->rcq_chain); @@ -821,6 +833,9 @@ static int qed_ll2_lb_rxq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) struct qed_ll2_info *p_ll2_conn = (struct qed_ll2_info *)p_cookie; int rc; + if (!p_ll2_conn) + return 0; + if (!QED_LL2_RX_REGISTERED(p_ll2_conn)) return 0; @@ -844,6 +859,9 @@ static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie) u16 new_idx = 0, num_bds = 0; int rc; + if (!p_ll2_conn) + return 0; + if (!QED_LL2_TX_REGISTERED(p_ll2_conn)) return 0; @@ -1725,6 +1743,8 @@ int qed_ll2_post_rx_buffer(void *cxt, if (!p_ll2_conn) return -EINVAL; p_rx = &p_ll2_conn->rx_queue; + if (!p_rx->set_prod_addr) + return -EIO; spin_lock_irqsave(&p_rx->lock, flags); if (!list_empty(&p_rx->free_descq)) diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 5bd58c65e163..6bb9ec98a12b 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -616,7 +616,12 @@ static int qed_enable_msix(struct qed_dev *cdev, rc = cnt; } - if (rc > 0) { + /* For VFs, we should return with an error in case we didn't get the + * exact number of msix vectors as we requested. + * Not doing that will lead to a crash when starting queues for + * this VF. + */ + if ((IS_PF(cdev) && rc > 0) || (IS_VF(cdev) && rc == cnt)) { /* MSI-x configuration was achieved */ int_params->out.int_mode = QED_INT_MODE_MSIX; int_params->out.num_vectors = rc; diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c index cd882c453394..caeef25c89bb 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c @@ -474,14 +474,18 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn, spin_lock_bh(&p_hwfn->mcp_info->cmd_lock); - if (!qed_mcp_has_pending_cmd(p_hwfn)) + if (!qed_mcp_has_pending_cmd(p_hwfn)) { + spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); break; + } rc = qed_mcp_update_pending_cmd(p_hwfn, p_ptt); - if (!rc) + if (!rc) { + spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); break; - else if (rc != -EAGAIN) + } else if (rc != -EAGAIN) { goto err; + } spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); @@ -498,6 +502,8 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn, return -EAGAIN; } + spin_lock_bh(&p_hwfn->mcp_info->cmd_lock); + /* Send the mailbox command */ qed_mcp_reread_offsets(p_hwfn, p_ptt); seq_num = ++p_hwfn->mcp_info->drv_mb_seq; @@ -524,14 +530,18 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn, spin_lock_bh(&p_hwfn->mcp_info->cmd_lock); - if (p_cmd_elem->b_is_completed) + if (p_cmd_elem->b_is_completed) { + spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); break; + } rc = qed_mcp_update_pending_cmd(p_hwfn, p_ptt); - if (!rc) + if (!rc) { + spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); break; - else if (rc != -EAGAIN) + } else if (rc != -EAGAIN) { goto err; + } spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); } while (++cnt < max_retries); @@ -554,6 +564,7 @@ _qed_mcp_cmd_and_union(struct qed_hwfn *p_hwfn, return -EAGAIN; } + spin_lock_bh(&p_hwfn->mcp_info->cmd_lock); qed_mcp_cmd_del_elem(p_hwfn, p_cmd_elem); spin_unlock_bh(&p_hwfn->mcp_info->cmd_lock); diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c index da864d12916b..4f4b79250a2b 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c +++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c @@ -1285,8 +1285,7 @@ qed_rdma_create_qp(void *rdma_cxt, if (!rdma_cxt || !in_params || !out_params || !p_hwfn->p_rdma_info->active) { - DP_ERR(p_hwfn->cdev, - "qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n", + pr_err("qed roce create qp failed due to NULL entry (rdma_cxt=%p, in=%p, out=%p, roce_info=?\n", rdma_cxt, in_params, out_params); return NULL; } diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h index 3efc5899f656..f313fd730331 100644 --- a/drivers/net/ethernet/qlogic/qede/qede.h +++ b/drivers/net/ethernet/qlogic/qede/qede.h @@ -494,6 +494,7 @@ struct qede_fastpath { #define QEDE_SP_HW_ERR 4 #define QEDE_SP_ARFS_CONFIG 5 #define QEDE_SP_AER 7 +#define QEDE_SP_DISABLE 8 #ifdef CONFIG_RFS_ACCEL int qede_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index c59b72c90293..a2e4dfb5cb44 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -831,7 +831,7 @@ int qede_configure_vlan_filters(struct qede_dev *edev) int qede_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) { struct qede_dev *edev = netdev_priv(dev); - struct qede_vlan *vlan = NULL; + struct qede_vlan *vlan; int rc = 0; DP_VERBOSE(edev, NETIF_MSG_IFDOWN, "Removing vlan 0x%04x\n", vid); @@ -842,7 +842,7 @@ int qede_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, u16 vid) if (vlan->vid == vid) break; - if (!vlan || (vlan->vid != vid)) { + if (list_entry_is_head(vlan, &edev->vlan_list, list)) { DP_VERBOSE(edev, (NETIF_MSG_IFUP | NETIF_MSG_IFDOWN), "Vlan isn't configured\n"); goto out; diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index 05e3a3b60269..e93f06e4a172 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -1006,6 +1006,13 @@ static void qede_sp_task(struct work_struct *work) struct qede_dev *edev = container_of(work, struct qede_dev, sp_task.work); + /* Disable execution of this deferred work once + * qede removal is in progress, this stop any future + * scheduling of sp_task. + */ + if (test_bit(QEDE_SP_DISABLE, &edev->sp_flags)) + return; + /* The locking scheme depends on the specific flag: * In case of QEDE_SP_RECOVERY, acquiring the RTNL lock is required to * ensure that ongoing flows are ended and new ones are not started. @@ -1297,6 +1304,7 @@ static void __qede_remove(struct pci_dev *pdev, enum qede_remove_mode mode) qede_rdma_dev_remove(edev, (mode == QEDE_REMOVE_RECOVERY)); if (mode != QEDE_REMOVE_RECOVERY) { + set_bit(QEDE_SP_DISABLE, &edev->sp_flags); unregister_netdev(ndev); cancel_delayed_work_sync(&edev->sp_task); @@ -1861,6 +1869,7 @@ static void qede_sync_free_irqs(struct qede_dev *edev) } edev->int_info.used_cnt = 0; + edev->int_info.msix_cnt = 0; } static int qede_req_msix_irqs(struct qede_dev *edev) @@ -2401,7 +2410,6 @@ static int qede_load(struct qede_dev *edev, enum qede_load_mode mode, goto out; err4: qede_sync_free_irqs(edev); - memset(&edev->int_info.msix_cnt, 0, sizeof(struct qed_int_info)); err3: qede_napi_disable_remove(edev); err2: diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index 27740c027681..c7923e22a4c4 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -114,7 +114,7 @@ static int ql_sem_spinlock(struct ql3_adapter *qdev, value = readl(&port_regs->CommonRegs.semaphoreReg); if ((value & (sem_mask >> 16)) == sem_bits) return 0; - ssleep(1); + mdelay(1000); } while (--seconds); return -1; } @@ -154,7 +154,7 @@ static int ql_wait_for_drvr_lock(struct ql3_adapter *qdev) "driver lock acquired\n"); return 1; } - ssleep(1); + mdelay(1000); } while (++i < 10); netdev_err(qdev->ndev, "Timed out waiting for driver lock...\n"); @@ -3290,7 +3290,7 @@ static int ql_adapter_reset(struct ql3_adapter *qdev) if ((value & ISP_CONTROL_SR) == 0) break; - ssleep(1); + mdelay(1000); } while ((--max_wait_time)); /* @@ -3326,7 +3326,7 @@ static int ql_adapter_reset(struct ql3_adapter *qdev) ispControlStatus); if ((value & ISP_CONTROL_FSR) == 0) break; - ssleep(1); + mdelay(1000); } while ((--max_wait_time)); } if (max_wait_time == 0) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index d8882d0b6b49..d51bac7ba5af 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -3156,8 +3156,10 @@ int qlcnic_83xx_flash_read32(struct qlcnic_adapter *adapter, u32 flash_addr, indirect_addr = QLC_83XX_FLASH_DIRECT_DATA(addr); ret = QLCRD32(adapter, indirect_addr, &err); - if (err == -EIO) + if (err == -EIO) { + qlcnic_83xx_unlock_flash(adapter); return err; + } word = ret; *(u32 *)p_data = word; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index c2faf96fcade..27c07b2412f4 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2692,6 +2692,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) kfree(ahw); err_out_free_res: + pci_disable_pcie_error_reporting(pdev); pci_release_regions(pdev); err_out_disable_pdev: diff --git a/drivers/net/ethernet/qualcomm/emac/emac.c b/drivers/net/ethernet/qualcomm/emac/emac.c index 8543bf3c3484..ad655f0a4965 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac.c @@ -735,12 +735,13 @@ static int emac_remove(struct platform_device *pdev) put_device(&adpt->phydev->mdio.dev); mdiobus_unregister(adpt->mii_bus); - free_netdev(netdev); if (adpt->phy.digital) iounmap(adpt->phy.digital); iounmap(adpt->phy.base); + free_netdev(netdev); + return 0; } diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c index fcdecddb2812..8d51b0cb545c 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c @@ -26,7 +26,7 @@ static int rmnet_is_real_dev_registered(const struct net_device *real_dev) } /* Needs rtnl lock */ -static struct rmnet_port* +struct rmnet_port* rmnet_get_port_rtnl(const struct net_device *real_dev) { return rtnl_dereference(real_dev->rx_handler_data); @@ -253,7 +253,10 @@ static int rmnet_config_notify_cb(struct notifier_block *nb, netdev_dbg(real_dev, "Kernel unregister\n"); rmnet_force_unassociate_device(real_dev); break; - + case NETDEV_CHANGEMTU: + if (rmnet_vnd_validate_real_dev_mtu(real_dev)) + return NOTIFY_BAD; + break; default: break; } @@ -329,9 +332,17 @@ static int rmnet_changelink(struct net_device *dev, struct nlattr *tb[], if (data[IFLA_RMNET_FLAGS]) { struct ifla_rmnet_flags *flags; + u32 old_data_format; + old_data_format = port->data_format; flags = nla_data(data[IFLA_RMNET_FLAGS]); port->data_format = flags->flags & flags->mask; + + if (rmnet_vnd_update_dev_mtu(port, real_dev)) { + port->data_format = old_data_format; + NL_SET_ERR_MSG_MOD(extack, "Invalid MTU on real dev"); + return -EINVAL; + } } return 0; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h index be515982d628..8d8d4690a074 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h @@ -73,4 +73,6 @@ int rmnet_add_bridge(struct net_device *rmnet_dev, struct netlink_ext_ack *extack); int rmnet_del_bridge(struct net_device *rmnet_dev, struct net_device *slave_dev); +struct rmnet_port* +rmnet_get_port_rtnl(const struct net_device *real_dev); #endif /* _RMNET_CONFIG_H_ */ diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c index d58b51d277f1..2adcf24848a4 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.c @@ -58,9 +58,30 @@ static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } +static int rmnet_vnd_headroom(struct rmnet_port *port) +{ + u32 headroom; + + headroom = sizeof(struct rmnet_map_header); + + if (port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV4) + headroom += sizeof(struct rmnet_map_ul_csum_header); + + return headroom; +} + static int rmnet_vnd_change_mtu(struct net_device *rmnet_dev, int new_mtu) { - if (new_mtu < 0 || new_mtu > RMNET_MAX_PACKET_SIZE) + struct rmnet_priv *priv = netdev_priv(rmnet_dev); + struct rmnet_port *port; + u32 headroom; + + port = rmnet_get_port_rtnl(priv->real_dev); + + headroom = rmnet_vnd_headroom(port); + + if (new_mtu < 0 || new_mtu > RMNET_MAX_PACKET_SIZE || + new_mtu > (priv->real_dev->mtu - headroom)) return -EINVAL; rmnet_dev->mtu = new_mtu; @@ -104,24 +125,24 @@ static void rmnet_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *s) { struct rmnet_priv *priv = netdev_priv(dev); - struct rmnet_vnd_stats total_stats; + struct rmnet_vnd_stats total_stats = { }; struct rmnet_pcpu_stats *pcpu_ptr; + struct rmnet_vnd_stats snapshot; unsigned int cpu, start; - memset(&total_stats, 0, sizeof(struct rmnet_vnd_stats)); - for_each_possible_cpu(cpu) { pcpu_ptr = per_cpu_ptr(priv->pcpu_stats, cpu); do { start = u64_stats_fetch_begin_irq(&pcpu_ptr->syncp); - total_stats.rx_pkts += pcpu_ptr->stats.rx_pkts; - total_stats.rx_bytes += pcpu_ptr->stats.rx_bytes; - total_stats.tx_pkts += pcpu_ptr->stats.tx_pkts; - total_stats.tx_bytes += pcpu_ptr->stats.tx_bytes; + snapshot = pcpu_ptr->stats; /* struct assignment */ } while (u64_stats_fetch_retry_irq(&pcpu_ptr->syncp, start)); - total_stats.tx_drops += pcpu_ptr->stats.tx_drops; + total_stats.rx_pkts += snapshot.rx_pkts; + total_stats.rx_bytes += snapshot.rx_bytes; + total_stats.tx_pkts += snapshot.tx_pkts; + total_stats.tx_bytes += snapshot.tx_bytes; + total_stats.tx_drops += snapshot.tx_drops; } s->rx_packets = total_stats.rx_pkts; @@ -229,6 +250,7 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev, { struct rmnet_priv *priv = netdev_priv(rmnet_dev); + u32 headroom; int rc; if (rmnet_get_endpoint(port, id)) { @@ -242,6 +264,13 @@ int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev, priv->real_dev = real_dev; + headroom = rmnet_vnd_headroom(port); + + if (rmnet_vnd_change_mtu(rmnet_dev, real_dev->mtu - headroom)) { + NL_SET_ERR_MSG_MOD(extack, "Invalid MTU on real dev"); + return -EINVAL; + } + rc = register_netdevice(rmnet_dev); if (!rc) { ep->egress_dev = rmnet_dev; @@ -283,3 +312,45 @@ int rmnet_vnd_do_flow_control(struct net_device *rmnet_dev, int enable) return 0; } + +int rmnet_vnd_validate_real_dev_mtu(struct net_device *real_dev) +{ + struct hlist_node *tmp_ep; + struct rmnet_endpoint *ep; + struct rmnet_port *port; + unsigned long bkt_ep; + u32 headroom; + + port = rmnet_get_port_rtnl(real_dev); + + headroom = rmnet_vnd_headroom(port); + + hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { + if (ep->egress_dev->mtu > (real_dev->mtu - headroom)) + return -1; + } + + return 0; +} + +int rmnet_vnd_update_dev_mtu(struct rmnet_port *port, + struct net_device *real_dev) +{ + struct hlist_node *tmp_ep; + struct rmnet_endpoint *ep; + unsigned long bkt_ep; + u32 headroom; + + headroom = rmnet_vnd_headroom(port); + + hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { + if (ep->egress_dev->mtu <= (real_dev->mtu - headroom)) + continue; + + if (rmnet_vnd_change_mtu(ep->egress_dev, + real_dev->mtu - headroom)) + return -1; + } + + return 0; +} diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h index 4967f3461ed1..dc3a4443ef0a 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_vnd.h @@ -18,4 +18,7 @@ int rmnet_vnd_dellink(u8 id, struct rmnet_port *port, void rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev); void rmnet_vnd_tx_fixup(struct sk_buff *skb, struct net_device *dev); void rmnet_vnd_setup(struct net_device *dev); +int rmnet_vnd_validate_real_dev_mtu(struct net_device *real_dev); +int rmnet_vnd_update_dev_mtu(struct rmnet_port *port, + struct net_device *real_dev); #endif /* _RMNET_VND_H_ */ diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 3bb36f4a984e..e690a1b09e98 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -1673,7 +1673,7 @@ static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) { switch(stringset) { case ETH_SS_STATS: - memcpy(data, *rtl8169_gstrings, sizeof(rtl8169_gstrings)); + memcpy(data, rtl8169_gstrings, sizeof(rtl8169_gstrings)); break; } } @@ -3547,7 +3547,6 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp) rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000); rtl_pcie_state_l2l3_disable(tp); - rtl_hw_aspm_clkreq_enable(tp, true); } DECLARE_RTL_COND(rtl_mac_ocp_e00e_cond) @@ -5161,7 +5160,8 @@ static int r8169_mdio_register(struct rtl8169_private *tp) new_bus->priv = tp; new_bus->parent = &pdev->dev; new_bus->irq[0] = PHY_IGNORE_INTERRUPT; - snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x", pci_dev_id(pdev)); + snprintf(new_bus->id, MII_BUS_ID_SIZE, "r8169-%x-%x", + pci_domain_nr(pdev->bus), pci_dev_id(pdev)); new_bus->read = r8169_mdio_read_reg; new_bus->write = r8169_mdio_write_reg; diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 6d84266c03ca..5cab2d3c0023 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2287,7 +2287,7 @@ static void sh_eth_get_strings(struct net_device *ndev, u32 stringset, u8 *data) { switch (stringset) { case ETH_SS_STATS: - memcpy(data, *sh_eth_gstrings_stats, + memcpy(data, sh_eth_gstrings_stats, sizeof(sh_eth_gstrings_stats)); break; } diff --git a/drivers/net/ethernet/sfc/ef10_sriov.c b/drivers/net/ethernet/sfc/ef10_sriov.c index 21fa6c0e8873..84041cd587d7 100644 --- a/drivers/net/ethernet/sfc/ef10_sriov.c +++ b/drivers/net/ethernet/sfc/ef10_sriov.c @@ -402,12 +402,17 @@ static int efx_ef10_pci_sriov_enable(struct efx_nic *efx, int num_vfs) return rc; } +/* Disable SRIOV and remove VFs + * If some VFs are attached to a guest (using Xen, only) nothing is + * done if force=false, and vports are freed if force=true (for the non + * attachedc ones, only) but SRIOV is not disabled and VFs are not + * removed in either case. + */ static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force) { struct pci_dev *dev = efx->pci_dev; - unsigned int vfs_assigned = 0; - - vfs_assigned = pci_vfs_assigned(dev); + unsigned int vfs_assigned = pci_vfs_assigned(dev); + int rc = 0; if (vfs_assigned && !force) { netif_info(efx, drv, efx->net_dev, "VFs are assigned to guests; " @@ -417,10 +422,12 @@ static int efx_ef10_pci_sriov_disable(struct efx_nic *efx, bool force) if (!vfs_assigned) pci_disable_sriov(dev); + else + rc = -EBUSY; efx_ef10_sriov_free_vf_vswitching(efx); efx->vf_count = 0; - return 0; + return rc; } int efx_ef10_sriov_configure(struct efx_nic *efx, int num_vfs) @@ -439,7 +446,6 @@ int efx_ef10_sriov_init(struct efx_nic *efx) void efx_ef10_sriov_fini(struct efx_nic *efx) { struct efx_ef10_nic_data *nic_data = efx->nic_data; - unsigned int i; int rc; if (!nic_data->vf) { @@ -449,14 +455,7 @@ void efx_ef10_sriov_fini(struct efx_nic *efx) return; } - /* Remove any VFs in the host */ - for (i = 0; i < efx->vf_count; ++i) { - struct efx_nic *vf_efx = nic_data->vf[i].efx; - - if (vf_efx) - vf_efx->pci_dev->driver->remove(vf_efx->pci_dev); - } - + /* Disable SRIOV and remove any VFs in the host */ rc = efx_ef10_pci_sriov_disable(efx, true); if (rc) netif_dbg(efx, drv, efx->net_dev, diff --git a/drivers/net/ethernet/sfc/efx_channels.c b/drivers/net/ethernet/sfc/efx_channels.c index a4a626e9cd9a..0a8799a208cf 100644 --- a/drivers/net/ethernet/sfc/efx_channels.c +++ b/drivers/net/ethernet/sfc/efx_channels.c @@ -889,18 +889,20 @@ int efx_set_channels(struct efx_nic *efx) if (efx_channel_is_xdp_tx(channel)) { efx_for_each_channel_tx_queue(tx_queue, channel) { tx_queue->queue = next_queue++; - netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is XDP %u, HW %u\n", - channel->channel, tx_queue->label, - xdp_queue_number, tx_queue->queue); + /* We may have a few left-over XDP TX * queues owing to xdp_tx_queue_count * not dividing evenly by EFX_MAX_TXQ_PER_CHANNEL. * We still allocate and probe those * TXQs, but never use them. */ - if (xdp_queue_number < efx->xdp_tx_queue_count) + if (xdp_queue_number < efx->xdp_tx_queue_count) { + netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is XDP %u, HW %u\n", + channel->channel, tx_queue->label, + xdp_queue_number, tx_queue->queue); efx->xdp_tx_queues[xdp_queue_number] = tx_queue; - xdp_queue_number++; + xdp_queue_number++; + } } } else { efx_for_each_channel_tx_queue(tx_queue, channel) { @@ -912,6 +914,7 @@ int efx_set_channels(struct efx_nic *efx) } } } + WARN_ON(xdp_queue_number != efx->xdp_tx_queue_count); rc = netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels); if (rc) diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index d1e908846f5d..22fbb0ae77fb 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -90,6 +90,7 @@ int efx_nic_init_interrupt(struct efx_nic *efx) efx->pci_dev->irq); goto fail1; } + efx->irqs_hooked = true; return 0; } diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c index 6eef0f45b133..2b29fd4cbdf4 100644 --- a/drivers/net/ethernet/sgi/ioc3-eth.c +++ b/drivers/net/ethernet/sgi/ioc3-eth.c @@ -835,6 +835,10 @@ static int ioc3eth_probe(struct platform_device *pdev) int err; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) { + dev_err(&pdev->dev, "Invalid resource\n"); + return -EINVAL; + } /* get mac addr from one wire prom */ if (ioc3eth_get_mac_addr(regs, mac_addr)) return -EPROBE_DEFER; /* not available yet */ diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index 620c26f71be8..e267b7ce3a45 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -443,7 +443,7 @@ static int sis900_probe(struct pci_dev *pci_dev, #endif /* setup various bits in PCI command register */ - ret = pci_enable_device(pci_dev); + ret = pcim_enable_device(pci_dev); if(ret) return ret; i = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32)); @@ -469,7 +469,7 @@ static int sis900_probe(struct pci_dev *pci_dev, ioaddr = pci_iomap(pci_dev, 0, 0); if (!ioaddr) { ret = -ENOMEM; - goto err_out_cleardev; + goto err_out; } sis_priv = netdev_priv(net_dev); @@ -581,8 +581,6 @@ static int sis900_probe(struct pci_dev *pci_dev, sis_priv->tx_ring_dma); err_out_unmap: pci_iounmap(pci_dev, ioaddr); -err_out_cleardev: - pci_release_regions(pci_dev); err_out: free_netdev(net_dev); return ret; @@ -2499,7 +2497,6 @@ static void sis900_remove(struct pci_dev *pci_dev) sis_priv->tx_ring_dma); pci_iounmap(pci_dev, sis_priv->ioaddr); free_netdev(net_dev); - pci_release_regions(pci_dev); } static int __maybe_unused sis900_suspend(struct device *dev) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index b70d44ac0990..3c73453725f9 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -76,10 +76,10 @@ enum power_event { #define LPI_CTRL_STATUS_TLPIEN 0x00000001 /* Transmit LPI Entry */ /* GMAC HW ADDR regs */ -#define GMAC_ADDR_HIGH(reg) (((reg > 15) ? 0x00000800 : 0x00000040) + \ - (reg * 8)) -#define GMAC_ADDR_LOW(reg) (((reg > 15) ? 0x00000804 : 0x00000044) + \ - (reg * 8)) +#define GMAC_ADDR_HIGH(reg) ((reg > 15) ? 0x00000800 + (reg - 16) * 8 : \ + 0x00000040 + (reg * 8)) +#define GMAC_ADDR_LOW(reg) ((reg > 15) ? 0x00000804 + (reg - 16) * 8 : \ + 0x00000044 + (reg * 8)) #define GMAC_MAX_PERFECT_ADDRESSES 1 #define GMAC_PCS_BASE 0x000000c0 /* PCS register base */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index b2a707e2ef43..678726c62a8a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -441,6 +441,12 @@ int stmmac_mdio_register(struct net_device *ndev) found = 1; } + if (!found && !mdio_node) { + dev_warn(dev, "No PHY found\n"); + err = -ENODEV; + goto no_phy_found; + } + /* Try to probe the XPCS by scanning all addresses. */ if (priv->hw->xpcs) { struct mdio_xpcs_args *xpcs = &priv->hw->xpcs_args; @@ -449,6 +455,7 @@ int stmmac_mdio_register(struct net_device *ndev) xpcs->bus = new_bus; + found = 0; for (addr = 0; addr < max_addr; addr++) { xpcs->addr = addr; @@ -458,13 +465,12 @@ int stmmac_mdio_register(struct net_device *ndev) break; } } - } - if (!found && !mdio_node) { - dev_warn(dev, "No PHY found\n"); - mdiobus_unregister(new_bus); - mdiobus_free(new_bus); - return -ENODEV; + if (!found && !mdio_node) { + dev_warn(dev, "No XPCS found\n"); + err = -ENODEV; + goto no_xpcs_found; + } } bus_register_done: @@ -472,6 +478,9 @@ int stmmac_mdio_register(struct net_device *ndev) return 0; +no_xpcs_found: +no_phy_found: + mdiobus_unregister(new_bus); bus_register_fail: mdiobus_free(new_bus); return err; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index af34a4cadbb0..53be8fc1d125 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -399,6 +399,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) struct device_node *np = pdev->dev.of_node; struct plat_stmmacenet_data *plat; struct stmmac_dma_cfg *dma_cfg; + int phy_mode; int rc; plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); @@ -413,10 +414,11 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) *mac = NULL; } - plat->phy_interface = device_get_phy_mode(&pdev->dev); - if (plat->phy_interface < 0) - return ERR_PTR(plat->phy_interface); + phy_mode = device_get_phy_mode(&pdev->dev); + if (phy_mode < 0) + return ERR_PTR(phy_mode); + plat->phy_interface = phy_mode; plat->interface = stmmac_of_get_mac_mode(np); if (plat->interface < 0) plat->interface = plat->phy_interface; @@ -626,6 +628,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) void stmmac_remove_config_dt(struct platform_device *pdev, struct plat_stmmacenet_data *plat) { + clk_disable_unprepare(plat->stmmac_clk); + clk_disable_unprepare(plat->pclk); of_node_put(plat->phy_node); of_node_put(plat->mdio_node); } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c index 40dc14d1415f..639980306115 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c @@ -689,14 +689,18 @@ static int tc_setup_taprio(struct stmmac_priv *priv, GFP_KERNEL); if (!plat->est) return -ENOMEM; + + mutex_init(&priv->plat->est->lock); } else { memset(plat->est, 0, sizeof(*plat->est)); } size = qopt->num_entries; + mutex_lock(&priv->plat->est->lock); priv->plat->est->gcl_size = size; priv->plat->est->enable = qopt->enable; + mutex_unlock(&priv->plat->est->lock); for (i = 0; i < size; i++) { s64 delta_ns = qopt->entries[i].interval; @@ -727,6 +731,7 @@ static int tc_setup_taprio(struct stmmac_priv *priv, priv->plat->est->gcl[i] = delta_ns | (gates << wid); } + mutex_lock(&priv->plat->est->lock); /* Adjust for real system time */ priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, ¤t_time); current_time_ns = timespec64_to_ktime(current_time); @@ -751,19 +756,23 @@ static int tc_setup_taprio(struct stmmac_priv *priv, priv->plat->est->ctr[0] = do_div(ctr, NSEC_PER_SEC); priv->plat->est->ctr[1] = (u32)ctr; - if (fpe && !priv->dma_cap.fpesel) + if (fpe && !priv->dma_cap.fpesel) { + mutex_unlock(&priv->plat->est->lock); return -EOPNOTSUPP; + } ret = stmmac_fpe_configure(priv, priv->ioaddr, priv->plat->tx_queues_to_use, priv->plat->rx_queues_to_use, fpe); if (ret && fpe) { + mutex_unlock(&priv->plat->est->lock); netdev_err(priv->dev, "failed to enable Frame Preemption\n"); return ret; } ret = stmmac_est_configure(priv, priv->ioaddr, priv->plat->est, priv->plat->clk_ptp_rate); + mutex_unlock(&priv->plat->est->lock); if (ret) { netdev_err(priv->dev, "failed to configure EST\n"); goto disable; @@ -773,9 +782,14 @@ static int tc_setup_taprio(struct stmmac_priv *priv, return 0; disable: - priv->plat->est->enable = false; - stmmac_est_configure(priv, priv->ioaddr, priv->plat->est, - priv->plat->clk_ptp_rate); + if (priv->plat->est) { + mutex_lock(&priv->plat->est->lock); + priv->plat->est->enable = false; + stmmac_est_configure(priv, priv->ioaddr, priv->plat->est, + priv->plat->clk_ptp_rate); + mutex_unlock(&priv->plat->est->lock); + } + return ret; } diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 74e748662ec0..860644d182ab 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -8191,8 +8191,9 @@ static int niu_pci_vpd_fetch(struct niu *np, u32 start) err = niu_pci_vpd_scan_props(np, here, end); if (err < 0) return err; + /* ret == 1 is not an error */ if (err == 1) - return -EINVAL; + return 0; } return 0; } diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index 501d676fd88b..0805edef5625 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -1433,12 +1433,12 @@ static void am65_cpsw_nuss_free_tx_chns(void *data) for (i = 0; i < common->tx_ch_num; i++) { struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i]; - if (!IS_ERR_OR_NULL(tx_chn->tx_chn)) - k3_udma_glue_release_tx_chn(tx_chn->tx_chn); - if (!IS_ERR_OR_NULL(tx_chn->desc_pool)) k3_cppi_desc_pool_destroy(tx_chn->desc_pool); + if (!IS_ERR_OR_NULL(tx_chn->tx_chn)) + k3_udma_glue_release_tx_chn(tx_chn->tx_chn); + memset(tx_chn, 0, sizeof(*tx_chn)); } } @@ -1458,12 +1458,12 @@ void am65_cpsw_nuss_remove_tx_chns(struct am65_cpsw_common *common) netif_napi_del(&tx_chn->napi_tx); - if (!IS_ERR_OR_NULL(tx_chn->tx_chn)) - k3_udma_glue_release_tx_chn(tx_chn->tx_chn); - if (!IS_ERR_OR_NULL(tx_chn->desc_pool)) k3_cppi_desc_pool_destroy(tx_chn->desc_pool); + if (!IS_ERR_OR_NULL(tx_chn->tx_chn)) + k3_udma_glue_release_tx_chn(tx_chn->tx_chn); + memset(tx_chn, 0, sizeof(*tx_chn)); } } @@ -1550,11 +1550,11 @@ static void am65_cpsw_nuss_free_rx_chns(void *data) rx_chn = &common->rx_chns; - if (!IS_ERR_OR_NULL(rx_chn->rx_chn)) - k3_udma_glue_release_rx_chn(rx_chn->rx_chn); - if (!IS_ERR_OR_NULL(rx_chn->desc_pool)) k3_cppi_desc_pool_destroy(rx_chn->desc_pool); + + if (!IS_ERR_OR_NULL(rx_chn->rx_chn)) + k3_udma_glue_release_rx_chn(rx_chn->rx_chn); } static int am65_cpsw_nuss_init_rx_chns(struct am65_cpsw_common *common) diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c index 2f5e0ad23ad7..31cefd6ef680 100644 --- a/drivers/net/ethernet/ti/cpsw_new.c +++ b/drivers/net/ethernet/ti/cpsw_new.c @@ -928,7 +928,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, struct cpdma_chan *txch; int ret, q_idx; - if (skb_padto(skb, CPSW_MIN_PACKET_SIZE)) { + if (skb_put_padto(skb, READ_ONCE(priv->tx_packet_min))) { cpsw_err(priv, tx_err, "packet pad failed\n"); ndev->stats.tx_dropped++; return NET_XMIT_DROP; @@ -1108,7 +1108,7 @@ static int cpsw_ndo_xdp_xmit(struct net_device *ndev, int n, for (i = 0; i < n; i++) { xdpf = frames[i]; - if (xdpf->len < CPSW_MIN_PACKET_SIZE) { + if (xdpf->len < READ_ONCE(priv->tx_packet_min)) { xdp_return_frame_rx_napi(xdpf); drops++; continue; @@ -1402,6 +1402,7 @@ static int cpsw_create_ports(struct cpsw_common *cpsw) priv->dev = dev; priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG); priv->emac_port = i + 1; + priv->tx_packet_min = CPSW_MIN_PACKET_SIZE; if (is_valid_ether_addr(slave_data->mac_addr)) { ether_addr_copy(priv->mac_addr, slave_data->mac_addr); @@ -1699,6 +1700,7 @@ static int cpsw_dl_switch_mode_set(struct devlink *dl, u32 id, priv = netdev_priv(sl_ndev); slave->port_vlan = vlan; + WRITE_ONCE(priv->tx_packet_min, CPSW_MIN_PACKET_SIZE_VLAN); if (netif_running(sl_ndev)) cpsw_port_add_switch_def_ale_entries(priv, slave); @@ -1727,6 +1729,7 @@ static int cpsw_dl_switch_mode_set(struct devlink *dl, u32 id, priv = netdev_priv(slave->ndev); slave->port_vlan = slave->data->dual_emac_res_vlan; + WRITE_ONCE(priv->tx_packet_min, CPSW_MIN_PACKET_SIZE); cpsw_port_add_dual_emac_def_ale_entries(priv, slave); } diff --git a/drivers/net/ethernet/ti/cpsw_priv.h b/drivers/net/ethernet/ti/cpsw_priv.h index 7b7f3596b20d..a100c93edee8 100644 --- a/drivers/net/ethernet/ti/cpsw_priv.h +++ b/drivers/net/ethernet/ti/cpsw_priv.h @@ -89,7 +89,8 @@ do { \ #define CPSW_POLL_WEIGHT 64 #define CPSW_RX_VLAN_ENCAP_HDR_SIZE 4 -#define CPSW_MIN_PACKET_SIZE (VLAN_ETH_ZLEN) +#define CPSW_MIN_PACKET_SIZE_VLAN (VLAN_ETH_ZLEN) +#define CPSW_MIN_PACKET_SIZE (ETH_ZLEN) #define CPSW_MAX_PACKET_SIZE (VLAN_ETH_FRAME_LEN +\ ETH_FCS_LEN +\ CPSW_RX_VLAN_ENCAP_HDR_SIZE) @@ -380,6 +381,7 @@ struct cpsw_priv { u32 emac_port; struct cpsw_common *cpsw; int offload_fwd_mark; + u32 tx_packet_min; }; #define ndev_to_cpsw(ndev) (((struct cpsw_priv *)netdev_priv(ndev))->cpsw) diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 267c080ee084..0072ffa6e19e 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -313,9 +313,8 @@ static void tlan_remove_one(struct pci_dev *pdev) pci_release_regions(pdev); #endif - free_netdev(dev); - cancel_work_sync(&priv->tlan_tqueue); + free_netdev(dev); } static void tlan_start(struct net_device *dev) diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index 030185301014..6bd3a389d389 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -774,12 +774,15 @@ static void temac_start_xmit_done(struct net_device *ndev) stat = be32_to_cpu(cur_p->app0); while (stat & STS_CTRL_APP0_CMPLT) { + /* Make sure that the other fields are read after bd is + * released by dma + */ + rmb(); dma_unmap_single(ndev->dev.parent, be32_to_cpu(cur_p->phys), be32_to_cpu(cur_p->len), DMA_TO_DEVICE); skb = (struct sk_buff *)ptr_from_txbd(cur_p); if (skb) dev_consume_skb_irq(skb); - cur_p->app0 = 0; cur_p->app1 = 0; cur_p->app2 = 0; cur_p->app3 = 0; @@ -788,6 +791,12 @@ static void temac_start_xmit_done(struct net_device *ndev) ndev->stats.tx_packets++; ndev->stats.tx_bytes += be32_to_cpu(cur_p->len); + /* app0 must be visible last, as it is used to flag + * availability of the bd + */ + smp_mb(); + cur_p->app0 = 0; + lp->tx_bd_ci++; if (lp->tx_bd_ci >= lp->tx_bd_num) lp->tx_bd_ci = 0; @@ -814,6 +823,9 @@ static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag) if (cur_p->app0) return NETDEV_TX_BUSY; + /* Make sure to read next bd app0 after this one */ + rmb(); + tail++; if (tail >= lp->tx_bd_num) tail = 0; @@ -849,7 +861,7 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) smp_mb(); /* Space might have just been freed - check again */ - if (temac_check_tx_bd_space(lp, num_frag)) + if (temac_check_tx_bd_space(lp, num_frag + 1)) return NETDEV_TX_BUSY; netif_wake_queue(ndev); @@ -876,7 +888,6 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_OK; } cur_p->phys = cpu_to_be32(skb_dma_addr); - ptr_to_txbd((void *)skb, cur_p); for (ii = 0; ii < num_frag; ii++) { if (++lp->tx_bd_tail >= lp->tx_bd_num) @@ -915,6 +926,11 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) } cur_p->app0 |= cpu_to_be32(STS_CTRL_APP0_EOP); + /* Mark last fragment with skb address, so it can be consumed + * in temac_start_xmit_done() + */ + ptr_to_txbd((void *)skb, cur_p); + tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; lp->tx_bd_tail++; if (lp->tx_bd_tail >= lp->tx_bd_num) @@ -926,6 +942,11 @@ temac_start_xmit(struct sk_buff *skb, struct net_device *ndev) wmb(); lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */ + if (temac_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) { + netdev_info(ndev, "%s -> netif_stop_queue\n", __func__); + netif_stop_queue(ndev); + } + return NETDEV_TX_OK; } diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 0c26f5bcc523..962831cdde4d 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -1191,9 +1191,8 @@ static int xemaclite_of_probe(struct platform_device *ofdev) } dev_info(dev, - "Xilinx EmacLite at 0x%08X mapped to 0x%08X, irq=%d\n", - (unsigned int __force)ndev->mem_start, - (unsigned int __force)lp->base_addr, ndev->irq); + "Xilinx EmacLite at 0x%08X mapped to 0x%p, irq=%d\n", + (unsigned int __force)ndev->mem_start, lp->base_addr, ndev->irq); return 0; error: diff --git a/drivers/net/fddi/defza.c b/drivers/net/fddi/defza.c index eaf85db53a5e..2e7d6cc16b2d 100644 --- a/drivers/net/fddi/defza.c +++ b/drivers/net/fddi/defza.c @@ -1504,9 +1504,8 @@ static int fza_probe(struct device *bdev) release_mem_region(start, len); err_out_kfree: - free_netdev(dev); - pr_err("%s: initialization failure, aborting!\n", fp->name); + free_netdev(dev); return ret; } diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c index 466622664424..e449d9466122 100644 --- a/drivers/net/fjes/fjes_main.c +++ b/drivers/net/fjes/fjes_main.c @@ -1262,6 +1262,10 @@ static int fjes_probe(struct platform_device *plat_dev) adapter->interrupt_watch_enable = false; res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); + if (!res) { + err = -EINVAL; + goto err_free_control_wq; + } hw->hw_res.start = res->start; hw->hw_res.size = resource_size(res); hw->hw_res.irq = platform_get_irq(plat_dev, 0); diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 71d6629e65c9..da13683d52d1 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -839,6 +839,12 @@ static void decode_data(struct sixpack *sp, unsigned char inbyte) return; } + if (sp->rx_count_cooked + 2 >= sizeof(sp->cooked_buf)) { + pr_err("6pack: cooked buffer overrun, data loss\n"); + sp->rx_count = 0; + return; + } + buf = sp->raw_buf; sp->cooked_buf[sp->rx_count_cooked++] = buf[0] | ((buf[1] << 2) & 0xc0); diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 17be2bb2985c..920e9f888cc3 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -799,6 +799,7 @@ static void mkiss_close(struct tty_struct *tty) ax->tty = NULL; unregister_netdev(ax->dev); + free_netdev(ax->dev); } /* Perform I/O control on an active ax25 channel. */ diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c index c0bf7d78276e..080b15fc0060 100644 --- a/drivers/net/ieee802154/mac802154_hwsim.c +++ b/drivers/net/ieee802154/mac802154_hwsim.c @@ -418,7 +418,7 @@ static int hwsim_new_edge_nl(struct sk_buff *msg, struct genl_info *info) struct hwsim_edge *e; u32 v0, v1; - if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] && + if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] || !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE]) return -EINVAL; @@ -480,7 +480,7 @@ static int hwsim_del_edge_nl(struct sk_buff *msg, struct genl_info *info) struct hwsim_edge *e; u32 v0, v1; - if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] && + if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] || !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE]) return -EINVAL; @@ -528,14 +528,14 @@ static int hwsim_set_edge_lqi(struct sk_buff *msg, struct genl_info *info) u32 v0, v1; u8 lqi; - if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] && + if (!info->attrs[MAC802154_HWSIM_ATTR_RADIO_ID] || !info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE]) return -EINVAL; if (nla_parse_nested_deprecated(edge_attrs, MAC802154_HWSIM_EDGE_ATTR_MAX, info->attrs[MAC802154_HWSIM_ATTR_RADIO_EDGE], hwsim_edge_policy, NULL)) return -EINVAL; - if (!edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID] && + if (!edge_attrs[MAC802154_HWSIM_EDGE_ATTR_ENDPOINT_ID] || !edge_attrs[MAC802154_HWSIM_EDGE_ATTR_LQI]) return -EINVAL; @@ -715,6 +715,8 @@ static int hwsim_subscribe_all_others(struct hwsim_phy *phy) return 0; +sub_fail: + hwsim_edge_unsubscribe_me(phy); me_fail: rcu_read_lock(); list_for_each_entry_rcu(e, &phy->edges, list) { @@ -722,8 +724,6 @@ static int hwsim_subscribe_all_others(struct hwsim_phy *phy) hwsim_free_edge(e); } rcu_read_unlock(); -sub_fail: - hwsim_edge_unsubscribe_me(phy); return -ENOMEM; } @@ -824,12 +824,17 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev, static void hwsim_del(struct hwsim_phy *phy) { struct hwsim_pib *pib; + struct hwsim_edge *e; hwsim_edge_unsubscribe_me(phy); list_del(&phy->list); rcu_read_lock(); + list_for_each_entry_rcu(e, &phy->edges, list) { + list_del_rcu(&e->list); + hwsim_free_edge(e); + } pib = rcu_dereference(phy->pib); rcu_read_unlock(); diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c index cd4d993b0bbb..4162a608a3bf 100644 --- a/drivers/net/ipa/ipa_main.c +++ b/drivers/net/ipa/ipa_main.c @@ -589,6 +589,7 @@ static int ipa_firmware_load(struct device *dev) } ret = of_address_to_resource(node, 0, &res); + of_node_put(node); if (ret) { dev_err(dev, "error %d getting \"memory-region\" resource\n", ret); diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 11ca5fa902a1..c601d3df2722 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -1818,7 +1818,7 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info) ctx.sa.rx_sa = rx_sa; ctx.secy = secy; memcpy(ctx.sa.key, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), - MACSEC_KEYID_LEN); + secy->key_len); err = macsec_offload(ops->mdo_add_rxsa, &ctx); if (err) @@ -2060,7 +2060,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info) ctx.sa.tx_sa = tx_sa; ctx.secy = secy; memcpy(ctx.sa.key, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), - MACSEC_KEYID_LEN); + secy->key_len); err = macsec_offload(ops->mdo_add_txsa, &ctx); if (err) diff --git a/drivers/net/mdio/mdio-ipq8064.c b/drivers/net/mdio/mdio-ipq8064.c index 1bd18857e1c5..f0a6bfa61645 100644 --- a/drivers/net/mdio/mdio-ipq8064.c +++ b/drivers/net/mdio/mdio-ipq8064.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include @@ -96,14 +96,34 @@ ipq8064_mdio_write(struct mii_bus *bus, int phy_addr, int reg_offset, u16 data) return ipq8064_mdio_wait_busy(priv); } +static const struct regmap_config ipq8064_mdio_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .can_multi_write = false, + /* the mdio lock is used by any user of this mdio driver */ + .disable_locking = true, + + .cache_type = REGCACHE_NONE, +}; + static int ipq8064_mdio_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct ipq8064_mdio *priv; + struct resource res; struct mii_bus *bus; + void __iomem *base; int ret; + if (of_address_to_resource(np, 0, &res)) + return -ENOMEM; + + base = ioremap(res.start, resource_size(&res)); + if (!base) + return -ENOMEM; + bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*priv)); if (!bus) return -ENOMEM; @@ -115,15 +135,10 @@ ipq8064_mdio_probe(struct platform_device *pdev) bus->parent = &pdev->dev; priv = bus->priv; - priv->base = device_node_to_regmap(np); - if (IS_ERR(priv->base)) { - if (priv->base == ERR_PTR(-EPROBE_DEFER)) - return -EPROBE_DEFER; - - dev_err(&pdev->dev, "error getting device regmap, error=%pe\n", - priv->base); + priv->base = devm_regmap_init_mmio(&pdev->dev, base, + &ipq8064_mdio_regmap_config); + if (IS_ERR(priv->base)) return PTR_ERR(priv->base); - } ret = of_mdiobus_register(bus, np); if (ret) diff --git a/drivers/net/mdio/mdio-mux.c b/drivers/net/mdio/mdio-mux.c index 6a1d3540210b..ccb3ee704eb1 100644 --- a/drivers/net/mdio/mdio-mux.c +++ b/drivers/net/mdio/mdio-mux.c @@ -82,6 +82,17 @@ static int mdio_mux_write(struct mii_bus *bus, int phy_id, static int parent_count; +static void mdio_mux_uninit_children(struct mdio_mux_parent_bus *pb) +{ + struct mdio_mux_child_bus *cb = pb->children; + + while (cb) { + mdiobus_unregister(cb->mii_bus); + mdiobus_free(cb->mii_bus); + cb = cb->next; + } +} + int mdio_mux_init(struct device *dev, struct device_node *mux_node, int (*switch_fn)(int cur, int desired, void *data), @@ -144,7 +155,7 @@ int mdio_mux_init(struct device *dev, cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL); if (!cb) { ret_val = -ENOMEM; - continue; + goto err_loop; } cb->bus_number = v; cb->parent = pb; @@ -152,8 +163,7 @@ int mdio_mux_init(struct device *dev, cb->mii_bus = mdiobus_alloc(); if (!cb->mii_bus) { ret_val = -ENOMEM; - devm_kfree(dev, cb); - continue; + goto err_loop; } cb->mii_bus->priv = cb; @@ -165,11 +175,15 @@ int mdio_mux_init(struct device *dev, cb->mii_bus->write = mdio_mux_write; r = of_mdiobus_register(cb->mii_bus, child_bus_node); if (r) { + mdiobus_free(cb->mii_bus); + if (r == -EPROBE_DEFER) { + ret_val = r; + goto err_loop; + } + devm_kfree(dev, cb); dev_err(dev, "Error: Failed to register MDIO bus for child %pOF\n", child_bus_node); - mdiobus_free(cb->mii_bus); - devm_kfree(dev, cb); } else { cb->next = pb->children; pb->children = cb; @@ -182,6 +196,10 @@ int mdio_mux_init(struct device *dev, dev_err(dev, "Error: No acceptable child buses found\n"); devm_kfree(dev, pb); + +err_loop: + mdio_mux_uninit_children(pb); + of_node_put(child_bus_node); err_pb_kz: put_device(&parent_bus->dev); err_parent_bus: @@ -193,14 +211,8 @@ EXPORT_SYMBOL_GPL(mdio_mux_init); void mdio_mux_uninit(void *mux_handle) { struct mdio_mux_parent_bus *pb = mux_handle; - struct mdio_mux_child_bus *cb = pb->children; - - while (cb) { - mdiobus_unregister(cb->mii_bus); - mdiobus_free(cb->mii_bus); - cb = cb->next; - } + mdio_mux_uninit_children(pb); put_device(&pb->mii_bus->dev); } EXPORT_SYMBOL_GPL(mdio_mux_uninit); diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c index 3811f1bde84e..b80ed2ffd45e 100644 --- a/drivers/net/netdevsim/ipsec.c +++ b/drivers/net/netdevsim/ipsec.c @@ -85,7 +85,7 @@ static int nsim_ipsec_parse_proto_keys(struct xfrm_state *xs, u32 *mykey, u32 *mysalt) { const char aes_gcm_name[] = "rfc4106(gcm(aes))"; - struct net_device *dev = xs->xso.dev; + struct net_device *dev = xs->xso.real_dev; unsigned char *key_data; char *alg_name = NULL; int key_len; @@ -134,7 +134,7 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs) u16 sa_idx; int ret; - dev = xs->xso.dev; + dev = xs->xso.real_dev; ns = netdev_priv(dev); ipsec = &ns->ipsec; @@ -194,7 +194,7 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs) static void nsim_ipsec_del_sa(struct xfrm_state *xs) { - struct netdevsim *ns = netdev_priv(xs->xso.dev); + struct netdevsim *ns = netdev_priv(xs->xso.real_dev); struct nsim_ipsec *ipsec = &ns->ipsec; u16 sa_idx; @@ -211,7 +211,7 @@ static void nsim_ipsec_del_sa(struct xfrm_state *xs) static bool nsim_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs) { - struct netdevsim *ns = netdev_priv(xs->xso.dev); + struct netdevsim *ns = netdev_priv(xs->xso.real_dev); struct nsim_ipsec *ipsec = &ns->ipsec; ipsec->ok++; diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index 69d3eacc2b96..c716074fdef0 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -792,16 +792,12 @@ static int dp83867_phy_reset(struct phy_device *phydev) { int err; - err = phy_write(phydev, DP83867_CTRL, DP83867_SW_RESET); + err = phy_write(phydev, DP83867_CTRL, DP83867_SW_RESTART); if (err < 0) return err; usleep_range(10, 20); - /* After reset FORCE_LINK_GOOD bit is set. Although the - * default value should be unset. Disable FORCE_LINK_GOOD - * for the phy to work properly. - */ return phy_modify(phydev, MII_DP83867_PHYCTRL, DP83867_PHYCR_FORCE_LINK_GOOD, 0); } diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 757e950fb745..b848439fa837 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -608,7 +608,8 @@ void mdiobus_unregister(struct mii_bus *bus) struct mdio_device *mdiodev; int i; - BUG_ON(bus->state != MDIOBUS_REGISTERED); + if (WARN_ON_ONCE(bus->state != MDIOBUS_REGISTERED)) + return; bus->state = MDIOBUS_UNREGISTERED; for (i = 0; i < PHY_MAX_ADDR; i++) { diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 9b0bc8b74bc0..69b20a466c61 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -349,11 +349,11 @@ static int ksz8041_config_aneg(struct phy_device *phydev) } static int ksz8051_ksz8795_match_phy_device(struct phy_device *phydev, - const u32 ksz_phy_id) + const bool ksz_8051) { int ret; - if ((phydev->phy_id & MICREL_PHY_ID_MASK) != ksz_phy_id) + if ((phydev->phy_id & MICREL_PHY_ID_MASK) != PHY_ID_KSZ8051) return 0; ret = phy_read(phydev, MII_BMSR); @@ -366,7 +366,7 @@ static int ksz8051_ksz8795_match_phy_device(struct phy_device *phydev, * the switch does not. */ ret &= BMSR_ERCAP; - if (ksz_phy_id == PHY_ID_KSZ8051) + if (ksz_8051) return ret; else return !ret; @@ -374,7 +374,7 @@ static int ksz8051_ksz8795_match_phy_device(struct phy_device *phydev, static int ksz8051_match_phy_device(struct phy_device *phydev) { - return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ8051); + return ksz8051_ksz8795_match_phy_device(phydev, true); } static int ksz8081_config_init(struct phy_device *phydev) @@ -402,7 +402,7 @@ static int ksz8061_config_init(struct phy_device *phydev) static int ksz8795_match_phy_device(struct phy_device *phydev) { - return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ87XX); + return ksz8051_ksz8795_match_phy_device(phydev, false); } static int ksz9021_load_values_from_of(struct phy_device *phydev, @@ -1374,8 +1374,6 @@ static struct phy_driver ksphy_driver[] = { .name = "Micrel KSZ87XX Switch", /* PHY_BASIC_FEATURES */ .config_init = kszphy_config_init, - .config_aneg = ksz8873mll_config_aneg, - .read_status = ksz8873mll_read_status, .match_phy_device = ksz8795_match_phy_device, .suspend = genphy_suspend, .resume = genphy_resume, diff --git a/drivers/net/phy/mscc/mscc_macsec.c b/drivers/net/phy/mscc/mscc_macsec.c index 10be266e48e8..b7b2521c73fb 100644 --- a/drivers/net/phy/mscc/mscc_macsec.c +++ b/drivers/net/phy/mscc/mscc_macsec.c @@ -501,7 +501,7 @@ static u32 vsc8584_macsec_flow_context_id(struct macsec_flow *flow) } /* Derive the AES key to get a key for the hash autentication */ -static int vsc8584_macsec_derive_key(const u8 key[MACSEC_KEYID_LEN], +static int vsc8584_macsec_derive_key(const u8 key[MACSEC_MAX_KEY_LEN], u16 key_len, u8 hkey[16]) { const u8 input[AES_BLOCK_SIZE] = {0}; diff --git a/drivers/net/phy/mscc/mscc_macsec.h b/drivers/net/phy/mscc/mscc_macsec.h index 9c6d25e36de2..453304bae778 100644 --- a/drivers/net/phy/mscc/mscc_macsec.h +++ b/drivers/net/phy/mscc/mscc_macsec.h @@ -81,7 +81,7 @@ struct macsec_flow { /* Highest takes precedence [0..15] */ u8 priority; - u8 key[MACSEC_KEYID_LEN]; + u8 key[MACSEC_MAX_KEY_LEN]; union { struct macsec_rx_sa *rx_sa; diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 575580d3ffe0..b4879306bb8a 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -246,6 +246,19 @@ static int rtl8211f_config_init(struct phy_device *phydev) return 0; } +static int rtl821x_resume(struct phy_device *phydev) +{ + int ret; + + ret = genphy_resume(phydev); + if (ret < 0) + return ret; + + msleep(20); + + return 0; +} + static int rtl8211e_config_init(struct phy_device *phydev) { int ret = 0, oldpage; @@ -624,7 +637,7 @@ static struct phy_driver realtek_drvs[] = { .ack_interrupt = &rtl8211f_ack_interrupt, .config_intr = &rtl8211f_config_intr, .suspend = genphy_suspend, - .resume = genphy_resume, + .resume = rtl821x_resume, .read_page = rtl821x_read_page, .write_page = rtl821x_write_page, }, { diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index 7d005896a0f9..33b2e0fb68bb 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -283,7 +283,7 @@ static struct channel *ppp_find_channel(struct ppp_net *pn, int unit); static int ppp_connect_channel(struct channel *pch, int unit); static int ppp_disconnect_channel(struct channel *pch); static void ppp_destroy_channel(struct channel *pch); -static int unit_get(struct idr *p, void *ptr); +static int unit_get(struct idr *p, void *ptr, int min); static int unit_set(struct idr *p, void *ptr, int n); static void unit_put(struct idr *p, int n); static void *unit_find(struct idr *p, int n); @@ -1045,9 +1045,20 @@ static int ppp_unit_register(struct ppp *ppp, int unit, bool ifname_is_set) mutex_lock(&pn->all_ppp_mutex); if (unit < 0) { - ret = unit_get(&pn->units_idr, ppp); + ret = unit_get(&pn->units_idr, ppp, 0); if (ret < 0) goto err; + if (!ifname_is_set) { + while (1) { + snprintf(ppp->dev->name, IFNAMSIZ, "ppp%i", ret); + if (!__dev_get_by_name(ppp->ppp_net, ppp->dev->name)) + break; + unit_put(&pn->units_idr, ret); + ret = unit_get(&pn->units_idr, ppp, ret + 1); + if (ret < 0) + goto err; + } + } } else { /* Caller asked for a specific unit number. Fail with -EEXIST * if unavailable. For backward compatibility, return -EEXIST @@ -1196,7 +1207,7 @@ static int ppp_nl_newlink(struct net *src_net, struct net_device *dev, * the PPP unit identifer as suffix (i.e. ppp). This allows * userspace to infer the device name using to the PPPIOCGUNIT ioctl. */ - if (!tb[IFLA_IFNAME]) + if (!tb[IFLA_IFNAME] || !nla_len(tb[IFLA_IFNAME]) || !*(char *)nla_data(tb[IFLA_IFNAME])) conf.ifname_is_set = false; err = ppp_dev_configure(src_net, dev, &conf); @@ -3378,9 +3389,9 @@ static int unit_set(struct idr *p, void *ptr, int n) } /* get new free unit number and associate pointer with it */ -static int unit_get(struct idr *p, void *ptr) +static int unit_get(struct idr *p, void *ptr, int min) { - return idr_alloc(p, ptr, 0, 0, GFP_KERNEL); + return idr_alloc(p, ptr, min, 0, GFP_KERNEL); } /* put unit number back to a pool */ diff --git a/drivers/net/usb/cdc_eem.c b/drivers/net/usb/cdc_eem.c index 0eeec80bec31..e4a570366646 100644 --- a/drivers/net/usb/cdc_eem.c +++ b/drivers/net/usb/cdc_eem.c @@ -123,10 +123,10 @@ static struct sk_buff *eem_tx_fixup(struct usbnet *dev, struct sk_buff *skb, } skb2 = skb_copy_expand(skb, EEM_HEAD, ETH_FCS_LEN + padlen, flags); + dev_kfree_skb_any(skb); if (!skb2) return NULL; - dev_kfree_skb_any(skb); skb = skb2; done: diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index fbfcbd0dcfcb..5b3aff2c279f 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2496,7 +2496,7 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, hso_net_init); if (!net) { dev_err(&interface->dev, "Unable to create ethernet device\n"); - goto exit; + goto err_hso_dev; } hso_net = netdev_priv(net); @@ -2509,13 +2509,13 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, USB_DIR_IN); if (!hso_net->in_endp) { dev_err(&interface->dev, "Can't find BULK IN endpoint\n"); - goto exit; + goto err_net; } hso_net->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT); if (!hso_net->out_endp) { dev_err(&interface->dev, "Can't find BULK OUT endpoint\n"); - goto exit; + goto err_net; } SET_NETDEV_DEV(net, &interface->dev); SET_NETDEV_DEVTYPE(net, &hso_type); @@ -2524,18 +2524,18 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL); if (!hso_net->mux_bulk_rx_urb_pool[i]) - goto exit; + goto err_mux_bulk_rx; hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE, GFP_KERNEL); if (!hso_net->mux_bulk_rx_buf_pool[i]) - goto exit; + goto err_mux_bulk_rx; } hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!hso_net->mux_bulk_tx_urb) - goto exit; + goto err_mux_bulk_rx; hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL); if (!hso_net->mux_bulk_tx_buf) - goto exit; + goto err_free_tx_urb; add_net_device(hso_dev); @@ -2543,7 +2543,7 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, result = register_netdev(net); if (result) { dev_err(&interface->dev, "Failed to register device\n"); - goto exit; + goto err_free_tx_buf; } hso_log_port(hso_dev); @@ -2551,8 +2551,21 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, hso_create_rfkill(hso_dev, interface); return hso_dev; -exit: - hso_free_net_device(hso_dev, true); + +err_free_tx_buf: + remove_net_device(hso_dev); + kfree(hso_net->mux_bulk_tx_buf); +err_free_tx_urb: + usb_free_urb(hso_net->mux_bulk_tx_urb); +err_mux_bulk_rx: + for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { + usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]); + kfree(hso_net->mux_bulk_rx_buf_pool[i]); + } +err_net: + free_netdev(net); +err_hso_dev: + kfree(hso_dev); return NULL; } diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 65b315bc60ab..a5cd42bae962 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -1159,7 +1159,7 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) { struct phy_device *phydev = dev->net->phydev; struct ethtool_link_ksettings ecmd; - int ladv, radv, ret; + int ladv, radv, ret, link; u32 buf; /* clear LAN78xx interrupt status */ @@ -1167,9 +1167,12 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) if (unlikely(ret < 0)) return -EIO; + mutex_lock(&phydev->lock); phy_read_status(phydev); + link = phydev->link; + mutex_unlock(&phydev->lock); - if (!phydev->link && dev->link_on) { + if (!link && dev->link_on) { dev->link_on = false; /* reset MAC */ @@ -1182,7 +1185,7 @@ static int lan78xx_link_reset(struct lan78xx_net *dev) return -EIO; del_timer(&dev->stat_monitor); - } else if (phydev->link && !dev->link_on) { + } else if (link && !dev->link_on) { dev->link_on = true; phy_ethtool_ksettings_get(phydev, &ecmd); @@ -1471,9 +1474,14 @@ static int lan78xx_set_eee(struct net_device *net, struct ethtool_eee *edata) static u32 lan78xx_get_link(struct net_device *net) { + u32 link; + + mutex_lock(&net->phydev->lock); phy_read_status(net->phydev); + link = net->phydev->link; + mutex_unlock(&net->phydev->lock); - return net->phydev->link; + return link; } static void lan78xx_get_drvinfo(struct net_device *net, diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 32e1335c94ad..2a748a924f83 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -132,9 +132,15 @@ static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, const void *data) { - return usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REGS, + int ret; + + ret = usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0, indx, data, size, 1000, GFP_NOIO); + if (ret < 0) + netif_dbg(pegasus, drv, pegasus->net, "%s failed with %d\n", __func__, ret); + + return ret; } /* @@ -145,10 +151,15 @@ static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data) { void *buf = &data; + int ret; - return usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REG, + ret = usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data, indx, buf, 1, 1000, GFP_NOIO); + if (ret < 0) + netif_dbg(pegasus, drv, pegasus->net, "%s failed with %d\n", __func__, ret); + + return ret; } static int update_eth_regs_async(pegasus_t *pegasus) @@ -188,10 +199,9 @@ static int update_eth_regs_async(pegasus_t *pegasus) static int __mii_op(pegasus_t *p, __u8 phy, __u8 indx, __u16 *regd, __u8 cmd) { - int i; - __u8 data[4] = { phy, 0, 0, indx }; + int i, ret; __le16 regdi; - int ret = -ETIMEDOUT; + __u8 data[4] = { phy, 0, 0, indx }; if (cmd & PHY_WRITE) { __le16 *t = (__le16 *) & data[1]; @@ -207,12 +217,15 @@ static int __mii_op(pegasus_t *p, __u8 phy, __u8 indx, __u16 *regd, __u8 cmd) if (data[0] & PHY_DONE) break; } - if (i >= REG_TIMEOUT) + if (i >= REG_TIMEOUT) { + ret = -ETIMEDOUT; goto fail; + } if (cmd & PHY_READ) { ret = get_registers(p, PhyData, 2, ®di); + if (ret < 0) + goto fail; *regd = le16_to_cpu(regdi); - return ret; } return 0; fail: @@ -235,9 +248,13 @@ static int write_mii_word(pegasus_t *pegasus, __u8 phy, __u8 indx, __u16 *regd) static int mdio_read(struct net_device *dev, int phy_id, int loc) { pegasus_t *pegasus = netdev_priv(dev); + int ret; u16 res; - read_mii_word(pegasus, phy_id, loc, &res); + ret = read_mii_word(pegasus, phy_id, loc, &res); + if (ret < 0) + return ret; + return (int)res; } @@ -251,10 +268,9 @@ static void mdio_write(struct net_device *dev, int phy_id, int loc, int val) static int read_eprom_word(pegasus_t *pegasus, __u8 index, __u16 *retdata) { - int i; - __u8 tmp = 0; + int ret, i; __le16 retdatai; - int ret; + __u8 tmp = 0; set_register(pegasus, EpromCtrl, 0); set_register(pegasus, EpromOffset, index); @@ -262,21 +278,25 @@ static int read_eprom_word(pegasus_t *pegasus, __u8 index, __u16 *retdata) for (i = 0; i < REG_TIMEOUT; i++) { ret = get_registers(pegasus, EpromCtrl, 1, &tmp); + if (ret < 0) + goto fail; if (tmp & EPROM_DONE) break; - if (ret == -ESHUTDOWN) - goto fail; } - if (i >= REG_TIMEOUT) + if (i >= REG_TIMEOUT) { + ret = -ETIMEDOUT; goto fail; + } ret = get_registers(pegasus, EpromData, 2, &retdatai); + if (ret < 0) + goto fail; *retdata = le16_to_cpu(retdatai); return ret; fail: - netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); - return -ETIMEDOUT; + netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__); + return ret; } #ifdef PEGASUS_WRITE_EEPROM @@ -324,10 +344,10 @@ static int write_eprom_word(pegasus_t *pegasus, __u8 index, __u16 data) return ret; fail: - netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); + netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__); return -ETIMEDOUT; } -#endif /* PEGASUS_WRITE_EEPROM */ +#endif /* PEGASUS_WRITE_EEPROM */ static inline int get_node_id(pegasus_t *pegasus, u8 *id) { @@ -367,19 +387,21 @@ static void set_ethernet_addr(pegasus_t *pegasus) return; err: eth_hw_addr_random(pegasus->net); - dev_info(&pegasus->intf->dev, "software assigned MAC address.\n"); + netif_dbg(pegasus, drv, pegasus->net, "software assigned MAC address.\n"); return; } static inline int reset_mac(pegasus_t *pegasus) { + int ret, i; __u8 data = 0x8; - int i; set_register(pegasus, EthCtrl1, data); for (i = 0; i < REG_TIMEOUT; i++) { - get_registers(pegasus, EthCtrl1, 1, &data); + ret = get_registers(pegasus, EthCtrl1, 1, &data); + if (ret < 0) + goto fail; if (~data & 0x08) { if (loopback) break; @@ -402,22 +424,29 @@ static inline int reset_mac(pegasus_t *pegasus) } if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { __u16 auxmode; - read_mii_word(pegasus, 3, 0x1b, &auxmode); + ret = read_mii_word(pegasus, 3, 0x1b, &auxmode); + if (ret < 0) + goto fail; auxmode |= 4; write_mii_word(pegasus, 3, 0x1b, &auxmode); } return 0; +fail: + netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__); + return ret; } static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) { - __u16 linkpart; - __u8 data[4]; pegasus_t *pegasus = netdev_priv(dev); int ret; + __u16 linkpart; + __u8 data[4]; - read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart); + ret = read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart); + if (ret < 0) + goto fail; data[0] = 0xc8; /* TX & RX enable, append status, no CRC */ data[1] = 0; if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL)) @@ -435,11 +464,16 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS2 || usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { u16 auxmode; - read_mii_word(pegasus, 0, 0x1b, &auxmode); + ret = read_mii_word(pegasus, 0, 0x1b, &auxmode); + if (ret < 0) + goto fail; auxmode |= 4; write_mii_word(pegasus, 0, 0x1b, &auxmode); } + return ret; +fail: + netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__); return ret; } @@ -447,9 +481,9 @@ static void read_bulk_callback(struct urb *urb) { pegasus_t *pegasus = urb->context; struct net_device *net; + u8 *buf = urb->transfer_buffer; int rx_status, count = urb->actual_length; int status = urb->status; - u8 *buf = urb->transfer_buffer; __u16 pkt_len; if (!pegasus) @@ -736,12 +770,16 @@ static inline void disable_net_traffic(pegasus_t *pegasus) set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp); } -static inline void get_interrupt_interval(pegasus_t *pegasus) +static inline int get_interrupt_interval(pegasus_t *pegasus) { u16 data; u8 interval; + int ret; + + ret = read_eprom_word(pegasus, 4, &data); + if (ret < 0) + return ret; - read_eprom_word(pegasus, 4, &data); interval = data >> 8; if (pegasus->usb->speed != USB_SPEED_HIGH) { if (interval < 0x80) { @@ -756,6 +794,8 @@ static inline void get_interrupt_interval(pegasus_t *pegasus) } } pegasus->intr_interval = interval; + + return 0; } static void set_carrier(struct net_device *net) @@ -821,7 +861,7 @@ static int pegasus_open(struct net_device *net) if (!pegasus->rx_skb) goto exit; - res = set_registers(pegasus, EthID, 6, net->dev_addr); + set_registers(pegasus, EthID, 6, net->dev_addr); usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, usb_rcvbulkpipe(pegasus->usb, 1), @@ -999,8 +1039,7 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd) data[0] = pegasus->phy; fallthrough; case SIOCDEVPRIVATE + 1: - read_mii_word(pegasus, data[0], data[1] & 0x1f, &data[3]); - res = 0; + res = read_mii_word(pegasus, data[0], data[1] & 0x1f, &data[3]); break; case SIOCDEVPRIVATE + 2: if (!capable(CAP_NET_ADMIN)) @@ -1034,22 +1073,25 @@ static void pegasus_set_multicast(struct net_device *net) static __u8 mii_phy_probe(pegasus_t *pegasus) { - int i; + int i, ret; __u16 tmp; for (i = 0; i < 32; i++) { - read_mii_word(pegasus, i, MII_BMSR, &tmp); + ret = read_mii_word(pegasus, i, MII_BMSR, &tmp); + if (ret < 0) + goto fail; if (tmp == 0 || tmp == 0xffff || (tmp & BMSR_MEDIA) == 0) continue; else return i; } - +fail: return 0xff; } static inline void setup_pegasus_II(pegasus_t *pegasus) { + int ret; __u8 data = 0xa5; set_register(pegasus, Reg1d, 0); @@ -1061,7 +1103,9 @@ static inline void setup_pegasus_II(pegasus_t *pegasus) set_register(pegasus, Reg7b, 2); set_register(pegasus, 0x83, data); - get_registers(pegasus, 0x83, 1, &data); + ret = get_registers(pegasus, 0x83, 1, &data); + if (ret < 0) + goto fail; if (data == 0xa5) pegasus->chip = 0x8513; @@ -1076,6 +1120,10 @@ static inline void setup_pegasus_II(pegasus_t *pegasus) set_register(pegasus, Reg81, 6); else set_register(pegasus, Reg81, 2); + + return; +fail: + netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__); } static void check_carrier(struct work_struct *work) @@ -1150,7 +1198,9 @@ static int pegasus_probe(struct usb_interface *intf, | NETIF_MSG_PROBE | NETIF_MSG_LINK); pegasus->features = usb_dev_id[dev_index].private; - get_interrupt_interval(pegasus); + res = get_interrupt_interval(pegasus); + if (res) + goto out2; if (reset_mac(pegasus)) { dev_err(&intf->dev, "can't reset MAC\n"); res = -EIO; diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index f5010f8ac1ec..0bb5b1c78654 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -3432,7 +3432,7 @@ static void rtl_clear_bp(struct r8152 *tp, u16 type) case RTL_VER_09: default: if (type == MCU_TYPE_USB) { - ocp_write_byte(tp, MCU_TYPE_USB, USB_BP2_EN, 0); + ocp_write_word(tp, MCU_TYPE_USB, USB_BP2_EN, 0); ocp_write_word(tp, MCU_TYPE_USB, USB_BP_8, 0); ocp_write_word(tp, MCU_TYPE_USB, USB_BP_9, 0); @@ -5282,9 +5282,10 @@ static int rtl8152_close(struct net_device *netdev) tp->rtl_ops.down(tp); mutex_unlock(&tp->control); + } + if (!res) usb_autopm_put_interface(tp->intf); - } free_all_mem(tp); @@ -6054,7 +6055,7 @@ static void rtl8152_get_strings(struct net_device *dev, u32 stringset, u8 *data) { switch (stringset) { case ETH_SS_STATS: - memcpy(data, *rtl8152_gstrings, sizeof(rtl8152_gstrings)); + memcpy(data, rtl8152_gstrings, sizeof(rtl8152_gstrings)); break; } } diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index d44657b54d2b..378a12ae2d95 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -1483,7 +1483,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) ret = smsc75xx_wait_ready(dev, 0); if (ret < 0) { netdev_warn(dev->net, "device not ready in smsc75xx_bind\n"); - goto err; + goto free_pdata; } smsc75xx_init_mac_address(dev); @@ -1492,7 +1492,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) ret = smsc75xx_reset(dev); if (ret < 0) { netdev_warn(dev->net, "smsc75xx_reset error %d\n", ret); - goto err; + goto cancel_work; } dev->net->netdev_ops = &smsc75xx_netdev_ops; @@ -1503,8 +1503,11 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->max_mtu = MAX_SINGLE_PACKET_SIZE; return 0; -err: +cancel_work: + cancel_work_sync(&pdata->set_multicast); +free_pdata: kfree(pdata); + dev->data[0] = 0; return ret; } @@ -1515,7 +1518,6 @@ static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf) cancel_work_sync(&pdata->set_multicast); netif_dbg(dev, ifdown, dev->net, "free pdata\n"); kfree(pdata); - pdata = NULL; dev->data[0] = 0; } } diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index ce9d8f4cc0d9..1888876969f2 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -63,7 +63,7 @@ static const unsigned long guest_offloads[] = { VIRTIO_NET_F_GUEST_CSUM }; -#define GUEST_OFFLOAD_LRO_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \ +#define GUEST_OFFLOAD_GRO_HW_MASK ((1ULL << VIRTIO_NET_F_GUEST_TSO4) | \ (1ULL << VIRTIO_NET_F_GUEST_TSO6) | \ (1ULL << VIRTIO_NET_F_GUEST_ECN) | \ (1ULL << VIRTIO_NET_F_GUEST_UFO)) @@ -195,6 +195,9 @@ struct virtnet_info { /* # of XDP queue pairs currently used by the driver */ u16 xdp_queue_pairs; + /* xdp_queue_pairs may be 0, when xdp is already loaded. So add this. */ + bool xdp_enabled; + /* I like... big packets and I cannot lie! */ bool big_packets; @@ -485,12 +488,41 @@ static int __virtnet_xdp_xmit_one(struct virtnet_info *vi, return 0; } -static struct send_queue *virtnet_xdp_sq(struct virtnet_info *vi) -{ - unsigned int qp; - - qp = vi->curr_queue_pairs - vi->xdp_queue_pairs + smp_processor_id(); - return &vi->sq[qp]; +/* when vi->curr_queue_pairs > nr_cpu_ids, the txq/sq is only used for xdp tx on + * the current cpu, so it does not need to be locked. + * + * Here we use marco instead of inline functions because we have to deal with + * three issues at the same time: 1. the choice of sq. 2. judge and execute the + * lock/unlock of txq 3. make sparse happy. It is difficult for two inline + * functions to perfectly solve these three problems at the same time. + */ +#define virtnet_xdp_get_sq(vi) ({ \ + struct netdev_queue *txq; \ + typeof(vi) v = (vi); \ + unsigned int qp; \ + \ + if (v->curr_queue_pairs > nr_cpu_ids) { \ + qp = v->curr_queue_pairs - v->xdp_queue_pairs; \ + qp += smp_processor_id(); \ + txq = netdev_get_tx_queue(v->dev, qp); \ + __netif_tx_acquire(txq); \ + } else { \ + qp = smp_processor_id() % v->curr_queue_pairs; \ + txq = netdev_get_tx_queue(v->dev, qp); \ + __netif_tx_lock(txq, raw_smp_processor_id()); \ + } \ + v->sq + qp; \ +}) + +#define virtnet_xdp_put_sq(vi, q) { \ + struct netdev_queue *txq; \ + typeof(vi) v = (vi); \ + \ + txq = netdev_get_tx_queue(v->dev, (q) - v->sq); \ + if (v->curr_queue_pairs > nr_cpu_ids) \ + __netif_tx_release(txq); \ + else \ + __netif_tx_unlock(txq); \ } static int virtnet_xdp_xmit(struct net_device *dev, @@ -516,7 +548,7 @@ static int virtnet_xdp_xmit(struct net_device *dev, if (!xdp_prog) return -ENXIO; - sq = virtnet_xdp_sq(vi); + sq = virtnet_xdp_get_sq(vi); if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) { ret = -EINVAL; @@ -564,12 +596,13 @@ static int virtnet_xdp_xmit(struct net_device *dev, sq->stats.kicks += kicks; u64_stats_update_end(&sq->stats.syncp); + virtnet_xdp_put_sq(vi, sq); return ret; } static unsigned int virtnet_get_headroom(struct virtnet_info *vi) { - return vi->xdp_queue_pairs ? VIRTIO_XDP_HEADROOM : 0; + return vi->xdp_enabled ? VIRTIO_XDP_HEADROOM : 0; } /* We copy the packet for XDP in the following cases: @@ -660,6 +693,12 @@ static struct sk_buff *receive_small(struct net_device *dev, len -= vi->hdr_len; stats->bytes += len; + if (unlikely(len > GOOD_PACKET_LEN)) { + pr_debug("%s: rx error: len %u exceeds max size %d\n", + dev->name, len, GOOD_PACKET_LEN); + dev->stats.rx_length_errors++; + goto err_len; + } rcu_read_lock(); xdp_prog = rcu_dereference(rq->xdp_prog); if (xdp_prog) { @@ -763,6 +802,7 @@ static struct sk_buff *receive_small(struct net_device *dev, err_xdp: rcu_read_unlock(); stats->xdp_drops++; +err_len: stats->drops++; put_page(page); xdp_xmit: @@ -816,6 +856,12 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, head_skb = NULL; stats->bytes += len - vi->hdr_len; + if (unlikely(len > truesize)) { + pr_debug("%s: rx error: len %u exceeds truesize %lu\n", + dev->name, len, (unsigned long)ctx); + dev->stats.rx_length_errors++; + goto err_skb; + } rcu_read_lock(); xdp_prog = rcu_dereference(rq->xdp_prog); if (xdp_prog) { @@ -943,13 +989,6 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, } rcu_read_unlock(); - if (unlikely(len > truesize)) { - pr_debug("%s: rx error: len %u exceeds truesize %lu\n", - dev->name, len, (unsigned long)ctx); - dev->stats.rx_length_errors++; - goto err_skb; - } - head_skb = page_to_skb(vi, rq, page, offset, len, truesize, !xdp_prog, metasize); curr_skb = head_skb; @@ -1467,12 +1506,13 @@ static int virtnet_poll(struct napi_struct *napi, int budget) xdp_do_flush(); if (xdp_xmit & VIRTIO_XDP_TX) { - sq = virtnet_xdp_sq(vi); + sq = virtnet_xdp_get_sq(vi); if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) { u64_stats_update_begin(&sq->stats.syncp); sq->stats.kicks++; u64_stats_update_end(&sq->stats.syncp); } + virtnet_xdp_put_sq(vi, sq); } return received; @@ -1513,6 +1553,8 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget) struct virtnet_info *vi = sq->vq->vdev->priv; unsigned int index = vq2txq(sq->vq); struct netdev_queue *txq; + int opaque; + bool done; if (unlikely(is_xdp_raw_buffer_queue(vi, index))) { /* We don't need to enable cb for XDP */ @@ -1522,10 +1564,28 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget) txq = netdev_get_tx_queue(vi->dev, index); __netif_tx_lock(txq, raw_smp_processor_id()); + virtqueue_disable_cb(sq->vq); free_old_xmit_skbs(sq, true); + + opaque = virtqueue_enable_cb_prepare(sq->vq); + + done = napi_complete_done(napi, 0); + + if (!done) + virtqueue_disable_cb(sq->vq); + __netif_tx_unlock(txq); - virtqueue_napi_complete(napi, sq->vq, 0); + if (done) { + if (unlikely(virtqueue_poll(sq->vq, opaque))) { + if (napi_schedule_prep(napi)) { + __netif_tx_lock(txq, raw_smp_processor_id()); + virtqueue_disable_cb(sq->vq); + __netif_tx_unlock(txq); + __napi_schedule(napi); + } + } + } if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS) netif_tx_wake_queue(txq); @@ -1557,7 +1617,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) if (virtio_net_hdr_from_skb(skb, &hdr->hdr, virtio_is_little_endian(vi->vdev), false, 0)) - BUG(); + return -EPROTO; if (vi->mergeable_rx_bufs) hdr->num_buffers = 0; @@ -2406,7 +2466,7 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_ECN) || virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_UFO) || virtio_has_feature(vi->vdev, VIRTIO_NET_F_GUEST_CSUM))) { - NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing LRO/CSUM, disable LRO/CSUM first"); + NL_SET_ERR_MSG_MOD(extack, "Can't set XDP while host is implementing GRO_HW/CSUM, disable GRO_HW/CSUM first"); return -EOPNOTSUPP; } @@ -2427,10 +2487,9 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, /* XDP requires extra queues for XDP_TX */ if (curr_qp + xdp_qp > vi->max_queue_pairs) { - NL_SET_ERR_MSG_MOD(extack, "Too few free TX rings available"); - netdev_warn(dev, "request %i queues but max is %i\n", + netdev_warn(dev, "XDP request %i queues but max is %i. XDP_TX and XDP_REDIRECT will operate in a slower locked tx mode.\n", curr_qp + xdp_qp, vi->max_queue_pairs); - return -ENOMEM; + xdp_qp = 0; } old_prog = rtnl_dereference(vi->rq[0].xdp_prog); @@ -2464,11 +2523,14 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, vi->xdp_queue_pairs = xdp_qp; if (prog) { + vi->xdp_enabled = true; for (i = 0; i < vi->max_queue_pairs; i++) { rcu_assign_pointer(vi->rq[i].xdp_prog, prog); if (i == 0 && !old_prog) virtnet_clear_guest_offloads(vi); } + } else { + vi->xdp_enabled = false; } for (i = 0; i < vi->max_queue_pairs; i++) { @@ -2538,15 +2600,15 @@ static int virtnet_set_features(struct net_device *dev, if (!vi->has_cvq) return 0; - if ((dev->features ^ features) & NETIF_F_LRO) { - if (vi->xdp_queue_pairs) + if ((dev->features ^ features) & NETIF_F_GRO_HW) { + if (vi->xdp_enabled) return -EBUSY; - if (features & NETIF_F_LRO) + if (features & NETIF_F_GRO_HW) offloads = vi->guest_offloads_capable; else offloads = vi->guest_offloads_capable & - ~GUEST_OFFLOAD_LRO_MASK; + ~GUEST_OFFLOAD_GRO_HW_MASK; err = virtnet_set_guest_offloads(vi, offloads); if (err) @@ -3021,9 +3083,9 @@ static int virtnet_probe(struct virtio_device *vdev) dev->features |= NETIF_F_RXCSUM; if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6)) - dev->features |= NETIF_F_LRO; + dev->features |= NETIF_F_GRO_HW; if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS)) - dev->hw_features |= NETIF_F_LRO; + dev->hw_features |= NETIF_F_GRO_HW; dev->vlan_features = dev->features; @@ -3231,8 +3293,11 @@ static __maybe_unused int virtnet_restore(struct virtio_device *vdev) virtnet_set_queues(vi, vi->curr_queue_pairs); err = virtnet_cpu_notif_add(vi); - if (err) + if (err) { + virtnet_freeze_down(vdev); + remove_vq_common(vi); return err; + } return 0; } diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index 7ec8652f2c26..66590e95c292 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -1,7 +1,7 @@ /* * Linux driver for VMware's vmxnet3 ethernet NIC. * - * Copyright (C) 2008-2020, VMware, Inc. All Rights Reserved. + * Copyright (C) 2008-2021, VMware, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -26,6 +26,10 @@ #include "vmxnet3_int.h" +#include +#include + +#define VXLAN_UDP_PORT 8472 struct vmxnet3_stat_desc { char desc[ETH_GSTRING_LEN]; @@ -277,6 +281,8 @@ netdev_features_t vmxnet3_features_check(struct sk_buff *skb, if (VMXNET3_VERSION_GE_4(adapter) && skb->encapsulation && skb->ip_summed == CHECKSUM_PARTIAL) { u8 l4_proto = 0; + u16 port; + struct udphdr *udph; switch (vlan_get_protocol(skb)) { case htons(ETH_P_IP): @@ -289,8 +295,20 @@ netdev_features_t vmxnet3_features_check(struct sk_buff *skb, return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); } - if (l4_proto != IPPROTO_UDP) + switch (l4_proto) { + case IPPROTO_UDP: + udph = udp_hdr(skb); + port = be16_to_cpu(udph->dest); + /* Check if offloaded port is supported */ + if (port != GENEVE_UDP_PORT && + port != IANA_VXLAN_UDP_PORT && + port != VXLAN_UDP_PORT) { + return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); + } + break; + default: return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK); + } } return features; } diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index b9b7e00b72a8..d406da82b4fb 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -1184,9 +1184,6 @@ static int vrf_dev_init(struct net_device *dev) dev->flags = IFF_MASTER | IFF_NOARP; - /* MTU is irrelevant for VRF device; set to 64k similar to lo */ - dev->mtu = 64 * 1024; - /* similarly, oper state is irrelevant; set to up to avoid confusion */ dev->operstate = IF_OPER_UP; netdev_lockdep_set_classes(dev); @@ -1315,22 +1312,24 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev, int orig_iif = skb->skb_iif; bool need_strict = rt6_need_strict(&ipv6_hdr(skb)->daddr); bool is_ndisc = ipv6_ndisc_frame(skb); - bool is_ll_src; + + nf_reset_ct(skb); /* loopback, multicast & non-ND link-local traffic; do not push through * packet taps again. Reset pkt_type for upper layers to process skb. - * for packets with lladdr src, however, skip so that the dst can be - * determine at input using original ifindex in the case that daddr - * needs strict + * For strict packets with a source LLA, determine the dst using the + * original ifindex. */ - is_ll_src = ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL; - if (skb->pkt_type == PACKET_LOOPBACK || - (need_strict && !is_ndisc && !is_ll_src)) { + if (skb->pkt_type == PACKET_LOOPBACK || (need_strict && !is_ndisc)) { skb->dev = vrf_dev; skb->skb_iif = vrf_dev->ifindex; IP6CB(skb)->flags |= IP6SKB_L3SLAVE; + if (skb->pkt_type == PACKET_LOOPBACK) skb->pkt_type = PACKET_HOST; + else if (ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL) + vrf_ip6_input_dst(skb, vrf_dev, orig_iif); + goto out; } @@ -1372,6 +1371,8 @@ static struct sk_buff *vrf_ip_rcv(struct net_device *vrf_dev, skb->skb_iif = vrf_dev->ifindex; IPCB(skb)->flags |= IPSKB_L3SLAVE; + nf_reset_ct(skb); + if (ipv4_is_multicast(ip_hdr(skb)->daddr)) goto out; @@ -1620,7 +1621,8 @@ static void vrf_setup(struct net_device *dev) * which breaks networking. */ dev->min_mtu = IPV6_MIN_MTU; - dev->max_mtu = ETH_MAX_MTU; + dev->max_mtu = IP6_MAX_MTU; + dev->mtu = dev->max_mtu; } static int vrf_validate(struct nlattr *tb[], struct nlattr *data[], diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index d3b698d9e2e6..48fbdce6a70e 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2163,6 +2163,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) struct neighbour *n; struct nd_msg *msg; + rcu_read_lock(); in6_dev = __in6_dev_get(dev); if (!in6_dev) goto out; @@ -2214,6 +2215,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb, __be32 vni) } out: + rcu_read_unlock(); consume_skb(skb); return NETDEV_TX_OK; } diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 7a364eca46d6..f083fb9038c3 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -197,12 +197,13 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr); void ath_hw_setbssidmask(struct ath_common *common); -void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); +void ath_key_delete(struct ath_common *common, u8 hw_key_idx); int ath_key_config(struct ath_common *common, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_key_conf *key); bool ath_hw_keyreset(struct ath_common *common, u16 entry); +bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac); void ath_hw_cycle_counters_update(struct ath_common *common); int32_t ath_hw_get_listen_time(struct ath_common *common); diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index f5c0f9bac840..36183fdfb7f0 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -5482,6 +5482,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, if (arvif->nohwcrypt && !test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) { + ret = -EINVAL; ath10k_warn(ar, "cryptmode module param needed for sw crypto\n"); goto err; } diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 36426efdb2ea..86f52bcb3e4d 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -3684,8 +3684,10 @@ static int ath10k_pci_probe(struct pci_dev *pdev, ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); if (bus_params.chip_id != 0xffffffff) { if (!ath10k_pci_chip_is_supported(pdev->device, - bus_params.chip_id)) + bus_params.chip_id)) { + ret = -ENODEV; goto err_unsupported; + } } } @@ -3696,11 +3698,15 @@ static int ath10k_pci_probe(struct pci_dev *pdev, } bus_params.chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); - if (bus_params.chip_id == 0xffffffff) + if (bus_params.chip_id == 0xffffffff) { + ret = -ENODEV; goto err_unsupported; + } - if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) - goto err_free_irq; + if (!ath10k_pci_chip_is_supported(pdev->device, bus_params.chip_id)) { + ret = -ENODEV; + goto err_unsupported; + } ret = ath10k_core_register(ar, &bus_params); if (ret) { diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index a68fe3a45a74..28de2c7ae899 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -329,7 +329,8 @@ static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, if (len < ALIGN(ie_len, 4)) { ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n", ie_id, ie_len, len); - return -EINVAL; + ret = -EINVAL; + goto err; } switch (ie_id) { diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 0738c784616f..63d70aecbd0f 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -4603,13 +4603,13 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw, if (ret) { ath11k_warn(ar->ab, "failed to delete peer vdev_id %d addr %pM\n", arvif->vdev_id, vif->addr); - return ret; + goto err; } ret = ath11k_wait_for_peer_delete_done(ar, arvif->vdev_id, vif->addr); if (ret) - return ret; + goto err; ar->num_peers--; } @@ -5123,11 +5123,6 @@ ath11k_mac_update_vif_chan(struct ath11k *ar, if (WARN_ON(!arvif->is_up)) continue; - ret = ath11k_mac_setup_bcn_tmpl(arvif); - if (ret) - ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n", - ret); - ret = ath11k_mac_vdev_restart(arvif, &vifs[i].new_ctx->def); if (ret) { ath11k_warn(ab, "failed to restart vdev %d: %d\n", @@ -5135,6 +5130,11 @@ ath11k_mac_update_vif_chan(struct ath11k *ar, continue; } + ret = ath11k_mac_setup_bcn_tmpl(arvif); + if (ret) + ath11k_warn(ab, "failed to update bcn tmpl during csa: %d\n", + ret); + ret = ath11k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, arvif->bssid); if (ret) { diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 5e866a193ed0..d065600791c1 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -521,7 +521,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } break; case DISABLE_KEY: - ath_key_delete(common, key); + ath_key_delete(common, key->hw_key_idx); break; default: ret = -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 2b7832b1c800..72ef319feeda 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1461,7 +1461,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, } break; case DISABLE_KEY: - ath_key_delete(common, key); + ath_key_delete(common, key->hw_key_idx); break; default: ret = -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 023599e10dd5..b7b65b1c90e8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -820,6 +820,7 @@ struct ath_hw { struct ath9k_pacal_info pacal_info; struct ar5416Stats stats; struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; + DECLARE_BITMAP(pending_del_keymap, ATH_KEYMAX); enum ath9k_int imask; u32 imrs2_reg; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 8dbf68b94228..5739c1dbf166 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -307,6 +307,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) hchan = ah->curchan; } + if (!hchan) { + fastcc = false; + hchan = ath9k_cmn_get_channel(sc->hw, ah, &sc->cur_chan->chandef); + } + if (!ath_prepare_reset(sc)) fastcc = false; @@ -821,12 +826,80 @@ static void ath9k_tx(struct ieee80211_hw *hw, ieee80211_free_txskb(hw, skb); } +static bool ath9k_txq_list_has_key(struct list_head *txq_list, u32 keyix) +{ + struct ath_buf *bf; + struct ieee80211_tx_info *txinfo; + struct ath_frame_info *fi; + + list_for_each_entry(bf, txq_list, list) { + if (bf->bf_state.stale || !bf->bf_mpdu) + continue; + + txinfo = IEEE80211_SKB_CB(bf->bf_mpdu); + fi = (struct ath_frame_info *)&txinfo->rate_driver_data[0]; + if (fi->keyix == keyix) + return true; + } + + return false; +} + +static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) +{ + struct ath_hw *ah = sc->sc_ah; + int i; + struct ath_txq *txq; + bool key_in_use = false; + + for (i = 0; !key_in_use && i < ATH9K_NUM_TX_QUEUES; i++) { + if (!ATH_TXQ_SETUP(sc, i)) + continue; + txq = &sc->tx.txq[i]; + if (!txq->axq_depth) + continue; + if (!ath9k_hw_numtxpending(ah, txq->axq_qnum)) + continue; + + ath_txq_lock(sc, txq); + key_in_use = ath9k_txq_list_has_key(&txq->axq_q, keyix); + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { + int idx = txq->txq_tailidx; + + while (!key_in_use && + !list_empty(&txq->txq_fifo[idx])) { + key_in_use = ath9k_txq_list_has_key( + &txq->txq_fifo[idx], keyix); + INCR(idx, ATH_TXFIFO_DEPTH); + } + } + ath_txq_unlock(sc, txq); + } + + return key_in_use; +} + +static void ath9k_pending_key_del(struct ath_softc *sc, u8 keyix) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + + if (!test_bit(keyix, ah->pending_del_keymap) || + ath9k_txq_has_key(sc, keyix)) + return; + + /* No more TXQ frames point to this key cache entry, so delete it. */ + clear_bit(keyix, ah->pending_del_keymap); + ath_key_delete(common, keyix); +} + static void ath9k_stop(struct ieee80211_hw *hw) { struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); bool prev_idle; + int i; ath9k_deinit_channel_context(sc); @@ -894,6 +967,14 @@ static void ath9k_stop(struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); + for (i = 0; i < ATH_KEYMAX; i++) + ath9k_pending_key_del(sc, i); + + /* Clear key cache entries explicitly to get rid of any potentially + * remaining keys. + */ + ath9k_cmn_init_crypto(sc->sc_ah); + ath9k_ps_restore(sc); sc->ps_idle = prev_idle; @@ -1543,12 +1624,11 @@ static void ath9k_del_ps_key(struct ath_softc *sc, { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_node *an = (struct ath_node *) sta->drv_priv; - struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key }; if (!an->ps_key) return; - ath_key_delete(common, &ps_key); + ath_key_delete(common, an->ps_key); an->ps_key = 0; an->key_idx[0] = 0; } @@ -1719,6 +1799,12 @@ static int ath9k_set_key(struct ieee80211_hw *hw, if (sta) an = (struct ath_node *)sta->drv_priv; + /* Delete pending key cache entries if no more frames are pointing to + * them in TXQs. + */ + for (i = 0; i < ATH_KEYMAX; i++) + ath9k_pending_key_del(sc, i); + switch (cmd) { case SET_KEY: if (sta) @@ -1748,7 +1834,15 @@ static int ath9k_set_key(struct ieee80211_hw *hw, } break; case DISABLE_KEY: - ath_key_delete(common, key); + if (ath9k_txq_has_key(sc, key->hw_key_idx)) { + /* Delay key cache entry deletion until there are no + * remaining TXQ frames pointing to this entry. + */ + set_bit(key->hw_key_idx, sc->sc_ah->pending_del_keymap); + ath_hw_keysetmac(common, key->hw_key_idx, NULL); + } else { + ath_key_delete(common, key->hw_key_idx); + } if (an) { for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) { if (an->key_idx[i] != key->hw_key_idx) diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig index b2d760873992..ba9bea79381c 100644 --- a/drivers/net/wireless/ath/carl9170/Kconfig +++ b/drivers/net/wireless/ath/carl9170/Kconfig @@ -16,13 +16,11 @@ config CARL9170 config CARL9170_LEDS bool "SoftLED Support" - depends on CARL9170 - select MAC80211_LEDS - select LEDS_CLASS - select NEW_LEDS default y + depends on CARL9170 + depends on MAC80211_LEDS help - This option is necessary, if you want your device' LEDs to blink + This option is necessary, if you want your device's LEDs to blink. Say Y, unless you need the LEDs for firmware debugging. diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 1816b4e7dc26..61b59a804e30 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -84,8 +84,7 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry) } EXPORT_SYMBOL(ath_hw_keyreset); -static bool ath_hw_keysetmac(struct ath_common *common, - u16 entry, const u8 *mac) +bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac) { u32 macHi, macLo; u32 unicast_flag = AR_KEYTABLE_VALID; @@ -125,6 +124,7 @@ static bool ath_hw_keysetmac(struct ath_common *common, return true; } +EXPORT_SYMBOL(ath_hw_keysetmac); static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, const struct ath_keyval *k, @@ -581,29 +581,38 @@ EXPORT_SYMBOL(ath_key_config); /* * Delete Key. */ -void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) +void ath_key_delete(struct ath_common *common, u8 hw_key_idx) { - ath_hw_keyreset(common, key->hw_key_idx); - if (key->hw_key_idx < IEEE80211_WEP_NKID) + /* Leave CCMP and TKIP (main key) configured to avoid disabling + * encryption for potentially pending frames already in a TXQ with the + * keyix pointing to this key entry. Instead, only clear the MAC address + * to prevent RX processing from using this key cache entry. + */ + if (test_bit(hw_key_idx, common->ccmp_keymap) || + test_bit(hw_key_idx, common->tkip_keymap)) + ath_hw_keysetmac(common, hw_key_idx, NULL); + else + ath_hw_keyreset(common, hw_key_idx); + if (hw_key_idx < IEEE80211_WEP_NKID) return; - clear_bit(key->hw_key_idx, common->keymap); - clear_bit(key->hw_key_idx, common->ccmp_keymap); - if (key->cipher != WLAN_CIPHER_SUITE_TKIP) + clear_bit(hw_key_idx, common->keymap); + clear_bit(hw_key_idx, common->ccmp_keymap); + if (!test_bit(hw_key_idx, common->tkip_keymap)) return; - clear_bit(key->hw_key_idx + 64, common->keymap); + clear_bit(hw_key_idx + 64, common->keymap); - clear_bit(key->hw_key_idx, common->tkip_keymap); - clear_bit(key->hw_key_idx + 64, common->tkip_keymap); + clear_bit(hw_key_idx, common->tkip_keymap); + clear_bit(hw_key_idx + 64, common->tkip_keymap); if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { - ath_hw_keyreset(common, key->hw_key_idx + 32); - clear_bit(key->hw_key_idx + 32, common->keymap); - clear_bit(key->hw_key_idx + 64 + 32, common->keymap); + ath_hw_keyreset(common, hw_key_idx + 32); + clear_bit(hw_key_idx + 32, common->keymap); + clear_bit(hw_key_idx + 64 + 32, common->keymap); - clear_bit(key->hw_key_idx + 32, common->tkip_keymap); - clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); + clear_bit(hw_key_idx + 32, common->tkip_keymap); + clear_bit(hw_key_idx + 64 + 32, common->tkip_keymap); } } EXPORT_SYMBOL(ath_key_delete); diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 706728fba72d..9f8e44210e89 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -293,23 +293,16 @@ static int wcn36xx_start(struct ieee80211_hw *hw) goto out_free_dxe_pool; } - wcn->hal_buf = kmalloc(WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); - if (!wcn->hal_buf) { - wcn36xx_err("Failed to allocate smd buf\n"); - ret = -ENOMEM; - goto out_free_dxe_ctl; - } - ret = wcn36xx_smd_load_nv(wcn); if (ret) { wcn36xx_err("Failed to push NV to chip\n"); - goto out_free_smd_buf; + goto out_free_dxe_ctl; } ret = wcn36xx_smd_start(wcn); if (ret) { wcn36xx_err("Failed to start chip\n"); - goto out_free_smd_buf; + goto out_free_dxe_ctl; } if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { @@ -336,8 +329,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw) out_smd_stop: wcn36xx_smd_stop(wcn); -out_free_smd_buf: - kfree(wcn->hal_buf); out_free_dxe_ctl: wcn36xx_dxe_free_ctl_blks(wcn); out_free_dxe_pool: @@ -372,8 +363,6 @@ static void wcn36xx_stop(struct ieee80211_hw *hw) wcn36xx_dxe_free_mem_pools(wcn); wcn36xx_dxe_free_ctl_blks(wcn); - - kfree(wcn->hal_buf); } static void wcn36xx_change_ps(struct wcn36xx *wcn, bool enable) @@ -1398,6 +1387,12 @@ static int wcn36xx_probe(struct platform_device *pdev) mutex_init(&wcn->hal_mutex); mutex_init(&wcn->scan_lock); + wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); + if (!wcn->hal_buf) { + ret = -ENOMEM; + goto out_wq; + } + ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32)); if (ret < 0) { wcn36xx_err("failed to set DMA mask: %d\n", ret); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 23e6422c2251..c2b6e5c966d0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -2767,8 +2767,9 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, struct brcmf_sta_info_le sta_info_le; u32 sta_flags; u32 is_tdls_peer; - s32 total_rssi; - s32 count_rssi; + s32 total_rssi_avg = 0; + s32 total_rssi = 0; + s32 count_rssi = 0; int rssi; u32 i; @@ -2834,25 +2835,27 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES); sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes); } - total_rssi = 0; - count_rssi = 0; for (i = 0; i < BRCMF_ANT_MAX; i++) { - if (sta_info_le.rssi[i]) { - sinfo->chain_signal_avg[count_rssi] = - sta_info_le.rssi[i]; - sinfo->chain_signal[count_rssi] = - sta_info_le.rssi[i]; - total_rssi += sta_info_le.rssi[i]; - count_rssi++; - } + if (sta_info_le.rssi[i] == 0 || + sta_info_le.rx_lastpkt_rssi[i] == 0) + continue; + sinfo->chains |= BIT(count_rssi); + sinfo->chain_signal[count_rssi] = + sta_info_le.rx_lastpkt_rssi[i]; + sinfo->chain_signal_avg[count_rssi] = + sta_info_le.rssi[i]; + total_rssi += sta_info_le.rx_lastpkt_rssi[i]; + total_rssi_avg += sta_info_le.rssi[i]; + count_rssi++; } if (count_rssi) { - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); - sinfo->chains = count_rssi; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); - total_rssi /= count_rssi; - sinfo->signal = total_rssi; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL); + sinfo->filled |= + BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG); + sinfo->signal = total_rssi / count_rssi; + sinfo->signal_avg = total_rssi_avg / count_rssi; } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) { memset(&scb_val, 0, sizeof(scb_val)); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 59c2b2b6027d..6d5d5c39c635 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -4157,7 +4157,6 @@ static int brcmf_sdio_bus_reset(struct device *dev) if (ret) { brcmf_err("Failed to probe after sdio device reset: ret %d\n", ret); - brcmf_sdiod_remove(sdiodev); } return ret; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c index 818e523f6025..fb76b4a69a05 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c @@ -1221,6 +1221,7 @@ static int brcms_bcma_probe(struct bcma_device *pdev) { struct brcms_info *wl; struct ieee80211_hw *hw; + int ret; dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n", pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class, @@ -1245,11 +1246,16 @@ static int brcms_bcma_probe(struct bcma_device *pdev) wl = brcms_attach(pdev); if (!wl) { pr_err("%s: brcms_attach failed!\n", __func__); - return -ENODEV; + ret = -ENODEV; + goto err_free_ieee80211; } brcms_led_register(wl); return 0; + +err_free_ieee80211: + ieee80211_free_hw(hw); + return ret; } static int brcms_suspend(struct bcma_device *pdev) diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index 37ce4fe136c5..cdea741be6f6 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -38,6 +38,7 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data, u32 sha1 = 0; u16 mac_type = 0, rf_id = 0; u8 *pnvm_data = NULL, *tmp; + bool hw_match = false; u32 size = 0; int ret; @@ -84,6 +85,9 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data, break; } + if (hw_match) + break; + mac_type = le16_to_cpup((__le16 *)data); rf_id = le16_to_cpup((__le16 *)(data + sizeof(__le16))); @@ -91,15 +95,9 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data, "Got IWL_UCODE_TLV_HW_TYPE mac_type 0x%0x rf_id 0x%0x\n", mac_type, rf_id); - if (mac_type != CSR_HW_REV_TYPE(trans->hw_rev) || - rf_id != CSR_HW_RFID_TYPE(trans->hw_rf_id)) { - IWL_DEBUG_FW(trans, - "HW mismatch, skipping PNVM section, mac_type 0x%0x, rf_id 0x%0x.\n", - CSR_HW_REV_TYPE(trans->hw_rev), trans->hw_rf_id); - ret = -ENOENT; - goto out; - } - + if (mac_type == CSR_HW_REV_TYPE(trans->hw_rev) && + rf_id == CSR_HW_RFID_TYPE(trans->hw_rf_id)) + hw_match = true; break; case IWL_UCODE_TLV_SEC_RT: { struct iwl_pnvm_section *section = (void *)data; @@ -150,6 +148,15 @@ static int iwl_pnvm_handle_section(struct iwl_trans *trans, const u8 *data, } done: + if (!hw_match) { + IWL_DEBUG_FW(trans, + "HW mismatch, skipping PNVM section (need mac_type 0x%x rf_id 0x%x)\n", + CSR_HW_REV_TYPE(trans->hw_rev), + CSR_HW_RFID_TYPE(trans->hw_rf_id)); + ret = -ENOENT; + goto out; + } + if (!size) { IWL_DEBUG_FW(trans, "Empty PNVM, skipping.\n"); ret = -ENOENT; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h index e4f91bce222d..61d3d4e0b7d9 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /****************************************************************************** * - * Copyright(c) 2020 Intel Corporation + * Copyright(c) 2020-2021 Intel Corporation * *****************************************************************************/ @@ -10,7 +10,7 @@ #include "fw/notif-wait.h" -#define MVM_UCODE_PNVM_TIMEOUT (HZ / 10) +#define MVM_UCODE_PNVM_TIMEOUT (HZ / 4) int iwl_pnvm_load(struct iwl_trans *trans, struct iwl_notif_wait_data *notif_wait); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index d42165559df6..8cba923b1ec6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -3794,6 +3794,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct cfg80211_chan_def chandef; struct iwl_mvm_phy_ctxt *phy_ctxt; + bool band_change_removal; int ret, i; IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value, @@ -3874,19 +3875,30 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw, cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT); /* - * Change the PHY context configuration as it is currently referenced - * only by the P2P Device MAC + * Check if the remain-on-channel is on a different band and that + * requires context removal, see iwl_mvm_phy_ctxt_changed(). If + * so, we'll need to release and then re-configure here, since we + * must not remove a PHY context that's part of a binding. */ - if (mvmvif->phy_ctxt->ref == 1) { + band_change_removal = + fw_has_capa(&mvm->fw->ucode_capa, + IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) && + mvmvif->phy_ctxt->channel->band != chandef.chan->band; + + if (mvmvif->phy_ctxt->ref == 1 && !band_change_removal) { + /* + * Change the PHY context configuration as it is currently + * referenced only by the P2P Device MAC (and we can modify it) + */ ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt, &chandef, 1, 1); if (ret) goto out_unlock; } else { /* - * The PHY context is shared with other MACs. Need to remove the - * P2P Device from the binding, allocate an new PHY context and - * create a new binding + * The PHY context is shared with other MACs (or we're trying to + * switch bands), so remove the P2P Device from the binding, + * allocate an new PHY context and create a new binding. */ phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm); if (!phy_ctxt) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c index 3939eccd3d5a..394598b14a17 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c @@ -345,6 +345,8 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm, * and know the dtim period. */ iwl_mvm_te_check_disconnect(mvm, te_data->vif, + !te_data->vif->bss_conf.assoc ? + "Not associated and the time event is over already..." : "No beacon heard and the time event is over already..."); break; default: @@ -843,6 +845,8 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm, * and know the dtim period. */ iwl_mvm_te_check_disconnect(mvm, vif, + !vif->bss_conf.assoc ? + "Not associated and the session protection is over already..." : "No beacon heard and the session protection is over already..."); spin_lock_bh(&mvm->time_event_lock); iwl_mvm_te_clear_data(mvm, te_data); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 7626117c01fa..7186e1dbbd6b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -1085,6 +1085,9 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_INVALID_STA)) return -1; + if (unlikely(ieee80211_is_any_nullfunc(fc)) && sta->he_cap.has_he) + return -1; + if (unlikely(ieee80211_is_probe_resp(fc))) iwl_mvm_probe_resp_set_noa(mvm, skb); diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c index ec1d6025081d..56f63f5f5dd3 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c @@ -126,7 +126,6 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, struct iwl_prph_scratch *prph_scratch; struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl; struct iwl_prph_info *prph_info; - void *iml_img; u32 control_flags = 0; int ret; int cmdq_size = max_t(u32, IWL_CMD_QUEUE_SIZE, @@ -234,14 +233,15 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, trans_pcie->prph_scratch = prph_scratch; /* Allocate IML */ - iml_img = dma_alloc_coherent(trans->dev, trans->iml_len, - &trans_pcie->iml_dma_addr, GFP_KERNEL); - if (!iml_img) { + trans_pcie->iml = dma_alloc_coherent(trans->dev, trans->iml_len, + &trans_pcie->iml_dma_addr, + GFP_KERNEL); + if (!trans_pcie->iml) { ret = -ENOMEM; goto err_free_ctxt_info; } - memcpy(iml_img, trans->iml, trans->iml_len); + memcpy(trans_pcie->iml, trans->iml, trans->iml_len); iwl_enable_fw_load_int_ctx_info(trans); @@ -290,6 +290,11 @@ void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans) trans_pcie->ctxt_info_dma_addr = 0; trans_pcie->ctxt_info_gen3 = NULL; + dma_free_coherent(trans->dev, trans->iml_len, trans_pcie->iml, + trans_pcie->iml_dma_addr); + trans_pcie->iml_dma_addr = 0; + trans_pcie->iml = NULL; + iwl_pcie_ctxt_info_free_fw_img(trans); dma_free_coherent(trans->dev, sizeof(*trans_pcie->prph_scratch), diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h index ff542d2f0054..f05025e8d11d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -336,6 +336,8 @@ struct cont_rec { * Context information addresses will be taken from here. * This is driver's local copy for keeping track of size and * count for allocating and freeing the memory. + * @iml: image loader image virtual address + * @iml_dma_addr: image loader image DMA address * @trans: pointer to the generic transport area * @scd_base_addr: scheduler sram base address in SRAM * @kw: keep warm address @@ -388,6 +390,7 @@ struct iwl_trans_pcie { }; struct iwl_prph_info *prph_info; struct iwl_prph_scratch *prph_scratch; + void *iml; dma_addr_t ctxt_info_dma_addr; dma_addr_t prph_info_dma_addr; dma_addr_t prph_scratch_dma_addr; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c index 4c3ca2a37696..b031e9304983 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c @@ -269,7 +269,8 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr) /* now that we got alive we can free the fw image & the context info. * paging memory cannot be freed included since FW will still use it */ - iwl_pcie_ctxt_info_free(trans); + if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210) + iwl_pcie_ctxt_info_free(trans); /* * Re-enable all the interrupts, including the RF-Kill one, now that diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 31e21d8f2972..79ee470fe566 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1629,8 +1629,13 @@ static int mac80211_hwsim_start(struct ieee80211_hw *hw) static void mac80211_hwsim_stop(struct ieee80211_hw *hw) { struct mac80211_hwsim_data *data = hw->priv; + data->started = false; hrtimer_cancel(&data->beacon_timer); + + while (!skb_queue_empty(&data->pending)) + ieee80211_free_txskb(hw, skb_dequeue(&data->pending)); + wiphy_dbg(hw->wiphy, "%s\n", __func__); } diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 33cf952cc01d..b2de8d03c5fa 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -1232,7 +1232,7 @@ static int mwifiex_pcie_delete_cmdrsp_buf(struct mwifiex_adapter *adapter) static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; - u32 tmp; + u32 *cookie; card->sleep_cookie_vbase = dma_alloc_coherent(&card->dev->dev, sizeof(u32), @@ -1243,13 +1243,11 @@ static int mwifiex_pcie_alloc_sleep_cookie_buf(struct mwifiex_adapter *adapter) "dma_alloc_coherent failed!\n"); return -ENOMEM; } + cookie = (u32 *)card->sleep_cookie_vbase; /* Init val of Sleep Cookie */ - tmp = FW_AWAKE_COOKIE; - put_unaligned(tmp, card->sleep_cookie_vbase); + *cookie = FW_AWAKE_COOKIE; - mwifiex_dbg(adapter, INFO, - "alloc_scook: sleep cookie=0x%x\n", - get_unaligned(card->sleep_cookie_vbase)); + mwifiex_dbg(adapter, INFO, "alloc_scook: sleep cookie=0x%x\n", *cookie); return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index 5795e44f8a52..f44f478bb970 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -1177,22 +1177,20 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta, int first_idx = 0, last_idx; int i, idx, count; bool fixed_rate, ack_timeout; - bool probe, ampdu, cck = false; + bool ampdu, cck = false; bool rs_idx; u32 rate_set_tsf; u32 final_rate, final_rate_flags, final_nss, txs; - fixed_rate = info->status.rates[0].count; - probe = !!(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); - txs = le32_to_cpu(txs_data[1]); - ampdu = !fixed_rate && (txs & MT_TXS1_AMPDU); + ampdu = txs & MT_TXS1_AMPDU; txs = le32_to_cpu(txs_data[3]); count = FIELD_GET(MT_TXS3_TX_COUNT, txs); last_idx = FIELD_GET(MT_TXS3_LAST_TX_RATE, txs); txs = le32_to_cpu(txs_data[0]); + fixed_rate = txs & MT_TXS0_FIXED_RATE; final_rate = FIELD_GET(MT_TXS0_TX_RATE, txs); ack_timeout = txs & MT_TXS0_ACK_TIMEOUT; @@ -1214,7 +1212,7 @@ static bool mt7615_fill_txs(struct mt7615_dev *dev, struct mt7615_sta *sta, first_idx = max_t(int, 0, last_idx - (count - 1) / MT7615_RATE_RETRY); - if (fixed_rate && !probe) { + if (fixed_rate) { info->status.rates[0].count = count; i = 0; goto out; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c index 4cf7c5d34325..490d55651de3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c @@ -133,20 +133,21 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, struct mt76_tx_info *tx_info) { struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); - struct mt7615_sta *msta = container_of(wcid, struct mt7615_sta, wcid); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); struct ieee80211_key_conf *key = info->control.hw_key; int pid, id; u8 *txwi = (u8 *)txwi_ptr; struct mt76_txwi_cache *t; + struct mt7615_sta *msta; void *txp; + msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL; if (!wcid) wcid = &dev->mt76.global_wcid; pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); - if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) { + if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && msta) { struct mt7615_phy *phy = &dev->phy; if ((info->hw_queue & MT_TX_HW_QUEUE_EXT_PHY) && mdev->phy2) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c index 3b29a6d3dc64..18082b4ce7d3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb_sdio.c @@ -243,14 +243,15 @@ int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, struct ieee80211_sta *sta, struct mt76_tx_info *tx_info) { - struct mt7615_sta *msta = container_of(wcid, struct mt7615_sta, wcid); struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); struct sk_buff *skb = tx_info->skb; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct mt7615_sta *msta; int pad; + msta = wcid ? container_of(wcid, struct mt7615_sta, wcid) : NULL; if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && - !msta->rate_probe) { + msta && !msta->rate_probe) { /* request to configure sampling rate */ spin_lock_bh(&dev->mt76.lock); mt7615_mac_set_rates(&dev->phy, msta, &info->control.rates[0], diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c index 0232b66acb4f..8f01ca1694bc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -335,6 +335,9 @@ mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap, if (nss < 2) return; + /* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */ + elem->phy_cap_info[7] |= min_t(int, nss - 1, 2) << 3; + if (vif != NL80211_IFTYPE_AP) return; @@ -348,9 +351,6 @@ mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap, c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB | IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB; elem->phy_cap_info[6] |= c; - - /* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */ - elem->phy_cap_info[7] |= min_t(int, nss - 1, 2) << 3; } static void diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index 44ef4bc7a46e..073c29eb2ed8 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -278,7 +278,7 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta, skb_set_queue_mapping(skb, qid); } - if (!(wcid->tx_info & MT_WCID_TX_INFO_SET)) + if (wcid && !(wcid->tx_info & MT_WCID_TX_INFO_SET)) ieee80211_get_tx_rates(info->control.vif, sta, skb, info->control.rates, 1); diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h index d6d1be4169e5..acb6b0cd3667 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h @@ -853,15 +853,10 @@ struct rtl8192eu_efuse { u8 usb_optional_function; u8 res9[2]; u8 mac_addr[ETH_ALEN]; /* 0xd7 */ - u8 res10[2]; - u8 vendor_name[7]; - u8 res11[2]; - u8 device_name[0x0b]; /* 0xe8 */ - u8 res12[2]; - u8 serial[0x0b]; /* 0xf5 */ - u8 res13[0x30]; + u8 device_info[80]; + u8 res11[3]; u8 unknown[0x0d]; /* 0x130 */ - u8 res14[0xc3]; + u8 res12[0xc3]; }; struct rtl8xxxu_reg8val { diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c index 9f1f93d04145..199e7e031d7d 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c @@ -554,9 +554,43 @@ rtl8192e_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40) } } +static void rtl8192eu_log_next_device_info(struct rtl8xxxu_priv *priv, + char *record_name, + char *device_info, + unsigned int *record_offset) +{ + char *record = device_info + *record_offset; + + /* A record is [ total length | 0x03 | value ] */ + unsigned char l = record[0]; + + /* + * The whole device info section seems to be 80 characters, make sure + * we don't read further. + */ + if (*record_offset + l > 80) { + dev_warn(&priv->udev->dev, + "invalid record length %d while parsing \"%s\" at offset %u.\n", + l, record_name, *record_offset); + return; + } + + if (l >= 2) { + char value[80]; + + memcpy(value, &record[2], l - 2); + value[l - 2] = '\0'; + dev_info(&priv->udev->dev, "%s: %s\n", record_name, value); + *record_offset = *record_offset + l; + } else { + dev_info(&priv->udev->dev, "%s not available.\n", record_name); + } +} + static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv) { struct rtl8192eu_efuse *efuse = &priv->efuse_wifi.efuse8192eu; + unsigned int record_offset; int i; if (efuse->rtl_id != cpu_to_le16(0x8129)) @@ -604,12 +638,25 @@ static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv) priv->has_xtalk = 1; priv->xtalk = priv->efuse_wifi.efuse8192eu.xtal_k & 0x3f; - dev_info(&priv->udev->dev, "Vendor: %.7s\n", efuse->vendor_name); - dev_info(&priv->udev->dev, "Product: %.11s\n", efuse->device_name); - if (memchr_inv(efuse->serial, 0xff, 11)) - dev_info(&priv->udev->dev, "Serial: %.11s\n", efuse->serial); - else - dev_info(&priv->udev->dev, "Serial not available.\n"); + /* + * device_info section seems to be laid out as records + * [ total length | 0x03 | value ] so: + * - vendor length + 2 + * - 0x03 + * - vendor string (not null terminated) + * - product length + 2 + * - 0x03 + * - product string (not null terminated) + * Then there is one or 2 0x00 on all the 4 devices I own or found + * dumped online. + * As previous version of the code handled an optional serial + * string, I now assume there may be a third record if the + * length is not 0. + */ + record_offset = 0; + rtl8192eu_log_next_device_info(priv, "Vendor", efuse->device_info, &record_offset); + rtl8192eu_log_next_device_info(priv, "Product", efuse->device_info, &record_offset); + rtl8192eu_log_next_device_info(priv, "Serial", efuse->device_info, &record_offset); if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) { unsigned char *raw = priv->efuse_wifi.raw; diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index b718f5d810be..79ad6232dce8 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -3510,26 +3510,28 @@ static void rtw8822c_pwrtrack_set(struct rtw_dev *rtwdev, u8 rf_path) } } -static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev, - struct rtw_swing_table *swing_table, - u8 path) +static void rtw8822c_pwr_track_stats(struct rtw_dev *rtwdev, u8 path) { - struct rtw_dm_info *dm_info = &rtwdev->dm_info; - u8 thermal_value, delta; + u8 thermal_value; if (rtwdev->efuse.thermal_meter[path] == 0xff) return; thermal_value = rtw_read_rf(rtwdev, path, RF_T_METER, 0x7e); - rtw_phy_pwrtrack_avg(rtwdev, thermal_value, path); +} - delta = rtw_phy_pwrtrack_get_delta(rtwdev, path); +static void rtw8822c_pwr_track_path(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table, + u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 delta; + delta = rtw_phy_pwrtrack_get_delta(rtwdev, path); dm_info->delta_power_index[path] = rtw_phy_pwrtrack_get_pwridx(rtwdev, swing_table, path, path, delta); - rtw8822c_pwrtrack_set(rtwdev, path); } @@ -3540,12 +3542,12 @@ static void __rtw8822c_pwr_track(struct rtw_dev *rtwdev) rtw_phy_config_swing_table(rtwdev, &swing_table); + for (i = 0; i < rtwdev->hal.rf_path_num; i++) + rtw8822c_pwr_track_stats(rtwdev, i); if (rtw_phy_pwrtrack_need_lck(rtwdev)) rtw8822c_do_lck(rtwdev); - for (i = 0; i < rtwdev->hal.rf_path_num; i++) rtw8822c_pwr_track_path(rtwdev, &swing_table, i); - } static void rtw8822c_pwr_track(struct rtw_dev *rtwdev) diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c index ce9892152f4d..99b21a2c8386 100644 --- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -203,7 +203,7 @@ int rsi_prepare_data_desc(struct rsi_common *common, struct sk_buff *skb) wh->frame_control |= cpu_to_le16(RSI_SET_PS_ENABLE); if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) && - (common->secinfo.security_enable)) { + info->control.hw_key) { if (rsi_is_cipher_wep(common)) ieee80211_size += 4; else @@ -470,9 +470,9 @@ int rsi_prepare_beacon(struct rsi_common *common, struct sk_buff *skb) } if (common->band == NL80211_BAND_2GHZ) - bcn_frm->bbp_info |= cpu_to_le16(RSI_RATE_1); + bcn_frm->rate_info |= cpu_to_le16(RSI_RATE_1); else - bcn_frm->bbp_info |= cpu_to_le16(RSI_RATE_6); + bcn_frm->rate_info |= cpu_to_le16(RSI_RATE_6); if (mac_bcn->data[tim_offset + 2] == 0) bcn_frm->frame_info |= cpu_to_le16(RSI_DATA_DESC_DTIM_BEACON); diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c index 16025300cddb..57c9e3559dfd 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -1028,7 +1028,6 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw, mutex_lock(&common->mutex); switch (cmd) { case SET_KEY: - secinfo->security_enable = true; status = rsi_hal_key_config(hw, vif, key, sta); if (status) { mutex_unlock(&common->mutex); @@ -1047,8 +1046,6 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw, break; case DISABLE_KEY: - if (vif->type == NL80211_IFTYPE_STATION) - secinfo->security_enable = false; rsi_dbg(ERR_ZONE, "%s: RSI del key\n", __func__); memset(key, 0, sizeof(struct ieee80211_key_conf)); status = rsi_hal_key_config(hw, vif, key, sta); diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c index 33c76d39a8e9..b6d050a2fbe7 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c @@ -1803,8 +1803,7 @@ int rsi_send_wowlan_request(struct rsi_common *common, u16 flags, RSI_WIFI_MGMT_Q); cmd_frame->desc.desc_dword0.frame_type = WOWLAN_CONFIG_PARAMS; cmd_frame->host_sleep_status = sleep_status; - if (common->secinfo.security_enable && - common->secinfo.gtk_cipher) + if (common->secinfo.gtk_cipher) flags |= RSI_WOW_GTK_REKEY; if (sleep_status) cmd_frame->wow_flags = flags; diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h index 73a19e43106b..b3e25bc28682 100644 --- a/drivers/net/wireless/rsi/rsi_main.h +++ b/drivers/net/wireless/rsi/rsi_main.h @@ -151,7 +151,6 @@ enum edca_queue { }; struct security_info { - bool security_enable; u32 ptk_cipher; u32 gtk_cipher; }; diff --git a/drivers/net/wireless/st/cw1200/cw1200_sdio.c b/drivers/net/wireless/st/cw1200/cw1200_sdio.c index b65ec14136c7..4c30b5772ce0 100644 --- a/drivers/net/wireless/st/cw1200/cw1200_sdio.c +++ b/drivers/net/wireless/st/cw1200/cw1200_sdio.c @@ -53,6 +53,7 @@ static const struct sdio_device_id cw1200_sdio_ids[] = { { SDIO_DEVICE(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200) }, { /* end: all zeroes */ }, }; +MODULE_DEVICE_TABLE(sdio, cw1200_sdio_ids); /* hwbus_ops implemetation */ diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c index 988581cc134b..1f856fbbc0ea 100644 --- a/drivers/net/wireless/st/cw1200/scan.c +++ b/drivers/net/wireless/st/cw1200/scan.c @@ -75,30 +75,27 @@ int cw1200_hw_scan(struct ieee80211_hw *hw, if (req->n_ssids > WSM_SCAN_MAX_NUM_OF_SSIDS) return -EINVAL; - /* will be unlocked in cw1200_scan_work() */ - down(&priv->scan.lock); - mutex_lock(&priv->conf_mutex); - frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0, req->ie_len); - if (!frame.skb) { - mutex_unlock(&priv->conf_mutex); - up(&priv->scan.lock); + if (!frame.skb) return -ENOMEM; - } if (req->ie_len) skb_put_data(frame.skb, req->ie, req->ie_len); + /* will be unlocked in cw1200_scan_work() */ + down(&priv->scan.lock); + mutex_lock(&priv->conf_mutex); + ret = wsm_set_template_frame(priv, &frame); if (!ret) { /* Host want to be the probe responder. */ ret = wsm_set_probe_responder(priv, true); } if (ret) { - dev_kfree_skb(frame.skb); mutex_unlock(&priv->conf_mutex); up(&priv->scan.lock); + dev_kfree_skb(frame.skb); return ret; } @@ -120,8 +117,8 @@ int cw1200_hw_scan(struct ieee80211_hw *hw, ++priv->scan.n_ssids; } - dev_kfree_skb(frame.skb); mutex_unlock(&priv->conf_mutex); + dev_kfree_skb(frame.skb); queue_work(priv->workqueue, &priv->scan.work); return 0; } diff --git a/drivers/net/wireless/ti/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c index 9547aea01b0f..ea0215246c5c 100644 --- a/drivers/net/wireless/ti/wl1251/cmd.c +++ b/drivers/net/wireless/ti/wl1251/cmd.c @@ -466,9 +466,12 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len, cmd->channels[i].channel = channels[i]->hw_value; } - cmd->params.ssid_len = ssid_len; - if (ssid) - memcpy(cmd->params.ssid, ssid, ssid_len); + if (ssid) { + int len = clamp_val(ssid_len, 0, IEEE80211_MAX_SSID_LEN); + + cmd->params.ssid_len = len; + memcpy(cmd->params.ssid, ssid, len); + } ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd)); if (ret < 0) { diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 9d7dbfe7fe0c..c6da0cfb4afb 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1503,6 +1503,13 @@ static int wl12xx_get_fuse_mac(struct wl1271 *wl) u32 mac1, mac2; int ret; + /* Device may be in ELP from the bootloader or kexec */ + ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); + if (ret < 0) + goto out; + + usleep_range(500000, 700000); + ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); if (ret < 0) goto out; diff --git a/drivers/net/wireless/virt_wifi.c b/drivers/net/wireless/virt_wifi.c index f9a17faed234..3cfd99067b2e 100644 --- a/drivers/net/wireless/virt_wifi.c +++ b/drivers/net/wireless/virt_wifi.c @@ -138,6 +138,29 @@ static struct ieee80211_supported_band band_5ghz = { /* Assigned at module init. Guaranteed locally-administered and unicast. */ static u8 fake_router_bssid[ETH_ALEN] __ro_after_init = {}; +static void virt_wifi_inform_bss(struct wiphy *wiphy) +{ + u64 tsf = div_u64(ktime_get_boottime_ns(), 1000); + struct cfg80211_bss *informed_bss; + static const struct { + u8 tag; + u8 len; + u8 ssid[8]; + } __packed ssid = { + .tag = WLAN_EID_SSID, + .len = 8, + .ssid = "VirtWifi", + }; + + informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz, + CFG80211_BSS_FTYPE_PRESP, + fake_router_bssid, tsf, + WLAN_CAPABILITY_ESS, 0, + (void *)&ssid, sizeof(ssid), + DBM_TO_MBM(-50), GFP_KERNEL); + cfg80211_put_bss(wiphy, informed_bss); +} + /* Called with the rtnl lock held. */ static int virt_wifi_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) @@ -161,28 +184,13 @@ static int virt_wifi_scan(struct wiphy *wiphy, /* Acquires and releases the rdev BSS lock. */ static void virt_wifi_scan_result(struct work_struct *work) { - struct { - u8 tag; - u8 len; - u8 ssid[8]; - } __packed ssid = { - .tag = WLAN_EID_SSID, .len = 8, .ssid = "VirtWifi", - }; - struct cfg80211_bss *informed_bss; struct virt_wifi_wiphy_priv *priv = container_of(work, struct virt_wifi_wiphy_priv, scan_result.work); struct wiphy *wiphy = priv_to_wiphy(priv); struct cfg80211_scan_info scan_info = { .aborted = false }; - u64 tsf = div_u64(ktime_get_boottime_ns(), 1000); - informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz, - CFG80211_BSS_FTYPE_PRESP, - fake_router_bssid, tsf, - WLAN_CAPABILITY_ESS, 0, - (void *)&ssid, sizeof(ssid), - DBM_TO_MBM(-50), GFP_KERNEL); - cfg80211_put_bss(wiphy, informed_bss); + virt_wifi_inform_bss(wiphy); if(priv->network_simulation && priv->network_simulation->generate_virt_scan_result) { @@ -236,10 +244,12 @@ static int virt_wifi_connect(struct wiphy *wiphy, struct net_device *netdev, if (!could_schedule) return -EBUSY; - if (sme->bssid) + if (sme->bssid) { ether_addr_copy(priv->connect_requested_bss, sme->bssid); - else + } else { + virt_wifi_inform_bss(wiphy); eth_zero_addr(priv->connect_requested_bss); + } wiphy_debug(wiphy, "connect\n"); @@ -252,11 +262,13 @@ static void virt_wifi_connect_complete(struct work_struct *work) struct virt_wifi_netdev_priv *priv = container_of(work, struct virt_wifi_netdev_priv, connect.work); u8 *requested_bss = priv->connect_requested_bss; - bool has_addr = !is_zero_ether_addr(requested_bss); bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid); u16 status = WLAN_STATUS_SUCCESS; - if (!priv->is_up || (has_addr && !right_addr)) + if (is_zero_ether_addr(requested_bss)) + requested_bss = NULL; + + if (!priv->is_up || (requested_bss && !right_addr)) status = WLAN_STATUS_UNSPECIFIED_FAILURE; else priv->is_connected = true; diff --git a/drivers/nfc/nfcsim.c b/drivers/nfc/nfcsim.c index a9864fcdfba6..dd27c85190d3 100644 --- a/drivers/nfc/nfcsim.c +++ b/drivers/nfc/nfcsim.c @@ -192,8 +192,7 @@ static void nfcsim_recv_wq(struct work_struct *work) if (!IS_ERR(skb)) dev_kfree_skb(skb); - - skb = ERR_PTR(-ENODEV); + return; } dev->cb(dev->nfc_digital_dev, dev->arg, skb); diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index 2403b71b601e..745478213ff2 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -2527,7 +2527,7 @@ static void deactivate_labels(void *region) static int init_active_labels(struct nd_region *nd_region) { - int i; + int i, rc = 0; for (i = 0; i < nd_region->ndr_mappings; i++) { struct nd_mapping *nd_mapping = &nd_region->mapping[i]; @@ -2546,13 +2546,14 @@ static int init_active_labels(struct nd_region *nd_region) else if (test_bit(NDD_LABELING, &nvdimm->flags)) /* fail, labels needed to disambiguate dpa */; else - return 0; + continue; dev_err(&nd_region->dev, "%s: is %s, failing probe\n", dev_name(&nd_mapping->nvdimm->dev), test_bit(NDD_LOCKED, &nvdimm->flags) ? "locked" : "disabled"); - return -ENXIO; + rc = -ENXIO; + goto out; } nd_mapping->ndd = ndd; atomic_inc(&nvdimm->busy); @@ -2586,13 +2587,17 @@ static int init_active_labels(struct nd_region *nd_region) break; } - if (i < nd_region->ndr_mappings) { + if (i < nd_region->ndr_mappings) + rc = -ENOMEM; + +out: + if (rc) { deactivate_labels(nd_region); - return -ENOMEM; + return rc; } return devm_add_action_or_reset(&nd_region->dev, deactivate_labels, - nd_region); + nd_region); } int nd_region_register_namespaces(struct nd_region *nd_region, int *err) diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig index a44d49d63968..494675aeaaad 100644 --- a/drivers/nvme/host/Kconfig +++ b/drivers/nvme/host/Kconfig @@ -71,7 +71,8 @@ config NVME_FC config NVME_TCP tristate "NVM Express over Fabrics TCP host driver" depends on INET - depends on BLK_DEV_NVME + depends on BLOCK + select NVME_CORE select NVME_FABRICS select CRYPTO select CRYPTO_CRC32C diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index f520a71a361f..ff5a16b17133 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -751,7 +751,10 @@ static inline blk_status_t nvme_setup_write_zeroes(struct nvme_ns *ns, cpu_to_le64(nvme_sect_to_lba(ns, blk_rq_pos(req))); cmnd->write_zeroes.length = cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1); - cmnd->write_zeroes.control = 0; + if (nvme_ns_has_pi(ns)) + cmnd->write_zeroes.control = cpu_to_le16(NVME_RW_PRINFO_PRACT); + else + cmnd->write_zeroes.control = 0; return BLK_STS_OK; } diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c index 8575724734e0..7015fba2e512 100644 --- a/drivers/nvme/host/fabrics.c +++ b/drivers/nvme/host/fabrics.c @@ -336,6 +336,11 @@ static void nvmf_log_connect_error(struct nvme_ctrl *ctrl, cmd->connect.recfmt); break; + case NVME_SC_HOST_PATH_ERROR: + dev_err(ctrl->device, + "Connect command failed: host path error\n"); + break; + default: dev_err(ctrl->device, "Connect command failed, error wo/DNR bit: %d\n", diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index c1f3446216c5..fb48a88d1acb 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1027,7 +1027,7 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx) static inline void nvme_update_cq_head(struct nvme_queue *nvmeq) { - u16 tmp = nvmeq->cq_head + 1; + u32 tmp = nvmeq->cq_head + 1; if (tmp == nvmeq->q_depth) { nvmeq->cq_head = 0; @@ -2596,7 +2596,9 @@ static void nvme_reset_work(struct work_struct *work) bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL); int result; - if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING)) { + if (dev->ctrl.state != NVME_CTRL_RESETTING) { + dev_warn(dev->ctrl.device, "ctrl state %d is not RESETTING\n", + dev->ctrl.state); result = -ENODEV; goto out; } @@ -2836,10 +2838,7 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) #ifdef CONFIG_ACPI static bool nvme_acpi_storage_d3(struct pci_dev *dev) { - struct acpi_device *adev; - struct pci_dev *root; - acpi_handle handle; - acpi_status status; + struct acpi_device *adev = ACPI_COMPANION(&dev->dev); u8 val; /* @@ -2847,28 +2846,9 @@ static bool nvme_acpi_storage_d3(struct pci_dev *dev) * must use D3 to support deep platform power savings during * suspend-to-idle. */ - root = pcie_find_root_port(dev); - if (!root) - return false; - adev = ACPI_COMPANION(&root->dev); if (!adev) return false; - - /* - * The property is defined in the PXSX device for South complex ports - * and in the PEGP device for North complex ports. - */ - status = acpi_get_handle(adev->handle, "PXSX", &handle); - if (ACPI_FAILURE(status)) { - status = acpi_get_handle(adev->handle, "PEGP", &handle); - if (ACPI_FAILURE(status)) - return false; - } - - if (acpi_bus_get_device(handle, &adev)) - return false; - if (fwnode_property_read_u8(acpi_fwnode_handle(adev), "StorageD3Enable", &val)) return false; @@ -3025,7 +3005,6 @@ static void nvme_remove(struct pci_dev *pdev) if (!pci_device_is_present(pdev)) { nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DEAD); nvme_dev_disable(dev, true); - nvme_dev_remove_admin(dev); } flush_work(&dev->ctrl.reset_work); diff --git a/drivers/nvme/host/trace.h b/drivers/nvme/host/trace.h index daaf700eae79..35bac7a25422 100644 --- a/drivers/nvme/host/trace.h +++ b/drivers/nvme/host/trace.h @@ -56,7 +56,7 @@ TRACE_EVENT(nvme_setup_cmd, __field(u8, fctype) __field(u16, cid) __field(u32, nsid) - __field(u64, metadata) + __field(bool, metadata) __array(u8, cdw10, 24) ), TP_fast_assign( @@ -66,13 +66,13 @@ TRACE_EVENT(nvme_setup_cmd, __entry->flags = cmd->common.flags; __entry->cid = cmd->common.command_id; __entry->nsid = le32_to_cpu(cmd->common.nsid); - __entry->metadata = le64_to_cpu(cmd->common.metadata); + __entry->metadata = !!blk_integrity_rq(req); __entry->fctype = cmd->fabrics.fctype; __assign_disk_name(__entry->disk, req->rq_disk); memcpy(__entry->cdw10, &cmd->common.cdw10, sizeof(__entry->cdw10)); ), - TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%llx, cmd=(%s %s)", + TP_printk("nvme%d: %sqid=%d, cmdid=%u, nsid=%u, flags=0x%x, meta=0x%x, cmd=(%s %s)", __entry->ctrl_id, __print_disk_name(__entry->disk), __entry->qid, __entry->cid, __entry->nsid, __entry->flags, __entry->metadata, diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 8b939e9db470..9a8fa2e582d5 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -379,10 +379,10 @@ static void nvmet_keep_alive_timer(struct work_struct *work) { struct nvmet_ctrl *ctrl = container_of(to_delayed_work(work), struct nvmet_ctrl, ka_work); - bool cmd_seen = ctrl->cmd_seen; + bool reset_tbkas = ctrl->reset_tbkas; - ctrl->cmd_seen = false; - if (cmd_seen) { + ctrl->reset_tbkas = false; + if (reset_tbkas) { pr_debug("ctrl %d reschedule traffic based keep-alive timer\n", ctrl->cntlid); schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ); @@ -792,6 +792,13 @@ void nvmet_sq_destroy(struct nvmet_sq *sq) percpu_ref_exit(&sq->ref); if (ctrl) { + /* + * The teardown flow may take some time, and the host may not + * send us keep-alive during this period, hence reset the + * traffic based keep-alive timer so we don't trigger a + * controller teardown as a result of a keep-alive expiration. + */ + ctrl->reset_tbkas = true; nvmet_ctrl_put(ctrl); sq->ctrl = NULL; /* allows reusing the queue later */ } @@ -942,7 +949,7 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq, } if (sq->ctrl) - sq->ctrl->cmd_seen = true; + sq->ctrl->reset_tbkas = true; return true; diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c index cd4e73aa9807..640031cbda7c 100644 --- a/drivers/nvme/target/fc.c +++ b/drivers/nvme/target/fc.c @@ -2499,13 +2499,6 @@ nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, u32 xfrlen = be32_to_cpu(cmdiu->data_len); int ret; - /* - * if there is no nvmet mapping to the targetport there - * shouldn't be requests. just terminate them. - */ - if (!tgtport->pe) - goto transport_error; - /* * Fused commands are currently not supported in the linux * implementation. @@ -2533,7 +2526,8 @@ nvmet_fc_handle_fcp_rqst(struct nvmet_fc_tgtport *tgtport, fod->req.cmd = &fod->cmdiubuf.sqe; fod->req.cqe = &fod->rspiubuf.cqe; - fod->req.port = tgtport->pe->port; + if (tgtport->pe) + fod->req.port = tgtport->pe->port; /* clear any response payload */ memset(&fod->rspiubuf, 0, sizeof(fod->rspiubuf)); diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c index b869b686e962..16d71cc5a50e 100644 --- a/drivers/nvme/target/loop.c +++ b/drivers/nvme/target/loop.c @@ -251,7 +251,8 @@ static const struct blk_mq_ops nvme_loop_admin_mq_ops = { static void nvme_loop_destroy_admin_queue(struct nvme_loop_ctrl *ctrl) { - clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags); + if (!test_and_clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags)) + return; nvmet_sq_destroy(&ctrl->queues[0].nvme_sq); blk_cleanup_queue(ctrl->ctrl.admin_q); blk_cleanup_queue(ctrl->ctrl.fabrics_q); @@ -287,6 +288,7 @@ static void nvme_loop_destroy_io_queues(struct nvme_loop_ctrl *ctrl) clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[i].flags); nvmet_sq_destroy(&ctrl->queues[i].nvme_sq); } + ctrl->ctrl.queue_count = 1; } static int nvme_loop_init_io_queues(struct nvme_loop_ctrl *ctrl) @@ -393,6 +395,7 @@ static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl) return 0; out_cleanup_queue: + clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags); blk_cleanup_queue(ctrl->ctrl.admin_q); out_cleanup_fabrics_q: blk_cleanup_queue(ctrl->ctrl.fabrics_q); @@ -450,8 +453,10 @@ static void nvme_loop_reset_ctrl_work(struct work_struct *work) nvme_loop_shutdown_ctrl(ctrl); if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) { - /* state change failure should never happen */ - WARN_ON_ONCE(1); + if (ctrl->ctrl.state != NVME_CTRL_DELETING && + ctrl->ctrl.state != NVME_CTRL_DELETING_NOIO) + /* state change failure for non-deleted ctrl? */ + WARN_ON_ONCE(1); return; } diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index ea96487b5424..4bf6d21290c2 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -166,7 +166,7 @@ struct nvmet_ctrl { struct nvmet_subsys *subsys; struct nvmet_sq **sqs; - bool cmd_seen; + bool reset_tbkas; struct mutex lock; u64 cap; diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 4df4f37e6b89..dedcb7aaf0d8 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -1467,7 +1467,6 @@ static void nvmet_tcp_state_change(struct sock *sk) case TCP_CLOSE_WAIT: case TCP_CLOSE: /* FALLTHRU */ - sk->sk_user_data = NULL; nvmet_tcp_schedule_release_queue(queue); break; default: diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 9b6ab83956c3..bb8fb2b3711d 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -549,15 +549,17 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) continue; if (len < 2 * sizeof(u32)) { dev_err(dev, "nvmem: invalid reg on %pOF\n", child); + of_node_put(child); return -EINVAL; } cell = kzalloc(sizeof(*cell), GFP_KERNEL); - if (!cell) + if (!cell) { + of_node_put(child); return -ENOMEM; + } cell->nvmem = nvmem; - cell->np = of_node_get(child); cell->offset = be32_to_cpup(addr++); cell->bytes = be32_to_cpup(addr); cell->name = kasprintf(GFP_KERNEL, "%pOFn", child); @@ -578,11 +580,12 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) cell->name, nvmem->stride); /* Cells already added will be freed later. */ kfree_const(cell->name); - of_node_put(cell->np); kfree(cell); + of_node_put(child); return -EINVAL; } + cell->np = of_node_get(child); nvmem_cell_add(cell); } diff --git a/drivers/of/address.c b/drivers/of/address.c index 73ddf2540f3f..cdf700fba5c4 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -1022,6 +1023,38 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) of_node_put(node); return ret; } + +int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np) +{ + struct device_node *node, *of_node = dev->of_node; + int count, i; + + count = of_property_count_elems_of_size(of_node, "memory-region", + sizeof(u32)); + /* + * If dev->of_node doesn't exist or doesn't contain memory-region, try + * the OF node having DMA configuration. + */ + if (count <= 0) { + of_node = np; + count = of_property_count_elems_of_size( + of_node, "memory-region", sizeof(u32)); + } + + for (i = 0; i < count; i++) { + node = of_parse_phandle(of_node, "memory-region", i); + /* + * There might be multiple memory regions, but only one + * restricted-dma-pool region is allowed. + */ + if (of_device_is_compatible(node, "restricted-dma-pool") && + of_device_is_available(node)) + return of_reserved_mem_device_init_by_idx(dev, of_node, + i); + } + + return 0; +} #endif /* CONFIG_HAS_DMA */ /** diff --git a/drivers/of/device.c b/drivers/of/device.c index 1122daa8e273..bc7bcfee1864 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -186,6 +186,9 @@ int of_dma_configure_id(struct device *dev, struct device_node *np, arch_setup_dma_ops(dev, dma_start, size, iommu, coherent); + if (!iommu) + return of_dma_set_restricted_buffer(dev, np); + return 0; } EXPORT_SYMBOL_GPL(of_dma_configure_id); diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 04a74c8f2315..74d2bd7a6550 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -501,11 +501,11 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, if (size && early_init_dt_reserve_memory_arch(base, size, nomap) == 0) - pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", - uname, &base, (unsigned long)size / SZ_1M); + pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); else - pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %ld MiB\n", - uname, &base, (unsigned long)size / SZ_1M); + pr_info("Reserved memory: failed to reserve memory for node '%s': base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); len -= t_len; if (first) { diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index d9e6a324de0a..c9494971ff21 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -161,12 +161,19 @@ struct bus_dma_region; #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_HAS_DMA) int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map); +int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np); #else static inline int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) { return -ENODEV; } +static inline int of_dma_set_restricted_buffer(struct device *dev, + struct device_node *np) +{ + /* Do nothing, successfully. */ + return 0; +} #endif #endif /* _LINUX_OF_PRIVATE_H */ diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index a7fbc5e37e19..6c95bbdf9265 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -134,9 +134,9 @@ static int __init __reserved_mem_alloc_size(unsigned long node, ret = early_init_dt_alloc_reserved_memory_arch(size, align, start, end, nomap, &base); if (ret == 0) { - pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n", + pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", uname, &base, - (unsigned long)size / SZ_1M); + (unsigned long)(size / SZ_1M)); break; } len -= t_len; @@ -146,8 +146,8 @@ static int __init __reserved_mem_alloc_size(unsigned long node, ret = early_init_dt_alloc_reserved_memory_arch(size, align, 0, 0, nomap, &base); if (ret == 0) - pr_debug("allocated memory for '%s' node: base %pa, size %ld MiB\n", - uname, &base, (unsigned long)size / SZ_1M); + pr_debug("allocated memory for '%s' node: base %pa, size %lu MiB\n", + uname, &base, (unsigned long)(size / SZ_1M)); } if (base == 0) { diff --git a/drivers/opp/of.c b/drivers/opp/of.c index f9bd3837e9d5..f3538ed56194 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -870,8 +870,9 @@ static int _of_add_opp_table_v2(struct device *dev, struct opp_table *opp_table) } } - /* There should be one of more OPP defined */ - if (WARN_ON(!count)) { + /* There should be one or more OPPs defined */ + if (!count) { + dev_err(dev, "%s: no supported OPPs", __func__); ret = -ENOENT; goto remove_static_opp; } diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig index 64e2f5e379aa..049c60016904 100644 --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig @@ -41,7 +41,6 @@ config PCI_TEGRA bool "NVIDIA Tegra PCIe controller" depends on ARCH_TEGRA || COMPILE_TEST depends on PCI_MSI_IRQ_DOMAIN - select PCI_MSI_ARCH_FALLBACKS help Say Y here if you want support for the PCIe host controller found on NVIDIA Tegra SoCs. @@ -68,7 +67,6 @@ config PCIE_RCAR_HOST bool "Renesas R-Car PCIe host controller" depends on ARCH_RENESAS || COMPILE_TEST depends on PCI_MSI_IRQ_DOMAIN - select PCI_MSI_ARCH_FALLBACKS help Say Y here if you want PCIe controller support on R-Car SoCs in host mode. @@ -97,7 +95,7 @@ config PCI_HOST_GENERIC config PCIE_XILINX bool "Xilinx AXI PCIe host bridge support" depends on OF || COMPILE_TEST - select PCI_MSI_ARCH_FALLBACKS + depends on PCI_MSI_IRQ_DOMAIN help Say 'Y' here if you want kernel to support the Xilinx AXI PCIe Host Bridge driver. diff --git a/drivers/pci/controller/dwc/pcie-intel-gw.c b/drivers/pci/controller/dwc/pcie-intel-gw.c index 5650cb78acba..5e1a284fdc53 100644 --- a/drivers/pci/controller/dwc/pcie-intel-gw.c +++ b/drivers/pci/controller/dwc/pcie-intel-gw.c @@ -39,6 +39,10 @@ #define PCIE_APP_IRN_PM_TO_ACK BIT(9) #define PCIE_APP_IRN_LINK_AUTO_BW_STAT BIT(11) #define PCIE_APP_IRN_BW_MGT BIT(12) +#define PCIE_APP_IRN_INTA BIT(13) +#define PCIE_APP_IRN_INTB BIT(14) +#define PCIE_APP_IRN_INTC BIT(15) +#define PCIE_APP_IRN_INTD BIT(16) #define PCIE_APP_IRN_MSG_LTR BIT(18) #define PCIE_APP_IRN_SYS_ERR_RC BIT(29) #define PCIE_APP_INTX_OFST 12 @@ -48,10 +52,8 @@ PCIE_APP_IRN_RX_VDM_MSG | PCIE_APP_IRN_SYS_ERR_RC | \ PCIE_APP_IRN_PM_TO_ACK | PCIE_APP_IRN_MSG_LTR | \ PCIE_APP_IRN_BW_MGT | PCIE_APP_IRN_LINK_AUTO_BW_STAT | \ - (PCIE_APP_INTX_OFST + PCI_INTERRUPT_INTA) | \ - (PCIE_APP_INTX_OFST + PCI_INTERRUPT_INTB) | \ - (PCIE_APP_INTX_OFST + PCI_INTERRUPT_INTC) | \ - (PCIE_APP_INTX_OFST + PCI_INTERRUPT_INTD)) + PCIE_APP_IRN_INTA | PCIE_APP_IRN_INTB | \ + PCIE_APP_IRN_INTC | PCIE_APP_IRN_INTD) #define BUS_IATU_OFFSET SZ_256M #define RESET_INTERVAL_MS 100 diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index d788f4d7f9aa..506f6a294eac 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -1841,7 +1841,7 @@ static int tegra_pcie_ep_raise_msi_irq(struct tegra_pcie_dw *pcie, u16 irq) if (unlikely(irq > 31)) return -EINVAL; - appl_writel(pcie, (1 << irq), APPL_MSI_CTRL_1); + appl_writel(pcie, BIT(irq), APPL_MSI_CTRL_1); return 0; } diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c index 0be485a25327..b1b41b61e0bd 100644 --- a/drivers/pci/controller/pci-aardvark.c +++ b/drivers/pci/controller/pci-aardvark.c @@ -56,7 +56,7 @@ #define PIO_COMPLETION_STATUS_UR 1 #define PIO_COMPLETION_STATUS_CRS 2 #define PIO_COMPLETION_STATUS_CA 4 -#define PIO_NON_POSTED_REQ BIT(0) +#define PIO_NON_POSTED_REQ BIT(10) #define PIO_ADDR_LS (PIO_BASE_ADDR + 0x8) #define PIO_ADDR_MS (PIO_BASE_ADDR + 0xc) #define PIO_WR_DATA (PIO_BASE_ADDR + 0x10) @@ -124,6 +124,7 @@ #define LTSSM_MASK 0x3f #define LTSSM_L0 0x10 #define RC_BAR_CONFIG 0x300 +#define VENDOR_ID_REG (LMI_BASE_ADDR + 0x44) /* PCIe core controller registers */ #define CTRL_CORE_BASE_ADDR 0x18000 @@ -385,6 +386,16 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) reg |= (IS_RC_MSK << IS_RC_SHIFT); advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + /* + * Replace incorrect PCI vendor id value 0x1b4b by correct value 0x11ab. + * VENDOR_ID_REG contains vendor id in low 16 bits and subsystem vendor + * id in high 16 bits. Updating this register changes readback value of + * read-only vendor id bits in PCIE_CORE_DEV_ID_REG register. Workaround + * for erratum 4.1: "The value of device and vendor ID is incorrect". + */ + reg = (PCI_VENDOR_ID_MARVELL << 16) | PCI_VENDOR_ID_MARVELL; + advk_writel(pcie, reg, VENDOR_ID_REG); + /* Set Advanced Error Capabilities and Control PF0 register */ reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX | PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN | @@ -514,7 +525,7 @@ static int advk_pcie_wait_pio(struct advk_pcie *pcie) udelay(PIO_RETRY_DELAY); } - dev_err(dev, "config read/write timed out\n"); + dev_err(dev, "PIO read/write transfer time out\n"); return -ETIMEDOUT; } @@ -657,6 +668,35 @@ static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus, return true; } +static bool advk_pcie_pio_is_running(struct advk_pcie *pcie) +{ + struct device *dev = &pcie->pdev->dev; + + /* + * Trying to start a new PIO transfer when previous has not completed + * cause External Abort on CPU which results in kernel panic: + * + * SError Interrupt on CPU0, code 0xbf000002 -- SError + * Kernel panic - not syncing: Asynchronous SError Interrupt + * + * Functions advk_pcie_rd_conf() and advk_pcie_wr_conf() are protected + * by raw_spin_lock_irqsave() at pci_lock_config() level to prevent + * concurrent calls at the same time. But because PIO transfer may take + * about 1.5s when link is down or card is disconnected, it means that + * advk_pcie_wait_pio() does not always have to wait for completion. + * + * Some versions of ARM Trusted Firmware handles this External Abort at + * EL3 level and mask it to prevent kernel panic. Relevant TF-A commit: + * https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=3c7dcdac5c50 + */ + if (advk_readl(pcie, PIO_START)) { + dev_err(dev, "Previous PIO read/write transfer is still running\n"); + return true; + } + + return false; +} + static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { @@ -673,9 +713,10 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, return pci_bridge_emul_conf_read(&pcie->bridge, where, size, val); - /* Start PIO */ - advk_writel(pcie, 0, PIO_START); - advk_writel(pcie, 1, PIO_ISR); + if (advk_pcie_pio_is_running(pcie)) { + *val = 0xffffffff; + return PCIBIOS_SET_FAILED; + } /* Program the control register */ reg = advk_readl(pcie, PIO_CTRL); @@ -694,7 +735,8 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn, /* Program the data strobe */ advk_writel(pcie, 0xf, PIO_WR_DATA_STRB); - /* Start the transfer */ + /* Clear PIO DONE ISR and start the transfer */ + advk_writel(pcie, 1, PIO_ISR); advk_writel(pcie, 1, PIO_START); ret = advk_pcie_wait_pio(pcie); @@ -734,9 +776,8 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, if (where % size) return PCIBIOS_SET_FAILED; - /* Start PIO */ - advk_writel(pcie, 0, PIO_START); - advk_writel(pcie, 1, PIO_ISR); + if (advk_pcie_pio_is_running(pcie)) + return PCIBIOS_SET_FAILED; /* Program the control register */ reg = advk_readl(pcie, PIO_CTRL); @@ -763,7 +804,8 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, /* Program the data strobe */ advk_writel(pcie, data_strobe, PIO_WR_DATA_STRB); - /* Start the transfer */ + /* Clear PIO DONE ISR and start the transfer */ + advk_writel(pcie, 1, PIO_ISR); advk_writel(pcie, 1, PIO_START); ret = advk_pcie_wait_pio(pcie); diff --git a/drivers/pci/controller/pci-ftpci100.c b/drivers/pci/controller/pci-ftpci100.c index da3cd216da00..aefef1986201 100644 --- a/drivers/pci/controller/pci-ftpci100.c +++ b/drivers/pci/controller/pci-ftpci100.c @@ -34,12 +34,12 @@ * Special configuration registers directly in the first few words * in I/O space. */ -#define PCI_IOSIZE 0x00 -#define PCI_PROT 0x04 /* AHB protection */ -#define PCI_CTRL 0x08 /* PCI control signal */ -#define PCI_SOFTRST 0x10 /* Soft reset counter and response error enable */ -#define PCI_CONFIG 0x28 /* PCI configuration command register */ -#define PCI_DATA 0x2C +#define FTPCI_IOSIZE 0x00 +#define FTPCI_PROT 0x04 /* AHB protection */ +#define FTPCI_CTRL 0x08 /* PCI control signal */ +#define FTPCI_SOFTRST 0x10 /* Soft reset counter and response error enable */ +#define FTPCI_CONFIG 0x28 /* PCI configuration command register */ +#define FTPCI_DATA 0x2C #define FARADAY_PCI_STATUS_CMD 0x04 /* Status and command */ #define FARADAY_PCI_PMC 0x40 /* Power management control */ @@ -195,9 +195,9 @@ static int faraday_raw_pci_read_config(struct faraday_pci *p, int bus_number, PCI_CONF_FUNCTION(PCI_FUNC(fn)) | PCI_CONF_WHERE(config) | PCI_CONF_ENABLE, - p->base + PCI_CONFIG); + p->base + FTPCI_CONFIG); - *value = readl(p->base + PCI_DATA); + *value = readl(p->base + FTPCI_DATA); if (size == 1) *value = (*value >> (8 * (config & 3))) & 0xFF; @@ -230,17 +230,17 @@ static int faraday_raw_pci_write_config(struct faraday_pci *p, int bus_number, PCI_CONF_FUNCTION(PCI_FUNC(fn)) | PCI_CONF_WHERE(config) | PCI_CONF_ENABLE, - p->base + PCI_CONFIG); + p->base + FTPCI_CONFIG); switch (size) { case 4: - writel(value, p->base + PCI_DATA); + writel(value, p->base + FTPCI_DATA); break; case 2: - writew(value, p->base + PCI_DATA + (config & 3)); + writew(value, p->base + FTPCI_DATA + (config & 3)); break; case 1: - writeb(value, p->base + PCI_DATA + (config & 3)); + writeb(value, p->base + FTPCI_DATA + (config & 3)); break; default: ret = PCIBIOS_BAD_REGISTER_NUMBER; @@ -469,7 +469,7 @@ static int faraday_pci_probe(struct platform_device *pdev) if (!faraday_res_to_memcfg(io->start - win->offset, resource_size(io), &val)) { /* setup I/O space size */ - writel(val, p->base + PCI_IOSIZE); + writel(val, p->base + FTPCI_IOSIZE); } else { dev_err(dev, "illegal IO mem size\n"); return -EINVAL; @@ -477,11 +477,11 @@ static int faraday_pci_probe(struct platform_device *pdev) } /* Setup hostbridge */ - val = readl(p->base + PCI_CTRL); + val = readl(p->base + FTPCI_CTRL); val |= PCI_COMMAND_IO; val |= PCI_COMMAND_MEMORY; val |= PCI_COMMAND_MASTER; - writel(val, p->base + PCI_CTRL); + writel(val, p->base + FTPCI_CTRL); /* Mask and clear all interrupts */ faraday_raw_pci_write_config(p, 0, 0, FARADAY_PCI_CTRL2 + 2, 2, 0xF000); if (variant->cascaded_irq) { diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-host-common.c index 6ce34a1deecb..603f6fbbe68a 100644 --- a/drivers/pci/controller/pci-host-common.c +++ b/drivers/pci/controller/pci-host-common.c @@ -77,6 +77,7 @@ int pci_host_common_probe(struct platform_device *pdev) bridge->sysdata = cfg; bridge->ops = (struct pci_ops *)&ops->pci_ops; + bridge->msi_domain = true; platform_set_drvdata(pdev, bridge); diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 03ed5cb1c4b2..b599b31ecab3 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -444,7 +444,6 @@ enum hv_pcibus_state { hv_pcibus_probed, hv_pcibus_installed, hv_pcibus_removing, - hv_pcibus_removed, hv_pcibus_maximum }; @@ -473,7 +472,6 @@ struct hv_pcibus_device { struct list_head dr_list; struct msi_domain_info msi_info; - struct msi_controller msi_chip; struct irq_domain *irq_domain; spinlock_t retarget_msi_interrupt_lock; @@ -1866,9 +1864,6 @@ static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus) if (!hbus->pci_bus) return -ENODEV; - hbus->pci_bus->msi = &hbus->msi_chip; - hbus->pci_bus->msi->dev = &hbus->hdev->device; - pci_lock_rescan_remove(); pci_scan_child_bus(hbus->pci_bus); hv_pci_assign_numa_node(hbus); @@ -3247,8 +3242,9 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) struct pci_packet teardown_packet; u8 buffer[sizeof(struct pci_message)]; } pkt; - struct hv_dr_state *dr; struct hv_pci_compl comp_pkt; + struct hv_pci_dev *hpdev, *tmp; + unsigned long flags; int ret; /* @@ -3260,9 +3256,16 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs) if (!keep_devs) { /* Delete any children which might still exist. */ - dr = kzalloc(sizeof(*dr), GFP_KERNEL); - if (dr && hv_pci_start_relations_work(hbus, dr)) - kfree(dr); + spin_lock_irqsave(&hbus->device_list_lock, flags); + list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry) { + list_del(&hpdev->list_entry); + if (hpdev->pci_slot) + pci_destroy_slot(hpdev->pci_slot); + /* For the two refs got in new_pcichild_device() */ + put_pcichild(hpdev); + put_pcichild(hpdev); + } + spin_unlock_irqrestore(&hbus->device_list_lock, flags); } ret = hv_send_resources_released(hdev); @@ -3305,13 +3308,23 @@ static int hv_pci_remove(struct hv_device *hdev) hbus = hv_get_drvdata(hdev); if (hbus->state == hv_pcibus_installed) { + tasklet_disable(&hdev->channel->callback_event); + hbus->state = hv_pcibus_removing; + tasklet_enable(&hdev->channel->callback_event); + destroy_workqueue(hbus->wq); + hbus->wq = NULL; + /* + * At this point, no work is running or can be scheduled + * on hbus-wq. We can't race with hv_pci_devices_present() + * or hv_pci_eject_device(), it's safe to proceed. + */ + /* Remove the bus from PCI's point of view. */ pci_lock_rescan_remove(); pci_stop_root_bus(hbus->pci_bus); hv_pci_remove_slots(hbus); pci_remove_root_bus(hbus->pci_bus); pci_unlock_rescan_remove(); - hbus->state = hv_pcibus_removed; } ret = hv_pci_bus_exit(hdev, false); @@ -3326,7 +3339,6 @@ static int hv_pci_remove(struct hv_device *hdev) irq_domain_free_fwnode(hbus->sysdata.fwnode); put_hvpcibus(hbus); wait_for_completion(&hbus->remove_event); - destroy_workqueue(hbus->wq); hv_put_dom_num(hbus->sysdata.domain); @@ -3480,6 +3492,9 @@ static void __exit exit_hv_pci_drv(void) static int __init init_hv_pci_drv(void) { + if (!hv_is_hyperv_initialized()) + return -ENODEV; + /* Set the invalid domain number's bit, so it will not be used */ set_bit(HVPCI_DOM_INVALID, hvpci_dom_map); diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c index 8fcabed7c6a6..c979229a6d0d 100644 --- a/drivers/pci/controller/pci-tegra.c +++ b/drivers/pci/controller/pci-tegra.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -78,23 +79,8 @@ #define AFI_MSI_FPCI_BAR_ST 0x64 #define AFI_MSI_AXI_BAR_ST 0x68 -#define AFI_MSI_VEC0 0x6c -#define AFI_MSI_VEC1 0x70 -#define AFI_MSI_VEC2 0x74 -#define AFI_MSI_VEC3 0x78 -#define AFI_MSI_VEC4 0x7c -#define AFI_MSI_VEC5 0x80 -#define AFI_MSI_VEC6 0x84 -#define AFI_MSI_VEC7 0x88 - -#define AFI_MSI_EN_VEC0 0x8c -#define AFI_MSI_EN_VEC1 0x90 -#define AFI_MSI_EN_VEC2 0x94 -#define AFI_MSI_EN_VEC3 0x98 -#define AFI_MSI_EN_VEC4 0x9c -#define AFI_MSI_EN_VEC5 0xa0 -#define AFI_MSI_EN_VEC6 0xa4 -#define AFI_MSI_EN_VEC7 0xa8 +#define AFI_MSI_VEC(x) (0x6c + ((x) * 4)) +#define AFI_MSI_EN_VEC(x) (0x8c + ((x) * 4)) #define AFI_CONFIGURATION 0xac #define AFI_CONFIGURATION_EN_FPCI (1 << 0) @@ -280,10 +266,10 @@ #define LINK_RETRAIN_TIMEOUT 100000 /* in usec */ struct tegra_msi { - struct msi_controller chip; DECLARE_BITMAP(used, INT_PCI_MSI_NR); struct irq_domain *domain; - struct mutex lock; + struct mutex map_lock; + spinlock_t mask_lock; void *virt; dma_addr_t phys; int irq; @@ -333,11 +319,6 @@ struct tegra_pcie_soc { } ectl; }; -static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip) -{ - return container_of(chip, struct tegra_msi, chip); -} - struct tegra_pcie { struct device *dev; @@ -372,6 +353,11 @@ struct tegra_pcie { struct dentry *debugfs; }; +static inline struct tegra_pcie *msi_to_pcie(struct tegra_msi *msi) +{ + return container_of(msi, struct tegra_pcie, msi); +} + struct tegra_pcie_port { struct tegra_pcie *pcie; struct device_node *np; @@ -1432,7 +1418,6 @@ static void tegra_pcie_phys_put(struct tegra_pcie *pcie) } } - static int tegra_pcie_get_resources(struct tegra_pcie *pcie) { struct device *dev = pcie->dev; @@ -1509,6 +1494,7 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie) phys_put: if (soc->program_uphy) tegra_pcie_phys_put(pcie); + return err; } @@ -1551,161 +1537,227 @@ static void tegra_pcie_pme_turnoff(struct tegra_pcie_port *port) afi_writel(pcie, val, AFI_PCIE_PME); } -static int tegra_msi_alloc(struct tegra_msi *chip) -{ - int msi; - - mutex_lock(&chip->lock); - - msi = find_first_zero_bit(chip->used, INT_PCI_MSI_NR); - if (msi < INT_PCI_MSI_NR) - set_bit(msi, chip->used); - else - msi = -ENOSPC; - - mutex_unlock(&chip->lock); - - return msi; -} - -static void tegra_msi_free(struct tegra_msi *chip, unsigned long irq) +static void tegra_pcie_msi_irq(struct irq_desc *desc) { - struct device *dev = chip->chip.dev; - - mutex_lock(&chip->lock); - - if (!test_bit(irq, chip->used)) - dev_err(dev, "trying to free unused MSI#%lu\n", irq); - else - clear_bit(irq, chip->used); - - mutex_unlock(&chip->lock); -} - -static irqreturn_t tegra_pcie_msi_irq(int irq, void *data) -{ - struct tegra_pcie *pcie = data; - struct device *dev = pcie->dev; + struct tegra_pcie *pcie = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); struct tegra_msi *msi = &pcie->msi; - unsigned int i, processed = 0; + struct device *dev = pcie->dev; + unsigned int i; + + chained_irq_enter(chip, desc); for (i = 0; i < 8; i++) { - unsigned long reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4); + unsigned long reg = afi_readl(pcie, AFI_MSI_VEC(i)); while (reg) { unsigned int offset = find_first_bit(®, 32); unsigned int index = i * 32 + offset; unsigned int irq; - /* clear the interrupt */ - afi_writel(pcie, 1 << offset, AFI_MSI_VEC0 + i * 4); - - irq = irq_find_mapping(msi->domain, index); + irq = irq_find_mapping(msi->domain->parent, index); if (irq) { - if (test_bit(index, msi->used)) - generic_handle_irq(irq); - else - dev_info(dev, "unhandled MSI\n"); + generic_handle_irq(irq); } else { /* * that's weird who triggered this? * just clear it */ dev_info(dev, "unexpected MSI\n"); + afi_writel(pcie, BIT(index % 32), AFI_MSI_VEC(index)); } /* see if there's any more pending in this vector */ - reg = afi_readl(pcie, AFI_MSI_VEC0 + i * 4); - - processed++; + reg = afi_readl(pcie, AFI_MSI_VEC(i)); } } - return processed > 0 ? IRQ_HANDLED : IRQ_NONE; + chained_irq_exit(chip, desc); } -static int tegra_msi_setup_irq(struct msi_controller *chip, - struct pci_dev *pdev, struct msi_desc *desc) +static void tegra_msi_top_irq_ack(struct irq_data *d) { - struct tegra_msi *msi = to_tegra_msi(chip); - struct msi_msg msg; - unsigned int irq; - int hwirq; + irq_chip_ack_parent(d); +} - hwirq = tegra_msi_alloc(msi); - if (hwirq < 0) - return hwirq; +static void tegra_msi_top_irq_mask(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} - irq = irq_create_mapping(msi->domain, hwirq); - if (!irq) { - tegra_msi_free(msi, hwirq); - return -EINVAL; - } +static void tegra_msi_top_irq_unmask(struct irq_data *d) +{ + pci_msi_unmask_irq(d); + irq_chip_unmask_parent(d); +} + +static struct irq_chip tegra_msi_top_chip = { + .name = "Tegra PCIe MSI", + .irq_ack = tegra_msi_top_irq_ack, + .irq_mask = tegra_msi_top_irq_mask, + .irq_unmask = tegra_msi_top_irq_unmask, +}; - irq_set_msi_desc(irq, desc); +static void tegra_msi_irq_ack(struct irq_data *d) +{ + struct tegra_msi *msi = irq_data_get_irq_chip_data(d); + struct tegra_pcie *pcie = msi_to_pcie(msi); + unsigned int index = d->hwirq / 32; - msg.address_lo = lower_32_bits(msi->phys); - msg.address_hi = upper_32_bits(msi->phys); - msg.data = hwirq; + /* clear the interrupt */ + afi_writel(pcie, BIT(d->hwirq % 32), AFI_MSI_VEC(index)); +} - pci_write_msi_msg(irq, &msg); +static void tegra_msi_irq_mask(struct irq_data *d) +{ + struct tegra_msi *msi = irq_data_get_irq_chip_data(d); + struct tegra_pcie *pcie = msi_to_pcie(msi); + unsigned int index = d->hwirq / 32; + unsigned long flags; + u32 value; - return 0; + spin_lock_irqsave(&msi->mask_lock, flags); + value = afi_readl(pcie, AFI_MSI_EN_VEC(index)); + value &= ~BIT(d->hwirq % 32); + afi_writel(pcie, value, AFI_MSI_EN_VEC(index)); + spin_unlock_irqrestore(&msi->mask_lock, flags); } -static void tegra_msi_teardown_irq(struct msi_controller *chip, - unsigned int irq) +static void tegra_msi_irq_unmask(struct irq_data *d) { - struct tegra_msi *msi = to_tegra_msi(chip); - struct irq_data *d = irq_get_irq_data(irq); - irq_hw_number_t hwirq = irqd_to_hwirq(d); + struct tegra_msi *msi = irq_data_get_irq_chip_data(d); + struct tegra_pcie *pcie = msi_to_pcie(msi); + unsigned int index = d->hwirq / 32; + unsigned long flags; + u32 value; - irq_dispose_mapping(irq); - tegra_msi_free(msi, hwirq); + spin_lock_irqsave(&msi->mask_lock, flags); + value = afi_readl(pcie, AFI_MSI_EN_VEC(index)); + value |= BIT(d->hwirq % 32); + afi_writel(pcie, value, AFI_MSI_EN_VEC(index)); + spin_unlock_irqrestore(&msi->mask_lock, flags); } -static struct irq_chip tegra_msi_irq_chip = { - .name = "Tegra PCIe MSI", - .irq_enable = pci_msi_unmask_irq, - .irq_disable = pci_msi_mask_irq, - .irq_mask = pci_msi_mask_irq, - .irq_unmask = pci_msi_unmask_irq, +static int tegra_msi_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force) +{ + return -EINVAL; +} + +static void tegra_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) +{ + struct tegra_msi *msi = irq_data_get_irq_chip_data(data); + + msg->address_lo = lower_32_bits(msi->phys); + msg->address_hi = upper_32_bits(msi->phys); + msg->data = data->hwirq; +} + +static struct irq_chip tegra_msi_bottom_chip = { + .name = "Tegra MSI", + .irq_ack = tegra_msi_irq_ack, + .irq_mask = tegra_msi_irq_mask, + .irq_unmask = tegra_msi_irq_unmask, + .irq_set_affinity = tegra_msi_set_affinity, + .irq_compose_msi_msg = tegra_compose_msi_msg, }; -static int tegra_msi_map(struct irq_domain *domain, unsigned int irq, - irq_hw_number_t hwirq) +static int tegra_msi_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *args) { - irq_set_chip_and_handler(irq, &tegra_msi_irq_chip, handle_simple_irq); - irq_set_chip_data(irq, domain->host_data); + struct tegra_msi *msi = domain->host_data; + unsigned int i; + int hwirq; + + mutex_lock(&msi->map_lock); + + hwirq = bitmap_find_free_region(msi->used, INT_PCI_MSI_NR, order_base_2(nr_irqs)); + + mutex_unlock(&msi->map_lock); + + if (hwirq < 0) + return -ENOSPC; + + for (i = 0; i < nr_irqs; i++) + irq_domain_set_info(domain, virq + i, hwirq + i, + &tegra_msi_bottom_chip, domain->host_data, + handle_edge_irq, NULL, NULL); tegra_cpuidle_pcie_irqs_in_use(); return 0; } -static const struct irq_domain_ops msi_domain_ops = { - .map = tegra_msi_map, +static void tegra_msi_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct tegra_msi *msi = domain->host_data; + + mutex_lock(&msi->map_lock); + + bitmap_release_region(msi->used, d->hwirq, order_base_2(nr_irqs)); + + mutex_unlock(&msi->map_lock); +} + +static const struct irq_domain_ops tegra_msi_domain_ops = { + .alloc = tegra_msi_domain_alloc, + .free = tegra_msi_domain_free, +}; + +static struct msi_domain_info tegra_msi_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_PCI_MSIX), + .chip = &tegra_msi_top_chip, }; +static int tegra_allocate_domains(struct tegra_msi *msi) +{ + struct tegra_pcie *pcie = msi_to_pcie(msi); + struct fwnode_handle *fwnode = dev_fwnode(pcie->dev); + struct irq_domain *parent; + + parent = irq_domain_create_linear(fwnode, INT_PCI_MSI_NR, + &tegra_msi_domain_ops, msi); + if (!parent) { + dev_err(pcie->dev, "failed to create IRQ domain\n"); + return -ENOMEM; + } + irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS); + + msi->domain = pci_msi_create_irq_domain(fwnode, &tegra_msi_info, parent); + if (!msi->domain) { + dev_err(pcie->dev, "failed to create MSI domain\n"); + irq_domain_remove(parent); + return -ENOMEM; + } + + return 0; +} + +static void tegra_free_domains(struct tegra_msi *msi) +{ + struct irq_domain *parent = msi->domain->parent; + + irq_domain_remove(msi->domain); + irq_domain_remove(parent); +} + static int tegra_pcie_msi_setup(struct tegra_pcie *pcie) { - struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); struct platform_device *pdev = to_platform_device(pcie->dev); struct tegra_msi *msi = &pcie->msi; struct device *dev = pcie->dev; int err; - mutex_init(&msi->lock); - - msi->chip.dev = dev; - msi->chip.setup_irq = tegra_msi_setup_irq; - msi->chip.teardown_irq = tegra_msi_teardown_irq; + mutex_init(&msi->map_lock); + spin_lock_init(&msi->mask_lock); - msi->domain = irq_domain_add_linear(dev->of_node, INT_PCI_MSI_NR, - &msi_domain_ops, &msi->chip); - if (!msi->domain) { - dev_err(dev, "failed to create IRQ domain\n"); - return -ENOMEM; + if (IS_ENABLED(CONFIG_PCI_MSI)) { + err = tegra_allocate_domains(msi); + if (err) + return err; } err = platform_get_irq_byname(pdev, "msi"); @@ -1714,12 +1766,7 @@ static int tegra_pcie_msi_setup(struct tegra_pcie *pcie) msi->irq = err; - err = request_irq(msi->irq, tegra_pcie_msi_irq, IRQF_NO_THREAD, - tegra_msi_irq_chip.name, pcie); - if (err < 0) { - dev_err(dev, "failed to request IRQ: %d\n", err); - goto free_irq_domain; - } + irq_set_chained_handler_and_data(msi->irq, tegra_pcie_msi_irq, pcie); /* Though the PCIe controller can address >32-bit address space, to * facilitate endpoints that support only 32-bit MSI target address, @@ -1740,14 +1787,14 @@ static int tegra_pcie_msi_setup(struct tegra_pcie *pcie) goto free_irq; } - host->msi = &msi->chip; - return 0; free_irq: - free_irq(msi->irq, pcie); + irq_set_chained_handler_and_data(msi->irq, NULL, NULL); free_irq_domain: - irq_domain_remove(msi->domain); + if (IS_ENABLED(CONFIG_PCI_MSI)) + tegra_free_domains(msi); + return err; } @@ -1755,22 +1802,18 @@ static void tegra_pcie_enable_msi(struct tegra_pcie *pcie) { const struct tegra_pcie_soc *soc = pcie->soc; struct tegra_msi *msi = &pcie->msi; - u32 reg; + u32 reg, msi_state[INT_PCI_MSI_NR / 32]; + int i; afi_writel(pcie, msi->phys >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST); afi_writel(pcie, msi->phys, AFI_MSI_AXI_BAR_ST); /* this register is in 4K increments */ afi_writel(pcie, 1, AFI_MSI_BAR_SZ); - /* enable all MSI vectors */ - afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC0); - afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC1); - afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC2); - afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC3); - afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC4); - afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC5); - afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC6); - afi_writel(pcie, 0xffffffff, AFI_MSI_EN_VEC7); + /* Restore the MSI allocation state */ + bitmap_to_arr32(msi_state, msi->used, INT_PCI_MSI_NR); + for (i = 0; i < ARRAY_SIZE(msi_state); i++) + afi_writel(pcie, msi_state[i], AFI_MSI_EN_VEC(i)); /* and unmask the MSI interrupt */ reg = afi_readl(pcie, AFI_INTR_MASK); @@ -1786,16 +1829,16 @@ static void tegra_pcie_msi_teardown(struct tegra_pcie *pcie) dma_free_attrs(pcie->dev, PAGE_SIZE, msi->virt, msi->phys, DMA_ATTR_NO_KERNEL_MAPPING); - if (msi->irq > 0) - free_irq(msi->irq, pcie); - for (i = 0; i < INT_PCI_MSI_NR; i++) { irq = irq_find_mapping(msi->domain, i); if (irq > 0) - irq_dispose_mapping(irq); + irq_domain_free_irqs(irq, 1); } - irq_domain_remove(msi->domain); + irq_set_chained_handler_and_data(msi->irq, NULL, NULL); + + if (IS_ENABLED(CONFIG_PCI_MSI)) + tegra_free_domains(msi); } static int tegra_pcie_disable_msi(struct tegra_pcie *pcie) @@ -1807,16 +1850,6 @@ static int tegra_pcie_disable_msi(struct tegra_pcie *pcie) value &= ~AFI_INTR_MASK_MSI_MASK; afi_writel(pcie, value, AFI_INTR_MASK); - /* disable all MSI vectors */ - afi_writel(pcie, 0, AFI_MSI_EN_VEC0); - afi_writel(pcie, 0, AFI_MSI_EN_VEC1); - afi_writel(pcie, 0, AFI_MSI_EN_VEC2); - afi_writel(pcie, 0, AFI_MSI_EN_VEC3); - afi_writel(pcie, 0, AFI_MSI_EN_VEC4); - afi_writel(pcie, 0, AFI_MSI_EN_VEC5); - afi_writel(pcie, 0, AFI_MSI_EN_VEC6); - afi_writel(pcie, 0, AFI_MSI_EN_VEC7); - return 0; } @@ -2506,6 +2539,7 @@ static const struct of_device_id tegra_pcie_of_match[] = { { .compatible = "nvidia,tegra20-pcie", .data = &tegra20_pcie }, { }, }; +MODULE_DEVICE_TABLE(of, tegra_pcie_of_match); static void *tegra_pcie_ports_seq_start(struct seq_file *s, loff_t *pos) { diff --git a/drivers/pci/controller/pcie-iproc-msi.c b/drivers/pci/controller/pcie-iproc-msi.c index eede4e8f3f75..81b4effeb130 100644 --- a/drivers/pci/controller/pcie-iproc-msi.c +++ b/drivers/pci/controller/pcie-iproc-msi.c @@ -171,7 +171,7 @@ static struct irq_chip iproc_msi_irq_chip = { static struct msi_domain_info iproc_msi_domain_info = { .flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | - MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX, + MSI_FLAG_PCI_MSIX, .chip = &iproc_msi_irq_chip, }; @@ -250,20 +250,23 @@ static int iproc_msi_irq_domain_alloc(struct irq_domain *domain, struct iproc_msi *msi = domain->host_data; int hwirq, i; + if (msi->nr_cpus > 1 && nr_irqs > 1) + return -EINVAL; + mutex_lock(&msi->bitmap_lock); - /* Allocate 'nr_cpus' number of MSI vectors each time */ - hwirq = bitmap_find_next_zero_area(msi->bitmap, msi->nr_msi_vecs, 0, - msi->nr_cpus, 0); - if (hwirq < msi->nr_msi_vecs) { - bitmap_set(msi->bitmap, hwirq, msi->nr_cpus); - } else { - mutex_unlock(&msi->bitmap_lock); - return -ENOSPC; - } + /* + * Allocate 'nr_irqs' multiplied by 'nr_cpus' number of MSI vectors + * each time + */ + hwirq = bitmap_find_free_region(msi->bitmap, msi->nr_msi_vecs, + order_base_2(msi->nr_cpus * nr_irqs)); mutex_unlock(&msi->bitmap_lock); + if (hwirq < 0) + return -ENOSPC; + for (i = 0; i < nr_irqs; i++) { irq_domain_set_info(domain, virq + i, hwirq + i, &iproc_msi_bottom_irq_chip, @@ -284,7 +287,8 @@ static void iproc_msi_irq_domain_free(struct irq_domain *domain, mutex_lock(&msi->bitmap_lock); hwirq = hwirq_to_canonical_hwirq(msi, data->hwirq); - bitmap_clear(msi->bitmap, hwirq, msi->nr_cpus); + bitmap_release_region(msi->bitmap, hwirq, + order_base_2(msi->nr_cpus * nr_irqs)); mutex_unlock(&msi->bitmap_lock); @@ -539,6 +543,9 @@ int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node) mutex_init(&msi->bitmap_lock); msi->nr_cpus = num_possible_cpus(); + if (msi->nr_cpus == 1) + iproc_msi_domain_info.flags |= MSI_FLAG_MULTI_PCI_MSI; + msi->nr_irqs = of_irq_count(node); if (!msi->nr_irqs) { dev_err(pcie->dev, "found no MSI GIC interrupt\n"); diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c index 23548b517e4b..9c10d87b6134 100644 --- a/drivers/pci/controller/pcie-mediatek.c +++ b/drivers/pci/controller/pcie-mediatek.c @@ -143,6 +143,7 @@ struct mtk_pcie_port; * struct mtk_pcie_soc - differentiate between host generations * @need_fix_class_id: whether this host's class ID needed to be fixed or not * @need_fix_device_id: whether this host's device ID needed to be fixed or not + * @no_msi: Bridge has no MSI support, and relies on an external block * @device_id: device ID which this host need to be fixed * @ops: pointer to configuration access functions * @startup: pointer to controller setting functions @@ -151,6 +152,7 @@ struct mtk_pcie_port; struct mtk_pcie_soc { bool need_fix_class_id; bool need_fix_device_id; + bool no_msi; unsigned int device_id; struct pci_ops *ops; int (*startup)(struct mtk_pcie_port *port); @@ -1087,6 +1089,7 @@ static int mtk_pcie_probe(struct platform_device *pdev) host->ops = pcie->soc->ops; host->sysdata = pcie; + host->msi_domain = pcie->soc->no_msi; err = pci_host_probe(host); if (err) @@ -1176,6 +1179,7 @@ static const struct dev_pm_ops mtk_pcie_pm_ops = { }; static const struct mtk_pcie_soc mtk_pcie_soc_v1 = { + .no_msi = true, .ops = &mtk_pcie_ops, .startup = mtk_pcie_startup_port, }; diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c index 2bee09b16255..062328054a9a 100644 --- a/drivers/pci/controller/pcie-rcar-host.c +++ b/drivers/pci/controller/pcie-rcar-host.c @@ -35,18 +35,12 @@ struct rcar_msi { DECLARE_BITMAP(used, INT_PCI_MSI_NR); struct irq_domain *domain; - struct msi_controller chip; - unsigned long pages; - struct mutex lock; + struct mutex map_lock; + spinlock_t mask_lock; int irq1; int irq2; }; -static inline struct rcar_msi *to_rcar_msi(struct msi_controller *chip) -{ - return container_of(chip, struct rcar_msi, chip); -} - /* Structure representing the PCIe interface */ struct rcar_pcie_host { struct rcar_pcie pcie; @@ -58,6 +52,11 @@ struct rcar_pcie_host { int (*phy_init_fn)(struct rcar_pcie_host *host); }; +static struct rcar_pcie_host *msi_to_host(struct rcar_msi *msi) +{ + return container_of(msi, struct rcar_pcie_host, msi); +} + static u32 rcar_read_conf(struct rcar_pcie *pcie, int where) { unsigned int shift = BITS_PER_BYTE * (where & 3); @@ -294,8 +293,6 @@ static int rcar_pcie_enable(struct rcar_pcie_host *host) bridge->sysdata = host; bridge->ops = &rcar_pcie_ops; - if (IS_ENABLED(CONFIG_PCI_MSI)) - bridge->msi = &host->msi.chip; return pci_host_probe(bridge); } @@ -475,42 +472,6 @@ static int rcar_pcie_phy_init_gen3(struct rcar_pcie_host *host) return err; } -static int rcar_msi_alloc(struct rcar_msi *chip) -{ - int msi; - - mutex_lock(&chip->lock); - - msi = find_first_zero_bit(chip->used, INT_PCI_MSI_NR); - if (msi < INT_PCI_MSI_NR) - set_bit(msi, chip->used); - else - msi = -ENOSPC; - - mutex_unlock(&chip->lock); - - return msi; -} - -static int rcar_msi_alloc_region(struct rcar_msi *chip, int no_irqs) -{ - int msi; - - mutex_lock(&chip->lock); - msi = bitmap_find_free_region(chip->used, INT_PCI_MSI_NR, - order_base_2(no_irqs)); - mutex_unlock(&chip->lock); - - return msi; -} - -static void rcar_msi_free(struct rcar_msi *chip, unsigned long irq) -{ - mutex_lock(&chip->lock); - clear_bit(irq, chip->used); - mutex_unlock(&chip->lock); -} - static irqreturn_t rcar_pcie_msi_irq(int irq, void *data) { struct rcar_pcie_host *host = data; @@ -529,18 +490,13 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data) unsigned int index = find_first_bit(®, 32); unsigned int msi_irq; - /* clear the interrupt */ - rcar_pci_write_reg(pcie, 1 << index, PCIEMSIFR); - - msi_irq = irq_find_mapping(msi->domain, index); + msi_irq = irq_find_mapping(msi->domain->parent, index); if (msi_irq) { - if (test_bit(index, msi->used)) - generic_handle_irq(msi_irq); - else - dev_info(dev, "unhandled MSI\n"); + generic_handle_irq(msi_irq); } else { /* Unknown MSI, just clear it */ dev_dbg(dev, "unexpected MSI\n"); + rcar_pci_write_reg(pcie, BIT(index), PCIEMSIFR); } /* see if there's any more pending in this vector */ @@ -550,149 +506,169 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data) return IRQ_HANDLED; } -static int rcar_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, - struct msi_desc *desc) +static void rcar_msi_top_irq_ack(struct irq_data *d) { - struct rcar_msi *msi = to_rcar_msi(chip); - struct rcar_pcie_host *host = container_of(chip, struct rcar_pcie_host, - msi.chip); - struct rcar_pcie *pcie = &host->pcie; - struct msi_msg msg; - unsigned int irq; - int hwirq; + irq_chip_ack_parent(d); +} - hwirq = rcar_msi_alloc(msi); - if (hwirq < 0) - return hwirq; +static void rcar_msi_top_irq_mask(struct irq_data *d) +{ + pci_msi_mask_irq(d); + irq_chip_mask_parent(d); +} - irq = irq_find_mapping(msi->domain, hwirq); - if (!irq) { - rcar_msi_free(msi, hwirq); - return -EINVAL; - } +static void rcar_msi_top_irq_unmask(struct irq_data *d) +{ + pci_msi_unmask_irq(d); + irq_chip_unmask_parent(d); +} - irq_set_msi_desc(irq, desc); +static struct irq_chip rcar_msi_top_chip = { + .name = "PCIe MSI", + .irq_ack = rcar_msi_top_irq_ack, + .irq_mask = rcar_msi_top_irq_mask, + .irq_unmask = rcar_msi_top_irq_unmask, +}; - msg.address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE; - msg.address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR); - msg.data = hwirq; +static void rcar_msi_irq_ack(struct irq_data *d) +{ + struct rcar_msi *msi = irq_data_get_irq_chip_data(d); + struct rcar_pcie *pcie = &msi_to_host(msi)->pcie; - pci_write_msi_msg(irq, &msg); + /* clear the interrupt */ + rcar_pci_write_reg(pcie, BIT(d->hwirq), PCIEMSIFR); +} - return 0; +static void rcar_msi_irq_mask(struct irq_data *d) +{ + struct rcar_msi *msi = irq_data_get_irq_chip_data(d); + struct rcar_pcie *pcie = &msi_to_host(msi)->pcie; + unsigned long flags; + u32 value; + + spin_lock_irqsave(&msi->mask_lock, flags); + value = rcar_pci_read_reg(pcie, PCIEMSIIER); + value &= ~BIT(d->hwirq); + rcar_pci_write_reg(pcie, value, PCIEMSIIER); + spin_unlock_irqrestore(&msi->mask_lock, flags); } -static int rcar_msi_setup_irqs(struct msi_controller *chip, - struct pci_dev *pdev, int nvec, int type) +static void rcar_msi_irq_unmask(struct irq_data *d) { - struct rcar_msi *msi = to_rcar_msi(chip); - struct rcar_pcie_host *host = container_of(chip, struct rcar_pcie_host, - msi.chip); - struct rcar_pcie *pcie = &host->pcie; - struct msi_desc *desc; - struct msi_msg msg; - unsigned int irq; - int hwirq; - int i; + struct rcar_msi *msi = irq_data_get_irq_chip_data(d); + struct rcar_pcie *pcie = &msi_to_host(msi)->pcie; + unsigned long flags; + u32 value; + + spin_lock_irqsave(&msi->mask_lock, flags); + value = rcar_pci_read_reg(pcie, PCIEMSIIER); + value |= BIT(d->hwirq); + rcar_pci_write_reg(pcie, value, PCIEMSIIER); + spin_unlock_irqrestore(&msi->mask_lock, flags); +} - /* MSI-X interrupts are not supported */ - if (type == PCI_CAP_ID_MSIX) - return -EINVAL; +static int rcar_msi_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force) +{ + return -EINVAL; +} - WARN_ON(!list_is_singular(&pdev->dev.msi_list)); - desc = list_entry(pdev->dev.msi_list.next, struct msi_desc, list); +static void rcar_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) +{ + struct rcar_msi *msi = irq_data_get_irq_chip_data(data); + struct rcar_pcie *pcie = &msi_to_host(msi)->pcie; - hwirq = rcar_msi_alloc_region(msi, nvec); - if (hwirq < 0) - return -ENOSPC; + msg->address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE; + msg->address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR); + msg->data = data->hwirq; +} - irq = irq_find_mapping(msi->domain, hwirq); - if (!irq) - return -ENOSPC; +static struct irq_chip rcar_msi_bottom_chip = { + .name = "Rcar MSI", + .irq_ack = rcar_msi_irq_ack, + .irq_mask = rcar_msi_irq_mask, + .irq_unmask = rcar_msi_irq_unmask, + .irq_set_affinity = rcar_msi_set_affinity, + .irq_compose_msi_msg = rcar_compose_msi_msg, +}; - for (i = 0; i < nvec; i++) { - /* - * irq_create_mapping() called from rcar_pcie_probe() pre- - * allocates descs, so there is no need to allocate descs here. - * We can therefore assume that if irq_find_mapping() above - * returns non-zero, then the descs are also successfully - * allocated. - */ - if (irq_set_msi_desc_off(irq, i, desc)) { - /* TODO: clear */ - return -EINVAL; - } - } +static int rcar_msi_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *args) +{ + struct rcar_msi *msi = domain->host_data; + unsigned int i; + int hwirq; - desc->nvec_used = nvec; - desc->msi_attrib.multiple = order_base_2(nvec); + mutex_lock(&msi->map_lock); - msg.address_lo = rcar_pci_read_reg(pcie, PCIEMSIALR) & ~MSIFE; - msg.address_hi = rcar_pci_read_reg(pcie, PCIEMSIAUR); - msg.data = hwirq; + hwirq = bitmap_find_free_region(msi->used, INT_PCI_MSI_NR, order_base_2(nr_irqs)); - pci_write_msi_msg(irq, &msg); + mutex_unlock(&msi->map_lock); + + if (hwirq < 0) + return -ENOSPC; + + for (i = 0; i < nr_irqs; i++) + irq_domain_set_info(domain, virq + i, hwirq + i, + &rcar_msi_bottom_chip, domain->host_data, + handle_edge_irq, NULL, NULL); return 0; } -static void rcar_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) +static void rcar_msi_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) { - struct rcar_msi *msi = to_rcar_msi(chip); - struct irq_data *d = irq_get_irq_data(irq); - - rcar_msi_free(msi, d->hwirq); -} + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct rcar_msi *msi = domain->host_data; -static struct irq_chip rcar_msi_irq_chip = { - .name = "R-Car PCIe MSI", - .irq_enable = pci_msi_unmask_irq, - .irq_disable = pci_msi_mask_irq, - .irq_mask = pci_msi_mask_irq, - .irq_unmask = pci_msi_unmask_irq, -}; + mutex_lock(&msi->map_lock); -static int rcar_msi_map(struct irq_domain *domain, unsigned int irq, - irq_hw_number_t hwirq) -{ - irq_set_chip_and_handler(irq, &rcar_msi_irq_chip, handle_simple_irq); - irq_set_chip_data(irq, domain->host_data); + bitmap_release_region(msi->used, d->hwirq, order_base_2(nr_irqs)); - return 0; + mutex_unlock(&msi->map_lock); } -static const struct irq_domain_ops msi_domain_ops = { - .map = rcar_msi_map, +static const struct irq_domain_ops rcar_msi_domain_ops = { + .alloc = rcar_msi_domain_alloc, + .free = rcar_msi_domain_free, +}; + +static struct msi_domain_info rcar_msi_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | + MSI_FLAG_MULTI_PCI_MSI), + .chip = &rcar_msi_top_chip, }; -static void rcar_pcie_unmap_msi(struct rcar_pcie_host *host) +static int rcar_allocate_domains(struct rcar_msi *msi) { - struct rcar_msi *msi = &host->msi; - int i, irq; + struct rcar_pcie *pcie = &msi_to_host(msi)->pcie; + struct fwnode_handle *fwnode = dev_fwnode(pcie->dev); + struct irq_domain *parent; + + parent = irq_domain_create_linear(fwnode, INT_PCI_MSI_NR, + &rcar_msi_domain_ops, msi); + if (!parent) { + dev_err(pcie->dev, "failed to create IRQ domain\n"); + return -ENOMEM; + } + irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS); - for (i = 0; i < INT_PCI_MSI_NR; i++) { - irq = irq_find_mapping(msi->domain, i); - if (irq > 0) - irq_dispose_mapping(irq); + msi->domain = pci_msi_create_irq_domain(fwnode, &rcar_msi_info, parent); + if (!msi->domain) { + dev_err(pcie->dev, "failed to create MSI domain\n"); + irq_domain_remove(parent); + return -ENOMEM; } - irq_domain_remove(msi->domain); + return 0; } -static void rcar_pcie_hw_enable_msi(struct rcar_pcie_host *host) +static void rcar_free_domains(struct rcar_msi *msi) { - struct rcar_pcie *pcie = &host->pcie; - struct rcar_msi *msi = &host->msi; - unsigned long base; - - /* setup MSI data target */ - base = virt_to_phys((void *)msi->pages); + struct irq_domain *parent = msi->domain->parent; - rcar_pci_write_reg(pcie, lower_32_bits(base) | MSIFE, PCIEMSIALR); - rcar_pci_write_reg(pcie, upper_32_bits(base), PCIEMSIAUR); - - /* enable all MSI interrupts */ - rcar_pci_write_reg(pcie, 0xffffffff, PCIEMSIIER); + irq_domain_remove(msi->domain); + irq_domain_remove(parent); } static int rcar_pcie_enable_msi(struct rcar_pcie_host *host) @@ -700,29 +676,24 @@ static int rcar_pcie_enable_msi(struct rcar_pcie_host *host) struct rcar_pcie *pcie = &host->pcie; struct device *dev = pcie->dev; struct rcar_msi *msi = &host->msi; - int err, i; - - mutex_init(&msi->lock); + struct resource res; + int err; - msi->chip.dev = dev; - msi->chip.setup_irq = rcar_msi_setup_irq; - msi->chip.setup_irqs = rcar_msi_setup_irqs; - msi->chip.teardown_irq = rcar_msi_teardown_irq; + mutex_init(&msi->map_lock); + spin_lock_init(&msi->mask_lock); - msi->domain = irq_domain_add_linear(dev->of_node, INT_PCI_MSI_NR, - &msi_domain_ops, &msi->chip); - if (!msi->domain) { - dev_err(dev, "failed to create IRQ domain\n"); - return -ENOMEM; - } + err = of_address_to_resource(dev->of_node, 0, &res); + if (err) + return err; - for (i = 0; i < INT_PCI_MSI_NR; i++) - irq_create_mapping(msi->domain, i); + err = rcar_allocate_domains(msi); + if (err) + return err; /* Two irqs are for MSI, but they are also used for non-MSI irqs */ err = devm_request_irq(dev, msi->irq1, rcar_pcie_msi_irq, IRQF_SHARED | IRQF_NO_THREAD, - rcar_msi_irq_chip.name, host); + rcar_msi_bottom_chip.name, host); if (err < 0) { dev_err(dev, "failed to request IRQ: %d\n", err); goto err; @@ -730,27 +701,32 @@ static int rcar_pcie_enable_msi(struct rcar_pcie_host *host) err = devm_request_irq(dev, msi->irq2, rcar_pcie_msi_irq, IRQF_SHARED | IRQF_NO_THREAD, - rcar_msi_irq_chip.name, host); + rcar_msi_bottom_chip.name, host); if (err < 0) { dev_err(dev, "failed to request IRQ: %d\n", err); goto err; } - /* setup MSI data target */ - msi->pages = __get_free_pages(GFP_KERNEL | GFP_DMA32, 0); - rcar_pcie_hw_enable_msi(host); + /* disable all MSIs */ + rcar_pci_write_reg(pcie, 0, PCIEMSIIER); + + /* + * Setup MSI data target using RC base address address, which + * is guaranteed to be in the low 32bit range on any RCar HW. + */ + rcar_pci_write_reg(pcie, lower_32_bits(res.start) | MSIFE, PCIEMSIALR); + rcar_pci_write_reg(pcie, upper_32_bits(res.start), PCIEMSIAUR); return 0; err: - rcar_pcie_unmap_msi(host); + rcar_free_domains(msi); return err; } static void rcar_pcie_teardown_msi(struct rcar_pcie_host *host) { struct rcar_pcie *pcie = &host->pcie; - struct rcar_msi *msi = &host->msi; /* Disable all MSI interrupts */ rcar_pci_write_reg(pcie, 0, PCIEMSIIER); @@ -758,9 +734,7 @@ static void rcar_pcie_teardown_msi(struct rcar_pcie_host *host) /* Disable address decoding of the MSI interrupt, MSIFE */ rcar_pci_write_reg(pcie, 0, PCIEMSIALR); - free_pages(msi->pages, 0); - - rcar_pcie_unmap_msi(host); + rcar_free_domains(&host->msi); } static int rcar_pcie_get_resources(struct rcar_pcie_host *host) @@ -1013,8 +987,17 @@ static int __maybe_unused rcar_pcie_resume(struct device *dev) dev_info(dev, "PCIe x%d: link up\n", (data >> 20) & 0x3f); /* Enable MSI */ - if (IS_ENABLED(CONFIG_PCI_MSI)) - rcar_pcie_hw_enable_msi(host); + if (IS_ENABLED(CONFIG_PCI_MSI)) { + struct resource res; + u32 val; + + of_address_to_resource(dev->of_node, 0, &res); + rcar_pci_write_reg(pcie, upper_32_bits(res.start), PCIEMSIAUR); + rcar_pci_write_reg(pcie, lower_32_bits(res.start) | MSIFE, PCIEMSIALR); + + bitmap_to_arr32(&val, host->msi.used, INT_PCI_MSI_NR); + rcar_pci_write_reg(pcie, val, PCIEMSIIER); + } rcar_pcie_hw_enable(host); diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c index 9705059523a6..0d6df73bb918 100644 --- a/drivers/pci/controller/pcie-rockchip-host.c +++ b/drivers/pci/controller/pcie-rockchip-host.c @@ -593,10 +593,6 @@ static int rockchip_pcie_parse_host_dt(struct rockchip_pcie *rockchip) if (err) return err; - err = rockchip_pcie_setup_irq(rockchip); - if (err) - return err; - rockchip->vpcie12v = devm_regulator_get_optional(dev, "vpcie12v"); if (IS_ERR(rockchip->vpcie12v)) { if (PTR_ERR(rockchip->vpcie12v) != -ENODEV) @@ -974,8 +970,6 @@ static int rockchip_pcie_probe(struct platform_device *pdev) if (err) goto err_vpcie; - rockchip_pcie_enable_interrupts(rockchip); - err = rockchip_pcie_init_irq_domain(rockchip); if (err < 0) goto err_deinit_port; @@ -993,6 +987,12 @@ static int rockchip_pcie_probe(struct platform_device *pdev) bridge->sysdata = rockchip; bridge->ops = &rockchip_pcie_ops; + err = rockchip_pcie_setup_irq(rockchip); + if (err) + goto err_remove_irq_domain; + + rockchip_pcie_enable_interrupts(rockchip); + err = pci_host_probe(bridge); if (err < 0) goto err_remove_irq_domain; diff --git a/drivers/pci/controller/pcie-xilinx.c b/drivers/pci/controller/pcie-xilinx.c index 8523be61bba5..d707edab6596 100644 --- a/drivers/pci/controller/pcie-xilinx.c +++ b/drivers/pci/controller/pcie-xilinx.c @@ -96,25 +96,23 @@ /** * struct xilinx_pcie_port - PCIe port information * @reg_base: IO Mapped Register Base - * @irq: Interrupt number - * @msi_pages: MSI pages * @dev: Device pointer + * @msi_map: Bitmap of allocated MSIs + * @map_lock: Mutex protecting the MSI allocation * @msi_domain: MSI IRQ domain pointer * @leg_domain: Legacy IRQ domain pointer * @resources: Bus Resources */ struct xilinx_pcie_port { void __iomem *reg_base; - u32 irq; - unsigned long msi_pages; struct device *dev; + unsigned long msi_map[BITS_TO_LONGS(XILINX_NUM_MSI_IRQS)]; + struct mutex map_lock; struct irq_domain *msi_domain; struct irq_domain *leg_domain; struct list_head resources; }; -static DECLARE_BITMAP(msi_irq_in_use, XILINX_NUM_MSI_IRQS); - static inline u32 pcie_read(struct xilinx_pcie_port *port, u32 reg) { return readl(port->reg_base + reg); @@ -203,151 +201,118 @@ static struct pci_ops xilinx_pcie_ops = { /* MSI functions */ -/** - * xilinx_pcie_destroy_msi - Free MSI number - * @irq: IRQ to be freed - */ -static void xilinx_pcie_destroy_msi(unsigned int irq) +static void xilinx_msi_top_irq_ack(struct irq_data *d) { - struct msi_desc *msi; - struct xilinx_pcie_port *port; - struct irq_data *d = irq_get_irq_data(irq); - irq_hw_number_t hwirq = irqd_to_hwirq(d); - - if (!test_bit(hwirq, msi_irq_in_use)) { - msi = irq_get_msi_desc(irq); - port = msi_desc_to_pci_sysdata(msi); - dev_err(port->dev, "Trying to free unused MSI#%d\n", irq); - } else { - clear_bit(hwirq, msi_irq_in_use); - } + /* + * xilinx_pcie_intr_handler() will have performed the Ack. + * Eventually, this should be fixed and the Ack be moved in + * the respective callbacks for INTx and MSI. + */ } -/** - * xilinx_pcie_assign_msi - Allocate MSI number - * - * Return: A valid IRQ on success and error value on failure. - */ -static int xilinx_pcie_assign_msi(void) -{ - int pos; - - pos = find_first_zero_bit(msi_irq_in_use, XILINX_NUM_MSI_IRQS); - if (pos < XILINX_NUM_MSI_IRQS) - set_bit(pos, msi_irq_in_use); - else - return -ENOSPC; +static struct irq_chip xilinx_msi_top_chip = { + .name = "PCIe MSI", + .irq_ack = xilinx_msi_top_irq_ack, +}; - return pos; +static int xilinx_msi_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force) +{ + return -EINVAL; } -/** - * xilinx_msi_teardown_irq - Destroy the MSI - * @chip: MSI Chip descriptor - * @irq: MSI IRQ to destroy - */ -static void xilinx_msi_teardown_irq(struct msi_controller *chip, - unsigned int irq) +static void xilinx_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) { - xilinx_pcie_destroy_msi(irq); - irq_dispose_mapping(irq); + struct xilinx_pcie_port *pcie = irq_data_get_irq_chip_data(data); + phys_addr_t pa = ALIGN_DOWN(virt_to_phys(pcie), SZ_4K); + + msg->address_lo = lower_32_bits(pa); + msg->address_hi = upper_32_bits(pa); + msg->data = data->hwirq; } -/** - * xilinx_pcie_msi_setup_irq - Setup MSI request - * @chip: MSI chip pointer - * @pdev: PCIe device pointer - * @desc: MSI descriptor pointer - * - * Return: '0' on success and error value on failure - */ -static int xilinx_pcie_msi_setup_irq(struct msi_controller *chip, - struct pci_dev *pdev, - struct msi_desc *desc) -{ - struct xilinx_pcie_port *port = pdev->bus->sysdata; - unsigned int irq; - int hwirq; - struct msi_msg msg; - phys_addr_t msg_addr; +static struct irq_chip xilinx_msi_bottom_chip = { + .name = "Xilinx MSI", + .irq_set_affinity = xilinx_msi_set_affinity, + .irq_compose_msi_msg = xilinx_compose_msi_msg, +}; - hwirq = xilinx_pcie_assign_msi(); - if (hwirq < 0) - return hwirq; +static int xilinx_msi_domain_alloc(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs, void *args) +{ + struct xilinx_pcie_port *port = domain->host_data; + int hwirq, i; - irq = irq_create_mapping(port->msi_domain, hwirq); - if (!irq) - return -EINVAL; + mutex_lock(&port->map_lock); - irq_set_msi_desc(irq, desc); + hwirq = bitmap_find_free_region(port->msi_map, XILINX_NUM_MSI_IRQS, order_base_2(nr_irqs)); - msg_addr = virt_to_phys((void *)port->msi_pages); + mutex_unlock(&port->map_lock); - msg.address_hi = 0; - msg.address_lo = msg_addr; - msg.data = irq; + if (hwirq < 0) + return -ENOSPC; - pci_write_msi_msg(irq, &msg); + for (i = 0; i < nr_irqs; i++) + irq_domain_set_info(domain, virq + i, hwirq + i, + &xilinx_msi_bottom_chip, domain->host_data, + handle_edge_irq, NULL, NULL); return 0; } -/* MSI Chip Descriptor */ -static struct msi_controller xilinx_pcie_msi_chip = { - .setup_irq = xilinx_pcie_msi_setup_irq, - .teardown_irq = xilinx_msi_teardown_irq, -}; +static void xilinx_msi_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct xilinx_pcie_port *port = domain->host_data; -/* HW Interrupt Chip Descriptor */ -static struct irq_chip xilinx_msi_irq_chip = { - .name = "Xilinx PCIe MSI", - .irq_enable = pci_msi_unmask_irq, - .irq_disable = pci_msi_mask_irq, - .irq_mask = pci_msi_mask_irq, - .irq_unmask = pci_msi_unmask_irq, -}; + mutex_lock(&port->map_lock); -/** - * xilinx_pcie_msi_map - Set the handler for the MSI and mark IRQ as valid - * @domain: IRQ domain - * @irq: Virtual IRQ number - * @hwirq: HW interrupt number - * - * Return: Always returns 0. - */ -static int xilinx_pcie_msi_map(struct irq_domain *domain, unsigned int irq, - irq_hw_number_t hwirq) -{ - irq_set_chip_and_handler(irq, &xilinx_msi_irq_chip, handle_simple_irq); - irq_set_chip_data(irq, domain->host_data); + bitmap_release_region(port->msi_map, d->hwirq, order_base_2(nr_irqs)); - return 0; + mutex_unlock(&port->map_lock); } -/* IRQ Domain operations */ -static const struct irq_domain_ops msi_domain_ops = { - .map = xilinx_pcie_msi_map, +static const struct irq_domain_ops xilinx_msi_domain_ops = { + .alloc = xilinx_msi_domain_alloc, + .free = xilinx_msi_domain_free, }; -/** - * xilinx_pcie_enable_msi - Enable MSI support - * @port: PCIe port information - */ -static int xilinx_pcie_enable_msi(struct xilinx_pcie_port *port) +static struct msi_domain_info xilinx_msi_info = { + .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS), + .chip = &xilinx_msi_top_chip, +}; + +static int xilinx_allocate_msi_domains(struct xilinx_pcie_port *pcie) { - phys_addr_t msg_addr; + struct fwnode_handle *fwnode = dev_fwnode(pcie->dev); + struct irq_domain *parent; - port->msi_pages = __get_free_pages(GFP_KERNEL, 0); - if (!port->msi_pages) + parent = irq_domain_create_linear(fwnode, XILINX_NUM_MSI_IRQS, + &xilinx_msi_domain_ops, pcie); + if (!parent) { + dev_err(pcie->dev, "failed to create IRQ domain\n"); return -ENOMEM; + } + irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS); - msg_addr = virt_to_phys((void *)port->msi_pages); - pcie_write(port, 0x0, XILINX_PCIE_REG_MSIBASE1); - pcie_write(port, msg_addr, XILINX_PCIE_REG_MSIBASE2); + pcie->msi_domain = pci_msi_create_irq_domain(fwnode, &xilinx_msi_info, parent); + if (!pcie->msi_domain) { + dev_err(pcie->dev, "failed to create MSI domain\n"); + irq_domain_remove(parent); + return -ENOMEM; + } return 0; } +static void xilinx_free_msi_domains(struct xilinx_pcie_port *pcie) +{ + struct irq_domain *parent = pcie->msi_domain->parent; + + irq_domain_remove(pcie->msi_domain); + irq_domain_remove(parent); +} + /* INTx Functions */ /** @@ -427,6 +392,8 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) } if (status & (XILINX_PCIE_INTR_INTX | XILINX_PCIE_INTR_MSI)) { + unsigned int irq; + val = pcie_read(port, XILINX_PCIE_REG_RPIFR1); /* Check whether interrupt valid */ @@ -439,20 +406,19 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) if (val & XILINX_PCIE_RPIFR1_MSI_INTR) { val = pcie_read(port, XILINX_PCIE_REG_RPIFR2) & XILINX_PCIE_RPIFR2_MSG_DATA; + irq = irq_find_mapping(port->msi_domain->parent, val); } else { val = (val & XILINX_PCIE_RPIFR1_INTR_MASK) >> XILINX_PCIE_RPIFR1_INTR_SHIFT; - val = irq_find_mapping(port->leg_domain, val); + irq = irq_find_mapping(port->leg_domain, val); } /* Clear interrupt FIFO register 1 */ pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK, XILINX_PCIE_REG_RPIFR1); - /* Handle the interrupt */ - if (IS_ENABLED(CONFIG_PCI_MSI) || - !(val & XILINX_PCIE_RPIFR1_MSI_INTR)) - generic_handle_irq(val); + if (irq) + generic_handle_irq(irq); } if (status & XILINX_PCIE_INTR_SLV_UNSUPP) @@ -498,12 +464,11 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) { struct device *dev = port->dev; - struct device_node *node = dev->of_node; struct device_node *pcie_intc_node; int ret; /* Setup INTx */ - pcie_intc_node = of_get_next_child(node, NULL); + pcie_intc_node = of_get_next_child(dev->of_node, NULL); if (!pcie_intc_node) { dev_err(dev, "No PCIe Intc node found\n"); return -ENODEV; @@ -520,18 +485,14 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port) /* Setup MSI */ if (IS_ENABLED(CONFIG_PCI_MSI)) { - port->msi_domain = irq_domain_add_linear(node, - XILINX_NUM_MSI_IRQS, - &msi_domain_ops, - &xilinx_pcie_msi_chip); - if (!port->msi_domain) { - dev_err(dev, "Failed to get a MSI IRQ domain\n"); - return -ENODEV; - } + phys_addr_t pa = ALIGN_DOWN(virt_to_phys(port), SZ_4K); - ret = xilinx_pcie_enable_msi(port); + ret = xilinx_allocate_msi_domains(port); if (ret) return ret; + + pcie_write(port, upper_32_bits(pa), XILINX_PCIE_REG_MSIBASE1); + pcie_write(port, lower_32_bits(pa), XILINX_PCIE_REG_MSIBASE2); } return 0; @@ -579,6 +540,7 @@ static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port) struct device *dev = port->dev; struct device_node *node = dev->of_node; struct resource regs; + unsigned int irq; int err; err = of_address_to_resource(node, 0, ®s); @@ -591,12 +553,12 @@ static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port) if (IS_ERR(port->reg_base)) return PTR_ERR(port->reg_base); - port->irq = irq_of_parse_and_map(node, 0); - err = devm_request_irq(dev, port->irq, xilinx_pcie_intr_handler, + irq = irq_of_parse_and_map(node, 0); + err = devm_request_irq(dev, irq, xilinx_pcie_intr_handler, IRQF_SHARED | IRQF_NO_THREAD, "xilinx-pcie", port); if (err) { - dev_err(dev, "unable to request irq %d\n", port->irq); + dev_err(dev, "unable to request irq %d\n", irq); return err; } @@ -624,7 +586,7 @@ static int xilinx_pcie_probe(struct platform_device *pdev) return -ENODEV; port = pci_host_bridge_priv(bridge); - + mutex_init(&port->map_lock); port->dev = dev; err = xilinx_pcie_parse_dt(port); @@ -644,11 +606,11 @@ static int xilinx_pcie_probe(struct platform_device *pdev) bridge->sysdata = port; bridge->ops = &xilinx_pcie_ops; -#ifdef CONFIG_PCI_MSI - xilinx_pcie_msi_chip.dev = dev; - bridge->msi = &xilinx_pcie_msi_chip; -#endif - return pci_host_probe(bridge); + err = pci_host_probe(bridge); + if (err) + xilinx_free_msi_domains(port); + + return err; } static const struct of_device_id xilinx_pcie_of_match[] = { diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index fb3840e222ad..9d06939736c0 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -563,6 +563,32 @@ void pciehp_power_off_slot(struct controller *ctrl) PCI_EXP_SLTCTL_PWR_OFF); } +static void pciehp_ignore_dpc_link_change(struct controller *ctrl, + struct pci_dev *pdev, int irq) +{ + /* + * Ignore link changes which occurred while waiting for DPC recovery. + * Could be several if DPC triggered multiple times consecutively. + */ + synchronize_hardirq(irq); + atomic_and(~PCI_EXP_SLTSTA_DLLSC, &ctrl->pending_events); + if (pciehp_poll_mode) + pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, + PCI_EXP_SLTSTA_DLLSC); + ctrl_info(ctrl, "Slot(%s): Link Down/Up ignored (recovered by DPC)\n", + slot_name(ctrl)); + + /* + * If the link is unexpectedly down after successful recovery, + * the corresponding link change may have been ignored above. + * Synthesize it to ensure that it is acted on. + */ + down_read(&ctrl->reset_lock); + if (!pciehp_check_link_active(ctrl)) + pciehp_request(ctrl, PCI_EXP_SLTSTA_DLLSC); + up_read(&ctrl->reset_lock); +} + static irqreturn_t pciehp_isr(int irq, void *dev_id) { struct controller *ctrl = (struct controller *)dev_id; @@ -706,6 +732,16 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) PCI_EXP_SLTCTL_ATTN_IND_ON); } + /* + * Ignore Link Down/Up events caused by Downstream Port Containment + * if recovery from the error succeeded. + */ + if ((events & PCI_EXP_SLTSTA_DLLSC) && pci_dpc_recovered(pdev) && + ctrl->state == ON_STATE) { + events &= ~PCI_EXP_SLTSTA_DLLSC; + pciehp_ignore_dpc_link_change(ctrl, pdev, irq); + } + /* * Disable requests have higher priority than Presence Detect Changed * or Data Link Layer State Changed events. diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index d52d118979a6..ac70851db7be 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -62,39 +62,18 @@ static void pci_msi_teardown_msi_irqs(struct pci_dev *dev) /* Arch hooks */ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) { - struct msi_controller *chip = dev->bus->msi; - int err; - - if (!chip || !chip->setup_irq) - return -EINVAL; - - err = chip->setup_irq(chip, dev, desc); - if (err < 0) - return err; - - irq_set_chip_data(desc->irq, chip); - - return 0; + return -EINVAL; } void __weak arch_teardown_msi_irq(unsigned int irq) { - struct msi_controller *chip = irq_get_chip_data(irq); - - if (!chip || !chip->teardown_irq) - return; - - chip->teardown_irq(chip, irq); } int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { - struct msi_controller *chip = dev->bus->msi; struct msi_desc *entry; int ret; - if (chip && chip->setup_irqs) - return chip->setup_irqs(chip, dev, nvec, type); /* * If an architecture wants to support multiple MSI, it needs to * override arch_setup_msi_irqs() @@ -113,11 +92,7 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) return 0; } -/* - * We have a default implementation available as a separate non-weak - * function, as it is used by the Xen x86 PCI code - */ -void default_teardown_msi_irqs(struct pci_dev *dev) +void __weak arch_teardown_msi_irqs(struct pci_dev *dev) { int i; struct msi_desc *entry; @@ -127,11 +102,6 @@ void default_teardown_msi_irqs(struct pci_dev *dev) for (i = 0; i < entry->nvec_used; i++) arch_teardown_msi_irq(entry->irq + i); } - -void __weak arch_teardown_msi_irqs(struct pci_dev *dev) -{ - return default_teardown_msi_irqs(dev); -} #endif /* CONFIG_PCI_MSI_ARCH_FALLBACKS */ static void default_restore_msi_irq(struct pci_dev *dev, int irq) @@ -171,24 +141,25 @@ static inline __attribute_const__ u32 msi_mask(unsigned x) * reliably as devices without an INTx disable bit will then generate a * level IRQ which will never be cleared. */ -u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) +void __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) { - u32 mask_bits = desc->masked; + raw_spinlock_t *lock = &desc->dev->msi_lock; + unsigned long flags; if (pci_msi_ignore_mask || !desc->msi_attrib.maskbit) - return 0; + return; - mask_bits &= ~mask; - mask_bits |= flag; + raw_spin_lock_irqsave(lock, flags); + desc->masked &= ~mask; + desc->masked |= flag; pci_write_config_dword(msi_desc_to_pci_dev(desc), desc->mask_pos, - mask_bits); - - return mask_bits; + desc->masked); + raw_spin_unlock_irqrestore(lock, flags); } static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag) { - desc->masked = __pci_msi_desc_mask_irq(desc, mask, flag); + __pci_msi_desc_mask_irq(desc, mask, flag); } static void __iomem *pci_msix_desc_addr(struct msi_desc *desc) @@ -317,13 +288,31 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) /* Don't touch the hardware now */ } else if (entry->msi_attrib.is_msix) { void __iomem *base = pci_msix_desc_addr(entry); + bool unmasked = !(entry->masked & PCI_MSIX_ENTRY_CTRL_MASKBIT); if (!base) goto skip; + /* + * The specification mandates that the entry is masked + * when the message is modified: + * + * "If software changes the Address or Data value of an + * entry while the entry is unmasked, the result is + * undefined." + */ + if (unmasked) + __pci_msix_desc_mask_irq(entry, PCI_MSIX_ENTRY_CTRL_MASKBIT); + writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR); writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR); writel(msg->data, base + PCI_MSIX_ENTRY_DATA); + + if (unmasked) + __pci_msix_desc_mask_irq(entry, 0); + + /* Ensure that the writes are visible in the device */ + readl(base + PCI_MSIX_ENTRY_DATA); } else { int pos = dev->msi_cap; u16 msgctl; @@ -344,6 +333,8 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg) pci_write_config_word(dev, pos + PCI_MSI_DATA_32, msg->data); } + /* Ensure that the writes are visible in the device */ + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); } skip: @@ -643,21 +634,21 @@ static int msi_capability_init(struct pci_dev *dev, int nvec, /* Configure MSI capability structure */ ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI); if (ret) { - msi_mask_irq(entry, mask, ~mask); + msi_mask_irq(entry, mask, 0); free_msi_irqs(dev); return ret; } ret = msi_verify_entries(dev); if (ret) { - msi_mask_irq(entry, mask, ~mask); + msi_mask_irq(entry, mask, 0); free_msi_irqs(dev); return ret; } ret = populate_msi_sysfs(dev); if (ret) { - msi_mask_irq(entry, mask, ~mask); + msi_mask_irq(entry, mask, 0); free_msi_irqs(dev); return ret; } @@ -698,6 +689,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, { struct irq_affinity_desc *curmsk, *masks = NULL; struct msi_desc *entry; + void __iomem *addr; int ret, i; int vec_count = pci_msix_vec_count(dev); @@ -718,6 +710,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, entry->msi_attrib.is_msix = 1; entry->msi_attrib.is_64 = 1; + if (entries) entry->msi_attrib.entry_nr = entries[i].entry; else @@ -729,6 +722,10 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, entry->msi_attrib.default_irq = dev->irq; entry->mask_base = base; + addr = pci_msix_desc_addr(entry); + if (addr) + entry->masked = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL); + list_add_tail(&entry->list, dev_to_msi_list(&dev->dev)); if (masks) curmsk++; @@ -739,26 +736,25 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base, return ret; } -static void msix_program_entries(struct pci_dev *dev, - struct msix_entry *entries) +static void msix_update_entries(struct pci_dev *dev, struct msix_entry *entries) { struct msi_desc *entry; - int i = 0; - void __iomem *desc_addr; for_each_pci_msi_entry(entry, dev) { - if (entries) - entries[i++].vector = entry->irq; + if (entries) { + entries->vector = entry->irq; + entries++; + } + } +} - desc_addr = pci_msix_desc_addr(entry); - if (desc_addr) - entry->masked = readl(desc_addr + - PCI_MSIX_ENTRY_VECTOR_CTRL); - else - entry->masked = 0; +static void msix_mask_all(void __iomem *base, int tsize) +{ + u32 ctrl = PCI_MSIX_ENTRY_CTRL_MASKBIT; + int i; - msix_mask_irq(entry, 1); - } + for (i = 0; i < tsize; i++, base += PCI_MSIX_ENTRY_SIZE) + writel(ctrl, base + PCI_MSIX_ENTRY_VECTOR_CTRL); } /** @@ -775,22 +771,33 @@ static void msix_program_entries(struct pci_dev *dev, static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec, struct irq_affinity *affd) { - int ret; - u16 control; void __iomem *base; + int ret, tsize; + u16 control; - /* Ensure MSI-X is disabled while it is set up */ - pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); + /* + * Some devices require MSI-X to be enabled before the MSI-X + * registers can be accessed. Mask all the vectors to prevent + * interrupts coming in before they're fully set up. + */ + pci_msix_clear_and_set_ctrl(dev, 0, PCI_MSIX_FLAGS_MASKALL | + PCI_MSIX_FLAGS_ENABLE); pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); /* Request & Map MSI-X table region */ - base = msix_map_region(dev, msix_table_size(control)); - if (!base) - return -ENOMEM; + tsize = msix_table_size(control); + base = msix_map_region(dev, tsize); + if (!base) { + ret = -ENOMEM; + goto out_disable; + } + + /* Ensure that all table entries are masked. */ + msix_mask_all(base, tsize); ret = msix_setup_entries(dev, base, entries, nvec, affd); if (ret) - return ret; + goto out_disable; ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX); if (ret) @@ -801,15 +808,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, if (ret) goto out_free; - /* - * Some devices require MSI-X to be enabled before we can touch the - * MSI-X registers. We need to mask all the vectors to prevent - * interrupts coming in before they're fully set up. - */ - pci_msix_clear_and_set_ctrl(dev, 0, - PCI_MSIX_FLAGS_MASKALL | PCI_MSIX_FLAGS_ENABLE); - - msix_program_entries(dev, entries); + msix_update_entries(dev, entries); ret = populate_msi_sysfs(dev); if (ret) @@ -843,6 +842,9 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, out_free: free_msi_irqs(dev); +out_disable: + pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); + return ret; } @@ -878,8 +880,15 @@ static int pci_msi_supported(struct pci_dev *dev, int nvec) * Any bridge which does NOT route MSI transactions from its * secondary bus to its primary bus must set NO_MSI flag on * the secondary pci_bus. - * We expect only arch-specific PCI host bus controller driver - * or quirks for specific PCI bridges to be setting NO_MSI. + * + * The NO_MSI flag can either be set directly by: + * - arch-specific PCI host bus controller drivers (deprecated) + * - quirks for specific PCI bridges + * + * or indirectly by platform-specific PCI host bridge drivers by + * advertising the 'msi_domain' property, which results in + * the NO_MSI flag when no MSI domain is found for this bridge + * at probe time. */ for (bus = dev->bus; bus; bus = bus->parent) if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) @@ -930,8 +939,7 @@ static void pci_msi_shutdown(struct pci_dev *dev) /* Return the device with MSI unmasked as initial states */ mask = msi_mask(desc->msi_attrib.multi_cap); - /* Keep cached state to be restored */ - __pci_msi_desc_mask_irq(desc, mask, ~mask); + msi_mask_irq(desc, mask, 0); /* Restore dev->irq to its default pin-assertion IRQ */ dev->irq = desc->msi_attrib.default_irq; @@ -1016,10 +1024,8 @@ static void pci_msix_shutdown(struct pci_dev *dev) } /* Return the device with MSI-X masked as initial states */ - for_each_pci_msi_entry(entry, dev) { - /* Keep cached states to be restored */ + for_each_pci_msi_entry(entry, dev) __pci_msix_desc_mask_irq(entry, 1); - } pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0); pci_intx_for_msi(dev, 1); diff --git a/drivers/pci/of.c b/drivers/pci/of.c index ac24cd5439a9..f70e9c64b37c 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -103,6 +103,13 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus) #endif } +bool pci_host_of_has_msi_map(struct device *dev) +{ + if (dev && dev->of_node) + return of_get_property(dev->of_node, "msi-map", NULL); + return false; +} + static inline int __of_pci_pci_compare(struct device_node *node, unsigned int data) { diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c index de1c331dbed4..f07c5dbc94e1 100644 --- a/drivers/pci/p2pdma.c +++ b/drivers/pci/p2pdma.c @@ -308,10 +308,41 @@ static const struct pci_p2pdma_whitelist_entry { {} }; +/* + * This lookup function tries to find the PCI device corresponding to a given + * host bridge. + * + * It assumes the host bridge device is the first PCI device in the + * bus->devices list and that the devfn is 00.0. These assumptions should hold + * for all the devices in the whitelist above. + * + * This function is equivalent to pci_get_slot(host->bus, 0), however it does + * not take the pci_bus_sem lock seeing __host_bridge_whitelist() must not + * sleep. + * + * For this to be safe, the caller should hold a reference to a device on the + * bridge, which should ensure the host_bridge device will not be freed + * or removed from the head of the devices list. + */ +static struct pci_dev *pci_host_bridge_dev(struct pci_host_bridge *host) +{ + struct pci_dev *root; + + root = list_first_entry_or_null(&host->bus->devices, + struct pci_dev, bus_list); + + if (!root) + return NULL; + if (root->devfn != PCI_DEVFN(0, 0)) + return NULL; + + return root; +} + static bool __host_bridge_whitelist(struct pci_host_bridge *host, bool same_host_bridge) { - struct pci_dev *root = pci_get_slot(host->bus, PCI_DEVFN(0, 0)); + struct pci_dev *root = pci_host_bridge_dev(host); const struct pci_p2pdma_whitelist_entry *entry; unsigned short vendor, device; @@ -320,7 +351,6 @@ static bool __host_bridge_whitelist(struct pci_host_bridge *host, vendor = root->vendor; device = root->device; - pci_dev_put(root); for (entry = pci_p2pdma_whitelist; entry->vendor; entry++) { if (vendor != entry->vendor || device != entry->device) diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index 781e45cf60d1..cd84cf52a92e 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c @@ -162,7 +162,7 @@ static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) len = utf16s_to_utf8s((const wchar_t *)obj->buffer.pointer, obj->buffer.length, UTF16_LITTLE_ENDIAN, - buf, PAGE_SIZE); + buf, PAGE_SIZE - 1); buf[len] = '\n'; } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e5c3fb43a791..089d2bcf0476 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1881,11 +1881,21 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) int err; int i, bars = 0; - if (atomic_inc_return(&dev->enable_cnt) > 1) { - pci_update_current_state(dev, dev->current_state); - return 0; /* already enabled */ + /* + * Power state could be unknown at this point, either due to a fresh + * boot or a device removal call. So get the current power state + * so that things like MSI message writing will behave as expected + * (e.g. if the device really is in D0 at enable time). + */ + if (dev->pm_cap) { + u16 pmcsr; + pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); + dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); } + if (atomic_inc_return(&dev->enable_cnt) > 1) + return 0; /* already enabled */ + bridge = pci_upstream_bridge(dev); if (bridge) pci_enable_bridge(bridge); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 0d1bc736e6c5..197075f71fd6 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -415,6 +415,8 @@ static inline bool pci_dev_is_disconnected(const struct pci_dev *dev) /* pci_dev priv_flags */ #define PCI_DEV_ADDED 0 +#define PCI_DPC_RECOVERED 1 +#define PCI_DPC_RECOVERING 2 static inline void pci_dev_assign_added(struct pci_dev *dev, bool added) { @@ -460,10 +462,12 @@ void pci_restore_dpc_state(struct pci_dev *dev); void pci_dpc_init(struct pci_dev *pdev); void dpc_process_error(struct pci_dev *pdev); pci_ers_result_t dpc_reset_link(struct pci_dev *pdev); +bool pci_dpc_recovered(struct pci_dev *pdev); #else static inline void pci_save_dpc_state(struct pci_dev *dev) {} static inline void pci_restore_dpc_state(struct pci_dev *dev) {} static inline void pci_dpc_init(struct pci_dev *pdev) {} +static inline bool pci_dpc_recovered(struct pci_dev *pdev) { return false; } #endif #ifdef CONFIG_PCI_ATS diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c index e05aba86a317..c556e7beafe3 100644 --- a/drivers/pci/pcie/dpc.c +++ b/drivers/pci/pcie/dpc.c @@ -71,6 +71,58 @@ void pci_restore_dpc_state(struct pci_dev *dev) pci_write_config_word(dev, dev->dpc_cap + PCI_EXP_DPC_CTL, *cap); } +static DECLARE_WAIT_QUEUE_HEAD(dpc_completed_waitqueue); + +#ifdef CONFIG_HOTPLUG_PCI_PCIE +static bool dpc_completed(struct pci_dev *pdev) +{ + u16 status; + + pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_STATUS, &status); + if ((status != 0xffff) && (status & PCI_EXP_DPC_STATUS_TRIGGER)) + return false; + + if (test_bit(PCI_DPC_RECOVERING, &pdev->priv_flags)) + return false; + + return true; +} + +/** + * pci_dpc_recovered - whether DPC triggered and has recovered successfully + * @pdev: PCI device + * + * Return true if DPC was triggered for @pdev and has recovered successfully. + * Wait for recovery if it hasn't completed yet. Called from the PCIe hotplug + * driver to recognize and ignore Link Down/Up events caused by DPC. + */ +bool pci_dpc_recovered(struct pci_dev *pdev) +{ + struct pci_host_bridge *host; + + if (!pdev->dpc_cap) + return false; + + /* + * Synchronization between hotplug and DPC is not supported + * if DPC is owned by firmware and EDR is not enabled. + */ + host = pci_find_host_bridge(pdev->bus); + if (!host->native_dpc && !IS_ENABLED(CONFIG_PCIE_EDR)) + return false; + + /* + * Need a timeout in case DPC never completes due to failure of + * dpc_wait_rp_inactive(). The spec doesn't mandate a time limit, + * but reports indicate that DPC completes within 4 seconds. + */ + wait_event_timeout(dpc_completed_waitqueue, dpc_completed(pdev), + msecs_to_jiffies(4000)); + + return test_and_clear_bit(PCI_DPC_RECOVERED, &pdev->priv_flags); +} +#endif /* CONFIG_HOTPLUG_PCI_PCIE */ + static int dpc_wait_rp_inactive(struct pci_dev *pdev) { unsigned long timeout = jiffies + HZ; @@ -91,8 +143,11 @@ static int dpc_wait_rp_inactive(struct pci_dev *pdev) pci_ers_result_t dpc_reset_link(struct pci_dev *pdev) { + pci_ers_result_t ret; u16 cap; + set_bit(PCI_DPC_RECOVERING, &pdev->priv_flags); + /* * DPC disables the Link automatically in hardware, so it has * already been reset by the time we get here. @@ -106,18 +161,27 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev) if (!pcie_wait_for_link(pdev, false)) pci_info(pdev, "Data Link Layer Link Active not cleared in 1000 msec\n"); - if (pdev->dpc_rp_extensions && dpc_wait_rp_inactive(pdev)) - return PCI_ERS_RESULT_DISCONNECT; + if (pdev->dpc_rp_extensions && dpc_wait_rp_inactive(pdev)) { + clear_bit(PCI_DPC_RECOVERED, &pdev->priv_flags); + ret = PCI_ERS_RESULT_DISCONNECT; + goto out; + } pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS, PCI_EXP_DPC_STATUS_TRIGGER); if (!pcie_wait_for_link(pdev, true)) { pci_info(pdev, "Data Link Layer Link Active not set in 1000 msec\n"); - return PCI_ERS_RESULT_DISCONNECT; + clear_bit(PCI_DPC_RECOVERED, &pdev->priv_flags); + ret = PCI_ERS_RESULT_DISCONNECT; + } else { + set_bit(PCI_DPC_RECOVERED, &pdev->priv_flags); + ret = PCI_ERS_RESULT_RECOVERED; } - - return PCI_ERS_RESULT_RECOVERED; +out: + clear_bit(PCI_DPC_RECOVERING, &pdev->priv_flags); + wake_up_all(&dpc_completed_waitqueue); + return ret; } static void dpc_process_rp_pio_error(struct pci_dev *pdev) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index ece90a23936d..a2a0ef497fa7 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -894,7 +894,6 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge) /* Temporarily move resources off the list */ list_splice_init(&bridge->windows, &resources); bus->sysdata = bridge->sysdata; - bus->msi = bridge->msi; bus->ops = bridge->ops; bus->number = bus->busn_res.start = bridge->busnr; #ifdef CONFIG_PCI_DOMAINS_GENERIC @@ -925,6 +924,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge) device_enable_async_suspend(bus->bridge); pci_set_bus_of_node(bus); pci_set_bus_msi_domain(bus); + if (bridge->msi_domain && !dev_get_msi_domain(&bus->dev) && + !pci_host_of_has_msi_map(parent)) + bus->bus_flags |= PCI_BUS_FLAGS_NO_MSI; if (!parent) set_dev_node(bus->bridge, pcibus_to_node(bus)); @@ -1052,7 +1054,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, return NULL; child->parent = parent; - child->msi = parent->msi; child->sysdata = parent->sysdata; child->bus_flags = parent->bus_flags; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index b570f297e3ec..d20d250b50aa 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include /* isa_dma_bridge_buggy */ #include "pci.h" @@ -1904,6 +1905,7 @@ static void quirk_ryzen_xhci_d3hot(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e0, quirk_ryzen_xhci_d3hot); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15e1, quirk_ryzen_xhci_d3hot); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1639, quirk_ryzen_xhci_d3hot); #ifdef CONFIG_X86_IO_APIC static int dmi_disable_ioapicreroute(const struct dmi_system_id *d) @@ -2584,10 +2586,8 @@ static int msi_ht_cap_enabled(struct pci_dev *dev) /* Check the HyperTransport MSI mapping to know whether MSI is enabled or not */ static void quirk_msi_ht_cap(struct pci_dev *dev) { - if (dev->subordinate && !msi_ht_cap_enabled(dev)) { - pci_warn(dev, "MSI quirk detected; subordinate MSI disabled\n"); - dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; - } + if (!msi_ht_cap_enabled(dev)) + quirk_disable_msi(dev); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, quirk_msi_ht_cap); @@ -2600,9 +2600,6 @@ static void quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) { struct pci_dev *pdev; - if (!dev->subordinate) - return; - /* * Check HT MSI cap on this chipset and the root one. A single one * having MSI is enough to be sure that MSI is supported. @@ -2610,10 +2607,8 @@ static void quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev) pdev = pci_get_slot(dev->bus, 0); if (!pdev) return; - if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) { - pci_warn(dev, "MSI quirk detected; subordinate MSI disabled\n"); - dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI; - } + if (!msi_ht_cap_enabled(pdev)) + quirk_msi_ht_cap(dev); pci_dev_put(pdev); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, @@ -3557,6 +3552,18 @@ static void quirk_no_bus_reset(struct pci_dev *dev) dev->dev_flags |= PCI_DEV_FLAGS_NO_BUS_RESET; } +/* + * Some NVIDIA GPU devices do not work with bus reset, SBR needs to be + * prevented for those affected devices. + */ +static void quirk_nvidia_no_bus_reset(struct pci_dev *dev) +{ + if ((dev->device & 0xffc0) == 0x2340) + quirk_no_bus_reset(dev); +} +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, + quirk_nvidia_no_bus_reset); + /* * Some Atheros AR9xxx and QCA988x chips do not behave after a bus reset. * The device will throw a Link Down error on AER-capable systems and @@ -3577,6 +3584,16 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0034, quirk_no_bus_reset); */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CAVIUM, 0xa100, quirk_no_bus_reset); +/* + * Some TI KeyStone C667X devices do not support bus/hot reset. The PCIESS + * automatically disables LTSSM when Secondary Bus Reset is received and + * the device stops working. Prevent bus reset for these devices. With + * this change, the device can be assigned to VMs with VFIO, but it will + * leak state between VMs. Reference + * https://e2e.ti.com/support/processors/f/791/t/954382 + */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0xb005, quirk_no_bus_reset); + static void quirk_no_pm_reset(struct pci_dev *dev) { /* @@ -3645,6 +3662,16 @@ static void quirk_apple_poweroff_thunderbolt(struct pci_dev *dev) return; if (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) return; + + /* + * SXIO/SXFP/SXLF turns off power to the Thunderbolt controller. + * We don't know how to turn it back on again, but firmware does, + * so we can only use SXIO/SXFP/SXLF if we're suspending via + * firmware. + */ + if (!pm_suspend_via_firmware()) + return; + bridge = ACPI_HANDLE(&dev->dev); if (!bridge) return; @@ -3912,6 +3939,69 @@ static int delay_250ms_after_flr(struct pci_dev *dev, int probe) return 0; } +#define PCI_DEVICE_ID_HINIC_VF 0x375E +#define HINIC_VF_FLR_TYPE 0x1000 +#define HINIC_VF_FLR_CAP_BIT (1UL << 30) +#define HINIC_VF_OP 0xE80 +#define HINIC_VF_FLR_PROC_BIT (1UL << 18) +#define HINIC_OPERATION_TIMEOUT 15000 /* 15 seconds */ + +/* Device-specific reset method for Huawei Intelligent NIC virtual functions */ +static int reset_hinic_vf_dev(struct pci_dev *pdev, int probe) +{ + unsigned long timeout; + void __iomem *bar; + u32 val; + + if (probe) + return 0; + + bar = pci_iomap(pdev, 0, 0); + if (!bar) + return -ENOTTY; + + /* Get and check firmware capabilities */ + val = ioread32be(bar + HINIC_VF_FLR_TYPE); + if (!(val & HINIC_VF_FLR_CAP_BIT)) { + pci_iounmap(pdev, bar); + return -ENOTTY; + } + + /* Set HINIC_VF_FLR_PROC_BIT for the start of FLR */ + val = ioread32be(bar + HINIC_VF_OP); + val = val | HINIC_VF_FLR_PROC_BIT; + iowrite32be(val, bar + HINIC_VF_OP); + + pcie_flr(pdev); + + /* + * The device must recapture its Bus and Device Numbers after FLR + * in order generate Completions. Issue a config write to let the + * device capture this information. + */ + pci_write_config_word(pdev, PCI_VENDOR_ID, 0); + + /* Firmware clears HINIC_VF_FLR_PROC_BIT when reset is complete */ + timeout = jiffies + msecs_to_jiffies(HINIC_OPERATION_TIMEOUT); + do { + val = ioread32be(bar + HINIC_VF_OP); + if (!(val & HINIC_VF_FLR_PROC_BIT)) + goto reset_complete; + msleep(20); + } while (time_before(jiffies, timeout)); + + val = ioread32be(bar + HINIC_VF_OP); + if (!(val & HINIC_VF_FLR_PROC_BIT)) + goto reset_complete; + + pci_warn(pdev, "Reset dev timeout, FLR ack reg: %#010x\n", val); + +reset_complete: + pci_iounmap(pdev, bar); + + return 0; +} + static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, reset_intel_82599_sfp_virtfn }, @@ -3923,6 +4013,8 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { { PCI_VENDOR_ID_INTEL, 0x0953, delay_250ms_after_flr }, { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID, reset_chelsio_generic_dev }, + { PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HINIC_VF, + reset_hinic_vf_dev }, { 0 } }; @@ -4763,6 +4855,8 @@ static const struct pci_dev_acs_enabled { { PCI_VENDOR_ID_AMPERE, 0xE00A, pci_quirk_xgene_acs }, { PCI_VENDOR_ID_AMPERE, 0xE00B, pci_quirk_xgene_acs }, { PCI_VENDOR_ID_AMPERE, 0xE00C, pci_quirk_xgene_acs }, + /* Broadcom multi-function device */ + { PCI_VENDOR_ID_BROADCOM, 0x16D7, pci_quirk_mf_endpoint_acs }, { PCI_VENDOR_ID_BROADCOM, 0xD714, pci_quirk_brcm_acs }, /* Amazon Annapurna Labs */ { PCI_VENDOR_ID_AMAZON_ANNAPURNA_LABS, 0x0031, pci_quirk_al_acs }, @@ -5164,7 +5258,8 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0422, quirk_no_ext_tags); static void quirk_amd_harvest_no_ats(struct pci_dev *pdev) { if ((pdev->device == 0x7312 && pdev->revision != 0x00) || - (pdev->device == 0x7340 && pdev->revision != 0xc5)) + (pdev->device == 0x7340 && pdev->revision != 0xc5) || + (pdev->device == 0x7341 && pdev->revision != 0x00)) return; pci_info(pdev, "disabling ATS\n"); @@ -5179,6 +5274,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x6900, quirk_amd_harvest_no_ats); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7312, quirk_amd_harvest_no_ats); /* AMD Navi14 dGPU */ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7340, quirk_amd_harvest_no_ats); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x7341, quirk_amd_harvest_no_ats); #endif /* CONFIG_PCI_ATS */ /* Freescale PCIe doesn't support MSI in RC mode */ diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index c6fe0cfec0f6..0bc4d4ba0c5f 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -693,7 +693,7 @@ static int pcifront_connect_and_init_dma(struct pcifront_device *pdev) spin_unlock(&pcifront_dev_lock); - if (!err && !swiotlb_nr_tbl()) { + if (!err && !is_swiotlb_active(&pdev->xdev->dev)) { err = pci_xen_swiotlb_init_late(); if (err) dev_err(&pdev->xdev->dev, "Could not setup SWIOTLB!\n"); diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 85887d885b5f..192c9049d654 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -112,6 +112,7 @@ static int i82092aa_pci_probe(struct pci_dev *dev, for (i = 0; i < socket_count; i++) { sockets[i].card_state = 1; /* 1 = present but empty */ sockets[i].io_base = pci_resource_start(dev, 0); + sockets[i].dev = dev; sockets[i].socket.features |= SS_CAP_PCCARD; sockets[i].socket.map_size = 0x1000; sockets[i].socket.irq_mask = 0; diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index 46defb1dcf86..bb019e383988 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -1212,7 +1212,7 @@ static int arm_cmn_init_irqs(struct arm_cmn *cmn) irq = cmn->dtc[i].irq; for (j = i; j--; ) { if (cmn->dtc[j].irq == irq) { - cmn->dtc[j].irq_friend = j - i; + cmn->dtc[j].irq_friend = i - j; goto next; } } diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c index 5274f7fe359e..afa8efbdad8f 100644 --- a/drivers/perf/arm_smmuv3_pmu.c +++ b/drivers/perf/arm_smmuv3_pmu.c @@ -275,7 +275,7 @@ static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu, struct perf_event *event, int idx) { u32 span, sid; - unsigned int num_ctrs = smmu_pmu->num_counters; + unsigned int cur_idx, num_ctrs = smmu_pmu->num_counters; bool filter_en = !!get_filter_enable(event); span = filter_en ? get_filter_span(event) : @@ -283,17 +283,19 @@ static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu, sid = filter_en ? get_filter_stream_id(event) : SMMU_PMCG_DEFAULT_FILTER_SID; - /* Support individual filter settings */ - if (!smmu_pmu->global_filter) { + cur_idx = find_first_bit(smmu_pmu->used_counters, num_ctrs); + /* + * Per-counter filtering, or scheduling the first globally-filtered + * event into an empty PMU so idx == 0 and it works out equivalent. + */ + if (!smmu_pmu->global_filter || cur_idx == num_ctrs) { smmu_pmu_set_event_filter(event, idx, span, sid); return 0; } - /* Requested settings same as current global settings*/ - idx = find_first_bit(smmu_pmu->used_counters, num_ctrs); - if (idx == num_ctrs || - smmu_pmu_check_global_filter(smmu_pmu->events[idx], event)) { - smmu_pmu_set_event_filter(event, 0, span, sid); + /* Otherwise, must match whatever's currently scheduled */ + if (smmu_pmu_check_global_filter(smmu_pmu->events[cur_idx], event)) { + smmu_pmu_set_evtyper(smmu_pmu, idx, get_event(event)); return 0; } diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c index 397540a4b799..7f7bc0993670 100644 --- a/drivers/perf/fsl_imx8_ddr_perf.c +++ b/drivers/perf/fsl_imx8_ddr_perf.c @@ -623,8 +623,10 @@ static int ddr_perf_probe(struct platform_device *pdev) name = devm_kasprintf(&pdev->dev, GFP_KERNEL, DDR_PERF_DEV_NAME "%d", num); - if (!name) - return -ENOMEM; + if (!name) { + ret = -ENOMEM; + goto cpuhp_state_err; + } pmu->devtype_data = of_device_get_match_data(&pdev->dev); diff --git a/drivers/phy/broadcom/phy-brcm-usb-init.h b/drivers/phy/broadcom/phy-brcm-usb-init.h index 899b9eb43fad..a39f30fa2e99 100644 --- a/drivers/phy/broadcom/phy-brcm-usb-init.h +++ b/drivers/phy/broadcom/phy-brcm-usb-init.h @@ -78,7 +78,7 @@ static inline u32 brcm_usb_readl(void __iomem *addr) * Other architectures (e.g., ARM) either do not support big endian, or * else leave I/O in little endian mode. */ - if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN)) + if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) return __raw_readl(addr); else return readl_relaxed(addr); @@ -87,7 +87,7 @@ static inline u32 brcm_usb_readl(void __iomem *addr) static inline void brcm_usb_writel(u32 val, void __iomem *addr) { /* See brcmnand_readl() comments */ - if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN)) + if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) __raw_writel(val, addr); else writel_relaxed(val, addr); diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c index aaa0bbe473f7..7d990613ce83 100644 --- a/drivers/phy/cadence/phy-cadence-sierra.c +++ b/drivers/phy/cadence/phy-cadence-sierra.c @@ -614,6 +614,7 @@ static int cdns_sierra_phy_probe(struct platform_device *pdev) sp->nsubnodes = node; if (sp->num_lanes > SIERRA_MAX_LANES) { + ret = -EINVAL; dev_err(dev, "Invalid lane configuration\n"); goto put_child2; } diff --git a/drivers/phy/intel/phy-intel-keembay-emmc.c b/drivers/phy/intel/phy-intel-keembay-emmc.c index eb7c635ed89a..0eb11ac7c2e2 100644 --- a/drivers/phy/intel/phy-intel-keembay-emmc.c +++ b/drivers/phy/intel/phy-intel-keembay-emmc.c @@ -95,7 +95,8 @@ static int keembay_emmc_phy_power(struct phy *phy, bool on_off) else freqsel = 0x0; - if (mhz < 50 || mhz > 200) + /* Check for EMMC clock rate*/ + if (mhz > 175) dev_warn(&phy->dev, "Unsupported rate: %d MHz\n", mhz); /* diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c index cdbcc49f7115..731c483a04de 100644 --- a/drivers/phy/mediatek/phy-mtk-tphy.c +++ b/drivers/phy/mediatek/phy-mtk-tphy.c @@ -949,6 +949,8 @@ static int mtk_phy_init(struct phy *phy) break; default: dev_err(tphy->dev, "incompatible PHY type\n"); + clk_disable_unprepare(instance->ref_clk); + clk_disable_unprepare(instance->da_ref_clk); return -EINVAL; } diff --git a/drivers/phy/socionext/phy-uniphier-pcie.c b/drivers/phy/socionext/phy-uniphier-pcie.c index e4adab375c73..6bdbd1f214dd 100644 --- a/drivers/phy/socionext/phy-uniphier-pcie.c +++ b/drivers/phy/socionext/phy-uniphier-pcie.c @@ -24,11 +24,13 @@ #define PORT_SEL_1 FIELD_PREP(PORT_SEL_MASK, 1) #define PCL_PHY_TEST_I 0x2000 -#define PCL_PHY_TEST_O 0x2004 #define TESTI_DAT_MASK GENMASK(13, 6) #define TESTI_ADR_MASK GENMASK(5, 1) #define TESTI_WR_EN BIT(0) +#define PCL_PHY_TEST_O 0x2004 +#define TESTO_DAT_MASK GENMASK(7, 0) + #define PCL_PHY_RESET 0x200c #define PCL_PHY_RESET_N_MNMODE BIT(8) /* =1:manual */ #define PCL_PHY_RESET_N BIT(0) /* =1:deasssert */ @@ -77,11 +79,12 @@ static void uniphier_pciephy_set_param(struct uniphier_pciephy_priv *priv, val = FIELD_PREP(TESTI_DAT_MASK, 1); val |= FIELD_PREP(TESTI_ADR_MASK, reg); uniphier_pciephy_testio_write(priv, val); - val = readl(priv->base + PCL_PHY_TEST_O); + val = readl(priv->base + PCL_PHY_TEST_O) & TESTO_DAT_MASK; /* update value */ - val &= ~FIELD_PREP(TESTI_DAT_MASK, mask); - val = FIELD_PREP(TESTI_DAT_MASK, mask & param); + val &= ~mask; + val |= mask & param; + val = FIELD_PREP(TESTI_DAT_MASK, val); val |= FIELD_PREP(TESTI_ADR_MASK, reg); uniphier_pciephy_testio_write(priv, val); uniphier_pciephy_testio_write(priv, val | TESTI_WR_EN); diff --git a/drivers/phy/ti/phy-dm816x-usb.c b/drivers/phy/ti/phy-dm816x-usb.c index 57adc08a89b2..9fe6ea6fdae5 100644 --- a/drivers/phy/ti/phy-dm816x-usb.c +++ b/drivers/phy/ti/phy-dm816x-usb.c @@ -242,19 +242,28 @@ static int dm816x_usb_phy_probe(struct platform_device *pdev) pm_runtime_enable(phy->dev); generic_phy = devm_phy_create(phy->dev, NULL, &ops); - if (IS_ERR(generic_phy)) - return PTR_ERR(generic_phy); + if (IS_ERR(generic_phy)) { + error = PTR_ERR(generic_phy); + goto clk_unprepare; + } phy_set_drvdata(generic_phy, phy); phy_provider = devm_of_phy_provider_register(phy->dev, of_phy_simple_xlate); - if (IS_ERR(phy_provider)) - return PTR_ERR(phy_provider); + if (IS_ERR(phy_provider)) { + error = PTR_ERR(phy_provider); + goto clk_unprepare; + } usb_add_phy_dev(&phy->phy); return 0; + +clk_unprepare: + pm_runtime_disable(phy->dev); + clk_unprepare(phy->refclk); + return error; } static int dm816x_usb_phy_remove(struct platform_device *pdev) diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index e28e25f98708..dceac7714872 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -894,6 +894,7 @@ static int wiz_probe(struct platform_device *pdev) if (wiz->typec_dir_delay < WIZ_TYPEC_DIR_DEBOUNCE_MIN || wiz->typec_dir_delay > WIZ_TYPEC_DIR_DEBOUNCE_MAX) { + ret = -EINVAL; dev_err(dev, "Invalid typec-dir-debounce property\n"); goto err_addr_to_resource; } diff --git a/drivers/pinctrl/intel/pinctrl-tigerlake.c b/drivers/pinctrl/intel/pinctrl-tigerlake.c index 3e354e02f408..bed769d99b8b 100644 --- a/drivers/pinctrl/intel/pinctrl-tigerlake.c +++ b/drivers/pinctrl/intel/pinctrl-tigerlake.c @@ -701,32 +701,32 @@ static const struct pinctrl_pin_desc tglh_pins[] = { static const struct intel_padgroup tglh_community0_gpps[] = { TGL_GPP(0, 0, 24, 0), /* GPP_A */ - TGL_GPP(1, 25, 44, 128), /* GPP_R */ - TGL_GPP(2, 45, 70, 32), /* GPP_B */ - TGL_GPP(3, 71, 78, INTEL_GPIO_BASE_NOMAP), /* vGPIO_0 */ + TGL_GPP(1, 25, 44, 32), /* GPP_R */ + TGL_GPP(2, 45, 70, 64), /* GPP_B */ + TGL_GPP(3, 71, 78, 96), /* vGPIO_0 */ }; static const struct intel_padgroup tglh_community1_gpps[] = { - TGL_GPP(0, 79, 104, 96), /* GPP_D */ - TGL_GPP(1, 105, 128, 64), /* GPP_C */ - TGL_GPP(2, 129, 136, 160), /* GPP_S */ - TGL_GPP(3, 137, 153, 192), /* GPP_G */ - TGL_GPP(4, 154, 180, 224), /* vGPIO */ + TGL_GPP(0, 79, 104, 128), /* GPP_D */ + TGL_GPP(1, 105, 128, 160), /* GPP_C */ + TGL_GPP(2, 129, 136, 192), /* GPP_S */ + TGL_GPP(3, 137, 153, 224), /* GPP_G */ + TGL_GPP(4, 154, 180, 256), /* vGPIO */ }; static const struct intel_padgroup tglh_community3_gpps[] = { - TGL_GPP(0, 181, 193, 256), /* GPP_E */ - TGL_GPP(1, 194, 217, 288), /* GPP_F */ + TGL_GPP(0, 181, 193, 288), /* GPP_E */ + TGL_GPP(1, 194, 217, 320), /* GPP_F */ }; static const struct intel_padgroup tglh_community4_gpps[] = { - TGL_GPP(0, 218, 241, 320), /* GPP_H */ + TGL_GPP(0, 218, 241, 352), /* GPP_H */ TGL_GPP(1, 242, 251, 384), /* GPP_J */ - TGL_GPP(2, 252, 266, 352), /* GPP_K */ + TGL_GPP(2, 252, 266, 416), /* GPP_K */ }; static const struct intel_padgroup tglh_community5_gpps[] = { - TGL_GPP(0, 267, 281, 416), /* GPP_I */ + TGL_GPP(0, 267, 281, 448), /* GPP_I */ TGL_GPP(1, 282, 290, INTEL_GPIO_BASE_NOMAP), /* JTAG */ }; diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c index 7815426e7aea..10002b8497fe 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c @@ -926,12 +926,10 @@ int mtk_pinconf_adv_pull_set(struct mtk_pinctrl *hw, err = hw->soc->bias_set(hw, desc, pullup); if (err) return err; - } else if (hw->soc->bias_set_combo) { - err = hw->soc->bias_set_combo(hw, desc, pullup, arg); - if (err) - return err; } else { - return -ENOTSUPP; + err = mtk_pinconf_bias_set_rev1(hw, desc, pullup); + if (err) + err = mtk_pinconf_bias_set(hw, desc, pullup); } } diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 899c16c17b6d..ef49402c0623 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -952,6 +952,7 @@ static int amd_gpio_remove(struct platform_device *pdev) static const struct acpi_device_id amd_gpio_acpi_match[] = { { "AMD0030", 0 }, { "AMDI0030", 0}, + { "AMDI0031", 0}, { }, }; MODULE_DEVICE_TABLE(acpi, amd_gpio_acpi_match); diff --git a/drivers/pinctrl/pinctrl-equilibrium.c b/drivers/pinctrl/pinctrl-equilibrium.c index 067271b7d35a..ac1c47f542c1 100644 --- a/drivers/pinctrl/pinctrl-equilibrium.c +++ b/drivers/pinctrl/pinctrl-equilibrium.c @@ -929,6 +929,7 @@ static const struct of_device_id eqbr_pinctrl_dt_match[] = { { .compatible = "intel,lgm-io" }, {} }; +MODULE_DEVICE_TABLE(of, eqbr_pinctrl_dt_match); static struct platform_driver eqbr_pinctrl_driver = { .probe = eqbr_pinctrl_probe, diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index ce2d8014b7e0..d0259577934e 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -351,6 +351,11 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) if (mcp_read(mcp, MCP_INTF, &intf)) goto unlock; + if (intf == 0) { + /* There is no interrupt pending */ + goto unlock; + } + if (mcp_read(mcp, MCP_INTCAP, &intcap)) goto unlock; @@ -368,11 +373,6 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) mcp->cached_gpio = gpio; mutex_unlock(&mcp->lock); - if (intf == 0) { - /* There is no interrupt pending */ - return IRQ_HANDLED; - } - dev_dbg(mcp->chip.parent, "intcap 0x%04X intf 0x%04X gpio_orig 0x%04X gpio 0x%04X\n", intcap, intf, gpio_orig, gpio); diff --git a/drivers/pinctrl/renesas/pfc-r8a7796.c b/drivers/pinctrl/renesas/pfc-r8a7796.c index 55f0344a3d3e..3878d6b0db14 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7796.c +++ b/drivers/pinctrl/renesas/pfc-r8a7796.c @@ -68,6 +68,7 @@ PIN_NOGP_CFG(QSPI1_MOSI_IO0, "QSPI1_MOSI_IO0", fn, CFG_FLAGS), \ PIN_NOGP_CFG(QSPI1_SPCLK, "QSPI1_SPCLK", fn, CFG_FLAGS), \ PIN_NOGP_CFG(QSPI1_SSL, "QSPI1_SSL", fn, CFG_FLAGS), \ + PIN_NOGP_CFG(PRESET_N, "PRESET#", fn, SH_PFC_PIN_CFG_PULL_DOWN),\ PIN_NOGP_CFG(RPC_INT_N, "RPC_INT#", fn, CFG_FLAGS), \ PIN_NOGP_CFG(RPC_RESET_N, "RPC_RESET#", fn, CFG_FLAGS), \ PIN_NOGP_CFG(RPC_WP_N, "RPC_WP#", fn, CFG_FLAGS), \ @@ -6109,7 +6110,7 @@ static const struct pinmux_bias_reg pinmux_bias_regs[] = { [ 4] = RCAR_GP_PIN(6, 29), /* USB30_OVC */ [ 5] = RCAR_GP_PIN(6, 30), /* GP6_30 */ [ 6] = RCAR_GP_PIN(6, 31), /* GP6_31 */ - [ 7] = SH_PFC_PIN_NONE, + [ 7] = PIN_PRESET_N, /* PRESET# */ [ 8] = SH_PFC_PIN_NONE, [ 9] = SH_PFC_PIN_NONE, [10] = SH_PFC_PIN_NONE, diff --git a/drivers/pinctrl/renesas/pfc-r8a77990.c b/drivers/pinctrl/renesas/pfc-r8a77990.c index aed04a4c6116..240aadc4611f 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77990.c +++ b/drivers/pinctrl/renesas/pfc-r8a77990.c @@ -54,10 +54,10 @@ PIN_NOGP_CFG(FSCLKST_N, "FSCLKST_N", fn, CFG_FLAGS), \ PIN_NOGP_CFG(MLB_REF, "MLB_REF", fn, CFG_FLAGS), \ PIN_NOGP_CFG(PRESETOUT_N, "PRESETOUT_N", fn, CFG_FLAGS), \ - PIN_NOGP_CFG(TCK, "TCK", fn, CFG_FLAGS), \ - PIN_NOGP_CFG(TDI, "TDI", fn, CFG_FLAGS), \ - PIN_NOGP_CFG(TMS, "TMS", fn, CFG_FLAGS), \ - PIN_NOGP_CFG(TRST_N, "TRST_N", fn, CFG_FLAGS) + PIN_NOGP_CFG(TCK, "TCK", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TDI, "TDI", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TMS, "TMS", fn, SH_PFC_PIN_CFG_PULL_UP), \ + PIN_NOGP_CFG(TRST_N, "TRST_N", fn, SH_PFC_PIN_CFG_PULL_UP) /* * F_() : just information diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 7d9bdedcd71b..3af4430543dc 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1229,7 +1229,7 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct device *dev = pctl->dev; struct resource res; int npins = STM32_GPIO_PINS_PER_BANK; - int bank_nr, err; + int bank_nr, err, i = 0; if (!IS_ERR(bank->rstc)) reset_control_deassert(bank->rstc); @@ -1251,9 +1251,14 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, of_property_read_string(np, "st,bank-name", &bank->gpio_chip.label); - if (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args)) { + if (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, i, &args)) { bank_nr = args.args[1] / STM32_GPIO_PINS_PER_BANK; bank->gpio_chip.base = args.args[1]; + + npins = args.args[2]; + while (!of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, + ++i, &args)) + npins += args.args[2]; } else { bank_nr = pctl->nbanks; bank->gpio_chip.base = bank_nr * STM32_GPIO_PINS_PER_BANK; diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c index 1d9fbabd02fb..949ddeb673bc 100644 --- a/drivers/platform/x86/asus-nb-wmi.c +++ b/drivers/platform/x86/asus-nb-wmi.c @@ -110,11 +110,6 @@ static struct quirk_entry quirk_asus_forceals = { .wmi_force_als_set = true, }; -static struct quirk_entry quirk_asus_vendor_backlight = { - .wmi_backlight_power = true, - .wmi_backlight_set_devstate = true, -}; - static struct quirk_entry quirk_asus_use_kbd_dock_devid = { .use_kbd_dock_devid = true, }; @@ -420,78 +415,6 @@ static const struct dmi_system_id asus_quirks[] = { }, .driver_data = &quirk_asus_forceals, }, - { - .callback = dmi_matched, - .ident = "ASUSTeK COMPUTER INC. GA401IH", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "GA401IH"), - }, - .driver_data = &quirk_asus_vendor_backlight, - }, - { - .callback = dmi_matched, - .ident = "ASUSTeK COMPUTER INC. GA401II", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "GA401II"), - }, - .driver_data = &quirk_asus_vendor_backlight, - }, - { - .callback = dmi_matched, - .ident = "ASUSTeK COMPUTER INC. GA401IU", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "GA401IU"), - }, - .driver_data = &quirk_asus_vendor_backlight, - }, - { - .callback = dmi_matched, - .ident = "ASUSTeK COMPUTER INC. GA401IV", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "GA401IV"), - }, - .driver_data = &quirk_asus_vendor_backlight, - }, - { - .callback = dmi_matched, - .ident = "ASUSTeK COMPUTER INC. GA401IVC", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "GA401IVC"), - }, - .driver_data = &quirk_asus_vendor_backlight, - }, - { - .callback = dmi_matched, - .ident = "ASUSTeK COMPUTER INC. GA502II", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "GA502II"), - }, - .driver_data = &quirk_asus_vendor_backlight, - }, - { - .callback = dmi_matched, - .ident = "ASUSTeK COMPUTER INC. GA502IU", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "GA502IU"), - }, - .driver_data = &quirk_asus_vendor_backlight, - }, - { - .callback = dmi_matched, - .ident = "ASUSTeK COMPUTER INC. GA502IV", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "GA502IV"), - }, - .driver_data = &quirk_asus_vendor_backlight, - }, { .callback = dmi_matched, .ident = "Asus Transformer T100TA / T100HA / T100CHI", diff --git a/drivers/platform/x86/pcengines-apuv2.c b/drivers/platform/x86/pcengines-apuv2.c index c37349f97bb8..d063d91db9bc 100644 --- a/drivers/platform/x86/pcengines-apuv2.c +++ b/drivers/platform/x86/pcengines-apuv2.c @@ -94,6 +94,7 @@ static struct gpiod_lookup_table gpios_led_table = { NULL, 1, GPIO_ACTIVE_LOW), GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_LINE_LED3, NULL, 2, GPIO_ACTIVE_LOW), + {} /* Terminating entry */ } }; @@ -123,6 +124,7 @@ static struct gpiod_lookup_table gpios_key_table = { .table = { GPIO_LOOKUP_IDX(AMD_FCH_GPIO_DRIVER_NAME, APU2_GPIO_LINE_MODESW, NULL, 0, GPIO_ACTIVE_LOW), + {} /* Terminating entry */ } }; diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 1c25af28a723..5c2f2e337b57 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -8806,6 +8806,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = { TPACPI_Q_LNV3('N', '2', 'O', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (2nd gen) */ TPACPI_Q_LNV3('N', '2', 'V', TPACPI_FAN_2CTL), /* P1 / X1 Extreme (3nd gen) */ TPACPI_Q_LNV3('N', '3', '0', TPACPI_FAN_2CTL), /* P15 (1st gen) / P15v (1st gen) */ + TPACPI_Q_LNV3('N', '3', '2', TPACPI_FAN_2CTL), /* X1 Carbon (9th gen) */ }; static int __init fan_init(struct ibm_init_struct *iibm) diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index fa7232ad8c39..352508d30467 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -2831,6 +2831,7 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) if (!dev->info_supported && !dev->system_event_supported) { pr_warn("No hotkey query interface found\n"); + error = -EINVAL; goto err_remove_filter; } diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c index 3743d895399e..99260915122c 100644 --- a/drivers/platform/x86/touchscreen_dmi.c +++ b/drivers/platform/x86/touchscreen_dmi.c @@ -299,6 +299,35 @@ static const struct ts_dmi_data estar_beauty_hd_data = { .properties = estar_beauty_hd_props, }; +/* Generic props + data for upside-down mounted GDIX1001 touchscreens */ +static const struct property_entry gdix1001_upside_down_props[] = { + PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"), + PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), + { } +}; + +static const struct ts_dmi_data gdix1001_00_upside_down_data = { + .acpi_name = "GDIX1001:00", + .properties = gdix1001_upside_down_props, +}; + +static const struct ts_dmi_data gdix1001_01_upside_down_data = { + .acpi_name = "GDIX1001:01", + .properties = gdix1001_upside_down_props, +}; + +static const struct property_entry glavey_tm800a550l_props[] = { + PROPERTY_ENTRY_STRING("firmware-name", "gt912-glavey-tm800a550l.fw"), + PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-glavey-tm800a550l.cfg"), + PROPERTY_ENTRY_U32("goodix,main-clk", 54), + { } +}; + +static const struct ts_dmi_data glavey_tm800a550l_data = { + .acpi_name = "GDIX1001:00", + .properties = glavey_tm800a550l_props, +}; + static const struct property_entry gp_electronic_t701_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-x", 960), PROPERTY_ENTRY_U32("touchscreen-size-y", 640), @@ -995,6 +1024,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"), }, }, + { /* Glavey TM800A550L */ + .driver_data = (void *)&glavey_tm800a550l_data, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), + /* Above strings are too generic, also match on BIOS version */ + DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"), + }, + }, { /* GP-electronic T701 */ .driver_data = (void *)&gp_electronic_t701_data, @@ -1268,6 +1306,24 @@ const struct dmi_system_id touchscreen_dmi_table[] = { DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"), }, }, + { + /* Teclast X89 (Android version / BIOS) */ + .driver_data = (void *)&gdix1001_00_upside_down_data, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "WISKY"), + DMI_MATCH(DMI_BOARD_NAME, "3G062i"), + }, + }, + { + /* Teclast X89 (Windows version / BIOS) */ + .driver_data = (void *)&gdix1001_01_upside_down_data, + .matches = { + /* tPAD is too generic, also match on bios date */ + DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), + DMI_MATCH(DMI_BOARD_NAME, "tPAD"), + DMI_MATCH(DMI_BIOS_DATE, "12/19/2014"), + }, + }, { /* Teclast X98 Plus II */ .driver_data = (void *)&teclast_x98plus2_data, @@ -1276,6 +1332,19 @@ const struct dmi_system_id touchscreen_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"), }, }, + { + /* Teclast X98 Pro */ + .driver_data = (void *)&gdix1001_00_upside_down_data, + .matches = { + /* + * Only match BIOS date, because the manufacturers + * BIOS does not report the board name at all + * (sometimes)... + */ + DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"), + DMI_MATCH(DMI_BIOS_DATE, "10/28/2015"), + }, + }, { /* Trekstor Primebook C11 */ .driver_data = (void *)&trekstor_primebook_c11_data, @@ -1351,6 +1420,22 @@ const struct dmi_system_id touchscreen_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "VINGA Twizzle J116"), }, }, + { + /* "WinBook TW100" */ + .driver_data = (void *)&gdix1001_00_upside_down_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), + DMI_MATCH(DMI_PRODUCT_NAME, "TW100") + } + }, + { + /* WinBook TW700 */ + .driver_data = (void *)&gdix1001_00_upside_down_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "WinBook"), + DMI_MATCH(DMI_PRODUCT_NAME, "TW700") + }, + }, { /* Yours Y8W81, same case and touchscreen as Chuwi Vi8 */ .driver_data = (void *)&chuwi_vi8_data, diff --git a/drivers/power/reset/gpio-poweroff.c b/drivers/power/reset/gpio-poweroff.c index c5067eb75370..1c5af2fef142 100644 --- a/drivers/power/reset/gpio-poweroff.c +++ b/drivers/power/reset/gpio-poweroff.c @@ -90,6 +90,7 @@ static const struct of_device_id of_gpio_poweroff_match[] = { { .compatible = "gpio-poweroff", }, {}, }; +MODULE_DEVICE_TABLE(of, of_gpio_poweroff_match); static struct platform_driver gpio_poweroff_driver = { .probe = gpio_poweroff_probe, diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index 1699b9269a78..602d968c498b 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -684,15 +684,16 @@ config AB8500_BM config BATTERY_GOLDFISH tristate "Goldfish battery driver" - depends on GOLDFISH || COMPILE_TEST depends on HAS_IOMEM help - Say Y to enable support for the battery and AC power in the - Goldfish emulator. + Say Y to enable support for the Goldfish battery and AC power + driver. Originated in the Android Studio Emulator (goldfish) it is + going to be used in other emulators. config BATTERY_RT5033 tristate "RT5033 fuel gauge support" - depends on MFD_RT5033 + depends on I2C + select REGMAP_I2C help This adds support for battery fuel gauge in Richtek RT5033 PMIC. The fuelgauge calculates and determines the battery state of charge diff --git a/drivers/power/supply/ab8500_btemp.c b/drivers/power/supply/ab8500_btemp.c index 909f0242bacb..4417d64c31f9 100644 --- a/drivers/power/supply/ab8500_btemp.c +++ b/drivers/power/supply/ab8500_btemp.c @@ -1142,6 +1142,7 @@ static const struct of_device_id ab8500_btemp_match[] = { { .compatible = "stericsson,ab8500-btemp", }, { }, }; +MODULE_DEVICE_TABLE(of, ab8500_btemp_match); static struct platform_driver ab8500_btemp_driver = { .probe = ab8500_btemp_probe, diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c index db65be026920..3d627768ad7b 100644 --- a/drivers/power/supply/ab8500_charger.c +++ b/drivers/power/supply/ab8500_charger.c @@ -413,6 +413,14 @@ static void ab8500_enable_disable_sw_fallback(struct ab8500_charger *di, static void ab8500_power_supply_changed(struct ab8500_charger *di, struct power_supply *psy) { + /* + * This happens if we get notifications or interrupts and + * the platform has been configured not to support one or + * other type of charging. + */ + if (!psy) + return; + if (di->autopower_cfg) { if (!di->usb.charger_connected && !di->ac.charger_connected && @@ -439,7 +447,15 @@ static void ab8500_charger_set_usb_connected(struct ab8500_charger *di, if (!connected) di->flags.vbus_drop_end = false; - sysfs_notify(&di->usb_chg.psy->dev.kobj, NULL, "present"); + /* + * Sometimes the platform is configured not to support + * USB charging and no psy has been created, but we still + * will get these notifications. + */ + if (di->usb_chg.psy) { + sysfs_notify(&di->usb_chg.psy->dev.kobj, NULL, + "present"); + } if (connected) { mutex_lock(&di->charger_attached_mutex); @@ -3663,6 +3679,7 @@ static const struct of_device_id ab8500_charger_match[] = { { .compatible = "stericsson,ab8500-charger", }, { }, }; +MODULE_DEVICE_TABLE(of, ab8500_charger_match); static struct platform_driver ab8500_charger_driver = { .probe = ab8500_charger_probe, diff --git a/drivers/power/supply/ab8500_fg.c b/drivers/power/supply/ab8500_fg.c index 592a73d4dde6..f1da757c939f 100644 --- a/drivers/power/supply/ab8500_fg.c +++ b/drivers/power/supply/ab8500_fg.c @@ -3249,6 +3249,7 @@ static const struct of_device_id ab8500_fg_match[] = { { .compatible = "stericsson,ab8500-fg", }, { }, }; +MODULE_DEVICE_TABLE(of, ab8500_fg_match); static struct platform_driver ab8500_fg_driver = { .probe = ab8500_fg_probe, diff --git a/drivers/power/supply/charger-manager.c b/drivers/power/supply/charger-manager.c index 6fcebe441552..333349275b96 100644 --- a/drivers/power/supply/charger-manager.c +++ b/drivers/power/supply/charger-manager.c @@ -1279,6 +1279,7 @@ static const struct of_device_id charger_manager_match[] = { }, {}, }; +MODULE_DEVICE_TABLE(of, charger_manager_match); static struct charger_desc *of_cm_parse_desc(struct device *dev) { diff --git a/drivers/power/supply/max17042_battery.c b/drivers/power/supply/max17042_battery.c index 2e9672fe4df1..794caf03658d 100644 --- a/drivers/power/supply/max17042_battery.c +++ b/drivers/power/supply/max17042_battery.c @@ -1094,7 +1094,7 @@ static int max17042_probe(struct i2c_client *client, } if (client->irq) { - unsigned int flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; + unsigned int flags = IRQF_ONESHOT; /* * On ACPI systems the IRQ may be handled by ACPI-event code, diff --git a/drivers/power/supply/rt5033_battery.c b/drivers/power/supply/rt5033_battery.c index f330452341f0..9ad0afe83d1b 100644 --- a/drivers/power/supply/rt5033_battery.c +++ b/drivers/power/supply/rt5033_battery.c @@ -164,9 +164,16 @@ static const struct i2c_device_id rt5033_battery_id[] = { }; MODULE_DEVICE_TABLE(i2c, rt5033_battery_id); +static const struct of_device_id rt5033_battery_of_match[] = { + { .compatible = "richtek,rt5033-battery", }, + { } +}; +MODULE_DEVICE_TABLE(of, rt5033_battery_of_match); + static struct i2c_driver rt5033_battery_driver = { .driver = { .name = "rt5033-battery", + .of_match_table = rt5033_battery_of_match, }, .probe = rt5033_battery_probe, .remove = rt5033_battery_remove, diff --git a/drivers/power/supply/sc2731_charger.c b/drivers/power/supply/sc2731_charger.c index 335cb857ef30..288b79836c13 100644 --- a/drivers/power/supply/sc2731_charger.c +++ b/drivers/power/supply/sc2731_charger.c @@ -524,6 +524,7 @@ static const struct of_device_id sc2731_charger_of_match[] = { { .compatible = "sprd,sc2731-charger", }, { } }; +MODULE_DEVICE_TABLE(of, sc2731_charger_of_match); static struct platform_driver sc2731_charger_driver = { .driver = { diff --git a/drivers/power/supply/sc27xx_fuel_gauge.c b/drivers/power/supply/sc27xx_fuel_gauge.c index 9c627618c224..1ae8374e1ceb 100644 --- a/drivers/power/supply/sc27xx_fuel_gauge.c +++ b/drivers/power/supply/sc27xx_fuel_gauge.c @@ -1342,6 +1342,7 @@ static const struct of_device_id sc27xx_fgu_of_match[] = { { .compatible = "sprd,sc2731-fgu", }, { } }; +MODULE_DEVICE_TABLE(of, sc27xx_fgu_of_match); static struct platform_driver sc27xx_fgu_driver = { .probe = sc27xx_fgu_probe, diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig index deb429a3dff1..1b5834ac6ca0 100644 --- a/drivers/ptp/Kconfig +++ b/drivers/ptp/Kconfig @@ -90,7 +90,8 @@ config PTP_1588_CLOCK_INES config PTP_1588_CLOCK_PCH tristate "Intel PCH EG20T as PTP clock" depends on X86_32 || COMPILE_TEST - depends on HAS_IOMEM && NET + depends on HAS_IOMEM && PCI + depends on NET imply PTP_1588_CLOCK help This driver adds support for using the PCH EG20T as a PTP @@ -108,7 +109,7 @@ config PTP_1588_CLOCK_PCH config PTP_1588_CLOCK_KVM tristate "KVM virtual PTP clock" depends on PTP_1588_CLOCK - depends on KVM_GUEST && X86 + depends on (KVM_GUEST && X86) || (HAVE_ARM_SMCCC_DISCOVERY && ARM_ARCH_TIMER) default y help This driver adds support for using kvm infrastructure as a PTP diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile index 7aff75f745dc..9fa5ede44b2b 100644 --- a/drivers/ptp/Makefile +++ b/drivers/ptp/Makefile @@ -4,6 +4,8 @@ # ptp-y := ptp_clock.o ptp_chardev.o ptp_sysfs.o +ptp_kvm-$(CONFIG_X86) := ptp_kvm_x86.o ptp_kvm_common.o +ptp_kvm-$(CONFIG_HAVE_ARM_SMCCC) := ptp_kvm_arm.o ptp_kvm_common.o obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o obj-$(CONFIG_PTP_1588_CLOCK_DTE) += ptp_dte.o obj-$(CONFIG_PTP_1588_CLOCK_INES) += ptp_ines.o diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 03a246e60fd9..21c4c34c52d8 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -63,7 +63,7 @@ static void enqueue_external_timestamp(struct timestamp_event_queue *queue, spin_unlock_irqrestore(&queue->lock, flags); } -s32 scaled_ppm_to_ppb(long ppm) +long scaled_ppm_to_ppb(long ppm) { /* * The 'freq' field in the 'struct timex' is in parts per @@ -80,7 +80,7 @@ s32 scaled_ppm_to_ppb(long ppm) s64 ppb = 1 + ppm; ppb *= 125; ppb >>= 13; - return (s32) ppb; + return (long) ppb; } EXPORT_SYMBOL(scaled_ppm_to_ppb); @@ -138,7 +138,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct __kernel_timex *tx) delta = ktime_to_ns(kt); err = ops->adjtime(ops, delta); } else if (tx->modes & ADJ_FREQUENCY) { - s32 ppb = scaled_ppm_to_ppb(tx->freq); + long ppb = scaled_ppm_to_ppb(tx->freq); if (ppb > ops->max_adj || ppb < -ops->max_adj) return -ERANGE; if (ops->adjfine) diff --git a/drivers/ptp/ptp_kvm_arm.c b/drivers/ptp/ptp_kvm_arm.c new file mode 100644 index 000000000000..b7d28c8dfb84 --- /dev/null +++ b/drivers/ptp/ptp_kvm_arm.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Virtual PTP 1588 clock for use with KVM guests + * Copyright (C) 2019 ARM Ltd. + * All Rights Reserved + */ + +#include +#include + +#include +#include + +int kvm_arch_ptp_init(void) +{ + int ret; + + ret = kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_PTP); + if (ret <= 0) + return -EOPNOTSUPP; + + return 0; +} + +int kvm_arch_ptp_get_clock(struct timespec64 *ts) +{ + return kvm_arch_ptp_get_crosststamp(NULL, ts, NULL); +} diff --git a/drivers/ptp/ptp_kvm.c b/drivers/ptp/ptp_kvm_common.c similarity index 60% rename from drivers/ptp/ptp_kvm.c rename to drivers/ptp/ptp_kvm_common.c index 658d33fc3195..fcae32f56f25 100644 --- a/drivers/ptp/ptp_kvm.c +++ b/drivers/ptp/ptp_kvm_common.c @@ -8,11 +8,11 @@ #include #include #include +#include #include +#include #include #include -#include -#include #include #include @@ -24,56 +24,29 @@ struct kvm_ptp_clock { static DEFINE_SPINLOCK(kvm_ptp_lock); -static struct pvclock_vsyscall_time_info *hv_clock; - -static struct kvm_clock_pairing clock_pair; -static phys_addr_t clock_pair_gpa; - static int ptp_kvm_get_time_fn(ktime_t *device_time, struct system_counterval_t *system_counter, void *ctx) { - unsigned long ret; + long ret; + u64 cycle; struct timespec64 tspec; - unsigned version; - int cpu; - struct pvclock_vcpu_time_info *src; + struct clocksource *cs; spin_lock(&kvm_ptp_lock); preempt_disable_notrace(); - cpu = smp_processor_id(); - src = &hv_clock[cpu].pvti; - - do { - /* - * We are using a TSC value read in the hosts - * kvm_hc_clock_pairing handling. - * So any changes to tsc_to_system_mul - * and tsc_shift or any other pvclock - * data invalidate that measurement. - */ - version = pvclock_read_begin(src); - - ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING, - clock_pair_gpa, - KVM_CLOCK_PAIRING_WALLCLOCK); - if (ret != 0) { - pr_err_ratelimited("clock pairing hypercall ret %lu\n", ret); - spin_unlock(&kvm_ptp_lock); - preempt_enable_notrace(); - return -EOPNOTSUPP; - } - - tspec.tv_sec = clock_pair.sec; - tspec.tv_nsec = clock_pair.nsec; - ret = __pvclock_read_cycles(src, clock_pair.tsc); - } while (pvclock_read_retry(src, version)); + ret = kvm_arch_ptp_get_crosststamp(&cycle, &tspec, &cs); + if (ret) { + spin_unlock(&kvm_ptp_lock); + preempt_enable_notrace(); + return ret; + } preempt_enable_notrace(); - system_counter->cycles = ret; - system_counter->cs = &kvm_clock; + system_counter->cycles = cycle; + system_counter->cs = cs; *device_time = timespec64_to_ktime(tspec); @@ -111,22 +84,17 @@ static int ptp_kvm_settime(struct ptp_clock_info *ptp, static int ptp_kvm_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) { - unsigned long ret; + long ret; struct timespec64 tspec; spin_lock(&kvm_ptp_lock); - ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING, - clock_pair_gpa, - KVM_CLOCK_PAIRING_WALLCLOCK); - if (ret != 0) { - pr_err_ratelimited("clock offset hypercall ret %lu\n", ret); + ret = kvm_arch_ptp_get_clock(&tspec); + if (ret) { spin_unlock(&kvm_ptp_lock); - return -EOPNOTSUPP; + return ret; } - tspec.tv_sec = clock_pair.sec; - tspec.tv_nsec = clock_pair.nsec; spin_unlock(&kvm_ptp_lock); memcpy(ts, &tspec, sizeof(struct timespec64)); @@ -168,19 +136,12 @@ static int __init ptp_kvm_init(void) { long ret; - if (!kvm_para_available()) - return -ENODEV; - - clock_pair_gpa = slow_virt_to_phys(&clock_pair); - hv_clock = pvclock_get_pvti_cpu0_va(); - - if (!hv_clock) - return -ENODEV; - - ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING, clock_pair_gpa, - KVM_CLOCK_PAIRING_WALLCLOCK); - if (ret == -KVM_ENOSYS || ret == -KVM_EOPNOTSUPP) - return -ENODEV; + ret = kvm_arch_ptp_init(); + if (ret) { + if (ret != -EOPNOTSUPP) + pr_err("fail to initialize ptp_kvm"); + return ret; + } kvm_ptp_clock.caps = ptp_kvm_caps; diff --git a/drivers/ptp/ptp_kvm_x86.c b/drivers/ptp/ptp_kvm_x86.c new file mode 100644 index 000000000000..3dd519dfc473 --- /dev/null +++ b/drivers/ptp/ptp_kvm_x86.c @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Virtual PTP 1588 clock for use with KVM guests + * + * Copyright (C) 2017 Red Hat Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct pvclock_vsyscall_time_info *hv_clock; + +static phys_addr_t clock_pair_gpa; +static struct kvm_clock_pairing clock_pair; + +int kvm_arch_ptp_init(void) +{ + long ret; + + if (!kvm_para_available()) + return -ENODEV; + + clock_pair_gpa = slow_virt_to_phys(&clock_pair); + hv_clock = pvclock_get_pvti_cpu0_va(); + if (!hv_clock) + return -ENODEV; + + ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING, clock_pair_gpa, + KVM_CLOCK_PAIRING_WALLCLOCK); + if (ret == -KVM_ENOSYS || ret == -KVM_EOPNOTSUPP) + return -ENODEV; + + return 0; +} + +int kvm_arch_ptp_get_clock(struct timespec64 *ts) +{ + long ret; + + ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING, + clock_pair_gpa, + KVM_CLOCK_PAIRING_WALLCLOCK); + if (ret != 0) { + pr_err_ratelimited("clock offset hypercall ret %lu\n", ret); + return -EOPNOTSUPP; + } + + ts->tv_sec = clock_pair.sec; + ts->tv_nsec = clock_pair.nsec; + + return 0; +} + +int kvm_arch_ptp_get_crosststamp(u64 *cycle, struct timespec64 *tspec, + struct clocksource **cs) +{ + struct pvclock_vcpu_time_info *src; + unsigned int version; + long ret; + int cpu; + + cpu = smp_processor_id(); + src = &hv_clock[cpu].pvti; + + do { + /* + * We are using a TSC value read in the hosts + * kvm_hc_clock_pairing handling. + * So any changes to tsc_to_system_mul + * and tsc_shift or any other pvclock + * data invalidate that measurement. + */ + version = pvclock_read_begin(src); + + ret = kvm_hypercall2(KVM_HC_CLOCK_PAIRING, + clock_pair_gpa, + KVM_CLOCK_PAIRING_WALLCLOCK); + if (ret != 0) { + pr_err_ratelimited("clock pairing hypercall ret %lu\n", ret); + return -EOPNOTSUPP; + } + tspec->tv_sec = clock_pair.sec; + tspec->tv_nsec = clock_pair.nsec; + *cycle = __pvclock_read_cycles(src, clock_pair.tsc); + } while (pvclock_read_retry(src, version)); + + *cs = &kvm_clock; + + return 0; +} diff --git a/drivers/pwm/pwm-img.c b/drivers/pwm/pwm-img.c index a34d95ed70b2..22c002e685b3 100644 --- a/drivers/pwm/pwm-img.c +++ b/drivers/pwm/pwm-img.c @@ -156,7 +156,7 @@ static int img_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) struct img_pwm_chip *pwm_chip = to_img_pwm_chip(chip); int ret; - ret = pm_runtime_get_sync(chip->dev); + ret = pm_runtime_resume_and_get(chip->dev); if (ret < 0) return ret; diff --git a/drivers/pwm/pwm-imx1.c b/drivers/pwm/pwm-imx1.c index f8b2c2e001a7..c17652c40e14 100644 --- a/drivers/pwm/pwm-imx1.c +++ b/drivers/pwm/pwm-imx1.c @@ -180,8 +180,6 @@ static int pwm_imx1_remove(struct platform_device *pdev) { struct pwm_imx1_chip *imx = platform_get_drvdata(pdev); - pwm_imx1_clk_disable_unprepare(&imx->chip); - return pwmchip_remove(&imx->chip); } diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c index 6c6b44fd3f43..2d11ac277de8 100644 --- a/drivers/pwm/pwm-spear.c +++ b/drivers/pwm/pwm-spear.c @@ -231,10 +231,6 @@ static int spear_pwm_probe(struct platform_device *pdev) static int spear_pwm_remove(struct platform_device *pdev) { struct spear_pwm_chip *pc = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < NUM_PWM; i++) - pwm_disable(&pc->chip.pwms[i]); /* clk was prepared in probe, hence unprepare it here */ clk_unprepare(pc->clk); diff --git a/drivers/pwm/pwm-sprd.c b/drivers/pwm/pwm-sprd.c index 5123d948efd6..9eeb59cb81b6 100644 --- a/drivers/pwm/pwm-sprd.c +++ b/drivers/pwm/pwm-sprd.c @@ -180,13 +180,10 @@ static int sprd_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, } } - if (state->period != cstate->period || - state->duty_cycle != cstate->duty_cycle) { - ret = sprd_pwm_config(spc, pwm, state->duty_cycle, - state->period); - if (ret) - return ret; - } + ret = sprd_pwm_config(spc, pwm, state->duty_cycle, + state->period); + if (ret) + return ret; sprd_pwm_write(spc, pwm->hwpwm, SPRD_PWM_ENABLE, 1); } else if (cstate->enabled) { diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c index 1daf591025c0..8c4e6657b61e 100644 --- a/drivers/pwm/pwm-tegra.c +++ b/drivers/pwm/pwm-tegra.c @@ -303,7 +303,6 @@ static int tegra_pwm_probe(struct platform_device *pdev) static int tegra_pwm_remove(struct platform_device *pdev) { struct tegra_pwm_chip *pc = platform_get_drvdata(pdev); - unsigned int i; int err; if (WARN_ON(!pc)) @@ -313,18 +312,6 @@ static int tegra_pwm_remove(struct platform_device *pdev) if (err < 0) return err; - for (i = 0; i < pc->chip.npwm; i++) { - struct pwm_device *pwm = &pc->chip.pwms[i]; - - if (!pwm_is_enabled(pwm)) - if (clk_prepare_enable(pc->clk) < 0) - continue; - - pwm_writel(pc, i, 0); - - clk_disable_unprepare(pc->clk); - } - reset_control_assert(pc->rst); clk_disable_unprepare(pc->clk); diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c index 3333b8905f1b..2c097ee6cb02 100644 --- a/drivers/regulator/bd718x7-regulator.c +++ b/drivers/regulator/bd718x7-regulator.c @@ -364,7 +364,7 @@ BD718XX_OPS(bd71837_buck_regulator_ops, regulator_list_voltage_linear_range, NULL); BD718XX_OPS(bd71837_buck_regulator_nolinear_ops, regulator_list_voltage_table, - regulator_map_voltage_ascend, bd718xx_set_voltage_sel_restricted, + regulator_map_voltage_ascend, bd71837_set_voltage_sel_restricted, regulator_get_voltage_sel_regmap, regulator_set_voltage_time_sel, NULL); /* diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 7b3de8b0b1ca..043b5f63b94a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1422,6 +1422,12 @@ static int set_machine_constraints(struct regulator_dev *rdev) * and we have control then make sure it is enabled. */ if (rdev->constraints->always_on || rdev->constraints->boot_on) { + /* If we want to enable this regulator, make sure that we know + * the supplying regulator. + */ + if (rdev->supply_name && !rdev->supply) + return -EPROBE_DEFER; + if (rdev->supply) { ret = regulator_enable(rdev->supply); if (ret < 0) { diff --git a/drivers/regulator/cros-ec-regulator.c b/drivers/regulator/cros-ec-regulator.c index eb3fc1db4edc..c4754f3cf233 100644 --- a/drivers/regulator/cros-ec-regulator.c +++ b/drivers/regulator/cros-ec-regulator.c @@ -225,8 +225,9 @@ static int cros_ec_regulator_probe(struct platform_device *pdev) drvdata->dev = devm_regulator_register(dev, &drvdata->desc, &cfg); if (IS_ERR(drvdata->dev)) { + ret = PTR_ERR(drvdata->dev); dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); - return PTR_ERR(drvdata->dev); + return ret; } platform_set_drvdata(pdev, drvdata); diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index e18d291c7f21..23fa429ebe76 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c @@ -250,7 +250,8 @@ static int da9052_regulator_set_voltage_time_sel(struct regulator_dev *rdev, case DA9052_ID_BUCK3: case DA9052_ID_LDO2: case DA9052_ID_LDO3: - ret = (new_sel - old_sel) * info->step_uV / 6250; + ret = DIV_ROUND_UP(abs(new_sel - old_sel) * info->step_uV, + 6250); break; } diff --git a/drivers/regulator/fan53880.c b/drivers/regulator/fan53880.c index e83eb4fb1876..94f02f3099dd 100644 --- a/drivers/regulator/fan53880.c +++ b/drivers/regulator/fan53880.c @@ -51,6 +51,7 @@ static const struct regulator_ops fan53880_ops = { REGULATOR_LINEAR_RANGE(800000, 0xf, 0x73, 25000), \ }, \ .n_linear_ranges = 2, \ + .n_voltages = 0x74, \ .vsel_reg = FAN53880_LDO ## _num ## VOUT, \ .vsel_mask = 0x7f, \ .enable_reg = FAN53880_ENABLE, \ @@ -76,8 +77,9 @@ static const struct regulator_desc fan53880_regulators[] = { REGULATOR_LINEAR_RANGE(600000, 0x1f, 0xf7, 12500), }, .n_linear_ranges = 2, + .n_voltages = 0xf8, .vsel_reg = FAN53880_BUCKVOUT, - .vsel_mask = 0x7f, + .vsel_mask = 0xff, .enable_reg = FAN53880_ENABLE, .enable_mask = 0x10, .enable_time = 480, @@ -95,6 +97,7 @@ static const struct regulator_desc fan53880_regulators[] = { REGULATOR_LINEAR_RANGE(3000000, 0x4, 0x70, 25000), }, .n_linear_ranges = 2, + .n_voltages = 0x71, .vsel_reg = FAN53880_BOOSTVOUT, .vsel_mask = 0x7f, .enable_reg = FAN53880_ENABLE_BOOST, diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c index dc631c1a46b4..d144a4bdb76d 100644 --- a/drivers/regulator/hi6421-regulator.c +++ b/drivers/regulator/hi6421-regulator.c @@ -366,9 +366,8 @@ static struct hi6421_regulator_info static int hi6421_regulator_enable(struct regulator_dev *rdev) { - struct hi6421_regulator_pdata *pdata; + struct hi6421_regulator_pdata *pdata = rdev_get_drvdata(rdev); - pdata = dev_get_drvdata(rdev->dev.parent); /* hi6421 spec requires regulator enablement must be serialized: * - Because when BUCK, LDO switching from off to on, it will have * a huge instantaneous current; so you can not turn on two or @@ -385,9 +384,10 @@ static int hi6421_regulator_enable(struct regulator_dev *rdev) static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev) { - struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); - u32 reg_val; + struct hi6421_regulator_info *info; + unsigned int reg_val; + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); if (reg_val & info->mode_mask) return REGULATOR_MODE_IDLE; @@ -397,9 +397,10 @@ static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev) static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev) { - struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); - u32 reg_val; + struct hi6421_regulator_info *info; + unsigned int reg_val; + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); if (reg_val & info->mode_mask) return REGULATOR_MODE_STANDBY; @@ -410,9 +411,10 @@ static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev) static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode) { - struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); - u32 new_mode; + struct hi6421_regulator_info *info; + unsigned int new_mode; + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); switch (mode) { case REGULATOR_MODE_NORMAL: new_mode = 0; @@ -434,9 +436,10 @@ static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) { - struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); - u32 new_mode; + struct hi6421_regulator_info *info; + unsigned int new_mode; + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); switch (mode) { case REGULATOR_MODE_NORMAL: new_mode = 0; @@ -459,7 +462,9 @@ static unsigned int hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev, int input_uV, int output_uV, int load_uA) { - struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); + struct hi6421_regulator_info *info; + + info = container_of(rdev->desc, struct hi6421_regulator_info, desc); if (load_uA > info->eco_microamp) return REGULATOR_MODE_NORMAL; @@ -543,14 +548,13 @@ static int hi6421_regulator_probe(struct platform_device *pdev) if (!pdata) return -ENOMEM; mutex_init(&pdata->lock); - platform_set_drvdata(pdev, pdata); for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) { /* assign per-regulator data */ info = &hi6421_regulator_info[i]; config.dev = pdev->dev.parent; - config.driver_data = info; + config.driver_data = pdata; config.regmap = pmic->regmap; rdev = devm_regulator_register(&pdev->dev, &info->desc, diff --git a/drivers/regulator/hi655x-regulator.c b/drivers/regulator/hi655x-regulator.c index ac2ee2030211..b44f492a2b83 100644 --- a/drivers/regulator/hi655x-regulator.c +++ b/drivers/regulator/hi655x-regulator.c @@ -72,7 +72,7 @@ enum hi655x_regulator_id { static int hi655x_is_enabled(struct regulator_dev *rdev) { unsigned int value = 0; - struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); + const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); regmap_read(rdev->regmap, regulator->status_reg, &value); return (value & rdev->desc->enable_mask); @@ -80,7 +80,7 @@ static int hi655x_is_enabled(struct regulator_dev *rdev) static int hi655x_disable(struct regulator_dev *rdev) { - struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); + const struct hi655x_regulator *regulator = rdev_get_drvdata(rdev); return regmap_write(rdev->regmap, regulator->disable_reg, rdev->desc->enable_mask); @@ -169,7 +169,6 @@ static const struct hi655x_regulator regulators[] = { static int hi655x_regulator_probe(struct platform_device *pdev) { unsigned int i; - struct hi655x_regulator *regulator; struct hi655x_pmic *pmic; struct regulator_config config = { }; struct regulator_dev *rdev; @@ -180,22 +179,17 @@ static int hi655x_regulator_probe(struct platform_device *pdev) return -ENODEV; } - regulator = devm_kzalloc(&pdev->dev, sizeof(*regulator), GFP_KERNEL); - if (!regulator) - return -ENOMEM; - - platform_set_drvdata(pdev, regulator); - config.dev = pdev->dev.parent; config.regmap = pmic->regmap; - config.driver_data = regulator; for (i = 0; i < ARRAY_SIZE(regulators); i++) { + config.driver_data = (void *) ®ulators[i]; + rdev = devm_regulator_register(&pdev->dev, ®ulators[i].rdesc, &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", - regulator->rdesc.name); + regulators[i].rdesc.name); return PTR_ERR(rdev); } } diff --git a/drivers/regulator/max77620-regulator.c b/drivers/regulator/max77620-regulator.c index 8d9731e4052b..5c439c850d09 100644 --- a/drivers/regulator/max77620-regulator.c +++ b/drivers/regulator/max77620-regulator.c @@ -814,6 +814,13 @@ static int max77620_regulator_probe(struct platform_device *pdev) config.dev = dev; config.driver_data = pmic; + /* + * Set of_node_reuse flag to prevent driver core from attempting to + * claim any pinmux resources already claimed by the parent device. + * Otherwise PMIC driver will fail to re-probe. + */ + device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent); + for (id = 0; id < MAX77620_NUM_REGS; id++) { struct regulator_dev *rdev; struct regulator_desc *rdesc; diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c index 13cb6ac9a892..1d4eb5dc4fac 100644 --- a/drivers/regulator/mt6358-regulator.c +++ b/drivers/regulator/mt6358-regulator.c @@ -457,7 +457,7 @@ static struct mt6358_regulator_info mt6358_regulators[] = { MT6358_REG_FIXED("ldo_vaud28", VAUD28, MT6358_LDO_VAUD28_CON0, 0, 2800000), MT6358_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx, - MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10, 0), + MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0xf, 0), MT6358_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx, MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00, 8), MT6358_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx, diff --git a/drivers/regulator/rt4801-regulator.c b/drivers/regulator/rt4801-regulator.c index 2055a9cb13ba..7a87788d3f09 100644 --- a/drivers/regulator/rt4801-regulator.c +++ b/drivers/regulator/rt4801-regulator.c @@ -66,7 +66,7 @@ static int rt4801_enable(struct regulator_dev *rdev) struct gpio_descs *gpios = priv->enable_gpios; int id = rdev_get_id(rdev), ret; - if (gpios->ndescs <= id) { + if (!gpios || gpios->ndescs <= id) { dev_warn(&rdev->dev, "no dedicated gpio can control\n"); goto bypass_gpio; } @@ -88,7 +88,7 @@ static int rt4801_disable(struct regulator_dev *rdev) struct gpio_descs *gpios = priv->enable_gpios; int id = rdev_get_id(rdev); - if (gpios->ndescs <= id) { + if (!gpios || gpios->ndescs <= id) { dev_warn(&rdev->dev, "no dedicated gpio can control\n"); goto bypass_gpio; } diff --git a/drivers/regulator/rtmv20-regulator.c b/drivers/regulator/rtmv20-regulator.c index 852fb2596ffd..2ee334174e2b 100644 --- a/drivers/regulator/rtmv20-regulator.c +++ b/drivers/regulator/rtmv20-regulator.c @@ -27,6 +27,7 @@ #define RTMV20_REG_LDIRQ 0x30 #define RTMV20_REG_LDSTAT 0x40 #define RTMV20_REG_LDMASK 0x50 +#define RTMV20_MAX_REGS (RTMV20_REG_LDMASK + 1) #define RTMV20_VID_MASK GENMASK(7, 4) #define RICHTEK_VID 0x80 @@ -36,7 +37,7 @@ #define RTMV20_WIDTH2_MASK GENMASK(7, 0) #define RTMV20_LBPLVL_MASK GENMASK(3, 0) #define RTMV20_LBPEN_MASK BIT(7) -#define RTMV20_STROBEPOL_MASK BIT(1) +#define RTMV20_STROBEPOL_MASK BIT(0) #define RTMV20_VSYNPOL_MASK BIT(1) #define RTMV20_FSINEN_MASK BIT(7) #define RTMV20_ESEN_MASK BIT(6) @@ -103,9 +104,47 @@ static int rtmv20_lsw_disable(struct regulator_dev *rdev) return 0; } +static int rtmv20_lsw_set_current_limit(struct regulator_dev *rdev, int min_uA, + int max_uA) +{ + int sel; + + if (min_uA > RTMV20_LSW_MAXUA || max_uA < RTMV20_LSW_MINUA) + return -EINVAL; + + if (max_uA > RTMV20_LSW_MAXUA) + max_uA = RTMV20_LSW_MAXUA; + + sel = (max_uA - RTMV20_LSW_MINUA) / RTMV20_LSW_STEPUA; + + /* Ensure the selected setting is still in range */ + if ((sel * RTMV20_LSW_STEPUA + RTMV20_LSW_MINUA) < min_uA) + return -EINVAL; + + sel <<= ffs(rdev->desc->csel_mask) - 1; + + return regmap_update_bits(rdev->regmap, rdev->desc->csel_reg, + rdev->desc->csel_mask, sel); +} + +static int rtmv20_lsw_get_current_limit(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &val); + if (ret) + return ret; + + val &= rdev->desc->csel_mask; + val >>= ffs(rdev->desc->csel_mask) - 1; + + return val * RTMV20_LSW_STEPUA + RTMV20_LSW_MINUA; +} + static const struct regulator_ops rtmv20_regulator_ops = { - .set_current_limit = regulator_set_current_limit_regmap, - .get_current_limit = regulator_get_current_limit_regmap, + .set_current_limit = rtmv20_lsw_set_current_limit, + .get_current_limit = rtmv20_lsw_get_current_limit, .enable = rtmv20_lsw_enable, .disable = rtmv20_lsw_disable, .is_enabled = regulator_is_enabled_regmap, @@ -275,6 +314,7 @@ static const struct regmap_config rtmv20_regmap_config = { .val_bits = 8, .cache_type = REGCACHE_RBTREE, .max_register = RTMV20_REG_LDMASK, + .num_reg_defaults_raw = RTMV20_MAX_REGS, .writeable_reg = rtmv20_is_accessible_reg, .readable_reg = rtmv20_is_accessible_reg, diff --git a/drivers/regulator/uniphier-regulator.c b/drivers/regulator/uniphier-regulator.c index 2e02e26b516c..e75b0973e325 100644 --- a/drivers/regulator/uniphier-regulator.c +++ b/drivers/regulator/uniphier-regulator.c @@ -201,6 +201,7 @@ static const struct of_device_id uniphier_regulator_match[] = { }, { /* Sentinel */ }, }; +MODULE_DEVICE_TABLE(of, uniphier_regulator_match); static struct platform_driver uniphier_regulator_driver = { .probe = uniphier_regulator_probe, diff --git a/drivers/remoteproc/remoteproc_cdev.c b/drivers/remoteproc/remoteproc_cdev.c index b19ea3057bde..ff92ed25d8b0 100644 --- a/drivers/remoteproc/remoteproc_cdev.c +++ b/drivers/remoteproc/remoteproc_cdev.c @@ -111,7 +111,7 @@ int rproc_char_device_add(struct rproc *rproc) void rproc_char_device_remove(struct rproc *rproc) { - __unregister_chrdev(MAJOR(rproc->dev.devt), rproc->index, 1, "remoteproc"); + cdev_del(&rproc->cdev); } void __init rproc_init_cdev(void) diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 5ec0502c04c4..3cbb67494c44 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -2302,7 +2302,6 @@ int rproc_del(struct rproc *rproc) mutex_unlock(&rproc->lock); rproc_delete_debug_dir(rproc); - rproc_char_device_remove(rproc); /* the rproc is downref'ed as soon as it's removed from the klist */ mutex_lock(&rproc_list_mutex); @@ -2313,6 +2312,7 @@ int rproc_del(struct rproc *rproc) synchronize_rcu(); device_del(&rproc->dev); + rproc_char_device_remove(rproc); return 0; } diff --git a/drivers/remoteproc/ti_k3_r5_remoteproc.c b/drivers/remoteproc/ti_k3_r5_remoteproc.c index 61dd7fa7c8a9..7db908986814 100644 --- a/drivers/remoteproc/ti_k3_r5_remoteproc.c +++ b/drivers/remoteproc/ti_k3_r5_remoteproc.c @@ -1202,9 +1202,9 @@ static int k3_r5_core_of_init(struct platform_device *pdev) core->tsp = k3_r5_core_of_get_tsp(dev, core->ti_sci); if (IS_ERR(core->tsp)) { + ret = PTR_ERR(core->tsp); dev_err(dev, "failed to construct ti-sci proc control, ret = %d\n", ret); - ret = PTR_ERR(core->tsp); goto err; } diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 84baec01aa30..2dca113c0bab 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -52,7 +52,8 @@ config RESET_BRCMSTB config RESET_BRCMSTB_RESCAL bool "Broadcom STB RESCAL reset controller" depends on HAS_IOMEM - default ARCH_BRCMSTB || COMPILE_TEST + depends on ARCH_BRCMSTB || COMPILE_TEST + default ARCH_BRCMSTB help This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on BCM7216. @@ -75,6 +76,7 @@ config RESET_IMX7 config RESET_INTEL_GW bool "Intel Reset Controller Driver" + depends on X86 || COMPILE_TEST depends on OF && HAS_IOMEM select REGMAP_MMIO help diff --git a/drivers/reset/core.c b/drivers/reset/core.c index a2df88e90011..f93388b9a4a1 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -567,7 +567,10 @@ static struct reset_control *__reset_control_get_internal( if (!rstc) return ERR_PTR(-ENOMEM); - try_module_get(rcdev->owner); + if (!try_module_get(rcdev->owner)) { + kfree(rstc); + return ERR_PTR(-ENODEV); + } rstc->rcdev = rcdev; list_add(&rstc->list, &rcdev->reset_control_head); diff --git a/drivers/reset/reset-a10sr.c b/drivers/reset/reset-a10sr.c index 7eacc89382f8..99b3bc8382f3 100644 --- a/drivers/reset/reset-a10sr.c +++ b/drivers/reset/reset-a10sr.c @@ -118,6 +118,7 @@ static struct platform_driver a10sr_reset_driver = { .probe = a10sr_reset_probe, .driver = { .name = "altr_a10sr_reset", + .of_match_table = a10sr_reset_of_match, }, }; module_platform_driver(a10sr_reset_driver); diff --git a/drivers/reset/reset-brcmstb.c b/drivers/reset/reset-brcmstb.c index f213264c8567..42c9d5241c53 100644 --- a/drivers/reset/reset-brcmstb.c +++ b/drivers/reset/reset-brcmstb.c @@ -111,6 +111,7 @@ static const struct of_device_id brcmstb_reset_of_match[] = { { .compatible = "brcm,brcmstb-reset" }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, brcmstb_reset_of_match); static struct platform_driver brcmstb_reset_driver = { .probe = brcmstb_reset_probe, diff --git a/drivers/reset/reset-ti-syscon.c b/drivers/reset/reset-ti-syscon.c index ef97c4dbbb4e..742056a2a756 100644 --- a/drivers/reset/reset-ti-syscon.c +++ b/drivers/reset/reset-ti-syscon.c @@ -58,8 +58,8 @@ struct ti_syscon_reset_data { unsigned int nr_controls; }; -#define to_ti_syscon_reset_data(rcdev) \ - container_of(rcdev, struct ti_syscon_reset_data, rcdev) +#define to_ti_syscon_reset_data(_rcdev) \ + container_of(_rcdev, struct ti_syscon_reset_data, rcdev) /** * ti_syscon_reset_assert() - assert device reset diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c index ebd433fa09dd..8c51768e9a72 100644 --- a/drivers/reset/reset-zynqmp.c +++ b/drivers/reset/reset-zynqmp.c @@ -53,7 +53,8 @@ static int zynqmp_reset_status(struct reset_controller_dev *rcdev, unsigned long id) { struct zynqmp_reset_data *priv = to_zynqmp_reset_data(rcdev); - int val, err; + int err; + u32 val; err = zynqmp_pm_reset_get_status(priv->data->reset_id + id, &val); if (err) diff --git a/drivers/rtc/proc.c b/drivers/rtc/proc.c index 73344598fc1b..cbcdbb19d848 100644 --- a/drivers/rtc/proc.c +++ b/drivers/rtc/proc.c @@ -23,8 +23,8 @@ static bool is_rtc_hctosys(struct rtc_device *rtc) int size; char name[NAME_SIZE]; - size = scnprintf(name, NAME_SIZE, "rtc%d", rtc->id); - if (size > NAME_SIZE) + size = snprintf(name, NAME_SIZE, "rtc%d", rtc->id); + if (size >= NAME_SIZE) return false; return !strncmp(name, CONFIG_RTC_HCTOSYS_DEVICE, NAME_SIZE); diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index d51cc12114cb..eae7cb9faf1e 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -717,8 +717,8 @@ static int max77686_init_rtc_regmap(struct max77686_rtc_info *info) add_rtc_irq: ret = regmap_add_irq_chip(info->rtc_regmap, info->rtc_irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT | - IRQF_SHARED, 0, info->drv_data->rtc_irq_chip, + IRQF_ONESHOT | IRQF_SHARED, + 0, info->drv_data->rtc_irq_chip, &info->rtc_irq_data); if (ret < 0) { dev_err(info->dev, "Failed to add RTC irq chip: %d\n", ret); diff --git a/drivers/rtc/rtc-mxc_v2.c b/drivers/rtc/rtc-mxc_v2.c index 91534560fe2a..d349cef09cb7 100644 --- a/drivers/rtc/rtc-mxc_v2.c +++ b/drivers/rtc/rtc-mxc_v2.c @@ -373,6 +373,7 @@ static const struct of_device_id mxc_ids[] = { { .compatible = "fsl,imx53-rtc", }, {} }; +MODULE_DEVICE_TABLE(of, mxc_ids); static struct platform_driver mxc_rtc_driver = { .driver = { diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c index d774aa18f57a..d096b58cd06c 100644 --- a/drivers/rtc/rtc-stm32.c +++ b/drivers/rtc/rtc-stm32.c @@ -754,7 +754,7 @@ static int stm32_rtc_probe(struct platform_device *pdev) ret = clk_prepare_enable(rtc->rtc_ck); if (ret) - goto err; + goto err_no_rtc_ck; if (rtc->data->need_dbp) regmap_update_bits(rtc->dbp, rtc->dbp_reg, @@ -830,10 +830,12 @@ static int stm32_rtc_probe(struct platform_device *pdev) } return 0; + err: + clk_disable_unprepare(rtc->rtc_ck); +err_no_rtc_ck: if (rtc->data->has_pclk) clk_disable_unprepare(rtc->pclk); - clk_disable_unprepare(rtc->rtc_ck); if (rtc->data->need_dbp) regmap_update_bits(rtc->dbp, rtc->dbp_reg, rtc->dbp_mask, 0); diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 3f9a6ef650fa..3c2ed6d01387 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -35,8 +35,8 @@ #define SCLP_VT220_MINOR 65 #define SCLP_VT220_DRIVER_NAME "sclp_vt220" #define SCLP_VT220_DEVICE_NAME "ttysclp" -#define SCLP_VT220_CONSOLE_NAME "ttyS" -#define SCLP_VT220_CONSOLE_INDEX 1 /* console=ttyS1 */ +#define SCLP_VT220_CONSOLE_NAME "ttysclp" +#define SCLP_VT220_CONSOLE_INDEX 0 /* console=ttysclp0 */ /* Representation of a single write request */ struct sclp_vt220_request { diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index dfcbe54591fb..93e22785a0e0 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -255,6 +255,9 @@ static ssize_t chp_status_write(struct device *dev, if (!num_args) return count; + /* Wait until previous actions have settled. */ + css_wait_for_slow_path(); + if (!strncasecmp(cmd, "on", 2) || !strcmp(cmd, "1")) { mutex_lock(&cp->lock); error = s390_vary_chpid(cp->chpid, 1); diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index fc06a4002168..93aa7eabe8b1 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -757,8 +757,6 @@ int chsc_chp_vary(struct chp_id chpid, int on) { struct channel_path *chp = chpid_to_chp(chpid); - /* Wait until previous actions have settled. */ - css_wait_for_slow_path(); /* * Redo PathVerification on the devices the chpid connects to */ diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 8c625b530035..9b61e9b131ad 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -86,6 +86,7 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work) struct vfio_ccw_private *private; struct irb *irb; bool is_final; + bool cp_is_finished = false; private = container_of(work, struct vfio_ccw_private, io_work); irb = &private->irb; @@ -94,14 +95,21 @@ static void vfio_ccw_sch_io_todo(struct work_struct *work) (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)); if (scsw_is_solicited(&irb->scsw)) { cp_update_scsw(&private->cp, &irb->scsw); - if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING) + if (is_final && private->state == VFIO_CCW_STATE_CP_PENDING) { cp_free(&private->cp); + cp_is_finished = true; + } } mutex_lock(&private->io_mutex); memcpy(private->io_region->irb_area, irb, sizeof(*irb)); mutex_unlock(&private->io_mutex); - if (private->mdev && is_final) + /* + * Reset to IDLE only if processing of a channel program + * has finished. Do not overwrite a possible processing + * state if the final interrupt was for HSCH or CSCH. + */ + if (private->mdev && cp_is_finished) private->state = VFIO_CCW_STATE_IDLE; if (private->io_trigger) diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c index 23e61aa638e4..e435a9cd92da 100644 --- a/drivers/s390/cio/vfio_ccw_fsm.c +++ b/drivers/s390/cio/vfio_ccw_fsm.c @@ -318,6 +318,7 @@ static void fsm_io_request(struct vfio_ccw_private *private, } err_out: + private->state = VFIO_CCW_STATE_IDLE; trace_vfio_ccw_fsm_io_request(scsw->cmd.fctl, schid, io_region->ret_code, errstr); } diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 1ad5f7018ec2..2280f51dd679 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -276,8 +276,6 @@ static ssize_t vfio_ccw_mdev_write_io_region(struct vfio_ccw_private *private, } vfio_ccw_fsm_event(private, VFIO_CCW_EVENT_IO_REQ); - if (region->ret_code != 0) - private->state = VFIO_CCW_STATE_IDLE; ret = (region->ret_code != 0) ? region->ret_code : count; out_unlock: diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index ecefc25eff0c..337353c9655e 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -135,12 +135,13 @@ static struct ap_queue_status ap_sm_recv(struct ap_queue *aq) { struct ap_queue_status status; struct ap_message *ap_msg; + bool found = false; status = ap_dqap(aq->qid, &aq->reply->psmid, aq->reply->msg, aq->reply->len); switch (status.response_code) { case AP_RESPONSE_NORMAL: - aq->queue_count--; + aq->queue_count = max_t(int, 0, aq->queue_count - 1); if (aq->queue_count > 0) mod_timer(&aq->timeout, jiffies + aq->request_timeout); @@ -150,8 +151,14 @@ static struct ap_queue_status ap_sm_recv(struct ap_queue *aq) list_del_init(&ap_msg->list); aq->pendingq_count--; ap_msg->receive(aq, ap_msg, aq->reply); + found = true; break; } + if (!found) { + AP_DBF_WARN("%s unassociated reply psmid=0x%016llx on 0x%02x.%04x\n", + __func__, aq->reply->psmid, + AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid)); + } fallthrough; case AP_RESPONSE_NO_PENDING_REPLY: if (!status.queue_empty || aq->queue_count <= 0) @@ -232,7 +239,7 @@ static enum ap_sm_wait ap_sm_write(struct ap_queue *aq) ap_msg->flags & AP_MSG_FLAG_SPECIAL); switch (status.response_code) { case AP_RESPONSE_NORMAL: - aq->queue_count++; + aq->queue_count = max_t(int, 1, aq->queue_count + 1); if (aq->queue_count == 1) mod_timer(&aq->timeout, jiffies + aq->request_timeout); list_move_tail(&ap_msg->list, &aq->pendingq); diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 8d9662e8b717..3c7f5ecf5511 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -487,6 +487,7 @@ static ssize_t zfcp_sysfs_port_fc_security_show(struct device *dev, if (0 == (status & ZFCP_STATUS_COMMON_OPEN) || 0 == (status & ZFCP_STATUS_COMMON_UNBLOCKED) || 0 == (status & ZFCP_STATUS_PORT_PHYS_OPEN) || + 0 != (status & ZFCP_STATUS_PORT_LINK_TEST) || 0 != (status & ZFCP_STATUS_COMMON_ERP_FAILED) || 0 != (status & ZFCP_STATUS_COMMON_ACCESS_BOXED)) i = sprintf(buf, "unknown\n"); diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index 24ace1824048..ec8a621d232d 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -40,7 +40,7 @@ struct sccb_mgr_info { u16 si_per_targ_ultra_nego; u16 si_per_targ_no_disc; u16 si_per_targ_wide_nego; - u16 si_flags; + u16 si_mflags; unsigned char si_card_family; unsigned char si_bustype; unsigned char si_card_model[3]; @@ -1073,22 +1073,22 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) ScamFlg = (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2); - pCardInfo->si_flags = 0x0000; + pCardInfo->si_mflags = 0x0000; if (i & 0x01) - pCardInfo->si_flags |= SCSI_PARITY_ENA; + pCardInfo->si_mflags |= SCSI_PARITY_ENA; if (!(i & 0x02)) - pCardInfo->si_flags |= SOFT_RESET; + pCardInfo->si_mflags |= SOFT_RESET; if (i & 0x10) - pCardInfo->si_flags |= EXTENDED_TRANSLATION; + pCardInfo->si_mflags |= EXTENDED_TRANSLATION; if (ScamFlg & SCAM_ENABLED) - pCardInfo->si_flags |= FLAG_SCAM_ENABLED; + pCardInfo->si_mflags |= FLAG_SCAM_ENABLED; if (ScamFlg & SCAM_LEVEL2) - pCardInfo->si_flags |= FLAG_SCAM_LEVEL2; + pCardInfo->si_mflags |= FLAG_SCAM_LEVEL2; j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L); if (i & 0x04) { @@ -1104,7 +1104,7 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD)) - pCardInfo->si_flags |= SUPPORT_16TAR_32LUN; + pCardInfo->si_mflags |= SUPPORT_16TAR_32LUN; pCardInfo->si_card_family = HARPOON_FAMILY; pCardInfo->si_bustype = BUSTYPE_PCI; @@ -1140,15 +1140,15 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) if (pCardInfo->si_card_model[1] == '3') { if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= LOW_BYTE_TERM; + pCardInfo->si_mflags |= LOW_BYTE_TERM; } else if (pCardInfo->si_card_model[2] == '0') { temp = RD_HARPOON(ioport + hp_xfer_pad); WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4))); if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= LOW_BYTE_TERM; + pCardInfo->si_mflags |= LOW_BYTE_TERM; WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4))); if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)) - pCardInfo->si_flags |= HIGH_BYTE_TERM; + pCardInfo->si_mflags |= HIGH_BYTE_TERM; WR_HARPOON(ioport + hp_xfer_pad, temp); } else { temp = RD_HARPOON(ioport + hp_ee_ctrl); @@ -1166,9 +1166,9 @@ static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo) WR_HARPOON(ioport + hp_ee_ctrl, temp); WR_HARPOON(ioport + hp_xfer_pad, temp2); if (!(temp3 & BIT(7))) - pCardInfo->si_flags |= LOW_BYTE_TERM; + pCardInfo->si_mflags |= LOW_BYTE_TERM; if (!(temp3 & BIT(6))) - pCardInfo->si_flags |= HIGH_BYTE_TERM; + pCardInfo->si_mflags |= HIGH_BYTE_TERM; } ARAM_ACCESS(ioport); @@ -1275,7 +1275,7 @@ static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id); CurrCard->ourId = pCardInfo->si_id; - i = (unsigned char)pCardInfo->si_flags; + i = (unsigned char)pCardInfo->si_mflags; if (i & SCSI_PARITY_ENA) WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P)); @@ -1289,14 +1289,14 @@ static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info j |= SCSI_TERM_ENA_H; WR_HARPOON(ioport + hp_ee_ctrl, j); - if (!(pCardInfo->si_flags & SOFT_RESET)) { + if (!(pCardInfo->si_mflags & SOFT_RESET)) { FPT_sresb(ioport, thisCard); FPT_scini(thisCard, pCardInfo->si_id, 0); } - if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS) + if (pCardInfo->si_mflags & POST_ALL_UNDERRRUNS) CurrCard->globalFlags |= F_NO_FILTER; if (pCurrNvRam) { diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index 725bb7f58054..12fed15dec66 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -493,7 +493,7 @@ ahc_inq(struct ahc_softc *ahc, u_int port) return ((ahc_inb(ahc, port)) | (ahc_inb(ahc, port+1) << 8) | (ahc_inb(ahc, port+2) << 16) - | (ahc_inb(ahc, port+3) << 24) + | (((uint64_t)ahc_inb(ahc, port+3)) << 24) | (((uint64_t)ahc_inb(ahc, port+4)) << 32) | (((uint64_t)ahc_inb(ahc, port+5)) << 40) | (((uint64_t)ahc_inb(ahc, port+6)) << 48) diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index a195bfe9eccc..7a78606598c4 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -53,6 +53,7 @@ static struct scsi_host_template aic94xx_sht = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index e4fdb473b990..9294a2c677b3 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -1928,8 +1928,12 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr if (ccb->arc_cdb_size <= 0x300) arc_cdb_size = (ccb->arc_cdb_size - 1) >> 6 | 1; - else - arc_cdb_size = (((ccb->arc_cdb_size + 0xff) >> 8) + 2) << 1 | 1; + else { + arc_cdb_size = ((ccb->arc_cdb_size + 0xff) >> 8) + 2; + if (arc_cdb_size > 0xF) + arc_cdb_size = 0xF; + arc_cdb_size = (arc_cdb_size << 1) | 1; + } ccb_post_stamp = (ccb->smid | arc_cdb_size); writel(0, &pmu->inbound_queueport_high); writel(ccb_post_stamp, &pmu->inbound_queueport_low); @@ -2420,10 +2424,17 @@ static void arcmsr_hbaD_doorbell_isr(struct AdapterControlBlock *pACB) static void arcmsr_hbaE_doorbell_isr(struct AdapterControlBlock *pACB) { - uint32_t outbound_doorbell, in_doorbell, tmp; + uint32_t outbound_doorbell, in_doorbell, tmp, i; struct MessageUnit_E __iomem *reg = pACB->pmuE; - in_doorbell = readl(®->iobound_doorbell); + if (pACB->adapter_type == ACB_ADAPTER_TYPE_F) { + for (i = 0; i < 5; i++) { + in_doorbell = readl(®->iobound_doorbell); + if (in_doorbell != 0) + break; + } + } else + in_doorbell = readl(®->iobound_doorbell); outbound_doorbell = in_doorbell ^ pACB->in_doorbell; do { writel(0, ®->host_int_status); /* clear interrupt */ diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 5c3513a4b450..987dc8135a9b 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -416,7 +416,7 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev) "beiscsi_hba_alloc - iscsi_host_alloc failed\n"); return NULL; } - shost->max_id = BE2_MAX_SESSIONS; + shost->max_id = BE2_MAX_SESSIONS - 1; shost->max_channel = 0; shost->max_cmd_len = BEISCSI_MAX_CMD_LEN; shost->max_lun = BEISCSI_NUM_MAX_LUN; @@ -5318,7 +5318,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba) /* Re-enable UER. If different TPE occurs then it is recoverable. */ beiscsi_set_uer_feature(phba); - phba->shost->max_id = phba->params.cxns_per_ctrl; + phba->shost->max_id = phba->params.cxns_per_ctrl - 1; phba->shost->can_queue = phba->params.ios_per_ctrl; ret = beiscsi_init_port(phba); if (ret < 0) { @@ -5745,6 +5745,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev, pci_disable_msix(phba->pcidev); pci_dev_put(phba->pcidev); iscsi_host_free(phba->shost); + pci_disable_pcie_error_reporting(pcidev); pci_set_drvdata(pcidev, NULL); disable_pci: pci_release_regions(pcidev); diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 1a0dc18d6915..ed300a279a38 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -1220,6 +1220,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) was a result from the ABTS request rather than the CLEANUP request */ set_bit(BNX2FC_FLAG_IO_CLEANUP, &io_req->req_flags); + rc = FAILED; goto done; } diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index fdd446765311..21efc73b87be 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -791,7 +791,7 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) return NULL; shost->dma_boundary = cnic->pcidev->dma_mask; shost->transportt = bnx2i_scsi_xport_template; - shost->max_id = ISCSI_MAX_CONNS_PER_HBA; + shost->max_id = ISCSI_MAX_CONNS_PER_HBA - 1; shost->max_channel = 0; shost->max_lun = 512; shost->max_cmd_len = 16; diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index f078b3c4e083..ecb134b4699f 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -337,7 +337,7 @@ void cxgbi_hbas_remove(struct cxgbi_device *cdev) EXPORT_SYMBOL_GPL(cxgbi_hbas_remove); int cxgbi_hbas_add(struct cxgbi_device *cdev, u64 max_lun, - unsigned int max_id, struct scsi_host_template *sht, + unsigned int max_conns, struct scsi_host_template *sht, struct scsi_transport_template *stt) { struct cxgbi_hba *chba; @@ -357,7 +357,7 @@ int cxgbi_hbas_add(struct cxgbi_device *cdev, u64 max_lun, shost->transportt = stt; shost->max_lun = max_lun; - shost->max_id = max_id; + shost->max_id = max_conns - 1; shost->max_channel = 0; shost->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE; diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index df5a3bbeba5e..fe8a5e5c0df8 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -508,7 +508,8 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) struct alua_port_group *tmp_pg; int len, k, off, bufflen = ALUA_RTPG_SIZE; unsigned char *desc, *buff; - unsigned err, retval; + unsigned err; + int retval; unsigned int tpg_desc_tbl_off; unsigned char orig_transition_tmo; unsigned long flags; @@ -548,12 +549,12 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) kfree(buff); return SCSI_DH_OK; } - if (!scsi_sense_valid(&sense_hdr)) { + if (retval < 0 || !scsi_sense_valid(&sense_hdr)) { sdev_printk(KERN_INFO, sdev, "%s: rtpg failed, result %d\n", ALUA_DH_NAME, retval); kfree(buff); - if (driver_byte(retval) == DRIVER_ERROR) + if (retval < 0) return SCSI_DH_DEV_TEMP_BUSY; return SCSI_DH_IO; } @@ -775,11 +776,11 @@ static unsigned alua_stpg(struct scsi_device *sdev, struct alua_port_group *pg) retval = submit_stpg(sdev, pg->group_id, &sense_hdr); if (retval) { - if (!scsi_sense_valid(&sense_hdr)) { + if (retval < 0 || !scsi_sense_valid(&sense_hdr)) { sdev_printk(KERN_INFO, sdev, "%s: stpg failed, result %d", ALUA_DH_NAME, retval); - if (driver_byte(retval) == DRIVER_ERROR) + if (retval < 0) return SCSI_DH_DEV_TEMP_BUSY; } else { sdev_printk(KERN_INFO, sdev, "%s: stpg failed\n", diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 5efc959493ec..85a71bafaea7 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -453,8 +453,8 @@ static int initialize_controller(struct scsi_device *sdev, if (!h->ctlr) err = SCSI_DH_RES_TEMP_UNAVAIL; else { - list_add_rcu(&h->node, &h->ctlr->dh_list); h->sdev = sdev; + list_add_rcu(&h->node, &h->ctlr->dh_list); } spin_unlock(&list_lock); err = SCSI_DH_OK; @@ -778,11 +778,11 @@ static void rdac_bus_detach( struct scsi_device *sdev ) spin_lock(&list_lock); if (h->ctlr) { list_del_rcu(&h->node); - h->sdev = NULL; kref_put(&h->ctlr->kref, release_controller); } spin_unlock(&list_lock); sdev->handler_data = NULL; + synchronize_rcu(); kfree(h); } diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 6c2a97f80b12..2c1028183b24 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1647,7 +1647,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) if (irq < 0) { dev_err(dev, "irq init: fail map phy interrupt %d\n", idx); - return -ENOENT; + return irq; } rc = devm_request_irq(dev, irq, phy_interrupts[j], 0, @@ -1655,7 +1655,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) if (rc) { dev_err(dev, "irq init: could not request phy interrupt %d, rc=%d\n", irq, rc); - return -ENOENT; + return rc; } } } @@ -1666,7 +1666,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) if (irq < 0) { dev_err(dev, "irq init: could not map cq interrupt %d\n", idx); - return -ENOENT; + return irq; } rc = devm_request_irq(dev, irq, cq_interrupt_v1_hw, 0, @@ -1674,7 +1674,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) if (rc) { dev_err(dev, "irq init: could not request cq interrupt %d, rc=%d\n", irq, rc); - return -ENOENT; + return rc; } } @@ -1684,7 +1684,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) if (irq < 0) { dev_err(dev, "irq init: could not map fatal interrupt %d\n", idx); - return -ENOENT; + return irq; } rc = devm_request_irq(dev, irq, fatal_interrupts[i], 0, @@ -1692,7 +1692,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) if (rc) { dev_err(dev, "irq init: could not request fatal interrupt %d, rc=%d\n", irq, rc); - return -ENOENT; + return rc; } } @@ -1769,6 +1769,7 @@ static struct scsi_host_template sht_v1_hw = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 6ef8730c61a6..b75d54339e40 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -3545,6 +3545,7 @@ static struct scsi_host_template sht_v2_hw = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 19170c7ac336..50a1c3478a6e 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -3126,6 +3126,7 @@ static struct scsi_host_template sht_v3_hw = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT @@ -3359,14 +3360,14 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba) { int i; - free_irq(pci_irq_vector(pdev, 1), hisi_hba); - free_irq(pci_irq_vector(pdev, 2), hisi_hba); - free_irq(pci_irq_vector(pdev, 11), hisi_hba); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 1), hisi_hba); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 2), hisi_hba); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, 11), hisi_hba); for (i = 0; i < hisi_hba->cq_nvecs; i++) { struct hisi_sas_cq *cq = &hisi_hba->cq[i]; int nr = hisi_sas_intr_conv ? 16 : 16 + i; - free_irq(pci_irq_vector(pdev, nr), cq); + devm_free_irq(&pdev->dev, pci_irq_vector(pdev, nr), cq); } pci_free_irq_vectors(pdev); } diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 2f162603876f..da3920a19d53 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -220,6 +220,9 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, goto fail; } + shost->cmd_per_lun = min_t(short, shost->cmd_per_lun, + shost->can_queue); + error = scsi_init_sense_cache(shost); if (error) goto fail; @@ -254,12 +257,11 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, device_enable_async_suspend(&shost->shost_dev); + get_device(&shost->shost_gendev); error = device_add(&shost->shost_dev); if (error) goto out_del_gendev; - get_device(&shost->shost_gendev); - if (shost->transportt->host_size) { shost->shost_data = kzalloc(shost->transportt->host_size, GFP_KERNEL); @@ -278,33 +280,36 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, if (!shost->work_q) { error = -EINVAL; - goto out_free_shost_data; + goto out_del_dev; } } error = scsi_sysfs_add_host(shost); if (error) - goto out_destroy_host; + goto out_del_dev; scsi_proc_host_add(shost); scsi_autopm_put_host(shost); return error; - out_destroy_host: - if (shost->work_q) - destroy_workqueue(shost->work_q); - out_free_shost_data: - kfree(shost->shost_data); + /* + * Any host allocation in this function will be freed in + * scsi_host_dev_release(). + */ out_del_dev: device_del(&shost->shost_dev); out_del_gendev: + /* + * Host state is SHOST_RUNNING so we have to explicitly release + * ->shost_dev. + */ + put_device(&shost->shost_dev); device_del(&shost->shost_gendev); out_disable_runtime_pm: device_disable_async_suspend(&shost->shost_gendev); pm_runtime_disable(&shost->shost_gendev); pm_runtime_set_suspended(&shost->shost_gendev); pm_runtime_put_noidle(&shost->shost_gendev); - scsi_mq_destroy_tags(shost); fail: return error; } @@ -345,7 +350,7 @@ static void scsi_host_dev_release(struct device *dev) ida_simple_remove(&host_index_ida, shost->host_no); - if (parent) + if (shost->shost_state != SHOST_CREATED) put_device(parent); kfree(shost); } @@ -392,8 +397,10 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) mutex_init(&shost->scan_mutex); index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL); - if (index < 0) - goto fail_kfree; + if (index < 0) { + kfree(shost); + return NULL; + } shost->host_no = index; shost->dma_channel = 0xff; @@ -486,7 +493,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) shost_printk(KERN_WARNING, shost, "error handler thread failed to spawn, error = %ld\n", PTR_ERR(shost->ehandler)); - goto fail_index_remove; + shost->ehandler = NULL; + goto fail; } shost->tmf_work_q = alloc_workqueue("scsi_tmf_%d", @@ -495,17 +503,18 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) if (!shost->tmf_work_q) { shost_printk(KERN_WARNING, shost, "failed to create tmf workq\n"); - goto fail_kthread; + goto fail; } scsi_proc_hostdir_add(shost->hostt); return shost; + fail: + /* + * Host state is still SHOST_CREATED and that is enough to release + * ->shost_gendev. scsi_host_dev_release() will free + * dev_name(&shost->shost_dev). + */ + put_device(&shost->shost_gendev); - fail_kthread: - kthread_stop(shost->ehandler); - fail_index_remove: - ida_simple_remove(&host_index_ida, shost->host_no); - fail_kfree: - kfree(shost); return NULL; } EXPORT_SYMBOL(scsi_host_alloc); diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index 93bc9019667f..9d7cc62ace2e 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -167,6 +167,7 @@ static struct scsi_host_template isci_sht = { .eh_abort_handler = sas_eh_abort_handler, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index a60b228d13f1..f40edb0dab70 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -1162,6 +1162,7 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK); FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x spp_type 0x%x\n", pp->spp.spp_flags, pp->spp.spp_type); + rdata->spp_type = pp->spp.spp_type; if (resp_code != FC_SPP_RESP_ACK) { if (resp_code == FC_SPP_RESP_CONF) @@ -1184,11 +1185,13 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, /* * Call prli provider if we should act as a target */ - prov = fc_passive_prov[rdata->spp_type]; - if (prov) { - memset(&temp_spp, 0, sizeof(temp_spp)); - prov->prli(rdata, pp->prli.prli_spp_len, - &pp->spp, &temp_spp); + if (rdata->spp_type < FC_FC4_PROV_SIZE) { + prov = fc_passive_prov[rdata->spp_type]; + if (prov) { + memset(&temp_spp, 0, sizeof(temp_spp)); + prov->prli(rdata, pp->prli.prli_spp_len, + &pp->spp, &temp_spp); + } } /* * Check if the image pair could be established diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 41b8192d207d..30d27b670674 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -230,11 +230,11 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_task *task) */ static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode) { - struct iscsi_conn *conn = task->conn; - struct iscsi_tm *tmf = &conn->tmhdr; + struct iscsi_session *session = task->conn->session; + struct iscsi_tm *tmf = &session->tmhdr; u64 hdr_lun; - if (conn->tmf_state == TMF_INITIAL) + if (session->tmf_state == TMF_INITIAL) return 0; if ((tmf->opcode & ISCSI_OPCODE_MASK) != ISCSI_OP_SCSI_TMFUNC) @@ -254,24 +254,19 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode) * Fail all SCSI cmd PDUs */ if (opcode != ISCSI_OP_SCSI_DATA_OUT) { - iscsi_conn_printk(KERN_INFO, conn, - "task [op %x itt " - "0x%x/0x%x] " - "rejected.\n", - opcode, task->itt, - task->hdr_itt); + iscsi_session_printk(KERN_INFO, session, + "task [op %x itt 0x%x/0x%x] rejected.\n", + opcode, task->itt, task->hdr_itt); return -EACCES; } /* * And also all data-out PDUs in response to R2T * if fast_abort is set. */ - if (conn->session->fast_abort) { - iscsi_conn_printk(KERN_INFO, conn, - "task [op %x itt " - "0x%x/0x%x] fast abort.\n", - opcode, task->itt, - task->hdr_itt); + if (session->fast_abort) { + iscsi_session_printk(KERN_INFO, session, + "task [op %x itt 0x%x/0x%x] fast abort.\n", + opcode, task->itt, task->hdr_itt); return -EACCES; } break; @@ -284,7 +279,7 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode) */ if (opcode == ISCSI_OP_SCSI_DATA_OUT && task->hdr_itt == tmf->rtt) { - ISCSI_DBG_SESSION(conn->session, + ISCSI_DBG_SESSION(session, "Preventing task %x/%x from sending " "data-out due to abort task in " "progress\n", task->itt, @@ -923,20 +918,21 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) { struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr; + struct iscsi_session *session = conn->session; conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; conn->tmfrsp_pdus_cnt++; - if (conn->tmf_state != TMF_QUEUED) + if (session->tmf_state != TMF_QUEUED) return; if (tmf->response == ISCSI_TMF_RSP_COMPLETE) - conn->tmf_state = TMF_SUCCESS; + session->tmf_state = TMF_SUCCESS; else if (tmf->response == ISCSI_TMF_RSP_NO_TASK) - conn->tmf_state = TMF_NOT_FOUND; + session->tmf_state = TMF_NOT_FOUND; else - conn->tmf_state = TMF_FAILED; - wake_up(&conn->ehwait); + session->tmf_state = TMF_FAILED; + wake_up(&session->ehwait); } static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) @@ -1348,7 +1344,6 @@ void iscsi_session_failure(struct iscsi_session *session, enum iscsi_err err) { struct iscsi_conn *conn; - struct device *dev; spin_lock_bh(&session->frwd_lock); conn = session->leadconn; @@ -1357,10 +1352,8 @@ void iscsi_session_failure(struct iscsi_session *session, return; } - dev = get_device(&conn->cls_conn->dev); + iscsi_get_conn(conn->cls_conn); spin_unlock_bh(&session->frwd_lock); - if (!dev) - return; /* * if the host is being removed bypass the connection * recovery initialization because we are going to kill @@ -1370,7 +1363,7 @@ void iscsi_session_failure(struct iscsi_session *session, iscsi_conn_error_event(conn->cls_conn, err); else iscsi_conn_failure(conn, err); - put_device(dev); + iscsi_put_conn(conn->cls_conn); } EXPORT_SYMBOL_GPL(iscsi_session_failure); @@ -1787,15 +1780,14 @@ EXPORT_SYMBOL_GPL(iscsi_target_alloc); static void iscsi_tmf_timedout(struct timer_list *t) { - struct iscsi_conn *conn = from_timer(conn, t, tmf_timer); - struct iscsi_session *session = conn->session; + struct iscsi_session *session = from_timer(session, t, tmf_timer); spin_lock(&session->frwd_lock); - if (conn->tmf_state == TMF_QUEUED) { - conn->tmf_state = TMF_TIMEDOUT; + if (session->tmf_state == TMF_QUEUED) { + session->tmf_state = TMF_TIMEDOUT; ISCSI_DBG_EH(session, "tmf timedout\n"); /* unblock eh_abort() */ - wake_up(&conn->ehwait); + wake_up(&session->ehwait); } spin_unlock(&session->frwd_lock); } @@ -1818,8 +1810,8 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, return -EPERM; } conn->tmfcmd_pdus_cnt++; - conn->tmf_timer.expires = timeout * HZ + jiffies; - add_timer(&conn->tmf_timer); + session->tmf_timer.expires = timeout * HZ + jiffies; + add_timer(&session->tmf_timer); ISCSI_DBG_EH(session, "tmf set timeout\n"); spin_unlock_bh(&session->frwd_lock); @@ -1833,12 +1825,12 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, * 3) session is terminated or restarted or userspace has * given up on recovery */ - wait_event_interruptible(conn->ehwait, age != session->age || + wait_event_interruptible(session->ehwait, age != session->age || session->state != ISCSI_STATE_LOGGED_IN || - conn->tmf_state != TMF_QUEUED); + session->tmf_state != TMF_QUEUED); if (signal_pending(current)) flush_signals(current); - del_timer_sync(&conn->tmf_timer); + del_timer_sync(&session->tmf_timer); mutex_lock(&session->eh_mutex); spin_lock_bh(&session->frwd_lock); @@ -2198,17 +2190,17 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) } /* only have one tmf outstanding at a time */ - if (conn->tmf_state != TMF_INITIAL) + if (session->tmf_state != TMF_INITIAL) goto failed; - conn->tmf_state = TMF_QUEUED; + session->tmf_state = TMF_QUEUED; - hdr = &conn->tmhdr; + hdr = &session->tmhdr; iscsi_prep_abort_task_pdu(task, hdr); if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) goto failed; - switch (conn->tmf_state) { + switch (session->tmf_state) { case TMF_SUCCESS: spin_unlock_bh(&session->frwd_lock); /* @@ -2223,7 +2215,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) */ spin_lock_bh(&session->frwd_lock); fail_scsi_task(task, DID_ABORT); - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; memset(hdr, 0, sizeof(*hdr)); spin_unlock_bh(&session->frwd_lock); iscsi_start_tx(conn); @@ -2234,7 +2226,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) goto failed_unlocked; case TMF_NOT_FOUND: if (!sc->SCp.ptr) { - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; memset(hdr, 0, sizeof(*hdr)); /* task completed before tmf abort response */ ISCSI_DBG_EH(session, "sc completed while abort in " @@ -2243,7 +2235,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) } fallthrough; default: - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; goto failed; } @@ -2300,11 +2292,11 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) conn = session->leadconn; /* only have one tmf outstanding at a time */ - if (conn->tmf_state != TMF_INITIAL) + if (session->tmf_state != TMF_INITIAL) goto unlock; - conn->tmf_state = TMF_QUEUED; + session->tmf_state = TMF_QUEUED; - hdr = &conn->tmhdr; + hdr = &session->tmhdr; iscsi_prep_lun_reset_pdu(sc, hdr); if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, @@ -2313,7 +2305,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) goto unlock; } - switch (conn->tmf_state) { + switch (session->tmf_state) { case TMF_SUCCESS: break; case TMF_TIMEDOUT: @@ -2321,7 +2313,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST); goto done; default: - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; goto unlock; } @@ -2333,7 +2325,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) spin_lock_bh(&session->frwd_lock); memset(hdr, 0, sizeof(*hdr)); fail_scsi_tasks(conn, sc->device->lun, DID_ERROR); - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; spin_unlock_bh(&session->frwd_lock); iscsi_start_tx(conn); @@ -2356,8 +2348,7 @@ void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) spin_lock_bh(&session->frwd_lock); if (session->state != ISCSI_STATE_LOGGED_IN) { session->state = ISCSI_STATE_RECOVERY_FAILED; - if (session->leadconn) - wake_up(&session->leadconn->ehwait); + wake_up(&session->ehwait); } spin_unlock_bh(&session->frwd_lock); } @@ -2402,7 +2393,7 @@ int iscsi_eh_session_reset(struct scsi_cmnd *sc) iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST); ISCSI_DBG_EH(session, "wait for relogin\n"); - wait_event_interruptible(conn->ehwait, + wait_event_interruptible(session->ehwait, session->state == ISCSI_STATE_TERMINATE || session->state == ISCSI_STATE_LOGGED_IN || session->state == ISCSI_STATE_RECOVERY_FAILED); @@ -2463,11 +2454,11 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc) conn = session->leadconn; /* only have one tmf outstanding at a time */ - if (conn->tmf_state != TMF_INITIAL) + if (session->tmf_state != TMF_INITIAL) goto unlock; - conn->tmf_state = TMF_QUEUED; + session->tmf_state = TMF_QUEUED; - hdr = &conn->tmhdr; + hdr = &session->tmhdr; iscsi_prep_tgt_reset_pdu(sc, hdr); if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, @@ -2476,7 +2467,7 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc) goto unlock; } - switch (conn->tmf_state) { + switch (session->tmf_state) { case TMF_SUCCESS: break; case TMF_TIMEDOUT: @@ -2484,7 +2475,7 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc) iscsi_conn_failure(conn, ISCSI_ERR_SCSI_EH_SESSION_RST); goto done; default: - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; goto unlock; } @@ -2496,7 +2487,7 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc) spin_lock_bh(&session->frwd_lock); memset(hdr, 0, sizeof(*hdr)); fail_scsi_tasks(conn, -1, DID_ERROR); - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; spin_unlock_bh(&session->frwd_lock); iscsi_start_tx(conn); @@ -2803,7 +2794,10 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, session->tt = iscsit; session->dd_data = cls_session->dd_data + sizeof(*session); + session->tmf_state = TMF_INITIAL; + timer_setup(&session->tmf_timer, iscsi_tmf_timedout, 0); mutex_init(&session->eh_mutex); + spin_lock_init(&session->frwd_lock); spin_lock_init(&session->back_lock); @@ -2907,7 +2901,6 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, conn->c_stage = ISCSI_CONN_INITIAL_STAGE; conn->id = conn_idx; conn->exp_statsn = 0; - conn->tmf_state = TMF_INITIAL; timer_setup(&conn->transport_timer, iscsi_check_transport_timeouts, 0); @@ -2933,8 +2926,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, goto login_task_data_alloc_fail; conn->login_task->data = conn->data = data; - timer_setup(&conn->tmf_timer, iscsi_tmf_timedout, 0); - init_waitqueue_head(&conn->ehwait); + init_waitqueue_head(&session->ehwait); return cls_conn; @@ -2969,7 +2961,7 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) * leading connection? then give up on recovery. */ session->state = ISCSI_STATE_TERMINATE; - wake_up(&conn->ehwait); + wake_up(&session->ehwait); } spin_unlock_bh(&session->frwd_lock); @@ -3044,7 +3036,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) * commands after successful recovery */ conn->stop_stage = 0; - conn->tmf_state = TMF_INITIAL; + session->tmf_state = TMF_INITIAL; session->age++; if (session->age == 16) session->age = 0; @@ -3058,7 +3050,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) spin_unlock_bh(&session->frwd_lock); iscsi_unblock_session(session->cls_session); - wake_up(&conn->ehwait); + wake_up(&session->ehwait); return 0; } EXPORT_SYMBOL_GPL(iscsi_conn_start); @@ -3089,9 +3081,10 @@ fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn) } } -static void iscsi_start_session_recovery(struct iscsi_session *session, - struct iscsi_conn *conn, int flag) +void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) { + struct iscsi_conn *conn = cls_conn->dd_data; + struct iscsi_session *session = conn->session; int old_stop_stage; mutex_lock(&session->eh_mutex); @@ -3145,31 +3138,10 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, spin_lock_bh(&session->frwd_lock); fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED); fail_mgmt_tasks(session, conn); - memset(&conn->tmhdr, 0, sizeof(conn->tmhdr)); + memset(&session->tmhdr, 0, sizeof(session->tmhdr)); spin_unlock_bh(&session->frwd_lock); mutex_unlock(&session->eh_mutex); } - -void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) -{ - struct iscsi_conn *conn = cls_conn->dd_data; - struct iscsi_session *session = conn->session; - - switch (flag) { - case STOP_CONN_RECOVER: - cls_conn->state = ISCSI_CONN_FAILED; - break; - case STOP_CONN_TERM: - cls_conn->state = ISCSI_CONN_DOWN; - break; - default: - iscsi_conn_printk(KERN_ERR, conn, - "invalid stop flag %d\n", flag); - return; - } - - iscsi_start_session_recovery(session, conn, flag); -} EXPORT_SYMBOL_GPL(iscsi_conn_stop); int iscsi_conn_bind(struct iscsi_cls_session *cls_session, diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 1bf939818c98..ee44a0d7730b 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -911,6 +911,14 @@ void sas_task_abort(struct sas_task *task) blk_abort_request(sc->request); } +int sas_slave_alloc(struct scsi_device *sdev) +{ + if (dev_is_sata(sdev_to_domain_dev(sdev)) && sdev->lun) + return -ENXIO; + + return 0; +} + void sas_target_destroy(struct scsi_target *starget) { struct domain_device *found_dev = starget->hostdata; @@ -957,5 +965,6 @@ EXPORT_SYMBOL_GPL(sas_task_abort); EXPORT_SYMBOL_GPL(sas_phy_reset); EXPORT_SYMBOL_GPL(sas_eh_device_reset_handler); EXPORT_SYMBOL_GPL(sas_eh_target_reset_handler); +EXPORT_SYMBOL_GPL(sas_slave_alloc); EXPORT_SYMBOL_GPL(sas_target_destroy); EXPORT_SYMBOL_GPL(sas_ioctl); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index b60945182db8..3d9889b3d5c8 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1179,6 +1179,15 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, phba->fcf.fcf_redisc_attempted = 0; /* reset */ goto out; } + } else if (vport->port_state > LPFC_FLOGI && + vport->fc_flag & FC_PT2PT) { + /* + * In a p2p topology, it is possible that discovery has + * already progressed, and this completion can be ignored. + * Recheck the indicated topology. + */ + if (!sp->cmn.fPort) + goto out; } flogifail: diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 2dde5ddc687d..37612299a34a 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -13080,6 +13080,8 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) if (!phba) return -ENOMEM; + INIT_LIST_HEAD(&phba->poll_list); + /* Perform generic PCI device enabling operation */ error = lpfc_enable_pci_dev(phba); if (error) @@ -13214,7 +13216,6 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) /* Enable RAS FW log support */ lpfc_sli4_ras_setup(phba); - INIT_LIST_HEAD(&phba->poll_list); timer_setup(&phba->cpuhp_poll_timer, lpfc_sli4_poll_hbtimer, 0); cpuhp_state_add_instance_nocalls(lpfc_cpuhp_state, &phba->cpuhp); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index bf171ef61abd..990b700de689 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -7825,7 +7825,7 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) "0393 Error %d during rpi post operation\n", rc); rc = -ENODEV; - goto out_destroy_queue; + goto out_free_iocblist; } lpfc_sli4_node_prep(phba); @@ -7991,8 +7991,9 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) out_unset_queue: /* Unset all the queues set up in this routine when error out */ lpfc_sli4_queue_unset(phba); -out_destroy_queue: +out_free_iocblist: lpfc_free_iocb_list(phba); +out_destroy_queue: lpfc_sli4_queue_destroy(phba); out_stop_timers: lpfc_stop_hba_timers(phba); diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 8df53446641a..422b726e2ac1 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -238,7 +238,7 @@ mraid_mm_get_adapter(mimd_t __user *umimd, int *rval) mimd_t mimd; uint32_t adapno; int iterator; - + bool is_found; if (copy_from_user(&mimd, umimd, sizeof(mimd_t))) { *rval = -EFAULT; @@ -254,12 +254,16 @@ mraid_mm_get_adapter(mimd_t __user *umimd, int *rval) adapter = NULL; iterator = 0; + is_found = false; list_for_each_entry(adapter, &adapters_list_g, list) { - if (iterator++ == adapno) break; + if (iterator++ == adapno) { + is_found = true; + break; + } } - if (!adapter) { + if (!is_found) { *rval = -ENODEV; return NULL; } @@ -725,6 +729,7 @@ ioctl_done(uioc_t *kioc) uint32_t adapno; int iterator; mraid_mmadp_t* adapter; + bool is_found; /* * When the kioc returns from driver, make sure it still doesn't @@ -747,19 +752,23 @@ ioctl_done(uioc_t *kioc) iterator = 0; adapter = NULL; adapno = kioc->adapno; + is_found = false; con_log(CL_ANN, ( KERN_WARNING "megaraid cmm: completed " "ioctl that was timedout before\n")); list_for_each_entry(adapter, &adapters_list_g, list) { - if (iterator++ == adapno) break; + if (iterator++ == adapno) { + is_found = true; + break; + } } kioc->timedout = 0; - if (adapter) { + if (is_found) mraid_mm_dealloc_kioc( adapter, kioc ); - } + } else { wake_up(&wait_q); diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 5e4137f10e0e..6b8ec57e8bdf 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2259,6 +2259,15 @@ enum MR_PERF_MODE { (mode) == MR_LATENCY_PERF_MODE ? "Latency" : \ "Unknown") +enum MEGASAS_LD_TARGET_ID_STATUS { + LD_TARGET_ID_INITIAL, + LD_TARGET_ID_ACTIVE, + LD_TARGET_ID_DELETED, +}; + +#define MEGASAS_TARGET_ID(sdev) \ + (((sdev->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id) + struct megasas_instance { unsigned int *reply_map; @@ -2323,6 +2332,9 @@ struct megasas_instance { struct megasas_pd_list pd_list[MEGASAS_MAX_PD]; struct megasas_pd_list local_pd_list[MEGASAS_MAX_PD]; u8 ld_ids[MEGASAS_MAX_LD_IDS]; + u8 ld_tgtid_status[MEGASAS_MAX_LD_IDS]; + u8 ld_ids_prev[MEGASAS_MAX_LD_IDS]; + u8 ld_ids_from_raidmap[MEGASAS_MAX_LD_IDS]; s8 init_id; u16 max_num_sge; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index cc45cdac1384..1a70cc995c28 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -127,6 +127,8 @@ static int megasas_register_aen(struct megasas_instance *instance, u32 seq_num, u32 class_locale_word); static void megasas_get_pd_info(struct megasas_instance *instance, struct scsi_device *sdev); +static void +megasas_set_ld_removed_by_fw(struct megasas_instance *instance); /* * PCI ID table for all supported controllers @@ -421,6 +423,12 @@ megasas_decode_evt(struct megasas_instance *instance) (class_locale.members.locale), format_class(class_locale.members.class), evt_detail->description); + + if (megasas_dbg_lvl & LD_PD_DEBUG) + dev_info(&instance->pdev->dev, + "evt_detail.args.ld.target_id/index %d/%d\n", + evt_detail->args.ld.target_id, evt_detail->args.ld.ld_index); + } /* @@ -1764,6 +1772,7 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) { struct megasas_instance *instance; struct MR_PRIV_DEVICE *mr_device_priv_data; + u32 ld_tgt_id; instance = (struct megasas_instance *) scmd->device->host->hostdata; @@ -1790,17 +1799,21 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) } } - if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) { + mr_device_priv_data = scmd->device->hostdata; + if (!mr_device_priv_data || + (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR)) { scmd->result = DID_NO_CONNECT << 16; scmd->scsi_done(scmd); return 0; } - mr_device_priv_data = scmd->device->hostdata; - if (!mr_device_priv_data) { - scmd->result = DID_NO_CONNECT << 16; - scmd->scsi_done(scmd); - return 0; + if (MEGASAS_IS_LOGICAL(scmd->device)) { + ld_tgt_id = MEGASAS_TARGET_ID(scmd->device); + if (instance->ld_tgtid_status[ld_tgt_id] == LD_TARGET_ID_DELETED) { + scmd->result = DID_NO_CONNECT << 16; + scmd->scsi_done(scmd); + return 0; + } } if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) @@ -2080,7 +2093,7 @@ static int megasas_slave_configure(struct scsi_device *sdev) static int megasas_slave_alloc(struct scsi_device *sdev) { - u16 pd_index = 0; + u16 pd_index = 0, ld_tgt_id; struct megasas_instance *instance ; struct MR_PRIV_DEVICE *mr_device_priv_data; @@ -2105,6 +2118,14 @@ static int megasas_slave_alloc(struct scsi_device *sdev) GFP_KERNEL); if (!mr_device_priv_data) return -ENOMEM; + + if (MEGASAS_IS_LOGICAL(sdev)) { + ld_tgt_id = MEGASAS_TARGET_ID(sdev); + instance->ld_tgtid_status[ld_tgt_id] = LD_TARGET_ID_ACTIVE; + if (megasas_dbg_lvl & LD_PD_DEBUG) + sdev_printk(KERN_INFO, sdev, "LD target ID %d created.\n", ld_tgt_id); + } + sdev->hostdata = mr_device_priv_data; atomic_set(&mr_device_priv_data->r1_ldio_hint, @@ -2114,6 +2135,19 @@ static int megasas_slave_alloc(struct scsi_device *sdev) static void megasas_slave_destroy(struct scsi_device *sdev) { + u16 ld_tgt_id; + struct megasas_instance *instance; + + instance = megasas_lookup_instance(sdev->host->host_no); + + if (MEGASAS_IS_LOGICAL(sdev)) { + ld_tgt_id = MEGASAS_TARGET_ID(sdev); + instance->ld_tgtid_status[ld_tgt_id] = LD_TARGET_ID_DELETED; + if (megasas_dbg_lvl & LD_PD_DEBUG) + sdev_printk(KERN_INFO, sdev, + "LD target ID %d removed from OS stack\n", ld_tgt_id); + } + kfree(sdev->hostdata); sdev->hostdata = NULL; } @@ -3472,6 +3506,22 @@ megasas_complete_abort(struct megasas_instance *instance, } } +static void +megasas_set_ld_removed_by_fw(struct megasas_instance *instance) +{ + uint i; + + for (i = 0; (i < MEGASAS_MAX_LD_IDS); i++) { + if (instance->ld_ids_prev[i] != 0xff && + instance->ld_ids_from_raidmap[i] == 0xff) { + if (megasas_dbg_lvl & LD_PD_DEBUG) + dev_info(&instance->pdev->dev, + "LD target ID %d removed from RAID map\n", i); + instance->ld_tgtid_status[i] = LD_TARGET_ID_DELETED; + } + } +} + /** * megasas_complete_cmd - Completes a command * @instance: Adapter soft state @@ -3634,9 +3684,13 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, fusion->fast_path_io = 0; } + if (instance->adapter_type >= INVADER_SERIES) + megasas_set_ld_removed_by_fw(instance); + megasas_sync_map_info(instance); spin_unlock_irqrestore(instance->host->host_lock, flags); + break; } if (opcode == MR_DCMD_CTRL_EVENT_GET_INFO || @@ -7439,11 +7493,16 @@ static int megasas_probe_one(struct pci_dev *pdev, return 0; fail_start_aen: + instance->unload = 1; + scsi_remove_host(instance->host); fail_io_attach: megasas_mgmt_info.count--; megasas_mgmt_info.max_index--; megasas_mgmt_info.instance[megasas_mgmt_info.max_index] = NULL; + if (instance->requestorId && !instance->skip_heartbeat_timer_del) + del_timer_sync(&instance->sriov_heartbeat_timer); + instance->instancet->disable_intr(instance); megasas_destroy_irqs(instance); @@ -7451,8 +7510,16 @@ static int megasas_probe_one(struct pci_dev *pdev, megasas_release_fusion(instance); else megasas_release_mfi(instance); + if (instance->msix_vectors) pci_free_irq_vectors(instance->pdev); + instance->msix_vectors = 0; + + if (instance->fw_crash_state != UNAVAILABLE) + megasas_free_host_crash_buffer(instance); + + if (instance->adapter_type != MFI_SERIES) + megasas_fusion_stop_watchdog(instance); fail_init_mfi: scsi_host_put(host); fail_alloc_instance: @@ -8764,8 +8831,10 @@ megasas_aen_polling(struct work_struct *work) union megasas_evt_class_locale class_locale; int event_type = 0; u32 seq_num; + u16 ld_target_id; int error; u8 dcmd_ret = DCMD_SUCCESS; + struct scsi_device *sdev1; if (!instance) { printk(KERN_ERR "invalid instance!\n"); @@ -8788,12 +8857,23 @@ megasas_aen_polling(struct work_struct *work) break; case MR_EVT_LD_OFFLINE: - case MR_EVT_CFG_CLEARED: case MR_EVT_LD_DELETED: + ld_target_id = instance->evt_detail->args.ld.target_id; + sdev1 = scsi_device_lookup(instance->host, + MEGASAS_MAX_PD_CHANNELS + + (ld_target_id / MEGASAS_MAX_DEV_PER_CHANNEL), + (ld_target_id - MEGASAS_MAX_DEV_PER_CHANNEL), + 0); + if (sdev1) + megasas_remove_scsi_device(sdev1); + + event_type = SCAN_VD_CHANNEL; + break; case MR_EVT_LD_CREATED: event_type = SCAN_VD_CHANNEL; break; + case MR_EVT_CFG_CLEARED: case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED: case MR_EVT_FOREIGN_CFG_IMPORTED: case MR_EVT_LD_STATE_CHANGE: diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index b6c08d620033..83f69c33b01a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -349,6 +349,10 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id) num_lds = le16_to_cpu(drv_map->raidMap.ldCount); + memcpy(instance->ld_ids_prev, + instance->ld_ids_from_raidmap, + sizeof(instance->ld_ids_from_raidmap)); + memset(instance->ld_ids_from_raidmap, 0xff, MEGASAS_MAX_LD_IDS); /*Convert Raid capability values to CPU arch */ for (i = 0; (num_lds > 0) && (i < MAX_LOGICAL_DRIVES_EXT); i++) { ld = MR_TargetIdToLdGet(i, drv_map); @@ -359,7 +363,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id) raid = MR_LdRaidGet(ld, drv_map); le32_to_cpus((u32 *)&raid->capability); - + instance->ld_ids_from_raidmap[i] = i; num_lds--; } diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index b0c01cf0428f..13022a42fd6f 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -3667,6 +3667,7 @@ static void megasas_sync_irqs(unsigned long instance_addr) if (irq_ctx->irq_poll_scheduled) { irq_ctx->irq_poll_scheduled = false; enable_irq(irq_ctx->os_irq); + complete_cmd_fusion(instance, irq_ctx->MSIxIndex, irq_ctx); } } } @@ -3698,6 +3699,7 @@ int megasas_irqpoll(struct irq_poll *irqpoll, int budget) irq_poll_complete(irqpoll); irq_ctx->irq_poll_scheduled = false; enable_irq(irq_ctx->os_irq); + complete_cmd_fusion(instance, irq_ctx->MSIxIndex, irq_ctx); } return num_entries; @@ -3714,6 +3716,7 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr) { struct megasas_instance *instance = (struct megasas_instance *)instance_addr; + struct megasas_irq_context *irq_ctx = NULL; u32 count, MSIxIndex; count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; @@ -3722,8 +3725,10 @@ megasas_complete_cmd_dpc_fusion(unsigned long instance_addr) if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) return; - for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++) - complete_cmd_fusion(instance, MSIxIndex, NULL); + for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++) { + irq_ctx = &instance->irq_context[MSIxIndex]; + complete_cmd_fusion(instance, MSIxIndex, irq_ctx); + } } /** @@ -5193,6 +5198,7 @@ megasas_alloc_fusion_context(struct megasas_instance *instance) if (!fusion->log_to_span) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); + kfree(instance->ctrl_context); return -ENOMEM; } } diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 5f845d7094fc..31c384108bc9 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -3526,6 +3526,28 @@ _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc) ioc->fw_events_cleanup = 1; while ((fw_event = dequeue_next_fw_event(ioc)) || (fw_event = ioc->current_event)) { + + /* + * Don't call cancel_work_sync() for current_event + * other than MPT3SAS_REMOVE_UNRESPONDING_DEVICES; + * otherwise we may observe deadlock if current + * hard reset issued as part of processing the current_event. + * + * Orginal logic of cleaning the current_event is added + * for handling the back to back host reset issued by the user. + * i.e. during back to back host reset, driver use to process + * the two instances of MPT3SAS_REMOVE_UNRESPONDING_DEVICES + * event back to back and this made the drives to unregister + * the devices from SML. + */ + + if (fw_event == ioc->current_event && + ioc->current_event->event != + MPT3SAS_REMOVE_UNRESPONDING_DEVICES) { + ioc->current_event = NULL; + continue; + } + /* * Wait on the fw_event to complete. If this returns 1, then * the event was never executed, and we need a put for the @@ -6007,8 +6029,10 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) handle, parent_handle, (u64)sas_expander->sas_address, sas_expander->num_phys); - if (!sas_expander->num_phys) + if (!sas_expander->num_phys) { + rc = -1; goto out_fail; + } sas_expander->phy = kcalloc(sas_expander->num_phys, sizeof(struct _sas_phy), GFP_KERNEL); if (!sas_expander->phy) { diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 6aa2697c4a15..b03c0f35d7b0 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -46,6 +46,7 @@ static struct scsi_host_template mvs_sht = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 0c0c886c7371..13b8ddec6189 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -101,6 +101,7 @@ static struct scsi_host_template pm8001_sht = { .max_sectors = SCSI_DEFAULT_MAX_SECTORS, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler, + .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, #ifdef CONFIG_COMPAT diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 39de9a9360d3..c3bb58885033 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -684,8 +684,7 @@ int pm8001_dev_found(struct domain_device *dev) void pm8001_task_done(struct sas_task *task) { - if (!del_timer(&task->slow_task->timer)) - return; + del_timer(&task->slow_task->timer); complete(&task->slow_task->completion); } @@ -693,9 +692,14 @@ static void pm8001_tmf_timedout(struct timer_list *t) { struct sas_task_slow *slow = from_timer(slow, t, timer); struct sas_task *task = slow->task; + unsigned long flags; - task->task_state_flags |= SAS_TASK_STATE_ABORTED; - complete(&task->slow_task->completion); + spin_lock_irqsave(&task->task_state_lock, flags); + if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { + task->task_state_flags |= SAS_TASK_STATE_ABORTED; + complete(&task->slow_task->completion); + } + spin_unlock_irqrestore(&task->task_state_lock, flags); } #define PM8001_TASK_TIMEOUT 20 @@ -748,13 +752,10 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev, } res = -TMF_RESP_FUNC_FAILED; /* Even TMF timed out, return direct. */ - if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { - pm8001_dbg(pm8001_ha, FAIL, - "TMF task[%x]timeout.\n", - tmf->tmf); - goto ex_err; - } + if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { + pm8001_dbg(pm8001_ha, FAIL, "TMF task[%x]timeout.\n", + tmf->tmf); + goto ex_err; } if (task->task_status.resp == SAS_TASK_COMPLETE && @@ -834,12 +835,9 @@ pm8001_exec_internal_task_abort(struct pm8001_hba_info *pm8001_ha, wait_for_completion(&task->slow_task->completion); res = TMF_RESP_FUNC_FAILED; /* Even TMF timed out, return direct. */ - if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) { - if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) { - pm8001_dbg(pm8001_ha, FAIL, - "TMF task timeout.\n"); - goto ex_err; - } + if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { + pm8001_dbg(pm8001_ha, FAIL, "TMF task timeout.\n"); + goto ex_err; } if (task->task_status.resp == SAS_TASK_COMPLETE && diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index 4869ef813dc4..63f99f4eeed9 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c @@ -1520,9 +1520,19 @@ void qedf_process_error_detect(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, { int rval; + if (io_req == NULL) { + QEDF_INFO(NULL, QEDF_LOG_IO, "io_req is NULL.\n"); + return; + } + + if (io_req->fcport == NULL) { + QEDF_INFO(NULL, QEDF_LOG_IO, "fcport is NULL.\n"); + return; + } + if (!cqe) { QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, - "cqe is NULL for io_req %p\n", io_req); + "cqe is NULL for io_req %p\n", io_req); return; } @@ -1538,6 +1548,16 @@ void qedf_process_error_detect(struct qedf_ctx *qedf, struct fcoe_cqe *cqe, le32_to_cpu(cqe->cqe_info.err_info.rx_buf_off), le32_to_cpu(cqe->cqe_info.err_info.rx_id)); + /* When flush is active, let the cmds be flushed out from the cleanup context */ + if (test_bit(QEDF_RPORT_IN_TARGET_RESET, &io_req->fcport->flags) || + (test_bit(QEDF_RPORT_IN_LUN_RESET, &io_req->fcport->flags) && + io_req->sc_cmd->device->lun == (u64)io_req->fcport->lun_reset_lun)) { + QEDF_ERR(&qedf->dbg_ctx, + "Dropping EQE for xid=0x%x as fcport is flushing", + io_req->xid); + return; + } + if (qedf->stop_io_on_error) { qedf_stop_all_io(qedf); return; diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index a464d0a4f465..846a02de4d51 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -1827,22 +1827,20 @@ static int qedf_vport_create(struct fc_vport *vport, bool disabled) fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf)); QEDF_WARN(&(base_qedf->dbg_ctx), "Failed to create vport, " "WWPN (0x%s) already exists.\n", buf); - goto err1; + return rc; } if (atomic_read(&base_qedf->link_state) != QEDF_LINK_UP) { QEDF_WARN(&(base_qedf->dbg_ctx), "Cannot create vport " "because link is not up.\n"); - rc = -EIO; - goto err1; + return -EIO; } vn_port = libfc_vport_create(vport, sizeof(struct qedf_ctx)); if (!vn_port) { QEDF_WARN(&(base_qedf->dbg_ctx), "Could not create lport " "for vport.\n"); - rc = -ENOMEM; - goto err1; + return -ENOMEM; } fcoe_wwn_to_str(vport->port_name, buf, sizeof(buf)); @@ -1866,7 +1864,7 @@ static int qedf_vport_create(struct fc_vport *vport, bool disabled) if (rc) { QEDF_ERR(&(base_qedf->dbg_ctx), "Could not allocate memory " "for lport stats.\n"); - goto err2; + goto err; } fc_set_wwnn(vn_port, vport->node_name); @@ -1884,7 +1882,7 @@ static int qedf_vport_create(struct fc_vport *vport, bool disabled) if (rc) { QEDF_WARN(&base_qedf->dbg_ctx, "Error adding Scsi_Host rc=0x%x.\n", rc); - goto err2; + goto err; } /* Set default dev_loss_tmo based on module parameter */ @@ -1925,9 +1923,10 @@ static int qedf_vport_create(struct fc_vport *vport, bool disabled) vport_qedf->dbg_ctx.host_no = vn_port->host->host_no; vport_qedf->dbg_ctx.pdev = base_qedf->pdev; -err2: + return 0; + +err: scsi_host_put(vn_port->host); -err1: return rc; } @@ -1968,8 +1967,7 @@ static int qedf_vport_destroy(struct fc_vport *vport) fc_lport_free_stats(vn_port); /* Release Scsi_Host */ - if (vn_port->host) - scsi_host_put(vn_port->host); + scsi_host_put(vn_port->host); out: return 0; diff --git a/drivers/scsi/qedi/qedi.h b/drivers/scsi/qedi/qedi.h index c342defc3f52..ce199a7a16b8 100644 --- a/drivers/scsi/qedi/qedi.h +++ b/drivers/scsi/qedi/qedi.h @@ -284,6 +284,7 @@ struct qedi_ctx { #define QEDI_IN_RECOVERY 5 #define QEDI_IN_OFFLINE 6 #define QEDI_IN_SHUTDOWN 7 +#define QEDI_BLOCK_IO 8 u8 mac[ETH_ALEN]; u32 src_ip[4]; diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index 440ddd2309f1..4c87640e6a91 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c @@ -73,7 +73,6 @@ static void qedi_process_logout_resp(struct qedi_ctx *qedi, spin_unlock(&qedi_conn->list_lock); cmd->state = RESPONSE_RECEIVED; - qedi_clear_task_idx(qedi, cmd->task_id); __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0); spin_unlock(&session->back_lock); @@ -138,7 +137,6 @@ static void qedi_process_text_resp(struct qedi_ctx *qedi, spin_unlock(&qedi_conn->list_lock); cmd->state = RESPONSE_RECEIVED; - qedi_clear_task_idx(qedi, cmd->task_id); __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr, qedi_conn->gen_pdu.resp_buf, @@ -161,16 +159,9 @@ static void qedi_tmf_resp_work(struct work_struct *work) set_bit(QEDI_CONN_FW_CLEANUP, &qedi_conn->flags); resp_hdr_ptr = (struct iscsi_tm_rsp *)qedi_cmd->tmf_resp_buf; - iscsi_block_session(session->cls_session); rval = qedi_cleanup_all_io(qedi, qedi_conn, qedi_cmd->task, true); - if (rval) { - qedi_clear_task_idx(qedi, qedi_cmd->task_id); - iscsi_unblock_session(session->cls_session); + if (rval) goto exit_tmf_resp; - } - - iscsi_unblock_session(session->cls_session); - qedi_clear_task_idx(qedi, qedi_cmd->task_id); spin_lock(&session->back_lock); __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL, 0); @@ -245,8 +236,6 @@ static void qedi_process_tmf_resp(struct qedi_ctx *qedi, goto unblock_sess; } - qedi_clear_task_idx(qedi, qedi_cmd->task_id); - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL, 0); kfree(resp_hdr_ptr); @@ -314,7 +303,6 @@ static void qedi_process_login_resp(struct qedi_ctx *qedi, "Freeing tid=0x%x for cid=0x%x\n", cmd->task_id, qedi_conn->iscsi_conn_id); cmd->state = RESPONSE_RECEIVED; - qedi_clear_task_idx(qedi, cmd->task_id); } static void qedi_get_rq_bdq_buf(struct qedi_ctx *qedi, @@ -468,7 +456,6 @@ static int qedi_process_nopin_mesg(struct qedi_ctx *qedi, } spin_unlock(&qedi_conn->list_lock); - qedi_clear_task_idx(qedi, cmd->task_id); } done: @@ -673,7 +660,6 @@ static void qedi_scsi_completion(struct qedi_ctx *qedi, if (qedi_io_tracing) qedi_trace_io(qedi, task, cmd->task_id, QEDI_IO_TRACE_RSP); - qedi_clear_task_idx(qedi, cmd->task_id); __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, conn->data, datalen); error: @@ -730,7 +716,6 @@ static void qedi_process_nopin_local_cmpl(struct qedi_ctx *qedi, cqe->itid, cmd->task_id); cmd->state = RESPONSE_RECEIVED; - qedi_clear_task_idx(qedi, cmd->task_id); spin_lock_bh(&session->back_lock); __iscsi_put_task(task); @@ -748,7 +733,6 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi, itt_t protoitt = 0; int found = 0; struct qedi_cmd *qedi_cmd = NULL; - u32 rtid = 0; u32 iscsi_cid; struct qedi_conn *qedi_conn; struct qedi_cmd *dbg_cmd; @@ -779,7 +763,6 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi, found = 1; mtask = qedi_cmd->task; tmf_hdr = (struct iscsi_tm *)mtask->hdr; - rtid = work->rtid; list_del_init(&work->list); kfree(work); @@ -821,8 +804,6 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi, if (qedi_cmd->state == CLEANUP_WAIT_FAILED) qedi_cmd->state = CLEANUP_RECV; - qedi_clear_task_idx(qedi_conn->qedi, rtid); - spin_lock(&qedi_conn->list_lock); if (likely(dbg_cmd->io_cmd_in_list)) { dbg_cmd->io_cmd_in_list = false; @@ -856,7 +837,6 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi, QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_TID, "Freeing tid=0x%x for cid=0x%x\n", cqe->itid, qedi_conn->iscsi_conn_id); - qedi_clear_task_idx(qedi_conn->qedi, cqe->itid); } else { qedi_get_proto_itt(qedi, cqe->itid, &ptmp_itt); @@ -1453,7 +1433,7 @@ static void qedi_tmf_work(struct work_struct *work) ldel_exit: spin_lock_bh(&qedi_conn->tmf_work_lock); - if (!qedi_cmd->list_tmf_work) { + if (qedi_cmd->list_tmf_work) { list_del_init(&list_work->list); qedi_cmd->list_tmf_work = NULL; kfree(list_work); diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c index 08c05403cd72..f51723e2d522 100644 --- a/drivers/scsi/qedi/qedi_iscsi.c +++ b/drivers/scsi/qedi/qedi_iscsi.c @@ -330,12 +330,22 @@ qedi_conn_create(struct iscsi_cls_session *cls_session, uint32_t cid) void qedi_mark_device_missing(struct iscsi_cls_session *cls_session) { - iscsi_block_session(cls_session); + struct iscsi_session *session = cls_session->dd_data; + struct qedi_conn *qedi_conn = session->leadconn->dd_data; + + spin_lock_bh(&session->frwd_lock); + set_bit(QEDI_BLOCK_IO, &qedi_conn->qedi->flags); + spin_unlock_bh(&session->frwd_lock); } void qedi_mark_device_available(struct iscsi_cls_session *cls_session) { - iscsi_unblock_session(cls_session); + struct iscsi_session *session = cls_session->dd_data; + struct qedi_conn *qedi_conn = session->leadconn->dd_data; + + spin_lock_bh(&session->frwd_lock); + clear_bit(QEDI_BLOCK_IO, &qedi_conn->qedi->flags); + spin_unlock_bh(&session->frwd_lock); } static int qedi_bind_conn_to_iscsi_cid(struct qedi_ctx *qedi, @@ -772,7 +782,6 @@ static int qedi_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task) } cmd->conn = conn->dd_data; - cmd->scsi_cmd = NULL; return qedi_iscsi_send_generic_request(task); } @@ -783,9 +792,16 @@ static int qedi_task_xmit(struct iscsi_task *task) struct qedi_cmd *cmd = task->dd_data; struct scsi_cmnd *sc = task->sc; + /* Clear now so in cleanup_task we know it didn't make it */ + cmd->scsi_cmd = NULL; + cmd->task_id = U16_MAX; + if (test_bit(QEDI_IN_SHUTDOWN, &qedi_conn->qedi->flags)) return -ENODEV; + if (test_bit(QEDI_BLOCK_IO, &qedi_conn->qedi->flags)) + return -EACCES; + cmd->state = 0; cmd->task = NULL; cmd->use_slowpath = false; @@ -1383,13 +1399,24 @@ static umode_t qedi_attr_is_visible(int param_type, int param) static void qedi_cleanup_task(struct iscsi_task *task) { - if (!task->sc || task->state == ISCSI_TASK_PENDING) { + struct qedi_cmd *cmd; + + if (task->state == ISCSI_TASK_PENDING) { QEDI_INFO(NULL, QEDI_LOG_IO, "Returning ref_cnt=%d\n", refcount_read(&task->refcount)); return; } - qedi_iscsi_unmap_sg_list(task->dd_data); + if (task->sc) + qedi_iscsi_unmap_sg_list(task->dd_data); + + cmd = task->dd_data; + if (cmd->task_id != U16_MAX) + qedi_clear_task_idx(iscsi_host_priv(task->conn->session->host), + cmd->task_id); + + cmd->task_id = U16_MAX; + cmd->scsi_cmd = NULL; } struct iscsi_transport qedi_iscsi_transport = { diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 69c5b5ee2169..b33eff9ea80b 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -642,7 +642,7 @@ static struct qedi_ctx *qedi_host_alloc(struct pci_dev *pdev) goto exit_setup_shost; } - shost->max_id = QEDI_MAX_ISCSI_CONNS_PER_HBA; + shost->max_id = QEDI_MAX_ISCSI_CONNS_PER_HBA - 1; shost->max_channel = 0; shost->max_lun = ~0; shost->max_cmd_len = 16; diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index dcae8f071c35..8d4976725a75 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1559,10 +1559,12 @@ void qlt_stop_phase2(struct qla_tgt *tgt) return; } + mutex_lock(&tgt->ha->optrom_mutex); mutex_lock(&vha->vha_tgt.tgt_mutex); tgt->tgt_stop = 0; tgt->tgt_stopped = 1; mutex_unlock(&vha->vha_tgt.tgt_mutex); + mutex_unlock(&tgt->ha->optrom_mutex); ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished\n", tgt); diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index ba84244c1b4f..9a8f9f902f3b 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -184,6 +184,7 @@ static struct { {"HP", "C3323-300", "4269", BLIST_NOTQ}, {"HP", "C5713A", NULL, BLIST_NOREPORTLUN}, {"HP", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2}, + {"HPE", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES}, {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN}, {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 31d7a6ddc9db..d89db29fa829 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -760,6 +760,7 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) case 0x07: /* operation in progress */ case 0x08: /* Long write in progress */ case 0x09: /* self test in progress */ + case 0x11: /* notify (enable spinup) required */ case 0x14: /* space allocation in progress */ case 0x1a: /* start stop unit in progress */ case 0x1b: /* sanitize in progress */ @@ -2071,9 +2072,7 @@ EXPORT_SYMBOL_GPL(scsi_mode_select); * @sshdr: place to put sense data (or NULL if no sense to be collected). * must be SCSI_SENSE_BUFFERSIZE big. * - * Returns zero if unsuccessful, or the header offset (either 4 - * or 8 depending on whether a six or ten byte command was - * issued) if successful. + * Returns zero if successful, or a negative error number on failure */ int scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, @@ -2120,6 +2119,8 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, len, sshdr, timeout, retries, NULL); + if (result < 0) + return result; /* This code looks awful: what it's doing is making sure an * ILLEGAL REQUEST sense return identifies the actual command @@ -2164,13 +2165,15 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, data->block_descriptor_length = buffer[3]; } data->header_length = header_length; + result = 0; } else if ((status_byte(result) == CHECK_CONDITION) && scsi_sense_valid(sshdr) && sshdr->sense_key == UNIT_ATTENTION && retry_count) { retry_count--; goto retry; } - + if (result > 0) + result = -EIO; return result; } EXPORT_SYMBOL(scsi_mode_sense); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 9af50e6f94c4..8e474b145249 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -453,7 +453,8 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, error = shost->hostt->target_alloc(starget); if(error) { - dev_printk(KERN_ERR, dev, "target allocation failed, error %d\n", error); + if (error != -ENXIO) + dev_err(dev, "target allocation failed, error %d\n", error); /* don't want scsi_target_reap to do the final * put because it will be under the host lock */ scsi_target_destroy(starget); diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index d6e344fa33ad..8173b67ec7b0 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -807,11 +807,17 @@ store_state_field(struct device *dev, struct device_attribute *attr, mutex_lock(&sdev->state_mutex); ret = scsi_device_set_state(sdev, state); /* - * If the device state changes to SDEV_RUNNING, we need to run - * the queue to avoid I/O hang. + * If the device state changes to SDEV_RUNNING, we need to + * run the queue to avoid I/O hang, and rescan the device + * to revalidate it. Running the queue first is necessary + * because another thread may be waiting inside + * blk_mq_freeze_queue_wait() and because that call may be + * waiting for pending I/O to finish. */ - if (ret == 0 && state == SDEV_RUNNING) + if (ret == 0 && state == SDEV_RUNNING) { blk_mq_run_hw_queues(sdev->request_queue, true); + scsi_rescan_device(dev); + } mutex_unlock(&sdev->state_mutex); return ret == 0 ? count : -EINVAL; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index c53c3f9fa526..ac07a9ef3578 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -440,39 +440,10 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj, struct device *dev = container_of(kobj, struct device, kobj); struct iscsi_iface *iface = iscsi_dev_to_iface(dev); struct iscsi_transport *t = iface->transport; - int param; - int param_type; + int param = -1; if (attr == &dev_attr_iface_enabled.attr) param = ISCSI_NET_PARAM_IFACE_ENABLE; - else if (attr == &dev_attr_iface_vlan_id.attr) - param = ISCSI_NET_PARAM_VLAN_ID; - else if (attr == &dev_attr_iface_vlan_priority.attr) - param = ISCSI_NET_PARAM_VLAN_PRIORITY; - else if (attr == &dev_attr_iface_vlan_enabled.attr) - param = ISCSI_NET_PARAM_VLAN_ENABLED; - else if (attr == &dev_attr_iface_mtu.attr) - param = ISCSI_NET_PARAM_MTU; - else if (attr == &dev_attr_iface_port.attr) - param = ISCSI_NET_PARAM_PORT; - else if (attr == &dev_attr_iface_ipaddress_state.attr) - param = ISCSI_NET_PARAM_IPADDR_STATE; - else if (attr == &dev_attr_iface_delayed_ack_en.attr) - param = ISCSI_NET_PARAM_DELAYED_ACK_EN; - else if (attr == &dev_attr_iface_tcp_nagle_disable.attr) - param = ISCSI_NET_PARAM_TCP_NAGLE_DISABLE; - else if (attr == &dev_attr_iface_tcp_wsf_disable.attr) - param = ISCSI_NET_PARAM_TCP_WSF_DISABLE; - else if (attr == &dev_attr_iface_tcp_wsf.attr) - param = ISCSI_NET_PARAM_TCP_WSF; - else if (attr == &dev_attr_iface_tcp_timer_scale.attr) - param = ISCSI_NET_PARAM_TCP_TIMER_SCALE; - else if (attr == &dev_attr_iface_tcp_timestamp_en.attr) - param = ISCSI_NET_PARAM_TCP_TIMESTAMP_EN; - else if (attr == &dev_attr_iface_cache_id.attr) - param = ISCSI_NET_PARAM_CACHE_ID; - else if (attr == &dev_attr_iface_redirect_en.attr) - param = ISCSI_NET_PARAM_REDIRECT_EN; else if (attr == &dev_attr_iface_def_taskmgmt_tmo.attr) param = ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO; else if (attr == &dev_attr_iface_header_digest.attr) @@ -509,6 +480,38 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj, param = ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN; else if (attr == &dev_attr_iface_initiator_name.attr) param = ISCSI_IFACE_PARAM_INITIATOR_NAME; + + if (param != -1) + return t->attr_is_visible(ISCSI_IFACE_PARAM, param); + + if (attr == &dev_attr_iface_vlan_id.attr) + param = ISCSI_NET_PARAM_VLAN_ID; + else if (attr == &dev_attr_iface_vlan_priority.attr) + param = ISCSI_NET_PARAM_VLAN_PRIORITY; + else if (attr == &dev_attr_iface_vlan_enabled.attr) + param = ISCSI_NET_PARAM_VLAN_ENABLED; + else if (attr == &dev_attr_iface_mtu.attr) + param = ISCSI_NET_PARAM_MTU; + else if (attr == &dev_attr_iface_port.attr) + param = ISCSI_NET_PARAM_PORT; + else if (attr == &dev_attr_iface_ipaddress_state.attr) + param = ISCSI_NET_PARAM_IPADDR_STATE; + else if (attr == &dev_attr_iface_delayed_ack_en.attr) + param = ISCSI_NET_PARAM_DELAYED_ACK_EN; + else if (attr == &dev_attr_iface_tcp_nagle_disable.attr) + param = ISCSI_NET_PARAM_TCP_NAGLE_DISABLE; + else if (attr == &dev_attr_iface_tcp_wsf_disable.attr) + param = ISCSI_NET_PARAM_TCP_WSF_DISABLE; + else if (attr == &dev_attr_iface_tcp_wsf.attr) + param = ISCSI_NET_PARAM_TCP_WSF; + else if (attr == &dev_attr_iface_tcp_timer_scale.attr) + param = ISCSI_NET_PARAM_TCP_TIMER_SCALE; + else if (attr == &dev_attr_iface_tcp_timestamp_en.attr) + param = ISCSI_NET_PARAM_TCP_TIMESTAMP_EN; + else if (attr == &dev_attr_iface_cache_id.attr) + param = ISCSI_NET_PARAM_CACHE_ID; + else if (attr == &dev_attr_iface_redirect_en.attr) + param = ISCSI_NET_PARAM_REDIRECT_EN; else if (iface->iface_type == ISCSI_IFACE_TYPE_IPV4) { if (attr == &dev_attr_ipv4_iface_ipaddress.attr) param = ISCSI_NET_PARAM_IPV4_ADDR; @@ -599,32 +602,7 @@ static umode_t iscsi_iface_attr_is_visible(struct kobject *kobj, return 0; } - switch (param) { - case ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO: - case ISCSI_IFACE_PARAM_HDRDGST_EN: - case ISCSI_IFACE_PARAM_DATADGST_EN: - case ISCSI_IFACE_PARAM_IMM_DATA_EN: - case ISCSI_IFACE_PARAM_INITIAL_R2T_EN: - case ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN: - case ISCSI_IFACE_PARAM_PDU_INORDER_EN: - case ISCSI_IFACE_PARAM_ERL: - case ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH: - case ISCSI_IFACE_PARAM_FIRST_BURST: - case ISCSI_IFACE_PARAM_MAX_R2T: - case ISCSI_IFACE_PARAM_MAX_BURST: - case ISCSI_IFACE_PARAM_CHAP_AUTH_EN: - case ISCSI_IFACE_PARAM_BIDI_CHAP_EN: - case ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL: - case ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN: - case ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN: - case ISCSI_IFACE_PARAM_INITIATOR_NAME: - param_type = ISCSI_IFACE_PARAM; - break; - default: - param_type = ISCSI_NET_PARAM; - } - - return t->attr_is_visible(param_type, param); + return t->attr_is_visible(ISCSI_NET_PARAM, param); } static struct attribute *iscsi_iface_attrs[] = { @@ -1979,6 +1957,8 @@ static void __iscsi_unblock_session(struct work_struct *work) */ void iscsi_unblock_session(struct iscsi_cls_session *session) { + flush_work(&session->block_work); + queue_work(iscsi_eh_timer_workq, &session->unblock_work); /* * Blocking the session can be done from any context so we only @@ -2351,6 +2331,18 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn) } EXPORT_SYMBOL_GPL(iscsi_destroy_conn); +void iscsi_put_conn(struct iscsi_cls_conn *conn) +{ + put_device(&conn->dev); +} +EXPORT_SYMBOL_GPL(iscsi_put_conn); + +void iscsi_get_conn(struct iscsi_cls_conn *conn) +{ + get_device(&conn->dev); +} +EXPORT_SYMBOL_GPL(iscsi_get_conn); + /* * iscsi interface functions */ @@ -2477,9 +2469,22 @@ static void iscsi_if_stop_conn(struct iscsi_cls_conn *conn, int flag) * it works. */ mutex_lock(&conn_mutex); + switch (flag) { + case STOP_CONN_RECOVER: + conn->state = ISCSI_CONN_FAILED; + break; + case STOP_CONN_TERM: + conn->state = ISCSI_CONN_DOWN; + break; + default: + iscsi_cls_conn_printk(KERN_ERR, conn, + "invalid stop flag %d\n", flag); + goto unlock; + } + conn->transport->stop_conn(conn, flag); +unlock: mutex_unlock(&conn_mutex); - } static void stop_conn_work_fn(struct work_struct *work) @@ -2904,6 +2909,13 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) default: err = transport->set_param(conn, ev->u.set_param.param, data, ev->u.set_param.len); + if ((conn->state == ISCSI_CONN_BOUND) || + (conn->state == ISCSI_CONN_UP)) { + err = transport->set_param(conn, ev->u.set_param.param, + data, ev->u.set_param.len); + } else { + return -ENOTCONN; + } } return err; @@ -2963,6 +2975,7 @@ static int iscsi_if_ep_disconnect(struct iscsi_transport *transport, mutex_lock(&conn->ep_mutex); conn->ep = NULL; mutex_unlock(&conn->ep_mutex); + conn->state = ISCSI_CONN_FAILED; } transport->ep_disconnect(ep); @@ -3730,6 +3743,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) ev->r.retcode = transport->bind_conn(session, conn, ev->u.b_conn.transport_eph, ev->u.b_conn.is_leading); + if (!ev->r.retcode) + conn->state = ISCSI_CONN_BOUND; mutex_unlock(&conn_mutex); if (ev->r.retcode || !transport->ep_connect) @@ -3969,7 +3984,8 @@ iscsi_conn_attr(local_ipaddr, ISCSI_PARAM_LOCAL_IPADDR); static const char *const connection_state_names[] = { [ISCSI_CONN_UP] = "up", [ISCSI_CONN_DOWN] = "down", - [ISCSI_CONN_FAILED] = "failed" + [ISCSI_CONN_FAILED] = "failed", + [ISCSI_CONN_BOUND] = "bound" }; static ssize_t show_conn_state(struct device *dev, diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index c9abed8429c9..4a96fb05731d 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -1229,16 +1229,15 @@ int sas_read_port_mode_page(struct scsi_device *sdev) char *buffer = kzalloc(BUF_SIZE, GFP_KERNEL), *msdata; struct sas_end_device *rdev = sas_sdev_to_rdev(sdev); struct scsi_mode_data mode_data; - int res, error; + int error; if (!buffer) return -ENOMEM; - res = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3, - &mode_data, NULL); + error = scsi_mode_sense(sdev, 1, 0x19, buffer, BUF_SIZE, 30*HZ, 3, + &mode_data, NULL); - error = -EINVAL; - if (!scsi_status_is_good(res)) + if (error) goto out; msdata = buffer + mode_data.header_length + diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 20a6564f87d9..f0c0935d7909 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1389,6 +1389,22 @@ static void sd_uninit_command(struct scsi_cmnd *SCpnt) } } +static bool sd_need_revalidate(struct block_device *bdev, + struct scsi_disk *sdkp) +{ + if (sdkp->device->removable || sdkp->write_prot) { + if (bdev_check_media_change(bdev)) + return true; + } + + /* + * Force a full rescan after ioctl(BLKRRPART). While the disk state has + * nothing to do with partitions, BLKRRPART is used to force a full + * revalidate after things like a format for historical reasons. + */ + return test_bit(GD_NEED_PART_SCAN, &bdev->bd_disk->state); +} + /** * sd_open - open a scsi disk device * @bdev: Block device of the scsi disk to open @@ -1425,10 +1441,8 @@ static int sd_open(struct block_device *bdev, fmode_t mode) if (!scsi_block_when_processing_errors(sdev)) goto error_out; - if (sdev->removable || sdkp->write_prot) { - if (bdev_check_media_change(bdev)) - sd_revalidate_disk(bdev->bd_disk); - } + if (sd_need_revalidate(bdev, sdkp)) + sd_revalidate_disk(bdev->bd_disk); /* * If the drive is empty, just let the open fail. @@ -2673,18 +2687,18 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer) * 5: Illegal Request, Sense Code 24: Invalid field in * CDB. */ - if (!scsi_status_is_good(res)) + if (res < 0) res = sd_do_mode_sense(sdkp, 0, 0, buffer, 4, &data, NULL); /* * Third attempt: ask 255 bytes, as we did earlier. */ - if (!scsi_status_is_good(res)) + if (res < 0) res = sd_do_mode_sense(sdkp, 0, 0x3F, buffer, 255, &data, NULL); } - if (!scsi_status_is_good(res)) { + if (res < 0) { sd_first_printk(KERN_WARNING, sdkp, "Test WP failed, assume Write Enabled\n"); } else { @@ -2745,7 +2759,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, first_len, &data, &sshdr); - if (!scsi_status_is_good(res)) + if (res < 0) goto bad_sense; if (!data.header_length) { @@ -2777,7 +2791,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) res = sd_do_mode_sense(sdkp, dbd, modepage, buffer, len, &data, &sshdr); - if (scsi_status_is_good(res)) { + if (!res) { int offset = data.header_length + data.block_descriptor_length; while (offset < len) { @@ -2895,7 +2909,7 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT, sdkp->max_retries, &data, &sshdr); - if (!scsi_status_is_good(res) || !data.header_length || + if (res < 0 || !data.header_length || data.length < 6) { sd_first_printk(KERN_WARNING, sdkp, "getting Control mode page failed, assume no ATO\n"); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index fd4b582110b2..4cb4ab9c6137 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -220,6 +220,8 @@ static unsigned int sr_get_events(struct scsi_device *sdev) return DISK_EVENT_EJECT_REQUEST; else if (med->media_event_code == 2) return DISK_EVENT_MEDIA_CHANGE; + else if (med->media_event_code == 3) + return DISK_EVENT_MEDIA_CHANGE; return 0; } @@ -928,7 +930,7 @@ static void get_capabilities(struct scsi_cd *cd) rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len, SR_TIMEOUT, 3, &data, NULL); - if (!scsi_status_is_good(rc) || data.length > ms_len || + if (rc < 0 || data.length > ms_len || data.header_length + data.block_descriptor_length > data.length) { /* failed, drive doesn't have capabilities mode page */ cd->cdi.speed = 1; diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index ded00a89bfc4..0ee0b80006e0 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -994,17 +994,40 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, struct storvsc_scan_work *wrk; void (*process_err_fn)(struct work_struct *work); struct hv_host_device *host_dev = shost_priv(host); - bool do_work = false; - switch (SRB_STATUS(vm_srb->srb_status)) { - case SRB_STATUS_ERROR: + /* + * In some situations, Hyper-V sets multiple bits in the + * srb_status, such as ABORTED and ERROR. So process them + * individually, with the most specific bits first. + */ + + if (vm_srb->srb_status & SRB_STATUS_INVALID_LUN) { + set_host_byte(scmnd, DID_NO_CONNECT); + process_err_fn = storvsc_remove_lun; + goto do_work; + } + + if (vm_srb->srb_status & SRB_STATUS_ABORTED) { + if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID && + /* Capacity data has changed */ + (asc == 0x2a) && (ascq == 0x9)) { + process_err_fn = storvsc_device_scan; + /* + * Retry the I/O that triggered this. + */ + set_host_byte(scmnd, DID_REQUEUE); + goto do_work; + } + } + + if (vm_srb->srb_status & SRB_STATUS_ERROR) { /* * Let upper layer deal with error when * sense message is present. */ - if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID) - break; + return; + /* * If there is an error; offline the device since all * error recovery strategies would have already been @@ -1017,37 +1040,19 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, set_host_byte(scmnd, DID_PASSTHROUGH); break; /* - * On Some Windows hosts TEST_UNIT_READY command can return - * SRB_STATUS_ERROR, let the upper level code deal with it - * based on the sense information. + * On some Hyper-V hosts TEST_UNIT_READY command can + * return SRB_STATUS_ERROR. Let the upper level code + * deal with it based on the sense information. */ case TEST_UNIT_READY: break; default: set_host_byte(scmnd, DID_ERROR); } - break; - case SRB_STATUS_INVALID_LUN: - set_host_byte(scmnd, DID_NO_CONNECT); - do_work = true; - process_err_fn = storvsc_remove_lun; - break; - case SRB_STATUS_ABORTED: - if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID && - (asc == 0x2a) && (ascq == 0x9)) { - do_work = true; - process_err_fn = storvsc_device_scan; - /* - * Retry the I/O that triggered this. - */ - set_host_byte(scmnd, DID_REQUEUE); - } - break; } + return; - if (!do_work) - return; - +do_work: /* * We need to schedule work to process this error; schedule it. */ diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index 081f54ab7d86..1421b1394d81 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -587,7 +587,13 @@ static void pvscsi_complete_request(struct pvscsi_adapter *adapter, case BTSTAT_SUCCESS: case BTSTAT_LINKED_COMMAND_COMPLETED: case BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG: - /* If everything went fine, let's move on.. */ + /* + * Commands like INQUIRY may transfer less data than + * requested by the initiator via bufflen. Set residual + * count to make upper layer aware of the actual amount + * of data returned. + */ + scsi_set_resid(cmd, scsi_bufflen(cmd) - e->dataLen); cmd->result = (DID_OK << 16); break; diff --git a/drivers/slimbus/messaging.c b/drivers/slimbus/messaging.c index d5879142dbef..ddf0371ad52b 100644 --- a/drivers/slimbus/messaging.c +++ b/drivers/slimbus/messaging.c @@ -66,7 +66,7 @@ int slim_alloc_txn_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn) int ret = 0; spin_lock_irqsave(&ctrl->txn_lock, flags); - ret = idr_alloc_cyclic(&ctrl->tid_idr, txn, 0, + ret = idr_alloc_cyclic(&ctrl->tid_idr, txn, 1, SLIM_MAX_TIDS, GFP_ATOMIC); if (ret < 0) { spin_unlock_irqrestore(&ctrl->txn_lock, flags); @@ -131,7 +131,8 @@ int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn) goto slim_xfer_err; } } - + /* Initialize tid to invalid value */ + txn->tid = 0; need_tid = slim_tid_txn(txn->mt, txn->mc); if (need_tid) { @@ -163,7 +164,7 @@ int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn) txn->mt, txn->mc, txn->la, ret); slim_xfer_err: - if (!clk_pause_msg && (!need_tid || ret == -ETIMEDOUT)) { + if (!clk_pause_msg && (txn->tid == 0 || ret == -ETIMEDOUT)) { /* * remove runtime-pm vote if this was TX only, or * if there was error during this transaction diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index 50cfd67c2871..d0540376221c 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -1065,7 +1065,8 @@ static void qcom_slim_ngd_setup(struct qcom_slim_ngd_ctrl *ctrl) { u32 cfg = readl_relaxed(ctrl->ngd->base); - if (ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN) + if (ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN || + ctrl->state == QCOM_SLIM_NGD_CTRL_ASLEEP) qcom_slim_ngd_init_dma(ctrl); /* By default enable message queues */ @@ -1116,6 +1117,7 @@ static int qcom_slim_ngd_power_up(struct qcom_slim_ngd_ctrl *ctrl) dev_info(ctrl->dev, "Subsys restart: ADSP active framer\n"); return 0; } + qcom_slim_ngd_setup(ctrl); return 0; } @@ -1506,6 +1508,7 @@ static int __maybe_unused qcom_slim_ngd_runtime_suspend(struct device *dev) struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(dev); int ret = 0; + qcom_slim_ngd_exit_dma(ctrl); if (!ctrl->qmi.handle) return 0; diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c index ec90b44fa0cd..6065aaab6740 100644 --- a/drivers/soc/ixp4xx/ixp4xx-npe.c +++ b/drivers/soc/ixp4xx/ixp4xx-npe.c @@ -690,8 +690,8 @@ static int ixp4xx_npe_probe(struct platform_device *pdev) if (!(ixp4xx_read_feature_bits() & (IXP4XX_FEATURE_RESET_NPEA << i))) { - dev_info(dev, "NPE%d at 0x%08x-0x%08x not available\n", - i, res->start, res->end); + dev_info(dev, "NPE%d at %pR not available\n", + i, res); continue; /* NPE already disabled or not present */ } npe->regs = devm_ioremap_resource(dev, res); @@ -699,13 +699,12 @@ static int ixp4xx_npe_probe(struct platform_device *pdev) return PTR_ERR(npe->regs); if (npe_reset(npe)) { - dev_info(dev, "NPE%d at 0x%08x-0x%08x does not reset\n", - i, res->start, res->end); + dev_info(dev, "NPE%d at %pR does not reset\n", + i, res); continue; } npe->valid = 1; - dev_info(dev, "NPE%d at 0x%08x-0x%08x registered\n", - i, res->start, res->end); + dev_info(dev, "NPE%d at %pR registered\n", i, res); found++; } diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c index 8c968382cea7..065a800717bd 100644 --- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c +++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c @@ -145,12 +145,12 @@ static irqreturn_t qmgr_irq1_a0(int irq, void *pdev) /* ACK - it may clear any bits so don't rely on it */ __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[0]); - en_bitmap = qmgr_regs->irqen[0]; + en_bitmap = __raw_readl(&qmgr_regs->irqen[0]); while (en_bitmap) { i = __fls(en_bitmap); /* number of the last "low" queue */ en_bitmap &= ~BIT(i); - src = qmgr_regs->irqsrc[i >> 3]; - stat = qmgr_regs->stat1[i >> 3]; + src = __raw_readl(&qmgr_regs->irqsrc[i >> 3]); + stat = __raw_readl(&qmgr_regs->stat1[i >> 3]); if (src & 4) /* the IRQ condition is inverted */ stat = ~stat; if (stat & BIT(src & 3)) { @@ -170,7 +170,8 @@ static irqreturn_t qmgr_irq2_a0(int irq, void *pdev) /* ACK - it may clear any bits so don't rely on it */ __raw_writel(0xFFFFFFFF, &qmgr_regs->irqstat[1]); - req_bitmap = qmgr_regs->irqen[1] & qmgr_regs->statne_h; + req_bitmap = __raw_readl(&qmgr_regs->irqen[1]) & + __raw_readl(&qmgr_regs->statne_h); while (req_bitmap) { i = __fls(req_bitmap); /* number of the last "high" queue */ req_bitmap &= ~BIT(i); diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c index a55f25511173..36ad66bb221b 100644 --- a/drivers/soc/mediatek/mtk-mmsys.c +++ b/drivers/soc/mediatek/mtk-mmsys.c @@ -5,13 +5,11 @@ */ #include +#include #include #include #include -#include "../../gpu/drm/mediatek/mtk_drm_ddp.h" -#include "../../gpu/drm/mediatek/mtk_drm_ddp_comp.h" - #define DISP_REG_CONFIG_DISP_OVL0_MOUT_EN 0x040 #define DISP_REG_CONFIG_DISP_OVL1_MOUT_EN 0x044 #define DISP_REG_CONFIG_DISP_OD_MOUT_EN 0x048 diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c index 9ea7f0168457..c1aa7815bd6e 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra30.c +++ b/drivers/soc/tegra/fuse/fuse-tegra30.c @@ -37,7 +37,8 @@ defined(CONFIG_ARCH_TEGRA_132_SOC) || \ defined(CONFIG_ARCH_TEGRA_210_SOC) || \ defined(CONFIG_ARCH_TEGRA_186_SOC) || \ - defined(CONFIG_ARCH_TEGRA_194_SOC) + defined(CONFIG_ARCH_TEGRA_194_SOC) || \ + defined(CONFIG_ARCH_TEGRA_234_SOC) static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset) { if (WARN_ON(!fuse->base)) diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index a418c3c7001c..304ff2ee7d75 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -422,7 +422,6 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus, struct completion *port_ready; struct sdw_dpn_prop *dpn_prop; struct sdw_prepare_ch prep_ch; - unsigned int time_left; bool intr = false; int ret = 0, val; u32 addr; @@ -479,15 +478,15 @@ static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus, /* Wait for completion on port ready */ port_ready = &s_rt->slave->port_ready[prep_ch.num]; - time_left = wait_for_completion_timeout(port_ready, - msecs_to_jiffies(dpn_prop->ch_prep_timeout)); + wait_for_completion_timeout(port_ready, + msecs_to_jiffies(dpn_prop->ch_prep_timeout)); val = sdw_read(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num)); - val &= p_rt->ch_mask; - if (!time_left || val) { + if ((val < 0) || (val & p_rt->ch_mask)) { + ret = (val < 0) ? val : -ETIMEDOUT; dev_err(&s_rt->slave->dev, - "Chn prep failed for port:%d\n", prep_ch.num); - return -ETIMEDOUT; + "Chn prep failed for port %d: %d\n", prep_ch.num, ret); + return ret; } } diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 197485f2c2b2..33c32e931767 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -68,7 +68,7 @@ #define BCM2835_SPI_FIFO_SIZE 64 #define BCM2835_SPI_FIFO_SIZE_3_4 48 #define BCM2835_SPI_DMA_MIN_LENGTH 96 -#define BCM2835_SPI_NUM_CS 4 /* raise as necessary */ +#define BCM2835_SPI_NUM_CS 24 /* raise as necessary */ #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ | SPI_NO_CS | SPI_3WIRE) @@ -84,6 +84,7 @@ MODULE_PARM_DESC(polling_limit_us, * struct bcm2835_spi - BCM2835 SPI controller * @regs: base address of register map * @clk: core clock, divided to calculate serial clock + * @clk_hz: core clock cached speed * @irq: interrupt, signals TX FIFO empty or RX FIFO ¾ full * @tfr: SPI transfer currently processed * @ctlr: SPI controller reverse lookup @@ -124,6 +125,7 @@ MODULE_PARM_DESC(polling_limit_us, struct bcm2835_spi { void __iomem *regs; struct clk *clk; + unsigned long clk_hz; int irq; struct spi_transfer *tfr; struct spi_controller *ctlr; @@ -1082,19 +1084,18 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, struct spi_transfer *tfr) { struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); - unsigned long spi_hz, clk_hz, cdiv; + unsigned long spi_hz, cdiv; unsigned long hz_per_byte, byte_limit; u32 cs = bs->prepare_cs[spi->chip_select]; /* set clock */ spi_hz = tfr->speed_hz; - clk_hz = clk_get_rate(bs->clk); - if (spi_hz >= clk_hz / 2) { + if (spi_hz >= bs->clk_hz / 2) { cdiv = 2; /* clk_hz/2 is the fastest we can go */ } else if (spi_hz) { /* CDIV must be a multiple of two */ - cdiv = DIV_ROUND_UP(clk_hz, spi_hz); + cdiv = DIV_ROUND_UP(bs->clk_hz, spi_hz); cdiv += (cdiv % 2); if (cdiv >= 65536) @@ -1102,7 +1103,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, } else { cdiv = 0; /* 0 is the slowest we can go */ } - tfr->effective_speed_hz = cdiv ? (clk_hz / cdiv) : (clk_hz / 65536); + tfr->effective_speed_hz = cdiv ? (bs->clk_hz / cdiv) : (bs->clk_hz / 65536); bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); /* handle all the 3-wire mode */ @@ -1195,6 +1196,12 @@ static int bcm2835_spi_setup(struct spi_device *spi) struct gpio_chip *chip; u32 cs; + if (spi->chip_select >= BCM2835_SPI_NUM_CS) { + dev_err(&spi->dev, "only %d chip-selects supported\n", + BCM2835_SPI_NUM_CS - 1); + return -EINVAL; + } + /* * Precalculate SPI slave's CS register value for ->prepare_message(): * The driver always uses software-controlled GPIO chip select, hence @@ -1288,7 +1295,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ctlr->use_gpio_descriptors = true; ctlr->mode_bits = BCM2835_SPI_MODE_BITS; ctlr->bits_per_word_mask = SPI_BPW_MASK(8); - ctlr->num_chipselect = BCM2835_SPI_NUM_CS; + ctlr->num_chipselect = 3; ctlr->setup = bcm2835_spi_setup; ctlr->transfer_one = bcm2835_spi_transfer_one; ctlr->handle_err = bcm2835_spi_handle_err; @@ -1312,6 +1319,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) return bs->irq ? bs->irq : -ENODEV; clk_prepare_enable(bs->clk); + bs->clk_hz = clk_get_rate(bs->clk); err = bcm2835_dma_init(ctlr, &pdev->dev, bs); if (err) diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 1a7352abd878..3d8948a17095 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -181,6 +181,8 @@ int spi_bitbang_setup(struct spi_device *spi) { struct spi_bitbang_cs *cs = spi->controller_state; struct spi_bitbang *bitbang; + bool initial_setup = false; + int retval; bitbang = spi_master_get_devdata(spi->master); @@ -189,22 +191,30 @@ int spi_bitbang_setup(struct spi_device *spi) if (!cs) return -ENOMEM; spi->controller_state = cs; + initial_setup = true; } /* per-word shift register access, in hardware or bitbanging */ cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)]; - if (!cs->txrx_word) - return -EINVAL; + if (!cs->txrx_word) { + retval = -EINVAL; + goto err_free; + } if (bitbang->setup_transfer) { - int retval = bitbang->setup_transfer(spi, NULL); + retval = bitbang->setup_transfer(spi, NULL); if (retval < 0) - return retval; + goto err_free; } dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); return 0; + +err_free: + if (initial_setup) + kfree(cs); + return retval; } EXPORT_SYMBOL_GPL(spi_bitbang_setup); diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index a3afd1b9ac56..ceb16e70d235 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -517,6 +517,12 @@ static int cdns_spi_probe(struct platform_device *pdev) goto clk_dis_apb; } + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); + pm_runtime_get_noresume(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); if (ret < 0) master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS; @@ -531,11 +537,6 @@ static int cdns_spi_probe(struct platform_device *pdev) /* SPI controller initializations */ cdns_spi_init_hw(xspi); - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - pm_runtime_use_autosuspend(&pdev->dev); - pm_runtime_set_autosuspend_delay(&pdev->dev, SPI_AUTOSUSPEND_TIMEOUT); - irq = platform_get_irq(pdev, 0); if (irq <= 0) { ret = -ENXIO; @@ -566,6 +567,9 @@ static int cdns_spi_probe(struct platform_device *pdev) master->bits_per_word_mask = SPI_BPW_MASK(8); + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_put_autosuspend(&pdev->dev); + ret = spi_register_master(master); if (ret) { dev_err(&pdev->dev, "spi_register_master failed\n"); diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index d0e5aa18b7ba..bdf94cc7be1a 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -440,6 +440,7 @@ static int fsl_spi_setup(struct spi_device *spi) { struct mpc8xxx_spi *mpc8xxx_spi; struct fsl_spi_reg __iomem *reg_base; + bool initial_setup = false; int retval; u32 hw_mode; struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi); @@ -452,6 +453,7 @@ static int fsl_spi_setup(struct spi_device *spi) if (!cs) return -ENOMEM; spi_set_ctldata(spi, cs); + initial_setup = true; } mpc8xxx_spi = spi_master_get_devdata(spi->master); @@ -475,6 +477,8 @@ static int fsl_spi_setup(struct spi_device *spi) retval = fsl_spi_setup_transfer(spi, NULL); if (retval < 0) { cs->hw_mode = hw_mode; /* Restore settings */ + if (initial_setup) + kfree(cs); return retval; } diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 831a38920fa9..0e3bc0b0a526 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -66,8 +66,7 @@ struct spi_imx_data; struct spi_imx_devtype_data { void (*intctrl)(struct spi_imx_data *, int); int (*prepare_message)(struct spi_imx_data *, struct spi_message *); - int (*prepare_transfer)(struct spi_imx_data *, struct spi_device *, - struct spi_transfer *); + int (*prepare_transfer)(struct spi_imx_data *, struct spi_device *); void (*trigger)(struct spi_imx_data *); int (*rx_available)(struct spi_imx_data *); void (*reset)(struct spi_imx_data *); @@ -506,8 +505,10 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, struct spi_message *msg) { struct spi_device *spi = msg->spi; + struct spi_transfer *xfer; u32 ctrl = MX51_ECSPI_CTRL_ENABLE; - u32 testreg; + u32 min_speed_hz = ~0U; + u32 testreg, delay; u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG); /* set Master or Slave mode */ @@ -568,15 +569,43 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); + /* + * Wait until the changes in the configuration register CONFIGREG + * propagate into the hardware. It takes exactly one tick of the + * SCLK clock, but we will wait two SCLK clock just to be sure. The + * effect of the delay it takes for the hardware to apply changes + * is noticable if the SCLK clock run very slow. In such a case, if + * the polarity of SCLK should be inverted, the GPIO ChipSelect might + * be asserted before the SCLK polarity changes, which would disrupt + * the SPI communication as the device on the other end would consider + * the change of SCLK polarity as a clock tick already. + * + * Because spi_imx->spi_bus_clk is only set in bitbang prepare_message + * callback, iterate over all the transfers in spi_message, find the + * one with lowest bus frequency, and use that bus frequency for the + * delay calculation. In case all transfers have speed_hz == 0, then + * min_speed_hz is ~0 and the resulting delay is zero. + */ + list_for_each_entry(xfer, &msg->transfers, transfer_list) { + if (!xfer->speed_hz) + continue; + min_speed_hz = min(xfer->speed_hz, min_speed_hz); + } + + delay = (2 * 1000000) / min_speed_hz; + if (likely(delay < 10)) /* SCLK is faster than 100 kHz */ + udelay(delay); + else /* SCLK is _very_ slow */ + usleep_range(delay, delay + 10); + return 0; } static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx, - struct spi_device *spi, - struct spi_transfer *t) + struct spi_device *spi) { u32 ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); - u32 clk = t->speed_hz, delay; + u32 clk; /* Clear BL field and set the right value */ ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; @@ -590,7 +619,7 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx, /* set clock speed */ ctrl &= ~(0xf << MX51_ECSPI_CTRL_POSTDIV_OFFSET | 0xf << MX51_ECSPI_CTRL_PREDIV_OFFSET); - ctrl |= mx51_ecspi_clkdiv(spi_imx, t->speed_hz, &clk); + ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->spi_bus_clk, &clk); spi_imx->spi_bus_clk = clk; if (spi_imx->usedma) @@ -598,23 +627,6 @@ static int mx51_ecspi_prepare_transfer(struct spi_imx_data *spi_imx, writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); - /* - * Wait until the changes in the configuration register CONFIGREG - * propagate into the hardware. It takes exactly one tick of the - * SCLK clock, but we will wait two SCLK clock just to be sure. The - * effect of the delay it takes for the hardware to apply changes - * is noticable if the SCLK clock run very slow. In such a case, if - * the polarity of SCLK should be inverted, the GPIO ChipSelect might - * be asserted before the SCLK polarity changes, which would disrupt - * the SPI communication as the device on the other end would consider - * the change of SCLK polarity as a clock tick already. - */ - delay = (2 * 1000000) / clk; - if (likely(delay < 10)) /* SCLK is faster than 100 kHz */ - udelay(delay); - else /* SCLK is _very_ slow */ - usleep_range(delay, delay + 10); - return 0; } @@ -702,13 +714,12 @@ static int mx31_prepare_message(struct spi_imx_data *spi_imx, } static int mx31_prepare_transfer(struct spi_imx_data *spi_imx, - struct spi_device *spi, - struct spi_transfer *t) + struct spi_device *spi) { unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; unsigned int clk; - reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, t->speed_hz, &clk) << + reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, spi_imx->spi_bus_clk, &clk) << MX31_CSPICTRL_DR_SHIFT; spi_imx->spi_bus_clk = clk; @@ -807,14 +818,13 @@ static int mx21_prepare_message(struct spi_imx_data *spi_imx, } static int mx21_prepare_transfer(struct spi_imx_data *spi_imx, - struct spi_device *spi, - struct spi_transfer *t) + struct spi_device *spi) { unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18; unsigned int clk; - reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, t->speed_hz, max, &clk) + reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, spi_imx->spi_bus_clk, max, &clk) << MX21_CSPICTRL_DR_SHIFT; spi_imx->spi_bus_clk = clk; @@ -883,13 +893,12 @@ static int mx1_prepare_message(struct spi_imx_data *spi_imx, } static int mx1_prepare_transfer(struct spi_imx_data *spi_imx, - struct spi_device *spi, - struct spi_transfer *t) + struct spi_device *spi) { unsigned int reg = MX1_CSPICTRL_ENABLE | MX1_CSPICTRL_MASTER; unsigned int clk; - reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, t->speed_hz, &clk) << + reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, spi_imx->spi_bus_clk, &clk) << MX1_CSPICTRL_DR_SHIFT; spi_imx->spi_bus_clk = clk; @@ -1195,6 +1204,16 @@ static int spi_imx_setupxfer(struct spi_device *spi, if (!t) return 0; + if (!t->speed_hz) { + if (!spi->max_speed_hz) { + dev_err(&spi->dev, "no speed_hz provided!\n"); + return -EINVAL; + } + dev_dbg(&spi->dev, "using spi->max_speed_hz!\n"); + spi_imx->spi_bus_clk = spi->max_speed_hz; + } else + spi_imx->spi_bus_clk = t->speed_hz; + spi_imx->bits_per_word = t->bits_per_word; /* @@ -1236,7 +1255,7 @@ static int spi_imx_setupxfer(struct spi_device *spi, spi_imx->slave_burst = t->len; } - spi_imx->devtype_data->prepare_transfer(spi_imx, spi, t); + spi_imx->devtype_data->prepare_transfer(spi_imx, spi); return 0; } diff --git a/drivers/spi/spi-loopback-test.c b/drivers/spi/spi-loopback-test.c index df981e55c24c..89b91cdfb2a5 100644 --- a/drivers/spi/spi-loopback-test.c +++ b/drivers/spi/spi-loopback-test.c @@ -874,7 +874,7 @@ static int spi_test_run_iter(struct spi_device *spi, test.transfers[i].len = len; if (test.transfers[i].tx_buf) test.transfers[i].tx_buf += tx_off; - if (test.transfers[i].tx_buf) + if (test.transfers[i].rx_buf) test.transfers[i].rx_buf += rx_off; } diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c index ecba6b4a5d85..c208efeadd18 100644 --- a/drivers/spi/spi-meson-spicc.c +++ b/drivers/spi/spi-meson-spicc.c @@ -725,7 +725,7 @@ static int meson_spicc_probe(struct platform_device *pdev) ret = clk_prepare_enable(spicc->pclk); if (ret) { dev_err(&pdev->dev, "pclk clock enable failed\n"); - goto out_master; + goto out_core_clk; } device_reset_optional(&pdev->dev); @@ -752,7 +752,7 @@ static int meson_spicc_probe(struct platform_device *pdev) ret = meson_spicc_clk_init(spicc); if (ret) { dev_err(&pdev->dev, "clock registration failed\n"); - goto out_master; + goto out_clk; } ret = devm_spi_register_master(&pdev->dev, master); @@ -764,9 +764,11 @@ static int meson_spicc_probe(struct platform_device *pdev) return 0; out_clk: - clk_disable_unprepare(spicc->core); clk_disable_unprepare(spicc->pclk); +out_core_clk: + clk_disable_unprepare(spicc->core); + out_master: spi_master_put(master); @@ -783,6 +785,8 @@ static int meson_spicc_remove(struct platform_device *pdev) clk_disable_unprepare(spicc->core); clk_disable_unprepare(spicc->pclk); + spi_master_put(spicc->master); + return 0; } diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 5d643051bf3d..83e56ee62649 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -433,14 +433,15 @@ static int mtk_spi_fifo_transfer(struct spi_master *master, mtk_spi_prepare_transfer(master, xfer); mtk_spi_setup_packet(master); - cnt = xfer->len / 4; - iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt); - - remainder = xfer->len % 4; - if (remainder > 0) { - reg_val = 0; - memcpy(®_val, xfer->tx_buf + (cnt * 4), remainder); - writel(reg_val, mdata->base + SPI_TX_DATA_REG); + if (xfer->tx_buf) { + cnt = xfer->len / 4; + iowrite32_rep(mdata->base + SPI_TX_DATA_REG, xfer->tx_buf, cnt); + remainder = xfer->len % 4; + if (remainder > 0) { + reg_val = 0; + memcpy(®_val, xfer->tx_buf + (cnt * 4), remainder); + writel(reg_val, mdata->base + SPI_TX_DATA_REG); + } } mtk_spi_enable_transfer(master); diff --git a/drivers/spi/spi-mux.c b/drivers/spi/spi-mux.c index 37dfc6e82804..9708b7827ff7 100644 --- a/drivers/spi/spi-mux.c +++ b/drivers/spi/spi-mux.c @@ -167,10 +167,17 @@ static int spi_mux_probe(struct spi_device *spi) return ret; } +static const struct spi_device_id spi_mux_id[] = { + { "spi-mux" }, + { } +}; +MODULE_DEVICE_TABLE(spi, spi_mux_id); + static const struct of_device_id spi_mux_of_match[] = { { .compatible = "spi-mux" }, { } }; +MODULE_DEVICE_TABLE(of, spi_mux_of_match); static struct spi_driver spi_mux_driver = { .probe = spi_mux_probe, @@ -178,6 +185,7 @@ static struct spi_driver spi_mux_driver = { .name = "spi-mux", .of_match_table = spi_mux_of_match, }, + .id_table = spi_mux_id, }; module_spi_driver(spi_mux_driver); diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c index ab9035662717..bcc0b5a3a459 100644 --- a/drivers/spi/spi-nxp-fspi.c +++ b/drivers/spi/spi-nxp-fspi.c @@ -1033,12 +1033,6 @@ static int nxp_fspi_probe(struct platform_device *pdev) goto err_put_ctrl; } - /* Clear potential interrupts */ - reg = fspi_readl(f, f->iobase + FSPI_INTR); - if (reg) - fspi_writel(f, reg, f->iobase + FSPI_INTR); - - /* find the resources - controller memory mapped space */ if (is_acpi_node(f->dev->fwnode)) res = platform_get_resource(pdev, IORESOURCE_MEM, 1); @@ -1076,6 +1070,11 @@ static int nxp_fspi_probe(struct platform_device *pdev) } } + /* Clear potential interrupts */ + reg = fspi_readl(f, f->iobase + FSPI_INTR); + if (reg) + fspi_writel(f, reg, f->iobase + FSPI_INTR); + /* find the irq */ ret = platform_get_irq(pdev, 0); if (ret < 0) diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index ccd817ee4917..0d0cd061d356 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -241,7 +241,7 @@ static int omap1_spi100k_setup_transfer(struct spi_device *spi, else word_len = spi->bits_per_word; - if (spi->bits_per_word > 32) + if (word_len > 32) return -EINVAL; cs->word_len = word_len; diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 71402f71ddd8..df28c6664aba 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c @@ -424,15 +424,22 @@ static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t) static int uwire_setup(struct spi_device *spi) { struct uwire_state *ust = spi->controller_state; + bool initial_setup = false; + int status; if (ust == NULL) { ust = kzalloc(sizeof(*ust), GFP_KERNEL); if (ust == NULL) return -ENOMEM; spi->controller_state = ust; + initial_setup = true; } - return uwire_setup_transfer(spi, NULL); + status = uwire_setup_transfer(spi, NULL); + if (status && initial_setup) + kfree(ust); + + return status; } static void uwire_cleanup(struct spi_device *spi) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index d4c9510af393..3596bbe4b776 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -1032,8 +1032,22 @@ static void omap2_mcspi_release_dma(struct spi_master *master) } } +static void omap2_mcspi_cleanup(struct spi_device *spi) +{ + struct omap2_mcspi_cs *cs; + + if (spi->controller_state) { + /* Unlink controller state from context save list */ + cs = spi->controller_state; + list_del(&cs->node); + + kfree(cs); + } +} + static int omap2_mcspi_setup(struct spi_device *spi) { + bool initial_setup = false; int ret; struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master); struct omap2_mcspi_regs *ctx = &mcspi->ctx; @@ -1051,35 +1065,28 @@ static int omap2_mcspi_setup(struct spi_device *spi) spi->controller_state = cs; /* Link this to context save list */ list_add_tail(&cs->node, &ctx->cs); + initial_setup = true; } ret = pm_runtime_get_sync(mcspi->dev); if (ret < 0) { pm_runtime_put_noidle(mcspi->dev); + if (initial_setup) + omap2_mcspi_cleanup(spi); return ret; } ret = omap2_mcspi_setup_transfer(spi, NULL); + if (ret && initial_setup) + omap2_mcspi_cleanup(spi); + pm_runtime_mark_last_busy(mcspi->dev); pm_runtime_put_autosuspend(mcspi->dev); return ret; } -static void omap2_mcspi_cleanup(struct spi_device *spi) -{ - struct omap2_mcspi_cs *cs; - - if (spi->controller_state) { - /* Unlink controller state from context save list */ - cs = spi->controller_state; - list_del(&cs->node); - - kfree(cs); - } -} - static irqreturn_t omap2_mcspi_irq_handler(int irq, void *data) { struct omap2_mcspi *mcspi = data; diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index d6b534d38e5d..56a62095ec8c 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1254,6 +1254,8 @@ static int setup_cs(struct spi_device *spi, struct chip_data *chip, chip->gpio_cs_inverted = spi->mode & SPI_CS_HIGH; err = gpiod_direction_output(gpiod, !chip->gpio_cs_inverted); + if (err) + gpiod_put(chip->gpiod_cs); } return err; @@ -1267,6 +1269,7 @@ static int setup(struct spi_device *spi) struct driver_data *drv_data = spi_controller_get_devdata(spi->controller); uint tx_thres, tx_hi_thres, rx_thres; + int err; switch (drv_data->ssp_type) { case QUARK_X1000_SSP: @@ -1413,7 +1416,11 @@ static int setup(struct spi_device *spi) if (drv_data->ssp_type == CE4100_SSP) return 0; - return setup_cs(spi, chip, chip_info); + err = setup_cs(spi, chip, chip_info); + if (err) + kfree(chip); + + return err; } static void cleanup(struct spi_device *spi) diff --git a/drivers/spi/spi-sprd.c b/drivers/spi/spi-sprd.c index b41a75749b49..28e70db9bbba 100644 --- a/drivers/spi/spi-sprd.c +++ b/drivers/spi/spi-sprd.c @@ -1068,6 +1068,7 @@ static const struct of_device_id sprd_spi_of_match[] = { { .compatible = "sprd,sc9860-spi", }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, sprd_spi_of_match); static struct platform_driver sprd_spi_driver = { .driver = { diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c index 2786470a5201..4f24f6392212 100644 --- a/drivers/spi/spi-stm32-qspi.c +++ b/drivers/spi/spi-stm32-qspi.c @@ -293,7 +293,7 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi, int err = 0; if (!op->data.nbytes) - return stm32_qspi_wait_nobusy(qspi); + goto wait_nobusy; if (readl_relaxed(qspi->io_base + QSPI_SR) & SR_TCF) goto out; @@ -314,6 +314,9 @@ static int stm32_qspi_wait_cmd(struct stm32_qspi *qspi, out: /* clear flags */ writel_relaxed(FCR_CTCF | FCR_CTEF, qspi->io_base + QSPI_FCR); +wait_nobusy: + if (!err) + err = stm32_qspi_wait_nobusy(qspi); return err; } diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index 0318f02d6212..a6dfc8fef20c 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -917,15 +917,18 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id) ier = readl_relaxed(spi->base + STM32H7_SPI_IER); mask = ier; - /* EOTIE is triggered on EOT, SUSP and TXC events. */ + /* + * EOTIE enables irq from EOT, SUSP and TXC events. We need to set + * SUSP to acknowledge it later. TXC is automatically cleared + */ + mask |= STM32H7_SPI_SR_SUSP; /* - * When TXTF is set, DXPIE and TXPIE are cleared. So in case of - * Full-Duplex, need to poll RXP event to know if there are remaining - * data, before disabling SPI. + * DXPIE is set in Full-Duplex, one IT will be raised if TXP and RXP + * are set. So in case of Full-Duplex, need to poll TXP and RXP event. */ - if (spi->rx_buf && !spi->cur_usedma) - mask |= STM32H7_SPI_SR_RXP; + if ((spi->cur_comm == SPI_FULL_DUPLEX) && !spi->cur_usedma) + mask |= STM32H7_SPI_SR_TXP | STM32H7_SPI_SR_RXP; if (!(sr & mask)) { dev_warn(spi->dev, "spurious IT (sr=0x%08x, ier=0x%08x)\n", @@ -1946,6 +1949,7 @@ static int stm32_spi_probe(struct platform_device *pdev) master->can_dma = stm32_spi_can_dma; pm_runtime_set_active(&pdev->dev); + pm_runtime_get_noresume(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = spi_register_master(master); @@ -1967,6 +1971,8 @@ static int stm32_spi_probe(struct platform_device *pdev) err_pm_disable: pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); err_dma_release: if (spi->dma_tx) dma_release_channel(spi->dma_tx); @@ -1983,9 +1989,14 @@ static int stm32_spi_remove(struct platform_device *pdev) struct spi_master *master = platform_get_drvdata(pdev); struct stm32_spi *spi = spi_master_get_devdata(master); + pm_runtime_get_sync(&pdev->dev); + spi_unregister_master(master); spi->cfg->disable(spi); + pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); if (master->dma_tx) dma_release_channel(master->dma_tx); if (master->dma_rx) @@ -1993,7 +2004,6 @@ static int stm32_spi_remove(struct platform_device *pdev) clk_disable_unprepare(spi->clk); - pm_runtime_disable(&pdev->dev); pinctrl_pm_select_sleep_state(&pdev->dev); diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 19238e1b76b4..803d92f8d031 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c @@ -290,6 +290,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master, } sun6i_spi_write(sspi, SUN6I_CLK_CTL_REG, reg); + /* Finally enable the bus - doing so before might raise SCK to HIGH */ + reg = sun6i_spi_read(sspi, SUN6I_GBL_CTL_REG); + reg |= SUN6I_GBL_CTL_BUS_ENABLE; + sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, reg); /* Setup the transfer now... */ if (sspi->tx_buf) @@ -398,7 +402,7 @@ static int sun6i_spi_runtime_resume(struct device *dev) } sun6i_spi_write(sspi, SUN6I_GBL_CTL_REG, - SUN6I_GBL_CTL_BUS_ENABLE | SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); + SUN6I_GBL_CTL_MASTER | SUN6I_GBL_CTL_TP); return 0; diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index b459e369079f..7fb020a1d66a 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -580,8 +580,10 @@ static void pch_spi_set_tx(struct pch_spi_data *data, int *bpw) data->pkt_tx_buff = kzalloc(size, GFP_KERNEL); if (data->pkt_tx_buff != NULL) { data->pkt_rx_buff = kzalloc(size, GFP_KERNEL); - if (!data->pkt_rx_buff) + if (!data->pkt_rx_buff) { kfree(data->pkt_tx_buff); + data->pkt_tx_buff = NULL; + } } if (!data->pkt_rx_buff) { diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c index 5d8a5ee62fa2..68193db8b2e3 100644 --- a/drivers/spi/spi-zynq-qspi.c +++ b/drivers/spi/spi-zynq-qspi.c @@ -528,18 +528,17 @@ static int zynq_qspi_exec_mem_op(struct spi_mem *mem, struct zynq_qspi *xqspi = spi_controller_get_devdata(mem->spi->master); int err = 0, i; u8 *tmpbuf; - u8 opcode = op->cmd.opcode; dev_dbg(xqspi->dev, "cmd:%#x mode:%d.%d.%d.%d\n", - opcode, op->cmd.buswidth, op->addr.buswidth, + op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, op->dummy.buswidth, op->data.buswidth); zynq_qspi_chipselect(mem->spi, true); zynq_qspi_config_op(xqspi, mem->spi); - if (op->cmd.nbytes) { + if (op->cmd.opcode) { reinit_completion(&xqspi->data_completion); - xqspi->txbuf = &opcode; + xqspi->txbuf = (u8 *)&op->cmd.opcode; xqspi->rxbuf = NULL; xqspi->tx_bytes = op->cmd.nbytes; xqspi->rx_bytes = op->cmd.nbytes; @@ -679,14 +678,14 @@ static int zynq_qspi_probe(struct platform_device *pdev) xqspi->irq = platform_get_irq(pdev, 0); if (xqspi->irq <= 0) { ret = -ENXIO; - goto remove_master; + goto clk_dis_all; } ret = devm_request_irq(&pdev->dev, xqspi->irq, zynq_qspi_irq, 0, pdev->name, xqspi); if (ret != 0) { ret = -ENXIO; dev_err(&pdev->dev, "request_irq failed\n"); - goto remove_master; + goto clk_dis_all; } ret = of_property_read_u32(np, "num-cs", @@ -694,8 +693,9 @@ static int zynq_qspi_probe(struct platform_device *pdev) if (ret < 0) { ctlr->num_chipselect = 1; } else if (num_cs > ZYNQ_QSPI_MAX_NUM_CS) { + ret = -EINVAL; dev_err(&pdev->dev, "only 2 chip selects are available\n"); - goto remove_master; + goto clk_dis_all; } else { ctlr->num_chipselect = num_cs; } diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 88f221e760f1..c640a9f4f1c8 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -47,10 +47,6 @@ static void spidev_release(struct device *dev) { struct spi_device *spi = to_spi_device(dev); - /* spi controllers may cleanup for released devices */ - if (spi->controller->cleanup) - spi->controller->cleanup(spi); - spi_controller_put(spi->controller); kfree(spi->driver_override); kfree(spi); @@ -550,6 +546,12 @@ static int spi_dev_check(struct device *dev, void *data) return 0; } +static void spi_cleanup(struct spi_device *spi) +{ + if (spi->controller->cleanup) + spi->controller->cleanup(spi); +} + /** * spi_add_device - Add spi_device allocated with spi_alloc_device * @spi: spi_device to register @@ -614,11 +616,13 @@ int spi_add_device(struct spi_device *spi) /* Device may be bound to an active driver when this returns */ status = device_add(&spi->dev); - if (status < 0) + if (status < 0) { dev_err(dev, "can't add %s, status %d\n", dev_name(&spi->dev), status); - else + spi_cleanup(spi); + } else { dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev)); + } done: mutex_unlock(&spi_add_lock); @@ -711,7 +715,9 @@ void spi_unregister_device(struct spi_device *spi) } if (ACPI_COMPANION(&spi->dev)) acpi_device_clear_enumerated(ACPI_COMPANION(&spi->dev)); - device_unregister(&spi->dev); + device_del(&spi->dev); + spi_cleanup(spi); + put_device(&spi->dev); } EXPORT_SYMBOL_GPL(spi_unregister_device); @@ -2607,9 +2613,10 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr) native_cs_mask |= BIT(i); } - ctlr->unused_native_cs = ffz(native_cs_mask); - if (num_cs_gpios && ctlr->max_native_cs && - ctlr->unused_native_cs >= ctlr->max_native_cs) { + ctlr->unused_native_cs = ffs(~native_cs_mask) - 1; + + if ((ctlr->flags & SPI_MASTER_GPIO_SS) && num_cs_gpios && + ctlr->max_native_cs && ctlr->unused_native_cs >= ctlr->max_native_cs) { dev_err(dev, "No unused native chip select available\n"); return -EINVAL; } diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c index f49ab1aa2149..4161e5d1f276 100644 --- a/drivers/ssb/scan.c +++ b/drivers/ssb/scan.c @@ -325,6 +325,7 @@ int ssb_bus_scan(struct ssb_bus *bus, if (bus->nr_devices > ARRAY_SIZE(bus->devices)) { pr_err("More than %d ssb cores found (%d)\n", SSB_MAX_NR_CORES, bus->nr_devices); + err = -EINVAL; goto err_unmap; } if (bus->bustype == SSB_BUSTYPE_SSB) { diff --git a/drivers/ssb/sdio.c b/drivers/ssb/sdio.c index 7fe0afb42234..66c5c2169704 100644 --- a/drivers/ssb/sdio.c +++ b/drivers/ssb/sdio.c @@ -411,7 +411,6 @@ static void ssb_sdio_block_write(struct ssb_device *dev, const void *buffer, sdio_claim_host(bus->host_sdio); if (unlikely(ssb_sdio_switch_core(bus, dev))) { error = -EIO; - memset((void *)buffer, 0xff, count); goto err_out; } offset |= bus->sdio_sbaddr & 0xffff; diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c index eeeeec97ad27..b545c2ca80a4 100644 --- a/drivers/staging/fbtft/fb_agm1264k-fl.c +++ b/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -84,9 +84,9 @@ static void reset(struct fbtft_par *par) dev_dbg(par->info->device, "%s()\n", __func__); - gpiod_set_value(par->gpio.reset, 0); - udelay(20); gpiod_set_value(par->gpio.reset, 1); + udelay(20); + gpiod_set_value(par->gpio.reset, 0); mdelay(120); } @@ -194,12 +194,12 @@ static void write_reg8_bus8(struct fbtft_par *par, int len, ...) /* select chip */ if (*buf) { /* cs1 */ - gpiod_set_value(par->CS0, 1); - gpiod_set_value(par->CS1, 0); - } else { - /* cs0 */ gpiod_set_value(par->CS0, 0); gpiod_set_value(par->CS1, 1); + } else { + /* cs0 */ + gpiod_set_value(par->CS0, 1); + gpiod_set_value(par->CS1, 0); } gpiod_set_value(par->RS, 0); /* RS->0 (command mode) */ @@ -397,8 +397,8 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) } kfree(convert_buf); - gpiod_set_value(par->CS0, 1); - gpiod_set_value(par->CS1, 1); + gpiod_set_value(par->CS0, 0); + gpiod_set_value(par->CS1, 0); return ret; } @@ -419,10 +419,10 @@ static int write(struct fbtft_par *par, void *buf, size_t len) for (i = 0; i < 8; ++i) gpiod_set_value(par->gpio.db[i], data & (1 << i)); /* set E */ - gpiod_set_value(par->EPIN, 1); + gpiod_set_value(par->EPIN, 0); udelay(5); /* unset E - write */ - gpiod_set_value(par->EPIN, 0); + gpiod_set_value(par->EPIN, 1); udelay(1); } diff --git a/drivers/staging/fbtft/fb_bd663474.c b/drivers/staging/fbtft/fb_bd663474.c index e2c7646588f8..1629c2c440a9 100644 --- a/drivers/staging/fbtft/fb_bd663474.c +++ b/drivers/staging/fbtft/fb_bd663474.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "fbtft.h" @@ -24,9 +23,6 @@ static int init_display(struct fbtft_par *par) { - if (par->gpio.cs) - gpiod_set_value(par->gpio.cs, 0); /* Activate chip */ - par->fbtftops.reset(par); /* Initialization sequence from Lib_UTFT */ diff --git a/drivers/staging/fbtft/fb_ili9163.c b/drivers/staging/fbtft/fb_ili9163.c index 05648c3ffe47..6582a2c90aaf 100644 --- a/drivers/staging/fbtft/fb_ili9163.c +++ b/drivers/staging/fbtft/fb_ili9163.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include