From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <gentoo-commits+bounces-906791-garchives=archives.gentoo.org@lists.gentoo.org>
Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(No client certificate requested)
	by finch.gentoo.org (Postfix) with ESMTPS id 35160138EBB
	for <garchives@archives.gentoo.org>; Sun, 16 Oct 2016 19:25:49 +0000 (UTC)
Received: from pigeon.gentoo.org (localhost [127.0.0.1])
	by pigeon.gentoo.org (Postfix) with SMTP id 83FF2E0881;
	Sun, 16 Oct 2016 19:25:48 +0000 (UTC)
Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(No client certificate requested)
	by pigeon.gentoo.org (Postfix) with ESMTPS id 5A485E0881
	for <gentoo-commits@lists.gentoo.org>; Sun, 16 Oct 2016 19:25:48 +0000 (UTC)
Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(No client certificate requested)
	by smtp.gentoo.org (Postfix) with ESMTPS id 04877340F1A
	for <gentoo-commits@lists.gentoo.org>; Sun, 16 Oct 2016 19:25:47 +0000 (UTC)
Received: from localhost.localdomain (localhost [127.0.0.1])
	by oystercatcher.gentoo.org (Postfix) with ESMTP id 7C77E2F2
	for <gentoo-commits@lists.gentoo.org>; Sun, 16 Oct 2016 19:25:45 +0000 (UTC)
From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Content-Transfer-Encoding: 8bit
Content-type: text/plain; charset=UTF-8
Reply-To: gentoo-dev@lists.gentoo.org, "Mike Pagano" <mpagano@gentoo.org>
Message-ID: <1476645930.37c6ecc6cfa4efebd1213f42f4651dfae47d23bf.mpagano@gentoo>
Subject: [gentoo-commits] proj/linux-patches:4.4 commit in: /
X-VCS-Repository: proj/linux-patches
X-VCS-Files: 0000_README 1024_linux-4.4.25.patch
X-VCS-Directories: /
X-VCS-Committer: mpagano
X-VCS-Committer-Name: Mike Pagano
X-VCS-Revision: 37c6ecc6cfa4efebd1213f42f4651dfae47d23bf
X-VCS-Branch: 4.4
Date: Sun, 16 Oct 2016 19:25:45 +0000 (UTC)
Precedence: bulk
List-Post: <mailto:gentoo-commits@lists.gentoo.org>
List-Help: <mailto:gentoo-commits+help@lists.gentoo.org>
List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org>
List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org>
List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org>
X-BeenThere: gentoo-commits@lists.gentoo.org
X-Archives-Salt: ad26066a-baf9-4baf-bf0d-c568b8a73bea
X-Archives-Hash: 7923815b1a4af4824e397756b4795907

commit:     37c6ecc6cfa4efebd1213f42f4651dfae47d23bf
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Oct 16 19:25:30 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Oct 16 19:25:30 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=37c6ecc6

Linux patch 4.4.25

 0000_README             |    4 +
 1024_linux-4.4.25.patch | 1149 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1153 insertions(+)

diff --git a/0000_README b/0000_README
index 4f6a4da..8be4294 100644
--- a/0000_README
+++ b/0000_README
@@ -139,6 +139,10 @@ Patch:  1023_linux-4.4.24.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.4.24
 
