kernel/patch-6.14-redhat.patch
Justin M. Forbes db404242eb
kernel-6.14.0-200
* Mon Mar 24 2025 Justin M. Forbes <jforbes@fedoraproject.org> [6.14.0-1]
- Reset RHEL_RELEASE for 6.15 cycle (Justin M. Forbes)
Resolves:

Signed-off-by: Justin M. Forbes <jforbes@fedoraproject.org>
2025-04-03 16:29:58 -06:00

2886 lines
95 KiB
Diff

Documentation/ABI/testing/sysfs-kernel-fadump | 3 +-
.../arch/powerpc/firmware-assisted-dump.rst | 22 +++
Makefile | 40 +++++
arch/arm/Kconfig | 4 +-
arch/arm64/Kconfig | 2 +-
arch/powerpc/include/asm/prom.h | 2 +
arch/powerpc/kernel/fadump.c | 21 +--
arch/powerpc/kernel/module_64.c | 4 -
arch/powerpc/kernel/prom_init.c | 2 +-
arch/s390/include/asm/ipl.h | 1 +
arch/s390/kernel/ipl.c | 5 +
arch/s390/kernel/setup.c | 4 +
arch/x86/kernel/setup.c | 22 ++-
arch/x86/tools/insn_decoder_test.c | 2 +-
crypto/akcipher.c | 3 +-
crypto/dh.c | 25 +++
crypto/seqiv.c | 15 +-
crypto/sig.c | 3 +-
crypto/testmgr.c | 6 +-
drivers/acpi/apei/hest.c | 8 +
drivers/acpi/irq.c | 17 ++-
drivers/acpi/scan.c | 9 ++
drivers/ata/libahci.c | 18 +++
drivers/char/ipmi/ipmi_dmi.c | 15 ++
drivers/char/ipmi/ipmi_msghandler.c | 16 +-
drivers/counter/microchip-tcb-capture.c | 19 +++
drivers/counter/stm32-lptimer-cnt.c | 24 +--
drivers/firmware/efi/Makefile | 1 +
drivers/firmware/efi/efi.c | 124 +++++++++++----
drivers/firmware/efi/secureboot.c | 38 +++++
drivers/hid/hid-plantronics.c | 144 ++++++++---------
drivers/hid/hid-rmi.c | 66 --------
drivers/hwtracing/coresight/coresight-etm4x-core.c | 19 +++
drivers/input/rmi4/rmi_driver.c | 124 +++++++++------
drivers/iommu/iommu.c | 22 +++
drivers/media/i2c/ov08x40.c | 170 +++++++++++----------
drivers/memstick/host/rtsx_usb_ms.c | 1 +
drivers/misc/mei/vsc-tp.c | 26 ++--
drivers/net/usb/qmi_wwan.c | 2 +
drivers/net/usb/usbnet.c | 21 ++-
drivers/pci/quirks.c | 24 +++
drivers/scsi/sd.c | 10 ++
drivers/tty/serial/8250/8250_dma.c | 2 +-
drivers/tty/serial/8250/8250_pci.c | 46 ++++++
drivers/tty/serial/fsl_lpuart.c | 17 +++
drivers/tty/serial/stm32-usart.c | 4 +-
drivers/usb/core/hub.c | 7 +
drivers/usb/host/xhci-ring.c | 4 +
drivers/usb/host/xhci.h | 13 +-
include/linux/crypto.h | 2 +
include/linux/efi.h | 22 ++-
include/linux/lsm_hook_defs.h | 1 +
include/linux/rmi.h | 1 +
include/linux/security.h | 9 ++
kernel/cgroup/rstat.c | 29 ++--
kernel/module/signing.c | 9 +-
net/atm/mpc.c | 2 +
net/ipv6/netfilter/nf_socket_ipv6.c | 23 +++
scripts/Makefile.extrawarn | 4 +
scripts/tags.sh | 2 +
security/integrity/platform_certs/load_uefi.c | 6 +-
security/lockdown/Kconfig | 13 ++
security/lockdown/lockdown.c | 11 ++
sound/pci/hda/patch_realtek.c | 2 +
sound/usb/mixer_quirks.c | 51 +++++++
tools/perf/Documentation/intel-hybrid.txt | 12 +-
tools/perf/Documentation/perf-list.txt | 2 +-
tools/perf/arch/x86/util/iostat.c | 2 +-
tools/perf/builtin-stat.c | 2 +-
tools/perf/util/mem-events.c | 2 +-
tools/perf/util/pmu.c | 4 +-
71 files changed, 987 insertions(+), 421 deletions(-)
diff --git a/Documentation/ABI/testing/sysfs-kernel-fadump b/Documentation/ABI/testing/sysfs-kernel-fadump
index 2f9daa7ca55b..b64b7622e6fc 100644
--- a/Documentation/ABI/testing/sysfs-kernel-fadump
+++ b/Documentation/ABI/testing/sysfs-kernel-fadump
@@ -55,4 +55,5 @@ Date: May 2024
Contact: linuxppc-dev@lists.ozlabs.org
Description: read/write
This is a special sysfs file available to setup additional
- parameters to be passed to capture kernel.
+ parameters to be passed to capture kernel. For HASH MMU it
+ is exported only if RMA size higher than 768MB.
diff --git a/Documentation/arch/powerpc/firmware-assisted-dump.rst b/Documentation/arch/powerpc/firmware-assisted-dump.rst
index 7e37aadd1f77..7e266e749cd5 100644
--- a/Documentation/arch/powerpc/firmware-assisted-dump.rst
+++ b/Documentation/arch/powerpc/firmware-assisted-dump.rst
@@ -120,6 +120,28 @@ to ensure that crash data is preserved to process later.
e.g.
# echo 1 > /sys/firmware/opal/mpipl/release_core
+-- Support for Additional Kernel Arguments in Fadump
+ Fadump has a feature that allows passing additional kernel arguments
+ to the fadump kernel. This feature was primarily designed to disable
+ kernel functionalities that are not required for the fadump kernel
+ and to reduce its memory footprint while collecting the dump.
+
+ Command to Add Additional Kernel Parameters to Fadump:
+ e.g.
+ # echo "nr_cpus=16" > /sys/kernel/fadump/bootargs_append
+
+ The above command is sufficient to add additional arguments to fadump.
+ An explicit service restart is not required.
+
+ Command to Retrieve the Additional Fadump Arguments:
+ e.g.
+ # cat /sys/kernel/fadump/bootargs_append
+
+Note: Additional kernel arguments for fadump with HASH MMU is only
+ supported if the RMA size is greater than 768 MB. If the RMA
+ size is less than 768 MB, the kernel does not export the
+ /sys/kernel/fadump/bootargs_append sysfs node.
+
Implementation details:
-----------------------
diff --git a/Makefile b/Makefile
index 8b6764d44a61..c580d2af3d49 100644
--- a/Makefile
+++ b/Makefile
@@ -22,6 +22,18 @@ $(if $(filter __%, $(MAKECMDGOALS)), \
PHONY := __all
__all:
+# Set RHEL variables
+# Note that this ifdef'ery is required to handle when building with
+# the O= mechanism (relocate the object file results) due to upstream
+# commit 67d7c302 which broke our RHEL include file
+ifneq ($(realpath source),)
+include $(realpath source)/Makefile.rhelver
+else
+ifneq ($(realpath Makefile.rhelver),)
+include Makefile.rhelver
+endif
+endif
+
# We are using a recursive build, so we need to do a little thinking
# to get the ordering right.
#
@@ -358,6 +370,17 @@ ifneq ($(filter install,$(MAKECMDGOALS)),)
endif
endif
+# CKI/cross compilation hack
+# Do we need to rebuild scripts after cross compilation?
+# If kernel was cross-compiled, these scripts have arch of build host.
+REBUILD_SCRIPTS_FOR_CROSS:=0
+
+# Regenerating config with incomplete source tree will produce different
+# config options. Disable it.
+ifeq ($(REBUILD_SCRIPTS_FOR_CROSS),1)
+may-sync-config:=
+endif
+
ifdef mixed-build
# ===========================================================================
# We're called with mixed targets (*config and build targets).
@@ -1915,6 +1938,23 @@ endif
ifdef CONFIG_MODULES
+scripts_build:
+ $(MAKE) $(build)=scripts/basic
+ $(MAKE) $(build)=scripts/mod
+ $(MAKE) $(build)=scripts scripts/module.lds
+ $(MAKE) $(build)=scripts scripts/unifdef
+ $(MAKE) $(build)=scripts
+
+prepare_after_cross:
+ # disable STACK_VALIDATION to avoid building objtool
+ sed -i '/^CONFIG_STACK_VALIDATION/d' ./include/config/auto.conf || true
+ # build minimum set of scripts and resolve_btfids to allow building
+ # external modules
+ $(MAKE) KBUILD_EXTMOD="" M="" scripts_build V=1
+ $(MAKE) -C tools/bpf/resolve_btfids
+
+PHONY += prepare_after_cross scripts_build
+
modules.order: $(build-dir)
@:
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 835b5f100e92..179ad4af54a7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1231,9 +1231,9 @@ config HIGHMEM
If unsure, say n.
config HIGHPTE
- bool "Allocate 2nd-level pagetables from highmem" if EXPERT
+ bool "Allocate 2nd-level pagetables from highmem"
depends on HIGHMEM
- default y
+ default n
help
The VM uses one page of physical memory for each page table.
For systems with a lot of processes, this can use a lot of
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 940343beb3d4..003bf6492519 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1400,7 +1400,7 @@ endchoice
config ARM64_FORCE_52BIT
bool "Force 52-bit virtual addresses for userspace"
- depends on ARM64_VA_BITS_52 && EXPERT
+ depends on ARM64_VA_BITS_52
help
For systems with 52-bit userspace VAs enabled, the kernel will attempt
to maintain compatibility with older software by providing 48-bit VAs
diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
index c0107d8ddd8c..f679a11a7e7f 100644
--- a/arch/powerpc/include/asm/prom.h
+++ b/arch/powerpc/include/asm/prom.h
@@ -17,6 +17,8 @@
struct device_node;
struct property;
+#define MIN_RMA 768 /* Minimum RMA (in MB) for CAS negotiation */
+
#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
#define OF_DT_END_NODE 0x2 /* End node */
#define OF_DT_PROP 0x3 /* Property: name off, size,
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 4b371c738213..26e3d151e048 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -33,6 +33,7 @@
#include <asm/fadump-internal.h>
#include <asm/setup.h>
#include <asm/interrupt.h>
+#include <asm/prom.h>
/*
* The CPU who acquired the lock to trigger the fadump crash should
@@ -1764,19 +1765,19 @@ void __init fadump_setup_param_area(void)
range_end = memblock_end_of_DRAM();
} else {
/*
- * Passing additional parameters is supported for hash MMU only
- * if the first memory block size is 768MB or higher.
+ * Memory range for passing additional parameters for HASH MMU
+ * must meet the following conditions:
+ * 1. The first memory block size must be higher than the
+ * minimum RMA (MIN_RMA) size. Bootloader can use memory
+ * upto RMA size. So it should be avoided.
+ * 2. The range should be between MIN_RMA and RMA size (ppc64_rma_size)
+ * 3. It must not overlap with the fadump reserved area.
*/
- if (ppc64_rma_size < 0x30000000)
+ if (ppc64_rma_size < MIN_RMA*1024*1024)
return;
- /*
- * 640 MB to 768 MB is not used by PFW/bootloader. So, try reserving
- * memory for passing additional parameters in this range to avoid
- * being stomped on by PFW/bootloader.
- */
- range_start = 0x2A000000;
- range_end = range_start + 0x4000000;
+ range_start = MIN_RMA * 1024 * 1024;
+ range_end = min(ppc64_rma_size, fw_dump.boot_mem_top);
}
fw_dump.param_area = memblock_phys_alloc_range(COMMAND_LINE_SIZE,
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 34a5aec4908f..126bf3b06ab7 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -258,10 +258,6 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
break;
}
}
- if (i == hdr->e_shnum) {
- pr_err("%s: doesn't contain __patchable_function_entries.\n", me->name);
- return -ENOEXEC;
- }
#endif
pr_debug("Looks like a total of %lu stubs, max\n", relocs);
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 57082fac4668..fce32b162ef3 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1061,7 +1061,7 @@ static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = {
.virt_base = cpu_to_be32(0xffffffff),
.virt_size = cpu_to_be32(0xffffffff),
.load_base = cpu_to_be32(0xffffffff),
- .min_rma = cpu_to_be32(512), /* 512MB min RMA */
+ .min_rma = cpu_to_be32(MIN_RMA),
.min_load = cpu_to_be32(0xffffffff), /* full client load */
.min_rma_percent = 0, /* min RMA percentage of total RAM */
.max_pft_size = 48, /* max log_2(hash table size) */
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h
index b0d00032479d..afb9544fb007 100644
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -139,6 +139,7 @@ int ipl_report_add_component(struct ipl_report *report, struct kexec_buf *kbuf,
unsigned char flags, unsigned short cert);
int ipl_report_add_certificate(struct ipl_report *report, void *key,
unsigned long addr, unsigned long len);
+bool ipl_get_secureboot(void);
/*
* DIAG 308 support
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 69be2309cde0..1d85c99be81b 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -2497,3 +2497,8 @@ int ipl_report_free(struct ipl_report *report)
}
#endif
+
+bool ipl_get_secureboot(void)
+{
+ return !!ipl_secure_flag;
+}
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index d78bcfe707b5..f3a71214a211 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -49,6 +49,7 @@
#include <linux/memory.h>
#include <linux/compat.h>
#include <linux/start_kernel.h>
+#include <linux/security.h>
#include <linux/hugetlb.h>
#include <linux/kmemleak.h>
@@ -916,6 +917,9 @@ void __init setup_arch(char **cmdline_p)
log_component_list();
+ if (ipl_get_secureboot())
+ security_lock_kernel_down("Secure IPL mode", LOCKDOWN_INTEGRITY_MAX);
+
/* Have one command line that is parsed and saved in /proc/cmdline */
/* boot_command_line has been already set up in early.c */
*cmdline_p = boot_command_line;
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index cebee310e200..8d015c5faf59 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -21,6 +21,7 @@
#include <linux/root_dev.h>
#include <linux/hugetlb.h>
#include <linux/tboot.h>
+#include <linux/security.h>
#include <linux/usb/xhci-dbgp.h>
#include <linux/static_call.h>
#include <linux/swiotlb.h>
@@ -907,6 +908,13 @@ void __init setup_arch(char **cmdline_p)
if (efi_enabled(EFI_BOOT))
efi_init();
+ efi_set_secure_boot(boot_params.secure_boot);
+
+#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT
+ if (efi_enabled(EFI_SECURE_BOOT))
+ security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_INTEGRITY_MAX);
+#endif
+
reserve_ibft_region();
x86_init.resources.dmi_setup();
@@ -1073,19 +1081,7 @@ void __init setup_arch(char **cmdline_p)
/* Allocate bigger log buffer */
setup_log_buf(1);
- if (efi_enabled(EFI_BOOT)) {
- switch (boot_params.secure_boot) {
- case efi_secureboot_mode_disabled:
- pr_info("Secure boot disabled\n");
- break;
- case efi_secureboot_mode_enabled:
- pr_info("Secure boot enabled\n");
- break;
- default:
- pr_info("Secure boot could not be determined\n");
- break;
- }
- }
+ efi_set_secure_boot(boot_params.secure_boot);
reserve_initrd();
diff --git a/arch/x86/tools/insn_decoder_test.c b/arch/x86/tools/insn_decoder_test.c
index 472540aeabc2..366e07546344 100644
--- a/arch/x86/tools/insn_decoder_test.c
+++ b/arch/x86/tools/insn_decoder_test.c
@@ -106,7 +106,7 @@ static void parse_args(int argc, char **argv)
}
}
-#define BUFSIZE 256
+#define BUFSIZE 4096
int main(int argc, char **argv)
{
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
index 72c82d9aa077..da1ac5de8252 100644
--- a/crypto/akcipher.c
+++ b/crypto/akcipher.c
@@ -141,8 +141,7 @@ int crypto_register_akcipher(struct akcipher_alg *alg)
if (!alg->encrypt)
alg->encrypt = akcipher_default_op;
- if (!alg->decrypt)
- alg->decrypt = akcipher_default_op;
+ alg->decrypt = akcipher_default_op;
if (!alg->set_priv_key)
alg->set_priv_key = akcipher_default_set_key;
diff --git a/crypto/dh.c b/crypto/dh.c
index afc0fd847761..e13258c3d1d1 100644
--- a/crypto/dh.c
+++ b/crypto/dh.c
@@ -227,10 +227,35 @@ static int dh_compute_value(struct kpp_request *req)
/* SP800-56A rev 3 5.6.2.1.3 key check */
} else {
+ MPI val_pct;
+
if (dh_is_pubkey_valid(ctx, val)) {
ret = -EAGAIN;
goto err_free_val;
}
+
+ /*
+ * SP800-56Arev3, 5.6.2.1.4: ("Owner Assurance
+ * of Pair-wise Consistency"): recompute the
+ * public key and check if the results match.
+ */
+ val_pct = mpi_alloc(0);
+ if (!val_pct) {
+ ret = -ENOMEM;
+ goto err_free_val;
+ }
+
+ ret = _compute_val(ctx, base, val_pct);
+ if (ret) {
+ mpi_free(val_pct);
+ goto err_free_val;
+ }
+
+ if (mpi_cmp(val, val_pct) != 0) {
+ fips_fail_notify();
+ panic("dh: pair-wise consistency test failed\n");
+ }
+ mpi_free(val_pct);
}
}
diff --git a/crypto/seqiv.c b/crypto/seqiv.c
index 17e11d51ddc3..9c136a3b6267 100644
--- a/crypto/seqiv.c
+++ b/crypto/seqiv.c
@@ -132,6 +132,19 @@ static int seqiv_aead_decrypt(struct aead_request *req)
return crypto_aead_decrypt(subreq);
}
+static int aead_init_seqiv(struct crypto_aead *aead)
+{
+ int err;
+
+ err = aead_init_geniv(aead);
+ if (err)
+ return err;
+
+ crypto_aead_set_flags(aead, CRYPTO_TFM_FIPS_COMPLIANCE);
+
+ return 0;
+}
+
static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
{
struct aead_instance *inst;
@@ -149,7 +162,7 @@ static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.encrypt = seqiv_aead_encrypt;
inst->alg.decrypt = seqiv_aead_decrypt;
- inst->alg.init = aead_init_geniv;
+ inst->alg.init = aead_init_seqiv;
inst->alg.exit = aead_exit_geniv;
inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
diff --git a/crypto/sig.c b/crypto/sig.c
index dfc7cae90802..2a58d726149d 100644
--- a/crypto/sig.c
+++ b/crypto/sig.c
@@ -106,8 +106,7 @@ static int sig_prepare_alg(struct sig_alg *alg)
{
struct crypto_alg *base = &alg->base;
- if (!alg->sign)
- alg->sign = sig_default_sign;
+ alg->sign = sig_default_sign;
if (!alg->verify)
alg->verify = sig_default_verify;
if (!alg->set_priv_key)
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index e61490ba4095..d24a50804349 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -4189,7 +4189,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
* Don't invoke decrypt test which requires a private key
* for vectors with only a public key.
*/
- if (vecs->public_key_vec) {
+ if (1 || vecs->public_key_vec) {
err = 0;
goto free_all;
}
@@ -4325,7 +4325,7 @@ static int test_sig_one(struct crypto_sig *tfm, const struct sig_testvec *vecs)
* Don't invoke sign test (which requires a private key)
* for vectors with only a public key.
*/
- if (vecs->public_key_vec)
+ if (1 || vecs->public_key_vec)
return 0;
sig_size = crypto_sig_keysize(tfm);
@@ -5169,14 +5169,12 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "ecdh-nist-p256",
.test = alg_test_kpp,
- .fips_allowed = 1,
.suite = {
.kpp = __VECS(ecdh_p256_tv_template)
}
}, {
.alg = "ecdh-nist-p384",
.test = alg_test_kpp,
- .fips_allowed = 1,
.suite = {
.kpp = __VECS(ecdh_p384_tv_template)
}
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index 20d757687e3d..90a13f20f052 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -142,6 +142,14 @@ static int apei_hest_parse(apei_hest_func_t func, void *data)
if (hest_disable || !hest_tab)
return -EINVAL;
+#ifdef CONFIG_ARM64
+ /* Ignore broken firmware */
+ if (!strncmp(hest_tab->header.oem_id, "HPE ", 6) &&
+ !strncmp(hest_tab->header.oem_table_id, "ProLiant", 8) &&
+ MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM)
+ return -EINVAL;
+#endif
+
hest_hdr = (struct acpi_hest_header *)(hest_tab + 1);
for (i = 0; i < hest_tab->error_source_count; i++) {
len = hest_esrc_len(hest_hdr);
diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
index 1687483ff319..390b67f19181 100644
--- a/drivers/acpi/irq.c
+++ b/drivers/acpi/irq.c
@@ -143,6 +143,7 @@ struct acpi_irq_parse_one_ctx {
unsigned int index;
unsigned long *res_flags;
struct irq_fwspec *fwspec;
+ bool skip_producer_check;
};
/**
@@ -216,7 +217,8 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
return AE_CTRL_TERMINATE;
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
eirq = &ares->data.extended_irq;
- if (eirq->producer_consumer == ACPI_PRODUCER)
+ if (!ctx->skip_producer_check &&
+ eirq->producer_consumer == ACPI_PRODUCER)
return AE_OK;
if (ctx->index >= eirq->interrupt_count) {
ctx->index -= eirq->interrupt_count;
@@ -252,8 +254,19 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares,
static int acpi_irq_parse_one(acpi_handle handle, unsigned int index,
struct irq_fwspec *fwspec, unsigned long *flags)
{
- struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec };
+ struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec, false };
+ /*
+ * Firmware on arm64-based HPE m400 platform incorrectly marks
+ * its UART interrupt as ACPI_PRODUCER rather than ACPI_CONSUMER.
+ * Don't do the producer/consumer check for that device.
+ */
+ if (IS_ENABLED(CONFIG_ARM64)) {
+ struct acpi_device *adev = acpi_get_acpi_dev(handle);
+
+ if (adev && !strcmp(acpi_device_hid(adev), "APMC0D08"))
+ ctx.skip_producer_check = true;
+ }
acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_irq_parse_one_cb, &ctx);
return ctx.rc;
}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 9f4efa8f75a6..b7d9f1e31c8f 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1801,6 +1801,15 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
if (!acpi_match_device_ids(device, ignore_serial_bus_ids))
return false;
+ /*
+ * Firmware on some arm64 X-Gene platforms will make the UART
+ * device appear as both a UART and a slave of that UART. Just
+ * bail out here for X-Gene UARTs.
+ */
+ if (IS_ENABLED(CONFIG_ARM64) &&
+ !strcmp(acpi_device_hid(device), "APMC0D08"))
+ return false;
+
INIT_LIST_HEAD(&resource_list);
acpi_dev_get_resources(device, &resource_list,
acpi_check_serial_bus_slave,
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index e7ace4b10f15..fbb2bbfd026d 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -730,6 +730,24 @@ int ahci_stop_engine(struct ata_port *ap)
tmp &= ~PORT_CMD_START;
writel(tmp, port_mmio + PORT_CMD);
+#ifdef CONFIG_ARM64
+ /* Rev Ax of Cavium CN99XX needs a hack for port stop */
+ if (dev_is_pci(ap->host->dev) &&
+ to_pci_dev(ap->host->dev)->vendor == 0x14e4 &&
+ to_pci_dev(ap->host->dev)->device == 0x9027 &&
+ midr_is_cpu_model_range(read_cpuid_id(),
+ MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN),
+ MIDR_CPU_VAR_REV(0, 0),
+ MIDR_CPU_VAR_REV(0, MIDR_REVISION_MASK))) {
+ tmp = readl(hpriv->mmio + 0x8000);
+ udelay(100);
+ writel(tmp | (1 << 26), hpriv->mmio + 0x8000);
+ udelay(100);
+ writel(tmp & ~(1 << 26), hpriv->mmio + 0x8000);
+ dev_warn(ap->host->dev, "CN99XX SATA reset workaround applied\n");
+ }
+#endif
+
/* wait for engine to stop. This could be as long as 500 msec */
tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
diff --git a/drivers/char/ipmi/ipmi_dmi.c b/drivers/char/ipmi/ipmi_dmi.c
index bbf7029e224b..cf7faa970dd6 100644
--- a/drivers/char/ipmi/ipmi_dmi.c
+++ b/drivers/char/ipmi/ipmi_dmi.c
@@ -215,6 +215,21 @@ static int __init scan_for_dmi_ipmi(void)
{
const struct dmi_device *dev = NULL;
+#ifdef CONFIG_ARM64
+ /* RHEL-only
+ * If this is ARM-based HPE m400, return now, because that platform
+ * reports the host-side ipmi address as intel port-io space, which
+ * does not exist in the ARM architecture.
+ */
+ const char *dmistr = dmi_get_system_info(DMI_PRODUCT_NAME);
+
+ if (dmistr && (strcmp("ProLiant m400 Server", dmistr) == 0)) {
+ pr_debug("%s does not support host ipmi\n", dmistr);
+ return 0;
+ }
+ /* END RHEL-only */
+#endif
+
while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev)))
dmi_decode_ipmi((const struct dmi_header *) dev->device_data);
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 1e5313748f8b..f2a56c624f54 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -35,6 +35,7 @@
#include <linux/uuid.h>
#include <linux/nospec.h>
#include <linux/vmalloc.h>
+#include <linux/dmi.h>
#include <linux/delay.h>
#define IPMI_DRIVER_VERSION "39.2"
@@ -5508,8 +5509,21 @@ static int __init ipmi_init_msghandler_mod(void)
{
int rv;
- pr_info("version " IPMI_DRIVER_VERSION "\n");
+#ifdef CONFIG_ARM64
+ /* RHEL-only
+ * If this is ARM-based HPE m400, return now, because that platform
+ * reports the host-side ipmi address as intel port-io space, which
+ * does not exist in the ARM architecture.
+ */
+ const char *dmistr = dmi_get_system_info(DMI_PRODUCT_NAME);
+ if (dmistr && (strcmp("ProLiant m400 Server", dmistr) == 0)) {
+ pr_debug("%s does not support host ipmi\n", dmistr);
+ return -ENOSYS;
+ }
+ /* END RHEL-only */
+#endif
+ pr_info("version " IPMI_DRIVER_VERSION "\n");
mutex_lock(&ipmi_interfaces_mutex);
rv = ipmi_register_driver();
mutex_unlock(&ipmi_interfaces_mutex);
diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
index 2f096a5b973d..c391ac38b990 100644
--- a/drivers/counter/microchip-tcb-capture.c
+++ b/drivers/counter/microchip-tcb-capture.c
@@ -368,6 +368,25 @@ static int mchp_tc_probe(struct platform_device *pdev)
channel);
}
+ /* Disable Quadrature Decoder and position measure */
+ ret = regmap_update_bits(regmap, ATMEL_TC_BMR, ATMEL_TC_QDEN | ATMEL_TC_POSEN, 0);
+ if (ret)
+ return ret;
+
+ /* Setup the period capture mode */
+ ret = regmap_update_bits(regmap, ATMEL_TC_REG(priv->channel[0], CMR),
+ ATMEL_TC_WAVE | ATMEL_TC_ABETRG | ATMEL_TC_CMR_MASK |
+ ATMEL_TC_TCCLKS,
+ ATMEL_TC_CMR_MASK);
+ if (ret)
+ return ret;
+
+ /* Enable clock and trigger counter */
+ ret = regmap_write(regmap, ATMEL_TC_REG(priv->channel[0], CCR),
+ ATMEL_TC_CLKEN | ATMEL_TC_SWTRG);
+ if (ret)
+ return ret;
+
priv->tc_cfg = tcb_config;
priv->regmap = regmap;
counter->name = dev_name(&pdev->dev);
diff --git a/drivers/counter/stm32-lptimer-cnt.c b/drivers/counter/stm32-lptimer-cnt.c
index cf73f65baf60..b249c8647639 100644
--- a/drivers/counter/stm32-lptimer-cnt.c
+++ b/drivers/counter/stm32-lptimer-cnt.c
@@ -58,37 +58,43 @@ static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv,
return 0;
}
+ ret = clk_enable(priv->clk);
+ if (ret)
+ goto disable_cnt;
+
/* LP timer must be enabled before writing CMP & ARR */
ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->ceiling);
if (ret)
- return ret;
+ goto disable_clk;
ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, 0);
if (ret)
- return ret;
+ goto disable_clk;
/* ensure CMP & ARR registers are properly written */
ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
(val & STM32_LPTIM_CMPOK_ARROK) == STM32_LPTIM_CMPOK_ARROK,
100, 1000);
if (ret)
- return ret;
+ goto disable_clk;
ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
STM32_LPTIM_CMPOKCF_ARROKCF);
if (ret)
- return ret;
+ goto disable_clk;
- ret = clk_enable(priv->clk);
- if (ret) {
- regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
- return ret;
- }
priv->enabled = true;
/* Start LP timer in continuous mode */
return regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
STM32_LPTIM_CNTSTRT, STM32_LPTIM_CNTSTRT);
+
+disable_clk:
+ clk_disable(priv->clk);
+disable_cnt:
+ regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
+
+ return ret;
}
static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index a2d0009560d0..4f3486e6a84b 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -25,6 +25,7 @@ subdir-$(CONFIG_EFI_STUB) += libstub
obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o
obj-$(CONFIG_EFI_TEST) += test/
obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o
+obj-$(CONFIG_EFI) += secureboot.o
obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o
obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o
obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 7309394b8fc9..d9f7cbba5769 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -33,6 +33,7 @@
#include <linux/memblock.h>
#include <linux/security.h>
#include <linux/notifier.h>
+#include <linux/bsearch.h>
#include <asm/early_ioremap.h>
@@ -1007,40 +1008,101 @@ int efi_mem_type(unsigned long phys_addr)
return -EINVAL;
}
+struct efi_error_code {
+ efi_status_t status;
+ int errno;
+ const char *description;
+};
+
+static const struct efi_error_code efi_error_codes[] = {
+ { EFI_SUCCESS, 0, "Success"},
+#if 0
+ { EFI_LOAD_ERROR, -EPICK_AN_ERRNO, "Load Error"},
+#endif
+ { EFI_INVALID_PARAMETER, -EINVAL, "Invalid Parameter"},
+ { EFI_UNSUPPORTED, -ENOSYS, "Unsupported"},
+ { EFI_BAD_BUFFER_SIZE, -ENOSPC, "Bad Buffer Size"},
+ { EFI_BUFFER_TOO_SMALL, -ENOSPC, "Buffer Too Small"},
+ { EFI_NOT_READY, -EAGAIN, "Not Ready"},
+ { EFI_DEVICE_ERROR, -EIO, "Device Error"},
+ { EFI_WRITE_PROTECTED, -EROFS, "Write Protected"},
+ { EFI_OUT_OF_RESOURCES, -ENOMEM, "Out of Resources"},
+#if 0
+ { EFI_VOLUME_CORRUPTED, -EPICK_AN_ERRNO, "Volume Corrupt"},
+ { EFI_VOLUME_FULL, -EPICK_AN_ERRNO, "Volume Full"},
+ { EFI_NO_MEDIA, -EPICK_AN_ERRNO, "No Media"},
+ { EFI_MEDIA_CHANGED, -EPICK_AN_ERRNO, "Media changed"},
+#endif
+ { EFI_NOT_FOUND, -ENOENT, "Not Found"},
+#if 0
+ { EFI_ACCESS_DENIED, -EPICK_AN_ERRNO, "Access Denied"},
+ { EFI_NO_RESPONSE, -EPICK_AN_ERRNO, "No Response"},
+ { EFI_NO_MAPPING, -EPICK_AN_ERRNO, "No mapping"},
+ { EFI_TIMEOUT, -EPICK_AN_ERRNO, "Time out"},
+ { EFI_NOT_STARTED, -EPICK_AN_ERRNO, "Not started"},
+ { EFI_ALREADY_STARTED, -EPICK_AN_ERRNO, "Already started"},
+#endif
+ { EFI_ABORTED, -EINTR, "Aborted"},
+#if 0
+ { EFI_ICMP_ERROR, -EPICK_AN_ERRNO, "ICMP Error"},
+ { EFI_TFTP_ERROR, -EPICK_AN_ERRNO, "TFTP Error"},
+ { EFI_PROTOCOL_ERROR, -EPICK_AN_ERRNO, "Protocol Error"},
+ { EFI_INCOMPATIBLE_VERSION, -EPICK_AN_ERRNO, "Incompatible Version"},
+#endif
+ { EFI_SECURITY_VIOLATION, -EACCES, "Security Policy Violation"},
+#if 0
+ { EFI_CRC_ERROR, -EPICK_AN_ERRNO, "CRC Error"},
+ { EFI_END_OF_MEDIA, -EPICK_AN_ERRNO, "End of Media"},
+ { EFI_END_OF_FILE, -EPICK_AN_ERRNO, "End of File"},
+ { EFI_INVALID_LANGUAGE, -EPICK_AN_ERRNO, "Invalid Languages"},
+ { EFI_COMPROMISED_DATA, -EPICK_AN_ERRNO, "Compromised Data"},
+
+ // warnings
+ { EFI_WARN_UNKOWN_GLYPH, -EPICK_AN_ERRNO, "Warning Unknown Glyph"},
+ { EFI_WARN_DELETE_FAILURE, -EPICK_AN_ERRNO, "Warning Delete Failure"},
+ { EFI_WARN_WRITE_FAILURE, -EPICK_AN_ERRNO, "Warning Write Failure"},
+ { EFI_WARN_BUFFER_TOO_SMALL, -EPICK_AN_ERRNO, "Warning Buffer Too Small"},
+#endif
+};
+
+static int
+efi_status_cmp_bsearch(const void *key, const void *item)
+{
+ u64 status = (u64)(uintptr_t)key;
+ struct efi_error_code *code = (struct efi_error_code *)item;
+
+ if (status < code->status)
+ return -1;
+ if (status > code->status)
+ return 1;
+ return 0;
+}
+
int efi_status_to_err(efi_status_t status)
{
- int err;
-
- switch (status) {
- case EFI_SUCCESS:
- err = 0;
- break;
- case EFI_INVALID_PARAMETER:
- err = -EINVAL;
- break;
- case EFI_OUT_OF_RESOURCES:
- err = -ENOSPC;
- break;
- case EFI_DEVICE_ERROR:
- err = -EIO;
- break;
- case EFI_WRITE_PROTECTED:
- err = -EROFS;
- break;
- case EFI_SECURITY_VIOLATION:
- err = -EACCES;
- break;
- case EFI_NOT_FOUND:
- err = -ENOENT;
- break;
- case EFI_ABORTED:
- err = -EINTR;
- break;
- default:
- err = -EINVAL;
- }
+ struct efi_error_code *found;
+ size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code);
- return err;
+ found = bsearch((void *)(uintptr_t)status, efi_error_codes,
+ sizeof(struct efi_error_code), num,
+ efi_status_cmp_bsearch);
+ if (!found)
+ return -EINVAL;
+ return found->errno;
+}
+
+const char *
+efi_status_to_str(efi_status_t status)
+{
+ struct efi_error_code *found;
+ size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code);
+
+ found = bsearch((void *)(uintptr_t)status, efi_error_codes,
+ sizeof(struct efi_error_code), num,
+ efi_status_cmp_bsearch);
+ if (!found)
+ return "Unknown error code";
+ return found->description;
}
EXPORT_SYMBOL_GPL(efi_status_to_err);
diff --git a/drivers/firmware/efi/secureboot.c b/drivers/firmware/efi/secureboot.c
new file mode 100644
index 000000000000..de0a3714a5d4
--- /dev/null
+++ b/drivers/firmware/efi/secureboot.c
@@ -0,0 +1,38 @@
+/* Core kernel secure boot support.
+ *
+ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/efi.h>
+#include <linux/kernel.h>
+#include <linux/printk.h>
+
+/*
+ * Decide what to do when UEFI secure boot mode is enabled.
+ */
+void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
+{
+ if (efi_enabled(EFI_BOOT)) {
+ switch (mode) {
+ case efi_secureboot_mode_disabled:
+ pr_info("Secure boot disabled\n");
+ break;
+ case efi_secureboot_mode_enabled:
+ set_bit(EFI_SECURE_BOOT, &efi.flags);
+ pr_info("Secure boot enabled\n");
+ break;
+ default:
+ pr_warn("Secure boot could not be determined (mode %u)\n",
+ mode);
+ break;
+ }
+ }
+}
diff --git a/drivers/hid/hid-plantronics.c b/drivers/hid/hid-plantronics.c
index 25cfd964dc25..acb9eb18f7cc 100644
--- a/drivers/hid/hid-plantronics.c
+++ b/drivers/hid/hid-plantronics.c
@@ -6,9 +6,6 @@
* Copyright (c) 2015-2018 Terry Junge <terry.junge@plantronics.com>
*/
-/*
- */
-
#include "hid-ids.h"
#include <linux/hid.h>
@@ -23,30 +20,28 @@
#define PLT_VOL_UP 0x00b1
#define PLT_VOL_DOWN 0x00b2
+#define PLT_MIC_MUTE 0x00b5
#define PLT1_VOL_UP (PLT_HID_1_0_PAGE | PLT_VOL_UP)
#define PLT1_VOL_DOWN (PLT_HID_1_0_PAGE | PLT_VOL_DOWN)
+#define PLT1_MIC_MUTE (PLT_HID_1_0_PAGE | PLT_MIC_MUTE)
#define PLT2_VOL_UP (PLT_HID_2_0_PAGE | PLT_VOL_UP)
#define PLT2_VOL_DOWN (PLT_HID_2_0_PAGE | PLT_VOL_DOWN)
+#define PLT2_MIC_MUTE (PLT_HID_2_0_PAGE | PLT_MIC_MUTE)
+#define HID_TELEPHONY_MUTE (HID_UP_TELEPHONY | 0x2f)
+#define HID_CONSUMER_MUTE (HID_UP_CONSUMER | 0xe2)
#define PLT_DA60 0xda60
#define PLT_BT300_MIN 0x0413
#define PLT_BT300_MAX 0x0418
-
-#define PLT_ALLOW_CONSUMER (field->application == HID_CP_CONSUMERCONTROL && \
- (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
-
-#define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0)
-#define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1)
-
#define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */
-#define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */
struct plt_drv_data {
unsigned long device_type;
- unsigned long last_volume_key_ts;
- u32 quirks;
+ unsigned long last_key_ts;
+ unsigned long double_key_to;
+ __u16 last_key;
};
static int plantronics_input_mapping(struct hid_device *hdev,
@@ -58,34 +53,43 @@ static int plantronics_input_mapping(struct hid_device *hdev,
unsigned short mapped_key;
struct plt_drv_data *drv_data = hid_get_drvdata(hdev);
unsigned long plt_type = drv_data->device_type;
+ int allow_mute = usage->hid == HID_TELEPHONY_MUTE;
+ int allow_consumer = field->application == HID_CP_CONSUMERCONTROL &&
+ (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER &&
+ usage->hid != HID_CONSUMER_MUTE;
/* special case for PTT products */
if (field->application == HID_GD_JOYSTICK)
goto defaulted;
- /* handle volume up/down mapping */
/* non-standard types or multi-HID interfaces - plt_type is PID */
if (!(plt_type & HID_USAGE_PAGE)) {
switch (plt_type) {
case PLT_DA60:
- if (PLT_ALLOW_CONSUMER)
+ if (allow_consumer)
goto defaulted;
- goto ignored;
+ if (usage->hid == HID_CONSUMER_MUTE) {
+ mapped_key = KEY_MICMUTE;
+ goto mapped;
+ }
+ break;
default:
- if (PLT_ALLOW_CONSUMER)
+ if (allow_consumer || allow_mute)
goto defaulted;
}
+ goto ignored;
}
- /* handle standard types - plt_type is 0xffa0uuuu or 0xffa2uuuu */
- /* 'basic telephony compliant' - allow default consumer page map */
- else if ((plt_type & HID_USAGE) >= PLT_BASIC_TELEPHONY &&
- (plt_type & HID_USAGE) != PLT_BASIC_EXCEPTION) {
- if (PLT_ALLOW_CONSUMER)
- goto defaulted;
- }
- /* not 'basic telephony' - apply legacy mapping */
- /* only map if the field is in the device's primary vendor page */
- else if (!((field->application ^ plt_type) & HID_USAGE_PAGE)) {
+
+ /* handle standard consumer control mapping */
+ /* and standard telephony mic mute mapping */
+ if (allow_consumer || allow_mute)
+ goto defaulted;
+
+ /* handle vendor unique types - plt_type is 0xffa0uuuu or 0xffa2uuuu */
+ /* if not 'basic telephony compliant' - map vendor unique controls */
+ if (!((plt_type & HID_USAGE) >= PLT_BASIC_TELEPHONY &&
+ (plt_type & HID_USAGE) != PLT_BASIC_EXCEPTION) &&
+ !((field->application ^ plt_type) & HID_USAGE_PAGE))
switch (usage->hid) {
case PLT1_VOL_UP:
case PLT2_VOL_UP:
@@ -95,8 +99,11 @@ static int plantronics_input_mapping(struct hid_device *hdev,
case PLT2_VOL_DOWN:
mapped_key = KEY_VOLUMEDOWN;
goto mapped;
+ case PLT1_MIC_MUTE:
+ case PLT2_MIC_MUTE:
+ mapped_key = KEY_MICMUTE;
+ goto mapped;
}
- }
/*
* Future mapping of call control or other usages,
@@ -105,6 +112,8 @@ static int plantronics_input_mapping(struct hid_device *hdev,
*/
ignored:
+ hid_dbg(hdev, "usage: %08x (appl: %08x) - ignored\n",
+ usage->hid, field->application);
return -1;
defaulted:
@@ -123,38 +132,26 @@ static int plantronics_event(struct hid_device *hdev, struct hid_field *field,
struct hid_usage *usage, __s32 value)
{
struct plt_drv_data *drv_data = hid_get_drvdata(hdev);
+ unsigned long prev_tsto, cur_ts;
+ __u16 prev_key, cur_key;
- if (drv_data->quirks & PLT_QUIRK_DOUBLE_VOLUME_KEYS) {
- unsigned long prev_ts, cur_ts;
+ /* Usages are filtered in plantronics_usages. */
- /* Usages are filtered in plantronics_usages. */
+ /* HZ too low for ms resolution - double key detection disabled */
+ /* or it is a key release - handle key presses only. */
+ if (!drv_data->double_key_to || !value)
+ return 0;
- if (!value) /* Handle key presses only. */
- return 0;
+ prev_tsto = drv_data->last_key_ts + drv_data->double_key_to;
+ cur_ts = drv_data->last_key_ts = jiffies;
+ prev_key = drv_data->last_key;
+ cur_key = drv_data->last_key = usage->code;
- prev_ts = drv_data->last_volume_key_ts;
- cur_ts = jiffies;
- if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_DOUBLE_KEY_TIMEOUT)
- return 1; /* Ignore the repeated key. */
-
- drv_data->last_volume_key_ts = cur_ts;
+ /* If the same key occurs in <= double_key_to -- ignore it */
+ if (prev_key == cur_key && time_before_eq(cur_ts, prev_tsto)) {
+ hid_dbg(hdev, "double key %d ignored\n", cur_key);
+ return 1; /* Ignore the repeated key. */
}
- if (drv_data->quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS) {
- unsigned long prev_ts, cur_ts;
-
- /* Usages are filtered in plantronics_usages. */
-
- if (!value) /* Handle key presses only. */
- return 0;
-
- prev_ts = drv_data->last_volume_key_ts;
- cur_ts = jiffies;
- if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT)
- return 1; /* Ignore the followed opposite volume key. */
-
- drv_data->last_volume_key_ts = cur_ts;
- }
-
return 0;
}
@@ -196,12 +193,16 @@ static int plantronics_probe(struct hid_device *hdev,
ret = hid_parse(hdev);
if (ret) {
hid_err(hdev, "parse failed\n");
- goto err;
+ return ret;
}
drv_data->device_type = plantronics_device_type(hdev);
- drv_data->quirks = id->driver_data;
- drv_data->last_volume_key_ts = jiffies - msecs_to_jiffies(PLT_DOUBLE_KEY_TIMEOUT);
+ drv_data->double_key_to = msecs_to_jiffies(PLT_DOUBLE_KEY_TIMEOUT);
+ drv_data->last_key_ts = jiffies - drv_data->double_key_to;
+
+ /* if HZ does not allow ms resolution - disable double key detection */
+ if (drv_data->double_key_to < PLT_DOUBLE_KEY_TIMEOUT)
+ drv_data->double_key_to = 0;
hid_set_drvdata(hdev, drv_data);
@@ -210,29 +211,10 @@ static int plantronics_probe(struct hid_device *hdev,
if (ret)
hid_err(hdev, "hw start failed\n");
-err:
return ret;
}
static const struct hid_device_id plantronics_devices[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES),
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES),
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES),
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
- .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
- USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES),
- .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
- { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
- USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES),
- .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
{ }
};
@@ -241,6 +223,14 @@ MODULE_DEVICE_TABLE(hid, plantronics_devices);
static const struct hid_usage_id plantronics_usages[] = {
{ HID_CP_VOLUMEUP, EV_KEY, HID_ANY_ID },
{ HID_CP_VOLUMEDOWN, EV_KEY, HID_ANY_ID },
+ { HID_TELEPHONY_MUTE, EV_KEY, HID_ANY_ID },
+ { HID_CONSUMER_MUTE, EV_KEY, HID_ANY_ID },
+ { PLT2_VOL_UP, EV_KEY, HID_ANY_ID },
+ { PLT2_VOL_DOWN, EV_KEY, HID_ANY_ID },
+ { PLT2_MIC_MUTE, EV_KEY, HID_ANY_ID },
+ { PLT1_VOL_UP, EV_KEY, HID_ANY_ID },
+ { PLT1_VOL_DOWN, EV_KEY, HID_ANY_ID },
+ { PLT1_MIC_MUTE, EV_KEY, HID_ANY_ID },
{ HID_TERMINATOR, HID_TERMINATOR, HID_TERMINATOR }
};
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
index d4af17fdba46..154f0403cbf4 100644
--- a/drivers/hid/hid-rmi.c
+++ b/drivers/hid/hid-rmi.c
@@ -321,21 +321,12 @@ static int rmi_input_event(struct hid_device *hdev, u8 *data, int size)
{
struct rmi_data *hdata = hid_get_drvdata(hdev);
struct rmi_device *rmi_dev = hdata->xport.rmi_dev;
- unsigned long flags;
if (!(test_bit(RMI_STARTED, &hdata->flags)))
return 0;
- pm_wakeup_event(hdev->dev.parent, 0);
-
- local_irq_save(flags);
-
rmi_set_attn_data(rmi_dev, data[1], &data[2], size - 2);
- generic_handle_irq(hdata->rmi_irq);
-
- local_irq_restore(flags);
-
return 1;
}
@@ -589,56 +580,6 @@ static const struct rmi_transport_ops hid_rmi_ops = {
.reset = rmi_hid_reset,
};
-static void rmi_irq_teardown(void *data)
-{
- struct rmi_data *hdata = data;
- struct irq_domain *domain = hdata->domain;
-
- if (!domain)
- return;
-
- irq_dispose_mapping(irq_find_mapping(domain, 0));
-
- irq_domain_remove(domain);
- hdata->domain = NULL;
- hdata->rmi_irq = 0;
-}
-
-static int rmi_irq_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw_irq_num)
-{
- irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_simple_irq);
-
- return 0;
-}
-
-static const struct irq_domain_ops rmi_irq_ops = {
- .map = rmi_irq_map,
-};
-
-static int rmi_setup_irq_domain(struct hid_device *hdev)
-{
- struct rmi_data *hdata = hid_get_drvdata(hdev);
- int ret;
-
- hdata->domain = irq_domain_create_linear(hdev->dev.fwnode, 1,
- &rmi_irq_ops, hdata);
- if (!hdata->domain)
- return -ENOMEM;
-
- ret = devm_add_action_or_reset(&hdev->dev, &rmi_irq_teardown, hdata);
- if (ret)
- return ret;
-
- hdata->rmi_irq = irq_create_mapping(hdata->domain, 0);
- if (hdata->rmi_irq <= 0) {
- hid_err(hdev, "Can't allocate an IRQ\n");
- return hdata->rmi_irq < 0 ? hdata->rmi_irq : -ENXIO;
- }
-
- return 0;
-}
-
static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
struct rmi_data *data = NULL;
@@ -711,18 +652,11 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id)
mutex_init(&data->page_mutex);
- ret = rmi_setup_irq_domain(hdev);
- if (ret) {
- hid_err(hdev, "failed to allocate IRQ domain\n");
- return ret;
- }
-
if (data->device_flags & RMI_DEVICE_HAS_PHYS_BUTTONS)
rmi_hid_pdata.gpio_data.disable = true;
data->xport.dev = hdev->dev.parent;
data->xport.pdata = rmi_hid_pdata;
- data->xport.pdata.irq = data->rmi_irq;
data->xport.proto_name = "hid";
data->xport.ops = &hid_rmi_ops;
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 2c1a60577728..06b06d0e7b4a 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/device.h>
+#include <linux/dmi.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/fs.h>
@@ -2380,6 +2381,16 @@ static const struct amba_id etm4_ids[] = {
{},
};
+static const struct dmi_system_id broken_coresight[] = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "HPE"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Apollo 70"),
+ },
+ },
+ { } /* terminating entry */
+};
+
MODULE_DEVICE_TABLE(amba, etm4_ids);
static struct amba_driver etm4x_amba_driver = {
@@ -2448,6 +2459,11 @@ static int __init etm4x_init(void)
{
int ret;
+ if (dmi_check_system(broken_coresight)) {
+ pr_info("ETM4 disabled due to firmware bug\n");
+ return 0;
+ }
+
ret = etm4_pm_setup();
/* etm4_pm_setup() does its own cleanup - exit on error */
@@ -2474,6 +2490,9 @@ static int __init etm4x_init(void)
static void __exit etm4x_exit(void)
{
+ if (dmi_check_system(broken_coresight))
+ return;
+
amba_driver_unregister(&etm4x_amba_driver);
platform_driver_unregister(&etm4_platform_driver);
etm4_pm_clear();
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 2168b6cd7167..5d7cda175a0c 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -182,34 +182,47 @@ void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
attn_data.data = fifo_data;
kfifo_put(&drvdata->attn_fifo, attn_data);
+
+ schedule_work(&drvdata->attn_work);
}
EXPORT_SYMBOL_GPL(rmi_set_attn_data);
-static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
+static void attn_callback(struct work_struct *work)
{
- struct rmi_device *rmi_dev = dev_id;
- struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
+ struct rmi_driver_data *drvdata = container_of(work,
+ struct rmi_driver_data,
+ attn_work);
struct rmi4_attn_data attn_data = {0};
int ret, count;
count = kfifo_get(&drvdata->attn_fifo, &attn_data);
- if (count) {
- *(drvdata->irq_status) = attn_data.irq_status;
- drvdata->attn_data = attn_data;
- }
+ if (!count)
+ return;
- ret = rmi_process_interrupt_requests(rmi_dev);
+ *(drvdata->irq_status) = attn_data.irq_status;
+ drvdata->attn_data = attn_data;
+
+ ret = rmi_process_interrupt_requests(drvdata->rmi_dev);
if (ret)
- rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev,
+ rmi_dbg(RMI_DEBUG_CORE, &drvdata->rmi_dev->dev,
"Failed to process interrupt request: %d\n", ret);
- if (count) {
- kfree(attn_data.data);
- drvdata->attn_data.data = NULL;
- }
+ kfree(attn_data.data);
+ drvdata->attn_data.data = NULL;
if (!kfifo_is_empty(&drvdata->attn_fifo))
- return rmi_irq_fn(irq, dev_id);
+ schedule_work(&drvdata->attn_work);
+}
+
+static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
+{
+ struct rmi_device *rmi_dev = dev_id;
+ int ret;
+
+ ret = rmi_process_interrupt_requests(rmi_dev);
+ if (ret)
+ rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev,
+ "Failed to process interrupt request: %d\n", ret);
return IRQ_HANDLED;
}
@@ -217,7 +230,6 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
static int rmi_irq_init(struct rmi_device *rmi_dev)
{
struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
- struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
int irq_flags = irq_get_trigger_type(pdata->irq);
int ret;
@@ -235,8 +247,6 @@ static int rmi_irq_init(struct rmi_device *rmi_dev)
return ret;
}
- data->enabled = true;
-
return 0;
}
@@ -886,23 +896,27 @@ void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake)
if (data->enabled)
goto out;
- enable_irq(irq);
- data->enabled = true;
- if (clear_wake && device_may_wakeup(rmi_dev->xport->dev)) {
- retval = disable_irq_wake(irq);
- if (retval)
- dev_warn(&rmi_dev->dev,
- "Failed to disable irq for wake: %d\n",
- retval);
- }
+ if (irq) {
+ enable_irq(irq);
+ data->enabled = true;
+ if (clear_wake && device_may_wakeup(rmi_dev->xport->dev)) {
+ retval = disable_irq_wake(irq);
+ if (retval)
+ dev_warn(&rmi_dev->dev,
+ "Failed to disable irq for wake: %d\n",
+ retval);
+ }
- /*
- * Call rmi_process_interrupt_requests() after enabling irq,
- * otherwise we may lose interrupt on edge-triggered systems.
- */
- irq_flags = irq_get_trigger_type(pdata->irq);
- if (irq_flags & IRQ_TYPE_EDGE_BOTH)
- rmi_process_interrupt_requests(rmi_dev);
+ /*
+ * Call rmi_process_interrupt_requests() after enabling irq,
+ * otherwise we may lose interrupt on edge-triggered systems.
+ */
+ irq_flags = irq_get_trigger_type(pdata->irq);
+ if (irq_flags & IRQ_TYPE_EDGE_BOTH)
+ rmi_process_interrupt_requests(rmi_dev);
+ } else {
+ data->enabled = true;
+ }
out:
mutex_unlock(&data->enabled_mutex);
@@ -922,20 +936,22 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
goto out;
data->enabled = false;
- disable_irq(irq);
- if (enable_wake && device_may_wakeup(rmi_dev->xport->dev)) {
- retval = enable_irq_wake(irq);
- if (retval)
- dev_warn(&rmi_dev->dev,
- "Failed to enable irq for wake: %d\n",
- retval);
- }
-
- /* make sure the fifo is clean */
- while (!kfifo_is_empty(&data->attn_fifo)) {
- count = kfifo_get(&data->attn_fifo, &attn_data);
- if (count)
- kfree(attn_data.data);
+ if (irq) {
+ disable_irq(irq);
+ if (enable_wake && device_may_wakeup(rmi_dev->xport->dev)) {
+ retval = enable_irq_wake(irq);
+ if (retval)
+ dev_warn(&rmi_dev->dev,
+ "Failed to enable irq for wake: %d\n",
+ retval);
+ }
+ } else {
+ /* make sure the fifo is clean */
+ while (!kfifo_is_empty(&data->attn_fifo)) {
+ count = kfifo_get(&data->attn_fifo, &attn_data);
+ if (count)
+ kfree(attn_data.data);
+ }
}
out:
@@ -978,6 +994,8 @@ static int rmi_driver_remove(struct device *dev)
rmi_disable_irq(rmi_dev, false);
+ cancel_work_sync(&data->attn_work);
+
rmi_f34_remove_sysfs(rmi_dev);
rmi_free_function_list(rmi_dev);
@@ -1223,9 +1241,15 @@ static int rmi_driver_probe(struct device *dev)
}
}
- retval = rmi_irq_init(rmi_dev);
- if (retval < 0)
- goto err_destroy_functions;
+ if (pdata->irq) {
+ retval = rmi_irq_init(rmi_dev);
+ if (retval < 0)
+ goto err_destroy_functions;
+ }
+
+ data->enabled = true;
+
+ INIT_WORK(&data->attn_work, attn_callback);
if (data->f01_container->dev.driver) {
/* Driver already bound, so enable ATTN now. */
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 60aed01e54f2..64758cca794b 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -8,6 +8,7 @@
#include <linux/amba/bus.h>
#include <linux/device.h>
+#include <linux/dmi.h>
#include <linux/kernel.h>
#include <linux/bits.h>
#include <linux/bug.h>
@@ -2909,6 +2910,27 @@ int iommu_dev_disable_feature(struct device *dev, enum iommu_dev_features feat)
}
EXPORT_SYMBOL_GPL(iommu_dev_disable_feature);
+#ifdef CONFIG_ARM64
+static int __init iommu_quirks(void)
+{
+ const char *vendor, *name;
+
+ vendor = dmi_get_system_info(DMI_SYS_VENDOR);
+ name = dmi_get_system_info(DMI_PRODUCT_NAME);
+
+ if (vendor &&
+ (strncmp(vendor, "GIGABYTE", 8) == 0 && name &&
+ (strncmp(name, "R120", 4) == 0 ||
+ strncmp(name, "R270", 4) == 0))) {
+ pr_warn("Gigabyte %s detected, force iommu passthrough mode", name);
+ iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
+ }
+
+ return 0;
+}
+arch_initcall(iommu_quirks);
+#endif
+
/**
* iommu_setup_default_domain - Set the default_domain for the group
* @group: Group to change
diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c
index b9682264e2f5..54575eea3c49 100644
--- a/drivers/media/i2c/ov08x40.c
+++ b/drivers/media/i2c/ov08x40.c
@@ -1322,9 +1322,6 @@ static int ov08x40_power_on(struct device *dev)
struct ov08x40 *ov08x = to_ov08x40(sd);
int ret;
- if (is_acpi_node(dev_fwnode(dev)))
- return 0;
-
ret = clk_prepare_enable(ov08x->xvclk);
if (ret < 0) {
dev_err(dev, "failed to enable xvclk\n");
@@ -1344,7 +1341,7 @@ static int ov08x40_power_on(struct device *dev)
}
gpiod_set_value_cansleep(ov08x->reset_gpio, 0);
- usleep_range(1500, 1800);
+ usleep_range(5000, 5500);
return 0;
@@ -1360,9 +1357,6 @@ static int ov08x40_power_off(struct device *dev)
struct v4l2_subdev *sd = dev_get_drvdata(dev);
struct ov08x40 *ov08x = to_ov08x40(sd);
- if (is_acpi_node(dev_fwnode(dev)))
- return 0;
-
gpiod_set_value_cansleep(ov08x->reset_gpio, 1);
regulator_bulk_disable(ARRAY_SIZE(ov08x40_supply_names),
ov08x->supplies);
@@ -1400,7 +1394,7 @@ static int ov08x40_read_reg(struct ov08x40 *ov08x,
ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs))
- return -EIO;
+ return ret < 0 ? ret : -EIO;
*val = be32_to_cpu(data_be);
@@ -1469,7 +1463,7 @@ static int ov08x40_write_reg(struct ov08x40 *ov08x,
u16 reg, u32 len, u32 __val)
{
struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
- int buf_i, val_i;
+ int buf_i, val_i, ret;
u8 buf[6], *val_p;
__be32 val;
@@ -1487,8 +1481,9 @@ static int ov08x40_write_reg(struct ov08x40 *ov08x,
while (val_i < 4)
buf[buf_i++] = val_p[val_i++];
- if (i2c_master_send(client, buf, len + 2) != len + 2)
- return -EIO;
+ ret = i2c_master_send(client, buf, len + 2);
+ if (ret != len + 2)
+ return ret < 0 ? ret : -EIO;
return 0;
}
@@ -1937,6 +1932,35 @@ static int ov08x40_stop_streaming(struct ov08x40 *ov08x)
OV08X40_REG_VALUE_08BIT, OV08X40_MODE_STANDBY);
}
+/* Verify chip ID */
+static int ov08x40_identify_module(struct ov08x40 *ov08x)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
+ int ret;
+ u32 val;
+
+ if (ov08x->identified)
+ return 0;
+
+ ret = ov08x40_read_reg(ov08x, OV08X40_REG_CHIP_ID,
+ OV08X40_REG_VALUE_24BIT, &val);
+ if (ret) {
+ dev_err(&client->dev, "error reading chip-id register: %d\n", ret);
+ return ret;
+ }
+
+ if (val != OV08X40_CHIP_ID) {
+ dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
+ OV08X40_CHIP_ID, val);
+ return -ENXIO;
+ }
+
+ dev_dbg(&client->dev, "chip id 0x%x\n", val);
+ ov08x->identified = true;
+
+ return 0;
+}
+
static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable)
{
struct ov08x40 *ov08x = to_ov08x40(sd);
@@ -1950,6 +1974,10 @@ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable)
if (ret < 0)
goto err_unlock;
+ ret = ov08x40_identify_module(ov08x);
+ if (ret)
+ goto err_rpm_put;
+
/*
* Apply default & customized values
* and then start streaming.
@@ -1974,32 +2002,6 @@ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
}
-/* Verify chip ID */
-static int ov08x40_identify_module(struct ov08x40 *ov08x)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd);
- int ret;
- u32 val;
-
- if (ov08x->identified)
- return 0;
-
- ret = ov08x40_read_reg(ov08x, OV08X40_REG_CHIP_ID,
- OV08X40_REG_VALUE_24BIT, &val);
- if (ret)
- return ret;
-
- if (val != OV08X40_CHIP_ID) {
- dev_err(&client->dev, "chip id mismatch: %x!=%x\n",
- OV08X40_CHIP_ID, val);
- return -ENXIO;
- }
-
- ov08x->identified = true;
-
- return 0;
-}
-
static const struct v4l2_subdev_video_ops ov08x40_video_ops = {
.s_stream = ov08x40_set_stream,
};
@@ -2151,65 +2153,69 @@ static int ov08x40_check_hwcfg(struct ov08x40 *ov08x, struct device *dev)
int ret;
u32 xvclk_rate;
- if (!fwnode)
- return -ENXIO;
+ /*
+ * Sometimes the fwnode graph is initialized by the bridge driver.
+ * Bridge drivers doing this also add sensor properties, wait for this.
+ */
+ ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
+ if (!ep)
+ return dev_err_probe(dev, -EPROBE_DEFER,
+ "waiting for fwnode graph endpoint\n");
- if (!is_acpi_node(fwnode)) {
- ov08x->xvclk = devm_clk_get(dev, NULL);
- if (IS_ERR(ov08x->xvclk)) {
- dev_err(dev, "could not get xvclk clock (%pe)\n",
- ov08x->xvclk);
- return PTR_ERR(ov08x->xvclk);
- }
+ ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
+ fwnode_handle_put(ep);
+ if (ret)
+ return dev_err_probe(dev, ret, "parsing endpoint failed\n");
- xvclk_rate = clk_get_rate(ov08x->xvclk);
+ ov08x->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(ov08x->reset_gpio)) {
+ ret = dev_err_probe(dev, PTR_ERR(ov08x->reset_gpio),
+ "getting reset GPIO\n");
+ goto out_err;
+ }
- ov08x->reset_gpio = devm_gpiod_get_optional(dev, "reset",
- GPIOD_OUT_LOW);
- if (IS_ERR(ov08x->reset_gpio))
- return PTR_ERR(ov08x->reset_gpio);
+ for (i = 0; i < ARRAY_SIZE(ov08x40_supply_names); i++)
+ ov08x->supplies[i].supply = ov08x40_supply_names[i];
- for (i = 0; i < ARRAY_SIZE(ov08x40_supply_names); i++)
- ov08x->supplies[i].supply = ov08x40_supply_names[i];
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ov08x40_supply_names),
+ ov08x->supplies);
+ if (ret)
+ goto out_err;
- ret = devm_regulator_bulk_get(dev,
- ARRAY_SIZE(ov08x40_supply_names),
- ov08x->supplies);
- if (ret)
- return ret;
+ ov08x->xvclk = devm_clk_get_optional(dev, NULL);
+ if (IS_ERR(ov08x->xvclk)) {
+ ret = dev_err_probe(dev, PTR_ERR(ov08x->xvclk),
+ "getting xvclk\n");
+ goto out_err;
+ }
+ if (ov08x->xvclk) {
+ xvclk_rate = clk_get_rate(ov08x->xvclk);
} else {
ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
&xvclk_rate);
if (ret) {
- dev_err(dev, "can't get clock frequency");
- return ret;
+ dev_err(dev, "can't get clock frequency\n");
+ goto out_err;
}
}
if (xvclk_rate != OV08X40_XVCLK) {
- dev_err(dev, "external clock %d is not supported",
+ dev_err(dev, "external clock %d is not supported\n",
xvclk_rate);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_err;
}
- ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
- if (!ep)
- return -ENXIO;
-
- ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
- fwnode_handle_put(ep);
- if (ret)
- return ret;
-
if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV08X40_DATA_LANES) {
- dev_err(dev, "number of CSI2 data lanes %d is not supported",
+ dev_err(dev, "number of CSI2 data lanes %d is not supported\n",
bus_cfg.bus.mipi_csi2.num_data_lanes);
ret = -EINVAL;
goto out_err;
}
if (!bus_cfg.nr_of_link_frequencies) {
- dev_err(dev, "no link frequencies defined");
+ dev_err(dev, "no link frequencies defined\n");
ret = -EINVAL;
goto out_err;
}
@@ -2222,7 +2228,7 @@ static int ov08x40_check_hwcfg(struct ov08x40 *ov08x, struct device *dev)
}
if (j == bus_cfg.nr_of_link_frequencies) {
- dev_err(dev, "no link frequency %lld supported",
+ dev_err(dev, "no link frequency %lld supported\n",
link_freq_menu_items[i]);
ret = -EINVAL;
goto out_err;
@@ -2246,10 +2252,8 @@ static int ov08x40_probe(struct i2c_client *client)
/* Check HW config */
ret = ov08x40_check_hwcfg(ov08x, &client->dev);
- if (ret) {
- dev_err(&client->dev, "failed to check hwcfg: %d", ret);
+ if (ret)
return ret;
- }
/* Initialize subdev */
v4l2_i2c_subdev_init(&ov08x->sd, client, &ov08x40_subdev_ops);
@@ -2264,10 +2268,8 @@ static int ov08x40_probe(struct i2c_client *client)
/* Check module identity */
ret = ov08x40_identify_module(ov08x);
- if (ret) {
- dev_err(&client->dev, "failed to find sensor: %d\n", ret);
+ if (ret)
goto probe_power_off;
- }
}
/* Set default mode to max resolution */
@@ -2324,11 +2326,14 @@ static void ov08x40_remove(struct i2c_client *client)
ov08x40_free_controls(ov08x);
pm_runtime_disable(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev))
+ ov08x40_power_off(&client->dev);
pm_runtime_set_suspended(&client->dev);
-
- ov08x40_power_off(&client->dev);
}
+static DEFINE_RUNTIME_DEV_PM_OPS(ov08x40_pm_ops, ov08x40_power_off,
+ ov08x40_power_on, NULL);
+
#ifdef CONFIG_ACPI
static const struct acpi_device_id ov08x40_acpi_ids[] = {
{"OVTI08F4"},
@@ -2349,6 +2354,7 @@ static struct i2c_driver ov08x40_i2c_driver = {
.name = "ov08x40",
.acpi_match_table = ACPI_PTR(ov08x40_acpi_ids),
.of_match_table = ov08x40_of_match,
+ .pm = pm_sleep_ptr(&ov08x40_pm_ops),
},
.probe = ov08x40_probe,
.remove = ov08x40_remove,
diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c
index 6eb892fd4d34..3878136227e4 100644
--- a/drivers/memstick/host/rtsx_usb_ms.c
+++ b/drivers/memstick/host/rtsx_usb_ms.c
@@ -813,6 +813,7 @@ static void rtsx_usb_ms_drv_remove(struct platform_device *pdev)
host->eject = true;
cancel_work_sync(&host->handle_req);
+ cancel_delayed_work_sync(&host->poll_card);
mutex_lock(&host->host_mutex);
if (host->req) {
diff --git a/drivers/misc/mei/vsc-tp.c b/drivers/misc/mei/vsc-tp.c
index 7be1649b1972..fa553d4914b6 100644
--- a/drivers/misc/mei/vsc-tp.c
+++ b/drivers/misc/mei/vsc-tp.c
@@ -36,20 +36,24 @@
#define VSC_TP_XFER_TIMEOUT_BYTES 700
#define VSC_TP_PACKET_PADDING_SIZE 1
#define VSC_TP_PACKET_SIZE(pkt) \
- (sizeof(struct vsc_tp_packet) + le16_to_cpu((pkt)->len) + VSC_TP_CRC_SIZE)
+ (sizeof(struct vsc_tp_packet_hdr) + le16_to_cpu((pkt)->hdr.len) + VSC_TP_CRC_SIZE)
#define VSC_TP_MAX_PACKET_SIZE \
- (sizeof(struct vsc_tp_packet) + VSC_TP_MAX_MSG_SIZE + VSC_TP_CRC_SIZE)
+ (sizeof(struct vsc_tp_packet_hdr) + VSC_TP_MAX_MSG_SIZE + VSC_TP_CRC_SIZE)
#define VSC_TP_MAX_XFER_SIZE \
(VSC_TP_MAX_PACKET_SIZE + VSC_TP_XFER_TIMEOUT_BYTES)
#define VSC_TP_NEXT_XFER_LEN(len, offset) \
- (len + sizeof(struct vsc_tp_packet) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE)
+ (len + sizeof(struct vsc_tp_packet_hdr) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE)
-struct vsc_tp_packet {
+struct vsc_tp_packet_hdr {
__u8 sync;
__u8 cmd;
__le16 len;
__le32 seq;
- __u8 buf[] __counted_by(len);
+};
+
+struct vsc_tp_packet {
+ struct vsc_tp_packet_hdr hdr;
+ __u8 buf[VSC_TP_MAX_XFER_SIZE - sizeof(struct vsc_tp_packet_hdr)];
};
struct vsc_tp {
@@ -158,12 +162,12 @@ static int vsc_tp_dev_xfer(struct vsc_tp *tp, void *obuf, void *ibuf, size_t len
static int vsc_tp_xfer_helper(struct vsc_tp *tp, struct vsc_tp_packet *pkt,
void *ibuf, u16 ilen)
{
- int ret, offset = 0, cpy_len, src_len, dst_len = sizeof(struct vsc_tp_packet);
+ int ret, offset = 0, cpy_len, src_len, dst_len = sizeof(struct vsc_tp_packet_hdr);
int next_xfer_len = VSC_TP_PACKET_SIZE(pkt) + VSC_TP_XFER_TIMEOUT_BYTES;
u8 *src, *crc_src, *rx_buf = tp->rx_buf;
int count_down = VSC_TP_MAX_XFER_COUNT;
u32 recv_crc = 0, crc = ~0;
- struct vsc_tp_packet ack;
+ struct vsc_tp_packet_hdr ack;
u8 *dst = (u8 *)&ack;
bool synced = false;
@@ -280,10 +284,10 @@ int vsc_tp_xfer(struct vsc_tp *tp, u8 cmd, const void *obuf, size_t olen,
guard(mutex)(&tp->mutex);
- pkt->sync = VSC_TP_PACKET_SYNC;
- pkt->cmd = cmd;
- pkt->len = cpu_to_le16(olen);
- pkt->seq = cpu_to_le32(++tp->seq);
+ pkt->hdr.sync = VSC_TP_PACKET_SYNC;
+ pkt->hdr.cmd = cmd;
+ pkt->hdr.len = cpu_to_le16(olen);
+ pkt->hdr.seq = cpu_to_le32(++tp->seq);
memcpy(pkt->buf, obuf, olen);
crc = ~crc32(~0, (u8 *)pkt, sizeof(pkt) + olen);
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
index e9208a8d2bfa..a5a4252ea19f 100644
--- a/drivers/net/usb/qmi_wwan.c
+++ b/drivers/net/usb/qmi_wwan.c
@@ -1365,9 +1365,11 @@ static const struct usb_device_id products[] = {
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a0, 0)}, /* Telit FN920C04 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a4, 0)}, /* Telit FN920C04 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a9, 0)}, /* Telit FN920C04 */
+ {QMI_QUIRK_SET_DTR(0x1bc7, 0x10b0, 0)}, /* Telit FE990B */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c0, 0)}, /* Telit FE910C04 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c4, 0)}, /* Telit FE910C04 */
{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c8, 0)}, /* Telit FE910C04 */
+ {QMI_QUIRK_SET_DTR(0x1bc7, 0x10d0, 0)}, /* Telit FN990B */
{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)}, /* Telit ME910 */
{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)}, /* Telit ME910 dual modem */
{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 44179f4e807f..aeab2308b150 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -178,6 +178,17 @@ int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress)
}
EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr);
+static bool usbnet_needs_usb_name_format(struct usbnet *dev, struct net_device *net)
+{
+ /* Point to point devices which don't have a real MAC address
+ * (or report a fake local one) have historically used the usb%d
+ * naming. Preserve this..
+ */
+ return (dev->driver_info->flags & FLAG_POINTTOPOINT) != 0 &&
+ (is_zero_ether_addr(net->dev_addr) ||
+ is_local_ether_addr(net->dev_addr));
+}
+
static void intr_complete (struct urb *urb)
{
struct usbnet *dev = urb->context;
@@ -1762,13 +1773,11 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
if (status < 0)
goto out1;
- // heuristic: "usb%d" for links we know are two-host,
- // else "eth%d" when there's reasonable doubt. userspace
- // can rename the link if it knows better.
+ /* heuristic: rename to "eth%d" if we are not sure this link
+ * is two-host (these links keep "usb%d")
+ */
if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
- ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
- /* somebody touched it*/
- !is_zero_ether_addr(net->dev_addr)))
+ !usbnet_needs_usb_name_format(dev, net))
strscpy(net->name, "eth%d", sizeof(net->name));
/* WLAN devices should always be named "wlan%d" */
if ((dev->driver_info->flags & FLAG_WLAN) != 0)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 82b21e34c545..0cf24ba613a2 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4452,6 +4452,30 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9000,
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9084,
quirk_bridge_cavm_thrx2_pcie_root);
+/*
+ * PCI BAR 5 is not setup correctly for the on-board AHCI controller
+ * on Broadcom's Vulcan processor. Added a quirk to fix BAR 5 by
+ * using BAR 4's resources which are populated correctly and NOT
+ * actually used by the AHCI controller.
+ */
+static void quirk_fix_vulcan_ahci_bars(struct pci_dev *dev)
+{
+ struct resource *r = &dev->resource[4];
+
+ if (!(r->flags & IORESOURCE_MEM) || (r->start == 0))
+ return;
+
+ /* Set BAR5 resource to BAR4 */
+ dev->resource[5] = *r;
+
+ /* Update BAR5 in pci config space */
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_5, r->start);
+
+ /* Clear BAR4's resource */
+ memset(r, 0, sizeof(*r));
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_BROADCOM, 0x9027, quirk_fix_vulcan_ahci_bars);
+
/*
* Intersil/Techwell TW686[4589]-based video capture cards have an empty (zero)
* class code. Fix it.
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 950d8c9fb884..77ac6f8c1805 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -121,6 +121,14 @@ static const char *sd_cache_types[] = {
"write back, no read (daft)"
};
+static const char *sd_probe_types[] = { "async", "sync" };
+
+static char sd_probe_type[6] = "async";
+module_param_string(probe, sd_probe_type, sizeof(sd_probe_type),
+ S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(probe, "async or sync. Setting to 'sync' disables asynchronous "
+ "device number assignments (sda, sdb, ...).");
+
static void sd_set_flush_flag(struct scsi_disk *sdkp,
struct queue_limits *lim)
{
@@ -4371,6 +4379,8 @@ static int __init init_sd(void)
goto err_out_class;
}
+ if (!strcmp(sd_probe_type, "sync"))
+ sd_template.gendrv.probe_type = PROBE_FORCE_SYNCHRONOUS;
err = scsi_register_driver(&sd_template.gendrv);
if (err)
goto err_out_driver;
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c
index f245a84f4a50..bdd26c9f34bd 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -162,7 +162,7 @@ void serial8250_tx_dma_flush(struct uart_8250_port *p)
*/
dma->tx_size = 0;
- dmaengine_terminate_async(dma->rxchan);
+ dmaengine_terminate_async(dma->txchan);
}
int serial8250_rx_dma(struct uart_8250_port *p)
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index df4d0d832e54..73c200127b08 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -2727,6 +2727,22 @@ static struct pci_serial_quirk pci_serial_quirks[] = {
.init = pci_oxsemi_tornado_init,
.setup = pci_oxsemi_tornado_setup,
},
+ {
+ .vendor = PCI_VENDOR_ID_INTASHIELD,
+ .device = 0x4026,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_oxsemi_tornado_init,
+ .setup = pci_oxsemi_tornado_setup,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTASHIELD,
+ .device = 0x4021,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_oxsemi_tornado_init,
+ .setup = pci_oxsemi_tornado_setup,
+ },
{
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x8811,
@@ -5253,6 +5269,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
pbn_b2_2_115200 },
+ { PCI_VENDOR_ID_INTASHIELD, 0x0BA2,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b2_2_115200 },
+ { PCI_VENDOR_ID_INTASHIELD, 0x0BA3,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b2_2_115200 },
/*
* Brainboxes UC-235/246
*/
@@ -5373,6 +5397,14 @@ static const struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
pbn_b2_4_115200 },
+ { PCI_VENDOR_ID_INTASHIELD, 0x0C42,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b2_4_115200 },
+ { PCI_VENDOR_ID_INTASHIELD, 0x0C43,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_b2_4_115200 },
/*
* Brainboxes UC-420
*/
@@ -5599,6 +5631,20 @@ static const struct pci_device_id serial_pci_tbl[] = {
PCI_ANY_ID, PCI_ANY_ID,
0, 0,
pbn_oxsemi_1_15625000 },
+ /*
+ * Brainboxes XC-235
+ */
+ { PCI_VENDOR_ID_INTASHIELD, 0x4026,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_oxsemi_1_15625000 },
+ /*
+ * Brainboxes XC-475
+ */
+ { PCI_VENDOR_ID_INTASHIELD, 0x4021,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ pbn_oxsemi_1_15625000 },
/*
* Perle PCI-RAS cards
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index c91b9d9818cd..79623b2482a0 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -1484,6 +1484,19 @@ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termio
unsigned long modem = lpuart32_read(&sport->port, UARTMODIR)
& ~(UARTMODIR_TXRTSPOL | UARTMODIR_TXRTSE);
+ u32 ctrl;
+
+ /* TXRTSE and TXRTSPOL only can be changed when transmitter is disabled. */
+ ctrl = lpuart32_read(&sport->port, UARTCTRL);
+ if (ctrl & UARTCTRL_TE) {
+ /* wait for the transmit engine to complete */
+ lpuart32_wait_bit_set(&sport->port, UARTSTAT, UARTSTAT_TC);
+ lpuart32_write(&sport->port, ctrl & ~UARTCTRL_TE, UARTCTRL);
+
+ while (lpuart32_read(&sport->port, UARTCTRL) & UARTCTRL_TE)
+ cpu_relax();
+ }
+
lpuart32_write(&sport->port, modem, UARTMODIR);
if (rs485->flags & SER_RS485_ENABLED) {
@@ -1503,6 +1516,10 @@ static int lpuart32_config_rs485(struct uart_port *port, struct ktermios *termio
}
lpuart32_write(&sport->port, modem, UARTMODIR);
+
+ if (ctrl & UARTCTRL_TE)
+ lpuart32_write(&sport->port, ctrl, UARTCTRL);
+
return 0;
}
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 1ec5d8c3aef8..0854ad8c90cd 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -965,10 +965,8 @@ static void stm32_usart_start_tx(struct uart_port *port)
{
struct tty_port *tport = &port->state->port;
- if (kfifo_is_empty(&tport->xmit_fifo) && !port->x_char) {
- stm32_usart_rs485_rts_disable(port);
+ if (kfifo_is_empty(&tport->xmit_fifo) && !port->x_char)
return;
- }
stm32_usart_rs485_rts_enable(port);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index dcba4281ea48..bb82bf5148b0 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -5856,6 +5856,13 @@ static void hub_event(struct work_struct *work)
(u16) hub->change_bits[0],
(u16) hub->event_bits[0]);
+ /* Don't disconnect USB-SATA on TrimSlice */
+ if (strcmp(dev_name(hdev->bus->controller), "tegra-ehci.0") == 0) {
+ if ((hdev->state == 7) && (hub->change_bits[0] == 0) &&
+ (hub->event_bits[0] == 0x2))
+ hub->event_bits[0] = 0;
+ }
+
/* Lock the device, then check to see if we were
* disconnected while waiting for the lock to succeed. */
usb_lock_device(hdev);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 965bffce301e..5e89e9cdcec2 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2865,6 +2865,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if (!ep_seg) {
if (ep->skip && usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
+ /* this event is unlikely to match any TD, don't skip them all */
+ if (trb_comp_code == COMP_STOPPED_LENGTH_INVALID)
+ return 0;
+
skip_isoc_td(xhci, td, ep, status);
if (!list_empty(&ep_ring->td_list))
continue;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 779b01dee068..59c6c1c701b9 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1759,11 +1759,20 @@ static inline void xhci_write_64(struct xhci_hcd *xhci,
}
-/* Link TRB chain should always be set on 0.95 hosts, and AMD 0.96 ISOC rings */
+/*
+ * Reportedly, some chapters of v0.95 spec said that Link TRB always has its chain bit set.
+ * Other chapters and later specs say that it should only be set if the link is inside a TD
+ * which continues from the end of one segment to the next segment.
+ *
+ * Some 0.95 hardware was found to misbehave if any link TRB doesn't have the chain bit set.
+ *
+ * 0.96 hardware from AMD and NEC was found to ignore unchained isochronous link TRBs when
+ * "resynchronizing the pipe" after a Missed Service Error.
+ */
static inline bool xhci_link_chain_quirk(struct xhci_hcd *xhci, enum xhci_ring_type type)
{
return (xhci->quirks & XHCI_LINK_TRB_QUIRK) ||
- (type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST));
+ (type == TYPE_ISOC && (xhci->quirks & (XHCI_AMD_0x96_HOST | XHCI_NEC_HOST)));
}
/* xHCI debugging */
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index b164da5e129e..72bfb79b491d 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -134,6 +134,8 @@
#define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200
#define CRYPTO_TFM_REQ_MAY_BACKLOG 0x00000400
+#define CRYPTO_TFM_FIPS_COMPLIANCE 0x80000000
+
/*
* Miscellaneous stuff.
*/
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 7d63d1d75f22..c7481fdedbdd 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -45,6 +45,8 @@ struct screen_info;
#define EFI_ABORTED (21 | (1UL << (BITS_PER_LONG-1)))
#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1)))
+#define EFI_IS_ERROR(x) ((x) & (1UL << (BITS_PER_LONG-1)))
+
typedef unsigned long efi_status_t;
typedef u8 efi_bool_t;
typedef u16 efi_char16_t; /* UNICODE character */
@@ -863,6 +865,14 @@ static inline int efi_range_is_wc(unsigned long start, unsigned long len)
#define EFI_MEM_ATTR 9 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
#define EFI_MEM_NO_SOFT_RESERVE 10 /* Is the kernel configured to ignore soft reservations? */
#define EFI_PRESERVE_BS_REGIONS 11 /* Are EFI boot-services memory segments available? */
+#define EFI_SECURE_BOOT 12 /* Are we in Secure Boot mode? */
+
+enum efi_secureboot_mode {
+ efi_secureboot_mode_unset,
+ efi_secureboot_mode_unknown,
+ efi_secureboot_mode_disabled,
+ efi_secureboot_mode_enabled,
+};
#ifdef CONFIG_EFI
/*
@@ -874,6 +884,8 @@ static inline bool efi_enabled(int feature)
}
extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
+extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode);
+
bool __pure __efi_soft_reserve_enabled(void);
static inline bool __pure efi_soft_reserve_enabled(void)
@@ -895,6 +907,8 @@ static inline bool efi_enabled(int feature)
static inline void
efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {}
+static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {}
+
static inline bool efi_soft_reserve_enabled(void)
{
return false;
@@ -909,6 +923,7 @@ static inline void efi_find_mirror(void) {}
#endif
extern int efi_status_to_err(efi_status_t status);
+extern const char *efi_status_to_str(efi_status_t status);
/*
* Variable Attributes
@@ -1124,13 +1139,6 @@ static inline bool efi_runtime_disabled(void) { return true; }
extern void efi_call_virt_check_flags(unsigned long flags, const void *caller);
extern unsigned long efi_call_virt_save_flags(void);
-enum efi_secureboot_mode {
- efi_secureboot_mode_unset,
- efi_secureboot_mode_unknown,
- efi_secureboot_mode_disabled,
- efi_secureboot_mode_enabled,
-};
-
static inline
enum efi_secureboot_mode efi_get_secureboot_mode(efi_get_variable_t *get_var)
{
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index e2f1ce37c41e..3fe30fcc506c 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -444,6 +444,7 @@ LSM_HOOK(int, 0, bpf_token_capable, const struct bpf_token *token, int cap)
LSM_HOOK(int, 0, locked_down, enum lockdown_reason what)
+
#ifdef CONFIG_PERF_EVENTS
LSM_HOOK(int, 0, perf_event_open, struct perf_event_attr *attr, int type)
LSM_HOOK(int, 0, perf_event_alloc, struct perf_event *event)
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index ab7eea01ab42..fff7c5f737fc 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -364,6 +364,7 @@ struct rmi_driver_data {
struct rmi4_attn_data attn_data;
DECLARE_KFIFO(attn_fifo, struct rmi4_attn_data, 16);
+ struct work_struct attn_work;
};
int rmi_register_transport_device(struct rmi_transport_dev *xport);
diff --git a/include/linux/security.h b/include/linux/security.h
index 980b6c207cad..a0f0b41d7dcc 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -2386,4 +2386,13 @@ static inline void security_initramfs_populated(void)
}
#endif /* CONFIG_SECURITY */
+#ifdef CONFIG_SECURITY_LOCKDOWN_LSM
+extern int security_lock_kernel_down(const char *where, enum lockdown_reason level);
+#else
+static inline int security_lock_kernel_down(const char *where, enum lockdown_reason level)
+{
+ return 0;
+}
+#endif /* CONFIG_SECURITY_LOCKDOWN_LSM */
+
#endif /* ! __LINUX_SECURITY_H */
diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c
index aac91466279f..3e01781aeb7b 100644
--- a/kernel/cgroup/rstat.c
+++ b/kernel/cgroup/rstat.c
@@ -612,36 +612,33 @@ static void cgroup_force_idle_show(struct seq_file *seq, struct cgroup_base_stat
void cgroup_base_stat_cputime_show(struct seq_file *seq)
{
struct cgroup *cgrp = seq_css(seq)->cgroup;
- u64 usage, utime, stime, ntime;
+ struct cgroup_base_stat bstat;
if (cgroup_parent(cgrp)) {
cgroup_rstat_flush_hold(cgrp);
- usage = cgrp->bstat.cputime.sum_exec_runtime;
+ bstat = cgrp->bstat;
cputime_adjust(&cgrp->bstat.cputime, &cgrp->prev_cputime,
- &utime, &stime);
- ntime = cgrp->bstat.ntime;
+ &bstat.cputime.utime, &bstat.cputime.stime);
cgroup_rstat_flush_release(cgrp);
} else {
- /* cgrp->bstat of root is not actually used, reuse it */
- root_cgroup_cputime(&cgrp->bstat);
- usage = cgrp->bstat.cputime.sum_exec_runtime;
- utime = cgrp->bstat.cputime.utime;
- stime = cgrp->bstat.cputime.stime;
- ntime = cgrp->bstat.ntime;
+ root_cgroup_cputime(&bstat);
}
- do_div(usage, NSEC_PER_USEC);
- do_div(utime, NSEC_PER_USEC);
- do_div(stime, NSEC_PER_USEC);
- do_div(ntime, NSEC_PER_USEC);
+ do_div(bstat.cputime.sum_exec_runtime, NSEC_PER_USEC);
+ do_div(bstat.cputime.utime, NSEC_PER_USEC);
+ do_div(bstat.cputime.stime, NSEC_PER_USEC);
+ do_div(bstat.ntime, NSEC_PER_USEC);
seq_printf(seq, "usage_usec %llu\n"
"user_usec %llu\n"
"system_usec %llu\n"
"nice_usec %llu\n",
- usage, utime, stime, ntime);
+ bstat.cputime.sum_exec_runtime,
+ bstat.cputime.utime,
+ bstat.cputime.stime,
+ bstat.ntime);
- cgroup_force_idle_show(seq, &cgrp->bstat);
+ cgroup_force_idle_show(seq, &bstat);
}
/* Add bpf kfuncs for cgroup_rstat_updated() and cgroup_rstat_flush() */
diff --git a/kernel/module/signing.c b/kernel/module/signing.c
index a2ff4242e623..f0d2be1ee4f1 100644
--- a/kernel/module/signing.c
+++ b/kernel/module/signing.c
@@ -61,10 +61,17 @@ int mod_verify_sig(const void *mod, struct load_info *info)
modlen -= sig_len + sizeof(ms);
info->len = modlen;
- return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
+ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
VERIFY_USE_SECONDARY_KEYRING,
VERIFYING_MODULE_SIGNATURE,
NULL, NULL);
+ if (ret == -ENOKEY && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) {
+ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
+ VERIFY_USE_PLATFORM_KEYRING,
+ VERIFYING_MODULE_SIGNATURE,
+ NULL, NULL);
+ }
+ return ret;
}
int module_sig_check(struct load_info *info, int flags)
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index 324e3ab96bb3..12da0269275c 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -1314,6 +1314,8 @@ static void MPOA_cache_impos_rcvd(struct k_message *msg,
holding_time = msg->content.eg_info.holding_time;
dprintk("(%s) entry = %p, holding_time = %u\n",
mpc->dev->name, entry, holding_time);
+ if (entry == NULL && !holding_time)
+ return;
if (entry == NULL && holding_time) {
entry = mpc->eg_ops->add_entry(msg, mpc);
mpc->eg_ops->put(entry);
diff --git a/net/ipv6/netfilter/nf_socket_ipv6.c b/net/ipv6/netfilter/nf_socket_ipv6.c
index a7690ec62325..9ea5ef56cb27 100644
--- a/net/ipv6/netfilter/nf_socket_ipv6.c
+++ b/net/ipv6/netfilter/nf_socket_ipv6.c
@@ -103,6 +103,10 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
struct sk_buff *data_skb = NULL;
int doff = 0;
int thoff = 0, tproto;
+#if IS_ENABLED(CONFIG_NF_CONNTRACK)
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn const *ct;
+#endif
tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL);
if (tproto < 0) {
@@ -136,6 +140,25 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
return NULL;
}
+#if IS_ENABLED(CONFIG_NF_CONNTRACK)
+ /* Do the lookup with the original socket address in
+ * case this is a reply packet of an established
+ * SNAT-ted connection.
+ */
+ ct = nf_ct_get(skb, &ctinfo);
+ if (ct &&
+ ((tproto != IPPROTO_ICMPV6 &&
+ ctinfo == IP_CT_ESTABLISHED_REPLY) ||
+ (tproto == IPPROTO_ICMPV6 &&
+ ctinfo == IP_CT_RELATED_REPLY)) &&
+ (ct->status & IPS_SRC_NAT_DONE)) {
+ daddr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.in6;
+ dport = (tproto == IPPROTO_TCP) ?
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.tcp.port :
+ ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
+ }
+#endif
+
return nf_socket_get_sock_v6(net, data_skb, doff, tproto, saddr, daddr,
sport, dport, indev);
}
diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
index dc081cf46d21..25fe35170155 100644
--- a/scripts/Makefile.extrawarn
+++ b/scripts/Makefile.extrawarn
@@ -20,6 +20,10 @@ KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member)
KBUILD_CFLAGS += -Wmissing-declarations
KBUILD_CFLAGS += -Wmissing-prototypes
+# temporarily disable a warning to allow compiling with gcc15, as suggested by
+# Jakub Jelinek in https://bugzilla.redhat.com/show_bug.cgi?id=2338533#c7
+KBUILD_CFLAGS += $(call cc-option,-Wno-error=unterminated-string-initialization)
+
ifneq ($(CONFIG_FRAME_WARN),0)
KBUILD_CFLAGS += -Wframe-larger-than=$(CONFIG_FRAME_WARN)
endif
diff --git a/scripts/tags.sh b/scripts/tags.sh
index 45eaf35f5bff..8cd9b8bbadc0 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -16,6 +16,8 @@ fi
ignore="$(echo "$RCS_FIND_IGNORE" | sed 's|\\||g' )"
# tags and cscope files should also ignore MODVERSION *.mod.c files
ignore="$ignore ( -name *.mod.c ) -prune -o"
+# RHEL tags and cscope should also ignore redhat/rpm
+ignore="$ignore ( -path redhat/rpm ) -prune -o"
# ignore arbitrary directories
if [ -n "${IGNORE_DIRS}" ]; then
diff --git a/security/integrity/platform_certs/load_uefi.c b/security/integrity/platform_certs/load_uefi.c
index d1fdd113450a..182e8090cfe8 100644
--- a/security/integrity/platform_certs/load_uefi.c
+++ b/security/integrity/platform_certs/load_uefi.c
@@ -74,7 +74,8 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
return NULL;
if (*status != EFI_BUFFER_TOO_SMALL) {
- pr_err("Couldn't get size: 0x%lx\n", *status);
+ pr_err("Couldn't get size: %s (0x%lx)\n",
+ efi_status_to_str(*status), *status);
return NULL;
}
@@ -85,7 +86,8 @@ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
*status = efi.get_variable(name, guid, NULL, &lsize, db);
if (*status != EFI_SUCCESS) {
kfree(db);
- pr_err("Error reading db var: 0x%lx\n", *status);
+ pr_err("Error reading db var: %s (0x%lx)\n",
+ efi_status_to_str(*status), *status);
return NULL;
}
diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig
index e84ddf484010..d0501353a4b9 100644
--- a/security/lockdown/Kconfig
+++ b/security/lockdown/Kconfig
@@ -16,6 +16,19 @@ config SECURITY_LOCKDOWN_LSM_EARLY
subsystem is fully initialised. If enabled, lockdown will
unconditionally be called before any other LSMs.
+config LOCK_DOWN_IN_EFI_SECURE_BOOT
+ bool "Lock down the kernel in EFI Secure Boot mode"
+ default n
+ depends on EFI && SECURITY_LOCKDOWN_LSM_EARLY
+ help
+ UEFI Secure Boot provides a mechanism for ensuring that the firmware
+ will only load signed bootloaders and kernels. Secure boot mode may
+ be determined from EFI variables provided by the system firmware if
+ not indicated by the boot parameters.
+
+ Enabling this option results in kernel lockdown being triggered if
+ EFI Secure Boot is set.
+
choice
prompt "Kernel default lockdown mode"
default LOCK_DOWN_KERNEL_FORCE_NONE
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
index cf83afa1d879..aba751e7abff 100644
--- a/security/lockdown/lockdown.c
+++ b/security/lockdown/lockdown.c
@@ -72,6 +72,17 @@ static int lockdown_is_locked_down(enum lockdown_reason what)
return 0;
}
+/**
+ * security_lock_kernel_down() - Put the kernel into lock-down mode.
+ *
+ * @where: Where the lock-down is originating from (e.g. command line option)
+ * @level: The lock-down level (can only increase)
+ */
+int security_lock_kernel_down(const char *where, enum lockdown_reason level)
+{
+ return lock_kernel_down(where, level);
+}
+
static struct security_hook_list lockdown_hooks[] __ro_after_init = {
LSM_HOOK_INIT(locked_down, lockdown_is_locked_down),
};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a84857a3c2bf..78aab243c8b6 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -10519,6 +10519,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8811, "HP Spectre x360 15-eb1xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
SND_PCI_QUIRK(0x103c, 0x8812, "HP Spectre x360 15-eb1xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1),
SND_PCI_QUIRK(0x103c, 0x881d, "HP 250 G8 Notebook PC", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
+ SND_PCI_QUIRK(0x103c, 0x881e, "HP Laptop 15s-du3xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2),
SND_PCI_QUIRK(0x103c, 0x8846, "HP EliteBook 850 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8847, "HP EliteBook x360 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x884b, "HP EliteBook 840 Aero G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED),
@@ -10783,6 +10784,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE),
SND_PCI_QUIRK(0x1043, 0x1da2, "ASUS UP6502ZA/ZD", ALC245_FIXUP_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1043, 0x1df3, "ASUS UM5606WA", ALC294_FIXUP_BASS_SPEAKER_15),
+ SND_PCI_QUIRK(0x1043, 0x1264, "ASUS UM5606KA", ALC294_FIXUP_BASS_SPEAKER_15),
SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502),
SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2),
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index ed6127b0389f..3d36d22f8e9e 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -4223,6 +4223,52 @@ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
}
}
+/*
+ * Some Plantronics headsets have control names that don't meet ALSA naming
+ * standards. This function fixes nonstandard source names. By the time
+ * this function is called the control name should look like one of these:
+ * "source names Playback Volume"
+ * "source names Playback Switch"
+ * "source names Capture Volume"
+ * "source names Capture Switch"
+ * If any of the trigger words are found in the name then the name will
+ * be changed to:
+ * "Headset Playback Volume"
+ * "Headset Playback Switch"
+ * "Headset Capture Volume"
+ * "Headset Capture Switch"
+ * depending on the current suffix.
+ */
+static void snd_fix_plt_name(struct snd_usb_audio *chip,
+ struct snd_ctl_elem_id *id)
+{
+ /* no variant of "Sidetone" should be added to this list */
+ static const char * const trigger[] = {
+ "Earphone", "Microphone", "Receive", "Transmit"
+ };
+ static const char * const suffix[] = {
+ " Playback Volume", " Playback Switch",
+ " Capture Volume", " Capture Switch"
+ };
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(trigger); i++)
+ if (strstr(id->name, trigger[i]))
+ goto triggered;
+ usb_audio_dbg(chip, "no change in %s\n", id->name);
+ return;
+
+triggered:
+ for (i = 0; i < ARRAY_SIZE(suffix); i++)
+ if (strstr(id->name, suffix[i])) {
+ usb_audio_dbg(chip, "fixing kctl name %s\n", id->name);
+ snprintf(id->name, sizeof(id->name), "Headset%s",
+ suffix[i]);
+ return;
+ }
+ usb_audio_dbg(chip, "something wrong in kctl name %s\n", id->name);
+}
+
void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
struct usb_mixer_elem_info *cval, int unitid,
struct snd_kcontrol *kctl)
@@ -4240,5 +4286,10 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
cval->min_mute = 1;
break;
}
+
+ /* ALSA-ify some Plantronics headset control names */
+ if (USB_ID_VENDOR(mixer->chip->usb_id) == 0x047f &&
+ (cval->control == UAC_FU_MUTE || cval->control == UAC_FU_VOLUME))
+ snd_fix_plt_name(mixer->chip, &kctl->id);
}
diff --git a/tools/perf/Documentation/intel-hybrid.txt b/tools/perf/Documentation/intel-hybrid.txt
index e7a776ad25d7..0379903673a4 100644
--- a/tools/perf/Documentation/intel-hybrid.txt
+++ b/tools/perf/Documentation/intel-hybrid.txt
@@ -8,15 +8,15 @@ Part of events are available on core cpu, part of events are available
on atom cpu and even part of events are available on both.
Kernel exports two new cpu pmus via sysfs:
-/sys/devices/cpu_core
-/sys/devices/cpu_atom
+/sys/bus/event_source/devices/cpu_core
+/sys/bus/event_source/devices/cpu_atom
The 'cpus' files are created under the directories. For example,
-cat /sys/devices/cpu_core/cpus
+cat /sys/bus/event_source/devices/cpu_core/cpus
0-15
-cat /sys/devices/cpu_atom/cpus
+cat /sys/bus/event_source/devices/cpu_atom/cpus
16-23
It indicates cpu0-cpu15 are core cpus and cpu16-cpu23 are atom cpus.
@@ -60,8 +60,8 @@ can't carry pmu information. So now this type is extended to be PMU aware
type. The PMU type ID is stored at attr.config[63:32].
PMU type ID is retrieved from sysfs.
-/sys/devices/cpu_atom/type
-/sys/devices/cpu_core/type
+/sys/bus/event_source/devices/cpu_atom/type
+/sys/bus/event_source/devices/cpu_core/type
The new attr.config layout for PERF_TYPE_HARDWARE:
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index d0c65fad419a..c3ffd93f94d7 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -188,7 +188,7 @@ in the CPU vendor specific documentation.
The available PMUs and their raw parameters can be listed with
- ls /sys/devices/*/format
+ ls /sys/bus/event_source/devices/*/format
For example the raw event "LSD.UOPS" core pmu event above could
be specified as
diff --git a/tools/perf/arch/x86/util/iostat.c b/tools/perf/arch/x86/util/iostat.c
index 00f645a0c18a..7442a2cd87ed 100644
--- a/tools/perf/arch/x86/util/iostat.c
+++ b/tools/perf/arch/x86/util/iostat.c
@@ -32,7 +32,7 @@
#define MAX_PATH 1024
#endif
-#define UNCORE_IIO_PMU_PATH "devices/uncore_iio_%d"
+#define UNCORE_IIO_PMU_PATH "bus/event_source/devices/uncore_iio_%d"
#define SYSFS_UNCORE_PMU_PATH "%s/"UNCORE_IIO_PMU_PATH
#define PLATFORM_MAPPING_PATH UNCORE_IIO_PMU_PATH"/die%d"
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 77e327d4a9a7..68ea7589c143 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -97,7 +97,7 @@
#include <internal/threadmap.h>
#define DEFAULT_SEPARATOR " "
-#define FREEZE_ON_SMI_PATH "devices/cpu/freeze_on_smi"
+#define FREEZE_ON_SMI_PATH "bus/event_source/devices/cpu/freeze_on_smi"
static void print_counters(struct timespec *ts, int argc, const char **argv);
diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c
index 3692e988c86e..0277d3e1505c 100644
--- a/tools/perf/util/mem-events.c
+++ b/tools/perf/util/mem-events.c
@@ -189,7 +189,7 @@ static bool perf_pmu__mem_events_supported(const char *mnt, struct perf_pmu *pmu
if (!e->event_name)
return true;
- scnprintf(path, PATH_MAX, "%s/devices/%s/events/%s", mnt, pmu->name, e->event_name);
+ scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/events/%s", mnt, pmu->name, e->event_name);
return !stat(path, &st);
}
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c
index 6206c8fe2bf9..a8193ac8f2e7 100644
--- a/tools/perf/util/pmu.c
+++ b/tools/perf/util/pmu.c
@@ -36,12 +36,12 @@
#define UNIT_MAX_LEN 31 /* max length for event unit name */
enum event_source {
- /* An event loaded from /sys/devices/<pmu>/events. */
+ /* An event loaded from /sys/bus/event_source/devices/<pmu>/events. */
EVENT_SRC_SYSFS,
/* An event loaded from a CPUID matched json file. */
EVENT_SRC_CPU_JSON,
/*
- * An event loaded from a /sys/devices/<pmu>/identifier matched json
+ * An event loaded from a /sys/bus/event_source/devices/<pmu>/identifier matched json
* file.
*/
EVENT_SRC_SYS_JSON,