Merge tag 'pm-6.13-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Jan 2025 17:04:10 +0000 (09:04 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 16 Jan 2025 17:04:10 +0000 (09:04 -0800)
Pull power management fixes from Rafael Wysocki:
 "Update the documentation of cpuidle governors that does not match the
  code any more after previous functional changes (Rafael Wysocki) and
  fix up the cpufreq Kconfig file broken inadvertently by a previous
  update (Viresh Kumar)"

* tag 'pm-6.13-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq: Move endif to the end of Kconfig file
  cpuidle: teo: Update documentation after previous changes
  cpuidle: menu: Update documentation after previous changes

41 files changed:
Documentation/sound/codecs/cs35l56.rst [new file with mode: 0644]
Documentation/sound/codecs/index.rst [new file with mode: 0644]
Documentation/sound/index.rst
MAINTAINERS
arch/x86/mm/init.c
drivers/acpi/acpi_video.c
drivers/block/zram/zram_drv.c
drivers/gpu/drm/nouveau/nouveau_acpi.c
drivers/pci/pcie/bwctrl.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_transport_iscsi.c
fs/btrfs/volumes.c
fs/proc/vmcore.c
include/linux/module.h
include/linux/seccomp.h
include/linux/userfaultfd_k.h
include/trace/events/hugetlbfs.h
mm/filemap.c
mm/huge_memory.c
mm/hugetlb.c
mm/kmemleak.c
mm/mempolicy.c
mm/mremap.c
mm/page-writeback.c
mm/vmscan.c
mm/vmstat.c
mm/zswap.c
scripts/decode_stacktrace.sh
sound/pci/hda/patch_realtek.c
sound/soc/codecs/Kconfig
sound/soc/codecs/cs42l43.c
sound/soc/codecs/es8316.c
sound/soc/codecs/es8326.c
sound/soc/codecs/tas2781-i2c.c
sound/soc/renesas/rcar/adg.c
sound/soc/renesas/rcar/core.c
sound/soc/renesas/rcar/rsnd.h
sound/soc/samsung/Kconfig
tools/testing/selftests/mm/cow.c
tools/testing/shared/linux/maple_tree.h
tools/testing/vma/linux/atomic.h

