From 62ba6d817c9175b92dcb1cf5d224a5d635a243f5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 18 Feb 2021 15:17:07 -0800 Subject: [PATCH 01/48] ACPICA: Fix race in generic_serial_bus (I2C) and GPIO op_region parameter handling commit c27f3d011b08540e68233cf56274fdc34bebb9b5 upstream. ACPICA commit c9e0116952363b0fa815143dca7e9a2eb4fefa61 The handling of the generic_serial_bus (I2C) and GPIO op_regions in acpi_ev_address_space_dispatch() passes a number of extra parameters to the address-space handler through the address-space Context pointer (instead of using more function parameters). The Context is shared between threads, so if multiple threads try to call the handler for the same address-space at the same time, then a second thread could change the parameters of a first thread while the handler is running for the first thread. An example of this race hitting is the Lenovo Yoga Tablet2 1015L, where there are both attrib_bytes accesses and attrib_byte accesses to the same address-space. The attrib_bytes access stores the number of bytes to transfer in Context->access_length. Where as for the attrib_byte access the number of bytes to transfer is always 1 and field_obj->Field.access_length is unused (so 0). Both types of accesses racing from different threads leads to the following problem: 1. Thread a. starts an attrib_bytes access, stores a non 0 value from field_obj->Field.access_length in Context->access_length 2. Thread b. starts an attrib_byte access, stores 0 in Context->access_length 3. Thread a. calls i2c_acpi_space_handler() (under Linux). Which sees that the access-type is ACPI_GSB_ACCESS_ATTRIB_MULTIBYTE and calls acpi_gsb_i2c_read_bytes(..., Context->access_length) 4. At this point Context->access_length is 0 (set by thread b.) rather then the field_obj->Field.access_length value from thread a. This 0 length reads leads to the following errors being logged: i2c i2c-0: adapter quirk: no zero length (addr 0x0078, size 0, read) i2c i2c-0: i2c read 0 bytes from client@0x78 starting at reg 0x0 failed, error: -95 Note this is just an example of the problems which this race can cause. There are likely many more (sporadic) problems caused by this race. This commit adds a new context_mutex to struct acpi_object_addr_handler and makes acpi_ev_address_space_dispatch() take that mutex when using the shared Context to pass extra parameters to an address-space handler, fixing this race. Note the new mutex must be taken *after* exiting the interpreter, therefor the existing acpi_ex_exit_interpreter() call is moved to above the code which stores the extra parameters in the Context. Link: https://github.com/acpica/acpica/commit/c9e01169 Signed-off-by: Hans de Goede Signed-off-by: Bob Moore Signed-off-by: Erik Kaneda Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpica/acobject.h | 1 + drivers/acpi/acpica/evhandler.c | 7 +++ drivers/acpi/acpica/evregion.c | 100 +++++++++++++++++++++----------- drivers/acpi/acpica/evxfregn.c | 2 + 4 files changed, 75 insertions(+), 35 deletions(-) diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index 9f0219a8cb98..dd7efafcb103 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -284,6 +284,7 @@ struct acpi_object_addr_handler { acpi_adr_space_handler handler; struct acpi_namespace_node *node; /* Parent device */ void *context; + acpi_mutex context_mutex; acpi_adr_space_setup setup; union acpi_operand_object *region_list; /* Regions using this handler */ union acpi_operand_object *next; diff --git a/drivers/acpi/acpica/evhandler.c b/drivers/acpi/acpica/evhandler.c index 5884eba047f7..3438dc187efb 100644 --- a/drivers/acpi/acpica/evhandler.c +++ b/drivers/acpi/acpica/evhandler.c @@ -489,6 +489,13 @@ acpi_ev_install_space_handler(struct acpi_namespace_node *node, /* Init handler obj */ + status = + acpi_os_create_mutex(&handler_obj->address_space.context_mutex); + if (ACPI_FAILURE(status)) { + acpi_ut_remove_reference(handler_obj); + goto unlock_and_exit; + } + handler_obj->address_space.space_id = (u8)space_id; handler_obj->address_space.handler_flags = flags; handler_obj->address_space.region_list = NULL; diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index 738d4b231f34..980efc9bd5ee 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -111,6 +111,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, union acpi_operand_object *region_obj2; void *region_context = NULL; struct acpi_connection_info *context; + acpi_mutex context_mutex; + u8 context_locked; acpi_physical_address address; ACPI_FUNCTION_TRACE(ev_address_space_dispatch); @@ -135,6 +137,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, } context = handler_desc->address_space.context; + context_mutex = handler_desc->address_space.context_mutex; + context_locked = FALSE; /* * It may be the case that the region has never been initialized. @@ -203,41 +207,6 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, handler = handler_desc->address_space.handler; address = (region_obj->region.address + region_offset); - /* - * Special handling for generic_serial_bus and general_purpose_io: - * There are three extra parameters that must be passed to the - * handler via the context: - * 1) Connection buffer, a resource template from Connection() op - * 2) Length of the above buffer - * 3) Actual access length from the access_as() op - * - * In addition, for general_purpose_io, the Address and bit_width fields - * are defined as follows: - * 1) Address is the pin number index of the field (bit offset from - * the previous Connection) - * 2) bit_width is the actual bit length of the field (number of pins) - */ - if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) && - context && field_obj) { - - /* Get the Connection (resource_template) buffer */ - - context->connection = field_obj->field.resource_buffer; - context->length = field_obj->field.resource_length; - context->access_length = field_obj->field.access_length; - } - if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && - context && field_obj) { - - /* Get the Connection (resource_template) buffer */ - - context->connection = field_obj->field.resource_buffer; - context->length = field_obj->field.resource_length; - context->access_length = field_obj->field.access_length; - address = field_obj->field.pin_number_index; - bit_width = field_obj->field.bit_length; - } - ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", ®ion_obj->region.handler->address_space, handler, @@ -255,11 +224,71 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, acpi_ex_exit_interpreter(); } + /* + * Special handling for generic_serial_bus and general_purpose_io: + * There are three extra parameters that must be passed to the + * handler via the context: + * 1) Connection buffer, a resource template from Connection() op + * 2) Length of the above buffer + * 3) Actual access length from the access_as() op + * + * Since we pass these extra parameters via the context, which is + * shared between threads, we must lock the context to avoid these + * parameters being changed from another thread before the handler + * has completed running. + * + * In addition, for general_purpose_io, the Address and bit_width fields + * are defined as follows: + * 1) Address is the pin number index of the field (bit offset from + * the previous Connection) + * 2) bit_width is the actual bit length of the field (number of pins) + */ + if ((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) && + context && field_obj) { + + status = + acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE(status)) { + goto re_enter_interpreter; + } + + context_locked = TRUE; + + /* Get the Connection (resource_template) buffer */ + + context->connection = field_obj->field.resource_buffer; + context->length = field_obj->field.resource_length; + context->access_length = field_obj->field.access_length; + } + if ((region_obj->region.space_id == ACPI_ADR_SPACE_GPIO) && + context && field_obj) { + + status = + acpi_os_acquire_mutex(context_mutex, ACPI_WAIT_FOREVER); + if (ACPI_FAILURE(status)) { + goto re_enter_interpreter; + } + + context_locked = TRUE; + + /* Get the Connection (resource_template) buffer */ + + context->connection = field_obj->field.resource_buffer; + context->length = field_obj->field.resource_length; + context->access_length = field_obj->field.access_length; + address = field_obj->field.pin_number_index; + bit_width = field_obj->field.bit_length; + } + /* Call the handler */ status = handler(function, address, bit_width, value, context, region_obj2->extra.region_context); + if (context_locked) { + acpi_os_release_mutex(context_mutex); + } + if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]", acpi_ut_get_region_name(region_obj->region. @@ -276,6 +305,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, } } +re_enter_interpreter: if (!(handler_desc->address_space.handler_flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c index da97fd0c6b51..3bb06f17a18b 100644 --- a/drivers/acpi/acpica/evxfregn.c +++ b/drivers/acpi/acpica/evxfregn.c @@ -201,6 +201,8 @@ acpi_remove_address_space_handler(acpi_handle device, /* Now we can delete the handler object */ + acpi_os_release_mutex(handler_obj->address_space. + context_mutex); acpi_ut_remove_reference(handler_obj); goto unlock_and_exit; } From 6d7fdad08fbd1d85a79012040f15852763c803c1 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Tue, 9 Mar 2021 16:16:18 -0600 Subject: [PATCH 02/48] ASoC: SOF: Intel: broadwell: fix mutual exclusion with catpt driver In v5.10, the "haswell" driver was replaced by the "catpt" driver, but the mutual exclusion with the SOF driver was not updated. This leads to errors with card names and UCM profiles not being loaded by PulseAudio. This fix should only be applied on v5.10-stable, the mutual exclusion was removed in 5.11. Reported-by: David Ward Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=211985 Fixes: 6cbfa11d2694 ("ASoC: Intel: Select catpt and deprecate haswell") Signed-off-by: Pierre-Louis Bossart Reviewed-by: Cezary Rojewski Acked-by: Mark Brown Cc: Cc: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- sound/soc/sof/intel/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index de7ff2d097ab..6708a2c5a838 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -84,7 +84,7 @@ config SND_SOC_SOF_BAYTRAIL config SND_SOC_SOF_BROADWELL_SUPPORT bool "SOF support for Broadwell" - depends on SND_SOC_INTEL_HASWELL=n + depends on SND_SOC_INTEL_CATPT=n help This adds support for Sound Open Firmware for Intel(R) platforms using the Broadwell processors. From ea222427ae9ced2ad6c39d0bbbd8f8c66b2a5045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20B=C3=B6sz=C3=B6rm=C3=A9nyi?= Date: Sun, 21 Feb 2021 06:12:16 +0100 Subject: [PATCH 03/48] nvme-pci: mark Kingston SKC2000 as not supporting the deepest power state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit dc22c1c058b5c4fe967a20589e36f029ee42a706 upstream My 2TB SKC2000 showed the exact same symptoms that were provided in 538e4a8c57 ("nvme-pci: avoid the deepest sleep state on Kingston A2000 SSDs"), i.e. a complete NVME lockup that needed cold boot to get it back. According to some sources, the A2000 is simply a rebadged SKC2000 with a slightly optimized firmware. Adding the SKC2000 PCI ID to the quirk list with the same workaround as the A2000 made my laptop survive a 5 hours long Yocto bootstrap buildfest which reliably triggered the SSD lockup previously. Signed-off-by: Zoltán Böszörményi Signed-off-by: Christoph Hellwig [sudip: adjust context] Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- drivers/nvme/host/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 4a33287371bd..25ffa61b72cc 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3264,6 +3264,8 @@ static const struct pci_device_id nvme_id_table[] = { .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, { PCI_DEVICE(0x15b7, 0x2001), /* Sandisk Skyhawk */ .driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, }, + { PCI_DEVICE(0x2646, 0x2262), /* KINGSTON SKC2000 NVMe SSD */ + .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(0x2646, 0x2263), /* KINGSTON A2000 NVMe SSD */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS, }, { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001), From a6425142f522d7e8ac5244ff94cf6cd844ddc818 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 2 Mar 2021 21:07:07 +0100 Subject: [PATCH 04/48] parisc: Enable -mlong-calls gcc option with CONFIG_COMPILE_TEST commit 778e45d7720d663811352943dd515b41f6849637 upstream The kernel test robot reported multiple linkage problems like this: hppa64-linux-ld: init/main.o(.init.text+0x56c): cannot reach printk init/main.o: in function `unknown_bootoption': (.init.text+0x56c): relocation truncated to fit: R_PARISC_PCREL22F against symbol `printk' defined in .text.unlikely section in kernel/printk/printk.o There are two ways to solve it: a) Enable the -mlong-call compiler option (CONFIG_MLONGCALLS), b) Add long branch stub support in 64-bit linker. While b) is the long-term solution, this patch works around the issue by automatically enabling the CONFIG_MLONGCALLS option when CONFIG_COMPILE_TEST is set, which indicates that a non-production kernel (e.g. 0-day kernel) is built. Signed-off-by: Helge Deller Reported-by: kernel test robot Fixes: 00e35f2b0e8a ("parisc: Enable -mlong-calls gcc option by default when !CONFIG_MODULES") Cc: stable@vger.kernel.org # v5.6+ Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- arch/parisc/Kconfig | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 04dc17d52ac2..14f3252f2da0 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -201,9 +201,12 @@ config PREFETCH def_bool y depends on PA8X00 || PA7200 +config PARISC_HUGE_KERNEL + def_bool y if !MODULES || UBSAN || FTRACE || COMPILE_TEST + config MLONGCALLS - def_bool y if !MODULES || UBSAN || FTRACE - bool "Enable the -mlong-calls compiler option for big kernels" if MODULES && !UBSAN && !FTRACE + def_bool y if PARISC_HUGE_KERNEL + bool "Enable the -mlong-calls compiler option for big kernels" if !PARISC_HUGE_KERNEL depends on PA8X00 help If you configure the kernel to include many drivers built-in instead From 7215d7742daf4c036567f03c647738e269d6a943 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 8 Feb 2021 17:57:20 -0700 Subject: [PATCH 05/48] arm64: Make CPU_BIG_ENDIAN depend on ld.bfd or ld.lld 13.0.0+ commit e9c6deee00e9197e75cd6aa0d265d3d45bd7cc28 upstream Similar to commit 28187dc8ebd9 ("ARM: 9025/1: Kconfig: CPU_BIG_ENDIAN depends on !LD_IS_LLD"), ld.lld prior to 13.0.0 does not properly support aarch64 big endian, leading to the following build error when CONFIG_CPU_BIG_ENDIAN is selected: ld.lld: error: unknown emulation: aarch64linuxb This has been resolved in LLVM 13. To avoid errors like this, only allow CONFIG_CPU_BIG_ENDIAN to be selected if using ld.bfd or ld.lld 13.0.0 and newer. While we are here, the indentation of this symbol used spaces since its introduction in commit a872013d6d03 ("arm64: kconfig: allow CPU_BIG_ENDIAN to be selected"). Change it to tabs to be consistent with kernel coding style. Link: https://github.com/ClangBuiltLinux/linux/issues/380 Link: https://github.com/ClangBuiltLinux/linux/issues/1288 Link: https://github.com/llvm/llvm-project/commit/7605a9a009b5fa3bdac07e3131c8d82f6d08feb7 Link: https://github.com/llvm/llvm-project/commit/eea34aae2e74e9b6fbdd5b95f479bc7f397bf387 Reported-by: Arnd Bergmann Signed-off-by: Nathan Chancellor Reviewed-by: Nick Desaulniers Link: https://lore.kernel.org/r/20210209005719.803608-1-nathan@kernel.org Signed-off-by: Will Deacon Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- arch/arm64/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index afe4bc55d4eb..c1be64228327 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -950,8 +950,9 @@ choice that is selected here. config CPU_BIG_ENDIAN - bool "Build big-endian kernel" - help + bool "Build big-endian kernel" + depends on !LD_IS_LLD || LLD_VERSION >= 130000 + help Say Y if you plan on running a kernel with a big-endian userspace. config CPU_LITTLE_ENDIAN From cf9317ceb5a119458bffbaf47c4d0e1a49d73123 Mon Sep 17 00:00:00 2001 From: Nikolay Borisov Date: Mon, 22 Feb 2021 18:40:43 +0200 Subject: [PATCH 06/48] btrfs: export and rename qgroup_reserve_meta commit 80e9baed722c853056e0c5374f51524593cb1031 upstream Signed-off-by: Nikolay Borisov Reviewed-by: David Sterba Signed-off-by: David Sterba Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/qgroup.c | 8 ++++---- fs/btrfs/qgroup.h | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index d504a9a20751..cd9b1a16489b 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -3875,8 +3875,8 @@ static int sub_root_meta_rsv(struct btrfs_root *root, int num_bytes, return num_bytes; } -static int qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, - enum btrfs_qgroup_rsv_type type, bool enforce) +int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, + enum btrfs_qgroup_rsv_type type, bool enforce) { struct btrfs_fs_info *fs_info = root->fs_info; int ret; @@ -3907,14 +3907,14 @@ int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, { int ret; - ret = qgroup_reserve_meta(root, num_bytes, type, enforce); + ret = btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce); if (ret <= 0 && ret != -EDQUOT) return ret; ret = try_flush_qgroup(root); if (ret < 0) return ret; - return qgroup_reserve_meta(root, num_bytes, type, enforce); + return btrfs_qgroup_reserve_meta(root, num_bytes, type, enforce); } void btrfs_qgroup_free_meta_all_pertrans(struct btrfs_root *root) diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h index 50dea9a2d8fb..7283e4f549af 100644 --- a/fs/btrfs/qgroup.h +++ b/fs/btrfs/qgroup.h @@ -361,6 +361,8 @@ int btrfs_qgroup_release_data(struct btrfs_inode *inode, u64 start, u64 len); int btrfs_qgroup_free_data(struct btrfs_inode *inode, struct extent_changeset *reserved, u64 start, u64 len); +int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, + enum btrfs_qgroup_rsv_type type, bool enforce); int __btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes, enum btrfs_qgroup_rsv_type type, bool enforce); /* Reserve metadata space for pertrans and prealloc type */ From bf6dd437c3bad5014cbd2b16dc4240b8069267b3 Mon Sep 17 00:00:00 2001 From: Nikolay Borisov Date: Mon, 22 Feb 2021 18:40:44 +0200 Subject: [PATCH 07/48] btrfs: don't flush from btrfs_delayed_inode_reserve_metadata commit 4d14c5cde5c268a2bc26addecf09489cb953ef64 upstream Calling btrfs_qgroup_reserve_meta_prealloc from btrfs_delayed_inode_reserve_metadata can result in flushing delalloc while holding a transaction and delayed node locks. This is deadlock prone. In the past multiple commits: * ae5e070eaca9 ("btrfs: qgroup: don't try to wait flushing if we're already holding a transaction") * 6f23277a49e6 ("btrfs: qgroup: don't commit transaction when we already hold the handle") Tried to solve various aspects of this but this was always a whack-a-mole game. Unfortunately those 2 fixes don't solve a deadlock scenario involving btrfs_delayed_node::mutex. Namely, one thread can call btrfs_dirty_inode as a result of reading a file and modifying its atime: PID: 6963 TASK: ffff8c7f3f94c000 CPU: 2 COMMAND: "test" #0 __schedule at ffffffffa529e07d #1 schedule at ffffffffa529e4ff #2 schedule_timeout at ffffffffa52a1bdd #3 wait_for_completion at ffffffffa529eeea <-- sleeps with delayed node mutex held #4 start_delalloc_inodes at ffffffffc0380db5 #5 btrfs_start_delalloc_snapshot at ffffffffc0393836 #6 try_flush_qgroup at ffffffffc03f04b2 #7 __btrfs_qgroup_reserve_meta at ffffffffc03f5bb6 <-- tries to reserve space and starts delalloc inodes. #8 btrfs_delayed_update_inode at ffffffffc03e31aa <-- acquires delayed node mutex #9 btrfs_update_inode at ffffffffc0385ba8 #10 btrfs_dirty_inode at ffffffffc038627b <-- TRANSACTIION OPENED #11 touch_atime at ffffffffa4cf0000 #12 generic_file_read_iter at ffffffffa4c1f123 #13 new_sync_read at ffffffffa4ccdc8a #14 vfs_read at ffffffffa4cd0849 #15 ksys_read at ffffffffa4cd0bd1 #16 do_syscall_64 at ffffffffa4a052eb #17 entry_SYSCALL_64_after_hwframe at ffffffffa540008c This will cause an asynchronous work to flush the delalloc inodes to happen which can try to acquire the same delayed_node mutex: PID: 455 TASK: ffff8c8085fa4000 CPU: 5 COMMAND: "kworker/u16:30" #0 __schedule at ffffffffa529e07d #1 schedule at ffffffffa529e4ff #2 schedule_preempt_disabled at ffffffffa529e80a #3 __mutex_lock at ffffffffa529fdcb <-- goes to sleep, never wakes up. #4 btrfs_delayed_update_inode at ffffffffc03e3143 <-- tries to acquire the mutex #5 btrfs_update_inode at ffffffffc0385ba8 <-- this is the same inode that pid 6963 is holding #6 cow_file_range_inline.constprop.78 at ffffffffc0386be7 #7 cow_file_range at ffffffffc03879c1 #8 btrfs_run_delalloc_range at ffffffffc038894c #9 writepage_delalloc at ffffffffc03a3c8f #10 __extent_writepage at ffffffffc03a4c01 #11 extent_write_cache_pages at ffffffffc03a500b #12 extent_writepages at ffffffffc03a6de2 #13 do_writepages at ffffffffa4c277eb #14 __filemap_fdatawrite_range at ffffffffa4c1e5bb #15 btrfs_run_delalloc_work at ffffffffc0380987 <-- starts running delayed nodes #16 normal_work_helper at ffffffffc03b706c #17 process_one_work at ffffffffa4aba4e4 #18 worker_thread at ffffffffa4aba6fd #19 kthread at ffffffffa4ac0a3d #20 ret_from_fork at ffffffffa54001ff To fully address those cases the complete fix is to never issue any flushing while holding the transaction or the delayed node lock. This patch achieves it by calling qgroup_reserve_meta directly which will either succeed without flushing or will fail and return -EDQUOT. In the latter case that return value is going to be propagated to btrfs_dirty_inode which will fallback to start a new transaction. That's fine as the majority of time we expect the inode will have BTRFS_DELAYED_NODE_INODE_DIRTY flag set which will result in directly copying the in-memory state. Fixes: c53e9653605d ("btrfs: qgroup: try to flush qgroup space when we get -EDQUOT") CC: stable@vger.kernel.org # 5.10+ Reviewed-by: Qu Wenruo Signed-off-by: Nikolay Borisov Signed-off-by: David Sterba [sudip: adjust context] Signed-off-by: Sudip Mukherjee Signed-off-by: Greg Kroah-Hartman --- fs/btrfs/delayed-inode.c | 3 ++- fs/btrfs/inode.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 36e0de34ec68..4e2cce5ca7f6 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -627,7 +627,8 @@ static int btrfs_delayed_inode_reserve_metadata( */ if (!src_rsv || (!trans->bytes_reserved && src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) { - ret = btrfs_qgroup_reserve_meta_prealloc(root, num_bytes, true); + ret = btrfs_qgroup_reserve_meta(root, num_bytes, + BTRFS_QGROUP_RSV_META_PREALLOC, true); if (ret < 0) return ret; ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes, diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9b3df72ceffb..cbeb0cdaca7a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5798,7 +5798,7 @@ static int btrfs_dirty_inode(struct inode *inode) return PTR_ERR(trans); ret = btrfs_update_inode(trans, root, inode); - if (ret && ret == -ENOSPC) { + if (ret && (ret == -ENOSPC || ret == -EDQUOT)) { /* whoops, lets try again with the full transaction */ btrfs_end_transaction(trans); trans = btrfs_start_transaction(root, 1); From 93d20ce4c47f9678011c4b293aa4242a8e184508 Mon Sep 17 00:00:00 2001 From: Andrey Ryabinin Date: Wed, 17 Feb 2021 17:30:04 +0300 Subject: [PATCH 08/48] iommu/amd: Fix sleeping in atomic in increase_address_space() commit 140456f994195b568ecd7fc2287a34eadffef3ca upstream. increase_address_space() calls get_zeroed_page(gfp) under spin_lock with disabled interrupts. gfp flags passed to increase_address_space() may allow sleeping, so it comes to this: BUG: sleeping function called from invalid context at mm/page_alloc.c:4342 in_atomic(): 1, irqs_disabled(): 1, pid: 21555, name: epdcbbf1qnhbsd8 Call Trace: dump_stack+0x66/0x8b ___might_sleep+0xec/0x110 __alloc_pages_nodemask+0x104/0x300 get_zeroed_page+0x15/0x40 iommu_map_page+0xdd/0x3e0 amd_iommu_map+0x50/0x70 iommu_map+0x106/0x220 vfio_iommu_type1_ioctl+0x76e/0x950 [vfio_iommu_type1] do_vfs_ioctl+0xa3/0x6f0 ksys_ioctl+0x66/0x70 __x64_sys_ioctl+0x16/0x20 do_syscall_64+0x4e/0x100 entry_SYSCALL_64_after_hwframe+0x44/0xa9 Fix this by moving get_zeroed_page() out of spin_lock/unlock section. Fixes: 754265bcab ("iommu/amd: Fix race in increase_address_space()") Signed-off-by: Andrey Ryabinin Acked-by: Will Deacon Cc: Link: https://lore.kernel.org/r/20210217143004.19165-1-arbn@yandex-team.com Signed-off-by: Joerg Roedel Signed-off-by: Andrey Ryabinin Signed-off-by: Greg Kroah-Hartman --- drivers/iommu/amd/iommu.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index b9cf59443843..5f1195791cb1 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -1503,6 +1503,10 @@ static bool increase_address_space(struct protection_domain *domain, bool ret = true; u64 *pte; + pte = (void *)get_zeroed_page(gfp); + if (!pte) + return false; + spin_lock_irqsave(&domain->lock, flags); amd_iommu_domain_get_pgtable(domain, &pgtable); @@ -1514,10 +1518,6 @@ static bool increase_address_space(struct protection_domain *domain, if (WARN_ON_ONCE(pgtable.mode == PAGE_MODE_6_LEVEL)) goto out; - pte = (void *)get_zeroed_page(gfp); - if (!pte) - goto out; - *pte = PM_LEVEL_PDE(pgtable.mode, iommu_virt_to_phys(pgtable.root)); pgtable.root = pte; @@ -1531,10 +1531,12 @@ static bool increase_address_space(struct protection_domain *domain, */ amd_iommu_domain_set_pgtable(domain, pte, pgtable.mode); + pte = NULL; ret = true; out: spin_unlock_irqrestore(&domain->lock, flags); + free_page((unsigned long)pte); return ret; } From f5526b77335da764e2789c7ee7a08c36cfd7422b Mon Sep 17 00:00:00 2001 From: Abhishek Pandit-Subedi Date: Wed, 30 Sep 2020 13:01:38 -0700 Subject: [PATCH 09/48] Bluetooth: btqca: Add valid le states quirk [ Upstream commit 547801380ec7e6104ea679f599d03c342b4b39a0 ] WCN3991 supports connectable advertisements so we need to add the valid le states quirk so the 'central-peripheral' role is exposed in userspace. Signed-off-by: Abhishek Pandit-Subedi Signed-off-by: Marcel Holtmann Signed-off-by: Sasha Levin --- drivers/bluetooth/hci_qca.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 5c26c7d94173..ad47ff0d55c2 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -78,6 +78,7 @@ enum qca_flags { enum qca_capabilities { QCA_CAP_WIDEBAND_SPEECH = BIT(0), + QCA_CAP_VALID_LE_STATES = BIT(1), }; /* HCI_IBS transmit side sleep protocol states */ @@ -1782,7 +1783,7 @@ static const struct qca_device_data qca_soc_data_wcn3991 = { { "vddch0", 450000 }, }, .num_vregs = 4, - .capabilities = QCA_CAP_WIDEBAND_SPEECH, + .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, }; static const struct qca_device_data qca_soc_data_wcn3998 = { @@ -2019,11 +2020,17 @@ static int qca_serdev_probe(struct serdev_device *serdev) hdev->shutdown = qca_power_off; } - /* Wideband speech support must be set per driver since it can't be - * queried via hci. - */ - if (data && (data->capabilities & QCA_CAP_WIDEBAND_SPEECH)) - set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); + if (data) { + /* Wideband speech support must be set per driver since it can't + * be queried via hci. Same with the valid le states quirk. + */ + if (data->capabilities & QCA_CAP_WIDEBAND_SPEECH) + set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, + &hdev->quirks); + + if (data->capabilities & QCA_CAP_VALID_LE_STATES) + set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); + } return 0; } From 36b3ba412d7c64121aca4af9fa7804efa567255f Mon Sep 17 00:00:00 2001 From: Tsuchiya Yuto Date: Wed, 28 Oct 2020 23:23:46 +0900 Subject: [PATCH 10/48] mwifiex: pcie: skip cancel_work_sync() on reset failure path [ Upstream commit 4add4d988f95f47493500a7a19c623827061589b ] If a reset is performed, but even the reset fails for some reasons (e.g., on Surface devices, the fw reset requires another quirks), cancel_work_sync() hangs in mwifiex_cleanup_pcie(). # firmware went into a bad state [...] [ 1608.281690] mwifiex_pcie 0000:03:00.0: info: shutdown mwifiex... [ 1608.282724] mwifiex_pcie 0000:03:00.0: rx_pending=0, tx_pending=1, cmd_pending=0 [ 1608.292400] mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed [ 1608.292405] mwifiex_pcie 0000:03:00.0: PREP_CMD: card is removed # reset performed after firmware went into a bad state [ 1609.394320] mwifiex_pcie 0000:03:00.0: WLAN FW already running! Skip FW dnld [ 1609.394335] mwifiex_pcie 0000:03:00.0: WLAN FW is active # but even the reset failed [ 1619.499049] mwifiex_pcie 0000:03:00.0: mwifiex_cmd_timeout_func: Timeout cmd id = 0xfa, act = 0xe000 [ 1619.499094] mwifiex_pcie 0000:03:00.0: num_data_h2c_failure = 0 [ 1619.499103] mwifiex_pcie 0000:03:00.0: num_cmd_h2c_failure = 0 [ 1619.499110] mwifiex_pcie 0000:03:00.0: is_cmd_timedout = 1 [ 1619.499117] mwifiex_pcie 0000:03:00.0: num_tx_timeout = 0 [ 1619.499124] mwifiex_pcie 0000:03:00.0: last_cmd_index = 0 [ 1619.499133] mwifiex_pcie 0000:03:00.0: last_cmd_id: fa 00 07 01 07 01 07 01 07 01 [ 1619.499140] mwifiex_pcie 0000:03:00.0: last_cmd_act: 00 e0 00 00 00 00 00 00 00 00 [ 1619.499147] mwifiex_pcie 0000:03:00.0: last_cmd_resp_index = 3 [ 1619.499155] mwifiex_pcie 0000:03:00.0: last_cmd_resp_id: 07 81 07 81 07 81 07 81 07 81 [ 1619.499162] mwifiex_pcie 0000:03:00.0: last_event_index = 2 [ 1619.499169] mwifiex_pcie 0000:03:00.0: last_event: 58 00 58 00 58 00 58 00 58 00 [ 1619.499177] mwifiex_pcie 0000:03:00.0: data_sent=0 cmd_sent=1 [ 1619.499185] mwifiex_pcie 0000:03:00.0: ps_mode=0 ps_state=0 [ 1619.499215] mwifiex_pcie 0000:03:00.0: info: _mwifiex_fw_dpc: unregister device # mwifiex_pcie_work hang happening [ 1823.233923] INFO: task kworker/3:1:44 blocked for more than 122 seconds. [ 1823.233932] Tainted: G WC OE 5.10.0-rc1-1-mainline #1 [ 1823.233935] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 1823.233940] task:kworker/3:1 state:D stack: 0 pid: 44 ppid: 2 flags:0x00004000 [ 1823.233960] Workqueue: events mwifiex_pcie_work [mwifiex_pcie] [ 1823.233965] Call Trace: [ 1823.233981] __schedule+0x292/0x820 [ 1823.233990] schedule+0x45/0xe0 [ 1823.233995] schedule_timeout+0x11c/0x160 [ 1823.234003] wait_for_completion+0x9e/0x100 [ 1823.234012] __flush_work.isra.0+0x156/0x210 [ 1823.234018] ? flush_workqueue_prep_pwqs+0x130/0x130 [ 1823.234026] __cancel_work_timer+0x11e/0x1a0 [ 1823.234035] mwifiex_cleanup_pcie+0x28/0xd0 [mwifiex_pcie] [ 1823.234049] mwifiex_free_adapter+0x24/0xe0 [mwifiex] [ 1823.234060] _mwifiex_fw_dpc+0x294/0x560 [mwifiex] [ 1823.234074] mwifiex_reinit_sw+0x15d/0x300 [mwifiex] [ 1823.234080] mwifiex_pcie_reset_done+0x50/0x80 [mwifiex_pcie] [ 1823.234087] pci_try_reset_function+0x5c/0x90 [ 1823.234094] process_one_work+0x1d6/0x3a0 [ 1823.234100] worker_thread+0x4d/0x3d0 [ 1823.234107] ? rescuer_thread+0x410/0x410 [ 1823.234112] kthread+0x142/0x160 [ 1823.234117] ? __kthread_bind_mask+0x60/0x60 [ 1823.234124] ret_from_fork+0x22/0x30 [...] This is a deadlock caused by calling cancel_work_sync() in mwifiex_cleanup_pcie(): - Device resets are done via mwifiex_pcie_card_reset() - which schedules card->work to call mwifiex_pcie_card_reset_work() - which calls pci_try_reset_function(). - This leads to mwifiex_pcie_reset_done() be called on the same workqueue, which in turn calls - mwifiex_reinit_sw() and that calls - _mwifiex_fw_dpc(). The problem is now that _mwifiex_fw_dpc() calls mwifiex_free_adapter() in case firmware initialization fails. That ends up calling mwifiex_cleanup_pcie(). Note that all those calls are still running on the workqueue. So when mwifiex_cleanup_pcie() now calls cancel_work_sync(), it's really waiting on itself to complete, causing a deadlock. This commit fixes the deadlock by skipping cancel_work_sync() on a reset failure path. After this commit, when reset fails, the following output is expected to be shown: kernel: mwifiex_pcie 0000:03:00.0: info: _mwifiex_fw_dpc: unregister device kernel: mwifiex: Failed to bring up adapter: -5 kernel: mwifiex_pcie 0000:03:00.0: reinit failed: -5 To reproduce this issue, for example, try putting the root port of wifi into D3 (replace "00:1d.3" with your setup). # put into D3 (root port) sudo setpci -v -s 00:1d.3 CAP_PM+4.b=0b Cc: Maximilian Luz Signed-off-by: Tsuchiya Yuto Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20201028142346.18355-1-kitakar@gmail.com Signed-off-by: Sasha Levin --- drivers/net/wireless/marvell/mwifiex/pcie.c | 18 +++++++++++++++++- drivers/net/wireless/marvell/mwifiex/pcie.h | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 6a10ff0377a2..33cf952cc01d 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -526,6 +526,8 @@ static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev) clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); + + card->pci_reset_ongoing = true; } /* @@ -554,6 +556,8 @@ static void mwifiex_pcie_reset_done(struct pci_dev *pdev) dev_err(&pdev->dev, "reinit failed: %d\n", ret); else mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); + + card->pci_reset_ongoing = false; } static const struct pci_error_handlers mwifiex_pcie_err_handler = { @@ -3142,7 +3146,19 @@ static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter) int ret; u32 fw_status; - cancel_work_sync(&card->work); + /* Perform the cancel_work_sync() only when we're not resetting + * the card. It's because that function never returns if we're + * in reset path. If we're here when resetting the card, it means + * that we failed to reset the card (reset failure path). + */ + if (!card->pci_reset_ongoing) { + mwifiex_dbg(adapter, MSG, "performing cancel_work_sync()...\n"); + cancel_work_sync(&card->work); + mwifiex_dbg(adapter, MSG, "cancel_work_sync() done\n"); + } else { + mwifiex_dbg(adapter, MSG, + "skipped cancel_work_sync() because we're in card reset failure path\n"); + } ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status); if (fw_status == FIRMWARE_READY_PCIE) { diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h index 843d57eda820..5ed613d65709 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.h +++ b/drivers/net/wireless/marvell/mwifiex/pcie.h @@ -242,6 +242,8 @@ struct pcie_service_card { struct mwifiex_msix_context share_irq_ctx; struct work_struct work; unsigned long work_flags; + + bool pci_reset_ongoing; }; static inline int From f7f227eb32d1ab0acb1d8358996a22dccddf48aa Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Wed, 11 Nov 2020 15:43:15 -0600 Subject: [PATCH 11/48] ASoC: Intel: sof_sdw: add quirk for new TigerLake-SDCA device [ Upstream commit 488cdbd8931fe4bc7f374a8b429e81d0e4b7ac76 ] Add quirks for jack detection, rt715 DAI and number of speakers. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Link: https://lore.kernel.org/r/20201111214318.150529-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/sof_sdw.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 0f1d845a0cca..9519e5403cbf 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -48,6 +48,16 @@ static int sof_sdw_quirk_cb(const struct dmi_system_id *id) } static const struct dmi_system_id sof_sdw_quirk_table[] = { + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") + }, + .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | + SOF_RT715_DAI_ID_FIX | + SOF_SDW_FOUR_SPK), + }, { .callback = sof_sdw_quirk_cb, .matches = { From b159a9a4d357d42d339ea9e459defb057ce9ac49 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 16 Nov 2020 12:57:13 +0200 Subject: [PATCH 12/48] bus: ti-sysc: Implement GPMC debug quirk to drop platform data [ Upstream commit cfeeea60af2f01c13b94d57a9bb1291e7bc181da ] We need to enable no-reset-on-init quirk for GPMC if the config option for CONFIG_OMAP_GPMC_DEBUG is set. Otherwise the GPMC driver code is unable to show the bootloader configured timings. Signed-off-by: Tony Lindgren Signed-off-by: Sasha Levin --- drivers/bus/ti-sysc.c | 10 ++++++++++ include/linux/platform_data/ti-sysc.h | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 92ecf1a78ec7..45f5530666d3 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -1379,6 +1379,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { SYSC_QUIRK_CLKDM_NOAUTO), SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -ENODEV, 0x500a0200, 0xffffffff, SYSC_QUIRK_CLKDM_NOAUTO), + SYSC_QUIRK("gpmc", 0, 0, 0x10, 0x14, 0x00000060, 0xffffffff, + SYSC_QUIRK_GPMC_DEBUG), SYSC_QUIRK("hdmi", 0, 0, 0x10, -ENODEV, 0x50030200, 0xffffffff, SYSC_QUIRK_OPT_CLKS_NEEDED), SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff, @@ -1814,6 +1816,14 @@ static void sysc_init_module_quirks(struct sysc *ddata) return; } +#ifdef CONFIG_OMAP_GPMC_DEBUG + if (ddata->cfg.quirks & SYSC_QUIRK_GPMC_DEBUG) { + ddata->cfg.quirks |= SYSC_QUIRK_NO_RESET_ON_INIT; + + return; + } +#endif + if (ddata->cfg.quirks & SYSC_MODULE_QUIRK_I2C) { ddata->pre_reset_quirk = sysc_pre_reset_quirk_i2c; ddata->post_reset_quirk = sysc_post_reset_quirk_i2c; diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h index 240dce553a0b..fafc1beea504 100644 --- a/include/linux/platform_data/ti-sysc.h +++ b/include/linux/platform_data/ti-sysc.h @@ -50,6 +50,7 @@ struct sysc_regbits { s8 emufree_shift; }; +#define SYSC_QUIRK_GPMC_DEBUG BIT(26) #define SYSC_MODULE_QUIRK_ENA_RESETDONE BIT(25) #define SYSC_MODULE_QUIRK_PRUSS BIT(24) #define SYSC_MODULE_QUIRK_DSS_RESET BIT(23) From be52e3ea452039fb416caac61e71aa2fc426a711 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Oct 2020 20:56:24 +0200 Subject: [PATCH 13/48] platform/x86: acer-wmi: Cleanup ACER_CAP_FOO defines [ Upstream commit 7c936d8d26afbc74deac0651d613dead2f76e81c ] Cleanup the ACER_CAP_FOO defines: -Switch to using BIT() macro. -The ACER_CAP_RFBTN flag is set, but it is never checked anywhere, drop it. -Drop the unused ACER_CAP_ANY define. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20201019185628.264473-2-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/platform/x86/acer-wmi.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 5592a929b593..75b1f6ceb76e 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -206,14 +206,12 @@ struct hotkey_function_type_aa { /* * Interface capability flags */ -#define ACER_CAP_MAILLED (1<<0) -#define ACER_CAP_WIRELESS (1<<1) -#define ACER_CAP_BLUETOOTH (1<<2) -#define ACER_CAP_BRIGHTNESS (1<<3) -#define ACER_CAP_THREEG (1<<4) -#define ACER_CAP_ACCEL (1<<5) -#define ACER_CAP_RFBTN (1<<6) -#define ACER_CAP_ANY (0xFFFFFFFF) +#define ACER_CAP_MAILLED BIT(0) +#define ACER_CAP_WIRELESS BIT(1) +#define ACER_CAP_BLUETOOTH BIT(2) +#define ACER_CAP_BRIGHTNESS BIT(3) +#define ACER_CAP_THREEG BIT(4) +#define ACER_CAP_ACCEL BIT(5) /* * Interface type flags @@ -1253,10 +1251,8 @@ static void __init type_aa_dmi_decode(const struct dmi_header *header, void *d) interface->capability |= ACER_CAP_THREEG; if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_BLUETOOTH) interface->capability |= ACER_CAP_BLUETOOTH; - if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) { - interface->capability |= ACER_CAP_RFBTN; + if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_RFBTN) commun_func_bitmap &= ~ACER_WMID3_GDS_RFBTN; - } commun_fn_key_number = type_aa->commun_fn_key_number; } From 74848026bcb1b86071f3adddd6988899e28fa74c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Oct 2020 20:56:25 +0200 Subject: [PATCH 14/48] platform/x86: acer-wmi: Cleanup accelerometer device handling [ Upstream commit 9feb0763e4985ccfae632de3bb2f029cc8389842 ] Cleanup accelerometer device handling: -Drop acer_wmi_accel_destroy instead directly call input_unregister_device. -The information tracked by the CAP_ACCEL flag mirrors acer_wmi_accel_dev being NULL. Drop the CAP flag, this is a preparation change for allowing users to override the capability flags. Dropping the flag stops users from causing a NULL pointer dereference by forcing the capability. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20201019185628.264473-3-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/platform/x86/acer-wmi.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 75b1f6ceb76e..184ec08d02a4 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -211,7 +211,6 @@ struct hotkey_function_type_aa { #define ACER_CAP_BLUETOOTH BIT(2) #define ACER_CAP_BRIGHTNESS BIT(3) #define ACER_CAP_THREEG BIT(4) -#define ACER_CAP_ACCEL BIT(5) /* * Interface type flags @@ -1516,7 +1515,7 @@ static int acer_gsensor_event(void) struct acpi_buffer output; union acpi_object out_obj[5]; - if (!has_cap(ACER_CAP_ACCEL)) + if (!acer_wmi_accel_dev) return -1; output.length = sizeof(out_obj); @@ -1890,8 +1889,6 @@ static int __init acer_wmi_accel_setup(void) gsensor_handle = acpi_device_handle(adev); acpi_dev_put(adev); - interface->capability |= ACER_CAP_ACCEL; - acer_wmi_accel_dev = input_allocate_device(); if (!acer_wmi_accel_dev) return -ENOMEM; @@ -1917,11 +1914,6 @@ static int __init acer_wmi_accel_setup(void) return err; } -static void acer_wmi_accel_destroy(void) -{ - input_unregister_device(acer_wmi_accel_dev); -} - static int __init acer_wmi_input_setup(void) { acpi_status status; @@ -2076,7 +2068,7 @@ static int acer_resume(struct device *dev) if (has_cap(ACER_CAP_BRIGHTNESS)) set_u32(data->brightness, ACER_CAP_BRIGHTNESS); - if (has_cap(ACER_CAP_ACCEL)) + if (acer_wmi_accel_dev) acer_gsensor_init(); return 0; @@ -2266,8 +2258,8 @@ static int __init acer_wmi_init(void) error_platform_register: if (wmi_has_guid(ACERWMID_EVENT_GUID)) acer_wmi_input_destroy(); - if (has_cap(ACER_CAP_ACCEL)) - acer_wmi_accel_destroy(); + if (acer_wmi_accel_dev) + input_unregister_device(acer_wmi_accel_dev); return err; } @@ -2277,8 +2269,8 @@ static void __exit acer_wmi_exit(void) if (wmi_has_guid(ACERWMID_EVENT_GUID)) acer_wmi_input_destroy(); - if (has_cap(ACER_CAP_ACCEL)) - acer_wmi_accel_destroy(); + if (acer_wmi_accel_dev) + input_unregister_device(acer_wmi_accel_dev); remove_debugfs(); platform_device_unregister(acer_platform_device); From 039cd40179e94a6eec5c76f5a143a39f44cdcfda Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Oct 2020 20:56:26 +0200 Subject: [PATCH 15/48] platform/x86: acer-wmi: Add new force_caps module parameter [ Upstream commit 39aa009bb66f9d5fbd1e58ca4aa03d6e6f2c9915 ] Add a new force_caps module parameter to allow overriding the drivers builtin capability detection mechanism. This can be used to for example: -Disable rfkill functionality on devices where there is an AA OEM DMI record advertising non functional rfkill switches -Force loading of the driver on devices with a missing AA OEM DMI record Note that force_caps is -1 when unset, this allows forcing the capability field to 0, which results in acer-wmi only providing WMI hotkey handling while disabling all other (led, rfkill, backlight) functionality. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20201019185628.264473-4-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/platform/x86/acer-wmi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 184ec08d02a4..74021163ca23 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -233,6 +233,7 @@ static int mailled = -1; static int brightness = -1; static int threeg = -1; static int force_series; +static int force_caps = -1; static bool ec_raw_mode; static bool has_type_aa; static u16 commun_func_bitmap; @@ -242,11 +243,13 @@ module_param(mailled, int, 0444); module_param(brightness, int, 0444); module_param(threeg, int, 0444); module_param(force_series, int, 0444); +module_param(force_caps, int, 0444); module_param(ec_raw_mode, bool, 0444); MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); MODULE_PARM_DESC(force_series, "Force a different laptop series"); +MODULE_PARM_DESC(force_caps, "Force the capability bitmask to this value"); MODULE_PARM_DESC(ec_raw_mode, "Enable EC raw mode"); struct acer_data { @@ -2169,7 +2172,7 @@ static int __init acer_wmi_init(void) } /* WMID always provides brightness methods */ interface->capability |= ACER_CAP_BRIGHTNESS; - } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa) { + } else if (!wmi_has_guid(WMID_GUID2) && interface && !has_type_aa && force_caps == -1) { pr_err("No WMID device detection method found\n"); return -ENODEV; } @@ -2199,6 +2202,9 @@ static int __init acer_wmi_init(void) if (acpi_video_get_backlight_type() != acpi_backlight_vendor) interface->capability &= ~ACER_CAP_BRIGHTNESS; + if (force_caps != -1) + interface->capability = force_caps; + if (wmi_has_guid(WMID_GUID3)) { if (ACPI_FAILURE(acer_wmi_enable_rf_button())) pr_warn("Cannot enable RF Button Driver\n"); From 2c9132e543b7cc5aa164f7fcb5106ae429a816ef Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Oct 2020 20:56:27 +0200 Subject: [PATCH 16/48] platform/x86: acer-wmi: Add ACER_CAP_SET_FUNCTION_MODE capability flag [ Upstream commit 82cb8a5c395ea5be20e0fe31a8fe84380a502ca5 ] Not all devices supporting WMID_GUID3 support the wmid3_set_function_mode() call, leading to errors like these: [ 60.138358] acer_wmi: Enabling RF Button failed: 0x1 - 0xff [ 60.140036] acer_wmi: Enabling Launch Manager failed: 0x1 - 0xff Add an ACER_CAP_SET_FUNCTION_MODE capability flag, so that these calls can be disabled through the new force_caps mechanism. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20201019185628.264473-5-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/platform/x86/acer-wmi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 74021163ca23..8662468491a3 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -211,6 +211,7 @@ struct hotkey_function_type_aa { #define ACER_CAP_BLUETOOTH BIT(2) #define ACER_CAP_BRIGHTNESS BIT(3) #define ACER_CAP_THREEG BIT(4) +#define ACER_CAP_SET_FUNCTION_MODE BIT(5) /* * Interface type flags @@ -2202,10 +2203,14 @@ static int __init acer_wmi_init(void) if (acpi_video_get_backlight_type() != acpi_backlight_vendor) interface->capability &= ~ACER_CAP_BRIGHTNESS; + if (wmi_has_guid(WMID_GUID3)) + interface->capability |= ACER_CAP_SET_FUNCTION_MODE; + if (force_caps != -1) interface->capability = force_caps; - if (wmi_has_guid(WMID_GUID3)) { + if (wmi_has_guid(WMID_GUID3) && + (interface->capability & ACER_CAP_SET_FUNCTION_MODE)) { if (ACPI_FAILURE(acer_wmi_enable_rf_button())) pr_warn("Cannot enable RF Button Driver\n"); From ba1a647e0f113944b54d7a4bd8db2f72caa76c6e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 19 Oct 2020 20:56:28 +0200 Subject: [PATCH 17/48] platform/x86: acer-wmi: Add support for SW_TABLET_MODE on Switch devices [ Upstream commit 5c54cb6c627e8f50f490e6b5656051a5ac29eab4 ] Add support for SW_TABLET_MODE on the Acer Switch 10 (SW5-012) and the acer Switch 10 (S1003) models. There is no way to detect if this is supported, so this uses DMI based quirks setting force_caps to ACER_CAP_KBD_DOCK (these devices have no other acer-wmi based functionality). The new SW_TABLET_MODE functionality can be tested on devices which are not in the DMI table by passing acer_wmi.force_caps=0x40 on the kernel commandline. Reviewed-by: Andy Shevchenko Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20201019185628.264473-6-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/platform/x86/acer-wmi.c | 109 +++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 8662468491a3..1efca84bc1bd 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -30,6 +30,7 @@ #include #include +ACPI_MODULE_NAME(KBUILD_MODNAME); MODULE_AUTHOR("Carlos Corbacho"); MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver"); MODULE_LICENSE("GPL"); @@ -80,7 +81,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); enum acer_wmi_event_ids { WMID_HOTKEY_EVENT = 0x1, - WMID_ACCEL_EVENT = 0x5, + WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5, }; static const struct key_entry acer_wmi_keymap[] __initconst = { @@ -128,7 +129,9 @@ struct event_return_value { u8 function; u8 key_num; u16 device_state; - u32 reserved; + u16 reserved1; + u8 kbd_dock_state; + u8 reserved2; } __attribute__((packed)); /* @@ -212,6 +215,7 @@ struct hotkey_function_type_aa { #define ACER_CAP_BRIGHTNESS BIT(3) #define ACER_CAP_THREEG BIT(4) #define ACER_CAP_SET_FUNCTION_MODE BIT(5) +#define ACER_CAP_KBD_DOCK BIT(6) /* * Interface type flags @@ -320,6 +324,15 @@ static int __init dmi_matched(const struct dmi_system_id *dmi) return 1; } +static int __init set_force_caps(const struct dmi_system_id *dmi) +{ + if (force_caps == -1) { + force_caps = (uintptr_t)dmi->driver_data; + pr_info("Found %s, set force_caps to 0x%x\n", dmi->ident, force_caps); + } + return 1; +} + static struct quirk_entry quirk_unknown = { }; @@ -498,6 +511,24 @@ static const struct dmi_system_id acer_quirks[] __initconst = { }, .driver_data = &quirk_acer_travelmate_2490, }, + { + .callback = set_force_caps, + .ident = "Acer Aspire Switch 10 SW5-012", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"), + }, + .driver_data = (void *)ACER_CAP_KBD_DOCK, + }, + { + .callback = set_force_caps, + .ident = "Acer One 10 (S1003)", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "One S1003"), + }, + .driver_data = (void *)ACER_CAP_KBD_DOCK, + }, {} }; @@ -1542,6 +1573,71 @@ static int acer_gsensor_event(void) return 0; } +/* + * Switch series keyboard dock status + */ +static int acer_kbd_dock_state_to_sw_tablet_mode(u8 kbd_dock_state) +{ + switch (kbd_dock_state) { + case 0x01: /* Docked, traditional clamshell laptop mode */ + return 0; + case 0x04: /* Stand-alone tablet */ + case 0x40: /* Docked, tent mode, keyboard not usable */ + return 1; + default: + pr_warn("Unknown kbd_dock_state 0x%02x\n", kbd_dock_state); + } + + return 0; +} + +static void acer_kbd_dock_get_initial_state(void) +{ + u8 *output, input[8] = { 0x05, 0x00, }; + struct acpi_buffer input_buf = { sizeof(input), input }; + struct acpi_buffer output_buf = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + acpi_status status; + int sw_tablet_mode; + + status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input_buf, &output_buf); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Error getting keyboard-dock initial status")); + return; + } + + obj = output_buf.pointer; + if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) { + pr_err("Unexpected output format getting keyboard-dock initial status\n"); + goto out_free_obj; + } + + output = obj->buffer.pointer; + if (output[0] != 0x00 || (output[3] != 0x05 && output[3] != 0x45)) { + pr_err("Unexpected output [0]=0x%02x [3]=0x%02x getting keyboard-dock initial status\n", + output[0], output[3]); + goto out_free_obj; + } + + sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(output[4]); + input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode); + +out_free_obj: + kfree(obj); +} + +static void acer_kbd_dock_event(const struct event_return_value *event) +{ + int sw_tablet_mode; + + if (!has_cap(ACER_CAP_KBD_DOCK)) + return; + + sw_tablet_mode = acer_kbd_dock_state_to_sw_tablet_mode(event->kbd_dock_state); + input_report_switch(acer_wmi_input_dev, SW_TABLET_MODE, sw_tablet_mode); + input_sync(acer_wmi_input_dev); +} + /* * Rfkill devices */ @@ -1769,8 +1865,9 @@ static void acer_wmi_notify(u32 value, void *context) sparse_keymap_report_event(acer_wmi_input_dev, scancode, 1, true); } break; - case WMID_ACCEL_EVENT: + case WMID_ACCEL_OR_KBD_DOCK_EVENT: acer_gsensor_event(); + acer_kbd_dock_event(&return_value); break; default: pr_warn("Unknown function number - %d - %d\n", @@ -1935,6 +2032,9 @@ static int __init acer_wmi_input_setup(void) if (err) goto err_free_dev; + if (has_cap(ACER_CAP_KBD_DOCK)) + input_set_capability(acer_wmi_input_dev, EV_SW, SW_TABLET_MODE); + status = wmi_install_notify_handler(ACERWMID_EVENT_GUID, acer_wmi_notify, NULL); if (ACPI_FAILURE(status)) { @@ -1942,6 +2042,9 @@ static int __init acer_wmi_input_setup(void) goto err_free_dev; } + if (has_cap(ACER_CAP_KBD_DOCK)) + acer_kbd_dock_get_initial_state(); + err = input_register_device(acer_wmi_input_dev); if (err) goto err_uninstall_notifier; From 8fb656fefdddd4c53c692f9d244a259ba3c9d961 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 23 Nov 2020 16:16:25 +0100 Subject: [PATCH 18/48] platform/x86: acer-wmi: Add ACER_CAP_KBD_DOCK quirk for the Aspire Switch 10E SW3-016 [ Upstream commit bf753400280d1384abb783efc0b42c491d6deec3 ] Add the Acer Aspire Switch 10E SW3-016 to the list of models which use the Acer Switch WMI interface for reporting SW_TABLET_MODE. Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20201123151625.5530-1-hdegoede@redhat.com Signed-off-by: Sasha Levin --- drivers/platform/x86/acer-wmi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 1efca84bc1bd..80983f9dfcd5 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -511,6 +511,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = { }, .driver_data = &quirk_acer_travelmate_2490, }, + { + .callback = set_force_caps, + .ident = "Acer Aspire Switch 10E SW3-016", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-016"), + }, + .driver_data = (void *)ACER_CAP_KBD_DOCK, + }, { .callback = set_force_caps, .ident = "Acer Aspire Switch 10 SW5-012", From 748446897d367d86b28406467072ab65079d0dc3 Mon Sep 17 00:00:00 2001 From: Ethan Warth Date: Tue, 17 Nov 2020 09:48:00 +0100 Subject: [PATCH 19/48] HID: mf: add support for 0079:1846 Mayflash/Dragonrise USB Gamecube Adapter [ Upstream commit 1008230f2abeb624f6d71b2e1c424fa4eeebbf84 ] Mayflash/Dragonrise seems to have yet another device ID for one of their Gamecube controller adapters. Previous to this commit, the adapter registered only one /dev/input/js* device, and all controller inputs (from any controller) were mapped to this device. This patch defines the 1846 USB device ID and enables the HID_QUIRK_MULTI_INPUT quirk for it, which fixes that (with the patch, four /dev/input/js* devices are created, one for each of the four controller ports). Signed-off-by: Ethan Warth Tested-by: Wladimir J. van der Laan Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-mf.c | 2 ++ drivers/hid/hid-quirks.c | 2 ++ 3 files changed, 5 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 94180c63571e..4b0033d48863 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -359,6 +359,7 @@ #define USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR 0x1803 #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE1 0x1843 #define USB_DEVICE_ID_DRAGONRISE_GAMECUBE2 0x1844 +#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE3 0x1846 #define USB_VENDOR_ID_DWAV 0x0eef #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 diff --git a/drivers/hid/hid-mf.c b/drivers/hid/hid-mf.c index fc75f30f537c..92d7ecd41a78 100644 --- a/drivers/hid/hid-mf.c +++ b/drivers/hid/hid-mf.c @@ -153,6 +153,8 @@ static const struct hid_device_id mf_devices[] = { .driver_data = HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2), .driver_data = 0 }, /* No quirk required */ + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), + .driver_data = HID_QUIRK_MULTI_INPUT }, { } }; MODULE_DEVICE_TABLE(hid, mf_devices); diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index bf7ecab5d9e5..2e38340e19df 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -72,6 +72,7 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_REDRAGON_SEYMUR2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER), HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, @@ -484,6 +485,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_DOLPHINBAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE1) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE3) }, #endif #if IS_ENABLED(CONFIG_HID_MICROSOFT) { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, From c5188a98d2fbac2e00e257f1ac0cff093c54ae9b Mon Sep 17 00:00:00 2001 From: Daniel Lee Kruse Date: Wed, 30 Sep 2020 05:36:35 +0200 Subject: [PATCH 20/48] media: cx23885: add more quirks for reset DMA on some AMD IOMMU [ Upstream commit dbf0b3a7b719eb3f72cb53c2ce7d34a012a9c261 ] On AMD Family 15h (Models 30h-3fh), I/O Memory Management Unit RiSC engine sometimes stalls, requiring a reset. As result, MythTV and w-scan won't scan channels on the AMD Kaveri APU with the Hauppauge QuadHD TV tuner card. For the solution I added the Input/Output Memory Management Unit's PCI Identity of 0x1423 to the broken_dev_id[] array, which is used by a quirks logic meant to fix similar problems with other AMD chipsets. Signed-off-by: Daniel Lee Kruse Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Sasha Levin --- drivers/media/pci/cx23885/cx23885-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index 4b0c53f61fb7..4e8132d4b2df 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -2074,6 +2074,10 @@ static struct { * 0x1451 is PCI ID for the IOMMU found on Ryzen */ { PCI_VENDOR_ID_AMD, 0x1451 }, + /* According to sudo lspci -nn, + * 0x1423 is the PCI ID for the IOMMU found on Kaveri + */ + { PCI_VENDOR_ID_AMD, 0x1423 }, }; static bool cx23885_does_need_dma_reset(void) From d3116e06fb16ad53183036c9e425f8d0a2acf200 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 2 Dec 2020 14:39:42 +0800 Subject: [PATCH 21/48] ACPI: video: Add DMI quirk for GIGABYTE GB-BXBT-2807 [ Upstream commit 25417185e9b5ff90746d50769d2a3fcd1629e254 ] The GIGABYTE GB-BXBT-2807 is a mini-PC which uses off the shelf components, like an Intel GPU which is meant for mobile systems. As such, it, by default, has a backlight controller exposed. Unfortunately, the backlight controller only confuses userspace, which sees the existence of a backlight device node and has the unrealistic belief that there is actually a backlight there! Add a DMI quirk to force the backlight off on this system. Signed-off-by: Jasper St. Pierre Reviewed-by: Chris Chiu Signed-off-by: Rafael J. Wysocki Signed-off-by: Sasha Levin --- drivers/acpi/video_detect.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 4f5463b2a217..811d298637cb 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -140,6 +140,13 @@ static const struct dmi_system_id video_detect_dmi_table[] = { }, { .callback = video_detect_force_vendor, + .ident = "GIGABYTE GB-BXBT-2807", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), + DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"), + }, + }, + { .ident = "Sony VPCEH3U1E", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), From 1b2ac1d95fb1619ed7dc345fe2e4ca4df2a81e3d Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Tue, 8 Dec 2020 14:04:14 +0800 Subject: [PATCH 22/48] ASoC: Intel: bytcr_rt5640: Add quirk for ARCHOS Cesium 140 [ Upstream commit 1bea2256aa96a2d7b1b576eb74e29d79edc9bea8 ] Tha ARCHOS Cesium 140 tablet has problem with the jack-sensing, thus the heaset functions are not working. Add quirk for this model to select the correct input map, jack-detect options and channel map to enable jack sensing and headset microphone. This device uses IN1 for its internal MIC and JD2 for jack-detect. Signed-off-by: Chris Chiu Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20201208060414.27646-1-chiu@endlessos.org Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/bytcr_rt5640.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 3af4cb87032c..d56db9f34373 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -437,6 +437,18 @@ static const struct dmi_system_id byt_rt5640_quirk_table[] = { BYT_RT5640_SSP0_AIF1 | BYT_RT5640_MCLK_EN), }, + { + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 140 CESIUM"), + }, + .driver_data = (void *)(BYT_RT5640_IN1_MAP | + BYT_RT5640_JD_SRC_JD2_IN4N | + BYT_RT5640_OVCD_TH_2000UA | + BYT_RT5640_OVCD_SF_0P75 | + BYT_RT5640_SSP0_AIF1 | + BYT_RT5640_MCLK_EN), + }, { .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), From 3db17e283a923af5dc8e9ba44b3173306dddfd17 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 22 May 2020 17:56:30 +0800 Subject: [PATCH 23/48] usb: cdns3: host: add .suspend_quirk for xhci-plat.c [ Upstream commit ed22764847e8100f0af9af91ccfa58e5c559bd47 ] cdns3 has some special PM sequence between xhci_bus_suspend and xhci_suspend, add quirk to implement it. Reviewed-by: Pawel Laszczak Signed-off-by: Peter Chen Signed-off-by: Sasha Levin --- drivers/usb/cdns3/host-export.h | 6 +++++ drivers/usb/cdns3/host.c | 43 +++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/drivers/usb/cdns3/host-export.h b/drivers/usb/cdns3/host-export.h index ae11810f8826..26041718a086 100644 --- a/drivers/usb/cdns3/host-export.h +++ b/drivers/usb/cdns3/host-export.h @@ -9,9 +9,11 @@ #ifndef __LINUX_CDNS3_HOST_EXPORT #define __LINUX_CDNS3_HOST_EXPORT +struct usb_hcd; #ifdef CONFIG_USB_CDNS3_HOST int cdns3_host_init(struct cdns3 *cdns); +int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd); #else @@ -21,6 +23,10 @@ static inline int cdns3_host_init(struct cdns3 *cdns) } static inline void cdns3_host_exit(struct cdns3 *cdns) { } +static inline int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd) +{ + return 0; +} #endif /* CONFIG_USB_CDNS3_HOST */ diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c index b3e2cb69762c..de8da737fa25 100644 --- a/drivers/usb/cdns3/host.c +++ b/drivers/usb/cdns3/host.c @@ -14,6 +14,18 @@ #include "drd.h" #include "host-export.h" #include +#include "../host/xhci.h" +#include "../host/xhci-plat.h" + +#define XECP_PORT_CAP_REG 0x8000 +#define XECP_AUX_CTRL_REG1 0x8120 + +#define CFG_RXDET_P3_EN BIT(15) +#define LPM_2_STB_SWITCH_EN BIT(25) + +static const struct xhci_plat_priv xhci_plat_cdns3_xhci = { + .suspend_quirk = xhci_cdns3_suspend_quirk, +}; static int __cdns3_host_init(struct cdns3 *cdns) { @@ -39,6 +51,11 @@ static int __cdns3_host_init(struct cdns3 *cdns) goto err1; } + ret = platform_device_add_data(xhci, &xhci_plat_cdns3_xhci, + sizeof(struct xhci_plat_priv)); + if (ret) + goto err1; + ret = platform_device_add(xhci); if (ret) { dev_err(cdns->dev, "failed to register xHCI device\n"); @@ -56,6 +73,32 @@ static int __cdns3_host_init(struct cdns3 *cdns) return ret; } +int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + u32 value; + + if (pm_runtime_status_suspended(hcd->self.controller)) + return 0; + + /* set usbcmd.EU3S */ + value = readl(&xhci->op_regs->command); + value |= CMD_PM_INDEX; + writel(value, &xhci->op_regs->command); + + if (hcd->regs) { + value = readl(hcd->regs + XECP_AUX_CTRL_REG1); + value |= CFG_RXDET_P3_EN; + writel(value, hcd->regs + XECP_AUX_CTRL_REG1); + + value = readl(hcd->regs + XECP_PORT_CAP_REG); + value |= LPM_2_STB_SWITCH_EN; + writel(value, hcd->regs + XECP_PORT_CAP_REG); + } + + return 0; +} + static void cdns3_host_exit(struct cdns3 *cdns) { platform_device_unregister(cdns->host_dev); From febf7d870371ea5b064299ddda2116600824c90c Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Fri, 22 May 2020 18:08:31 +0800 Subject: [PATCH 24/48] usb: cdns3: host: add xhci_plat_priv quirk XHCI_SKIP_PHY_INIT [ Upstream commit 68ed3f3d8a057bd34254e885a6306fedc0936e50 ] cdns3 manages PHY by own DRD driver, so skip the management by HCD core. Reviewed-by: Jun Li Reviewed-by: Pawel Laszczak Signed-off-by: Peter Chen Signed-off-by: Sasha Levin --- drivers/usb/cdns3/host.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c index de8da737fa25..f84739327a16 100644 --- a/drivers/usb/cdns3/host.c +++ b/drivers/usb/cdns3/host.c @@ -24,6 +24,7 @@ #define LPM_2_STB_SWITCH_EN BIT(25) static const struct xhci_plat_priv xhci_plat_cdns3_xhci = { + .quirks = XHCI_SKIP_PHY_INIT, .suspend_quirk = xhci_cdns3_suspend_quirk, }; From 8694c4e2b19c26bc4c0a714d362f6b53cde2d650 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 28 Sep 2020 15:20:03 +0800 Subject: [PATCH 25/48] usb: cdns3: add quirk for enable runtime pm by default [ Upstream commit 7cea9657756b2c83069a775c0671ff169bce456a ] Some vendors (eg: NXP) may want to enable runtime pm by default for power saving, add one quirk for it. Reviewed-by: Jun Li Signed-off-by: Peter Chen Signed-off-by: Sasha Levin --- drivers/usb/cdns3/core.c | 3 ++- drivers/usb/cdns3/core.h | 4 ++++ drivers/usb/cdns3/host.c | 20 +++++++++++++++++--- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 039ab5d2435e..29affbf1e828 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -569,7 +569,8 @@ static int cdns3_probe(struct platform_device *pdev) device_set_wakeup_capable(dev, true); pm_runtime_set_active(dev); pm_runtime_enable(dev); - pm_runtime_forbid(dev); + if (!(cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW)) + pm_runtime_forbid(dev); /* * The controller needs less time between bus and controller suspend, diff --git a/drivers/usb/cdns3/core.h b/drivers/usb/cdns3/core.h index 8a40d53d5ede..3176f924293a 100644 --- a/drivers/usb/cdns3/core.h +++ b/drivers/usb/cdns3/core.h @@ -42,6 +42,8 @@ struct cdns3_role_driver { struct cdns3_platform_data { int (*platform_suspend)(struct device *dev, bool suspend, bool wakeup); + unsigned long quirks; +#define CDNS3_DEFAULT_PM_RUNTIME_ALLOW BIT(0) }; /** @@ -73,6 +75,7 @@ struct cdns3_platform_data { * @wakeup_pending: wakeup interrupt pending * @pdata: platform data from glue layer * @lock: spinlock structure + * @xhci_plat_data: xhci private data structure pointer */ struct cdns3 { struct device *dev; @@ -106,6 +109,7 @@ struct cdns3 { bool wakeup_pending; struct cdns3_platform_data *pdata; spinlock_t lock; + struct xhci_plat_priv *xhci_plat_data; }; int cdns3_hw_role_switch(struct cdns3 *cdns); diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c index f84739327a16..c3b29a9c77a5 100644 --- a/drivers/usb/cdns3/host.c +++ b/drivers/usb/cdns3/host.c @@ -52,15 +52,25 @@ static int __cdns3_host_init(struct cdns3 *cdns) goto err1; } - ret = platform_device_add_data(xhci, &xhci_plat_cdns3_xhci, + cdns->xhci_plat_data = kmemdup(&xhci_plat_cdns3_xhci, + sizeof(struct xhci_plat_priv), GFP_KERNEL); + if (!cdns->xhci_plat_data) { + ret = -ENOMEM; + goto err1; + } + + if (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW) + cdns->xhci_plat_data->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; + + ret = platform_device_add_data(xhci, cdns->xhci_plat_data, sizeof(struct xhci_plat_priv)); if (ret) - goto err1; + goto free_memory; ret = platform_device_add(xhci); if (ret) { dev_err(cdns->dev, "failed to register xHCI device\n"); - goto err1; + goto free_memory; } /* Glue needs to access xHCI region register for Power management */ @@ -69,6 +79,9 @@ static int __cdns3_host_init(struct cdns3 *cdns) cdns->xhci_regs = hcd->regs; return 0; + +free_memory: + kfree(cdns->xhci_plat_data); err1: platform_device_put(xhci); return ret; @@ -102,6 +115,7 @@ int xhci_cdns3_suspend_quirk(struct usb_hcd *hcd) static void cdns3_host_exit(struct cdns3 *cdns) { + kfree(cdns->xhci_plat_data); platform_device_unregister(cdns->host_dev); cdns->host_dev = NULL; cdns3_drd_host_off(cdns); From 0ff1f97510fde30905cb8cafbd5b0daca72e2315 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Mon, 23 Nov 2020 12:49:31 +0200 Subject: [PATCH 26/48] usb: cdns3: fix NULL pointer dereference on no platform data [ Upstream commit 448373d9db1a7000072f65103af19e20503f0c0c ] Some platforms (e.g. TI) will not have any platform data which will lead to NULL pointer dereference if we don't check for NULL pdata. Fixes: 7cea9657756b ("usb: cdns3: add quirk for enable runtime pm by default") Reported-by: Nishanth Menon Signed-off-by: Roger Quadros Acked-by: Pawel Laszczak Signed-off-by: Peter Chen Signed-off-by: Sasha Levin --- drivers/usb/cdns3/core.c | 2 +- drivers/usb/cdns3/host.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 29affbf1e828..6eeb7ed8e91f 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -569,7 +569,7 @@ static int cdns3_probe(struct platform_device *pdev) device_set_wakeup_capable(dev, true); pm_runtime_set_active(dev); pm_runtime_enable(dev); - if (!(cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW)) + if (!(cdns->pdata && (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW))) pm_runtime_forbid(dev); /* diff --git a/drivers/usb/cdns3/host.c b/drivers/usb/cdns3/host.c index c3b29a9c77a5..102977790d60 100644 --- a/drivers/usb/cdns3/host.c +++ b/drivers/usb/cdns3/host.c @@ -59,7 +59,7 @@ static int __cdns3_host_init(struct cdns3 *cdns) goto err1; } - if (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW) + if (cdns->pdata && (cdns->pdata->quirks & CDNS3_DEFAULT_PM_RUNTIME_ALLOW)) cdns->xhci_plat_data->quirks |= XHCI_DEFAULT_PM_RUNTIME_ALLOW; ret = platform_device_add_data(xhci, cdns->xhci_plat_data, From 422da3196be9ee17a642c1fe98d2dd07bf088ec0 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 10 Nov 2020 16:00:57 -0600 Subject: [PATCH 27/48] PCI: Add function 1 DMA alias quirk for Marvell 9215 SATA controller [ Upstream commit 059983790a4c963d92943e55a61fca55be427d55 ] Add function 1 DMA alias quirk for Marvell 88SS9215 PCIe SSD Controller. Link: https://bugzilla.kernel.org/show_bug.cgi?id=42679#c135 Link: https://lore.kernel.org/r/20201110220516.697934-1-helgaas@kernel.org Reported-by: John Smith Signed-off-by: Bjorn Helgaas Signed-off-by: Sasha Levin --- drivers/pci/quirks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index fb1dc11e7cc5..b570f297e3ec 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3998,6 +3998,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9183, /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c46 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0, quirk_dma_func1_alias); +/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c135 */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9215, + quirk_dma_func1_alias); /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c127 */ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9220, quirk_dma_func1_alias); From c7ebe45e403dd38bc93ee56820a4a5cc4d67f66e Mon Sep 17 00:00:00 2001 From: Vitaly Kuznetsov Date: Mon, 1 Feb 2021 15:28:43 +0100 Subject: [PATCH 28/48] KVM: x86: Supplement __cr4_reserved_bits() with X86_FEATURE_PCID check [ Upstream commit 4683d758f48e6ae87d3d3493ffa00aceb955ee16 ] Commit 7a873e455567 ("KVM: selftests: Verify supported CR4 bits can be set before KVM_SET_CPUID2") reveals that KVM allows to set X86_CR4_PCIDE even when PCID support is missing: ==== Test Assertion Failure ==== x86_64/set_sregs_test.c:41: rc pid=6956 tid=6956 - Invalid argument 1 0x000000000040177d: test_cr4_feature_bit at set_sregs_test.c:41 2 0x00000000004014fc: main at set_sregs_test.c:119 3 0x00007f2d9346d041: ?? ??:0 4 0x000000000040164d: _start at ??:? KVM allowed unsupported CR4 bit (0x20000) Add X86_FEATURE_PCID feature check to __cr4_reserved_bits() to make kvm_is_valid_cr4() fail. Signed-off-by: Vitaly Kuznetsov Message-Id: <20210201142843.108190-1-vkuznets@redhat.com> Signed-off-by: Paolo Bonzini Signed-off-by: Sasha Levin --- arch/x86/kvm/x86.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index e7ca622a468f..2249a7d7ca27 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -404,6 +404,8 @@ bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type); __reserved_bits |= X86_CR4_UMIP; \ if (!__cpu_has(__c, X86_FEATURE_VMX)) \ __reserved_bits |= X86_CR4_VMXE; \ + if (!__cpu_has(__c, X86_FEATURE_PCID)) \ + __reserved_bits |= X86_CR4_PCIDE; \ __reserved_bits; \ }) From ff72a41132b3422e9be342889513446a3367d653 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 4 Feb 2021 14:33:01 -0600 Subject: [PATCH 29/48] ASoC: Intel: sof_sdw: add missing TGL_HDMI quirk for Dell SKU 0A32 [ Upstream commit 45c92ec32b43c6cb42341ebf07577eefed9d87ec ] We missed adding the TGL_HDMI quirk which is very much needed to expose the 4 display pipelines and will be required on TGL topologies. Fixes: 488cdbd8931fe ('ASoC: Intel: sof_sdw: add quirk for new TigerLake-SDCA device') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210204203312.27112-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/sof_sdw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 9519e5403cbf..daca06dde99b 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -54,7 +54,8 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") }, - .driver_data = (void *)(SOF_RT711_JD_SRC_JD2 | + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD2 | SOF_RT715_DAI_ID_FIX | SOF_SDW_FOUR_SPK), }, From dbaa2667515edf5b0c3f9deb56d60bfedcea7651 Mon Sep 17 00:00:00 2001 From: Stanley Chu Date: Tue, 22 Dec 2020 15:29:28 +0800 Subject: [PATCH 30/48] scsi: ufs-mediatek: Enable UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL [ Upstream commit 46ec9592ffd679fa26142dcb9e5119aad7e60b55 ] Flush during hibern8 is sufficient on MediaTek platforms, thus enable UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL to skip enabling fWriteBoosterBufferFlush during WriteBooster initialization. Link: https://lore.kernel.org/r/20201222072928.32328-1-stanley.chu@mediatek.com Reviewed-by: Avri Altman Signed-off-by: Stanley Chu Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ufs/ufs-mediatek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index 914a827a93ee..934713472ebc 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -566,6 +566,7 @@ static int ufs_mtk_init(struct ufs_hba *hba) /* Enable WriteBooster */ hba->caps |= UFSHCD_CAP_WB_EN; + hba->quirks |= UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL; hba->vps->wb_flush_threshold = UFS_WB_BUF_REMAIN_PERCENT(80); /* From 2fc01226c288413261085450954faf8d027b65c0 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 21 Dec 2020 10:24:40 +0900 Subject: [PATCH 31/48] scsi: ufs: Add a quirk to permit overriding UniPro defaults [ Upstream commit b1d0d2eb89d4e3a25b212a9d836587503537067e ] The UniPro specification states that attribute IDs of the following parameters are vendor-specific so some SoCs could have no regions at the defined addresses: - DME_LocalFC0ProtectionTimeOutVal - DME_LocalTC0ReplayTimeOutVal - DME_LocalAFC0ReqTimeOutVal In addition, the following parameters should be set considering the compatibility between host and device. - PA_PWRMODEUSERDATA0 - PA_PWRMODEUSERDATA1 - PA_PWRMODEUSERDATA2 - PA_PWRMODEUSERDATA3 - PA_PWRMODEUSERDATA4 - PA_PWRMODEUSERDATA5 Introduce a quirk to allow vendor drivers to override the UniPro defaults. Link: https://lore.kernel.org/r/1fedd3dea0ccc980913a5995a10510d86a5b01b9.1608513782.git.kwmad.kim@samsung.com Acked-by: Avri Altman Signed-off-by: Kiwoong Kim Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ufs/ufshcd.c | 38 ++++++++++++++++++++------------------ drivers/scsi/ufs/ufshcd.h | 6 ++++++ 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 813289328467..379d44d6b9eb 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4153,25 +4153,27 @@ static int ufshcd_change_power_mode(struct ufs_hba *hba, ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HSSERIES), pwr_mode->hs_rate); - ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), - DL_FC0ProtectionTimeOutVal_Default); - ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), - DL_TC0ReplayTimeOutVal_Default); - ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), - DL_AFC0ReqTimeOutVal_Default); - ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA3), - DL_FC1ProtectionTimeOutVal_Default); - ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA4), - DL_TC1ReplayTimeOutVal_Default); - ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA5), - DL_AFC1ReqTimeOutVal_Default); + if (!(hba->quirks & UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING)) { + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), + DL_FC0ProtectionTimeOutVal_Default); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), + DL_TC0ReplayTimeOutVal_Default); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), + DL_AFC0ReqTimeOutVal_Default); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA3), + DL_FC1ProtectionTimeOutVal_Default); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA4), + DL_TC1ReplayTimeOutVal_Default); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA5), + DL_AFC1ReqTimeOutVal_Default); - ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalFC0ProtectionTimeOutVal), - DL_FC0ProtectionTimeOutVal_Default); - ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalTC0ReplayTimeOutVal), - DL_TC0ReplayTimeOutVal_Default); - ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalAFC0ReqTimeOutVal), - DL_AFC0ReqTimeOutVal_Default); + ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalFC0ProtectionTimeOutVal), + DL_FC0ProtectionTimeOutVal_Default); + ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalTC0ReplayTimeOutVal), + DL_TC0ReplayTimeOutVal_Default); + ufshcd_dme_set(hba, UIC_ARG_MIB(DME_LocalAFC0ReqTimeOutVal), + DL_AFC0ReqTimeOutVal_Default); + } ret = ufshcd_uic_change_pwr_mode(hba, pwr_mode->pwr_rx << 4 | pwr_mode->pwr_tx); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 6c62a281c863..fcca4e15c8cd 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -544,6 +544,12 @@ enum ufshcd_quirks { */ UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL = 1 << 12, + /* + * This quirk needs to disable unipro timeout values + * before power mode change + */ + UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING = 1 << 13, + }; enum ufshcd_caps { From eece8fe5ebb0ef25151840df73a71857e7177b70 Mon Sep 17 00:00:00 2001 From: Aswath Govindraju Date: Tue, 5 Jan 2021 16:28:12 +0530 Subject: [PATCH 32/48] misc: eeprom_93xx46: Add quirk to support Microchip 93LC46B eeprom [ Upstream commit f6f1f8e6e3eea25f539105d48166e91f0ab46dd1 ] A dummy zero bit is sent preceding the data during a read transfer by the Microchip 93LC46B eeprom (section 2.7 of[1]). This results in right shift of data during a read. In order to ignore this bit a quirk can be added to send an extra zero bit after the read address. Add a quirk to ignore the zero bit sent before data by adding a zero bit after the read address. [1] - https://www.mouser.com/datasheet/2/268/20001749K-277859.pdf Signed-off-by: Aswath Govindraju Link: https://lore.kernel.org/r/20210105105817.17644-3-a-govindraju@ti.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/misc/eeprom/eeprom_93xx46.c | 15 +++++++++++++++ include/linux/eeprom_93xx46.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index d92c4d2c521a..6e5f544c9c73 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -35,6 +35,10 @@ static const struct eeprom_93xx46_devtype_data atmel_at93c46d_data = { EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH, }; +static const struct eeprom_93xx46_devtype_data microchip_93lc46b_data = { + .quirks = EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE, +}; + struct eeprom_93xx46_dev { struct spi_device *spi; struct eeprom_93xx46_platform_data *pdata; @@ -55,6 +59,11 @@ static inline bool has_quirk_instruction_length(struct eeprom_93xx46_dev *edev) return edev->pdata->quirks & EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH; } +static inline bool has_quirk_extra_read_cycle(struct eeprom_93xx46_dev *edev) +{ + return edev->pdata->quirks & EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE; +} + static int eeprom_93xx46_read(void *priv, unsigned int off, void *val, size_t count) { @@ -96,6 +105,11 @@ static int eeprom_93xx46_read(void *priv, unsigned int off, dev_dbg(&edev->spi->dev, "read cmd 0x%x, %d Hz\n", cmd_addr, edev->spi->max_speed_hz); + if (has_quirk_extra_read_cycle(edev)) { + cmd_addr <<= 1; + bits += 1; + } + spi_message_init(&m); t[0].tx_buf = (char *)&cmd_addr; @@ -363,6 +377,7 @@ static void select_deassert(void *context) static const struct of_device_id eeprom_93xx46_of_table[] = { { .compatible = "eeprom-93xx46", }, { .compatible = "atmel,at93c46d", .data = &atmel_at93c46d_data, }, + { .compatible = "microchip,93lc46b", .data = µchip_93lc46b_data, }, {} }; MODULE_DEVICE_TABLE(of, eeprom_93xx46_of_table); diff --git a/include/linux/eeprom_93xx46.h b/include/linux/eeprom_93xx46.h index eec7928ff8fe..99580c22f91a 100644 --- a/include/linux/eeprom_93xx46.h +++ b/include/linux/eeprom_93xx46.h @@ -16,6 +16,8 @@ struct eeprom_93xx46_platform_data { #define EEPROM_93XX46_QUIRK_SINGLE_WORD_READ (1 << 0) /* Instructions such as EWEN are (addrlen + 2) in length. */ #define EEPROM_93XX46_QUIRK_INSTRUCTION_LENGTH (1 << 1) +/* Add extra cycle after address during a read */ +#define EEPROM_93XX46_QUIRK_EXTRA_READ_CYCLE BIT(2) /* * optional hooks to control additional logic From c32b34115357ca555189b48296bbd4242b5cd256 Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Tue, 19 Jan 2021 12:33:41 +0900 Subject: [PATCH 33/48] scsi: ufs: Introduce a quirk to allow only page-aligned sg entries [ Upstream commit 2b2bfc8aa519f696087475ed8e8c61850c673272 ] Some SoCs require a single scatterlist entry for smaller than page size, i.e. 4KB. When dispatching commands with more than one scatterlist entry under 4KB in size the following behavior is observed: A command to read a block range is dispatched with two scatterlist entries that are named AAA and BBB. After dispatching, the host builds two PRDT entries and during transmission, device sends just one DATA IN because device doesn't care about host DMA. The host then transfers the combined amount of data from start address of the area named AAA. As a consequence, the area that follows AAA in memory would be corrupted. |<------------->| +-------+------------ +-------+ + AAA + (corrupted) ... + BBB + +-------+------------ +-------+ To avoid this we need to enforce page size alignment for sg entries. Link: https://lore.kernel.org/r/56dddef94f60bd9466fd77e69f64bbbd657ed2a1.1611026909.git.kwmad.kim@samsung.com Signed-off-by: Kiwoong Kim Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ufs/ufshcd.c | 2 ++ drivers/scsi/ufs/ufshcd.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 379d44d6b9eb..5a7cc2e42ffd 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -4748,6 +4748,8 @@ static int ufshcd_slave_configure(struct scsi_device *sdev) struct request_queue *q = sdev->request_queue; blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1); + if (hba->quirks & UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE) + blk_queue_update_dma_alignment(q, PAGE_SIZE - 1); if (ufshcd_is_rpm_autosuspend_allowed(hba)) sdev->rpm_autosuspend = 1; diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index fcca4e15c8cd..a0bc118f9188 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -550,6 +550,10 @@ enum ufshcd_quirks { */ UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING = 1 << 13, + /* + * This quirk allows only sg entries aligned with page size. + */ + UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE = 1 << 13, }; enum ufshcd_caps { From 0905bfe69ac2240a6b01b06da21b7c5da0d028ae Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Mon, 21 Dec 2020 10:24:41 +0900 Subject: [PATCH 34/48] scsi: ufs: ufs-exynos: Apply vendor-specific values for three timeouts [ Upstream commit a967ddb22d94eb476ccef983b5f2730fa4d184d0 ] Set optimized values for the following timeouts: - FC0_PROTECTION_TIMER - TC0_REPLAY_TIMER - AFC0_REQUEST_TIMER Exynos doesn't yet use traffic class #1. Link: https://lore.kernel.org/r/a0ff44f665a4f31d2f945fd71de03571204c576c.1608513782.git.kwmad.kim@samsung.com Signed-off-by: Kiwoong Kim Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ufs/ufs-exynos.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c index 5e6b95dbb578..2993ac877a61 100644 --- a/drivers/scsi/ufs/ufs-exynos.c +++ b/drivers/scsi/ufs/ufs-exynos.c @@ -653,6 +653,11 @@ static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba, } } + /* setting for three timeout values for traffic class #0 */ + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), 8064); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), 28224); + ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), 20160); + return 0; out: return ret; @@ -1249,7 +1254,8 @@ struct exynos_ufs_drv_data exynos_ufs_drvs = { UFSHCI_QUIRK_BROKEN_HCE | UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR | UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR | - UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL, + UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL | + UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING, .opts = EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL | EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL | EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX | From e74b237ef989facf9b3e0874cf9fddd0c6df957f Mon Sep 17 00:00:00 2001 From: Kiwoong Kim Date: Tue, 19 Jan 2021 12:33:42 +0900 Subject: [PATCH 35/48] scsi: ufs: ufs-exynos: Use UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE [ Upstream commit f1ef9047aaab036edb39261b0a7a6bdcf3010b87 ] Exynos needs scatterlist entries aligned to page size because it isn't capable of transferring data contained in one DATA IN operation to seversal areas in memory. Link: https://lore.kernel.org/r/80d7e27d6ec537e650a6bd74897b6c60618efcdc.1611026909.git.kwmad.kim@samsung.com Signed-off-by: Kiwoong Kim Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ufs/ufs-exynos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c index 2993ac877a61..f54b494ca448 100644 --- a/drivers/scsi/ufs/ufs-exynos.c +++ b/drivers/scsi/ufs/ufs-exynos.c @@ -1255,7 +1255,8 @@ struct exynos_ufs_drv_data exynos_ufs_drvs = { UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR | UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR | UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL | - UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING, + UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING | + UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE, .opts = EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL | EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL | EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX | From e62bdb34858cf25262e36f9f41aaf558577576ac Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 13 Jan 2021 19:33:33 +0100 Subject: [PATCH 36/48] drm/msm/a5xx: Remove overwriting A5XX_PC_DBG_ECO_CNTL register [ Upstream commit 8f03c30cb814213e36032084a01f49a9e604a3e3 ] The PC_DBG_ECO_CNTL register on the Adreno A5xx family gets programmed to some different values on a per-model basis. At least, this is what we intend to do here; Unfortunately, though, this register is being overwritten with a static magic number, right after applying the GPU-specific configuration (including the GPU-specific quirks) and that is effectively nullifying the efforts. Let's remove the redundant and wrong write to the PC_DBG_ECO_CNTL register in order to retain the wanted configuration for the target GPU. Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Jordan Crouse Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 69ed2c609466..5e11cdb207d8 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -626,8 +626,6 @@ static int a5xx_hw_init(struct msm_gpu *gpu) if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI) gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8)); - gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0xc0200100); - /* Enable USE_RETENTION_FLOPS */ gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x02000000); From 5b652628349903df12c03154aad81d0afd987d21 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Thu, 10 Dec 2020 16:55:10 +0800 Subject: [PATCH 37/48] mmc: sdhci-of-dwcmshc: set SDHCI_QUIRK2_PRESET_VALUE_BROKEN [ Upstream commit 5f7dfda4f2cec580c135fd81d96a05006651c128 ] The SDHCI_PRESET_FOR_* registers are not set(all read as zeros), so set the quirk. Signed-off-by: Jisheng Zhang Link: https://lore.kernel.org/r/20201210165510.76b917e5@xhacker.debian Signed-off-by: Ulf Hansson Signed-off-by: Sasha Levin --- drivers/mmc/host/sdhci-of-dwcmshc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index d90020ed3622..59d8d96ce206 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c @@ -112,6 +112,7 @@ static const struct sdhci_ops sdhci_dwcmshc_ops = { static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { .ops = &sdhci_dwcmshc_ops, .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, }; static int dwcmshc_probe(struct platform_device *pdev) From 96c4c0a9405e0a5b9c8fcb6d338628a799a3b350 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 30 Jan 2021 21:33:23 +0100 Subject: [PATCH 38/48] HID: i2c-hid: Add I2C_HID_QUIRK_NO_IRQ_AFTER_RESET for ITE8568 EC on Voyo Winpad A15 [ Upstream commit fc6a31b00739356809dd566e16f2c4325a63285d ] The ITE8568 EC on the Voyo Winpad A15 presents itself as an I2C-HID attached keyboard and mouse (which seems to never send any events). This needs the I2C_HID_QUIRK_NO_IRQ_AFTER_RESET quirk, otherwise we get the following errors: [ 3688.770850] i2c_hid i2c-ITE8568:00: failed to reset device. [ 3694.915865] i2c_hid i2c-ITE8568:00: failed to reset device. [ 3701.059717] i2c_hid i2c-ITE8568:00: failed to reset device. [ 3707.205944] i2c_hid i2c-ITE8568:00: failed to reset device. [ 3708.227940] i2c_hid i2c-ITE8568:00: can't add hid device: -61 [ 3708.236518] i2c_hid: probe of i2c-ITE8568:00 failed with error -61 Which leads to a significant boot delay. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina Signed-off-by: Sasha Levin --- drivers/hid/hid-ids.h | 2 ++ drivers/hid/i2c-hid/i2c-hid-core.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 4b0033d48863..06813f297dcc 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -639,6 +639,8 @@ #define USB_DEVICE_ID_INNEX_GENESIS_ATARI 0x4745 #define USB_VENDOR_ID_ITE 0x048d +#define I2C_VENDOR_ID_ITE 0x103c +#define I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15 0x184f #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 #define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index aeff1ffb0c8b..cb7758d59014 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -171,6 +171,8 @@ static const struct i2c_hid_quirks { I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, { I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288, I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, + { I2C_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15, + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_3118, I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, { USB_VENDOR_ID_ELAN, HID_ANY_ID, From d78acca2afe50a73e89617732ba029098e7abaac Mon Sep 17 00:00:00 2001 From: Olivia Mackintosh Date: Fri, 5 Feb 2021 18:42:56 +0000 Subject: [PATCH 39/48] ALSA: usb-audio: Add DJM750 to Pioneer mixer quirk [ Upstream commit a07df82c799013236aa90a140785775eda9f9523 ] This allows for N different devices to use the pioneer mixer quirk for setting capture/record type and recording level. The impementation has not changed much with the exception of an additional mask on private_value to allow storing of a device index: DEVICE MASK 0xff000000 GROUP_MASK 0x00ff0000 VALUE_MASK 0x0000ffff This could be improved by changing the arrays of wValues for each channel to contain named definitions (e.g. SND_DJM_CAP_LINE). It would improve readability and perhaps would allow using the same array for multiple channels. The channel number can be specified on the control next to the wIndex. Feedback is very much appreciated as I'm not the most proficient C programmer but am learning as I go. Signed-off-by: Olivia Mackintosh Link: https://lore.kernel.org/r/20210205184256.10201-2-livvy@base.nu Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/mixer_quirks.c | 360 +++++++++++++++++++++++++-------------- 1 file changed, 228 insertions(+), 132 deletions(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index df036a359f2f..788b75cb9447 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -2603,141 +2603,221 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer) } /* - * Pioneer DJ DJM-250MK2 and maybe other DJM models + * Pioneer DJ DJM Mixers * - * For playback, no duplicate mapping should be set. - * There are three mixer stereo channels (CH1, CH2, AUX) - * and three stereo sources (Playback 1-2, Playback 3-4, Playback 5-6). - * Each channel should be mapped just once to one source. - * If mapped multiple times, only one source will play on given channel - * (sources are not mixed together). + * These devices generally have options for soft-switching the playback and + * capture sources in addition to the recording level. Although different + * devices have different configurations, there seems to be canonical values + * for specific capture/playback types: See the definitions of these below. * - * For recording, duplicate mapping is OK. We will get the same signal multiple times. - * - * Channels 7-8 are in both directions fixed to FX SEND / FX RETURN. - * - * See also notes in the quirks-table.h file. + * The wValue is masked with the stereo channel number. e.g. Setting Ch2 to + * capture phono would be 0x0203. Capture, playback and capture level have + * different wIndexes. */ -struct snd_pioneer_djm_option { - const u16 wIndex; - const u16 wValue; - const char *name; -}; +// Capture types +#define SND_DJM_CAP_LINE 0x00 +#define SND_DJM_CAP_CDLINE 0x01 +#define SND_DJM_CAP_PHONO 0x03 +#define SND_DJM_CAP_PFADER 0x06 +#define SND_DJM_CAP_XFADERA 0x07 +#define SND_DJM_CAP_XFADERB 0x08 +#define SND_DJM_CAP_MIC 0x09 +#define SND_DJM_CAP_AUX 0x0d +#define SND_DJM_CAP_RECOUT 0x0a +#define SND_DJM_CAP_NONE 0x0f +#define SND_DJM_CAP_CH1PFADER 0x11 +#define SND_DJM_CAP_CH2PFADER 0x12 -static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_level[] = { - { .name = "-5 dB", .wValue = 0x0300, .wIndex = 0x8003 }, - { .name = "-10 dB", .wValue = 0x0200, .wIndex = 0x8003 }, - { .name = "-15 dB", .wValue = 0x0100, .wIndex = 0x8003 }, - { .name = "-19 dB", .wValue = 0x0000, .wIndex = 0x8003 } -}; +// Playback types +#define SND_DJM_PB_CH1 0x00 +#define SND_DJM_PB_CH2 0x01 +#define SND_DJM_PB_AUX 0x04 -static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_ch12[] = { - { .name = "CH1 Control Tone PHONO", .wValue = 0x0103, .wIndex = 0x8002 }, - { .name = "CH1 Control Tone LINE", .wValue = 0x0100, .wIndex = 0x8002 }, - { .name = "Post CH1 Fader", .wValue = 0x0106, .wIndex = 0x8002 }, - { .name = "Cross Fader A", .wValue = 0x0107, .wIndex = 0x8002 }, - { .name = "Cross Fader B", .wValue = 0x0108, .wIndex = 0x8002 }, - { .name = "MIC", .wValue = 0x0109, .wIndex = 0x8002 }, - { .name = "AUX", .wValue = 0x010d, .wIndex = 0x8002 }, - { .name = "REC OUT", .wValue = 0x010a, .wIndex = 0x8002 } -}; +#define SND_DJM_WINDEX_CAP 0x8002 +#define SND_DJM_WINDEX_CAPLVL 0x8003 +#define SND_DJM_WINDEX_PB 0x8016 -static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_ch34[] = { - { .name = "CH2 Control Tone PHONO", .wValue = 0x0203, .wIndex = 0x8002 }, - { .name = "CH2 Control Tone LINE", .wValue = 0x0200, .wIndex = 0x8002 }, - { .name = "Post CH2 Fader", .wValue = 0x0206, .wIndex = 0x8002 }, - { .name = "Cross Fader A", .wValue = 0x0207, .wIndex = 0x8002 }, - { .name = "Cross Fader B", .wValue = 0x0208, .wIndex = 0x8002 }, - { .name = "MIC", .wValue = 0x0209, .wIndex = 0x8002 }, - { .name = "AUX", .wValue = 0x020d, .wIndex = 0x8002 }, - { .name = "REC OUT", .wValue = 0x020a, .wIndex = 0x8002 } -}; +// kcontrol->private_value layout +#define SND_DJM_VALUE_MASK 0x0000ffff +#define SND_DJM_GROUP_MASK 0x00ff0000 +#define SND_DJM_DEVICE_MASK 0xff000000 +#define SND_DJM_GROUP_SHIFT 16 +#define SND_DJM_DEVICE_SHIFT 24 -static const struct snd_pioneer_djm_option snd_pioneer_djm_options_capture_ch56[] = { - { .name = "REC OUT", .wValue = 0x030a, .wIndex = 0x8002 }, - { .name = "Post CH1 Fader", .wValue = 0x0311, .wIndex = 0x8002 }, - { .name = "Post CH2 Fader", .wValue = 0x0312, .wIndex = 0x8002 }, - { .name = "Cross Fader A", .wValue = 0x0307, .wIndex = 0x8002 }, - { .name = "Cross Fader B", .wValue = 0x0308, .wIndex = 0x8002 }, - { .name = "MIC", .wValue = 0x0309, .wIndex = 0x8002 }, - { .name = "AUX", .wValue = 0x030d, .wIndex = 0x8002 } -}; +// device table index +#define SND_DJM_250MK2_IDX 0x0 +#define SND_DJM_750_IDX 0x1 -static const struct snd_pioneer_djm_option snd_pioneer_djm_options_playback_12[] = { - { .name = "CH1", .wValue = 0x0100, .wIndex = 0x8016 }, - { .name = "CH2", .wValue = 0x0101, .wIndex = 0x8016 }, - { .name = "AUX", .wValue = 0x0104, .wIndex = 0x8016 } -}; -static const struct snd_pioneer_djm_option snd_pioneer_djm_options_playback_34[] = { - { .name = "CH1", .wValue = 0x0200, .wIndex = 0x8016 }, - { .name = "CH2", .wValue = 0x0201, .wIndex = 0x8016 }, - { .name = "AUX", .wValue = 0x0204, .wIndex = 0x8016 } -}; - -static const struct snd_pioneer_djm_option snd_pioneer_djm_options_playback_56[] = { - { .name = "CH1", .wValue = 0x0300, .wIndex = 0x8016 }, - { .name = "CH2", .wValue = 0x0301, .wIndex = 0x8016 }, - { .name = "AUX", .wValue = 0x0304, .wIndex = 0x8016 } -}; - -struct snd_pioneer_djm_option_group { - const char *name; - const struct snd_pioneer_djm_option *options; - const size_t count; - const u16 default_value; -}; - -#define snd_pioneer_djm_option_group_item(_name, suffix, _default_value) { \ +#define SND_DJM_CTL(_name, suffix, _default_value, _windex) { \ .name = _name, \ - .options = snd_pioneer_djm_options_##suffix, \ - .count = ARRAY_SIZE(snd_pioneer_djm_options_##suffix), \ - .default_value = _default_value } + .options = snd_djm_opts_##suffix, \ + .noptions = ARRAY_SIZE(snd_djm_opts_##suffix), \ + .default_value = _default_value, \ + .wIndex = _windex } -static const struct snd_pioneer_djm_option_group snd_pioneer_djm_option_groups[] = { - snd_pioneer_djm_option_group_item("Master Capture Level Capture Switch", capture_level, 0), - snd_pioneer_djm_option_group_item("Capture 1-2 Capture Switch", capture_ch12, 2), - snd_pioneer_djm_option_group_item("Capture 3-4 Capture Switch", capture_ch34, 2), - snd_pioneer_djm_option_group_item("Capture 5-6 Capture Switch", capture_ch56, 0), - snd_pioneer_djm_option_group_item("Playback 1-2 Playback Switch", playback_12, 0), - snd_pioneer_djm_option_group_item("Playback 3-4 Playback Switch", playback_34, 1), - snd_pioneer_djm_option_group_item("Playback 5-6 Playback Switch", playback_56, 2) +#define SND_DJM_DEVICE(suffix) { \ + .controls = snd_djm_ctls_##suffix, \ + .ncontrols = ARRAY_SIZE(snd_djm_ctls_##suffix) } + + +struct snd_djm_device { + const char *name; + const struct snd_djm_ctl *controls; + size_t ncontrols; }; -// layout of the kcontrol->private_value: -#define SND_PIONEER_DJM_VALUE_MASK 0x0000ffff -#define SND_PIONEER_DJM_GROUP_MASK 0xffff0000 -#define SND_PIONEER_DJM_GROUP_SHIFT 16 - -static int snd_pioneer_djm_controls_info(struct snd_kcontrol *kctl, struct snd_ctl_elem_info *info) -{ - u16 group_index = kctl->private_value >> SND_PIONEER_DJM_GROUP_SHIFT; - size_t count; +struct snd_djm_ctl { const char *name; - const struct snd_pioneer_djm_option_group *group; + const u16 *options; + size_t noptions; + u16 default_value; + u16 wIndex; +}; - if (group_index >= ARRAY_SIZE(snd_pioneer_djm_option_groups)) +static const char *snd_djm_get_label_caplevel(u16 wvalue) +{ + switch (wvalue) { + case 0x0000: return "-19dB"; + case 0x0100: return "-15dB"; + case 0x0200: return "-10dB"; + case 0x0300: return "-5dB"; + default: return NULL; + } +}; + +static const char *snd_djm_get_label_cap(u16 wvalue) +{ + switch (wvalue & 0x00ff) { + case SND_DJM_CAP_LINE: return "Control Tone LINE"; + case SND_DJM_CAP_CDLINE: return "Control Tone CD/LINE"; + case SND_DJM_CAP_PHONO: return "Control Tone PHONO"; + case SND_DJM_CAP_PFADER: return "Post Fader"; + case SND_DJM_CAP_XFADERA: return "Cross Fader A"; + case SND_DJM_CAP_XFADERB: return "Cross Fader B"; + case SND_DJM_CAP_MIC: return "Mic"; + case SND_DJM_CAP_RECOUT: return "Rec Out"; + case SND_DJM_CAP_AUX: return "Aux"; + case SND_DJM_CAP_NONE: return "None"; + case SND_DJM_CAP_CH1PFADER: return "Post Fader Ch1"; + case SND_DJM_CAP_CH2PFADER: return "Post Fader Ch2"; + default: return NULL; + } +}; + +static const char *snd_djm_get_label_pb(u16 wvalue) +{ + switch (wvalue & 0x00ff) { + case SND_DJM_PB_CH1: return "Ch1"; + case SND_DJM_PB_CH2: return "Ch2"; + case SND_DJM_PB_AUX: return "Aux"; + default: return NULL; + } +}; + +static const char *snd_djm_get_label(u16 wvalue, u16 windex) +{ + switch (windex) { + case SND_DJM_WINDEX_CAPLVL: return snd_djm_get_label_caplevel(wvalue); + case SND_DJM_WINDEX_CAP: return snd_djm_get_label_cap(wvalue); + case SND_DJM_WINDEX_PB: return snd_djm_get_label_pb(wvalue); + default: return NULL; + } +}; + + +// DJM-250MK2 +static const u16 snd_djm_opts_cap_level[] = { + 0x0000, 0x0100, 0x0200, 0x0300 }; + +static const u16 snd_djm_opts_250mk2_cap1[] = { + 0x0103, 0x0100, 0x0106, 0x0107, 0x0108, 0x0109, 0x010d, 0x010a }; + +static const u16 snd_djm_opts_250mk2_cap2[] = { + 0x0203, 0x0200, 0x0206, 0x0207, 0x0208, 0x0209, 0x020d, 0x020a }; + +static const u16 snd_djm_opts_250mk2_cap3[] = { + 0x030a, 0x0311, 0x0312, 0x0307, 0x0308, 0x0309, 0x030d }; + +static const u16 snd_djm_opts_250mk2_pb1[] = { 0x0100, 0x0101, 0x0104 }; +static const u16 snd_djm_opts_250mk2_pb2[] = { 0x0200, 0x0201, 0x0204 }; +static const u16 snd_djm_opts_250mk2_pb3[] = { 0x0300, 0x0301, 0x0304 }; + +static const struct snd_djm_ctl snd_djm_ctls_250mk2[] = { + SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL), + SND_DJM_CTL("Ch1 Input", 250mk2_cap1, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch2 Input", 250mk2_cap2, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch3 Input", 250mk2_cap3, 0, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch1 Output", 250mk2_pb1, 0, SND_DJM_WINDEX_PB), + SND_DJM_CTL("Ch2 Output", 250mk2_pb2, 1, SND_DJM_WINDEX_PB), + SND_DJM_CTL("Ch3 Output", 250mk2_pb3, 2, SND_DJM_WINDEX_PB) +}; + + +// DJM-750 +static const u16 snd_djm_opts_750_cap1[] = { + 0x0101, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a, 0x010f }; +static const u16 snd_djm_opts_750_cap2[] = { + 0x0200, 0x0201, 0x0206, 0x0207, 0x0208, 0x0209, 0x020a, 0x020f }; +static const u16 snd_djm_opts_750_cap3[] = { + 0x0300, 0x0301, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a, 0x030f }; +static const u16 snd_djm_opts_750_cap4[] = { + 0x0401, 0x0403, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040f }; + +static const struct snd_djm_ctl snd_djm_ctls_750[] = { + SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL), + SND_DJM_CTL("Ch1 Input", 750_cap1, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch2 Input", 750_cap2, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch3 Input", 750_cap3, 0, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch4 Input", 750_cap4, 0, SND_DJM_WINDEX_CAP) +}; + + +static const struct snd_djm_device snd_djm_devices[] = { + SND_DJM_DEVICE(250mk2), + SND_DJM_DEVICE(750) +}; + + +static int snd_djm_controls_info(struct snd_kcontrol *kctl, + struct snd_ctl_elem_info *info) +{ + unsigned long private_value = kctl->private_value; + u8 device_idx = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT; + u8 ctl_idx = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT; + const struct snd_djm_device *device = &snd_djm_devices[device_idx]; + const char *name; + const struct snd_djm_ctl *ctl; + size_t noptions; + + if (ctl_idx >= device->ncontrols) + return -EINVAL; + + ctl = &device->controls[ctl_idx]; + noptions = ctl->noptions; + if (info->value.enumerated.item >= noptions) + info->value.enumerated.item = noptions - 1; + + name = snd_djm_get_label(ctl->options[info->value.enumerated.item], + ctl->wIndex); + if (!name) return -EINVAL; - group = &snd_pioneer_djm_option_groups[group_index]; - count = group->count; - if (info->value.enumerated.item >= count) - info->value.enumerated.item = count - 1; - name = group->options[info->value.enumerated.item].name; strlcpy(info->value.enumerated.name, name, sizeof(info->value.enumerated.name)); info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; info->count = 1; - info->value.enumerated.items = count; + info->value.enumerated.items = noptions; return 0; } -static int snd_pioneer_djm_controls_update(struct usb_mixer_interface *mixer, u16 group, u16 value) +static int snd_djm_controls_update(struct usb_mixer_interface *mixer, + u8 device_idx, u8 group, u16 value) { int err; + const struct snd_djm_device *device = &snd_djm_devices[device_idx]; - if (group >= ARRAY_SIZE(snd_pioneer_djm_option_groups) - || value >= snd_pioneer_djm_option_groups[group].count) + if ((group >= device->ncontrols) || value >= device->controls[group].noptions) return -EINVAL; err = snd_usb_lock_shutdown(mixer->chip); @@ -2748,63 +2828,76 @@ static int snd_pioneer_djm_controls_update(struct usb_mixer_interface *mixer, u1 mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), USB_REQ_SET_FEATURE, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - snd_pioneer_djm_option_groups[group].options[value].wValue, - snd_pioneer_djm_option_groups[group].options[value].wIndex, + device->controls[group].options[value], + device->controls[group].wIndex, NULL, 0); snd_usb_unlock_shutdown(mixer->chip); return err; } -static int snd_pioneer_djm_controls_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *elem) +static int snd_djm_controls_get(struct snd_kcontrol *kctl, + struct snd_ctl_elem_value *elem) { - elem->value.enumerated.item[0] = kctl->private_value & SND_PIONEER_DJM_VALUE_MASK; + elem->value.enumerated.item[0] = kctl->private_value & SND_DJM_VALUE_MASK; return 0; } -static int snd_pioneer_djm_controls_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *elem) +static int snd_djm_controls_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *elem) { struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl); struct usb_mixer_interface *mixer = list->mixer; unsigned long private_value = kctl->private_value; - u16 group = (private_value & SND_PIONEER_DJM_GROUP_MASK) >> SND_PIONEER_DJM_GROUP_SHIFT; + + u8 device = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT; + u8 group = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT; u16 value = elem->value.enumerated.item[0]; - kctl->private_value = (group << SND_PIONEER_DJM_GROUP_SHIFT) | value; + kctl->private_value = ((device << SND_DJM_DEVICE_SHIFT) | + (group << SND_DJM_GROUP_SHIFT) | + value); - return snd_pioneer_djm_controls_update(mixer, group, value); + return snd_djm_controls_update(mixer, device, group, value); } -static int snd_pioneer_djm_controls_resume(struct usb_mixer_elem_list *list) +static int snd_djm_controls_resume(struct usb_mixer_elem_list *list) { unsigned long private_value = list->kctl->private_value; - u16 group = (private_value & SND_PIONEER_DJM_GROUP_MASK) >> SND_PIONEER_DJM_GROUP_SHIFT; - u16 value = (private_value & SND_PIONEER_DJM_VALUE_MASK); + u8 device = (private_value & SND_DJM_DEVICE_MASK) >> SND_DJM_DEVICE_SHIFT; + u8 group = (private_value & SND_DJM_GROUP_MASK) >> SND_DJM_GROUP_SHIFT; + u16 value = (private_value & SND_DJM_VALUE_MASK); - return snd_pioneer_djm_controls_update(list->mixer, group, value); + return snd_djm_controls_update(list->mixer, device, group, value); } -static int snd_pioneer_djm_controls_create(struct usb_mixer_interface *mixer) +static int snd_djm_controls_create(struct usb_mixer_interface *mixer, + const u8 device_idx) { int err, i; - const struct snd_pioneer_djm_option_group *group; + u16 value; + + const struct snd_djm_device *device = &snd_djm_devices[device_idx]; + struct snd_kcontrol_new knew = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, .index = 0, - .info = snd_pioneer_djm_controls_info, - .get = snd_pioneer_djm_controls_get, - .put = snd_pioneer_djm_controls_put + .info = snd_djm_controls_info, + .get = snd_djm_controls_get, + .put = snd_djm_controls_put }; - for (i = 0; i < ARRAY_SIZE(snd_pioneer_djm_option_groups); i++) { - group = &snd_pioneer_djm_option_groups[i]; - knew.name = group->name; - knew.private_value = (i << SND_PIONEER_DJM_GROUP_SHIFT) | group->default_value; - err = snd_pioneer_djm_controls_update(mixer, i, group->default_value); + for (i = 0; i < device->ncontrols; i++) { + value = device->controls[i].default_value; + knew.name = device->controls[i].name; + knew.private_value = ( + (device_idx << SND_DJM_DEVICE_SHIFT) | + (i << SND_DJM_GROUP_SHIFT) | + value); + err = snd_djm_controls_update(mixer, device_idx, i, value); if (err) return err; - err = add_single_ctl_with_resume(mixer, 0, snd_pioneer_djm_controls_resume, + err = add_single_ctl_with_resume(mixer, 0, snd_djm_controls_resume, &knew, NULL); if (err) return err; @@ -2917,7 +3010,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) err = snd_bbfpro_controls_create(mixer); break; case USB_ID(0x2b73, 0x0017): /* Pioneer DJ DJM-250MK2 */ - err = snd_pioneer_djm_controls_create(mixer); + err = snd_djm_controls_create(mixer, SND_DJM_250MK2_IDX); + break; + case USB_ID(0x08e4, 0x017f): /* Pioneer DJ DJM-750 */ + err = snd_djm_controls_create(mixer, SND_DJM_750_IDX); break; } From 015d38539db9121147682380111f7a460eb46df4 Mon Sep 17 00:00:00 2001 From: Fabian Lesniak Date: Fri, 5 Feb 2021 22:51:16 +0100 Subject: [PATCH 40/48] ALSA: usb-audio: add mixer quirks for Pioneer DJM-900NXS2 [ Upstream commit fee03efc69345344c8851596d74d93199b175bfe ] This commit adds mixer quirks for the Pioneer DJM-900NXS2 mixer. This device has 6 capture channels, 5 of them allow setting the signal source. This adds controls for these, similar to the DJM-250Mk2. However, playpack channels are not controllable via software like on the 250Mk2, as they can only be set manually on the mixing console. Read-only controls showing the currently selected playback channels are omitted. Signed-off-by: Fabian Lesniak Link: https://lore.kernel.org/r/20210205215116.258724-2-fabian@lesniak-it.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/mixer_quirks.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 788b75cb9447..448de77f43fd 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -2618,6 +2618,7 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer) // Capture types #define SND_DJM_CAP_LINE 0x00 #define SND_DJM_CAP_CDLINE 0x01 +#define SND_DJM_CAP_DIGITAL 0x02 #define SND_DJM_CAP_PHONO 0x03 #define SND_DJM_CAP_PFADER 0x06 #define SND_DJM_CAP_XFADERA 0x07 @@ -2628,6 +2629,8 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer) #define SND_DJM_CAP_NONE 0x0f #define SND_DJM_CAP_CH1PFADER 0x11 #define SND_DJM_CAP_CH2PFADER 0x12 +#define SND_DJM_CAP_CH3PFADER 0x13 +#define SND_DJM_CAP_CH4PFADER 0x14 // Playback types #define SND_DJM_PB_CH1 0x00 @@ -2648,6 +2651,7 @@ static int snd_bbfpro_controls_create(struct usb_mixer_interface *mixer) // device table index #define SND_DJM_250MK2_IDX 0x0 #define SND_DJM_750_IDX 0x1 +#define SND_DJM_900NXS2_IDX 0x2 #define SND_DJM_CTL(_name, suffix, _default_value, _windex) { \ @@ -2692,6 +2696,7 @@ static const char *snd_djm_get_label_cap(u16 wvalue) switch (wvalue & 0x00ff) { case SND_DJM_CAP_LINE: return "Control Tone LINE"; case SND_DJM_CAP_CDLINE: return "Control Tone CD/LINE"; + case SND_DJM_CAP_DIGITAL: return "Control Tone DIGITAL"; case SND_DJM_CAP_PHONO: return "Control Tone PHONO"; case SND_DJM_CAP_PFADER: return "Post Fader"; case SND_DJM_CAP_XFADERA: return "Cross Fader A"; @@ -2702,6 +2707,8 @@ static const char *snd_djm_get_label_cap(u16 wvalue) case SND_DJM_CAP_NONE: return "None"; case SND_DJM_CAP_CH1PFADER: return "Post Fader Ch1"; case SND_DJM_CAP_CH2PFADER: return "Post Fader Ch2"; + case SND_DJM_CAP_CH3PFADER: return "Post Fader Ch3"; + case SND_DJM_CAP_CH4PFADER: return "Post Fader Ch4"; default: return NULL; } }; @@ -2774,9 +2781,32 @@ static const struct snd_djm_ctl snd_djm_ctls_750[] = { }; +// DJM-900NXS2 +static const u16 snd_djm_opts_900nxs2_cap1[] = { + 0x0100, 0x0102, 0x0103, 0x0106, 0x0107, 0x0108, 0x0109, 0x010a }; +static const u16 snd_djm_opts_900nxs2_cap2[] = { + 0x0200, 0x0202, 0x0203, 0x0206, 0x0207, 0x0208, 0x0209, 0x020a }; +static const u16 snd_djm_opts_900nxs2_cap3[] = { + 0x0300, 0x0302, 0x0303, 0x0306, 0x0307, 0x0308, 0x0309, 0x030a }; +static const u16 snd_djm_opts_900nxs2_cap4[] = { + 0x0400, 0x0402, 0x0403, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a }; +static const u16 snd_djm_opts_900nxs2_cap5[] = { + 0x0507, 0x0508, 0x0509, 0x050a, 0x0511, 0x0512, 0x0513, 0x0514 }; + +static const struct snd_djm_ctl snd_djm_ctls_900nxs2[] = { + SND_DJM_CTL("Capture Level", cap_level, 0, SND_DJM_WINDEX_CAPLVL), + SND_DJM_CTL("Ch1 Input", 900nxs2_cap1, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch2 Input", 900nxs2_cap2, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch3 Input", 900nxs2_cap3, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch4 Input", 900nxs2_cap4, 2, SND_DJM_WINDEX_CAP), + SND_DJM_CTL("Ch5 Input", 900nxs2_cap5, 3, SND_DJM_WINDEX_CAP) +}; + + static const struct snd_djm_device snd_djm_devices[] = { SND_DJM_DEVICE(250mk2), - SND_DJM_DEVICE(750) + SND_DJM_DEVICE(750), + SND_DJM_DEVICE(900nxs2) }; @@ -3015,6 +3045,9 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) case USB_ID(0x08e4, 0x017f): /* Pioneer DJ DJM-750 */ err = snd_djm_controls_create(mixer, SND_DJM_750_IDX); break; + case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */ + err = snd_djm_controls_create(mixer, SND_DJM_900NXS2_IDX); + break; } return err; From 1d3efd15e8a43ce2ea91c040f77ef67a0b2b3bc5 Mon Sep 17 00:00:00 2001 From: Nadeem Athani Date: Tue, 9 Feb 2021 15:46:21 +0100 Subject: [PATCH 41/48] PCI: cadence: Retrain Link to work around Gen2 training defect [ Upstream commit 4740b969aaf58adeca6829947a3ad8da423976cf ] Cadence controller will not initiate autonomous speed change if strapped as Gen2. The Retrain Link bit is set as quirk to enable this speed change. Link: https://lore.kernel.org/r/20210209144622.26683-3-nadeem@cadence.com Signed-off-by: Nadeem Athani Signed-off-by: Lorenzo Pieralisi Signed-off-by: Sasha Levin --- drivers/pci/controller/cadence/pci-j721e.c | 3 + .../controller/cadence/pcie-cadence-host.c | 81 ++++++++++++++----- drivers/pci/controller/cadence/pcie-cadence.h | 11 ++- 3 files changed, 76 insertions(+), 19 deletions(-) diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c index 586b9d69fa5e..d34ca0fda0f6 100644 --- a/drivers/pci/controller/cadence/pci-j721e.c +++ b/drivers/pci/controller/cadence/pci-j721e.c @@ -63,6 +63,7 @@ enum j721e_pcie_mode { struct j721e_pcie_data { enum j721e_pcie_mode mode; + bool quirk_retrain_flag; }; static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset) @@ -270,6 +271,7 @@ static struct pci_ops cdns_ti_pcie_host_ops = { static const struct j721e_pcie_data j721e_pcie_rc_data = { .mode = PCI_MODE_RC, + .quirk_retrain_flag = true, }; static const struct j721e_pcie_data j721e_pcie_ep_data = { @@ -378,6 +380,7 @@ static int j721e_pcie_probe(struct platform_device *pdev) bridge->ops = &cdns_ti_pcie_host_ops; rc = pci_host_bridge_priv(bridge); + rc->quirk_retrain_flag = data->quirk_retrain_flag; cdns_pcie = &rc->pcie; cdns_pcie->dev = dev; diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c index 1cb7cfc75d6e..73dcf8cf98fb 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-host.c +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c @@ -77,6 +77,68 @@ static struct pci_ops cdns_pcie_host_ops = { .write = pci_generic_config_write, }; +static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie) +{ + struct device *dev = pcie->dev; + int retries; + + /* Check if the link is up or not */ + for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { + if (cdns_pcie_link_up(pcie)) { + dev_info(dev, "Link up\n"); + return 0; + } + usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); + } + + return -ETIMEDOUT; +} + +static int cdns_pcie_retrain(struct cdns_pcie *pcie) +{ + u32 lnk_cap_sls, pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET; + u16 lnk_stat, lnk_ctl; + int ret = 0; + + /* + * Set retrain bit if current speed is 2.5 GB/s, + * but the PCIe root port support is > 2.5 GB/s. + */ + + lnk_cap_sls = cdns_pcie_readl(pcie, (CDNS_PCIE_RP_BASE + pcie_cap_off + + PCI_EXP_LNKCAP)); + if ((lnk_cap_sls & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB) + return ret; + + lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA); + if ((lnk_stat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) { + lnk_ctl = cdns_pcie_rp_readw(pcie, + pcie_cap_off + PCI_EXP_LNKCTL); + lnk_ctl |= PCI_EXP_LNKCTL_RL; + cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL, + lnk_ctl); + + ret = cdns_pcie_host_wait_for_link(pcie); + } + return ret; +} + +static int cdns_pcie_host_start_link(struct cdns_pcie_rc *rc) +{ + struct cdns_pcie *pcie = &rc->pcie; + int ret; + + ret = cdns_pcie_host_wait_for_link(pcie); + + /* + * Retrain link for Gen2 training defect + * if quirk flag is set. + */ + if (!ret && rc->quirk_retrain_flag) + ret = cdns_pcie_retrain(pcie); + + return ret; +} static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc) { @@ -399,23 +461,6 @@ static int cdns_pcie_host_init(struct device *dev, return cdns_pcie_host_init_address_translation(rc); } -static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie) -{ - struct device *dev = pcie->dev; - int retries; - - /* Check if the link is up or not */ - for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { - if (cdns_pcie_link_up(pcie)) { - dev_info(dev, "Link up\n"); - return 0; - } - usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); - } - - return -ETIMEDOUT; -} - int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) { struct device *dev = rc->pcie.dev; @@ -458,7 +503,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) return ret; } - ret = cdns_pcie_host_wait_for_link(pcie); + ret = cdns_pcie_host_start_link(rc); if (ret) dev_dbg(dev, "PCIe link never came up\n"); diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h index feed1e3038f4..6705a5fedfbb 100644 --- a/drivers/pci/controller/cadence/pcie-cadence.h +++ b/drivers/pci/controller/cadence/pcie-cadence.h @@ -119,7 +119,7 @@ * Root Port Registers (PCI configuration space for the root port function) */ #define CDNS_PCIE_RP_BASE 0x00200000 - +#define CDNS_PCIE_RP_CAP_OFFSET 0xc0 /* * Address Translation Registers @@ -290,6 +290,7 @@ struct cdns_pcie { * @device_id: PCI device ID * @avail_ib_bar: Satus of RP_BAR0, RP_BAR1 and RP_NO_BAR if it's free or * available + * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2 */ struct cdns_pcie_rc { struct cdns_pcie pcie; @@ -298,6 +299,7 @@ struct cdns_pcie_rc { u32 vendor_id; u32 device_id; bool avail_ib_bar[CDNS_PCIE_RP_MAX_IB]; + bool quirk_retrain_flag; }; /** @@ -413,6 +415,13 @@ static inline void cdns_pcie_rp_writew(struct cdns_pcie *pcie, cdns_pcie_write_sz(addr, 0x2, value); } +static inline u16 cdns_pcie_rp_readw(struct cdns_pcie *pcie, u32 reg) +{ + void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg; + + return cdns_pcie_read_sz(addr, 0x2); +} + /* Endpoint Function register access */ static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn, u32 reg, u8 value) From c08344abc9714f7ea43f338a177031d5ec1bcde3 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:26 -0600 Subject: [PATCH 42/48] ASoC: Intel: sof_sdw: reorganize quirks by generation [ Upstream commit 3d09cf8d0d791a41a75123e135f604d59f4aa870 ] The quirk table is a mess, let's reorganize it by generation before making sure that the quirks are consistent for each generation. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210208233336.59449-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/sof_sdw.c | 73 +++++++++++++++++--------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index daca06dde99b..9e2e8f508ed4 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -48,37 +48,14 @@ static int sof_sdw_quirk_cb(const struct dmi_system_id *id) } static const struct dmi_system_id sof_sdw_quirk_table[] = { + /* CometLake devices */ { .callback = sof_sdw_quirk_cb, .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), }, - .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_RT711_JD_SRC_JD2 | - SOF_RT715_DAI_ID_FIX | - SOF_SDW_FOUR_SPK), - }, - { - .callback = sof_sdw_quirk_cb, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") - }, - .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_RT711_JD_SRC_JD2 | - SOF_RT715_DAI_ID_FIX), - }, - { - .callback = sof_sdw_quirk_cb, - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), - DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") - }, - .driver_data = (void *)(SOF_SDW_TGL_HDMI | - SOF_RT711_JD_SRC_JD2 | - SOF_RT715_DAI_ID_FIX | - SOF_SDW_FOUR_SPK), + .driver_data = (void *)SOF_SDW_PCH_DMIC, }, { .callback = sof_sdw_quirk_cb, @@ -109,7 +86,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { SOF_RT715_DAI_ID_FIX | SOF_SDW_FOUR_SPK), }, - { + { .callback = sof_sdw_quirk_cb, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), @@ -119,6 +96,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { SOF_RT715_DAI_ID_FIX | SOF_SDW_FOUR_SPK), }, + /* IceLake devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), + }, + .driver_data = (void *)SOF_SDW_PCH_DMIC, + }, + /* TigerLake devices */ { .callback = sof_sdw_quirk_cb, .matches = { @@ -134,18 +121,23 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { { .callback = sof_sdw_quirk_cb, .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Ice Lake Client"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A3E") }, - .driver_data = (void *)SOF_SDW_PCH_DMIC, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD2 | + SOF_RT715_DAI_ID_FIX), }, { .callback = sof_sdw_quirk_cb, .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "CometLake Client"), + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E") }, - .driver_data = (void *)SOF_SDW_PCH_DMIC, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD2 | + SOF_RT715_DAI_ID_FIX | + SOF_SDW_FOUR_SPK), }, { .callback = sof_sdw_quirk_cb, @@ -167,7 +159,18 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { SOF_SDW_PCH_DMIC | SOF_SDW_FOUR_SPK), }, - + /* TigerLake-SDCA devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A32") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_RT711_JD_SRC_JD2 | + SOF_RT715_DAI_ID_FIX | + SOF_SDW_FOUR_SPK), + }, {} }; From 2dba0f805416ef88c0fa4c3e4c5603aa4078e329 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Feb 2021 17:33:28 -0600 Subject: [PATCH 43/48] ASoC: Intel: sof_sdw: add quirk for HP Spectre x360 convertible [ Upstream commit d92e279dee56b4b65c1af21f972413f172a9734a ] This set of devices has SoundWire support along with DMICs. The DMI information was provided by users for 3 separate skus. BugLink: https://github.com/thesofproject/linux/issues/2700 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Kai Vehmanen Link: https://lore.kernel.org/r/20210208233336.59449-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sasha Levin --- sound/soc/intel/boards/sof_sdw.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 9e2e8f508ed4..1d7677376e74 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -159,6 +159,22 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { SOF_SDW_PCH_DMIC | SOF_SDW_FOUR_SPK), }, + { + /* + * this entry covers multiple HP SKUs. The family name + * does not seem robust enough, so we use a partial + * match that ignores the product name suffix + * (e.g. 15-eb1xxx, 14t-ea000 or 13-aw2xxx) + */ + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Spectre x360 Convertible"), + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_SDW_PCH_DMIC | + SOF_RT711_JD_SRC_JD2), + }, /* TigerLake-SDCA devices */ { .callback = sof_sdw_quirk_cb, From 1611c323df9f5ddfc1ed36c9deec6052da9d40df Mon Sep 17 00:00:00 2001 From: Avri Altman Date: Thu, 11 Feb 2021 12:46:38 +0200 Subject: [PATCH 44/48] scsi: ufs: Fix a duplicate dev quirk number [ Upstream commit 9599a1cf23330008d90b7c232efe95de7510ff29 ] Fixes: 2b2bfc8aa519 ("scsi: ufs: Introduce a quirk to allow only page-aligned sg entries") Link: https://lore.kernel.org/r/20210211104638.292499-1-avri.altman@wdc.com Reviewed-by: Bean Huo Signed-off-by: Avri Altman Signed-off-by: Martin K. Petersen Signed-off-by: Sasha Levin --- drivers/scsi/ufs/ufshcd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index a0bc118f9188..812aa348751e 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -553,7 +553,7 @@ enum ufshcd_quirks { /* * This quirk allows only sg entries aligned with page size. */ - UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE = 1 << 13, + UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE = 1 << 14, }; enum ufshcd_caps { From 3b659091587a39bc581e0cf2775b03d18ed97fa7 Mon Sep 17 00:00:00 2001 From: Babu Moger Date: Tue, 2 Mar 2021 12:51:31 -0600 Subject: [PATCH 45/48] KVM: SVM: Clear the CR4 register on reset [ Upstream commit 9e46f6c6c959d9bb45445c2e8f04a75324a0dfd0 ] This problem was reported on a SVM guest while executing kexec. Kexec fails to load the new kernel when the PCID feature is enabled. When kexec starts loading the new kernel, it starts the process by resetting the vCPU's and then bringing each vCPU online one by one. The vCPU reset is supposed to reset all the register states before the vCPUs are brought online. However, the CR4 register is not reset during this process. If this register is already setup during the last boot, all the flags can remain intact. The X86_CR4_PCIDE bit can only be enabled in long mode. So, it must be enabled much later in SMP initialization. Having the X86_CR4_PCIDE bit set during SMP boot can cause a boot failures. Fix the issue by resetting the CR4 register in init_vmcb(). Signed-off-by: Babu Moger Message-Id: <161471109108.30811.6392805173629704166.stgit@bmoger-ubuntu> Signed-off-by: Paolo Bonzini Signed-off-by: Sasha Levin --- arch/x86/kvm/svm/svm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 76ab1ee0784a..642f0da31ac4 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1192,6 +1192,7 @@ static void init_vmcb(struct vcpu_svm *svm) init_sys_seg(&save->ldtr, SEG_TYPE_LDT); init_sys_seg(&save->tr, SEG_TYPE_BUSY_TSS16); + svm_set_cr4(&svm->vcpu, 0); svm_set_efer(&svm->vcpu, 0); save->dr6 = 0xffff0ff0; kvm_set_rflags(&svm->vcpu, 2); From e88e01440a480d2d30d18657ab9a2e2f2e4c23a8 Mon Sep 17 00:00:00 2001 From: Julian Einwag Date: Tue, 16 Feb 2021 13:25:43 +0100 Subject: [PATCH 46/48] nvme-pci: mark Seagate Nytro XM1440 as QUIRK_NO_NS_DESC_LIST. [ Upstream commit 5e112d3fb89703a4981ded60561b5647db3693bf ] The kernel fails to fully detect these SSDs, only the character devices are present: [ 10.785605] nvme nvme0: pci function 0000:04:00.0 [ 10.876787] nvme nvme1: pci function 0000:81:00.0 [ 13.198614] nvme nvme0: missing or invalid SUBNQN field. [ 13.198658] nvme nvme1: missing or invalid SUBNQN field. [ 13.206896] nvme nvme0: Shutdown timeout set to 20 seconds [ 13.215035] nvme nvme1: Shutdown timeout set to 20 seconds [ 13.225407] nvme nvme0: 16/0/0 default/read/poll queues [ 13.233602] nvme nvme1: 16/0/0 default/read/poll queues [ 13.239627] nvme nvme0: Identify Descriptors failed (8194) [ 13.246315] nvme nvme1: Identify Descriptors failed (8194) Adding the NVME_QUIRK_NO_NS_DESC_LIST fixes this problem. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205679 Signed-off-by: Julian Einwag Signed-off-by: Christoph Hellwig Reviewed-by: Keith Busch Signed-off-by: Sasha Levin --- drivers/nvme/host/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 25ffa61b72cc..776b9591c709 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3235,7 +3235,8 @@ static const struct pci_device_id nvme_id_table[] = { { PCI_DEVICE(0x126f, 0x2263), /* Silicon Motion unidentified */ .driver_data = NVME_QUIRK_NO_NS_DESC_LIST, }, { PCI_DEVICE(0x1bb1, 0x0100), /* Seagate Nytro Flash Storage */ - .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, + .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY | + NVME_QUIRK_NO_NS_DESC_LIST, }, { PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */ .driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, }, { PCI_DEVICE(0x1c58, 0x0023), /* WDC SN200 adapter */ From c8714d1faae829ebb4139c73bcbc0d66fd7edbc9 Mon Sep 17 00:00:00 2001 From: Pascal Terjan Date: Tue, 23 Feb 2021 22:10:46 +0000 Subject: [PATCH 47/48] nvme-pci: add quirks for Lexar 256GB SSD [ Upstream commit 6e6a6828c517fb6819479bf5187df5f39084eb9e ] Add the NVME_QUIRK_NO_NS_DESC_LIST and NVME_QUIRK_IGNORE_DEV_SUBNQN quirks for this buggy device. Reported and tested in https://bugs.mageia.org/show_bug.cgi?id=28417 Signed-off-by: Pascal Terjan Signed-off-by: Christoph Hellwig Signed-off-by: Sasha Levin --- drivers/nvme/host/pci.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 776b9591c709..99c59f93a064 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3250,6 +3250,9 @@ static const struct pci_device_id nvme_id_table[] = { NVME_QUIRK_IGNORE_DEV_SUBNQN, }, { PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */ .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x1b4b, 0x1092), /* Lexar 256 GB SSD */ + .driver_data = NVME_QUIRK_NO_NS_DESC_LIST | + NVME_QUIRK_IGNORE_DEV_SUBNQN, }, { PCI_DEVICE(0x1d1d, 0x1f1f), /* LighNVM qemu device */ .driver_data = NVME_QUIRK_LIGHTNVM, }, { PCI_DEVICE(0x1d1d, 0x2807), /* CNEX WL */ From dfbf345b63c31518e269f7f0adf55bbf57017e23 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 11 Mar 2021 14:17:30 +0100 Subject: [PATCH 48/48] Linux 5.10.23 Tested-by: Hulk Robot Tested-by: Pavel Machek (CIP) Tested-by: Shuah Khan Tested-by: Guenter Roeck Tested-by: Jason Self Tested-by: Ross Schmidt Tested-by: Florian Fainelli Tested-by: Linux Kernel Functional Testing Tested-by: Jon Hunter Link: https://lore.kernel.org/r/20210310182834.696191666@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 12a2a7271fcb..7fdb78b48f55 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 VERSION = 5 PATCHLEVEL = 10 -SUBLEVEL = 22 +SUBLEVEL = 23 EXTRAVERSION = NAME = Dare mighty things