+Patch:  1024_linux-4.4.25.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.4.25
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1024_linux-4.4.25.patch b/1024_linux-4.4.25.patch
new file mode 100644
index 0000000..e75e66a
--- /dev/null
+++ b/1024_linux-4.4.25.patch
@@ -0,0 +1,1149 @@
+diff --git a/Makefile b/Makefile
+index cdbc185c3539..578a82554923 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 4
+-SUBLEVEL = 24
++SUBLEVEL = 25
+ EXTRAVERSION =
+ NAME = Blurry Fish Butt
+ 
+diff --git a/arch/arm/boot/dts/armada-390.dtsi b/arch/arm/boot/dts/armada-390.dtsi
+index 094e39c66039..6cd18d8aaac7 100644
+--- a/arch/arm/boot/dts/armada-390.dtsi
++++ b/arch/arm/boot/dts/armada-390.dtsi
+@@ -47,6 +47,8 @@
+ #include "armada-39x.dtsi"
+ 
+ / {
++	compatible = "marvell,armada390";
++
+ 	soc {
+ 		internal-regs {
+ 			pinctrl@18000 {
+@@ -54,4 +56,5 @@
+ 				reg = <0x18000 0x20>;
+ 			};
+ 		};
++	};
+ };
+diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
+index a4c1762b53ea..e00d50ef678f 100644
+--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
+@@ -5,6 +5,7 @@
+ #include <dt-bindings/reset/qcom,gcc-msm8960.h>
+ #include <dt-bindings/clock/qcom,mmcc-msm8960.h>
+ #include <dt-bindings/soc/qcom,gsbi.h>
++#include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ / {
+ 	model = "Qualcomm APQ8064";
+@@ -354,22 +355,50 @@
+ 
+ 					compatible = "qcom,pm8921-gpio";
+ 					reg = <0x150>;
+-					interrupts = <192 1>, <193 1>, <194 1>,
+-						     <195 1>, <196 1>, <197 1>,
+-						     <198 1>, <199 1>, <200 1>,
+-						     <201 1>, <202 1>, <203 1>,
+-						     <204 1>, <205 1>, <206 1>,
+-						     <207 1>, <208 1>, <209 1>,
+-						     <210 1>, <211 1>, <212 1>,
+-						     <213 1>, <214 1>, <215 1>,
+-						     <216 1>, <217 1>, <218 1>,
+-						     <219 1>, <220 1>, <221 1>,
+-						     <222 1>, <223 1>, <224 1>,
+-						     <225 1>, <226 1>, <227 1>,
+-						     <228 1>, <229 1>, <230 1>,
+-						     <231 1>, <232 1>, <233 1>,
+-						     <234 1>, <235 1>;
+-
++					interrupts = <192 IRQ_TYPE_NONE>,
++						     <193 IRQ_TYPE_NONE>,
++						     <194 IRQ_TYPE_NONE>,
++						     <195 IRQ_TYPE_NONE>,
++						     <196 IRQ_TYPE_NONE>,
++						     <197 IRQ_TYPE_NONE>,
++						     <198 IRQ_TYPE_NONE>,
++						     <199 IRQ_TYPE_NONE>,
++						     <200 IRQ_TYPE_NONE>,
++						     <201 IRQ_TYPE_NONE>,
++						     <202 IRQ_TYPE_NONE>,
++						     <203 IRQ_TYPE_NONE>,
++						     <204 IRQ_TYPE_NONE>,
++						     <205 IRQ_TYPE_NONE>,
++						     <206 IRQ_TYPE_NONE>,
++						     <207 IRQ_TYPE_NONE>,
++						     <208 IRQ_TYPE_NONE>,
++						     <209 IRQ_TYPE_NONE>,
++						     <210 IRQ_TYPE_NONE>,
++						     <211 IRQ_TYPE_NONE>,
++						     <212 IRQ_TYPE_NONE>,
++						     <213 IRQ_TYPE_NONE>,
++						     <214 IRQ_TYPE_NONE>,
++						     <215 IRQ_TYPE_NONE>,
++						     <216 IRQ_TYPE_NONE>,
++						     <217 IRQ_TYPE_NONE>,
++						     <218 IRQ_TYPE_NONE>,
++						     <219 IRQ_TYPE_NONE>,
++						     <220 IRQ_TYPE_NONE>,
++						     <221 IRQ_TYPE_NONE>,
++						     <222 IRQ_TYPE_NONE>,
++						     <223 IRQ_TYPE_NONE>,
++						     <224 IRQ_TYPE_NONE>,
++						     <225 IRQ_TYPE_NONE>,
++						     <226 IRQ_TYPE_NONE>,
++						     <227 IRQ_TYPE_NONE>,
++						     <228 IRQ_TYPE_NONE>,
++						     <229 IRQ_TYPE_NONE>,
++						     <230 IRQ_TYPE_NONE>,
++						     <231 IRQ_TYPE_NONE>,
++						     <232 IRQ_TYPE_NONE>,
++						     <233 IRQ_TYPE_NONE>,
++						     <234 IRQ_TYPE_NONE>,
++						     <235 IRQ_TYPE_NONE>;
+ 					gpio-controller;
+ 					#gpio-cells = <2>;
+ 
+@@ -381,9 +410,18 @@
+ 					gpio-controller;
+ 					#gpio-cells = <2>;
+ 					interrupts =
+-					<128 1>, <129 1>, <130 1>, <131 1>,
+-					<132 1>, <133 1>, <134 1>, <135 1>,
+-					<136 1>, <137 1>, <138 1>, <139 1>;
++					<128 IRQ_TYPE_NONE>,
++					<129 IRQ_TYPE_NONE>,
++					<130 IRQ_TYPE_NONE>,
++					<131 IRQ_TYPE_NONE>,
++					<132 IRQ_TYPE_NONE>,
++					<133 IRQ_TYPE_NONE>,
++					<134 IRQ_TYPE_NONE>,
++					<135 IRQ_TYPE_NONE>,
++					<136 IRQ_TYPE_NONE>,
++					<137 IRQ_TYPE_NONE>,
++					<138 IRQ_TYPE_NONE>,
++					<139 IRQ_TYPE_NONE>;
+ 				};
+ 
+ 				rtc@11d {
+diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
+index d6476d11212e..3251b206e55a 100644
+--- a/arch/mips/kvm/emulate.c
++++ b/arch/mips/kvm/emulate.c
+@@ -807,6 +807,47 @@ enum emulation_result kvm_mips_emul_tlbr(struct kvm_vcpu *vcpu)
+ 	return EMULATE_FAIL;
+ }
+ 
++/**
++ * kvm_mips_invalidate_guest_tlb() - Indicates a change in guest MMU map.
++ * @vcpu:	VCPU with changed mappings.
++ * @tlb:	TLB entry being removed.
++ *
++ * This is called to indicate a single change in guest MMU mappings, so that we
++ * can arrange TLB flushes on this and other CPUs.
++ */
++static void kvm_mips_invalidate_guest_tlb(struct kvm_vcpu *vcpu,
++					  struct kvm_mips_tlb *tlb)
++{
++	int cpu, i;
++	bool user;
++
++	/* No need to flush for entries which are already invalid */
++	if (!((tlb->tlb_lo[0] | tlb->tlb_lo[1]) & ENTRYLO_V))
++		return;
++	/* User address space doesn't need flushing for KSeg2/3 changes */
++	user = tlb->tlb_hi < KVM_GUEST_KSEG0;
++
++	preempt_disable();
++
++	/*
++	 * Probe the shadow host TLB for the entry being overwritten, if one
++	 * matches, invalidate it
++	 */
++	kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi);
++
++	/* Invalidate the whole ASID on other CPUs */
++	cpu = smp_processor_id();
++	for_each_possible_cpu(i) {
++		if (i == cpu)
++			continue;
++		if (user)
++			vcpu->arch.guest_user_asid[i] = 0;
++		vcpu->arch.guest_kernel_asid[i] = 0;
++	}
++
++	preempt_enable();
++}
++
+ /* Write Guest TLB Entry @ Index */
+ enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu)
+ {
+@@ -826,11 +867,8 @@ enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu)
+ 	}
+ 
+ 	tlb = &vcpu->arch.guest_tlb[index];
+-	/*
+-	 * Probe the shadow host TLB for the entry being overwritten, if one
+-	 * matches, invalidate it
+-	 */
+-	kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi);
++
++	kvm_mips_invalidate_guest_tlb(vcpu, tlb);
+ 
+ 	tlb->tlb_mask = kvm_read_c0_guest_pagemask(cop0);
+ 	tlb->tlb_hi = kvm_read_c0_guest_entryhi(cop0);
+@@ -859,11 +897,7 @@ enum emulation_result kvm_mips_emul_tlbwr(struct kvm_vcpu *vcpu)
+ 
+ 	tlb = &vcpu->arch.guest_tlb[index];
+ 
+-	/*
+-	 * Probe the shadow host TLB for the entry being overwritten, if one
+-	 * matches, invalidate it
+-	 */
+-	kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi);
++	kvm_mips_invalidate_guest_tlb(vcpu, tlb);
+ 
+ 	tlb->tlb_mask = kvm_read_c0_guest_pagemask(cop0);
+ 	tlb->tlb_hi = kvm_read_c0_guest_entryhi(cop0);
+@@ -982,6 +1016,7 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc,
+ 	int32_t rt, rd, copz, sel, co_bit, op;
+ 	uint32_t pc = vcpu->arch.pc;
+ 	unsigned long curr_pc;
++	int cpu, i;
+ 
+ 	/*
+ 	 * Update PC and hold onto current PC in case there is
+@@ -1089,8 +1124,16 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc,
+ 						vcpu->arch.gprs[rt]
+ 						& ASID_MASK);
+ 
++					preempt_disable();
+ 					/* Blow away the shadow host TLBs */
+ 					kvm_mips_flush_host_tlb(1);
++					cpu = smp_processor_id();
++					for_each_possible_cpu(i)
++						if (i != cpu) {
++							vcpu->arch.guest_user_asid[i] = 0;
++							vcpu->arch.guest_kernel_asid[i] = 0;
++						}
++					preempt_enable();
+ 				}
+ 				kvm_write_c0_guest_entryhi(cop0,
+ 							   vcpu->arch.gprs[rt]);
+diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
+index 070fa8552051..627d129d7fcb 100644
+--- a/arch/powerpc/include/asm/reg.h
++++ b/arch/powerpc/include/asm/reg.h
+@@ -708,6 +708,7 @@
+ #define   MMCR0_FCHV	0x00000001UL /* freeze conditions in hypervisor mode */
+ #define SPRN_MMCR1	798
+ #define SPRN_MMCR2	785
++#define SPRN_UMMCR2	769
+ #define SPRN_MMCRA	0x312
+ #define   MMCRA_SDSYNC	0x80000000UL /* SDAR synced with SIAR */
+ #define   MMCRA_SDAR_DCACHE_MISS 0x40000000UL
+diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
+index 2afdb9c0937d..729f8faa95c5 100644
+--- a/arch/powerpc/kvm/book3s_emulate.c
++++ b/arch/powerpc/kvm/book3s_emulate.c
+@@ -498,6 +498,7 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
+ 	case SPRN_MMCR0:
+ 	case SPRN_MMCR1:
+ 	case SPRN_MMCR2:
++	case SPRN_UMMCR2:
+ #endif
+ 		break;
+ unprivileged:
+@@ -640,6 +641,7 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val
+ 	case SPRN_MMCR0:
+ 	case SPRN_MMCR1:
+ 	case SPRN_MMCR2:
++	case SPRN_UMMCR2:
+ 	case SPRN_TIR:
+ #endif
+ 		*spr_val = 0;
+diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
+index fd5875179e5c..6d63cd67b09b 100644
+--- a/arch/powerpc/kvm/booke.c
++++ b/arch/powerpc/kvm/booke.c
+@@ -2033,7 +2033,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+ 		if (type == KVMPPC_DEBUG_NONE)
+ 			continue;
+ 
+-		if (type & !(KVMPPC_DEBUG_WATCH_READ |
++		if (type & ~(KVMPPC_DEBUG_WATCH_READ |
+ 			     KVMPPC_DEBUG_WATCH_WRITE |
+ 			     KVMPPC_DEBUG_BREAKPOINT))
+ 			return -EINVAL;
+diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
+index df6b4eeac0bd..0988e204f1e3 100644
+--- a/arch/x86/kernel/apic/vector.c
++++ b/arch/x86/kernel/apic/vector.c
+@@ -659,11 +659,28 @@ void irq_complete_move(struct irq_cfg *cfg)
+  */
+ void irq_force_complete_move(struct irq_desc *desc)
+ {
+-	struct irq_data *irqdata = irq_desc_get_irq_data(desc);
+-	struct apic_chip_data *data = apic_chip_data(irqdata);
+-	struct irq_cfg *cfg = data ? &data->cfg : NULL;
++	struct irq_data *irqdata;
++	struct apic_chip_data *data;
++	struct irq_cfg *cfg;
+ 	unsigned int cpu;
+ 
++	/*
++	 * The function is called for all descriptors regardless of which
++	 * irqdomain they belong to. For example if an IRQ is provided by
++	 * an irq_chip as part of a GPIO driver, the chip data for that
++	 * descriptor is specific to the irq_chip in question.
++	 *
++	 * Check first that the chip_data is what we expect
++	 * (apic_chip_data) before touching it any further.
++	 */
++	irqdata = irq_domain_get_irq_data(x86_vector_domain,
++					  irq_desc_get_irq(desc));
++	if (!irqdata)
++		return;
++
++	data = apic_chip_data(irqdata);
++	cfg = data ? &data->cfg : NULL;
++
+ 	if (!cfg)
+ 		return;
+ 
+diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
+index 569c1e4f96fe..38b3ead7222d 100644
+--- a/arch/x86/kernel/e820.c
++++ b/arch/x86/kernel/e820.c
+@@ -347,7 +347,7 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
+ 		 * continue building up new bios map based on this
+ 		 * information
+ 		 */
+-		if (current_type != last_type || current_type == E820_PRAM) {
++		if (current_type != last_type) {
+ 			if (last_type != 0)	 {
+ 				new_bios[new_bios_entry].size =
+ 					change_point[chgidx]->addr - last_addr;
+@@ -753,7 +753,7 @@ u64 __init early_reserve_e820(u64 size, u64 align)
+ /*
+  * Find the highest page frame number we have available
+  */
+-static unsigned long __init e820_end_pfn(unsigned long limit_pfn)
++static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
+ {
+ 	int i;
+ 	unsigned long last_pfn = 0;
+@@ -764,11 +764,7 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn)
+ 		unsigned long start_pfn;
+ 		unsigned long end_pfn;
+ 
+-		/*
+-		 * Persistent memory is accounted as ram for purposes of
+-		 * establishing max_pfn and mem_map.
+-		 */
+-		if (ei->type != E820_RAM && ei->type != E820_PRAM)
++		if (ei->type != type)
+ 			continue;
+ 
+ 		start_pfn = ei->addr >> PAGE_SHIFT;
+@@ -793,12 +789,12 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn)
+ }
+ unsigned long __init e820_end_of_ram_pfn(void)
+ {
+-	return e820_end_pfn(MAX_ARCH_PFN);
++	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
+ }
+ 
+ unsigned long __init e820_end_of_low_ram_pfn(void)
+ {
+-	return e820_end_pfn(1UL << (32-PAGE_SHIFT));
++	return e820_end_pfn(1UL << (32 - PAGE_SHIFT), E820_RAM);
+ }
+ 
+ static void early_panic(char *msg)
+diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
+index 558f50edebca..479a409ddac8 100644
+--- a/arch/x86/kernel/ptrace.c
++++ b/arch/x86/kernel/ptrace.c
+@@ -188,8 +188,8 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs)
+ 		return sp;
+ 
+ 	prev_esp = (u32 *)(context);
+-	if (prev_esp)
+-		return (unsigned long)prev_esp;
++	if (*prev_esp)
++		return (unsigned long)*prev_esp;
+ 
+ 	return (unsigned long)regs;
+ }
+diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c
+index de0337ebd658..4f3137d9a35e 100644
+--- a/drivers/char/tpm/tpm-dev.c
++++ b/drivers/char/tpm/tpm-dev.c
+@@ -139,7 +139,7 @@ static ssize_t tpm_write(struct file *file, const char __user *buf,
+ 
+ 	/* atomic tpm command send and result receive */
+ 	out_size = tpm_transmit(priv->chip, priv->data_buffer,
+-				sizeof(priv->data_buffer));
++				sizeof(priv->data_buffer), 0);
+ 	if (out_size < 0) {
+ 		mutex_unlock(&priv->buffer_mutex);
+ 		return out_size;
+diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
+index c50637db3a8a..17abe52e6365 100644
+--- a/drivers/char/tpm/tpm-interface.c
++++ b/drivers/char/tpm/tpm-interface.c
+@@ -328,8 +328,8 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
+ /*
+  * Internal kernel interface to transmit TPM commands
+  */
+-ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
+-		     size_t bufsiz)
++ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
++		     unsigned int flags)
+ {
+ 	ssize_t rc;
+ 	u32 count, ordinal;
+@@ -348,7 +348,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
+ 		return -E2BIG;
+ 	}
+ 
+-	mutex_lock(&chip->tpm_mutex);
++	if (!(flags & TPM_TRANSMIT_UNLOCKED))
++		mutex_lock(&chip->tpm_mutex);
+ 
+ 	rc = chip->ops->send(chip, (u8 *) buf, count);
+ 	if (rc < 0) {
+@@ -391,20 +392,21 @@ out_recv:
+ 		dev_err(chip->pdev,
+ 			"tpm_transmit: tpm_recv: error %zd\n", rc);
+ out:
+-	mutex_unlock(&chip->tpm_mutex);
++	if (!(flags & TPM_TRANSMIT_UNLOCKED))
++		mutex_unlock(&chip->tpm_mutex);
+ 	return rc;
+ }
+ 
+ #define TPM_DIGEST_SIZE 20
+ #define TPM_RET_CODE_IDX 6
+ 
+-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd,
+-			 int len, const char *desc)
++ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd,
++			 int len, unsigned int flags, const char *desc)
+ {
+-	struct tpm_output_header *header;
++	const struct tpm_output_header *header;
+ 	int err;
+ 
+-	len = tpm_transmit(chip, (u8 *) cmd, len);
++	len = tpm_transmit(chip, (const u8 *)cmd, len, flags);
+ 	if (len <  0)
+ 		return len;
+ 	else if (len < TPM_HEADER_SIZE)
+@@ -452,7 +454,8 @@ ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
+ 		tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ 		tpm_cmd.params.getcap_in.subcap = subcap_id;
+ 	}
+-	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
++	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
++			      desc);
+ 	if (!rc)
+ 		*cap = tpm_cmd.params.getcap_out.cap;
+ 	return rc;
+@@ -468,7 +471,7 @@ void tpm_gen_interrupt(struct tpm_chip *chip)
+ 	tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ 	tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
+ 
+-	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
++	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
+ 			      "attempting to determine the timeouts");
+ }
+ EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
+@@ -489,7 +492,7 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
+ 	start_cmd.header.in = tpm_startup_header;
+ 
+ 	start_cmd.params.startup_in.startup_type = startup_type;
+-	return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE,
++	return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
+ 				"attempting to start the TPM");
+ }
+ 
+@@ -505,7 +508,8 @@ int tpm_get_timeouts(struct tpm_chip *chip)
+ 	tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+ 	tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ 	tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
+-	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, NULL);
++	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
++			      NULL);
+ 
+ 	if (rc == TPM_ERR_INVALID_POSTINIT) {
+ 		/* The TPM is not started, we are the first to talk to it.
+@@ -519,7 +523,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
+ 		tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ 		tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
+ 		rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
+-				  NULL);
++				      0, NULL);
+ 	}
+ 	if (rc) {
+ 		dev_err(chip->pdev,
+@@ -580,7 +584,7 @@ duration:
+ 	tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ 	tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
+ 
+-	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
++	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
+ 			      "attempting to determine the durations");
+ 	if (rc)
+ 		return rc;
+@@ -636,7 +640,7 @@ static int tpm_continue_selftest(struct tpm_chip *chip)
+ 	struct tpm_cmd_t cmd;
+ 
+ 	cmd.header.in = continue_selftest_header;
+-	rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
++	rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE, 0,
+ 			      "continue selftest");
+ 	return rc;
+ }
+@@ -656,7 +660,7 @@ int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+ 
+ 	cmd.header.in = pcrread_header;
+ 	cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
+-	rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE,
++	rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE, 0,
+ 			      "attempting to read a pcr value");
+ 
+ 	if (rc == 0)
+@@ -754,7 +758,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
+ 	cmd.header.in = pcrextend_header;
+ 	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
+ 	memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
+-	rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
++	rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0,
+ 			      "attempting extend a PCR value");
+ 
+ 	tpm_chip_put(chip);
+@@ -793,7 +797,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
+ 		/* Attempt to read a PCR value */
+ 		cmd.header.in = pcrread_header;
+ 		cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0);
+-		rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE);
++		rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE, 0);
+ 		/* Some buggy TPMs will not respond to tpm_tis_ready() for
+ 		 * around 300ms while the self test is ongoing, keep trying
+ 		 * until the self test duration expires. */
+@@ -834,7 +838,7 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
+ 	if (chip == NULL)
+ 		return -ENODEV;
+ 
+-	rc = tpm_transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
++	rc = tpm_transmit_cmd(chip, cmd, buflen, 0, "attempting tpm_cmd");
+ 
+ 	tpm_chip_put(chip);
+ 	return rc;
+@@ -936,14 +940,15 @@ int tpm_pm_suspend(struct device *dev)
+ 		cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr);
+ 		memcpy(cmd.params.pcrextend_in.hash, dummy_hash,
+ 		       TPM_DIGEST_SIZE);
+-		rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
++		rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0,
+ 				      "extending dummy pcr before suspend");
+ 	}
+ 
+ 	/* now do the actual savestate */
+ 	for (try = 0; try < TPM_RETRY; try++) {
+ 		cmd.header.in = savestate_header;
+-		rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL);
++		rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, 0,
++				      NULL);
+ 
+ 		/*
+ 		 * If the TPM indicates that it is too busy to respond to
+@@ -1027,8 +1032,8 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
+ 		tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
+ 
+ 		err = tpm_transmit_cmd(chip, &tpm_cmd,
+-				   TPM_GETRANDOM_RESULT_SIZE + num_bytes,
+-				   "attempting get random");
++				       TPM_GETRANDOM_RESULT_SIZE + num_bytes,
++				       0, "attempting get random");
+ 		if (err)
+ 			break;
+ 
+diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
+index ee66fd4673f3..f880856aa75e 100644
+--- a/drivers/char/tpm/tpm-sysfs.c
++++ b/drivers/char/tpm/tpm-sysfs.c
+@@ -39,7 +39,7 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
+ 	struct tpm_chip *chip = dev_get_drvdata(dev);
+ 
+ 	tpm_cmd.header.in = tpm_readpubek_header;
+-	err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
++	err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, 0,
+ 			       "attempting to read the PUBEK");
+ 	if (err)
+ 		goto out;
+diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
+index a4257a32964f..2216861f89f1 100644
+--- a/drivers/char/tpm/tpm.h
++++ b/drivers/char/tpm/tpm.h
+@@ -498,11 +498,15 @@ extern struct class *tpm_class;
+ extern dev_t tpm_devt;
+ extern const struct file_operations tpm_fops;
+ 
++enum tpm_transmit_flags {
++	TPM_TRANSMIT_UNLOCKED	= BIT(0),
++};
++
++ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
++		     unsigned int flags);
++ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd, int len,
++			 unsigned int flags, const char *desc);
+ ssize_t	tpm_getcap(struct device *, __be32, cap_t *, const char *);
+-ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
+-		     size_t bufsiz);
+-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd, int len,
+-			 const char *desc);
+ extern int tpm_get_timeouts(struct tpm_chip *);
+ extern void tpm_gen_interrupt(struct tpm_chip *);
+ extern int tpm_do_selftest(struct tpm_chip *);
+diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
+index 678af51fb29e..cb7e4f6b70ba 100644
+--- a/drivers/char/tpm/tpm2-cmd.c
++++ b/drivers/char/tpm/tpm2-cmd.c
+@@ -264,7 +264,7 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+ 	       sizeof(cmd.params.pcrread_in.pcr_select));
+ 	cmd.params.pcrread_in.pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7);
+ 
+-	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
++	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
+ 			      "attempting to read a pcr value");
+ 	if (rc == 0) {
+ 		buf = cmd.params.pcrread_out.digest;
+@@ -312,7 +312,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
+ 	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
+ 	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
+ 
+-	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
++	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
+ 			      "attempting extend a PCR value");
+ 
+ 	return rc;
+@@ -358,7 +358,7 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max)
+ 		cmd.header.in = tpm2_getrandom_header;
+ 		cmd.params.getrandom_in.size = cpu_to_be16(num_bytes);
+ 
+-		err = tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
++		err = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
+ 				       "attempting get random");
+ 		if (err)
+ 			break;
+@@ -416,12 +416,12 @@ static void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle,
+ }
+ 
+ /**
+- * tpm2_seal_trusted() - seal a trusted key
+- * @chip_num: A specific chip number for the request or TPM_ANY_NUM
+- * @options: authentication values and other options
++ * tpm2_seal_trusted() - seal the payload of a trusted key
++ * @chip_num: TPM chip to use
+  * @payload: the key data in clear and encrypted form
++ * @options: authentication values and other options
+  *
+- * Returns < 0 on error and 0 on success.
++ * Return: < 0 on error and 0 on success.
+  */
+ int tpm2_seal_trusted(struct tpm_chip *chip,
+ 		      struct trusted_key_payload *payload,
+@@ -472,7 +472,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
+ 		goto out;
+ 	}
+ 
+-	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "sealing data");
++	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, 0, "sealing data");
+ 	if (rc)
+ 		goto out;
+ 
+@@ -494,10 +494,18 @@ out:
+ 	return rc;
+ }
+ 
+-static int tpm2_load(struct tpm_chip *chip,
+-		     struct trusted_key_payload *payload,
+-		     struct trusted_key_options *options,
+-		     u32 *blob_handle)
++/**
++ * tpm2_load_cmd() - execute a TPM2_Load command
++ * @chip_num: TPM chip to use
++ * @payload: the key data in clear and encrypted form
++ * @options: authentication values and other options
++ *
++ * Return: same as with tpm_transmit_cmd
++ */
++static int tpm2_load_cmd(struct tpm_chip *chip,
++			 struct trusted_key_payload *payload,
++			 struct trusted_key_options *options,
++			 u32 *blob_handle, unsigned int flags)
+ {
+ 	struct tpm_buf buf;
+ 	unsigned int private_len;
+@@ -532,7 +540,7 @@ static int tpm2_load(struct tpm_chip *chip,
+ 		goto out;
+ 	}
+ 
+-	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "loading blob");
++	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, "loading blob");
+ 	if (!rc)
+ 		*blob_handle = be32_to_cpup(
+ 			(__be32 *) &buf.data[TPM_HEADER_SIZE]);
+@@ -546,7 +554,16 @@ out:
+ 	return rc;
+ }
+ 
+-static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
++/**
++ * tpm2_flush_context_cmd() - execute a TPM2_FlushContext command
++ * @chip_num: TPM chip to use
++ * @payload: the key data in clear and encrypted form
++ * @options: authentication values and other options
++ *
++ * Return: same as with tpm_transmit_cmd
++ */
++static void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle,
++				   unsigned int flags)
+ {
+ 	struct tpm_buf buf;
+ 	int rc;
+@@ -560,7 +577,8 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
+ 
+ 	tpm_buf_append_u32(&buf, handle);
+ 
+-	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "flushing context");
++	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags,
++			      "flushing context");
+ 	if (rc)
+ 		dev_warn(chip->pdev, "0x%08x was not flushed, rc=%d\n", handle,
+ 			 rc);
+@@ -568,10 +586,18 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
+ 	tpm_buf_destroy(&buf);
+ }
+ 
+-static int tpm2_unseal(struct tpm_chip *chip,
+-		       struct trusted_key_payload *payload,
+-		       struct trusted_key_options *options,
+-		       u32 blob_handle)
++/**
++ * tpm2_unseal_cmd() - execute a TPM2_Unload command
++ * @chip_num: TPM chip to use
++ * @payload: the key data in clear and encrypted form
++ * @options: authentication values and other options
++ *
++ * Return: same as with tpm_transmit_cmd
++ */
++static int tpm2_unseal_cmd(struct tpm_chip *chip,
++			   struct trusted_key_payload *payload,
++			   struct trusted_key_options *options,
++			   u32 blob_handle, unsigned int flags)
+ {
+ 	struct tpm_buf buf;
+ 	u16 data_len;
+@@ -589,7 +615,7 @@ static int tpm2_unseal(struct tpm_chip *chip,
+ 			     options->blobauth /* hmac */,
+ 			     TPM_DIGEST_SIZE);
+ 
+-	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "unsealing");
++	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, "unsealing");
+ 	if (rc > 0)
+ 		rc = -EPERM;
+ 
+@@ -608,12 +634,12 @@ static int tpm2_unseal(struct tpm_chip *chip,
+ }
+ 
+ /**
+- * tpm_unseal_trusted() - unseal a trusted key
+- * @chip_num: A specific chip number for the request or TPM_ANY_NUM
+- * @options: authentication values and other options
++ * tpm_unseal_trusted() - unseal the payload of a trusted key
++ * @chip_num: TPM chip to use
+  * @payload: the key data in clear and encrypted form
++ * @options: authentication values and other options
+  *
+- * Returns < 0 on error and 0 on success.
++ * Return: < 0 on error and 0 on success.
+  */
+ int tpm2_unseal_trusted(struct tpm_chip *chip,
+ 			struct trusted_key_payload *payload,
+@@ -622,14 +648,17 @@ int tpm2_unseal_trusted(struct tpm_chip *chip,
+ 	u32 blob_handle;
+ 	int rc;
+ 
+-	rc = tpm2_load(chip, payload, options, &blob_handle);
++	mutex_lock(&chip->tpm_mutex);
++	rc = tpm2_load_cmd(chip, payload, options, &blob_handle,
++			   TPM_TRANSMIT_UNLOCKED);
+ 	if (rc)
+-		return rc;
+-
+-	rc = tpm2_unseal(chip, payload, options, blob_handle);
+-
+-	tpm2_flush_context(chip, blob_handle);
++		goto out;
+ 
++	rc = tpm2_unseal_cmd(chip, payload, options, blob_handle,
++			     TPM_TRANSMIT_UNLOCKED);
++	tpm2_flush_context_cmd(chip, blob_handle, TPM_TRANSMIT_UNLOCKED);
++out:
++	mutex_unlock(&chip->tpm_mutex);
+ 	return rc;
+ }
+ 
+@@ -655,7 +684,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,  u32 *value,
+ 	cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(property_id);
+ 	cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1);
+ 
+-	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), desc);
++	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, desc);
+ 	if (!rc)
+ 		*value = be32_to_cpu(cmd.params.get_tpm_pt_out.value);
+ 
+@@ -689,7 +718,7 @@ int tpm2_startup(struct tpm_chip *chip, u16 startup_type)
+ 	cmd.header.in = tpm2_startup_header;
+ 
+ 	cmd.params.startup_in.startup_type = cpu_to_be16(startup_type);
+-	return tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
++	return tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
+ 				"attempting to start the TPM");
+ }
+ EXPORT_SYMBOL_GPL(tpm2_startup);
+@@ -718,7 +747,7 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
+ 	cmd.header.in = tpm2_shutdown_header;
+ 	cmd.params.startup_in.startup_type = cpu_to_be16(shutdown_type);
+ 
+-	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), "stopping the TPM");
++	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, "stopping the TPM");
+ 
+ 	/* In places where shutdown command is sent there's no much we can do
+ 	 * except print the error code on a system failure.
+@@ -784,7 +813,7 @@ static int tpm2_start_selftest(struct tpm_chip *chip, bool full)
+ 	cmd.header.in = tpm2_selftest_header;
+ 	cmd.params.selftest_in.full_test = full;
+ 
+-	rc = tpm_transmit_cmd(chip, &cmd, TPM2_SELF_TEST_IN_SIZE,
++	rc = tpm_transmit_cmd(chip, &cmd, TPM2_SELF_TEST_IN_SIZE, 0,
+ 			      "continue selftest");
+ 
+ 	/* At least some prototype chips seem to give RC_TESTING error
+@@ -836,7 +865,7 @@ int tpm2_do_selftest(struct tpm_chip *chip)
+ 		cmd.params.pcrread_in.pcr_select[1] = 0x00;
+ 		cmd.params.pcrread_in.pcr_select[2] = 0x00;
+ 
+-		rc = tpm_transmit_cmd(chip, (u8 *) &cmd, sizeof(cmd), NULL);
++		rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, NULL);
+ 		if (rc < 0)
+ 			break;
+ 
+@@ -885,7 +914,7 @@ int tpm2_probe(struct tpm_chip *chip)
+ 	cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(0x100);
+ 	cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1);
+ 
+-	rc = tpm_transmit(chip, (const char *) &cmd, sizeof(cmd));
++	rc = tpm_transmit(chip, (const u8 *)&cmd, sizeof(cmd), 0);
+ 	if (rc <  0)
+ 		return rc;
+ 	else if (rc < TPM_HEADER_SIZE)
+diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
+index 61e64293b765..2b21398c3adc 100644
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -149,6 +149,11 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
+ 	struct crb_priv *priv = chip->vendor.priv;
+ 	int rc = 0;
+ 
++	/* Zero the cancel register so that the next command will not get
++	 * canceled.
++	 */
++	iowrite32(0, &priv->cca->cancel);
++
+ 	if (len > le32_to_cpu(ioread32(&priv->cca->cmd_size))) {
+ 		dev_err(&chip->dev,
+ 			"invalid command count value %x %zx\n",
+@@ -182,8 +187,6 @@ static void crb_cancel(struct tpm_chip *chip)
+ 
+ 	if ((priv->flags & CRB_FL_ACPI_START) && crb_do_acpi_start(chip))
+ 		dev_err(&chip->dev, "ACPI Start failed\n");
+-
+-	iowrite32(0, &priv->cca->cancel);
+ }
+ 
+ static bool crb_req_canceled(struct tpm_chip *chip, u8 status)
+diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
+index e342565e8715..1855b9ee807f 100644
+--- a/drivers/cpuidle/cpuidle-arm.c
++++ b/drivers/cpuidle/cpuidle-arm.c
+@@ -135,6 +135,7 @@ static int __init arm_idle_init(void)
+ 		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ 		if (!dev) {
+ 			pr_err("Failed to allocate cpuidle device\n");
++			ret = -ENOMEM;
+ 			goto out_fail;
+ 		}
+ 		dev->cpu = cpu;
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index 4d92df6ef9fe..7398262a2fab 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -1460,6 +1460,7 @@ config MFD_WM8350
+ config MFD_WM8350_I2C
+ 	bool "Wolfson Microelectronics WM8350 with I2C"
+ 	select MFD_WM8350
++	select REGMAP_I2C
+ 	depends on I2C=y
+ 	help
+ 	  The WM8350 is an integrated audio and power management
+diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c
+index 06c205868573..c216c3a55793 100644
+--- a/drivers/mfd/atmel-hlcdc.c
++++ b/drivers/mfd/atmel-hlcdc.c
+@@ -50,8 +50,9 @@ static int regmap_atmel_hlcdc_reg_write(void *context, unsigned int reg,
+ 	if (reg <= ATMEL_HLCDC_DIS) {
+ 		u32 status;
+ 
+-		readl_poll_timeout(hregmap->regs + ATMEL_HLCDC_SR, status,
+-				   !(status & ATMEL_HLCDC_SIP), 1, 100);
++		readl_poll_timeout_atomic(hregmap->regs + ATMEL_HLCDC_SR,
++					  status, !(status & ATMEL_HLCDC_SIP),
++					  1, 100);
+ 	}
+ 
+ 	writel(val, hregmap->regs + reg);
+diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
+index dbd907d7170e..691dab791f7a 100644
+--- a/drivers/mfd/rtsx_usb.c
++++ b/drivers/mfd/rtsx_usb.c
+@@ -46,9 +46,6 @@ static void rtsx_usb_sg_timed_out(unsigned long data)
+ 
+ 	dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__);
+ 	usb_sg_cancel(&ucr->current_sg);
+-
+-	/* we know the cancellation is caused by time-out */
+-	ucr->current_sg.status = -ETIMEDOUT;
+ }
+ 
+ static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr,
+@@ -67,12 +64,15 @@ static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr,
+ 	ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout);
+ 	add_timer(&ucr->sg_timer);
+ 	usb_sg_wait(&ucr->current_sg);
+-	del_timer_sync(&ucr->sg_timer);
++	if (!del_timer_sync(&ucr->sg_timer))
++		ret = -ETIMEDOUT;
++	else
++		ret = ucr->current_sg.status;
+ 
+ 	if (act_len)
+ 		*act_len = ucr->current_sg.bytes;
+ 
+-	return ucr->current_sg.status;
++	return ret;
+ }
+ 
+ int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe,
+diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
+index d409ceb2231e..c118a7ec94d6 100644
+--- a/include/linux/mfd/88pm80x.h
++++ b/include/linux/mfd/88pm80x.h
+@@ -350,7 +350,7 @@ static inline int pm80x_dev_suspend(struct device *dev)
+ 	int irq = platform_get_irq(pdev, 0);
+ 
+ 	if (device_may_wakeup(dev))
+-		set_bit((1 << irq), &chip->wu_flag);
++		set_bit(irq, &chip->wu_flag);
+ 
+ 	return 0;
+ }
+@@ -362,7 +362,7 @@ static inline int pm80x_dev_resume(struct device *dev)
+ 	int irq = platform_get_irq(pdev, 0);
+ 
+ 	if (device_may_wakeup(dev))
+-		clear_bit((1 << irq), &chip->wu_flag);
++		clear_bit(irq, &chip->wu_flag);
+ 
+ 	return 0;
+ }
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index 4ff237dbc006..445601c580d6 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -298,17 +298,34 @@ u32 (*arch_gettimeoffset)(void) = default_arch_gettimeoffset;
+ static inline u32 arch_gettimeoffset(void) { return 0; }
+ #endif
+ 
++static inline s64 timekeeping_delta_to_ns(struct tk_read_base *tkr,
++					  cycle_t delta)
++{
++	s64 nsec;
++
++	nsec = delta * tkr->mult + tkr->xtime_nsec;
++	nsec >>= tkr->shift;
++
++	/* If arch requires, add in get_arch_timeoffset() */
++	return nsec + arch_gettimeoffset();
++}
++
+ static inline s64 timekeeping_get_ns(struct tk_read_base *tkr)
+ {
+ 	cycle_t delta;
+-	s64 nsec;
+ 
+ 	delta = timekeeping_get_delta(tkr);
++	return timekeeping_delta_to_ns(tkr, delta);
++}
+ 
+-	nsec = (delta * tkr->mult + tkr->xtime_nsec) >> tkr->shift;
++static inline s64 timekeeping_cycles_to_ns(struct tk_read_base *tkr,
++					    cycle_t cycles)
++{
++	cycle_t delta;
+ 
+-	/* If arch requires, add in get_arch_timeoffset() */
+-	return nsec + arch_gettimeoffset();
++	/* calculate the delta since the last update_wall_time */
++	delta = clocksource_delta(cycles, tkr->cycle_last, tkr->mask);
++	return timekeeping_delta_to_ns(tkr, delta);
+ }
+ 
+ /**
+@@ -385,8 +402,11 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf)
+ 		tkr = tkf->base + (seq & 0x01);
+ 		now = ktime_to_ns(tkr->base);
+ 
+-		now += clocksource_delta(tkr->read(tkr->clock),
+-					 tkr->cycle_last, tkr->mask);
++		now += timekeeping_delta_to_ns(tkr,
++				clocksource_delta(
++					tkr->read(tkr->clock),
++					tkr->cycle_last,
++					tkr->mask));
+ 	} while (read_seqcount_retry(&tkf->seq, seq));
+ 
+ 	return now;
+diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
+index 1d950fbb2aec..2d1fe34781fa 100644
+--- a/security/integrity/ima/ima_api.c
++++ b/security/integrity/ima/ima_api.c
+@@ -202,7 +202,7 @@ int ima_collect_measurement(struct integrity_iint_cache *iint,
+ 	} hash;
+ 
+ 	if (xattr_value)
+-		*xattr_len = ima_read_xattr(file->f_path.dentry, xattr_value);
++		*xattr_len = ima_read_xattr(file_dentry(file), xattr_value);
+ 
+ 	if (!(iint->flags & IMA_COLLECTED)) {
+ 		u64 i_version = file_inode(file)->i_version;
+diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
+index 1873b5536f80..ed5a9c110b3a 100644
+--- a/security/integrity/ima/ima_appraise.c
++++ b/security/integrity/ima/ima_appraise.c
+@@ -189,7 +189,7 @@ int ima_appraise_measurement(int func, struct integrity_iint_cache *iint,
+ {
+ 	static const char op[] = "appraise_data";
+ 	char *cause = "unknown";
+-	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *dentry = file_dentry(file);
+ 	struct inode *inode = d_backing_inode(dentry);
+ 	enum integrity_status status = INTEGRITY_UNKNOWN;
+ 	int rc = xattr_len, hash_start = 0;
+@@ -289,7 +289,7 @@ out:
+  */
+ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
+ {
+-	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *dentry = file_dentry(file);
+ 	int rc = 0;
+ 
+ 	/* do not collect and update hash for digital signatures */
+diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
+index 36470af7eda7..92b819e4f729 100644
+--- a/sound/pci/ali5451/ali5451.c
++++ b/sound/pci/ali5451/ali5451.c
+@@ -1408,6 +1408,7 @@ snd_ali_playback_pointer(struct snd_pcm_substream *substream)
+ 	spin_unlock(&codec->reg_lock);
+ 	dev_dbg(codec->card->dev, "playback pointer returned cso=%xh.\n", cso);
+ 
++	cso %= runtime->buffer_size;
+ 	return cso;
+ }
+ 
+@@ -1428,6 +1429,7 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream)
+ 	cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
+ 	spin_unlock(&codec->reg_lock);
+ 
++	cso %= runtime->buffer_size;
+ 	return cso;
+ }
+ 
+diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
+index 81b7da8e56d3..183311cb849e 100644
+--- a/sound/usb/line6/driver.c
++++ b/sound/usb/line6/driver.c
+@@ -29,7 +29,7 @@
+ /*
+ 	This is Line 6's MIDI manufacturer ID.
+ */
+-const unsigned char line6_midi_id[] = {
++const unsigned char line6_midi_id[3] = {
+ 	0x00, 0x01, 0x0c
+ };
+ EXPORT_SYMBOL_GPL(line6_midi_id);
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index f6c3bf79af9a..04991b009132 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -1831,6 +1831,7 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
+ }
+ 
+ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
++					 struct usb_mixer_elem_info *cval,
+ 					 struct snd_kcontrol *kctl)
+ {
+ 	/* Approximation using 10 ranges based on output measurement on hw v1.2.
+@@ -1848,10 +1849,19 @@ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
+ 		41, 50, TLV_DB_MINMAX_ITEM(-441, 0),
+ 	);
+ 
+-	usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n");
+-	kctl->tlv.p = scale;
+-	kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+-	kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
++	if (cval->min == 0 && cval->max == 50) {
++		usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk (0-50 variant)\n");
++		kctl->tlv.p = scale;
++		kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
++		kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
++
++	} else if (cval->min == 0 && cval->max <= 1000) {
++		/* Some other clearly broken DragonFly variant.
++		 * At least a 0..53 variant (hw v1.0) exists.
++		 */
++		usb_audio_info(mixer->chip, "ignoring too narrow dB range on a DragonFly device");
++		kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
++	}
+ }
+ 
+ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
+@@ -1860,8 +1870,8 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
+ {
+ 	switch (mixer->chip->usb_id) {
+ 	case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
+-		if (unitid == 7 && cval->min == 0 && cval->max == 50)
+-			snd_dragonfly_quirk_db_scale(mixer, kctl);
++		if (unitid == 7 && cval->control == UAC_FU_VOLUME)
++			snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
+ 		break;
+ 	}
+ }