diff --git a/Documentation/sound/codecs/cs35l56.rst b/Documentation/sound/codecs/cs35l56.rst
new file mode 100644 (file)
index 0000000..98c6f6c
--- /dev/null
@@ -0,0 +1,292 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+=====================================================================
+Audio drivers for Cirrus Logic CS35L54/56/57 Boosted Smart Amplifiers
+=====================================================================
+:Copyright: 2025 Cirrus Logic, Inc. and
+                 Cirrus Logic International Semiconductor Ltd.
+
+Contact: patches@opensource.cirrus.com
+
+Summary
+=======
+
+The high-level summary of this document is:
+
+**If you have a laptop that uses CS35L54/56/57 amplifiers but audio is not
+working, DO NOT ATTEMPT TO USE FIRMWARE AND SETTINGS FROM ANOTHER LAPTOP,
+EVEN IF THAT LAPTOP SEEMS SIMILAR.**
+
+The CS35L54/56/57 amplifiers must be correctly configured for the power
+supply voltage, speaker impedance, maximum speaker voltage/current, and
+other external hardware connections.
+
+The amplifiers feature advanced boost technology that increases the voltage
+used to drive the speakers, while proprietary speaker protection algorithms
+allow these boosted amplifiers to push the limits of the speakers without
+causing damage. These **must** be configured correctly.
+
+Supported Cirrus Logic amplifiers
+---------------------------------
+
+The cs35l56 drivers support:
+
+* CS35L54
+* CS35L56
+* CS35L57
+
+There are two drivers in the kernel
+
+*For systems using SoundWire*: sound/soc/codecs/cs35l56.c and associated files
+
+*For systems using HDA*: sound/pci/hda/cs35l56_hda.c
+
+Firmware
+========
+
+The amplifier is controlled and managed by firmware running on the internal
+DSP. Firmware files are essential to enable the full capabilities of the
+amplifier.
+
+Firmware is distributed in the linux-firmware repository:
+https://gitlab.com/kernel-firmware/linux-firmware.git
+
+On most SoundWire systems the amplifier has a default minimum capability to
+produce audio. However this will be
+
+* at low volume, to protect the speakers, since the speaker specifications
+  and power supply voltages are unknown.
+* a mono mix of left and right channels.
+
+On some SoundWire systems that have both CS42L43 and CS35L56/57 the CS35L56/57
+receive their audio from the CS42L43 instead of directly from the host
+SoundWire interface. These systems can be identified by the CS42L43 showing
+in dmesg as a SoundWire device, but the CS35L56/57 as SPI. On these systems
+the firmware is *mandatory* to enable receiving the audio from the CS42L43.
+
+On HDA systems the firmware is *mandatory* to enable HDA bridge mode. There
+will not be any audio from the amplifiers without firmware.
+
+Cirrus Logic firmware files
+---------------------------
+
+Each amplifier requires two firmware files. One file has a .wmfw suffix, the
+other has a .bin suffix.
+
+The firmware is customized by the OEM to match the hardware of each laptop,
+and the firmware is specific to that laptop. Because of this, there are many
+firmware files in linux-firmware for these amplifiers. Firmware files are
+**not interchangeable between laptops**.
+
+Cirrus Logic submits files for known laptops to the upstream linux-firmware
+repository. Providing Cirrus Logic is aware of a particular laptop and has
+permission from the manufacturer to publish the firmware, it will be pushed
+to linux-firmware. You may need to upgrade to a newer release of
+linux-firmware to obtain the firmware for your laptop.
+
+**Important:** the Makefile for linux-firmware creates symlinks that are listed
+in the WHENCE file. These symlinks are required for the CS35L56 driver to be
+able to load the firmware.
+
+How do I know which firmware file I should have?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+All firmware file names are qualified with a unique "system ID". On normal
+x86 PCs with PCI audio this is the Vendor Subsystem ID (SSID) of the host
+PCI audio interface.
+
+The SSID can be viewed using the lspci tool::
+
+  lspci -v -nn | grep -A2 -i audio
+  0000:00:1f.3 Audio device [0403]: Intel Corporation Meteor Lake-P HD Audio Controller [8086:7e28]
+  Subsystem: Dell Meteor Lake-P HD Audio Controller [1028:0c63]
+
+In this example the SSID is 10280c63.
+
+The format of the firmware file names is:
+
+    cs35lxx-b0-dsp1-misc-SSID[-spkidX]-ampN
+
+Where:
+
+  * cs35lxx-b0 is the amplifier model and silicon revision. This information
+    is logged by the driver during initialization.
+  * SSID is the 8-digit hexadecimal SSID value.
+  * ampN is the amplifier number (for example amp1). This is the same as
+    the prefix on the ALSA control names except that it is always lower-case
+    in the file name.
+  * spkidX is an optional part, used for laptops that have firmware
+    configurations for different makes and models of internal speakers.
+
+Sound Open Firmware and ALSA topology files
+-------------------------------------------
+
+All SoundWire systems will require a Sound Open Firmware (SOF) for the
+host CPU audio DSP, together with an ALSA topology file (.tplg).
+
+The SOF firmware will usually be provided by the manufacturer of the host
+CPU (i.e. Intel or AMD). The .tplg file is normally part of the SOF firmware
+release.
+
+SOF binary builds are available from: https://github.com/thesofproject/sof-bin/releases
+
+The main SOF source is here: https://github.com/thesofproject
+
+ALSA-ucm configurations
+-----------------------
+Typically an appropriate ALSA-ucm configuration file is needed for
+use-case managers and audio servers such as PipeWire.
+
+Configuration files are available from the alsa-ucm-conf repository:
+https://git.alsa-project.org/?p=alsa-ucm-conf.git
+
+Kernel log messages
+===================
+
+SoundWire
+---------
+A successful initialization will look like this (this will be repeated for
+each amplifier)::
+
+  [ 7.568374] cs35l56 sdw:0:0:01fa:3556:01:0: supply VDD_P not found, using dummy regulator
+  [ 7.605208] cs35l56 sdw:0:0:01fa:3556:01:0: supply VDD_IO not found, using dummy regulator
+  [ 7.605313] cs35l56 sdw:0:0:01fa:3556:01:0: supply VDD_A not found, using dummy regulator
+  [ 7.939279] cs35l56 sdw:0:0:01fa:3556:01:0: Cirrus Logic CS35L56 Rev B0 OTP3 fw:3.4.4 (patched=0)
+  [ 7.947844] cs35l56 sdw:0:0:01fa:3556:01:0: Slave 4 state check1: UNATTACHED, status was 1
+  [ 8.740280] cs35l56 sdw:0:0:01fa:3556:01:0: supply VDD_B not found, using dummy regulator
+  [ 8.740552] cs35l56 sdw:0:0:01fa:3556:01:0: supply VDD_AMP not found, using dummy regulator
+  [ 9.242164] cs35l56 sdw:0:0:01fa:3556:01:0: DSP1: cirrus/cs35l56-b0-dsp1-misc-xxxxxxxx.wmfw: format 3 timestamp 0x66b2b872
+  [ 9.242173] cs35l56 sdw:0:0:01fa:3556:01:0: DSP1: cirrus/cs35l56-b0-dsp1-misc-xxxxxxxx.wmfw: Tue 05 Dec 2023 21:37:21 GMT Standard Time
+  [ 9.991709] cs35l56 sdw:0:0:01fa:3556:01:0: DSP1: Firmware: 1a00d6 vendor: 0x2 v3.11.23, 41 algorithms
+  [10.039098] cs35l56 sdw:0:0:01fa:3556:01:0: DSP1: cirrus/cs35l56-b0-dsp1-misc-xxxxxxxx-amp1.bin: v3.11.23
+  [10.879235] cs35l56 sdw:0:0:01fa:3556:01:0: Slave 4 state check1: UNATTACHED, status was 1
+  [11.401536] cs35l56 sdw:0:0:01fa:3556:01:0: Calibration applied
+
+HDA
+---
+A successful initialization will look like this (this will be repeated for
+each amplifier)::
+
+  [ 6.306475] cs35l56-hda i2c-CSC3556:00-cs35l56-hda.0: Cirrus Logic CS35L56 Rev B0 OTP3 fw:3.4.4 (patched=0)
+  [ 6.613892] cs35l56-hda i2c-CSC3556:00-cs35l56-hda.0: DSP system name: 'xxxxxxxx', amp name: 'AMP1'
+  [ 8.266660] snd_hda_codec_cs8409 ehdaudio0D0: bound i2c-CSC3556:00-cs35l56-hda.0 (ops cs35l56_hda_comp_ops [snd_hda_scodec_cs35l56])
+  [ 8.287525] cs35l56-hda i2c-CSC3556:00-cs35l56-hda.0: DSP1: cirrus/cs35l56-b0-dsp1-misc-xxxxxxxx.wmfw: format 3 timestamp 0x66b2b872
+  [ 8.287528] cs35l56-hda i2c-CSC3556:00-cs35l56-hda.0: DSP1: cirrus/cs35l56-b0-dsp1-misc-xxxxxxxx.wmfw: Tue 05 Dec 2023 21:37:21 GMT Standard Time
+  [ 9.984335] cs35l56-hda i2c-CSC3556:00-cs35l56-hda.0: DSP1: Firmware: 1a00d6 vendor: 0x2 v3.11.23, 41 algorithms
+  [10.085797] cs35l56-hda i2c-CSC3556:00-cs35l56-hda.0: DSP1: cirrus/cs35l56-b0-dsp1-misc-xxxxxxxx-amp1.bin: v3.11.23
+  [10.655237] cs35l56-hda i2c-CSC3556:00-cs35l56-hda.0: Calibration applied
+
+Important messages
+~~~~~~~~~~~~~~~~~~
+Cirrus Logic CS35L56 Rev B0 OTP3 fw:3.4.4 (patched=0)
+  Shows that the driver has been able to read device ID registers from the
+  amplifier.
+
+    * The actual amplifier type and silicon revision (CS35L56 B0 in this
+      example) is shown, as read from the amplifier identification registers.
+    * (patched=0) is normal, and indicates that the amplifier has been hard
+      reset and is running default ROM firmware.
+    * (patched=1) means that something has previously downloaded firmware
+      to the amplifier and the driver does not have control of the RESET
+      signal to be able to replace this preloaded firmware. This is normal
+      for systems where the BIOS downloads firmware to the amplifiers
+      before OS boot.
+      This status can also be seen if the cs35l56 kernel module is unloaded
+      and reloaded on a system where the driver does not have control of
+      RESET. SoundWire systems typically do not give the driver control of
+      RESET and only a BIOS (re)boot can reset the amplifiers.
+
+DSP1: cirrus/cs35l56-b0-dsp1-misc-xxxxxxxx.wmfw
+  Shows that a .wmfw firmware file was found and downloaded.
+
+DSP1: cirrus/cs35l56-b0-dsp1-misc-xxxxxxxx-amp1.bin
+  Shows that a .bin firmware file was found and downloaded.
+
+Calibration applied
+  Factory calibration data in EFI was written to the amplifier.
+
+Error messages
+==============
+This section explains some of the error messages that the driver can log.
+
+Algorithm coefficient version %d.%d.%d but expected %d.%d.%d
+  The version of the .bin file content does not match the loaded firmware.
+  Caused by mismatched .wmfw and .bin file, or .bin file was found but
+  .wmfw was not.
+
+No %s for algorithm %x
+  The version of the .bin file content does not match the loaded firmware.
+  Caused by mismatched .wmfw and .bin file, or .bin file was found but
+  .wmfw was not.
+
+.bin file required but not found
+  HDA driver did not find a .bin file that matches this hardware.
+
+Calibration disabled due to missing firmware controls
+  Driver was not able to write EFI calibration data to firmware registers.
+  This typically means that either:
+
+    * The driver did not find a suitable wmfw for this hardware, or
+    * The amplifier has already been patched with firmware by something
+      previously, and the driver does not have control of a hard RESET line
+      to be able to reset the amplifier and download the firmware files it
+      found. This situation is indicated by the device identification
+      string in the kernel log shows "(patched=1)"
+
+Failed to write calibration
+  Same meaning and cause as "Calibration disabled due to missing firmware
+  controls"
+
+Failed to read calibration data from EFI
+  Factory calibration data in EFI is missing, empty or corrupt.
+  This is most likely to be cause by accidentally deleting the file from
+  the EFI filesystem.
+
+No calibration for silicon ID
+  The factory calibration data in EFI does not match this hardware.
+  The most likely cause is that an amplifier has been replaced on the
+  motherboard without going through manufacturer calibration process to
+  generate calibration data for the new amplifier.
+
+Did not find any buses for CSCxxxx
+  Only on HDA systems. The HDA codec driver found an ACPI entry for
+  Cirrus Logic companion amps, but could not enumerate the ACPI entries for
+  the I2C/SPI buses. The most likely cause of this is that:
+
+    * The relevant bus driver (I2C or SPI) is not part of the kernel.
+    * The HDA codec driver was built-in to the kernel but the I2C/SPI
+      bus driver is a module and so the HDA codec driver cannot call the
+      bus driver functions.
+
+init_completion timed out
+  The SoundWire bus controller (host end) did not enumerate the amplifier.
+  In other words, the ACPI says there is an amplifier but for some reason
+  it was not detected on the bus.
+
+No AF01 node
+  Indicates an error in ACPI. A SoundWire system should have a Device()
+  node named "AF01" but it was not found.
+
+Failed to get spk-id-gpios
+  ACPI says that the driver should request a GPIO but the driver was not
+  able to get that GPIO. The most likely cause is that the kernel does not
+  include the correct GPIO or PINCTRL driver for this system.
+
+Failed to read spk-id
+  ACPI says that the driver should request a GPIO but the driver was not
+  able to read that GPIO.
+
+Unexpected spk-id element count
+  AF01 contains more speaker ID GPIO entries than the driver supports
+
+Overtemp error
+  Amplifier overheat protection was triggered and the amplifier shut down
+  to protect itself.
+
+Amp short error
+  Amplifier detected a short-circuit on the speaker output pins and shut
+  down for protection. This would normally indicate a damaged speaker.
+
+Hibernate wake failed
+  The driver tried to wake the amplifier from its power-saving state but
+  did not see the expected responses from the amplifier. This can be caused
+  by using firmware that does not match the hardware.
diff --git a/Documentation/sound/codecs/index.rst b/Documentation/sound/codecs/index.rst
new file mode 100644 (file)
index 0000000..2cb95d8
--- /dev/null
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Codec-Specific Information
+==========================
+
+.. toctree::
+   :maxdepth: 2
+
+   cs35l56
index c437f2a4bc85f0021ccd417e59206a97797e5220..51cd736f65b528c79d53f30f3e0cce7aff44d2e3 100644 (file)
@@ -13,6 +13,7 @@ Sound Subsystem Documentation
    alsa-configuration
    hd-audio/index
    cards/index
+   codecs/index
    utimers
 
 .. only::  subproject and html
index a87ddad78e26f28ffd0f3433560d6db1518f9f95..0fa7c5728f1e64d031f4a47b6fce1db484ce0fc2 100644 (file)
@@ -5465,6 +5465,7 @@ L:        linux-sound@vger.kernel.org
 L:     patches@opensource.cirrus.com
 S:     Maintained
 F:     Documentation/devicetree/bindings/sound/cirrus,cs*
+F:     Documentation/sound/codecs/cs*
 F:     drivers/mfd/cs42l43*
 F:     drivers/pinctrl/cirrus/pinctrl-cs42l43*
 F:     drivers/spi/spi-cs42l43*
@@ -21988,6 +21989,7 @@ W:      https://github.com/thesofproject/linux/
 F:     sound/soc/sof/
 
 SOUND - GENERIC SOUND CARD (Simple-Audio-Card, Audio-Graph-Card)
+M:     Mark Brown <broonie@kernel.org>
 M:     Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
 S:     Supported
 L:     linux-sound@vger.kernel.org
index c6d29f283001aee26d98c0b014f284329b605fe6..62aa4d66a032d59191e79d34fc0cdaa4f32f88db 100644 (file)
@@ -1080,7 +1080,8 @@ struct execmem_info __init *execmem_arch_setup(void)
 
        start = MODULES_VADDR + offset;
 
-       if (IS_ENABLED(CONFIG_ARCH_HAS_EXECMEM_ROX)) {
+       if (IS_ENABLED(CONFIG_ARCH_HAS_EXECMEM_ROX) &&
+           cpu_feature_enabled(X86_FEATURE_PSE)) {
                pgprot = PAGE_KERNEL_ROX;
                flags = EXECMEM_KASAN_SHADOW | EXECMEM_ROX_CACHE;
        } else {
index 8274a17872ed31de9257d5d048f0fbbee03add95..a972831dbd667d5f25781522c66809f5cf31e91c 100644 (file)
@@ -610,16 +610,28 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
        return 0;
 }
 
+/**
+ * acpi_video_device_EDID() - Get EDID from ACPI _DDC
+ * @device: video output device (LCD, CRT, ..)
+ * @edid: address for returned EDID pointer
+ * @length: _DDC length to request (must be a multiple of 128)
+ *
+ * Get EDID from ACPI _DDC. On success, a pointer to the EDID data is written
+ * to the @edid address, and the length of the EDID is returned. The caller is
+ * responsible for freeing the edid pointer.
+ *
+ * Return the length of EDID (positive value) on success or error (negative
+ * value).
+ */
 static int
-acpi_video_device_EDID(struct acpi_video_device *device,
-                      union acpi_object **edid, int length)
+acpi_video_device_EDID(struct acpi_video_device *device, void **edid, int length)
 {
-       int status;
+       acpi_status status;
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
        union acpi_object *obj;
        union acpi_object arg0 = { ACPI_TYPE_INTEGER };
        struct acpi_object_list args = { 1, &arg0 };
-
+       int ret;
 
        *edid = NULL;
 
@@ -636,16 +648,17 @@ acpi_video_device_EDID(struct acpi_video_device *device,
 
        obj = buffer.pointer;
 
-       if (obj && obj->type == ACPI_TYPE_BUFFER)
-               *edid = obj;
-       else {
+       if (obj && obj->type == ACPI_TYPE_BUFFER) {
+               *edid = kmemdup(obj->buffer.pointer, obj->buffer.length, GFP_KERNEL);
+               ret = *edid ? obj->buffer.length : -ENOMEM;
+       } else {
                acpi_handle_debug(device->dev->handle,
                                 "Invalid _DDC data for length %d\n", length);
-               status = -EFAULT;
-               kfree(obj);
+               ret = -EFAULT;
        }
 
-       return status;
+       kfree(obj);
+       return ret;
 }
 
 /* bus */
@@ -1435,9 +1448,7 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
 {
        struct acpi_video_bus *video;
        struct acpi_video_device *video_device;
-       union acpi_object *buffer = NULL;
-       acpi_status status;
-       int i, length;
+       int i, length, ret;
 
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
@@ -1477,16 +1488,10 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
                }
 
                for (length = 512; length > 0; length -= 128) {
-                       status = acpi_video_device_EDID(video_device, &buffer,
-                                                       length);
-                       if (ACPI_SUCCESS(status))
-                               break;
+                       ret = acpi_video_device_EDID(video_device, edid, length);
+                       if (ret > 0)
+                               return ret;
                }
-               if (!length)
-                       continue;
-
-               *edid = buffer->buffer.pointer;
-               return length;
        }
 
        return -ENODEV;
index 45df5eeabc5e3df07ad8525a6b33813f0bb49749..7903a4da40acfb02aba7a7f5aee49d162965350f 100644 (file)
@@ -1468,6 +1468,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize)
        zram->mem_pool = zs_create_pool(zram->disk->disk_name);
        if (!zram->mem_pool) {
                vfree(zram->table);
+               zram->table = NULL;
                return false;
        }
 
index 8f0c69aad248ea34c5e5b34738067f67cb6ce938..21b56cc7605ce37e3f6f8c60151bfbb854cad312 100644 (file)
@@ -384,7 +384,7 @@ nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
        if (ret < 0)
                return NULL;
 
-       return kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
+       return edid;
 }
 
 bool nouveau_acpi_video_backlight_use_native(void)
index b59cacc740fa24d5f08a679ed4c0564ffe236b94..0a5e7efbce2ccafb67b8a8e7a67e5d5623663208 100644 (file)
@@ -303,14 +303,17 @@ static int pcie_bwnotif_probe(struct pcie_device *srv)
        if (ret)
                return ret;
 
-       ret = devm_request_irq(&srv->device, srv->irq, pcie_bwnotif_irq,
-                              IRQF_SHARED, "PCIe bwctrl", srv);
-       if (ret)
-               return ret;
-
        scoped_guard(rwsem_write, &pcie_bwctrl_setspeed_rwsem) {
                scoped_guard(rwsem_write, &pcie_bwctrl_lbms_rwsem) {
-                       port->link_bwctrl = no_free_ptr(data);
+                       port->link_bwctrl = data;
+
+                       ret = request_irq(srv->irq, pcie_bwnotif_irq,
+                                         IRQF_SHARED, "PCIe bwctrl", srv);
+                       if (ret) {
+                               port->link_bwctrl = NULL;
+                               return ret;
+                       }
+
                        pcie_bwnotif_enable(srv);
                }
        }
@@ -331,11 +334,15 @@ static void pcie_bwnotif_remove(struct pcie_device *srv)
 
        pcie_cooling_device_unregister(data->cdev);
 
-       pcie_bwnotif_disable(srv->port);
+       scoped_guard(rwsem_write, &pcie_bwctrl_setspeed_rwsem) {
+               scoped_guard(rwsem_write, &pcie_bwctrl_lbms_rwsem) {
+                       pcie_bwnotif_disable(srv->port);
+
+                       free_irq(srv->irq, srv);
 
-       scoped_guard(rwsem_write, &pcie_bwctrl_setspeed_rwsem)
-               scoped_guard(rwsem_write, &pcie_bwctrl_lbms_rwsem)
                        srv->port->link_bwctrl = NULL;
+               }
+       }
 }
 
 static int pcie_bwnotif_suspend(struct pcie_device *srv)
index adee6f60c966553ffb9dc632b12646d7225477d5..0cc6a0f77b09229418a092b793bf077cd9ad440b 100644 (file)
@@ -210,6 +210,9 @@ static int scsi_check_passthrough(struct scsi_cmnd *scmd,
        struct scsi_sense_hdr sshdr;
        enum sam_status status;
 
+       if (!scmd->result)
+               return 0;
+
        if (!failures)
                return 0;
 
index fde7de3b1e55381f7cd468ad308a3e4ee9417c8c..9b47f91c5b9720255b029f6a15c276efe50dc7fc 100644 (file)
@@ -4104,7 +4104,7 @@ iscsi_if_rx(struct sk_buff *skb)
                }
                do {
                        /*
-                        * special case for GET_STATS:
+                        * special case for GET_STATS, GET_CHAP and GET_HOST_STATS:
                         * on success - sending reply and stats from
                         * inside of if_recv_msg(),
                         * on error - fall through.
@@ -4113,6 +4113,8 @@ iscsi_if_rx(struct sk_buff *skb)
                                break;
                        if (ev->type == ISCSI_UEVENT_GET_CHAP && !err)
                                break;
+                       if (ev->type == ISCSI_UEVENT_GET_HOST_STATS && !err)
+                               break;
                        err = iscsi_if_send_reply(portid, nlh->nlmsg_type,
                                                  ev, sizeof(*ev));
                        if (err == -EAGAIN && --retries < 0) {
index 1cccaf9c2b0d5d4029440c46a4a92c7d6541d474..3d0ac8bdb21fe4a62c5cd5c85fb60373fb4473f4 100644 (file)
@@ -797,6 +797,10 @@ static int get_canonical_dev_path(const char *dev_path, char *canonical)
        if (ret)
                goto out;
        resolved_path = d_path(&path, path_buf, PATH_MAX);
+       if (IS_ERR(resolved_path)) {
+               ret = PTR_ERR(resolved_path);
+               goto out;
+       }
        ret = strscpy(canonical, resolved_path, PATH_MAX);
 out:
        kfree(path_buf);
index 3d8a82cee63e3611c4723c3c41c15e6f8b43035b..658bf199d4247949966235e7c3e8afff42a7cbc7 100644 (file)
@@ -404,6 +404,8 @@ static ssize_t __read_vmcore(struct iov_iter *iter, loff_t *fpos)
                        if (!iov_iter_count(iter))
                                return acc;
                }
+
+               cond_resched();
        }
 
        return acc;
index 94acbacdcdf189e27013088de2202bccac9717e0..b3a643435357986f3f9fe852260ca07f371cf86c 100644 (file)
@@ -773,7 +773,8 @@ void *__module_writable_address(struct module *mod, void *loc);
 
 static inline void *module_writable_address(struct module *mod, void *loc)
 {
-       if (!IS_ENABLED(CONFIG_ARCH_HAS_EXECMEM_ROX) || !mod)
+       if (!IS_ENABLED(CONFIG_ARCH_HAS_EXECMEM_ROX) || !mod ||
+           mod->state != MODULE_STATE_UNFORMED)
                return loc;
        return __module_writable_address(mod, loc);
 }
index 341980599c71242d3bb95b544c954278efcc65b9..e45531455d3bbe4ea0ec9e873b73bc3f02bfa2e5 100644 (file)
@@ -55,10 +55,10 @@ struct seccomp_data;
 
 #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
 static inline int secure_computing(void) { return 0; }
-static inline int __secure_computing(const struct seccomp_data *sd) { return 0; }
 #else
 static inline void secure_computing_strict(int this_syscall) { return; }
 #endif
+static inline int __secure_computing(const struct seccomp_data *sd) { return 0; }
 
 static inline long prctl_get_seccomp(void)
 {
index cb40f1a1d0811d4e8122fe300a1d63eaa2db7214..75342022d144145eaebfe7b534fc9021bef7318a 100644 (file)
@@ -247,6 +247,13 @@ static inline bool vma_can_userfault(struct vm_area_struct *vma,
            vma_is_shmem(vma);
 }
 
+static inline bool vma_has_uffd_without_event_remap(struct vm_area_struct *vma)
+{
+       struct userfaultfd_ctx *uffd_ctx = vma->vm_userfaultfd_ctx.ctx;
+
+       return uffd_ctx && (uffd_ctx->features & UFFD_FEATURE_EVENT_REMAP) == 0;
+}
+
 extern int dup_userfaultfd(struct vm_area_struct *, struct list_head *);
 extern void dup_userfaultfd_complete(struct list_head *);
 void dup_userfaultfd_fail(struct list_head *);
@@ -402,6 +409,11 @@ static inline bool userfaultfd_wp_async(struct vm_area_struct *vma)
        return false;
 }
 
+static inline bool vma_has_uffd_without_event_remap(struct vm_area_struct *vma)
+{
+       return false;
+}
+
 #endif /* CONFIG_USERFAULTFD */
 
 static inline bool userfaultfd_wp_use_markers(struct vm_area_struct *vma)
index 8331c904a9ba871ecc159925c4ddea38dc0fa2d4..59605dfaeeb43d9e7657e338fdbe740e8486a286 100644 (file)
@@ -23,7 +23,7 @@ TRACE_EVENT(hugetlbfs_alloc_inode,
        TP_fast_assign(
                __entry->dev            = inode->i_sb->s_dev;
                __entry->ino            = inode->i_ino;
-               __entry->dir            = dir->i_ino;
+               __entry->dir            = dir ? dir->i_ino : 0;
                __entry->mode           = mode;
        ),
 
index 33b60d448fca518b0385a1f28e2480bc71043111..4f476411a9a2dadf6b24f1852eda2e2d429a9df9 100644 (file)
@@ -1523,7 +1523,7 @@ void folio_end_read(struct folio *folio, bool success)
        /* Must be in bottom byte for x86 to work */
        BUILD_BUG_ON(PG_uptodate > 7);
        VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
-       VM_BUG_ON_FOLIO(folio_test_uptodate(folio), folio);
+       VM_BUG_ON_FOLIO(success && folio_test_uptodate(folio), folio);
 
        if (likely(success))
                mask |= 1 << PG_uptodate;
@@ -2996,7 +2996,7 @@ static inline loff_t folio_seek_hole_data(struct xa_state *xas,
                if (ops->is_partially_uptodate(folio, offset, bsz) ==
                                                        seek_data)
                        break;
-               start = (start + bsz) & ~(bsz - 1);
+               start = (start + bsz) & ~((u64)bsz - 1);
                offset += bsz;
        } while (offset < folio_size(folio));
 unlock:
index e53d83b3e5cf9702d5ddfaef7cd172a9a203e955..db64116a4f84899d719e8fae688e29a2bd771cd3 100644 (file)
@@ -2206,6 +2206,16 @@ static pmd_t move_soft_dirty_pmd(pmd_t pmd)
        return pmd;
 }
 
+static pmd_t clear_uffd_wp_pmd(pmd_t pmd)
+{
+       if (pmd_present(pmd))
+               pmd = pmd_clear_uffd_wp(pmd);
+       else if (is_swap_pmd(pmd))
+               pmd = pmd_swp_clear_uffd_wp(pmd);
+
+       return pmd;
+}
+
 bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
                  unsigned long new_addr, pmd_t *old_pmd, pmd_t *new_pmd)
 {
@@ -2244,6 +2254,8 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
                        pgtable_trans_huge_deposit(mm, new_pmd, pgtable);
                }
                pmd = move_soft_dirty_pmd(pmd);
+               if (vma_has_uffd_without_event_remap(vma))
+                       pmd = clear_uffd_wp_pmd(pmd);
                set_pmd_at(mm, new_addr, new_pmd, pmd);
                if (force_flush)
                        flush_pmd_tlb_range(vma, old_addr, old_addr + PMD_SIZE);
index c498874a717011d137cebc2b87f468cbc43b7e3d..eaaec19caa7ceef4bb2f9333b3f8d605bb7ceb76 100644 (file)
@@ -5402,6 +5402,7 @@ static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr,
                          unsigned long new_addr, pte_t *src_pte, pte_t *dst_pte,
                          unsigned long sz)
 {
+       bool need_clear_uffd_wp = vma_has_uffd_without_event_remap(vma);
        struct hstate *h = hstate_vma(vma);
        struct mm_struct *mm = vma->vm_mm;
        spinlock_t *src_ptl, *dst_ptl;
@@ -5418,7 +5419,18 @@ static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr,
                spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
 
        pte = huge_ptep_get_and_clear(mm, old_addr, src_pte);
-       set_huge_pte_at(mm, new_addr, dst_pte, pte, sz);
+
+       if (need_clear_uffd_wp && pte_marker_uffd_wp(pte))
+               huge_pte_clear(mm, new_addr, dst_pte, sz);
+       else {
+               if (need_clear_uffd_wp) {
+                       if (pte_present(pte))
+                               pte = huge_pte_clear_uffd_wp(pte);
+                       else if (is_swap_pte(pte))
+                               pte = pte_swp_clear_uffd_wp(pte);
+               }
+               set_huge_pte_at(mm, new_addr, dst_pte, pte, sz);
+       }
 
        if (src_ptl != dst_ptl)
                spin_unlock(src_ptl);
index 737af23f4f4e1ebfec6852820ca2cdc0e64dad2a..820ba3b5cbfc8f1d0ad29197f481ff39037b0b0a 100644 (file)
@@ -1093,7 +1093,7 @@ void __ref kmemleak_alloc_percpu(const void __percpu *ptr, size_t size,
        pr_debug("%s(0x%px, %zu)\n", __func__, ptr, size);
 
        if (kmemleak_enabled && ptr && !IS_ERR_PCPU(ptr))
-               create_object_percpu((__force unsigned long)ptr, size, 0, gfp);
+               create_object_percpu((__force unsigned long)ptr, size, 1, gfp);
 }
 EXPORT_SYMBOL_GPL(kmemleak_alloc_percpu);
 
index 04f35659717aedbf95787ba35965f3d2ed5ade22..162407fbf2bc76099f5c93da1add7056fe2df009 100644 (file)
@@ -2268,7 +2268,8 @@ struct page *alloc_pages_mpol_noprof(gfp_t gfp, unsigned int order,
 
        page = __alloc_pages_noprof(gfp, order, nid, nodemask);
 
-       if (unlikely(pol->mode == MPOL_INTERLEAVE) && page) {
+       if (unlikely(pol->mode == MPOL_INTERLEAVE ||
+                    pol->mode == MPOL_WEIGHTED_INTERLEAVE) && page) {
                /* skip NUMA_INTERLEAVE_HIT update if numa stats is disabled */
                if (static_branch_likely(&vm_numa_stat_key) &&
                    page_to_nid(page) == nid) {
index 60473413836bea6015c4efe68303703415f659f4..cff7f552f909045d156fc848f20e5d7aa7ca297b 100644 (file)
@@ -138,6 +138,7 @@ static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
                struct vm_area_struct *new_vma, pmd_t *new_pmd,
                unsigned long new_addr, bool need_rmap_locks)
 {
+       bool need_clear_uffd_wp = vma_has_uffd_without_event_remap(vma);
        struct mm_struct *mm = vma->vm_mm;
        pte_t *old_pte, *new_pte, pte;
        pmd_t dummy_pmdval;
@@ -216,7 +217,18 @@ static int move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
                        force_flush = true;
                pte = move_pte(pte, old_addr, new_addr);
                pte = move_soft_dirty_pte(pte);
-               set_pte_at(mm, new_addr, new_pte, pte);
+
+               if (need_clear_uffd_wp && pte_marker_uffd_wp(pte))
+                       pte_clear(mm, new_addr, new_pte);
+               else {
+                       if (need_clear_uffd_wp) {
+                               if (pte_present(pte))
+                                       pte = pte_clear_uffd_wp(pte);
+                               else if (is_swap_pte(pte))
+                                       pte = pte_swp_clear_uffd_wp(pte);
+                       }
+                       set_pte_at(mm, new_addr, new_pte, pte);
+               }
        }
 
        arch_leave_lazy_mmu_mode();
@@ -278,6 +290,15 @@ static bool move_normal_pmd(struct vm_area_struct *vma, unsigned long old_addr,
        if (WARN_ON_ONCE(!pmd_none(*new_pmd)))
                return false;
 
+       /* If this pmd belongs to a uffd vma with remap events disabled, we need
+        * to ensure that the uffd-wp state is cleared from all pgtables. This
+        * means recursing into lower page tables in move_page_tables(), and we
+        * can reuse the existing code if we simply treat the entry as "not
+        * moved".
+        */
+       if (vma_has_uffd_without_event_remap(vma))
+               return false;
+
        /*
         * We don't have to worry about the ordering of src and dst
         * ptlocks because exclusive mmap_lock prevents deadlock.
@@ -333,6 +354,15 @@ static bool move_normal_pud(struct vm_area_struct *vma, unsigned long old_addr,
        if (WARN_ON_ONCE(!pud_none(*new_pud)))
                return false;
 
+       /* If this pud belongs to a uffd vma with remap events disabled, we need
+        * to ensure that the uffd-wp state is cleared from all pgtables. This
+        * means recursing into lower page tables in move_page_tables(), and we
+        * can reuse the existing code if we simply treat the entry as "not
+        * moved".
+        */
+       if (vma_has_uffd_without_event_remap(vma))
+               return false;
+
        /*
         * We don't have to worry about the ordering of src and dst
         * ptlocks because exclusive mmap_lock prevents deadlock.
index d213ead9567509bb8aad36ac0bb0a8a5d2fbc153..d9861e42b2bd2431e3a5538061bfe49821c13826 100644 (file)
@@ -692,6 +692,8 @@ static unsigned long bdi_ratio_from_pages(unsigned long pages)
        unsigned long ratio;
 
        global_dirty_limits(&background_thresh, &dirty_thresh);
+       if (!dirty_thresh)
+               return -EINVAL;
        ratio = div64_u64(pages * 100ULL * BDI_RATIO_SCALE, dirty_thresh);
 
        return ratio;
@@ -790,13 +792,15 @@ int bdi_set_min_bytes(struct backing_dev_info *bdi, u64 min_bytes)
 {
        int ret;
        unsigned long pages = min_bytes >> PAGE_SHIFT;
-       unsigned long min_ratio;
+       long min_ratio;
 
        ret = bdi_check_pages_limit(pages);
        if (ret)
                return ret;
 
        min_ratio = bdi_ratio_from_pages(pages);
+       if (min_ratio < 0)
+               return min_ratio;
        return __bdi_set_min_ratio(bdi, min_ratio);
 }
 
@@ -809,13 +813,15 @@ int bdi_set_max_bytes(struct backing_dev_info *bdi, u64 max_bytes)
 {
        int ret;
        unsigned long pages = max_bytes >> PAGE_SHIFT;
-       unsigned long max_ratio;
+       long max_ratio;
 
        ret = bdi_check_pages_limit(pages);
        if (ret)
                return ret;
 
        max_ratio = bdi_ratio_from_pages(pages);
+       if (max_ratio < 0)
+               return max_ratio;
        return __bdi_set_max_ratio(bdi, max_ratio);
 }
 
index 9a859b7d18d79aadb573c2104474aea555828166..b1ec5ece067e165d72ac064ba0744346d36a589c 100644 (file)
@@ -4642,6 +4642,9 @@ retry:
                reset_batch_size(walk);
        }
 
+       __mod_lruvec_state(lruvec, PGDEMOTE_KSWAPD + reclaimer_offset(),
+                                       stat.nr_demoted);
+
        item = PGSTEAL_KSWAPD + reclaimer_offset();
        if (!cgroup_reclaim(sc))
                __count_vm_events(item, reclaimed);
index 4d016314a56c95e6247f8970511afb364e686278..16bfe1c694dd4e0c98b39337a367a2ea86e8f3bd 100644 (file)
@@ -2122,10 +2122,20 @@ static void __init start_shepherd_timer(void)
 {
        int cpu;
 
-       for_each_possible_cpu(cpu)
+       for_each_possible_cpu(cpu) {
                INIT_DEFERRABLE_WORK(per_cpu_ptr(&vmstat_work, cpu),
                        vmstat_update);
 
+               /*
+                * For secondary CPUs during CPU hotplug scenarios,
+                * vmstat_cpu_online() will enable the work.
+                * mm/vmstat:online enables and disables vmstat_work
+                * symmetrically during CPU hotplug events.
+                */
+               if (!cpu_online(cpu))
+                       disable_delayed_work_sync(&per_cpu(vmstat_work, cpu));
+       }
+
        schedule_delayed_work(&shepherd,
                round_jiffies_relative(sysctl_stat_interval));
 }
@@ -2148,13 +2158,14 @@ static int vmstat_cpu_online(unsigned int cpu)
        if (!node_state(cpu_to_node(cpu), N_CPU)) {
                node_set_state(cpu_to_node(cpu), N_CPU);
        }
+       enable_delayed_work(&per_cpu(vmstat_work, cpu));
 
        return 0;
 }
 
 static int vmstat_cpu_down_prep(unsigned int cpu)
 {
-       cancel_delayed_work_sync(&per_cpu(vmstat_work, cpu));
+       disable_delayed_work_sync(&per_cpu(vmstat_work, cpu));
        return 0;
 }
 
index 5a27af8d86ea99da5dc6926915fb6b658f45fde9..30f5a27a686203ffa3de0a68d2d94c45eb67bb95 100644 (file)
@@ -251,7 +251,7 @@ static struct zswap_pool *zswap_pool_create(char *type, char *compressor)
        struct zswap_pool *pool;
        char name[38]; /* 'zswap' + 32 char (max) num + \0 */
        gfp_t gfp = __GFP_NORETRY | __GFP_NOWARN | __GFP_KSWAPD_RECLAIM;
-       int ret;
+       int ret, cpu;
 
        if (!zswap_has_pool) {
                /* if either are unset, pool initialization failed, and we
@@ -285,6 +285,9 @@ static struct zswap_pool *zswap_pool_create(char *type, char *compressor)
                goto error;
        }
 
+       for_each_possible_cpu(cpu)
+               mutex_init(&per_cpu_ptr(pool->acomp_ctx, cpu)->mutex);
+
        ret = cpuhp_state_add_instance(CPUHP_MM_ZSWP_POOL_PREPARE,
                                       &pool->node);
        if (ret)
@@ -821,11 +824,12 @@ static int zswap_cpu_comp_prepare(unsigned int cpu, struct hlist_node *node)
        struct acomp_req *req;
        int ret;
 
-       mutex_init(&acomp_ctx->mutex);
-
+       mutex_lock(&acomp_ctx->mutex);
        acomp_ctx->buffer = kmalloc_node(PAGE_SIZE * 2, GFP_KERNEL, cpu_to_node(cpu));
-       if (!acomp_ctx->buffer)
-               return -ENOMEM;
+       if (!acomp_ctx->buffer) {
+               ret = -ENOMEM;
+               goto buffer_fail;
+       }
 
        acomp = crypto_alloc_acomp_node(pool->tfm_name, 0, 0, cpu_to_node(cpu));
        if (IS_ERR(acomp)) {
@@ -855,12 +859,15 @@ static int zswap_cpu_comp_prepare(unsigned int cpu, struct hlist_node *node)
        acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
                                   crypto_req_done, &acomp_ctx->wait);
 
+       mutex_unlock(&acomp_ctx->mutex);
        return 0;
 
 req_fail:
        crypto_free_acomp(acomp_ctx->acomp);
 acomp_fail:
        kfree(acomp_ctx->buffer);
+buffer_fail:
+       mutex_unlock(&acomp_ctx->mutex);
        return ret;
 }
 
@@ -869,27 +876,43 @@ static int zswap_cpu_comp_dead(unsigned int cpu, struct hlist_node *node)
        struct zswap_pool *pool = hlist_entry(node, struct zswap_pool, node);
        struct crypto_acomp_ctx *acomp_ctx = per_cpu_ptr(pool->acomp_ctx, cpu);
 
+       mutex_lock(&acomp_ctx->mutex);
        if (!IS_ERR_OR_NULL(acomp_ctx)) {
                if (!IS_ERR_OR_NULL(acomp_ctx->req))
                        acomp_request_free(acomp_ctx->req);
+               acomp_ctx->req = NULL;
                if (!IS_ERR_OR_NULL(acomp_ctx->acomp))
                        crypto_free_acomp(acomp_ctx->acomp);
                kfree(acomp_ctx->buffer);
        }
+       mutex_unlock(&acomp_ctx->mutex);
 
        return 0;
 }
 
-/* Prevent CPU hotplug from freeing up the per-CPU acomp_ctx resources */
-static struct crypto_acomp_ctx *acomp_ctx_get_cpu(struct crypto_acomp_ctx __percpu *acomp_ctx)
+static struct crypto_acomp_ctx *acomp_ctx_get_cpu_lock(struct zswap_pool *pool)
 {
-       cpus_read_lock();
-       return raw_cpu_ptr(acomp_ctx);
+       struct crypto_acomp_ctx *acomp_ctx;
+
+       for (;;) {
+               acomp_ctx = raw_cpu_ptr(pool->acomp_ctx);
+               mutex_lock(&acomp_ctx->mutex);
+               if (likely(acomp_ctx->req))
+                       return acomp_ctx;
+               /*
+                * It is possible that we were migrated to a different CPU after
+                * getting the per-CPU ctx but before the mutex was acquired. If
+                * the old CPU got offlined, zswap_cpu_comp_dead() could have
+                * already freed ctx->req (among other things) and set it to
+                * NULL. Just try again on the new CPU that we ended up on.
+                */
+               mutex_unlock(&acomp_ctx->mutex);
+       }
 }
 
-static void acomp_ctx_put_cpu(void)
+static void acomp_ctx_put_unlock(struct crypto_acomp_ctx *acomp_ctx)
 {
-       cpus_read_unlock();
+       mutex_unlock(&acomp_ctx->mutex);
 }
 
 static bool zswap_compress(struct page *page, struct zswap_entry *entry,
@@ -905,9 +928,7 @@ static bool zswap_compress(struct page *page, struct zswap_entry *entry,
        gfp_t gfp;
        u8 *dst;
 
-       acomp_ctx = acomp_ctx_get_cpu(pool->acomp_ctx);
-       mutex_lock(&acomp_ctx->mutex);
-
+       acomp_ctx = acomp_ctx_get_cpu_lock(pool);
        dst = acomp_ctx->buffer;
        sg_init_table(&input, 1);
        sg_set_page(&input, page, PAGE_SIZE, 0);
@@ -960,8 +981,7 @@ unlock:
        else if (alloc_ret)
                zswap_reject_alloc_fail++;
 
-       mutex_unlock(&acomp_ctx->mutex);
-       acomp_ctx_put_cpu();
+       acomp_ctx_put_unlock(acomp_ctx);
        return comp_ret == 0 && alloc_ret == 0;
 }
 
@@ -972,9 +992,7 @@ static void zswap_decompress(struct zswap_entry *entry, struct folio *folio)
        struct crypto_acomp_ctx *acomp_ctx;
        u8 *src;
 
-       acomp_ctx = acomp_ctx_get_cpu(entry->pool->acomp_ctx);
-       mutex_lock(&acomp_ctx->mutex);
-
+       acomp_ctx = acomp_ctx_get_cpu_lock(entry->pool);
        src = zpool_map_handle(zpool, entry->handle, ZPOOL_MM_RO);
        /*
         * If zpool_map_handle is atomic, we cannot reliably utilize its mapped buffer
@@ -998,11 +1016,10 @@ static void zswap_decompress(struct zswap_entry *entry, struct folio *folio)
        acomp_request_set_params(acomp_ctx->req, &input, &output, entry->length, PAGE_SIZE);
        BUG_ON(crypto_wait_req(crypto_acomp_decompress(acomp_ctx->req), &acomp_ctx->wait));
        BUG_ON(acomp_ctx->req->dlen != PAGE_SIZE);
-       mutex_unlock(&acomp_ctx->mutex);
 
        if (src != acomp_ctx->buffer)
                zpool_unmap_handle(zpool, entry->handle);
-       acomp_ctx_put_cpu();
+       acomp_ctx_put_unlock(acomp_ctx);
 }
 
 /*********************************
index 46fa18b80fc1bc40734fcc9c8752af591e4e2737..17abc4e7a9855b10e76acfdb92847e1671d6c2bd 100755 (executable)
@@ -286,6 +286,18 @@ handle_line() {
                last=$(( $last - 1 ))
        fi
 
+       # Extract info after the symbol if present. E.g.:
+       # func_name+0x54/0x80 (P)
+       #                     ^^^
+       # The regex assumes only uppercase letters will be used. To be
+       # extended if needed.
+       local info_str=""
+       if [[ ${words[$last]} =~ \([A-Z]*\) ]]; then
+               info_str=${words[$last]}
+               unset words[$last]
+               last=$(( $last - 1 ))
+       fi
+
        if [[ ${words[$last]} =~ \[([^]]+)\] ]]; then
                module=${words[$last]}
                # some traces format is "(%pS)", which like "(foo+0x0/0x1 [bar])"
@@ -313,9 +325,9 @@ handle_line() {
        # Add up the line number to the symbol
        if [[ -z ${module} ]]
        then
-               echo "${words[@]}" "$symbol"
+               echo "${words[@]}" "$symbol ${info_str}"
        else
-               echo "${words[@]}" "$symbol $module"
+               echo "${words[@]}" "$symbol $module ${info_str}"
        fi
 }
 
index b74b566f675e94c7cdd76fc66312534dbc546866..ad66378d7321aadaf6c538bd53b48d985c2727fb 100644 (file)
@@ -10641,6 +10641,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1e1f, "ASUS Vivobook 15 X1504VAP", ALC2XX_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
        SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS),
+       SND_PCI_QUIRK(0x1043, 0x1e63, "ASUS H7606W", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1),
+       SND_PCI_QUIRK(0x1043, 0x1e83, "ASUS GA605W", ALC285_FIXUP_ASUS_GU605_SPI_SPEAKER2_TO_DAC1),
        SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401),
        SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2),
@@ -10930,8 +10932,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x38e0, "Yoga Y990 Intel VECO Dual", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38f8, "Yoga Book 9i", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x38df, "Y990 YG DUAL", ALC287_FIXUP_TAS2781_I2C),
-       SND_PCI_QUIRK(0x17aa, 0x38f9, "Thinkbook 16P Gen5", ALC287_FIXUP_CS35L41_I2C_2),
-       SND_PCI_QUIRK(0x17aa, 0x38fa, "Thinkbook 16P Gen5", ALC287_FIXUP_CS35L41_I2C_2),
+       SND_PCI_QUIRK(0x17aa, 0x38f9, "Thinkbook 16P Gen5", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
+       SND_PCI_QUIRK(0x17aa, 0x38fa, "Thinkbook 16P Gen5", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD),
        SND_PCI_QUIRK(0x17aa, 0x38fd, "ThinkBook plus Gen5 Hybrid", ALC287_FIXUP_TAS2781_I2C),
        SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
        SND_PCI_QUIRK(0x17aa, 0x3913, "Lenovo 145", ALC236_FIXUP_LENOVO_INV_DMIC),
@@ -10995,6 +10997,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
        SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC),
        SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
+       SND_PCI_QUIRK(0x1f66, 0x0105, "Ayaneo Portable Game Player", ALC287_FIXUP_CS35L41_I2C_2),
        SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
        SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13),
        SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),
index 0f2df7c91e186a67efcdf5129290b249228f7bd4..0b9e87dc2b6cfa2299fc3281c83933c3703298a2 100644 (file)
@@ -2451,6 +2451,7 @@ config SND_SOC_WM8993
 
 config SND_SOC_WM8994
        tristate
+       depends on MFD_WM8994
 
 config SND_SOC_WM8995
        tristate
index 4236f78beec069239021ff1da28277b7e6e927a0..83c21c17fb80b4f31f113ab5f94d1e519a46e793 100644 (file)
@@ -2404,6 +2404,7 @@ static int cs42l43_codec_runtime_resume(struct device *dev)
 
 static const struct dev_pm_ops cs42l43_codec_pm_ops = {
        RUNTIME_PM_OPS(NULL, cs42l43_codec_runtime_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
 };
 
 static const struct platform_device_id cs42l43_codec_id_table[] = {
index 61729e5b50a8e49626415249835812f181a0d783..f508df01145bfbb20f01eb08ba8cd7df340b9049 100644 (file)
@@ -39,7 +39,9 @@ struct es8316_priv {
        struct snd_soc_jack *jack;
        int irq;
        unsigned int sysclk;
-       unsigned int allowed_rates[ARRAY_SIZE(supported_mclk_lrck_ratios)];
+       /* ES83xx supports halving the MCLK so it supports twice as many rates
+        */
+       unsigned int allowed_rates[ARRAY_SIZE(supported_mclk_lrck_ratios) * 2];
        struct snd_pcm_hw_constraint_list sysclk_constraints;
        bool jd_inverted;
 };
@@ -386,6 +388,12 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
                if (freq % ratio == 0)
                        es8316->allowed_rates[count++] = freq / ratio;
+
+               /* We also check if the halved MCLK produces a valid rate
+                * since the codec supports halving the MCLK.
+                */
+               if ((freq / ratio) % 2 == 0)
+                       es8316->allowed_rates[count++] = freq / ratio / 2;
        }
 
        if (count) {
index a5603b6176889a9fff635bce3492f26eacfb8671..b06eead7e0f6f043616a35ead0b14ab27bd423ab 100644 (file)
@@ -616,7 +616,7 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction)
                                        0x0F, 0x0F);
                        if (es8326->version > ES8326_VERSION_B) {
                                regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x40);
-                               regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x10);
+                               regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x30);
                        }
                }
        } else {
@@ -631,6 +631,8 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction)
                        regmap_write(es8326->regmap, ES8326_HPR_OFFSET_INI, offset_r);
                        es8326->calibrated = true;
                }
+               regmap_update_bits(es8326->regmap, ES8326_CLK_INV, 0xc0, 0x00);
+                regmap_update_bits(es8326->regmap, ES8326_CLK_MUX, 0x80, 0x00);
                if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
                        regmap_update_bits(es8326->regmap, ES8326_DAC_DSM, 0x01, 0x01);
                        usleep_range(1000, 5000);
@@ -645,7 +647,7 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction)
                } else {
                        msleep(300);
                        if (es8326->version > ES8326_VERSION_B) {
-                               regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x50);
+                               regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x70);
                                regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x00);
                        }
                        regmap_update_bits(es8326->regmap,  ES8326_ADC_MUTE,
@@ -676,6 +678,10 @@ static int es8326_set_bias_level(struct snd_soc_component *codec,
                regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x00);
                regmap_update_bits(es8326->regmap,  ES8326_CLK_CTL, 0x20, 0x20);
                regmap_update_bits(es8326->regmap, ES8326_RESET, 0x02, 0x00);
+               if (es8326->version > ES8326_VERSION_B) {
+                       regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x40);
+                       regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x30);
+               }
                break;
        case SND_SOC_BIAS_PREPARE:
                break;
@@ -683,6 +689,12 @@ static int es8326_set_bias_level(struct snd_soc_component *codec,
                regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x3b);
                regmap_update_bits(es8326->regmap, ES8326_CLK_CTL, 0x20, 0x00);
                regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, ES8326_IO_INPUT);
+               if (es8326->version > ES8326_VERSION_B) {
+                       regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x40);
+                       regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x70, 0x10);
+               }
+               regmap_update_bits(es8326->regmap, ES8326_CLK_INV, 0xc0, 0xc0);
+               regmap_update_bits(es8326->regmap, ES8326_CLK_MUX, 0x80, 0x80);
                break;
        case SND_SOC_BIAS_OFF:
                clk_disable_unprepare(es8326->mclk);
@@ -773,7 +785,10 @@ static void es8326_jack_button_handler(struct work_struct *work)
        case 0x6f:
        case 0x4b:
                /* button volume up */
-               cur_button = SND_JACK_BTN_1;
+               if ((iface == 0x6f) && (es8326->version > ES8326_VERSION_B))
+                       cur_button = SND_JACK_BTN_0;
+               else
+                       cur_button = SND_JACK_BTN_1;
                break;
        case 0x27:
                /* button volume down */
@@ -1082,7 +1097,7 @@ static void es8326_init(struct snd_soc_component *component)
        regmap_write(es8326->regmap, ES8326_ADC2_SRC, 0x66);
        es8326_disable_micbias(es8326->component);
        if (es8326->version > ES8326_VERSION_B) {
-               regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x73, 0x13);
+               regmap_update_bits(es8326->regmap, ES8326_ANA_MICBIAS, 0x73, 0x10);
                regmap_update_bits(es8326->regmap, ES8326_VMIDSEL, 0x40, 0x40);
        }
 
index fb8cd2284fe85c3fd06f5f8869ff6609a14853f8..728bf78ae71f30952852535d84ee41c6f4d32681 100644 (file)
@@ -78,7 +78,7 @@ static const struct bulk_reg_val tas2781_cali_start_reg[] = {
        X2781_CL_STT_VAL(TAS2781_PRM_INT_MASK_REG, 0xfe, false),
        X2781_CL_STT_VAL(TAS2781_PRM_CLK_CFG_REG, 0xdd, false),
        X2781_CL_STT_VAL(TAS2781_PRM_RSVD_REG, 0x20, false),
-       X2781_CL_STT_VAL(TAS2781_PRM_TEST_57_REG, 0x14, false),
+       X2781_CL_STT_VAL(TAS2781_PRM_TEST_57_REG, 0x14, true),
        X2781_CL_STT_VAL(TAS2781_PRM_TEST_62_REG, 0x45, true),
        X2781_CL_STT_VAL(TAS2781_PRM_PVDD_UVLO_REG, 0x03, false),
        X2781_CL_STT_VAL(TAS2781_PRM_CHNL_0_REG, 0xa8, false),
index 0f190abf00e756cae97cb29ecbf7adb2f02c9e5a..191f212d338c22ce02214a92e26fac6e45260c3e 100644 (file)
@@ -374,12 +374,12 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
        return 0;
 }
 
-void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
+int rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
 {
        struct rsnd_adg *adg = rsnd_priv_to_adg(priv);
        struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
        struct clk *clk;
-       int i;
+       int ret = 0, i;
 
        if (enable) {
                rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr);
@@ -389,18 +389,33 @@ void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
 
        for_each_rsnd_clkin(clk, adg, i) {
                if (enable) {
-                       clk_prepare_enable(clk);
+                       ret = clk_prepare_enable(clk);
 
                        /*
                         * We shouldn't use clk_get_rate() under
                         * atomic context. Let's keep it when
                         * rsnd_adg_clk_enable() was called
                         */
+                       if (ret < 0)
+                               break;
+
                        adg->clkin_rate[i] = clk_get_rate(clk);
                } else {
-                       clk_disable_unprepare(clk);
+                       if (adg->clkin_rate[i])
+                               clk_disable_unprepare(clk);
+
+                       adg->clkin_rate[i] = 0;
                }
        }
+
+       /*
+        * rsnd_adg_clk_enable() might return error (_disable() will not).
+        * We need to rollback in such case
+        */
+       if (ret < 0)
+               rsnd_adg_clk_disable(priv);
+
+       return ret;
 }
 
 static struct clk *rsnd_adg_create_null_clk(struct rsnd_priv *priv,
@@ -753,7 +768,10 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
        if (ret)
                return ret;
 
-       rsnd_adg_clk_enable(priv);
+       ret = rsnd_adg_clk_enable(priv);
+       if (ret)
+               return ret;
+
        rsnd_adg_clk_dbg_info(priv, NULL);
 
        return 0;
index e2234928c9e881d3ea2af3f496e70a49db0e0880..d3709fd0409e43a2266cbc306db0812435e4c4bc 100644 (file)
@@ -2086,9 +2086,7 @@ static int __maybe_unused rsnd_resume(struct device *dev)
 {
        struct rsnd_priv *priv = dev_get_drvdata(dev);
 
-       rsnd_adg_clk_enable(priv);
-
-       return 0;
+       return rsnd_adg_clk_enable(priv);
 }
 
 static const struct dev_pm_ops rsnd_pm_ops = {
index 3c164d8e3b16bf19d140b4db6da2b115468e132e..a5f54b65313c401e5491229f38ec464efe3eece4 100644 (file)
@@ -608,7 +608,7 @@ int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *cmd_mod,
                                 struct rsnd_dai_stream *io);
 #define rsnd_adg_clk_enable(priv)      rsnd_adg_clk_control(priv, 1)
 #define rsnd_adg_clk_disable(priv)     rsnd_adg_clk_control(priv, 0)
-void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable);
+int rsnd_adg_clk_control(struct rsnd_priv *priv, int enable);
 void rsnd_adg_clk_dbg_info(struct rsnd_priv *priv, struct seq_file *m);
 
 /*
index 4b1ea7b2c79617c3ffaa493ae9de0629c1943378..60b4b7b7521554e2f4e09eb8cd6d07cae3dfb5a8 100644 (file)
@@ -127,8 +127,9 @@ config SND_SOC_SAMSUNG_TM2_WM5110
 
 config SND_SOC_SAMSUNG_ARIES_WM8994
        tristate "SoC I2S Audio support for WM8994 on Aries"
-       depends on SND_SOC_SAMSUNG && MFD_WM8994 && IIO && EXTCON
+       depends on SND_SOC_SAMSUNG && I2C && IIO && EXTCON
        select SND_SOC_BT_SCO
+       select MFD_WM8994
        select SND_SOC_WM8994
        select SND_SAMSUNG_I2S
        help
@@ -140,8 +141,9 @@ config SND_SOC_SAMSUNG_ARIES_WM8994
 
 config SND_SOC_SAMSUNG_MIDAS_WM1811
        tristate "SoC I2S Audio support for Midas boards"
-       depends on SND_SOC_SAMSUNG && IIO
+       depends on SND_SOC_SAMSUNG && I2C && IIO
        select SND_SAMSUNG_I2S
+       select MFD_WM8994
        select SND_SOC_WM8994
        help
          Say Y if you want to add support for SoC audio on the Midas boards.
index 32c6ccc2a6be98bc8cdd8c0f9f584174a6972db1..1238e1c5aae150568b64cf5837f86b1499695181 100644 (file)
@@ -758,7 +758,7 @@ static void do_run_with_base_page(test_fn fn, bool swapout)
        }
 
        /* Populate a base page. */
-       memset(mem, 0, pagesize);
+       memset(mem, 1, pagesize);
 
        if (swapout) {
                madvise(mem, pagesize, MADV_PAGEOUT);
@@ -824,12 +824,12 @@ static void do_run_with_thp(test_fn fn, enum thp_run thp_run, size_t thpsize)
         * Try to populate a THP. Touch the first sub-page and test if
         * we get the last sub-page populated automatically.
         */
-       mem[0] = 0;
+       mem[0] = 1;
        if (!pagemap_is_populated(pagemap_fd, mem + thpsize - pagesize)) {
                ksft_test_result_skip("Did not get a THP populated\n");
                goto munmap;
        }
-       memset(mem, 0, thpsize);
+       memset(mem, 1, thpsize);
 
        size = thpsize;
        switch (thp_run) {
@@ -1012,7 +1012,7 @@ static void run_with_hugetlb(test_fn fn, const char *desc, size_t hugetlbsize)
        }
 
        /* Populate an huge page. */
-       memset(mem, 0, hugetlbsize);
+       memset(mem, 1, hugetlbsize);
 
        /*
         * We need a total of two hugetlb pages to handle COW/unsharing
index 06c89bdcc515410e6262ee65a084c02cd8b241bc..f67d47d32857cee296c2784da57825c9a31cd340 100644 (file)
@@ -2,6 +2,6 @@
 #define atomic_t int32_t
 #define atomic_inc(x) uatomic_inc(x)
 #define atomic_read(x) uatomic_read(x)
-#define atomic_set(x, y) do {} while (0)
+#define atomic_set(x, y) uatomic_set(x, y)
 #define U8_MAX UCHAR_MAX
 #include "../../../../include/linux/maple_tree.h"
index e01f66f989827985b038812e86ed13a15bb21115..3e1b6adc027b996b310cc74d07a1a9071e642fab 100644 (file)
@@ -6,7 +6,7 @@
 #define atomic_t int32_t
 #define atomic_inc(x) uatomic_inc(x)
 #define atomic_read(x) uatomic_read(x)
-#define atomic_set(x, y) do {} while (0)
+#define atomic_set(x, y) uatomic_set(x, y)
 #define U8_MAX UCHAR_MAX
 
 #endif /* _LINUX_ATOMIC_H */
This page took 0.221642 seconds and 4 git commands to generate.